viem 2.21.60 → 2.22.1

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 (61) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/_cjs/actions/index.js +4 -2
  3. package/_cjs/actions/index.js.map +1 -1
  4. package/_cjs/actions/public/simulate.js +112 -0
  5. package/_cjs/actions/public/simulate.js.map +1 -0
  6. package/_cjs/chains/definitions/mainnet.js +1 -1
  7. package/_cjs/chains/definitions/mainnet.js.map +1 -1
  8. package/_cjs/clients/decorators/public.js +2 -0
  9. package/_cjs/clients/decorators/public.js.map +1 -1
  10. package/_cjs/errors/version.js +1 -1
  11. package/_cjs/errors/version.js.map +1 -1
  12. package/_cjs/index.js.map +1 -1
  13. package/_cjs/types/eip1193.js.map +1 -1
  14. package/_esm/actions/index.js +1 -0
  15. package/_esm/actions/index.js.map +1 -1
  16. package/_esm/actions/public/simulate.js +152 -0
  17. package/_esm/actions/public/simulate.js.map +1 -0
  18. package/_esm/chains/definitions/mainnet.js +1 -1
  19. package/_esm/chains/definitions/mainnet.js.map +1 -1
  20. package/_esm/clients/decorators/public.js +2 -0
  21. package/_esm/clients/decorators/public.js.map +1 -1
  22. package/_esm/errors/version.js +1 -1
  23. package/_esm/errors/version.js.map +1 -1
  24. package/_esm/index.js.map +1 -1
  25. package/_esm/types/eip1193.js.map +1 -1
  26. package/_types/actions/index.d.ts +1 -0
  27. package/_types/actions/index.d.ts.map +1 -1
  28. package/_types/actions/public/createAccessList.d.ts +3 -3
  29. package/_types/actions/public/createAccessList.d.ts.map +1 -1
  30. package/_types/actions/public/simulate.d.ts +114 -0
  31. package/_types/actions/public/simulate.d.ts.map +1 -0
  32. package/_types/chains/definitions/mainnet.d.ts +1 -1
  33. package/_types/clients/decorators/public.d.ts +44 -0
  34. package/_types/clients/decorators/public.d.ts.map +1 -1
  35. package/_types/errors/version.d.ts +1 -1
  36. package/_types/errors/version.d.ts.map +1 -1
  37. package/_types/experimental/erc7821/actions/execute.d.ts +2 -2
  38. package/_types/experimental/erc7821/actions/execute.d.ts.map +1 -1
  39. package/_types/experimental/erc7821/decorators/erc7821.d.ts +1 -1
  40. package/_types/experimental/erc7821/decorators/erc7821.d.ts.map +1 -1
  41. package/_types/index.d.ts +1 -0
  42. package/_types/index.d.ts.map +1 -1
  43. package/_types/types/calls.d.ts +9 -4
  44. package/_types/types/calls.d.ts.map +1 -1
  45. package/_types/types/eip1193.d.ts +36 -0
  46. package/_types/types/eip1193.d.ts.map +1 -1
  47. package/_types/types/multicall.d.ts +9 -7
  48. package/_types/types/multicall.d.ts.map +1 -1
  49. package/actions/index.ts +6 -0
  50. package/actions/public/createAccessList.ts +3 -3
  51. package/actions/public/simulate.ts +290 -0
  52. package/chains/definitions/mainnet.ts +1 -1
  53. package/clients/decorators/public.ts +51 -0
  54. package/errors/version.ts +1 -1
  55. package/experimental/erc7821/actions/execute.ts +2 -2
  56. package/experimental/erc7821/decorators/erc7821.ts +1 -1
  57. package/index.ts +4 -0
  58. package/package.json +2 -2
  59. package/types/calls.ts +20 -11
  60. package/types/eip1193.ts +38 -0
  61. package/types/multicall.ts +29 -10
