@subql/node-solana 6.1.0 → 6.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -1
- package/dist/.tsbuildinfo +1 -1
- package/dist/solana/decoder.js +4 -2
- package/dist/solana/decoder.js.map +1 -1
- package/package.json +2 -2
package/dist/solana/decoder.js
CHANGED
|
@@ -143,12 +143,13 @@ class SolanaDecoder {
|
|
|
143
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
|
+
logger.warn(`Unable to decode instruction for program: ${programId}. No IDL.`);
|
|
146
147
|
return null;
|
|
147
148
|
}
|
|
148
149
|
return decodeInstruction(idl, instruction.data);
|
|
149
150
|
}
|
|
150
151
|
catch (e) {
|
|
151
|
-
logger.
|
|
152
|
+
logger.warn(`Failed to decode instruction: ${e}`);
|
|
152
153
|
}
|
|
153
154
|
return null;
|
|
154
155
|
}
|
|
@@ -160,12 +161,13 @@ class SolanaDecoder {
|
|
|
160
161
|
const programId = log.programId;
|
|
161
162
|
const idl = this.idls[programId] ?? (await this.getIdlFromChain(programId));
|
|
162
163
|
if (!idl) {
|
|
164
|
+
logger.warn(`Unable to decode log for program: ${programId}. No IDL.`);
|
|
163
165
|
return null;
|
|
164
166
|
}
|
|
165
167
|
return decodeLog(idl, log.message);
|
|
166
168
|
}
|
|
167
169
|
catch (e) {
|
|
168
|
-
logger.
|
|
170
|
+
logger.warn(`Failed to decode log: ${e}`);
|
|
169
171
|
}
|
|
170
172
|
return null;
|
|
171
173
|
}
|
|
@@ -1 +1 @@
|
|
|
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
|
+
{"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 logger.warn(\n `Unable to decode instruction for program: ${programId}. No IDL.`,\n );\n return null;\n }\n\n return decodeInstruction(idl, instruction.data);\n } catch (e) {\n logger.warn(`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 logger.warn(`Unable to decode log for program: ${programId}. No IDL.`);\n return null;\n }\n\n return decodeLog(idl, log.message);\n } catch (e) {\n logger.warn(`Failed to decode log: ${e}`);\n }\n return null;\n }\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@subql/node-solana",
|
|
3
|
-
"version": "6.1.
|
|
3
|
+
"version": "6.1.1",
|
|
4
4
|
"description": "",
|
|
5
5
|
"author": "Ian He",
|
|
6
6
|
"license": "GPL-3.0",
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
"@nestjs/platform-express": "^11.0.8",
|
|
27
27
|
"@nestjs/schedule": "^5.0.1",
|
|
28
28
|
"@solana/kit": "^3.0.2",
|
|
29
|
-
"@subql/common-solana": "1.1.
|
|
29
|
+
"@subql/common-solana": "1.1.1",
|
|
30
30
|
"@subql/node-core": "^18.3.3",
|
|
31
31
|
"@subql/testing": "^2.2.1",
|
|
32
32
|
"@subql/types-solana": "1.1.0",
|