@subql/node-starknet 5.7.3-1 → 5.8.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 (72) hide show
  1. package/CHANGELOG.md +5 -1
  2. package/dist/.tsbuildinfo +1 -1
  3. package/dist/blockchain.service.d.ts +30 -0
  4. package/dist/blockchain.service.js +111 -0
  5. package/dist/blockchain.service.js.map +1 -0
  6. package/dist/{indexer/project.service.test.js → blockchain.service.spec.js} +7 -7
  7. package/dist/blockchain.service.spec.js.map +1 -0
  8. package/dist/indexer/fetch.module.js +29 -27
  9. package/dist/indexer/fetch.module.js.map +1 -1
  10. package/dist/indexer/indexer.manager.d.ts +6 -10
  11. package/dist/indexer/indexer.manager.js +15 -11
  12. package/dist/indexer/indexer.manager.js.map +1 -1
  13. package/dist/indexer/worker/worker-fetch.module.js +7 -18
  14. package/dist/indexer/worker/worker-fetch.module.js.map +1 -1
  15. package/dist/indexer/worker/worker.js.map +1 -1
  16. package/dist/indexer/worker/worker.module.js +0 -1
  17. package/dist/indexer/worker/worker.module.js.map +1 -1
  18. package/dist/indexer/worker/worker.service.js +1 -0
  19. package/dist/indexer/worker/worker.service.js.map +1 -1
  20. package/dist/init.js +1 -2
  21. package/dist/init.js.map +1 -1
  22. package/dist/starknet/api.service.starknet.d.ts +2 -2
  23. package/dist/starknet/api.service.starknet.js +10 -8
  24. package/dist/starknet/api.service.starknet.js.map +1 -1
  25. package/dist/starknet/{api.service.starknet.test.js → api.service.starknet.spec.js} +11 -3
  26. package/dist/starknet/api.service.starknet.spec.js.map +1 -0
  27. package/dist/starknet/api.starknet.d.ts +2 -3
  28. package/dist/starknet/api.starknet.js +1 -3
  29. package/dist/starknet/api.starknet.js.map +1 -1
  30. package/dist/starknet/{block.starknet.test.js → block.starknet.spec.js} +1 -1
  31. package/dist/starknet/{block.starknet.test.js.map → block.starknet.spec.js.map} +1 -1
  32. package/dist/starknet/{decodeCalldata.test.js → decodeCalldata.spec.js} +1 -1
  33. package/dist/starknet/{decodeCalldata.test.js.map → decodeCalldata.spec.js.map} +1 -1
  34. package/dist/subcommands/reindex.module.js +19 -8
  35. package/dist/subcommands/reindex.module.js.map +1 -1
  36. package/dist/subcommands/testing.module.js +14 -32
  37. package/dist/subcommands/testing.module.js.map +1 -1
  38. package/dist/subcommands/testing.service.js.map +1 -1
  39. package/package.json +11 -12
  40. package/dist/indexer/blockDispatcher/block-dispatcher.service.d.ts +0 -15
  41. package/dist/indexer/blockDispatcher/block-dispatcher.service.js +0 -51
  42. package/dist/indexer/blockDispatcher/block-dispatcher.service.js.map +0 -1
  43. package/dist/indexer/blockDispatcher/index.d.ts +0 -4
  44. package/dist/indexer/blockDispatcher/index.js +0 -10
  45. package/dist/indexer/blockDispatcher/index.js.map +0 -1
  46. package/dist/indexer/blockDispatcher/starknet-block-dispatcher.d.ts +0 -5
  47. package/dist/indexer/blockDispatcher/starknet-block-dispatcher.js +0 -5
  48. package/dist/indexer/blockDispatcher/starknet-block-dispatcher.js.map +0 -1
  49. package/dist/indexer/blockDispatcher/worker-block-dispatcher.service.d.ts +0 -17
  50. package/dist/indexer/blockDispatcher/worker-block-dispatcher.service.js +0 -48
  51. package/dist/indexer/blockDispatcher/worker-block-dispatcher.service.js.map +0 -1
  52. package/dist/indexer/ds-processor.service.d.ts +0 -6
  53. package/dist/indexer/ds-processor.service.js +0 -22
  54. package/dist/indexer/ds-processor.service.js.map +0 -1
  55. package/dist/indexer/dynamic-ds.service.d.ts +0 -8
  56. package/dist/indexer/dynamic-ds.service.js +0 -69
  57. package/dist/indexer/dynamic-ds.service.js.map +0 -1
  58. package/dist/indexer/fetch.service.d.ts +0 -20
  59. package/dist/indexer/fetch.service.js +0 -74
  60. package/dist/indexer/fetch.service.js.map +0 -1
  61. package/dist/indexer/project.service.d.ts +0 -15
  62. package/dist/indexer/project.service.js +0 -71
  63. package/dist/indexer/project.service.js.map +0 -1
  64. package/dist/indexer/project.service.test.js.map +0 -1
  65. package/dist/indexer/unfinalizedBlocks.service.d.ts +0 -10
  66. package/dist/indexer/unfinalizedBlocks.service.js +0 -48
  67. package/dist/indexer/unfinalizedBlocks.service.js.map +0 -1
  68. package/dist/starknet/api.service.starknet.test.js.map +0 -1
  69. /package/dist/{indexer/project.service.test.d.ts → blockchain.service.spec.d.ts} +0 -0
  70. /package/dist/starknet/{api.service.starknet.test.d.ts → api.service.starknet.spec.d.ts} +0 -0
  71. /package/dist/starknet/{block.starknet.test.d.ts → block.starknet.spec.d.ts} +0 -0
  72. /package/dist/starknet/{decodeCalldata.test.d.ts → decodeCalldata.spec.d.ts} +0 -0
package/dist/init.js CHANGED
@@ -7,7 +7,6 @@ const core_1 = require("@nestjs/core");
7
7
  const common_1 = require("@subql/common");
8
8
  const node_core_1 = require("@subql/node-core");
9
9
  const app_module_1 = require("./app.module");
10
- const fetch_service_1 = require("./indexer/fetch.service");
11
10
  const yargs_1 = require("./yargs");
12
11
  const pjson = require('../package.json');
13
12
  const { argv } = yargs_1.yargsOptions;
@@ -26,7 +25,7 @@ async function bootstrap() {
26
25
  });
27
26
  await app.init();
28
27
  const projectService = app.get('IProjectService');
29
- const fetchService = app.get(fetch_service_1.FetchService);
28
+ const fetchService = app.get(node_core_1.FetchService);
30
29
  // Initialise async services, we do this here rather than in factories, so we can capture one off eventss
31
30
  await projectService.init();
32
31
  await fetchService.init(projectService.startHeight);
package/dist/init.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"init.js","sourceRoot":"","sources":["../src/init.ts"],"names":[],"mappings":";AAAA,8DAA8D;AAC9D,mCAAmC;;AAsBnC,8BAiCC;AArDD,uCAA2C;AAC3C,0CAA8C;AAC9C,gDAK0B;AAC1B,6CAAyC;AACzC,2DAAuD;AAEvD,mCAAuC;AACvC,MAAM,KAAK,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC;AAEzC,MAAM,EAAE,IAAI,EAAE,GAAG,oBAAY,CAAC;AAE9B,MAAM,MAAM,GAAG,IAAA,qBAAS,EAAC,YAAY,CAAC,CAAC;AAEvC,IAAA,sBAAa,EAAC,KAAK,EAAE,MAAM,CAAC,CAAC;AAEtB,KAAK,UAAU,SAAS;IAC7B,MAAM,CAAC,IAAI,CAAC,WAAW,KAAK,CAAC,IAAI,eAAe,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;IACjE,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC;IAEzB,MAAM,IAAI,GAAG,MAAM,IAAA,wBAAY,EAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAE3C,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;QAChB,MAAM,CAAC,IAAI,CACT,mHAAmH,CACpH,CAAC;IACJ,CAAC;IAED,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,kBAAW,CAAC,MAAM,CAAC,sBAAS,EAAE;YAC9C,MAAM,EAAE,IAAI,sBAAU,CAAC,CAAC,CAAC,KAAK,CAAC;SAChC,CAAC,CAAC;QACH,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;QAEjB,MAAM,cAAc,GAAmB,GAAG,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;QAClE,MAAM,YAAY,GAAG,GAAG,CAAC,GAAG,CAAC,4BAAY,CAAC,CAAC;QAE3C,yGAAyG;QACzG,MAAM,cAAc,CAAC,IAAI,EAAE,CAAC;QAC5B,MAAM,YAAY,CAAC,IAAI,CAAC,cAAc,CAAC,WAAW,CAAC,CAAC;QAEpD,GAAG,CAAC,mBAAmB,EAAE,CAAC;QAE1B,MAAM,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAEvB,MAAM,CAAC,IAAI,CAAC,yBAAyB,IAAI,EAAE,CAAC,CAAC;IAC/C,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,IAAA,yBAAa,EAAC,IAAI,KAAK,CAAC,sBAAsB,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC;IACzE,CAAC;AACH,CAAC","sourcesContent":["// Copyright 2020-2025 SubQuery Pte Ltd authors & contributors\n// SPDX-License-Identifier: GPL-3.0\n\nimport { NestFactory } from '@nestjs/core';\nimport { notifyUpdates } from '@subql/common';\nimport {\n exitWithError,\n getLogger,\n getValidPort,\n NestLogger,\n} from '@subql/node-core';\nimport { AppModule } from './app.module';\nimport { FetchService } from './indexer/fetch.service';\nimport { ProjectService } from './indexer/project.service';\nimport { yargsOptions } from './yargs';\nconst pjson = require('../package.json');\n\nconst { argv } = yargsOptions;\n\nconst logger = getLogger('subql-node');\n\nnotifyUpdates(pjson, logger);\n\nexport async function bootstrap(): Promise<void> {\n logger.info(`Current ${pjson.name} version is ${pjson.version}`);\n const debug = argv.debug;\n\n const port = await getValidPort(argv.port);\n\n if (argv.unsafe) {\n logger.warn(\n 'UNSAFE MODE IS ENABLED. This is not recommended for most projects and will not be supported by our hosted service',\n );\n }\n\n try {\n const app = await NestFactory.create(AppModule, {\n logger: new NestLogger(!!debug),\n });\n await app.init();\n\n const projectService: ProjectService = app.get('IProjectService');\n const fetchService = app.get(FetchService);\n\n // Initialise async services, we do this here rather than in factories, so we can capture one off eventss\n await projectService.init();\n await fetchService.init(projectService.startHeight);\n\n app.enableShutdownHooks();\n\n await app.listen(port);\n\n logger.info(`Node started on port: ${port}`);\n } catch (e) {\n exitWithError(new Error('Node failed to start', { cause: e }), logger);\n }\n}\n"]}
1
+ {"version":3,"file":"init.js","sourceRoot":"","sources":["../src/init.ts"],"names":[],"mappings":";AAAA,8DAA8D;AAC9D,mCAAmC;;AAsBnC,8BAiCC;AArDD,uCAA2C;AAC3C,0CAA8C;AAC9C,gDAO0B;AAC1B,6CAAyC;AACzC,mCAAuC;AACvC,MAAM,KAAK,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC;AAEzC,MAAM,EAAE,IAAI,EAAE,GAAG,oBAAY,CAAC;AAE9B,MAAM,MAAM,GAAG,IAAA,qBAAS,EAAC,YAAY,CAAC,CAAC;AAEvC,IAAA,sBAAa,EAAC,KAAK,EAAE,MAAM,CAAC,CAAC;AAEtB,KAAK,UAAU,SAAS;IAC7B,MAAM,CAAC,IAAI,CAAC,WAAW,KAAK,CAAC,IAAI,eAAe,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;IACjE,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC;IAEzB,MAAM,IAAI,GAAG,MAAM,IAAA,wBAAY,EAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAE3C,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;QAChB,MAAM,CAAC,IAAI,CACT,mHAAmH,CACpH,CAAC;IACJ,CAAC;IAED,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,kBAAW,CAAC,MAAM,CAAC,sBAAS,EAAE;YAC9C,MAAM,EAAE,IAAI,sBAAU,CAAC,CAAC,CAAC,KAAK,CAAC;SAChC,CAAC,CAAC;QACH,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;QAEjB,MAAM,cAAc,GAAmB,GAAG,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;QAClE,MAAM,YAAY,GAAG,GAAG,CAAC,GAAG,CAAC,wBAAY,CAAC,CAAC;QAE3C,yGAAyG;QACzG,MAAM,cAAc,CAAC,IAAI,EAAE,CAAC;QAC5B,MAAM,YAAY,CAAC,IAAI,CAAC,cAAc,CAAC,WAAW,CAAC,CAAC;QAEpD,GAAG,CAAC,mBAAmB,EAAE,CAAC;QAE1B,MAAM,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAEvB,MAAM,CAAC,IAAI,CAAC,yBAAyB,IAAI,EAAE,CAAC,CAAC;IAC/C,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,IAAA,yBAAa,EAAC,IAAI,KAAK,CAAC,sBAAsB,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC;IACzE,CAAC;AACH,CAAC","sourcesContent":["// Copyright 2020-2025 SubQuery Pte Ltd authors & contributors\n// SPDX-License-Identifier: GPL-3.0\n\nimport { NestFactory } from '@nestjs/core';\nimport { notifyUpdates } from '@subql/common';\nimport {\n exitWithError,\n FetchService,\n getLogger,\n getValidPort,\n NestLogger,\n ProjectService,\n} from '@subql/node-core';\nimport { AppModule } from './app.module';\nimport { yargsOptions } from './yargs';\nconst pjson = require('../package.json');\n\nconst { argv } = yargsOptions;\n\nconst logger = getLogger('subql-node');\n\nnotifyUpdates(pjson, logger);\n\nexport async function bootstrap(): Promise<void> {\n logger.info(`Current ${pjson.name} version is ${pjson.version}`);\n const debug = argv.debug;\n\n const port = await getValidPort(argv.port);\n\n if (argv.unsafe) {\n logger.warn(\n 'UNSAFE MODE IS ENABLED. This is not recommended for most projects and will not be supported by our hosted service',\n );\n }\n\n try {\n const app = await NestFactory.create(AppModule, {\n logger: new NestLogger(!!debug),\n });\n await app.init();\n\n const projectService: ProjectService = app.get('IProjectService');\n const fetchService = app.get(FetchService);\n\n // Initialise async services, we do this here rather than in factories, so we can capture one off eventss\n await projectService.init();\n await fetchService.init(projectService.startHeight);\n\n app.enableShutdownHooks();\n\n await app.listen(port);\n\n logger.info(`Node started on port: ${port}`);\n } catch (e) {\n exitWithError(new Error('Node failed to start', { cause: e }), logger);\n }\n}\n"]}
@@ -10,8 +10,8 @@ export declare class StarknetApiService extends ApiService<StarknetApi, SafeStar
10
10
  private fetchBlocksFunction?;
