@subql/node-starknet 6.0.2-0 → 6.0.3-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 (41) hide show
  1. package/CHANGELOG.md +6 -1
  2. package/dist/.tsbuildinfo +1 -1
  3. package/dist/blockchain.service.js.map +1 -1
  4. package/dist/indexer/types.js +1 -1
  5. package/dist/indexer/types.js.map +1 -1
  6. package/dist/starknet/api.starknet.d.ts +1 -1
  7. package/dist/starknet/api.starknet.js +1 -6
  8. package/dist/starknet/api.starknet.js.map +1 -1
  9. package/dist/starknet/decodeCalldata.d.ts +1 -1
  10. package/dist/starknet/decodeCalldata.js.map +1 -1
  11. package/dist/starknet/finalized.block.starknet.d.ts +1 -1
  12. package/dist/starknet/finalized.block.starknet.js.map +1 -1
  13. package/dist/starknet/safe-api.d.ts +4 -5
  14. package/dist/starknet/safe-api.js.map +1 -1
  15. package/dist/starknet/utils.starknet.d.ts +3 -2
  16. package/dist/starknet/utils.starknet.js +7 -2
  17. package/dist/starknet/utils.starknet.js.map +1 -1
  18. package/package.json +16 -6
  19. package/test/projectFixture/template-v1.0.0/package.json +30 -0
  20. package/test/projectFixture/v1.0.0/package.json +30 -0
  21. package/dist/blockchain.service.spec.d.ts +0 -1
  22. package/dist/blockchain.service.spec.js +0 -27
  23. package/dist/blockchain.service.spec.js.map +0 -1
  24. package/dist/indexer/dictionary/v1/starknetDictionaryV1.spec.d.ts +0 -1
  25. package/dist/indexer/dictionary/v1/starknetDictionaryV1.spec.js +0 -189
  26. package/dist/indexer/dictionary/v1/starknetDictionaryV1.spec.js.map +0 -1
  27. package/dist/starknet/api.service.starknet.spec.d.ts +0 -1
  28. package/dist/starknet/api.service.starknet.spec.js +0 -79
  29. package/dist/starknet/api.service.starknet.spec.js.map +0 -1
  30. package/dist/starknet/api.starknet.test.d.ts +0 -1
  31. package/dist/starknet/api.starknet.test.js +0 -183
  32. package/dist/starknet/api.starknet.test.js.map +0 -1
  33. package/dist/starknet/block.starknet.spec.d.ts +0 -1
  34. package/dist/starknet/block.starknet.spec.js +0 -158
  35. package/dist/starknet/block.starknet.spec.js.map +0 -1
  36. package/dist/starknet/decodeCalldata.spec.d.ts +0 -1
  37. package/dist/starknet/decodeCalldata.spec.js +0 -112
  38. package/dist/starknet/decodeCalldata.spec.js.map +0 -1
  39. package/dist/starknet/finalized.block.starknet.spec.d.ts +0 -1
  40. package/dist/starknet/finalized.block.starknet.spec.js +0 -112
  41. package/dist/starknet/finalized.block.starknet.spec.js.map +0 -1
