@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.
Files changed (42) hide show
  1. package/LICENSE +55 -0
  2. package/lib/aptos/aptos-plugin.d.ts +14 -0
  3. package/lib/aptos/aptos-plugin.js +190 -0
  4. package/lib/aptos/aptos-plugin.js.map +1 -0
  5. package/lib/aptos/index.d.ts +1 -0
  6. package/lib/aptos/index.js +3 -1
  7. package/lib/aptos/index.js.map +1 -1
  8. package/lib/core/eth-plugin.d.ts +14 -0
  9. package/lib/core/eth-plugin.js +221 -0
  10. package/lib/core/eth-plugin.js.map +1 -0
  11. package/lib/core/index.d.ts +3 -0
  12. package/lib/core/index.js +7 -1
  13. package/lib/core/index.js.map +1 -1
  14. package/lib/core/solana-plugin.d.ts +9 -0
  15. package/lib/core/solana-plugin.js +79 -0
  16. package/lib/core/solana-plugin.js.map +1 -0
  17. package/lib/core/sui-plugin.d.ts +8 -0
  18. package/lib/core/sui-plugin.js +46 -0
  19. package/lib/core/sui-plugin.js.map +1 -0
  20. package/lib/gen/index.d.ts +2 -1
  21. package/lib/gen/index.js +2 -1
  22. package/lib/gen/index.js.map +1 -1
  23. package/lib/plugin.d.ts +15 -0
  24. package/lib/plugin.js +32 -0
  25. package/lib/plugin.js.map +1 -0
  26. package/lib/processor-runner.js +0 -0
  27. package/lib/service.d.ts +7 -19
  28. package/lib/service.js +36 -486
  29. package/lib/service.js.map +1 -1
  30. package/package.json +6 -12
  31. package/src/aptos/aptos-plugin.ts +217 -0
  32. package/src/aptos/index.ts +2 -0
  33. package/src/core/eth-plugin.ts +255 -0
  34. package/src/core/index.ts +4 -0
  35. package/src/core/solana-plugin.ts +97 -0
  36. package/src/core/sui-plugin.ts +54 -0
  37. package/src/gen/index.ts +3 -1
  38. package/src/plugin.ts +41 -0
  39. package/src/service.ts +32 -563
  40. package/src/target-ethers-sentio/tsconfig.json +1 -1
  41. package/src/types/global.d.ts +15 -0
  42. 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 contractConfigs: ContractConfig[]
77
- private accountConfigs: AccountConfig[]
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
- return {
96
- // TODO project setting
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.eventHandlers = []
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
- // Part 1.a, prepare EVM processors
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 processBindingInternal = (request: DataBinding) => {
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
  }