@sentio/sdk 1.36.3 → 1.36.4
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/LICENSE +55 -0
- package/lib/aptos/aptos-plugin.d.ts +14 -0
- package/lib/aptos/aptos-plugin.js +190 -0
- package/lib/aptos/aptos-plugin.js.map +1 -0
- package/lib/aptos/index.d.ts +1 -0
- package/lib/aptos/index.js +3 -1
- package/lib/aptos/index.js.map +1 -1
- package/lib/core/eth-plugin.d.ts +14 -0
- package/lib/core/eth-plugin.js +221 -0
- package/lib/core/eth-plugin.js.map +1 -0
- package/lib/core/index.d.ts +3 -0
- package/lib/core/index.js +7 -1
- package/lib/core/index.js.map +1 -1
- package/lib/core/solana-plugin.d.ts +9 -0
- package/lib/core/solana-plugin.js +79 -0
- package/lib/core/solana-plugin.js.map +1 -0
- package/lib/core/sui-plugin.d.ts +8 -0
- package/lib/core/sui-plugin.js +46 -0
- package/lib/core/sui-plugin.js.map +1 -0
- package/lib/gen/index.d.ts +2 -1
- package/lib/gen/index.js +2 -1
- package/lib/gen/index.js.map +1 -1
- package/lib/plugin.d.ts +15 -0
- package/lib/plugin.js +32 -0
- package/lib/plugin.js.map +1 -0
- package/lib/processor-runner.js +0 -0
- package/lib/service.d.ts +7 -19
- package/lib/service.js +36 -486
- package/lib/service.js.map +1 -1
- package/package.json +6 -12
- package/src/aptos/aptos-plugin.ts +217 -0
- package/src/aptos/index.ts +2 -0
- package/src/core/eth-plugin.ts +255 -0
- package/src/core/index.ts +4 -0
- package/src/core/solana-plugin.ts +97 -0
- package/src/core/sui-plugin.ts +54 -0
- package/src/gen/index.ts +3 -1
- package/src/plugin.ts +41 -0
- package/src/service.ts +32 -563
- package/src/target-ethers-sentio/tsconfig.json +1 -1
- package/src/types/global.d.ts +15 -0
- package/lib/release.config.js +0 -39
package/src/service.ts
CHANGED
|
@@ -1,20 +1,8 @@
|
|
|
1
|
-
import { Block, Log } from '@ethersproject/abstract-provider'
|
|
2
1
|
import { CallContext, ServerError, Status } from 'nice-grpc'
|
|
3
|
-
import { CHAIN_IDS } from './utils/chain'
|
|
4
2
|
|
|
5
3
|
import {
|
|
6
|
-
AccountConfig,
|
|
7
|
-
AptosCallHandlerConfig,
|
|
8
|
-
AptosEventHandlerConfig,
|
|
9
|
-
ContractConfig,
|
|
10
|
-
Data_SolInstruction,
|
|
11
4
|
DataBinding,
|
|
12
|
-
EventTrackingConfig,
|
|
13
|
-
ExportConfig,
|
|
14
5
|
HandlerType,
|
|
15
|
-
LogFilter,
|
|
16
|
-
LogHandlerConfig,
|
|
17
|
-
MetricConfig,
|
|
18
6
|
ProcessBindingResponse,
|
|
19
7
|
ProcessBindingsRequest,
|
|
20
8
|
ProcessConfigRequest,
|
|
@@ -22,63 +10,31 @@ import {
|
|
|
22
10
|
ProcessorServiceImplementation,
|
|
23
11
|
ProcessResult,
|
|
24
12
|
StartRequest,
|
|
25
|
-
TemplateInstance,
|
|
26
13
|
} from './gen'
|
|
27
14
|
|
|
28
15
|
import { Empty } from './gen/google/protobuf/empty'
|
|
29
16
|
import Long from 'long'
|
|
30
|
-
import { Trace } from './core'
|
|
31
|
-
import { Instruction as SolInstruction } from '@project-serum/anchor'
|
|
32
17
|
import { MetricState } from './core/meter'
|
|
33
18
|
import { ExporterState } from './core/exporter'
|
|
34
19
|
import { EventTrackerState } from './core/event-tracker'
|
|
35
|
-
import {
|
|
36
|
-
AptosAccountProcessorState,
|
|
37
|
-
AptosProcessorState,
|
|
38
|
-
MoveResourcesWithVersionPayload,
|
|
39
|
-
} from './aptos/aptos-processor'
|
|
40
|
-
import { AccountProcessorState } from './core/account-processor'
|
|
41
|
-
import { SuiProcessorState } from './core/sui-processor'
|
|
42
|
-
import { SolanaProcessorState } from './core/solana-processor'
|
|
43
|
-
import { ProcessorState } from './binds'
|
|
44
20
|
import { ProcessorTemplateProcessorState, TemplateInstanceState } from './core/base-processor-template'
|
|
45
|
-
import { toBigInt } from './core/numberish'
|
|
46
|
-
import { MoveResource, Transaction_UserTransaction } from 'aptos-sdk/src/generated'
|
|
47
21
|
|
|
48
22
|
// (Long.prototype as any).toBigInt = function() {
|
|
49
23
|
// return BigInt(this.toString())
|
|
50
24
|
// };
|
|
25
|
+
import { PluginManager } from './plugin'
|
|
51
26
|
;(BigInt.prototype as any).toJSON = function () {
|
|
52
27
|
return this.toString()
|
|
53
28
|
}
|
|
54
29
|
|
|
55
|
-
const DEFAULT_MAX_BLOCK = Long.ZERO
|
|
30
|
+
export const DEFAULT_MAX_BLOCK = Long.ZERO
|
|
56
31
|
|
|
57
|
-
const USER_PROCESSOR = 'user_processor'
|
|
32
|
+
export const USER_PROCESSOR = 'user_processor'
|
|
58
33
|
|
|
59
34
|
export class ProcessorServiceImpl implements ProcessorServiceImplementation {
|
|
60
|
-
// eth handlers
|
|
61
|
-
private eventHandlers: ((event: Log) => Promise<ProcessResult>)[] = []
|
|
62
|
-
private traceHandlers: ((trace: Trace) => Promise<ProcessResult>)[] = []
|
|
63
|
-
private blockHandlers: ((block: Block) => Promise<ProcessResult>)[] = []
|
|
64
|
-
|
|
65
|
-
// aptos handlers
|
|
66
|
-
private aptosEventHandlers: ((event: any) => Promise<ProcessResult>)[] = []
|
|
67
|
-
private aptosCallHandlers: ((func: any) => Promise<ProcessResult>)[] = []
|
|
68
|
-
private aptosResourceHandlers: ((resourceWithVersion: MoveResourcesWithVersionPayload) => Promise<ProcessResult>)[] =
|
|
69
|
-
[]
|
|
70
|
-
|
|
71
|
-
// map from chain id to list of processors
|
|
72
|
-
// private blockHandlers = new Map<string, ((block: Block) => Promise<ProcessResult>)[]>()
|
|
73
|
-
// private processorsByChainId = new Map<string, BaseProcessor<BaseContract, BoundContractView<BaseContract, any>>>()
|
|
74
|
-
|
|
75
35
|
private started = false
|
|
76
|
-
private
|
|
77
|
-
|
|
78
|
-
private templateInstances: TemplateInstance[]
|
|
79
|
-
private metricConfigs: MetricConfig[]
|
|
80
|
-
private eventTrackingConfigs: EventTrackingConfig[]
|
|
81
|
-
private exportConfigs: ExportConfig[]
|
|
36
|
+
private processorConfig: ProcessConfigResponse
|
|
37
|
+
|
|
82
38
|
private readonly loader: () => void
|
|
83
39
|
|
|
84
40
|
private readonly shutdownHandler?: () => void
|
|
@@ -92,40 +48,26 @@ export class ProcessorServiceImpl implements ProcessorServiceImplementation {
|
|
|
92
48
|
if (!this.started) {
|
|
93
49
|
throw new ServerError(Status.UNAVAILABLE, 'Service Not started.')
|
|
94
50
|
}
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
config: undefined,
|
|
98
|
-
contractConfigs: this.contractConfigs,
|
|
99
|
-
accountConfigs: this.accountConfigs,
|
|
100
|
-
templateInstances: this.templateInstances,
|
|
101
|
-
eventTrackingConfigs: this.eventTrackingConfigs,
|
|
102
|
-
metricConfigs: this.metricConfigs,
|
|
103
|
-
exportConfigs: this.exportConfigs,
|
|
51
|
+
if (!this.processorConfig) {
|
|
52
|
+
throw new ServerError(Status.INTERNAL, 'Process config empty.')
|
|
104
53
|
}
|
|
54
|
+
return this.processorConfig
|
|
105
55
|
}
|
|
106
56
|
|
|
107
57
|
async configure() {
|
|
108
|
-
this.
|
|
109
|
-
this.templateInstances = []
|
|
110
|
-
// this.processorsByChainId.clear()
|
|
111
|
-
this.contractConfigs = []
|
|
112
|
-
this.accountConfigs = []
|
|
113
|
-
|
|
58
|
+
this.processorConfig = ProcessConfigResponse.fromPartial({})
|
|
114
59
|
// This syntax is to copy values instead of using references
|
|
115
|
-
this.templateInstances = [...TemplateInstanceState.INSTANCE.getValues()]
|
|
116
|
-
this.eventTrackingConfigs = []
|
|
117
|
-
this.metricConfigs = []
|
|
118
|
-
this.exportConfigs = []
|
|
60
|
+
this.processorConfig.templateInstances = [...TemplateInstanceState.INSTANCE.getValues()]
|
|
119
61
|
|
|
120
62
|
// part 0, prepare metrics and event tracking configs
|
|
121
63
|
for (const metric of MetricState.INSTANCE.getValues()) {
|
|
122
|
-
this.metricConfigs.push({
|
|
64
|
+
this.processorConfig.metricConfigs.push({
|
|
123
65
|
...metric.config,
|
|
124
66
|
})
|
|
125
67
|
}
|
|
126
68
|
|
|
127
69
|
for (const eventTracker of EventTrackerState.INSTANCE.getValues()) {
|
|
128
|
-
this.eventTrackingConfigs.push({
|
|
70
|
+
this.processorConfig.eventTrackingConfigs.push({
|
|
129
71
|
distinctAggregationByDays: eventTracker.options.distinctByDays || [],
|
|
130
72
|
eventName: eventTracker.name,
|
|
131
73
|
retentionConfig: undefined,
|
|
@@ -136,271 +78,13 @@ export class ProcessorServiceImpl implements ProcessorServiceImplementation {
|
|
|
136
78
|
}
|
|
137
79
|
|
|
138
80
|
for (const exporter of ExporterState.INSTANCE.getValues()) {
|
|
139
|
-
this.exportConfigs.push({
|
|
81
|
+
this.processorConfig.exportConfigs.push({
|
|
140
82
|
name: exporter.name,
|
|
141
83
|
channel: exporter.channel,
|
|
142
84
|
})
|
|
143
85
|
}
|
|
144
86
|
|
|
145
|
-
|
|
146
|
-
for (const processor of ProcessorState.INSTANCE.getValues()) {
|
|
147
|
-
// If server favor incremental update this need to change
|
|
148
|
-
// Start basic config for contract
|
|
149
|
-
const chainId = processor.getChainId()
|
|
150
|
-
// this.processorsByChainId.set(chainId, processor)
|
|
151
|
-
|
|
152
|
-
const contractConfig: ContractConfig = {
|
|
153
|
-
processorType: USER_PROCESSOR,
|
|
154
|
-
contract: {
|
|
155
|
-
name: processor.config.name,
|
|
156
|
-
chainId: chainId.toString(),
|
|
157
|
-
address: processor.config.address,
|
|
158
|
-
abi: '',
|
|
159
|
-
},
|
|
160
|
-
intervalConfigs: [],
|
|
161
|
-
logConfigs: [],
|
|
162
|
-
traceConfigs: [],
|
|
163
|
-
startBlock: processor.config.startBlock,
|
|
164
|
-
endBlock: DEFAULT_MAX_BLOCK,
|
|
165
|
-
instructionConfig: undefined,
|
|
166
|
-
aptosEventConfigs: [],
|
|
167
|
-
aptosCallConfigs: [],
|
|
168
|
-
}
|
|
169
|
-
if (processor.config.endBlock) {
|
|
170
|
-
contractConfig.endBlock = processor.config.endBlock
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
// Step 1. Prepare all the block handlers
|
|
174
|
-
for (const blockHandler of processor.blockHandlers) {
|
|
175
|
-
const handlerId = this.blockHandlers.push(blockHandler.handler) - 1
|
|
176
|
-
// TODO wrap the block handler into one
|
|
177
|
-
|
|
178
|
-
contractConfig.intervalConfigs.push({
|
|
179
|
-
slot: 0,
|
|
180
|
-
slotInterval: blockHandler.blockInterval,
|
|
181
|
-
minutes: 0,
|
|
182
|
-
minutesInterval: blockHandler.timeIntervalInMinutes,
|
|
183
|
-
handlerId: handlerId,
|
|
184
|
-
})
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
// Step 2. Prepare all trace handlers
|
|
188
|
-
for (const traceHandler of processor.traceHandlers) {
|
|
189
|
-
const handlerId = this.traceHandlers.push(traceHandler.handler) - 1
|
|
190
|
-
contractConfig.traceConfigs.push({
|
|
191
|
-
signature: traceHandler.signature,
|
|
192
|
-
handlerId: handlerId,
|
|
193
|
-
})
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
// Step 3. Prepare all the event handlers
|
|
197
|
-
for (const eventsHandler of processor.eventHandlers) {
|
|
198
|
-
// associate id with filter
|
|
199
|
-
const handlerId = this.eventHandlers.push(eventsHandler.handler) - 1
|
|
200
|
-
const logConfig: LogHandlerConfig = {
|
|
201
|
-
handlerId: handlerId,
|
|
202
|
-
filters: [],
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
for (const filter of eventsHandler.filters) {
|
|
206
|
-
if (!filter.topics) {
|
|
207
|
-
throw new ServerError(Status.INVALID_ARGUMENT, 'Topic should not be null')
|
|
208
|
-
}
|
|
209
|
-
const logFilter: LogFilter = {
|
|
210
|
-
addressType: undefined,
|
|
211
|
-
address: contractConfig.contract?.address,
|
|
212
|
-
topics: [],
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
for (const ts of filter.topics) {
|
|
216
|
-
let hashes: string[] = []
|
|
217
|
-
if (Array.isArray(ts)) {
|
|
218
|
-
hashes = hashes.concat(ts)
|
|
219
|
-
} else if (ts) {
|
|
220
|
-
hashes.push(ts)
|
|
221
|
-
}
|
|
222
|
-
logFilter.topics.push({ hashes: hashes })
|
|
223
|
-
}
|
|
224
|
-
logConfig.filters.push(logFilter)
|
|
225
|
-
}
|
|
226
|
-
contractConfig.logConfigs.push(logConfig)
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
// Finish up a contract
|
|
230
|
-
this.contractConfigs.push(contractConfig)
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
// part 1.b prepare EVM account processors
|
|
234
|
-
for (const processor of AccountProcessorState.INSTANCE.getValues()) {
|
|
235
|
-
const accountConfig: AccountConfig = {
|
|
236
|
-
address: processor.config.address,
|
|
237
|
-
chainId: processor.getChainId().toString(),
|
|
238
|
-
startBlock: processor.config.startBlock ? Long.fromValue(processor.config.startBlock) : Long.ZERO,
|
|
239
|
-
aptosIntervalConfigs: [],
|
|
240
|
-
intervalConfigs: [],
|
|
241
|
-
logConfigs: [],
|
|
242
|
-
}
|
|
243
|
-
// TODO add interval
|
|
244
|
-
for (const eventsHandler of processor.eventHandlers) {
|
|
245
|
-
// associate id with filter
|
|
246
|
-
const handlerId = this.eventHandlers.push(eventsHandler.handler) - 1
|
|
247
|
-
const logConfig: LogHandlerConfig = {
|
|
248
|
-
handlerId: handlerId,
|
|
249
|
-
filters: [],
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
for (const filter of eventsHandler.filters) {
|
|
253
|
-
if (!filter.topics) {
|
|
254
|
-
throw new ServerError(Status.INVALID_ARGUMENT, 'Topic should not be null')
|
|
255
|
-
}
|
|
256
|
-
const logFilter: LogFilter = {
|
|
257
|
-
addressType: filter.addressType,
|
|
258
|
-
address: filter.address,
|
|
259
|
-
topics: [],
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
for (const ts of filter.topics) {
|
|
263
|
-
let hashes: string[] = []
|
|
264
|
-
if (Array.isArray(ts)) {
|
|
265
|
-
hashes = hashes.concat(ts)
|
|
266
|
-
} else if (ts) {
|
|
267
|
-
hashes.push(ts)
|
|
268
|
-
}
|
|
269
|
-
logFilter.topics.push({ hashes: hashes })
|
|
270
|
-
}
|
|
271
|
-
logConfig.filters.push(logFilter)
|
|
272
|
-
}
|
|
273
|
-
accountConfig.logConfigs.push(logConfig)
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
this.accountConfigs.push(accountConfig)
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
// Part 2, prepare solana constractors
|
|
280
|
-
for (const solanaProcessor of SolanaProcessorState.INSTANCE.getValues()) {
|
|
281
|
-
const contractConfig: ContractConfig = {
|
|
282
|
-
processorType: USER_PROCESSOR,
|
|
283
|
-
contract: {
|
|
284
|
-
name: solanaProcessor.contractName,
|
|
285
|
-
chainId: solanaProcessor.network,
|
|
286
|
-
address: solanaProcessor.address,
|
|
287
|
-
abi: '',
|
|
288
|
-
},
|
|
289
|
-
logConfigs: [],
|
|
290
|
-
traceConfigs: [],
|
|
291
|
-
intervalConfigs: [],
|
|
292
|
-
startBlock: solanaProcessor.config.startSlot,
|
|
293
|
-
endBlock: DEFAULT_MAX_BLOCK,
|
|
294
|
-
instructionConfig: {
|
|
295
|
-
innerInstruction: solanaProcessor.processInnerInstruction,
|
|
296
|
-
parsedInstruction: solanaProcessor.fromParsedInstruction !== null,
|
|
297
|
-
rawDataInstruction: solanaProcessor.decodeInstruction !== null,
|
|
298
|
-
},
|
|
299
|
-
aptosEventConfigs: [],
|
|
300
|
-
aptosCallConfigs: [],
|
|
301
|
-
}
|
|
302
|
-
this.contractConfigs.push(contractConfig)
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
// Part 3, prepare sui constractors
|
|
306
|
-
for (const suiProcessor of SuiProcessorState.INSTANCE.getValues()) {
|
|
307
|
-
const contractConfig: ContractConfig = {
|
|
308
|
-
processorType: USER_PROCESSOR,
|
|
309
|
-
contract: {
|
|
310
|
-
name: 'sui contract',
|
|
311
|
-
chainId: CHAIN_IDS.SUI_DEVNET,
|
|
312
|
-
address: suiProcessor.address,
|
|
313
|
-
abi: '',
|
|
314
|
-
},
|
|
315
|
-
logConfigs: [],
|
|
316
|
-
intervalConfigs: [],
|
|
317
|
-
traceConfigs: [],
|
|
318
|
-
startBlock: suiProcessor.config.startSeqNumber,
|
|
319
|
-
endBlock: DEFAULT_MAX_BLOCK,
|
|
320
|
-
instructionConfig: undefined,
|
|
321
|
-
aptosEventConfigs: [],
|
|
322
|
-
aptosCallConfigs: [],
|
|
323
|
-
}
|
|
324
|
-
this.contractConfigs.push(contractConfig)
|
|
325
|
-
}
|
|
326
|
-
|
|
327
|
-
// Part 4, prepare aptos constractors
|
|
328
|
-
for (const aptosProcessor of AptosProcessorState.INSTANCE.getValues()) {
|
|
329
|
-
const contractConfig: ContractConfig = {
|
|
330
|
-
processorType: USER_PROCESSOR,
|
|
331
|
-
contract: {
|
|
332
|
-
name: aptosProcessor.moduleName,
|
|
333
|
-
chainId: aptosProcessor.getChainId(),
|
|
334
|
-
address: aptosProcessor.config.address,
|
|
335
|
-
abi: '',
|
|
336
|
-
},
|
|
337
|
-
intervalConfigs: [],
|
|
338
|
-
logConfigs: [],
|
|
339
|
-
traceConfigs: [],
|
|
340
|
-
startBlock: Long.fromString(aptosProcessor.config.startVersion.toString()),
|
|
341
|
-
endBlock: DEFAULT_MAX_BLOCK,
|
|
342
|
-
instructionConfig: undefined,
|
|
343
|
-
aptosEventConfigs: [],
|
|
344
|
-
aptosCallConfigs: [],
|
|
345
|
-
}
|
|
346
|
-
// 1. Prepare event handlers
|
|
347
|
-
for (const handler of aptosProcessor.eventHandlers) {
|
|
348
|
-
const handlerId = this.aptosEventHandlers.push(handler.handler) - 1
|
|
349
|
-
const eventHandlerConfig: AptosEventHandlerConfig = {
|
|
350
|
-
filters: handler.filters.map((f) => {
|
|
351
|
-
return {
|
|
352
|
-
type: f.type,
|
|
353
|
-
account: f.account || '',
|
|
354
|
-
}
|
|
355
|
-
}),
|
|
356
|
-
handlerId,
|
|
357
|
-
}
|
|
358
|
-
contractConfig.aptosEventConfigs.push(eventHandlerConfig)
|
|
359
|
-
}
|
|
360
|
-
|
|
361
|
-
// 2. Prepare function handlers
|
|
362
|
-
for (const handler of aptosProcessor.callHandlers) {
|
|
363
|
-
const handlerId = this.aptosCallHandlers.push(handler.handler) - 1
|
|
364
|
-
const functionHandlerConfig: AptosCallHandlerConfig = {
|
|
365
|
-
filters: handler.filters.map((filter) => {
|
|
366
|
-
return {
|
|
367
|
-
function: filter.function,
|
|
368
|
-
typeArguments: filter.typeArguments || [],
|
|
369
|
-
withTypeArguments: filter.typeArguments ? true : false,
|
|
370
|
-
includeFailed: filter.includeFailed || false,
|
|
371
|
-
}
|
|
372
|
-
}),
|
|
373
|
-
handlerId,
|
|
374
|
-
}
|
|
375
|
-
contractConfig.aptosCallConfigs.push(functionHandlerConfig)
|
|
376
|
-
}
|
|
377
|
-
this.contractConfigs.push(contractConfig)
|
|
378
|
-
}
|
|
379
|
-
|
|
380
|
-
for (const aptosProcessor of AptosAccountProcessorState.INSTANCE.getValues()) {
|
|
381
|
-
const accountConfig: AccountConfig = {
|
|
382
|
-
address: aptosProcessor.config.address,
|
|
383
|
-
chainId: aptosProcessor.getChainId(),
|
|
384
|
-
startBlock: Long.fromValue(aptosProcessor.config.startVersion.toString()),
|
|
385
|
-
aptosIntervalConfigs: [],
|
|
386
|
-
intervalConfigs: [],
|
|
387
|
-
logConfigs: [],
|
|
388
|
-
}
|
|
389
|
-
for (const handler of aptosProcessor.resourcesHandlers) {
|
|
390
|
-
const handlerId = this.aptosResourceHandlers.push(handler.handler) - 1
|
|
391
|
-
accountConfig.aptosIntervalConfigs.push({
|
|
392
|
-
intervalConfig: {
|
|
393
|
-
handlerId: handlerId,
|
|
394
|
-
minutes: 0,
|
|
395
|
-
minutesInterval: handler.timeIntervalInMinutes,
|
|
396
|
-
slot: 0,
|
|
397
|
-
slotInterval: handler.versionInterval,
|
|
398
|
-
},
|
|
399
|
-
type: handler.type || '',
|
|
400
|
-
})
|
|
401
|
-
}
|
|
402
|
-
this.accountConfigs.push(accountConfig)
|
|
403
|
-
}
|
|
87
|
+
PluginManager.INSTANCE.configure(this.processorConfig)
|
|
404
88
|
}
|
|
405
89
|
|
|
406
90
|
async start(request: StartRequest, context: CallContext): Promise<Empty> {
|
|
@@ -409,6 +93,18 @@ export class ProcessorServiceImpl implements ProcessorServiceImplementation {
|
|
|
409
93
|
}
|
|
410
94
|
|
|
411
95
|
try {
|
|
96
|
+
try {
|
|
97
|
+
require('./core/eth-plugin')
|
|
98
|
+
require('./core/sui-plugin')
|
|
99
|
+
require('./aptos/aptos-plugin')
|
|
100
|
+
require('./core/solana-plugin')
|
|
101
|
+
} catch (e) {
|
|
102
|
+
require('@sentio/sdk/lib/core/eth-plugin')
|
|
103
|
+
require('@sentio/sdk/lib/core/sui-plugin')
|
|
104
|
+
require('@sentio/sdk/lib/aptos/aptos-plugin')
|
|
105
|
+
require('@sentio/sdk/lib/core/solana-plugin')
|
|
106
|
+
}
|
|
107
|
+
|
|
412
108
|
this.loader()
|
|
413
109
|
} catch (e) {
|
|
414
110
|
throw new ServerError(Status.INVALID_ARGUMENT, 'Failed to load processor: ' + errorString(e))
|
|
@@ -457,7 +153,7 @@ export class ProcessorServiceImpl implements ProcessorServiceImplementation {
|
|
|
457
153
|
|
|
458
154
|
let updated = false
|
|
459
155
|
const t = TemplateInstanceState.INSTANCE.getValues()
|
|
460
|
-
if (TemplateInstanceState.INSTANCE.getValues().length !== this.templateInstances.length) {
|
|
156
|
+
if (TemplateInstanceState.INSTANCE.getValues().length !== this.processorConfig.templateInstances.length) {
|
|
461
157
|
await this.configure()
|
|
462
158
|
updated = true
|
|
463
159
|
}
|
|
@@ -469,31 +165,7 @@ export class ProcessorServiceImpl implements ProcessorServiceImplementation {
|
|
|
469
165
|
}
|
|
470
166
|
|
|
471
167
|
async processBinding(request: DataBinding, options?: CallContext): Promise<ProcessResult> {
|
|
472
|
-
const
|
|
473
|
-
switch (request.handlerType) {
|
|
474
|
-
case HandlerType.APT_CALL:
|
|
475
|
-
return this.processAptosFunctionCall(request)
|
|
476
|
-
case HandlerType.APT_EVENT:
|
|
477
|
-
return this.processAptosEvent(request)
|
|
478
|
-
case HandlerType.APT_RESOURCE:
|
|
479
|
-
return this.processAptosResource(request)
|
|
480
|
-
case HandlerType.ETH_LOG:
|
|
481
|
-
return this.processLog(request)
|
|
482
|
-
case HandlerType.ETH_TRACE:
|
|
483
|
-
return this.processTrace(request)
|
|
484
|
-
case HandlerType.ETH_BLOCK:
|
|
485
|
-
return this.processBlock(request)
|
|
486
|
-
case HandlerType.SOL_INSTRUCTION:
|
|
487
|
-
return this.processSolInstruction(request)
|
|
488
|
-
// TODO migrate SUI cases
|
|
489
|
-
// case HandlerType.INSTRUCTION:
|
|
490
|
-
// return this.processInstruction(request)
|
|
491
|
-
default:
|
|
492
|
-
throw new ServerError(Status.INVALID_ARGUMENT, 'No handle type registered ' + request.handlerType)
|
|
493
|
-
}
|
|
494
|
-
}
|
|
495
|
-
|
|
496
|
-
const result = await processBindingInternal(request)
|
|
168
|
+
const result = await PluginManager.INSTANCE.processBinding(request)
|
|
497
169
|
recordRuntimeInfo(result, request.handlerType)
|
|
498
170
|
return result
|
|
499
171
|
}
|
|
@@ -502,7 +174,7 @@ export class ProcessorServiceImpl implements ProcessorServiceImplementation {
|
|
|
502
174
|
for await (const request of requests) {
|
|
503
175
|
const result = await this.processBinding(request)
|
|
504
176
|
let updated = false
|
|
505
|
-
if (TemplateInstanceState.INSTANCE.getValues().length !== this.templateInstances.length) {
|
|
177
|
+
if (TemplateInstanceState.INSTANCE.getValues().length !== this.processorConfig.templateInstances.length) {
|
|
506
178
|
await this.configure()
|
|
507
179
|
updated = true
|
|
508
180
|
}
|
|
@@ -512,214 +184,11 @@ export class ProcessorServiceImpl implements ProcessorServiceImplementation {
|
|
|
512
184
|
}
|
|
513
185
|
}
|
|
514
186
|
}
|
|
515
|
-
|
|
516
|
-
async processLog(request: DataBinding): Promise<ProcessResult> {
|
|
517
|
-
if (!request.data) {
|
|
518
|
-
throw new ServerError(Status.INVALID_ARGUMENT, "Log can't be null")
|
|
519
|
-
}
|
|
520
|
-
|
|
521
|
-
const promises: Promise<ProcessResult>[] = []
|
|
522
|
-
let log: Log
|
|
523
|
-
if (request.data.ethLog) {
|
|
524
|
-
log = request.data.ethLog.log as Log
|
|
525
|
-
} else {
|
|
526
|
-
const jsonString = Utf8ArrayToStr(request.data.raw)
|
|
527
|
-
log = JSON.parse(jsonString)
|
|
528
|
-
}
|
|
529
|
-
|
|
530
|
-
for (const handlerId of request.handlerIds) {
|
|
531
|
-
const handler = this.eventHandlers[handlerId]
|
|
532
|
-
promises.push(
|
|
533
|
-
handler(log).catch((e) => {
|
|
534
|
-
throw new ServerError(Status.INTERNAL, 'error processing log: ' + JSON.stringify(log) + '\n' + errorString(e))
|
|
535
|
-
})
|
|
536
|
-
)
|
|
537
|
-
}
|
|
538
|
-
return mergeProcessResults(await Promise.all(promises))
|
|
539
|
-
}
|
|
540
|
-
|
|
541
|
-
async processSolInstruction(request: DataBinding): Promise<ProcessResult> {
|
|
542
|
-
if (!request.data) {
|
|
543
|
-
throw new ServerError(Status.INVALID_ARGUMENT, 'instruction data cannot be empty')
|
|
544
|
-
}
|
|
545
|
-
|
|
546
|
-
const instruction = request.data.solInstruction || Data_SolInstruction.decode(request.data.raw) // JSON.parse(jsonString)
|
|
547
|
-
const promises: Promise<ProcessResult>[] = []
|
|
548
|
-
|
|
549
|
-
// Only have instruction handlers for solana processors
|
|
550
|
-
for (const processor of SolanaProcessorState.INSTANCE.getValues()) {
|
|
551
|
-
if (processor.address === instruction.programAccountId) {
|
|
552
|
-
let parsedInstruction: SolInstruction | null = null
|
|
553
|
-
if (instruction.parsed) {
|
|
554
|
-
parsedInstruction = processor.getParsedInstruction(instruction.parsed as { type: string; info: any })
|
|
555
|
-
} else if (instruction.instructionData) {
|
|
556
|
-
parsedInstruction = processor.getParsedInstruction(instruction.instructionData)
|
|
557
|
-
}
|
|
558
|
-
if (parsedInstruction == null) {
|
|
559
|
-
continue
|
|
560
|
-
}
|
|
561
|
-
const insHandler = processor.getInstructionHandler(parsedInstruction)
|
|
562
|
-
if (insHandler == null) {
|
|
563
|
-
continue
|
|
564
|
-
}
|
|
565
|
-
const res = await processor.handleInstruction(
|
|
566
|
-
parsedInstruction,
|
|
567
|
-
instruction.accounts,
|
|
568
|
-
insHandler,
|
|
569
|
-
instruction.slot
|
|
570
|
-
)
|
|
571
|
-
|
|
572
|
-
promises.push(Promise.resolve(res))
|
|
573
|
-
}
|
|
574
|
-
}
|
|
575
|
-
return mergeProcessResults(await Promise.all(promises))
|
|
576
|
-
}
|
|
577
|
-
|
|
578
|
-
async processBlock(binding: DataBinding): Promise<ProcessResult> {
|
|
579
|
-
if (!binding.data) {
|
|
580
|
-
throw new ServerError(Status.INVALID_ARGUMENT, "Block can't be empty")
|
|
581
|
-
}
|
|
582
|
-
let block: Block
|
|
583
|
-
if (binding.data.ethBlock?.block) {
|
|
584
|
-
block = binding.data.ethBlock.block as Block
|
|
585
|
-
} else {
|
|
586
|
-
const jsonString = Utf8ArrayToStr(binding.data.raw)
|
|
587
|
-
block = JSON.parse(jsonString)
|
|
588
|
-
}
|
|
589
|
-
|
|
590
|
-
const promises: Promise<ProcessResult>[] = []
|
|
591
|
-
for (const handlerId of binding.handlerIds) {
|
|
592
|
-
promises.push(
|
|
593
|
-
this.blockHandlers[handlerId](block).catch((e) => {
|
|
594
|
-
throw new ServerError(Status.INTERNAL, 'error processing block: ' + block.number + '\n' + errorString(e))
|
|
595
|
-
})
|
|
596
|
-
)
|
|
597
|
-
}
|
|
598
|
-
return mergeProcessResults(await Promise.all(promises))
|
|
599
|
-
}
|
|
600
|
-
|
|
601
|
-
async processTrace(binding: DataBinding): Promise<ProcessResult> {
|
|
602
|
-
if (!binding.data) {
|
|
603
|
-
throw new ServerError(Status.INVALID_ARGUMENT, "Trace can't be empty")
|
|
604
|
-
}
|
|
605
|
-
let trace: Trace
|
|
606
|
-
if (binding.data.ethTrace?.trace) {
|
|
607
|
-
trace = binding.data.ethTrace.trace as Trace
|
|
608
|
-
} else {
|
|
609
|
-
const jsonString = Utf8ArrayToStr(binding.data.raw)
|
|
610
|
-
trace = JSON.parse(jsonString)
|
|
611
|
-
}
|
|
612
|
-
|
|
613
|
-
const promises: Promise<ProcessResult>[] = []
|
|
614
|
-
|
|
615
|
-
for (const handlerId of binding.handlerIds) {
|
|
616
|
-
promises.push(
|
|
617
|
-
this.traceHandlers[handlerId](trace).catch((e) => {
|
|
618
|
-
throw new ServerError(
|
|
619
|
-
Status.INTERNAL,
|
|
620
|
-
'error processing trace: ' + JSON.stringify(trace) + '\n' + errorString(e)
|
|
621
|
-
)
|
|
622
|
-
})
|
|
623
|
-
)
|
|
624
|
-
}
|
|
625
|
-
return mergeProcessResults(await Promise.all(promises))
|
|
626
|
-
}
|
|
627
|
-
|
|
628
|
-
async processAptosEvent(binding: DataBinding): Promise<ProcessResult> {
|
|
629
|
-
if (!binding.data) {
|
|
630
|
-
throw new ServerError(Status.INVALID_ARGUMENT, "Event can't be empty")
|
|
631
|
-
}
|
|
632
|
-
const promises: Promise<ProcessResult>[] = []
|
|
633
|
-
let event: Transaction_UserTransaction
|
|
634
|
-
if (binding.data.aptEvent?.event) {
|
|
635
|
-
event = binding.data.aptEvent?.event as Transaction_UserTransaction
|
|
636
|
-
} else {
|
|
637
|
-
const jsonString = Utf8ArrayToStr(binding.data.raw)
|
|
638
|
-
event = JSON.parse(jsonString)
|
|
639
|
-
}
|
|
640
|
-
|
|
641
|
-
for (const handlerId of binding.handlerIds) {
|
|
642
|
-
// only support aptos event for now
|
|
643
|
-
promises.push(
|
|
644
|
-
this.aptosEventHandlers[handlerId](event).catch((e) => {
|
|
645
|
-
throw new ServerError(
|
|
646
|
-
Status.INTERNAL,
|
|
647
|
-
'error processing event: ' + JSON.stringify(event) + '\n' + errorString(e)
|
|
648
|
-
)
|
|
649
|
-
})
|
|
650
|
-
)
|
|
651
|
-
}
|
|
652
|
-
return mergeProcessResults(await Promise.all(promises))
|
|
653
|
-
}
|
|
654
|
-
|
|
655
|
-
async processAptosResource(binding: DataBinding): Promise<ProcessResult> {
|
|
656
|
-
if (!binding.data) {
|
|
657
|
-
throw new ServerError(Status.INVALID_ARGUMENT, "Event can't be empty")
|
|
658
|
-
}
|
|
659
|
-
|
|
660
|
-
const resource: MoveResourcesWithVersionPayload = {
|
|
661
|
-
resources: [],
|
|
662
|
-
version: 0n,
|
|
663
|
-
timestamp: 0,
|
|
664
|
-
}
|
|
665
|
-
if (binding.data.aptResource?.resources) {
|
|
666
|
-
if (binding.data.aptResource.timestampMicros.greaterThan(Number.MAX_SAFE_INTEGER)) {
|
|
667
|
-
throw new ServerError(Status.INVALID_ARGUMENT, 'timestamp is too large')
|
|
668
|
-
}
|
|
669
|
-
resource.timestamp = binding.data.aptResource.timestampMicros.toNumber()
|
|
670
|
-
resource.version = toBigInt(binding.data.aptResource.version)
|
|
671
|
-
resource.resources = binding.data.aptResource.resources as MoveResource[]
|
|
672
|
-
} else {
|
|
673
|
-
const jsonString = Utf8ArrayToStr(binding.data.raw)
|
|
674
|
-
const json = JSON.parse(jsonString)
|
|
675
|
-
if (Long.fromString(json.timestamp).greaterThan(Number.MAX_SAFE_INTEGER)) {
|
|
676
|
-
throw new ServerError(Status.INVALID_ARGUMENT, 'timestamp is too large')
|
|
677
|
-
}
|
|
678
|
-
resource.timestamp = parseInt(json.timestamp)
|
|
679
|
-
resource.version = toBigInt(json.version)
|
|
680
|
-
}
|
|
681
|
-
|
|
682
|
-
const promises: Promise<ProcessResult>[] = []
|
|
683
|
-
for (const handlerId of binding.handlerIds) {
|
|
684
|
-
promises.push(
|
|
685
|
-
this.aptosResourceHandlers[handlerId](resource).catch((e) => {
|
|
686
|
-
throw new ServerError(
|
|
687
|
-
Status.INTERNAL,
|
|
688
|
-
'error processing event: ' + JSON.stringify(resource) + '\n' + errorString(e)
|
|
689
|
-
)
|
|
690
|
-
})
|
|
691
|
-
)
|
|
692
|
-
}
|
|
693
|
-
return mergeProcessResults(await Promise.all(promises))
|
|
694
|
-
}
|
|
695
|
-
|
|
696
|
-
async processAptosFunctionCall(binding: DataBinding): Promise<ProcessResult> {
|
|
697
|
-
if (!binding.data) {
|
|
698
|
-
throw new ServerError(Status.INVALID_ARGUMENT, "Event can't be empty")
|
|
699
|
-
}
|
|
700
|
-
let call: Transaction_UserTransaction
|
|
701
|
-
if (binding.data.aptCall?.call) {
|
|
702
|
-
call = binding.data.aptCall?.call as Transaction_UserTransaction
|
|
703
|
-
} else {
|
|
704
|
-
const jsonString = Utf8ArrayToStr(binding.data.raw)
|
|
705
|
-
call = JSON.parse(jsonString)
|
|
706
|
-
}
|
|
707
|
-
|
|
708
|
-
const promises: Promise<ProcessResult>[] = []
|
|
709
|
-
for (const handlerId of binding.handlerIds) {
|
|
710
|
-
// only support aptos call for now
|
|
711
|
-
const promise = this.aptosCallHandlers[handlerId](call).catch((e) => {
|
|
712
|
-
throw new ServerError(Status.INTERNAL, 'error processing call: ' + JSON.stringify(call) + '\n' + errorString(e))
|
|
713
|
-
})
|
|
714
|
-
promises.push(promise)
|
|
715
|
-
}
|
|
716
|
-
return mergeProcessResults(await Promise.all(promises))
|
|
717
|
-
}
|
|
718
187
|
}
|
|
719
188
|
|
|
720
189
|
// https://ourcodeworld.com/articles/read/164/how-to-convert-an-uint8array-to-string-in-javascript
|
|
721
190
|
/* eslint-disable */
|
|
722
|
-
function Utf8ArrayToStr(array: Uint8Array) {
|
|
191
|
+
export function Utf8ArrayToStr(array: Uint8Array) {
|
|
723
192
|
let out, i, len, c
|
|
724
193
|
let char2, char3
|
|
725
194
|
|
|
@@ -758,7 +227,7 @@ function Utf8ArrayToStr(array: Uint8Array) {
|
|
|
758
227
|
return out
|
|
759
228
|
}
|
|
760
229
|
|
|
761
|
-
function mergeProcessResults(results: ProcessResult[]): ProcessResult {
|
|
230
|
+
export function mergeProcessResults(results: ProcessResult[]): ProcessResult {
|
|
762
231
|
const res = ProcessResult.fromPartial({})
|
|
763
232
|
|
|
764
233
|
for (const r of results) {
|
|
@@ -781,6 +250,6 @@ function recordRuntimeInfo(results: ProcessResult, handlerType: HandlerType) {
|
|
|
781
250
|
}
|
|
782
251
|
}
|
|
783
252
|
|
|
784
|
-
function errorString(e: Error): string {
|
|
253
|
+
export function errorString(e: Error): string {
|
|
785
254
|
return e.stack || e.message
|
|
786
255
|
}
|