@hyperlane-xyz/sdk 16.0.0 → 16.1.0

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 (77) hide show
  1. package/dist/block-explorer/etherscan.d.ts +1 -12
  2. package/dist/block-explorer/etherscan.d.ts.map +1 -1
  3. package/dist/block-explorer/etherscan.js +14 -2
  4. package/dist/block-explorer/etherscan.js.map +1 -1
  5. package/dist/block-explorer/utils.d.ts +3 -0
  6. package/dist/block-explorer/utils.d.ts.map +1 -0
  7. package/dist/block-explorer/utils.js +16 -0
  8. package/dist/block-explorer/utils.js.map +1 -0
  9. package/dist/consts/testChains.d.ts +2 -0
  10. package/dist/consts/testChains.d.ts.map +1 -1
  11. package/dist/consts/testChains.js +36 -1
  12. package/dist/consts/testChains.js.map +1 -1
  13. package/dist/contracts/contracts.d.ts +9 -1
  14. package/dist/contracts/contracts.d.ts.map +1 -1
  15. package/dist/contracts/contracts.js +15 -1
  16. package/dist/contracts/contracts.js.map +1 -1
  17. package/dist/deploy/verify/ContractVerifier.d.ts.map +1 -1
  18. package/dist/deploy/verify/ContractVerifier.js +16 -5
  19. package/dist/deploy/verify/ContractVerifier.js.map +1 -1
  20. package/dist/index.d.ts +3 -1
  21. package/dist/index.d.ts.map +1 -1
  22. package/dist/index.js +3 -1
  23. package/dist/index.js.map +1 -1
  24. package/dist/metadata/ChainMetadataManager.d.ts +10 -0
  25. package/dist/metadata/ChainMetadataManager.d.ts.map +1 -1
  26. package/dist/metadata/ChainMetadataManager.js +33 -2
  27. package/dist/metadata/ChainMetadataManager.js.map +1 -1
  28. package/dist/metadata/blockExplorer.d.ts.map +1 -1
  29. package/dist/metadata/blockExplorer.js +27 -1
  30. package/dist/metadata/blockExplorer.js.map +1 -1
  31. package/dist/metadata/blockExplorer.test.js +176 -1
  32. package/dist/metadata/blockExplorer.test.js.map +1 -1
  33. package/dist/providers/transactions/submitter/ethersV5/EV5TimelockSubmitter.d.ts.map +1 -1
  34. package/dist/providers/transactions/submitter/ethersV5/EV5TimelockSubmitter.js +3 -3
  35. package/dist/providers/transactions/submitter/ethersV5/EV5TimelockSubmitter.js.map +1 -1
  36. package/dist/rpc/evm/EvmEventLogsReader.d.ts +79 -0
  37. package/dist/rpc/evm/EvmEventLogsReader.d.ts.map +1 -0
  38. package/dist/rpc/evm/EvmEventLogsReader.hardhat-test.d.ts +2 -0
  39. package/dist/rpc/evm/EvmEventLogsReader.hardhat-test.d.ts.map +1 -0
  40. package/dist/rpc/evm/EvmEventLogsReader.hardhat-test.js +279 -0
  41. package/dist/rpc/evm/EvmEventLogsReader.hardhat-test.js.map +1 -0
  42. package/dist/rpc/evm/EvmEventLogsReader.js +107 -0
  43. package/dist/rpc/evm/EvmEventLogsReader.js.map +1 -0
  44. package/dist/rpc/evm/types.d.ts +11 -0
  45. package/dist/rpc/evm/types.d.ts.map +1 -0
  46. package/dist/rpc/evm/types.js +2 -0
  47. package/dist/rpc/evm/types.js.map +1 -0
  48. package/dist/rpc/evm/utils.d.ts +18 -0
  49. package/dist/rpc/evm/utils.d.ts.map +1 -0
  50. package/dist/rpc/evm/utils.hardhat-test.d.ts +2 -0
  51. package/dist/rpc/evm/utils.hardhat-test.d.ts.map +1 -0
  52. package/dist/rpc/evm/utils.hardhat-test.js +144 -0
  53. package/dist/rpc/evm/utils.hardhat-test.js.map +1 -0
  54. package/dist/rpc/evm/utils.js +67 -0
  55. package/dist/rpc/evm/utils.js.map +1 -0
  56. package/dist/timelock/evm/EvmTimelockReader.d.ts +30 -0
  57. package/dist/timelock/evm/EvmTimelockReader.d.ts.map +1 -0
  58. package/dist/timelock/evm/EvmTimelockReader.hardhat-test.d.ts +2 -0
  59. package/dist/timelock/evm/EvmTimelockReader.hardhat-test.d.ts.map +1 -0
  60. package/dist/timelock/evm/EvmTimelockReader.hardhat-test.js +649 -0
  61. package/dist/timelock/evm/EvmTimelockReader.hardhat-test.js.map +1 -0
  62. package/dist/timelock/evm/EvmTimelockReader.js +173 -0
  63. package/dist/timelock/evm/EvmTimelockReader.js.map +1 -0
  64. package/dist/timelock/evm/utils.d.ts +4 -0
  65. package/dist/timelock/evm/utils.d.ts.map +1 -0
  66. package/dist/timelock/evm/utils.js +11 -0
  67. package/dist/timelock/evm/utils.js.map +1 -0
  68. package/dist/timelock/types.d.ts +11 -0
  69. package/dist/timelock/types.d.ts.map +1 -1
  70. package/dist/timelock/types.js.map +1 -1
  71. package/dist/token/checker.js +2 -2
  72. package/dist/token/checker.js.map +1 -1
  73. package/dist/token/types.d.ts +1 -1
  74. package/dist/token/xerc20.d.ts.map +1 -1
  75. package/dist/token/xerc20.js +3 -35
  76. package/dist/token/xerc20.js.map +1 -1
  77. package/package.json +5 -5
