@sentio/sdk 2.0.0-rc.13 → 2.0.0-rc.15
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/lib/aptos/api.d.ts +5 -0
- package/lib/aptos/api.js +21 -0
- package/lib/aptos/api.js.map +1 -0
- package/lib/aptos/aptos-plugin.d.ts +14 -0
- package/lib/aptos/aptos-plugin.js +146 -0
- package/lib/aptos/aptos-plugin.js.map +1 -0
- package/lib/aptos/aptos-processor.d.ts +72 -0
- package/lib/aptos/aptos-processor.js +201 -0
- package/lib/aptos/aptos-processor.js.map +1 -0
- package/lib/aptos/builtin/0x1.d.ts +2140 -0
- package/lib/aptos/builtin/0x1.js +2727 -0
- package/lib/aptos/builtin/0x1.js.map +1 -0
- package/lib/aptos/builtin/0x3.d.ts +573 -0
- package/lib/aptos/builtin/0x3.js +496 -0
- package/lib/aptos/builtin/0x3.js.map +1 -0
- package/lib/aptos/builtin/index.d.ts +2 -0
- package/lib/aptos/builtin/index.js +6 -0
- package/lib/aptos/builtin/index.js.map +1 -0
- package/lib/aptos/codegen/codegen.d.ts +23 -0
- package/lib/aptos/codegen/codegen.js +388 -0
- package/lib/aptos/codegen/codegen.js.map +1 -0
- package/lib/aptos/codegen/index.d.ts +1 -0
- package/lib/aptos/codegen/index.js +2 -0
- package/lib/aptos/codegen/index.js.map +1 -0
- package/lib/aptos/codegen/typegen.d.ts +18 -0
- package/lib/aptos/codegen/typegen.js +145 -0
- package/lib/aptos/codegen/typegen.js.map +1 -0
- package/lib/aptos/codegen/typegen.test.d.ts +1 -0
- package/lib/aptos/codegen/typegen.test.js.map +1 -0
- package/lib/aptos/context.d.ts +21 -0
- package/lib/aptos/context.js +59 -0
- package/lib/aptos/context.js.map +1 -0
- package/lib/aptos/index.d.ts +9 -0
- package/lib/aptos/index.js +8 -0
- package/lib/aptos/index.js.map +1 -0
- package/lib/aptos/models.d.ts +37 -0
- package/lib/aptos/models.js +2 -0
- package/lib/aptos/models.js.map +1 -0
- package/lib/aptos/move-coder.d.ts +22 -0
- package/lib/aptos/move-coder.js +164 -0
- package/lib/aptos/move-coder.js.map +1 -0
- package/lib/aptos/move-types.d.ts +10 -0
- package/lib/aptos/move-types.js +2 -0
- package/lib/aptos/move-types.js.map +1 -0
- package/lib/aptos/network.d.ts +11 -0
- package/lib/aptos/network.js +27 -0
- package/lib/aptos/network.js.map +1 -0
- package/lib/aptos/run-codegen.d.ts +1 -0
- package/lib/aptos/run-codegen.js +12 -0
- package/lib/aptos/run-codegen.js.map +1 -0
- package/lib/aptos/tests/aptos.test.d.ts +1 -0
- package/lib/aptos/tests/aptos.test.js.map +1 -0
- package/lib/aptos/tests/souffl3.d.ts +1 -0
- package/lib/aptos/tests/souffl3.js +44 -0
- package/lib/aptos/tests/souffl3.js.map +1 -0
- package/lib/aptos/tests/types/index.d.ts +3 -0
- package/lib/aptos/tests/types/index.js +7 -0
- package/lib/aptos/tests/types/index.js.map +1 -0
- package/lib/aptos/tests/types/reserved.d.ts +445 -0
- package/lib/aptos/tests/types/reserved.js +301 -0
- package/lib/aptos/tests/types/reserved.js.map +1 -0
- package/lib/aptos/tests/types/soffl3.d.ts +1065 -0
- package/lib/aptos/tests/types/soffl3.js +548 -0
- package/lib/aptos/tests/types/soffl3.js.map +1 -0
- package/lib/aptos/tests/types/souffle.d.ts +440 -0
- package/lib/aptos/tests/types/souffle.js +295 -0
- package/lib/aptos/tests/types/souffle.js.map +1 -0
- package/lib/aptos/types.d.ts +9 -0
- package/lib/aptos/types.js +130 -0
- package/lib/aptos/types.js.map +1 -0
- package/lib/aptos/types.test.d.ts +1 -0
- package/lib/aptos/types.test.js.map +1 -0
- package/lib/aptos/utils.d.ts +7 -0
- package/lib/aptos/utils.js +20 -0
- package/lib/aptos/utils.js.map +1 -0
- package/lib/builtin/internal/eacaggregatorproxy_processor.js +90 -180
- package/lib/builtin/internal/eacaggregatorproxy_processor.js.map +1 -1
- package/lib/builtin/internal/erc1155_processor.js +25 -50
- package/lib/builtin/internal/erc1155_processor.js.map +1 -1
- package/lib/builtin/internal/erc20_processor.js +40 -80
- package/lib/builtin/internal/erc20_processor.js.map +1 -1
- package/lib/builtin/internal/erc20bytes_processor.js +30 -60
- package/lib/builtin/internal/erc20bytes_processor.js.map +1 -1
- package/lib/builtin/internal/erc721_processor.js +45 -90
- package/lib/builtin/internal/erc721_processor.js.map +1 -1
- package/lib/builtin/internal/weth9_processor.js +30 -60
- package/lib/builtin/internal/weth9_processor.js.map +1 -1
- package/lib/{utils/chain.d.ts → chain.d.ts} +0 -0
- package/lib/{utils/chain.js → chain.js} +0 -0
- package/lib/chain.js.map +1 -0
- package/lib/core/context.js +1 -1
- package/lib/core/context.js.map +1 -1
- package/lib/core/sui-plugin.js +1 -1
- package/lib/core/sui-plugin.js.map +1 -1
- package/lib/error.d.ts +1 -1
- package/lib/error.js +10 -12
- package/lib/error.js.map +1 -1
- package/lib/eth/base-processor-template.d.ts +3 -3
- package/lib/eth/base-processor-template.js.map +1 -1
- package/lib/eth/base-processor.d.ts +3 -3
- package/lib/eth/base-processor.js.map +1 -1
- package/lib/eth/{eth-event.d.ts → eth.d.ts} +1 -1
- package/lib/eth/eth.js +2 -0
- package/lib/eth/eth.js.map +1 -0
- package/lib/eth/index.d.ts +1 -0
- package/lib/eth/index.js +1 -0
- package/lib/eth/index.js.map +1 -1
- package/lib/index.d.ts +2 -2
- package/lib/index.js +2 -2
- package/lib/index.js.map +1 -1
- package/lib/solana/builtin/index.d.ts +1 -0
- package/lib/solana/builtin/index.js +2 -0
- package/lib/solana/builtin/index.js.map +1 -0
- package/lib/solana/builtin/spl-token-processor.d.ts +39 -0
- package/lib/solana/builtin/spl-token-processor.js +254 -0
- package/lib/solana/builtin/spl-token-processor.js.map +1 -0
- package/lib/solana/builtin/types.d.ts +427 -0
- package/lib/solana/builtin/types.js +200 -0
- package/lib/solana/builtin/types.js.map +1 -0
- package/lib/solana/codegen/codegen.d.ts +1 -0
- package/lib/solana/codegen/codegen.js +122 -0
- package/lib/solana/codegen/codegen.js.map +1 -0
- package/lib/solana/codegen/index.d.ts +1 -0
- package/lib/solana/codegen/index.js +2 -0
- package/lib/solana/codegen/index.js.map +1 -0
- package/lib/solana/index.d.ts +4 -0
- package/lib/solana/index.js +5 -0
- package/lib/solana/index.js.map +1 -0
- package/lib/solana/run-codegen.d.ts +2 -0
- package/lib/solana/run-codegen.js +12 -0
- package/lib/solana/run-codegen.js.map +1 -0
- package/lib/solana/solana-context.d.ts +9 -0
- package/lib/solana/solana-context.js +28 -0
- package/lib/solana/solana-context.js.map +1 -0
- package/lib/solana/solana-options.d.ts +10 -0
- package/lib/solana/solana-options.js +10 -0
- package/lib/solana/solana-options.js.map +1 -0
- package/lib/solana/solana-plugin.d.ts +9 -0
- package/lib/solana/solana-plugin.js +87 -0
- package/lib/solana/solana-plugin.js.map +1 -0
- package/lib/solana/solana-processor.d.ts +43 -0
- package/lib/solana/solana-processor.js +72 -0
- package/lib/solana/solana-processor.js.map +1 -0
- package/lib/solana/tests/solana.test.d.ts +1 -0
- package/lib/solana/tests/solana.test.js.map +1 -0
- package/lib/solana/tests/types/basic_1.d.ts +26 -0
- package/lib/solana/tests/types/basic_1.js +63 -0
- package/lib/solana/tests/types/basic_1.js.map +1 -0
- package/lib/solana/tests/types/basic_1_processor.d.ts +21 -0
- package/lib/solana/tests/types/basic_1_processor.js +35 -0
- package/lib/solana/tests/types/basic_1_processor.js.map +1 -0
- package/lib/solana/tests/types/token_bridge.d.ts +29 -0
- package/lib/solana/tests/types/token_bridge.js +938 -0
- package/lib/solana/tests/types/token_bridge.js.map +1 -0
- package/lib/solana/tests/types/token_bridge_processor.d.ts +212 -0
- package/lib/solana/tests/types/token_bridge_processor.js +134 -0
- package/lib/solana/tests/types/token_bridge_processor.js.map +1 -0
- package/lib/solana/tests/wormhole-token-bridge.d.ts +15 -0
- package/lib/solana/tests/wormhole-token-bridge.js +79 -0
- package/lib/solana/tests/wormhole-token-bridge.js.map +1 -0
- package/lib/target-ethers-sentio/view-function.cjs +4 -9
- package/lib/target-ethers-sentio/view-function.cjs.map +1 -1
- package/lib/testing/test-processor-server.js +1 -1
- package/lib/testing/test-processor-server.js.map +1 -1
- package/lib/testing/test-provider.js +1 -1
- package/lib/testing/test-provider.js.map +1 -1
- package/lib/utils/index.d.ts +0 -1
- package/lib/utils/index.js +0 -1
- package/lib/utils/index.js.map +1 -1
- package/package.json +34 -11
- package/src/aptos/abis/0x1.json +9205 -0
- package/src/aptos/abis/0x3.json +1515 -0
- package/src/aptos/api.ts +23 -0
- package/src/aptos/aptos-plugin.ts +183 -0
- package/src/aptos/aptos-processor.ts +331 -0
- package/src/aptos/builtin/0x1.ts +4911 -0
- package/src/aptos/builtin/0x3.ts +1092 -0
- package/src/aptos/builtin/index.ts +5 -0
- package/src/aptos/codegen/codegen.ts +470 -0
- package/src/aptos/codegen/index.ts +1 -0
- package/src/aptos/codegen/tsconfig.json +8 -0
- package/src/aptos/codegen/typegen.ts +165 -0
- package/src/aptos/context.ts +72 -0
- package/src/aptos/index.ts +10 -0
- package/src/aptos/models.ts +47 -0
- package/src/aptos/move-coder.ts +201 -0
- package/src/aptos/move-types.ts +11 -0
- package/src/aptos/network.ts +29 -0
- package/src/aptos/run-codegen.ts +13 -0
- package/src/aptos/tests/abis/reserved.json +402 -0
- package/src/aptos/tests/abis/soffl3.json +1411 -0
- package/src/aptos/tests/abis/souffle.json +389 -0
- package/src/aptos/tests/souffl3.ts +57 -0
- package/src/aptos/tests/types/index.ts +6 -0
- package/src/aptos/tests/types/reserved.ts +881 -0
- package/src/aptos/tests/types/soffl3.ts +1820 -0
- package/src/aptos/tests/types/souffle.ts +880 -0
- package/src/aptos/types.ts +149 -0
- package/src/aptos/utils.ts +26 -0
- package/src/builtin/internal/eacaggregatorproxy_processor.ts +90 -162
- package/src/builtin/internal/erc1155_processor.ts +25 -49
- package/src/builtin/internal/erc20_processor.ts +40 -72
- package/src/builtin/internal/erc20bytes_processor.ts +30 -54
- package/src/builtin/internal/erc721_processor.ts +45 -81
- package/src/builtin/internal/weth9_processor.ts +30 -54
- package/src/{utils/chain.ts → chain.ts} +0 -0
- package/src/core/context.ts +1 -1
- package/src/core/sui-plugin.ts +1 -1
- package/src/error.ts +12 -14
- package/src/eth/base-processor-template.ts +3 -3
- package/src/eth/base-processor.ts +4 -4
- package/src/eth/{eth-event.ts → eth.ts} +1 -1
- package/src/eth/index.ts +2 -0
- package/src/index.ts +2 -2
- package/src/solana/builtin/index.ts +1 -0
- package/src/solana/builtin/spl-token-processor.ts +298 -0
- package/src/solana/builtin/types.ts +279 -0
- package/src/solana/codegen/codegen.ts +140 -0
- package/src/solana/codegen/index.ts +1 -0
- package/src/solana/codegen/tsconfig.json +8 -0
- package/src/solana/index.ts +4 -0
- package/src/solana/run-codegen.ts +13 -0
- package/src/solana/solana-context.ts +30 -0
- package/src/solana/solana-options.ts +11 -0
- package/src/solana/solana-plugin.ts +103 -0
- package/src/solana/solana-processor.ts +102 -0
- package/src/solana/tests/abis/basic_1.json +62 -0
- package/src/solana/tests/abis/token_bridge.json +937 -0
- package/src/solana/tests/types/basic_1.ts +62 -0
- package/src/solana/tests/types/basic_1_processor.ts +42 -0
- package/src/solana/tests/types/token_bridge.ts +937 -0
- package/src/solana/tests/types/token_bridge_processor.ts +150 -0
- package/src/solana/tests/wormhole-token-bridge.ts +96 -0
- package/src/target-ethers-sentio/view-function.cts +4 -11
- package/src/testing/test-processor-server.ts +1 -1
- package/src/testing/test-provider.ts +1 -1
- package/src/utils/index.ts +0 -1
- package/lib/eth/eth-event.js +0 -2
- package/lib/eth/eth-event.js.map +0 -1
- package/lib/utils/chain.js.map +0 -1
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import path from 'path'
|
|
2
|
+
import fs from 'fs'
|
|
3
|
+
import chalk from 'chalk'
|
|
4
|
+
import { Idl } from '@project-serum/anchor'
|
|
5
|
+
import { IdlAccountItem, IdlField, IdlInstruction, IdlType } from '@project-serum/anchor/dist/cjs/idl.js'
|
|
6
|
+
|
|
7
|
+
export function codeGenSolanaProcessor(abisDir: string, targetPath = path.join('src', 'types', 'solana')) {
|
|
8
|
+
if (!fs.existsSync(abisDir)) {
|
|
9
|
+
return
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const abisFiles = fs.readdirSync(abisDir)
|
|
13
|
+
|
|
14
|
+
if (abisFiles.length > 0) {
|
|
15
|
+
console.log(chalk.green('Generated Types for Solana'))
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
for (const file of abisFiles) {
|
|
19
|
+
if (path.extname(file) === '.json') {
|
|
20
|
+
if (!fs.existsSync(targetPath)) {
|
|
21
|
+
fs.mkdirSync(targetPath, { recursive: true })
|
|
22
|
+
}
|
|
23
|
+
const idlContent = fs.readFileSync(path.join(abisDir, file), 'utf-8')
|
|
24
|
+
const idlObj = JSON.parse(idlContent)
|
|
25
|
+
const idlName = idlObj.name
|
|
26
|
+
const idlFile = path.join(targetPath, idlName + '.ts')
|
|
27
|
+
fs.writeFileSync(idlFile, `export const ${idlName}_idl = ${idlContent}`)
|
|
28
|
+
fs.writeFileSync(path.join(targetPath, `${idlName}_processor.ts`), codeGenSolanaIdlProcessor(idlObj))
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function codeGenSolanaIdlProcessor(idlObj: Idl): string {
|
|
34
|
+
const idlName = idlObj.name
|
|
35
|
+
const idlNamePascalCase = toPascalCase(idlName)
|
|
36
|
+
const instructions: any[] = idlObj.instructions
|
|
37
|
+
return `import { BorshInstructionCoder, Instruction, Idl } from '@project-serum/anchor'
|
|
38
|
+
import { SolanaBaseProcessor, SolanaContext, SolanaBindOptions } from "@sentio/sdk/solana"
|
|
39
|
+
import { ${idlName}_idl } from "./${idlName}.js"
|
|
40
|
+
import { PublicKey } from '@solana/web3.js'
|
|
41
|
+
|
|
42
|
+
export class ${idlNamePascalCase}Processor extends SolanaBaseProcessor {
|
|
43
|
+
static DEFAULT_OPTIONS = {
|
|
44
|
+
name: '${idlNamePascalCase}',
|
|
45
|
+
instructionCoder: new BorshInstructionCoder(${idlName}_idl as Idl)
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
static bind(options: SolanaBindOptions): ${idlNamePascalCase}Processor {
|
|
49
|
+
return new ${idlNamePascalCase}Processor( { ...${idlNamePascalCase}Processor.DEFAULT_OPTIONS, ...options })
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
${instructions.map((ins) => codeGenSolanaInstruction(idlNamePascalCase, ins)).join('')}
|
|
53
|
+
}
|
|
54
|
+
`
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function codeGenSolanaInstruction(idlName: string, ins: IdlInstruction): string {
|
|
58
|
+
const instructionName = ins.name
|
|
59
|
+
|
|
60
|
+
const argsType = codeGenInstructionArgsType(ins.args)
|
|
61
|
+
const accountType = codeGenAccountType(ins.accounts)
|
|
62
|
+
|
|
63
|
+
return `
|
|
64
|
+
on${
|
|
65
|
+
instructionName.charAt(0).toUpperCase() + instructionName.slice(1)
|
|
66
|
+
}(handler: (args: ${argsType}, accounts: ${accountType}, ctx: SolanaContext) => void): ${idlName}Processor {
|
|
67
|
+
this.onInstruction('${instructionName}', (ins: Instruction, ctx, accounts: string[]) => {
|
|
68
|
+
const origin = ins.data as any
|
|
69
|
+
if (origin) {
|
|
70
|
+
const data = ${codeGenInstructionArgs(ins.args)}
|
|
71
|
+
const accountData = ${codeGenAccountTypeArgs(ins.accounts)}
|
|
72
|
+
handler(data, accountData, ctx)
|
|
73
|
+
}
|
|
74
|
+
})
|
|
75
|
+
return this
|
|
76
|
+
}
|
|
77
|
+
`
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function codeGenInstructionArgs(args: IdlField[]): string {
|
|
81
|
+
return `{ ${args.map((arg) => codeGenInstructionArg(arg.name, arg.type)).join(', ')} }`
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function codeGenInstructionArg(name: string, type: IdlType): string {
|
|
85
|
+
const mType = mapType(type)
|
|
86
|
+
if (mType === 'bigint') {
|
|
87
|
+
return `${name}: BigInt(origin.${name}.toString())`
|
|
88
|
+
}
|
|
89
|
+
return `${name}: origin.${name} as ${mType}`
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function codeGenInstructionArgsType(args: IdlField[]): string {
|
|
93
|
+
return `{ ${args.map((arg) => arg.name + ': ' + mapType(arg.type)).join(', ')} }`
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function codeGenAccountType(args: IdlAccountItem[]): string {
|
|
97
|
+
return `{ ${args.map((arg) => arg.name + ': string').join(', ')} }`
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
function codeGenAccountTypeArgs(args: IdlAccountItem[]): string {
|
|
101
|
+
return `{ ${args.map((arg, idx) => `${arg.name}: accounts[${idx}]`).join(', ')} }`
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// Reference: https://github.com/coral-xyz/anchor/blob/93332766f13e86efbe77c9986722731742317ede/ts/src/program/namespace/types.ts#L104
|
|
105
|
+
function mapType(tpe: IdlType): string {
|
|
106
|
+
// TODO handle complex type
|
|
107
|
+
switch (tpe) {
|
|
108
|
+
case 'publicKey':
|
|
109
|
+
return 'PublicKey'
|
|
110
|
+
case 'bool':
|
|
111
|
+
return 'boolean'
|
|
112
|
+
case 'string':
|
|
113
|
+
return 'string'
|
|
114
|
+
case 'u8':
|
|
115
|
+
case 'i8':
|
|
116
|
+
case 'u16':
|
|
117
|
+
case 'i16':
|
|
118
|
+
case 'u32':
|
|
119
|
+
case 'i32':
|
|
120
|
+
case 'f32':
|
|
121
|
+
case 'f64':
|
|
122
|
+
return 'number'
|
|
123
|
+
case 'u64':
|
|
124
|
+
case 'i64':
|
|
125
|
+
case 'u128':
|
|
126
|
+
case 'i128':
|
|
127
|
+
return 'bigint'
|
|
128
|
+
default:
|
|
129
|
+
return 'any'
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
function toPascalCase(str: string) {
|
|
134
|
+
return `${str}`
|
|
135
|
+
.toLowerCase()
|
|
136
|
+
.replace(new RegExp(/[-_]+/, 'g'), ' ')
|
|
137
|
+
.replace(new RegExp(/[^\w\s]/, 'g'), '')
|
|
138
|
+
.replace(new RegExp(/\s+(.)(\w*)/, 'g'), ($1, $2, $3) => `${$2.toUpperCase() + $3}`)
|
|
139
|
+
.replace(new RegExp(/\w/), (s) => s.toUpperCase())
|
|
140
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './codegen.js'
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import path from 'path'
|
|
4
|
+
import { codeGenSolanaProcessor } from './codegen/codegen.js'
|
|
5
|
+
|
|
6
|
+
if (process.argv.length > 3) {
|
|
7
|
+
const abisDir = process.argv[2]
|
|
8
|
+
const targetDir = process.argv[3]
|
|
9
|
+
codeGenSolanaProcessor(abisDir, targetDir)
|
|
10
|
+
} else {
|
|
11
|
+
console.error('Not enough argument')
|
|
12
|
+
process.exit(1)
|
|
13
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { normalizeLabels, Labels, BaseContext, RecordMetaData, CHAIN_IDS } from '@sentio/sdk'
|
|
2
|
+
|
|
3
|
+
export class SolanaContext extends BaseContext {
|
|
4
|
+
network: string
|
|
5
|
+
address: string
|
|
6
|
+
programName: string
|
|
7
|
+
blockNumber: bigint
|
|
8
|
+
|
|
9
|
+
constructor(programName: string, network: string, address: string, slot: bigint) {
|
|
10
|
+
super()
|
|
11
|
+
this.network = network || CHAIN_IDS.SOLANA_MAINNET
|
|
12
|
+
this.programName = programName
|
|
13
|
+
this.address = address
|
|
14
|
+
this.blockNumber = slot
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
getMetaData(name: string, labels: Labels): RecordMetaData {
|
|
18
|
+
return {
|
|
19
|
+
address: this.address,
|
|
20
|
+
contractName: this.programName,
|
|
21
|
+
blockNumber: this.blockNumber,
|
|
22
|
+
transactionIndex: 0,
|
|
23
|
+
transactionHash: '', // TODO add
|
|
24
|
+
logIndex: 0,
|
|
25
|
+
chainId: this.network,
|
|
26
|
+
name: name,
|
|
27
|
+
labels: normalizeLabels(labels),
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { InstructionCoder } from './solana-processor.js'
|
|
2
|
+
|
|
3
|
+
export class SolanaBindOptions {
|
|
4
|
+
address: string
|
|
5
|
+
network?: string
|
|
6
|
+
name?: string
|
|
7
|
+
startBlock?: bigint | number
|
|
8
|
+
endBlock?: bigint | number
|
|
9
|
+
processInnerInstruction?: boolean
|
|
10
|
+
instructionCoder?: InstructionCoder
|
|
11
|
+
}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { errorString, mergeProcessResults, Plugin, PluginManager, USER_PROCESSOR } from '@sentio/runtime'
|
|
2
|
+
import { ContractConfig, DataBinding, HandlerType, ProcessConfigResponse, ProcessResult } from '@sentio/protos'
|
|
3
|
+
|
|
4
|
+
import { ServerError, Status } from 'nice-grpc'
|
|
5
|
+
|
|
6
|
+
import { SolanaProcessorState } from './solana-processor.js'
|
|
7
|
+
import { Instruction as SolInstruction } from '@project-serum/anchor'
|
|
8
|
+
|
|
9
|
+
export class SolanaPlugin extends Plugin {
|
|
10
|
+
name: string = 'SolanaPlugin'
|
|
11
|
+
|
|
12
|
+
async configure(config: ProcessConfigResponse) {
|
|
13
|
+
// Part 2, prepare solana constractors
|
|
14
|
+
for (const solanaProcessor of SolanaProcessorState.INSTANCE.getValues()) {
|
|
15
|
+
const contractConfig: ContractConfig = {
|
|
16
|
+
transactionConfig: [],
|
|
17
|
+
processorType: USER_PROCESSOR,
|
|
18
|
+
contract: {
|
|
19
|
+
name: solanaProcessor.contractName,
|
|
20
|
+
chainId: solanaProcessor.network,
|
|
21
|
+
address: solanaProcessor.address,
|
|
22
|
+
abi: '',
|
|
23
|
+
},
|
|
24
|
+
logConfigs: [],
|
|
25
|
+
traceConfigs: [],
|
|
26
|
+
intervalConfigs: [],
|
|
27
|
+
startBlock: solanaProcessor.config.startSlot,
|
|
28
|
+
endBlock: 0n,
|
|
29
|
+
instructionConfig: {
|
|
30
|
+
innerInstruction: solanaProcessor.processInnerInstruction,
|
|
31
|
+
parsedInstruction: solanaProcessor.fromParsedInstruction !== null,
|
|
32
|
+
rawDataInstruction: solanaProcessor.decodeInstruction !== null,
|
|
33
|
+
},
|
|
34
|
+
aptosEventConfigs: [],
|
|
35
|
+
aptosCallConfigs: [],
|
|
36
|
+
}
|
|
37
|
+
config.contractConfigs.push(contractConfig)
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
supportedHandlers = [HandlerType.SOL_INSTRUCTION]
|
|
42
|
+
|
|
43
|
+
processBinding(request: DataBinding): Promise<ProcessResult> {
|
|
44
|
+
switch (request.handlerType) {
|
|
45
|
+
case HandlerType.SOL_INSTRUCTION:
|
|
46
|
+
return this.processSolInstruction(request)
|
|
47
|
+
default:
|
|
48
|
+
throw new ServerError(Status.INVALID_ARGUMENT, 'No handle type registered ' + request.handlerType)
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
async processSolInstruction(request: DataBinding): Promise<ProcessResult> {
|
|
53
|
+
if (!request.data) {
|
|
54
|
+
throw new ServerError(Status.INVALID_ARGUMENT, 'instruction data cannot be empty')
|
|
55
|
+
}
|
|
56
|
+
if (!request.data.solInstruction) {
|
|
57
|
+
throw new ServerError(Status.INVALID_ARGUMENT, 'instruction data cannot be empty')
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const instruction = request.data.solInstruction
|
|
61
|
+
const promises: Promise<ProcessResult>[] = []
|
|
62
|
+
|
|
63
|
+
// Only have instruction handlers for solana processors
|
|
64
|
+
for (const processor of SolanaProcessorState.INSTANCE.getValues()) {
|
|
65
|
+
if (processor.address === instruction.programAccountId) {
|
|
66
|
+
let parsedInstruction: SolInstruction | null = null
|
|
67
|
+
|
|
68
|
+
try {
|
|
69
|
+
if (instruction.parsed) {
|
|
70
|
+
parsedInstruction = processor.getParsedInstruction(instruction.parsed as { type: string; info: any })
|
|
71
|
+
} else if (instruction.instructionData) {
|
|
72
|
+
parsedInstruction = processor.getParsedInstruction(instruction.instructionData)
|
|
73
|
+
}
|
|
74
|
+
} catch (e) {
|
|
75
|
+
throw new ServerError(
|
|
76
|
+
Status.INTERNAL,
|
|
77
|
+
'Failed to decode instruction: ' + JSON.stringify(instruction) + errorString(e)
|
|
78
|
+
)
|
|
79
|
+
}
|
|
80
|
+
if (parsedInstruction == null) {
|
|
81
|
+
continue
|
|
82
|
+
}
|
|
83
|
+
const insHandler = processor.getInstructionHandler(parsedInstruction)
|
|
84
|
+
if (insHandler == null) {
|
|
85
|
+
continue
|
|
86
|
+
}
|
|
87
|
+
const res = processor
|
|
88
|
+
.handleInstruction(parsedInstruction, instruction.accounts, insHandler, instruction.slot)
|
|
89
|
+
.catch((e) => {
|
|
90
|
+
throw new ServerError(
|
|
91
|
+
Status.INTERNAL,
|
|
92
|
+
'Error processing instruction: ' + JSON.stringify(instruction) + '\n' + errorString(e)
|
|
93
|
+
)
|
|
94
|
+
})
|
|
95
|
+
|
|
96
|
+
promises.push(res)
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
return mergeProcessResults(await Promise.all(promises))
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
PluginManager.INSTANCE.register(new SolanaPlugin())
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { ProcessResult } from '@sentio/protos'
|
|
2
|
+
import { SolanaContext } from './solana-context.js'
|
|
3
|
+
import { Instruction } from '@project-serum/anchor'
|
|
4
|
+
import { SolanaBindOptions } from './solana-options.js'
|
|
5
|
+
import { ListStateStorage } from '@sentio/runtime'
|
|
6
|
+
import { CHAIN_IDS } from '@sentio/sdk'
|
|
7
|
+
|
|
8
|
+
type IndexConfigure = {
|
|
9
|
+
startSlot: bigint
|
|
10
|
+
endSlot?: bigint
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export interface InstructionCoder {
|
|
14
|
+
decode(ix: Buffer | string, encoding?: 'hex' | 'base58'): Instruction | null
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export type SolanaInstructionHandler = (instruction: Instruction, ctx: SolanaContext, accounts?: string[]) => void
|
|
18
|
+
|
|
19
|
+
export class SolanaProcessorState extends ListStateStorage<SolanaBaseProcessor> {
|
|
20
|
+
static INSTANCE: SolanaProcessorState = new SolanaProcessorState()
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export class SolanaBaseProcessor {
|
|
24
|
+
public instructionHandlerMap: Map<string, SolanaInstructionHandler> = new Map()
|
|
25
|
+
address: string
|
|
26
|
+
endpoint: string
|
|
27
|
+
contractName: string
|
|
28
|
+
network: string
|
|
29
|
+
processInnerInstruction: boolean
|
|
30
|
+
config: IndexConfigure = { startSlot: 0n }
|
|
31
|
+
instructionCoder: InstructionCoder
|
|
32
|
+
|
|
33
|
+
decodeInstruction(rawInstruction: string): Instruction | null {
|
|
34
|
+
if (this.instructionCoder) {
|
|
35
|
+
return this.instructionCoder.decode(rawInstruction, 'base58')
|
|
36
|
+
}
|
|
37
|
+
return null
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
fromParsedInstruction: (instruction: { type: string; info: any }) => Instruction | null
|
|
41
|
+
|
|
42
|
+
constructor(options: SolanaBindOptions) {
|
|
43
|
+
this.address = options.address
|
|
44
|
+
this.contractName = options.name || ''
|
|
45
|
+
this.processInnerInstruction = options.processInnerInstruction || false
|
|
46
|
+
this.network = options.network || CHAIN_IDS.SOLANA_MAINNET
|
|
47
|
+
if (options.instructionCoder) {
|
|
48
|
+
this.instructionCoder = options.instructionCoder
|
|
49
|
+
}
|
|
50
|
+
if (options.startBlock) {
|
|
51
|
+
this.startSlot(options.startBlock)
|
|
52
|
+
}
|
|
53
|
+
if (options.endBlock) {
|
|
54
|
+
this.endBlock(options.endBlock)
|
|
55
|
+
}
|
|
56
|
+
this.endpoint = options.network || 'https://api.mainnet-beta.solana.com'
|
|
57
|
+
|
|
58
|
+
SolanaProcessorState.INSTANCE.addValue(this)
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
public onInstruction(instructionName: string, handler: SolanaInstructionHandler) {
|
|
62
|
+
this.instructionHandlerMap.set(instructionName, handler)
|
|
63
|
+
return this
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
public getParsedInstruction(ins: string | { type: string; info: any }): Instruction | null {
|
|
67
|
+
if (ins) {
|
|
68
|
+
if ((ins as { type: string; info: any }).info) {
|
|
69
|
+
return this.fromParsedInstruction ? this.fromParsedInstruction(ins as { type: string; info: any }) : null
|
|
70
|
+
}
|
|
71
|
+
if (this.decodeInstruction != null) {
|
|
72
|
+
return this.decodeInstruction(ins as string)
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return null
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
public getInstructionHandler(parsedInstruction: Instruction): SolanaInstructionHandler | undefined {
|
|
79
|
+
return this.instructionHandlerMap.get(parsedInstruction.name)
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
public async handleInstruction(
|
|
83
|
+
parsedInstruction: Instruction,
|
|
84
|
+
accounts: string[],
|
|
85
|
+
handler: SolanaInstructionHandler,
|
|
86
|
+
slot: bigint
|
|
87
|
+
): Promise<ProcessResult> {
|
|
88
|
+
const ctx = new SolanaContext(this.contractName, this.network, this.address, slot)
|
|
89
|
+
await handler(parsedInstruction, ctx, accounts)
|
|
90
|
+
return ctx.getProcessResult()
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
public startSlot(startSlot: bigint | number) {
|
|
94
|
+
this.config.startSlot = BigInt(startSlot)
|
|
95
|
+
return this
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
public endBlock(endBlock: bigint | number) {
|
|
99
|
+
this.config.endSlot = BigInt(endBlock)
|
|
100
|
+
return this
|
|
101
|
+
}
|
|
102
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
{
|
|
2
|
+
"accounts": [
|
|
3
|
+
{
|
|
4
|
+
"name": "MyAccount",
|
|
5
|
+
"type": {
|
|
6
|
+
"kind": "struct",
|
|
7
|
+
"fields": [
|
|
8
|
+
{
|
|
9
|
+
"name": "data",
|
|
10
|
+
"type": "u64"
|
|
11
|
+
}
|
|
12
|
+
]
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
],
|
|
16
|
+
"instructions": [
|
|
17
|
+
{
|
|
18
|
+
"name": "initialize",
|
|
19
|
+
"accounts": [
|
|
20
|
+
{
|
|
21
|
+
"name": "myAccount",
|
|
22
|
+
"isMut": true,
|
|
23
|
+
"isSigner": true
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
"name": "user",
|
|
27
|
+
"isMut": true,
|
|
28
|
+
"isSigner": true
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
"name": "systemProgram",
|
|
32
|
+
"isMut": false,
|
|
33
|
+
"isSigner": false
|
|
34
|
+
}
|
|
35
|
+
],
|
|
36
|
+
"args": [
|
|
37
|
+
{
|
|
38
|
+
"name": "data",
|
|
39
|
+
"type": "u64"
|
|
40
|
+
}
|
|
41
|
+
]
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
"name": "update",
|
|
45
|
+
"accounts": [
|
|
46
|
+
{
|
|
47
|
+
"name": "myAccount",
|
|
48
|
+
"isMut": true,
|
|
49
|
+
"isSigner": false
|
|
50
|
+
}
|
|
51
|
+
],
|
|
52
|
+
"args": [
|
|
53
|
+
{
|
|
54
|
+
"name": "data",
|
|
55
|
+
"type": "u64"
|
|
56
|
+
}
|
|
57
|
+
]
|
|
58
|
+
}
|
|
59
|
+
],
|
|
60
|
+
"name": "basic_1",
|
|
61
|
+
"version": "0.1.0"
|
|
62
|
+
}
|