@subql/node-ethereum 6.2.1 → 6.2.2-1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/CHANGELOG.md +3 -0
  2. package/dist/.tsbuildinfo +1 -1
  3. package/dist/configure/SubqueryProject.js +7 -0
  4. package/dist/configure/SubqueryProject.js.map +1 -1
  5. package/dist/utils/project.d.ts +14 -1
  6. package/dist/utils/project.js +100 -0
  7. package/dist/utils/project.js.map +1 -1
  8. package/dist/utils/string.d.ts +8 -0
  9. package/dist/utils/string.js +202 -1
  10. package/dist/utils/string.js.map +1 -1
  11. package/package.json +4 -3
  12. package/dist/blockchain.service.test.d.ts +0 -1
  13. package/dist/blockchain.service.test.js +0 -27
  14. package/dist/blockchain.service.test.js.map +0 -1
  15. package/dist/ethereum/api.ethereum.test.d.ts +0 -1
  16. package/dist/ethereum/api.ethereum.test.js +0 -266
  17. package/dist/ethereum/api.ethereum.test.js.map +0 -1
  18. package/dist/ethereum/api.service.ethereum.test.d.ts +0 -1
  19. package/dist/ethereum/api.service.ethereum.test.js +0 -91
  20. package/dist/ethereum/api.service.ethereum.test.js.map +0 -1
  21. package/dist/ethereum/ethers/celo/celo-ws-provider.spec.d.ts +0 -1
  22. package/dist/ethereum/ethers/celo/celo-ws-provider.spec.js +0 -33
  23. package/dist/ethereum/ethers/celo/celo-ws-provider.spec.js.map +0 -1
  24. package/dist/ethereum/ethers/json-rpc-batch-provider.spec.d.ts +0 -1
  25. package/dist/ethereum/ethers/json-rpc-batch-provider.spec.js +0 -63
  26. package/dist/ethereum/ethers/json-rpc-batch-provider.spec.js.map +0 -1
  27. package/dist/ethereum/ethers/op/op-provider.spec.d.ts +0 -1
  28. package/dist/ethereum/ethers/op/op-provider.spec.js +0 -32
  29. package/dist/ethereum/ethers/op/op-provider.spec.js.map +0 -1
  30. package/dist/indexer/dictionary/utils.spec.d.ts +0 -1
  31. package/dist/indexer/dictionary/utils.spec.js +0 -101
  32. package/dist/indexer/dictionary/utils.spec.js.map +0 -1
  33. package/dist/indexer/dictionary/v1/ethDictionaryV1.spec.d.ts +0 -1
  34. package/dist/indexer/dictionary/v1/ethDictionaryV1.spec.js +0 -519
  35. package/dist/indexer/dictionary/v1/ethDictionaryV1.spec.js.map +0 -1
  36. package/dist/indexer/dictionary/v2/ethDictionaryV2.spec.d.ts +0 -1
  37. package/dist/indexer/dictionary/v2/ethDictionaryV2.spec.js +0 -585
  38. package/dist/indexer/dictionary/v2/ethDictionaryV2.spec.js.map +0 -1
  39. package/dist/indexer/dictionary/v2/utils.spec.d.ts +0 -1
  40. package/dist/indexer/dictionary/v2/utils.spec.js +0 -92
  41. package/dist/indexer/dictionary/v2/utils.spec.js.map +0 -1
  42. package/dist/indexer/unfinalizedBlocks.service.spec.d.ts +0 -1
  43. package/dist/indexer/unfinalizedBlocks.service.spec.js +0 -169
  44. package/dist/indexer/unfinalizedBlocks.service.spec.js.map +0 -1
@@ -5,6 +5,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
5
5
  exports.createSubQueryProject = createSubQueryProject;
6
6
  const common_ethereum_1 = require("@subql/common-ethereum");
7
7
  const node_core_1 = require("@subql/node-core");
8
+ const project_1 = require("../utils/project");
8
9
  const { version: packageVersion } = require('../../package.json');
9
10
  async function createSubQueryProject(path, rawManifest, reader, root, // If project local then directory otherwise temp directory
10
11
  networkOverrides) {
@@ -20,6 +21,12 @@ networkOverrides) {
20
21
  isRuntimeDs: common_ethereum_1.isRuntimeDs,
21
22
  isCustomDs: common_ethereum_1.isCustomDs,
22
23
  });
24
+ // Resolve custom types in topic filters at project load time
25
+ (0, project_1.resolveTopicFiltersInProject)(project.dataSources, root);
26
+ // Also resolve in templates
27
+ if (project.templates && project.templates.length > 0) {
28
+ (0, project_1.resolveTopicFiltersInProject)(project.templates, root);
29
+ }
23
30
  return project;
24
31
  }
25
32
  //# sourceMappingURL=SubqueryProject.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"SubqueryProject.js","sourceRoot":"","sources":["../../src/configure/SubqueryProject.ts"],"names":[],"mappings":";AAAA,8DAA8D;AAC9D,mCAAmC;;AAqCnC,sDAqBC;AAxDD,4DAMgC;AAChC,gDAAmE;AASnE,MAAM,EAAE,OAAO,EAAE,cAAc,EAAE,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAAC;AAmB3D,KAAK,UAAU,qBAAqB,CACzC,IAAY,EACZ,WAAoB,EACpB,MAAc,EACd,IAAY,EAAE,2DAA2D;AACzE,gBAAyC;IAEzC,MAAM,OAAO,GAAG,MAAM,+BAAmB,CAAC,MAAM,CAAkB;QAChE,aAAa,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,IAAA,8CAA4B,EAAC,GAAG,CAAC,CAAC,QAAQ;QAClE,IAAI;QACJ,WAAW;QACX,MAAM;QACN,IAAI;QACJ,UAAU,EAAE,cAAc;QAC1B,gBAAgB,EAAE,qCAAmB,CAAC,KAAK;QAC3C,gBAAgB;QAChB,WAAW,EAAX,6BAAW;QACX,UAAU,EAAV,4BAAU;KACX,CAAC,CAAC;IAEH,OAAO,OAAO,CAAC;AACjB,CAAC","sourcesContent":["// Copyright 2020-2025 SubQuery Pte Ltd authors & contributors\n// SPDX-License-Identifier: GPL-3.0\n\nimport {\n parseEthereumProjectManifest,\n SubqlEthereumDataSource,\n isRuntimeDs,\n EthereumHandlerKind,\n isCustomDs,\n} from '@subql/common-ethereum';\nimport { BaseSubqueryProject, CronFilter } from '@subql/node-core';\nimport { Reader } from '@subql/types-core';\nimport {\n EthereumNetworkConfig,\n RuntimeDatasourceTemplate,\n CustomDatasourceTemplate,\n EthereumBlockFilter,\n} from '@subql/types-ethereum';\n\nconst { version: packageVersion } = require('../../package.json');\n\nexport type EthereumProjectDs = SubqlEthereumDataSource;\n\nexport type EthereumProjectDsTemplate =\n | RuntimeDatasourceTemplate\n | CustomDatasourceTemplate;\n\nexport type SubqlProjectBlockFilter = EthereumBlockFilter & CronFilter;\n\n// This is the runtime type after we have mapped genesisHash to chainId and endpoint/dict have been provided when dealing with deployments\ntype NetworkConfig = EthereumNetworkConfig & { chainId: string };\n\nexport type SubqueryProject = BaseSubqueryProject<\n EthereumProjectDs,\n EthereumProjectDsTemplate,\n NetworkConfig\n>;\n\nexport async function createSubQueryProject(\n path: string,\n rawManifest: unknown,\n reader: Reader,\n root: string, // If project local then directory otherwise temp directory\n networkOverrides?: Partial<NetworkConfig>,\n): Promise<SubqueryProject> {\n const project = await BaseSubqueryProject.create<SubqueryProject>({\n parseManifest: (raw) => parseEthereumProjectManifest(raw).asV1_0_0,\n path,\n rawManifest,\n reader,\n root,\n nodeSemver: packageVersion,\n blockHandlerKind: EthereumHandlerKind.Block,\n networkOverrides,\n isRuntimeDs,\n isCustomDs,\n });\n\n return project;\n}\n"]}