@@ -0,0 +1,279 @@
1
+ import chai, { expect } from 'chai';
2
+ import chaiAsPromised from 'chai-as-promised';
3
+ import { ethers } from 'ethers';
4
+ import hre from 'hardhat';
5
+ import { ERC20Test__factory } from '@hyperlane-xyz/core';
6
+ import { assert } from '@hyperlane-xyz/utils';
7
+ import { KNOWN_BASE_TIMELOCK_CONTRACT, TestChainName, baseTestChain, } from '../../consts/testChains.js';
8
+ import { MultiProvider } from '../../providers/MultiProvider.js';
9
+ import { randomAddress, randomInt } from '../../test/testUtils.js';
10
+ import { EvmEtherscanLikeEventLogsReader, EvmEventLogsReader, EvmRpcEventLogsReader, } from './EvmEventLogsReader.js';
11
+ chai.use(chaiAsPromised);
12
+ describe('EvmEventLogsReader', () => {
13
+ let contractOwner;
14
+ let tokenRecipient1;
15
+ let tokenRecipient2;
16
+ let providerChainTest1;
17
+ let multiProvider;
18
+ let testContract;
19
+ let erc20Factory;
20
+ let deploymentBlockNumber;
21
+ const transferTopic = ethers.utils.id('Transfer(address,address,uint256)');
22
+ beforeEach(async () => {
23
+ [contractOwner, tokenRecipient1, tokenRecipient2] =
24
+ await hre.ethers.getSigners();
25
+ assert(contractOwner.provider, 'Provider should be available');
26
+ // Initialize MultiProvider with test chain
27
+ multiProvider = MultiProvider.createTestMultiProvider({
28
+ signer: contractOwner,
29
+ provider: contractOwner.provider,
30
+ });
31
+ providerChainTest1 = contractOwner.provider;
32
+ // Get contract factory for ERC20Test
33
+ erc20Factory = new ERC20Test__factory(contractOwner);
34
+ });
35
+ async function deployTestErc20() {
36
+ testContract = await erc20Factory.deploy('TestToken', 'TST', ethers.utils.parseEther('1000000'), 18);
37
+ await testContract.deployed();
38
+ assert(testContract.deployTransaction.blockNumber, 'Expected the Contract deployment block number to be defined');
39
+ deploymentBlockNumber = testContract.deployTransaction.blockNumber;
40
+ }
41
+ async function mineRandomNumberOfBlocks() {
42
+ const blocksToMine = randomInt(5, 20);
43
+ for (let blockNum = 0; blockNum < blocksToMine; blockNum++) {
44
+ await providerChainTest1.send('evm_mine', []);
45
+ }
46
+ }
47
+ describe('constructor', () => {
48
+ it('should initialize with BlockExplorer strategy when useRPC is false', async () => {
49
+ const readerWithRpc = EvmEventLogsReader.fromConfig({
50
+ chain: TestChainName.test1,
51
+ }, multiProvider);
52
+ // Access the private property indirectly
53
+ expect(readerWithRpc['logReaderStrategy']).to.be.instanceOf(EvmEtherscanLikeEventLogsReader);
54
+ });
55
+ it('should initialize with RPC strategy when useRPC is true', async () => {
56
+ const readerWithRpc = EvmEventLogsReader.fromConfig({
57
+ chain: TestChainName.test1,
58
+ useRPC: true,
59
+ }, multiProvider);
60
+ // Access the private property indirectly
61
+ expect(readerWithRpc['logReaderStrategy']).to.be.instanceOf(EvmRpcEventLogsReader);
62
+ });
63
+ it('should initialize with RPC strategy when no explorer is available', async () => {
64
+ const multiProviderNoExplorer = new MultiProvider({});
65
+ multiProviderNoExplorer.setSharedSigner(contractOwner);
66
+ const reader = EvmEventLogsReader.fromConfig({
67
+ chain: TestChainName.test1,
68
+ // Even when false, should use RPC if no explorer
69
+ useRPC: false,
70
+ }, multiProviderNoExplorer);
71
+ // Access the private property indirectly
72
+ expect(reader['logReaderStrategy']).to.be.instanceOf(EvmRpcEventLogsReader);
73
+ });
74
+ });
75
+ describe(`${EvmEventLogsReader.prototype.getLogsByTopic.name} (rpc)`, () => {
76
+ let reader;
77
+ beforeEach(async () => {
78
+ await deployTestErc20();
79
+ reader = EvmEventLogsReader.fromConfig({
80
+ chain: TestChainName.test1,
81
+ useRPC: true,
82
+ paginationBlockRange: 1000,
83
+ }, multiProvider);
84
+ });
85
+ it('should retrieve logs for Transfer events emitted by the contract', async () => {
86
+ // Emit some Transfer events
87
+ const tx1 = await testContract.transfer(tokenRecipient1.address, ethers.utils.parseEther('100'));
88
+ await tx1.wait();
89
+ const tx2 = await testContract.transfer(tokenRecipient2.address, ethers.utils.parseEther('200'));
90
+ await tx2.wait();
91
+ const logs = await reader.getLogsByTopic({
92
+ eventTopic: transferTopic,
93
+ contractAddress: testContract.address,
94
+ fromBlock: deploymentBlockNumber,
95
+ });
96
+ // Should have 3 transfer events: 1 from constructor mint + 2 from transfers
97
+ expect(logs).to.have.length(3);
98
+ logs.forEach((log) => {
99
+ expect(log.address).to.equal(testContract.address);
100
+ expect(log.topics[0]).to.equal(transferTopic);
101
+ });
102
+ });
103
+ it('should work when fromBlock is not specified (uses deployment block)', async () => {
104
+ // Emit Transfer event
105
+ const tx = await testContract.transfer(tokenRecipient1.address, ethers.utils.parseEther('100'));
106
+ await tx.wait();
107
+ const logs = await reader.getLogsByTopic({
108
+ eventTopic: transferTopic,
109
+ contractAddress: testContract.address,
110
+ });
111
+ // Should have 2 transfer events: 1 from constructor mint + 1 from transfer
112
+ expect(logs).to.have.length(2);
113
+ logs.forEach((log) => {
114
+ expect(log.address).to.equal(testContract.address);
115
+ expect(log.topics[0]).to.equal(transferTopic);
116
+ });
117
+ });
118
+ it('should work when toBlock is not specified (uses current block)', async () => {
119
+ // Emit Transfer event
120
+ const tx = await testContract.transfer(tokenRecipient1.address, ethers.utils.parseEther('100'));
121
+ await tx.wait();
122
+ const logs = await reader.getLogsByTopic({
123
+ eventTopic: transferTopic,
124
+ contractAddress: testContract.address,
125
+ fromBlock: deploymentBlockNumber,
126
+ // No toBlock specified
127
+ });
128
+ // Should have 2 transfer events: 1 from constructor mint + 1 from transfer
129
+ expect(logs).to.have.length(2);
130
+ logs.forEach((log) => {
131
+ expect(log.address).to.equal(testContract.address);
132
+ expect(log.topics[0]).to.equal(transferTopic);
133
+ });
134
+ });
135
+ it('should work when both fromBlock and toBlock are specified', async () => {
136
+ await mineRandomNumberOfBlocks();
137
+ const startBlock = await providerChainTest1.getBlockNumber();
138
+ // Emit event in first block
139
+ const tx1 = await testContract.transfer(tokenRecipient1.address, ethers.utils.parseEther('100'));
140
+ await tx1.wait();
141
+ const firstEventBlock = await providerChainTest1.getBlockNumber();
142
+ await mineRandomNumberOfBlocks();
143
+ // Emit event in later block
144
+ const tx2 = await testContract.transfer(tokenRecipient1.address, ethers.utils.parseEther('200'));
145
+ await tx2.wait();
146
+ // Query only the first event's block range
147
+ const logs = await reader.getLogsByTopic({
148
+ eventTopic: transferTopic,
149
+ contractAddress: testContract.address,
150
+ fromBlock: startBlock,
151
+ toBlock: firstEventBlock,
152
+ });
153
+ expect(logs).to.have.length(1);
154
+ expect(logs[0].blockNumber).to.equal(firstEventBlock);
155
+ expect(logs[0].address).to.equal(testContract.address);
156
+ expect(logs[0].topics[0]).to.equal(transferTopic);
157
+ });
158
+ it('should return empty array when no logs match the filter', async () => {
159
+ // Emit an event just to be sure that filtering works as expected
160
+ const tx = await testContract.transfer(tokenRecipient1.address, ethers.utils.parseEther('100'));
161
+ await tx.wait();
162
+ const nonExistentTopic = ethers.utils.id('NonExistentEvent(uint256)');
163
+ const logs = await reader.getLogsByTopic({
164
+ eventTopic: nonExistentTopic,
165
+ contractAddress: testContract.address,
166
+ fromBlock: deploymentBlockNumber,
167
+ });
168
+ expect(logs).to.have.length(0);
169
+ });
170
+ it('should handle multiple events across different blocks', async () => {
171
+ const numberOfEventsToEmit = randomInt(3, 10);
172
+ const eventBlocks = [];
173
+ for (let i = 0; i < numberOfEventsToEmit; i++) {
174
+ const tx = await testContract.mint(ethers.utils.parseEther(`${(i + 1) * 50}`));
175
+ await tx.wait();
176
+ eventBlocks.push(await providerChainTest1.getBlockNumber());
177
+ // Mine a few blocks between events
178
+ await mineRandomNumberOfBlocks();
179
+ }
180
+ // +1 because of the transfer event emitted on contract deployment
181
+ const expectedNumberOfEvents = numberOfEventsToEmit + 1;
182
+ const logs = await reader.getLogsByTopic({
183
+ eventTopic: transferTopic,
184
+ contractAddress: testContract.address,
185
+ fromBlock: deploymentBlockNumber,
186
+ });
187
+ expect(logs).to.have.length(expectedNumberOfEvents);
188
+ // Verify all logs are from the correct contract and have the right topic
189
+ logs.forEach((log) => {
190
+ expect(log.address).to.equal(testContract.address);
191
+ expect(log.topics[0]).to.equal(transferTopic);
192
+ });
193
+ });
194
+ it('should work with small logPageSize (testing chunking)', async () => {
195
+ const readerWithSmallPageSize = EvmEventLogsReader.fromConfig({
196
+ chain: TestChainName.test1,
197
+ useRPC: true,
198
+ paginationBlockRange: 2,
199
+ }, multiProvider);
200
+ const numberOfEventsToEmit = 5;
201
+ for (let i = 0; i < numberOfEventsToEmit; i++) {
202
+ const tx = await testContract.mint(ethers.utils.parseEther(`${(i + 1) * 100}`));
203
+ await tx.wait();
204
+ }
205
+ // +1 because of the transfer event emitted on contract deployment
206
+ const expectedNumberOfEvents = numberOfEventsToEmit + 1;
207
+ const logs = await readerWithSmallPageSize.getLogsByTopic({
208
+ eventTopic: transferTopic,
209
+ contractAddress: testContract.address,
210
+ fromBlock: deploymentBlockNumber,
211
+ });
212
+ expect(logs).to.have.length(expectedNumberOfEvents);
213
+ });
214
+ it('should throw an error for non-existing contract address', async () => {
215
+ const nonExistentAddress = randomAddress();
216
+ await expect(reader.getLogsByTopic({
217
+ eventTopic: transferTopic,
218
+ contractAddress: nonExistentAddress,
219
+ fromBlock: deploymentBlockNumber,
220
+ })).to.be.rejected;
221
+ });
222
+ it('should handle edge case where fromBlock equals toBlock', async () => {
223
+ // Emit event
224
+ const tx = await testContract.transfer(tokenRecipient1.address, ethers.utils.parseEther('100'));
225
+ await tx.wait();
226
+ const eventBlock = await providerChainTest1.getBlockNumber();
227
+ const logs = await reader.getLogsByTopic({
228
+ eventTopic: transferTopic,
229
+ contractAddress: testContract.address,
230
+ fromBlock: eventBlock,
231
+ toBlock: eventBlock,
232
+ });
233
+ expect(logs).to.have.length(1);
234
+ expect(logs[0].blockNumber).to.equal(eventBlock);
235
+ });
236
+ });
237
+ describe(`${EvmEventLogsReader.prototype.getLogsByTopic.name} (block explorer)`, () => {
238
+ let reader;
239
+ let multiProvider;
240
+ beforeEach(async () => {
241
+ await deployTestErc20();
242
+ multiProvider = new MultiProvider({
243
+ base: baseTestChain,
244
+ });
245
+ reader = EvmEventLogsReader.fromConfig({
246
+ chain: baseTestChain.name,
247
+ }, multiProvider);
248
+ });
249
+ it('should get the expected number of events when fromBlock is not provided', async () => {
250
+ const res = await reader.getLogsByTopic({
251
+ contractAddress: KNOWN_BASE_TIMELOCK_CONTRACT,
252
+ // CallExecuted signature
253
+ eventTopic: '0xc2617efa69bab66782fa219543714338489c4e9e178271560a91b82c3f612b58',
254
+ // Omitting from block to test getting contract deployment block from explorer
255
+ toBlock: 32986242,
256
+ });
257
+ expect(res.length).to.equal(5);
258
+ });
259
+ });
260
+ describe('error handling', () => {
261
+ let reader;
262
+ beforeEach(async () => {
263
+ await deployTestErc20();
264
+ reader = EvmEventLogsReader.fromConfig({
265
+ chain: TestChainName.test1,
266
+ useRPC: true,
267
+ }, multiProvider);
268
+ });
269
+ it('should not allow invalid topic signatures', async () => {
270
+ const invalidTopic = 'invalid-topic';
271
+ expect(reader.getLogsByTopic({
272
+ eventTopic: invalidTopic,
273
+ contractAddress: testContract.address,
274
+ fromBlock: deploymentBlockNumber,
275
+ })).to.be.rejectedWith();
276
+ });
277
+ });
278
+ });
279
+ //# sourceMappingURL=EvmEventLogsReader.hardhat-test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EvmEventLogsReader.hardhat-test.js","sourceRoot":"","sources":["../../../src/rpc/evm/EvmEventLogsReader.hardhat-test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,107 @@
1
+ import { z } from 'zod';
2
+ import { rootLogger } from '@hyperlane-xyz/utils';
3
+ import { getContractDeploymentTransaction, getLogsFromEtherscanLikeExplorerAPI, } from '../../block-explorer/etherscan.js';
4
+ import { assertIsContractAddress } from '../../contracts/contracts.js';
5
+ import { ZBytes32String, ZHash, ZUint } from '../../metadata/customZodTypes.js';
6
+ import { getContractCreationBlockFromRpc, getLogsFromRpc } from './utils.js';
7
+ export const GetLogByTopicOptionsSchema = z.object({
8
+ eventTopic: ZBytes32String,
9
+ contractAddress: ZHash,
10
+ fromBlock: ZUint.optional(),
11
+ toBlock: ZUint.optional(),
12
+ });
13
+ export const RequiredGetLogByTopicOptionsSchema = GetLogByTopicOptionsSchema.required();
14
+ export class EvmEtherscanLikeEventLogsReader {
15
+ chain;
16
+ config;
17
+ multiProvider;
18
+ constructor(chain, config, multiProvider) {
19
+ this.chain = chain;
20
+ this.config = config;
21
+ this.multiProvider = multiProvider;
22
+ }
23
+ async getContractDeploymentBlockNumber(address) {
24
+ const contractDeploymentTx = await getContractDeploymentTransaction({ apiUrl: this.config.apiUrl, apiKey: this.config.apiKey }, { contractAddress: address });
25
+ const deploymentTransactionReceipt = await this.multiProvider
26
+ .getProvider(this.chain)
27
+ .getTransactionReceipt(contractDeploymentTx.txHash);
28
+ return deploymentTransactionReceipt.blockNumber;
29
+ }
30
+ async getContractLogs(options) {
31
+ const parsedOptions = RequiredGetLogByTopicOptionsSchema.parse(options);
32
+ return getLogsFromEtherscanLikeExplorerAPI({
33
+ apiUrl: this.config.apiUrl,
34
+ apiKey: this.config.apiKey,
35
+ }, {
36
+ address: parsedOptions.contractAddress,
37
+ fromBlock: parsedOptions.fromBlock,
38
+ toBlock: parsedOptions.toBlock,
39
+ topic0: parsedOptions.eventTopic,
40
+ });
41
+ }
42
+ }
43
+ export class EvmRpcEventLogsReader {
44
+ chain;
45
+ config;
46
+ multiProvider;
47
+ constructor(chain, config, multiProvider) {
48
+ this.chain = chain;
49
+ this.config = config;
50
+ this.multiProvider = multiProvider;
51
+ }
52
+ getContractDeploymentBlockNumber(address) {
53
+ return getContractCreationBlockFromRpc(this.chain, address, this.multiProvider);
54
+ }
55
+ getContractLogs(options) {
56
+ const parsedOptions = RequiredGetLogByTopicOptionsSchema.parse(options);
57
+ return getLogsFromRpc({
58
+ chain: this.chain,
59
+ contractAddress: parsedOptions.contractAddress,
60
+ topic: parsedOptions.eventTopic,
61
+ fromBlock: parsedOptions.fromBlock,
62
+ toBlock: parsedOptions.toBlock,
63
+ multiProvider: this.multiProvider,
64
+ range: this.config.paginationBlockRange,
65
+ });
66
+ }
67
+ }
68
+ export class EvmEventLogsReader {
69
+ config;
70
+ multiProvider;
71
+ logReaderStrategy;
72
+ logger;
73
+ constructor(config, multiProvider, logReaderStrategy, logger) {
74
+ this.config = config;
75
+ this.multiProvider = multiProvider;
76
+ this.logReaderStrategy = logReaderStrategy;
77
+ this.logger = logger;
78
+ }
79
+ static fromConfig(config, multiProvider, logger = rootLogger.child({
80
+ module: EvmEventLogsReader.name,
81
+ })) {
82
+ const explorer = multiProvider.tryGetEvmExplorerMetadata(config.chain);
83
+ let logReaderStrategy;
84
+ if (explorer && !config.useRPC) {
85
+ logReaderStrategy = new EvmEtherscanLikeEventLogsReader(config.chain, explorer, multiProvider);
86
+ }
87
+ else {
88
+ logReaderStrategy = new EvmRpcEventLogsReader(config.chain, { paginationBlockRange: config.paginationBlockRange }, multiProvider);
89
+ }
90
+ return new EvmEventLogsReader(config, multiProvider, logReaderStrategy, logger);
91
+ }
92
+ async getLogsByTopic(options) {
93
+ const parsedOptions = GetLogByTopicOptionsSchema.parse(options);
94
+ const provider = this.multiProvider.getProvider(this.config.chain);
95
+ await assertIsContractAddress(this.multiProvider, this.config.chain, options.contractAddress);
96
+ const fromBlock = parsedOptions.fromBlock ??
97
+ (await this.logReaderStrategy.getContractDeploymentBlockNumber(parsedOptions.contractAddress));
98
+ const toBlock = parsedOptions.toBlock ?? (await provider.getBlockNumber());
99
+ return this.logReaderStrategy.getContractLogs({
100
+ contractAddress: parsedOptions.contractAddress,
101
+ eventTopic: parsedOptions.eventTopic,
102
+ fromBlock,
103
+ toBlock,
104
+ });
105
+ }
106
+ }
107
+ //# sourceMappingURL=EvmEventLogsReader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EvmEventLogsReader.js","sourceRoot":"","sources":["../../../src/rpc/evm/EvmEventLogsReader.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import { Address, HexString } from '@hyperlane-xyz/utils';
2
+ export type GetEventLogsResponse = {
3
+ address: Address;
4
+ blockNumber: number;
5
+ data: HexString;
6
+ logIndex: number;
7
+ topics: ReadonlyArray<HexString>;
8
+ transactionHash: HexString;
9
+ transactionIndex: number;
10
+ };
11
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/rpc/evm/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAE1D,MAAM,MAAM,oBAAoB,GAAG;IACjC,OAAO,EAAE,OAAO,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,SAAS,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,aAAa,CAAC,SAAS,CAAC,CAAC;IACjC,eAAe,EAAE,SAAS,CAAC;IAC3B,gBAAgB,EAAE,MAAM,CAAC;CAC1B,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/rpc/evm/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,18 @@
1
+ import { Log } from 'viem';
2
+ import { Address } from '@hyperlane-xyz/utils';
3
+ import { MultiProvider } from '../../providers/MultiProvider.js';
4
+ import { ChainNameOrId } from '../../types.js';
5
+ import { GetEventLogsResponse } from './types.js';
6
+ export declare function getContractCreationBlockFromRpc(chain: ChainNameOrId, contractAddress: Address, multiProvider: MultiProvider): Promise<number>;
7
+ export type GetLogsFromRpcOptions = {
8
+ chain: ChainNameOrId;
9
+ contractAddress: Address;
10
+ multiProvider: MultiProvider;
11
+ fromBlock: number;
12
+ topic: string;
13
+ toBlock?: number;
14
+ range?: number;
15
+ };
16
+ export declare function getLogsFromRpc({ chain, contractAddress, multiProvider, fromBlock, topic, toBlock, range, }: GetLogsFromRpcOptions): Promise<GetEventLogsResponse[]>;
17
+ export declare function viemLogFromGetEventLogsResponse(log: GetEventLogsResponse): Log;
18
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/rpc/evm/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAO,GAAG,EAAE,MAAM,MAAM,CAAC;AAEhC,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAM/C,OAAO,EAAE,aAAa,EAAE,MAAM,kCAAkC,CAAC;AACjE,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAE/C,OAAO,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAGlD,wBAAsB,+BAA+B,CACnD,KAAK,EAAE,aAAa,EACpB,eAAe,EAAE,OAAO,EACxB,aAAa,EAAE,aAAa,GAC3B,OAAO,CAAC,MAAM,CAAC,CA2BjB;AAED,MAAM,MAAM,qBAAqB,GAAG;IAClC,KAAK,EAAE,aAAa,CAAC;IACrB,eAAe,EAAE,OAAO,CAAC;IACzB,aAAa,EAAE,aAAa,CAAC;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,wBAAsB,cAAc,CAAC,EACnC,KAAK,EACL,eAAe,EACf,aAAa,EACb,SAAS,EACT,KAAK,EACL,OAAO,EACP,KAAW,GACZ,EAAE,qBAAqB,GAAG,OAAO,CAAC,oBAAoB,EAAE,CAAC,CAoCzD;AAED,wBAAgB,+BAA+B,CAC7C,GAAG,EAAE,oBAAoB,GACxB,GAAG,CAYL"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=utils.hardhat-test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.hardhat-test.d.ts","sourceRoot":"","sources":["../../../src/rpc/evm/utils.hardhat-test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,144 @@
1
+ import chai, { expect } from 'chai';
2
+ import chaiAsPromised from 'chai-as-promised';
3
+ import { ethers } from 'ethers';
4
+ import hre from 'hardhat';
5
+ import { ERC20Test__factory } from '@hyperlane-xyz/core';
6
+ import { assert } from '@hyperlane-xyz/utils';
7
+ import { TestChainName } from '../../consts/testChains.js';
8
+ import { MultiProvider } from '../../providers/MultiProvider.js';
9
+ import { randomAddress, randomInt } from '../../test/testUtils.js';
10
+ import { getContractCreationBlockFromRpc, getLogsFromRpc } from './utils.js';
11
+ chai.use(chaiAsPromised);
12
+ describe('RPC Utils', () => {
13
+ let contractOwner;
14
+ let tokenRecipient1;
15
+ let tokenRecipient2;
16
+ let providerChainTest1;
17
+ let multiProvider;
18
+ let testContract;
19
+ let erc20Factory;
20
+ let deploymentBlockNumber;
21
+ const transferTopic = ethers.utils.id('Transfer(address,address,uint256)');
22
+ beforeEach(async () => {
23
+ [contractOwner, tokenRecipient1, tokenRecipient2] =
24
+ await hre.ethers.getSigners();
25
+ assert(contractOwner.provider, 'Expected provider to be defined on the signer');
26
+ // Initialize MultiProvider with test chain
27
+ multiProvider = MultiProvider.createTestMultiProvider({
28
+ signer: contractOwner,
29
+ provider: contractOwner.provider,
30
+ });
31
+ providerChainTest1 = contractOwner.provider;
32
+ // Get contract factory for ERC20Test
33
+ erc20Factory = new ERC20Test__factory(contractOwner);
34
+ });
35
+ async function deployTestErc20() {
36
+ testContract = await erc20Factory.deploy('TestToken', 'TST', ethers.utils.parseEther('1000000'), 18);
37
+ await testContract.deployed();
38
+ assert(testContract.deployTransaction.blockNumber, 'Expected the Contract deployment block number to be defined');
39
+ deploymentBlockNumber = testContract.deployTransaction.blockNumber;
40
+ }
41
+ async function mineRandomNumberOfBlocks() {
42
+ const blocksToMine = randomInt(69, 420);
43
+ for (let blockNum = 0; blockNum < blocksToMine; blockNum++) {
44
+ await providerChainTest1.send('evm_mine', []);
45
+ }
46
+ }
47
+ describe(getContractCreationBlockFromRpc.name, () => {
48
+ it('should find the correct deployment block for a deployed contract', async () => {
49
+ await mineRandomNumberOfBlocks();
50
+ await deployTestErc20();
51
+ await mineRandomNumberOfBlocks();
52
+ const foundBlock = await getContractCreationBlockFromRpc(TestChainName.test1, testContract.address, multiProvider);
53
+ expect(foundBlock).to.equal(deploymentBlockNumber);
54
+ const contractCode = await providerChainTest1.getCode(testContract.address);
55
+ expect(contractCode).not.to.equal('0x');
56
+ });
57
+ it('should throw an error for non-existing contract address', async () => {
58
+ const nonExistentAddress = randomAddress();
59
+ await expect(getContractCreationBlockFromRpc(TestChainName.test1, nonExistentAddress, multiProvider)).to.be.rejectedWith(`Address "${nonExistentAddress}" on chain "${TestChainName.test1}" is not a contract`);
60
+ });
61
+ });
62
+ describe(getLogsFromRpc.name, () => {
63
+ beforeEach(async () => {
64
+ await deployTestErc20();
65
+ });
66
+ it('should retrieve logs for Transfer events emitted by the contract', async () => {
67
+ // Emit some Transfer events
68
+ const tx1 = await testContract.transfer(tokenRecipient1.address, ethers.utils.parseEther('100'));
69
+ await tx1.wait();
70
+ const tx2 = await testContract.transfer(tokenRecipient2.address, ethers.utils.parseEther('200'));
71
+ await tx2.wait();
72
+ const logs = await getLogsFromRpc({
73
+ chain: TestChainName.test1,
74
+ contractAddress: testContract.address,
75
+ multiProvider,
76
+ fromBlock: deploymentBlockNumber,
77
+ topic: transferTopic,
78
+ });
79
+ // Should have 3 transfer events: 1 from constructor mint + 2 from transfers
80
+ expect(logs).to.have.length(3);
81
+ logs.forEach((log) => {
82
+ expect(log.address).to.equal(testContract.address);
83
+ expect(log.topics[0]).to.equal(transferTopic);
84
+ });
85
+ });
86
+ it('should work when fromBlock and toBlock are provided', async () => {
87
+ await mineRandomNumberOfBlocks();
88
+ const startBlock = await providerChainTest1.getBlockNumber();
89
+ // Emit event in first block
90
+ const tx1 = await testContract.transfer(tokenRecipient1.address, ethers.utils.parseEther('100'));
91
+ await tx1.wait();
92
+ const firstEventBlock = await providerChainTest1.getBlockNumber();
93
+ await mineRandomNumberOfBlocks();
94
+ // Emit event in later block
95
+ const tx2 = await testContract.transfer(tokenRecipient1.address, ethers.utils.parseEther('200'));
96
+ await tx2.wait();
97
+ // Query only the first event's block range
98
+ const logs = await getLogsFromRpc({
99
+ chain: TestChainName.test1,
100
+ contractAddress: testContract.address,
101
+ multiProvider,
102
+ fromBlock: startBlock,
103
+ toBlock: firstEventBlock,
104
+ topic: transferTopic,
105
+ });
106
+ expect(logs).to.have.length(1);
107
+ expect(logs[0].blockNumber).to.equal(firstEventBlock);
108
+ });
109
+ it('should work when a custom range parameter is provided', async () => {
110
+ const numberOfEventsToEmit = randomInt(1, 47);
111
+ for (let i = 0; i < numberOfEventsToEmit; i++) {
112
+ const tx = await testContract.mint(ethers.utils.parseEther(`${(i + 1) * 100}`));
113
+ await tx.wait();
114
+ }
115
+ // +1 because of the transfer event emitted on contract deployment
116
+ const expectedNumberOfEvents = numberOfEventsToEmit + 1;
117
+ const logs = await getLogsFromRpc({
118
+ chain: TestChainName.test1,
119
+ contractAddress: testContract.address,
120
+ multiProvider,
121
+ fromBlock: deploymentBlockNumber,
122
+ topic: transferTopic,
123
+ // Small range to test chunking
124
+ range: 2,
125
+ });
126
+ expect(logs).to.have.length(expectedNumberOfEvents);
127
+ });
128
+ it('should return empty array when no logs match the criteria', async () => {
129
+ // Emitting an event just to be sure that filtering works as expected
130
+ const tx1 = await testContract.transfer(tokenRecipient1.address, ethers.utils.parseEther('100'));
131
+ await tx1.wait();
132
+ const nonExistentTopic = ethers.utils.id('NonExistentEvent(uint256)');
133
+ const logs = await getLogsFromRpc({
134
+ chain: TestChainName.test1,
135
+ contractAddress: testContract.address,
136
+ multiProvider,
137
+ fromBlock: deploymentBlockNumber,
138
+ topic: nonExistentTopic,
139
+ });
140
+ expect(logs).to.have.length(0);
141
+ });
142
+ });
143
+ });
144
+ //# sourceMappingURL=utils.hardhat-test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.hardhat-test.js","sourceRoot":"","sources":["../../../src/rpc/evm/utils.hardhat-test.ts"],"names":[],"mappings":"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"}