@subql/node-ethereum 3.11.0 → 3.11.1-0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (85) hide show
  1. package/dist/.tsbuildinfo +1 -1
  2. package/dist/ethereum/api.connection.d.ts +4 -4
  3. package/dist/ethereum/api.connection.js.map +1 -1
  4. package/dist/ethereum/api.ethereum.d.ts +4 -3
  5. package/dist/ethereum/api.ethereum.js +6 -3
  6. package/dist/ethereum/api.ethereum.js.map +1 -1
  7. package/dist/ethereum/api.ethereum.test.js +13 -1
  8. package/dist/ethereum/api.ethereum.test.js.map +1 -1
  9. package/dist/ethereum/api.service.ethereum.d.ts +2 -2
  10. package/dist/ethereum/api.service.ethereum.js.map +1 -1
  11. package/dist/ethereum/block.ethereum.js +6 -2
  12. package/dist/ethereum/block.ethereum.js.map +1 -1
  13. package/dist/ethereum/utils.ethereum.d.ts +8 -1
  14. package/dist/ethereum/utils.ethereum.js +17 -1
  15. package/dist/ethereum/utils.ethereum.js.map +1 -1
  16. package/dist/indexer/blockDispatcher/block-dispatcher.service.d.ts +2 -3
  17. package/dist/indexer/blockDispatcher/block-dispatcher.service.js +1 -4
  18. package/dist/indexer/blockDispatcher/block-dispatcher.service.js.map +1 -1
  19. package/dist/indexer/blockDispatcher/ethereum-block-dispatcher.d.ts +2 -1
  20. package/dist/indexer/blockDispatcher/ethereum-block-dispatcher.js.map +1 -1
  21. package/dist/indexer/blockDispatcher/worker-block-dispatcher.service.d.ts +2 -1
  22. package/dist/indexer/blockDispatcher/worker-block-dispatcher.service.js +0 -12
  23. package/dist/indexer/blockDispatcher/worker-block-dispatcher.service.js.map +1 -1
  24. package/dist/indexer/dictionary/ethDictionary.service.d.ts +9 -0
  25. package/dist/indexer/dictionary/ethDictionary.service.js +59 -0
  26. package/dist/indexer/dictionary/ethDictionary.service.js.map +1 -0
  27. package/dist/indexer/dictionary/utils.d.ts +3 -0
  28. package/dist/indexer/dictionary/utils.js +24 -0
  29. package/dist/indexer/dictionary/utils.js.map +1 -0
  30. package/dist/indexer/dictionary/utils.spec.js +83 -0
  31. package/dist/indexer/dictionary/utils.spec.js.map +1 -0
  32. package/dist/indexer/dictionary/v1/ethDictionaryV1.d.ts +16 -0
  33. package/dist/indexer/dictionary/v1/ethDictionaryV1.js +202 -0
  34. package/dist/indexer/dictionary/v1/ethDictionaryV1.js.map +1 -0
  35. package/dist/indexer/{fetch.service.spec.js → dictionary/v1/ethDictionaryV1.spec.js} +45 -23
  36. package/dist/indexer/dictionary/v1/ethDictionaryV1.spec.js.map +1 -0
  37. package/dist/indexer/dictionary/v1/index.d.ts +1 -0
  38. package/dist/indexer/dictionary/v1/index.js +20 -0
  39. package/dist/indexer/dictionary/v1/index.js.map +1 -0
  40. package/dist/indexer/dictionary/v2/ethDictionaryV2.d.ts +14 -0
  41. package/dist/indexer/dictionary/v2/ethDictionaryV2.js +188 -0
  42. package/dist/indexer/dictionary/v2/ethDictionaryV2.js.map +1 -0
  43. package/dist/indexer/dictionary/v2/ethDictionaryV2.spec.d.ts +1 -0
  44. package/dist/indexer/dictionary/v2/ethDictionaryV2.spec.js +232 -0
  45. package/dist/indexer/dictionary/v2/ethDictionaryV2.spec.js.map +1 -0
  46. package/dist/indexer/dictionary/v2/index.d.ts +2 -0
  47. package/dist/indexer/dictionary/v2/index.js +21 -0
  48. package/dist/indexer/dictionary/v2/index.js.map +1 -0
  49. package/dist/indexer/dictionary/v2/types.d.ts +75 -0
  50. package/dist/indexer/dictionary/v2/types.js +5 -0
  51. package/dist/indexer/dictionary/v2/types.js.map +1 -0
  52. package/dist/indexer/dictionary/v2/utils.d.ts +4 -0
  53. package/dist/indexer/dictionary/v2/utils.js +22 -0
  54. package/dist/indexer/dictionary/v2/utils.js.map +1 -0
  55. package/dist/indexer/dictionary/v2/utils.spec.d.ts +1 -0
  56. package/dist/indexer/dictionary/v2/utils.spec.js +98 -0
  57. package/dist/indexer/dictionary/v2/utils.spec.js.map +1 -0
  58. package/dist/indexer/fetch.module.js +4 -3
  59. package/dist/indexer/fetch.module.js.map +1 -1
  60. package/dist/indexer/fetch.service.d.ts +4 -14
  61. package/dist/indexer/fetch.service.js +4 -177
  62. package/dist/indexer/fetch.service.js.map +1 -1
  63. package/dist/indexer/indexer.manager.d.ts +5 -5
  64. package/dist/indexer/indexer.manager.js +3 -3
  65. package/dist/indexer/indexer.manager.js.map +1 -1
  66. package/dist/indexer/unfinalizedBlocks.service.d.ts +1 -5
  67. package/dist/indexer/unfinalizedBlocks.service.js +5 -21
  68. package/dist/indexer/unfinalizedBlocks.service.js.map +1 -1
  69. package/dist/indexer/worker/worker.service.d.ts +4 -4
  70. package/dist/indexer/worker/worker.service.js +1 -1
  71. package/dist/indexer/worker/worker.service.js.map +1 -1
  72. package/dist/indexer/worker/worker.unfinalizedBlocks.service.d.ts +2 -2
  73. package/dist/indexer/worker/worker.unfinalizedBlocks.service.js +2 -6
  74. package/dist/indexer/worker/worker.unfinalizedBlocks.service.js.map +1 -1
  75. package/dist/subcommands/testing.service.d.ts +2 -2
  76. package/dist/subcommands/testing.service.js.map +1 -1
  77. package/package.json +8 -7
  78. package/dist/indexer/dictionary.service.d.ts +0 -11
  79. package/dist/indexer/dictionary.service.js +0 -72
  80. package/dist/indexer/dictionary.service.js.map +0 -1
  81. package/dist/indexer/dictionary.service.spec.js +0 -15
  82. package/dist/indexer/dictionary.service.spec.js.map +0 -1
  83. package/dist/indexer/fetch.service.spec.js.map +0 -1
  84. /package/dist/indexer/{dictionary.service.spec.d.ts → dictionary/utils.spec.d.ts} +0 -0
  85. /package/dist/indexer/{fetch.service.spec.d.ts → dictionary/v1/ethDictionaryV1.spec.d.ts} +0 -0
@@ -1,6 +1,6 @@
1
1
  import { OnApplicationShutdown } from '@nestjs/common';
2
2
  import { EventEmitter2 } from '@nestjs/event-emitter';
3
- import { NodeConfig, SmartBatchService, StoreCacheService, StoreService, IProjectService, BlockDispatcher, ProcessBlockResponse, ApiService, IProjectUpgradeService, PoiSyncService } from '@subql/node-core';
3
+ import { NodeConfig, SmartBatchService, StoreCacheService, StoreService, IProjectService, BlockDispatcher, ProcessBlockResponse, ApiService, IProjectUpgradeService, PoiSyncService, IBlock } from '@subql/node-core';
4
4
  import { EthereumProjectDs, SubqueryProject } from '../../configure/SubqueryProject';
5
5
  import { DynamicDsService } from '../dynamic-ds.service';
6
6
  import { IndexerManager } from '../indexer.manager';
@@ -11,6 +11,5 @@ import { BlockContent } from '../types';
11
11
  export declare class BlockDispatcherService extends BlockDispatcher<BlockContent, EthereumProjectDs> implements OnApplicationShutdown {
12
12
  private indexerManager;
13
13
  constructor(apiService: ApiService, nodeConfig: NodeConfig, indexerManager: IndexerManager, eventEmitter: EventEmitter2, projectService: IProjectService<EthereumProjectDs>, projectUpgradeService: IProjectUpgradeService, smartBatchService: SmartBatchService, storeService: StoreService, storeCacheService: StoreCacheService, poiSyncService: PoiSyncService, project: SubqueryProject, dynamicDsService: DynamicDsService);
14
- protected getBlockHeight(block: BlockContent): number;
15
- protected indexBlock(block: BlockContent): Promise<ProcessBlockResponse>;
14
+ protected indexBlock(block: IBlock<BlockContent>): Promise<ProcessBlockResponse>;
16
15
  }
@@ -29,11 +29,8 @@ let BlockDispatcherService = class BlockDispatcherService extends node_core_1.Bl
29
29
  super(nodeConfig, eventEmitter, projectService, projectUpgradeService, smartBatchService, storeService, storeCacheService, poiSyncService, project, dynamicDsService, apiService.fetchBlocks.bind(apiService));
30
30
  this.indexerManager = indexerManager;
31
31
  }
32
- getBlockHeight(block) {
33
- return block.number;
34
- }
35
32
  async indexBlock(block) {
36
- return this.indexerManager.indexBlock(block, await this.projectService.getDataSources(this.getBlockHeight(block)));
33
+ return this.indexerManager.indexBlock(block, await this.projectService.getDataSources(block.getHeader().blockHeight));
37
34
  }
38
35
  };