11
11
  private fetchBlocksBatches;
12
12
  private nodeConfig;
13
- constructor(project: SubqueryProject, connectionPoolService: ConnectionPoolService<StarknetApiConnection>, eventEmitter: EventEmitter2, nodeConfig: NodeConfig);
14
- init(): Promise<StarknetApiService>;
13
+ private constructor();
14
+ static create(project: SubqueryProject, connectionPoolService: ConnectionPoolService<StarknetApiConnection>, eventEmitter: EventEmitter2, nodeConfig: NodeConfig): Promise<StarknetApiService>;
15
15
  protected metadataMismatchError(metadata: string, expected: string, actual: string): Error;
16
16
  get api(): StarknetApi;
17
17
  safeApi(height: number): SafeStarknetProvider;
@@ -16,6 +16,7 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
16
16
  var __importDefault = (this && this.__importDefault) || function (mod) {
17
17
  return (mod && mod.__esModule) ? mod : { "default": mod };
18
18
  };
19
+ var StarknetApiService_1;
19
20
  Object.defineProperty(exports, "__esModule", { value: true });
20
21
  exports.StarknetApiService = void 0;
21
22
  const assert_1 = __importDefault(require("assert"));
@@ -26,7 +27,7 @@ const NodeConfig_1 = require("../configure/NodeConfig");
26
27
  const project_1 = require("../utils/project");
27
28
  const api_connection_1 = require("./api.connection");
28
29
  const logger = (0, node_core_1.getLogger)('api');
