viem 0.0.1-alpha.21 → 0.0.1-alpha.23

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (181) hide show
  1. package/dist/{chain-32f56cfa.d.ts → chain-4b39613a.d.ts} +2 -2
  2. package/dist/{chain-f12cdc7f.d.ts → chain-aa4898d0.d.ts} +1 -1
  3. package/dist/chains.d.ts +3 -3
  4. package/dist/chains.js +46 -46
  5. package/dist/chains.mjs +1 -1
  6. package/dist/{chunk-EC3NUIJE.js → chunk-7Y5QVLX7.js} +13 -13
  7. package/dist/{chunk-EC3NUIJE.js.map → chunk-7Y5QVLX7.js.map} +1 -1
  8. package/dist/{chunk-KEHGSYDO.js → chunk-BV5NTHUX.js} +14 -13
  9. package/dist/chunk-BV5NTHUX.js.map +1 -0
  10. package/dist/{chunk-46BO7YAQ.mjs → chunk-EGVXCZNJ.mjs} +4 -3
  11. package/dist/chunk-EGVXCZNJ.mjs.map +1 -0
  12. package/dist/{chunk-57ZOFERP.mjs → chunk-GX2KDAM3.mjs} +2 -2
  13. package/dist/{chunk-57ZOFERP.mjs.map → chunk-GX2KDAM3.mjs.map} +0 -0
  14. package/dist/{chunk-W7BWWAC4.js → chunk-NW6724MI.js} +14 -14
  15. package/dist/{chunk-W7BWWAC4.js.map → chunk-NW6724MI.js.map} +0 -0
  16. package/dist/{chunk-DGO77E2H.mjs → chunk-RJLUZTJS.mjs} +86 -3
  17. package/dist/chunk-RJLUZTJS.mjs.map +1 -0
  18. package/dist/{chunk-O2GYLJVD.js → chunk-SSPRUPGN.js} +405 -165
  19. package/dist/chunk-SSPRUPGN.js.map +1 -0
  20. package/dist/{chunk-DSPMAIDO.mjs → chunk-TXHOG6KU.mjs} +2 -2
  21. package/dist/{chunk-DSPMAIDO.mjs.map → chunk-TXHOG6KU.mjs.map} +1 -1
  22. package/dist/{chunk-62VTYU2V.mjs → chunk-XBUH66KN.mjs} +406 -166
  23. package/dist/chunk-XBUH66KN.mjs.map +1 -0
  24. package/dist/{chunk-KZMJR27B.js → chunk-ZKYGWITF.js} +147 -64
  25. package/dist/chunk-ZKYGWITF.js.map +1 -0
  26. package/dist/clients/index.d.ts +7 -7
  27. package/dist/clients/index.js +3 -3
  28. package/dist/clients/index.mjs +2 -2
  29. package/dist/{contract-9af4608b.d.ts → contract-4c3a37b3.d.ts} +14 -3
  30. package/dist/{createClient-5d316c7e.d.ts → createClient-55a04188.d.ts} +2 -2
  31. package/dist/{createPublicClient-9d2b42e1.d.ts → createPublicClient-3b27b282.d.ts} +3 -3
  32. package/dist/{createTestClient-79498dab.d.ts → createTestClient-93f9eac6.d.ts} +3 -3
  33. package/dist/{createWalletClient-f69a5230.d.ts → createWalletClient-c10df94d.d.ts} +3 -3
  34. package/dist/{eip1193-6c485d63.d.ts → eip1193-4c24765a.d.ts} +1 -1
  35. package/dist/ens.d.ts +1 -0
  36. package/dist/ens.js +11 -0
  37. package/dist/ens.js.map +1 -0
  38. package/dist/ens.mjs +11 -0
  39. package/dist/ens.mjs.map +1 -0
  40. package/dist/index.d.ts +174 -113
  41. package/dist/index.js +16 -6
  42. package/dist/index.mjs +15 -5
  43. package/dist/normalize-ef9240c0.d.ts +33 -0
  44. package/dist/{parseGwei-4308ad80.d.ts → parseGwei-3411cf2d.d.ts} +101 -37
  45. package/dist/public.d.ts +9 -9
  46. package/dist/public.js +4 -4
  47. package/dist/public.mjs +3 -3
  48. package/dist/{sendTransaction-1c8290a9.d.ts → sendTransaction-f17a2389.d.ts} +3 -3
  49. package/dist/{stopImpersonatingAccount-7781842a.d.ts → stopImpersonatingAccount-afb26486.d.ts} +2 -2
  50. package/dist/test.d.ts +5 -5
  51. package/dist/test.js +3 -3
  52. package/dist/test.mjs +2 -2
  53. package/dist/{transactionRequest-341b6ed2.d.ts → transactionRequest-93e9f001.d.ts} +2 -2
  54. package/dist/utils/index.d.ts +14 -16
  55. package/dist/utils/index.js +8 -2
  56. package/dist/utils/index.mjs +7 -1
  57. package/dist/wallet.d.ts +7 -7
  58. package/dist/wallet.js +3 -3
  59. package/dist/wallet.mjs +2 -2
  60. package/dist/{watchAsset-afaad3c7.d.ts → watchAsset-efd3dd05.d.ts} +3 -3
  61. package/dist/{watchPendingTransactions-3b722547.d.ts → watchPendingTransactions-57df1a13.d.ts} +17 -27
  62. package/dist/{webSocket-b180e679.d.ts → webSocket-d2e7bd0e.d.ts} +2 -2
  63. package/dist/window.d.ts +2 -2
  64. package/package.json +8 -2
  65. package/src/_test/abis.ts +7 -0
  66. package/src/_test/bench.ts +4 -4
  67. package/src/_test/constants.ts +4 -3
  68. package/src/_test/index.ts +4 -2
  69. package/src/_test/utils.ts +39 -1
  70. package/src/actions/index.test.ts +1 -0
  71. package/src/actions/index.ts +2 -0
  72. package/src/actions/public/call.bench.ts +5 -5
  73. package/src/actions/public/deployContract.ts +4 -4
  74. package/src/actions/public/estimateGas.bench.ts +6 -6
  75. package/src/actions/public/getBlock.bench.ts +5 -5
  76. package/src/actions/public/getBlockNumber.bench.ts +5 -5
  77. package/src/actions/public/getFilterChanges.test.ts +9 -9
  78. package/src/actions/public/getFilterLogs.test.ts +7 -7
  79. package/src/actions/public/getGasPrice.bench.ts +1 -10
  80. package/src/actions/public/getLogs.test.ts +7 -7
  81. package/src/actions/public/getTransaction.bench.ts +5 -5
  82. package/src/actions/public/getTransactionReceipt.bench.ts +5 -5
  83. package/src/actions/public/index.test.ts +1 -0
  84. package/src/actions/public/index.ts +3 -0
  85. package/src/actions/public/multicall.test.ts +452 -0
  86. package/src/actions/public/multicall.ts +103 -0
  87. package/src/actions/public/readContract.test.ts +226 -26
  88. package/src/actions/public/readContract.ts +13 -27
  89. package/src/actions/public/simulateContract.bench.ts +10 -0
  90. package/src/actions/public/simulateContract.test.ts +209 -37
  91. package/src/actions/public/simulateContract.ts +17 -21
  92. package/src/actions/public/watchContractEvent.test.ts +61 -57
  93. package/src/actions/public/watchEvent.test.ts +42 -37
  94. package/src/actions/test/impersonateAccount.test.ts +4 -6
  95. package/src/actions/test/sendUnsignedTransaction.test.ts +2 -2
  96. package/src/actions/test/stopImpersonatingAccount.test.ts +5 -7
  97. package/src/actions/wallet/signMessage.test.ts +0 -1
  98. package/src/actions/wallet/switchChain.test.ts +1 -2
  99. package/src/actions/wallet/watchAsset.test.ts +1 -2
  100. package/src/actions/wallet/writeContract.test.ts +37 -7
  101. package/src/actions/wallet/writeContract.ts +5 -14
  102. package/src/clients/transports/fallback.test.ts +34 -0
  103. package/src/clients/transports/fallback.ts +3 -1
  104. package/src/clients/transports/http.test.ts +0 -1
  105. package/src/clients/transports/webSocket.test.ts +0 -1
  106. package/src/constants/abis.test.ts +53 -0
  107. package/src/constants/abis.ts +44 -0
  108. package/src/constants/index.test.ts +14 -0
  109. package/src/constants/index.ts +3 -0
  110. package/src/constants/solidity.test.ts +41 -0
  111. package/src/constants/solidity.ts +35 -0
  112. package/src/ens.ts +5 -0
  113. package/src/errors/abi.test.ts +0 -2
  114. package/src/errors/base.test.ts +44 -2
  115. package/src/errors/base.ts +12 -12
  116. package/src/errors/block.test.ts +6 -6
  117. package/src/errors/contract.test.ts +233 -0
  118. package/src/errors/contract.ts +133 -80
  119. package/src/errors/index.ts +4 -2
  120. package/src/errors/request.test.ts +3 -4
  121. package/src/errors/request.ts +17 -17
  122. package/src/errors/rpc.test.ts +1 -2
  123. package/src/errors/transaction.test.ts +12 -12
  124. package/src/errors/transport.test.ts +0 -1
  125. package/src/index.test.ts +47 -0
  126. package/src/index.ts +10 -0
  127. package/src/types/contract.ts +55 -4
  128. package/src/types/index.ts +5 -0
  129. package/src/types/multicall.ts +82 -0
  130. package/src/utils/abi/decodeAbi.test.ts +1 -2
  131. package/src/utils/abi/decodeAbi.ts +11 -7
  132. package/src/utils/abi/decodeDeployData.test.ts +7 -15
  133. package/src/utils/abi/decodeDeployData.ts +10 -7
  134. package/src/utils/abi/decodeErrorResult.test.ts +103 -3
  135. package/src/utils/abi/decodeErrorResult.ts +30 -13
  136. package/src/utils/abi/decodeFunctionData.test.ts +0 -1
  137. package/src/utils/abi/decodeFunctionResult.test.ts +80 -9
  138. package/src/utils/abi/decodeFunctionResult.ts +15 -11
  139. package/src/utils/abi/encodeAbi.test.ts +3 -4
  140. package/src/utils/abi/encodeAbi.ts +19 -10
  141. package/src/utils/abi/encodeDeployData.test.ts +6 -13
  142. package/src/utils/abi/encodeDeployData.ts +10 -7
  143. package/src/utils/abi/encodeErrorResult.test.ts +2 -7
  144. package/src/utils/abi/encodeErrorResult.ts +18 -11
  145. package/src/utils/abi/encodeEventTopics.test.ts +11 -14
  146. package/src/utils/abi/encodeEventTopics.ts +15 -9
  147. package/src/utils/abi/encodeFunctionData.test.ts +5 -7
  148. package/src/utils/abi/encodeFunctionData.ts +16 -9
  149. package/src/utils/abi/encodeFunctionResult.test.ts +10 -15
  150. package/src/utils/abi/encodeFunctionResult.ts +9 -7
  151. package/src/utils/abi/getAbiItem.test.ts +547 -0
  152. package/src/utils/abi/getAbiItem.ts +93 -3
  153. package/src/utils/abi/index.ts +5 -1
  154. package/src/utils/address/getAddress.test.ts +6 -6
  155. package/src/utils/contract/getContractError.test.ts +247 -62
  156. package/src/utils/contract/getContractError.ts +30 -38
  157. package/src/utils/data/pad.bench.ts +0 -9
  158. package/src/utils/data/trim.bench.ts +0 -16
  159. package/src/utils/encoding/encodeBytes.bench.ts +0 -12
  160. package/src/utils/encoding/encodeHex.bench.ts +0 -11
  161. package/src/utils/ens/index.test.ts +13 -0
  162. package/src/utils/ens/index.ts +5 -0
  163. package/src/utils/ens/labelhash.test.ts +55 -0
  164. package/src/utils/ens/labelhash.ts +16 -0
  165. package/src/utils/ens/namehash.test.ts +65 -0
  166. package/src/utils/ens/namehash.ts +28 -0
  167. package/src/utils/ens/normalize.bench.ts +14 -0
  168. package/src/utils/ens/normalize.test.ts +35 -0
  169. package/src/utils/ens/normalize.ts +14 -0
  170. package/src/utils/hash/keccak256.ts +3 -5
  171. package/src/utils/index.test.ts +3 -0
  172. package/src/utils/index.ts +4 -0
  173. package/src/utils/rpc.test.ts +3 -6
  174. package/src/utils/unit/formatUnit.bench.ts +0 -5
  175. package/src/utils/unit/parseUnit.bench.ts +0 -5
  176. package/dist/chunk-46BO7YAQ.mjs.map +0 -1
  177. package/dist/chunk-62VTYU2V.mjs.map +0 -1
  178. package/dist/chunk-DGO77E2H.mjs.map +0 -1
  179. package/dist/chunk-KEHGSYDO.js.map +0 -1
  180. package/dist/chunk-KZMJR27B.js.map +0 -1
  181. package/dist/chunk-O2GYLJVD.js.map +0 -1