1
+ {"version":3,"file":"SubqueryProject.js","sourceRoot":"","sources":["../../src/configure/SubqueryProject.ts"],"names":[],"mappings":";AAAA,8DAA8D;AAC9D,mCAAmC;;AAsCnC,sDAgCC;AApED,4DAMgC;AAChC,gDAAmE;AAQnE,8CAAgE;AAEhE,MAAM,EAAE,OAAO,EAAE,cAAc,EAAE,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAAC;AAmB3D,KAAK,UAAU,qBAAqB,CACzC,IAAY,EACZ,WAAoB,EACpB,MAAc,EACd,IAAY,EAAE,2DAA2D;AACzE,gBAAyC;IAEzC,MAAM,OAAO,GAAG,MAAM,+BAAmB,CAAC,MAAM,CAAkB;QAChE,aAAa,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,IAAA,8CAA4B,EAAC,GAAG,CAAC,CAAC,QAAQ;QAClE,IAAI;QACJ,WAAW;QACX,MAAM;QACN,IAAI;QACJ,UAAU,EAAE,cAAc;QAC1B,gBAAgB,EAAE,qCAAmB,CAAC,KAAK;QAC3C,gBAAgB;QAChB,WAAW,EAAX,6BAAW;QACX,UAAU,EAAV,4BAAU;KACX,CAAC,CAAC;IAEH,6DAA6D;IAC7D,IAAA,sCAA4B,EAAC,OAAO,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC;IAExD,4BAA4B;IAC5B,IAAI,OAAO,CAAC,SAAS,IAAI,OAAO,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACtD,IAAA,sCAA4B,EAC1B,OAAO,CAAC,SAAsC,EAC9C,IAAI,CACL,CAAC;IACJ,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC","sourcesContent":["// Copyright 2020-2025 SubQuery Pte Ltd authors & contributors\n// SPDX-License-Identifier: GPL-3.0\n\nimport {\n parseEthereumProjectManifest,\n SubqlEthereumDataSource,\n isRuntimeDs,\n EthereumHandlerKind,\n isCustomDs,\n} from '@subql/common-ethereum';\nimport { BaseSubqueryProject, CronFilter } from '@subql/node-core';\nimport { Reader } from '@subql/types-core';\nimport {\n EthereumNetworkConfig,\n RuntimeDatasourceTemplate,\n CustomDatasourceTemplate,\n EthereumBlockFilter,\n} from '@subql/types-ethereum';\nimport { resolveTopicFiltersInProject } from '../utils/project';\n\nconst { version: packageVersion } = require('../../package.json');\n\nexport type EthereumProjectDs = SubqlEthereumDataSource;\n\nexport type EthereumProjectDsTemplate =\n | RuntimeDatasourceTemplate\n | CustomDatasourceTemplate;\n\nexport type SubqlProjectBlockFilter = EthereumBlockFilter & CronFilter;\n\n// This is the runtime type after we have mapped genesisHash to chainId and endpoint/dict have been provided when dealing with deployments\ntype NetworkConfig = EthereumNetworkConfig & { chainId: string };\n\nexport type SubqueryProject = BaseSubqueryProject<\n EthereumProjectDs,\n EthereumProjectDsTemplate,\n NetworkConfig\n>;\n\nexport async function createSubQueryProject(\n path: string,\n rawManifest: unknown,\n reader: Reader,\n root: string, // If project local then directory otherwise temp directory\n networkOverrides?: Partial<NetworkConfig>,\n): Promise<SubqueryProject> {\n const project = await BaseSubqueryProject.create<SubqueryProject>({\n parseManifest: (raw) => parseEthereumProjectManifest(raw).asV1_0_0,\n path,\n rawManifest,\n reader,\n root,\n nodeSemver: packageVersion,\n blockHandlerKind: EthereumHandlerKind.Block,\n networkOverrides,\n isRuntimeDs,\n isCustomDs,\n });\n\n // Resolve custom types in topic filters at project load time\n resolveTopicFiltersInProject(project.dataSources, root);\n\n // Also resolve in templates\n if (project.templates && project.templates.length > 0) {\n resolveTopicFiltersInProject(\n project.templates as SubqlEthereumDataSource[],\n root,\n );\n }\n\n return project;\n}\n"]}
@@ -1,7 +1,20 @@
1
- import { SubqlRuntimeHandler, SubqlCustomHandler, SubqlHandler } from '@subql/common-ethereum';
1
+ import { SubqlRuntimeHandler, SubqlCustomHandler, SubqlHandler, SubqlEthereumDataSource } from '@subql/common-ethereum';
2
2
  import { EthereumProjectDs, SubqueryProject } from '../configure/SubqueryProject';
3
3
  export declare function isBaseHandler(handler: SubqlHandler): handler is SubqlRuntimeHandler;
4
4
  export declare function isCustomHandler(handler: SubqlHandler): handler is SubqlCustomHandler;
5
5
  export declare function retryOnFailEth<T>(request: () => Promise<T>, errors?: string[]): Promise<T>;
6
6
  export declare function onlyHasLogDataSources(dataSources: EthereumProjectDs[]): boolean;
7
7
  export declare function isOnlyEventHandlers(project: SubqueryProject): boolean;
8
+ /**
9
+ * Resolves custom types (enums, structs) in topic filters for all datasources at project load time.
10
+ * Mutates the datasource handlers' topic filters in-place.
11
+ *
12
+ * This ensures that:
13
+ * - Enums are replaced with uint8
14
+ * - Structs are replaced with tuple notation (type1,type2,...)
15
+ * - No runtime ABI resolution is needed
16
+ *
17
+ * @param dataSources - Array of datasources to process (mutated in-place)
18
+ * @param projectPath - The project root path for loading ABI files
19
+ */
20
+ export declare function resolveTopicFiltersInProject(dataSources: SubqlEthereumDataSource[], projectPath: string): void;
@@ -7,8 +7,11 @@ exports.isCustomHandler = isCustomHandler;
7
7
  exports.retryOnFailEth = retryOnFailEth;