29
- let StarknetApiService = class StarknetApiService extends node_core_1.ApiService {
30
+ let StarknetApiService = StarknetApiService_1 = class StarknetApiService extends node_core_1.ApiService {
30
31
  project;
31
32
  fetchBlocksFunction;
32
33
  fetchBlocksBatches = () => {
@@ -40,20 +41,21 @@ let StarknetApiService = class StarknetApiService extends node_core_1.ApiService
40
41
  this.nodeConfig = new NodeConfig_1.StarknetNodeConfig(nodeConfig);
41
42
  this.updateBlockFetching();
42
43
  }
43
- async init() {
44
+ static async create(project, connectionPoolService, eventEmitter, nodeConfig) {
44
45
  let network;
45
46
  try {
46
- network = this.project.network;
47
+ network = project.network;
47
48
  }
48
49
  catch (e) {
49
50
  (0, node_core_1.exitWithError)(new Error(`Failed to init api`, { cause: e }), logger);
50
51
  }
51
- if (this.nodeConfig.primaryNetworkEndpoint) {
52
- const [endpoint, config] = this.nodeConfig.primaryNetworkEndpoint;
52
+ if (nodeConfig.primaryNetworkEndpoint) {
53
+ const [endpoint, config] = nodeConfig.primaryNetworkEndpoint;
53
54
  network.endpoint[endpoint] = config;
54
55
  }
55
- await this.createConnections(network, (endpoint, config) => api_connection_1.StarknetApiConnection.create(endpoint, this.fetchBlocksBatches, this.eventEmitter, config));
56
- return this;
56
+ const apiService = new StarknetApiService_1(project, connectionPoolService, eventEmitter, nodeConfig);
57
+ await apiService.createConnections(project.network, (endpoint, config) => api_connection_1.StarknetApiConnection.create(endpoint, apiService.fetchBlocksBatches, eventEmitter, config));
58
+ return apiService;
57
59
  }
58
60
  metadataMismatchError(metadata, expected, actual) {
59
61
  return Error(`Value of ${metadata} does not match across all endpoints. Please check that your endpoints are for the same network.\n
@@ -146,7 +148,7 @@ let StarknetApiService = class StarknetApiService extends node_core_1.ApiService
146
148
  }
147
149
  };
148
150
  exports.StarknetApiService = StarknetApiService;
149
- exports.StarknetApiService = StarknetApiService = __decorate([
151
+ exports.StarknetApiService = StarknetApiService = StarknetApiService_1 = __decorate([
150
152
  (0, common_1.Injectable)(),
151
153
  __param(0, (0, common_1.Inject)('ISubqueryProject')),
152
154
  __metadata("design:paramtypes", [Object, node_core_1.ConnectionPoolService,
@@ -1 +1 @@
1
- {"version":3,"file":"api.service.starknet.js","sourceRoot":"","sources":["../../src/starknet/api.service.starknet.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 assert from 'assert';\nimport { Inject, Injectable } from '@nestjs/common';\nimport { EventEmitter2 } from '@nestjs/event-emitter';\nimport {\n ApiService,\n ConnectionPoolService,\n getLogger,\n NodeConfig,\n profilerWrap,\n IBlock,\n exitWithError,\n} from '@subql/node-core';\nimport { IEndpointConfig } from '@subql/types-core';\nimport {\n StarknetBlock,\n StarknetNetworkConfig,\n IStarknetEndpointConfig,\n LightStarknetBlock,\n} from '@subql/types-starknet';\nimport { StarknetNodeConfig } from '../configure/NodeConfig';\nimport { SubqueryProject } from '../configure/SubqueryProject';\nimport { isOnlyEventHandlers } from '../utils/project';\nimport {\n StarknetApiConnection,\n FetchFunc,\n GetFetchFunc,\n} from './api.connection';\nimport { StarknetApi } from './api.starknet';\nimport SafeStarknetProvider from './safe-api';\nconst logger = getLogger('api');\n\n@Injectable()\nexport class StarknetApiService extends ApiService<\n StarknetApi,\n SafeStarknetProvider,\n IBlock<StarknetBlock>[] | IBlock<LightStarknetBlock>[],\n StarknetApiConnection,\n IStarknetEndpointConfig\n> {\n private fetchBlocksFunction?: FetchFunc;\n private fetchBlocksBatches: GetFetchFunc = () => {\n assert(this.fetchBlocksFunction, 'Fetch blocks function is not defined');\n return this.fetchBlocksFunction;\n };\n private nodeConfig: StarknetNodeConfig;\n\n constructor(\n @Inject('ISubqueryProject') private project: SubqueryProject,\n connectionPoolService: ConnectionPoolService<StarknetApiConnection>,\n eventEmitter: EventEmitter2,\n nodeConfig: NodeConfig,\n ) {\n super(connectionPoolService, eventEmitter);\n this.nodeConfig = new StarknetNodeConfig(nodeConfig);\n\n this.updateBlockFetching();\n }\n\n async init(): Promise<StarknetApiService> {\n let network: StarknetNetworkConfig;\n try {\n network = this.project.network;\n } catch (e) {\n exitWithError(new Error(`Failed to init api`, { cause: e }), logger);\n }\n\n if (this.nodeConfig.primaryNetworkEndpoint) {\n const [endpoint, config] = this.nodeConfig.primaryNetworkEndpoint;\n (network.endpoint as Record<string, IEndpointConfig>)[endpoint] = config;\n }\n\n await this.createConnections(network, (endpoint, config) =>\n StarknetApiConnection.create(\n endpoint,\n this.fetchBlocksBatches,\n this.eventEmitter,\n config,\n ),\n );\n\n return this;\n }\n\n protected metadataMismatchError(\n metadata: string,\n expected: string,\n actual: string,\n ): Error {\n return Error(\n `Value of ${metadata} does not match across all endpoints. Please check that your endpoints are for the same network.\\n\n Expected: ${expected}\n Actual: ${actual}`,\n );\n }\n\n get api(): StarknetApi {\n return this.unsafeApi;\n }\n\n safeApi(height: number): SafeStarknetProvider {\n const maxRetries = 5;\n\n const retryErrorCodes = [\n 'UNKNOWN_ERROR',\n 'NOT_IMPLEMENTED',\n 'NETWORK_ERROR',\n 'SERVER_ERROR',\n 'TIMEOUT',\n 'BAD_DATA',\n 'CANCELLED',\n ];\n\n const handler: ProxyHandler<SafeStarknetProvider> = {\n get: (target, prop, receiver) => {\n const originalMethod = target[prop as keyof SafeStarknetProvider];\n if (typeof originalMethod === 'function') {\n return async (\n ...args: Parameters<typeof originalMethod>\n ): Promise<ReturnType<typeof originalMethod>> => {\n let retries = 0;\n let currentApi = target;\n let throwingError: Error | undefined;\n\n while (retries < maxRetries) {\n try {\n return await (originalMethod as Function).apply(\n currentApi,\n args,\n );\n } catch (error: any) {\n // other than retryErrorCodes, other errors does not have anything to do with network request, retrying would not change its outcome\n if (!retryErrorCodes.includes(error?.code)) {\n throw error;\n }\n\n logger.warn(\n `Request failed with api at height ${height} (retry ${retries}): ${error.message}`,\n );\n throwingError = error;\n currentApi = this.unsafeApi.getSafeApi(height);\n retries++;\n }\n }\n\n logger.error(\n `Maximum retries (${maxRetries}) exceeded for api at height ${height}`,\n );\n if (!throwingError) {\n throw new Error('Failed to make request, maximum retries failed');\n }\n throw throwingError;\n };\n }\n return Reflect.get(target, prop, receiver);\n },\n };\n\n return new Proxy(this.unsafeApi.getSafeApi(height), handler);\n }\n\n private async fetchFullBlocksBatch(\n api: StarknetApi,\n batch: number[],\n ): Promise<IBlock<StarknetBlock>[]> {\n return api.fetchBlocks(batch);\n }\n\n private async fetchLightBlocksBatch(\n api: StarknetApi,\n batch: number[],\n ): Promise<IBlock<LightStarknetBlock>[]> {\n return api.fetchBlocksLight(batch);\n }\n\n updateBlockFetching(): void {\n const onlyEventHandlers = isOnlyEventHandlers(this.project);\n const skipTransactions =\n this.nodeConfig.skipTransactions && onlyEventHandlers;\n\n if (this.nodeConfig.skipTransactions) {\n if (onlyEventHandlers) {\n logger.info(\n 'skipTransactions is enabled, only events and block headers will be fetched.',\n );\n } else {\n logger.info(\n `skipTransactions is disabled, the project contains handlers that aren't event handlers.`,\n );\n }\n } else {\n if (onlyEventHandlers) {\n logger.warn(\n 'skipTransactions is disabled, the project contains only event handlers, it could be enabled to improve indexing performance.',\n );\n } else {\n logger.info(`skipTransactions is disabled.`);\n }\n }\n\n const fetchFunc = skipTransactions\n ? this.fetchLightBlocksBatch.bind(this)\n : this.fetchFullBlocksBatch.bind(this);\n\n if (this.nodeConfig?.profiler) {\n this.fetchBlocksFunction = profilerWrap(\n fetchFunc,\n 'StarknetApi',\n 'fetchBlocksBatches',\n ) as FetchFunc;\n } else {\n this.fetchBlocksFunction = fetchFunc;\n }\n }\n}\n"]}
1
+ {"version":3,"file":"api.service.starknet.js","sourceRoot":"","sources":["../../src/starknet/api.service.starknet.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 assert from 'assert';\nimport { Inject, Injectable } from '@nestjs/common';\nimport { EventEmitter2 } from '@nestjs/event-emitter';\nimport {\n ApiService,\n ConnectionPoolService,\n getLogger,\n NodeConfig,\n profilerWrap,\n IBlock,\n exitWithError,\n} from '@subql/node-core';\nimport { IEndpointConfig } from '@subql/types-core';\nimport {\n StarknetBlock,\n StarknetNetworkConfig,\n IStarknetEndpointConfig,\n LightStarknetBlock,\n} from '@subql/types-starknet';\nimport { StarknetNodeConfig } from '../configure/NodeConfig';\nimport { SubqueryProject } from '../configure/SubqueryProject';\nimport { isOnlyEventHandlers } from '../utils/project';\nimport {\n StarknetApiConnection,\n FetchFunc,\n GetFetchFunc,\n} from './api.connection';\nimport { StarknetApi } from './api.starknet';\nimport SafeStarknetProvider from './safe-api';\nconst logger = getLogger('api');\n\n@Injectable()\nexport class StarknetApiService extends ApiService<\n StarknetApi,\n SafeStarknetProvider,\n IBlock<StarknetBlock>[] | IBlock<LightStarknetBlock>[],\n StarknetApiConnection,\n IStarknetEndpointConfig\n> {\n private fetchBlocksFunction?: FetchFunc;\n private fetchBlocksBatches: GetFetchFunc = () => {\n assert(this.fetchBlocksFunction, 'Fetch blocks function is not defined');\n return this.fetchBlocksFunction;\n };\n private nodeConfig: StarknetNodeConfig;\n\n private constructor(\n @Inject('ISubqueryProject') private project: SubqueryProject,\n connectionPoolService: ConnectionPoolService<StarknetApiConnection>,\n eventEmitter: EventEmitter2,\n nodeConfig: NodeConfig,\n ) {\n super(connectionPoolService, eventEmitter);\n this.nodeConfig = new StarknetNodeConfig(nodeConfig);\n\n this.updateBlockFetching();\n }\n\n static async create(\n project: SubqueryProject,\n connectionPoolService: ConnectionPoolService<StarknetApiConnection>,\n eventEmitter: EventEmitter2,\n nodeConfig: NodeConfig,\n ): Promise<StarknetApiService> {\n let network: StarknetNetworkConfig;\n try {\n network = project.network;\n } catch (e) {\n exitWithError(new Error(`Failed to init api`, { cause: e }), logger);\n }\n\n if (nodeConfig.primaryNetworkEndpoint) {\n const [endpoint, config] = nodeConfig.primaryNetworkEndpoint;\n (network.endpoint as Record<string, IEndpointConfig>)[endpoint] = config;\n }\n\n const apiService = new StarknetApiService(\n project,\n connectionPoolService,\n eventEmitter,\n nodeConfig,\n );\n\n await apiService.createConnections(project.network, (endpoint, config) =>\n StarknetApiConnection.create(\n endpoint,\n apiService.fetchBlocksBatches,\n eventEmitter,\n config,\n ),\n );\n\n return apiService;\n }\n\n protected metadataMismatchError(\n metadata: string,\n expected: string,\n actual: string,\n ): Error {\n return Error(\n `Value of ${metadata} does not match across all endpoints. Please check that your endpoints are for the same network.\\n\n Expected: ${expected}\n Actual: ${actual}`,\n );\n }\n\n get api(): StarknetApi {\n return this.unsafeApi;\n }\n\n safeApi(height: number): SafeStarknetProvider {\n const maxRetries = 5;\n\n const retryErrorCodes = [\n 'UNKNOWN_ERROR',\n 'NOT_IMPLEMENTED',\n 'NETWORK_ERROR',\n 'SERVER_ERROR',\n 'TIMEOUT',\n 'BAD_DATA',\n 'CANCELLED',\n ];\n\n const handler: ProxyHandler<SafeStarknetProvider> = {\n get: (target, prop, receiver) => {\n const originalMethod = target[prop as keyof SafeStarknetProvider];\n if (typeof originalMethod === 'function') {\n return async (\n ...args: Parameters<typeof originalMethod>\n ): Promise<ReturnType<typeof originalMethod>> => {\n let retries = 0;\n let currentApi = target;\n let throwingError: Error | undefined;\n\n while (retries < maxRetries) {\n try {\n return await (originalMethod as Function).apply(\n currentApi,\n args,\n );\n } catch (error: any) {\n // other than retryErrorCodes, other errors does not have anything to do with network request, retrying would not change its outcome\n if (!retryErrorCodes.includes(error?.code)) {\n throw error;\n }\n\n logger.warn(\n `Request failed with api at height ${height} (retry ${retries}): ${error.message}`,\n );\n throwingError = error;\n currentApi = this.unsafeApi.getSafeApi(height);\n retries++;\n }\n }\n\n logger.error(\n `Maximum retries (${maxRetries}) exceeded for api at height ${height}`,\n );\n if (!throwingError) {\n throw new Error('Failed to make request, maximum retries failed');\n }\n throw throwingError;\n };\n }\n return Reflect.get(target, prop, receiver);\n },\n };\n\n return new Proxy(this.unsafeApi.getSafeApi(height), handler);\n }\n\n private async fetchFullBlocksBatch(\n api: StarknetApi,\n batch: number[],\n ): Promise<IBlock<StarknetBlock>[]> {\n return api.fetchBlocks(batch);\n }\n\n private async fetchLightBlocksBatch(\n api: StarknetApi,\n batch: number[],\n ): Promise<IBlock<LightStarknetBlock>[]> {\n return api.fetchBlocksLight(batch);\n }\n\n updateBlockFetching(): void {\n const onlyEventHandlers = isOnlyEventHandlers(this.project);\n const skipTransactions =\n this.nodeConfig.skipTransactions && onlyEventHandlers;\n\n if (this.nodeConfig.skipTransactions) {\n if (onlyEventHandlers) {\n logger.info(\n 'skipTransactions is enabled, only events and block headers will be fetched.',\n );\n } else {\n logger.info(\n `skipTransactions is disabled, the project contains handlers that aren't event handlers.`,\n );\n }\n } else {\n if (onlyEventHandlers) {\n logger.warn(\n 'skipTransactions is disabled, the project contains only event handlers, it could be enabled to improve indexing performance.',\n );\n } else {\n logger.info(`skipTransactions is disabled.`);\n }\n }\n\n const fetchFunc = skipTransactions\n ? this.fetchLightBlocksBatch.bind(this)\n : this.fetchFullBlocksBatch.bind(this);\n\n if (this.nodeConfig?.profiler) {\n this.fetchBlocksFunction = profilerWrap(\n fetchFunc,\n 'StarknetApi',\n 'fetchBlocksBatches',\n ) as FetchFunc;\n } else {\n this.fetchBlocksFunction = fetchFunc;\n }\n }\n}\n"]}
@@ -36,14 +36,22 @@ const prepareApiService = async (endpoint = HTTP_ENDPOINT) => {
36
36
  provide: 'ISubqueryProject',
37
37
  useFactory: () => testSubqueryProject(endpoint),
38
38
  },
39
- api_service_starknet_1.StarknetApiService,
39
+ {
40
+ provide: api_service_starknet_1.StarknetApiService,
41
+ useFactory: api_service_starknet_1.StarknetApiService.create,
42
+ inject: [
43
+ 'ISubqueryProject',
44
+ node_core_1.ConnectionPoolService,
45
+ event_emitter_1.EventEmitter2,
46
+ node_core_1.NodeConfig,
47
+ ],
48
+ },
40
49
  ],
41
50
  imports: [event_emitter_1.EventEmitterModule.forRoot()],
42
51
  }).compile();
43
52
  const app = module.createNestApplication();
44
53
  await app.init();
45
54
  const apiService = app.get(api_service_starknet_1.StarknetApiService);
46
- await apiService.init();
47
55
  return [apiService, app];
48
56
  };
49
57
  jest.setTimeout(90000);
@@ -68,4 +76,4 @@ describe('ApiService', () => {
68
76
  expect(height).toBeGreaterThan(975_650);
69
77
  });
70
78
  });
71
- //# sourceMappingURL=api.service.starknet.test.js.map
79
+ //# sourceMappingURL=api.service.starknet.spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api.service.starknet.spec.js","sourceRoot":"","sources":["../../src/starknet/api.service.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 { INestApplication } from '@nestjs/common';\nimport { EventEmitter2, EventEmitterModule } from '@nestjs/event-emitter';\nimport { Test } from '@nestjs/testing';\nimport {\n ConnectionPoolService,\n ConnectionPoolStateManager,\n NodeConfig,\n} from '@subql/node-core';\nimport { GraphQLSchema } from 'graphql';\nimport { range } from 'lodash';\nimport { SubqueryProject } from '../configure/SubqueryProject';\nimport { StarknetApiService } from './api.service.starknet';\n\n// Add api key to work\nconst HTTP_ENDPOINT = 'https://free-rpc.nethermind.io/mainnet-juno/v0_7';\n\nfunction testSubqueryProject(endpoint: string): SubqueryProject {\n return {\n network: {\n endpoint: [endpoint],\n chainId: '0x534e5f4d41494e',\n },\n dataSources: [],\n id: 'test',\n root: './',\n schema: new GraphQLSchema({}),\n templates: [],\n } as any;\n}\n\nconst prepareApiService = async (\n endpoint: string = HTTP_ENDPOINT,\n): Promise<[StarknetApiService, INestApplication]> => {\n const module = await Test.createTestingModule({\n providers: [\n ConnectionPoolService,\n ConnectionPoolStateManager,\n {\n provide: NodeConfig,\n useFactory: () => ({}),\n },\n {\n provide: 'ISubqueryProject',\n useFactory: () => testSubqueryProject(endpoint),\n },\n {\n provide: StarknetApiService,\n useFactory: StarknetApiService.create,\n inject: [\n 'ISubqueryProject',\n ConnectionPoolService,\n EventEmitter2,\n NodeConfig,\n ],\n },\n ],\n imports: [EventEmitterModule.forRoot()],\n }).compile();\n\n const app = module.createNestApplication();\n await app.init();\n const apiService = app.get(StarknetApiService);\n return [apiService, app];\n};\n\njest.setTimeout(90000);\ndescribe('ApiService', () => {\n let apiService: StarknetApiService;\n let app: INestApplication;\n\n beforeEach(async () => {\n [apiService, app] = await prepareApiService();\n });\n\n afterEach(async () => {\n return app?.close();\n });\n\n it('can instantiate api', () => {\n expect(apiService.api.getChainId()).toEqual('0x534e5f4d41494e');\n });\n\n it('can fetch blocks', async () => {\n await expect(\n apiService.api.fetchBlocks(range(50000, 50004)),\n ).resolves.toHaveLength(4);\n });\n\n it('can get the finalized height', async () => {\n const height = (await apiService.api.getFinalizedBlock()).block_number;\n\n console.log('Finalized height', height);\n expect(height).toBeGreaterThan(975_650);\n });\n});\n"]}
@@ -1,7 +1,7 @@
1
1
  import { EventEmitter2 } from '@nestjs/event-emitter';
