@sentio/sdk 1.8.1 → 1.9.0
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/base-processor.d.ts +7 -0
- package/lib/base-processor.js +28 -1
- package/lib/base-processor.js.map +1 -1
- package/lib/builtin/internal/erc20_processor.d.ts +87 -2
- package/lib/builtin/internal/erc20_processor.js +54 -0
- package/lib/builtin/internal/erc20_processor.js.map +1 -1
- package/lib/builtin/internal/erc20bytes_processor.d.ts +42 -2
- package/lib/builtin/internal/erc20bytes_processor.js +27 -0
- package/lib/builtin/internal/erc20bytes_processor.js.map +1 -1
- package/lib/builtin/internal/weth9_processor.d.ts +50 -2
- package/lib/builtin/internal/weth9_processor.js +33 -0
- package/lib/builtin/internal/weth9_processor.js.map +1 -1
- package/lib/context.d.ts +15 -11
- package/lib/context.js +21 -13
- package/lib/context.js.map +1 -1
- package/lib/gen/processor/protos/processor.d.ts +13 -1
- package/lib/gen/processor/protos/processor.js +83 -12
- package/lib/gen/processor/protos/processor.js.map +1 -1
- package/lib/index.d.ts +1 -0
- package/lib/index.js.map +1 -1
- package/lib/meter.d.ts +4 -4
- package/lib/meter.js +11 -0
- package/lib/meter.js.map +1 -1
- package/lib/service.d.ts +3 -1
- package/lib/service.js +34 -2
- package/lib/service.js.map +1 -1
- package/lib/target-ethers-sentio/codegen.js +8 -0
- package/lib/target-ethers-sentio/codegen.js.map +1 -1
- package/lib/target-ethers-sentio/functions.d.ts +3 -0
- package/lib/target-ethers-sentio/functions.js +54 -0
- package/lib/target-ethers-sentio/functions.js.map +1 -0
- package/lib/trace.d.ts +35 -0
- package/lib/trace.js +22 -0
- package/lib/trace.js.map +1 -0
- package/package.json +1 -1
- package/src/base-processor.ts +34 -0
- package/src/builtin/internal/erc20_processor.ts +183 -1
- package/src/builtin/internal/erc20bytes_processor.ts +94 -1
- package/src/builtin/internal/weth9_processor.ts +108 -1
- package/src/context.ts +23 -14
- package/src/gen/processor/protos/processor.ts +104 -13
- package/src/index.ts +1 -0
- package/src/meter.ts +19 -8
- package/src/service.ts +43 -2
- package/src/target-ethers-sentio/codegen.ts +8 -0
- package/src/target-ethers-sentio/functions.ts +55 -0
- package/src/trace.ts +64 -0
|
@@ -123,6 +123,7 @@ export interface ContractConfig {
|
|
|
123
123
|
contract: ContractInfo | undefined;
|
|
124
124
|
blockConfigs: BlockHandlerConfig[];
|
|
125
125
|
logConfigs: LogHandlerConfig[];
|
|
126
|
+
traceConfigs: TraceHandlerConfig[];
|
|
126
127
|
startBlock: Long;
|
|
127
128
|
endBlock: Long;
|
|
128
129
|
instructionConfig: InstructionHandlerConfig | undefined;
|
|
@@ -151,6 +152,11 @@ export interface BlockHandlerConfig {
|
|
|
151
152
|
handlerId: number;
|
|
152
153
|
}
|
|
153
154
|
|
|
155
|
+
export interface TraceHandlerConfig {
|
|
156
|
+
signature: string;
|
|
157
|
+
handlerId: number;
|
|
158
|
+
}
|
|
159
|
+
|
|
154
160
|
export interface LogHandlerConfig {
|
|
155
161
|
filters: LogFilter[];
|
|
156
162
|
handlerId: number;
|
|
@@ -180,7 +186,7 @@ export interface ProcessLogsResponse {
|
|
|
180
186
|
}
|
|
181
187
|
|
|
182
188
|
export interface ProcessTracesRequest {
|
|
183
|
-
|
|
189
|
+
traceBindings: TraceBinding[];
|
|
184
190
|
}
|
|
185
191
|
|
|
186
192
|
export interface ProcessTracesResponse {
|
|
@@ -524,6 +530,7 @@ function createBaseContractConfig(): ContractConfig {
|
|
|
524
530
|
contract: undefined,
|
|
525
531
|
blockConfigs: [],
|
|
526
532
|
logConfigs: [],
|
|
533
|
+
traceConfigs: [],
|
|
527
534
|
startBlock: Long.UZERO,
|
|
528
535
|
endBlock: Long.UZERO,
|
|
529
536
|
instructionConfig: undefined,
|
|
@@ -545,6 +552,9 @@ export const ContractConfig = {
|
|
|
545
552
|
for (const v of message.logConfigs) {
|
|
546
553
|
LogHandlerConfig.encode(v!, writer.uint32(26).fork()).ldelim();
|
|
547
554
|
}
|
|
555
|
+
for (const v of message.traceConfigs) {
|
|
556
|
+
TraceHandlerConfig.encode(v!, writer.uint32(18).fork()).ldelim();
|
|
557
|
+
}
|
|
548
558
|
if (!message.startBlock.isZero()) {
|
|
549
559
|
writer.uint32(32).uint64(message.startBlock);
|
|
550
560
|
}
|
|
@@ -583,6 +593,11 @@ export const ContractConfig = {
|
|
|
583
593
|
LogHandlerConfig.decode(reader, reader.uint32())
|
|
584
594
|
);
|
|
585
595
|
break;
|
|
596
|
+
case 2:
|
|
597
|
+
message.traceConfigs.push(
|
|
598
|
+
TraceHandlerConfig.decode(reader, reader.uint32())
|
|
599
|
+
);
|
|
600
|
+
break;
|
|
586
601
|
case 4:
|
|
587
602
|
message.startBlock = reader.uint64() as Long;
|
|
588
603
|
break;
|
|
@@ -617,6 +632,9 @@ export const ContractConfig = {
|
|
|
617
632
|
logConfigs: Array.isArray(object?.logConfigs)
|
|
618
633
|
? object.logConfigs.map((e: any) => LogHandlerConfig.fromJSON(e))
|
|
619
634
|
: [],
|
|
635
|
+
traceConfigs: Array.isArray(object?.traceConfigs)
|
|
636
|
+
? object.traceConfigs.map((e: any) => TraceHandlerConfig.fromJSON(e))
|
|
637
|
+
: [],
|
|
620
638
|
startBlock: isSet(object.startBlock)
|
|
621
639
|
? Long.fromValue(object.startBlock)
|
|
622
640
|
: Long.UZERO,
|
|
@@ -652,6 +670,13 @@ export const ContractConfig = {
|
|
|
652
670
|
} else {
|
|
653
671
|
obj.logConfigs = [];
|
|
654
672
|
}
|
|
673
|
+
if (message.traceConfigs) {
|
|
674
|
+
obj.traceConfigs = message.traceConfigs.map((e) =>
|
|
675
|
+
e ? TraceHandlerConfig.toJSON(e) : undefined
|
|
676
|
+
);
|
|
677
|
+
} else {
|
|
678
|
+
obj.traceConfigs = [];
|
|
679
|
+
}
|
|
655
680
|
message.startBlock !== undefined &&
|
|
656
681
|
(obj.startBlock = (message.startBlock || Long.UZERO).toString());
|
|
657
682
|
message.endBlock !== undefined &&
|
|
@@ -675,6 +700,8 @@ export const ContractConfig = {
|
|
|
675
700
|
object.blockConfigs?.map((e) => BlockHandlerConfig.fromPartial(e)) || [];
|
|
676
701
|
message.logConfigs =
|
|
677
702
|
object.logConfigs?.map((e) => LogHandlerConfig.fromPartial(e)) || [];
|
|
703
|
+
message.traceConfigs =
|
|
704
|
+
object.traceConfigs?.map((e) => TraceHandlerConfig.fromPartial(e)) || [];
|
|
678
705
|
message.startBlock =
|
|
679
706
|
object.startBlock !== undefined && object.startBlock !== null
|
|
680
707
|
? Long.fromValue(object.startBlock)
|
|
@@ -994,6 +1021,68 @@ export const BlockHandlerConfig = {
|
|
|
994
1021
|
},
|
|
995
1022
|
};
|
|
996
1023
|
|
|
1024
|
+
function createBaseTraceHandlerConfig(): TraceHandlerConfig {
|
|
1025
|
+
return { signature: "", handlerId: 0 };
|
|
1026
|
+
}
|
|
1027
|
+
|
|
1028
|
+
export const TraceHandlerConfig = {
|
|
1029
|
+
encode(
|
|
1030
|
+
message: TraceHandlerConfig,
|
|
1031
|
+
writer: _m0.Writer = _m0.Writer.create()
|
|
1032
|
+
): _m0.Writer {
|
|
1033
|
+
if (message.signature !== "") {
|
|
1034
|
+
writer.uint32(10).string(message.signature);
|
|
1035
|
+
}
|
|
1036
|
+
if (message.handlerId !== 0) {
|
|
1037
|
+
writer.uint32(16).int32(message.handlerId);
|
|
1038
|
+
}
|
|
1039
|
+
return writer;
|
|
1040
|
+
},
|
|
1041
|
+
|
|
1042
|
+
decode(input: _m0.Reader | Uint8Array, length?: number): TraceHandlerConfig {
|
|
1043
|
+
const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input);
|
|
1044
|
+
let end = length === undefined ? reader.len : reader.pos + length;
|
|
1045
|
+
const message = createBaseTraceHandlerConfig();
|
|
1046
|
+
while (reader.pos < end) {
|
|
1047
|
+
const tag = reader.uint32();
|
|
1048
|
+
switch (tag >>> 3) {
|
|
1049
|
+
case 1:
|
|
1050
|
+
message.signature = reader.string();
|
|
1051
|
+
break;
|
|
1052
|
+
case 2:
|
|
1053
|
+
message.handlerId = reader.int32();
|
|
1054
|
+
break;
|
|
1055
|
+
default:
|
|
1056
|
+
reader.skipType(tag & 7);
|
|
1057
|
+
break;
|
|
1058
|
+
}
|
|
1059
|
+
}
|
|
1060
|
+
return message;
|
|
1061
|
+
},
|
|
1062
|
+
|
|
1063
|
+
fromJSON(object: any): TraceHandlerConfig {
|
|
1064
|
+
return {
|
|
1065
|
+
signature: isSet(object.signature) ? String(object.signature) : "",
|
|
1066
|
+
handlerId: isSet(object.handlerId) ? Number(object.handlerId) : 0,
|
|
1067
|
+
};
|
|
1068
|
+
},
|
|
1069
|
+
|
|
1070
|
+
toJSON(message: TraceHandlerConfig): unknown {
|
|
1071
|
+
const obj: any = {};
|
|
1072
|
+
message.signature !== undefined && (obj.signature = message.signature);
|
|
1073
|
+
message.handlerId !== undefined &&
|
|
1074
|
+
(obj.handlerId = Math.round(message.handlerId));
|
|
1075
|
+
return obj;
|
|
1076
|
+
},
|
|
1077
|
+
|
|
1078
|
+
fromPartial(object: DeepPartial<TraceHandlerConfig>): TraceHandlerConfig {
|
|
1079
|
+
const message = createBaseTraceHandlerConfig();
|
|
1080
|
+
message.signature = object.signature ?? "";
|
|
1081
|
+
message.handlerId = object.handlerId ?? 0;
|
|
1082
|
+
return message;
|
|
1083
|
+
},
|
|
1084
|
+
};
|
|
1085
|
+
|
|
997
1086
|
function createBaseLogHandlerConfig(): LogHandlerConfig {
|
|
998
1087
|
return { filters: [], handlerId: 0 };
|
|
999
1088
|
}
|
|
@@ -1400,7 +1489,7 @@ export const ProcessLogsResponse = {
|
|
|
1400
1489
|
};
|
|
1401
1490
|
|
|
1402
1491
|
function createBaseProcessTracesRequest(): ProcessTracesRequest {
|
|
1403
|
-
return {
|
|
1492
|
+
return { traceBindings: [] };
|
|
1404
1493
|
}
|
|
1405
1494
|
|
|
1406
1495
|
export const ProcessTracesRequest = {
|
|
@@ -1408,8 +1497,8 @@ export const ProcessTracesRequest = {
|
|
|
1408
1497
|
message: ProcessTracesRequest,
|
|
1409
1498
|
writer: _m0.Writer = _m0.Writer.create()
|
|
1410
1499
|
): _m0.Writer {
|
|
1411
|
-
for (const v of message.
|
|
1412
|
-
|
|
1500
|
+
for (const v of message.traceBindings) {
|
|
1501
|
+
TraceBinding.encode(v!, writer.uint32(10).fork()).ldelim();
|
|
1413
1502
|
}
|
|
1414
1503
|
return writer;
|
|
1415
1504
|
},
|
|
@@ -1425,7 +1514,9 @@ export const ProcessTracesRequest = {
|
|
|
1425
1514
|
const tag = reader.uint32();
|
|
1426
1515
|
switch (tag >>> 3) {
|
|
1427
1516
|
case 1:
|
|
1428
|
-
message.
|
|
1517
|
+
message.traceBindings.push(
|
|
1518
|
+
TraceBinding.decode(reader, reader.uint32())
|
|
1519
|
+
);
|
|
1429
1520
|
break;
|
|
1430
1521
|
default:
|
|
1431
1522
|
reader.skipType(tag & 7);
|
|
@@ -1437,28 +1528,28 @@ export const ProcessTracesRequest = {
|
|
|
1437
1528
|
|
|
1438
1529
|
fromJSON(object: any): ProcessTracesRequest {
|
|
1439
1530
|
return {
|
|
1440
|
-
|
|
1441
|
-
? object.
|
|
1531
|
+
traceBindings: Array.isArray(object?.traceBindings)
|
|
1532
|
+
? object.traceBindings.map((e: any) => TraceBinding.fromJSON(e))
|
|
1442
1533
|
: [],
|
|
1443
1534
|
};
|
|
1444
1535
|
},
|
|
1445
1536
|
|
|
1446
1537
|
toJSON(message: ProcessTracesRequest): unknown {
|
|
1447
1538
|
const obj: any = {};
|
|
1448
|
-
if (message.
|
|
1449
|
-
obj.
|
|
1450
|
-
e ?
|
|
1539
|
+
if (message.traceBindings) {
|
|
1540
|
+
obj.traceBindings = message.traceBindings.map((e) =>
|
|
1541
|
+
e ? TraceBinding.toJSON(e) : undefined
|
|
1451
1542
|
);
|
|
1452
1543
|
} else {
|
|
1453
|
-
obj.
|
|
1544
|
+
obj.traceBindings = [];
|
|
1454
1545
|
}
|
|
1455
1546
|
return obj;
|
|
1456
1547
|
},
|
|
1457
1548
|
|
|
1458
1549
|
fromPartial(object: DeepPartial<ProcessTracesRequest>): ProcessTracesRequest {
|
|
1459
1550
|
const message = createBaseProcessTracesRequest();
|
|
1460
|
-
message.
|
|
1461
|
-
object.
|
|
1551
|
+
message.traceBindings =
|
|
1552
|
+
object.traceBindings?.map((e) => TraceBinding.fromPartial(e)) || [];
|
|
1462
1553
|
return message;
|
|
1463
1554
|
},
|
|
1464
1555
|
};
|
package/src/index.ts
CHANGED
|
@@ -12,6 +12,7 @@ export { transformEtherError } from './error'
|
|
|
12
12
|
export { ProcessorState } from './processor-state'
|
|
13
13
|
export { BigNumber as BigDecimal } from 'bignumber.js'
|
|
14
14
|
export { EthersError } from './error'
|
|
15
|
+
export type { TypedTrace } from './trace'
|
|
15
16
|
|
|
16
17
|
export { getProcessor, addProcessor, getContractByABI, addContractByABI, getContractName } from './binds'
|
|
17
18
|
|
package/src/meter.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { RecordMetaData } from './gen/processor/protos/processor'
|
|
2
|
-
import {
|
|
2
|
+
import { BaseContext, Context, SolanaContext } from './context'
|
|
3
3
|
import { toMetricValue, Numberish } from './numberish'
|
|
4
4
|
import Long from 'long'
|
|
5
5
|
|
|
@@ -8,7 +8,7 @@ export function normalizeName(name: string) {
|
|
|
8
8
|
return name.slice(0, 100).replace(regex, '_')
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
-
function GetRecordMetaData(ctx:
|
|
11
|
+
function GetRecordMetaData(ctx: BaseContext, name: string, labels: Labels): RecordMetaData {
|
|
12
12
|
name = normalizeName(name)
|
|
13
13
|
|
|
14
14
|
if (ctx instanceof Context) {
|
|
@@ -34,6 +34,17 @@ function GetRecordMetaData(ctx: EthContext | SolanaContext, name: string, labels
|
|
|
34
34
|
labels: labels,
|
|
35
35
|
}
|
|
36
36
|
}
|
|
37
|
+
if (ctx.trace) {
|
|
38
|
+
return {
|
|
39
|
+
contractAddress: ctx.contract.rawContract.address,
|
|
40
|
+
blockNumber: Long.fromNumber(ctx.trace.blockNumber, true),
|
|
41
|
+
transactionIndex: ctx.trace.transactionPosition, // TODO make sure if this is the right value to set
|
|
42
|
+
logIndex: -1,
|
|
43
|
+
chainId: ctx.chainId.toString(),
|
|
44
|
+
name: name,
|
|
45
|
+
labels: labels,
|
|
46
|
+
}
|
|
47
|
+
}
|
|
37
48
|
} else if (ctx instanceof SolanaContext) {
|
|
38
49
|
return {
|
|
39
50
|
contractAddress: ctx.address,
|
|
@@ -51,10 +62,10 @@ function GetRecordMetaData(ctx: EthContext | SolanaContext, name: string, labels
|
|
|
51
62
|
export type Labels = { [key: string]: string }
|
|
52
63
|
|
|
53
64
|
export class Counter {
|
|
54
|
-
private readonly ctx:
|
|
65
|
+
private readonly ctx: BaseContext
|
|
55
66
|
private readonly name: string
|
|
56
67
|
|
|
57
|
-
constructor(name: string, ctx:
|
|
68
|
+
constructor(name: string, ctx: BaseContext) {
|
|
58
69
|
this.name = name
|
|
59
70
|
this.ctx = ctx
|
|
60
71
|
}
|
|
@@ -79,9 +90,9 @@ export class Counter {
|
|
|
79
90
|
|
|
80
91
|
export class Gauge {
|
|
81
92
|
private readonly name: string
|
|
82
|
-
private readonly ctx:
|
|
93
|
+
private readonly ctx: BaseContext
|
|
83
94
|
|
|
84
|
-
constructor(name: string, ctx:
|
|
95
|
+
constructor(name: string, ctx: BaseContext) {
|
|
85
96
|
this.name = name
|
|
86
97
|
this.ctx = ctx
|
|
87
98
|
}
|
|
@@ -96,13 +107,13 @@ export class Gauge {
|
|
|
96
107
|
}
|
|
97
108
|
|
|
98
109
|
export class Meter {
|
|
99
|
-
private readonly ctx:
|
|
110
|
+
private readonly ctx: BaseContext
|
|
100
111
|
|
|
101
112
|
// TODO is map necessary since we are sending request remotely?
|
|
102
113
|
// counterMap = new Map<string, Counter>()
|
|
103
114
|
// gaugeMap = new Map<string, Gauge>()
|
|
104
115
|
|
|
105
|
-
constructor(ctx:
|
|
116
|
+
constructor(ctx: BaseContext) {
|
|
106
117
|
this.ctx = ctx
|
|
107
118
|
}
|
|
108
119
|
|
package/src/service.ts
CHANGED
|
@@ -23,16 +23,19 @@ import {
|
|
|
23
23
|
ProcessTransactionsResponse,
|
|
24
24
|
StartRequest,
|
|
25
25
|
TemplateInstance,
|
|
26
|
+
TraceBinding,
|
|
26
27
|
} from './gen/processor/protos/processor'
|
|
27
28
|
|
|
28
29
|
import { Empty } from './gen/google/protobuf/empty'
|
|
29
30
|
import Long from 'long'
|
|
30
31
|
import { TextDecoder } from 'util'
|
|
32
|
+
import { Trace } from './trace'
|
|
31
33
|
|
|
32
34
|
const DEFAULT_MAX_BLOCK = Long.ZERO
|
|
33
35
|
|
|
34
36
|
export class ProcessorServiceImpl implements ProcessorServiceImplementation {
|
|
35
37
|
private eventHandlers: ((event: Log) => Promise<ProcessResult>)[] = []
|
|
38
|
+
private traceHandlers: ((trace: Trace) => Promise<ProcessResult>)[] = []
|
|
36
39
|
private blockHandlers: ((block: Block) => Promise<ProcessResult>)[] = []
|
|
37
40
|
|
|
38
41
|
// map from chain id to list of processors
|
|
@@ -88,6 +91,7 @@ export class ProcessorServiceImpl implements ProcessorServiceImplementation {
|
|
|
88
91
|
},
|
|
89
92
|
blockConfigs: [],
|
|
90
93
|
logConfigs: [],
|
|
94
|
+
traceConfigs: [],
|
|
91
95
|
startBlock: processor.config.startBlock,
|
|
92
96
|
endBlock: DEFAULT_MAX_BLOCK,
|
|
93
97
|
instructionConfig: undefined,
|
|
@@ -104,7 +108,16 @@ export class ProcessorServiceImpl implements ProcessorServiceImplementation {
|
|
|
104
108
|
})
|
|
105
109
|
}
|
|
106
110
|
|
|
107
|
-
// Step 2. Prepare all
|
|
111
|
+
// Step 2. Prepare all trace handlers
|
|
112
|
+
for (const traceHandler of processor.traceHandlers) {
|
|
113
|
+
const handlerId = this.traceHandlers.push(traceHandler.handler) - 1
|
|
114
|
+
contractConfig.traceConfigs.push({
|
|
115
|
+
signature: traceHandler.signature,
|
|
116
|
+
handlerId: handlerId,
|
|
117
|
+
})
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// Step 3. Prepare all the event handlers
|
|
108
121
|
for (const eventsHandler of processor.eventHandlers) {
|
|
109
122
|
// associate id with filter
|
|
110
123
|
const handlerId = this.eventHandlers.push(eventsHandler.handler) - 1
|
|
@@ -151,6 +164,7 @@ export class ProcessorServiceImpl implements ProcessorServiceImplementation {
|
|
|
151
164
|
},
|
|
152
165
|
blockConfigs: [],
|
|
153
166
|
logConfigs: [],
|
|
167
|
+
traceConfigs: [],
|
|
154
168
|
startBlock: solanaProcessor.config.startSlot,
|
|
155
169
|
endBlock: DEFAULT_MAX_BLOCK,
|
|
156
170
|
instructionConfig: {
|
|
@@ -388,10 +402,37 @@ export class ProcessorServiceImpl implements ProcessorServiceImplementation {
|
|
|
388
402
|
}
|
|
389
403
|
|
|
390
404
|
async processTraces(request: ProcessTracesRequest, context: CallContext): Promise<ProcessTracesResponse> {
|
|
405
|
+
if (!this.started) {
|
|
406
|
+
throw new ServerError(Status.UNAVAILABLE, 'Service Not started.')
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
const promises = request.traceBindings.map((binding) => this.processTrace(binding))
|
|
410
|
+
const results = await Promise.all(promises)
|
|
411
|
+
|
|
412
|
+
const res = ProcessResult.fromPartial({})
|
|
413
|
+
|
|
414
|
+
for (const r of results) {
|
|
415
|
+
res.counters = res.counters.concat(r.counters)
|
|
416
|
+
res.gauges = res.gauges.concat(r.gauges)
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
recordRuntimeInfo(res, HandlerType.TRACE)
|
|
391
420
|
return {
|
|
392
|
-
result:
|
|
421
|
+
result: res,
|
|
393
422
|
}
|
|
394
423
|
}
|
|
424
|
+
|
|
425
|
+
async processTrace(binding: TraceBinding): Promise<ProcessResult> {
|
|
426
|
+
if (!binding.trace) {
|
|
427
|
+
throw new ServerError(Status.INVALID_ARGUMENT, "Trace can't be empty")
|
|
428
|
+
}
|
|
429
|
+
const jsonString = Utf8ArrayToStr(binding.trace.raw)
|
|
430
|
+
const trace: Trace = JSON.parse(jsonString)
|
|
431
|
+
|
|
432
|
+
return this.traceHandlers[binding.handlerId](trace).catch((e) => {
|
|
433
|
+
throw new ServerError(Status.INTERNAL, 'error processing trace: ' + jsonString + '\n' + e.toString())
|
|
434
|
+
})
|
|
435
|
+
}
|
|
395
436
|
}
|
|
396
437
|
|
|
397
438
|
// https://ourcodeworld.com/articles/read/164/how-to-convert-an-uint8array-to-string-in-javascript
|
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
import { reservedKeywords } from '@typechain/ethers-v5/dist/codegen/reserved-keywords'
|
|
10
10
|
import { generateInputTypes } from '@typechain/ethers-v5/dist/codegen/types'
|
|
11
11
|
import { getFullSignatureForEvent } from 'typechain/dist/utils/signatures'
|
|
12
|
+
import { codegenCallTraceTypes, codegenFunctions } from './functions'
|
|
12
13
|
|
|
13
14
|
export function codeGenIndex(contract: Contract): string {
|
|
14
15
|
return `
|
|
@@ -72,6 +73,8 @@ export function codeGenSentioFile(contract: Contract): string {
|
|
|
72
73
|
.join('\n')}
|
|
73
74
|
}
|
|
74
75
|
|
|
76
|
+
${Object.values(contract.functions).map(codegenCallTraceTypes).join('\n')}
|
|
77
|
+
|
|
75
78
|
export class ${contract.name}Processor extends BaseProcessor<${contract.name}, ${contract.name}BoundContractView> {
|
|
76
79
|
${Object.values(contract.events)
|
|
77
80
|
.map((events) => {
|
|
@@ -83,6 +86,10 @@ export function codeGenSentioFile(contract: Contract): string {
|
|
|
83
86
|
})
|
|
84
87
|
.join('\n')}
|
|
85
88
|
|
|
89
|
+
${Object.values(contract.functions)
|
|
90
|
+
.map((f) => codegenFunctions(f, contract.name))
|
|
91
|
+
.join('\n')}
|
|
92
|
+
|
|
86
93
|
public static filters = templateContract.filters
|
|
87
94
|
|
|
88
95
|
protected CreateBoundContractView(): ${contract.name}BoundContractView {
|
|
@@ -134,6 +141,7 @@ export function codeGenSentioFile(contract: Contract): string {
|
|
|
134
141
|
'ContractView',
|
|
135
142
|
'DummyProvider',
|
|
136
143
|
'getContractName',
|
|
144
|
+
'TypedTrace',
|
|
137
145
|
],
|
|
138
146
|
'./common': ['PromiseOrValue'],
|
|
139
147
|
'./index': [`${contract.name}`, `${contract.name}__factory`],
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { generateInputTypes } from '@typechain/ethers-v5/dist/codegen/types'
|
|
2
|
+
import { FunctionDeclaration, getSignatureForFn } from 'typechain'
|
|
3
|
+
|
|
4
|
+
export function codegenFunctions(fns: FunctionDeclaration[], contractName: string): string {
|
|
5
|
+
if (fns.length === 1) {
|
|
6
|
+
return generateFunction(fns[0], contractName)
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
return fns.map((fn) => generateFunction(fn, contractName, getFullSignatureAsSymbolForFunction(fn))).join('\n')
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export function codegenCallTraceTypes(fns: FunctionDeclaration[]): string {
|
|
13
|
+
if (fns.length === 1) {
|
|
14
|
+
return codegenCallTraceType(fns[0])
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
return fns.map((fn) => codegenCallTraceType(fn, getFullSignatureAsSymbolForFunction(fn))).join('\n')
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function codegenCallTraceType(fn: FunctionDeclaration, overloadedName?: string): string {
|
|
21
|
+
return `
|
|
22
|
+
export interface ${capitalizeFirstChar(overloadedName ?? fn.name)}CallTrace extends TypedTrace {
|
|
23
|
+
args: [${generateInputTypes(fn.inputs, { useStructs: true })}]
|
|
24
|
+
}
|
|
25
|
+
`
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function generateFunction(fn: FunctionDeclaration, contractName: string, overloadedName?: string): string {
|
|
29
|
+
return `
|
|
30
|
+
on${capitalizeFirstChar(overloadedName ?? fn.name)}Call(
|
|
31
|
+
handler: (trace: ${capitalizeFirstChar(overloadedName ?? fn.name)}CallTrace, ctx: ${contractName}Context) => void
|
|
32
|
+
) {
|
|
33
|
+
return super.onTrace("${getSignatureForFn(fn)}", handler);
|
|
34
|
+
}
|
|
35
|
+
`
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function getFullSignatureAsSymbolForFunction(fn: FunctionDeclaration): string {
|
|
39
|
+
return `${fn.name}_${fn.inputs
|
|
40
|
+
.map((e) => {
|
|
41
|
+
if (e.type.type === 'array') {
|
|
42
|
+
return e.type.itemType.originalType + '_array'
|
|
43
|
+
} else {
|
|
44
|
+
return e.type.originalType
|
|
45
|
+
}
|
|
46
|
+
})
|
|
47
|
+
.join('_')}`
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function capitalizeFirstChar(input: string): string {
|
|
51
|
+
if (!input) {
|
|
52
|
+
return input
|
|
53
|
+
}
|
|
54
|
+
return input[0].toUpperCase() + (input.length > 1 ? input.substring(1) : '')
|
|
55
|
+
}
|
package/src/trace.ts
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
// https://github.com/openethereum/parity-ethereum/blob/55c90d4016505317034e3e98f699af07f5404b63/rpc/src/v1/types/trace.rs#L482
|
|
2
|
+
import { Result } from '@ethersproject/abi'
|
|
3
|
+
|
|
4
|
+
export interface TypedTrace<TArgsArray extends Array<any> = any, TArgsObject = any> extends Trace {
|
|
5
|
+
args: TArgsArray & TArgsObject
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export interface Trace {
|
|
9
|
+
args?: Result
|
|
10
|
+
|
|
11
|
+
action: TraceAction
|
|
12
|
+
blockHash: string
|
|
13
|
+
blockNumber: number
|
|
14
|
+
result: TraceResult
|
|
15
|
+
subtraces: number
|
|
16
|
+
traceAddress: number[]
|
|
17
|
+
transactionHash: string
|
|
18
|
+
transactionPosition: number
|
|
19
|
+
type: string
|
|
20
|
+
error?: string
|
|
21
|
+
}
|
|
22
|
+
// export type CallType = "call" | "callcode" | "delegatecall" | "staticcall"
|
|
23
|
+
|
|
24
|
+
export interface TraceAction {
|
|
25
|
+
from: string
|
|
26
|
+
to: string
|
|
27
|
+
value: number
|
|
28
|
+
gas: number
|
|
29
|
+
input: string
|
|
30
|
+
callType: string
|
|
31
|
+
|
|
32
|
+
init?: string
|
|
33
|
+
address?: string
|
|
34
|
+
balance?: string
|
|
35
|
+
refundAddress?: string
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// TODO are more field missing for FailedCall, FailedCreate
|
|
39
|
+
export interface TraceResult {
|
|
40
|
+
gasUsed: number
|
|
41
|
+
output: string
|
|
42
|
+
address?: string
|
|
43
|
+
code?: string
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// const TRACE: Trace = {
|
|
47
|
+
// action: {
|
|
48
|
+
// from: '0xd771111cbfa2bbdafbf9f0e58b49b3f827da31f5',
|
|
49
|
+
// callType: 'call',
|
|
50
|
+
// gas: 0x12154,
|
|
51
|
+
// input:
|
|
52
|
+
// '0xb1a417f4000000000000000000000000d771111cbfa2bbdafbf9f0e58b49b3f827da31f5000000000000000000000000d771111cbfa2bbdafbf9f0e58b49b3f827da31f500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000131888b5aaf000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000',
|
|
53
|
+
// to: '0x0baba1ad5be3a5c0a66e7ac838a129bf948f1ea4',
|
|
54
|
+
// value: 0x131888b5aaf0000,
|
|
55
|
+
// },
|
|
56
|
+
// blockHash: '0x5451711bc530a7c04128fedbe149eb359c10eccd44a83909d448c5244c7eea26',
|
|
57
|
+
// blockNumber: 15533908,
|
|
58
|
+
// result: { gasUsed: 0x114c1, output: '0x' },
|
|
59
|
+
// subtraces: 1,
|
|
60
|
+
// traceAddress: [],
|
|
61
|
+
// transactionHash: '0x66dce11d6217042ed709a38e507e7762c93b1bde4a0447ae7a243493bbdffc0e',
|
|
62
|
+
// transactionPosition: 73,
|
|
63
|
+
// type: 'call',
|
|
64
|
+
// }
|