8
8
  exports.onlyHasLogDataSources = onlyHasLogDataSources;
9
9
  exports.isOnlyEventHandlers = isOnlyEventHandlers;
10
+ exports.resolveTopicFiltersInProject = resolveTopicFiltersInProject;
10
11
  const common_ethereum_1 = require("@subql/common-ethereum");
11
12
  const node_core_1 = require("@subql/node-core");
13
+ const string_1 = require("./string");
14
+ const logger = (0, node_core_1.getLogger)('project');
12
15
  function isBaseHandler(handler) {
13
16
  return Object.values(common_ethereum_1.EthereumHandlerKind).includes(handler.kind);
14
17
  }
@@ -45,4 +48,101 @@ function isOnlyEventHandlers(project) {
45
48
  const hasNonEventTemplate = !!project.templates.find((ds) => dsContainsNonEventHandlers(ds));
46
49
  return !hasNonEventHandler && !hasNonEventTemplate;
47
50
  }
51
+ /**
52
+ * Helper function to load ABI interface from a datasource
53
+ */
54
+ function getAbiInterfaceFromDs(ds, projectPath) {
55
+ try {
56
+ if (!ds?.options?.abi || !projectPath) {
57
+ return undefined;
58
+ }
59
+ return (0, common_ethereum_1.getAbiInterface)(projectPath, ds.options.abi);
60
+ }
61
+ catch (error) {
62
+ logger.warn(`Failed to load ABI interface for datasource: ${error instanceof Error ? error.message : 'Unknown error'}`);
63
+ return undefined;
64
+ }
65
+ }
66
+ /**
67
+ * Process event handler topic filters and resolve custom types
68
+ */
69
+ function processEventHandlerFilters(handler, customTypes) {
70
+ if (handler.kind !== common_ethereum_1.EthereumHandlerKind.Event) {
71
+ return;
72
+ }
73
+ const logFilter = handler.filter;
74
+ if (!logFilter?.topics) {
75
+ return;
76
+ }
77
+ // Only resolve custom types in the first topic (topic0), which is the event signature
78
+ const topic = logFilter.topics[0];
79
+ if (typeof topic === 'string' &&
80
+ topic.trim() !== '' &&
81
+ !topic.startsWith('0x')) {
82
+ const resolved = (0, string_1.resolveCustomTypesInSignature)(topic, customTypes);
83
+ if (resolved !== topic) {
84
+ logFilter.topics[0] = resolved;
85
+ logger.info(`Resolved topic filter: "${topic}" -> "${resolved}"`);
86
+ }
87
+ }
88
+ }
89
+ /**
90
+ * Process transaction handler function filters and resolve custom types
91
+ */
92
+ function processTransactionHandlerFilters(handler, customTypes) {
93
+ if (handler.kind !== common_ethereum_1.EthereumHandlerKind.Call) {
94
+ return;
95
+ }
96
+ const txFilter = handler.filter;
97
+ if (!txFilter?.function) {
98
+ return;
99
+ }
100
+ const funcSig = txFilter.function;
101
+ if (typeof funcSig === 'string' && !funcSig.startsWith('0x')) {
102
+ const resolved = (0, string_1.resolveCustomTypesInSignature)(funcSig, customTypes);
103
+ if (resolved !== funcSig) {
104
+ txFilter.function = resolved;
105
+ logger.info(`Resolved function filter: "${funcSig}" -> "${resolved}"`);
106
+ }
107
+ }
108
+ }
109
+ /**
110
+ * Resolves custom types (enums, structs) in topic filters for all datasources at project load time.
111
+ * Mutates the datasource handlers' topic filters in-place.
112
+ *
113
+ * This ensures that:
114
+ * - Enums are replaced with uint8
115
+ * - Structs are replaced with tuple notation (type1,type2,...)
116
+ * - No runtime ABI resolution is needed
117
+ *
118
+ * @param dataSources - Array of datasources to process (mutated in-place)
119
+ * @param projectPath - The project root path for loading ABI files
120
+ */
121
+ function resolveTopicFiltersInProject(dataSources, projectPath) {
122
+ for (const ds of dataSources) {
123
+ try {
124
+ // Load ABI interface
125
+ const abiInterface = getAbiInterfaceFromDs(ds, projectPath);
126
+ if (!abiInterface) {
127
+ continue;
128
+ }
129
+ // Extract custom types once per datasource
130
+ const customTypes = (0, string_1.extractCustomTypesFromAbi)(abiInterface);
131
+ if (customTypes.size === 0) {
132
+ continue; // No custom types, no need to process
133
+ }
134
+ // Log discovered custom types
135
+ const customTypeNames = Array.from(customTypes.keys()).join(', ');
136
+ logger.info(`Found custom types in ABI '${ds.options?.abi}': ${customTypeNames}`);
137
+ // Process each handler
138
+ for (const handler of ds.mapping.handlers) {
139
+ processEventHandlerFilters(handler, customTypes);
140
+ processTransactionHandlerFilters(handler, customTypes);
141
+ }
142
+ }
143
+ catch (error) {
144
+ logger.warn(`Failed to resolve custom types for datasource: ${error instanceof Error ? error.message : 'Unknown error'}`);
145
+ }
146
+ }
147
+ }
48
148
  //# sourceMappingURL=project.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"project.js","sourceRoot":"","sources":["../../src/utils/project.ts"],"names":[],"mappings":";AAAA,8DAA8D;AAC9D,mCAAmC;;AAiBnC,sCAIC;AAED,0CAIC;AAID,wCAKC;AAED,sDAYC;AAcD,kDASC;AAvED,4DAQgC;AAChC,gDAA+C;AAM/C,SAAgB,aAAa,CAC3B,OAAqB;IAErB,OAAO,MAAM,CAAC,MAAM,CAAS,qCAAmB,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;AAC3E,CAAC;AAED,SAAgB,eAAe,CAC7B,OAAqB;IAErB,OAAO,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;AACjC,CAAC;AAED,MAAM,aAAa,GAAG,CAAC,SAAS,CAAC,CAAC;AAClC,4DAA4D;AACrD,KAAK,UAAU,cAAc,CAClC,OAAyB,EACzB,MAAM,GAAG,aAAa;IAEtB,OAAO,IAAA,uBAAW,EAAC,OAAO,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;AAC5E,CAAC;AAED,SAAgB,qBAAqB,CACnC,WAAgC;IAEhC,KAAK,MAAM,EAAE,IAAI,WAAW,EAAE,CAAC;QAC7B,KAAK,MAAM,OAAO,IAAI,EAAE,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC;YAC1C,IAAI,OAAO,CAAC,IAAI,KAAK,0CAAwB,CAAC,QAAQ,EAAE,CAAC;gBACvD,OAAO,KAAK,CAAC;YACf,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,0BAA0B,CAAC,EAAqB;IACvD,IAAI,IAAA,6BAAW,EAAC,EAAE,CAAC,EAAE,CAAC;QACpB,OAAO,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAC/B,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,KAAK,qCAAmB,CAAC,KAAK,CACxD,CAAC;IACJ,CAAC;SAAM,IAAI,IAAA,4BAAU,EAAC,EAAE,CAAC,EAAE,CAAC;QAC1B,gDAAgD;QAChD,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAgB,mBAAmB,CAAC,OAAwB;IAC1D,MAAM,kBAAkB,GAAG,CAAC,CAAC,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,CAC3D,0BAA0B,CAAC,EAAE,CAAC,CAC/B,CAAC;IACF,MAAM,mBAAmB,GAAG,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,CAC1D,0BAA0B,CAAC,EAAuB,CAAC,CACpD,CAAC;IAEF,OAAO,CAAC,kBAAkB,IAAI,CAAC,mBAAmB,CAAC;AACrD,CAAC","sourcesContent":["// Copyright 2020-2025 SubQuery Pte Ltd authors & contributors\n// SPDX-License-Identifier: GPL-3.0\n\nimport {\n SubqlRuntimeHandler,\n SubqlCustomHandler,\n SubqlHandler,\n EthereumHandlerKind,\n SubqlEthereumHandlerKind,\n isCustomDs,\n isRuntimeDs,\n} from '@subql/common-ethereum';\nimport { retryOnFail } from '@subql/node-core';\nimport {\n EthereumProjectDs,\n SubqueryProject,\n} from '../configure/SubqueryProject';\n\nexport function isBaseHandler(\n handler: SubqlHandler,\n): handler is SubqlRuntimeHandler {\n return Object.values<string>(EthereumHandlerKind).includes(handler.kind);\n}\n\nexport function isCustomHandler(\n handler: SubqlHandler,\n): handler is SubqlCustomHandler {\n return !isBaseHandler(handler);\n}\n\nconst handledErrors = ['timeout'];\n// eslint-disable-next-line @typescript-eslint/require-await\nexport async function retryOnFailEth<T>(\n request: () => Promise<T>,\n errors = handledErrors,\n): Promise<T> {\n return retryOnFail(request, (e) => !!errors.find((t) => t === e?.reason));\n}\n\nexport function onlyHasLogDataSources(\n dataSources: EthereumProjectDs[],\n): boolean {\n for (const ds of dataSources) {\n for (const handler of ds.mapping.handlers) {\n if (handler.kind !== SubqlEthereumHandlerKind.EthEvent) {\n return false;\n }\n }\n }\n\n return true;\n}\n\nfunction dsContainsNonEventHandlers(ds: EthereumProjectDs): boolean {\n if (isRuntimeDs(ds)) {\n return !!ds.mapping.handlers.find(\n (handler) => handler.kind !== EthereumHandlerKind.Event,\n );\n } else if (isCustomDs(ds)) {\n // TODO this can be improved upon in the future.\n return true;\n }\n return true;\n}\n\nexport function isOnlyEventHandlers(project: SubqueryProject): boolean {\n const hasNonEventHandler = !!project.dataSources.find((ds) =>\n dsContainsNonEventHandlers(ds),\n );\n const hasNonEventTemplate = !!project.templates.find((ds) =>\n dsContainsNonEventHandlers(ds as EthereumProjectDs),\n );\n\n return !hasNonEventHandler && !hasNonEventTemplate;\n}\n"]}