2
2
  import { IBlock } from '@subql/node-core';
3
3
  import { ApiWrapper, StarknetBlock, StarknetRuntimeDatasource, IStarknetEndpointConfig, LightStarknetBlock, StarknetResult, StarknetTransaction, StarknetLog, StarknetContractCall } from '@subql/types-starknet';
4
- import { RpcProvider, Abi } from 'starknet';
4
+ import { RpcProvider, Abi, BlockIdentifier } from 'starknet';
5
5
  import { SPEC } from 'starknet-types-07';
6
6
  import { HEADER_WITH_STATUS } from './finalized.block.starknet';
7
7
  import SafeStarknetProvider from './safe-api';
@@ -31,14 +31,13 @@ export declare class StarknetApi implements ApiWrapper {
31
31
  * @returns {Promise<BLOCK_HEADER>}
32
32
  */
33
33
  getFinalizedBlock(): Promise<HEADER_WITH_STATUS>;
34
- getFinalizedBlockHeight(): Promise<number>;
35
34
  getBestBlockHeight(): Promise<number>;
36
35
  getChainId(): string;
37
36
  getGenesisHash(): string;
38
37
  getSpecVersion(): string;
39
38
  getBlockByHeightOrHash(heightOrHash: number | string): Promise<SPEC.BLOCK_WITH_RECEIPTS>;
40
39
  fetchBlock(blockNumber: number): Promise<IBlock<StarknetBlock>>;
41
- private fetchLightBlock;
40
+ fetchLightBlock(blockNumber: BlockIdentifier): Promise<IBlock<LightStarknetBlock>>;
42
41
  fetchBlocks(bufferBlocks: number[]): Promise<IBlock<StarknetBlock>[]>;
43
42
  fetchBlocksLight(bufferBlocks: number[]): Promise<IBlock<LightStarknetBlock>[]>;
44
43
  get api(): RpcProvider;
@@ -117,9 +117,6 @@ class StarknetApi {
117
117
  const block = await this.finalizedBlockService.getFinalizedBlock();
118
118
  return block;
119
119
  }
120
- async getFinalizedBlockHeight() {
121
- return (await this.getFinalizedBlock()).block_number;
122
- }
123
120
  async getBestBlockHeight() {
124
121
  return (await this.client.getBlockLatestAccepted()).block_number;
125
122
  }
@@ -169,6 +166,7 @@ class StarknetApi {
169
166
  }
170
167
  }
