viem 0.0.1-alpha.24 → 0.0.1-alpha.25

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 (154) hide show
  1. package/contract/package.json +4 -0
  2. package/dist/call-ac509982.d.ts +23 -0
  3. package/dist/{chain-e33d019b.d.ts → chain-c4ccb458.d.ts} +1 -1
  4. package/dist/{chain-afa13f5a.d.ts → chain-f16512e8.d.ts} +20 -1
  5. package/dist/chains.d.ts +20 -8
  6. package/dist/chains.js +46 -46
  7. package/dist/chains.mjs +1 -1
  8. package/dist/{chunk-YQUC52RL.mjs → chunk-2Y3UZMSP.mjs} +77 -84
  9. package/dist/chunk-2Y3UZMSP.mjs.map +1 -0
  10. package/dist/{chunk-A2HXAZXC.js → chunk-CD2XJOBJ.js} +135 -142
  11. package/dist/chunk-CD2XJOBJ.js.map +1 -0
  12. package/dist/{chunk-LQVMDX5I.mjs → chunk-KSAO4Y4Q.mjs} +133 -54
  13. package/dist/chunk-KSAO4Y4Q.mjs.map +1 -0
  14. package/dist/{chunk-3ARWEJ3G.mjs → chunk-LEPQJNVO.mjs} +18 -2
  15. package/dist/chunk-LEPQJNVO.mjs.map +1 -0
  16. package/dist/{chunk-ZYSXBTBB.js → chunk-NUXMGPMK.js} +30 -14
  17. package/dist/chunk-NUXMGPMK.js.map +1 -0
  18. package/dist/{chunk-4D5XG6XB.js → chunk-THMRUG4D.js} +148 -69
  19. package/dist/chunk-THMRUG4D.js.map +1 -0
  20. package/dist/{contract-70f4ddbe.d.ts → contract-9e76e561.d.ts} +44 -31
  21. package/dist/contract.d.ts +123 -0
  22. package/dist/contract.js +53 -0
  23. package/dist/{clients/index.js.map → contract.js.map} +0 -0
  24. package/dist/contract.mjs +53 -0
  25. package/dist/{clients/index.mjs.map → contract.mjs.map} +0 -0
  26. package/dist/{createClient-60e3ab98.d.ts → createClient-68ee4bb4.d.ts} +3 -3
  27. package/dist/{createPublicClient-d3d12dc3.d.ts → createPublicClient-b732194e.d.ts} +3 -3
  28. package/dist/{createTestClient-5f4532c4.d.ts → createTestClient-dedf321e.d.ts} +3 -3
  29. package/dist/{createWalletClient-9ec3df4f.d.ts → createWalletClient-75813d83.d.ts} +3 -3
  30. package/dist/decodeErrorResult-0b934d23.d.ts +16 -0
  31. package/dist/{eip1193-9317a312.d.ts → eip1193-6f9ba163.d.ts} +1 -1
  32. package/dist/ens.d.ts +82 -1
  33. package/dist/ens.js +208 -3
  34. package/dist/ens.js.map +1 -1
  35. package/dist/ens.mjs +209 -4
  36. package/dist/ens.mjs.map +1 -1
  37. package/dist/getAbiItem-c8e6e7d4.d.ts +97 -0
  38. package/dist/index.d.ts +85 -175
  39. package/dist/index.js +237 -279
  40. package/dist/index.js.map +1 -1
  41. package/dist/index.mjs +245 -287
  42. package/dist/index.mjs.map +1 -1
  43. package/dist/public.d.ts +352 -10
  44. package/dist/public.js +3 -4
  45. package/dist/public.mjs +6 -7
  46. package/dist/readContract-4f6e2692.d.ts +10 -0
  47. package/dist/rpc-a5a7f376.d.ts +121 -0
  48. package/dist/{sendTransaction-54a0d509.d.ts → sendTransaction-e713f90c.d.ts} +3 -3
  49. package/dist/test.d.ts +160 -5
  50. package/dist/test.js +222 -18
  51. package/dist/test.js.map +1 -1
  52. package/dist/test.mjs +233 -29
  53. package/dist/test.mjs.map +1 -1
  54. package/dist/transactionReceipt-2a86c7c7.d.ts +26 -0
  55. package/dist/{transactionRequest-bdf57f7d.d.ts → transactionRequest-c7794f5e.d.ts} +1 -1
  56. package/dist/utils/index.d.ts +224 -20
  57. package/dist/utils/index.js +2 -6
  58. package/dist/utils/index.mjs +3 -7
  59. package/dist/wallet.d.ts +41 -7
  60. package/dist/wallet.js +3 -3
  61. package/dist/wallet.mjs +2 -2
  62. package/dist/watchEvent-c346c12d.d.ts +41 -0
  63. package/dist/window.d.ts +2 -2
  64. package/ens/package.json +4 -0
  65. package/package.json +13 -9
  66. package/src/_test/constants.ts +2 -0
  67. package/src/_test/utils.ts +10 -5
  68. package/src/actions/ens/getEnsAddress.bench.ts +26 -0
  69. package/src/actions/ens/getEnsAddress.test.ts +97 -0
  70. package/src/actions/ens/getEnsAddress.ts +122 -0
  71. package/src/actions/ens/getEnsName.bench.ts +30 -0
  72. package/src/actions/ens/getEnsName.test.ts +101 -0
  73. package/src/actions/ens/getEnsName.ts +106 -0
  74. package/src/actions/ens/index.test.ts +12 -0
  75. package/src/actions/ens/index.ts +3 -0
  76. package/src/actions/index.ts +3 -3
  77. package/src/actions/public/createEventFilter.test.ts +36 -4
  78. package/src/actions/public/createEventFilter.ts +27 -10
  79. package/src/actions/public/getFilterChanges.test.ts +198 -4
  80. package/src/actions/public/getFilterLogs.test.ts +195 -2
  81. package/src/actions/public/getLogs.test.ts +201 -2
  82. package/src/actions/public/index.test.ts +0 -1
  83. package/src/actions/public/index.ts +1 -7
  84. package/src/actions/public/multicall.ts +8 -3
  85. package/src/actions/public/simulateContract.ts +1 -4
  86. package/src/actions/public/watchContractEvent.test.ts +4 -4
  87. package/src/actions/{public → wallet}/deployContract.test.ts +1 -2
  88. package/src/actions/{public → wallet}/deployContract.ts +0 -0
  89. package/src/actions/wallet/index.test.ts +1 -0
  90. package/src/actions/wallet/index.ts +6 -0
  91. package/src/chains.test.ts +44 -1517
  92. package/src/clients/transports/webSocket.test.ts +1 -0
  93. package/src/clients/transports/webSocket.ts +1 -0
  94. package/src/contract.test.ts +31 -0
  95. package/src/contract.ts +68 -0
  96. package/src/ens.test.ts +15 -0
  97. package/src/ens.ts +4 -1
  98. package/src/errors/abi.ts +18 -2
  99. package/src/errors/chain.test.ts +46 -0
  100. package/src/errors/chain.ts +33 -0
  101. package/src/errors/contract.ts +2 -2
  102. package/src/errors/index.ts +3 -0
  103. package/src/index.test.ts +0 -147
  104. package/src/index.ts +0 -257
  105. package/src/public.test.ts +36 -0
  106. package/src/public.ts +2 -6
  107. package/src/test.test.ts +38 -0
  108. package/src/test.ts +1 -0
  109. package/src/types/contract.ts +144 -40
  110. package/src/types/index.ts +2 -1
  111. package/src/types/utils.ts +21 -0
  112. package/src/utils/abi/decodeErrorResult.test.ts +1 -1
  113. package/src/utils/abi/decodeEventLog.test.ts +542 -0
  114. package/src/utils/abi/decodeEventLog.ts +107 -0
  115. package/src/utils/abi/decodeFunctionData.test.ts +1 -2
  116. package/src/utils/abi/decodeFunctionData.ts +5 -2
  117. package/src/utils/abi/encodeFunctionData.ts +1 -4
  118. package/src/utils/abi/index.test.ts +1 -0
  119. package/src/utils/abi/index.ts +6 -0
  120. package/src/utils/ens/index.test.ts +1 -0
  121. package/src/utils/ens/index.ts +2 -0
  122. package/src/utils/ens/packetToBytes.test.ts +11 -0
  123. package/src/utils/ens/packetToBytes.ts +29 -0
  124. package/src/utils/index.test.ts +1 -3
  125. package/src/utils/index.ts +3 -2
  126. package/src/utils/rpc.test.ts +1 -0
  127. package/src/utils/rpc.ts +4 -2
  128. package/src/wallet.test.ts +19 -0
  129. package/wallet/package.json +4 -0
  130. package/clients/package.json +0 -4
  131. package/dist/chunk-3ARWEJ3G.mjs.map +0 -1
  132. package/dist/chunk-4D5XG6XB.js.map +0 -1
  133. package/dist/chunk-6QTEW2BE.mjs +0 -260
  134. package/dist/chunk-6QTEW2BE.mjs.map +0 -1
  135. package/dist/chunk-A2HXAZXC.js.map +0 -1
  136. package/dist/chunk-KRPS5CIB.mjs +0 -256
  137. package/dist/chunk-KRPS5CIB.mjs.map +0 -1
  138. package/dist/chunk-LQVMDX5I.mjs.map +0 -1
  139. package/dist/chunk-N3IOPT3R.js +0 -256
  140. package/dist/chunk-N3IOPT3R.js.map +0 -1
  141. package/dist/chunk-YQUC52RL.mjs.map +0 -1
  142. package/dist/chunk-ZSTVHQ6J.js +0 -260
  143. package/dist/chunk-ZSTVHQ6J.js.map +0 -1
  144. package/dist/chunk-ZYSXBTBB.js.map +0 -1
  145. package/dist/clients/index.d.ts +0 -9
  146. package/dist/clients/index.js +0 -24
  147. package/dist/clients/index.mjs +0 -24
  148. package/dist/normalize-ef9240c0.d.ts +0 -33
  149. package/dist/parseGwei-492ab7dd.d.ts +0 -355
  150. package/dist/rpc-26932bae.d.ts +0 -61
  151. package/dist/stopImpersonatingAccount-c1a4b7e5.d.ts +0 -156
  152. package/dist/watchAsset-d59d6e35.d.ts +0 -38
  153. package/dist/watchPendingTransactions-ea21b31d.d.ts +0 -373
  154. package/dist/webSocket-775b4037.d.ts +0 -83