1
+ {"version":3,"file":"project.js","sourceRoot":"","sources":["../../src/utils/project.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 { Interface } from '@ethersproject/abi';\nimport {\n SubqlRuntimeHandler,\n SubqlCustomHandler,\n SubqlHandler,\n EthereumHandlerKind,\n SubqlEthereumHandlerKind,\n isCustomDs,\n isRuntimeDs,\n SubqlEthereumDataSource,\n EthereumLogFilter,\n EthereumTransactionFilter,\n getAbiInterface,\n} from '@subql/common-ethereum';\nimport { getLogger, retryOnFail } from '@subql/node-core';\nimport {\n EthereumProjectDs,\n SubqueryProject,\n} from '../configure/SubqueryProject';\nimport {\n extractCustomTypesFromAbi,\n resolveCustomTypesInSignature,\n} from './string';\n\nconst logger = getLogger('project');\n\nexport function isBaseHandler(\n handler: SubqlHandler,\n): handler is SubqlRuntimeHandler {\n return Object.values<string>(EthereumHandlerKind).includes(handler.kind);\n}\n\nexport function isCustomHandler(\n handler: SubqlHandler,\n): handler is SubqlCustomHandler {\n return !isBaseHandler(handler);\n}\n\nconst handledErrors = ['timeout'];\n// eslint-disable-next-line @typescript-eslint/require-await\nexport async function retryOnFailEth<T>(\n request: () => Promise<T>,\n errors = handledErrors,\n): Promise<T> {\n return retryOnFail(request, (e) => !!errors.find((t) => t === e?.reason));\n}\n\nexport function onlyHasLogDataSources(\n dataSources: EthereumProjectDs[],\n): boolean {\n for (const ds of dataSources) {\n for (const handler of ds.mapping.handlers) {\n if (handler.kind !== SubqlEthereumHandlerKind.EthEvent) {\n return false;\n }\n }\n }\n\n return true;\n}\n\nfunction dsContainsNonEventHandlers(ds: EthereumProjectDs): boolean {\n if (isRuntimeDs(ds)) {\n return !!ds.mapping.handlers.find(\n (handler) => handler.kind !== EthereumHandlerKind.Event,\n );\n } else if (isCustomDs(ds)) {\n // TODO this can be improved upon in the future.\n return true;\n }\n return true;\n}\n\nexport function isOnlyEventHandlers(project: SubqueryProject): boolean {\n const hasNonEventHandler = !!project.dataSources.find((ds) =>\n dsContainsNonEventHandlers(ds),\n );\n const hasNonEventTemplate = !!project.templates.find((ds) =>\n dsContainsNonEventHandlers(ds as EthereumProjectDs),\n );\n\n return !hasNonEventHandler && !hasNonEventTemplate;\n}\n\n/**\n * Helper function to load ABI interface from a datasource\n */\nfunction getAbiInterfaceFromDs(\n ds: SubqlEthereumDataSource,\n projectPath: string,\n): Interface | undefined {\n try {\n if (!ds?.options?.abi || !projectPath) {\n return undefined;\n }\n\n return getAbiInterface(projectPath, ds.options.abi);\n } catch (error) {\n logger.warn(\n `Failed to load ABI interface for datasource: ${\n error instanceof Error ? error.message : 'Unknown error'\n }`,\n );\n return undefined;\n }\n}\n\n/**\n * Process event handler topic filters and resolve custom types\n */\nfunction processEventHandlerFilters(\n handler: SubqlHandler,\n customTypes: Map<string, any>,\n): void {\n if (handler.kind !== EthereumHandlerKind.Event) {\n return;\n }\n\n const logFilter = handler.filter as EthereumLogFilter | undefined;\n if (!logFilter?.topics) {\n return;\n }\n\n // Only resolve custom types in the first topic (topic0), which is the event signature\n const topic = logFilter.topics[0];\n if (\n typeof topic === 'string' &&\n topic.trim() !== '' &&\n !topic.startsWith('0x')\n ) {\n const resolved = resolveCustomTypesInSignature(topic, customTypes);\n if (resolved !== topic) {\n logFilter.topics[0] = resolved;\n logger.info(`Resolved topic filter: \"${topic}\" -> \"${resolved}\"`);\n }\n }\n}\n\n/**\n * Process transaction handler function filters and resolve custom types\n */\nfunction processTransactionHandlerFilters(\n handler: SubqlHandler,\n customTypes: Map<string, any>,\n): void {\n if (handler.kind !== EthereumHandlerKind.Call) {\n return;\n }\n\n const txFilter = handler.filter as EthereumTransactionFilter | undefined;\n if (!txFilter?.function) {\n return;\n }\n\n const funcSig = txFilter.function;\n if (typeof funcSig === 'string' && !funcSig.startsWith('0x')) {\n const resolved = resolveCustomTypesInSignature(funcSig, customTypes);\n if (resolved !== funcSig) {\n txFilter.function = resolved;\n logger.info(`Resolved function filter: \"${funcSig}\" -> \"${resolved}\"`);\n }\n }\n}\n\n/**\n * Resolves custom types (enums, structs) in topic filters for all datasources at project load time.\n * Mutates the datasource handlers' topic filters in-place.\n *\n * This ensures that:\n * - Enums are replaced with uint8\n * - Structs are replaced with tuple notation (type1,type2,...)\n * - No runtime ABI resolution is needed\n *\n * @param dataSources - Array of datasources to process (mutated in-place)\n * @param projectPath - The project root path for loading ABI files\n */\nexport function resolveTopicFiltersInProject(\n dataSources: SubqlEthereumDataSource[],\n projectPath: string,\n): void {\n for (const ds of dataSources) {\n try {\n // Load ABI interface\n const abiInterface = getAbiInterfaceFromDs(ds, projectPath);\n if (!abiInterface) {\n continue;\n }\n\n // Extract custom types once per datasource\n const customTypes = extractCustomTypesFromAbi(abiInterface);\n if (customTypes.size === 0) {\n continue; // No custom types, no need to process\n }\n\n // Log discovered custom types\n const customTypeNames = Array.from(customTypes.keys()).join(', ');\n logger.info(\n `Found custom types in ABI '${ds.options?.abi}': ${customTypeNames}`,\n );\n\n // Process each handler\n for (const handler of ds.mapping.handlers) {\n processEventHandlerFilters(handler, customTypes);\n processTransactionHandlerFilters(handler, customTypes);\n }\n } catch (error) {\n logger.warn(\n `Failed to resolve custom types for datasource: ${\n error instanceof Error ? error.message : 'Unknown error'\n }`,\n );\n }\n }\n}\n"]}
@@ -1,4 +1,12 @@
1
+ import { Interface } from '@ethersproject/abi';
1
2
  export declare function stringNormalizedEq(a: string, b?: string): boolean;
