@subql/node-solana 6.0.6 → 6.0.8-0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -7,16 +7,21 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
7
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
8
  return c > 3 && r && Object.defineProperty(target, key, r), r;
9
9
  };
10
+ var __importDefault = (this && this.__importDefault) || function (mod) {
11
+ return (mod && mod.__esModule) ? mod : { "default": mod };
12
+ };
10
13
  Object.defineProperty(exports, "__esModule", { value: true });
11
14
  exports.AppModule = void 0;
15
+ const node_path_1 = __importDefault(require("node:path"));
12
16
  const common_1 = require("@nestjs/common");
13
17
  const event_emitter_1 = require("@nestjs/event-emitter");
14
18
  const schedule_1 = require("@nestjs/schedule");
15
19
  const node_core_1 = require("@subql/node-core");
16
20
  const configure_module_1 = require("./configure/configure.module");
17
21
  const fetch_module_1 = require("./indexer/fetch.module");
22
+ const kitPath = require.resolve('@solana/kit');
18
23
  // eslint-disable-next-line @typescript-eslint/no-var-requires
19
- const { version: ethersSdkVersion } = require('ethers/package.json');
24
+ const { version: solanaSdkVersion } = require(node_path_1.default.resolve(kitPath, '../../package.json'));
20
25
  // eslint-disable-next-line @typescript-eslint/no-var-requires
21
26
  const { version: packageVersion } = require('../package.json');