39
36
  BlockDispatcherService = __decorate([
@@ -1 +1 @@
1
- {"version":3,"file":"block-dispatcher.service.js","sourceRoot":"","sources":["../../../src/indexer/blockDispatcher/block-dispatcher.service.ts"],"names":[],"mappings":";AAAA,8DAA8D;AAC9D,mCAAmC;;;;;;;;;;;;;;;AAEnC,2CAA2E;AAC3E,yDAAsD;AACtD,gDAY0B;AAC1B,qEAGyC;AACzC,8DAAyD;AACzD,wDAAoD;AAGpD;;GAEG;AAEI,IAAM,sBAAsB,GAA5B,MAAM,sBACX,SAAQ,2BAAgD;IAGxD,YACE,UAAsB,EACtB,UAAsB,EACd,cAA8B,EACtC,YAA2B,EAE3B,cAAkD,EAElD,qBAA6C,EAC7C,iBAAoC,EACpC,YAA0B,EAC1B,iBAAoC,EACpC,cAA8B,EACF,OAAwB,EACpD,gBAAkC;QAElC,KAAK,CACH,UAAU,EACV,YAAY,EACZ,cAAc,EACd,qBAAqB,EACrB,iBAAiB,EACjB,YAAY,EACZ,iBAAiB,EACjB,cAAc,EACd,OAAO,EACP,gBAAgB,EAChB,UAAU,CAAC,WAAW,CAAC,IAAI,CAAC,UAAU,CAAC,CACxC,CAAC;QAzBM,mBAAc,GAAd,cAAc,CAAgB;IA0BxC,CAAC;IAES,cAAc,CAAC,KAAmB;QAC1C,OAAO,KAAK,CAAC,MAAM,CAAC;IACtB,CAAC;IAES,KAAK,CAAC,UAAU,CACxB,KAAmB;QAEnB,OAAO,IAAI,CAAC,cAAc,CAAC,UAAU,CACnC,KAAK,EACL,MAAM,IAAI,CAAC,cAAc,CAAC,cAAc,CAAC,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC,CACrE,CAAC;IACJ,CAAC;CACF,CAAA;AA/CY,sBAAsB;IADlC,IAAA,mBAAU,GAAE;IAUR,WAAA,IAAA,eAAM,EAAC,iBAAiB,CAAC,CAAA;IAEzB,WAAA,IAAA,eAAM,EAAC,wBAAwB,CAAC,CAAA;IAMhC,YAAA,IAAA,eAAM,EAAC,kBAAkB,CAAC,CAAA;qCAZf,sBAAU;QACV,sBAAU;QACE,gCAAc;QACxB,6BAAa,kBAKR,6BAAiB;QACtB,wBAAY;QACP,6BAAiB;QACpB,0BAAc;QACO,iCAAe;QAClC,qCAAgB;GAlBzB,sBAAsB,CA+ClC;AA/CY,wDAAsB","sourcesContent":["// Copyright 2020-2024 SubQuery Pte Ltd authors & contributors\n// SPDX-License-Identifier: GPL-3.0\n\nimport { Inject, Injectable, OnApplicationShutdown } from '@nestjs/common';\nimport { EventEmitter2 } from '@nestjs/event-emitter';\nimport {\n NodeConfig,\n SmartBatchService,\n StoreCacheService,\n StoreService,\n IProjectService,\n PoiService,\n BlockDispatcher,\n ProcessBlockResponse,\n ApiService,\n IProjectUpgradeService,\n PoiSyncService,\n} from '@subql/node-core';\nimport {\n EthereumProjectDs,\n SubqueryProject,\n} from '../../configure/SubqueryProject';\nimport { DynamicDsService } from '../dynamic-ds.service';\nimport { IndexerManager } from '../indexer.manager';\nimport { BlockContent } from '../types';\n\n/**\n * @description Intended to behave the same as WorkerBlockDispatcherService but doesn't use worker threads or any parallel processing\n */\n@Injectable()\nexport class BlockDispatcherService\n extends BlockDispatcher<BlockContent, EthereumProjectDs>\n implements OnApplicationShutdown\n{\n constructor(\n apiService: ApiService,\n nodeConfig: NodeConfig,\n private indexerManager: IndexerManager,\n eventEmitter: EventEmitter2,\n @Inject('IProjectService')\n projectService: IProjectService<EthereumProjectDs>,\n @Inject('IProjectUpgradeService')\n projectUpgradeService: IProjectUpgradeService,\n smartBatchService: SmartBatchService,\n storeService: StoreService,\n storeCacheService: StoreCacheService,\n poiSyncService: PoiSyncService,\n @Inject('ISubqueryProject') project: SubqueryProject,\n dynamicDsService: DynamicDsService,\n ) {\n super(\n nodeConfig,\n eventEmitter,\n projectService,\n projectUpgradeService,\n smartBatchService,\n storeService,\n storeCacheService,\n poiSyncService,\n project,\n dynamicDsService,\n apiService.fetchBlocks.bind(apiService),\n );\n }\n\n protected getBlockHeight(block: BlockContent): number {\n return block.number;\n }\n\n protected async indexBlock(\n block: BlockContent,\n ): Promise<ProcessBlockResponse> {\n return this.indexerManager.indexBlock(\n block,\n await this.projectService.getDataSources(this.getBlockHeight(block)),\n );\n }\n}\n"]}
1
+ {"version":3,"file":"block-dispatcher.service.js","sourceRoot":"","sources":["../../../src/indexer/blockDispatcher/block-dispatcher.service.ts"],"names":[],"mappings":";AAAA,8DAA8D;AAC9D,mCAAmC;;;;;;;;;;;;;;;AAEnC,2CAA2E;AAC3E,yDAAsD;AACtD,gDAY0B;AAC1B,qEAGyC;AACzC,8DAAyD;AACzD,wDAAoD;AAGpD;;GAEG;AAEI,IAAM,sBAAsB,GAA5B,MAAM,sBACX,SAAQ,2BAAgD;IAGxD,YACE,UAAsB,EACtB,UAAsB,EACd,cAA8B,EACtC,YAA2B,EAE3B,cAAkD,EAElD,qBAA6C,EAC7C,iBAAoC,EACpC,YAA0B,EAC1B,iBAAoC,EACpC,cAA8B,EACF,OAAwB,EACpD,gBAAkC;QAElC,KAAK,CACH,UAAU,EACV,YAAY,EACZ,cAAc,EACd,qBAAqB,EACrB,iBAAiB,EACjB,YAAY,EACZ,iBAAiB,EACjB,cAAc,EACd,OAAO,EACP,gBAAgB,EAChB,UAAU,CAAC,WAAW,CAAC,IAAI,CAAC,UAAU,CAAC,CACxC,CAAC;QAzBM,mBAAc,GAAd,cAAc,CAAgB;IA0BxC,CAAC;IAES,KAAK,CAAC,UAAU,CACxB,KAA2B;QAE3B,OAAO,IAAI,CAAC,cAAc,CAAC,UAAU,CACnC,KAAK,EACL,MAAM,IAAI,CAAC,cAAc,CAAC,cAAc,CAAC,KAAK,CAAC,SAAS,EAAE,CAAC,WAAW,CAAC,CACxE,CAAC;IACJ,CAAC;CACF,CAAA;AA3CY,sBAAsB;IADlC,IAAA,mBAAU,GAAE;IAUR,WAAA,IAAA,eAAM,EAAC,iBAAiB,CAAC,CAAA;IAEzB,WAAA,IAAA,eAAM,EAAC,wBAAwB,CAAC,CAAA;IAMhC,YAAA,IAAA,eAAM,EAAC,kBAAkB,CAAC,CAAA;qCAZf,sBAAU;QACV,sBAAU;QACE,gCAAc;QACxB,6BAAa,kBAKR,6BAAiB;QACtB,wBAAY;QACP,6BAAiB;QACpB,0BAAc;QACO,iCAAe;QAClC,qCAAgB;GAlBzB,sBAAsB,CA2ClC;AA3CY,wDAAsB","sourcesContent":["// Copyright 2020-2024 SubQuery Pte Ltd authors & contributors\n// SPDX-License-Identifier: GPL-3.0\n\nimport { Inject, Injectable, OnApplicationShutdown } from '@nestjs/common';\nimport { EventEmitter2 } from '@nestjs/event-emitter';\nimport {\n NodeConfig,\n SmartBatchService,\n StoreCacheService,\n StoreService,\n IProjectService,\n BlockDispatcher,\n ProcessBlockResponse,\n ApiService,\n IProjectUpgradeService,\n PoiSyncService,\n IBlock,\n} from '@subql/node-core';\nimport {\n EthereumProjectDs,\n SubqueryProject,\n} from '../../configure/SubqueryProject';\nimport { DynamicDsService } from '../dynamic-ds.service';\nimport { IndexerManager } from '../indexer.manager';\nimport { BlockContent } from '../types';\n\n/**\n * @description Intended to behave the same as WorkerBlockDispatcherService but doesn't use worker threads or any parallel processing\n */\n@Injectable()\nexport class BlockDispatcherService\n extends BlockDispatcher<BlockContent, EthereumProjectDs>\n implements OnApplicationShutdown\n{\n constructor(\n apiService: ApiService,\n nodeConfig: NodeConfig,\n private indexerManager: IndexerManager,\n eventEmitter: EventEmitter2,\n @Inject('IProjectService')\n projectService: IProjectService<EthereumProjectDs>,\n @Inject('IProjectUpgradeService')\n projectUpgradeService: IProjectUpgradeService,\n smartBatchService: SmartBatchService,\n storeService: StoreService,\n storeCacheService: StoreCacheService,\n poiSyncService: PoiSyncService,\n @Inject('ISubqueryProject') project: SubqueryProject,\n dynamicDsService: DynamicDsService,\n ) {\n super(\n nodeConfig,\n eventEmitter,\n projectService,\n projectUpgradeService,\n smartBatchService,\n storeService,\n storeCacheService,\n poiSyncService,\n project,\n dynamicDsService,\n apiService.fetchBlocks.bind(apiService),\n );\n }\n\n protected async indexBlock(\n block: IBlock<BlockContent>,\n ): Promise<ProcessBlockResponse> {\n return this.indexerManager.indexBlock(\n block,\n await this.projectService.getDataSources(block.getHeader().blockHeight),\n );\n }\n}\n"]}
@@ -1,4 +1,5 @@
1
1
  import { IBlockDispatcher } from '@subql/node-core';
2
- export interface IEthereumBlockDispatcher extends IBlockDispatcher {
2
+ import { EthereumBlock } from '@subql/types-ethereum';
3
+ export interface IEthereumBlockDispatcher extends IBlockDispatcher<EthereumBlock> {
3
4
  init(onDynamicDsCreated: (height: number) => Promise<void>): Promise<void>;
4
5
  }
@@ -1 +1 @@
1
- {"version":3,"file":"ethereum-block-dispatcher.js","sourceRoot":"","sources":["../../../src/indexer/blockDispatcher/ethereum-block-dispatcher.ts"],"names":[],"mappings":";AAAA,8DAA8D;AAC9D,mCAAmC","sourcesContent":["// Copyright 2020-2024 SubQuery Pte Ltd authors & contributors\n// SPDX-License-Identifier: GPL-3.0\n\nimport { IBlockDispatcher } from '@subql/node-core';\n\nexport interface IEthereumBlockDispatcher extends IBlockDispatcher {\n init(onDynamicDsCreated: (height: number) => Promise<void>): Promise<void>;\n}\n"]}
1
+ {"version":3,"file":"ethereum-block-dispatcher.js","sourceRoot":"","sources":["../../../src/indexer/blockDispatcher/ethereum-block-dispatcher.ts"],"names":[],"mappings":";AAAA,8DAA8D;AAC9D,mCAAmC","sourcesContent":["// Copyright 2020-2024 SubQuery Pte Ltd authors & contributors\n// SPDX-License-Identifier: GPL-3.0\n\nimport { IBlockDispatcher, IBlock } from '@subql/node-core';\nimport { EthereumBlock } from '@subql/types-ethereum';\n\nexport interface IEthereumBlockDispatcher\n extends IBlockDispatcher<EthereumBlock> {\n init(onDynamicDsCreated: (height: number) => Promise<void>): Promise<void>;\n}\n"]}
@@ -1,6 +1,7 @@
1
1
  import { OnApplicationShutdown } from '@nestjs/common';
2
2
  import { EventEmitter2 } from '@nestjs/event-emitter';
3
3
  import { NodeConfig, SmartBatchService, StoreService, StoreCacheService, IProjectService, WorkerBlockDispatcher, ConnectionPoolStateManager, IProjectUpgradeService, PoiSyncService, InMemoryCacheService } from '@subql/node-core';
4
+ import { EthereumBlock } from '@subql/types-ethereum';
4
5
  import { EthereumProjectDs, SubqueryProject } from '../../configure/SubqueryProject';
5
6
  import { EthereumApiConnection } from '../../ethereum/api.connection';
6
7
  import { DynamicDsService } from '../dynamic-ds.service';
@@ -9,7 +10,7 @@ import { IIndexerWorker } from '../worker/worker';
9
10
  type IndexerWorker = IIndexerWorker & {
10
11
  terminate: () => Promise<number>;
11
12
  };
12
- export declare class WorkerBlockDispatcherService extends WorkerBlockDispatcher<EthereumProjectDs, IndexerWorker> implements OnApplicationShutdown {
13
+ export declare class WorkerBlockDispatcherService extends WorkerBlockDispatcher<EthereumProjectDs, IndexerWorker, EthereumBlock> implements OnApplicationShutdown {
13
14
  constructor(nodeConfig: NodeConfig, eventEmitter: EventEmitter2, projectService: IProjectService<EthereumProjectDs>, projectUpgadeService: IProjectUpgradeService, smartBatchService: SmartBatchService, cacheService: InMemoryCacheService, storeService: StoreService, storeCacheService: StoreCacheService, poiSyncService: PoiSyncService, project: SubqueryProject, dynamicDsService: DynamicDsService, unfinalizedBlocksSevice: UnfinalizedBlocksService, connectionPoolState: ConnectionPoolStateManager<EthereumApiConnection>);
14
15
  protected fetchBlock(worker: IndexerWorker, height: number): Promise<void>;
15
16
  }
@@ -30,19 +30,7 @@ let WorkerBlockDispatcherService = class WorkerBlockDispatcherService extends no
30
30
  super(nodeConfig, eventEmitter, projectService, projectUpgadeService, smartBatchService, storeService, storeCacheService, poiSyncService, project, dynamicDsService, () => (0, node_core_1.createIndexerWorker)(path_1.default.resolve(__dirname, '../../../dist/indexer/worker/worker.js'), [], storeService.getStore(), cacheService.getCache(), dynamicDsService, unfinalizedBlocksSevice, connectionPoolState, project.root, projectService.startHeight));
31
31
  }
32
32
  async fetchBlock(worker, height) {
33
- const start = new Date();
34
33
  await worker.fetchBlock(height, null);
35
- const end = new Date();
36
- // const waitTime = end.getTime() - start.getTime();
37
- // if (waitTime > 1000) {
38
- // logger.info(
39
- // `Waiting to fetch block ${height}: ${chalk.red(`${waitTime}ms`)}`,
40
- // );
41
- // } else if (waitTime > 200) {
42
- // logger.info(
43
- // `Waiting to fetch block ${height}: ${chalk.yellow(`${waitTime}ms`)}`,
44
- // );
45
- // }
46
34
  }
47
35
  };
48
36
  WorkerBlockDispatcherService = __decorate([
@@ -1 +1 @@
1
- {"version":3,"file":"worker-block-dispatcher.service.js","sourceRoot":"","sources":["../../../src/indexer/blockDispatcher/worker-block-dispatcher.service.ts"],"names":[],"mappings":";AAAA,8DAA8D;AAC9D,mCAAmC;;;;;;;;;;;;;;;;;;AAEnC,gDAAwB;AACxB,2CAA2E;AAC3E,yDAAsD;AACtD,gDAa0B;AAC1B,qEAGyC;AAEzC,8DAAyD;AAEzD,4EAAwE;AAQjE,IAAM,4BAA4B,GAAlC,MAAM,4BACX,SAAQ,iCAAuD;IAG/D,YACE,UAAsB,EACtB,YAA2B,EAE3B,cAAkD,EAElD,oBAA4C,EAC5C,iBAAoC,EACpC,YAAkC,EAClC,YAA0B,EAC1B,iBAAoC,EACpC,cAA8B,EACF,OAAwB,EACpD,gBAAkC,EAClC,uBAAiD,EACjD,mBAAsE;QAEtE,KAAK,CACH,UAAU,EACV,YAAY,EACZ,cAAc,EACd,oBAAoB,EACpB,iBAAiB,EACjB,YAAY,EACZ,iBAAiB,EACjB,cAAc,EACd,OAAO,EACP,gBAAgB,EAChB,GAAG,EAAE,CACH,IAAA,+BAAmB,EAMjB,cAAI,CAAC,OAAO,CAAC,SAAS,EAAE,wCAAwC,CAAC,EACjE,EAAE,EACF,YAAY,CAAC,QAAQ,EAAE,EACvB,YAAY,CAAC,QAAQ,EAAE,EACvB,gBAAgB,EAChB,uBAAuB,EACvB,mBAAmB,EACnB,OAAO,CAAC,IAAI,EACZ,cAAc,CAAC,WAAW,CAC3B,CACJ,CAAC;IACJ,CAAC;IAES,KAAK,CAAC,UAAU,CACxB,MAAqB,EACrB,MAAc;QAEd,MAAM,KAAK,GAAG,IAAI,IAAI,EAAE,CAAC;QACzB,MAAM,MAAM,CAAC,UAAU,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QACtC,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;QAEvB,oDAAoD;QACpD,yBAAyB;QACzB,iBAAiB;QACjB,yEAAyE;QACzE,OAAO;QACP,+BAA+B;QAC/B,iBAAiB;QACjB,4EAA4E;QAC5E,OAAO;QACP,IAAI;IACN,CAAC;CACF,CAAA;AAvEY,4BAA4B;IADxC,IAAA,mBAAU,GAAE;IAQR,WAAA,IAAA,eAAM,EAAC,iBAAiB,CAAC,CAAA;IAEzB,WAAA,IAAA,eAAM,EAAC,wBAAwB,CAAC,CAAA;IAOhC,WAAA,IAAA,eAAM,EAAC,kBAAkB,CAAC,CAAA;qCAXf,sBAAU;QACR,6BAAa,kBAKR,6BAAiB;QACtB,gCAAoB;QACpB,wBAAY;QACP,6BAAiB;QACpB,0BAAc;QACO,iCAAe;QAClC,qCAAgB;QACT,oDAAwB;QAC5B,sCAA0B;GAnBtC,4BAA4B,CAuExC;AAvEY,oEAA4B","sourcesContent":["// Copyright 2020-2024 SubQuery Pte Ltd authors & contributors\n// SPDX-License-Identifier: GPL-3.0\n\nimport path from 'path';\nimport { Inject, Injectable, OnApplicationShutdown } from '@nestjs/common';\nimport { EventEmitter2 } from '@nestjs/event-emitter';\nimport {\n NodeConfig,\n SmartBatchService,\n StoreService,\n PoiService,\n StoreCacheService,\n IProjectService,\n WorkerBlockDispatcher,\n ConnectionPoolStateManager,\n IProjectUpgradeService,\n PoiSyncService,\n InMemoryCacheService,\n createIndexerWorker,\n} from '@subql/node-core';\nimport {\n EthereumProjectDs,\n SubqueryProject,\n} from '../../configure/SubqueryProject';\nimport { EthereumApiConnection } from '../../ethereum/api.connection';\nimport { DynamicDsService } from '../dynamic-ds.service';\nimport { BlockContent } from '../types';\nimport { UnfinalizedBlocksService } from '../unfinalizedBlocks.service';\nimport { IIndexerWorker } from '../worker/worker';\n\ntype IndexerWorker = IIndexerWorker & {\n terminate: () => Promise<number>;\n};\n\n@Injectable()\nexport class WorkerBlockDispatcherService\n extends WorkerBlockDispatcher<EthereumProjectDs, IndexerWorker>\n implements OnApplicationShutdown\n{\n constructor(\n nodeConfig: NodeConfig,\n eventEmitter: EventEmitter2,\n @Inject('IProjectService')\n projectService: IProjectService<EthereumProjectDs>,\n @Inject('IProjectUpgradeService')\n projectUpgadeService: IProjectUpgradeService,\n smartBatchService: SmartBatchService,\n cacheService: InMemoryCacheService,\n storeService: StoreService,\n storeCacheService: StoreCacheService,\n poiSyncService: PoiSyncService,\n @Inject('ISubqueryProject') project: SubqueryProject,\n dynamicDsService: DynamicDsService,\n unfinalizedBlocksSevice: UnfinalizedBlocksService,\n connectionPoolState: ConnectionPoolStateManager<EthereumApiConnection>,\n ) {\n super(\n nodeConfig,\n eventEmitter,\n projectService,\n projectUpgadeService,\n smartBatchService,\n storeService,\n storeCacheService,\n poiSyncService,\n project,\n dynamicDsService,\n () =>\n createIndexerWorker<\n IIndexerWorker,\n EthereumApiConnection,\n BlockContent,\n EthereumProjectDs\n >(\n path.resolve(__dirname, '../../../dist/indexer/worker/worker.js'),\n [],\n storeService.getStore(),\n cacheService.getCache(),\n dynamicDsService,\n unfinalizedBlocksSevice,\n connectionPoolState,\n project.root,\n projectService.startHeight,\n ),\n );\n }\n\n protected async fetchBlock(\n worker: IndexerWorker,\n height: number,\n ): Promise<void> {\n const start = new Date();\n await worker.fetchBlock(height, null);\n const end = new Date();\n\n // const waitTime = end.getTime() - start.getTime();\n // if (waitTime > 1000) {\n // logger.info(\n // `Waiting to fetch block ${height}: ${chalk.red(`${waitTime}ms`)}`,\n // );\n // } else if (waitTime > 200) {\n // logger.info(\n // `Waiting to fetch block ${height}: ${chalk.yellow(`${waitTime}ms`)}`,\n // );\n // }\n }\n}\n"]}
1
+ {"version":3,"file":"worker-block-dispatcher.service.js","sourceRoot":"","sources":["../../../src/indexer/blockDispatcher/worker-block-dispatcher.service.ts"],"names":[],"mappings":";AAAA,8DAA8D;AAC9D,mCAAmC;;;;;;;;;;;;;;;;;;AAEnC,gDAAwB;AACxB,2CAA2E;AAC3E,yDAAsD;AACtD,gDAY0B;AAE1B,qEAGyC;AAEzC,8DAAyD;AAEzD,4EAAwE;AAQjE,IAAM,4BAA4B,GAAlC,MAAM,4BACX,SAAQ,iCAAsE;IAG9E,YACE,UAAsB,EACtB,YAA2B,EAE3B,cAAkD,EAElD,oBAA4C,EAC5C,iBAAoC,EACpC,YAAkC,EAClC,YAA0B,EAC1B,iBAAoC,EACpC,cAA8B,EACF,OAAwB,EACpD,gBAAkC,EAClC,uBAAiD,EACjD,mBAAsE;QAEtE,KAAK,CACH,UAAU,EACV,YAAY,EACZ,cAAc,EACd,oBAAoB,EACpB,iBAAiB,EACjB,YAAY,EACZ,iBAAiB,EACjB,cAAc,EACd,OAAO,EACP,gBAAgB,EAChB,GAAG,EAAE,CACH,IAAA,+BAAmB,EAMjB,cAAI,CAAC,OAAO,CAAC,SAAS,EAAE,wCAAwC,CAAC,EACjE,EAAE,EACF,YAAY,CAAC,QAAQ,EAAE,EACvB,YAAY,CAAC,QAAQ,EAAE,EACvB,gBAAgB,EAChB,uBAAuB,EACvB,mBAAmB,EACnB,OAAO,CAAC,IAAI,EACZ,cAAc,CAAC,WAAW,CAC3B,CACJ,CAAC;IACJ,CAAC;IAES,KAAK,CAAC,UAAU,CACxB,MAAqB,EACrB,MAAc;QAEd,MAAM,MAAM,CAAC,UAAU,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IACxC,CAAC;CACF,CAAA;AA1DY,4BAA4B;IADxC,IAAA,mBAAU,GAAE;IAQR,WAAA,IAAA,eAAM,EAAC,iBAAiB,CAAC,CAAA;IAEzB,WAAA,IAAA,eAAM,EAAC,wBAAwB,CAAC,CAAA;IAOhC,WAAA,IAAA,eAAM,EAAC,kBAAkB,CAAC,CAAA;qCAXf,sBAAU;QACR,6BAAa,kBAKR,6BAAiB;QACtB,gCAAoB;QACpB,wBAAY;QACP,6BAAiB;QACpB,0BAAc;QACO,iCAAe;QAClC,qCAAgB;QACT,oDAAwB;QAC5B,sCAA0B;GAnBtC,4BAA4B,CA0DxC;AA1DY,oEAA4B","sourcesContent":["// Copyright 2020-2024 SubQuery Pte Ltd authors & contributors\n// SPDX-License-Identifier: GPL-3.0\n\nimport path from 'path';\nimport { Inject, Injectable, OnApplicationShutdown } from '@nestjs/common';\nimport { EventEmitter2 } from '@nestjs/event-emitter';\nimport {\n NodeConfig,\n SmartBatchService,\n StoreService,\n StoreCacheService,\n IProjectService,\n WorkerBlockDispatcher,\n ConnectionPoolStateManager,\n IProjectUpgradeService,\n PoiSyncService,\n InMemoryCacheService,\n createIndexerWorker,\n} from '@subql/node-core';\nimport { EthereumBlock } from '@subql/types-ethereum';\nimport {\n EthereumProjectDs,\n SubqueryProject,\n} from '../../configure/SubqueryProject';\nimport { EthereumApiConnection } from '../../ethereum/api.connection';\nimport { DynamicDsService } from '../dynamic-ds.service';\nimport { BlockContent } from '../types';\nimport { UnfinalizedBlocksService } from '../unfinalizedBlocks.service';\nimport { IIndexerWorker } from '../worker/worker';\n\ntype IndexerWorker = IIndexerWorker & {\n terminate: () => Promise<number>;\n};\n\n@Injectable()\nexport class WorkerBlockDispatcherService\n extends WorkerBlockDispatcher<EthereumProjectDs, IndexerWorker, EthereumBlock>\n implements OnApplicationShutdown\n{\n constructor(\n nodeConfig: NodeConfig,\n eventEmitter: EventEmitter2,\n @Inject('IProjectService')\n projectService: IProjectService<EthereumProjectDs>,\n @Inject('IProjectUpgradeService')\n projectUpgadeService: IProjectUpgradeService,\n smartBatchService: SmartBatchService,\n cacheService: InMemoryCacheService,\n storeService: StoreService,\n storeCacheService: StoreCacheService,\n poiSyncService: PoiSyncService,\n @Inject('ISubqueryProject') project: SubqueryProject,\n dynamicDsService: DynamicDsService,\n unfinalizedBlocksSevice: UnfinalizedBlocksService,\n connectionPoolState: ConnectionPoolStateManager<EthereumApiConnection>,\n ) {\n super(\n nodeConfig,\n eventEmitter,\n projectService,\n projectUpgadeService,\n smartBatchService,\n storeService,\n storeCacheService,\n poiSyncService,\n project,\n dynamicDsService,\n () =>\n createIndexerWorker<\n IIndexerWorker,\n EthereumApiConnection,\n BlockContent,\n EthereumProjectDs\n >(\n path.resolve(__dirname, '../../../dist/indexer/worker/worker.js'),\n [],\n storeService.getStore(),\n cacheService.getCache(),\n dynamicDsService,\n unfinalizedBlocksSevice,\n connectionPoolState,\n project.root,\n projectService.startHeight,\n ),\n );\n }\n\n protected async fetchBlock(\n worker: IndexerWorker,\n height: number,\n ): Promise<void> {\n await worker.fetchBlock(height, null);\n }\n}\n"]}
@@ -0,0 +1,9 @@
1
+ import { EventEmitter2 } from '@nestjs/event-emitter';
2
+ import { NodeConfig, DictionaryService } from '@subql/node-core';
3
+ import { EthereumBlock, SubqlDatasource } from '@subql/types-ethereum';
4
+ import { SubqueryProject } from '../../configure/SubqueryProject';
5
+ export declare class EthDictionaryService extends DictionaryService<SubqlDatasource, EthereumBlock> {
6
+ protected project: SubqueryProject;
7
+ constructor(project: SubqueryProject, nodeConfig: NodeConfig, eventEmitter: EventEmitter2);
8
+ initDictionaries(): Promise<void>;
9
+ }
@@ -0,0 +1,59 @@
1
+ "use strict";
2
+ // Copyright 2020-2024 SubQuery Pte Ltd authors & contributors
3
+ // SPDX-License-Identifier: GPL-3.0
4
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
5
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
6
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
7
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
8
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
9
+ };
10
+ var __metadata = (this && this.__metadata) || function (k, v) {
11
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
12
+ };
13
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
14
+ return function (target, key) { decorator(target, key, paramIndex); }
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.EthDictionaryService = void 0;
18
+ const common_1 = require("@nestjs/common");
19
+ const event_emitter_1 = require("@nestjs/event-emitter");
20
+ const common_2 = require("@subql/common");
21
+ const node_core_1 = require("@subql/node-core");
22
+ const SubqueryProject_1 = require("../../configure/SubqueryProject");
23
+ const v1_1 = require("./v1");
24
+ const v2_1 = require("./v2");
25
+ let EthDictionaryService = class EthDictionaryService extends node_core_1.DictionaryService {
26
+ constructor(project, nodeConfig, eventEmitter) {
27
+ super(project.network.chainId, nodeConfig, eventEmitter);
28
+ this.project = project;
29
+ }
30
+ async initDictionaries() {
31
+ const dictionariesV1 = [];
32
+ const dictionariesV2 = [];
33
+ if (!this.project) {
34
+ throw new Error(`Project in Dictionary service not initialized `);
35
+ }
36
+ const dictionaryEndpoints = await this.getDictionaryEndpoints(common_2.NETWORK_FAMILY.ethereum, this.project.network);
37
+ for (const endpoint of dictionaryEndpoints) {
38
+ try {
39
+ const dictionaryV2 = await v2_1.EthDictionaryV2.create(endpoint, this.nodeConfig, this.eventEmitter, this.project, this.project.network.chainId);
40
+ dictionariesV2.push(dictionaryV2);
41
+ }
42
+ catch (e) {
43
+ const dictionaryV1 = await v1_1.EthDictionaryV1.create(this.project, this.nodeConfig, this.eventEmitter, endpoint);
44
+ dictionariesV1.push(dictionaryV1);
45
+ }
46
+ }
47
+ // v2 should be prioritised
48
+ this.init([...dictionariesV2, ...dictionariesV1]);
49
+ }
50
+ };
51
+ EthDictionaryService = __decorate([
52
+ (0, common_1.Injectable)(),
53
+ __param(0, (0, common_1.Inject)('ISubqueryProject')),
54
+ __metadata("design:paramtypes", [SubqueryProject_1.SubqueryProject,
55
+ node_core_1.NodeConfig,
56
+ event_emitter_1.EventEmitter2])
57
+ ], EthDictionaryService);
58
+ exports.EthDictionaryService = EthDictionaryService;
59
+ //# sourceMappingURL=ethDictionary.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ethDictionary.service.js","sourceRoot":"","sources":["../../../src/indexer/dictionary/ethDictionary.service.ts"],"names":[],"mappings":";AAAA,8DAA8D;AAC9D,mCAAmC;;;;;;;;;;;;;;;AAEnC,2CAAoD;AACpD,yDAAsD;AACtD,0CAA+C;AAC/C,gDAAiE;AAEjE,qEAAkE;AAClE,6BAAuC;AACvC,6BAAuC;AAGhC,IAAM,oBAAoB,GAA1B,MAAM,oBAAqB,SAAQ,6BAGzC;IACC,YACwC,OAAwB,EAC9D,UAAsB,EACtB,YAA2B;QAE3B,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,EAAE,UAAU,EAAE,YAAY,CAAC,CAAC;QAJnB,YAAO,GAAP,OAAO,CAAiB;IAKhE,CAAC;IAED,KAAK,CAAC,gBAAgB;QACpB,MAAM,cAAc,GAAsB,EAAE,CAAC;QAC7C,MAAM,cAAc,GAAsB,EAAE,CAAC;QAE7C,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE;YACjB,MAAM,IAAI,KAAK,CAAC,gDAAgD,CAAC,CAAC;SACnE;QAED,MAAM,mBAAmB,GAAG,MAAM,IAAI,CAAC,sBAAsB,CAC3D,uBAAc,CAAC,QAAQ,EACvB,IAAI,CAAC,OAAO,CAAC,OAAO,CACrB,CAAC;QAEF,KAAK,MAAM,QAAQ,IAAI,mBAAmB,EAAE;YAC1C,IAAI;gBACF,MAAM,YAAY,GAAG,MAAM,oBAAe,CAAC,MAAM,CAC/C,QAAQ,EACR,IAAI,CAAC,UAAU,EACf,IAAI,CAAC,YAAY,EACjB,IAAI,CAAC,OAAO,EACZ,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,CAC7B,CAAC;gBACF,cAAc,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;aACnC;YAAC,OAAO,CAAC,EAAE;gBACV,MAAM,YAAY,GAAG,MAAM,oBAAe,CAAC,MAAM,CAC/C,IAAI,CAAC,OAAO,EACZ,IAAI,CAAC,UAAU,EACf,IAAI,CAAC,YAAY,EACjB,QAAQ,CACT,CAAC;gBACF,cAAc,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;aACnC;SACF;QACD,2BAA2B;QAC3B,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,cAAc,EAAE,GAAG,cAAc,CAAC,CAAC,CAAC;IACpD,CAAC;CACF,CAAA;AAhDY,oBAAoB;IADhC,IAAA,mBAAU,GAAE;IAMR,WAAA,IAAA,eAAM,EAAC,kBAAkB,CAAC,CAAA;qCAAoB,iCAAe;QAClD,sBAAU;QACR,6BAAa;GAPlB,oBAAoB,CAgDhC;AAhDY,oDAAoB","sourcesContent":["// Copyright 2020-2024 SubQuery Pte Ltd authors & contributors\n// SPDX-License-Identifier: GPL-3.0\n\nimport { Inject, Injectable } from '@nestjs/common';\nimport { EventEmitter2 } from '@nestjs/event-emitter';\nimport { NETWORK_FAMILY } from '@subql/common';\nimport { NodeConfig, DictionaryService } from '@subql/node-core';\nimport { EthereumBlock, SubqlDatasource } from '@subql/types-ethereum';\nimport { SubqueryProject } from '../../configure/SubqueryProject';\nimport { EthDictionaryV1 } from './v1';\nimport { EthDictionaryV2 } from './v2';\n\n@Injectable()\nexport class EthDictionaryService extends DictionaryService<\n SubqlDatasource,\n EthereumBlock\n> {\n constructor(\n @Inject('ISubqueryProject') protected project: SubqueryProject,\n nodeConfig: NodeConfig,\n eventEmitter: EventEmitter2,\n ) {\n super(project.network.chainId, nodeConfig, eventEmitter);\n }\n\n async initDictionaries(): Promise<void> {\n const dictionariesV1: EthDictionaryV1[] = [];\n const dictionariesV2: EthDictionaryV2[] = [];\n\n if (!this.project) {\n throw new Error(`Project in Dictionary service not initialized `);\n }\n\n const dictionaryEndpoints = await this.getDictionaryEndpoints(\n NETWORK_FAMILY.ethereum,\n this.project.network,\n );\n\n for (const endpoint of dictionaryEndpoints) {\n try {\n const dictionaryV2 = await EthDictionaryV2.create(\n endpoint,\n this.nodeConfig,\n this.eventEmitter,\n this.project,\n this.project.network.chainId,\n );\n dictionariesV2.push(dictionaryV2);\n } catch (e) {\n const dictionaryV1 = await EthDictionaryV1.create(\n this.project,\n this.nodeConfig,\n this.eventEmitter,\n endpoint,\n );\n dictionariesV1.push(dictionaryV1);\n }\n }\n // v2 should be prioritised\n this.init([...dictionariesV2, ...dictionariesV1]);\n }\n}\n"]}
@@ -0,0 +1,3 @@
1
+ import { SubqlDatasource } from '@subql/types-ethereum';
2
+ import { EthereumProjectDsTemplate, EthereumProjectDs } from '../../configure/SubqueryProject';
3
+ export declare function ethFilterDs(dataSources: (EthereumProjectDs | EthereumProjectDsTemplate)[]): SubqlDatasource[];
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ // Copyright 2020-2024 SubQuery Pte Ltd authors & contributors
3
+ // SPDX-License-Identifier: GPL-3.0
4
+ Object.defineProperty(exports, "__esModule", { value: true });
5
+ exports.ethFilterDs = void 0;
6
+ const lodash_1 = require("lodash");
7
+ function isTemplateDs(ds) {
8
+ return !!(ds === null || ds === void 0 ? void 0 : ds.name);
9
+ }
10
+ function ethFilterDs(dataSources) {
11
+ const [normalDataSources, templateDataSources] = (0, lodash_1.partition)(dataSources, (ds) => !isTemplateDs(ds));
12
+ // Group templ
13
+ const groupedDataSources = Object.values((0, lodash_1.groupBy)(templateDataSources, (ds) => ds.name)).map((grouped) => {
14
+ if (grouped.length === 1) {
15
+ return grouped[0];
16
+ }
17
+ const options = grouped.map((ds) => ds.options);
18
+ const ref = grouped[0];
19
+ return Object.assign(Object.assign({}, ref), { groupedOptions: options });
20
+ });
21
+ return [...normalDataSources, ...groupedDataSources];
22
+ }
23
+ exports.ethFilterDs = ethFilterDs;
24
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../src/indexer/dictionary/utils.ts"],"names":[],"mappings":";AAAA,8DAA8D;AAC9D,mCAAmC;;;AAGnC,mCAA4C;AAM5C,SAAS,YAAY,CACnB,EAAiD;IAEjD,OAAO,CAAC,CAAC,CAAC,EAAgC,aAAhC,EAAE,uBAAF,EAAE,CAAgC,IAAI,CAAA,CAAC;AACnD,CAAC;AAED,SAAgB,WAAW,CACzB,WAA8D;IAE9D,MAAM,CAAC,iBAAiB,EAAE,mBAAmB,CAAC,GAAG,IAAA,kBAAS,EACxD,WAAW,EACX,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,YAAY,CAAC,EAAE,CAAC,CAC1B,CAAC;IAEF,cAAc;IACd,MAAM,kBAAkB,GAAG,MAAM,CAAC,MAAM,CACtC,IAAA,gBAAO,EACL,mBAAkD,EAClD,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,IAAI,CAChB,CACF,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE;QAChB,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE;YACxB,OAAO,OAAO,CAAC,CAAC,CAAC,CAAC;SACnB;QAED,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC;QAChD,MAAM,GAAG,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;QAEvB,uCACK,GAAG,KACN,cAAc,EAAE,OAAO,IACvB;IACJ,CAAC,CAAC,CAAC;IAEH,OAAO,CAAC,GAAG,iBAAiB,EAAE,GAAG,kBAAkB,CAAC,CAAC;AACvD,CAAC;AA7BD,kCA6BC","sourcesContent":["// Copyright 2020-2024 SubQuery Pte Ltd authors & contributors\n// SPDX-License-Identifier: GPL-3.0\n\nimport { SubqlDatasource } from '@subql/types-ethereum';\nimport { groupBy, partition } from 'lodash';\nimport {\n EthereumProjectDsTemplate,\n EthereumProjectDs,\n} from '../../configure/SubqueryProject';\n\nfunction isTemplateDs(\n ds: EthereumProjectDs | EthereumProjectDsTemplate,\n): ds is EthereumProjectDsTemplate {\n return !!(ds as EthereumProjectDsTemplate)?.name;\n}\n\nexport function ethFilterDs(\n dataSources: (EthereumProjectDs | EthereumProjectDsTemplate)[],\n): SubqlDatasource[] {\n const [normalDataSources, templateDataSources] = partition(\n dataSources,\n (ds) => !isTemplateDs(ds),\n );\n\n // Group templ\n const groupedDataSources = Object.values(\n groupBy(\n templateDataSources as EthereumProjectDsTemplate[],\n (ds) => ds.name,\n ),\n ).map((grouped) => {\n if (grouped.length === 1) {\n return grouped[0];\n }\n\n const options = grouped.map((ds) => ds.options);\n const ref = grouped[0];\n\n return {\n ...ref,\n groupedOptions: options,\n };\n });\n\n return [...normalDataSources, ...groupedDataSources];\n}\n"]}
@@ -0,0 +1,83 @@
1
+ "use strict";
2
+ // Copyright 2020-2024 SubQuery Pte Ltd authors & contributors
3
+ // SPDX-License-Identifier: GPL-3.0
4
+ Object.defineProperty(exports, "__esModule", { value: true });
5
+ const types_ethereum_1 = require("@subql/types-ethereum");
6
+ const utils_1 = require("./utils");
7
+ describe('Dictionary utils', () => {
8
+ it('can filter eth ds with multiple dynamic ds/templates', () => {
9
+ const mockTempDs = [
10
+ {
11
+ name: 'ERC721',
12
+ kind: types_ethereum_1.EthereumDatasourceKind.Runtime,
13
+ assets: new Map(),
14
+ mapping: {
15
+ file: '',
16
+ handlers: [
17
+ {
18
+ handler: 'handleERC721',
19
+ kind: types_ethereum_1.EthereumHandlerKind.Event,
20
+ filter: {
21
+ topics: ['Transfer(address, address, uint256)'],
22
+ },
23
+ },
24
+ ],
25
+ },
26
+ },
27
+ {
28
+ name: 'ERC1155',
29
+ kind: types_ethereum_1.EthereumDatasourceKind.Runtime,
30
+ assets: new Map(),
31
+ mapping: {
32
+ file: '',
33
+ handlers: [
34
+ {
35
+ handler: 'handleERC1155',
36
+ kind: types_ethereum_1.EthereumHandlerKind.Event,
37
+ filter: {
38
+ topics: [
39
+ 'TransferSingle(address, address, address, uint256, uint256)',
40
+ ],
41
+ },
42
+ },
43
+ ],
44
+ },
45
+ },
46
+ ];
47
+ const ds = {
48
+ kind: types_ethereum_1.EthereumDatasourceKind.Runtime,
49
+ assets: new Map(),
50
+ startBlock: 1,
51
+ mapping: {
52
+ file: '',
53
+ handlers: [
54
+ {
55
+ handler: 'handleDyanmicDs',
56
+ kind: types_ethereum_1.EthereumHandlerKind.Event,
57
+ filter: {
58
+ topics: [
59
+ 'TransferSingle(address, address, address, uint256, uint256)',
60
+ ],
61
+ },
62
+ },
63
+ ],
64
+ },
65
+ };
66
+ const duplicateDataSources = [
67
+ Object.assign(Object.assign({}, mockTempDs[0]), { options: { address: 'address1' } }),
68
+ Object.assign(Object.assign({}, mockTempDs[0]), { options: { address: 'address2' } }),
69
+ Object.assign(Object.assign({}, mockTempDs[1]), { options: { address: 'address3' } }),
70
+ ];
71
+ const dataSources = [ds, ...duplicateDataSources];
72
+ // Runtime + ERC721 + ERC721 + ERC1155
73
+ expect(dataSources.length).toBe(4);
74
+ const filteredDs = (0, utils_1.ethFilterDs)(dataSources);
75
+ // Runtime + ERC721 (groupedOptions) + ERC1155
76
+ expect(filteredDs.length).toBe(3);
77
+ expect(filteredDs[1].groupedOptions).toStrictEqual([
78
+ { address: 'address1' },
79
+ { address: 'address2' },
80
+ ]);
81
+ });
82
+ });
83
+ //# sourceMappingURL=utils.spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.spec.js","sourceRoot":"","sources":["../../../src/indexer/dictionary/utils.spec.ts"],"names":[],"mappings":";AAAA,8DAA8D;AAC9D,mCAAmC;;AAEnC,0DAI+B;AAE/B,mCAAsC;AAEtC,QAAQ,CAAC,kBAAkB,EAAE,GAAG,EAAE;IAChC,EAAE,CAAC,sDAAsD,EAAE,GAAG,EAAE;QAC9D,MAAM,UAAU,GAAgC;YAC9C;gBACE,IAAI,EAAE,QAAQ;gBACd,IAAI,EAAE,uCAAsB,CAAC,OAAO;gBACpC,MAAM,EAAE,IAAI,GAAG,EAAE;gBACjB,OAAO,EAAE;oBACP,IAAI,EAAE,EAAE;oBACR,QAAQ,EAAE;wBACR;4BACE,OAAO,EAAE,cAAc;4BACvB,IAAI,EAAE,oCAAmB,CAAC,KAAK;4BAC/B,MAAM,EAAE;gCACN,MAAM,EAAE,CAAC,qCAAqC,CAAC;6BAChD;yBACF;qBACF;iBACF;aACF;YACD;gBACE,IAAI,EAAE,SAAS;gBACf,IAAI,EAAE,uCAAsB,CAAC,OAAO;gBACpC,MAAM,EAAE,IAAI,GAAG,EAAE;gBACjB,OAAO,EAAE;oBACP,IAAI,EAAE,EAAE;oBACR,QAAQ,EAAE;wBACR;4BACE,OAAO,EAAE,eAAe;4BACxB,IAAI,EAAE,oCAAmB,CAAC,KAAK;4BAC/B,MAAM,EAAE;gCACN,MAAM,EAAE;oCACN,6DAA6D;iCAC9D;6BACF;yBACF;qBACF;iBACF;aACF;SACF,CAAC;QAEF,MAAM,EAAE,GAA2B;YACjC,IAAI,EAAE,uCAAsB,CAAC,OAAO;YACpC,MAAM,EAAE,IAAI,GAAG,EAAE;YACjB,UAAU,EAAE,CAAC;YACb,OAAO,EAAE;gBACP,IAAI,EAAE,EAAE;gBACR,QAAQ,EAAE;oBACR;wBACE,OAAO,EAAE,iBAAiB;wBAC1B,IAAI,EAAE,oCAAmB,CAAC,KAAK;wBAC/B,MAAM,EAAE;4BACN,MAAM,EAAE;gCACN,6DAA6D;6BAC9D;yBACF;qBACF;iBACF;aACF;SACF,CAAC;QAEF,MAAM,oBAAoB,GAAG;4CACtB,UAAU,CAAC,CAAC,CAAC,KAAE,OAAO,EAAE,EAAE,OAAO,EAAE,UAAU,EAAE;4CAC/C,UAAU,CAAC,CAAC,CAAC,KAAE,OAAO,EAAE,EAAE,OAAO,EAAE,UAAU,EAAE;4CAC/C,UAAU,CAAC,CAAC,CAAC,KAAE,OAAO,EAAE,EAAE,OAAO,EAAE,UAAU,EAAE;SACrD,CAAC;QAEF,MAAM,WAAW,GAAG,CAAC,EAAE,EAAE,GAAG,oBAAoB,CAAC,CAAC;QAClD,sCAAsC;QACtC,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAEnC,MAAM,UAAU,GAAG,IAAA,mBAAW,EAAC,WAAW,CAAC,CAAC;QAC5C,8CAA8C;QAC9C,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClC,MAAM,CAAE,UAAU,CAAC,CAAC,CAAS,CAAC,cAAc,CAAC,CAAC,aAAa,CAAC;YAC1D,EAAE,OAAO,EAAE,UAAU,EAAE;YACvB,EAAE,OAAO,EAAE,UAAU,EAAE;SACxB,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["// Copyright 2020-2024 SubQuery Pte Ltd authors & contributors\n// SPDX-License-Identifier: GPL-3.0\n\nimport {\n EthereumDatasourceKind,\n EthereumHandlerKind,\n SubqlRuntimeDatasource,\n} from '@subql/types-ethereum';\nimport { EthereumProjectDsTemplate } from '../../configure/SubqueryProject';\nimport { ethFilterDs } from './utils';\n\ndescribe('Dictionary utils', () => {\n it('can filter eth ds with multiple dynamic ds/templates', () => {\n const mockTempDs: EthereumProjectDsTemplate[] = [\n {\n name: 'ERC721',\n kind: EthereumDatasourceKind.Runtime,\n assets: new Map(),\n mapping: {\n file: '',\n handlers: [\n {\n handler: 'handleERC721',\n kind: EthereumHandlerKind.Event,\n filter: {\n topics: ['Transfer(address, address, uint256)'],\n },\n },\n ],\n },\n },\n {\n name: 'ERC1155',\n kind: EthereumDatasourceKind.Runtime,\n assets: new Map(),\n mapping: {\n file: '',\n handlers: [\n {\n handler: 'handleERC1155',\n kind: EthereumHandlerKind.Event,\n filter: {\n topics: [\n 'TransferSingle(address, address, address, uint256, uint256)',\n ],\n },\n },\n ],\n },\n },\n ];\n\n const ds: SubqlRuntimeDatasource = {\n kind: EthereumDatasourceKind.Runtime,\n assets: new Map(),\n startBlock: 1,\n mapping: {\n file: '',\n handlers: [\n {\n handler: 'handleDyanmicDs',\n kind: EthereumHandlerKind.Event,\n filter: {\n topics: [\n 'TransferSingle(address, address, address, uint256, uint256)',\n ],\n },\n },\n ],\n },\n };\n\n const duplicateDataSources = [\n { ...mockTempDs[0], options: { address: 'address1' } },\n { ...mockTempDs[0], options: { address: 'address2' } },\n { ...mockTempDs[1], options: { address: 'address3' } },\n ];\n\n const dataSources = [ds, ...duplicateDataSources];\n // Runtime + ERC721 + ERC721 + ERC1155\n expect(dataSources.length).toBe(4);\n\n const filteredDs = ethFilterDs(dataSources);\n // Runtime + ERC721 (groupedOptions) + ERC1155\n expect(filteredDs.length).toBe(3);\n expect((filteredDs[1] as any).groupedOptions).toStrictEqual([\n { address: 'address1' },\n { address: 'address2' },\n ]);\n });\n});\n"]}
@@ -0,0 +1,16 @@
1
+ import { EventEmitter2 } from '@nestjs/event-emitter';
2
+ import { NodeConfig, DictionaryV1 } from '@subql/node-core';
3
+ import { DictionaryQueryCondition, DictionaryQueryEntry as DictionaryV1QueryEntry } from '@subql/types-core';
4
+ import { SubqlDatasource, SubqlEthereumProcessorOptions } from '@subql/types-ethereum';
5
+ import { EthereumProjectDs, EthereumProjectDsTemplate, SubqueryProject } from '../../../configure/SubqueryProject';
6
+ export declare function appendDsOptions(dsOptions: SubqlEthereumProcessorOptions | SubqlEthereumProcessorOptions[], conditions: DictionaryQueryCondition[]): void;
7
+ export type GroupedEthereumProjectDs = SubqlDatasource & {
8
+ groupedOptions?: SubqlEthereumProcessorOptions[];
9
+ };
10
+ export declare function buildDictionaryV1QueryEntries(dataSources: GroupedEthereumProjectDs[]): DictionaryV1QueryEntry[];
11
+ export declare class EthDictionaryV1 extends DictionaryV1<GroupedEthereumProjectDs> {
12
+ private constructor();
13
+ static create(project: SubqueryProject, nodeConfig: NodeConfig, eventEmitter: EventEmitter2, dictionaryUrl?: string): Promise<EthDictionaryV1>;
14
+ private static getEvmChainId;
15
+ buildDictionaryQueryEntries(dataSources: (EthereumProjectDs | EthereumProjectDsTemplate)[]): DictionaryV1QueryEntry[];
16
+ }
@@ -0,0 +1,202 @@
1
+ "use strict";
2
+ // Copyright 2020-2024 SubQuery Pte Ltd authors & contributors
3
+ // SPDX-License-Identifier: GPL-3.0
4
+ var __importDefault = (this && this.__importDefault) || function (mod) {
5
+ return (mod && mod.__esModule) ? mod : { "default": mod };
6
+ };
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.EthDictionaryV1 = exports.buildDictionaryV1QueryEntries = exports.appendDsOptions = void 0;
9
+ const node_core_1 = require("@subql/node-core");
10
+ const types_ethereum_1 = require("@subql/types-ethereum");
11
+ const json5_1 = __importDefault(require("json5"));
12
+ const lodash_1 = require("lodash");
13
+ const node_fetch_1 = __importDefault(require("node-fetch"));
14
+ const string_1 = require("../../../utils/string");
15
+ const yargs_1 = require("../../../yargs");
16
+ const utils_1 = require("../utils");
17
+ const CHAIN_ALIASES_URL = 'https://raw.githubusercontent.com/subquery/templates/main/chainAliases.json5';
18
+ const logger = (0, node_core_1.getLogger)('eth-dictionary v1');
19
+ function appendDsOptions(dsOptions, conditions) {
20
+ const queryAddressLimit = yargs_1.yargsOptions.argv['query-address-limit'];
21
+ if (Array.isArray(dsOptions)) {
22
+ const addresses = dsOptions.map((option) => option.address).filter(Boolean);
23
+ if (addresses.length > queryAddressLimit) {
24
+ logger.debug(`Addresses length: ${addresses.length} is exceeding limit: ${queryAddressLimit}. Consider increasing this value with the flag --query-address-limit `);
25
+ }
26
+ if (addresses.length !== 0 && addresses.length <= queryAddressLimit) {
27
+ conditions.push({
28
+ field: 'address',
29
+ value: addresses,
30
+ matcher: 'in',
31
+ });
32
+ }
33
+ }
34
+ else {
35
+ if (dsOptions === null || dsOptions === void 0 ? void 0 : dsOptions.address) {
36
+ conditions.push({
37
+ field: 'address',
38
+ value: dsOptions.address.toLowerCase(),
39
+ matcher: 'equalTo',
40
+ });
41
+ }
42
+ }
43
+ }
44
+ exports.appendDsOptions = appendDsOptions;
45
+ function eventFilterToQueryEntry(filter, dsOptions) {
46
+ const conditions = [];
47
+ appendDsOptions(dsOptions, conditions);
48
+ if (filter.topics) {
49
+ for (let i = 0; i < Math.min(filter.topics.length, 4); i++) {
50
+ const topic = filter.topics[i];
51
+ if (!topic) {
52
+ continue;
53
+ }
54
+ const field = `topics${i}`;
55
+ if (topic === '!null') {
56
+ conditions.push({
57
+ field,
58
+ value: false,
59
+ matcher: 'isNull',
60
+ });
61
+ }
62
+ else {
63
+ conditions.push({
64
+ field,
65
+ value: (0, string_1.eventToTopic)(topic),
66
+ matcher: 'equalTo',
67
+ });
68
+ }
69
+ }
70
+ }
71
+ return {
72
+ entity: 'evmLogs',
73
+ conditions,
74
+ };
75
+ }
76
+ function callFilterToQueryEntry(filter, dsOptions) {
77
+ const conditions = [];
78
+ appendDsOptions(dsOptions, conditions);
79
+ for (const condition of conditions) {
80
+ if (condition.field === 'address') {
81
+ condition.field = 'to';
82
+ }
83
+ }
84
+ if (filter.from) {
85
+ conditions.push({
86
+ field: 'from',
87
+ value: filter.from.toLowerCase(),
88
+ matcher: 'equalTo',
89
+ });
90
+ }
91
+ const optionsAddresses = conditions.find((c) => c.field === 'to');
92
+ if (!optionsAddresses) {
93
+ if (filter.to) {
94
+ conditions.push({
95
+ field: 'to',
96
+ value: filter.to.toLowerCase(),
97
+ matcher: 'equalTo',
98
+ });
99
+ }
100
+ else if (filter.to === null) {
101
+ conditions.push({
102
+ field: 'to',
103
+ value: true,
104
+ matcher: 'isNull',
105
+ });
106
+ }
107
+ }
108
+ else if (optionsAddresses && (filter.to || filter.to === null)) {
109
+ logger.warn(`TransactionFilter 'to' conflict with 'address' in data source options`);
110
+ }
111
+ if (filter.function === null || filter.function === '0x') {
112
+ conditions.push({
113
+ field: 'func',
114
+ value: true,
115
+ matcher: 'isNull',
116
+ });
117
+ }
118
+ else if (filter.function) {
119
+ conditions.push({
120
+ field: 'func',
121
+ value: (0, string_1.functionToSighash)(filter.function),
122
+ matcher: 'equalTo',
123
+ });
124
+ }
125
+ return {
126
+ entity: 'evmTransactions',
127
+ conditions,
128
+ };
129
+ }
130
+ function buildDictionaryV1QueryEntries(dataSources) {
131
+ var _a;
132
+ const queryEntries = [];
133
+ for (const ds of dataSources) {
134
+ for (const handler of ds.mapping.handlers) {
135
+ // No filters, cant use dictionary
136
+ if (!handler.filter)
137
+ return [];
138
+ switch (handler.kind) {
139
+ case types_ethereum_1.EthereumHandlerKind.Block:
140
+ return [];
141
+ case types_ethereum_1.EthereumHandlerKind.Call: {
142
+ const filter = handler.filter;
143
+ if (filter.from !== undefined ||
144
+ filter.to !== undefined ||
145
+ filter.function !== undefined) {
146
+ queryEntries.push(callFilterToQueryEntry(filter, ds.options));
147
+ }
148
+ else {
149
+ return [];
150
+ }
151
+ break;
152
+ }
153
+ case types_ethereum_1.EthereumHandlerKind.Event: {
154
+ const filter = handler.filter;
155
+ if (ds.groupedOptions) {
156
+ queryEntries.push(eventFilterToQueryEntry(filter, ds.groupedOptions));
157
+ }
158
+ else if (((_a = ds.options) === null || _a === void 0 ? void 0 : _a.address) || filter.topics) {
159
+ queryEntries.push(eventFilterToQueryEntry(filter, ds.options));
160
+ }
161
+ else {
162
+ return [];
163
+ }
164
+ break;
165
+ }
166
+ default:
167
+ }
168
+ }
169
+ }
170
+ return (0, lodash_1.uniqBy)(queryEntries, (item) => `${item.entity}|${JSON.stringify((0, lodash_1.sortBy)(item.conditions, (c) => c.field))}`);
171
+ }
172
+ exports.buildDictionaryV1QueryEntries = buildDictionaryV1QueryEntries;
173
+ class EthDictionaryV1 extends node_core_1.DictionaryV1 {
174
+ constructor(project, nodeConfig, eventEmitter, dictionaryUrl, chainId) {
175
+ super(dictionaryUrl, chainId !== null && chainId !== void 0 ? chainId : project.network.chainId, nodeConfig, eventEmitter);
176
+ }
177
+ static async create(project, nodeConfig, eventEmitter, dictionaryUrl) {
178
+ /*Some dictionarys for EVM are built with other SDKs as they are chains with an EVM runtime
179
+ * we maintain a list of aliases so we can map the evmChainId to the genesis hash of the other SDKs
180
+ * e.g moonbeam is built with Substrate SDK but can be used as an EVM dictionary
181
+ */
182
+ const chainAliases = await this.getEvmChainId();
183
+ const chainAlias = chainAliases[project.network.chainId];
184
+ const dictionary = new EthDictionaryV1(project, nodeConfig, eventEmitter, dictionaryUrl, chainAlias);
185
+ await dictionary.init();
186
+ return dictionary;
187
+ }
188
+ static async getEvmChainId() {
189
+ const response = await (0, node_fetch_1.default)(CHAIN_ALIASES_URL);
190
+ const raw = await response.text();
191
+ // We use JSON5 here because the file has comments in it
192
+ return json5_1.default.parse(raw);
193
+ }
194
+ buildDictionaryQueryEntries(
195
+ // Add name to datasource as templates have this set
196
+ dataSources) {
197
+ const filteredDs = (0, utils_1.ethFilterDs)(dataSources);
198
+ return buildDictionaryV1QueryEntries(filteredDs);
199
+ }
200
+ }
201
+ exports.EthDictionaryV1 = EthDictionaryV1;
202
+ //# sourceMappingURL=ethDictionaryV1.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ethDictionaryV1.js","sourceRoot":"","sources":["../../../../src/indexer/dictionary/v1/ethDictionaryV1.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2020-2024 SubQuery Pte Ltd authors & contributors\n// SPDX-License-Identifier: GPL-3.0\n\nimport { EventEmitter2 } from '@nestjs/event-emitter';\nimport { NodeConfig, DictionaryV1, getLogger } from '@subql/node-core';\nimport {\n DictionaryQueryCondition,\n DictionaryQueryEntry as DictionaryV1QueryEntry,\n} from '@subql/types-core';\nimport {\n EthereumHandlerKind,\n EthereumLogFilter,\n EthereumTransactionFilter,\n SubqlDatasource,\n SubqlEthereumProcessorOptions,\n} from '@subql/types-ethereum';\nimport JSON5 from 'json5';\nimport { sortBy, uniqBy } from 'lodash';\nimport fetch from 'node-fetch';\nimport {\n EthereumProjectDs,\n EthereumProjectDsTemplate,\n SubqueryProject,\n} from '../../../configure/SubqueryProject';\nimport { eventToTopic, functionToSighash } from '../../../utils/string';\nimport { yargsOptions } from '../../../yargs';\nimport { ethFilterDs } from '../utils';\n\nconst CHAIN_ALIASES_URL =\n 'https://raw.githubusercontent.com/subquery/templates/main/chainAliases.json5';\n\nconst logger = getLogger('eth-dictionary v1');\n\nexport function appendDsOptions(\n dsOptions: SubqlEthereumProcessorOptions | SubqlEthereumProcessorOptions[],\n conditions: DictionaryQueryCondition[],\n): void {\n const queryAddressLimit = yargsOptions.argv['query-address-limit'];\n if (Array.isArray(dsOptions)) {\n const addresses = dsOptions.map((option) => option.address).filter(Boolean);\n\n if (addresses.length > queryAddressLimit) {\n logger.debug(\n `Addresses length: ${addresses.length} is exceeding limit: ${queryAddressLimit}. Consider increasing this value with the flag --query-address-limit `,\n );\n }\n\n if (addresses.length !== 0 && addresses.length <= queryAddressLimit) {\n conditions.push({\n field: 'address',\n value: addresses,\n matcher: 'in',\n });\n }\n } else {\n if (dsOptions?.address) {\n conditions.push({\n field: 'address',\n value: dsOptions.address.toLowerCase(),\n matcher: 'equalTo',\n });\n }\n }\n}\n\nfunction eventFilterToQueryEntry(\n filter: EthereumLogFilter,\n dsOptions: SubqlEthereumProcessorOptions | SubqlEthereumProcessorOptions[],\n): DictionaryV1QueryEntry {\n const conditions: DictionaryQueryCondition[] = [];\n appendDsOptions(dsOptions, conditions);\n if (filter.topics) {\n for (let i = 0; i < Math.min(filter.topics.length, 4); i++) {\n const topic = filter.topics[i];\n if (!topic) {\n continue;\n }\n const field = `topics${i}`;\n\n if (topic === '!null') {\n conditions.push({\n field,\n value: false as any, // TODO update types to allow boolean\n matcher: 'isNull',\n });\n } else {\n conditions.push({\n field,\n value: eventToTopic(topic),\n matcher: 'equalTo',\n });\n }\n }\n }\n return {\n entity: 'evmLogs',\n conditions,\n };\n}\n\nfunction callFilterToQueryEntry(\n filter: EthereumTransactionFilter,\n dsOptions: SubqlEthereumProcessorOptions | SubqlEthereumProcessorOptions[],\n): DictionaryV1QueryEntry {\n const conditions: DictionaryQueryCondition[] = [];\n appendDsOptions(dsOptions, conditions);\n\n for (const condition of conditions) {\n if (condition.field === 'address') {\n condition.field = 'to';\n }\n }\n if (filter.from) {\n conditions.push({\n field: 'from',\n value: filter.from.toLowerCase(),\n matcher: 'equalTo',\n });\n }\n const optionsAddresses = conditions.find((c) => c.field === 'to');\n if (!optionsAddresses) {\n if (filter.to) {\n conditions.push({\n field: 'to',\n value: filter.to.toLowerCase(),\n matcher: 'equalTo',\n });\n } else if (filter.to === null) {\n conditions.push({\n field: 'to',\n value: true as any, // TODO update types to allow boolean\n matcher: 'isNull',\n });\n }\n } else if (optionsAddresses && (filter.to || filter.to === null)) {\n logger.warn(\n `TransactionFilter 'to' conflict with 'address' in data source options`,\n );\n }\n\n if (filter.function === null || filter.function === '0x') {\n conditions.push({\n field: 'func',\n value: true,\n matcher: 'isNull',\n });\n } else if (filter.function) {\n conditions.push({\n field: 'func',\n value: functionToSighash(filter.function),\n matcher: 'equalTo',\n });\n }\n return {\n entity: 'evmTransactions',\n conditions,\n };\n}\n\nexport type GroupedEthereumProjectDs = SubqlDatasource & {\n groupedOptions?: SubqlEthereumProcessorOptions[];\n};\n\nexport function buildDictionaryV1QueryEntries(\n dataSources: GroupedEthereumProjectDs[],\n): DictionaryV1QueryEntry[] {\n const queryEntries: DictionaryV1QueryEntry[] = [];\n\n for (const ds of dataSources) {\n for (const handler of ds.mapping.handlers) {\n // No filters, cant use dictionary\n if (!handler.filter) return [];\n\n switch (handler.kind) {\n case EthereumHandlerKind.Block:\n return [];\n case EthereumHandlerKind.Call: {\n const filter = handler.filter as EthereumTransactionFilter;\n if (\n filter.from !== undefined ||\n filter.to !== undefined ||\n filter.function !== undefined\n ) {\n queryEntries.push(callFilterToQueryEntry(filter, ds.options));\n } else {\n return [];\n }\n break;\n }\n case EthereumHandlerKind.Event: {\n const filter = handler.filter as EthereumLogFilter;\n if (ds.groupedOptions) {\n queryEntries.push(\n eventFilterToQueryEntry(filter, ds.groupedOptions),\n );\n } else if (ds.options?.address || filter.topics) {\n queryEntries.push(eventFilterToQueryEntry(filter, ds.options));\n } else {\n return [];\n }\n break;\n }\n default:\n }\n }\n }\n\n return uniqBy(\n queryEntries,\n (item) =>\n `${item.entity}|${JSON.stringify(\n sortBy(item.conditions, (c) => c.field),\n )}`,\n );\n}\n\nexport class EthDictionaryV1 extends DictionaryV1<GroupedEthereumProjectDs> {\n private constructor(\n project: SubqueryProject,\n nodeConfig: NodeConfig,\n eventEmitter: EventEmitter2,\n dictionaryUrl: string,\n chainId?: string,\n ) {\n super(\n dictionaryUrl,\n chainId ?? project.network.chainId,\n nodeConfig,\n eventEmitter,\n );\n }\n\n static async create(\n project: SubqueryProject,\n nodeConfig: NodeConfig,\n eventEmitter: EventEmitter2,\n dictionaryUrl?: string,\n ): Promise<EthDictionaryV1> {\n /*Some dictionarys for EVM are built with other SDKs as they are chains with an EVM runtime\n * we maintain a list of aliases so we can map the evmChainId to the genesis hash of the other SDKs\n * e.g moonbeam is built with Substrate SDK but can be used as an EVM dictionary\n */\n const chainAliases = await this.getEvmChainId();\n const chainAlias = chainAliases[project.network.chainId];\n\n const dictionary = new EthDictionaryV1(\n project,\n nodeConfig,\n eventEmitter,\n dictionaryUrl,\n chainAlias,\n );\n await dictionary.init();\n return dictionary;\n }\n\n private static async getEvmChainId(): Promise<Record<string, string>> {\n const response = await fetch(CHAIN_ALIASES_URL);\n\n const raw = await response.text();\n // We use JSON5 here because the file has comments in it\n return JSON5.parse(raw);\n }\n\n buildDictionaryQueryEntries(\n // Add name to datasource as templates have this set\n dataSources: (EthereumProjectDs | EthereumProjectDsTemplate)[],\n ): DictionaryV1QueryEntry[] {\n const filteredDs = ethFilterDs(dataSources);\n return buildDictionaryV1QueryEntries(filteredDs);\n }\n}\n"]}