@subql/common-solana 0.0.0-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 +7 -0
- package/LICENSE +674 -0
- package/dist/.tsbuildinfo +1 -0
- package/dist/codegen/codegen.d.ts +4 -0
- package/dist/codegen/codegen.js +68 -0
- package/dist/codegen/codegen.js.map +1 -0
- package/dist/codegen/codegen.spec.d.ts +1 -0
- package/dist/codegen/codegen.spec.js +130 -0
- package/dist/codegen/codegen.spec.js.map +1 -0
- package/dist/codegen/idl.d.ts +11 -0
- package/dist/codegen/idl.js +88 -0
- package/dist/codegen/idl.js.map +1 -0
- package/dist/codegen/index.d.ts +2 -0
- package/dist/codegen/index.js +21 -0
- package/dist/codegen/index.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +51 -0
- package/dist/index.js.map +1 -0
- package/dist/project/index.d.ts +7 -0
- package/dist/project/index.js +27 -0
- package/dist/project/index.js.map +1 -0
- package/dist/project/load.d.ts +2 -0
- package/dist/project/load.js +12 -0
- package/dist/project/load.js.map +1 -0
- package/dist/project/models.d.ts +81 -0
- package/dist/project/models.js +270 -0
- package/dist/project/models.js.map +1 -0
- package/dist/project/project.spec.d.ts +1 -0
- package/dist/project/project.spec.js +109 -0
- package/dist/project/project.spec.js.map +1 -0
- package/dist/project/types.d.ts +4 -0
- package/dist/project/types.js +5 -0
- package/dist/project/types.js.map +1 -0
- package/dist/project/utils.d.ts +9 -0
- package/dist/project/utils.js +30 -0
- package/dist/project/utils.js.map +1 -0
- package/dist/project/versioned/ProjectManifestVersioned.d.ts +26 -0
- package/dist/project/versioned/ProjectManifestVersioned.js +56 -0
- package/dist/project/versioned/ProjectManifestVersioned.js.map +1 -0
- package/dist/project/versioned/index.d.ts +2 -0
- package/dist/project/versioned/index.js +21 -0
- package/dist/project/versioned/index.js.map +1 -0
- package/dist/project/versioned/v1_0_0/index.d.ts +1 -0
- package/dist/project/versioned/v1_0_0/index.js +20 -0
- package/dist/project/versioned/v1_0_0/index.js.map +1 -0
- package/dist/project/versioned/v1_0_0/model.d.ts +52 -0
- package/dist/project/versioned/v1_0_0/model.js +236 -0
- package/dist/project/versioned/v1_0_0/model.js.map +1 -0
- package/package.json +40 -0
- package/src/codegen/codegen.spec.ts +145 -0
- package/src/codegen/codegen.ts +90 -0
- package/src/codegen/idl.ts +89 -0
- package/src/codegen/index.ts +5 -0
- package/src/index.ts +16 -0
- package/src/project/index.ts +11 -0
- package/src/project/load.ts +10 -0
- package/src/project/models.ts +213 -0
- package/src/project/project.spec.ts +123 -0
- package/src/project/types.ts +19 -0
- package/src/project/utils.ts +50 -0
- package/src/project/versioned/ProjectManifestVersioned.ts +71 -0
- package/src/project/versioned/index.ts +5 -0
- package/src/project/versioned/v1_0_0/index.ts +4 -0
- package/src/project/versioned/v1_0_0/model.ts +200 -0
- package/templates/idl.ts.ejs +10 -0
- package/test/abiTest/project.yaml +51 -0
- package/test/project_1.0.0.yaml +91 -0
- package/tsconfig.json +12 -0
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { SubqlDatasource, SubqlRuntimeDatasource } from '@subql/types-solana';
|
|
2
|
+
import { Data } from 'ejs';
|
|
3
|
+
export declare function validateDiscriminators(dataSources: SubqlRuntimeDatasource[], projectPath: string): Promise<void>;
|
|
4
|
+
export declare function generateIDLInterfaces(dataSources: SubqlDatasource[], projectPath: string, renderTemplate: (templatePath: string, outputPath: string, templateData: Data) => Promise<void>): Promise<void>;
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Copyright 2020-2025 SubQuery Pte Ltd authors & contributors
|
|
3
|
+
// SPDX-License-Identifier: GPL-3.0
|
|
4
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
5
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
6
|
+
};
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.validateDiscriminators = validateDiscriminators;
|
|
9
|
+
exports.generateIDLInterfaces = generateIDLInterfaces;
|
|
10
|
+
const node_assert_1 = __importDefault(require("node:assert"));
|
|
11
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
12
|
+
const renderers_js_1 = require("@codama/renderers-js");
|
|
13
|
+
const types_solana_1 = require("@subql/types-solana");
|
|
14
|
+
const codama_1 = require("codama");
|
|
15
|
+
const idl_1 = require("./idl");
|
|
16
|
+
const INSTRUCTION_TEMPLATE_TS = node_path_1.default.resolve(__dirname, '../../templates/idl.ts.ejs');
|
|
17
|
+
const CODAMA_PATH = '/src/types/program-interfaces';
|
|
18
|
+
const IDL_PATH = '/src/types/handler-inputs';
|
|
19
|
+
async function validateDiscriminators(dataSources, projectPath) {
|
|
20
|
+
const issues = [];
|
|
21
|
+
for (const ds of dataSources) {
|
|
22
|
+
for (const handler of ds.mapping.handlers) {
|
|
23
|
+
if (!handler.filter) {
|
|
24
|
+
break;
|
|
25
|
+
}
|
|
26
|
+
switch (handler.kind) {
|
|
27
|
+
case types_solana_1.SolanaHandlerKind.Instruction: {
|
|
28
|
+
if (handler.filter.discriminator && handler.filter.programId) {
|
|
29
|
+
const fileRef = ds.assets?.get(handler.filter.programId);
|
|
30
|
+
if (!fileRef) {
|
|
31
|
+
issues.push(`Datasource has a handler with a discriminator but no IDL file reference`);
|
|
32
|
+
continue;
|
|
33
|
+
}
|
|
34
|
+
const idlPath = node_path_1.default.join(projectPath, fileRef.file);
|
|
35
|
+
const idl = await (0, idl_1.parseIdlFromFile)(idlPath);
|
|
36
|
+
if (!(0, idl_1.findInstructionDiscriminatorByName)(idl.getRoot(), handler.filter.discriminator)) {
|
|
37
|
+
issues.push(`Datasource has a handler with a discriminator ${handler.filter.discriminator} but no matching instruction found in IDL`);
|
|
38
|
+
}
|
|
39
|
+
// TODO check discriminator in IDL
|
|
40
|
+
}
|
|
41
|
+
break;
|
|
42
|
+
}
|
|
43
|
+
default:
|
|
44
|
+
/* Do nothing, there is nothing extra to validate*/
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
(0, node_assert_1.default)(issues.length === 0, issues.join('\n'));
|
|
49
|
+
}
|
|
50
|
+
async function generateIDLInterfaces(dataSources, projectPath, renderTemplate) {
|
|
51
|
+
const allAssets = new Map(dataSources.filter((ds) => ds.assets !== undefined).flatMap((ds) => Array.from(ds.assets.entries())));
|
|
52
|
+
await validateDiscriminators(dataSources.filter((ds) => ds.kind === types_solana_1.SolanaDatasourceKind.Runtime), projectPath);
|
|
53
|
+
for (const [name, fileRef] of allAssets) {
|
|
54
|
+
const idlPath = node_path_1.default.join(projectPath, fileRef.file);
|
|
55
|
+
const idl = await (0, idl_1.parseIdlFromFile)(idlPath);
|
|
56
|
+
const output = node_path_1.default.join(projectPath, CODAMA_PATH, name);
|
|
57
|
+
await idl.accept((0, renderers_js_1.renderVisitor)(output, {}));
|
|
58
|
+
const instructionNames = idl.getRoot().program.instructions.map((inst) => (0, codama_1.pascalCase)(inst.name));
|
|
59
|
+
await renderTemplate(INSTRUCTION_TEMPLATE_TS, node_path_1.default.join(projectPath, IDL_PATH, `${name}.ts`), {
|
|
60
|
+
props: {
|
|
61
|
+
name,
|
|
62
|
+
instructions: instructionNames,
|
|
63
|
+
},
|
|
64
|
+
});
|
|
65
|
+
console.log(`* IDL ${name} generated`);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=codegen.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codegen.js","sourceRoot":"","sources":["../../src/codegen/codegen.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2020-2025 SubQuery Pte Ltd authors & contributors\n// SPDX-License-Identifier: GPL-3.0\n\nimport assert from 'node:assert';\nimport path from 'node:path';\nimport {renderVisitor} from '@codama/renderers-js';\nimport {SolanaDatasourceKind, SolanaHandlerKind, SubqlDatasource, SubqlRuntimeDatasource} from '@subql/types-solana';\nimport {pascalCase} from 'codama';\nimport {Data} from 'ejs';\nimport {parseIdlFromFile, findInstructionDiscriminatorByName} from './idl';\n\nconst INSTRUCTION_TEMPLATE_TS = path.resolve(__dirname, '../../templates/idl.ts.ejs');\nconst CODAMA_PATH = '/src/types/program-interfaces';\nconst IDL_PATH = '/src/types/handler-inputs';\n\nexport async function validateDiscriminators(\n dataSources: SubqlRuntimeDatasource[],\n projectPath: string\n): Promise<void> {\n const issues: string[] = [];\n\n for (const ds of dataSources) {\n for (const handler of ds.mapping.handlers) {\n if (!handler.filter) {\n break;\n }\n switch (handler.kind) {\n case SolanaHandlerKind.Instruction: {\n if (handler.filter.discriminator && handler.filter.programId) {\n const fileRef = ds.assets?.get(handler.filter.programId);\n if (!fileRef) {\n issues.push(`Datasource has a handler with a discriminator but no IDL file reference`);\n continue;\n }\n\n const idlPath = path.join(projectPath, fileRef.file);\n const idl = await parseIdlFromFile(idlPath);\n\n if (!findInstructionDiscriminatorByName(idl.getRoot(), handler.filter.discriminator)) {\n issues.push(\n `Datasource has a handler with a discriminator ${handler.filter.discriminator} but no matching instruction found in IDL`\n );\n }\n // TODO check discriminator in IDL\n }\n break;\n }\n default:\n /* Do nothing, there is nothing extra to validate*/\n }\n }\n }\n\n assert(issues.length === 0, issues.join('\\n'));\n}\n\nexport async function generateIDLInterfaces(\n dataSources: SubqlDatasource[],\n projectPath: string,\n renderTemplate: (templatePath: string, outputPath: string, templateData: Data) => Promise<void>\n): Promise<void> {\n const allAssets = new Map(\n dataSources.filter((ds) => ds.assets !== undefined).flatMap((ds) => Array.from(ds.assets!.entries()))\n );\n\n await validateDiscriminators(\n dataSources.filter((ds) => ds.kind === SolanaDatasourceKind.Runtime) as SubqlRuntimeDatasource[],\n projectPath\n );\n\n for (const [name, fileRef] of allAssets) {\n const idlPath = path.join(projectPath, fileRef.file);\n const idl = await parseIdlFromFile(idlPath);\n\n const output = path.join(projectPath, CODAMA_PATH, name);\n\n await idl.accept(renderVisitor(output, {}));\n\n const instructionNames = idl.getRoot().program.instructions.map((inst) => pascalCase(inst.name));\n\n await renderTemplate(INSTRUCTION_TEMPLATE_TS, path.join(projectPath, IDL_PATH, `${name}.ts`), {\n props: {\n name,\n instructions: instructionNames,\n },\n });\n\n console.log(`* IDL ${name} generated`);\n }\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Copyright 2020-2025 SubQuery Pte Ltd authors & contributors
|
|
3
|
+
// SPDX-License-Identifier: GPL-3.0
|
|
4
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
5
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
6
|
+
};
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
9
|
+
const types_solana_1 = require("@subql/types-solana");
|
|
10
|
+
const rimraf_1 = __importDefault(require("rimraf"));
|
|
11
|
+
const codegen_1 = require("./codegen");
|
|
12
|
+
const outDir = node_path_1.default.join(__dirname, 'test-output');
|
|
13
|
+
describe('IDL Codegen', () => {
|
|
14
|
+
afterEach(() => {
|
|
15
|
+
rimraf_1.default.sync(outDir);
|
|
16
|
+
});
|
|
17
|
+
it('can generate an interface from an IDL', async () => {
|
|
18
|
+
const ds = {
|
|
19
|
+
kind: types_solana_1.SolanaDatasourceKind.Runtime,
|
|
20
|
+
startBlock: 0,
|
|
21
|
+
assets: new Map([
|
|
22
|
+
['jupiter', { file: '../../../../node/test/JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4.idl.json' }],
|
|
23
|
+
]),
|
|
24
|
+
mapping: {
|
|
25
|
+
file: '',
|
|
26
|
+
handlers: [],
|
|
27
|
+
},
|
|
28
|
+
};
|
|
29
|
+
const renderTemplate = jest.fn().mockImplementation((templatePath, outputPath, templateData) => {
|
|
30
|
+
/* DO nothing*/
|
|
31
|
+
});
|
|
32
|
+
await expect((0, codegen_1.generateIDLInterfaces)([ds], outDir, renderTemplate)).resolves.not.toThrow();
|
|
33
|
+
expect(renderTemplate).toHaveBeenCalledWith(node_path_1.default.resolve(__dirname, '../../templates/idl.ts.ejs'), node_path_1.default.join(outDir, '/src/types/handler-inputs/jupiter.ts'), {
|
|
34
|
+
props: {
|
|
35
|
+
name: 'jupiter',
|
|
36
|
+
instructions: [
|
|
37
|
+
'Claim',
|
|
38
|
+
'ClaimToken',
|
|
39
|
+
'CloseToken',
|
|
40
|
+
'CreateOpenOrders',
|
|
41
|
+
'CreateProgramOpenOrders',
|
|
42
|
+
'CreateTokenLedger',
|
|
43
|
+
'CreateTokenAccount',
|
|
44
|
+
'ExactOutRoute',
|
|
45
|
+
'Route',
|
|
46
|
+
'RouteWithTokenLedger',
|
|
47
|
+
'SetTokenLedger',
|
|
48
|
+
'SharedAccountsExactOutRoute',
|
|
49
|
+
'SharedAccountsRoute',
|
|
50
|
+
'SharedAccountsRouteWithTokenLedger',
|
|
51
|
+
],
|
|
52
|
+
},
|
|
53
|
+
});
|
|
54
|
+
});
|
|
55
|
+
describe('validating discriminators agains IDLs', () => {
|
|
56
|
+
it('can validate that a discriminator is part of an IDL', async () => {
|
|
57
|
+
const ds = {
|
|
58
|
+
kind: types_solana_1.SolanaDatasourceKind.Runtime,
|
|
59
|
+
startBlock: 0,
|
|
60
|
+
assets: new Map([
|
|
61
|
+
[
|
|
62
|
+
'JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4',
|
|
63
|
+
{ file: '../../../../node/test/JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4.idl.json' },
|
|
64
|
+
],
|
|
65
|
+
]),
|
|
66
|
+
mapping: {
|
|
67
|
+
file: '',
|
|
68
|
+
handlers: [
|
|
69
|
+
{
|
|
70
|
+
handler: 'handleClaimToken',
|
|
71
|
+
kind: types_solana_1.SolanaHandlerKind.Instruction,
|
|
72
|
+
filter: {
|
|
73
|
+
programId: 'JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4',
|
|
74
|
+
discriminator: 'ClaimToken',
|
|
75
|
+
},
|
|
76
|
+
},
|
|
77
|
+
],
|
|
78
|
+
},
|
|
79
|
+
};
|
|
80
|
+
await expect((0, codegen_1.validateDiscriminators)([ds], outDir)).resolves.not.toThrow();
|
|
81
|
+
});
|
|
82
|
+
it('throws when an idl does not include the discriminator', async () => {
|
|
83
|
+
const ds = {
|
|
84
|
+
kind: types_solana_1.SolanaDatasourceKind.Runtime,
|
|
85
|
+
startBlock: 0,
|
|
86
|
+
assets: new Map([
|
|
87
|
+
[
|
|
88
|
+
'JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4',
|
|
89
|
+
{ file: '../../../../node/test/JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4.idl.json' },
|
|
90
|
+
],
|
|
91
|
+
]),
|
|
92
|
+
mapping: {
|
|
93
|
+
file: '',
|
|
94
|
+
handlers: [
|
|
95
|
+
{
|
|
96
|
+
handler: 'handleClaimToken',
|
|
97
|
+
kind: types_solana_1.SolanaHandlerKind.Instruction,
|
|
98
|
+
filter: {
|
|
99
|
+
programId: 'JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4',
|
|
100
|
+
discriminator: 'InvalidDiscriminator',
|
|
101
|
+
},
|
|
102
|
+
},
|
|
103
|
+
],
|
|
104
|
+
},
|
|
105
|
+
};
|
|
106
|
+
await expect((0, codegen_1.validateDiscriminators)([ds], outDir)).rejects.toThrow('Datasource has a handler with a discriminator InvalidDiscriminator but no matching instruction found in IDL');
|
|
107
|
+
});
|
|
108
|
+
it('throws when there is no IDL', async () => {
|
|
109
|
+
const ds = {
|
|
110
|
+
kind: types_solana_1.SolanaDatasourceKind.Runtime,
|
|
111
|
+
startBlock: 0,
|
|
112
|
+
mapping: {
|
|
113
|
+
file: '',
|
|
114
|
+
handlers: [
|
|
115
|
+
{
|
|
116
|
+
handler: 'handleClaimToken',
|
|
117
|
+
kind: types_solana_1.SolanaHandlerKind.Instruction,
|
|
118
|
+
filter: {
|
|
119
|
+
programId: 'JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4',
|
|
120
|
+
discriminator: 'ClaimToken',
|
|
121
|
+
},
|
|
122
|
+
},
|
|
123
|
+
],
|
|
124
|
+
},
|
|
125
|
+
};
|
|
126
|
+
await expect((0, codegen_1.validateDiscriminators)([ds], outDir)).rejects.toThrow('Datasource has a handler with a discriminator but no IDL file reference');
|
|
127
|
+
});
|
|
128
|
+
});
|
|
129
|
+
});
|
|
130
|
+
//# sourceMappingURL=codegen.spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codegen.spec.js","sourceRoot":"","sources":["../../src/codegen/codegen.spec.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2020-2025 SubQuery Pte Ltd authors & contributors\n// SPDX-License-Identifier: GPL-3.0\n\nimport path from 'node:path';\nimport {SolanaDatasourceKind, SolanaHandlerKind, SubqlRuntimeDatasource} from '@subql/types-solana';\nimport rimraf from 'rimraf';\nimport {generateIDLInterfaces, validateDiscriminators} from './codegen';\n\nconst outDir = path.join(__dirname, 'test-output');\n\ndescribe('IDL Codegen', () => {\n afterEach(() => {\n rimraf.sync(outDir);\n });\n\n it('can generate an interface from an IDL', async () => {\n const ds: SubqlRuntimeDatasource = {\n kind: SolanaDatasourceKind.Runtime,\n startBlock: 0,\n assets: new Map([\n ['jupiter', {file: '../../../../node/test/JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4.idl.json'}],\n ]),\n mapping: {\n file: '',\n handlers: [],\n },\n };\n\n const renderTemplate = jest.fn().mockImplementation((templatePath, outputPath, templateData) => {\n /* DO nothing*/\n });\n\n await expect(generateIDLInterfaces([ds], outDir, renderTemplate)).resolves.not.toThrow();\n\n expect(renderTemplate).toHaveBeenCalledWith(\n path.resolve(__dirname, '../../templates/idl.ts.ejs'),\n path.join(outDir, '/src/types/handler-inputs/jupiter.ts'),\n {\n props: {\n name: 'jupiter',\n instructions: [\n 'Claim',\n 'ClaimToken',\n 'CloseToken',\n 'CreateOpenOrders',\n 'CreateProgramOpenOrders',\n 'CreateTokenLedger',\n 'CreateTokenAccount',\n 'ExactOutRoute',\n 'Route',\n 'RouteWithTokenLedger',\n 'SetTokenLedger',\n 'SharedAccountsExactOutRoute',\n 'SharedAccountsRoute',\n 'SharedAccountsRouteWithTokenLedger',\n ],\n },\n }\n );\n });\n\n describe('validating discriminators agains IDLs', () => {\n it('can validate that a discriminator is part of an IDL', async () => {\n const ds: SubqlRuntimeDatasource = {\n kind: SolanaDatasourceKind.Runtime,\n startBlock: 0,\n assets: new Map([\n [\n 'JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4',\n {file: '../../../../node/test/JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4.idl.json'},\n ],\n ]),\n mapping: {\n file: '',\n handlers: [\n {\n handler: 'handleClaimToken',\n kind: SolanaHandlerKind.Instruction,\n filter: {\n programId: 'JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4',\n discriminator: 'ClaimToken',\n },\n },\n ],\n },\n };\n\n await expect(validateDiscriminators([ds], outDir)).resolves.not.toThrow();\n });\n\n it('throws when an idl does not include the discriminator', async () => {\n const ds: SubqlRuntimeDatasource = {\n kind: SolanaDatasourceKind.Runtime,\n startBlock: 0,\n assets: new Map([\n [\n 'JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4',\n {file: '../../../../node/test/JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4.idl.json'},\n ],\n ]),\n mapping: {\n file: '',\n handlers: [\n {\n handler: 'handleClaimToken',\n kind: SolanaHandlerKind.Instruction,\n filter: {\n programId: 'JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4',\n discriminator: 'InvalidDiscriminator',\n },\n },\n ],\n },\n };\n\n await expect(validateDiscriminators([ds], outDir)).rejects.toThrow(\n 'Datasource has a handler with a discriminator InvalidDiscriminator but no matching instruction found in IDL'\n );\n });\n\n it('throws when there is no IDL', async () => {\n const ds: SubqlRuntimeDatasource = {\n kind: SolanaDatasourceKind.Runtime,\n startBlock: 0,\n mapping: {\n file: '',\n handlers: [\n {\n handler: 'handleClaimToken',\n kind: SolanaHandlerKind.Instruction,\n filter: {\n programId: 'JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4',\n discriminator: 'ClaimToken',\n },\n },\n ],\n },\n };\n\n await expect(validateDiscriminators([ds], outDir)).rejects.toThrow(\n 'Datasource has a handler with a discriminator but no IDL file reference'\n );\n });\n });\n});\n"]}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { AnchorIdl, IdlV01 } from '@codama/nodes-from-anchor';
|
|
2
|
+
import { BytesValueNode, InstructionNode, RootNode, Codama } from 'codama';
|
|
3
|
+
export type Idl = AnchorIdl | RootNode;
|
|
4
|
+
export declare function isAnchorIdl(idl: Idl): idl is AnchorIdl;
|
|
5
|
+
export declare function isAnchorIdlV01(idl: Idl): idl is IdlV01;
|
|
6
|
+
export declare function isRootNode(idl: Idl): idl is RootNode;
|
|
7
|
+
export declare function parseIdl(idl: Idl): Codama;
|
|
8
|
+
export declare function parseIdlFromFile(path: string): Promise<Codama>;
|
|
9
|
+
export declare function getBytesFromBytesValueNode(node: BytesValueNode): Uint8Array;
|
|
10
|
+
export declare function getInstructionDiscriminatorBytes(node: InstructionNode): Buffer;
|
|
11
|
+
export declare function findInstructionDiscriminatorByName(rootNode: RootNode, name: string): Buffer | undefined;
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Copyright 2020-2025 SubQuery Pte Ltd authors & contributors
|
|
3
|
+
// SPDX-License-Identifier: GPL-3.0
|
|
4
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
5
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
6
|
+
};
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.isAnchorIdl = isAnchorIdl;
|
|
9
|
+
exports.isAnchorIdlV01 = isAnchorIdlV01;
|
|
10
|
+
exports.isRootNode = isRootNode;
|
|
11
|
+
exports.parseIdl = parseIdl;
|
|
12
|
+
exports.parseIdlFromFile = parseIdlFromFile;
|
|
13
|
+
exports.getBytesFromBytesValueNode = getBytesFromBytesValueNode;
|
|
14
|
+
exports.getInstructionDiscriminatorBytes = getInstructionDiscriminatorBytes;
|
|
15
|
+
exports.findInstructionDiscriminatorByName = findInstructionDiscriminatorByName;
|
|
16
|
+
const node_fs_1 = __importDefault(require("node:fs"));
|
|
17
|
+
const nodes_from_anchor_1 = require("@codama/nodes-from-anchor");
|
|
18
|
+
const codecs_strings_1 = require("@solana/codecs-strings");
|
|
19
|
+
const codama_1 = require("codama");
|
|
20
|
+
function isAnchorIdl(idl) {
|
|
21
|
+
return !isRootNode(idl);
|
|
22
|
+
}
|
|
23
|
+
function isAnchorIdlV01(idl) {
|
|
24
|
+
return isAnchorIdl(idl) && idl.metadata.spec === '0.1.0';
|
|
25
|
+
}
|
|
26
|
+
function isRootNode(idl) {
|
|
27
|
+
return !!idl.program?.publicKey;
|
|
28
|
+
}
|
|
29
|
+
function parseIdl(idl) {
|
|
30
|
+
let codama = (0, codama_1.createFromRoot)((0, nodes_from_anchor_1.rootNodeFromAnchor)(idl));
|
|
31
|
+
// Check if the idl was an anchor idl
|
|
32
|
+
if (codama.getRoot().program.publicKey === '') {
|
|
33
|
+
codama = (0, codama_1.createFromRoot)(idl);
|
|
34
|
+
}
|
|
35
|
+
return codama;
|
|
36
|
+
}
|
|
37
|
+
async function parseIdlFromFile(path) {
|
|
38
|
+
const idlStr = await node_fs_1.default.promises.readFile(path, 'utf-8');
|
|
39
|
+
const idlJSON = JSON.parse(idlStr);
|
|
40
|
+
return parseIdl(idlJSON);
|
|
41
|
+
}
|
|
42
|
+
function getBytesFromBytesValueNode(node) {
|
|
43
|
+
switch (node.encoding) {
|
|
44
|
+
case 'utf8':
|
|
45
|
+
return (0, codecs_strings_1.getUtf8Encoder)().encode(node.data);
|
|
46
|
+
case 'base16':
|
|
47
|
+
return (0, codecs_strings_1.getBase16Encoder)().encode(node.data);
|
|
48
|
+
case 'base58':
|
|
49
|
+
return (0, codecs_strings_1.getBase58Encoder)().encode(node.data);
|
|
50
|
+
case 'base64':
|
|
51
|
+
default:
|
|
52
|
+
return (0, codecs_strings_1.getBase64Encoder)().encode(node.data);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
function getInstructionDiscriminatorBytes(node) {
|
|
56
|
+
const discArg = node.arguments.find((arg) => arg.name === 'discriminator');
|
|
57
|
+
if (!discArg) {
|
|
58
|
+
throw new Error(`Instruction ${node.name} does not have a discriminator`);
|
|
59
|
+
}
|
|
60
|
+
// TODO what about other types of discriminators or ones that are larger than 1 byte?
|
|
61
|
+
switch (discArg.defaultValue?.kind) {
|
|
62
|
+
case 'numberValueNode':
|
|
63
|
+
return Buffer.from([discArg.defaultValue.number]);
|
|
64
|
+
case 'bytesValueNode':
|
|
65
|
+
return Buffer.from(getBytesFromBytesValueNode(discArg.defaultValue));
|
|
66
|
+
case undefined:
|
|
67
|
+
break;
|
|
68
|
+
default:
|
|
69
|
+
throw new Error(`Unable to handle unknown discriminator type ${discArg.defaultValue?.kind}`);
|
|
70
|
+
}
|
|
71
|
+
throw new Error(`Unable to find discriminator for instruction ${node.name}`);
|
|
72
|
+
}
|
|
73
|
+
function findInstructionDiscriminatorByName(rootNode, name) {
|
|
74
|
+
const inst = rootNode.program.instructions.find((inst) => inst.name === name || inst.name === (0, codama_1.camelCase)(name));
|
|
75
|
+
if (!inst) {
|
|
76
|
+
return undefined;
|
|
77
|
+
}
|
|
78
|
+
try {
|
|
79
|
+
return getInstructionDiscriminatorBytes(inst);
|
|
80
|
+
}
|
|
81
|
+
catch (e) {
|
|
82
|
+
// logger.debug(
|
|
83
|
+
// `Failed to get discriminator for instruction ${inst.name}: ${e}`,
|
|
84
|
+
// );
|
|
85
|
+
return undefined;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
//# sourceMappingURL=idl.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"idl.js","sourceRoot":"","sources":["../../src/codegen/idl.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 {AnchorIdl, IdlV01, rootNodeFromAnchor} from '@codama/nodes-from-anchor';\nimport {getBase16Encoder, getBase58Encoder, getBase64Encoder, getUtf8Encoder} from '@solana/codecs-strings';\nimport {BytesValueNode, InstructionNode, RootNode, Codama, createFromRoot, camelCase} from 'codama';\n\nexport type Idl = AnchorIdl | RootNode;\n\nexport function isAnchorIdl(idl: Idl): idl is AnchorIdl {\n return !isRootNode(idl);\n}\n\nexport function isAnchorIdlV01(idl: Idl): idl is IdlV01 {\n return isAnchorIdl(idl) && (idl.metadata as {spec?: string}).spec === '0.1.0';\n}\n\nexport function isRootNode(idl: Idl): idl is RootNode {\n return !!(idl as RootNode).program?.publicKey;\n}\n\nexport function parseIdl(idl: Idl): Codama {\n let codama = createFromRoot(rootNodeFromAnchor(idl as AnchorIdl));\n // Check if the idl was an anchor idl\n if (codama.getRoot().program.publicKey === '') {\n codama = createFromRoot(idl as RootNode);\n }\n\n return codama;\n}\n\nexport async function parseIdlFromFile(path: string): Promise<Codama> {\n const idlStr = await fs.promises.readFile(path, 'utf-8');\n const idlJSON = JSON.parse(idlStr);\n\n return parseIdl(idlJSON);\n}\n\nexport function getBytesFromBytesValueNode(node: BytesValueNode): Uint8Array {\n switch (node.encoding) {\n case 'utf8':\n return getUtf8Encoder().encode(node.data) as Uint8Array;\n case 'base16':\n return getBase16Encoder().encode(node.data) as Uint8Array;\n case 'base58':\n return getBase58Encoder().encode(node.data) as Uint8Array;\n case 'base64':\n default:\n return getBase64Encoder().encode(node.data) as Uint8Array;\n }\n}\n\nexport function getInstructionDiscriminatorBytes(node: InstructionNode): Buffer {\n const discArg = node.arguments.find((arg) => arg.name === 'discriminator');\n if (!discArg) {\n throw new Error(`Instruction ${node.name} does not have a discriminator`);\n }\n\n // TODO what about other types of discriminators or ones that are larger than 1 byte?\n switch (discArg.defaultValue?.kind) {\n case 'numberValueNode':\n return Buffer.from([discArg.defaultValue.number]);\n case 'bytesValueNode':\n return Buffer.from(getBytesFromBytesValueNode(discArg.defaultValue));\n case undefined:\n break;\n default:\n throw new Error(`Unable to handle unknown discriminator type ${discArg.defaultValue?.kind}`);\n }\n\n throw new Error(`Unable to find discriminator for instruction ${node.name}`);\n}\n\nexport function findInstructionDiscriminatorByName(rootNode: RootNode, name: string): Buffer | undefined {\n const inst = rootNode.program.instructions.find((inst) => inst.name === name || inst.name === camelCase(name));\n if (!inst) {\n return undefined;\n }\n\n try {\n return getInstructionDiscriminatorBytes(inst);\n } catch (e) {\n // logger.debug(\n // `Failed to get discriminator for instruction ${inst.name}: ${e}`,\n // );\n return undefined;\n }\n}\n"]}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Copyright 2020-2025 SubQuery Pte Ltd authors & contributors
|
|
3
|
+
// SPDX-License-Identifier: GPL-3.0
|
|
4
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
5
|
+
if (k2 === undefined) k2 = k;
|
|
6
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
7
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
8
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
9
|
+
}
|
|
10
|
+
Object.defineProperty(o, k2, desc);
|
|
11
|
+
}) : (function(o, m, k, k2) {
|
|
12
|
+
if (k2 === undefined) k2 = k;
|
|
13
|
+
o[k2] = m[k];
|
|
14
|
+
}));
|
|
15
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
16
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
17
|
+
};
|
|
18
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
19
|
+
__exportStar(require("./codegen"), exports);
|
|
20
|
+
__exportStar(require("./idl"), exports);
|
|
21
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/codegen/index.ts"],"names":[],"mappings":";AAAA,8DAA8D;AAC9D,mCAAmC;;;;;;;;;;;;;;;;AAEnC,4CAA0B;AAC1B,wCAAsB","sourcesContent":["// Copyright 2020-2025 SubQuery Pte Ltd authors & contributors\n// SPDX-License-Identifier: GPL-3.0\n\nexport * from './codegen';\nexport * from './idl';\n"]}
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Copyright 2020-2025 SubQuery Pte Ltd authors & contributors
|
|
3
|
+
// SPDX-License-Identifier: GPL-3.0
|
|
4
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
5
|
+
if (k2 === undefined) k2 = k;
|
|
6
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
7
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
8
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
9
|
+
}
|
|
10
|
+
Object.defineProperty(o, k2, desc);
|
|
11
|
+
}) : (function(o, m, k, k2) {
|
|
12
|
+
if (k2 === undefined) k2 = k;
|
|
13
|
+
o[k2] = m[k];
|
|
14
|
+
}));
|
|
15
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
16
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
17
|
+
}) : function(o, v) {
|
|
18
|
+
o["default"] = v;
|
|
19
|
+
});
|
|
20
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
21
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
22
|
+
};
|
|
23
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
24
|
+
var ownKeys = function(o) {
|
|
25
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
26
|
+
var ar = [];
|
|
27
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
28
|
+
return ar;
|
|
29
|
+
};
|
|
30
|
+
return ownKeys(o);
|
|
31
|
+
};
|
|
32
|
+
return function (mod) {
|
|
33
|
+
if (mod && mod.__esModule) return mod;
|
|
34
|
+
var result = {};
|
|
35
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
36
|
+
__setModuleDefault(result, mod);
|
|
37
|
+
return result;
|
|
38
|
+
};
|
|
39
|
+
})();
|
|
40
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
41
|
+
__exportStar(require("./codegen"), exports);
|
|
42
|
+
__exportStar(require("./project"), exports);
|
|
43
|
+
const c = __importStar(require("./codegen"));
|
|
44
|
+
const p = __importStar(require("./project"));
|
|
45
|
+
// This provides a compiled time check to ensure that the correct exports are provided
|
|
46
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
47
|
+
const _ = {
|
|
48
|
+
...p,
|
|
49
|
+
...c,
|
|
50
|
+
};
|
|
51
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA,8DAA8D;AAC9D,mCAAmC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEnC,4CAA0B;AAC1B,4CAA0B;AAG1B,6CAA+B;AAC/B,6CAA+B;AAE/B,sFAAsF;AACtF,6DAA6D;AAC7D,MAAM,CAAC,GAAG;IACR,GAAG,CAAC;IACJ,GAAG,CAAC;CACyB,CAAC","sourcesContent":["// Copyright 2020-2025 SubQuery Pte Ltd authors & contributors\n// SPDX-License-Identifier: GPL-3.0\n\nexport * from './codegen';\nexport * from './project';\n\nimport {SolanaNetworkModule} from '@subql/types-solana';\nimport * as c from './codegen';\nimport * as p from './project';\n\n// This provides a compiled time check to ensure that the correct exports are provided\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nconst _ = {\n ...p,\n ...c,\n} satisfies SolanaNetworkModule;\n"]}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Copyright 2020-2025 SubQuery Pte Ltd authors & contributors
|
|
3
|
+
// SPDX-License-Identifier: GPL-3.0
|
|
4
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
5
|
+
if (k2 === undefined) k2 = k;
|
|
6
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
7
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
8
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
9
|
+
}
|
|
10
|
+
Object.defineProperty(o, k2, desc);
|
|
11
|
+
}) : (function(o, m, k, k2) {
|
|
12
|
+
if (k2 === undefined) k2 = k;
|
|
13
|
+
o[k2] = m[k];
|
|
14
|
+
}));
|
|
15
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
16
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
17
|
+
};
|
|
18
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
19
|
+
exports.parseProjectManifest = void 0;
|
|
20
|
+
__exportStar(require("./load"), exports);
|
|
21
|
+
__exportStar(require("./models"), exports);
|
|
22
|
+
__exportStar(require("./types"), exports);
|
|
23
|
+
__exportStar(require("./utils"), exports);
|
|
24
|
+
__exportStar(require("./versioned"), exports);
|
|
25
|
+
const load_1 = require("./load");
|
|
26
|
+
Object.defineProperty(exports, "parseProjectManifest", { enumerable: true, get: function () { return load_1.parseSolanaProjectManifest; } });
|
|
27
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/project/index.ts"],"names":[],"mappings":";AAAA,8DAA8D;AAC9D,mCAAmC;;;;;;;;;;;;;;;;;AAEnC,yCAAuB;AACvB,2CAAyB;AACzB,0CAAwB;AACxB,0CAAwB;AACxB,8CAA4B;AAE5B,iCAAoD;AACb,qGAD9B,iCAA0B,OACwB","sourcesContent":["// Copyright 2020-2025 SubQuery Pte Ltd authors & contributors\n// SPDX-License-Identifier: GPL-3.0\n\nexport * from './load';\nexport * from './models';\nexport * from './types';\nexport * from './utils';\nexport * from './versioned';\n\nimport { parseSolanaProjectManifest } from './load';\nexport { parseSolanaProjectManifest as parseProjectManifest };\n"]}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Copyright 2020-2025 SubQuery Pte Ltd authors & contributors
|
|
3
|
+
// SPDX-License-Identifier: GPL-3.0
|
|
4
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
5
|
+
exports.parseSolanaProjectManifest = parseSolanaProjectManifest;
|
|
6
|
+
const versioned_1 = require("./versioned");
|
|
7
|
+
function parseSolanaProjectManifest(raw) {
|
|
8
|
+
const projectManifest = new versioned_1.SolanaProjectManifestVersioned(raw);
|
|
9
|
+
projectManifest.validate();
|
|
10
|
+
return projectManifest;
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=load.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"load.js","sourceRoot":"","sources":["../../src/project/load.ts"],"names":[],"mappings":";AAAA,8DAA8D;AAC9D,mCAAmC;;AAInC,gEAIC;AAND,2CAAuF;AAEvF,SAAgB,0BAA0B,CAAC,GAAY;IACrD,MAAM,eAAe,GAAG,IAAI,0CAA8B,CAAC,GAA+B,CAAC,CAAC;IAC5F,eAAe,CAAC,QAAQ,EAAE,CAAC;IAC3B,OAAO,eAAe,CAAC;AACzB,CAAC","sourcesContent":["// Copyright 2020-2025 SubQuery Pte Ltd authors & contributors\n// SPDX-License-Identifier: GPL-3.0\n\nimport { SolanaProjectManifestVersioned, VersionedProjectManifest } from './versioned';\n\nexport function parseSolanaProjectManifest(raw: unknown): SolanaProjectManifestVersioned {\n const projectManifest = new SolanaProjectManifestVersioned(raw as VersionedProjectManifest);\n projectManifest.validate();\n return projectManifest;\n}\n"]}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { BaseDataSource, BlockFilterImpl } from '@subql/common';
|
|
2
|
+
import { FileReference } from '@subql/types-core';
|
|
3
|
+
import { SolanaHandlerKind, SolanaDatasourceKind, SolanaLogFilter, SubqlCustomHandler, SubqlMapping, SubqlHandler, SubqlRuntimeHandler, SubqlRuntimeDatasource, SubqlCustomDatasource, SubqlBlockHandler, SubqlTransactionHandler, SolanaTransactionFilter, SolanaBlockFilter, SolanaInstructionFilter, SubqlInstructionHandler, SubqlLogHandler, InstructionAccountFilter } from '@subql/types-solana';
|
|
4
|
+
export declare class BlockFilter extends BlockFilterImpl implements SolanaBlockFilter {
|
|
5
|
+
}
|
|
6
|
+
export declare class TransactionFilter implements SolanaTransactionFilter {
|
|
7
|
+
signerAccountKey?: string;
|
|
8
|
+
}
|
|
9
|
+
export declare class InstructionFilter implements SolanaInstructionFilter {
|
|
10
|
+
programId?: string;
|
|
11
|
+
discriminator?: string;
|
|
12
|
+
accounts?: [
|
|
13
|
+
InstructionAccountFilter,
|
|
14
|
+
InstructionAccountFilter?,
|
|
15
|
+
InstructionAccountFilter?,
|
|
16
|
+
InstructionAccountFilter?,
|
|
17
|
+
InstructionAccountFilter?,
|
|
18
|
+
InstructionAccountFilter?,
|
|
19
|
+
InstructionAccountFilter?,
|
|
20
|
+
InstructionAccountFilter?,
|
|
21
|
+
InstructionAccountFilter?,
|
|
22
|
+
InstructionAccountFilter?,
|
|
23
|
+
InstructionAccountFilter?,
|
|
24
|
+
InstructionAccountFilter?,
|
|
25
|
+
InstructionAccountFilter?,
|
|
26
|
+
InstructionAccountFilter?,
|
|
27
|
+
InstructionAccountFilter?,
|
|
28
|
+
InstructionAccountFilter?
|
|
29
|
+
];
|
|
30
|
+
includeFalied?: boolean;
|
|
31
|
+
}
|
|
32
|
+
export declare class LogFilter implements SolanaLogFilter {
|
|
33
|
+
programId?: string;
|
|
34
|
+
}
|
|
35
|
+
export declare class BlockHandler implements SubqlBlockHandler {
|
|
36
|
+
filter?: BlockFilter;
|
|
37
|
+
kind: SolanaHandlerKind.Block;
|
|
38
|
+
handler: string;
|
|
39
|
+
}
|
|
40
|
+
export declare class TransactionHandler implements SubqlTransactionHandler {
|
|
41
|
+
filter?: SolanaTransactionFilter;
|
|
42
|
+
kind: SolanaHandlerKind.Transaction;
|
|
43
|
+
handler: string;
|
|
44
|
+
}
|
|
45
|
+
export declare class InstructionHandler implements SubqlInstructionHandler {
|
|
46
|
+
filter?: SolanaInstructionFilter;
|
|
47
|
+
kind: SolanaHandlerKind.Instruction;
|
|
48
|
+
handler: string;
|
|
49
|
+
}
|
|
50
|
+
export declare class LogHandler implements SubqlLogHandler {
|
|
51
|
+
filter?: SolanaLogFilter;
|
|
52
|
+
kind: SolanaHandlerKind.Log;
|
|
53
|
+
handler: string;
|
|
54
|
+
}
|
|
55
|
+
export declare class CustomHandler implements SubqlCustomHandler {
|
|
56
|
+
kind: string;
|
|
57
|
+
handler: string;
|
|
58
|
+
filter?: Record<string, unknown>;
|
|
59
|
+
}
|
|
60
|
+
export declare class SolanaMapping implements SubqlMapping {
|
|
61
|
+
handlers: SubqlHandler[];
|
|
62
|
+
file: string;
|
|
63
|
+
}
|
|
64
|
+
export declare class CustomMapping implements SubqlMapping<SubqlCustomHandler> {
|
|
65
|
+
handlers: CustomHandler[];
|
|
66
|
+
file: string;
|
|
67
|
+
}
|
|
68
|
+
export declare class RuntimeDataSourceBase<M extends SubqlMapping<SubqlRuntimeHandler>> extends BaseDataSource implements SubqlRuntimeDatasource<M> {
|
|
69
|
+
kind: SolanaDatasourceKind.Runtime;
|
|
70
|
+
mapping: M;
|
|
71
|
+
assets?: Map<string, FileReference>;
|
|
72
|
+
}
|
|
73
|
+
export declare class FileReferenceImpl implements FileReference {
|
|
74
|
+
file: string;
|
|
75
|
+
}
|
|
76
|
+
export declare class CustomDataSourceBase<K extends string, M extends SubqlMapping = SubqlMapping<SubqlCustomHandler>> extends BaseDataSource implements SubqlCustomDatasource<K, M> {
|
|
77
|
+
kind: K;
|
|
78
|
+
mapping: M;
|
|
79
|
+
assets: Map<string, FileReference>;
|
|
80
|
+
processor: FileReference;
|
|
81
|
+
}
|