22
27
  let AppModule = class AppModule {
@@ -33,7 +38,7 @@ exports.AppModule = AppModule = __decorate([
33
38
  fetch_module_1.FetchModule,
34
39
  node_core_1.MetaModule.forRoot({
35
40
  version: packageVersion,
36
- sdkVersion: { name: 'ethers.js', version: ethersSdkVersion },
41
+ sdkVersion: { name: '@solana/kit', version: solanaSdkVersion },
37
42
  }),
38
43
  ],
39
44
  controllers: [],
@@ -1 +1 @@
1
- {"version":3,"file":"app.module.js","sourceRoot":"","sources":["../src/app.module.ts"],"names":[],"mappings":";AAAA,8DAA8D;AAC9D,mCAAmC;;;;;;;;;AAEnC,2CAAwC;AACxC,yDAA2D;AAC3D,+CAAkD;AAClD,gDAAoE;AACpE,mEAA+D;AAC/D,yDAAqD;AAErD,8DAA8D;AAC9D,MAAM,EAAE,OAAO,EAAE,gBAAgB,EAAE,GAAG,OAAO,CAAC,qBAAqB,CAAC,CAAC;AACrE,8DAA8D;AAC9D,MAAM,EAAE,OAAO,EAAE,cAAc,EAAE,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC;AAiBxD,IAAM,SAAS,GAAf,MAAM,SAAS;CAAG,CAAA;AAAZ,8BAAS;oBAAT,SAAS;IAfrB,IAAA,eAAM,EAAC;QACN,OAAO,EAAE;YACP,oBAAQ,CAAC,OAAO,EAAE;YAClB,kCAAkB,CAAC,OAAO,EAAE;YAC5B,kCAAe,CAAC,QAAQ,EAAE;YAC1B,yBAAc,CAAC,OAAO,EAAE;YACxB,sBAAU;YACV,0BAAW;YACX,sBAAU,CAAC,OAAO,CAAC;gBACjB,OAAO,EAAE,cAAc;gBACvB,UAAU,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,gBAAgB,EAAE;aAC7D,CAAC;SACH;QACD,WAAW,EAAE,EAAE;KAChB,CAAC;GACW,SAAS,CAAG","sourcesContent":["// Copyright 2020-2025 SubQuery Pte Ltd authors & contributors\n// SPDX-License-Identifier: GPL-3.0\n\nimport { Module } from '@nestjs/common';\nimport { EventEmitterModule } from '@nestjs/event-emitter';\nimport { ScheduleModule } from '@nestjs/schedule';\nimport { DbModule, CoreModule, MetaModule } from '@subql/node-core';\nimport { ConfigureModule } from './configure/configure.module';\nimport { FetchModule } from './indexer/fetch.module';\n\n// eslint-disable-next-line @typescript-eslint/no-var-requires\nconst { version: ethersSdkVersion } = require('ethers/package.json');\n// eslint-disable-next-line @typescript-eslint/no-var-requires\nconst { version: packageVersion } = require('../package.json');\n\n@Module({\n imports: [\n DbModule.forRoot(),\n EventEmitterModule.forRoot(),\n ConfigureModule.register(),\n ScheduleModule.forRoot(),\n CoreModule,\n FetchModule,\n MetaModule.forRoot({\n version: packageVersion,\n sdkVersion: { name: 'ethers.js', version: ethersSdkVersion },\n }),\n ],\n controllers: [],\n})\nexport class AppModule {}\n"]}
1
+ {"version":3,"file":"app.module.js","sourceRoot":"","sources":["../src/app.module.ts"],"names":[],"mappings":";AAAA,8DAA8D;AAC9D,mCAAmC;;;;;;;;;;;;AAEnC,0DAA6B;AAC7B,2CAAwC;AACxC,yDAA2D;AAC3D,+CAAkD;AAClD,gDAAoE;AACpE,mEAA+D;AAC/D,yDAAqD;AAErD,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC;AAC/C,8DAA8D;AAC9D,MAAM,EAAE,OAAO,EAAE,gBAAgB,EAAE,GAAG,OAAO,CAAC,mBAAI,CAAC,OAAO,CACxD,OAAO,EACP,oBAAoB,CACrB,CAAC,CAAC;AACH,8DAA8D;AAC9D,MAAM,EAAE,OAAO,EAAE,cAAc,EAAE,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC;AAiBxD,IAAM,SAAS,GAAf,MAAM,SAAS;CAAG,CAAA;AAAZ,8BAAS;oBAAT,SAAS;IAfrB,IAAA,eAAM,EAAC;QACN,OAAO,EAAE;YACP,oBAAQ,CAAC,OAAO,EAAE;YAClB,kCAAkB,CAAC,OAAO,EAAE;YAC5B,kCAAe,CAAC,QAAQ,EAAE;YAC1B,yBAAc,CAAC,OAAO,EAAE;YACxB,sBAAU;YACV,0BAAW;YACX,sBAAU,CAAC,OAAO,CAAC;gBACjB,OAAO,EAAE,cAAc;gBACvB,UAAU,EAAE,EAAE,IAAI,EAAE,aAAa,EAAE,OAAO,EAAE,gBAAgB,EAAE;aAC/D,CAAC;SACH;QACD,WAAW,EAAE,EAAE;KAChB,CAAC;GACW,SAAS,CAAG","sourcesContent":["// Copyright 2020-2025 SubQuery Pte Ltd authors & contributors\n// SPDX-License-Identifier: GPL-3.0\n\nimport path from 'node:path';\nimport { Module } from '@nestjs/common';\nimport { EventEmitterModule } from '@nestjs/event-emitter';\nimport { ScheduleModule } from '@nestjs/schedule';\nimport { DbModule, CoreModule, MetaModule } from '@subql/node-core';\nimport { ConfigureModule } from './configure/configure.module';\nimport { FetchModule } from './indexer/fetch.module';\n\nconst kitPath = require.resolve('@solana/kit');\n// eslint-disable-next-line @typescript-eslint/no-var-requires\nconst { version: solanaSdkVersion } = require(path.resolve(\n kitPath,\n '../../package.json',\n));\n// eslint-disable-next-line @typescript-eslint/no-var-requires\nconst { version: packageVersion } = require('../package.json');\n\n@Module({\n imports: [\n DbModule.forRoot(),\n EventEmitterModule.forRoot(),\n ConfigureModule.register(),\n ScheduleModule.forRoot(),\n CoreModule,\n FetchModule,\n MetaModule.forRoot({\n version: packageVersion,\n sdkVersion: { name: '@solana/kit', version: solanaSdkVersion },\n }),\n ],\n controllers: [],\n})\nexport class AppModule {}\n"]}
@@ -57,6 +57,12 @@ function sanitiseDictionaryConditions(dictionaryConditions) {
57
57
  else {
58
58
  dictionaryConditions.logs = (0, lodash_1.uniqBy)(dictionaryConditions.logs, (log) => JSON.stringify(log));
59
59
  }
60
+ if (!dictionaryConditions.instructions?.length) {
61
+ delete dictionaryConditions.instructions;
62
+ }
63
+ else {
64
+ dictionaryConditions.instructions = (0, lodash_1.uniqBy)(dictionaryConditions.instructions, (inst) => JSON.stringify(inst));
65
+ }
60
66
  if (!dictionaryConditions.transactions?.length) {
61
67
  delete dictionaryConditions.transactions;
62
68
  }
@@ -1 +1 @@
1
- {"version":3,"file":"solanaDictionaryV2.js","sourceRoot":"","sources":["../../../../src/indexer/dictionary/v2/solanaDictionaryV2.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 {\n getDefaultResponseTransformerForSolanaRpc,\n innerInstructionsConfigs,\n KEYPATH_WILDCARD,\n messageConfig,\n} from '@solana/rpc-transformers';\nimport {\n NodeConfig,\n DictionaryV2,\n RawDictionaryResponseData,\n DictionaryResponse,\n getLogger,\n IBlock,\n} from '@subql/node-core';\nimport {\n SolanaBlock,\n SolanaHandlerKind,\n SolanaInstructionFilter,\n SolanaLogFilter,\n SolanaTransactionFilter,\n SubqlDatasource,\n} from '@subql/types-solana';\nimport { uniqBy } from 'lodash';\nimport {\n SolanaProjectDs,\n SolanaProjectDsTemplate,\n SubqueryProject,\n} from '../../../configure/SubqueryProject';\nimport { SolanaApi, SolanaDecoder } from '../../../solana';\nimport { formatBlockUtil, transformBlock } from '../../../solana/block.solana';\nimport {\n SolanaDictionaryV2QueryEntry,\n SolanaDictionaryTxConditions,\n SolanaDictionaryLogConditions,\n SolanaDictionaryInstructionConditions,\n RawSolanaBlock,\n} from './types';\n\nconst MIN_FETCH_LIMIT = 200;\n\nconst logger = getLogger('dictionary-v2');\n\nfunction txFilterToDictionaryCondition(\n filter?: SolanaTransactionFilter,\n): SolanaDictionaryTxConditions {\n const txConditions: SolanaDictionaryTxConditions = {};\n\n if (filter?.signerAccountKey) {\n txConditions.signerAccountKeys = [filter.signerAccountKey];\n }\n\n return txConditions;\n}\n\nfunction instructionFilterToDictionaryCondition(\n decoder: SolanaDecoder,\n filter?: SolanaInstructionFilter,\n): SolanaDictionaryInstructionConditions {\n const instConditions: SolanaDictionaryInstructionConditions = {};\n\n if (filter?.accounts) {\n instConditions.accounts = filter.accounts;\n }\n\n if (filter?.programId) {\n instConditions.programIds = [filter.programId];\n }\n\n if (filter?.discriminator) {\n if (!filter.programId) {\n throw new Error(\n 'programId is required to be set when a discriminator is provided',\n );\n }\n const disc = decoder.parseDiscriminator(\n filter.discriminator,\n filter.programId,\n );\n instConditions.discriminators = [`0x${disc.toString('hex')}`];\n }\n\n /*\n undefined -> failed + successful\n true -> successful\n false -> failed\n */\n if (!filter?.includeFailed) {\n instConditions.isCommitted = true;\n }\n\n return instConditions;\n}\n\nfunction logFilterToDictionaryCondition(\n filter?: SolanaLogFilter,\n): SolanaDictionaryLogConditions {\n const logConditions: SolanaDictionaryLogConditions = {};\n\n if (filter?.programId) {\n logConditions.programIds = [filter.programId];\n }\n\n return logConditions;\n}\n\nfunction sanitiseDictionaryConditions(\n dictionaryConditions: SolanaDictionaryV2QueryEntry,\n): SolanaDictionaryV2QueryEntry {\n if (!dictionaryConditions.logs?.length) {\n delete dictionaryConditions.logs;\n } else {\n dictionaryConditions.logs = uniqBy(dictionaryConditions.logs, (log) =>\n JSON.stringify(log),\n );\n }\n\n if (!dictionaryConditions.transactions?.length) {\n delete dictionaryConditions.transactions;\n } else {\n dictionaryConditions.transactions = uniqBy(\n dictionaryConditions.transactions,\n (tx) => JSON.stringify(tx),\n );\n }\n\n return dictionaryConditions;\n}\n\nexport function buildDictionaryV2QueryEntry(\n decoder: SolanaDecoder,\n dataSources: SolanaProjectDs[],\n): SolanaDictionaryV2QueryEntry {\n const dictionaryConditions: SolanaDictionaryV2QueryEntry = {\n logs: [],\n transactions: [],\n };\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 SolanaHandlerKind.Block:\n if (handler.filter?.modulo === undefined) {\n return {};\n }\n break;\n case SolanaHandlerKind.Transaction: {\n if (\n handler.filter &&\n Object.values(handler.filter).filter((v) => v !== undefined).length\n ) {\n dictionaryConditions.transactions ??= [];\n dictionaryConditions.transactions.push(\n txFilterToDictionaryCondition(handler.filter),\n );\n }\n break;\n }\n case SolanaHandlerKind.Instruction: {\n if (\n handler.filter &&\n Object.values(handler.filter).filter((v) => v !== undefined).length\n ) {\n dictionaryConditions.instructions ??= [];\n dictionaryConditions.instructions.push(\n instructionFilterToDictionaryCondition(decoder, handler.filter),\n );\n }\n break;\n }\n case SolanaHandlerKind.Log: {\n if (\n handler.filter &&\n Object.values(handler.filter).filter((v) => v !== undefined).length\n ) {\n dictionaryConditions.logs ??= [];\n dictionaryConditions.logs.push(\n logFilterToDictionaryCondition(handler.filter),\n );\n }\n\n break;\n }\n default:\n }\n }\n }\n\n return sanitiseDictionaryConditions(dictionaryConditions);\n}\n\nfunction parseBlock(\n block: RawSolanaBlock,\n decoder: SolanaDecoder,\n): SolanaBlock {\n const methodName = 'parseBlock';\n\n // This is based on https://github.com/anza-xyz/kit/blob/main/packages/rpc-api/src/index.ts#L257\n const transformer = getDefaultResponseTransformerForSolanaRpc({\n allowedNumericKeyPaths: {\n [methodName]: [\n [\n 'transactions',\n KEYPATH_WILDCARD,\n 'meta',\n 'preTokenBalances',\n KEYPATH_WILDCARD,\n 'accountIndex',\n ],\n [\n 'transactions',\n KEYPATH_WILDCARD,\n 'meta',\n 'preTokenBalances',\n KEYPATH_WILDCARD,\n 'uiTokenAmount',\n 'decimals',\n ],\n [\n 'transactions',\n KEYPATH_WILDCARD,\n 'meta',\n 'postTokenBalances',\n KEYPATH_WILDCARD,\n 'accountIndex',\n ],\n [\n 'transactions',\n KEYPATH_WILDCARD,\n 'meta',\n 'postTokenBalances',\n KEYPATH_WILDCARD,\n 'uiTokenAmount',\n 'decimals',\n ],\n [\n 'transactions',\n KEYPATH_WILDCARD,\n 'meta',\n 'rewards',\n KEYPATH_WILDCARD,\n 'commission',\n ],\n ...innerInstructionsConfigs.map((c) => [\n 'transactions',\n KEYPATH_WILDCARD,\n 'meta',\n 'innerInstructions',\n KEYPATH_WILDCARD,\n ...c,\n ]),\n ...messageConfig.map(\n (c) =>\n [\n 'transactions',\n KEYPATH_WILDCARD,\n 'transaction',\n 'message',\n ...c,\n ] as const,\n ),\n ['rewards', KEYPATH_WILDCARD, 'commission'],\n ],\n },\n });\n\n const rpcBlock = transformer(\n { result: block },\n { methodName, params: undefined },\n );\n\n const res = transformBlock(rpcBlock as any, decoder);\n\n return res;\n}\n\nexport class SolanaDictionaryV2 extends DictionaryV2<\n SolanaBlock,\n SubqlDatasource,\n SolanaDictionaryV2QueryEntry\n> {\n // #skipTransactions: boolean;\n\n constructor(\n endpoint: string,\n nodeConfig: NodeConfig,\n project: SubqueryProject,\n private api: SolanaApi,\n ) {\n super(endpoint, project.network.chainId, nodeConfig);\n // this.#skipTransactions = !!new SolanaNodeConfig(nodeConfig)\n // .skipTransactions;\n }\n\n static async create(\n endpoint: string,\n nodeConfig: NodeConfig,\n project: SubqueryProject,\n api: SolanaApi,\n ): Promise<SolanaDictionaryV2> {\n const dictionary = new SolanaDictionaryV2(\n endpoint,\n nodeConfig,\n project,\n api,\n );\n await dictionary.init();\n return dictionary;\n }\n\n buildDictionaryQueryEntries(\n dataSources: (SolanaProjectDs | SolanaProjectDsTemplate)[],\n ): SolanaDictionaryV2QueryEntry {\n return buildDictionaryV2QueryEntry(this.api.decoder, dataSources);\n }\n\n // eslint-disable-next-line @typescript-eslint/require-await\n async getData(\n startBlock: number,\n endBlock: number,\n limit: number = MIN_FETCH_LIMIT,\n ): Promise<DictionaryResponse<IBlock<SolanaBlock> | number> | undefined> {\n return super.getData(startBlock, endBlock, limit, {\n blockHeader: true,\n logs: { transaction: true /*!this.#skipTransactions*/ },\n instructions: { transaction: true },\n transactions: { log: true, instructions: true },\n });\n }\n\n convertResponseBlocks<RFB = RawSolanaBlock>(\n data: RawDictionaryResponseData<RFB>,\n ): DictionaryResponse<IBlock<SolanaBlock>> | undefined {\n try {\n const blocks: IBlock<SolanaBlock>[] = (\n (data.blocks as unknown[]) || []\n ).map((b) => formatBlockUtil(parseBlock(b, this.api.decoder)));\n\n if (!blocks.length) {\n return {\n batchBlocks: [],\n lastBufferedHeight: undefined, // This will get set to the request end block in the base class.\n } as any;\n }\n return {\n batchBlocks: blocks,\n lastBufferedHeight: Number(\n blocks[blocks.length - 1].getHeader().blockHeight,\n ),\n };\n } catch (e: any) {\n logger.error(e, `Failed to handle block response`);\n throw e;\n }\n }\n}\n"]}
1
+ {"version":3,"file":"solanaDictionaryV2.js","sourceRoot":"","sources":["../../../../src/indexer/dictionary/v2/solanaDictionaryV2.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 {\n getDefaultResponseTransformerForSolanaRpc,\n innerInstructionsConfigs,\n KEYPATH_WILDCARD,\n messageConfig,\n} from '@solana/rpc-transformers';\nimport {\n NodeConfig,\n DictionaryV2,\n RawDictionaryResponseData,\n DictionaryResponse,\n getLogger,\n IBlock,\n} from '@subql/node-core';\nimport {\n SolanaBlock,\n SolanaHandlerKind,\n SolanaInstructionFilter,\n SolanaLogFilter,\n SolanaTransactionFilter,\n SubqlDatasource,\n} from '@subql/types-solana';\nimport { uniqBy } from 'lodash';\nimport {\n SolanaProjectDs,\n SolanaProjectDsTemplate,\n SubqueryProject,\n} from '../../../configure/SubqueryProject';\nimport { SolanaApi, SolanaDecoder } from '../../../solana';\nimport { formatBlockUtil, transformBlock } from '../../../solana/block.solana';\nimport {\n SolanaDictionaryV2QueryEntry,\n SolanaDictionaryTxConditions,\n SolanaDictionaryLogConditions,\n SolanaDictionaryInstructionConditions,\n RawSolanaBlock,\n} from './types';\n\nconst MIN_FETCH_LIMIT = 200;\n\nconst logger = getLogger('dictionary-v2');\n\nfunction txFilterToDictionaryCondition(\n filter?: SolanaTransactionFilter,\n): SolanaDictionaryTxConditions {\n const txConditions: SolanaDictionaryTxConditions = {};\n\n if (filter?.signerAccountKey) {\n txConditions.signerAccountKeys = [filter.signerAccountKey];\n }\n\n return txConditions;\n}\n\nfunction instructionFilterToDictionaryCondition(\n decoder: SolanaDecoder,\n filter?: SolanaInstructionFilter,\n): SolanaDictionaryInstructionConditions {\n const instConditions: SolanaDictionaryInstructionConditions = {};\n\n if (filter?.accounts) {\n instConditions.accounts = filter.accounts;\n }\n\n if (filter?.programId) {\n instConditions.programIds = [filter.programId];\n }\n\n if (filter?.discriminator) {\n if (!filter.programId) {\n throw new Error(\n 'programId is required to be set when a discriminator is provided',\n );\n }\n const disc = decoder.parseDiscriminator(\n filter.discriminator,\n filter.programId,\n );\n instConditions.discriminators = [`0x${disc.toString('hex')}`];\n }\n\n /*\n undefined -> failed + successful\n true -> successful\n false -> failed\n */\n if (!filter?.includeFailed) {\n instConditions.isCommitted = true;\n }\n\n return instConditions;\n}\n\nfunction logFilterToDictionaryCondition(\n filter?: SolanaLogFilter,\n): SolanaDictionaryLogConditions {\n const logConditions: SolanaDictionaryLogConditions = {};\n\n if (filter?.programId) {\n logConditions.programIds = [filter.programId];\n }\n\n return logConditions;\n}\n\nfunction sanitiseDictionaryConditions(\n dictionaryConditions: SolanaDictionaryV2QueryEntry,\n): SolanaDictionaryV2QueryEntry {\n if (!dictionaryConditions.logs?.length) {\n delete dictionaryConditions.logs;\n } else {\n dictionaryConditions.logs = uniqBy(dictionaryConditions.logs, (log) =>\n JSON.stringify(log),\n );\n }\n\n if (!dictionaryConditions.instructions?.length) {\n delete dictionaryConditions.instructions;\n } else {\n dictionaryConditions.instructions = uniqBy(\n dictionaryConditions.instructions,\n (inst) => JSON.stringify(inst),\n );\n }\n\n if (!dictionaryConditions.transactions?.length) {\n delete dictionaryConditions.transactions;\n } else {\n dictionaryConditions.transactions = uniqBy(\n dictionaryConditions.transactions,\n (tx) => JSON.stringify(tx),\n );\n }\n\n return dictionaryConditions;\n}\n\nexport function buildDictionaryV2QueryEntry(\n decoder: SolanaDecoder,\n dataSources: SolanaProjectDs[],\n): SolanaDictionaryV2QueryEntry {\n const dictionaryConditions: SolanaDictionaryV2QueryEntry = {\n logs: [],\n transactions: [],\n };\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 SolanaHandlerKind.Block:\n if (handler.filter?.modulo === undefined) {\n return {};\n }\n break;\n case SolanaHandlerKind.Transaction: {\n if (\n handler.filter &&\n Object.values(handler.filter).filter((v) => v !== undefined).length\n ) {\n dictionaryConditions.transactions ??= [];\n dictionaryConditions.transactions.push(\n txFilterToDictionaryCondition(handler.filter),\n );\n }\n break;\n }\n case SolanaHandlerKind.Instruction: {\n if (\n handler.filter &&\n Object.values(handler.filter).filter((v) => v !== undefined).length\n ) {\n dictionaryConditions.instructions ??= [];\n dictionaryConditions.instructions.push(\n instructionFilterToDictionaryCondition(decoder, handler.filter),\n );\n }\n break;\n }\n case SolanaHandlerKind.Log: {\n if (\n handler.filter &&\n Object.values(handler.filter).filter((v) => v !== undefined).length\n ) {\n dictionaryConditions.logs ??= [];\n dictionaryConditions.logs.push(\n logFilterToDictionaryCondition(handler.filter),\n );\n }\n\n break;\n }\n default:\n }\n }\n }\n\n return sanitiseDictionaryConditions(dictionaryConditions);\n}\n\nfunction parseBlock(\n block: RawSolanaBlock,\n decoder: SolanaDecoder,\n): SolanaBlock {\n const methodName = 'parseBlock';\n\n // This is based on https://github.com/anza-xyz/kit/blob/main/packages/rpc-api/src/index.ts#L257\n const transformer = getDefaultResponseTransformerForSolanaRpc({\n allowedNumericKeyPaths: {\n [methodName]: [\n [\n 'transactions',\n KEYPATH_WILDCARD,\n 'meta',\n 'preTokenBalances',\n KEYPATH_WILDCARD,\n 'accountIndex',\n ],\n [\n 'transactions',\n KEYPATH_WILDCARD,\n 'meta',\n 'preTokenBalances',\n KEYPATH_WILDCARD,\n 'uiTokenAmount',\n 'decimals',\n ],\n [\n 'transactions',\n KEYPATH_WILDCARD,\n 'meta',\n 'postTokenBalances',\n KEYPATH_WILDCARD,\n 'accountIndex',\n ],\n [\n 'transactions',\n KEYPATH_WILDCARD,\n 'meta',\n 'postTokenBalances',\n KEYPATH_WILDCARD,\n 'uiTokenAmount',\n 'decimals',\n ],\n [\n 'transactions',\n KEYPATH_WILDCARD,\n 'meta',\n 'rewards',\n KEYPATH_WILDCARD,\n 'commission',\n ],\n ...innerInstructionsConfigs.map((c) => [\n 'transactions',\n KEYPATH_WILDCARD,\n 'meta',\n 'innerInstructions',\n KEYPATH_WILDCARD,\n ...c,\n ]),\n ...messageConfig.map(\n (c) =>\n [\n 'transactions',\n KEYPATH_WILDCARD,\n 'transaction',\n 'message',\n ...c,\n ] as const,\n ),\n ['rewards', KEYPATH_WILDCARD, 'commission'],\n ],\n },\n });\n\n const rpcBlock = transformer(\n { result: block },\n { methodName, params: undefined },\n );\n\n const res = transformBlock(rpcBlock as any, decoder);\n\n return res;\n}\n\nexport class SolanaDictionaryV2 extends DictionaryV2<\n SolanaBlock,\n SubqlDatasource,\n SolanaDictionaryV2QueryEntry\n> {\n // #skipTransactions: boolean;\n\n constructor(\n endpoint: string,\n nodeConfig: NodeConfig,\n project: SubqueryProject,\n private api: SolanaApi,\n ) {\n super(endpoint, project.network.chainId, nodeConfig);\n // this.#skipTransactions = !!new SolanaNodeConfig(nodeConfig)\n // .skipTransactions;\n }\n\n static async create(\n endpoint: string,\n nodeConfig: NodeConfig,\n project: SubqueryProject,\n api: SolanaApi,\n ): Promise<SolanaDictionaryV2> {\n const dictionary = new SolanaDictionaryV2(\n endpoint,\n nodeConfig,\n project,\n api,\n );\n await dictionary.init();\n return dictionary;\n }\n\n buildDictionaryQueryEntries(\n dataSources: (SolanaProjectDs | SolanaProjectDsTemplate)[],\n ): SolanaDictionaryV2QueryEntry {\n return buildDictionaryV2QueryEntry(this.api.decoder, dataSources);\n }\n\n // eslint-disable-next-line @typescript-eslint/require-await\n async getData(\n startBlock: number,\n endBlock: number,\n limit: number = MIN_FETCH_LIMIT,\n ): Promise<DictionaryResponse<IBlock<SolanaBlock> | number> | undefined> {\n return super.getData(startBlock, endBlock, limit, {\n blockHeader: true,\n logs: { transaction: true /*!this.#skipTransactions*/ },\n instructions: { transaction: true },\n transactions: { log: true, instructions: true },\n });\n }\n\n convertResponseBlocks<RFB = RawSolanaBlock>(\n data: RawDictionaryResponseData<RFB>,\n ): DictionaryResponse<IBlock<SolanaBlock>> | undefined {\n try {\n const blocks: IBlock<SolanaBlock>[] = (\n (data.blocks as unknown[]) || []\n ).map((b) => formatBlockUtil(parseBlock(b, this.api.decoder)));\n\n if (!blocks.length) {\n return {\n batchBlocks: [],\n lastBufferedHeight: undefined, // This will get set to the request end block in the base class.\n } as any;\n }\n return {\n batchBlocks: blocks,\n lastBufferedHeight: Number(\n blocks[blocks.length - 1].getHeader().blockHeight,\n ),\n };\n } catch (e: any) {\n logger.error(e, `Failed to handle block response`);\n throw e;\n }\n }\n}\n"]}
@@ -22,6 +22,7 @@ const types_solana_1 = require("@subql/types-solana");
22
22
  const lodash_1 = require("lodash");
23
23
  const blockchain_service_1 = require("../blockchain.service");
24
24
  const solana_1 = require("../solana");
25
+ const block_solana_1 = require("../solana/block.solana");
25
26
  const utils_solana_1 = require("../solana/utils.solana");
26
27
  const unfinalizedBlocks_service_1 = require("./unfinalizedBlocks.service");
27
28
  let IndexerManager = class IndexerManager extends node_core_1.BaseIndexerManager {
@@ -34,7 +35,14 @@ let IndexerManager = class IndexerManager extends node_core_1.BaseIndexerManager
34
35
  return super.internalIndexBlock(block, dataSources, () => this.blockchainService.getSafeApi(block.block));
35
36
  }
36
37
  getDsProcessor(ds, safeApi) {
37
- return this.sandboxService.getDsProcessor(ds, safeApi, this.apiService.api);
38
+ const sandbox = this.sandboxService;
39
+ return sandbox.getDsProcessor(ds, safeApi, this.apiService.api, {
40
+ // Inject the decoder into the sandbox but create a new object to remove access to other methods
41
+ decoder: {
42
+ decodeInstruction: this.apiService.decoder.decodeInstructionRaw.bind(this.apiService.decoder),
43
+ decodeLogs: (logs) => (0, block_solana_1.wrapLogs)(logs, this.apiService.decoder),
44
+ },
45
+ });
38
46
  }
39
47
  async indexBlockData(block, dataSources, getVM) {
40
48
  await this.indexBlockContent(block, dataSources, getVM);
@@ -1 +1 @@
1
- {"version":3,"file":"indexer.manager.js","sourceRoot":"","sources":["../../src/indexer/indexer.manager.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 { Inject, Injectable } from '@nestjs/common';\nimport {\n isBlockHandlerProcessor,\n isCustomDs,\n isRuntimeDs,\n SubqlSolanaCustomDataSource,\n SubqlSolanaDataSource,\n isInstructionHandlerProcessor,\n isTransactionHandlerProcessor,\n isLogHandlerProcessor,\n} from '@subql/common-solana';\nimport {\n NodeConfig,\n profiler,\n IndexerSandbox,\n ProcessBlockResponse,\n BaseIndexerManager,\n IBlock,\n SandboxService,\n DsProcessorService,\n DynamicDsService,\n} from '@subql/node-core';\nimport {\n SolanaHandlerKind,\n SolanaTransaction,\n SolanaBlock,\n SubqlRuntimeDatasource,\n SolanaBlockFilter,\n SolanaTransactionFilter,\n SolanaInstruction,\n SolanaInstructionFilter,\n SolanaRuntimeHandlerInputMap,\n SolanaLogMessage,\n SolanaLogFilter,\n} from '@subql/types-solana';\nimport { groupBy } from 'lodash';\nimport { BlockchainService } from '../blockchain.service';\nimport { SolanaProjectDs } from '../configure/SubqueryProject';\nimport {\n SolanaApi,\n SolanaApiService,\n SolanaDecoder,\n SolanaSafeApi,\n} from '../solana';\nimport {\n filterBlocksProcessor,\n filterInstructionsProcessor,\n filterLogsProcessor,\n filterTransactionsProcessor,\n} from '../solana/utils.solana';\nimport { BlockContent } from './types';\nimport { UnfinalizedBlocksService } from './unfinalizedBlocks.service';\n\n@Injectable()\nexport class IndexerManager extends BaseIndexerManager<\n SolanaApi,\n SolanaSafeApi,\n BlockContent,\n SolanaApiService,\n SubqlSolanaDataSource,\n SubqlSolanaCustomDataSource,\n ReturnType<typeof getFilterTypeMap>,\n typeof ProcessorTypeMap,\n SolanaRuntimeHandlerInputMap\n> {\n protected isRuntimeDs = isRuntimeDs;\n protected isCustomDs = isCustomDs;\n\n constructor(\n @Inject('APIService') apiService: SolanaApiService,\n nodeConfig: NodeConfig,\n sandboxService: SandboxService<SolanaSafeApi, SolanaApi>,\n dsProcessorService: DsProcessorService<\n SubqlSolanaDataSource,\n SubqlSolanaCustomDataSource\n >,\n dynamicDsService: DynamicDsService<SubqlSolanaDataSource>,\n @Inject('IUnfinalizedBlocksService')\n unfinalizedBlocksService: UnfinalizedBlocksService,\n @Inject('IBlockchainService') blockchainService: BlockchainService,\n ) {\n super(\n apiService,\n nodeConfig,\n sandboxService,\n dsProcessorService,\n dynamicDsService,\n unfinalizedBlocksService,\n getFilterTypeMap(apiService.decoder),\n ProcessorTypeMap,\n blockchainService,\n );\n }\n\n @profiler()\n async indexBlock(\n block: IBlock<BlockContent>,\n dataSources: SubqlSolanaDataSource[],\n ): Promise<ProcessBlockResponse> {\n return super.internalIndexBlock(block, dataSources, () =>\n this.blockchainService.getSafeApi(block.block),\n );\n }\n\n protected getDsProcessor(\n ds: SubqlSolanaDataSource,\n safeApi: SolanaSafeApi,\n ): IndexerSandbox {\n return this.sandboxService.getDsProcessor(ds, safeApi, this.apiService.api);\n }\n\n protected async indexBlockData(\n block: BlockContent,\n dataSources: SolanaProjectDs[],\n getVM: (d: SolanaProjectDs) => Promise<IndexerSandbox>,\n ): Promise<void> {\n await this.indexBlockContent(block, dataSources, getVM);\n\n for (const tx of block.transactions) {\n await this.indexTransaction(tx, dataSources, getVM);\n\n // There is probably only one item per group but that could change based on the data structure\n const innerInstructions = groupBy(\n tx.meta?.innerInstructions,\n (inner) => inner.index,\n );\n\n for (const [idx, instruction] of Object.entries(\n tx.transaction.message.instructions ?? [],\n )) {\n await this.indexInstruction(instruction, dataSources, getVM);\n\n for (const innerInstrutions1 of innerInstructions[idx] ?? []) {\n for (const innerInstrution of innerInstrutions1.instructions) {\n await this.indexInstruction(innerInstrution, dataSources, getVM);\n }\n }\n }\n\n for (const log of tx.meta?.logs ?? []) {\n await this.indexLog(log, dataSources, getVM);\n }\n }\n // console.timeEnd(`Indexed block ${block.blockHeight}`);\n }\n\n private async indexBlockContent(\n block: SolanaBlock,\n dataSources: SolanaProjectDs[],\n getVM: (d: SolanaProjectDs) => Promise<IndexerSandbox>,\n ): Promise<void> {\n for (const ds of dataSources) {\n await this.indexData(SolanaHandlerKind.Block, block, ds, getVM);\n }\n }\n\n private async indexTransaction(\n tx: SolanaTransaction,\n dataSources: SolanaProjectDs[],\n getVM: (d: SolanaProjectDs) => Promise<IndexerSandbox>,\n ): Promise<void> {\n for (const ds of dataSources) {\n await this.indexData(SolanaHandlerKind.Transaction, tx, ds, getVM);\n }\n }\n\n private async indexInstruction(\n instruction: SolanaInstruction,\n dataSources: SolanaProjectDs[],\n getVM: (d: SolanaProjectDs) => Promise<IndexerSandbox>,\n ): Promise<void> {\n for (const ds of dataSources) {\n await this.indexData(\n SolanaHandlerKind.Instruction,\n instruction,\n ds,\n getVM,\n );\n }\n }\n\n private async indexLog(\n log: SolanaLogMessage,\n dataSources: SolanaProjectDs[],\n getVM: (d: SolanaProjectDs) => Promise<IndexerSandbox>,\n ): Promise<void> {\n for (const ds of dataSources) {\n await this.indexData(SolanaHandlerKind.Log, log, ds, getVM);\n }\n }\n\n // eslint-disable-next-line @typescript-eslint/require-await\n protected async prepareFilteredData(\n kind: SolanaHandlerKind,\n data: any,\n ds: SubqlRuntimeDatasource,\n ): Promise<any> {\n // Ensure any provided IDLs are available\n await this.apiService.api.decoder.loadIdls(ds);\n\n return DataIDLParser[kind](data);\n }\n}\n\nconst ProcessorTypeMap = {\n [SolanaHandlerKind.Block]: isBlockHandlerProcessor,\n [SolanaHandlerKind.Transaction]: isTransactionHandlerProcessor,\n [SolanaHandlerKind.Instruction]: isInstructionHandlerProcessor,\n [SolanaHandlerKind.Log]: isLogHandlerProcessor,\n};\n\nconst getFilterTypeMap = (decoder: SolanaDecoder) => ({\n [SolanaHandlerKind.Block]: (\n data: SolanaBlock,\n filter: SolanaBlockFilter,\n ds: SubqlSolanaDataSource,\n ) => filterBlocksProcessor(data, filter),\n [SolanaHandlerKind.Transaction]: (\n data: SolanaTransaction,\n filter: SolanaTransactionFilter,\n ds: SubqlSolanaDataSource,\n ) => filterTransactionsProcessor(data, filter),\n [SolanaHandlerKind.Instruction]: (\n data: SolanaInstruction,\n filter: SolanaInstructionFilter,\n ds: SubqlSolanaDataSource,\n ) => filterInstructionsProcessor(data, decoder, filter),\n [SolanaHandlerKind.Log]: (\n data: SolanaLogMessage,\n filter: SolanaLogFilter,\n ds: SubqlSolanaDataSource,\n ) => filterLogsProcessor(data, filter),\n});\n\nconst DataIDLParser = {\n [SolanaHandlerKind.Block]: (data: SolanaBlock) => data,\n [SolanaHandlerKind.Transaction]: (data: SolanaTransaction) => data,\n [SolanaHandlerKind.Instruction]: async (data: SolanaInstruction) => {\n // Preload the decoded data\n await data.decodedData;\n return data;\n },\n [SolanaHandlerKind.Log]: async (data: SolanaLogMessage) => {\n // Preload the decoded data\n await data.decodedMessage;\n return data;\n },\n};\n"]}
1
+ {"version":3,"file":"indexer.manager.js","sourceRoot":"","sources":["../../src/indexer/indexer.manager.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 { Inject, Injectable } from '@nestjs/common';\nimport {\n isBlockHandlerProcessor,\n isCustomDs,\n isRuntimeDs,\n SubqlSolanaCustomDataSource,\n SubqlSolanaDataSource,\n isInstructionHandlerProcessor,\n isTransactionHandlerProcessor,\n isLogHandlerProcessor,\n} from '@subql/common-solana';\nimport {\n NodeConfig,\n profiler,\n IndexerSandbox,\n ProcessBlockResponse,\n BaseIndexerManager,\n IBlock,\n SandboxService,\n DsProcessorService,\n DynamicDsService,\n} from '@subql/node-core';\nimport {\n SolanaHandlerKind,\n SolanaTransaction,\n SolanaBlock,\n SubqlRuntimeDatasource,\n SolanaBlockFilter,\n SolanaTransactionFilter,\n SolanaInstruction,\n SolanaInstructionFilter,\n SolanaRuntimeHandlerInputMap,\n SolanaLogMessage,\n SolanaLogFilter,\n Decoder,\n} from '@subql/types-solana';\nimport { groupBy } from 'lodash';\nimport { BlockchainService } from '../blockchain.service';\nimport { SolanaProjectDs } from '../configure/SubqueryProject';\nimport {\n SolanaApi,\n SolanaApiService,\n SolanaDecoder,\n SolanaSafeApi,\n} from '../solana';\nimport { wrapLogs } from '../solana/block.solana';\nimport {\n filterBlocksProcessor,\n filterInstructionsProcessor,\n filterLogsProcessor,\n filterTransactionsProcessor,\n} from '../solana/utils.solana';\nimport { BlockContent } from './types';\nimport { UnfinalizedBlocksService } from './unfinalizedBlocks.service';\n\n@Injectable()\nexport class IndexerManager extends BaseIndexerManager<\n SolanaApi,\n SolanaSafeApi,\n BlockContent,\n SolanaApiService,\n SubqlSolanaDataSource,\n SubqlSolanaCustomDataSource,\n ReturnType<typeof getFilterTypeMap>,\n typeof ProcessorTypeMap,\n SolanaRuntimeHandlerInputMap\n> {\n protected isRuntimeDs = isRuntimeDs;\n protected isCustomDs = isCustomDs;\n\n constructor(\n @Inject('APIService') apiService: SolanaApiService,\n nodeConfig: NodeConfig,\n sandboxService: SandboxService<SolanaSafeApi, SolanaApi>,\n dsProcessorService: DsProcessorService<\n SubqlSolanaDataSource,\n SubqlSolanaCustomDataSource\n >,\n dynamicDsService: DynamicDsService<SubqlSolanaDataSource>,\n @Inject('IUnfinalizedBlocksService')\n unfinalizedBlocksService: UnfinalizedBlocksService,\n @Inject('IBlockchainService') blockchainService: BlockchainService,\n ) {\n super(\n apiService,\n nodeConfig,\n sandboxService,\n dsProcessorService,\n dynamicDsService,\n unfinalizedBlocksService,\n getFilterTypeMap(apiService.decoder),\n ProcessorTypeMap,\n blockchainService,\n );\n }\n\n @profiler()\n async indexBlock(\n block: IBlock<BlockContent>,\n dataSources: SubqlSolanaDataSource[],\n ): Promise<ProcessBlockResponse> {\n return super.internalIndexBlock(block, dataSources, () =>\n this.blockchainService.getSafeApi(block.block),\n );\n }\n\n protected getDsProcessor(\n ds: SubqlSolanaDataSource,\n safeApi: SolanaSafeApi,\n ): IndexerSandbox {\n const sandbox = (this as any).sandboxService as SandboxService<\n SolanaSafeApi,\n SolanaApi\n >;\n return sandbox.getDsProcessor(ds, safeApi, this.apiService.api, {\n // Inject the decoder into the sandbox but create a new object to remove access to other methods\n decoder: {\n decodeInstruction: this.apiService.decoder.decodeInstructionRaw.bind(\n this.apiService.decoder,\n ),\n decodeLogs: (logs: readonly string[] | null) =>\n wrapLogs(logs, this.apiService.decoder),\n } satisfies Decoder,\n });\n }\n\n protected async indexBlockData(\n block: BlockContent,\n dataSources: SolanaProjectDs[],\n getVM: (d: SolanaProjectDs) => Promise<IndexerSandbox>,\n ): Promise<void> {\n await this.indexBlockContent(block, dataSources, getVM);\n\n for (const tx of block.transactions) {\n await this.indexTransaction(tx, dataSources, getVM);\n\n // There is probably only one item per group but that could change based on the data structure\n const innerInstructions = groupBy(\n tx.meta?.innerInstructions,\n (inner) => inner.index,\n );\n\n for (const [idx, instruction] of Object.entries(\n tx.transaction.message.instructions ?? [],\n )) {\n await this.indexInstruction(instruction, dataSources, getVM);\n\n for (const innerInstrutions1 of innerInstructions[idx] ?? []) {\n for (const innerInstrution of innerInstrutions1.instructions) {\n await this.indexInstruction(innerInstrution, dataSources, getVM);\n }\n }\n }\n\n for (const log of tx.meta?.logs ?? []) {\n await this.indexLog(log, dataSources, getVM);\n }\n }\n // console.timeEnd(`Indexed block ${block.blockHeight}`);\n }\n\n private async indexBlockContent(\n block: SolanaBlock,\n dataSources: SolanaProjectDs[],\n getVM: (d: SolanaProjectDs) => Promise<IndexerSandbox>,\n ): Promise<void> {\n for (const ds of dataSources) {\n await this.indexData(SolanaHandlerKind.Block, block, ds, getVM);\n }\n }\n\n private async indexTransaction(\n tx: SolanaTransaction,\n dataSources: SolanaProjectDs[],\n getVM: (d: SolanaProjectDs) => Promise<IndexerSandbox>,\n ): Promise<void> {\n for (const ds of dataSources) {\n await this.indexData(SolanaHandlerKind.Transaction, tx, ds, getVM);\n }\n }\n\n private async indexInstruction(\n instruction: SolanaInstruction,\n dataSources: SolanaProjectDs[],\n getVM: (d: SolanaProjectDs) => Promise<IndexerSandbox>,\n ): Promise<void> {\n for (const ds of dataSources) {\n await this.indexData(\n SolanaHandlerKind.Instruction,\n instruction,\n ds,\n getVM,\n );\n }\n }\n\n private async indexLog(\n log: SolanaLogMessage,\n dataSources: SolanaProjectDs[],\n getVM: (d: SolanaProjectDs) => Promise<IndexerSandbox>,\n ): Promise<void> {\n for (const ds of dataSources) {\n await this.indexData(SolanaHandlerKind.Log, log, ds, getVM);\n }\n }\n\n // eslint-disable-next-line @typescript-eslint/require-await\n protected async prepareFilteredData(\n kind: SolanaHandlerKind,\n data: any,\n ds: SubqlRuntimeDatasource,\n ): Promise<any> {\n // Ensure any provided IDLs are available\n await this.apiService.api.decoder.loadIdls(ds);\n\n return DataIDLParser[kind](data);\n }\n}\n\nconst ProcessorTypeMap = {\n [SolanaHandlerKind.Block]: isBlockHandlerProcessor,\n [SolanaHandlerKind.Transaction]: isTransactionHandlerProcessor,\n [SolanaHandlerKind.Instruction]: isInstructionHandlerProcessor,\n [SolanaHandlerKind.Log]: isLogHandlerProcessor,\n};\n\nconst getFilterTypeMap = (decoder: SolanaDecoder) => ({\n [SolanaHandlerKind.Block]: (\n data: SolanaBlock,\n filter: SolanaBlockFilter,\n ds: SubqlSolanaDataSource,\n ) => filterBlocksProcessor(data, filter),\n [SolanaHandlerKind.Transaction]: (\n data: SolanaTransaction,\n filter: SolanaTransactionFilter,\n ds: SubqlSolanaDataSource,\n ) => filterTransactionsProcessor(data, filter),\n [SolanaHandlerKind.Instruction]: (\n data: SolanaInstruction,\n filter: SolanaInstructionFilter,\n ds: SubqlSolanaDataSource,\n ) => filterInstructionsProcessor(data, decoder, filter),\n [SolanaHandlerKind.Log]: (\n data: SolanaLogMessage,\n filter: SolanaLogFilter,\n ds: SubqlSolanaDataSource,\n ) => filterLogsProcessor(data, filter),\n});\n\nconst DataIDLParser = {\n [SolanaHandlerKind.Block]: (data: SolanaBlock) => data,\n [SolanaHandlerKind.Transaction]: (data: SolanaTransaction) => data,\n [SolanaHandlerKind.Instruction]: async (data: SolanaInstruction) => {\n // Preload the decoded data\n await data.decodedData;\n return data;\n },\n [SolanaHandlerKind.Log]: async (data: SolanaLogMessage) => {\n // Preload the decoded data\n await data.decodedMessage;\n return data;\n },\n};\n"]}
@@ -1,5 +1,5 @@
1
1
  import { EventEmitter2 } from '@nestjs/event-emitter';
2
- import { Rpc } from '@solana/kit';
2
+ import { Rpc } from '@solana/rpc';
3
3
  import { SolanaRpcApi } from '@solana/rpc-api';
4
4
  import { Header, IBlock } from '@subql/node-core';
5
5
  import { SolanaBlock, ISolanaEndpointConfig } from '@subql/types-solana';
@@ -4,7 +4,7 @@
4
4
  Object.defineProperty(exports, "__esModule", { value: true });
5
5
  exports.SolanaApi = void 0;
6
6
  const addresses_1 = require("@solana/addresses");
7
- const kit_1 = require("@solana/kit");
7
+ const rpc_1 = require("@solana/rpc");
8
8
  const node_core_1 = require("@subql/node-core");
9
9
  const block_solana_1 = require("./block.solana");
10
10
  // eslint-disable-next-line @typescript-eslint/no-var-requires
@@ -36,7 +36,7 @@ class SolanaApi {
36
36
  try {
37
37
  // Keep-Alive is enabled by default, for more details see:
38
38
  // https://github.com/anza-xyz/kit/tree/main/packages/rpc-transport-http#config
39
- const client = (0, kit_1.createSolanaRpc)(endpoint, {
39
+ const client = (0, rpc_1.createSolanaRpc)(endpoint, {
40
40
  headers: {
41
41
  userAgent: `SubQuery Node ${packageVersion}`,
42
42
  ...config?.headers, // TYPES ISSUE
@@ -1 +1 @@
1
- {"version":3,"file":"api.solana.js","sourceRoot":"","sources":["../../src/solana/api.solana.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2020-2025 SubQuery Pte Ltd authors & contributors\n// SPDX-License-Identifier: GPL-3.0\n\nimport { EventEmitter2 } from '@nestjs/event-emitter';\nimport { assertIsAddress } from '@solana/addresses';\nimport { createSolanaRpc, Rpc } from '@solana/kit';\nimport { SolanaRpcApi } from '@solana/rpc-api';\nimport {\n backoffRetry,\n BlockUnavailableError,\n delay,\n getLogger,\n Header,\n IBlock,\n} from '@subql/node-core';\nimport { SolanaBlock, ISolanaEndpointConfig } from '@subql/types-solana';\nimport {\n formatBlockUtil,\n solanaBlockToHeader,\n transformBlock,\n} from './block.solana';\nimport { SolanaDecoder } from './decoder';\n\n// eslint-disable-next-line @typescript-eslint/no-var-requires\nconst { version: packageVersion } = require('../../package.json');\n\nconst logger = getLogger('api.ethereum');\n\nexport type SolanaSafeApi = undefined;\n\nconst REQUEST_TIMEOUT = 30_000;\n\nexport class SolanaApi {\n #client: Rpc<SolanaRpcApi>;\n\n // This is used within the sandbox when HTTP is used\n #genesisBlockHash: string;\n #requestTimeout: number;\n\n /**\n * @param {string} endpoint - The endpoint of the RPC provider\n * @param {number} blockConfirmations - Used to determine how many blocks behind the head a block is considered finalized. Not used if the network has a concrete finalization mechanism.\n * @param {object} eventEmitter - Used to monitor the number of RPC requests\n */\n private constructor(\n client: Rpc<SolanaRpcApi>,\n genesisHash: string,\n private endpoint: string,\n private eventEmitter: EventEmitter2,\n readonly decoder: SolanaDecoder,\n requestTimeout: number = REQUEST_TIMEOUT,\n ) {\n this.#client = client;\n this.#genesisBlockHash = genesisHash;\n this.#requestTimeout = requestTimeout;\n }\n\n static async create(\n endpoint: string,\n eventEmitter: EventEmitter2,\n decoder: SolanaDecoder,\n config?: ISolanaEndpointConfig,\n ): Promise<SolanaApi> {\n try {\n // Keep-Alive is enabled by default, for more details see:\n // https://github.com/anza-xyz/kit/tree/main/packages/rpc-transport-http#config\n const client = createSolanaRpc(endpoint, {\n headers: {\n userAgent: `SubQuery Node ${packageVersion}`,\n ...(config?.headers as any), // TYPES ISSUE\n },\n });\n\n const genesisBlockHash = await client\n .getGenesisHash()\n .send({\n abortSignal: AbortSignal.timeout(\n config?.requestTimeout ?? REQUEST_TIMEOUT,\n ),\n })\n .catch((e) => {\n throw new Error('Failed to get genesis hash', { cause: e });\n });\n\n return new SolanaApi(\n client,\n genesisBlockHash,\n endpoint,\n eventEmitter,\n decoder,\n config?.requestTimeout,\n );\n } catch (e) {\n console.error('CrateSoalana API', e);\n throw e;\n }\n }\n\n async getFinalizedBlockHeader(): Promise<Header> {\n try {\n const height = await this.getFinalizedBlockHeight();\n // This needs retries becasue if the endpoint is load balanced you might get a different node that doesn't yet have this block\n const header = await backoffRetry(() => this.getHeaderByHeight(height));\n return header;\n } catch (e) {\n throw new Error('Failed to get finalized header', { cause: e });\n }\n }\n\n async getFinalizedBlockHeight(): Promise<number> {\n try {\n const finalizedHeight = await this.#client\n .getSlot({ commitment: 'finalized' })\n .send({ abortSignal: AbortSignal.timeout(this.#requestTimeout) });\n\n return Number(finalizedHeight);\n } catch (e) {\n throw new Error('Failed to get finalized height', { cause: e });\n }\n }\n\n async getBestBlockHeight(): Promise<number> {\n try {\n const confirmedHeight = await this.#client\n .getSlot({ commitment: 'confirmed' })\n .send({ abortSignal: AbortSignal.timeout(this.#requestTimeout) });\n\n return Number(confirmedHeight);\n } catch (e) {\n throw new Error('Failed to get best height', { cause: e });\n }\n }\n\n getRuntimeChain(): string {\n switch (this.#genesisBlockHash) {\n case '5eykt4UsFv8P8NJdTREpY1vzqKqZKvdpKuc147dw2N9d':\n return 'mainnet';\n case 'EKLxEB4xoEDq9AAn5HhFiP5WqdhNVc4An2HvJyzHzx7u': // Not tested\n return 'testnet;';\n case 'GH7ome3EiwEr7tu9JuTh2dpYWBJK3z69Xm1ZE3MEE6JC':\n return 'devnet';\n default:\n return 'unknown';\n }\n }\n\n getGenesisHash(): string {\n return this.#genesisBlockHash;\n }\n\n getSpecName(): string {\n return 'solana';\n }\n\n async getHeaderByHeight(height: number | bigint): Promise<Header> {\n const slot = typeof height === 'number' ? BigInt(height) : height;\n const block = await this.#client\n .getBlock(slot, {\n maxSupportedTransactionVersion: 0,\n transactionDetails: 'none',\n rewards: false,\n commitment: 'confirmed', // This is used by unfinalized blocks\n })\n .send({ abortSignal: AbortSignal.timeout(this.#requestTimeout) });\n\n if (!block) {\n // No block for that slot\n throw new BlockUnavailableError();\n }\n\n return solanaBlockToHeader(block);\n }\n\n async fetchBlock(blockNumber: number): Promise<IBlock<SolanaBlock>> {\n try {\n const rawBlock = await this.#client\n .getBlock(BigInt(blockNumber), {\n encoding: 'json',\n transactionDetails: 'full',\n maxSupportedTransactionVersion: 0,\n })\n .send({ abortSignal: AbortSignal.timeout(this.#requestTimeout) });\n\n if (!rawBlock) {\n // No block for that slot\n throw new BlockUnavailableError();\n }\n\n this.eventEmitter.emit('fetchBlock');\n return formatBlockUtil(transformBlock(rawBlock, this.decoder));\n } catch (e: any) {\n console.log('Failed to fetch block', blockNumber, e.message);\n throw this.handleError(e);\n }\n }\n\n async fetchBlocks(bufferBlocks: number[]): Promise<IBlock<SolanaBlock>[]> {\n return Promise.all(bufferBlocks.map(async (num) => this.fetchBlock(num)));\n }\n\n get api(): Rpc<SolanaRpcApi> {\n return this.#client;\n }\n\n getSafeApi(blockHeight: number): SolanaSafeApi {\n return;\n // throw new Error('Safe Api is not supported');\n }\n\n // This method is designed to be compatible with @solana/web3.js so that @coral-xyz/anchor IDLs can be fetched.\n async getAccountInfo(address: unknown): Promise<{ data: Buffer } | null> {\n const addressStr =\n typeof address === 'string' ? address : (address as any).toBase58();\n assertIsAddress(addressStr);\n\n const res = await this.#client\n .getAccountInfo(addressStr, {\n encoding: 'base64',\n })\n .send({ abortSignal: AbortSignal.timeout(REQUEST_TIMEOUT) });\n\n if (res.value) {\n return {\n data: Buffer.from(res.value.data[0], 'base64'),\n };\n }\n\n return null;\n }\n\n // eslint-disable-next-line @typescript-eslint/require-await\n async connect(): Promise<void> {\n logger.error('Ethereum API connect is not implemented');\n throw new Error('Not implemented: connect');\n }\n\n async disconnect(): Promise<void> {\n // NO-OP\n // TODO implement if websockets are supported\n // if (this.client instanceof WebSocketProvider) {\n // await this.client.destroy();\n // } else {\n // logger.warn('Disconnect called on HTTP provider');\n // }\n }\n\n handleError(e: Error): Error {\n if ((e as any)?.context?.statusCode === 429) {\n const { hostname } = new URL(this.endpoint);\n return new Error(`Rate Limited at endpoint: ${hostname}`);\n }\n\n return e;\n }\n}\n"]}
1
+ {"version":3,"file":"api.solana.js","sourceRoot":"","sources":["../../src/solana/api.solana.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2020-2025 SubQuery Pte Ltd authors & contributors\n// SPDX-License-Identifier: GPL-3.0\n\nimport { EventEmitter2 } from '@nestjs/event-emitter';\nimport { assertIsAddress } from '@solana/addresses';\nimport { createSolanaRpc, Rpc } from '@solana/rpc';\nimport { SolanaRpcApi } from '@solana/rpc-api';\nimport {\n backoffRetry,\n BlockUnavailableError,\n delay,\n getLogger,\n Header,\n IBlock,\n} from '@subql/node-core';\nimport { SolanaBlock, ISolanaEndpointConfig } from '@subql/types-solana';\nimport {\n formatBlockUtil,\n solanaBlockToHeader,\n transformBlock,\n} from './block.solana';\nimport { SolanaDecoder } from './decoder';\n\n// eslint-disable-next-line @typescript-eslint/no-var-requires\nconst { version: packageVersion } = require('../../package.json');\n\nconst logger = getLogger('api.ethereum');\n\nexport type SolanaSafeApi = undefined;\n\nconst REQUEST_TIMEOUT = 30_000;\n\nexport class SolanaApi {\n #client: Rpc<SolanaRpcApi>;\n\n // This is used within the sandbox when HTTP is used\n #genesisBlockHash: string;\n #requestTimeout: number;\n\n /**\n * @param {string} endpoint - The endpoint of the RPC provider\n * @param {number} blockConfirmations - Used to determine how many blocks behind the head a block is considered finalized. Not used if the network has a concrete finalization mechanism.\n * @param {object} eventEmitter - Used to monitor the number of RPC requests\n */\n private constructor(\n client: Rpc<SolanaRpcApi>,\n genesisHash: string,\n private endpoint: string,\n private eventEmitter: EventEmitter2,\n readonly decoder: SolanaDecoder,\n requestTimeout: number = REQUEST_TIMEOUT,\n ) {\n this.#client = client;\n this.#genesisBlockHash = genesisHash;\n this.#requestTimeout = requestTimeout;\n }\n\n static async create(\n endpoint: string,\n eventEmitter: EventEmitter2,\n decoder: SolanaDecoder,\n config?: ISolanaEndpointConfig,\n ): Promise<SolanaApi> {\n try {\n // Keep-Alive is enabled by default, for more details see:\n // https://github.com/anza-xyz/kit/tree/main/packages/rpc-transport-http#config\n const client = createSolanaRpc(endpoint, {\n headers: {\n userAgent: `SubQuery Node ${packageVersion}`,\n ...(config?.headers as any), // TYPES ISSUE\n },\n });\n\n const genesisBlockHash = await client\n .getGenesisHash()\n .send({\n abortSignal: AbortSignal.timeout(\n config?.requestTimeout ?? REQUEST_TIMEOUT,\n ),\n })\n .catch((e) => {\n throw new Error('Failed to get genesis hash', { cause: e });\n });\n\n return new SolanaApi(\n client,\n genesisBlockHash,\n endpoint,\n eventEmitter,\n decoder,\n config?.requestTimeout,\n );\n } catch (e) {\n console.error('CrateSoalana API', e);\n throw e;\n }\n }\n\n async getFinalizedBlockHeader(): Promise<Header> {\n try {\n const height = await this.getFinalizedBlockHeight();\n // This needs retries becasue if the endpoint is load balanced you might get a different node that doesn't yet have this block\n const header = await backoffRetry(() => this.getHeaderByHeight(height));\n return header;\n } catch (e) {\n throw new Error('Failed to get finalized header', { cause: e });\n }\n }\n\n async getFinalizedBlockHeight(): Promise<number> {\n try {\n const finalizedHeight = await this.#client\n .getSlot({ commitment: 'finalized' })\n .send({ abortSignal: AbortSignal.timeout(this.#requestTimeout) });\n\n return Number(finalizedHeight);\n } catch (e) {\n throw new Error('Failed to get finalized height', { cause: e });\n }\n }\n\n async getBestBlockHeight(): Promise<number> {\n try {\n const confirmedHeight = await this.#client\n .getSlot({ commitment: 'confirmed' })\n .send({ abortSignal: AbortSignal.timeout(this.#requestTimeout) });\n\n return Number(confirmedHeight);\n } catch (e) {\n throw new Error('Failed to get best height', { cause: e });\n }\n }\n\n getRuntimeChain(): string {\n switch (this.#genesisBlockHash) {\n case '5eykt4UsFv8P8NJdTREpY1vzqKqZKvdpKuc147dw2N9d':\n return 'mainnet';\n case 'EKLxEB4xoEDq9AAn5HhFiP5WqdhNVc4An2HvJyzHzx7u': // Not tested\n return 'testnet;';\n case 'GH7ome3EiwEr7tu9JuTh2dpYWBJK3z69Xm1ZE3MEE6JC':\n return 'devnet';\n default:\n return 'unknown';\n }\n }\n\n getGenesisHash(): string {\n return this.#genesisBlockHash;\n }\n\n getSpecName(): string {\n return 'solana';\n }\n\n async getHeaderByHeight(height: number | bigint): Promise<Header> {\n const slot = typeof height === 'number' ? BigInt(height) : height;\n const block = await this.#client\n .getBlock(slot, {\n maxSupportedTransactionVersion: 0,\n transactionDetails: 'none',\n rewards: false,\n commitment: 'confirmed', // This is used by unfinalized blocks\n })\n .send({ abortSignal: AbortSignal.timeout(this.#requestTimeout) });\n\n if (!block) {\n // No block for that slot\n throw new BlockUnavailableError();\n }\n\n return solanaBlockToHeader(block);\n }\n\n async fetchBlock(blockNumber: number): Promise<IBlock<SolanaBlock>> {\n try {\n const rawBlock = await this.#client\n .getBlock(BigInt(blockNumber), {\n encoding: 'json',\n transactionDetails: 'full',\n maxSupportedTransactionVersion: 0,\n })\n .send({ abortSignal: AbortSignal.timeout(this.#requestTimeout) });\n\n if (!rawBlock) {\n // No block for that slot\n throw new BlockUnavailableError();\n }\n\n this.eventEmitter.emit('fetchBlock');\n return formatBlockUtil(transformBlock(rawBlock, this.decoder));\n } catch (e: any) {\n console.log('Failed to fetch block', blockNumber, e.message);\n throw this.handleError(e);\n }\n }\n\n async fetchBlocks(bufferBlocks: number[]): Promise<IBlock<SolanaBlock>[]> {\n return Promise.all(bufferBlocks.map(async (num) => this.fetchBlock(num)));\n }\n\n get api(): Rpc<SolanaRpcApi> {\n return this.#client;\n }\n\n getSafeApi(blockHeight: number): SolanaSafeApi {\n return;\n // throw new Error('Safe Api is not supported');\n }\n\n // This method is designed to be compatible with @solana/web3.js so that @coral-xyz/anchor IDLs can be fetched.\n async getAccountInfo(address: unknown): Promise<{ data: Buffer } | null> {\n const addressStr =\n typeof address === 'string' ? address : (address as any).toBase58();\n assertIsAddress(addressStr);\n\n const res = await this.#client\n .getAccountInfo(addressStr, {\n encoding: 'base64',\n })\n .send({ abortSignal: AbortSignal.timeout(REQUEST_TIMEOUT) });\n\n if (res.value) {\n return {\n data: Buffer.from(res.value.data[0], 'base64'),\n };\n }\n\n return null;\n }\n\n // eslint-disable-next-line @typescript-eslint/require-await\n async connect(): Promise<void> {\n logger.error('Ethereum API connect is not implemented');\n throw new Error('Not implemented: connect');\n }\n\n async disconnect(): Promise<void> {\n // NO-OP\n // TODO implement if websockets are supported\n // if (this.client instanceof WebSocketProvider) {\n // await this.client.destroy();\n // } else {\n // logger.warn('Disconnect called on HTTP provider');\n // }\n }\n\n handleError(e: Error): Error {\n if ((e as any)?.context?.statusCode === 429) {\n const { hostname } = new URL(this.endpoint);\n return new Error(`Rate Limited at endpoint: ${hostname}`);\n }\n\n return e;\n }\n}\n"]}
@@ -1,6 +1,6 @@
1
1
  import type { UnixTimestamp, Blockhash, Slot, TransactionForFullJson } from '@solana/rpc-types';
2
2
  import { type Header, type IBlock } from '@subql/node-core';
3
- import type { SolanaBlock, BaseSolanaBlock } from '@subql/types-solana';
3
+ import type { SolanaBlock, BaseSolanaBlock, SolanaLogMessage } from '@subql/types-solana';
4
4
  import { SolanaDecoder } from './decoder';
5
5
  type RawSolanaBlock = Readonly<{
6
6
  /** The number of blocks beneath this block */
@@ -15,6 +15,7 @@ type RawSolanaBlock = Readonly<{
15
15
  previousBlockhash: Blockhash;
16
16
  transactions: readonly TransactionForFullJson<0>[];
17
17
  }>;
18
+ export declare function wrapLogs(logs: readonly string[] | null, decoder: SolanaDecoder): SolanaLogMessage[] | null;
18
19
  /**
19
20
  * Transforms a block from a raw response to the types injected into handlers*/
20
21
  export declare function transformBlock(block: RawSolanaBlock, decoder: SolanaDecoder): SolanaBlock;
@@ -2,6 +2,7 @@
2
2
  // Copyright 2020-2025 SubQuery Pte Ltd authors & contributors
3
3
  // SPDX-License-Identifier: GPL-3.0
4
4
  Object.defineProperty(exports, "__esModule", { value: true });
5
+ exports.wrapLogs = wrapLogs;
5
6
  exports.transformBlock = transformBlock;
6
7
  exports.formatBlockUtil = formatBlockUtil;
7
8
  exports.solanaBlockToHeader = solanaBlockToHeader;
@@ -1 +1 @@
1
- {"version":3,"file":"block.solana.js","sourceRoot":"","sources":["../../src/solana/block.solana.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 type {\n UnixTimestamp,\n Blockhash,\n Slot,\n TransactionForFullJson,\n} from '@solana/rpc-types';\nimport { getLogger, type Header, type IBlock } from '@subql/node-core';\nimport type {\n SolanaBlock,\n BaseSolanaBlock,\n SolanaInstruction,\n DecodedData,\n SolanaLogMessage,\n} from '@subql/types-solana';\nimport { SolanaDecoder } from './decoder';\n\nconst logger = getLogger('SolanaBlock');\n\ntype RawSolanaBlock = Readonly<{\n /** The number of blocks beneath this block */\n blockHeight: bigint;\n /** Estimated production time, as Unix timestamp */\n blockTime: UnixTimestamp;\n /** the blockhash of this block */\n blockhash: Blockhash;\n /** The slot index of this block's parent */\n parentSlot: Slot;\n /** The blockhash of this block's parent */\n previousBlockhash: Blockhash;\n\n transactions: readonly TransactionForFullJson<0>[];\n}>;\n\n// We use this function to omit properties without accessing getters\nfunction omit<T>(input: T, omit: (keyof T)[]) {\n const json: Record<string, any> = {};\n\n for (const key of Object.getOwnPropertyNames(input)) {\n if (!omit.includes(key as keyof T)) {\n json[key] = (input as any)[key];\n }\n }\n\n return json;\n}\n\nfunction wrapInstruction(\n index: number[],\n instruction: Omit<\n SolanaInstruction,\n 'index' | 'block' | 'transaction' | 'decodedData'\n >,\n transaction: TransactionForFullJson<0>,\n block: BaseSolanaBlock,\n decoder: SolanaDecoder,\n): SolanaInstruction {\n let pendingDecode: Promise<DecodedData | null>;\n // XXX if we make this fully circular toJSON will need to be added to omit the transaction on the instruction\n const res = {\n ...instruction,\n index,\n transaction,\n block,\n get decodedData(): Promise<DecodedData | null> {\n pendingDecode ??= decoder.decodeInstruction(this);\n return pendingDecode;\n },\n };\n\n // Implement this in order to calculate block size\n (res as any).toJSON = () => {\n return omit(res, ['block', 'decodedData', 'transaction']);\n };\n\n return res;\n}\n\nfunction wrapLogs(\n logs: readonly string[] | null,\n decoder: SolanaDecoder,\n): SolanaLogMessage[] | null {\n if (logs === null) {\n return null;\n }\n const res: SolanaLogMessage[] = [];\n\n // Keep a stack of the instruction programs\n const instructionPath: string[] = [];\n\n for (const [idx, log] of Object.entries(logs)) {\n let pendingDecode: Promise<DecodedData | null>;\n if (log.startsWith('Program log:')) {\n res.push({\n message: log,\n programId: instructionPath[instructionPath.length - 1],\n logIndex: parseInt(idx, 10),\n type: 'log',\n decodedMessage: Promise.resolve(null),\n });\n } else if (log.startsWith('Program data:')) {\n res.push({\n message: log,\n programId: instructionPath[instructionPath.length - 1],\n logIndex: parseInt(idx, 10),\n type: 'data',\n get decodedMessage(): Promise<DecodedData | null> {\n pendingDecode ??= decoder.decodeLog(this);\n return pendingDecode;\n }, // TODO getter function to parse\n });\n } else if (log.startsWith('Program return:')) {\n res.push({\n message: log,\n programId: instructionPath[instructionPath.length - 1],\n logIndex: parseInt(idx, 10),\n type: 'other',\n get decodedMessage(): Promise<DecodedData | null> {\n pendingDecode ??= decoder.decodeLog(this);\n return pendingDecode;\n }, // TODO getter function to parse, can return data be dcoded?\n });\n } else if (log.startsWith('Program consumption:')) {\n // DO nothing\n } else if (log.startsWith('Program')) {\n const [, /* \"Program\"*/ programAddress, mode, ...rest] = log.split(' '); // TODO doesn't work with compute units\n switch (mode) {\n case 'invoke':\n instructionPath.push(programAddress);\n break;\n case 'success':\n // TODO need to check this is always the last item\n instructionPath.pop();\n break;\n case 'consumed':\n // Do nothing\n break;\n case 'failed:':\n // TODO\n instructionPath.pop();\n break;\n default:\n throw new Error(`Unknown log mode: ${mode}, log: ${log}`);\n }\n } else {\n /**\n * Known examples (prefixes):\n * * Transfer\n * * Create Account\n * * Allocate\n * * Instruction references an unknown account\n * */\n\n logger.warn(`Unable to parse log message: ${log}`);\n }\n }\n\n // Implement this in order to calculate block size\n res.forEach((r) => {\n (r as any).toJSON = () => {\n return omit(r, ['decodedMessage']);\n };\n });\n\n return res;\n}\n\ntype DictionaryLog = {\n message: string;\n logIndex: number;\n programId: string;\n kind: 'data' | 'log' | 'other';\n};\n\nfunction wrapDictionaryLogs(\n logs: DictionaryLog[],\n decoder: SolanaDecoder,\n): SolanaLogMessage[] {\n return logs.map((l) => {\n let pendingDecode: Promise<DecodedData | null>;\n const res = {\n message: l.message,\n programId: l.programId,\n logIndex: l.logIndex,\n type: l.kind,\n get decodedMessage() {\n if (!['other', 'data'].includes(l.kind)) {\n return Promise.resolve(null);\n }\n\n pendingDecode ??= decoder.decodeLog(this);\n return pendingDecode;\n },\n };\n\n // Implement this in order to calculate block size\n (res as any).toJSON = () => {\n return omit(res, ['decodedMessage']);\n };\n\n return res;\n });\n}\n\n/**\n * Transforms a block from a raw response to the types injected into handlers*/\nexport function transformBlock(\n block: RawSolanaBlock,\n decoder: SolanaDecoder,\n): SolanaBlock {\n const { transactions, ...baseBlock } = block;\n return {\n ...baseBlock,\n transactions: transactions.map((tx) => {\n try {\n return {\n ...tx,\n block: baseBlock,\n transaction: {\n ...tx.transaction,\n message: {\n ...tx.transaction.message,\n instructions: tx.transaction.message.instructions.map(\n (instruction, index) =>\n wrapInstruction([index], instruction, tx, baseBlock, decoder),\n ),\n },\n },\n meta: tx.meta\n ? {\n ...tx.meta,\n innerInstructions: tx.meta.innerInstructions.map(\n (innerInstruction) => ({\n ...innerInstruction,\n instructions: innerInstruction.instructions.map(\n (instruction, innerIndex) =>\n wrapInstruction(\n [innerInstruction.index, innerIndex],\n instruction,\n tx,\n baseBlock,\n decoder,\n ),\n ),\n }),\n ),\n // Dictionary blocks have logs instead of logMessages that are already somewhat wrapped\n logs: (tx.meta as any).logs\n ? wrapDictionaryLogs((tx.meta as any).logs, decoder)\n : wrapLogs(tx.meta.logMessages, decoder),\n }\n : null,\n };\n } catch (e) {\n throw new Error(\n `Failed to transform transaction: ${tx.transaction.signatures[0]}`,\n { cause: e },\n );\n }\n }),\n };\n}\n\nexport function formatBlockUtil<B extends SolanaBlock = SolanaBlock>(\n block: B,\n): IBlock<B> {\n return {\n block,\n getHeader: () => solanaBlockToHeader(block),\n };\n}\n\nexport function solanaBlockToHeader(block: BaseSolanaBlock): Header {\n return {\n blockHeight: Number(block.parentSlot) + 1, // The blocks don't include the slot because they assume you know that when making the request\n blockHash: block.blockhash,\n parentHash: block.previousBlockhash,\n timestamp: new Date(Number(block.blockTime) * 1000),\n };\n}\n"]}
1
+ {"version":3,"file":"block.solana.js","sourceRoot":"","sources":["../../src/solana/block.solana.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 type {\n UnixTimestamp,\n Blockhash,\n Slot,\n TransactionForFullJson,\n} from '@solana/rpc-types';\nimport { getLogger, type Header, type IBlock } from '@subql/node-core';\nimport type {\n SolanaBlock,\n BaseSolanaBlock,\n SolanaInstruction,\n DecodedData,\n SolanaLogMessage,\n} from '@subql/types-solana';\nimport { SolanaDecoder } from './decoder';\n\nconst logger = getLogger('SolanaBlock');\n\ntype RawSolanaBlock = Readonly<{\n /** The number of blocks beneath this block */\n blockHeight: bigint;\n /** Estimated production time, as Unix timestamp */\n blockTime: UnixTimestamp;\n /** the blockhash of this block */\n blockhash: Blockhash;\n /** The slot index of this block's parent */\n parentSlot: Slot;\n /** The blockhash of this block's parent */\n previousBlockhash: Blockhash;\n\n transactions: readonly TransactionForFullJson<0>[];\n}>;\n\n// We use this function to omit properties without accessing getters\nfunction omit<T>(input: T, omit: (keyof T)[]) {\n const json: Record<string, any> = {};\n\n for (const key of Object.getOwnPropertyNames(input)) {\n if (!omit.includes(key as keyof T)) {\n json[key] = (input as any)[key];\n }\n }\n\n return json;\n}\n\nfunction wrapInstruction(\n index: number[],\n instruction: Omit<\n SolanaInstruction,\n 'index' | 'block' | 'transaction' | 'decodedData'\n >,\n transaction: TransactionForFullJson<0>,\n block: BaseSolanaBlock,\n decoder: SolanaDecoder,\n): SolanaInstruction {\n let pendingDecode: Promise<DecodedData | null>;\n // XXX if we make this fully circular toJSON will need to be added to omit the transaction on the instruction\n const res = {\n ...instruction,\n index,\n transaction,\n block,\n get decodedData(): Promise<DecodedData | null> {\n pendingDecode ??= decoder.decodeInstruction(this);\n return pendingDecode;\n },\n };\n\n // Implement this in order to calculate block size\n (res as any).toJSON = () => {\n return omit(res, ['block', 'decodedData', 'transaction']);\n };\n\n return res;\n}\n\nexport function wrapLogs(\n logs: readonly string[] | null,\n decoder: SolanaDecoder,\n): SolanaLogMessage[] | null {\n if (logs === null) {\n return null;\n }\n const res: SolanaLogMessage[] = [];\n\n // Keep a stack of the instruction programs\n const instructionPath: string[] = [];\n\n for (const [idx, log] of Object.entries(logs)) {\n let pendingDecode: Promise<DecodedData | null>;\n if (log.startsWith('Program log:')) {\n res.push({\n message: log,\n programId: instructionPath[instructionPath.length - 1],\n logIndex: parseInt(idx, 10),\n type: 'log',\n decodedMessage: Promise.resolve(null),\n });\n } else if (log.startsWith('Program data:')) {\n res.push({\n message: log,\n programId: instructionPath[instructionPath.length - 1],\n logIndex: parseInt(idx, 10),\n type: 'data',\n get decodedMessage(): Promise<DecodedData | null> {\n pendingDecode ??= decoder.decodeLog(this);\n return pendingDecode;\n }, // TODO getter function to parse\n });\n } else if (log.startsWith('Program return:')) {\n res.push({\n message: log,\n programId: instructionPath[instructionPath.length - 1],\n logIndex: parseInt(idx, 10),\n type: 'other',\n get decodedMessage(): Promise<DecodedData | null> {\n pendingDecode ??= decoder.decodeLog(this);\n return pendingDecode;\n }, // TODO getter function to parse, can return data be dcoded?\n });\n } else if (log.startsWith('Program consumption:')) {\n // DO nothing\n } else if (log.startsWith('Program')) {\n const [, /* \"Program\"*/ programAddress, mode, ...rest] = log.split(' '); // TODO doesn't work with compute units\n switch (mode) {\n case 'invoke':\n instructionPath.push(programAddress);\n break;\n case 'success':\n // TODO need to check this is always the last item\n instructionPath.pop();\n break;\n case 'consumed':\n // Do nothing\n break;\n case 'failed:':\n // TODO\n instructionPath.pop();\n break;\n default:\n throw new Error(`Unknown log mode: ${mode}, log: ${log}`);\n }\n } else {\n /**\n * Known examples (prefixes):\n * * Transfer\n * * Create Account\n * * Allocate\n * * Instruction references an unknown account\n * */\n\n logger.warn(`Unable to parse log message: ${log}`);\n }\n }\n\n // Implement this in order to calculate block size\n res.forEach((r) => {\n (r as any).toJSON = () => {\n return omit(r, ['decodedMessage']);\n };\n });\n\n return res;\n}\n\ntype DictionaryLog = {\n message: string;\n logIndex: number;\n programId: string;\n kind: 'data' | 'log' | 'other';\n};\n\nfunction wrapDictionaryLogs(\n logs: DictionaryLog[],\n decoder: SolanaDecoder,\n): SolanaLogMessage[] {\n return logs.map((l) => {\n let pendingDecode: Promise<DecodedData | null>;\n const res = {\n message: l.message,\n programId: l.programId,\n logIndex: l.logIndex,\n type: l.kind,\n get decodedMessage() {\n if (!['other', 'data'].includes(l.kind)) {\n return Promise.resolve(null);\n }\n\n pendingDecode ??= decoder.decodeLog(this);\n return pendingDecode;\n },\n };\n\n // Implement this in order to calculate block size\n (res as any).toJSON = () => {\n return omit(res, ['decodedMessage']);\n };\n\n return res;\n });\n}\n\n/**\n * Transforms a block from a raw response to the types injected into handlers*/\nexport function transformBlock(\n block: RawSolanaBlock,\n decoder: SolanaDecoder,\n): SolanaBlock {\n const { transactions, ...baseBlock } = block;\n return {\n ...baseBlock,\n transactions: transactions.map((tx) => {\n try {\n return {\n ...tx,\n block: baseBlock,\n transaction: {\n ...tx.transaction,\n message: {\n ...tx.transaction.message,\n instructions: tx.transaction.message.instructions.map(\n (instruction, index) =>\n wrapInstruction([index], instruction, tx, baseBlock, decoder),\n ),\n },\n },\n meta: tx.meta\n ? {\n ...tx.meta,\n innerInstructions: tx.meta.innerInstructions.map(\n (innerInstruction) => ({\n ...innerInstruction,\n instructions: innerInstruction.instructions.map(\n (instruction, innerIndex) =>\n wrapInstruction(\n [innerInstruction.index, innerIndex],\n instruction,\n tx,\n baseBlock,\n decoder,\n ),\n ),\n }),\n ),\n // Dictionary blocks have logs instead of logMessages that are already somewhat wrapped\n logs: (tx.meta as any).logs\n ? wrapDictionaryLogs((tx.meta as any).logs, decoder)\n : wrapLogs(tx.meta.logMessages, decoder),\n }\n : null,\n };\n } catch (e) {\n throw new Error(\n `Failed to transform transaction: ${tx.transaction.signatures[0]}`,\n { cause: e },\n );\n }\n }),\n };\n}\n\nexport function formatBlockUtil<B extends SolanaBlock = SolanaBlock>(\n block: B,\n): IBlock<B> {\n return {\n block,\n getHeader: () => solanaBlockToHeader(block),\n };\n}\n\nexport function solanaBlockToHeader(block: BaseSolanaBlock): Header {\n return {\n blockHeight: Number(block.parentSlot) + 1, // The blocks don't include the slot because they assume you know that when making the request\n blockHash: block.blockhash,\n parentHash: block.previousBlockhash,\n timestamp: new Date(Number(block.blockTime) * 1000),\n };\n}\n"]}
@@ -1,4 +1,4 @@
1
- import { Base58EncodedBytes } from '@solana/kit';
1
+ import { Base58EncodedBytes, TransactionForFullJson } from '@solana/kit';
2
2
  import { Idl } from '@subql/common-solana';
3
3
  import { DecodedData, SolanaInstruction, SolanaLogMessage, SubqlDatasource } from '@subql/types-solana';
4
4
  export declare function decodeInstruction(idl: Idl, data: Base58EncodedBytes): DecodedData | null;
@@ -8,6 +8,7 @@ export declare class SolanaDecoder {
8
8
  loadIdls(ds: SubqlDatasource): Promise<void>;
9
9
  getIdlFromChain(programId: string): Promise<Idl | null>;
10
10
  parseDiscriminator(input: string, programId: string): Buffer;
11
+ decodeInstructionRaw(instruction: TransactionForFullJson<0>['transaction']['message']['instructions'][number], transaction: TransactionForFullJson<0>): Promise<DecodedData | null>;
11
12
  decodeInstruction(instruction: SolanaInstruction): Promise<DecodedData | null>;
12
13
  decodeLog(log: SolanaLogMessage): Promise<DecodedData | null>;
13
14
  }
@@ -138,9 +138,9 @@ class SolanaDecoder {
138
138
  }
139
139
  return discriminator;
140
140
  }
141
- async decodeInstruction(instruction) {
141
+ async decodeInstructionRaw(instruction, transaction) {
142
142
  try {
143
- const programId = (0, utils_solana_1.getProgramId)(instruction);
143
+ const programId = (0, utils_solana_1.allAccounts)(transaction)[instruction.programIdIndex];
144
144
  const idl = this.idls[programId] ?? (await this.getIdlFromChain(programId));
145
145
  if (!idl) {
146
146
  return null;
@@ -152,6 +152,9 @@ class SolanaDecoder {
152
152
  }
153
153
  return null;
154
154
  }
155
+ async decodeInstruction(instruction) {
156
+ return this.decodeInstructionRaw(instruction, instruction.transaction);
157
+ }
155
158
  async decodeLog(log) {
156
159
  try {
157
160
  const programId = log.programId;
@@ -1 +1 @@
1
- {"version":3,"file":"decoder.js","sourceRoot":"","sources":["../../src/solana/decoder.ts"],"names":[],"mappings":";AAAA,8DAA8D;AAC9D,mCAAmC;;;;;;;;;;;;;;;AA0FnC,8CAKC;AAGD,8BA4BC;AA5HD,sDAAyB;AACzB,2DAAsD;AAEtD,wDAM8B;AAC9B,gDAA6C;AAO7C,wCAAqC;AACrC,gDAAwB;AACxB,mCAA+E;AAC/E,oDAA8C;AAC9C,iDAA8C;AAE9C,MAAM,MAAM,GAAG,IAAA,qBAAS,EAAC,eAAe,CAAC,CAAC;AAE1C,SAAS,sBAAsB,CAC7B,QAAkB,EAClB,IAAY;IAEZ,OAAO,QAAQ,CAAC,OAAO,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE;QACjD,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,IAAA,gDAAgC,EAAC,IAAI,CAAC,CAAC;YACrD,OAAO,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QACnC,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,MAAM,CAAC,KAAK,CACV,+CAA+C,IAAI,CAAC,IAAI,KAAK,CAAC,EAAE,CACjE,CAAC;YACF,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC;AAED,+CAA+C;AAC/C,SAAS,aAAa,CAAC,KAAkC;IACvD,IAAI,CAAC;QACH,OAAO,MAAM,CAAC,IAAI,CAAC,cAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;IACzC,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,OAAO,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;IACtC,CAAC;AACH,CAAC;AAED,SAAS,UAAU,CACjB,GAAQ,EACR,IAAiC,EACjC,gBAGkD;IAElD,MAAM,IAAI,GAAG,IAAA,wBAAQ,EAAC,GAAG,CAAC,CAAC,OAAO,EAAE,CAAC;IAErC,MAAM,MAAM,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC;IAEnC,MAAM,IAAI,GAAG,gBAAgB,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IAC5C,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,MAAM,CAAC,IAAI,CACT,oDAAoD,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CACxE,CAAC;QACF,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,CAAC;QACH,iDAAiD;QACjD,MAAM,KAAK,GAAG,IAAA,6BAAY,EAAC,CAAC,IAAI,EAAE,IAAI,CAAC,OAAO,EAAE,IAAW,CAAC,CAAC,CAAC;QAE9D,0BAA0B;QAC1B,MAAM,EAAE,aAAa,EAAE,GAAG,OAAO,EAAE,GAAG,KAAK,CAAC,MAAM,CAAC,MAAM,CAAQ,CAAC;QAElE,OAAO;YACL,IAAI,EAAE,OAAO;YACb,IAAI,EAAE,IAAI,CAAC,IAAI;SAChB,CAAC;IACJ,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,MAAM,CAAC,IAAI,CAAC,+BAA+B,IAAI,CAAC,IAAI,YAAY,CAAC,EAAE,CAAC,CAAC;QACrE,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,SAAgB,iBAAiB,CAC/B,GAAQ,EACR,IAAwB;IAExB,OAAO,UAAU,CAAC,GAAG,EAAE,IAAI,EAAE,sBAAsB,CAAC,CAAC;AACvD,CAAC;AAED,uEAAuE;AACvE,SAAgB,SAAS,CAAC,GAAQ,EAAE,OAAe;IACjD,sCAAsC;IACtC,IAAI,CAAC,IAAA,8BAAc,EAAC,GAAG,CAAC,EAAE,CAAC;QACzB,MAAM,IAAI,KAAK,CAAC,uDAAuD,CAAC,CAAC;IAC3E,CAAC;IAED,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,gBAAgB,EAAE,EAAE,CAAQ,CAAC;IAC7D,MAAM,SAAS,GAAG,aAAa,CAAC,OAAO,CAAC,CAAC;IAEzC,+DAA+D;IAC/D,MAAM,KAAK,GAAG,GAAG,CAAC,MAAM,EAAE,IAAI,CAC5B,CAAC,CAAC,EAAE,EAAE,CAAC,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,KAAK,CAAC,CAC7D,CAAC;IAEF,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,IAAI,KAAK,CAAC,mCAAmC,CAAC,CAAC;IACvD,CAAC;IAED,wFAAwF;IACxF,MAAM,KAAK,GAAG,SAAS;SACpB,QAAQ,CAAC,KAAK,CAAC,aAAa,CAAC,MAAM,CAAC;SACpC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAEtB,OAAO,UAAU,CAAC,GAAG,EAAE,KAAY,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE;QAClD,OAAO,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,IAAI,CACnC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,KAAK,CAAC,IAAI,IAAI,CAAC,CAAC,IAAI,KAAK,IAAA,kBAAS,EAAC,KAAK,CAAC,IAAI,CAAC,CACjE,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAa,aAAa;IACxB,IAAI,GAA+B,EAAE,CAAC;IAEtC,KAAK,CAAC,QAAQ,CAAC,EAAmB;QAChC,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC;YACf,OAAO;QACT,CAAC;QAED,KAAK,MAAM,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,MAAM,CAAC,OAAO,EAAE,EAAE,CAAC;YACnD,IAAI,CAAC;gBACH,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;oBACpB,SAAS;gBACX,CAAC;gBACD,MAAM,GAAG,GAAG,MAAM,iBAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC;gBACnE,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;gBAClC,MAAM,CAAC,IAAI,CAAC,kBAAkB,IAAI,EAAE,CAAC,CAAC;YACxC,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACX,MAAM,IAAI,KAAK,CAAC,iCAAiC,IAAI,IAAI,IAAI,EAAE,CAAC,CAAC;YACnE,CAAC;QACH,CAAC;IACH,CAAC;IAED,4DAA4D;IAC5D,KAAK,CAAC,eAAe,CAAC,SAAiB;QACrC,MAAM,IAAI,KAAK,CAAC,kCAAkC,CAAC,CAAC;QACpD,+DAA+D;QAC/D,iCAAiC;QACjC,MAAM;QAEN,+BAA+B;IACjC,CAAC;IAGD,kBAAkB,CAAC,KAAa,EAAE,SAAiB;QACjD,IAAI,IAAA,aAAK,EAAC,KAAK,CAAC,EAAE,CAAC;YACjB,OAAO,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC;QACrD,CAAC;QAED,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACjC,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,MAAM,IAAI,KAAK,CAAC,kCAAkC,SAAS,EAAE,CAAC,CAAC;QACjE,CAAC;QAED,MAAM,IAAI,GAAG,IAAA,wBAAQ,EAAC,GAAG,CAAC,CAAC,OAAO,EAAE,CAAC;QAErC,MAAM,aAAa,GAAG,IAAA,kDAAkC,EAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QACtE,IAAI,CAAC,aAAa,EAAE,CAAC;YACnB,OAAO,MAAM,CAAC,IAAI,CAAC,cAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;QACzC,CAAC;QAED,OAAO,aAAa,CAAC;IACvB,CAAC;IAED,KAAK,CAAC,iBAAiB,CACrB,WAA8B;QAE9B,IAAI,CAAC;YACH,MAAM,SAAS,GAAG,IAAA,2BAAY,EAAC,WAAW,CAAC,CAAC;YAE5C,MAAM,GAAG,GACP,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,eAAe,CAAC,SAAS,CAAC,CAAC,CAAC;YAElE,IAAI,CAAC,GAAG,EAAE,CAAC;gBACT,OAAO,IAAI,CAAC;YACd,CAAC;YAED,OAAO,iBAAiB,CAAC,GAAG,EAAE,WAAW,CAAC,IAAI,CAAC,CAAC;QAClD,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,MAAM,CAAC,KAAK,CAAC,iCAAiC,CAAC,EAAE,CAAC,CAAC;QACrD,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC;IAED,KAAK,CAAC,SAAS,CAAC,GAAqB;QACnC,IAAI,CAAC;YACH,MAAM,SAAS,GAAG,GAAG,CAAC,SAAS,CAAC;YAEhC,MAAM,GAAG,GACP,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,eAAe,CAAC,SAAS,CAAC,CAAC,CAAC;YAElE,IAAI,CAAC,GAAG,EAAE,CAAC;gBACT,OAAO,IAAI,CAAC;YACd,CAAC;YAED,OAAO,SAAS,CAAC,GAAG,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;QACrC,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,MAAM,CAAC,KAAK,CAAC,yBAAyB,CAAC,EAAE,CAAC,CAAC;QAC7C,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;CACF;AA3FD,sCA2FC;AA1DC;IADC,IAAA,oBAAO,GAAE;;;oCAC4C,MAAM;uDAkB3D","sourcesContent":["// Copyright 2020-2025 SubQuery Pte Ltd authors & contributors\n// SPDX-License-Identifier: GPL-3.0\n\nimport fs from 'node:fs';\nimport { getNodeCodec } from '@codama/dynamic-codecs';\nimport { Base58EncodedBytes } from '@solana/kit';\nimport {\n parseIdl,\n Idl,\n isAnchorIdlV01,\n getInstructionDiscriminatorBytes,\n findInstructionDiscriminatorByName,\n} from '@subql/common-solana';\nimport { getLogger } from '@subql/node-core';\nimport {\n DecodedData,\n SolanaInstruction,\n SolanaLogMessage,\n SubqlDatasource,\n} from '@subql/types-solana';\nimport { isHex } from '@subql/utils';\nimport bs58 from 'bs58';\nimport { camelCase, DefinedTypeNode, InstructionNode, RootNode } from 'codama';\nimport { Memoize } from '../utils/decorators';\nimport { getProgramId } from './utils.solana';\n\nconst logger = getLogger('SolanaDecoder');\n\nfunction findInstructionForData(\n rootNode: RootNode,\n data: Buffer,\n): InstructionNode | undefined {\n return rootNode.program.instructions.find((inst) => {\n try {\n const bytes = getInstructionDiscriminatorBytes(inst);\n return data.indexOf(bytes) === 0;\n } catch (e) {\n logger.debug(\n `Failed to get discriminator for instruction ${inst.name}: ${e}`,\n );\n return false;\n }\n });\n}\n\n// Converts a base58 or base64 string to Buffer\nfunction basedToBuffer(input: string | Base58EncodedBytes): Buffer {\n try {\n return Buffer.from(bs58.decode(input));\n } catch (e) {\n return Buffer.from(input, 'base64');\n }\n}\n\nfunction decodeData(\n idl: Idl,\n data: Base58EncodedBytes | string,\n getEncodableNode: (\n rootNode: RootNode,\n data: Buffer,\n ) => InstructionNode | DefinedTypeNode | undefined,\n): DecodedData | null {\n const root = parseIdl(idl).getRoot();\n\n const buffer = basedToBuffer(data);\n\n const node = getEncodableNode(root, buffer);\n if (!node) {\n logger.warn(\n `Failed to find instruction with discriminator in ${root.program.name}`,\n );\n return null;\n }\n\n try {\n // Path is required to find other defined structs\n const codec = getNodeCodec([root, root.program, node as any]);\n\n // Strip the discriminator\n const { discriminator, ...decoded } = codec.decode(buffer) as any;\n\n return {\n data: decoded,\n name: node.name,\n };\n } catch (e) {\n logger.warn(`Failed to decode data name: ${node.name}, error: ${e}`);\n return null;\n }\n}\n\nexport function decodeInstruction(\n idl: Idl,\n data: Base58EncodedBytes,\n): DecodedData | null {\n return decodeData(idl, data, findInstructionForData);\n}\n\n// Codama doesn't support Logs so extra work is required to decode logs\nexport function decodeLog(idl: Idl, message: string): DecodedData | null {\n // Older versions don't support events\n if (!isAnchorIdlV01(idl)) {\n throw new Error('Only Anchor IDL v0.1.0 is supported for decoding logs');\n }\n\n const msgData = message.replace('Program data: ', '') as any;\n const msgBuffer = basedToBuffer(msgData);\n\n // Codama doesn't include events so we have to find it manually\n const event = idl.events?.find(\n (e) => msgBuffer.indexOf(Buffer.from(e.discriminator)) === 0,\n );\n\n if (!event) {\n throw new Error('Unable to find event for log data');\n }\n\n // Input needs to be without the discriminator because we're just going to decode a type\n const input = msgBuffer\n .subarray(event.discriminator.length)\n .toString('base64');\n\n return decodeData(idl, input as any, (root, data) => {\n return root.program.definedTypes.find(\n (t) => t.name === event.name || t.name === camelCase(event.name),\n );\n });\n}\n\nexport class SolanaDecoder {\n idls: Record<string, Idl | null> = {};\n\n async loadIdls(ds: SubqlDatasource): Promise<void> {\n if (!ds.assets) {\n return;\n }\n\n for (const [name, { file }] of ds.assets.entries()) {\n try {\n if (this.idls[name]) {\n continue;\n }\n const raw = await fs.promises.readFile(file, { encoding: 'utf8' });\n this.idls[name] = JSON.parse(raw);\n logger.info(`Loaded IDL for ${name}`);\n } catch (e) {\n throw new Error(`Failed to load datasource IDL ${name}:${file}`);\n }\n }\n }\n\n // eslint-disable-next-line @typescript-eslint/require-await\n async getIdlFromChain(programId: string): Promise<Idl | null> {\n throw new Error('Not implemented: getIdlFromChain');\n // this.idls[programId] ??= await Program.fetchIdl(programId, {\n // connection: this.api as any,\n // });\n\n // return this.idls[programId];\n }\n\n @Memoize()\n parseDiscriminator(input: string, programId: string): Buffer {\n if (isHex(input)) {\n return Buffer.from(input.replace('0x', ''), 'hex');\n }\n\n const idl = this.idls[programId];\n if (!idl) {\n throw new Error(`Unable to find IDL for program ${programId}`);\n }\n\n const root = parseIdl(idl).getRoot();\n\n const discriminator = findInstructionDiscriminatorByName(root, input);\n if (!discriminator) {\n return Buffer.from(bs58.decode(input));\n }\n\n return discriminator;\n }\n\n async decodeInstruction(\n instruction: SolanaInstruction,\n ): Promise<DecodedData | null> {\n try {\n const programId = getProgramId(instruction);\n\n const idl =\n this.idls[programId] ?? (await this.getIdlFromChain(programId));\n\n if (!idl) {\n return null;\n }\n\n return decodeInstruction(idl, instruction.data);\n } catch (e) {\n logger.debug(`Failed to decode instruction: ${e}`);\n }\n\n return null;\n }\n\n async decodeLog(log: SolanaLogMessage): Promise<DecodedData | null> {\n try {\n const programId = log.programId;\n\n const idl =\n this.idls[programId] ?? (await this.getIdlFromChain(programId));\n\n if (!idl) {\n return null;\n }\n\n return decodeLog(idl, log.message);\n } catch (e) {\n logger.debug(`Failed to decode log: ${e}`);\n }\n return null;\n }\n}\n"]}
1
+ {"version":3,"file":"decoder.js","sourceRoot":"","sources":["../../src/solana/decoder.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 fs from 'node:fs';\nimport { getNodeCodec } from '@codama/dynamic-codecs';\nimport { Base58EncodedBytes, TransactionForFullJson } from '@solana/kit';\nimport {\n parseIdl,\n Idl,\n isAnchorIdlV01,\n getInstructionDiscriminatorBytes,\n findInstructionDiscriminatorByName,\n} from '@subql/common-solana';\nimport { getLogger } from '@subql/node-core';\nimport {\n DecodedData,\n Decoder,\n SolanaInstruction,\n SolanaLogMessage,\n SubqlDatasource,\n} from '@subql/types-solana';\nimport { isHex } from '@subql/utils';\nimport bs58 from 'bs58';\nimport { camelCase, DefinedTypeNode, InstructionNode, RootNode } from 'codama';\nimport { Memoize } from '../utils/decorators';\nimport { allAccounts, getProgramId } from './utils.solana';\n\nconst logger = getLogger('SolanaDecoder');\n\nfunction findInstructionForData(\n rootNode: RootNode,\n data: Buffer,\n): InstructionNode | undefined {\n return rootNode.program.instructions.find((inst) => {\n try {\n const bytes = getInstructionDiscriminatorBytes(inst);\n return data.indexOf(bytes) === 0;\n } catch (e) {\n logger.debug(\n `Failed to get discriminator for instruction ${inst.name}: ${e}`,\n );\n return false;\n }\n });\n}\n\n// Converts a base58 or base64 string to Buffer\nfunction basedToBuffer(input: string | Base58EncodedBytes): Buffer {\n try {\n return Buffer.from(bs58.decode(input));\n } catch (e) {\n return Buffer.from(input, 'base64');\n }\n}\n\nfunction decodeData(\n idl: Idl,\n data: Base58EncodedBytes | string,\n getEncodableNode: (\n rootNode: RootNode,\n data: Buffer,\n ) => InstructionNode | DefinedTypeNode | undefined,\n): DecodedData | null {\n const root = parseIdl(idl).getRoot();\n\n const buffer = basedToBuffer(data);\n\n const node = getEncodableNode(root, buffer);\n if (!node) {\n logger.warn(\n `Failed to find instruction with discriminator in ${root.program.name}`,\n );\n return null;\n }\n\n try {\n // Path is required to find other defined structs\n const codec = getNodeCodec([root, root.program, node as any]);\n\n // Strip the discriminator\n const { discriminator, ...decoded } = codec.decode(buffer) as any;\n\n return {\n data: decoded,\n name: node.name,\n };\n } catch (e) {\n logger.warn(`Failed to decode data name: ${node.name}, error: ${e}`);\n return null;\n }\n}\n\nexport function decodeInstruction(\n idl: Idl,\n data: Base58EncodedBytes,\n): DecodedData | null {\n return decodeData(idl, data, findInstructionForData);\n}\n\n// Codama doesn't support Logs so extra work is required to decode logs\nexport function decodeLog(idl: Idl, message: string): DecodedData | null {\n // Older versions don't support events\n if (!isAnchorIdlV01(idl)) {\n throw new Error('Only Anchor IDL v0.1.0 is supported for decoding logs');\n }\n\n const msgData = message.replace('Program data: ', '') as any;\n const msgBuffer = basedToBuffer(msgData);\n\n // Codama doesn't include events so we have to find it manually\n const event = idl.events?.find(\n (e) => msgBuffer.indexOf(Buffer.from(e.discriminator)) === 0,\n );\n\n if (!event) {\n throw new Error('Unable to find event for log data');\n }\n\n // Input needs to be without the discriminator because we're just going to decode a type\n const input = msgBuffer\n .subarray(event.discriminator.length)\n .toString('base64');\n\n return decodeData(idl, input as any, (root, data) => {\n return root.program.definedTypes.find(\n (t) => t.name === event.name || t.name === camelCase(event.name),\n );\n });\n}\n\nexport class SolanaDecoder {\n idls: Record<string, Idl | null> = {};\n\n async loadIdls(ds: SubqlDatasource): Promise<void> {\n if (!ds.assets) {\n return;\n }\n\n for (const [name, { file }] of ds.assets.entries()) {\n try {\n if (this.idls[name]) {\n continue;\n }\n const raw = await fs.promises.readFile(file, { encoding: 'utf8' });\n this.idls[name] = JSON.parse(raw);\n logger.info(`Loaded IDL for ${name}`);\n } catch (e) {\n throw new Error(`Failed to load datasource IDL ${name}:${file}`);\n }\n }\n }\n\n // eslint-disable-next-line @typescript-eslint/require-await\n async getIdlFromChain(programId: string): Promise<Idl | null> {\n throw new Error('Not implemented: getIdlFromChain');\n // this.idls[programId] ??= await Program.fetchIdl(programId, {\n // connection: this.api as any,\n // });\n\n // return this.idls[programId];\n }\n\n @Memoize()\n parseDiscriminator(input: string, programId: string): Buffer {\n if (isHex(input)) {\n return Buffer.from(input.replace('0x', ''), 'hex');\n }\n\n const idl = this.idls[programId];\n if (!idl) {\n throw new Error(`Unable to find IDL for program ${programId}`);\n }\n\n const root = parseIdl(idl).getRoot();\n\n const discriminator = findInstructionDiscriminatorByName(root, input);\n if (!discriminator) {\n return Buffer.from(bs58.decode(input));\n }\n\n return discriminator;\n }\n\n async decodeInstructionRaw(\n instruction: TransactionForFullJson<0>['transaction']['message']['instructions'][number],\n transaction: TransactionForFullJson<0>,\n ): Promise<DecodedData | null> {\n try {\n const programId = allAccounts(transaction)[instruction.programIdIndex];\n\n const idl =\n this.idls[programId] ?? (await this.getIdlFromChain(programId));\n\n if (!idl) {\n return null;\n }\n\n return decodeInstruction(idl, instruction.data);\n } catch (e) {\n logger.debug(`Failed to decode instruction: ${e}`);\n }\n\n return null;\n }\n\n async decodeInstruction(\n instruction: SolanaInstruction,\n ): Promise<DecodedData | null> {\n return this.decodeInstructionRaw(instruction, instruction.transaction);\n }\n\n async decodeLog(log: SolanaLogMessage): Promise<DecodedData | null> {\n try {\n const programId = log.programId;\n\n const idl =\n this.idls[programId] ?? (await this.getIdlFromChain(programId));\n\n if (!idl) {\n return null;\n }\n\n return decodeLog(idl, log.message);\n } catch (e) {\n logger.debug(`Failed to decode log: ${e}`);\n }\n return null;\n }\n}\n"]}
@@ -1,6 +1,7 @@
1
- import { TransactionForFullJson } from '@solana/kit';
1
+ import { Address, TransactionForFullJson } from '@solana/kit';
2
2
  import { SolanaLogMessage, SolanaBlock, SolanaBlockFilter, SolanaInstruction, SolanaInstructionFilter, SolanaLogFilter, SolanaTransaction, SolanaTransactionFilter } from '@subql/types-solana';
3
3
  import { SolanaDecoder } from './decoder';
4
+ export declare function allAccounts(transaction: SolanaTransaction | TransactionForFullJson<0>): Address[];
4
5
  export declare function getAccountByIndex(instruction: SolanaInstruction, index: number): string;
5
6
  export declare function getProgramId(instruction: SolanaInstruction): string;
6
7
  export declare function filterBlocksProcessor(block: SolanaBlock, filter: SolanaBlockFilter): boolean;
@@ -5,6 +5,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  return (mod && mod.__esModule) ? mod : { "default": mod };
6
6
  };
7
7
  Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.allAccounts = allAccounts;
8
9
  exports.getAccountByIndex = getAccountByIndex;
9
10
  exports.getProgramId = getProgramId;
10
11
  exports.filterBlocksProcessor = filterBlocksProcessor;
@@ -1 +1 @@
1
- {"version":3,"file":"utils.solana.js","sourceRoot":"","sources":["../../src/solana/utils.solana.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 { TransactionForFullJson } from '@solana/kit';\nimport { filterBlockTimestamp } from '@subql/node-core';\nimport {\n SolanaLogMessage,\n SolanaBlock,\n SolanaBlockFilter,\n SolanaInstruction,\n SolanaInstructionFilter,\n SolanaLogFilter,\n SolanaTransaction,\n SolanaTransactionFilter,\n} from '@subql/types-solana';\nimport bs58 from 'bs58';\nimport { SubqlProjectBlockFilter } from '../configure/SubqueryProject';\nimport { SolanaDecoder } from './decoder';\n\nfunction allAccounts(\n transaction: SolanaTransaction | TransactionForFullJson<0>,\n) {\n return [\n ...transaction.transaction.message.accountKeys,\n ...(transaction.meta?.loadedAddresses.writable ?? []),\n ...(transaction.meta?.loadedAddresses.readonly ?? []),\n ];\n}\n\nexport function getAccountByIndex(\n instruction: SolanaInstruction,\n index: number,\n): string {\n return allAccounts(instruction.transaction)[index];\n}\n\nexport function getProgramId(instruction: SolanaInstruction): string {\n return getAccountByIndex(instruction, instruction.programIdIndex);\n}\n\nexport function filterBlocksProcessor(\n block: SolanaBlock,\n filter: SolanaBlockFilter,\n): boolean {\n if (filter?.modulo && Number(block.blockHeight) % filter.modulo !== 0) {\n return false;\n }\n // Multiply to add MS\n if (\n !filterBlockTimestamp(\n Number(block.blockTime) * 1000,\n filter as SubqlProjectBlockFilter,\n )\n ) {\n return false;\n }\n return true;\n}\n\nexport function filterTransactionsProcessor(\n transaction: SolanaTransaction | TransactionForFullJson<0>,\n filter?: SolanaTransactionFilter,\n): boolean {\n if (!filter) return true;\n\n if (filter.signerAccountKey) {\n // The signature at index i corresponds to the public key at index i in message.accountKeys\n const sigAccounts = transaction.transaction.signatures.map(\n (sig, idx) => transaction.transaction.message.accountKeys[idx],\n );\n if (!sigAccounts.some((account) => account === filter.signerAccountKey)) {\n return false;\n }\n }\n\n return true;\n}\n\nexport function filterInstructionsProcessor(\n instruction: SolanaInstruction,\n decoder: SolanaDecoder,\n filter?: SolanaInstructionFilter,\n): boolean {\n if (!filter) return true;\n\n if (!filter.includeFailed) {\n if (instruction.transaction.meta?.err) {\n return false;\n }\n }\n\n const programId = getProgramId(instruction);\n if (filter.programId) {\n if (filter.programId !== programId) {\n return false;\n }\n }\n\n if (filter.accounts) {\n const accounts = instruction.transaction.transaction.message.accountKeys;\n for (let i = 0; i < filter.accounts.length; i++) {\n const filterAccounts = filter.accounts[i];\n if (!filterAccounts) {\n continue;\n }\n const instructionAccountIndex = instruction.accounts[i];\n if (!filterAccounts.includes(accounts[instructionAccountIndex])) {\n return false;\n }\n }\n }\n\n if (filter.discriminator) {\n const discriminator = decoder.parseDiscriminator(\n filter.discriminator,\n programId,\n );\n\n const data = Buffer.from(bs58.decode(instruction.data));\n\n if (data.indexOf(discriminator) !== 0) {\n return false;\n }\n }\n\n return true;\n}\n\nexport function filterLogsProcessor(\n log: SolanaLogMessage,\n // idls?: Map<string, Idl>,\n filter?: SolanaLogFilter,\n): boolean {\n if (!filter) return true;\n\n if (filter.programId && filter.programId !== log.programId) {\n return false;\n }\n\n // if (filter.name) {\n // const disc = getAnchorDiscriminator(filter.name, 'event');\n // const disc58 = bs58.encode(disc)\n // if (!instruction.data.startsWith(disc58)) {\n // return false;\n // }\n // }\n\n // TODO parse log data\n\n return true;\n}\n"]}
1
+ {"version":3,"file":"utils.solana.js","sourceRoot":"","sources":["../../src/solana/utils.solana.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 { Address, TransactionForFullJson } from '@solana/kit';\nimport { filterBlockTimestamp } from '@subql/node-core';\nimport {\n SolanaLogMessage,\n SolanaBlock,\n SolanaBlockFilter,\n SolanaInstruction,\n SolanaInstructionFilter,\n SolanaLogFilter,\n SolanaTransaction,\n SolanaTransactionFilter,\n} from '@subql/types-solana';\nimport bs58 from 'bs58';\nimport { SubqlProjectBlockFilter } from '../configure/SubqueryProject';\nimport { SolanaDecoder } from './decoder';\n\nexport function allAccounts(\n transaction: SolanaTransaction | TransactionForFullJson<0>,\n): Address[] {\n return [\n ...transaction.transaction.message.accountKeys,\n ...(transaction.meta?.loadedAddresses.writable ?? []),\n ...(transaction.meta?.loadedAddresses.readonly ?? []),\n ];\n}\n\nexport function getAccountByIndex(\n instruction: SolanaInstruction,\n index: number,\n): string {\n return allAccounts(instruction.transaction)[index];\n}\n\nexport function getProgramId(instruction: SolanaInstruction): string {\n return getAccountByIndex(instruction, instruction.programIdIndex);\n}\n\nexport function filterBlocksProcessor(\n block: SolanaBlock,\n filter: SolanaBlockFilter,\n): boolean {\n if (filter?.modulo && Number(block.blockHeight) % filter.modulo !== 0) {\n return false;\n }\n // Multiply to add MS\n if (\n !filterBlockTimestamp(\n Number(block.blockTime) * 1000,\n filter as SubqlProjectBlockFilter,\n )\n ) {\n return false;\n }\n return true;\n}\n\nexport function filterTransactionsProcessor(\n transaction: SolanaTransaction | TransactionForFullJson<0>,\n filter?: SolanaTransactionFilter,\n): boolean {\n if (!filter) return true;\n\n if (filter.signerAccountKey) {\n // The signature at index i corresponds to the public key at index i in message.accountKeys\n const sigAccounts = transaction.transaction.signatures.map(\n (sig, idx) => transaction.transaction.message.accountKeys[idx],\n );\n if (!sigAccounts.some((account) => account === filter.signerAccountKey)) {\n return false;\n }\n }\n\n return true;\n}\n\nexport function filterInstructionsProcessor(\n instruction: SolanaInstruction,\n decoder: SolanaDecoder,\n filter?: SolanaInstructionFilter,\n): boolean {\n if (!filter) return true;\n\n if (!filter.includeFailed) {\n if (instruction.transaction.meta?.err) {\n return false;\n }\n }\n\n const programId = getProgramId(instruction);\n if (filter.programId) {\n if (filter.programId !== programId) {\n return false;\n }\n }\n\n if (filter.accounts) {\n const accounts = instruction.transaction.transaction.message.accountKeys;\n for (let i = 0; i < filter.accounts.length; i++) {\n const filterAccounts = filter.accounts[i];\n if (!filterAccounts) {\n continue;\n }\n const instructionAccountIndex = instruction.accounts[i];\n if (!filterAccounts.includes(accounts[instructionAccountIndex])) {\n return false;\n }\n }\n }\n\n if (filter.discriminator) {\n const discriminator = decoder.parseDiscriminator(\n filter.discriminator,\n programId,\n );\n\n const data = Buffer.from(bs58.decode(instruction.data));\n\n if (data.indexOf(discriminator) !== 0) {\n return false;\n }\n }\n\n return true;\n}\n\nexport function filterLogsProcessor(\n log: SolanaLogMessage,\n // idls?: Map<string, Idl>,\n filter?: SolanaLogFilter,\n): boolean {\n if (!filter) return true;\n\n if (filter.programId && filter.programId !== log.programId) {\n return false;\n }\n\n // if (filter.name) {\n // const disc = getAnchorDiscriminator(filter.name, 'event');\n // const disc58 = bs58.encode(disc)\n // if (!instruction.data.startsWith(disc58)) {\n // return false;\n // }\n // }\n\n // TODO parse log data\n\n return true;\n}\n"]}
@@ -54,6 +54,7 @@ exports.TestingFeatureModule = TestingFeatureModule = __decorate([
54
54
  },
55
55
  node_core_1.DsProcessorService,
56
56
  node_core_1.DynamicDsService,
57
+ node_core_1.MultiChainRewindService,
57
58
  ],
58
59
  controllers: [],
59
60
  exports: [node_core_1.TestRunner],