2
3
  export declare function hexStringEq(a: string, b: string): boolean;
4
+ export interface AbiCustomType {
5
+ name: string;
6
+ type: 'enum' | 'struct';
7
+ resolvedType: string;
8
+ }
9
+ export declare function extractCustomTypesFromAbi(abiInterface: Interface): Map<string, AbiCustomType>;
10
+ export declare function resolveCustomTypesInSignature(signature: string, customTypes: Map<string, AbiCustomType>): string;
3
11
  export declare function eventToTopic(input: string): string;
4
12
  export declare function functionToSighash(input: string): string;
@@ -4,6 +4,8 @@
4
4
  Object.defineProperty(exports, "__esModule", { value: true });
5
5
  exports.stringNormalizedEq = stringNormalizedEq;
6
6
  exports.hexStringEq = hexStringEq;
7
+ exports.extractCustomTypesFromAbi = extractCustomTypesFromAbi;
8
+ exports.resolveCustomTypesInSignature = resolveCustomTypesInSignature;
7
9
  exports.eventToTopic = eventToTopic;
8
10
  exports.functionToSighash = functionToSighash;
9
11
  const abi_1 = require("@ethersproject/abi");
@@ -20,11 +22,210 @@ function hexStringEq(a, b) {
20
22
  }
21
23
  const eventTopicsCache = {};
22
24
  const functionSighashCache = {};