171
168
  async fetchLightBlock(blockNumber) {
169
+ // Cast to remove PENDING_BLOCK_WITH_TX_HASHES type
172
170
  const block = (await this.client.getBlockWithTxHashes(blockNumber));
173
171
  const lightBlock = {
174
172
  ...block,
@@ -1 +1 @@
1
- {"version":3,"file":"api.starknet.js","sourceRoot":"","sources":["../../src/starknet/api.starknet.ts"],"names":[],"mappings":";AAAA,8DAA8D;AAC9D,mCAAmC;;;;;;AAEnC,oDAA4B;AAC5B,4CAAoB;AAGpB,gDAAqD;AAYrD,uCASkB;AAElB,yEAGoC;AACpC,0DAA8C;AAC9C,qDAU0B;AAE1B,8DAA8D;AAC9D,MAAM,EAAE,OAAO,EAAE,cAAc,EAAE,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAAC;AAElE,MAAM,MAAM,GAAG,IAAA,qBAAS,EAAC,cAAc,CAAC,CAAC;AAEzC,KAAK,UAAU,UAAU,CACvB,EAA6B;IAE7B,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC;QACf,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,MAAM,GAAG,GAA2B,EAAE,CAAC;IAEvC,KAAK,MAAM,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,MAAM,CAAC,OAAO,EAAE,EAAE,CAAC;QACnD,IAAI,CAAC;YACH,GAAG,CAAC,IAAI,CAAC,GAAG,MAAM,YAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC;QACrE,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,MAAM,IAAI,KAAK,CAAC,mCAAmC,IAAI,EAAE,CAAC,CAAC;QAC7D,CAAC;IACH,CAAC;IAED,OAAO,GAAG,CAAC;AACb,CAAC;AAED,MAAa,WAAW;IAuBZ;IACA;IACA;IAxBF,MAAM,CAAc;IAE5B,oDAAoD;IAC5C,cAAc,CAAwB;IACtC,aAAa,CAAuB;IACpC,kBAAkB,GAAwB,EAAE,CAAC;IAC7C,OAAO,CAAU;IACjB,WAAW,CAAU;IACrB,qBAAqB,CAAwB;IAErD,eAAe;IACP,qBAAqB,GAAG,IAAI,CAAC;IAErC,IAAI,oBAAoB;QACtB,OAAO,IAAI,CAAC,qBAAqB,CAAC;IACpC,CAAC;IAED;;;OAGG;IACH,YACU,QAAgB,EAChB,YAA2B,EAC3B,MAAgC;QAFhC,aAAQ,GAAR,QAAQ,CAAQ;QAChB,iBAAY,GAAZ,YAAY,CAAe;QAC3B,WAAM,GAAN,MAAM,CAA0B;QAExC,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,YAAY,EAAE,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAC;QAE/D,MAAM,WAAW,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;QAE9C,MAAM,CAAC,IAAI,CAAC,aAAa,QAAQ,aAAa,WAAW,EAAE,CAAC,CAAC;QAE7D,IAAI,WAAW,KAAK,OAAO,IAAI,WAAW,KAAK,MAAM,EAAE,CAAC;YACtD,MAAM,IAAI,KAAK,CAAC,yBAAyB,QAAQ,EAAE,CAAC,CAAC;QACvD,CAAC;QACD,MAAM,UAAU,GAA2C;YACzD,OAAO,EAAE,IAAI,CAAC,QAAQ;YACtB,OAAO,EAAE;gBACP,YAAY,EAAE,iBAAiB,cAAc,EAAE;gBAC/C,GAAG,MAAM,EAAE,OAAO;aACnB;YACD,KAAK,EAAE,IAAI,CAAC,MAAM,EAAE,SAAS,IAAI,KAAK;SACvC,CAAC;QACF,YAAY,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;YAClC,UAAU,CAAC,OAAe,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC;QAC5C,CAAC,CAAC,CAAC;QACH,IAAI,CAAC,MAAM,GAAG,IAAI,sBAAW,CAAC,UAAU,CAAC,CAAC;QAC1C,IAAI,CAAC,qBAAqB,GAAG,IAAI,gDAAqB,CACpD,IAAI,CAAC,sBAAsB,CAAC,IAAI,CAAC,IAAI,CAAC,EACtC,MAAM,CACP,CAAC;IACJ,CAAC;IAED,IAAY,YAAY;QACtB,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC;YACxB,MAAM,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAC;QACpD,CAAC;QACD,OAAO,IAAI,CAAC,aAAa,CAAC;IAC5B,CAAC;IAED,KAAK,CAAC,IAAI;QACR,IAAI,CAAC;YACH,IAAI,CAAC,aAAa,GAAG,MAAM,IAAI,CAAC,eAAe,EAAE,CAAC;YAClD,IAAI,CAAC,OAAO,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC;YAC9C,IAAI,CAAC,WAAW,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,cAAc,EAAE,CAAC;QACxD,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,IAAK,CAAW,CAAC,OAAO,CAAC,UAAU,CAAC,kBAAkB,CAAC,EAAE,CAAC;gBACxD,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,CAAC;oBACzB,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC;gBAC9C,CAAC;gBAED,MAAM,CAAC,IAAI,CACT,mBAAmB,IAAI,CAAC,QAAQ,kCAAkC;oBAChE,iIAAiI,CACpI,CAAC;gBAEF,OAAO,IAAI,CAAC,IAAI,EAAE,CAAC;YACrB,CAAC;YAED,MAAM,CAAC,CAAC;QACV,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,eAAe;QAC3B,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;QACnD,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;YACnB,MAAM,IAAI,KAAK,CAAC,kDAAkD,CAAC,CAAC;QACtE,CAAC;QACD,aAAa;QACb,yIAAyI;QACzI,OAAO,KAAK,CAAC;IACf,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,iBAAiB;QACrB,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,qBAAqB,CAAC,iBAAiB,EAAE,CAAC;QACnE,OAAO,KAAK,CAAC;IACf,CAAC;IAED,KAAK,CAAC,uBAAuB;QAC3B,OAAO,CAAC,MAAM,IAAI,CAAC,iBAAiB,EAAE,CAAC,CAAC,YAAY,CAAC;IACvD,CAAC;IAED,KAAK,CAAC,kBAAkB;QACtB,OAAO,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,sBAAsB,EAAE,CAAC,CAAC,YAAY,CAAC;IACnE,CAAC;IAED,UAAU;QACR,IAAA,gBAAM,EAAC,IAAI,CAAC,OAAO,EAAE,8BAA8B,CAAC,CAAC;QACrD,OAAO,IAAI,CAAC,OAAO,CAAC;IACtB,CAAC;IAED,cAAc;QACZ,OAAO,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC;IACtC,CAAC;IAED,cAAc;QACZ,IAAA,gBAAM,EAAC,IAAI,CAAC,WAAW,EAAE,8BAA8B,CAAC,CAAC;QACzD,OAAO,IAAI,CAAC,WAAW,CAAC;IAC1B,CAAC;IAED,KAAK,CAAC,sBAAsB,CAC1B,YAA6B;QAE7B,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,oBAAoB,CAAC,YAAY,CAAC,CAAC;QACnE,IAAI,CAAC,IAAA,iCAAgB,EAAC,KAAK,CAAC,EAAE,CAAC;YAC7B,MAAM,SAAS,KAAK,4CAA4C,KAAK,CAAC,WAAW,EAAE,CAAC;QACtF,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,WAAmB;QAClC,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,sBAAsB,CAAC,WAAW,CAAC,CAAC;YAChE,MAAM,cAAc,GAAG,IAAA,4BAAW,EAAC,QAAQ,CAAC,CAAC;YAE7C,MAAM,qBAAqB,GAAG,QAAQ,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,KAAK,EAAE,EAAE;gBACpE,MAAM,oBAAoB,GAAG,IAAA,kCAAiB,EAC5C,EAAE,EACF,cAAc,EACd,KAAK,CACN,CAAC;gBACF,OAAO;oBACL,GAAG,oBAAoB;oBACvB,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,EAAE,CAC1C,IAAA,0BAAS,EAAC,CAAC,EAAE,QAAQ,EAAE,oBAAoB,EAAE,cAAc,CAAC,CAC7D;iBACF,CAAC;YACJ,CAAC,CAAC,CAAC;YAEH,MAAM,IAAI,GAAkB,qBAAqB,CAAC,OAAO,CAAC,CAAC,EAAE,EAAE,EAAE,CAC/D,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;gBAClB,GAAG,CAAC;gBACJ,WAAW,EAAE,EAAE;aAChB,CAAC,CAAC,CACJ,CAAC;YAEF,MAAM,KAAK,GAAkB;gBAC3B,GAAG,cAAc;gBACjB,YAAY,EAAE,qBAAqB;gBACnC,IAAI;aACL,CAAC;YAEF,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;YACrC,OAAO,IAAA,gCAAe,EAAC,KAAK,CAAC,CAAC;QAChC,CAAC;QAAC,OAAO,CAAM,EAAE,CAAC;YAChB,MAAM,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;QAC5B,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,eAAe,CAC3B,WAAmB;QAEnB,MAAM,KAAK,GAAG,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,oBAAoB,CACnD,WAAW,CACZ,CAA8B,CAAC;QAChC,MAAM,UAAU,GAAuB;YACrC,GAAG,KAAK;YACR,SAAS,EAAE,KAAK,CAAC,UAAU;YAC3B,WAAW,EAAE,KAAK,CAAC,YAAY;YAC/B,UAAU,EAAE,KAAK,CAAC,WAAW;YAC7B,OAAO,EAAE,KAAK,CAAC,QAAQ;YACvB,gBAAgB,EAAE,KAAK,CAAC,iBAAiB;YACzC,UAAU,EAAE,KAAK,CAAC,YAAY;YAC9B,eAAe,EAAE,KAAK,CAAC,gBAAgB;YACvC,IAAI,EAAE,EAAE;SACT,CAAC;QACF,OAAO,IAAA,gCAAe,EAAqB,UAAU,CAAC,CAAC;IACzD,CAAC;IAED,KAAK,CAAC,WAAW,CAAC,YAAsB;QACtC,OAAO,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IAC5E,CAAC;IAED,KAAK,CAAC,gBAAgB,CACpB,YAAsB;QAEtB,OAAO,OAAO,CAAC,GAAG,CAChB,YAAY,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC,CAC3D,CAAC;IACJ,CAAC;IAED,IAAI,GAAG;QACL,OAAO,IAAI,CAAC,MAAM,CAAC;IACrB,CAAC;IAEO,cAAc,CAAC,OAAe,EAAE,MAA8B;QACpE,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;YACrB,MAAM,IAAI,KAAK,CAAC,cAAc,OAAO,4BAA4B,CAAC,CAAC;QACrE,CAAC;QAED,uFAAuF;QACvF,IAAI,CAAC,IAAI,CAAC,kBAAkB,CAAC,OAAO,CAAC,EAAE,CAAC;YACtC,+CAA+C;YAC/C,IAAI,CAAC;gBACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC;gBAE3C,IAAI,CAAC,kBAAkB,CAAC,OAAO,CAAC,GAAG,MAAM,CAAC;YAC5C,CAAC;YAAC,OAAO,CAAM,EAAE,CAAC;gBAChB,MAAM,CAAC,KAAK,CAAC,wBAAwB,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;gBAClD,MAAM,IAAI,KAAK,CAAC,gBAAgB,CAAC,CAAC;YACpC,CAAC;QACH,CAAC;QAED,OAAO,IAAI,CAAC,kBAAkB,CAAC,OAAO,CAAC,CAAC;IAC1C,CAAC;IAED,KAAK,CAAC,QAAQ,CACZ,GAAgB,EAChB,EAA6B;QAE7B,IAAI,CAAC;YACH,IAAI,CAAC,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC;gBACtB,MAAM,CAAC,IAAI,CAAC,gCAAgC,CAAC,CAAC;gBAC9C,OAAO,GAAG,CAAC;YACb,CAAC;YACD,MAAM,YAAY,GAAG,IAAA,gCAAe,EAAC,GAAG,CAAC,CAAC;YAC1C,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,EAAE,CAAC,CAAC;YACpC,MAAM,IAAI,GAAG,IAAI,CAAC,cAAc,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;YACzD,MAAM,SAAS,GAAG,iBAAM,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;YAC5C,MAAM,UAAU,GAAG,mBAAQ,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;YAC/C,MAAM,QAAQ,GAAG,mBAAQ,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;YAC3C,MAAM,CAAC,MAAM,CAAC,GAAG,iBAAM,CAAC,WAAW,CACjC,CAAC,YAAY,CAAC,EACd,SAAS,EACT,UAAU,EACV,QAAQ,CACT,CAAC;YACF,GAAG,CAAC,IAAI,GAAG,MAAW,CAAC;YACvB,OAAO,GAAG,CAAC;QACb,CAAC;QAAC,OAAO,CAAM,EAAE,CAAC;YAChB,MAAM,CAAC,IAAI,CAAC,6BAA6B,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;YACtD,OAAO,GAAG,CAAC;QACb,CAAC;IACH,CAAC;IAED,KAAK,CAAC,gBAAgB,CACpB,WAAgC,EAChC,EAA6B;QAE7B,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,EAAE,CAAC,CAAC;YACpC,iDAAiD;YACjD,IAAI,CAAC,WAAW,CAAC,YAAY,EAAE,CAAC;gBAC9B,WAAW,CAAC,YAAY,GAAG,WAAW,CAAC,aAAa,EAAE,CAAC;YACzD,CAAC;YACD,IAAI,WAAW,CAAC,YAAY,IAAI,WAAW,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACpE,MAAM,IAAI,CAAC,sBAAsB,CAAC,WAAW,CAAC,YAAY,EAAE,EAAE,EAAE,MAAM,CAAC,CAAC;YAC1E,CAAC;iBAAM,CAAC;gBACN,MAAM,CAAC,IAAI,CACT,0FAA0F,WAAW,CAAC,IAAI,EAAE,CAC7G,CAAC;YACJ,CAAC;YACD,WAAW,CAAC,IAAI;gBACd,WAAW,CAAC,IAAI;oBACf,CAAC,MAAM,OAAO,CAAC,GAAG,CACjB,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,CAC5D,CAAyC,CAAC;YAE7C,OAAO,WAAW,CAAC;QACrB,CAAC;QAAC,OAAO,CAAM,EAAE,CAAC;YAChB,MAAM,CAAC,IAAI,CAAC,qCAAqC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;YAC9D,OAAO,WAAW,CAAC;QACrB,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,sBAAsB,CAClC,YAAoC,EACpC,EAA6B,EAC7B,MAA8B;QAE9B,MAAM,OAAO,CAAC,GAAG,CACf,YAAY,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;YAC9B,IAAI,IAAS,CAAC;YACd,IAAI,CAAC;gBACH,IACE,EAAE,CAAC,OAAO,EAAE,OAAO;oBACnB,IAAA,sBAAK,EAAC,EAAE,CAAC,OAAO,CAAC,OAAO,EAAE,IAAI,CAAC,EAAE,CAAC;oBAClC,EAAE,CAAC,OAAO,CAAC,GAAG,EACd,CAAC;oBACD,IAAI,GAAG,IAAI,CAAC,cAAc,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;gBACrD,CAAC;qBAAM,CAAC;oBACN,mHAAmH;oBACnH,IAAI,CAAC,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC;wBACtC,IAAI,GAAG,MAAM,IAAA,4CAA2B,EAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;oBACjE,CAAC;yBAAM,CAAC;wBACN,IAAI,GAAG,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;oBAC1C,CAAC;gBACH,CAAC;gBACD,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC,qBAAqB,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;YACnE,CAAC;YAAC,OAAO,CAAM,EAAE,CAAC;gBAChB,MAAM,CAAC,IAAI,CACT,oDAAoD,IAAI,CAAC,EAAE,KAAK,CAAC,CAAC,OAAO,EAAE,CAC5E,CAAC;YACJ,CAAC;QACH,CAAC,CAAC,CACH,CAAC;IACJ,CAAC;IAED,MAAM,CAAC,qBAAqB,CAAC,IAAS,EAAE,IAA0B;QAChE,MAAM,QAAQ,GAAG,IAAI,mBAAQ,CAAC,IAAI,CAAC,CAAC;QACpC,MAAM,EAAE,MAAM,EAAE,GAAG,QAAQ,CAAC,MAAM;aAC/B,eAAe,EAAE;aACjB,IAAI,CACH,CAAC,OAAiB,EAAE,EAAE,CACpB,IAAA,oCAAmB,EAAC,OAAO,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC,QAAQ,CACvC,CAAC;QACnB,MAAM,WAAW,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,GAAQ,EAAE,EAAE;YAC1C,OAAO,GAAG,CAAC,IAAc,CAAC;QAC5B,CAAC,CAAC,CAAC;QACH,MAAM,GAAG,GAAG,QAAQ,CAAC,gBAAgB,CAAC,WAAW,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;QAClE,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE;YAChD,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC;YAC5B,OAAO,GAAG,CAAC;QACb,CAAC,EAAE,EAAE,CAAC,CAAC;QACP,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,4DAA4D;IAC5D,KAAK,CAAC,OAAO;QACX,MAAM,CAAC,KAAK,CAAC,yCAAyC,CAAC,CAAC;QACxD,MAAM,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAC;IACrC,CAAC;IAED,MAAM;IACN,KAAK,CAAC,UAAU;QACd,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC;IAC3B,CAAC;IAED,WAAW,CAAC,CAAQ;QAClB,IAAK,CAAS,EAAE,MAAM,KAAK,GAAG,EAAE,CAAC;YAC/B,MAAM,EAAE,QAAQ,EAAE,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YAC5C,OAAO,IAAI,KAAK,CAAC,6BAA6B,QAAQ,EAAE,CAAC,CAAC;QAC5D,CAAC;QAED,OAAO,CAAC,CAAC;IACX,CAAC;IAED,UAAU,CAAC,MAAc;QACvB,OAAO,IAAI,kBAAoB,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACvD,CAAC;CACF;AA7WD,kCA6WC","sourcesContent":["// Copyright 2020-2025 SubQuery Pte Ltd authors & contributors\n// SPDX-License-Identifier: GPL-3.0\n\nimport assert from 'assert';\nimport fs from 'fs';\nimport { EventEmitter2 } from '@nestjs/event-emitter';\nimport { BlockWithTxs } from '@starknet-io/types-js';\nimport { getLogger, IBlock } from '@subql/node-core';\nimport {\n ApiWrapper,\n StarknetBlock,\n StarknetRuntimeDatasource,\n IStarknetEndpointConfig,\n LightStarknetBlock,\n StarknetResult,\n StarknetTransaction,\n StarknetLog,\n StarknetContractCall,\n} from '@subql/types-starknet';\nimport {\n ProviderInterface,\n RpcProvider,\n RpcProviderOptions,\n events,\n CallData,\n Abi,\n AbiEntry,\n FunctionAbi,\n} from 'starknet';\nimport { SPEC } from 'starknet-types-07';\nimport {\n FinalizedBlockService,\n HEADER_WITH_STATUS,\n} from './finalized.block.starknet';\nimport SafeStarknetProvider from './safe-api';\nimport {\n hexEq,\n encodeSelectorToHex,\n fetchAbiFromContractAddress,\n formatBlock,\n formatBlockUtil,\n formatLog,\n formatTransaction,\n reverseToRawLog,\n isFinalizedBlock,\n} from './utils.starknet';\n\n// eslint-disable-next-line @typescript-eslint/no-var-requires\nconst { version: packageVersion } = require('../../package.json');\n\nconst logger = getLogger('api.starknet');\n\nasync function loadAssets(\n ds: StarknetRuntimeDatasource,\n): Promise<Record<string, string>> {\n if (!ds.assets) {\n return {};\n }\n const res: Record<string, string> = {};\n\n for (const [name, { file }] of ds.assets.entries()) {\n try {\n res[name] = await fs.promises.readFile(file, { encoding: 'utf8' });\n } catch (e) {\n throw new Error(`Failed to load datasource asset ${file}`);\n }\n }\n\n return res;\n}\n\nexport class StarknetApi implements ApiWrapper {\n private client: RpcProvider;\n\n // This is used within the sandbox when HTTP is used\n private nonBatchClient?: SafeStarknetProvider;\n private _genesisBlock?: Record<string, any>;\n private contractInterfaces: Record<string, Abi> = {};\n private chainId?: string;\n private specVersion?: string;\n private finalizedBlockService: FinalizedBlockService;\n\n // Starknet POS\n private _supportsFinalization = true;\n\n get supportsFinalization(): boolean {\n return this._supportsFinalization;\n }\n\n /**\n * @param {string} endpoint - The endpoint of the RPC provider\n * @param {object} eventEmitter - Used to monitor the number of RPC requests\n */\n constructor(\n private endpoint: string,\n private eventEmitter: EventEmitter2,\n private config?: IStarknetEndpointConfig,\n ) {\n const { hostname, protocol, searchParams } = new URL(endpoint);\n\n const protocolStr = protocol.replace(':', '');\n\n logger.info(`Api host: ${hostname}, method: ${protocolStr}`);\n\n if (protocolStr !== 'https' && protocolStr !== 'http') {\n throw new Error(`Unsupported protocol: ${protocol}`);\n }\n const connection: RpcProviderOptions | ProviderInterface = {\n nodeUrl: this.endpoint,\n headers: {\n 'User-Agent': `Subquery-Node ${packageVersion}`,\n ...config?.headers,\n },\n batch: this.config?.batchSize ?? false,\n };\n searchParams.forEach((value, name) => {\n (connection.headers as any)[name] = value;\n });\n this.client = new RpcProvider(connection);\n this.finalizedBlockService = new FinalizedBlockService(\n this.getBlockByHeightOrHash.bind(this),\n logger,\n );\n }\n\n private get genesisBlock(): Record<string, any> {\n if (!this._genesisBlock) {\n throw new Error('Genesis block is not available');\n }\n return this._genesisBlock;\n }\n\n async init(): Promise<void> {\n try {\n this._genesisBlock = await this.getGenesisBlock();\n this.chainId = await this.client.getChainId();\n this.specVersion = await this.client.getSpecVersion();\n } catch (e) {\n if ((e as Error).message.startsWith('Invalid response')) {\n if (!this.nonBatchClient) {\n throw new Error('No suitable client found');\n }\n\n logger.warn(\n `The RPC Node at ${this.endpoint} cannot process batch requests. ` +\n `Switching to non-batch mode for subsequent requests. Please consider checking if batch processing is supported on the RPC node.`,\n );\n\n return this.init();\n }\n\n throw e;\n }\n }\n\n private async getGenesisBlock(): Promise<BlockWithTxs> {\n const block = await this.client.getBlockWithTxs(1);\n if (block === null) {\n throw new Error(`Getting genesis block returned null from block 1`);\n }\n // @ts-ignore\n // TODO, @starknet-io/types-js is not align with starknet rpc types, follow this ticket https://github.com/starknet-io/types-js/issues/31\n return block;\n }\n\n /***\n * Get the latest block (with its header)\n * @returns {Promise<BLOCK_HEADER>}\n */\n async getFinalizedBlock(): Promise<HEADER_WITH_STATUS> {\n const block = await this.finalizedBlockService.getFinalizedBlock();\n return block;\n }\n\n async getFinalizedBlockHeight(): Promise<number> {\n return (await this.getFinalizedBlock()).block_number;\n }\n\n async getBestBlockHeight(): Promise<number> {\n return (await this.client.getBlockLatestAccepted()).block_number;\n }\n\n getChainId(): string {\n assert(this.chainId, 'Api has not been initialised');\n return this.chainId;\n }\n\n getGenesisHash(): string {\n return this.genesisBlock.block_hash;\n }\n\n getSpecVersion(): string {\n assert(this.specVersion, 'Api has not been initialised');\n return this.specVersion;\n }\n\n async getBlockByHeightOrHash(\n heightOrHash: number | string,\n ): Promise<SPEC.BLOCK_WITH_RECEIPTS> {\n const block = await this.client.getBlockWithReceipts(heightOrHash);\n if (!isFinalizedBlock(block)) {\n throw `Block ${block} is not a fulfilled block, its parent is ${block.parent_hash}`;\n }\n return block;\n }\n\n async fetchBlock(blockNumber: number): Promise<IBlock<StarknetBlock>> {\n try {\n const rawBlock = await this.getBlockByHeightOrHash(blockNumber);\n const formattedBlock = formatBlock(rawBlock);\n\n const formattedTransactions = rawBlock.transactions.map((tx, index) => {\n const formattedTransaction = formatTransaction(\n tx,\n formattedBlock,\n index,\n );\n return {\n ...formattedTransaction,\n logs: tx.receipt.events.map((l, logIndex) =>\n formatLog(l, logIndex, formattedTransaction, formattedBlock),\n ),\n };\n });\n\n const logs: StarknetLog[] = formattedTransactions.flatMap((tx) =>\n tx.logs.map((l) => ({\n ...l,\n transaction: tx,\n })),\n );\n\n const block: StarknetBlock = {\n ...formattedBlock,\n transactions: formattedTransactions,\n logs,\n };\n\n this.eventEmitter.emit('fetchBlock');\n return formatBlockUtil(block);\n } catch (e: any) {\n throw this.handleError(e);\n }\n }\n\n private async fetchLightBlock(\n blockNumber: number,\n ): Promise<IBlock<LightStarknetBlock>> {\n const block = (await this.client.getBlockWithTxHashes(\n blockNumber,\n )) as SPEC.BLOCK_WITH_TX_HASHES;\n const lightBlock: LightStarknetBlock = {\n ...block,\n blockHash: block.block_hash,\n blockNumber: block.block_number,\n parentHash: block.parent_hash,\n newRoot: block.new_root,\n sequencerAddress: block.sequencer_address,\n l1GasPrice: block.l1_gas_price,\n starknetVersion: block.starknet_version,\n logs: [],\n };\n return formatBlockUtil<LightStarknetBlock>(lightBlock);\n }\n\n async fetchBlocks(bufferBlocks: number[]): Promise<IBlock<StarknetBlock>[]> {\n return Promise.all(bufferBlocks.map(async (num) => this.fetchBlock(num)));\n }\n\n async fetchBlocksLight(\n bufferBlocks: number[],\n ): Promise<IBlock<LightStarknetBlock>[]> {\n return Promise.all(\n bufferBlocks.map(async (num) => this.fetchLightBlock(num)),\n );\n }\n\n get api(): RpcProvider {\n return this.client;\n }\n\n private buildInterface(abiName: string, assets: Record<string, string>): Abi {\n if (!assets[abiName]) {\n throw new Error(`ABI named \"${abiName}\" not referenced in assets`);\n }\n\n // This assumes that all datasources have a different abi name or they are the same abi\n if (!this.contractInterfaces[abiName]) {\n // Constructing the interface validates the ABI\n try {\n const abiObj = JSON.parse(assets[abiName]);\n\n this.contractInterfaces[abiName] = abiObj;\n } catch (e: any) {\n logger.error(`Unable to parse ABI: ${e.message}`);\n throw new Error('ABI is invalid');\n }\n }\n\n return this.contractInterfaces[abiName];\n }\n\n async parseLog<T extends StarknetResult = StarknetResult>(\n log: StarknetLog,\n ds: StarknetRuntimeDatasource,\n ): Promise<StarknetLog | StarknetLog<T>> {\n try {\n if (!ds?.options?.abi) {\n logger.warn('No ABI provided for datasource');\n return log;\n }\n const emittedEvent = reverseToRawLog(log);\n const assets = await loadAssets(ds);\n const iAbi = this.buildInterface(ds.options.abi, assets);\n const abiEvents = events.getAbiEvents(iAbi);\n const abiStructs = CallData.getAbiStruct(iAbi);\n const abiEnums = CallData.getAbiEnum(iAbi);\n const [parsed] = events.parseEvents(\n [emittedEvent],\n abiEvents,\n abiStructs,\n abiEnums,\n );\n log.args = parsed as T;\n return log;\n } catch (e: any) {\n logger.warn(`Failed to parse log data: ${e.message}`);\n return log;\n }\n }\n\n async parseTransaction<T extends StarknetResult = StarknetResult>(\n transaction: StarknetTransaction,\n ds: StarknetRuntimeDatasource,\n ): Promise<StarknetTransaction> {\n try {\n const assets = await loadAssets(ds);\n // If decoded calls not exist, try to parse first\n if (!transaction.decodedCalls) {\n transaction.decodedCalls = transaction.parseCallData();\n }\n if (transaction.decodedCalls && transaction.decodedCalls.length > 0) {\n await this.handleDecodedCallsArgs(transaction.decodedCalls, ds, assets);\n } else {\n logger.warn(\n `No decoded calls found in transaction, will skip decode call data for this transaction ${transaction.hash}`,\n );\n }\n transaction.logs =\n transaction.logs &&\n ((await Promise.all(\n transaction.logs.map(async (log) => this.parseLog(log, ds)),\n )) as Array<StarknetLog | StarknetLog<T>>);\n\n return transaction;\n } catch (e: any) {\n logger.warn(`Failed to parse transaction data: ${e.message}`);\n return transaction;\n }\n }\n\n private async handleDecodedCallsArgs(\n decodedCalls: StarknetContractCall[],\n ds: StarknetRuntimeDatasource,\n assets: Record<string, string>,\n ): Promise<void> {\n await Promise.all(\n decodedCalls.map(async (call) => {\n let iAbi: Abi;\n try {\n if (\n ds.options?.address &&\n hexEq(ds.options.address, call.to) &&\n ds.options.abi\n ) {\n iAbi = this.buildInterface(ds.options.abi, assets);\n } else {\n //We could register this abi in memory improve performance, maybe just record with address instead of abi name here\n if (!this.contractInterfaces[call.to]) {\n iAbi = await fetchAbiFromContractAddress(this.client, call.to);\n } else {\n iAbi = this.contractInterfaces[call.to];\n }\n }\n call.decodedArgs = StarknetApi.DecodeCallDataWithAbi(iAbi, call);\n } catch (e: any) {\n logger.warn(\n `Could not decode call data with contract address ${call.to}: ${e.message}`,\n );\n }\n }),\n );\n }\n\n static DecodeCallDataWithAbi(iAbi: Abi, call: StarknetContractCall): any {\n const callData = new CallData(iAbi);\n const { inputs } = callData.parser\n .getLegacyFormat()\n .find(\n (abiItem: AbiEntry) =>\n encodeSelectorToHex(abiItem.name) === call.selector,\n ) as FunctionAbi;\n const inputsTypes = inputs.map((inp: any) => {\n return inp.type as string;\n });\n const res = callData.decodeParameters(inputsTypes, call.calldata);\n const result = inputs.reduce((acc, item, index) => {\n acc[item.name] = res[index];\n return acc;\n }, {});\n return result;\n }\n\n // eslint-disable-next-line @typescript-eslint/require-await\n async connect(): Promise<void> {\n logger.error('Starknet API connect is not implemented');\n throw new Error('Not implemented');\n }\n\n //TODO\n async disconnect(): Promise<void> {\n return Promise.resolve();\n }\n\n handleError(e: Error): Error {\n if ((e as any)?.status === 429) {\n const { hostname } = new URL(this.endpoint);\n return new Error(`Rate Limited at endpoint: ${hostname}`);\n }\n\n return e;\n }\n\n getSafeApi(height: number) {\n return new SafeStarknetProvider(this.client, height);\n }\n}\n"]}
1
+ {"version":3,"file":"api.starknet.js","sourceRoot":"","sources":["../../src/starknet/api.starknet.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 assert from 'assert';\nimport fs from 'fs';\nimport { EventEmitter2 } from '@nestjs/event-emitter';\nimport { BlockWithTxs } from '@starknet-io/types-js';\nimport { getLogger, IBlock } from '@subql/node-core';\nimport {\n ApiWrapper,\n StarknetBlock,\n StarknetRuntimeDatasource,\n IStarknetEndpointConfig,\n LightStarknetBlock,\n StarknetResult,\n StarknetTransaction,\n StarknetLog,\n StarknetContractCall,\n} from '@subql/types-starknet';\nimport {\n ProviderInterface,\n RpcProvider,\n RpcProviderOptions,\n events,\n CallData,\n Abi,\n AbiEntry,\n FunctionAbi,\n BlockIdentifier,\n} from 'starknet';\nimport { SPEC } from 'starknet-types-07';\nimport {\n FinalizedBlockService,\n HEADER_WITH_STATUS,\n} from './finalized.block.starknet';\nimport SafeStarknetProvider from './safe-api';\nimport {\n hexEq,\n encodeSelectorToHex,\n fetchAbiFromContractAddress,\n formatBlock,\n formatBlockUtil,\n formatLog,\n formatTransaction,\n reverseToRawLog,\n isFinalizedBlock,\n} from './utils.starknet';\n\n// eslint-disable-next-line @typescript-eslint/no-var-requires\nconst { version: packageVersion } = require('../../package.json');\n\nconst logger = getLogger('api.starknet');\n\nasync function loadAssets(\n ds: StarknetRuntimeDatasource,\n): Promise<Record<string, string>> {\n if (!ds.assets) {\n return {};\n }\n const res: Record<string, string> = {};\n\n for (const [name, { file }] of ds.assets.entries()) {\n try {\n res[name] = await fs.promises.readFile(file, { encoding: 'utf8' });\n } catch (e) {\n throw new Error(`Failed to load datasource asset ${file}`);\n }\n }\n\n return res;\n}\n\nexport class StarknetApi implements ApiWrapper {\n private client: RpcProvider;\n\n // This is used within the sandbox when HTTP is used\n private nonBatchClient?: SafeStarknetProvider;\n private _genesisBlock?: Record<string, any>;\n private contractInterfaces: Record<string, Abi> = {};\n private chainId?: string;\n private specVersion?: string;\n private finalizedBlockService: FinalizedBlockService;\n\n // Starknet POS\n private _supportsFinalization = true;\n\n get supportsFinalization(): boolean {\n return this._supportsFinalization;\n }\n\n /**\n * @param {string} endpoint - The endpoint of the RPC provider\n * @param {object} eventEmitter - Used to monitor the number of RPC requests\n */\n constructor(\n private endpoint: string,\n private eventEmitter: EventEmitter2,\n private config?: IStarknetEndpointConfig,\n ) {\n const { hostname, protocol, searchParams } = new URL(endpoint);\n\n const protocolStr = protocol.replace(':', '');\n\n logger.info(`Api host: ${hostname}, method: ${protocolStr}`);\n\n if (protocolStr !== 'https' && protocolStr !== 'http') {\n throw new Error(`Unsupported protocol: ${protocol}`);\n }\n const connection: RpcProviderOptions | ProviderInterface = {\n nodeUrl: this.endpoint,\n headers: {\n 'User-Agent': `Subquery-Node ${packageVersion}`,\n ...config?.headers,\n },\n batch: this.config?.batchSize ?? false,\n };\n searchParams.forEach((value, name) => {\n (connection.headers as any)[name] = value;\n });\n this.client = new RpcProvider(connection);\n this.finalizedBlockService = new FinalizedBlockService(\n this.getBlockByHeightOrHash.bind(this),\n logger,\n );\n }\n\n private get genesisBlock(): Record<string, any> {\n if (!this._genesisBlock) {\n throw new Error('Genesis block is not available');\n }\n return this._genesisBlock;\n }\n\n async init(): Promise<void> {\n try {\n this._genesisBlock = await this.getGenesisBlock();\n this.chainId = await this.client.getChainId();\n this.specVersion = await this.client.getSpecVersion();\n } catch (e) {\n if ((e as Error).message.startsWith('Invalid response')) {\n if (!this.nonBatchClient) {\n throw new Error('No suitable client found');\n }\n\n logger.warn(\n `The RPC Node at ${this.endpoint} cannot process batch requests. ` +\n `Switching to non-batch mode for subsequent requests. Please consider checking if batch processing is supported on the RPC node.`,\n );\n\n return this.init();\n }\n\n throw e;\n }\n }\n\n private async getGenesisBlock(): Promise<BlockWithTxs> {\n const block = await this.client.getBlockWithTxs(1);\n if (block === null) {\n throw new Error(`Getting genesis block returned null from block 1`);\n }\n // @ts-ignore\n // TODO, @starknet-io/types-js is not align with starknet rpc types, follow this ticket https://github.com/starknet-io/types-js/issues/31\n return block;\n }\n\n /***\n * Get the latest block (with its header)\n * @returns {Promise<BLOCK_HEADER>}\n */\n async getFinalizedBlock(): Promise<HEADER_WITH_STATUS> {\n const block = await this.finalizedBlockService.getFinalizedBlock();\n return block;\n }\n\n async getBestBlockHeight(): Promise<number> {\n return (await this.client.getBlockLatestAccepted()).block_number;\n }\n\n getChainId(): string {\n assert(this.chainId, 'Api has not been initialised');\n return this.chainId;\n }\n\n getGenesisHash(): string {\n return this.genesisBlock.block_hash;\n }\n\n getSpecVersion(): string {\n assert(this.specVersion, 'Api has not been initialised');\n return this.specVersion;\n }\n\n async getBlockByHeightOrHash(\n heightOrHash: number | string,\n ): Promise<SPEC.BLOCK_WITH_RECEIPTS> {\n const block = await this.client.getBlockWithReceipts(heightOrHash);\n if (!isFinalizedBlock(block)) {\n throw `Block ${block} is not a fulfilled block, its parent is ${block.parent_hash}`;\n }\n return block;\n }\n\n async fetchBlock(blockNumber: number): Promise<IBlock<StarknetBlock>> {\n try {\n const rawBlock = await this.getBlockByHeightOrHash(blockNumber);\n const formattedBlock = formatBlock(rawBlock);\n\n const formattedTransactions = rawBlock.transactions.map((tx, index) => {\n const formattedTransaction = formatTransaction(\n tx,\n formattedBlock,\n index,\n );\n return {\n ...formattedTransaction,\n logs: tx.receipt.events.map((l, logIndex) =>\n formatLog(l, logIndex, formattedTransaction, formattedBlock),\n ),\n };\n });\n\n const logs: StarknetLog[] = formattedTransactions.flatMap((tx) =>\n tx.logs.map((l) => ({\n ...l,\n transaction: tx,\n })),\n );\n\n const block: StarknetBlock = {\n ...formattedBlock,\n transactions: formattedTransactions,\n logs,\n };\n\n this.eventEmitter.emit('fetchBlock');\n return formatBlockUtil(block);\n } catch (e: any) {\n throw this.handleError(e);\n }\n }\n\n async fetchLightBlock(\n blockNumber: BlockIdentifier,\n ): Promise<IBlock<LightStarknetBlock>> {\n // Cast to remove PENDING_BLOCK_WITH_TX_HASHES type\n const block = (await this.client.getBlockWithTxHashes(\n blockNumber,\n )) as SPEC.BLOCK_WITH_TX_HASHES;\n const lightBlock: LightStarknetBlock = {\n ...block,\n blockHash: block.block_hash,\n blockNumber: block.block_number,\n parentHash: block.parent_hash,\n newRoot: block.new_root,\n sequencerAddress: block.sequencer_address,\n l1GasPrice: block.l1_gas_price,\n starknetVersion: block.starknet_version,\n logs: [],\n };\n return formatBlockUtil<LightStarknetBlock>(lightBlock);\n }\n\n async fetchBlocks(bufferBlocks: number[]): Promise<IBlock<StarknetBlock>[]> {\n return Promise.all(bufferBlocks.map(async (num) => this.fetchBlock(num)));\n }\n\n async fetchBlocksLight(\n bufferBlocks: number[],\n ): Promise<IBlock<LightStarknetBlock>[]> {\n return Promise.all(\n bufferBlocks.map(async (num) => this.fetchLightBlock(num)),\n );\n }\n\n get api(): RpcProvider {\n return this.client;\n }\n\n private buildInterface(abiName: string, assets: Record<string, string>): Abi {\n if (!assets[abiName]) {\n throw new Error(`ABI named \"${abiName}\" not referenced in assets`);\n }\n\n // This assumes that all datasources have a different abi name or they are the same abi\n if (!this.contractInterfaces[abiName]) {\n // Constructing the interface validates the ABI\n try {\n const abiObj = JSON.parse(assets[abiName]);\n\n this.contractInterfaces[abiName] = abiObj;\n } catch (e: any) {\n logger.error(`Unable to parse ABI: ${e.message}`);\n throw new Error('ABI is invalid');\n }\n }\n\n return this.contractInterfaces[abiName];\n }\n\n async parseLog<T extends StarknetResult = StarknetResult>(\n log: StarknetLog,\n ds: StarknetRuntimeDatasource,\n ): Promise<StarknetLog | StarknetLog<T>> {\n try {\n if (!ds?.options?.abi) {\n logger.warn('No ABI provided for datasource');\n return log;\n }\n const emittedEvent = reverseToRawLog(log);\n const assets = await loadAssets(ds);\n const iAbi = this.buildInterface(ds.options.abi, assets);\n const abiEvents = events.getAbiEvents(iAbi);\n const abiStructs = CallData.getAbiStruct(iAbi);\n const abiEnums = CallData.getAbiEnum(iAbi);\n const [parsed] = events.parseEvents(\n [emittedEvent],\n abiEvents,\n abiStructs,\n abiEnums,\n );\n log.args = parsed as T;\n return log;\n } catch (e: any) {\n logger.warn(`Failed to parse log data: ${e.message}`);\n return log;\n }\n }\n\n async parseTransaction<T extends StarknetResult = StarknetResult>(\n transaction: StarknetTransaction,\n ds: StarknetRuntimeDatasource,\n ): Promise<StarknetTransaction> {\n try {\n const assets = await loadAssets(ds);\n // If decoded calls not exist, try to parse first\n if (!transaction.decodedCalls) {\n transaction.decodedCalls = transaction.parseCallData();\n }\n if (transaction.decodedCalls && transaction.decodedCalls.length > 0) {\n await this.handleDecodedCallsArgs(transaction.decodedCalls, ds, assets);\n } else {\n logger.warn(\n `No decoded calls found in transaction, will skip decode call data for this transaction ${transaction.hash}`,\n );\n }\n transaction.logs =\n transaction.logs &&\n ((await Promise.all(\n transaction.logs.map(async (log) => this.parseLog(log, ds)),\n )) as Array<StarknetLog | StarknetLog<T>>);\n\n return transaction;\n } catch (e: any) {\n logger.warn(`Failed to parse transaction data: ${e.message}`);\n return transaction;\n }\n }\n\n private async handleDecodedCallsArgs(\n decodedCalls: StarknetContractCall[],\n ds: StarknetRuntimeDatasource,\n assets: Record<string, string>,\n ): Promise<void> {\n await Promise.all(\n decodedCalls.map(async (call) => {\n let iAbi: Abi;\n try {\n if (\n ds.options?.address &&\n hexEq(ds.options.address, call.to) &&\n ds.options.abi\n ) {\n iAbi = this.buildInterface(ds.options.abi, assets);\n } else {\n //We could register this abi in memory improve performance, maybe just record with address instead of abi name here\n if (!this.contractInterfaces[call.to]) {\n iAbi = await fetchAbiFromContractAddress(this.client, call.to);\n } else {\n iAbi = this.contractInterfaces[call.to];\n }\n }\n call.decodedArgs = StarknetApi.DecodeCallDataWithAbi(iAbi, call);\n } catch (e: any) {\n logger.warn(\n `Could not decode call data with contract address ${call.to}: ${e.message}`,\n );\n }\n }),\n );\n }\n\n static DecodeCallDataWithAbi(iAbi: Abi, call: StarknetContractCall): any {\n const callData = new CallData(iAbi);\n const { inputs } = callData.parser\n .getLegacyFormat()\n .find(\n (abiItem: AbiEntry) =>\n encodeSelectorToHex(abiItem.name) === call.selector,\n ) as FunctionAbi;\n const inputsTypes = inputs.map((inp: any) => {\n return inp.type as string;\n });\n const res = callData.decodeParameters(inputsTypes, call.calldata);\n const result = inputs.reduce((acc, item, index) => {\n acc[item.name] = res[index];\n return acc;\n }, {});\n return result;\n }\n\n // eslint-disable-next-line @typescript-eslint/require-await\n async connect(): Promise<void> {\n logger.error('Starknet API connect is not implemented');\n throw new Error('Not implemented');\n }\n\n //TODO\n async disconnect(): Promise<void> {\n return Promise.resolve();\n }\n\n handleError(e: Error): Error {\n if ((e as any)?.status === 429) {\n const { hostname } = new URL(this.endpoint);\n return new Error(`Rate Limited at endpoint: ${hostname}`);\n }\n\n return e;\n }\n\n getSafeApi(height: number): SafeStarknetProvider {\n return new SafeStarknetProvider(this.client, height);\n }\n}\n"]}
@@ -155,4 +155,4 @@ describe('block filters', () => {
155
155
  });
156
156
  });
