From 3e5bcbf1233ea3cc8674767c10bd8dccdfd99182 Mon Sep 17 00:00:00 2001 From: awkweb Date: Wed, 24 May 2023 18:58:31 -0400 Subject: [PATCH] fix: getContract estimateGas (#572) * wip: fix getContract estimateGas * chore: rome config * feat: estimateGas with wallet client * chore: rome * chore: format * chore: changeset --------- Co-authored-by: tmm --- .changeset/perfect-dingos-repair.md | 5 + package.json | 69 ++----- pnpm-lock.yaml | 168 ++++++++++++------ site/docs/contract/getContract.md | 1 + src/actions/getContract.test-d.ts | 141 +++++---------- src/actions/getContract.test.ts | 37 +++- src/actions/getContract.ts | 160 +++++++++++------ .../public/estimateContractGas.test-d.ts | 36 ++++ src/actions/public/estimateContractGas.ts | 14 +- 9 files changed, 369 insertions(+), 262 deletions(-) create mode 100644 .changeset/perfect-dingos-repair.md create mode 100644 src/actions/public/estimateContractGas.test-d.ts diff --git a/.changeset/perfect-dingos-repair.md b/.changeset/perfect-dingos-repair.md new file mode 100644 index 0000000000..541e358a8b --- /dev/null +++ b/.changeset/perfect-dingos-repair.md @@ -0,0 +1,5 @@ +--- +"viem": patch +--- + +Fixed contract instance `estimateGas` typing. diff --git a/package.json b/package.json index d93efdc016..1ceeb6ac94 100644 --- a/package.json +++ b/package.json @@ -111,39 +111,17 @@ }, "typesVersions": { "*": { - "abi": [ - "./dist/types/abi.d.ts" - ], - "accounts": [ - "./dist/types/accounts/index.d.ts" - ], - "chains": [ - "./dist/types/chains.d.ts" - ], - "contract": [ - "./dist/types/contract.d.ts" - ], - "ens": [ - "./dist/types/ens.d.ts" - ], - "ethers": [ - "./dist/types/ethers.d.ts" - ], - "public": [ - "./dist/types/public.d.ts" - ], - "test": [ - "./dist/types/test.d.ts" - ], - "utils": [ - "./dist/types/utils/index.d.ts" - ], - "wallet": [ - "./dist/types/wallet.d.ts" - ], - "window": [ - "./dist/types/window.d.ts" - ] + "abi": ["./dist/types/abi.d.ts"], + "accounts": ["./dist/types/accounts/index.d.ts"], + "chains": ["./dist/types/chains.d.ts"], + "contract": ["./dist/types/contract.d.ts"], + "ens": ["./dist/types/ens.d.ts"], + "ethers": ["./dist/types/ethers.d.ts"], + "public": ["./dist/types/public.d.ts"], + "test": ["./dist/types/test.d.ts"], + "utils": ["./dist/types/utils/index.d.ts"], + "wallet": ["./dist/types/wallet.d.ts"], + "window": ["./dist/types/window.d.ts"] } }, "dependencies": { @@ -169,37 +147,28 @@ "@vitest/coverage-c8": "^0.30.1", "@vitest/ui": "^0.30.1", "@wagmi/cli": "^0.1.6", - "bun": "^0.5.5", + "bun": "^0.5.9", "ethers": "^5.7.2", "ethers@6": "npm:ethers@^6.0.2", "fs-extra": "^10.1.0", - "rimraf": "^4.1.2", - "rome": "^12.0.0", + "rimraf": "^4.4.1", + "rome": "~12.0.0", "simple-git-hooks": "^2.8.1", "size-limit": "^8.2.4", - "typescript": "^5.0.3", + "typescript": "^5.0.4", "vite": "^4.1.4", "vitest": "~0.30.1" }, "license": "MIT", "repository": "wagmi-dev/viem", - "authors": [ - "awkweb.eth", - "jxom.eth" - ], + "authors": ["awkweb.eth", "jxom.eth"], "funding": [ { "type": "github", "url": "https://github.com/sponsors/wagmi-dev" } ], - "keywords": [ - "eth", - "ethereum", - "dapps", - "wallet", - "web3" - ], + "keywords": ["eth", "ethereum", "dapps", "wallet", "web3"], "size-limit": [ { "path": "./dist/cjs/index.js" @@ -217,9 +186,7 @@ "vitepress@1.0.0-alpha.61": "patches/vitepress@1.0.0-alpha.61.patch" }, "peerDependencyRules": { - "ignoreMissing": [ - "@algolia/client-search" - ] + "ignoreMissing": ["@algolia/client-search"] } } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 05b52f57f7..291c216a79 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -29,10 +29,10 @@ importers: version: 1.2.0 '@wagmi/chains': specifier: 0.2.16 - version: 0.2.16(typescript@5.0.3) + version: 0.2.16(typescript@5.0.4) abitype: specifier: 0.8.2 - version: 0.8.2(typescript@5.0.3) + version: 0.8.2(typescript@5.0.4) isomorphic-ws: specifier: 5.0.0 version: 5.0.0(ws@8.12.0) @@ -72,24 +72,24 @@ importers: version: 0.30.1 '@wagmi/cli': specifier: ^0.1.6 - version: 0.1.6(typescript@5.0.3) + version: 0.1.6(typescript@5.0.4) bun: - specifier: ^0.5.5 - version: 0.5.6 + specifier: ^0.5.9 + version: 0.5.9 ethers: specifier: ^5.7.2 version: 5.7.2 ethers@6: specifier: npm:ethers@^6.0.2 - version: /ethers@6.3.0 + version: /ethers@6.4.0 fs-extra: specifier: ^10.1.0 version: 10.1.0 rimraf: - specifier: ^4.1.2 - version: 4.1.2 + specifier: ^4.4.1 + version: 4.4.1 rome: - specifier: ^12.0.0 + specifier: ~12.0.0 version: 12.0.0 simple-git-hooks: specifier: ^2.8.1 @@ -98,8 +98,8 @@ importers: specifier: ^8.2.4 version: 8.2.4 typescript: - specifier: ^5.0.3 - version: 5.0.3 + specifier: ^5.0.4 + version: 5.0.4 vite: specifier: ^4.1.4 version: 4.1.4(@types/node@18.16.3) @@ -461,6 +461,7 @@ packages: /@adraffy/ens-normalize@1.9.0: resolution: {integrity: sha512-iowxq3U30sghZotgl4s/oJRci6WPBfNO5YYgk2cIOMCHr3LeGPcsZjCEr+33Q4N+oV3OABDAtA+pyvWjbvBifQ==} + dev: false /@algolia/autocomplete-core@1.7.4: resolution: {integrity: sha512-daoLpQ3ps/VTMRZDEBfU8ixXd+amZcNJ4QSP3IERGyzqnL5Ch8uSRFt/4G8pUvW9c3o6GA4vtVv4I4lmnkdXyg==} @@ -2014,48 +2015,48 @@ packages: '@octokit/openapi-types': 12.11.0 dev: true - /@oven/bun-darwin-aarch64@0.5.6: - resolution: {integrity: sha512-QaSQ0kZdnXU+s/MjzxheE4Rj2L0LuNdb+m0P+HZIiDFzvsEtOPZyObL7pAWw1zXNalRQeHVeWR7g3pWUH5CqZg==} + /@oven/bun-darwin-aarch64@0.5.9: + resolution: {integrity: sha512-4AfiEln+yA5FzR1mEpcd8816ziq0rPT9IQOFMmGbtMLXvYRfWul3ywaquI7nl8c8RU3Lzu5Itlwirx65DKJ19A==} cpu: [arm64] os: [darwin] requiresBuild: true dev: true optional: true - /@oven/bun-darwin-x64-baseline@0.5.6: - resolution: {integrity: sha512-HInWods1mG+RXaNisjn564vALytCal1oYtPy+snVRFhZKWuJgFeW4uRiOMf5iHcgst6svV6zZxjbM4I69UmcnA==} + /@oven/bun-darwin-x64-baseline@0.5.9: + resolution: {integrity: sha512-hhsUtMHor9h4fQozPOzSy82P0smT8xaFJouumJv6ekxngZ5Xa13BWfUJZsdTcB+pBsdMUC8V8MRfNFyfiZZiog==} cpu: [x64] os: [darwin] requiresBuild: true dev: true optional: true - /@oven/bun-darwin-x64@0.5.6: - resolution: {integrity: sha512-rUvUMPmEHWQVXYyh2jX0IKga2WyqY2W94iNaV3UziO1AC+7ZWKGCra6RrPweqlnUYrjzfi72MNa57PPOV0WCkg==} + /@oven/bun-darwin-x64@0.5.9: + resolution: {integrity: sha512-YYYg9qIFcvwQqO4GKs7SkpOLCERxHUKpmrZ7yl0DWPAfZWm7xqoTOs1ceCgAUygkKZ9/eLcj5VD8qjhth4Ynyg==} cpu: [x64] os: [darwin] requiresBuild: true dev: true optional: true - /@oven/bun-linux-aarch64@0.5.6: - resolution: {integrity: sha512-/nFibpC73QmUmDJb6MihyM3lNNzXKYaZIQ5eHRqoYeU2dE2LEAbkMpBVDOoL+y2ZEnE2z67+f1WuLTcTPmEwwA==} + /@oven/bun-linux-aarch64@0.5.9: + resolution: {integrity: sha512-D0kZM+VDLhxPKXnczG3d2LlrzWp+bv6LIhjIC/2UTUNdipjO5tFHoCbsQvcPpg+hJYsj0We43pdFPbIC7cL+dg==} cpu: [arm64] os: [linux] requiresBuild: true dev: true optional: true - /@oven/bun-linux-x64-baseline@0.5.6: - resolution: {integrity: sha512-0tbproUyIrZ6VSGysHLr0Uwsy+v5Dc5Wj6Xx1cBUC/ylnP60eBQHc9U+Xjat3Vlk3rGp95mbIP4PIInSDIFQvw==} + /@oven/bun-linux-x64-baseline@0.5.9: + resolution: {integrity: sha512-HO4HMmOMRz7SWEUR4P+iZe3RHDgkrYkNmW1clKIddgrVNf3pS+lKOZBW/GcX2cjjHMRp6vcjPvOxa9oXfqLuVA==} cpu: [x64] os: [linux] requiresBuild: true dev: true optional: true - /@oven/bun-linux-x64@0.5.6: - resolution: {integrity: sha512-wjLAzC0TEv3oqZIFcSajzQV6Otj0Dcuf7EiOQjUYtfugsEFUEtHqXhMUivk0ryKGONjd0PqxIqK7gRJH6aOSkw==} + /@oven/bun-linux-x64@0.5.9: + resolution: {integrity: sha512-ORE/a3XpDZPZwL/2dvlkJOt3lBd637eonsluY49IcjhYci3eDXKA3S6A2x9H7MVTUhv8G7z6fDztRVh+W7Rz6A==} cpu: [x64] os: [linux] requiresBuild: true @@ -2264,6 +2265,10 @@ packages: resolution: {integrity: sha512-Wha1UwsB3CYdqUm2PPzh/1gujGCNtWVUYF0mB00fJFoR4gTyWTDPjSm+zBF787Ahw8vSGgBja90MkgFwvB86Dg==} dev: true + /@types/node@18.15.13: + resolution: {integrity: sha512-N+0kuo9KgrUQ1Sn/ifDXsvg0TTleP7rIy4zOBGECxAljqvqfqpTfzx0Q1NUedOixRMBfe2Whhb056a42cWs26Q==} + dev: true + /@types/node@18.16.3: resolution: {integrity: sha512-OPs5WnnT1xkCBiuQrZA4+YAV4HEJejmHneyraIaxsbev5yCEr6KMwINNFP9wQeFIw8FWcoTqF3vQsa5CDaI+8Q==} dev: true @@ -2613,7 +2618,7 @@ packages: - vue dev: true - /@wagmi/chains@0.2.16(typescript@5.0.3): + /@wagmi/chains@0.2.16(typescript@5.0.4): resolution: {integrity: sha512-rkWaI2PxCnbD8G07ZZff5QXftnSkYL0h5f4DkHCG3fGYYr/ZDvmCL4bMae7j7A9sAif1csPPBmbCzHp3R5ogCQ==} peerDependencies: typescript: '>=4.9.4' @@ -2621,10 +2626,10 @@ packages: typescript: optional: true dependencies: - typescript: 5.0.3 + typescript: 5.0.4 dev: false - /@wagmi/chains@0.2.7(typescript@5.0.3): + /@wagmi/chains@0.2.7(typescript@5.0.4): resolution: {integrity: sha512-Oqnkl5n9MTBdMzgIwwdSKEDfm0Vdv2CYBaDyTa5SiTjFNaIfT6MRATLg7KbI3JydfxqJphsVFL+TZZqFvkte/g==} peerDependencies: typescript: '>=4.9.4' @@ -2632,10 +2637,10 @@ packages: typescript: optional: true dependencies: - typescript: 5.0.3 + typescript: 5.0.4 dev: true - /@wagmi/cli@0.1.6(typescript@5.0.3): + /@wagmi/cli@0.1.6(typescript@5.0.4): resolution: {integrity: sha512-4ri/QATYDnLNZKVbnulW1Skfu2K5Jc+O0joULoHC6Ag/8Z1QlMEHl9GRXhO+6q68tv382EnVxjIUm6VuzbWpqA==} engines: {node: '>=14'} hasBin: true @@ -2652,8 +2657,8 @@ packages: optional: true dependencies: '@ethersproject/address': 5.7.0 - '@wagmi/chains': 0.2.7(typescript@5.0.3) - abitype: 0.3.0(typescript@5.0.3)(zod@3.20.2) + '@wagmi/chains': 0.2.7(typescript@5.0.4) + abitype: 0.3.0(typescript@5.0.4)(zod@3.20.2) abort-controller: 3.0.0 bundle-require: 3.1.2(esbuild@0.15.13) cac: 6.7.14 @@ -2673,7 +2678,7 @@ packages: pathe: 1.1.0 picocolors: 1.0.0 prettier: 2.8.3 - typescript: 5.0.3 + typescript: 5.0.4 zod: 3.20.2 dev: true @@ -2791,7 +2796,7 @@ packages: resolution: {integrity: sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==} dev: true - /abitype@0.3.0(typescript@5.0.3)(zod@3.20.2): + /abitype@0.3.0(typescript@5.0.4)(zod@3.20.2): resolution: {integrity: sha512-0YokyAV4hKMcy97Pl+6QgZBlBdZJN2llslOs7kiFY+cu7kMlVXDBpxMExfv0krzBCQt2t7hNovpQ3y/zvEm18A==} engines: {pnpm: '>=7'} peerDependencies: @@ -2801,11 +2806,11 @@ packages: zod: optional: true dependencies: - typescript: 5.0.3 + typescript: 5.0.4 zod: 3.20.2 dev: true - /abitype@0.8.2(typescript@5.0.3): + /abitype@0.8.2(typescript@5.0.4): resolution: {integrity: sha512-B1ViNMGpfx/qjVQi0RTc2HEFHuR9uoCoTEkwELT5Y7pBPtBbctYijz9BK6+Kd0hQ3S70FhYTO2dWWk0QNUEXMA==} peerDependencies: typescript: '>=5.0.4' @@ -2814,7 +2819,7 @@ packages: zod: optional: true dependencies: - typescript: 5.0.3 + typescript: 5.0.4 dev: false /abort-controller@3.0.0: @@ -2866,8 +2871,8 @@ packages: resolution: {integrity: sha512-H7wUZRn8WpTq9jocdxQ2c8x2sKo9ZVmzfRE13GiNJXfp7NcKYEdvl3vspKjXox6RIG2VtaRe4JFvxG4rqp2Zuw==} dev: true - /aes-js@4.0.0-beta.3: - resolution: {integrity: sha512-/xJX0/VTPcbc5xQE2VUP91y1xN8q/rDfhEzLm+vLc3hYvb5+qHCnpJRuFcrKn63zumK/sCwYYzhG8HP78JYSTA==} + /aes-js@4.0.0-beta.5: + resolution: {integrity: sha512-G965FqalsNyrPqgEGON7nIx1e/OVENSgiEIzyC63haUMuvNnwIgIjMs52hlTCKhkBny7A2ORNlfY9Zu+jmGk1Q==} dev: true /agent-base@6.0.2: @@ -3078,6 +3083,12 @@ packages: concat-map: 0.0.1 dev: true + /brace-expansion@2.0.1: + resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} + dependencies: + balanced-match: 1.0.2 + dev: true + /braces@3.0.2: resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==} engines: {node: '>=8'} @@ -3132,19 +3143,19 @@ packages: resolution: {integrity: sha512-c4XXSAo4gA03XE3EIOB1bcLxUvWMzhiE9AQdoZi+3fplNLpyeOw7UJM3o1UCtk00NYZQIbgC/eJ88QrlSdxhxg==} dev: true - /bun@0.5.6: - resolution: {integrity: sha512-IzjJd/1l07ZqdgRgReZ6V1WvFs51+DsTmakjvuP7DXccpx3OXhxFaayRUsr+3rA+7dnre+P7j8e7sGB2gYad8g==} + /bun@0.5.9: + resolution: {integrity: sha512-gX4ped5KlWCf6HZId0O4lU2hcbfELeL3Sp6uKjbsTZR3Wu1/grOuXI/jrKd38aFiPdgMnWR0+mWcKuQuIbMUzw==} cpu: [arm64, x64] os: [darwin, linux] hasBin: true requiresBuild: true optionalDependencies: - '@oven/bun-darwin-aarch64': 0.5.6 - '@oven/bun-darwin-x64': 0.5.6 - '@oven/bun-darwin-x64-baseline': 0.5.6 - '@oven/bun-linux-aarch64': 0.5.6 - '@oven/bun-linux-x64': 0.5.6 - '@oven/bun-linux-x64-baseline': 0.5.6 + '@oven/bun-darwin-aarch64': 0.5.9 + '@oven/bun-darwin-x64': 0.5.9 + '@oven/bun-darwin-x64-baseline': 0.5.9 + '@oven/bun-linux-aarch64': 0.5.9 + '@oven/bun-linux-x64': 0.5.9 + '@oven/bun-linux-x64-baseline': 0.5.9 dev: true /bundle-require@3.1.2(esbuild@0.15.13): @@ -4086,14 +4097,15 @@ packages: - utf-8-validate dev: true - /ethers@6.3.0: - resolution: {integrity: sha512-CKFYvTne1YT4S1glTiu7TgGsj0t6c6GAD7evrIk8zbeUb6nK8dcUPAiAWM8uDX/1NmRTvLM9+1Vnn49hwKtEzw==} + /ethers@6.4.0: + resolution: {integrity: sha512-nksaMCwX+BOdV2NQ1/57OehSD2JtujbhrdC2+Fb9VpvBO0WO6h+WWwu3oMMw7aUiTa5lvQcWX1vl4aOy7Q3CTg==} engines: {node: '>=14.0.0'} dependencies: - '@adraffy/ens-normalize': 1.9.0 + '@adraffy/ens-normalize': github.com/ricmoo/ens-normalize.js/2d040533e57e4f25f9a7cc4715e219658ad454b5 '@noble/hashes': 1.1.2 '@noble/secp256k1': 1.7.1 - aes-js: 4.0.0-beta.3 + '@types/node': 18.15.13 + aes-js: 4.0.0-beta.5 tslib: 2.4.0 ws: 8.5.0 transitivePeerDependencies: @@ -4447,6 +4459,16 @@ packages: path-is-absolute: 1.0.1 dev: true + /glob@9.3.5: + resolution: {integrity: sha512-e1LleDykUz2Iu+MTYdkSsuWX8lvAjAcs0Xef0lNIu0S2wOAzuTxCJtcd9S3cijlwYF18EsU3rzb8jPVobxDh9Q==} + engines: {node: '>=16 || 14 >=14.17'} + dependencies: + fs.realpath: 1.0.0 + minimatch: 8.0.4 + minipass: 4.2.8 + path-scurry: 1.9.2 + dev: true + /globals@11.12.0: resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} engines: {node: '>=4'} @@ -5018,6 +5040,11 @@ packages: yallist: 4.0.0 dev: true + /lru-cache@9.1.1: + resolution: {integrity: sha512-65/Jky17UwSb0BuB9V+MyDpsOtXKmYwzhyl+cOa9XUiI4uV2Ouy/2voFP3+al0BjZbJgMBD8FojMpAf+Z+qn4A==} + engines: {node: 14 || >=16.14} + dev: true + /magic-string@0.25.9: resolution: {integrity: sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==} dependencies: @@ -5137,6 +5164,13 @@ packages: brace-expansion: 1.1.11 dev: true + /minimatch@8.0.4: + resolution: {integrity: sha512-W0Wvr9HyFXZRGIDgCicunpQ299OKXs9RgZfaukz4qAW/pJhcpUfupc9c+OObPOFueNy8VSrZgEmDtk6Kh4WzDA==} + engines: {node: '>=16 || 14 >=14.17'} + dependencies: + brace-expansion: 2.0.1 + dev: true + /minimist-options@4.1.0: resolution: {integrity: sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==} engines: {node: '>= 6'} @@ -5150,6 +5184,16 @@ packages: resolution: {integrity: sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==} dev: true + /minipass@4.2.8: + resolution: {integrity: sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ==} + engines: {node: '>=8'} + dev: true + + /minipass@6.0.2: + resolution: {integrity: sha512-MzWSV5nYVT7mVyWCwn2o7JH13w2TBRmmSqSRCKzTw+lmft9X4z+3wjvs06Tzijo5z4W/kahUCDpRXTF+ZrmF/w==} + engines: {node: '>=16 || 14 >=14.17'} + dev: true + /mixme@0.5.4: resolution: {integrity: sha512-3KYa4m4Vlqx98GPdOHghxSdNtTvcP8E0kkaJ5Dlh+h2DRzF7zpuVVcA8B0QpKd11YJeP9QQ7ASkKzOeu195Wzw==} engines: {node: '>= 8.0.0'} @@ -5455,6 +5499,14 @@ packages: resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} dev: true + /path-scurry@1.9.2: + resolution: {integrity: sha512-qSDLy2aGFPm8i4rsbHd4MNyTcrzHFsLQykrtbuGRknZZCBBVXSv2tSCDN2Cg6Rt/GFRw8GoW9y9Ecw5rIPG1sg==} + engines: {node: '>=16 || 14 >=14.17'} + dependencies: + lru-cache: 9.1.1 + minipass: 6.0.2 + dev: true + /path-type@4.0.0: resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} engines: {node: '>=8'} @@ -5841,10 +5893,12 @@ packages: glob: 7.2.3 dev: true - /rimraf@4.1.2: - resolution: {integrity: sha512-BlIbgFryTbw3Dz6hyoWFhKk+unCcHMSkZGrTFVAx2WmttdBSonsdtRlwiuTbDqTKr+UlXIUqJVS4QT5tUzGENQ==} + /rimraf@4.4.1: + resolution: {integrity: sha512-Gk8NlF062+T9CqNGn6h4tls3k6T1+/nXdOcSZVikNVtlRdYpA7wRJJMoXmuvOnLW844rPjdQ7JgXCYM6PPC/og==} engines: {node: '>=14'} hasBin: true + dependencies: + glob: 9.3.5 dev: true /rollup@3.15.0: @@ -6450,6 +6504,12 @@ packages: resolution: {integrity: sha512-xv8mOEDnigb/tN9PSMTwSEqAnUvkoXMQlicOb0IUVDBSQCgBSaAAROUZYy2IcUy5qU6XajK5jjjO7TMWqBTKZA==} engines: {node: '>=12.20'} hasBin: true + dev: true + + /typescript@5.0.4: + resolution: {integrity: sha512-cW9T5W9xY37cc+jfEnaUvX91foxtHkza3Nw3wkoF4sSlKn0MONdkdEndig/qPBWXNkmplh3NzayQzCiHM4/hqw==} + engines: {node: '>=12.20'} + hasBin: true /ufo@1.1.1: resolution: {integrity: sha512-MvlCc4GHrmZdAllBc0iUDowff36Q9Ndw/UzqmEKyrfSzokTd9ZCy1i+IIk5hrYKkjoYVQyNbrw7/F8XJ2rEwTg==} @@ -7077,3 +7137,9 @@ packages: /zod@3.20.2: resolution: {integrity: sha512-1MzNQdAvO+54H+EaK5YpyEy0T+Ejo/7YLHS93G3RnYWh5gaotGHwGeN/ZO687qEDU2y4CdStQYXVHIgrUl5UVQ==} dev: true + + github.com/ricmoo/ens-normalize.js/2d040533e57e4f25f9a7cc4715e219658ad454b5: + resolution: {tarball: https://codeload.github.com/ricmoo/ens-normalize.js/tar.gz/2d040533e57e4f25f9a7cc4715e219658ad454b5} + name: '@adraffy/ens-normalize' + version: 1.9.0 + dev: true diff --git a/site/docs/contract/getContract.md b/site/docs/contract/getContract.md index 6c0b6ce3a2..fd5e596dc0 100644 --- a/site/docs/contract/getContract.md +++ b/site/docs/contract/getContract.md @@ -167,6 +167,7 @@ If you pass in a [`publicClient`](https://viem.sh/docs/clients/public.html), the If you pass in a [`walletClient`](/docs/clients/wallet.html), the following methods are available: +- [`estimateGas`](/docs/contract/estimateContractGas.html) - [`write`](/docs/contract/writeContract.html) #### Calling methods diff --git a/src/actions/getContract.test-d.ts b/src/actions/getContract.test-d.ts index 823b36f913..a667a417ab 100644 --- a/src/actions/getContract.test-d.ts +++ b/src/actions/getContract.test-d.ts @@ -33,16 +33,6 @@ const walletClientWithoutChain = createWalletClient({ transport: http(localHttpUrl), }) -type ReadFunctionNames = ExtractAbiFunctionNames< - typeof wagmiContractConfig.abi, - 'pure' | 'view' -> -type WriteFunctionNames = ExtractAbiFunctionNames< - typeof wagmiContractConfig.abi, - 'nonpayable' | 'payable' -> -type EventNames = ExtractAbiEventNames - test('public and wallet client', () => { const contract = getContract({ ...wagmiContractConfig, @@ -50,26 +40,14 @@ test('public and wallet client', () => { walletClient, }) - expectTypeOf(contract).toMatchTypeOf<{ - createEventFilter: { - [_ in EventNames]: Function - } - estimateGas: { - [_ in WriteFunctionNames]: Function - } - read: { - [_ in ReadFunctionNames]: Function - } - simulate: { - [_ in WriteFunctionNames]: Function - } - watchEvent: { - [_ in EventNames]: Function - } - write: { - [_ in WriteFunctionNames]: Function - } - }>() + expectTypeOf().toEqualTypeOf< + | 'createEventFilter' + | 'estimateGas' + | 'read' + | 'simulate' + | 'watchEvent' + | 'write' + >() }) test('no wallet client', () => { @@ -78,28 +56,9 @@ test('no wallet client', () => { publicClient, }) - expectTypeOf(contract).toMatchTypeOf<{ - createEventFilter: { - [_ in EventNames]: Function - } - estimateGas: { - [_ in WriteFunctionNames]: Function - } - read: { - [_ in ReadFunctionNames]: Function - } - simulate: { - [_ in WriteFunctionNames]: Function - } - watchEvent: { - [_ in EventNames]: Function - } - }>() - expectTypeOf(contract).not.toMatchTypeOf<{ - write: { - [_ in WriteFunctionNames]: Function - } - }>() + expectTypeOf().toEqualTypeOf< + 'createEventFilter' | 'estimateGas' | 'read' | 'simulate' | 'watchEvent' + >() }) test('no public client', () => { @@ -108,28 +67,7 @@ test('no public client', () => { walletClient, }) - expectTypeOf(contract).toMatchTypeOf<{ - write: { - [_ in WriteFunctionNames]: Function - } - }>() - expectTypeOf(contract).not.toMatchTypeOf<{ - createEventFilter: { - [_ in EventNames]: Function - } - estimateGas: { - [_ in WriteFunctionNames]: Function - } - read: { - [_ in ReadFunctionNames]: Function - } - simulate: { - [_ in WriteFunctionNames]: Function - } - watchEvent: { - [_ in EventNames]: Function - } - }>() + expectTypeOf().toEqualTypeOf<'estimateGas' | 'write'>() }) test('without const assertion on `abi`', () => { @@ -177,7 +115,7 @@ test('`abi` declared as `Abi` type', () => { ...wagmiContractConfig, abi, publicClient, - walletClient: walletClient, + walletClient, }) contract.createEventFilter.Transfer({ from: '0x' }) @@ -489,11 +427,6 @@ test('no read functions', () => { [_ in WriteFunctionNames]: Function } }>() - expectTypeOf(contract).not.toMatchTypeOf<{ - read: { - [_ in string]: Function - } - }>() }) test('no write functions', () => { @@ -570,11 +503,6 @@ test('no write functions', () => { [_ in EventNames]: Function } }>() - expectTypeOf(contract).not.toMatchTypeOf<{ - write: { - [_ in WriteFunctionNames]: Function - } - }>() }) test('no events', () => { @@ -643,14 +571,6 @@ test('no events', () => { [_ in WriteFunctionNames]: Function } }>() - expectTypeOf(contract).not.toMatchTypeOf<{ - createEventFilter: { - [_ in string]: Function - } - watchEvent: { - [_ in string]: Function - } - }>() }) test('empty abi', () => { @@ -839,3 +759,38 @@ test('argument permutations', async () => { function onLogs() {} }) + +test('estimateGas', () => { + const contract1 = getContract({ + ...wagmiContractConfig, + publicClient, + }) + // `account` required + contract1.estimateGas.mint({ account: '0x' }) + contract1.estimateGas.approve(['0x', 123n], { account: '0x' }) + + const contract2 = getContract({ + ...wagmiContractConfig, + walletClient, + }) + // `account` inherited from `walletClient` + contract2.estimateGas.mint() + contract2.estimateGas.approve(['0x', 123n]) + + const contract3 = getContract({ + ...wagmiContractConfig, + walletClient: walletClientWithoutAccount, + }) + // `account` required + contract3.estimateGas.mint({ account: '0x' }) + contract3.estimateGas.approve(['0x', 123n], { account: '0x' }) + + const contract4 = getContract({ + ...wagmiContractConfig, + publicClient, + walletClient, + }) + // `account` inherited from `walletClient` + contract4.estimateGas.mint() + contract4.estimateGas.approve(['0x', 123n]) +}) diff --git a/src/actions/getContract.test.ts b/src/actions/getContract.test.ts index 7fffd92d0c..967edf3f64 100644 --- a/src/actions/getContract.test.ts +++ b/src/actions/getContract.test.ts @@ -1,10 +1,14 @@ import type { AbiEvent } from 'abitype' -import { expect, test } from 'vitest' +import { describe, expect, test } from 'vitest' import { wagmiContractConfig } from '../_test/abis.js' import { accounts } from '../_test/constants.js' -import { publicClient, walletClient } from '../_test/utils.js' +import { + publicClient, + walletClient, + walletClientWithAccount, +} from '../_test/utils.js' import { getContract, @@ -65,12 +69,29 @@ test('createEventFilter', async () => { ).resolves.toBeDefined() }) -test('estimateGas', async () => { - await expect( - contract.estimateGas.mint({ - account: accounts[0].address, - }), - ).resolves.toBeDefined() +describe('estimateGas', async () => { + test('account required', async () => { + await expect( + contract.estimateGas.mint({ + account: accounts[0].address, + }), + ).resolves.toBeDefined() + }) + + test('account inherited from wallet client', async () => { + const contract1 = getContract({ + ...wagmiContractConfig, + publicClient, + walletClient: walletClientWithAccount, + }) + await expect(contract1.estimateGas.mint()).resolves.toBeDefined() + + const contract2 = getContract({ + ...wagmiContractConfig, + walletClient: walletClientWithAccount, + }) + await expect(contract2.estimateGas.mint()).resolves.toBeDefined() + }) }) test('read', async () => { diff --git a/src/actions/getContract.ts b/src/actions/getContract.ts index 9c4ad90219..d7c807d91f 100644 --- a/src/actions/getContract.ts +++ b/src/actions/getContract.ts @@ -90,6 +90,7 @@ export type GetContractParameters< * * If you pass in a [`walletClient`](https://viem.sh/docs/clients/wallet.html), the following methods are available: * + * - [`estimateGas`](https://viem.sh/docs/contract/estimateContractGas.html) * - [`write`](https://viem.sh/docs/contract/writeContract.html) */ walletClient?: TWalletClient @@ -163,7 +164,7 @@ export type GetContractReturnType< * import { createPublicClient, getContract, http, parseAbi } from 'viem' * import { mainnet } from 'viem/chains' * - * const client = createPublicClient({ + * const publicClient = createPublicClient({ * chain: mainnet, * transport: http(), * }) @@ -179,9 +180,8 @@ export type GetContractReturnType< estimateGas: { [FunctionName in _WriteFunctionNames]: GetEstimateFunction< _Narrowable, - TPublicClient extends PublicClient - ? TPublicClient['chain'] - : undefined, + TPublicClient['chain'], + undefined, TAbi, FunctionName > @@ -197,7 +197,7 @@ export type GetContractReturnType< * import { createPublicClient, getContract, http, parseAbi } from 'viem' * import { mainnet } from 'viem/chains' * - * const client = createPublicClient({ + * const publicClient = createPublicClient({ * chain: mainnet, * transport: http(), * }) @@ -213,9 +213,7 @@ export type GetContractReturnType< simulate: { [FunctionName in _WriteFunctionNames]: GetSimulateFunction< _Narrowable, - TPublicClient extends PublicClient - ? TPublicClient['chain'] - : undefined, + TPublicClient['chain'], TAbi, FunctionName > @@ -231,7 +229,7 @@ export type GetContractReturnType< * import { createPublicClient, getContract, http, parseAbi } from 'viem' * import { mainnet } from 'viem/chains' * - * const client = createPublicClient({ + * const publicClient = createPublicClient({ * chain: mainnet, * transport: http(), * }) @@ -260,7 +258,7 @@ export type GetContractReturnType< * import { createPublicClient, getContract, http, parseAbi } from 'viem' * import { mainnet } from 'viem/chains' * - * const client = createPublicClient({ + * const publicClient = createPublicClient({ * chain: mainnet, * transport: http(), * }) @@ -288,6 +286,35 @@ export type GetContractReturnType< ? IsNever<_WriteFunctionNames> extends true ? unknown : { + /** + * Estimates the gas necessary to complete a transaction without submitting it to the network. + * + * @example + * import { createWalletClient, getContract, http, parseAbi } from 'viem' + * import { mainnet } from 'viem/chains' + * + * const walletClient = createWalletClient({ + * chain: mainnet, + * transport: http(), + * }) + * const contract = getContract({ + * address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2', + * abi: parseAbi(['function mint() public']), + * walletClient, + * }) + * const gas = await contract.estimateGas.mint({ + * account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + * }) + */ + estimateGas: { + [FunctionName in _WriteFunctionNames]: GetEstimateFunction< + _Narrowable, + TWalletClient['chain'], + TWalletClient['account'], + TAbi, + FunctionName + > + } /** * Executes a write function on a contract. * @@ -301,14 +328,14 @@ export type GetContractReturnType< * import { createWalletClient, getContract, http, parseAbi } from 'viem' * import { mainnet } from 'viem/chains' * - * const client = createWalletClient({ + * const walletClient = createWalletClient({ * chain: mainnet, * transport: http(), * }) * const contract = getContract({ * address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2', * abi: parseAbi(['function mint(uint32 tokenId) nonpayable']), - * publicClient, + * walletClient, * }) * const hash = await contract.write.min([69420], { * address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2', @@ -317,12 +344,8 @@ export type GetContractReturnType< write: { [FunctionName in _WriteFunctionNames]: GetWriteFunction< _Narrowable, - TWalletClient extends WalletClient - ? TWalletClient['chain'] - : undefined, - TWalletClient extends WalletClient - ? TWalletClient['account'] - : undefined, + TWalletClient['chain'], + TWalletClient['account'], TAbi, FunctionName > @@ -434,32 +457,7 @@ export function getContract< }, ) - if (hasWriteFunction) { - contract.estimateGas = new Proxy( - {}, - { - get(_, functionName: string) { - return ( - ...parameters: [ - args?: readonly unknown[], - options?: Omit< - EstimateContractGasParameters, - 'abi' | 'address' | 'functionName' | 'args' - >, - ] - ) => { - const { args, options } = getFunctionParameters(parameters) - return estimateContractGas(publicClient, { - abi, - address, - functionName, - args, - ...options, - } as EstimateContractGasParameters) - } - }, - }, - ) + if (hasWriteFunction) contract.simulate = new Proxy( {}, { @@ -485,7 +483,6 @@ export function getContract< }, }, ) - } if (hasEvent) { contract.createEventFilter = new Proxy( @@ -587,6 +584,38 @@ export function getContract< ) } + if (hasPublicClient || hasWalletClient) + if (hasWriteFunction) + contract.estimateGas = new Proxy( + {}, + { + get(_, functionName: string) { + return ( + ...parameters: [ + args?: readonly unknown[], + options?: Omit< + EstimateContractGasParameters, + 'abi' | 'address' | 'functionName' | 'args' + >, + ] + ) => { + const { args, options } = getFunctionParameters(parameters) + const client = (publicClient ?? walletClient)! + return estimateContractGas(client, { + abi, + address, + functionName, + args, + ...options, + account: + (options as EstimateContractGasParameters).account ?? + (walletClient as WalletClient).account, + } as EstimateContractGasParameters) + } + }, + }, + ) + return contract as unknown as GetContractReturnType< TAbi, TPublicClient, @@ -659,6 +688,7 @@ type GetReadFunction< type GetEstimateFunction< Narrowable extends boolean, TChain extends Chain | undefined, + TAccount extends Account | undefined, TAbi extends Abi | readonly unknown[], TFunctionName extends string, TAbiFunction extends AbiFunction = TAbi extends Abi @@ -667,20 +697,36 @@ type GetEstimateFunction< Args = AbiParametersToPrimitiveTypes, Options = Prettify< Omit< - EstimateContractGasParameters, + EstimateContractGasParameters, 'abi' | 'address' | 'args' | 'functionName' > >, + // For making `options` parameter required if `TAccount` + IsOptionsRequired = IsUndefined, > = Narrowable extends true ? ( ...parameters: Args extends readonly [] - ? [options?: Options] - : [args: Args, options?: Options] + ? IsOptionsRequired extends true + ? [options: Options] + : [options?: Options] + : [ + args: Args, + ...parameters: IsOptionsRequired extends true + ? [options: Options] + : [options?: Options], + ] ) => Promise : ( ...parameters: - | [options?: Options] - | [args: readonly unknown[], options?: Options] + | (IsOptionsRequired extends true + ? [options: Options] + : [options?: Options]) + | [ + args: readonly unknown[], + ...parameters: IsOptionsRequired extends true + ? [options: Options] + : [options?: Options], + ] ) => Promise type GetSimulateFunction< @@ -759,13 +805,17 @@ type GetWriteFunction< 'abi' | 'address' | 'args' | 'functionName' > >, - Rest extends IsOptionsRequired extends true - ? [options: Options] - : [options?: Options], >( ...parameters: Args extends readonly [] - ? Rest - : [args: Args, ...parameters: Rest] + ? IsOptionsRequired extends true + ? [options: Options] + : [options?: Options] + : [ + args: Args, + ...parameters: IsOptionsRequired extends true + ? [options: Options] + : [options?: Options], + ] ) => Promise : < TChainOverride extends Chain | undefined, diff --git a/src/actions/public/estimateContractGas.test-d.ts b/src/actions/public/estimateContractGas.test-d.ts new file mode 100644 index 0000000000..a07b4d7ecc --- /dev/null +++ b/src/actions/public/estimateContractGas.test-d.ts @@ -0,0 +1,36 @@ +import { test } from 'vitest' + +import { wagmiContractConfig } from '../../_test/abis.js' +import { accounts } from '../../_test/constants.js' +import { + publicClient, + walletClient, + walletClientWithAccount, +} from '../../_test/utils.js' +import { estimateContractGas } from './estimateContractGas.js' + +test('publicClient', () => { + estimateContractGas(publicClient, { + ...wagmiContractConfig, + functionName: 'mint', + args: [69420n], + account: accounts[0].address, + }) +}) + +test('wallet client without account', () => { + estimateContractGas(walletClient, { + ...wagmiContractConfig, + functionName: 'mint', + args: [69420n], + account: accounts[0].address, + }) +}) + +test('wallet client with account', () => { + estimateContractGas(walletClientWithAccount, { + ...wagmiContractConfig, + functionName: 'mint', + args: [69420n], + }) +}) diff --git a/src/actions/public/estimateContractGas.ts b/src/actions/public/estimateContractGas.ts index c961ecd7bd..51ed4b0cbb 100644 --- a/src/actions/public/estimateContractGas.ts +++ b/src/actions/public/estimateContractGas.ts @@ -1,5 +1,6 @@ import type { Abi } from 'abitype' +import type { Account } from '../../accounts/types.js' import { parseAccount } from '../../accounts/utils/parseAccount.js' import type { PublicClient } from '../../clients/createPublicClient.js' import type { Transport } from '../../clients/transports/createTransport.js' @@ -12,14 +13,16 @@ import { } from '../../utils/abi/encodeFunctionData.js' import { getContractError } from '../../utils/errors/getContractError.js' +import type { WalletClient } from '../../clients/createWalletClient.js' import { type EstimateGasParameters, estimateGas } from './estimateGas.js' export type EstimateContractGasParameters< TAbi extends Abi | readonly unknown[] = Abi, TFunctionName extends string = string, TChain extends Chain | undefined = Chain | undefined, + TAccount extends Account | undefined = undefined, > = ContractFunctionConfig & - Omit, 'data' | 'to' | 'value'> & + Omit, 'data' | 'to' | 'value'> & GetValue['value']> export type EstimateContractGasReturnType = bigint @@ -55,17 +58,19 @@ export async function estimateContractGas< TAbi extends Abi | readonly unknown[], TFunctionName extends string, TChain extends Chain | undefined, + TAccount extends Account | undefined = undefined, >( - client: PublicClient, + client: + | PublicClient + | WalletClient, { abi, address, args, functionName, ...request - }: EstimateContractGasParameters, + }: EstimateContractGasParameters, ): Promise { - const account = parseAccount(request.account) const data = encodeFunctionData({ abi, args, @@ -79,6 +84,7 @@ export async function estimateContractGas< } as unknown as EstimateGasParameters) return gas } catch (err) { + const account = request.account ? parseAccount(request.account) : undefined throw getContractError(err as BaseError, { abi: abi as Abi, address,