25
+ function extractCustomTypesFromAbi(abiInterface) {
26
+ const customTypes = new Map();
27
+ try {
28
+ // Process event fragments
29
+ Object.values(abiInterface.events).forEach((eventFragment) => {
30
+ eventFragment.inputs.forEach((input) => {
31
+ extractCustomTypeFromInput(input, customTypes);
32
+ });
33
+ });
34
+ // Process function fragments
35
+ Object.values(abiInterface.functions).forEach((functionFragment) => {
36
+ functionFragment.inputs.forEach((input) => {
37
+ extractCustomTypeFromInput(input, customTypes);
38
+ });
39
+ });
40
+ }
41
+ catch (error) {
42
+ // Silently handle extraction errors in runtime
43
+ }
44
+ return customTypes;
45
+ }
46
+ function extractCustomTypeFromInput(input, customTypes) {
47
+ // Handle tuple types (structs)
48
+ if (input.type === 'tuple' && input.internalType) {
49
+ // Extract struct name from internal type (e.g., "struct MoreData" -> "MoreData", "contract.MoreData" -> "MoreData")
50
+ const structName = input.internalType
51
+ .replace(/^struct\s+/, '') // Remove "struct " prefix
52
+ .replace(/^.*\./, ''); // Remove contract prefix if present (e.g., "contract.Name" -> "Name")
53
+ if (!customTypes.has(structName) && input.components) {
54
+ const tupleType = `(${input.components
55
+ .map((comp) => resolveBaseType(comp.type))
56
+ .join(',')})`;
57
+ customTypes.set(structName, {
58
+ name: structName,
59
+ type: 'struct',
60
+ resolvedType: tupleType,
61
+ });
62
+ }
63
+ }
64
+ // Handle enum types - look for custom internal types that aren't standard solidity types
65
+ if (input.internalType && input.internalType !== input.type) {
66
+ // Extract enum name from internal type (e.g., "enum DisputeType" -> "DisputeType", "contract.DisputeType" -> "DisputeType")
67
+ const enumName = input.internalType
68
+ .replace(/^enum\s+/, '') // Remove "enum " prefix
69
+ .replace(/^.*\./, ''); // Remove contract prefix if present (e.g., "contract.Name" -> "Name")
70
+ // Check if it's likely an enum (uint8/uint256 type with custom internal type)
71
+ if ((input.type === 'uint8' || input.type === 'uint256') &&
72
+ !enumName.startsWith('struct ') &&
73
+ !isStandardSolidityType(enumName)) {
74
+ if (!customTypes.has(enumName)) {
75
+ customTypes.set(enumName, {
76
+ name: enumName,
77
+ type: 'enum',
78
+ resolvedType: 'uint8',
79
+ });
80
+ }
81
+ }
82
+ }
83
+ // Recursively handle components for nested tuples
84
+ if (input.components) {
85
+ input.components.forEach((comp) => {
86
+ extractCustomTypeFromInput(comp, customTypes);
87
+ });
88
+ }
89
+ }
90
+ function resolveBaseType(type) {
91
+ // Map common type aliases to their canonical forms
92
+ const typeMapping = {
93
+ uint: 'uint256',
94
+ int: 'int256',
95
+ };
96
+ return typeMapping[type] || type;
97
+ }
98
+ function isStandardSolidityType(type) {
99
+ const standardTypes = [
100
+ 'address',
101
+ 'bool',
102
+ 'string',
103
+ 'bytes',
104
+ // uint variants
105
+ 'uint',
106
+ 'uint8',
107
+ 'uint16',
108
+ 'uint24',
109
+ 'uint32',
110
+ 'uint40',
111
+ 'uint48',
112
+ 'uint56',
113
+ 'uint64',
114
+ 'uint72',
115
+ 'uint80',
116
+ 'uint88',
117
+ 'uint96',
118
+ 'uint104',
119
+ 'uint112',
120
+ 'uint120',
121
+ 'uint128',
122
+ 'uint136',
123
+ 'uint144',
124
+ 'uint152',
125
+ 'uint160',
126
+ 'uint168',
127
+ 'uint176',
128
+ 'uint184',
129
+ 'uint192',
130
+ 'uint200',
131
+ 'uint208',
132
+ 'uint216',
133
+ 'uint224',
134
+ 'uint232',
135
+ 'uint240',
136
+ 'uint248',
137
+ 'uint256',
138
+ // int variants
139
+ 'int',
140
+ 'int8',
141
+ 'int16',
142
+ 'int24',
143
+ 'int32',
144
+ 'int40',
145
+ 'int48',
146
+ 'int56',
147
+ 'int64',
148
+ 'int72',
149
+ 'int80',
150
+ 'int88',
151
+ 'int96',
152
+ 'int104',
153
+ 'int112',
154
+ 'int120',
155
+ 'int128',
156
+ 'int136',
157
+ 'int144',
158
+ 'int152',
159
+ 'int160',
160
+ 'int168',
161
+ 'int176',
162
+ 'int184',
163
+ 'int192',
164
+ 'int200',
165
+ 'int208',
166
+ 'int216',
167
+ 'int224',
168
+ 'int232',
169
+ 'int240',
170
+ 'int248',
171
+ 'int256',
172
+ // bytes variants
173
+ 'bytes1',
174
+ 'bytes2',
175
+ 'bytes3',
176
+ 'bytes4',
177
+ 'bytes5',
178
+ 'bytes6',
179
+ 'bytes7',
180
+ 'bytes8',
181
+ 'bytes9',
182
+ 'bytes10',
183
+ 'bytes11',
184
+ 'bytes12',
185
+ 'bytes13',
186
+ 'bytes14',
187
+ 'bytes15',
188
+ 'bytes16',
189
+ 'bytes17',
190
+ 'bytes18',
191
+ 'bytes19',
192
+ 'bytes20',
193
+ 'bytes21',
194
+ 'bytes22',
195
+ 'bytes23',
196
+ 'bytes24',
197
+ 'bytes25',
198
+ 'bytes26',
199
+ 'bytes27',
200
+ 'bytes28',
201
+ 'bytes29',
202
+ 'bytes30',
203
+ 'bytes31',
204
+ 'bytes32',
205
+ ];
206
+ // handle array types
207
+ const baseType = type.replace(/\[\d*\]$/, '');
208
+ return standardTypes.includes(baseType);
209
+ }
210
+ function resolveCustomTypesInSignature(signature, customTypes) {
211
+ let resolvedSignature = signature;
212
+ // Replace custom types in the signature
213
+ customTypes.forEach((customType, typeName) => {
214
+ // Create regex to match the custom type name as a parameter type
215
+ const regex = new RegExp(`\\b${escapeRegex(typeName)}\\b`, 'g');
216
+ resolvedSignature = resolvedSignature.replace(regex, customType.resolvedType);
217
+ });
218
+ return resolvedSignature;
219
+ }
220
+ function escapeRegex(string) {
221
+ return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
222
+ }
23
223
  function eventToTopic(input) {
24
224
  if ((0, bytes_1.isHexString)(input))
25
225
  return input;
26
226
  if (!eventTopicsCache[input]) {
27
- eventTopicsCache[input] = (0, hash_1.id)(abi_1.EventFragment.fromString(input).format());
227
+ const cleanedInput = input.replace(/\bindexed\b/g, '');
228
+ eventTopicsCache[input] = (0, hash_1.id)(abi_1.EventFragment.fromString(cleanedInput).format());
28
229
  }
29
230
  return eventTopicsCache[input];
30
231
  }