157
157
  });
158
- //# sourceMappingURL=block.starknet.test.js.map
158
+ //# sourceMappingURL=block.starknet.spec.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"block.starknet.test.js","sourceRoot":"","sources":["../../src/starknet/block.starknet.test.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
+ {"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"]}
@@ -109,4 +109,4 @@ describe('decode', () => {
109
109
  expect(() => (0, decodeCalldata_1.decodeInvokeCalldata)(invalidCalldata)).toThrow(decodeCalldata_1.DecodeCalldataError);
110
110
  });
111
111
  });
112
- //# sourceMappingURL=decodeCalldata.test.js.map
112
+ //# sourceMappingURL=decodeCalldata.spec.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"decodeCalldata.test.js","sourceRoot":"","sources":["../../src/starknet/decodeCalldata.test.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
+ {"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"]}
@@ -14,10 +14,9 @@ const event_emitter_1 = require("@nestjs/event-emitter");
14
14
  const schedule_1 = require("@nestjs/schedule");
15
15
  const node_core_1 = require("@subql/node-core");
16
16
  const x_sequelize_1 = require("@subql/x-sequelize");
17
+ const blockchain_service_1 = require("../blockchain.service");
17
18
  const configure_module_1 = require("../configure/configure.module");
18
- const ds_processor_service_1 = require("../indexer/ds-processor.service");
19
- const dynamic_ds_service_1 = require("../indexer/dynamic-ds.service");
20
- const unfinalizedBlocks_service_1 = require("../indexer/unfinalizedBlocks.service");
19
+ const starknet_1 = require("../starknet");
21
20
  let ReindexFeatureModule = class ReindexFeatureModule {
22
21
  };