@@ -0,0 +1,290 @@
1
+ import type { Abi, AbiStateMutability, Address, Narrow } from 'abitype'
2
+ import * as BlockOverrides from 'ox/BlockOverrides'
3
+
4
+ import {
5
+ type ParseAccountErrorType,
6
+ parseAccount,
7
+ } from '../../accounts/utils/parseAccount.js'
8
+ import type { Client } from '../../clients/createClient.js'
9
+ import type { Transport } from '../../clients/transports/createTransport.js'
10
+ import { AbiDecodingZeroDataError } from '../../errors/abi.js'
11
+ import type { BaseError } from '../../errors/base.js'
12
+ import { RawContractError } from '../../errors/contract.js'
13
+ import { UnknownNodeError } from '../../errors/node.js'
14
+ import type { ErrorType } from '../../errors/utils.js'
15
+ import type { Account } from '../../types/account.js'
16
+ import type { Block, BlockTag } from '../../types/block.js'
17
+ import type { Call, Calls } from '../../types/calls.js'
18
+ import type { Chain } from '../../types/chain.js'
19
+ import type { Log } from '../../types/log.js'
20
+ import type { Hex } from '../../types/misc.js'
21
+ import type { MulticallResults } from '../../types/multicall.js'
22
+ import type { StateOverride } from '../../types/stateOverride.js'
23
+ import type { TransactionRequest } from '../../types/transaction.js'
24
+ import type { ExactPartial, UnionOmit } from '../../types/utils.js'
25
+ import {
26
+ type DecodeFunctionResultErrorType,
27
+ decodeFunctionResult,
28
+ } from '../../utils/abi/decodeFunctionResult.js'
29
+ import {
30
+ type EncodeFunctionDataErrorType,
31
+ encodeFunctionData,
32
+ } from '../../utils/abi/encodeFunctionData.js'
33
+ import {
34
+ type NumberToHexErrorType,
35
+ numberToHex,
36
+ } from '../../utils/encoding/toHex.js'
37
+ import { getContractError } from '../../utils/errors/getContractError.js'
38
+ import {
39
+ type GetNodeErrorReturnType,
40
+ getNodeError,
41
+ } from '../../utils/errors/getNodeError.js'
42
+ import {
43
+ type FormatBlockErrorType,
44
+ formatBlock,
45
+ } from '../../utils/formatters/block.js'
46
+ import { formatLog } from '../../utils/formatters/log.js'
47
+ import {
48
+ type FormatTransactionRequestErrorType,
49
+ formatTransactionRequest,
50
+ } from '../../utils/formatters/transactionRequest.js'
51
+ import {
52
+ type SerializeStateOverrideErrorType,
53
+ serializeStateOverride,
54
+ } from '../../utils/stateOverride.js'
55
+ import {
56
+ type AssertRequestErrorType,
57
+ assertRequest,
58
+ } from '../../utils/transaction/assertRequest.js'
59
+
60
+ type CallExtraProperties = ExactPartial<
61
+ UnionOmit<
62
+ TransactionRequest,
63
+ 'blobs' | 'data' | 'kzg' | 'to' | 'sidecars' | 'value'
64
+ >
65
+ > & {
66
+ /** Account attached to the call (msg.sender). */
67
+ account?: Account | Address | undefined
68
+ }
69
+
70
+ export type SimulateParameters<
71
+ calls extends readonly unknown[] = readonly unknown[],
72
+ > = {
73
+ /** Blocks to simulate. */
74
+ blocks: readonly {
75
+ /** Block overrides. */
76
+ blockOverrides?: BlockOverrides.BlockOverrides | undefined
77
+ /** Calls to execute. */
78
+ calls: Calls<Narrow<calls>, CallExtraProperties>
79
+ /** State overrides. */
80
+ stateOverrides?: StateOverride | undefined
81
+ }[]
82
+ /** Whether to return the full transactions. */
83
+ returnFullTransactions?: boolean
84
+ /** Whether to trace transfers. */
85
+ traceTransfers?: boolean
86
+ /** Whether to enable validation mode. */
87
+ validation?: boolean
88
+ } & (
89
+ | {
90
+ /** The balance of the account at a block number. */
91
+ blockNumber?: bigint | undefined
92
+ blockTag?: undefined
93
+ }
94
+ | {
95
+ blockNumber?: undefined
96
+ /**
97
+ * The balance of the account at a block tag.
98
+ * @default 'latest'
99
+ */
100
+ blockTag?: BlockTag | undefined
101
+ }
102
+ )
103
+
104
+ export type SimulateReturnType<
105
+ calls extends readonly unknown[] = readonly unknown[],
106
+ > = readonly (Block & {
107
+ calls: MulticallResults<
108
+ Narrow<calls>,
109
+ true,
110
+ {
111
+ extraProperties: {
112
+ data: Hex
113
+ gasUsed: bigint
114
+ logs?: Log[] | undefined
115
+ }
116
+ error: Error
117
+ mutability: AbiStateMutability
118
+ }
119
+ >
120
+ })[]
121
+
122
+ export type SimulateErrorType =
123
+ | AssertRequestErrorType
124
+ | DecodeFunctionResultErrorType
125
+ | EncodeFunctionDataErrorType
126
+ | FormatBlockErrorType
127
+ | FormatTransactionRequestErrorType
128
+ | GetNodeErrorReturnType
129
+ | ParseAccountErrorType
130
+ | SerializeStateOverrideErrorType
131
+ | NumberToHexErrorType
132
+ | ErrorType
133
+
134
+ /**
135
+ * Simulates a set of calls on block(s) with optional block and state overrides.
136
+ *
137
+ * @example
138
+ * ```ts
139
+ * import { createClient, http, parseEther } from 'viem'
140
+ * import { simulate } from 'viem/actions'
141
+ * import { mainnet } from 'viem/chains'
142
+ *
143
+ * const client = createClient({
144
+ * chain: mainnet,
145
+ * transport: http(),
146
+ * })
147
+ *
148
+ * const result = await simulate(client, {
149
+ * blocks: [{
150
+ * blockOverrides: {
151
+ * number: 69420n,
152
+ * },
153
+ * calls: [{
154
+ * {
155
+ * account: '0x5a0b54d5dc17e482fe8b0bdca5320161b95fb929',
156
+ * data: '0xdeadbeef',
157
+ * to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8',
158
+ * },
159
+ * {
160
+ * account: '0x5a0b54d5dc17e482fe8b0bdca5320161b95fb929',
161
+ * to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8',
162
+ * value: parseEther('1'),
163
+ * },
164
+ * }],
165
+ * stateOverrides: [{
166
+ * address: '0x5a0b54d5dc17e482fe8b0bdca5320161b95fb929',
167
+ * balance: parseEther('10'),
168
+ * }],
169
+ * }]
170
+ * })
171
+ * ```
172
+ *
173
+ * @param client - Client to use.
174
+ * @param parameters - {@link SimulateParameters}
175
+ * @returns Simulated blocks. {@link SimulateReturnType}
176
+ */
177
+ export async function simulate<
178
+ chain extends Chain | undefined,
179
+ const calls extends readonly unknown[],
180
+ >(
181
+ client: Client<Transport, chain>,
182
+ parameters: SimulateParameters<calls>,
183
+ ): Promise<SimulateReturnType<calls>> {
184
+ const {
185
+ blockNumber,
186
+ blockTag = 'latest',
187
+ blocks,
188
+ returnFullTransactions,
189
+ traceTransfers,
190
+ validation,
191
+ } = parameters
192
+
193
+ try {
194
+ const blockStateCalls = []
195
+ for (const block of blocks) {
196
+ const blockOverrides = block.blockOverrides
197
+ ? BlockOverrides.toRpc(block.blockOverrides)
198
+ : undefined
199
+ const calls = block.calls.map((call_) => {
200
+ const call = call_ as Call<unknown, CallExtraProperties>
201
+ const account = call.account ? parseAccount(call.account) : undefined
202
+ const request = {
203
+ ...call,
204
+ data: call.abi ? encodeFunctionData(call) : call.data,
205
+ from: call.from ?? account?.address,
206
+ } as const
207
+ assertRequest(request)
208
+ return formatTransactionRequest(request)
209
+ })
210
+ const stateOverrides = block.stateOverrides
211
+ ? serializeStateOverride(block.stateOverrides)
212
+ : undefined
213
+
214
+ blockStateCalls.push({
215
+ blockOverrides,
216
+ calls,
217
+ stateOverrides,
218
+ })
219
+ }
220
+
221
+ const blockNumberHex = blockNumber ? numberToHex(blockNumber) : undefined
222
+ const block = blockNumberHex || blockTag
223
+
224
+ const result = await client.request({
225
+ method: 'eth_simulateV1',
226
+ params: [
227
+ { blockStateCalls, returnFullTransactions, traceTransfers, validation },
228
+ block,
229
+ ],
230
+ })
231
+
232
+ return result.map((block, i) => ({
233
+ ...formatBlock(block),
234
+ calls: block.calls.map((call, j) => {
235
+ const { abi, args, functionName, to } = blocks[i].calls[j] as Call<
236
+ unknown,
237
+ CallExtraProperties
238
+ >
239
+
240
+ const data = call.error?.data ?? call.returnData
241
+ const gasUsed = BigInt(call.gasUsed)
242
+ const logs = call.logs?.map((log) => formatLog(log))
243
+ const status = call.status === '0x1' ? 'success' : 'failure'
244
+
245
+ const result = abi
246
+ ? decodeFunctionResult({
247
+ abi,
248
+ data,
249
+ functionName,
250
+ })
251
+ : null
252
+
253
+ const error = (() => {
254
+ if (status === 'success') return undefined
255
+
256
+ let error = undefined
257
+ if (call.error?.data === '0x') error = new AbiDecodingZeroDataError()
258
+ else if (call.error) error = new RawContractError(call.error)
259
+
260
+ if (!error) return undefined
261
+ return getContractError(error, {
262
+ abi: (abi ?? []) as Abi,
263
+ address: to,
264
+ args,
265
+ functionName: functionName ?? '<unknown>',
266
+ })
267
+ })()
268
+
269
+ return {
270
+ data,
271
+ gasUsed,
272
+ logs,
273
+ status,
274
+ ...(status === 'success'
275
+ ? {
276
+ result,
277
+ }
278
+ : {
279
+ error,
280
+ }),
281
+ }
282
+ }),
283
+ })) as unknown as SimulateReturnType<calls>
284
+ } catch (e) {
285
+ const cause = e as BaseError
286
+ const error = getNodeError(cause, {})
287
+ if (error instanceof UnknownNodeError) throw cause
288
+ throw error
289
+ }
290
+ }
@@ -6,7 +6,7 @@ export const mainnet = /*#__PURE__*/ defineChain({
6
6
  nativeCurrency: { name: 'Ether', symbol: 'ETH', decimals: 18 },
7
7
  rpcUrls: {
8
8
  default: {
9
- http: ['https://cloudflare-eth.com'],
9
+ http: ['https://eth.merkle.io'],
10
10
  },
11
11
  },
12
12
  blockExplorers: {
@@ -180,6 +180,11 @@ import {
180
180
  type ReadContractReturnType,
181
181
  readContract,
182
182
  } from '../../actions/public/readContract.js'
183
+ import {
184
+ type SimulateParameters,
185
+ type SimulateReturnType,
186
+ simulate,
187
+ } from '../../actions/public/simulate.js'
183
188
  import {
184
189
  type SimulateContractParameters,
185
190
  type SimulateContractReturnType,
@@ -1520,6 +1525,51 @@ export type PublicActions<
1520
1525
  sendRawTransaction: (
1521
1526
  args: SendRawTransactionParameters,
1522
1527
  ) => Promise<SendRawTransactionReturnType>
1528
+ /**
1529
+ * Simulates a set of calls on block(s) with optional block and state overrides.
1530
+ *
1531
+ * @example
1532
+ * ```ts
1533
+ * import { createPublicClient, http, parseEther } from 'viem'
1534
+ * import { mainnet } from 'viem/chains'
1535
+ *
1536
+ * const client = createPublicClient({
1537
+ * chain: mainnet,
1538
+ * transport: http(),
1539
+ * })
1540
+ *
1541
+ * const result = await client.simulate({
1542
+ * blocks: [{
1543
+ * blockOverrides: {
1544
+ * number: 69420n,
1545
+ * },
1546
+ * calls: [{
1547
+ * {
1548
+ * account: '0x5a0b54d5dc17e482fe8b0bdca5320161b95fb929',
1549
+ * data: '0xdeadbeef',
1550
+ * to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8',
1551
+ * },
1552
+ * {
1553
+ * account: '0x5a0b54d5dc17e482fe8b0bdca5320161b95fb929',
1554
+ * to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8',
1555
+ * value: parseEther('1'),
1556
+ * },
1557
+ * }],
1558
+ * stateOverrides: [{
1559
+ * address: '0x5a0b54d5dc17e482fe8b0bdca5320161b95fb929',
1560
+ * balance: parseEther('10'),
1561
+ * }],
1562
+ * }]
1563
+ * })
1564
+ * ```
1565
+ *
1566
+ * @param client - Client to use.
1567
+ * @param parameters - {@link SimulateParameters}
1568
+ * @returns Simulated blocks. {@link SimulateReturnType}
1569
+ */
1570
+ simulate: <const calls extends readonly unknown[]>(
1571
+ args: SimulateParameters<calls>,
1572
+ ) => Promise<SimulateReturnType<calls>>
1523
1573
  /**
1524
1574
  * Simulates/validates a contract interaction. This is useful for retrieving **return data** and **revert reasons** of contract write functions.
1525
1575
  *
@@ -1908,6 +1958,7 @@ export function publicActions<
1908
1958
  prepareTransactionRequest(client as any, args as any) as any,
1909
1959
  readContract: (args) => readContract(client, args),
1910
1960
  sendRawTransaction: (args) => sendRawTransaction(client, args),
1961
+ simulate: (args) => simulate(client, args),
1911
1962
  simulateContract: (args) => simulateContract(client, args),
1912
1963
  verifyMessage: (args) => verifyMessage(client, args),
1913
1964
  verifySiweMessage: (args) => verifySiweMessage(client, args),
package/errors/version.ts CHANGED
@@ -1 +1 @@
1
- export const version = '2.21.60'
1
+ export const version = '2.22.1'
@@ -40,10 +40,10 @@ import {
40
40
  import { supportsExecutionMode } from './supportsExecutionMode.js'
41
41
 
42
42
  export type ExecuteParameters<
43
+ calls extends readonly unknown[] = readonly unknown[],
43
44
  chain extends Chain | undefined = Chain | undefined,
44
45
  account extends Account | undefined = Account | undefined,
45
46
  chainOverride extends Chain | undefined = Chain | undefined,
46
- calls extends readonly unknown[] = readonly unknown[],
47
47
  _derivedChain extends Chain | undefined = DeriveChain<chain, chainOverride>,
48
48
  > = UnionEvaluate<
49
49
  UnionPick<
@@ -149,7 +149,7 @@ export async function execute<
149
149
  chainOverride extends Chain | undefined = undefined,
150
150
  >(
151
151
  client: Client<Transport, chain, account>,
152
- parameters: ExecuteParameters<chain, account, chainOverride, calls>,
152
+ parameters: ExecuteParameters<calls, chain, account, chainOverride>,
153
153
  ): Promise<ExecuteReturnType> {
154
154
  const { address, authorizationList, opData } = parameters
155
155
 
@@ -89,7 +89,7 @@ export type Erc7821Actions<
89
89
  const calls extends readonly unknown[],
90
90
  chainOverride extends Chain | undefined = undefined,
91
91
  >(
92
- parameters: ExecuteParameters<chain, account, chainOverride, calls>,
92
+ parameters: ExecuteParameters<calls, chain, account, chainOverride>,
93
93
  ) => Promise<ExecuteReturnType>
94
94
  /**
95
95
  * Checks if the contract supports the ERC-7821 execution mode.
package/index.ts CHANGED
@@ -36,6 +36,10 @@ export {
36
36
  parseAbiParameter,
37
37
  parseAbiParameters,
38
38
  } from 'abitype'
39
+ export type {
40
+ BlockOverrides,
41
+ Rpc as RpcBlockOverrides,
42
+ } from 'ox/BlockOverrides'
39
43
 
40
44
  export {
41
45
  getContract,
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "viem",
3
3
  "description": "TypeScript Interface for Ethereum",
4
- "version": "2.21.60",
4
+ "version": "2.22.1",
5
5
  "main": "./_cjs/index.js",
6
6
  "module": "./_esm/index.js",
7
7
  "types": "./_types/index.d.ts",
@@ -177,7 +177,7 @@
177
177
  "@scure/bip39": "1.5.0",
178
178
  "abitype": "1.0.7",
179
179
  "isows": "1.0.6",
180
- "ox": "0.4.4",
180
+ "ox": "0.6.0",
181
181
  "webauthn-p256": "0.0.10",
182
182
  "ws": "8.18.0"
183
183
  },
package/types/calls.ts CHANGED
@@ -3,31 +3,40 @@ import type { Hex } from './misc.js'
3
3
  import type { GetMulticallContractParameters } from './multicall.js'
4
4
  import type { OneOf, Prettify } from './utils.js'
5
5
 
6
- export type Call<call = unknown> = OneOf<
7
- | {
6
+ export type Call<
7
+ call = unknown,
8
+ extraProperties extends Record<string, unknown> = {},
9
+ > = OneOf<
10
+ | (extraProperties & {
8
11
  data?: Hex | undefined
9
12
  to: Address
10
13
  value?: bigint | undefined
11
- }
12
- | (Omit<
13
- GetMulticallContractParameters<call, AbiStateMutability>,
14
- 'address'
15
- > & {
16
- to: Address
17
- value?: bigint | undefined
18
14
  })
15
+ | (extraProperties &
16
+ (Omit<
17
+ GetMulticallContractParameters<call, AbiStateMutability>,
18
+ 'address'
19
+ > & {
20
+ to: Address
21
+ value?: bigint | undefined
22
+ }))
19
23
  >
20
24
 
21
25
  export type Calls<
22
26
  calls extends readonly unknown[],
27
+ extraProperties extends Record<string, unknown> = {},
23
28
  ///
24
29
  result extends readonly any[] = [],
25
30
  > = calls extends readonly [] // no calls, return empty
26
31
  ? readonly []
27
32
  : calls extends readonly [infer call] // one call left before returning `result`
28
- ? readonly [...result, Prettify<Call<call>>]
33
+ ? readonly [...result, Prettify<Call<call, extraProperties>>]
29
34
  : calls extends readonly [infer call, ...infer rest] // grab first call and recurse through `rest`
30
- ? Calls<[...rest], [...result, Prettify<Call<call>>]>
35
+ ? Calls<
36
+ [...rest],
37
+ extraProperties,
38
+ [...result, Prettify<Call<call, extraProperties>>]
39
+ >
31
40
  : readonly unknown[] extends calls
32
41
  ? calls
33
42
  : // If `calls` is *some* array but we couldn't assign `unknown[]` to it, then it must hold some known/homogenous type!
package/types/eip1193.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import type { Address } from 'abitype'
2
2
 
3
+ import type * as BlockOverrides from 'ox/BlockOverrides'
3
4
  import type {
4
5
  RpcEstimateUserOperationGasReturnType,
5
6
  RpcGetUserOperationByHashReturnType,
@@ -1124,6 +1125,43 @@ export type PublicRpcSchema = [
1124
1125
  Parameters: [signedTransaction: Hex]
1125
1126
  ReturnType: Hash
1126
1127
  },
1128
+ /**
1129
+ * @description Simulates execution of a set of calls with optional block and state overrides.
1130
+ * @example
1131
+ * provider.request({ method: 'eth_simulateV1', params: [{ blockStateCalls: [{ calls: [{ from: '0x...', to: '0x...', value: '0x...', data: '0x...' }] }] }, 'latest'] })
1132
+ * // => { ... }
1133
+ */
1134
+ {
1135
+ Method: 'eth_simulateV1'
1136
+ Parameters: [
1137
+ {
1138
+ blockStateCalls: readonly {
1139
+ blockOverrides?: BlockOverrides.Rpc | undefined
1140
+ calls?: readonly ExactPartial<TransactionRequest>[] | undefined
1141
+ stateOverrides?: RpcStateOverride | undefined
1142
+ }[]
1143
+ returnFullTransactions?: boolean | undefined
1144
+ traceTransfers?: boolean | undefined
1145
+ validation?: boolean | undefined
1146
+ },
1147
+ BlockNumber | BlockTag,
1148
+ ]
1149
+ ReturnType: readonly (Block & {
1150
+ calls: readonly {
1151
+ error?:
1152
+ | {
1153
+ data?: Hex | undefined
1154
+ code: number
1155
+ message: string
1156
+ }
1157
+ | undefined
1158
+ logs?: readonly Log[] | undefined
1159
+ gasUsed: Hex
1160
+ returnData: Hex
1161
+ status: Hex
1162
+ }[]
1163
+ })[]
1164
+ },
1127
1165
  /**
1128
1166
  * @description Destroys a filter based on filter ID
1129
1167
  * @link https://eips.ethereum.org/EIPS/eip-1474
@@ -68,9 +68,10 @@ export type MulticallResults<
68
68
  contracts extends readonly unknown[] = readonly ContractFunctionParameters[],
69
69
  allowFailure extends boolean = true,
70
70
  options extends {
71
- error?: Error
71
+ error?: Error | undefined
72
+ extraProperties?: Record<string, unknown> | undefined
72
73
  mutability: AbiStateMutability
73
- } = { error: Error; mutability: AbiStateMutability },
74
+ } = { error: Error; extraProperties: {}; mutability: AbiStateMutability },
74
75
  ///
75
76
  result extends any[] = [],
76
77
  > = contracts extends readonly [] // no contracts, return empty
@@ -81,7 +82,8 @@ export type MulticallResults<
81
82
  MulticallResponse<
82
83
  GetMulticallContractReturnType<contract, options['mutability']>,
83
84
  options['error'],
84
- allowFailure
85
+ allowFailure,
86
+ options['extraProperties']
85
87
  >,
86
88
  ]
87
89
  : contracts extends readonly [infer contract, ...infer rest] // grab first contract and recurse through `rest`
@@ -94,12 +96,18 @@ export type MulticallResults<
94
96
  MulticallResponse<
95
97
  GetMulticallContractReturnType<contract, options['mutability']>,
96
98
  options['error'],
97
- allowFailure
99
+ allowFailure,
100
+ options['extraProperties']
98
101
  >,
99
102
  ]
100
103
  >
101
104
  : readonly unknown[] extends contracts
102
- ? MulticallResponse<unknown, options['error'], allowFailure>[]
105
+ ? MulticallResponse<
106
+ unknown,
107
+ options['error'],
108
+ allowFailure,
109
+ options['extraProperties']
110
+ >[]
103
111
  : // If `contracts` is *some* array but we couldn't assign `unknown[]` to it, then it must hold some known/homogenous type!
104
112
  // use this to infer the param types in the case of Array.map() argument
105
113
  contracts extends readonly (infer contract extends
@@ -107,23 +115,34 @@ export type MulticallResults<
107
115
  ? MulticallResponse<
108
116
  GetMulticallContractReturnType<contract, options['mutability']>,
109
117
  options['error'],
110
- allowFailure
118
+ allowFailure,
119
+ options['extraProperties']
111
120
  >[]
112
121
  : // Fallback
113
- MulticallResponse<unknown, options['error'], allowFailure>[]
122
+ MulticallResponse<
123
+ unknown,
124
+ options['error'],
125
+ allowFailure,
126
+ options['extraProperties']
127
+ >[]
114
128
 
115
129
  export type MulticallResponse<
116
130
  result = unknown,
117
131
  error = unknown,
118
132
  allowFailure extends boolean = true,
133
+ extraProperties extends Record<string, unknown> | undefined = {},
119
134
  > = allowFailure extends true
120
135
  ?
121
- | { error?: undefined; result: result; status: 'success' }
122
- | {
136
+ | (extraProperties & {
137
+ error?: undefined
138
+ result: result
139
+ status: 'success'
140
+ })
141
+ | (extraProperties & {
123
142
  error: unknown extends error ? Error : error
124
143
  result?: undefined
125
144
  status: 'failure'
126
- }
145
+ })
127
146
  : result
128
147
 
129
148
  // infer contract parameters from `unknown`