@sentio/sdk 1.31.6 → 1.32.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.
Files changed (54) hide show
  1. package/lib/aptos/aptos-processor.d.ts +5 -5
  2. package/lib/aptos/aptos-processor.js +7 -4
  3. package/lib/aptos/aptos-processor.js.map +1 -1
  4. package/lib/cli/cli.js +12 -1
  5. package/lib/cli/cli.js.map +1 -1
  6. package/lib/cli/commands/login-server.js +4 -5
  7. package/lib/cli/commands/login-server.js.map +1 -1
  8. package/lib/cli/commands/run-login.js +6 -2
  9. package/lib/cli/commands/run-login.js.map +1 -1
  10. package/lib/cli/config.d.ts +1 -0
  11. package/lib/cli/config.js +13 -18
  12. package/lib/cli/config.js.map +1 -1
  13. package/lib/cli/upload.js +3 -2
  14. package/lib/cli/upload.js.map +1 -1
  15. package/lib/core/base-processor-template.d.ts +6 -5
  16. package/lib/core/base-processor-template.js +7 -4
  17. package/lib/core/base-processor-template.js.map +1 -1
  18. package/lib/core/base-processor.d.ts +6 -6
  19. package/lib/core/base-processor.js +7 -4
  20. package/lib/core/base-processor.js.map +1 -1
  21. package/lib/core/logger.js +1 -1
  22. package/lib/core/logger.js.map +1 -1
  23. package/lib/core/solana-processor.js +1 -0
  24. package/lib/core/solana-processor.js.map +1 -1
  25. package/lib/gen/chainquery/protos/chainquery.d.ts +106 -0
  26. package/lib/gen/chainquery/protos/chainquery.js +377 -2
  27. package/lib/gen/chainquery/protos/chainquery.js.map +1 -1
  28. package/lib/gen/processor/protos/processor.d.ts +17 -3
  29. package/lib/gen/processor/protos/processor.js +145 -21
  30. package/lib/gen/processor/protos/processor.js.map +1 -1
  31. package/lib/service.d.ts +2 -0
  32. package/lib/service.js +145 -48
  33. package/lib/service.js.map +1 -1
  34. package/lib/testing/test-processor-server.js +6 -3
  35. package/lib/testing/test-processor-server.js.map +1 -1
  36. package/lib/utils/chain.d.ts +2 -2
  37. package/lib/utils/chain.js +6 -4
  38. package/lib/utils/chain.js.map +1 -1
  39. package/package.json +1 -1
  40. package/src/aptos/aptos-processor.ts +22 -7
  41. package/src/cli/cli.ts +12 -1
  42. package/src/cli/commands/login-server.ts +4 -5
  43. package/src/cli/commands/run-login.ts +6 -2
  44. package/src/cli/config.ts +15 -18
  45. package/src/cli/upload.ts +5 -2
  46. package/src/core/base-processor-template.ts +18 -9
  47. package/src/core/base-processor.ts +18 -9
  48. package/src/core/logger.ts +1 -1
  49. package/src/core/solana-processor.ts +1 -0
  50. package/src/gen/chainquery/protos/chainquery.ts +479 -1
  51. package/src/gen/processor/protos/processor.ts +167 -19
  52. package/src/service.ts +180 -49
  53. package/src/testing/test-processor-server.ts +6 -3
  54. package/src/utils/chain.ts +8 -6