@@ -1 +1 @@
1
- {"version":3,"file":"string.js","sourceRoot":"","sources":["../../src/utils/string.ts"],"names":[],"mappings":";AAAA,8DAA8D;AAC9D,mCAAmC;;AAMnC,gDAEC;AAED,kCAKC;AAKD,oCAQC;AAED,8CAYC;AAxCD,4CAAqE;AACrE,gDAAgF;AAChF,8CAAyC;AAEzC,SAAgB,kBAAkB,CAAC,CAAS,EAAE,CAAU;IACtD,OAAO,CAAC,CAAC,WAAW,EAAE,KAAK,CAAC,EAAE,WAAW,EAAE,CAAC;AAC9C,CAAC;AAED,SAAgB,WAAW,CAAC,CAAS,EAAE,CAAS;IAC9C,IAAI,CAAC,IAAA,mBAAW,EAAC,CAAC,CAAC,IAAI,CAAC,IAAA,mBAAW,EAAC,CAAC,CAAC,EAAE,CAAC;QACvC,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC;IAChD,CAAC;IACD,OAAO,kBAAkB,CAAC,IAAA,qBAAa,EAAC,CAAC,CAAC,EAAE,IAAA,qBAAa,EAAC,CAAC,CAAC,CAAC,CAAC;AAChE,CAAC;AAED,MAAM,gBAAgB,GAA2B,EAAE,CAAC;AACpD,MAAM,oBAAoB,GAA2B,EAAE,CAAC;AAExD,SAAgB,YAAY,CAAC,KAAa;IACxC,IAAI,IAAA,mBAAW,EAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IAErC,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,EAAE,CAAC;QAC7B,gBAAgB,CAAC,KAAK,CAAC,GAAG,IAAA,SAAE,EAAC,mBAAa,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;IACzE,CAAC;IAED,OAAO,gBAAgB,CAAC,KAAK,CAAC,CAAC;AACjC,CAAC;AAED,SAAgB,iBAAiB,CAAC,KAAa;IAC7C,IAAI,IAAA,mBAAW,EAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IAErC,IAAI,CAAC,oBAAoB,CAAC,KAAK,CAAC,EAAE,CAAC;QACjC,oBAAoB,CAAC,KAAK,CAAC,GAAG,IAAA,oBAAY,EACxC,IAAA,SAAE,EAAC,sBAAgB,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,MAAM,EAAE,CAAC,EAC/C,CAAC,EACD,CAAC,CACF,CAAC;IACJ,CAAC;IAED,OAAO,oBAAoB,CAAC,KAAK,CAAC,CAAC;AACrC,CAAC","sourcesContent":["// Copyright 2020-2025 SubQuery Pte Ltd authors & contributors\n// SPDX-License-Identifier: GPL-3.0\n\nimport { EventFragment, FunctionFragment } from '@ethersproject/abi';\nimport { isHexString, hexStripZeros, hexDataSlice } from '@ethersproject/bytes';\nimport { id } from '@ethersproject/hash';\n\nexport function stringNormalizedEq(a: string, b?: string): boolean {\n return a.toLowerCase() === b?.toLowerCase();\n}\n\nexport function hexStringEq(a: string, b: string): boolean {\n if (!isHexString(a) || !isHexString(b)) {\n throw new Error('Inputs are not hex strings');\n }\n return stringNormalizedEq(hexStripZeros(a), hexStripZeros(b));\n}\n\nconst eventTopicsCache: Record<string, string> = {};\nconst functionSighashCache: Record<string, string> = {};\n\nexport function eventToTopic(input: string): string {\n if (isHexString(input)) return input;\n\n if (!eventTopicsCache[input]) {\n eventTopicsCache[input] = id(EventFragment.fromString(input).format());\n }\n\n return eventTopicsCache[input];\n}\n\nexport function functionToSighash(input: string): string {\n if (isHexString(input)) return input;\n\n if (!functionSighashCache[input]) {\n functionSighashCache[input] = hexDataSlice(\n id(FunctionFragment.fromString(input).format()),\n 0,\n 4,\n );\n }\n\n return functionSighashCache[input];\n}\n"]}
1
+ {"version":3,"file":"string.js","sourceRoot":"","sources":["../../src/utils/string.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 { EventFragment, FunctionFragment, Interface } from '@ethersproject/abi';\nimport { isHexString, hexStripZeros, hexDataSlice } from '@ethersproject/bytes';\nimport { id } from '@ethersproject/hash';\n\nexport function stringNormalizedEq(a: string, b?: string): boolean {\n return a.toLowerCase() === b?.toLowerCase();\n}\n\nexport function hexStringEq(a: string, b: string): boolean {\n if (!isHexString(a) || !isHexString(b)) {\n throw new Error('Inputs are not hex strings');\n }\n return stringNormalizedEq(hexStripZeros(a), hexStripZeros(b));\n}\n\nconst eventTopicsCache: Record<string, string> = {};\nconst functionSighashCache: Record<string, string> = {};\n\nexport interface AbiCustomType {\n name: string;\n type: 'enum' | 'struct';\n resolvedType: string;\n}\n\nexport function extractCustomTypesFromAbi(\n abiInterface: Interface,\n): Map<string, AbiCustomType> {\n const customTypes = new Map<string, AbiCustomType>();\n\n try {\n // Process event fragments\n Object.values(abiInterface.events).forEach(\n (eventFragment: EventFragment) => {\n eventFragment.inputs.forEach((input) => {\n extractCustomTypeFromInput(input, customTypes);\n });\n },\n );\n\n // Process function fragments\n Object.values(abiInterface.functions).forEach(\n (functionFragment: FunctionFragment) => {\n functionFragment.inputs.forEach((input) => {\n extractCustomTypeFromInput(input, customTypes);\n });\n },\n );\n } catch (error) {\n // Silently handle extraction errors in runtime\n }\n\n return customTypes;\n}\n\nfunction extractCustomTypeFromInput(\n input: { type: string; internalType?: string; components?: any[] },\n customTypes: Map<string, AbiCustomType>,\n): void {\n // Handle tuple types (structs)\n if (input.type === 'tuple' && input.internalType) {\n // Extract struct name from internal type (e.g., \"struct MoreData\" -> \"MoreData\", \"contract.MoreData\" -> \"MoreData\")\n const structName = input.internalType\n .replace(/^struct\\s+/, '') // Remove \"struct \" prefix\n .replace(/^.*\\./, ''); // Remove contract prefix if present (e.g., \"contract.Name\" -> \"Name\")\n\n if (!customTypes.has(structName) && input.components) {\n const tupleType = `(${input.components\n .map((comp: any) => resolveBaseType(comp.type))\n .join(',')})`;\n customTypes.set(structName, {\n name: structName,\n type: 'struct',\n resolvedType: tupleType,\n });\n }\n }\n\n // Handle enum types - look for custom internal types that aren't standard solidity types\n if (input.internalType && input.internalType !== input.type) {\n // Extract enum name from internal type (e.g., \"enum DisputeType\" -> \"DisputeType\", \"contract.DisputeType\" -> \"DisputeType\")\n const enumName = input.internalType\n .replace(/^enum\\s+/, '') // Remove \"enum \" prefix\n .replace(/^.*\\./, ''); // Remove contract prefix if present (e.g., \"contract.Name\" -> \"Name\")\n\n // Check if it's likely an enum (uint8/uint256 type with custom internal type)\n if (\n (input.type === 'uint8' || input.type === 'uint256') &&\n !enumName.startsWith('struct ') &&\n !isStandardSolidityType(enumName)\n ) {\n if (!customTypes.has(enumName)) {\n customTypes.set(enumName, {\n name: enumName,\n type: 'enum',\n resolvedType: 'uint8',\n });\n }\n }\n }\n\n // Recursively handle components for nested tuples\n if (input.components) {\n input.components.forEach((comp: any) => {\n extractCustomTypeFromInput(comp, customTypes);\n });\n }\n}\n\nfunction resolveBaseType(type: string): string {\n // Map common type aliases to their canonical forms\n const typeMapping: Record<string, string> = {\n uint: 'uint256',\n int: 'int256',\n };\n return typeMapping[type] || type;\n}\n\nfunction isStandardSolidityType(type: string): boolean {\n const standardTypes = [\n 'address',\n 'bool',\n 'string',\n 'bytes',\n // uint variants\n 'uint',\n 'uint8',\n 'uint16',\n 'uint24',\n 'uint32',\n 'uint40',\n 'uint48',\n 'uint56',\n 'uint64',\n 'uint72',\n 'uint80',\n 'uint88',\n 'uint96',\n 'uint104',\n 'uint112',\n 'uint120',\n 'uint128',\n 'uint136',\n 'uint144',\n 'uint152',\n 'uint160',\n 'uint168',\n 'uint176',\n 'uint184',\n 'uint192',\n 'uint200',\n 'uint208',\n 'uint216',\n 'uint224',\n 'uint232',\n 'uint240',\n 'uint248',\n 'uint256',\n // int variants\n 'int',\n 'int8',\n 'int16',\n 'int24',\n 'int32',\n 'int40',\n 'int48',\n 'int56',\n 'int64',\n 'int72',\n 'int80',\n 'int88',\n 'int96',\n 'int104',\n 'int112',\n 'int120',\n 'int128',\n 'int136',\n 'int144',\n 'int152',\n 'int160',\n 'int168',\n 'int176',\n 'int184',\n 'int192',\n 'int200',\n 'int208',\n 'int216',\n 'int224',\n 'int232',\n 'int240',\n 'int248',\n 'int256',\n // bytes variants\n 'bytes1',\n 'bytes2',\n 'bytes3',\n 'bytes4',\n 'bytes5',\n 'bytes6',\n 'bytes7',\n 'bytes8',\n 'bytes9',\n 'bytes10',\n 'bytes11',\n 'bytes12',\n 'bytes13',\n 'bytes14',\n 'bytes15',\n 'bytes16',\n 'bytes17',\n 'bytes18',\n 'bytes19',\n 'bytes20',\n 'bytes21',\n 'bytes22',\n 'bytes23',\n 'bytes24',\n 'bytes25',\n 'bytes26',\n 'bytes27',\n 'bytes28',\n 'bytes29',\n 'bytes30',\n 'bytes31',\n 'bytes32',\n ];\n\n // handle array types\n const baseType = type.replace(/\\[\\d*\\]$/, '');\n return standardTypes.includes(baseType);\n}\n\nexport function resolveCustomTypesInSignature(\n signature: string,\n customTypes: Map<string, AbiCustomType>,\n): string {\n let resolvedSignature = signature;\n\n // Replace custom types in the signature\n customTypes.forEach((customType, typeName) => {\n // Create regex to match the custom type name as a parameter type\n const regex = new RegExp(`\\\\b${escapeRegex(typeName)}\\\\b`, 'g');\n resolvedSignature = resolvedSignature.replace(\n regex,\n customType.resolvedType,\n );\n });\n\n return resolvedSignature;\n}\n\nfunction escapeRegex(string: string): string {\n return string.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n}\n\nexport function eventToTopic(input: string): string {\n if (isHexString(input)) return input;\n\n if (!eventTopicsCache[input]) {\n const cleanedInput = input.replace(/\\bindexed\\b/g, '');\n eventTopicsCache[input] = id(\n EventFragment.fromString(cleanedInput).format(),\n );\n }\n\n return eventTopicsCache[input];\n}\n\nexport function functionToSighash(input: string): string {\n if (isHexString(input)) return input;\n\n if (!functionSighashCache[input]) {\n functionSighashCache[input] = hexDataSlice(\n id(FunctionFragment.fromString(input).format()),\n 0,\n 4,\n );\n }\n\n return functionSighashCache[input];\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@subql/node-ethereum",
3
- "version": "6.2.1",
3
+ "version": "6.2.2-1",
4
4
  "description": "",
5
5
  "author": "Ian He",
6
6
  "license": "GPL-3.0",
@@ -25,7 +25,7 @@
25
25
  "@nestjs/platform-express": "^11.0.7",
26
26
  "@nestjs/schedule": "^5.0.1",
27
27
  "@subql/common": "^5.7.3",
28
- "@subql/common-ethereum": "4.9.3",
28
+ "@subql/common-ethereum": "4.9.4-0",
29
29
  "@subql/node-core": "^18.3.1",
30
30
  "@subql/testing": "^2.2.1",
31
31
  "@subql/types-ethereum": "4.2.2",
@@ -69,5 +69,6 @@
69
69
  "README.md",
70
70
  "CHANGELOG.md",
71
71
  "LICENSE"
72
- ]
72
+ ],
73
+ "stableVersion": "6.2.2-0"
73
74
  }