@@ -11,7 +11,7 @@ test('constructor()', () => {
11
11
  stateMutability: 'nonpayable',
12
12
  type: 'constructor',
13
13
  },
14
- ] as const,
14
+ ],
15
15
  bytecode:
16
16
  '0x6080604052348015600f57600080fd5b50603f80601d6000396000f3fe6080604052600080fdfea2646970667358221220116554d4ba29ee08da9e97dc54ff9a2a65d67a648140d616fc225a25ff08c86364736f6c63430008070033',
17
17
  data: '0x6080604052348015600f57600080fd5b50603f80601d6000396000f3fe6080604052600080fdfea2646970667358221220116554d4ba29ee08da9e97dc54ff9a2a65d67a648140d616fc225a25ff08c86364736f6c63430008070033',
@@ -22,13 +22,12 @@ test('constructor()', () => {
22
22
  })
23
23
  expect(
24
24
  decodeDeployData({
25
- // @ts-expect-error
26
25
  abi: [
27
26
  {
28
27
  stateMutability: 'nonpayable',
29
28
  type: 'constructor',
30
29
  },
31
- ] as const,
30
+ ],
32
31
  bytecode:
33
32
  '0x6080604052348015600f57600080fd5b50603f80601d6000396000f3fe6080604052600080fdfea2646970667358221220116554d4ba29ee08da9e97dc54ff9a2a65d67a648140d616fc225a25ff08c86364736f6c63430008070033',
34
33
  data: '0x6080604052348015600f57600080fd5b50603f80601d6000396000f3fe6080604052600080fdfea2646970667358221220116554d4ba29ee08da9e97dc54ff9a2a65d67a648140d616fc225a25ff08c86364736f6c63430008070033',
@@ -54,7 +53,7 @@ test('constructor(uint256)', () => {
54
53
  stateMutability: 'nonpayable',
55
54
  type: 'constructor',
56
55
  },
57
- ] as const,
56
+ ],
58
57
  bytecode:
59
58
  '0x6080604052348015600f57600080fd5b50603f80601d6000396000f3fe6080604052600080fdfea2646970667358221220116554d4ba29ee08da9e97dc54ff9a2a65d67a648140d616fc225a25ff08c86364736f6c63430008070033',
60
59
  data: '0x6080604052348015600f57600080fd5b50603f80601d6000396000f3fe6080604052600080fdfea2646970667358221220116554d4ba29ee08da9e97dc54ff9a2a65d67a648140d616fc225a25ff08c86364736f6c634300080700330000000000000000000000000000000000000000000000000000000000010f2c',
@@ -69,8 +68,7 @@ test('constructor(uint256)', () => {
69
68
  test('error: constructor not found', () => {
70
69
  expect(() =>
71
70
  decodeDeployData({
72
- // @ts-expect-error
73
- abi: [{}] as const,
71
+ abi: [{}],
74
72
  bytecode:
75
73
  '0x6080604052348015600f57600080fd5b50603f80601d6000396000f3fe6080604052600080fdfea2646970667358221220116554d4ba29ee08da9e97dc54ff9a2a65d67a648140d616fc225a25ff08c86364736f6c63430008070033',
76
74
  data: '0x6080604052348015600f57600080fd5b50603f80601d6000396000f3fe6080604052600080fdfea2646970667358221220116554d4ba29ee08da9e97dc54ff9a2a65d67a648140d616fc225a25ff08c86364736f6c634300080700330000000000000000000000000000000000000000000000000000000000010f2c',
@@ -80,7 +78,6 @@ test('error: constructor not found', () => {
80
78
  Make sure you are using the correct ABI and that the constructor exists on it.
81
79
 
82
80
  Docs: https://viem.sh/docs/contract/decodeDeployData
83
-
84
81
  Version: viem@1.0.2"
85
82
  `)
86
83
  })
@@ -88,13 +85,12 @@ test('error: constructor not found', () => {
88
85
  test('error: no inputs', () => {
89
86
  expect(() =>
90
87
  decodeDeployData({
91
- // @ts-expect-error
92
88
  abi: [
93
89
  {
94
90
  stateMutability: 'nonpayable',
95
91
  type: 'constructor',
96
92
  },
97
- ] as const,
93
+ ],
98
94
  bytecode:
99
95
  '0x6080604052348015600f57600080fd5b50603f80601d6000396000f3fe6080604052600080fdfea2646970667358221220116554d4ba29ee08da9e97dc54ff9a2a65d67a648140d616fc225a25ff08c86364736f6c63430008070033',
100
96
  data: '0x6080604052348015600f57600080fd5b50603f80601d6000396000f3fe6080604052600080fdfea2646970667358221220116554d4ba29ee08da9e97dc54ff9a2a65d67a648140d616fc225a25ff08c86364736f6c634300080700330000000000000000000000000000000000000000000000000000000000010f2c',
@@ -105,7 +101,6 @@ test('error: no inputs', () => {
105
101
  Make sure you are using the correct ABI, and that the \`inputs\` attribute on the constructor exists.
106
102
 
107
103
  Docs: https://viem.sh/docs/contract/decodeDeployData
108
-
109
104
  Version: viem@1.0.2"
110
105
  `,
111
106
  )
@@ -117,7 +112,7 @@ test('error: no inputs', () => {
117
112
  stateMutability: 'nonpayable',
118
113
  type: 'constructor',
119
114
  },
120
- ] as const,
115
+ ],
121
116
  bytecode:
122
117
  '0x6080604052348015600f57600080fd5b50603f80601d6000396000f3fe6080604052600080fdfea2646970667358221220116554d4ba29ee08da9e97dc54ff9a2a65d67a648140d616fc225a25ff08c86364736f6c63430008070033',
123
118
  data: '0x6080604052348015600f57600080fd5b50603f80601d6000396000f3fe6080604052600080fdfea2646970667358221220116554d4ba29ee08da9e97dc54ff9a2a65d67a648140d616fc225a25ff08c86364736f6c634300080700330000000000000000000000000000000000000000000000000000000000010f2c',
@@ -128,20 +123,18 @@ test('error: no inputs', () => {
128
123
  Make sure you are using the correct ABI, and that the \`inputs\` attribute on the constructor exists.
129
124
 
130
125
  Docs: https://viem.sh/docs/contract/decodeDeployData
131
-
132
126
  Version: viem@1.0.2"
133
127
  `,
134
128
  )
135
129
  expect(() =>
136
130
  decodeDeployData({
137
- // @ts-expect-error
138
131
  abi: [
139
132
  {
140
133
  inputs: undefined,
141
134
  stateMutability: 'nonpayable',
142
135
  type: 'constructor',
143
136
  },
144
- ] as const,
137
+ ],
145
138
  bytecode:
146
139
  '0x6080604052348015600f57600080fd5b50603f80601d6000396000f3fe6080604052600080fdfea2646970667358221220116554d4ba29ee08da9e97dc54ff9a2a65d67a648140d616fc225a25ff08c86364736f6c63430008070033',
147
140
  data: '0x6080604052348015600f57600080fd5b50603f80601d6000396000f3fe6080604052600080fdfea2646970667358221220116554d4ba29ee08da9e97dc54ff9a2a65d67a648140d616fc225a25ff08c86364736f6c634300080700330000000000000000000000000000000000000000000000000000000000010f2c',
@@ -152,7 +145,6 @@ test('error: no inputs', () => {
152
145
  Make sure you are using the correct ABI, and that the \`inputs\` attribute on the constructor exists.
153
146
 
154
147
  Docs: https://viem.sh/docs/contract/decodeDeployData
155
-
156
148
  Version: viem@1.0.2"
157
149
  `,
158
150
  )
@@ -9,24 +9,27 @@ import { decodeAbi } from './decodeAbi'
9
9
 
10
10
  const docsPath = '/docs/contract/decodeDeployData'
11
11
 
12
- export type DecodeDeployDataArgs<TAbi extends Abi = Abi> = {
13
- abi: TAbi
14
- bytecode: Hex
15
- data: Hex
16
- }
12
+ export type DecodeDeployDataArgs<TAbi extends Abi | readonly unknown[] = Abi> =
13
+ {
14
+ abi: TAbi
15
+ bytecode: Hex
16
+ data: Hex
17
+ }
17
18
  export type DecodeDeployDataResponse = {
18
19
  args?: readonly unknown[] | undefined
19
20
  bytecode: Hex
20
21
  }
21
22
 
22
- export function decodeDeployData<TAbi extends Abi = Abi>({
23
+ export function decodeDeployData<TAbi extends Abi | readonly unknown[]>({
23
24
  abi,
24
25
  bytecode,
25
26
  data,
26
27
  }: DecodeDeployDataArgs<TAbi>): DecodeDeployDataResponse {
27
28
  if (data === bytecode) return { bytecode }
28
29
 
29
- const description = abi.find((x) => 'type' in x && x.type === 'constructor')
30
+ const description = (abi as Abi).find(
31
+ (x) => 'type' in x && x.type === 'constructor',
32
+ )
30
33
  if (!description) throw new AbiConstructorNotFoundError({ docsPath })
31
34
  if (!('inputs' in description))
32
35
  throw new AbiConstructorParamsNotFoundError({ docsPath })
@@ -14,7 +14,15 @@ test('revert SoldOutError()', () => {
14
14
  ],
15
15
  data: '0x7f6df6bb',
16
16
  }),
17
- ).toEqual({ errorName: 'SoldOutError', args: undefined })
17
+ ).toEqual({
18
+ abiItem: {
19
+ inputs: [],
20
+ name: 'SoldOutError',
21
+ type: 'error',
22
+ },
23
+ errorName: 'SoldOutError',
24
+ args: undefined,
25
+ })
18
26
  expect(
19
27
  decodeErrorResult({
20
28
  abi: [
@@ -26,7 +34,14 @@ test('revert SoldOutError()', () => {
26
34
  ],
27
35
  data: '0x7f6df6bb',
28
36
  }),
29
- ).toEqual({ errorName: 'SoldOutError', args: undefined })
37
+ ).toEqual({
38
+ abiItem: {
39
+ name: 'SoldOutError',
40
+ type: 'error',
41
+ },
42
+ errorName: 'SoldOutError',
43
+ args: undefined,
44
+ })
30
45
  })
31
46
 
32
47
  test('revert AccessDeniedError(string)', () => {
@@ -48,6 +63,17 @@ test('revert AccessDeniedError(string)', () => {
48
63
  data: '0x83aa206e0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001a796f7520646f206e6f7420686176652061636365737320736572000000000000',
49
64
  }),
50
65
  ).toEqual({
66
+ abiItem: {
67
+ inputs: [
68
+ {
69
+ internalType: 'string',
70
+ name: 'a',
71
+ type: 'string',
72
+ },
73
+ ],
74
+ name: 'AccessDeniedError',
75
+ type: 'error',
76
+ },
51
77
  errorName: 'AccessDeniedError',
52
78
  args: ['you do not have access ser'],
53
79
  })
@@ -94,6 +120,39 @@ test('revert AccessDeniedError((uint256,bool,address,uint256))', () => {
94
120
  data: '0x0a1895610000000000000000000000000000000000000000000000000000000000010f2c0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000a5cc3c03994db5b0d9a5eedd10cabab0813678ac0000000000000000000000000000000000000000000000000000000000000029',
95
121
  }),
96
122
  ).toEqual({
123
+ abiItem: {
124
+ inputs: [
125
+ {
126
+ components: [
127
+ {
128
+ internalType: 'uint256',
129
+ name: 'weight',
130
+ type: 'uint256',
131
+ },
132
+ {
133
+ internalType: 'bool',
134
+ name: 'voted',
135
+ type: 'bool',
136
+ },
137
+ {
138
+ internalType: 'address',
139
+ name: 'delegate',
140
+ type: 'address',
141
+ },
142
+ {
143
+ internalType: 'uint256',
144
+ name: 'vote',
145
+ type: 'uint256',
146
+ },
147
+ ],
148
+ internalType: 'struct Ballot.Voter',
149
+ name: 'voter',
150
+ type: 'tuple',
151
+ },
152
+ ],
153
+ name: 'AccessDeniedError',
154
+ type: 'error',
155
+ },
97
156
  errorName: 'AccessDeniedError',
98
157
  args: [
99
158
  {
@@ -106,6 +165,48 @@ test('revert AccessDeniedError((uint256,bool,address,uint256))', () => {
106
165
  })
107
166
  })
108
167
 
168
+ test('Error(string)', () => {
169
+ expect(
170
+ decodeErrorResult({
171
+ data: '0x08c379a0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000047465737400000000000000000000000000000000000000000000000000000000',
172
+ }),
173
+ ).toEqual({
174
+ abiItem: {
175
+ inputs: [
176
+ {
177
+ name: 'message',
178
+ type: 'string',
179
+ },
180
+ ],
181
+ name: 'Error',
182
+ type: 'error',
183
+ },
184
+ errorName: 'Error',
185
+ args: ['test'],
186
+ })
187
+ })
188
+
189
+ test.todo('Panic(uint256)')
190
+
191
+ test('zero data', () => {
192
+ expect(() =>
193
+ decodeErrorResult({
194
+ abi: [
195
+ {
196
+ inputs: [],
197
+ name: 'SoldOutError',
198
+ type: 'error',
199
+ },
200
+ ],
201
+ data: '0x',
202
+ }),
203
+ ).toThrowErrorMatchingInlineSnapshot(`
204
+ "Cannot decode zero data (\\"0x\\") with ABI parameters.
205
+
206
+ Version: viem@1.0.2"
207
+ `)
208
+ })
209
+
109
210
  test("errors: error doesn't exist", () => {
110
211
  expect(() =>
111
212
  decodeErrorResult({
@@ -124,7 +225,6 @@ test("errors: error doesn't exist", () => {
124
225
  You can look up the signature \\"0xa3741467\\" here: https://sig.eth.samczsun.com/.
125
226
 
126
227
  Docs: https://viem.sh/docs/contract/decodeErrorResult
127
-
128
228
  Version: viem@1.0.2"
129
229
  `)
130
230
  })
@@ -1,28 +1,45 @@
1
- import { Abi } from 'abitype'
2
- import { AbiErrorSignatureNotFoundError } from '../../errors'
3
- import { Hex } from '../../types'
1
+ import { Abi, AbiError } from 'abitype'
2
+ import { solidityError, solidityPanic } from '../../constants'
3
+ import {
4
+ AbiDecodingZeroDataError,
5
+ AbiErrorSignatureNotFoundError,
6
+ } from '../../errors'
7
+ import { AbiItem, Hex } from '../../types'
4
8
  import { slice } from '../data'
5
9
  import { getFunctionSignature } from '../hash'
6
10
  import { decodeAbi } from './decodeAbi'
7
11
  import { formatAbiItem } from './formatAbiItem'
8
12
 
9
- export type DecodeErrorResultArgs = { abi: Abi; data: Hex }
13
+ export type DecodeErrorResultArgs = { abi?: Abi; data: Hex }
10
14
 
11
- export function decodeErrorResult({ abi, data }: DecodeErrorResultArgs) {
15
+ export type DecodeErrorResultResponse = {
16
+ abiItem: AbiItem
17
+ errorName: string
18
+ args?: readonly unknown[]
19
+ }
20
+
21
+ export function decodeErrorResult({
22
+ abi,
23
+ data,
24
+ }: DecodeErrorResultArgs): DecodeErrorResultResponse {
12
25
  const signature = slice(data, 0, 4)
13
- const description = abi.find(
14
- (x) => signature === getFunctionSignature(formatAbiItem(x)),
26
+ if (signature === '0x') throw new AbiDecodingZeroDataError()
27
+
28
+ const abi_ = [...(abi || []), solidityError, solidityPanic]
29
+ const abiItem = abi_.find(
30
+ (x) =>
31
+ x.type === 'error' &&
32
+ signature === getFunctionSignature(formatAbiItem(x)),
15
33
  )
16
- if (!description)
34
+ if (!abiItem)
17
35
  throw new AbiErrorSignatureNotFoundError(signature, {
18
36
  docsPath: '/docs/contract/decodeErrorResult',
19
37
  })
20
38
  return {
21
- errorName: (description as { name: string }).name,
22
- args: ('inputs' in description &&
23
- description.inputs &&
24
- description.inputs.length > 0
25
- ? decodeAbi({ data: slice(data, 4), params: description.inputs })
39
+ abiItem,
40
+ args: ('inputs' in abiItem && abiItem.inputs && abiItem.inputs.length > 0
41
+ ? decodeAbi({ data: slice(data, 4), params: abiItem.inputs })
26
42
  : undefined) as readonly unknown[] | undefined,
43
+ errorName: (abiItem as { name: string }).name,
27
44
  }
28
45
  }
@@ -134,7 +134,6 @@ test("errors: function doesn't exist", () => {
134
134
  You can look up the signature \\"0xa3741467\\" here: https://sig.eth.samczsun.com/.
135
135
 
136
136
  Docs: https://viem.sh/docs/contract/decodeFunctionData
137
-
138
137
  Version: viem@1.0.2"
139
138
  `)
140
139
  })
@@ -13,7 +13,7 @@ test('returns ()', () => {
13
13
  stateMutability: 'pure',
14
14
  type: 'function',
15
15
  },
16
- ] as const,
16
+ ],
17
17
  functionName: 'foo',
18
18
  data: '0x',
19
19
  }),
@@ -28,7 +28,7 @@ test('returns ()', () => {
28
28
  stateMutability: 'pure',
29
29
  type: 'function',
30
30
  },
31
- ] as const,
31
+ ],
32
32
  functionName: 'foo',
33
33
  // @ts-expect-error
34
34
  data: '',
@@ -53,7 +53,7 @@ test('returns (address)', () => {
53
53
  stateMutability: 'pure',
54
54
  type: 'function',
55
55
  },
56
- ] as const,
56
+ ],
57
57
  functionName: 'foo',
58
58
  data: '0x000000000000000000000000a5cc3c03994db5b0d9a5eedd10cabab0813678ac',
59
59
  }),
@@ -111,7 +111,7 @@ test('returns (Bar)', () => {
111
111
  stateMutability: 'pure',
112
112
  type: 'function',
113
113
  },
114
- ] as const,
114
+ ],
115
115
  functionName: 'bar',
116
116
  data: '0x000000000000000000000000a5cc3c03994db5b0d9a5eedd10cabab0813678ac0000000000000000000000000000000000000000000000000000000000010f2c0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000a5cc3c03994db5b0d9a5eedd10cabab0813678ac0000000000000000000000000000000000000000000000000000000000000045',
117
117
  }),
@@ -182,7 +182,7 @@ test('returns (Bar, string)', () => {
182
182
  stateMutability: 'pure',
183
183
  type: 'function',
184
184
  },
185
- ] as const,
185
+ ],
186
186
  functionName: 'baz',
187
187
  data: '0x000000000000000000000000a5cc3c03994db5b0d9a5eedd10cabab0813678ac0000000000000000000000000000000000000000000000000000000000010f2c0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000a5cc3c03994db5b0d9a5eedd10cabab0813678ac000000000000000000000000000000000000000000000000000000000000004500000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000057761676d69000000000000000000000000000000000000000000000000000000',
188
188
  }),
@@ -200,6 +200,79 @@ test('returns (Bar, string)', () => {
200
200
  ])
201
201
  })
202
202
 
203
+ test('overloads', () => {
204
+ expect(
205
+ decodeFunctionResult({
206
+ abi: [
207
+ {
208
+ inputs: [{ internalType: 'uint256', name: 'x', type: 'uint256' }],
209
+ name: 'foo',
210
+ outputs: [
211
+ {
212
+ internalType: 'uint256',
213
+ name: 'x',
214
+ type: 'uint256',
215
+ },
216
+ ],
217
+ stateMutability: 'pure',
218
+ type: 'function',
219
+ },
220
+ {
221
+ inputs: [],
222
+ name: 'foo',
223
+ outputs: [
224
+ {
225
+ internalType: 'address',
226
+ name: 'sender',
227
+ type: 'address',
228
+ },
229
+ ],
230
+ stateMutability: 'pure',
231
+ type: 'function',
232
+ },
233
+ ],
234
+ functionName: 'foo',
235
+ data: '0x000000000000000000000000a5cc3c03994db5b0d9a5eedd10cabab0813678ac',
236
+ }),
237
+ ).toEqual('0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC')
238
+
239
+ expect(
240
+ decodeFunctionResult({
241
+ abi: [
242
+ {
243
+ inputs: [{ internalType: 'uint256', name: 'x', type: 'uint256' }],
244
+ name: 'foo',
245
+ outputs: [
246
+ {
247
+ internalType: 'uint256',
248
+ name: 'x',
249
+ type: 'uint256',
250
+ },
251
+ ],
252
+ stateMutability: 'pure',
253
+ type: 'function',
254
+ },
255
+ {
256
+ inputs: [],
257
+ name: 'foo',
258
+ outputs: [
259
+ {
260
+ internalType: 'address',
261
+ name: 'sender',
262
+ type: 'address',
263
+ },
264
+ ],
265
+ stateMutability: 'pure',
266
+ type: 'function',
267
+ },
268
+ ],
269
+ functionName: 'foo',
270
+ data: '0x0000000000000000000000000000000000000000000000000000000000000069',
271
+ args: [10n],
272
+ }),
273
+ ).toEqual(105n)
274
+ })
275
+
203
276
  test("error: function doesn't exist", () => {
204
277
  expect(() =>
205
278
  decodeFunctionResult({
@@ -217,7 +290,7 @@ test("error: function doesn't exist", () => {
217
290
  stateMutability: 'pure',
218
291
  type: 'function',
219
292
  },
220
- ] as const,
293
+ ],
221
294
  // @ts-expect-error
222
295
  functionName: 'baz',
223
296
  data: '0x000000000000000000000000a5cc3c03994db5b0d9a5eedd10cabab0813678ac',
@@ -228,7 +301,6 @@ test("error: function doesn't exist", () => {
228
301
  Make sure you are using the correct ABI and that the function exists on it.
229
302
 
230
303
  Docs: https://viem.sh/docs/contract/decodeFunctionResult
231
-
232
304
  Version: viem@1.0.2"
233
305
  `,
234
306
  )
@@ -244,7 +316,7 @@ test("error: function doesn't exist", () => {
244
316
  stateMutability: 'pure',
245
317
  type: 'function',
246
318
  },
247
- ] as const,
319
+ ],
248
320
  functionName: 'foo',
249
321
  data: '0x000000000000000000000000a5cc3c03994db5b0d9a5eedd10cabab0813678ac',
250
322
  }),
@@ -255,7 +327,6 @@ test("error: function doesn't exist", () => {
255
327
  Make sure you are using the correct ABI and that the function exists on it.
256
328
 
257
329
  Docs: https://viem.sh/docs/contract/decodeFunctionResult
258
-
259
330
  Version: viem@1.0.2"
260
331
  `,
261
332
  )
@@ -1,46 +1,50 @@
1
- import { Abi, ExtractAbiFunctionNames } from 'abitype'
1
+ import { Abi, Narrow } from 'abitype'
2
2
  import {
3
3
  AbiFunctionNotFoundError,
4
4
  AbiFunctionOutputsNotFoundError,
5
5
  } from '../../errors'
6
-
7
6
  import {
7
+ ExtractArgsFromAbi,
8
8
  ExtractFunctionNameFromAbi,
9
9
  ExtractResultFromAbi,
10
10
  Hex,
11
11
  } from '../../types'
12
12
  import { decodeAbi } from './decodeAbi'
13
+ import { getAbiItem, GetAbiItemArgs } from './getAbiItem'
13
14
 
14
15
  const docsPath = '/docs/contract/decodeFunctionResult'
15
16
 
16
17
  export type DecodeFunctionResultArgs<
17
18
  TAbi extends Abi | readonly unknown[] = Abi,
18
- TFunctionName extends string = any,
19
+ TFunctionName extends string = string,
19
20
  > = {
20
- abi: TAbi
21
+ abi: Narrow<TAbi>
21
22
  functionName: ExtractFunctionNameFromAbi<TAbi, TFunctionName>
22
23
  data: Hex
23
- }
24
+ } & Partial<ExtractArgsFromAbi<TAbi, TFunctionName>>
24
25
 
25
26
  export type DecodeFunctionResultResponse<
26
27
  TAbi extends Abi | readonly unknown[] = Abi,
27
- TFunctionName extends string = any,
28
+ TFunctionName extends string = string,
28
29
  > = ExtractResultFromAbi<TAbi, TFunctionName>
29
30
 
30
31
  export function decodeFunctionResult<
31
- TAbi extends Abi | readonly unknown[] = Abi,
32
- TFunctionName extends string = any,
32
+ TAbi extends Abi | readonly unknown[],
33
+ TFunctionName extends string,
33
34
  >({
34
35
  abi,
36
+ args,
35
37
  functionName,
36
38
  data,
37
39
  }: DecodeFunctionResultArgs<TAbi, TFunctionName>): DecodeFunctionResultResponse<
38
40
  TAbi,
39
41
  TFunctionName
40
42
  > {
41
- const description = (abi as Abi).find(
42
- (x) => 'name' in x && x.name === functionName,
43
- )
43
+ const description = getAbiItem({
44
+ abi,
45
+ args,
46
+ name: functionName,
47
+ } as GetAbiItemArgs)
44
48
  if (!description)
45
49
  throw new AbiFunctionNotFoundError(functionName, { docsPath })
46
50
  if (!('outputs' in description))
@@ -745,7 +745,7 @@ describe('static', () => {
745
745
  { internalType: 'uint256[2]', name: 'xOut', type: 'uint256[2]' },
746
746
  { internalType: 'bool', name: 'yOut', type: 'bool' },
747
747
  { internalType: 'string[3]', name: 'zOut', type: 'string[3]' },
748
- ] as any,
748
+ ],
749
749
  values: [[420n, 69n], true, ['wagmi', 'viem', 'lol']],
750
750
  }),
751
751
  ).toMatchInlineSnapshot(
@@ -885,7 +885,7 @@ describe('dynamic', () => {
885
885
  name: 'zIn',
886
886
  type: 'string',
887
887
  },
888
- ] as const,
888
+ ],
889
889
  values: [[420n, 69n], true, 'wagmi'],
890
890
  }),
891
891
  ).toMatchInlineSnapshot(
@@ -1202,7 +1202,7 @@ describe('dynamic', () => {
1202
1202
  name: 'wagmiIn',
1203
1203
  type: 'tuple',
1204
1204
  },
1205
- ] as const,
1205
+ ],
1206
1206
  values: [
1207
1207
  {
1208
1208
  foo: {
@@ -1390,7 +1390,6 @@ test('invalid type', () => {
1390
1390
  Please provide a valid ABI type.
1391
1391
 
1392
1392
  Docs: https://viem.sh/docs/contract/encodeAbi
1393
-
1394
1393
  Version: viem@1.0.2"
1395
1394
  `)
1396
1395
  })
@@ -2,6 +2,7 @@ import {
2
2
  AbiParameter,
3
3
  AbiParametersToPrimitiveTypes,
4
4
  AbiParameterToPrimitiveType,
5
+ Narrow,
5
6
  } from 'abitype'
6
7
 
7
8
  import {
@@ -14,25 +15,33 @@ import { Hex } from '../../types'
14
15
  import { concat, padHex, size, slice } from '../data'
15
16
  import { boolToHex, numberToHex, stringToHex } from '../encoding'
16
17
 
17
- export type EncodeAbiArgs<TParams extends readonly AbiParameter[]> = {
18
- params: TParams
19
- values: AbiParametersToPrimitiveTypes<TParams>
18
+ export type EncodeAbiArgs<
19
+ TParams extends
20
+ | readonly AbiParameter[]
21
+ | readonly unknown[] = readonly AbiParameter[],
22
+ > = {
23
+ params: Narrow<TParams>
24
+ values: TParams extends readonly AbiParameter[]
25
+ ? AbiParametersToPrimitiveTypes<TParams>
26
+ : never
20
27
  }
21
28
 
22
29
  /**
23
30
  * @description Encodes a list of primitive values into an ABI-encoded hex value.
24
31
  */
25
- export function encodeAbi<TParams extends readonly AbiParameter[]>({
26
- params,
27
- values,
28
- }: EncodeAbiArgs<TParams>) {
32
+ export function encodeAbi<
33
+ TParams extends readonly AbiParameter[] | readonly unknown[],
34
+ >({ params, values }: EncodeAbiArgs<TParams>) {
29
35
  if (params.length !== values.length)
30
36
  throw new AbiEncodingLengthMismatchError({
31
- expectedLength: params.length,
37
+ expectedLength: params.length as number,
32
38
  givenLength: values.length,
33
39
  })
34
40
  // Prepare the parameters to determine dynamic types to encode.
35
- const preparedParams = prepareParams({ params, values })
41
+ const preparedParams = prepareParams({
42
+ params: params as readonly AbiParameter[],
43
+ values,
44
+ })
36
45
  const data = encodeParams(preparedParams)
37
46
  if (data.length === 0) return '0x'
38
47
  return data
@@ -49,7 +58,7 @@ function prepareParams<TParams extends readonly AbiParameter[]>({
49
58
  params,
50
59
  values,
51
60
  }: {
52
- params: TParams
61
+ params: Narrow<TParams>
53
62
  values: AbiParametersToPrimitiveTypes<TParams>
54
63
  }) {
55
64
  let preparedParams: PreparedParam[] = []