@@ -79,13 +79,13 @@ export function addressTypeToJSON(object: AddressType): string {
79
79
  export enum HandlerType {
80
80
  UNKNOWN = 0,
81
81
  ETH_LOG = 1,
82
- BLOCK = 2,
83
- TRANSACTION = 3,
84
- INSTRUCTION = 4,
82
+ ETH_BLOCK = 2,
85
83
  ETH_TRACE = 5,
84
+ SOL_INSTRUCTIONS = 4,
86
85
  APT_EVENT = 6,
87
86
  APT_CALL = 7,
88
87
  APT_RESOURCE = 8,
88
+ SUI_TRANSACTION = 3,
89
89
  UNRECOGNIZED = -1,
90
90
  }
91
91
 
@@ -98,17 +98,14 @@ export function handlerTypeFromJSON(object: any): HandlerType {
98
98
  case "ETH_LOG":
99
99
  return HandlerType.ETH_LOG;
100
100
  case 2:
101
- case "BLOCK":
102
- return HandlerType.BLOCK;
103
- case 3:
104
- case "TRANSACTION":
105
- return HandlerType.TRANSACTION;
106
- case 4:
107
- case "INSTRUCTION":
108
- return HandlerType.INSTRUCTION;
101
+ case "ETH_BLOCK":
102
+ return HandlerType.ETH_BLOCK;
109
103
  case 5:
110
104
  case "ETH_TRACE":
111
105
  return HandlerType.ETH_TRACE;
106
+ case 4:
107
+ case "SOL_INSTRUCTIONS":
108
+ return HandlerType.SOL_INSTRUCTIONS;
112
109
  case 6:
113
110
  case "APT_EVENT":
114
111
  return HandlerType.APT_EVENT;
@@ -118,6 +115,9 @@ export function handlerTypeFromJSON(object: any): HandlerType {
118
115
  case 8:
119
116
  case "APT_RESOURCE":
120
117
  return HandlerType.APT_RESOURCE;
118
+ case 3:
119
+ case "SUI_TRANSACTION":
120
+ return HandlerType.SUI_TRANSACTION;
121
121
  case -1:
122
122
  case "UNRECOGNIZED":
123
123
  default:
@@ -131,20 +131,20 @@ export function handlerTypeToJSON(object: HandlerType): string {
131
131
  return "UNKNOWN";
132
132
  case HandlerType.ETH_LOG:
133
133
  return "ETH_LOG";
134
- case HandlerType.BLOCK:
135
- return "BLOCK";
136
- case HandlerType.TRANSACTION:
137
- return "TRANSACTION";
138
- case HandlerType.INSTRUCTION:
139
- return "INSTRUCTION";
134
+ case HandlerType.ETH_BLOCK:
135
+ return "ETH_BLOCK";
140
136
  case HandlerType.ETH_TRACE:
141
137
  return "ETH_TRACE";
138
+ case HandlerType.SOL_INSTRUCTIONS:
139
+ return "SOL_INSTRUCTIONS";
142
140
  case HandlerType.APT_EVENT:
143
141
  return "APT_EVENT";
144
142
  case HandlerType.APT_CALL:
145
143
  return "APT_CALL";
146
144
  case HandlerType.APT_RESOURCE:
147
145
  return "APT_RESOURCE";
146
+ case HandlerType.SUI_TRANSACTION:
147
+ return "SUI_TRANSACTION";
148
148
  case HandlerType.UNRECOGNIZED:
149
149
  default:
150
150
  return "UNRECOGNIZED";
@@ -315,10 +315,17 @@ export interface AccountConfig {
315
315
  logConfigs: LogHandlerConfig[];
316
316
  }
317
317
 
318
+ export interface HandleInterval {
319
+ recentInterval: number;
320
+ backfillInterval: number;
321
+ }
322
+
318
323
  export interface OnIntervalConfig {
319
324
  handlerId: number;
320
325
  minutes: number;
326
+ minutesInterval?: HandleInterval | undefined;
321
327
  slot: number;
328
+ slotInterval?: HandleInterval | undefined;
322
329
  }
323
330
 
324
331
  export interface AptosOnIntervalConfig {
@@ -440,6 +447,7 @@ export interface DataBinding {
440
447
  data: Data | undefined;
441
448
  handlerId: number;
442
449
  handlerType: HandlerType;
450
+ handlerIds: number[];
443
451
  }
444
452
 
445
453
  export interface BlockBinding {
@@ -1803,8 +1811,81 @@ export const AccountConfig = {
1803
1811
  },
1804
1812
  };
1805
1813
 
1814
+ function createBaseHandleInterval(): HandleInterval {
1815
+ return { recentInterval: 0, backfillInterval: 0 };
1816
+ }
1817
+
1818
+ export const HandleInterval = {
1819
+ encode(
1820
+ message: HandleInterval,
1821
+ writer: _m0.Writer = _m0.Writer.create()
1822
+ ): _m0.Writer {
1823
+ if (message.recentInterval !== 0) {
1824
+ writer.uint32(8).int32(message.recentInterval);
1825
+ }
1826
+ if (message.backfillInterval !== 0) {
1827
+ writer.uint32(16).int32(message.backfillInterval);
1828
+ }
1829
+ return writer;
1830
+ },
1831
+
1832
+ decode(input: _m0.Reader | Uint8Array, length?: number): HandleInterval {
1833
+ const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input);
1834
+ let end = length === undefined ? reader.len : reader.pos + length;
1835
+ const message = createBaseHandleInterval();
1836
+ while (reader.pos < end) {
1837
+ const tag = reader.uint32();
1838
+ switch (tag >>> 3) {
1839
+ case 1:
1840
+ message.recentInterval = reader.int32();
1841
+ break;
1842
+ case 2:
1843
+ message.backfillInterval = reader.int32();
1844
+ break;
1845
+ default:
1846
+ reader.skipType(tag & 7);
1847
+ break;
1848
+ }
1849
+ }
1850
+ return message;
1851
+ },
1852
+
1853
+ fromJSON(object: any): HandleInterval {
1854
+ return {
1855
+ recentInterval: isSet(object.recentInterval)
1856
+ ? Number(object.recentInterval)
1857
+ : 0,
1858
+ backfillInterval: isSet(object.backfillInterval)
1859
+ ? Number(object.backfillInterval)
1860
+ : 0,
1861
+ };
1862
+ },
1863
+
1864
+ toJSON(message: HandleInterval): unknown {
1865
+ const obj: any = {};
1866
+ message.recentInterval !== undefined &&
1867
+ (obj.recentInterval = Math.round(message.recentInterval));
1868
+ message.backfillInterval !== undefined &&
1869
+ (obj.backfillInterval = Math.round(message.backfillInterval));
1870
+ return obj;
1871
+ },
1872
+
1873
+ fromPartial(object: DeepPartial<HandleInterval>): HandleInterval {
1874
+ const message = createBaseHandleInterval();
1875
+ message.recentInterval = object.recentInterval ?? 0;
1876
+ message.backfillInterval = object.backfillInterval ?? 0;
1877
+ return message;
1878
+ },
1879
+ };
1880
+
1806
1881
  function createBaseOnIntervalConfig(): OnIntervalConfig {
1807
- return { handlerId: 0, minutes: 0, slot: 0 };
1882
+ return {
1883
+ handlerId: 0,
1884
+ minutes: 0,
1885
+ minutesInterval: undefined,
1886
+ slot: 0,
1887
+ slotInterval: undefined,
1888
+ };
1808
1889
  }
1809
1890
 
1810
1891
  export const OnIntervalConfig = {
@@ -1818,9 +1899,21 @@ export const OnIntervalConfig = {
1818
1899
  if (message.minutes !== 0) {
1819
1900
  writer.uint32(16).int32(message.minutes);
1820
1901
  }
1902
+ if (message.minutesInterval !== undefined) {
1903
+ HandleInterval.encode(
1904
+ message.minutesInterval,
1905
+ writer.uint32(34).fork()
1906
+ ).ldelim();
1907
+ }
1821
1908
  if (message.slot !== 0) {
1822
1909
  writer.uint32(24).int32(message.slot);
1823
1910
  }
1911
+ if (message.slotInterval !== undefined) {
1912
+ HandleInterval.encode(
1913
+ message.slotInterval,
1914
+ writer.uint32(42).fork()
1915
+ ).ldelim();
1916
+ }
1824
1917
  return writer;
1825
1918
  },
1826
1919
 
@@ -1837,9 +1930,18 @@ export const OnIntervalConfig = {
1837
1930
  case 2:
1838
1931
  message.minutes = reader.int32();
1839
1932
  break;
1933
+ case 4:
1934
+ message.minutesInterval = HandleInterval.decode(
1935
+ reader,
1936
+ reader.uint32()
1937
+ );
1938
+ break;
1840
1939
  case 3:
1841
1940
  message.slot = reader.int32();
1842
1941
  break;
1942
+ case 5:
1943
+ message.slotInterval = HandleInterval.decode(reader, reader.uint32());
1944
+ break;
1843
1945
  default:
1844
1946
  reader.skipType(tag & 7);
1845
1947
  break;
@@ -1852,7 +1954,13 @@ export const OnIntervalConfig = {
1852
1954
  return {
1853
1955
  handlerId: isSet(object.handlerId) ? Number(object.handlerId) : 0,
1854
1956
  minutes: isSet(object.minutes) ? Number(object.minutes) : 0,
1957
+ minutesInterval: isSet(object.minutesInterval)
1958
+ ? HandleInterval.fromJSON(object.minutesInterval)
1959
+ : undefined,
1855
1960
  slot: isSet(object.slot) ? Number(object.slot) : 0,
1961
+ slotInterval: isSet(object.slotInterval)
1962
+ ? HandleInterval.fromJSON(object.slotInterval)
1963
+ : undefined,
1856
1964
  };
1857
1965
  },
1858
1966
 
@@ -1862,7 +1970,15 @@ export const OnIntervalConfig = {
1862
1970
  (obj.handlerId = Math.round(message.handlerId));
1863
1971
  message.minutes !== undefined &&
1864
1972
  (obj.minutes = Math.round(message.minutes));
1973
+ message.minutesInterval !== undefined &&
1974
+ (obj.minutesInterval = message.minutesInterval
1975
+ ? HandleInterval.toJSON(message.minutesInterval)
1976
+ : undefined);
1865
1977
  message.slot !== undefined && (obj.slot = Math.round(message.slot));
1978
+ message.slotInterval !== undefined &&
1979
+ (obj.slotInterval = message.slotInterval
1980
+ ? HandleInterval.toJSON(message.slotInterval)
1981
+ : undefined);
1866
1982
  return obj;
1867
1983
  },
1868
1984
 
@@ -1870,7 +1986,15 @@ export const OnIntervalConfig = {
1870
1986
  const message = createBaseOnIntervalConfig();
1871
1987
  message.handlerId = object.handlerId ?? 0;
1872
1988
  message.minutes = object.minutes ?? 0;
1989
+ message.minutesInterval =
1990
+ object.minutesInterval !== undefined && object.minutesInterval !== null
1991
+ ? HandleInterval.fromPartial(object.minutesInterval)
1992
+ : undefined;
1873
1993
  message.slot = object.slot ?? 0;
1994
+ message.slotInterval =
1995
+ object.slotInterval !== undefined && object.slotInterval !== null
1996
+ ? HandleInterval.fromPartial(object.slotInterval)
1997
+ : undefined;
1874
1998
  return message;
1875
1999
  },
1876
2000
  };
@@ -3530,7 +3654,7 @@ export const Data = {
3530
3654
  };
3531
3655
 
3532
3656
  function createBaseDataBinding(): DataBinding {
3533
- return { data: undefined, handlerId: 0, handlerType: 0 };
3657
+ return { data: undefined, handlerId: 0, handlerType: 0, handlerIds: [] };
3534
3658
  }
3535
3659
 
3536
3660
  export const DataBinding = {
@@ -3547,6 +3671,11 @@ export const DataBinding = {
3547
3671
  if (message.handlerType !== 0) {
3548
3672
  writer.uint32(24).int32(message.handlerType);
3549
3673
  }
3674
+ writer.uint32(34).fork();
3675
+ for (const v of message.handlerIds) {
3676
+ writer.int32(v);
3677
+ }
3678
+ writer.ldelim();
3550
3679
  return writer;
3551
3680
  },
3552
3681
 
@@ -3566,6 +3695,16 @@ export const DataBinding = {
3566
3695
  case 3:
3567
3696
  message.handlerType = reader.int32() as any;
3568
3697
  break;
3698
+ case 4:
3699
+ if ((tag & 7) === 2) {
3700
+ const end2 = reader.uint32() + reader.pos;
3701
+ while (reader.pos < end2) {
3702
+ message.handlerIds.push(reader.int32());
3703
+ }
3704
+ } else {
3705
+ message.handlerIds.push(reader.int32());
3706
+ }
3707
+ break;
3569
3708
  default:
3570
3709
  reader.skipType(tag & 7);
3571
3710
  break;
@@ -3581,6 +3720,9 @@ export const DataBinding = {
3581
3720
  handlerType: isSet(object.handlerType)
3582
3721
  ? handlerTypeFromJSON(object.handlerType)
3583
3722
  : 0,
3723
+ handlerIds: Array.isArray(object?.handlerIds)
3724
+ ? object.handlerIds.map((e: any) => Number(e))
3725
+ : [],
3584
3726
  };
3585
3727
  },
3586
3728
 
@@ -3592,6 +3734,11 @@ export const DataBinding = {
3592
3734
  (obj.handlerId = Math.round(message.handlerId));
3593
3735
  message.handlerType !== undefined &&
3594
3736
  (obj.handlerType = handlerTypeToJSON(message.handlerType));
3737
+ if (message.handlerIds) {
3738
+ obj.handlerIds = message.handlerIds.map((e) => Math.round(e));
3739
+ } else {
3740
+ obj.handlerIds = [];
3741
+ }
3595
3742
  return obj;
3596
3743
  },
3597
3744
 
@@ -3603,6 +3750,7 @@ export const DataBinding = {
3603
3750
  : undefined;
3604
3751
  message.handlerId = object.handlerId ?? 0;
3605
3752
  message.handlerType = object.handlerType ?? 0;
3753
+ message.handlerIds = object.handlerIds?.map((e) => e) || [];
3606
3754
  return message;
3607
3755
  },
3608
3756
  };
package/src/service.ts CHANGED
@@ -12,6 +12,7 @@ import {
12
12
  EventTrackingConfig,
13
13
  ExportConfig,
14
14
  HandlerType,
15
+ Instruction,
15
16
  LogFilter,
16
17
  LogHandlerConfig,
17
18
  MetricConfig,
@@ -32,7 +33,7 @@ import { Empty } from './gen/google/protobuf/empty'
32
33
  import Long from 'long'
33
34
  import { TextDecoder } from 'util'
34
35
  import { Trace } from './core'
35
- import { Instruction } from '@project-serum/anchor'
36
+ import { Instruction as SolInstruction } from '@project-serum/anchor'
36
37
  import { MetricState } from './core/meter'
37
38
  import { ExporterState } from './core/exporter'
38
39
  import { EventTrackerState } from './core/event-tracker'
@@ -55,9 +56,12 @@ const DEFAULT_MAX_BLOCK = Long.ZERO
55
56
  const USER_PROCESSOR = 'user_processor'
56
57
 
57
58
  export class ProcessorServiceImpl implements ProcessorServiceImplementation {
59
+ // eth handlers
58
60
  private eventHandlers: ((event: Log) => Promise<ProcessResult>)[] = []
59
61
  private traceHandlers: ((trace: Trace) => Promise<ProcessResult>)[] = []
60
62
  private blockHandlers: ((block: Block) => Promise<ProcessResult>)[] = []
63
+
64
+ // aptos handlers
61
65
  private aptosEventHandlers: ((event: any) => Promise<ProcessResult>)[] = []
62
66
  private aptosCallHandlers: ((func: any) => Promise<ProcessResult>)[] = []
63
67
  private aptosResourceHandlers: ((resourceWithVersion: MoveResourcesWithVersionPayload) => Promise<ProcessResult>)[] =
@@ -171,8 +175,10 @@ export class ProcessorServiceImpl implements ProcessorServiceImplementation {
171
175
  // TODO wrap the block handler into one
172
176
 
173
177
  contractConfig.intervalConfigs.push({
174
- slot: blockHandler.blockInterval || 1,
175
- minutes: blockHandler.timeIntervalInMinutes || 0,
178
+ slot: 0,
179
+ slotInterval: blockHandler.blockInterval,
180
+ minutes: 0,
181
+ minutesInterval: blockHandler.timeIntervalInMinutes,
176
182
  handlerId: handlerId,
177
183
  })
178
184
  }
@@ -387,8 +393,10 @@ export class ProcessorServiceImpl implements ProcessorServiceImplementation {
387
393
  accountConfig.aptosIntervalConfigs.push({
388
394
  intervalConfig: {
389
395
  handlerId: handlerId,
390
- minutes: handler.timeIntervalInMinutes || 0,
391
- slot: handler.versionInterval || 0,
396
+ minutes: 0,
397
+ minutesInterval: handler.timeIntervalInMinutes,
398
+ slot: 0,
399
+ slotInterval: handler.versionInterval,
392
400
  },
393
401
  type: handler.type || '',
394
402
  })
@@ -465,18 +473,37 @@ export class ProcessorServiceImpl implements ProcessorServiceImplementation {
465
473
  }
466
474
 
467
475
  async processBinding(request: DataBinding, options?: CallContext): Promise<ProcessResult> {
468
- switch (request.handlerType) {
469
- case HandlerType.APT_CALL:
470
- return this.processAptosFunctionCall(request)
471
- case HandlerType.APT_EVENT:
472
- return this.processAptosEvent(request)
473
- case HandlerType.APT_RESOURCE:
474
- return this.processAptosResource(request)
475
- case HandlerType.ETH_LOG:
476
- return this.processLog(request)
477
- default:
478
- throw new ServerError(Status.INVALID_ARGUMENT, 'No handle type registered ' + request.handlerType)
476
+ if (request.handlerIds.length == 0) {
477
+ request.handlerIds = [request.handlerId]
478
+ }
479
+
480
+ const processBindingInternal = (request: DataBinding) => {
481
+ switch (request.handlerType) {
482
+ case HandlerType.APT_CALL:
483
+ return this.processAptosFunctionCall(request)
484
+ case HandlerType.APT_EVENT:
485
+ return this.processAptosEvent(request)
486
+ case HandlerType.APT_RESOURCE:
487
+ return this.processAptosResource(request)
488
+ case HandlerType.ETH_LOG:
489
+ return this.processLog(request)
490
+ case HandlerType.ETH_TRACE:
491
+ return this.processTrace(request)
492
+ case HandlerType.ETH_BLOCK:
493
+ return this.processBlockNew(request)
494
+ case HandlerType.SOL_INSTRUCTIONS:
495
+ return this.processInstructionsNew(request)
496
+ // TODO migrate SOLANA SUI cases
497
+ // case HandlerType.INSTRUCTION:
498
+ // return this.processInstruction(request)
499
+ default:
500
+ throw new ServerError(Status.INVALID_ARGUMENT, 'No handle type registered ' + request.handlerType)
501
+ }
479
502
  }
503
+
504
+ const result = await processBindingInternal(request)
505
+ recordRuntimeInfo(result, request.handlerType)
506
+ return result
480
507
  }
481
508
 
482
509
  async processLogs(request: ProcessBindingsRequest, context: CallContext): Promise<ProcessBindingResponse> {
@@ -511,17 +538,23 @@ export class ProcessorServiceImpl implements ProcessorServiceImplementation {
511
538
  if (!l.data) {
512
539
  throw new ServerError(Status.INVALID_ARGUMENT, "Log can't be null")
513
540
  }
541
+ if (l.handlerIds.length == 0) {
542
+ l.handlerIds = [l.handlerId]
543
+ }
514
544
 
515
- try {
516
- const jsonString = Utf8ArrayToStr(l.data.raw)
517
- const log: Log = JSON.parse(jsonString)
518
- const handler = this.eventHandlers[l.handlerId]
519
- return handler(log).catch((e) => {
520
- throw new ServerError(Status.INTERNAL, 'error processing log: ' + jsonString + '\n' + errorString(e))
521
- })
522
- } catch (e) {
523
- throw new ServerError(Status.INTERNAL, 'error parse log: ' + l)
545
+ const promises: Promise<ProcessResult>[] = []
546
+ const jsonString = Utf8ArrayToStr(l.data.raw)
547
+ const log: Log = JSON.parse(jsonString)
548
+
549
+ for (const handlerId of l.handlerIds) {
550
+ const handler = this.eventHandlers[handlerId]
551
+ promises.push(
552
+ handler(log).catch((e) => {
553
+ throw new ServerError(Status.INTERNAL, 'error processing log: ' + jsonString + '\n' + errorString(e))
554
+ })
555
+ )
524
556
  }
557
+ return mergeProcessResults(await Promise.all(promises))
525
558
  }
526
559
 
527
560
  async processTransactions(
@@ -557,7 +590,7 @@ export class ProcessorServiceImpl implements ProcessorServiceImplementation {
557
590
  await Promise.all(processorPromises)
558
591
  }
559
592
 
560
- recordRuntimeInfo(result, HandlerType.TRANSACTION)
593
+ recordRuntimeInfo(result, HandlerType.SUI_TRANSACTION)
561
594
  return {
562
595
  result,
563
596
  configUpdated: false,
@@ -586,7 +619,7 @@ export class ProcessorServiceImpl implements ProcessorServiceImplementation {
586
619
  new Promise((resolve, _) => {
587
620
  for (const processor of SolanaProcessorState.INSTANCE.getValues()) {
588
621
  if (processor.address === instruction.programAccountId) {
589
- let parsedInstruction: Instruction | null = null
622
+ let parsedInstruction: SolInstruction | null = null
590
623
  if (instruction.parsed) {
591
624
  parsedInstruction = processor.getParsedInstruction(
592
625
  JSON.parse(new TextDecoder().decode(instruction.parsed))
@@ -620,13 +653,64 @@ export class ProcessorServiceImpl implements ProcessorServiceImplementation {
620
653
  await Promise.all(processorPromises)
621
654
  }
622
655
 
623
- recordRuntimeInfo(result, HandlerType.INSTRUCTION)
656
+ recordRuntimeInfo(result, HandlerType.SOL_INSTRUCTIONS)
624
657
  return {
625
658
  result,
626
659
  configUpdated: false,
627
660
  }
628
661
  }
629
662
 
663
+ async processInstructionsNew(request: DataBinding): Promise<ProcessResult> {
664
+ if (!this.started) {
665
+ throw new ServerError(Status.UNAVAILABLE, 'Service not started.')
666
+ }
667
+ if (!request.data) {
668
+ throw new ServerError(Status.INVALID_ARGUMENT, 'instruction data cannot be empty')
669
+ }
670
+
671
+ const jsonString = Utf8ArrayToStr(request.data.raw)
672
+ const instructions: Instruction[] = JSON.parse(jsonString)
673
+ const promises: Promise<ProcessResult>[] = []
674
+
675
+ // Only have instruction handlers for solana processors
676
+ if (SolanaProcessorState.INSTANCE.getValues()) {
677
+ for (const instruction of instructions) {
678
+ if (!instruction) {
679
+ throw new ServerError(Status.INVALID_ARGUMENT, 'instruction cannot be null')
680
+ }
681
+
682
+ for (const processor of SolanaProcessorState.INSTANCE.getValues()) {
683
+ if (processor.address === instruction.programAccountId) {
684
+ let parsedInstruction: SolInstruction | null = null
685
+ if (instruction.parsed) {
686
+ parsedInstruction = processor.getParsedInstruction(
687
+ JSON.parse(new TextDecoder().decode(instruction.parsed))
688
+ )
689
+ } else if (instruction.instructionData) {
690
+ parsedInstruction = processor.getParsedInstruction(instruction.instructionData)
691
+ }
692
+ if (parsedInstruction == null) {
693
+ continue
694
+ }
695
+ const insHandler = processor.getInstructionHandler(parsedInstruction)
696
+ if (insHandler == null) {
697
+ continue
698
+ }
699
+ const res = await processor.handleInstruction(
700
+ parsedInstruction,
701
+ instruction.accounts,
702
+ insHandler,
703
+ instruction.slot
704
+ )
705
+
706
+ promises.push(Promise.resolve(res))
707
+ }
708
+ }
709
+ }
710
+ }
711
+ return mergeProcessResults(await Promise.all(promises))
712
+ }
713
+
630
714
  async processBlocks(request: ProcessBlocksRequest, context: CallContext): Promise<ProcessBindingResponse> {
631
715
  if (!this.started) {
632
716
  throw new ServerError(Status.UNAVAILABLE, 'Service Not started.')
@@ -635,7 +719,7 @@ export class ProcessorServiceImpl implements ProcessorServiceImplementation {
635
719
  const promises = request.blockBindings.map((binding) => this.processBlock(binding))
636
720
  const result = mergeProcessResults(await Promise.all(promises))
637
721
 
638
- recordRuntimeInfo(result, HandlerType.BLOCK)
722
+ recordRuntimeInfo(result, HandlerType.ETH_BLOCK)
639
723
  return {
640
724
  result,
641
725
  configUpdated: false,
@@ -660,6 +744,30 @@ export class ProcessorServiceImpl implements ProcessorServiceImplementation {
660
744
  return mergeProcessResults(await Promise.all(promises))
661
745
  }
662
746
 
747
+ // TODO remove above old processBlock logic
748
+ async processBlockNew(binding: DataBinding): Promise<ProcessResult> {
749
+ if (!binding.data) {
750
+ throw new ServerError(Status.INVALID_ARGUMENT, "Block can't be empty")
751
+ }
752
+ if (binding.handlerIds.length == 0) {
753
+ binding.handlerIds = [binding.handlerId]
754
+ }
755
+
756
+ const jsonString = Utf8ArrayToStr(binding.data.raw)
757
+
758
+ const block: Block = JSON.parse(jsonString)
759
+
760
+ const promises: Promise<ProcessResult>[] = []
761
+ for (const handlerId of binding.handlerIds) {
762
+ promises.push(
763
+ this.blockHandlers[handlerId](block).catch((e) => {
764
+ throw new ServerError(Status.INTERNAL, 'error processing block: ' + block.number + '\n' + errorString(e))
765
+ })
766
+ )
767
+ }
768
+ return mergeProcessResults(await Promise.all(promises))
769
+ }
770
+
663
771
  async processTraces(request: ProcessBindingsRequest, context: CallContext): Promise<ProcessBindingResponse> {
664
772
  if (!this.started) {
665
773
  throw new ServerError(Status.UNAVAILABLE, 'Service Not started.')
@@ -679,26 +787,41 @@ export class ProcessorServiceImpl implements ProcessorServiceImplementation {
679
787
  if (!binding.data) {
680
788
  throw new ServerError(Status.INVALID_ARGUMENT, "Trace can't be empty")
681
789
  }
790
+ if (binding.handlerIds.length == 0) {
791
+ binding.handlerIds = [binding.handlerId]
792
+ }
682
793
  const jsonString = Utf8ArrayToStr(binding.data.raw)
683
794
  const trace: Trace = JSON.parse(jsonString)
684
795
 
685
- return this.traceHandlers[binding.handlerId](trace).catch((e) => {
686
- throw new ServerError(Status.INTERNAL, 'error processing trace: ' + jsonString + '\n' + errorString(e))
687
- })
796
+ const promises: Promise<ProcessResult>[] = []
797
+
798
+ for (const handlerId of binding.handlerIds) {
799
+ promises.push(
800
+ this.traceHandlers[handlerId](trace).catch((e) => {
801
+ throw new ServerError(Status.INTERNAL, 'error processing trace: ' + jsonString + '\n' + errorString(e))
802
+ })
803
+ )
804
+ }
805
+ return mergeProcessResults(await Promise.all(promises))
688
806
  }
689
807
 
690
808
  async processAptosEvent(binding: DataBinding): Promise<ProcessResult> {
691
809
  if (!binding.data) {
692
810
  throw new ServerError(Status.INVALID_ARGUMENT, "Event can't be empty")
693
811
  }
812
+ const promises: Promise<ProcessResult>[] = []
694
813
  const jsonString = Utf8ArrayToStr(binding.data.raw)
695
814
  const event = JSON.parse(jsonString)
696
- // only support aptos event for now
697
- const result = await this.aptosEventHandlers[binding.handlerId](event).catch((e) => {
698
- throw new ServerError(Status.INTERNAL, 'error processing event: ' + jsonString + '\n' + errorString(e))
699
- })
700
- recordRuntimeInfo(result, HandlerType.APT_EVENT)
701
- return result
815
+
816
+ for (const handlerId of binding.handlerIds) {
817
+ // only support aptos event for now
818
+ promises.push(
819
+ this.aptosEventHandlers[handlerId](event).catch((e) => {
820
+ throw new ServerError(Status.INTERNAL, 'error processing event: ' + jsonString + '\n' + errorString(e))
821
+ })
822
+ )
823
+ }
824
+ return mergeProcessResults(await Promise.all(promises))
702
825
  }
703
826
 
704
827
  async processAptosResource(binding: DataBinding): Promise<ProcessResult> {
@@ -707,11 +830,15 @@ export class ProcessorServiceImpl implements ProcessorServiceImplementation {
707
830
  }
708
831
  const jsonString = Utf8ArrayToStr(binding.data.raw)
709
832
  const json = JSON.parse(jsonString) as MoveResourcesWithVersionPayload
710
- const result = await this.aptosResourceHandlers[binding.handlerId](json).catch((e) => {
711
- throw new ServerError(Status.INTERNAL, 'error processing event: ' + jsonString + '\n' + errorString(e))
712
- })
713
- recordRuntimeInfo(result, HandlerType.APT_RESOURCE)
714
- return result
833
+ const promises: Promise<ProcessResult>[] = []
834
+ for (const handlerId of binding.handlerIds) {
835
+ promises.push(
836
+ this.aptosResourceHandlers[handlerId](json).catch((e) => {
837
+ throw new ServerError(Status.INTERNAL, 'error processing event: ' + jsonString + '\n' + errorString(e))
838
+ })
839
+ )
840
+ }
841
+ return mergeProcessResults(await Promise.all(promises))
715
842
  }
716
843
 
717
844
  async processAptosFunctionCall(binding: DataBinding): Promise<ProcessResult> {
@@ -720,12 +847,16 @@ export class ProcessorServiceImpl implements ProcessorServiceImplementation {
720
847
  }
721
848
  const jsonString = Utf8ArrayToStr(binding.data.raw)
722
849
  const call = JSON.parse(jsonString)
723
- // only support aptos call for now
724
- const result = await this.aptosCallHandlers[binding.handlerId](call).catch((e) => {
725
- throw new ServerError(Status.INTERNAL, 'error processing call: ' + jsonString + '\n' + errorString(e))
726
- })
727
- recordRuntimeInfo(result, HandlerType.APT_CALL)
728
- return result
850
+
851
+ const promises: Promise<ProcessResult>[] = []
852
+ for (const handlerId of binding.handlerIds) {
853
+ // only support aptos call for now
854
+ const promise = this.aptosCallHandlers[handlerId](call).catch((e) => {
855
+ throw new ServerError(Status.INTERNAL, 'error processing call: ' + jsonString + '\n' + errorString(e))
856
+ })
857
+ promises.push(promise)
858
+ }
859
+ return mergeProcessResults(await Promise.all(promises))
729
860
  }
730
861
  }
731
862