@@ -1 +0,0 @@
1
- export {};
@@ -1,27 +0,0 @@
1
- "use strict";
2
- // Copyright 2020-2025 SubQuery Pte Ltd authors & contributors
3
- // SPDX-License-Identifier: GPL-3.0
4
- Object.defineProperty(exports, "__esModule", { value: true });
5
- const event_emitter_1 = require("@nestjs/event-emitter");
6
- const blockchain_service_1 = require("./blockchain.service");
7
- const ethereum_1 = require("./ethereum");
8
- const HTTP_ENDPOINT = 'https://ethereum.rpc.subquery.network/public';
9
- const mockApiService = () => {
10
- const ethApi = new ethereum_1.EthereumApi(HTTP_ENDPOINT, 20, new event_emitter_1.EventEmitter2());
11
- // await ethApi.init();
12
- return {
13
- unsafeApi: ethApi,
14
- };
15
- };
16
- describe('BlockchainService', () => {
17
- let blockchainService;
18
- beforeEach(() => {
19
- const apiService = mockApiService();
20
- blockchainService = new blockchain_service_1.BlockchainService(apiService);
21
- });
22
- it('can get a block timestamps', async () => {
23
- const timestamp = await blockchainService.getBlockTimestamp(4_000_000);
24
- expect(timestamp).toEqual(new Date('2017-07-09T20:52:47.000Z'));
25
- });
26
- });
27
- //# sourceMappingURL=blockchain.service.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"blockchain.service.test.js","sourceRoot":"","sources":["../src/blockchain.service.test.ts"],"names":[],"mappings":";AAAA,8DAA8D;AAC9D,mCAAmC;;AAEnC,yDAAsD;AACtD,6DAAyD;AACzD,yCAA6D;AAE7D,MAAM,aAAa,GAAG,8CAA8C,CAAC;AAErE,MAAM,cAAc,GAAG,GAAuB,EAAE;IAC9C,MAAM,MAAM,GAAG,IAAI,sBAAW,CAAC,aAAa,EAAE,EAAE,EAAE,IAAI,6BAAa,EAAE,CAAC,CAAC;IAEvE,uBAAuB;IAEvB,OAAO;QACL,SAAS,EAAE,MAAM;KACX,CAAC;AACX,CAAC,CAAC;AAEF,QAAQ,CAAC,mBAAmB,EAAE,GAAG,EAAE;IACjC,IAAI,iBAAoC,CAAC;IAEzC,UAAU,CAAC,GAAG,EAAE;QACd,MAAM,UAAU,GAAG,cAAc,EAAE,CAAC;QAEpC,iBAAiB,GAAG,IAAI,sCAAiB,CAAC,UAAU,CAAC,CAAC;IACxD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,4BAA4B,EAAE,KAAK,IAAI,EAAE;QAC1C,MAAM,SAAS,GAAG,MAAM,iBAAiB,CAAC,iBAAiB,CAAC,SAAS,CAAC,CAAC;QAEvE,MAAM,CAAC,SAAS,CAAC,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,0BAA0B,CAAC,CAAC,CAAC;IAClE,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 { EventEmitter2 } from '@nestjs/event-emitter';\nimport { BlockchainService } from './blockchain.service';\nimport { EthereumApi, EthereumApiService } from './ethereum';\n\nconst HTTP_ENDPOINT = 'https://ethereum.rpc.subquery.network/public';\n\nconst mockApiService = (): EthereumApiService => {\n const ethApi = new EthereumApi(HTTP_ENDPOINT, 20, new EventEmitter2());\n\n // await ethApi.init();\n\n return {\n unsafeApi: ethApi,\n } as any;\n};\n\ndescribe('BlockchainService', () => {\n let blockchainService: BlockchainService;\n\n beforeEach(() => {\n const apiService = mockApiService();\n\n blockchainService = new BlockchainService(apiService);\n });\n\n it('can get a block timestamps', async () => {\n const timestamp = await blockchainService.getBlockTimestamp(4_000_000);\n\n expect(timestamp).toEqual(new Date('2017-07-09T20:52:47.000Z'));\n });\n});\n"]}
@@ -1 +0,0 @@
1
- export {};