@@ -1,158 +0,0 @@
1
- "use strict";
2
- // Copyright 2020-2025 SubQuery Pte Ltd authors & contributors
3
- // SPDX-License-Identifier: GPL-3.0
4
- Object.defineProperty(exports, "__esModule", { value: true });
5
- const event_emitter_1 = require("@nestjs/event-emitter");
6
- const api_starknet_1 = require("./api.starknet");
7
- const block_starknet_1 = require("./block.starknet");
8
- const utils_starknet_1 = require("./utils.starknet");
9
- const HTTP_ENDPOINT = 'https://free-rpc.nethermind.io/mainnet-juno/v0_7';
10
- jest.setTimeout(100000);
11
- describe('block filters', () => {
12
- let strkApi;
13
- const eventEmitter = new event_emitter_1.EventEmitter2();
14
- const fetchBlock = async (height) => {
15
- const block = await strkApi.fetchBlock(height);
16
- return block.block;
17
- };
18
- beforeAll(async () => {
19
- strkApi = new api_starknet_1.StarknetApi(HTTP_ENDPOINT, eventEmitter);
20
- await strkApi.init();
21
- });
22
- describe('Filter transactions', () => {
23
- it('filter with invoke tx', async () => {
24
- // https://starkscan.co/tx/0x00b3173b7a65b32fc8669da8f4676a7ef10c6f58ddd3159db7c0cd3de1025443
25
- const block = await fetchBlock(986480);
26
- const tx = block.transactions.find((tx) => tx.hash ===
27
- '0xb3173b7a65b32fc8669da8f4676a7ef10c6f58ddd3159db7c0cd3de1025443');
28
- // Filter by address
29
- expect((0, block_starknet_1.filterTransactionsProcessor)(tx, {
30
- type: 'INVOKE',
31
- // StarkGate: STRK Token Transfer
32
- function: '0x83afd3f4caedc6eebf44246fe54e38c95e3179a5ec9ea81740eca5b482d12e',
33
- }, '0x0xxxxx')).toBeFalsy();
34
- expect((0, block_starknet_1.filterTransactionsProcessor)(tx, {
35
- type: 'INVOKE',
36
- }, '0x04718f5a0fc34cc1af16a1cdee98ffb20c31f5cd61d6ab07201858f4287c938d')).toBeTruthy();
37
- // Expect filtered match transaction will attach will decodedCalls
38
- expect(tx.decodedCalls?.length).toBe(4);
39
- // filter function selector with both text and hex
40
- expect((0, block_starknet_1.filterTransactionsProcessor)(tx, {
41
- function: 'approve',
42
- }, '0x04718f5a0fc34cc1af16a1cdee98ffb20c31f5cd61d6ab07201858f4287c938d')).toBeFalsy();
43
- expect((0, block_starknet_1.filterTransactionsProcessor)(tx, {
44
- function: '0x83afd3f4caedc6eebf44246fe54e38c95e3179a5ec9ea81740eca5b482d12e',
45
- }, '0x04718f5a0fc34cc1af16a1cdee98ffb20c31f5cd61d6ab07201858f4287c938d')).toBeTruthy();
46
- expect((0, block_starknet_1.filterTransactionsProcessor)(tx, {
47
- function: 'transfer',
48
- }, '0x04718f5a0fc34cc1af16a1cdee98ffb20c31f5cd61d6ab07201858f4287c938d')).toBeTruthy();
49
- //Filter with "to"
50
- expect((0, block_starknet_1.filterTransactionsProcessor)(tx, {
51
- to: '0x04718f5a0fc34cc1af16a1cdee98ffb20c31f5cd61d6ab07201858f4287c938d',
52
- })).toBeTruthy();
53
- expect((0, block_starknet_1.filterTransactionsProcessor)(tx, {
54
- to: '0x047aaaaad',
55
- })).toBeFalsy();
56
- //Filter with function is "null"
57
- expect((0, block_starknet_1.filterTransactionsProcessor)(tx, {
58
- function: null,
59
- })).toBeFalsy();
60
- //Filter with to is "null"
61
- expect((0, block_starknet_1.filterTransactionsProcessor)(tx, {
62
- to: null,
63
- })).toBeFalsy();
64
- });
65
- it('filter with tx function or to is null', () => {
66
- const mockTx1 = {
67
- calldata: ['0xmock', null],
68
- parseCallData: jest.fn(),
69
- };
70
- //Filter with function is "null"
71
- expect((0, block_starknet_1.filterTransactionsProcessor)(mockTx1, {
72
- function: null,
73
- })).toBeTruthy();
74
- //Filter with to is "null"
75
- expect((0, block_starknet_1.filterTransactionsProcessor)(mockTx1, {
76
- to: null,
77
- })).toBeTruthy();
78
- // test with decode calls
79
- const mockTx2 = {
80
- parseCallData: () => {
81
- return [{ to: null, selector: null, calldata: [] }];
82
- },
83
- };
84
- //Filter with function is "null"
85
- expect((0, block_starknet_1.filterTransactionsProcessor)(mockTx2, {
86
- function: null,
87
- })).toBeTruthy();
88
- //Filter with to is "null"
89
- expect((0, block_starknet_1.filterTransactionsProcessor)(mockTx2, {
90
- to: null,
91
- })).toBeTruthy();
92
- });
93
- it('should filter tx with multiple conditions', async () => {
94
- const block_997058 = await fetchBlock(997058);
95
- // https://starkscan.co/tx/0x055588e82f864f830c4d1d1117e6e8d61a917ef18cf79961af001dc321d96cb3
96
- const txWithdraw = block_997058.transactions.find((tx) => tx.hash ===
97
- '0x55588e82f864f830c4d1d1117e6e8d61a917ef18cf79961af001dc321d96cb3');
98
- expect((0, block_starknet_1.filterTransactionsProcessor)(txWithdraw, {
99
- to: '0x04c0a5193d58f74fbace4b74dcf65481e734ed1714121bdc571da345540efa05',
100
- function: 'withdraw',
101
- type: 'INVOKE',
102
- })).toBeTruthy();
103
- expect((0, block_starknet_1.filterTransactionsProcessor)(txWithdraw, {
104
- to: '0x04c0a5193d58f74fbace4b74dcf65481e734ed1714121bdc571da345540efa05',
105
- function: '0x015511cc3694f64379908437d6d64458dc76d02482052bfb8a5b33a72c054c77', // with extra 0 padding
106
- type: 'INVOKE',
107
- })).toBeTruthy();
108
- });
109
- it('decodeCalls only on filtered tx', async () => {
110
- // https://starkscan.co/tx/0x00b3173b7a65b32fc8669da8f4676a7ef10c6f58ddd3159db7c0cd3de1025443
111
- const block = await fetchBlock(986480);
112
- const tx = block.transactions.find((tx) => tx.hash ===
113
- '0xb3173b7a65b32fc8669da8f4676a7ef10c6f58ddd3159db7c0cd3de1025443');
114
- // Filter should be failed, and it should not decode calls
115
- expect((0, block_starknet_1.filterTransactionsProcessor)(tx, {
116
- type: 'INVOKE',
117
- function: 'mockFn',
118
- }, '0x0xxxxx')).toBeFalsy();
119
- expect(tx.decodedCalls).toBeUndefined();
120
- });
121
- it('filter L1 / Invoke v0 transaction', async () => {
122
- // https://starkscan.co/tx/0x043ce8e6e2ad703a81701f85ce26a8fb32ad54cc2fac7685ed0b1367a4813ade
123
- const block = await fetchBlock(981920);
124
- const tx = block.transactions.find((tx) => (0, utils_starknet_1.hexEq)(tx.hash, '0x043ce8e6e2ad703a81701f85ce26a8fb32ad54cc2fac7685ed0b1367a4813ade'));
125
- // Filter by address
126
- expect((0, block_starknet_1.filterTransactionsProcessor)(tx, {
127
- type: 'L1_HANDLER',
128
- }, '0x073314940630fd6dcda0d772d4c972c4e0a9946bef9dabf4ef84eda8ef542b82')).toBeTruthy();
129
- // Filter by Selector
130
- expect((0, block_starknet_1.filterTransactionsProcessor)(tx, {
131
- function: '0x01b64b1b3b690b43b9b514fb81377518f4039cd3e4f4914d8a6bdf01d679fb19',
132
- }, '0x073314940630fd6dcda0d772d4c972c4e0a9946bef9dabf4ef84eda8ef542b82')).toBeTruthy();
133
- });
134
- });
135
- describe('Filter logs', () => {
136
- it('filter events with plain text also hex', async () => {
137
- // https://starkscan.co/tx/0x04b546ff4375c16c30c03bd92d2d9082041e5e9397f5bda4f832661d6c029655#events
138
- const block = await fetchBlock(986480);
139
- const testLog = block.logs[2];
140
- expect(testLog.transaction.hash).toEqual('0x4b546ff4375c16c30c03bd92d2d9082041e5e9397f5bda4f832661d6c029655');
141
- // Filter with "address"
142
- expect((0, block_starknet_1.filterLogsProcessor)(block.logs[2], {}, '0x06a9e4c6f0799160ea8ddc43ff982a5f83d7f633e9732ce42701de1288ff705f')).toBeTruthy();
143
- expect((0, block_starknet_1.filterLogsProcessor)(block.logs[2], {
144
- topics: ['Transfer'],
145
- })).toBeFalsy();
146
- // Event name can be in plain text or hex
147
- expect((0, block_starknet_1.filterLogsProcessor)(block.logs[2], {
148
- topics: [
149
- '0x1a2f334228cee715f1f0f54053bb6b5eac54fa336e0bc1aacf7516decb0471d',
150
- ],
151
- })).toBeTruthy();
152
- expect((0, block_starknet_1.filterLogsProcessor)(block.logs[2], {
153
- topics: ['StoreSetRecord'],
154
- })).toBeTruthy();
155
- });
156
- });
157
- });
158
- //# sourceMappingURL=block.starknet.spec.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"block.starknet.spec.js","sourceRoot":"","sources":["../../src/starknet/block.starknet.spec.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2020-2025 SubQuery Pte Ltd authors & contributors\n// SPDX-License-Identifier: GPL-3.0\n\nimport { EventEmitter2 } from '@nestjs/event-emitter';\nimport { StarknetBlock, StarknetTransaction } from '@subql/types-starknet';\nimport { StarknetApi } from './api.starknet';\nimport {\n filterLogsProcessor,\n filterTransactionsProcessor,\n} from './block.starknet';\nimport { hexEq } from './utils.starknet';\n\nconst HTTP_ENDPOINT = 'https://free-rpc.nethermind.io/mainnet-juno/v0_7';\n\njest.setTimeout(100000);\n\ndescribe('block filters', () => {\n let strkApi: StarknetApi;\n const eventEmitter = new EventEmitter2();\n\n const fetchBlock = async (height: number) => {\n const block = await strkApi.fetchBlock(height);\n\n return block.block as StarknetBlock;\n };\n\n beforeAll(async () => {\n strkApi = new StarknetApi(HTTP_ENDPOINT, eventEmitter);\n await strkApi.init();\n });\n\n describe('Filter transactions', () => {\n it('filter with invoke tx', async () => {\n // https://starkscan.co/tx/0x00b3173b7a65b32fc8669da8f4676a7ef10c6f58ddd3159db7c0cd3de1025443\n const block = await fetchBlock(986480);\n const tx = block.transactions.find(\n (tx) =>\n tx.hash ===\n '0xb3173b7a65b32fc8669da8f4676a7ef10c6f58ddd3159db7c0cd3de1025443',\n );\n // Filter by address\n expect(\n filterTransactionsProcessor(\n tx!,\n {\n type: 'INVOKE',\n // StarkGate: STRK Token Transfer\n function:\n '0x83afd3f4caedc6eebf44246fe54e38c95e3179a5ec9ea81740eca5b482d12e',\n },\n '0x0xxxxx',\n ),\n ).toBeFalsy();\n\n expect(\n filterTransactionsProcessor(\n tx!,\n {\n type: 'INVOKE',\n },\n '0x04718f5a0fc34cc1af16a1cdee98ffb20c31f5cd61d6ab07201858f4287c938d',\n ),\n ).toBeTruthy();\n\n // Expect filtered match transaction will attach will decodedCalls\n expect(tx!.decodedCalls?.length).toBe(4);\n\n // filter function selector with both text and hex\n expect(\n filterTransactionsProcessor(\n tx!,\n {\n function: 'approve',\n },\n '0x04718f5a0fc34cc1af16a1cdee98ffb20c31f5cd61d6ab07201858f4287c938d',\n ),\n ).toBeFalsy();\n\n expect(\n filterTransactionsProcessor(\n tx!,\n {\n function:\n '0x83afd3f4caedc6eebf44246fe54e38c95e3179a5ec9ea81740eca5b482d12e',\n },\n '0x04718f5a0fc34cc1af16a1cdee98ffb20c31f5cd61d6ab07201858f4287c938d',\n ),\n ).toBeTruthy();\n\n expect(\n filterTransactionsProcessor(\n tx!,\n {\n function: 'transfer',\n },\n '0x04718f5a0fc34cc1af16a1cdee98ffb20c31f5cd61d6ab07201858f4287c938d',\n ),\n ).toBeTruthy();\n\n //Filter with \"to\"\n expect(\n filterTransactionsProcessor(tx!, {\n to: '0x04718f5a0fc34cc1af16a1cdee98ffb20c31f5cd61d6ab07201858f4287c938d',\n }),\n ).toBeTruthy();\n\n expect(\n filterTransactionsProcessor(tx!, {\n to: '0x047aaaaad',\n }),\n ).toBeFalsy();\n\n //Filter with function is \"null\"\n expect(\n filterTransactionsProcessor(tx!, {\n function: null,\n }),\n ).toBeFalsy();\n\n //Filter with to is \"null\"\n expect(\n filterTransactionsProcessor(tx!, {\n to: null,\n }),\n ).toBeFalsy();\n });\n\n it('filter with tx function or to is null', () => {\n const mockTx1 = {\n calldata: ['0xmock', null],\n parseCallData: jest.fn(),\n } as unknown as StarknetTransaction;\n //Filter with function is \"null\"\n expect(\n filterTransactionsProcessor(mockTx1, {\n function: null,\n }),\n ).toBeTruthy();\n\n //Filter with to is \"null\"\n expect(\n filterTransactionsProcessor(mockTx1, {\n to: null,\n }),\n ).toBeTruthy();\n\n // test with decode calls\n const mockTx2 = {\n parseCallData: () => {\n return [{ to: null, selector: null, calldata: [] }];\n },\n } as unknown as StarknetTransaction;\n\n //Filter with function is \"null\"\n expect(\n filterTransactionsProcessor(mockTx2, {\n function: null,\n }),\n ).toBeTruthy();\n\n //Filter with to is \"null\"\n expect(\n filterTransactionsProcessor(mockTx2, {\n to: null,\n }),\n ).toBeTruthy();\n });\n\n it('should filter tx with multiple conditions', async () => {\n const block_997058 = await fetchBlock(997058);\n // https://starkscan.co/tx/0x055588e82f864f830c4d1d1117e6e8d61a917ef18cf79961af001dc321d96cb3\n const txWithdraw = block_997058.transactions.find(\n (tx) =>\n tx.hash ===\n '0x55588e82f864f830c4d1d1117e6e8d61a917ef18cf79961af001dc321d96cb3',\n );\n expect(\n filterTransactionsProcessor(txWithdraw!, {\n to: '0x04c0a5193d58f74fbace4b74dcf65481e734ed1714121bdc571da345540efa05',\n function: 'withdraw',\n type: 'INVOKE',\n }),\n ).toBeTruthy();\n\n expect(\n filterTransactionsProcessor(txWithdraw!, {\n to: '0x04c0a5193d58f74fbace4b74dcf65481e734ed1714121bdc571da345540efa05',\n function:\n '0x015511cc3694f64379908437d6d64458dc76d02482052bfb8a5b33a72c054c77', // with extra 0 padding\n type: 'INVOKE',\n }),\n ).toBeTruthy();\n });\n\n it('decodeCalls only on filtered tx', async () => {\n // https://starkscan.co/tx/0x00b3173b7a65b32fc8669da8f4676a7ef10c6f58ddd3159db7c0cd3de1025443\n const block = await fetchBlock(986480);\n const tx = block.transactions.find(\n (tx) =>\n tx.hash ===\n '0xb3173b7a65b32fc8669da8f4676a7ef10c6f58ddd3159db7c0cd3de1025443',\n );\n // Filter should be failed, and it should not decode calls\n expect(\n filterTransactionsProcessor(\n tx!,\n {\n type: 'INVOKE',\n function: 'mockFn',\n },\n '0x0xxxxx',\n ),\n ).toBeFalsy();\n\n expect(tx!.decodedCalls).toBeUndefined();\n });\n\n it('filter L1 / Invoke v0 transaction', async () => {\n // https://starkscan.co/tx/0x043ce8e6e2ad703a81701f85ce26a8fb32ad54cc2fac7685ed0b1367a4813ade\n const block = await fetchBlock(981920);\n const tx = block.transactions.find((tx) =>\n hexEq(\n tx.hash,\n '0x043ce8e6e2ad703a81701f85ce26a8fb32ad54cc2fac7685ed0b1367a4813ade',\n ),\n );\n\n // Filter by address\n expect(\n filterTransactionsProcessor(\n tx!,\n {\n type: 'L1_HANDLER',\n },\n '0x073314940630fd6dcda0d772d4c972c4e0a9946bef9dabf4ef84eda8ef542b82',\n ),\n ).toBeTruthy();\n\n // Filter by Selector\n expect(\n filterTransactionsProcessor(\n tx!,\n {\n function:\n '0x01b64b1b3b690b43b9b514fb81377518f4039cd3e4f4914d8a6bdf01d679fb19',\n },\n '0x073314940630fd6dcda0d772d4c972c4e0a9946bef9dabf4ef84eda8ef542b82',\n ),\n ).toBeTruthy();\n });\n });\n\n describe('Filter logs', () => {\n it('filter events with plain text also hex', async () => {\n // https://starkscan.co/tx/0x04b546ff4375c16c30c03bd92d2d9082041e5e9397f5bda4f832661d6c029655#events\n const block = await fetchBlock(986480);\n\n const testLog = block.logs[2]!;\n expect(testLog.transaction.hash).toEqual(\n '0x4b546ff4375c16c30c03bd92d2d9082041e5e9397f5bda4f832661d6c029655',\n );\n // Filter with \"address\"\n expect(\n filterLogsProcessor(\n block.logs[2]!,\n {},\n '0x06a9e4c6f0799160ea8ddc43ff982a5f83d7f633e9732ce42701de1288ff705f',\n ),\n ).toBeTruthy();\n\n expect(\n filterLogsProcessor(block.logs[2]!, {\n topics: ['Transfer'],\n }),\n ).toBeFalsy();\n\n // Event name can be in plain text or hex\n expect(\n filterLogsProcessor(block.logs[2]!, {\n topics: [\n '0x1a2f334228cee715f1f0f54053bb6b5eac54fa336e0bc1aacf7516decb0471d',\n ],\n }),\n ).toBeTruthy();\n\n expect(\n filterLogsProcessor(block.logs[2]!, {\n topics: ['StoreSetRecord'],\n }),\n ).toBeTruthy();\n });\n });\n});\n"]}
@@ -1 +0,0 @@
1
- export {};
@@ -1,112 +0,0 @@
1
- "use strict";
2
- // Copyright 2020-2025 SubQuery Pte Ltd authors & contributors
3
- // SPDX-License-Identifier: GPL-3.0
4
- Object.defineProperty(exports, "__esModule", { value: true });
5
- const decodeCalldata_1 = require("./decodeCalldata");
6
- describe('decode', () => {
7
- // From https://starkscan.co/tx/0x06b8627ba886d457d32cc5a2ef0cc99741fc67b1142ce3f180a29b817b6f5f33
8
- test('should decode legacy calldata correctly', () => {
9
- const calldata = [
10
- '0x3',
11
- '0x49d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7',
12
- '0x219209e083275171774dab1df80982e9df2096516f06319c5c6d71ae0a8480c',
13
- '0x0',
14
- '0x3',
15
- '0x4c0a5193d58f74fbace4b74dcf65481e734ed1714121bdc571da345540efa05',
16
- '0xc73f681176fc7b3f9693986fd7b14581e8d540519e27400e88b8713932be01',
17
- '0x3',
18
- '0x2',
19
- '0x4c0a5193d58f74fbace4b74dcf65481e734ed1714121bdc571da345540efa05',
20
- '0x271680756697a04d1447ad4c21d53bdf15966bdc5b78bd52d4fc2153aa76bda',
21
- '0x5',
22
- '0x1',
23
- '0x6',
24
- '0x4c0a5193d58f74fbace4b74dcf65481e734ed1714121bdc571da345540efa05',
25
- '0x738a4f05910',
26
- '0x0',
27
- '0x49d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7',
28
- '0x738a4f05910',
29
- '0x49d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7',
30
- ];
31
- const decoded = (0, decodeCalldata_1.decodeInvokeCalldata)(calldata);
32
- expect(decoded).toEqual([
33
- {
34
- calldata: [
35
- '0x4c0a5193d58f74fbace4b74dcf65481e734ed1714121bdc571da345540efa05',
36
- '0x738a4f05910',
37
- '0x0',
38
- ],
39
- selector: '0x219209e083275171774dab1df80982e9df2096516f06319c5c6d71ae0a8480c',
40
- to: '0x49d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7',
41
- },
42
- {
43
- calldata: [
44
- '0x49d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7',
45
- '0x738a4f05910',
46
- ],
47
- selector: '0xc73f681176fc7b3f9693986fd7b14581e8d540519e27400e88b8713932be01',
48
- to: '0x4c0a5193d58f74fbace4b74dcf65481e734ed1714121bdc571da345540efa05',
49
- },
50
- {
51
- calldata: [
52
- '0x49d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7',
53
- ],
54
- selector: '0x271680756697a04d1447ad4c21d53bdf15966bdc5b78bd52d4fc2153aa76bda',
55
- to: '0x4c0a5193d58f74fbace4b74dcf65481e734ed1714121bdc571da345540efa05',
56
- },
57
- ]);
58
- });
59
- // From https://starkscan.co/tx/0x06a031ca9916acc3a3723f2f15c2a0c32e756c887b33271d914b1309f57be0f0
60
- test('should decode new calldata correctly', () => {
61
- const calldata = [
62
- '0x3',
63
- '0x49d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7',
64
- '0x219209e083275171774dab1df80982e9df2096516f06319c5c6d71ae0a8480c',
65
- '0x3',
66
- '0x4c0a5193d58f74fbace4b74dcf65481e734ed1714121bdc571da345540efa05',
67
- '0x1dccd9ffaff50',
68
- '0x0',
69
- '0x4c0a5193d58f74fbace4b74dcf65481e734ed1714121bdc571da345540efa05',
70
- '0xc73f681176fc7b3f9693986fd7b14581e8d540519e27400e88b8713932be01',
71
- '0x2',
72
- '0x49d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7',
73
- '0x1dccd9ffaff50',
74
- '0x4c0a5193d58f74fbace4b74dcf65481e734ed1714121bdc571da345540efa05',
75
- '0x271680756697a04d1447ad4c21d53bdf15966bdc5b78bd52d4fc2153aa76bda',
76
- '0x1',
77
- '0x49d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7',
78
- ];
79
- const decoded = (0, decodeCalldata_1.decodeInvokeCalldata)(calldata);
80
- expect(decoded).toEqual([
81
- {
82
- calldata: [
83
- '0x4c0a5193d58f74fbace4b74dcf65481e734ed1714121bdc571da345540efa05',
84
- '0x1dccd9ffaff50',
85
- '0x0',
86
- ],
87
- selector: '0x219209e083275171774dab1df80982e9df2096516f06319c5c6d71ae0a8480c',
88
- to: '0x49d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7',
89
- },
90
- {
91
- calldata: [
92
- '0x49d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7',
93
- '0x1dccd9ffaff50',
94
- ],
95
- selector: '0xc73f681176fc7b3f9693986fd7b14581e8d540519e27400e88b8713932be01',
96
- to: '0x4c0a5193d58f74fbace4b74dcf65481e734ed1714121bdc571da345540efa05',
97
- },
98
- {
99
- calldata: [
100
- '0x49d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7',
101
- ],
102
- selector: '0x271680756697a04d1447ad4c21d53bdf15966bdc5b78bd52d4fc2153aa76bda',
103
- to: '0x4c0a5193d58f74fbace4b74dcf65481e734ed1714121bdc571da345540efa05',
104
- },
105
- ]);
106
- });
107
- test('should throw DecodeCalldataError for invalid calldata', () => {
108
- const invalidCalldata = ['0x1', 'invalid_field_element'];
109
- expect(() => (0, decodeCalldata_1.decodeInvokeCalldata)(invalidCalldata)).toThrow(decodeCalldata_1.DecodeCalldataError);
110
- });
111
- });
112
- //# sourceMappingURL=decodeCalldata.spec.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"decodeCalldata.spec.js","sourceRoot":"","sources":["../../src/starknet/decodeCalldata.spec.ts"],"names":[],"mappings":";AAAA,8DAA8D;AAC9D,mCAAmC;;AAEnC,qDAA6E;AAE7E,QAAQ,CAAC,QAAQ,EAAE,GAAG,EAAE;IACtB,kGAAkG;IAClG,IAAI,CAAC,yCAAyC,EAAE,GAAG,EAAE;QACnD,MAAM,QAAQ,GAAG;YACf,KAAK;YACL,mEAAmE;YACnE,mEAAmE;YACnE,KAAK;YACL,KAAK;YACL,mEAAmE;YACnE,kEAAkE;YAClE,KAAK;YACL,KAAK;YACL,mEAAmE;YACnE,mEAAmE;YACnE,KAAK;YACL,KAAK;YACL,KAAK;YACL,mEAAmE;YACnE,eAAe;YACf,KAAK;YACL,mEAAmE;YACnE,eAAe;YACf,mEAAmE;SACpE,CAAC;QAEF,MAAM,OAAO,GAAG,IAAA,qCAAoB,EAAC,QAAQ,CAAC,CAAC;QAE/C,MAAM,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC;YACtB;gBACE,QAAQ,EAAE;oBACR,mEAAmE;oBACnE,eAAe;oBACf,KAAK;iBACN;gBACD,QAAQ,EACN,mEAAmE;gBACrE,EAAE,EAAE,mEAAmE;aACxE;YACD;gBACE,QAAQ,EAAE;oBACR,mEAAmE;oBACnE,eAAe;iBAChB;gBACD,QAAQ,EACN,kEAAkE;gBACpE,EAAE,EAAE,mEAAmE;aACxE;YACD;gBACE,QAAQ,EAAE;oBACR,mEAAmE;iBACpE;gBACD,QAAQ,EACN,mEAAmE;gBACrE,EAAE,EAAE,mEAAmE;aACxE;SACF,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,kGAAkG;IAClG,IAAI,CAAC,sCAAsC,EAAE,GAAG,EAAE;QAChD,MAAM,QAAQ,GAAG;YACf,KAAK;YACL,mEAAmE;YACnE,mEAAmE;YACnE,KAAK;YACL,mEAAmE;YACnE,iBAAiB;YACjB,KAAK;YACL,mEAAmE;YACnE,kEAAkE;YAClE,KAAK;YACL,mEAAmE;YACnE,iBAAiB;YACjB,mEAAmE;YACnE,mEAAmE;YACnE,KAAK;YACL,mEAAmE;SACpE,CAAC;QAEF,MAAM,OAAO,GAAG,IAAA,qCAAoB,EAAC,QAAQ,CAAC,CAAC;QAE/C,MAAM,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC;YACtB;gBACE,QAAQ,EAAE;oBACR,mEAAmE;oBACnE,iBAAiB;oBACjB,KAAK;iBACN;gBACD,QAAQ,EACN,mEAAmE;gBACrE,EAAE,EAAE,mEAAmE;aACxE;YACD;gBACE,QAAQ,EAAE;oBACR,mEAAmE;oBACnE,iBAAiB;iBAClB;gBACD,QAAQ,EACN,kEAAkE;gBACpE,EAAE,EAAE,mEAAmE;aACxE;YACD;gBACE,QAAQ,EAAE;oBACR,mEAAmE;iBACpE;gBACD,QAAQ,EACN,mEAAmE;gBACrE,EAAE,EAAE,mEAAmE;aACxE;SACF,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,uDAAuD,EAAE,GAAG,EAAE;QACjE,MAAM,eAAe,GAAG,CAAC,KAAK,EAAE,uBAAuB,CAAC,CAAC;QACzD,MAAM,CAAC,GAAG,EAAE,CAAC,IAAA,qCAAoB,EAAC,eAAe,CAAC,CAAC,CAAC,OAAO,CACzD,oCAAmB,CACpB,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["// Copyright 2020-2025 SubQuery Pte Ltd authors & contributors\n// SPDX-License-Identifier: GPL-3.0\n\nimport { decodeInvokeCalldata, DecodeCalldataError } from './decodeCalldata';\n\ndescribe('decode', () => {\n // From https://starkscan.co/tx/0x06b8627ba886d457d32cc5a2ef0cc99741fc67b1142ce3f180a29b817b6f5f33\n test('should decode legacy calldata correctly', () => {\n const calldata = [\n '0x3',\n '0x49d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7',\n '0x219209e083275171774dab1df80982e9df2096516f06319c5c6d71ae0a8480c',\n '0x0',\n '0x3',\n '0x4c0a5193d58f74fbace4b74dcf65481e734ed1714121bdc571da345540efa05',\n '0xc73f681176fc7b3f9693986fd7b14581e8d540519e27400e88b8713932be01',\n '0x3',\n '0x2',\n '0x4c0a5193d58f74fbace4b74dcf65481e734ed1714121bdc571da345540efa05',\n '0x271680756697a04d1447ad4c21d53bdf15966bdc5b78bd52d4fc2153aa76bda',\n '0x5',\n '0x1',\n '0x6',\n '0x4c0a5193d58f74fbace4b74dcf65481e734ed1714121bdc571da345540efa05',\n '0x738a4f05910',\n '0x0',\n '0x49d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7',\n '0x738a4f05910',\n '0x49d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7',\n ];\n\n const decoded = decodeInvokeCalldata(calldata);\n\n expect(decoded).toEqual([\n {\n calldata: [\n '0x4c0a5193d58f74fbace4b74dcf65481e734ed1714121bdc571da345540efa05',\n '0x738a4f05910',\n '0x0',\n ],\n selector:\n '0x219209e083275171774dab1df80982e9df2096516f06319c5c6d71ae0a8480c',\n to: '0x49d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7',\n },\n {\n calldata: [\n '0x49d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7',\n '0x738a4f05910',\n ],\n selector:\n '0xc73f681176fc7b3f9693986fd7b14581e8d540519e27400e88b8713932be01',\n to: '0x4c0a5193d58f74fbace4b74dcf65481e734ed1714121bdc571da345540efa05',\n },\n {\n calldata: [\n '0x49d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7',\n ],\n selector:\n '0x271680756697a04d1447ad4c21d53bdf15966bdc5b78bd52d4fc2153aa76bda',\n to: '0x4c0a5193d58f74fbace4b74dcf65481e734ed1714121bdc571da345540efa05',\n },\n ]);\n });\n\n // From https://starkscan.co/tx/0x06a031ca9916acc3a3723f2f15c2a0c32e756c887b33271d914b1309f57be0f0\n test('should decode new calldata correctly', () => {\n const calldata = [\n '0x3',\n '0x49d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7',\n '0x219209e083275171774dab1df80982e9df2096516f06319c5c6d71ae0a8480c',\n '0x3',\n '0x4c0a5193d58f74fbace4b74dcf65481e734ed1714121bdc571da345540efa05',\n '0x1dccd9ffaff50',\n '0x0',\n '0x4c0a5193d58f74fbace4b74dcf65481e734ed1714121bdc571da345540efa05',\n '0xc73f681176fc7b3f9693986fd7b14581e8d540519e27400e88b8713932be01',\n '0x2',\n '0x49d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7',\n '0x1dccd9ffaff50',\n '0x4c0a5193d58f74fbace4b74dcf65481e734ed1714121bdc571da345540efa05',\n '0x271680756697a04d1447ad4c21d53bdf15966bdc5b78bd52d4fc2153aa76bda',\n '0x1',\n '0x49d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7',\n ];\n\n const decoded = decodeInvokeCalldata(calldata);\n\n expect(decoded).toEqual([\n {\n calldata: [\n '0x4c0a5193d58f74fbace4b74dcf65481e734ed1714121bdc571da345540efa05',\n '0x1dccd9ffaff50',\n '0x0',\n ],\n selector:\n '0x219209e083275171774dab1df80982e9df2096516f06319c5c6d71ae0a8480c',\n to: '0x49d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7',\n },\n {\n calldata: [\n '0x49d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7',\n '0x1dccd9ffaff50',\n ],\n selector:\n '0xc73f681176fc7b3f9693986fd7b14581e8d540519e27400e88b8713932be01',\n to: '0x4c0a5193d58f74fbace4b74dcf65481e734ed1714121bdc571da345540efa05',\n },\n {\n calldata: [\n '0x49d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7',\n ],\n selector:\n '0x271680756697a04d1447ad4c21d53bdf15966bdc5b78bd52d4fc2153aa76bda',\n to: '0x4c0a5193d58f74fbace4b74dcf65481e734ed1714121bdc571da345540efa05',\n },\n ]);\n });\n\n test('should throw DecodeCalldataError for invalid calldata', () => {\n const invalidCalldata = ['0x1', 'invalid_field_element'];\n expect(() => decodeInvokeCalldata(invalidCalldata)).toThrow(\n DecodeCalldataError,\n );\n });\n});\n"]}
@@ -1 +0,0 @@
1
- export {};
@@ -1,112 +0,0 @@
1
- "use strict";
2
- // Copyright 2020-2025 SubQuery Pte Ltd authors & contributors
3
- // SPDX-License-Identifier: GPL-3.0
4
- var __importDefault = (this && this.__importDefault) || function (mod) {
5
- return (mod && mod.__esModule) ? mod : { "default": mod };
6
- };
7
- Object.defineProperty(exports, "__esModule", { value: true });
8
- const pino_1 = __importDefault(require("pino"));
9
- const finalized_block_starknet_1 = require("./finalized.block.starknet");
10
- const createMockBlock = (block_number, status) => ({
11
- block_number,
12
- status,
13
- block_hash: `0xabc${block_number}`,
14
- parent_hash: `0xparent${block_number - 1}`,
15
- new_root: `0xnewroot${block_number}`,
16
- timestamp: 1700000000 + block_number,
17
- sequencer_address: `0xsequencer${block_number}`,
18
- transactions: [],
19
- starknet_version: '',
20
- l1_da_mode: 'BLOB',
21
- l1_gas_price: { price_in_wei: '0', price_in_fri: '0' },
22
- l1_data_gas_price: { price_in_wei: '0', price_in_fri: '0' },
23
- });
24
- // **Mock blocks**
25
- const mockBlocks = {
26
- latest: createMockBlock(10, 'ACCEPTED_ON_L2'),
27
- 10: createMockBlock(10, 'ACCEPTED_ON_L2'),
28
- 9: createMockBlock(9, 'ACCEPTED_ON_L2'),
29
- 8: createMockBlock(8, 'ACCEPTED_ON_L2'),
30
- 7: createMockBlock(7, 'ACCEPTED_ON_L1'), // latest ACCEPTED_ON_L1
31
- 6: createMockBlock(6, 'ACCEPTED_ON_L1'),
32
- 5: createMockBlock(5, 'ACCEPTED_ON_L1'),
33
- 4: createMockBlock(4, 'ACCEPTED_ON_L1'),
34
- 3: createMockBlock(3, 'ACCEPTED_ON_L1'),
35
- 2: createMockBlock(2, 'ACCEPTED_ON_L1'),
36
- 1: createMockBlock(1, 'ACCEPTED_ON_L1'),
37
- 0: createMockBlock(0, 'ACCEPTED_ON_L1'),
38
- };
39
- const mockBlockService = {
40
- async getBlock(heightOrHash) {
41
- if (mockBlocks[heightOrHash] !== undefined) {
42
- return Promise.resolve(mockBlocks[heightOrHash]);
43
- }
44
- return Promise.reject(new Error(`Block ${heightOrHash} not found`));
45
- },
46
- };
47
- // **initialize logger**
48
- const mockLogger = (0, pino_1.default)({ level: 'debug' });
49
- describe('FinalizedBlockService', () => {
50
- let service;
51
- beforeEach(() => {
52
- service = new finalized_block_starknet_1.FinalizedBlockService(mockBlockService.getBlock, mockLogger);
53
- });
54
- // **Test 1: `findFirstAcceptedOnL1`**
55
- it('should find the first ACCEPTED_ON_L1 block', async () => {
56
- const result = await service.findFirstAcceptedOnL1();
57
- expect(result).toBeDefined();
58
- expect(result?.block_number).toBe(0);
59
- expect(result?.status).toBe('ACCEPTED_ON_L1');
60
- });
61
- // **Test 2: `binarySearchAcceptedOnL1`**
62
- it('should find the latest ACCEPTED_ON_L1 block via binary search', async () => {
63
- const result = await service.binarySearchAcceptedOnL1(1, 10);
64
- expect(result).toBeDefined();
65
- expect(result?.block_number).toBe(7);
66
- expect(result?.status).toBe('ACCEPTED_ON_L1');
67
- });
68
- // **Test 3: `getFinalizedBlock` - First call (initialize cache)**
69
- it('should initialize latestAcceptedBlock and return the correct block', async () => {
70
- const result = await service.getFinalizedBlock();
71
- expect(result).toBeDefined();
72
- expect(result.block_number).toBe(7);
73
- expect(result.status).toBe('ACCEPTED_ON_L1');
74
- });
75
- // **Test 4: `getFinalizedBlock` - Return cached block and verify `getBlock` is not called**
76
- it('should return cached block if next block remains ACCEPTED_ON_L2 and not call `getBlock`', async () => {
77
- const getBlockSpy = jest.spyOn(mockBlockService, 'getBlock');
78
- let result = await service.getFinalizedBlock(); // First call - initializes cache
79
- expect(result.block_number).toBe(7); // Should return cached block 3
80
- jest.clearAllMocks(); // Reset call count for the second invocation
81
- result = await service.getFinalizedBlock(); // Second call - should use cache
82
- expect(result).toBeDefined();
83
- expect(result.block_number).toBe(7); // Should return cached block 3
84
- expect(getBlockSpy).not.toHaveBeenCalled(); // Ensure `getBlock` was NOT called again
85
- });
86
- // **Test 5: `getFinalizedBlock` - Update when next block becomes L1**
87
- it('should update latestAcceptedBlock if next block changes to ACCEPTED_ON_L1', async () => {
88
- await service.getFinalizedBlock(); // Initialize cache
89
- mockBlocks[8].status = 'ACCEPTED_ON_L1'; // Change block 8 to L1
90
- const result = await service.getFinalizedBlock();
91
- expect(result).toBeDefined();
92
- expect(result.block_number).toBe(8); // Now should update to block 8
93
- });
94
- // No blocks are accepted on L1 with devnets
95
- it('works with devnet', async () => {
96
- const blocks = {
97
- latest: createMockBlock(4, 'ACCEPTED_ON_L2'),
98
- 4: createMockBlock(4, 'ACCEPTED_ON_L2'),
99
- 3: createMockBlock(3, 'ACCEPTED_ON_L2'),
100
- 2: createMockBlock(2, 'ACCEPTED_ON_L2'),
101
- 1: createMockBlock(1, 'ACCEPTED_ON_L2'),
102
- 0: createMockBlock(0, 'ACCEPTED_ON_L2'),
103
- };
104
- service = new finalized_block_starknet_1.FinalizedBlockService((hashOrNumber) => {
105
- return blocks[hashOrNumber];
106
- }, mockLogger);
107
- const result = await service.getFinalizedBlock();
108
- expect(result).toBeDefined();
109
- expect(result.block_number).toBe(0);
110
- });
111
- });
112
- //# sourceMappingURL=finalized.block.starknet.spec.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"finalized.block.starknet.spec.js","sourceRoot":"","sources":["../../src/starknet/finalized.block.starknet.spec.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2020-2025 SubQuery Pte Ltd authors & contributors\n// SPDX-License-Identifier: GPL-3.0\n\nimport P from 'pino';\nimport { SPEC } from 'starknet-types-07';\nimport { FinalizedBlockService } from './finalized.block.starknet';\n\nconst createMockBlock = (\n block_number: number,\n status: 'ACCEPTED_ON_L1' | 'ACCEPTED_ON_L2',\n): SPEC.BLOCK_WITH_RECEIPTS => ({\n block_number,\n status,\n block_hash: `0xabc${block_number}`,\n parent_hash: `0xparent${block_number - 1}`,\n new_root: `0xnewroot${block_number}`,\n timestamp: 1700000000 + block_number,\n sequencer_address: `0xsequencer${block_number}`,\n transactions: [],\n starknet_version: '',\n l1_da_mode: 'BLOB',\n l1_gas_price: { price_in_wei: '0', price_in_fri: '0' },\n l1_data_gas_price: { price_in_wei: '0', price_in_fri: '0' },\n});\n\n// **Mock blocks**\nconst mockBlocks: Record<number | string, SPEC.BLOCK_WITH_RECEIPTS> = {\n latest: createMockBlock(10, 'ACCEPTED_ON_L2'),\n 10: createMockBlock(10, 'ACCEPTED_ON_L2'),\n 9: createMockBlock(9, 'ACCEPTED_ON_L2'),\n 8: createMockBlock(8, 'ACCEPTED_ON_L2'),\n 7: createMockBlock(7, 'ACCEPTED_ON_L1'), // latest ACCEPTED_ON_L1\n 6: createMockBlock(6, 'ACCEPTED_ON_L1'),\n 5: createMockBlock(5, 'ACCEPTED_ON_L1'),\n 4: createMockBlock(4, 'ACCEPTED_ON_L1'),\n 3: createMockBlock(3, 'ACCEPTED_ON_L1'),\n 2: createMockBlock(2, 'ACCEPTED_ON_L1'),\n 1: createMockBlock(1, 'ACCEPTED_ON_L1'),\n 0: createMockBlock(0, 'ACCEPTED_ON_L1'),\n};\n\nconst mockBlockService = {\n async getBlock(\n heightOrHash: number | string,\n ): Promise<SPEC.BLOCK_WITH_RECEIPTS> {\n if (mockBlocks[heightOrHash] !== undefined) {\n return Promise.resolve(mockBlocks[heightOrHash]);\n }\n return Promise.reject(new Error(`Block ${heightOrHash} not found`));\n },\n};\n\n// **initialize logger**\nconst mockLogger = P({ level: 'debug' });\n\ndescribe('FinalizedBlockService', () => {\n let service: FinalizedBlockService;\n\n beforeEach(() => {\n service = new FinalizedBlockService(mockBlockService.getBlock, mockLogger);\n });\n\n // **Test 1: `findFirstAcceptedOnL1`**\n it('should find the first ACCEPTED_ON_L1 block', async () => {\n const result = await (service as any).findFirstAcceptedOnL1();\n expect(result).toBeDefined();\n expect(result?.block_number).toBe(0);\n expect(result?.status).toBe('ACCEPTED_ON_L1');\n });\n\n // **Test 2: `binarySearchAcceptedOnL1`**\n it('should find the latest ACCEPTED_ON_L1 block via binary search', async () => {\n const result = await (service as any).binarySearchAcceptedOnL1(1, 10);\n expect(result).toBeDefined();\n expect(result?.block_number).toBe(7);\n expect(result?.status).toBe('ACCEPTED_ON_L1');\n });\n\n // **Test 3: `getFinalizedBlock` - First call (initialize cache)**\n it('should initialize latestAcceptedBlock and return the correct block', async () => {\n const result = await service.getFinalizedBlock();\n expect(result).toBeDefined();\n expect(result.block_number).toBe(7);\n expect(result.status).toBe('ACCEPTED_ON_L1');\n });\n\n // **Test 4: `getFinalizedBlock` - Return cached block and verify `getBlock` is not called**\n it('should return cached block if next block remains ACCEPTED_ON_L2 and not call `getBlock`', async () => {\n const getBlockSpy = jest.spyOn(mockBlockService, 'getBlock');\n\n let result = await service.getFinalizedBlock(); // First call - initializes cache\n expect(result.block_number).toBe(7); // Should return cached block 3\n\n jest.clearAllMocks(); // Reset call count for the second invocation\n\n result = await service.getFinalizedBlock(); // Second call - should use cache\n\n expect(result).toBeDefined();\n expect(result.block_number).toBe(7); // Should return cached block 3\n expect(getBlockSpy).not.toHaveBeenCalled(); // Ensure `getBlock` was NOT called again\n });\n\n // **Test 5: `getFinalizedBlock` - Update when next block becomes L1**\n it('should update latestAcceptedBlock if next block changes to ACCEPTED_ON_L1', async () => {\n await service.getFinalizedBlock(); // Initialize cache\n mockBlocks[8].status = 'ACCEPTED_ON_L1'; // Change block 8 to L1\n const result = await service.getFinalizedBlock();\n expect(result).toBeDefined();\n expect(result.block_number).toBe(8); // Now should update to block 8\n });\n\n // No blocks are accepted on L1 with devnets\n it('works with devnet', async () => {\n const blocks = {\n latest: createMockBlock(4, 'ACCEPTED_ON_L2'),\n 4: createMockBlock(4, 'ACCEPTED_ON_L2'),\n 3: createMockBlock(3, 'ACCEPTED_ON_L2'),\n 2: createMockBlock(2, 'ACCEPTED_ON_L2'),\n 1: createMockBlock(1, 'ACCEPTED_ON_L2'),\n 0: createMockBlock(0, 'ACCEPTED_ON_L2'),\n };\n\n service = new FinalizedBlockService(\n (hashOrNumber: number | string): any => {\n return blocks[hashOrNumber];\n },\n mockLogger,\n );\n\n const result = await service.getFinalizedBlock();\n expect(result).toBeDefined();\n expect(result.block_number).toBe(0);\n });\n});\n"]}