@@ -0,0 +1,106 @@
1
+ import { PublicClient } from '../../clients'
2
+ import { panicReasons } from '../../constants'
3
+ import {
4
+ ChainDoesNotSupportContract,
5
+ ContractFunctionExecutionError,
6
+ ContractFunctionRevertedError,
7
+ } from '../../errors'
8
+ import type { Address, Prettify } from '../../types'
9
+ import { encodeHex } from '../../utils'
10
+ import { packetToBytes } from '../../utils/ens'
11
+ import { readContract, ReadContractArgs } from '../public'
12
+
13
+ export type GetEnsNameArgs = Prettify<
14
+ Pick<ReadContractArgs, 'blockNumber' | 'blockTag'> & {
15
+ /** Address to get ENS name for. */
16
+ address: Address
17
+ /** Address of ENS Universal Resolver Contract. */
18
+ universalResolverAddress?: Address
19
+ }
20
+ >
21
+
22
+ /**
23
+ * @description Gets primary name for specified address.
24
+ *
25
+ * - Calls `reverse(bytes)` on ENS Universal Resolver Contract.
26
+ *
27
+ * @example
28
+ * const ensName = await getEnsName(publicClient, {
29
+ * address: '0xd2135CfB216b74109775236E36d4b433F1DF507B',
30
+ * })
31
+ * // 'wagmi-dev.eth'
32
+ */
33
+ export async function getEnsName(
34
+ client: PublicClient,
35
+ {
36
+ address,
37
+ blockNumber,
38
+ blockTag,
39
+ universalResolverAddress: universalResolverAddress_,
40
+ }: GetEnsNameArgs,
41
+ ) {
42
+ let universalResolverAddress = universalResolverAddress_
43
+ if (!universalResolverAddress) {
44
+ if (!client.chain)
45
+ throw new Error(
46
+ 'client chain not configured. universalResolverAddress is required.',
47
+ )
48
+
49
+ const contract = client.chain?.contracts?.ensUniversalResolver
50
+ if (!contract)
51
+ throw new ChainDoesNotSupportContract({
52
+ chain: client.chain,
53
+ contract: { name: 'ensUniversalResolver' },
54
+ })
55
+
56
+ if (
57
+ blockNumber &&
58
+ contract.blockCreated &&
59
+ contract.blockCreated > blockNumber
60
+ )
61
+ throw new ChainDoesNotSupportContract({
62
+ blockNumber,
63
+ chain: client.chain,
64
+ contract: {
65
+ name: 'ensUniversalResolver',
66
+ blockCreated: contract.blockCreated,
67
+ },
68
+ })
69
+
70
+ universalResolverAddress = contract.address
71
+ }
72
+
73
+ const reverseNode = `${address.toLowerCase().substring(2)}.addr.reverse`
74
+ try {
75
+ const res = await readContract(client, {
76
+ address: universalResolverAddress,
77
+ abi: [
78
+ {
79
+ name: 'reverse',
80
+ type: 'function',
81
+ stateMutability: 'view',
82
+ inputs: [{ type: 'bytes', name: 'reverseName' }],
83
+ outputs: [
84
+ { type: 'string', name: 'resolvedName' },
85
+ { type: 'address', name: 'resolvedAddress' },
86
+ { type: 'address', name: 'reverseResolver' },
87
+ { type: 'address', name: 'resolver' },
88
+ ],
89
+ },
90
+ ],
91
+ functionName: 'reverse',
92
+ args: [encodeHex(packetToBytes(reverseNode))],
93
+ blockNumber,
94
+ blockTag,
95
+ })
96
+ return res[0]
97
+ } catch (error) {
98
+ if (
99
+ error instanceof ContractFunctionExecutionError &&
100
+ (error.cause as ContractFunctionRevertedError).reason === panicReasons[50]
101
+ )
102
+ // No primary name set for address.
103
+ return null
104
+ throw error
105
+ }
106
+ }
@@ -0,0 +1,12 @@
1
+ import { expect, test } from 'vitest'
2
+
3
+ import * as actions from './index'
4
+
5
+ test('exports actions', () => {
6
+ expect(actions).toMatchInlineSnapshot(`
7
+ {
8
+ "getEnsAddress": [Function],
9
+ "getEnsName": [Function],
10
+ }
11
+ `)
12
+ })
@@ -0,0 +1,3 @@
1
+ export { getEnsAddress, type GetEnsAddressArgs } from './getEnsAddress'
2
+
3
+ export { getEnsName, type GetEnsNameArgs } from './getEnsName'
@@ -4,7 +4,6 @@ export {
4
4
  createContractEventFilter,
5
5
  createEventFilter,
6
6
  createPendingTransactionFilter,
7
- deployContract,
8
7
  estimateGas,
9
8
  getBalance,
10
9
  getBlock,
@@ -43,8 +42,6 @@ export type {
43
42
  CreateEventFilterArgs,
44
43
  CreateEventFilterResponse,
45
44
  CreatePendingTransactionFilterResponse,
46
- DeployContractArgs,
47
- DeployContractResponse,
48
45
  EstimateGasArgs,
49
46
  EstimateGasResponse,
50
47
  GetBalanceArgs,
@@ -156,6 +153,7 @@ export type {
156
153
 
157
154
  export {
158
155
  addChain,
156
+ deployContract,
159
157
  getAccounts,
160
158
  getPermissions,
161
159
  requestAccounts,
@@ -167,6 +165,8 @@ export {
167
165
  writeContract,
168
166
  } from './wallet'
169
167
  export type {
168
+ DeployContractArgs,
169
+ DeployContractResponse,
170
170
  FormattedTransactionRequest,
171
171
  GetPermissionsResponse,
172
172
  RequestPermissionsResponse,
@@ -111,7 +111,7 @@ describe('buildFilterTopics', () => {
111
111
  ])
112
112
  })
113
113
 
114
- test.skip('named args', () => {
114
+ test('named args', () => {
115
115
  expect(
116
116
  buildFilterTopics({
117
117
  event: 'Transfer(address indexed from, address indexed to)',
@@ -155,9 +155,43 @@ describe('buildFilterTopics', () => {
155
155
  '0x000000000000000000000000000000000000000000000000000000000000000c',
156
156
  '0x0000000000000000000000000000000000000000000000000000000000000001',
157
157
  ])
158
+
159
+ expect(
160
+ buildFilterTopics({
161
+ event:
162
+ 'Transfer(string indexed baz, uint indexed foo, bool indexed bar)',
163
+ args: {
164
+ baz: 'watermelon sugar high',
165
+ foo: 12,
166
+ bar: true,
167
+ },
168
+ }),
169
+ ).toEqual([
170
+ '0xd72ffe8f642f870a4e0b389d4e008752294ecfa2a379b4a9790c067aef635088',
171
+ '0xdb31e24017b555ff340729aa37fadedf910b5395e13a218e76e155c39527bf02',
172
+ '0x000000000000000000000000000000000000000000000000000000000000000c',
173
+ '0x0000000000000000000000000000000000000000000000000000000000000001',
174
+ ])
175
+
176
+ expect(
177
+ buildFilterTopics({
178
+ event:
179
+ 'Transfer(bytes indexed baz, uint indexed foo, bool indexed bar)',
180
+ args: {
181
+ baz: '0x69420',
182
+ foo: 12,
183
+ bar: true,
184
+ },
185
+ }),
186
+ ).toEqual([
187
+ '0xd0ac01db7189fe6027705e6dda462153bf4aec72630a11dcec054ac78bac314d',
188
+ '0xd36b1a27d526376a81ba9b34292f4103e8340cc80a493e43aa00a14ebd0df4c5',
189
+ '0x000000000000000000000000000000000000000000000000000000000000000c',
190
+ '0x0000000000000000000000000000000000000000000000000000000000000001',
191
+ ])
158
192
  })
159
193
 
160
- test.skip('unnamed args', () => {
194
+ test('unnamed args', () => {
161
195
  expect(
162
196
  buildFilterTopics({
163
197
  event: 'Transfer(address indexed, address indexed, uint indexed)',
@@ -240,6 +274,4 @@ describe('buildFilterTopics', () => {
240
274
  ],
241
275
  ])
242
276
  })
243
-
244
- // TODO: more arg types
245
277
  })
@@ -1,3 +1,4 @@
1
+ import { Abi } from 'abitype'
1
2
  import type { PublicClient } from '../../clients'
2
3
 
3
4
  import type {
@@ -9,7 +10,14 @@ import type {
9
10
  Filter,
10
11
  LogTopic,
11
12
  } from '../../types'
12
- import { getEventSignature, numberToHex } from '../../utils'
13
+ import {
14
+ EncodeEventTopicsArgs,
15
+ encodeEventTopics,
16
+ extractFunctionName,
17
+ extractFunctionParams,
18
+ numberToHex,
19
+ getAbiItem,
20
+ } from '../../utils'
13
21
 
14
22
  export type EventFilterArgs<TEventDefinition extends EventDefinition> =
15
23
  ExtractArgsFromEventDefinition<TEventDefinition>
@@ -43,9 +51,7 @@ export async function createEventFilter<
43
51
  }: CreateEventFilterArgs<TEventDefinition> = {},
44
52
  ): Promise<CreateEventFilterResponse> {
45
53
  let topics: LogTopic[] = []
46
- if (event) {
47
- topics = buildFilterTopics({ event, args })
48
- }
54
+ if (event) topics = buildFilterTopics({ event, args })
49
55
  const id = await client.request({
50
56
  method: 'eth_newFilter',
51
57
  params: [
@@ -61,16 +67,27 @@ export async function createEventFilter<
61
67
  return { id, type: 'event' }
62
68
  }
63
69
 
64
- export function buildFilterTopics<TEventDefinition extends EventDefinition,>({
70
+ export function buildFilterTopics<TEventDefinition extends EventDefinition>({
65
71
  event,
66
- args: _args,
72
+ args,
67
73
  }: {
68
74
  event: TEventDefinition
69
75
  args?: EventFilterArgs<TEventDefinition>
70
76
  }) {
71
- const signature = getEventSignature(event)
72
-
73
- // TODO: support args
77
+ const eventName = extractFunctionName(event)!
78
+ const abi = unstable_parseAbi(event)
79
+ return encodeEventTopics({ abi, eventName, args } as EncodeEventTopicsArgs)
80
+ }
74
81
 
75
- return [signature]
82
+ // REFACTOR: Implement a full version of `parseAbi` that supports more types (functions, errors) & more complex arg types (structs & arrays).
83
+ function unstable_parseAbi(definition: EventDefinition): Abi {
84
+ const name = extractFunctionName(definition)!
85
+ const params = extractFunctionParams(definition)
86
+ return [
87
+ {
88
+ type: 'event',
89
+ name,
90
+ inputs: params || [],
91
+ },
92
+ ]
76
93
  }
@@ -17,7 +17,7 @@ import {
17
17
  setIntervalMining,
18
18
  stopImpersonatingAccount,
19
19
  } from '../test'
20
- import { sendTransaction } from '../wallet'
20
+ import { sendTransaction, writeContract } from '../wallet'
21
21
  import { parseEther } from '../../utils'
22
22
  import type { Hash, Log } from '../../types'
23
23
  import { createBlockFilter } from './createBlockFilter'
@@ -30,6 +30,9 @@ beforeAll(async () => {
30
30
  await impersonateAccount(testClient, {
31
31
  address: address.vitalik,
32
32
  })
33
+ await impersonateAccount(testClient, {
34
+ address: address.usdcHolder,
35
+ })
33
36
  })
34
37
 
35
38
  afterAll(async () => {
@@ -37,6 +40,9 @@ afterAll(async () => {
37
40
  await stopImpersonatingAccount(testClient, {
38
41
  address: address.vitalik,
39
42
  })
43
+ await stopImpersonatingAccount(testClient, {
44
+ address: address.usdcHolder,
45
+ })
40
46
  })
41
47
 
42
48
  test('default', async () => {
@@ -135,7 +141,8 @@ describe('events', () => {
135
141
 
136
142
  test('args: event', async () => {
137
143
  const filter = await createEventFilter(publicClient, {
138
- event: 'Transfer(address from, address to, uint256 value)',
144
+ event:
145
+ 'Transfer(address indexed from, address indexed to, uint256 value)',
139
146
  })
140
147
 
141
148
  await sendTransaction(walletClient, {
@@ -172,7 +179,8 @@ describe('events', () => {
172
179
 
173
180
  test('args: fromBlock/toBlock', async () => {
174
181
  const filter = await createEventFilter(publicClient, {
175
- event: 'Transfer(address from, address to, uint256 value)',
182
+ event:
183
+ 'Transfer(address indexed from, address indexed to, uint256 value)',
176
184
  fromBlock: initialBlockNumber - 5n,
177
185
  toBlock: initialBlockNumber,
178
186
  })
@@ -185,5 +193,191 @@ describe('events', () => {
185
193
  expect(logs.length).toBe(0)
186
194
  })
187
195
 
188
- test.todo('args: args')
196
+ test('args: singular `from`', async () => {
197
+ const namedFilter = await createEventFilter(publicClient, {
198
+ event:
199
+ 'Transfer(address indexed from, address indexed to, uint256 value)',
200
+ args: {
201
+ from: address.vitalik,
202
+ },
203
+ })
204
+ const unnamedFilter = await createEventFilter(publicClient, {
205
+ event: 'Transfer(address indexed, address indexed, uint256)',
206
+ args: [address.vitalik],
207
+ })
208
+
209
+ await writeContract(walletClient, {
210
+ ...usdcContractConfig,
211
+ from: address.usdcHolder,
212
+ functionName: 'transfer',
213
+ args: [accounts[0].address, 1n],
214
+ })
215
+ await writeContract(walletClient, {
216
+ ...usdcContractConfig,
217
+ from: address.vitalik,
218
+ functionName: 'transfer',
219
+ args: [accounts[1].address, 1n],
220
+ })
221
+ await writeContract(walletClient, {
222
+ ...usdcContractConfig,
223
+ from: address.vitalik,
224
+ functionName: 'transfer',
225
+ args: [accounts[1].address, 1n],
226
+ })
227
+ await writeContract(walletClient, {
228
+ ...usdcContractConfig,
229
+ from: address.vitalik,
230
+ functionName: 'approve',
231
+ args: [address.vitalik, 1n],
232
+ })
233
+ await mine(testClient, { blocks: 1 })
234
+
235
+ expect(
236
+ (await getFilterChanges(publicClient, { filter: namedFilter })).length,
237
+ ).toBe(2)
238
+ expect(
239
+ (await getFilterChanges(publicClient, { filter: unnamedFilter })).length,
240
+ ).toBe(2)
241
+ })
242
+
243
+ test('args: multiple `from`', async () => {
244
+ const namedFilter = await createEventFilter(publicClient, {
245
+ event:
246
+ 'Transfer(address indexed from, address indexed to, uint256 value)',
247
+ args: {
248
+ from: [address.usdcHolder, address.vitalik],
249
+ },
250
+ })
251
+ const unnamedFilter = await createEventFilter(publicClient, {
252
+ event: 'Transfer(address indexed, address indexed, uint256)',
253
+ args: [[address.usdcHolder, address.vitalik]],
254
+ })
255
+
256
+ await writeContract(walletClient, {
257
+ ...usdcContractConfig,
258
+ from: address.usdcHolder,
259
+ functionName: 'transfer',
260
+ args: [accounts[0].address, 1n],
261
+ })
262
+ await writeContract(walletClient, {
263
+ ...usdcContractConfig,
264
+ from: address.vitalik,
265
+ functionName: 'transfer',
266
+ args: [accounts[1].address, 1n],
267
+ })
268
+ await writeContract(walletClient, {
269
+ ...usdcContractConfig,
270
+ from: address.vitalik,
271
+ functionName: 'transfer',
272
+ args: [accounts[1].address, 1n],
273
+ })
274
+ await writeContract(walletClient, {
275
+ ...usdcContractConfig,
276
+ from: address.vitalik,
277
+ functionName: 'approve',
278
+ args: [address.vitalik, 1n],
279
+ })
280
+ await mine(testClient, { blocks: 1 })
281
+
282
+ expect(
283
+ (await getFilterChanges(publicClient, { filter: namedFilter })).length,
284
+ ).toBe(3)
285
+ expect(
286
+ (await getFilterChanges(publicClient, { filter: unnamedFilter })).length,
287
+ ).toBe(3)
288
+ })
289
+
290
+ test('args: singular `to`', async () => {
291
+ const namedFilter = await createEventFilter(publicClient, {
292
+ event:
293
+ 'Transfer(address indexed from, address indexed to, uint256 value)',
294
+ args: {
295
+ to: accounts[0].address,
296
+ },
297
+ })
298
+ const unnamedFilter = await createEventFilter(publicClient, {
299
+ event: 'Transfer(address indexed, address indexed, uint256)',
300
+ args: [null, accounts[0].address],
301
+ })
302
+
303
+ await writeContract(walletClient, {
304
+ ...usdcContractConfig,
305
+ from: address.usdcHolder,
306
+ functionName: 'transfer',
307
+ args: [accounts[0].address, 1n],
308
+ })
309
+ await writeContract(walletClient, {
310
+ ...usdcContractConfig,
311
+ from: address.vitalik,
312
+ functionName: 'transfer',
313
+ args: [accounts[1].address, 1n],
314
+ })
315
+ await writeContract(walletClient, {
316
+ ...usdcContractConfig,
317
+ from: address.vitalik,
318
+ functionName: 'transfer',
319
+ args: [accounts[1].address, 1n],
320
+ })
321
+ await writeContract(walletClient, {
322
+ ...usdcContractConfig,
323
+ from: address.vitalik,
324
+ functionName: 'approve',
325
+ args: [address.vitalik, 1n],
326
+ })
327
+ await mine(testClient, { blocks: 1 })
328
+
329
+ expect(
330
+ (await getFilterChanges(publicClient, { filter: namedFilter })).length,
331
+ ).toBe(1)
332
+ expect(
333
+ (await getFilterChanges(publicClient, { filter: unnamedFilter })).length,
334
+ ).toBe(1)
335
+ })
336
+
337
+ test('args: multiple `to`', async () => {
338
+ const namedFilter = await createEventFilter(publicClient, {
339
+ event:
340
+ 'Transfer(address indexed from, address indexed to, uint256 value)',
341
+ args: {
342
+ to: [accounts[0].address, accounts[1].address],
343
+ },
344
+ })
345
+ const unnamedFilter = await createEventFilter(publicClient, {
346
+ event: 'Transfer(address indexed, address indexed, uint256)',
347
+ args: [null, [accounts[0].address, accounts[1].address]],
348
+ })
349
+
350
+ await writeContract(walletClient, {
351
+ ...usdcContractConfig,
352
+ from: address.usdcHolder,
353
+ functionName: 'transfer',
354
+ args: [accounts[0].address, 1n],
355
+ })
356
+ await writeContract(walletClient, {
357
+ ...usdcContractConfig,
358
+ from: address.vitalik,
359
+ functionName: 'transfer',
360
+ args: [accounts[1].address, 1n],
361
+ })
362
+ await writeContract(walletClient, {
363
+ ...usdcContractConfig,
364
+ from: address.vitalik,
365
+ functionName: 'transfer',
366
+ args: [accounts[1].address, 1n],
367
+ })
368
+ await writeContract(walletClient, {
369
+ ...usdcContractConfig,
370
+ from: address.vitalik,
371
+ functionName: 'approve',
372
+ args: [address.vitalik, 1n],
373
+ })
374
+ await mine(testClient, { blocks: 1 })
375
+
376
+ expect(
377
+ (await getFilterChanges(publicClient, { filter: namedFilter })).length,
378
+ ).toBe(3)
379
+ expect(
380
+ (await getFilterChanges(publicClient, { filter: unnamedFilter })).length,
381
+ ).toBe(3)
382
+ })
189
383
  })