23
22
  exports.ReindexFeatureModule = ReindexFeatureModule;
@@ -35,17 +34,29 @@ exports.ReindexFeatureModule = ReindexFeatureModule = __decorate([
35
34
  node_core_1.ForceCleanService,
36
35
  {
37
36
  provide: 'UnfinalizedBlocksService',
38
- useClass: unfinalizedBlocks_service_1.UnfinalizedBlocksService,
37
+ useClass: node_core_1.UnfinalizedBlocksService,
39
38
  },
40
39
  {
41
40
  provide: 'DynamicDsService',
42
- useClass: dynamic_ds_service_1.DynamicDsService,
41
+ useClass: node_core_1.DynamicDsService,
43
42
  },
44
- ds_processor_service_1.DsProcessorService,
43
+ node_core_1.DsProcessorService,
44
+ node_core_1.ConnectionPoolStateManager,
45
+ node_core_1.ConnectionPoolService,
45
46
  {
46
47
  // Used to work with DI for unfinalizedBlocksService but not used with reindex
47
- provide: node_core_1.ApiService,
48
- useFactory: () => undefined,
48
+ provide: 'APIService',
49
+ useFactory: starknet_1.StarknetApiService.create,
50
+ inject: [
51
+ 'ISubqueryProject',
52
+ node_core_1.ConnectionPoolService,
53
+ event_emitter_1.EventEmitter2,
54
+ node_core_1.NodeConfig,
55
+ ],
56
+ },
57
+ {
58
+ provide: 'IBlockchainService',
59
+ useClass: blockchain_service_1.BlockchainService,
49
60
  },
50
61
  schedule_1.SchedulerRegistry,
51
62
  ],
@@ -1 +1 @@
1
- {"version":3,"file":"reindex.module.js","sourceRoot":"","sources":["../../src/subcommands/reindex.module.ts"],"names":[],"mappings":";AAAA,8DAA8D;AAC9D,mCAAmC;;;;;;;;;AAEnC,2CAAwC;AACxC,yDAA0E;AAC1E,+CAAqD;AACrD,gDAS0B;AAC1B,oDAA+C;AAC/C,oEAAgE;AAChE,0EAAqE;AACrE,sEAAiE;AACjE,oFAAgF;AA+BzE,IAAM,oBAAoB,GAA1B,MAAM,oBAAoB;CAAG,CAAA;AAAvB,oDAAoB;+BAApB,oBAAoB;IA7BhC,IAAA,eAAM,EAAC;QACN,SAAS,EAAE;YACT;gBACE,OAAO,EAAE,qBAAqB;gBAC9B,UAAU,EAAE,6BAAiB;gBAC7B,MAAM,EAAE,CAAC,sBAAU,EAAE,6BAAa,EAAE,4BAAiB,EAAE,uBAAS,CAAC;aAClE;YACD,wBAAY;YACZ,0BAAc;YACd,sBAAU;YACV,6BAAiB;YACjB;gBACE,OAAO,EAAE,0BAA0B;gBACnC,QAAQ,EAAE,oDAAwB;aACnC;YACD;gBACE,OAAO,EAAE,kBAAkB;gBAC3B,QAAQ,EAAE,qCAAgB;aAC3B;YACD,yCAAkB;YAClB;gBACE,8EAA8E;gBAC9E,OAAO,EAAE,sBAAU;gBACnB,UAAU,EAAE,GAAG,EAAE,CAAC,SAAS;aAC5B;YACD,4BAAiB;SAClB;QACD,WAAW,EAAE,EAAE;KAChB,CAAC;GACW,oBAAoB,CAAG;AAW7B,IAAM,aAAa,GAAnB,MAAM,aAAa;CAAG,CAAA;AAAhB,sCAAa;wBAAb,aAAa;IATzB,IAAA,eAAM,EAAC;QACN,OAAO,EAAE;YACP,oBAAQ,CAAC,OAAO,EAAE;YAClB,kCAAe,CAAC,QAAQ,EAAE;YAC1B,oBAAoB;YACpB,kCAAkB,CAAC,OAAO,EAAE;SAC7B;QACD,WAAW,EAAE,EAAE;KAChB,CAAC;GACW,aAAa,CAAG","sourcesContent":["// Copyright 2020-2025 SubQuery Pte Ltd authors & contributors\n// SPDX-License-Identifier: GPL-3.0\n\nimport { Module } from '@nestjs/common';\nimport { EventEmitter2, EventEmitterModule } from '@nestjs/event-emitter';\nimport { SchedulerRegistry } from '@nestjs/schedule';\nimport {\n ApiService,\n DbModule,\n ForceCleanService,\n StoreService,\n ReindexService,\n PoiService,\n storeModelFactory,\n NodeConfig,\n} from '@subql/node-core';\nimport { Sequelize } from '@subql/x-sequelize';\nimport { ConfigureModule } from '../configure/configure.module';\nimport { DsProcessorService } from '../indexer/ds-processor.service';\nimport { DynamicDsService } from '../indexer/dynamic-ds.service';\nimport { UnfinalizedBlocksService } from '../indexer/unfinalizedBlocks.service';\n\n@Module({\n providers: [\n {\n provide: 'IStoreModelProvider',\n useFactory: storeModelFactory,\n inject: [NodeConfig, EventEmitter2, SchedulerRegistry, Sequelize],\n },\n StoreService,\n ReindexService,\n PoiService,\n ForceCleanService,\n {\n provide: 'UnfinalizedBlocksService',\n useClass: UnfinalizedBlocksService,\n },\n {\n provide: 'DynamicDsService',\n useClass: DynamicDsService,\n },\n DsProcessorService,\n {\n // Used to work with DI for unfinalizedBlocksService but not used with reindex\n provide: ApiService,\n useFactory: () => undefined,\n },\n SchedulerRegistry,\n ],\n controllers: [],\n})\nexport class ReindexFeatureModule {}\n\n@Module({\n imports: [\n DbModule.forRoot(),\n ConfigureModule.register(),\n ReindexFeatureModule,\n EventEmitterModule.forRoot(),\n ],\n controllers: [],\n})\nexport class ReindexModule {}\n"]}
1
+ {"version":3,"file":"reindex.module.js","sourceRoot":"","sources":["../../src/subcommands/reindex.module.ts"],"names":[],"mappings":";AAAA,8DAA8D;AAC9D,mCAAmC;;;;;;;;;AAEnC,2CAAwC;AACxC,yDAA0E;AAC1E,+CAAqD;AACrD,gDAa0B;AAC1B,oDAA+C;AAC/C,8DAA0D;AAC1D,oEAAgE;AAChE,0CAAiD;AA2C1C,IAAM,oBAAoB,GAA1B,MAAM,oBAAoB;CAAG,CAAA;AAAvB,oDAAoB;+BAApB,oBAAoB;IAzChC,IAAA,eAAM,EAAC;QACN,SAAS,EAAE;YACT;gBACE,OAAO,EAAE,qBAAqB;gBAC9B,UAAU,EAAE,6BAAiB;gBAC7B,MAAM,EAAE,CAAC,sBAAU,EAAE,6BAAa,EAAE,4BAAiB,EAAE,uBAAS,CAAC;aAClE;YACD,wBAAY;YACZ,0BAAc;YACd,sBAAU;YACV,6BAAiB;YACjB;gBACE,OAAO,EAAE,0BAA0B;gBACnC,QAAQ,EAAE,oCAAwB;aACnC;YACD;gBACE,OAAO,EAAE,kBAAkB;gBAC3B,QAAQ,EAAE,4BAAgB;aAC3B;YACD,8BAAkB;YAClB,sCAA0B;YAC1B,iCAAqB;YACrB;gBACE,8EAA8E;gBAC9E,OAAO,EAAE,YAAY;gBACrB,UAAU,EAAE,6BAAkB,CAAC,MAAM;gBACrC,MAAM,EAAE;oBACN,kBAAkB;oBAClB,iCAAqB;oBACrB,6BAAa;oBACb,sBAAU;iBACX;aACF;YACD;gBACE,OAAO,EAAE,oBAAoB;gBAC7B,QAAQ,EAAE,sCAAiB;aAC5B;YACD,4BAAiB;SAClB;QACD,WAAW,EAAE,EAAE;KAChB,CAAC;GACW,oBAAoB,CAAG;AAW7B,IAAM,aAAa,GAAnB,MAAM,aAAa;CAAG,CAAA;AAAhB,sCAAa;wBAAb,aAAa;IATzB,IAAA,eAAM,EAAC;QACN,OAAO,EAAE;YACP,oBAAQ,CAAC,OAAO,EAAE;YAClB,kCAAe,CAAC,QAAQ,EAAE;YAC1B,oBAAoB;YACpB,kCAAkB,CAAC,OAAO,EAAE;SAC7B;QACD,WAAW,EAAE,EAAE;KAChB,CAAC;GACW,aAAa,CAAG","sourcesContent":["// Copyright 2020-2025 SubQuery Pte Ltd authors & contributors\n// SPDX-License-Identifier: GPL-3.0\n\nimport { Module } from '@nestjs/common';\nimport { EventEmitter2, EventEmitterModule } from '@nestjs/event-emitter';\nimport { SchedulerRegistry } from '@nestjs/schedule';\nimport {\n DbModule,\n ForceCleanService,\n StoreService,\n ReindexService,\n PoiService,\n storeModelFactory,\n NodeConfig,\n UnfinalizedBlocksService,\n DynamicDsService,\n DsProcessorService,\n ConnectionPoolService,\n ConnectionPoolStateManager,\n} from '@subql/node-core';\nimport { Sequelize } from '@subql/x-sequelize';\nimport { BlockchainService } from '../blockchain.service';\nimport { ConfigureModule } from '../configure/configure.module';\nimport { StarknetApiService } from '../starknet';\n\n@Module({\n providers: [\n {\n provide: 'IStoreModelProvider',\n useFactory: storeModelFactory,\n inject: [NodeConfig, EventEmitter2, SchedulerRegistry, Sequelize],\n },\n StoreService,\n ReindexService,\n PoiService,\n ForceCleanService,\n {\n provide: 'UnfinalizedBlocksService',\n useClass: UnfinalizedBlocksService,\n },\n {\n provide: 'DynamicDsService',\n useClass: DynamicDsService,\n },\n DsProcessorService,\n ConnectionPoolStateManager,\n ConnectionPoolService,\n {\n // Used to work with DI for unfinalizedBlocksService but not used with reindex\n provide: 'APIService',\n useFactory: StarknetApiService.create,\n inject: [\n 'ISubqueryProject',\n ConnectionPoolService,\n EventEmitter2,\n NodeConfig,\n ],\n },\n {\n provide: 'IBlockchainService',\n useClass: BlockchainService,\n },\n SchedulerRegistry,\n ],\n controllers: [],\n})\nexport class ReindexFeatureModule {}\n\n@Module({\n imports: [\n DbModule.forRoot(),\n ConfigureModule.register(),\n ReindexFeatureModule,\n EventEmitterModule.forRoot(),\n ],\n controllers: [],\n})\nexport class ReindexModule {}\n"]}