@sentio/sdk 2.57.9-rc.1 → 2.57.9-rc.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/aptos/aptos-plugin.d.ts.map +1 -1
- package/lib/aptos/aptos-plugin.js +4 -2
- package/lib/aptos/aptos-plugin.js.map +1 -1
- package/lib/aptos/aptos-processor.d.ts +8 -2
- package/lib/aptos/aptos-processor.d.ts.map +1 -1
- package/lib/aptos/aptos-processor.js +11 -4
- package/lib/aptos/aptos-processor.js.map +1 -1
- package/lib/aptos/builtin/0x1.d.ts +155 -155
- package/lib/aptos/builtin/0x1.d.ts.map +1 -1
- package/lib/aptos/builtin/0x1.js +395 -308
- package/lib/aptos/builtin/0x1.js.map +1 -1
- package/lib/aptos/builtin/0x3.d.ts +52 -52
- package/lib/aptos/builtin/0x3.d.ts.map +1 -1
- package/lib/aptos/builtin/0x3.js +135 -102
- package/lib/aptos/builtin/0x3.js.map +1 -1
- package/lib/aptos/builtin/0x4.d.ts +12 -12
- package/lib/aptos/builtin/0x4.d.ts.map +1 -1
- package/lib/aptos/builtin/0x4.js +22 -22
- package/lib/aptos/builtin/0x4.js.map +1 -1
- package/lib/core/normalization.d.ts.map +1 -1
- package/lib/core/normalization.js +69 -3
- package/lib/core/normalization.js.map +1 -1
- package/lib/core/normalization.test.js.map +1 -1
- package/lib/eth/abi-decoder/decode-worker.d.ts +27 -0
- package/lib/eth/abi-decoder/decode-worker.d.ts.map +1 -0
- package/lib/eth/abi-decoder/decode-worker.js +63 -0
- package/lib/eth/abi-decoder/decode-worker.js.map +1 -0
- package/lib/eth/abi-decoder/index.d.ts +4 -0
- package/lib/eth/abi-decoder/index.d.ts.map +1 -0
- package/lib/eth/abi-decoder/index.js +134 -0
- package/lib/eth/abi-decoder/index.js.map +1 -0
- package/lib/eth/base-processor.d.ts.map +1 -1
- package/lib/eth/base-processor.js +7 -7
- package/lib/eth/base-processor.js.map +1 -1
- package/lib/move/filter.d.ts +1 -0
- package/lib/move/filter.d.ts.map +1 -1
- package/lib/move/filter.js.map +1 -1
- package/lib/move/shared-network-codegen.js +3 -3
- package/lib/move/shared-network-codegen.js.map +1 -1
- package/lib/store/codegen.js +1 -1
- package/lib/store/codegen.js.map +1 -1
- package/lib/store/convert.d.ts +1 -0
- package/lib/store/convert.d.ts.map +1 -1
- package/lib/store/convert.js +16 -0
- package/lib/store/convert.js.map +1 -1
- package/lib/store/decorators.d.ts +1 -0
- package/lib/store/decorators.d.ts.map +1 -1
- package/lib/store/decorators.js +2 -1
- package/lib/store/decorators.js.map +1 -1
- package/lib/store/schema.js +1 -1
- package/lib/store/schema.js.map +1 -1
- package/lib/store/types.d.ts +1 -0
- package/lib/store/types.d.ts.map +1 -1
- package/lib/store/types.js +3 -0
- package/lib/store/types.js.map +1 -1
- package/lib/sui/builtin/0x1.d.ts +7 -7
- package/lib/sui/builtin/0x1.d.ts.map +1 -1
- package/lib/sui/builtin/0x1.js +12 -12
- package/lib/sui/builtin/0x1.js.map +1 -1
- package/lib/sui/builtin/0x2.d.ts +34 -34
- package/lib/sui/builtin/0x2.d.ts.map +1 -1
- package/lib/sui/builtin/0x2.js +72 -66
- package/lib/sui/builtin/0x2.js.map +1 -1
- package/lib/sui/builtin/0x3.d.ts +14 -14
- package/lib/sui/builtin/0x3.d.ts.map +1 -1
- package/lib/sui/builtin/0x3.js +44 -26
- package/lib/sui/builtin/0x3.js.map +1 -1
- package/lib/sui/sui-plugin.d.ts.map +1 -1
- package/lib/sui/sui-plugin.js +2 -1
- package/lib/sui/sui-plugin.js.map +1 -1
- package/lib/tsup.config.ts +1 -1
- package/package.json +5 -3
- package/src/aptos/aptos-plugin.ts +4 -2
- package/src/aptos/aptos-processor.ts +18 -4
- package/src/aptos/builtin/0x1.ts +644 -155
- package/src/aptos/builtin/0x3.ts +208 -52
- package/src/aptos/builtin/0x4.ts +59 -12
- package/src/bundle.config.ts +1 -1
- package/src/core/normalization.ts +69 -4
- package/src/eth/abi-decoder/decode-worker.ts +85 -0
- package/src/eth/abi-decoder/index.ts +133 -0
- package/src/eth/base-processor.ts +19 -20
- package/src/move/filter.ts +1 -0
- package/src/move/shared-network-codegen.ts +3 -3
- package/src/store/codegen.ts +1 -1
- package/src/store/convert.ts +17 -0
- package/src/store/decorators.ts +2 -0
- package/src/store/schema.ts +1 -1
- package/src/store/types.ts +4 -0
- package/src/sui/builtin/0x1.ts +33 -7
- package/src/sui/builtin/0x2.ts +177 -34
- package/src/sui/builtin/0x3.ts +45 -14
- package/src/sui/sui-plugin.ts +2 -1
- package/src/tsup.config.ts +1 -1
package/src/aptos/builtin/0x4.ts
CHANGED
@@ -4,7 +4,7 @@
|
|
4
4
|
|
5
5
|
/* Generated types for 0x4, original address 0x4 */
|
6
6
|
|
7
|
-
import { CallFilter, MoveFetchConfig } from "@sentio/sdk/move";
|
7
|
+
import { CallFilter, MoveFetchConfig, EventFilter } from "@sentio/sdk/move";
|
8
8
|
import {
|
9
9
|
AptosBindOptions,
|
10
10
|
AptosBaseProcessor,
|
@@ -45,16 +45,26 @@ export class token extends AptosBaseProcessor {
|
|
45
45
|
onEventMutation(
|
46
46
|
func: (event: token.MutationInstance, ctx: AptosContext) => void,
|
47
47
|
fetchConfig?: Partial<MoveFetchConfig>,
|
48
|
+
eventFilter?: Omit<EventFilter, "type" | "account">,
|
48
49
|
): token {
|
49
|
-
this.onMoveEvent(
|
50
|
+
this.onMoveEvent(
|
51
|
+
func,
|
52
|
+
{ ...(eventFilter ?? {}), type: "token::Mutation" },
|
53
|
+
fetchConfig,
|
54
|
+
);
|
50
55
|
return this;
|
51
56
|
}
|
52
57
|
|
53
58
|
onEventMutationEvent(
|
54
59
|
func: (event: token.MutationEventInstance, ctx: AptosContext) => void,
|
55
60
|
fetchConfig?: Partial<MoveFetchConfig>,
|
61
|
+
eventFilter?: Omit<EventFilter, "type" | "account">,
|
56
62
|
): token {
|
57
|
-
this.onMoveEvent(
|
63
|
+
this.onMoveEvent(
|
64
|
+
func,
|
65
|
+
{ ...(eventFilter ?? {}), type: "token::MutationEvent" },
|
66
|
+
fetchConfig,
|
67
|
+
);
|
58
68
|
return this;
|
59
69
|
}
|
60
70
|
}
|
@@ -436,16 +446,26 @@ export class collection extends AptosBaseProcessor {
|
|
436
446
|
onEventBurn(
|
437
447
|
func: (event: collection.BurnInstance, ctx: AptosContext) => void,
|
438
448
|
fetchConfig?: Partial<MoveFetchConfig>,
|
449
|
+
eventFilter?: Omit<EventFilter, "type" | "account">,
|
439
450
|
): collection {
|
440
|
-
this.onMoveEvent(
|
451
|
+
this.onMoveEvent(
|
452
|
+
func,
|
453
|
+
{ ...(eventFilter ?? {}), type: "collection::Burn" },
|
454
|
+
fetchConfig,
|
455
|
+
);
|
441
456
|
return this;
|
442
457
|
}
|
443
458
|
|
444
459
|
onEventBurnEvent(
|
445
460
|
func: (event: collection.BurnEventInstance, ctx: AptosContext) => void,
|
446
461
|
fetchConfig?: Partial<MoveFetchConfig>,
|
462
|
+
eventFilter?: Omit<EventFilter, "type" | "account">,
|
447
463
|
): collection {
|
448
|
-
this.onMoveEvent(
|
464
|
+
this.onMoveEvent(
|
465
|
+
func,
|
466
|
+
{ ...(eventFilter ?? {}), type: "collection::BurnEvent" },
|
467
|
+
fetchConfig,
|
468
|
+
);
|
449
469
|
return this;
|
450
470
|
}
|
451
471
|
|
@@ -455,10 +475,11 @@ export class collection extends AptosBaseProcessor {
|
|
455
475
|
ctx: AptosContext,
|
456
476
|
) => void,
|
457
477
|
fetchConfig?: Partial<MoveFetchConfig>,
|
478
|
+
eventFilter?: Omit<EventFilter, "type" | "account">,
|
458
479
|
): collection {
|
459
480
|
this.onMoveEvent(
|
460
481
|
func,
|
461
|
-
{ type: "collection::ConcurrentBurnEvent" },
|
482
|
+
{ ...(eventFilter ?? {}), type: "collection::ConcurrentBurnEvent" },
|
462
483
|
fetchConfig,
|
463
484
|
);
|
464
485
|
return this;
|
@@ -470,10 +491,11 @@ export class collection extends AptosBaseProcessor {
|
|
470
491
|
ctx: AptosContext,
|
471
492
|
) => void,
|
472
493
|
fetchConfig?: Partial<MoveFetchConfig>,
|
494
|
+
eventFilter?: Omit<EventFilter, "type" | "account">,
|
473
495
|
): collection {
|
474
496
|
this.onMoveEvent(
|
475
497
|
func,
|
476
|
-
{ type: "collection::ConcurrentMintEvent" },
|
498
|
+
{ ...(eventFilter ?? {}), type: "collection::ConcurrentMintEvent" },
|
477
499
|
fetchConfig,
|
478
500
|
);
|
479
501
|
return this;
|
@@ -482,40 +504,65 @@ export class collection extends AptosBaseProcessor {
|
|
482
504
|
onEventMint(
|
483
505
|
func: (event: collection.MintInstance, ctx: AptosContext) => void,
|
484
506
|
fetchConfig?: Partial<MoveFetchConfig>,
|
507
|
+
eventFilter?: Omit<EventFilter, "type" | "account">,
|
485
508
|
): collection {
|
486
|
-
this.onMoveEvent(
|
509
|
+
this.onMoveEvent(
|
510
|
+
func,
|
511
|
+
{ ...(eventFilter ?? {}), type: "collection::Mint" },
|
512
|
+
fetchConfig,
|
513
|
+
);
|
487
514
|
return this;
|
488
515
|
}
|
489
516
|
|
490
517
|
onEventMintEvent(
|
491
518
|
func: (event: collection.MintEventInstance, ctx: AptosContext) => void,
|
492
519
|
fetchConfig?: Partial<MoveFetchConfig>,
|
520
|
+
eventFilter?: Omit<EventFilter, "type" | "account">,
|
493
521
|
): collection {
|
494
|
-
this.onMoveEvent(
|
522
|
+
this.onMoveEvent(
|
523
|
+
func,
|
524
|
+
{ ...(eventFilter ?? {}), type: "collection::MintEvent" },
|
525
|
+
fetchConfig,
|
526
|
+
);
|
495
527
|
return this;
|
496
528
|
}
|
497
529
|
|
498
530
|
onEventMutation(
|
499
531
|
func: (event: collection.MutationInstance, ctx: AptosContext) => void,
|
500
532
|
fetchConfig?: Partial<MoveFetchConfig>,
|
533
|
+
eventFilter?: Omit<EventFilter, "type" | "account">,
|
501
534
|
): collection {
|
502
|
-
this.onMoveEvent(
|
535
|
+
this.onMoveEvent(
|
536
|
+
func,
|
537
|
+
{ ...(eventFilter ?? {}), type: "collection::Mutation" },
|
538
|
+
fetchConfig,
|
539
|
+
);
|
503
540
|
return this;
|
504
541
|
}
|
505
542
|
|
506
543
|
onEventMutationEvent(
|
507
544
|
func: (event: collection.MutationEventInstance, ctx: AptosContext) => void,
|
508
545
|
fetchConfig?: Partial<MoveFetchConfig>,
|
546
|
+
eventFilter?: Omit<EventFilter, "type" | "account">,
|
509
547
|
): collection {
|
510
|
-
this.onMoveEvent(
|
548
|
+
this.onMoveEvent(
|
549
|
+
func,
|
550
|
+
{ ...(eventFilter ?? {}), type: "collection::MutationEvent" },
|
551
|
+
fetchConfig,
|
552
|
+
);
|
511
553
|
return this;
|
512
554
|
}
|
513
555
|
|
514
556
|
onEventSetMaxSupply(
|
515
557
|
func: (event: collection.SetMaxSupplyInstance, ctx: AptosContext) => void,
|
516
558
|
fetchConfig?: Partial<MoveFetchConfig>,
|
559
|
+
eventFilter?: Omit<EventFilter, "type" | "account">,
|
517
560
|
): collection {
|
518
|
-
this.onMoveEvent(
|
561
|
+
this.onMoveEvent(
|
562
|
+
func,
|
563
|
+
{ ...(eventFilter ?? {}), type: "collection::SetMaxSupply" },
|
564
|
+
fetchConfig,
|
565
|
+
);
|
519
566
|
return this;
|
520
567
|
}
|
521
568
|
}
|
package/src/bundle.config.ts
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
import { Labels } from './meter.js'
|
2
2
|
import { BigDecimal } from './big-decimal.js'
|
3
3
|
import { BN } from 'fuels'
|
4
|
-
import { RichStruct, RichValue, RichValue_NullValue } from '@sentio/protos'
|
4
|
+
import { CoinID, RichStruct, RichValue, RichValue_NullValue, TokenAmount } from '@sentio/protos'
|
5
5
|
import { toBigInteger, toBigDecimal } from './numberish.js'
|
6
6
|
|
7
7
|
export const SENTIO_BIGINT_STRING_SUFFIX = ':sto_bi'
|
@@ -116,6 +116,9 @@ function normalizeToRichValue(value: any): RichValue {
|
|
116
116
|
const v = BigInt(value)
|
117
117
|
return { bigintValue: toBigInteger(v) }
|
118
118
|
case 'number':
|
119
|
+
if (isNaN(value) || !isFinite(value)) {
|
120
|
+
throw new Error("can't submit NaN or Infinity value")
|
121
|
+
}
|
119
122
|
if (Number.isInteger(value)) {
|
120
123
|
return { intValue: value }
|
121
124
|
}
|
@@ -138,6 +141,9 @@ function normalizeToRichValue(value: any): RichValue {
|
|
138
141
|
}
|
139
142
|
if (BN.isBN(value)) {
|
140
143
|
const value1 = new BigDecimal(value.toString())
|
144
|
+
if (value1.isNaN() || !value1.isFinite()) {
|
145
|
+
throw new Error("can't submit NaN or Infinity value")
|
146
|
+
}
|
141
147
|
return { bigdecimalValue: toBigDecimal(value1) }
|
142
148
|
}
|
143
149
|
if (Array.isArray(value)) {
|
@@ -152,13 +158,16 @@ function normalizeToRichValue(value: any): RichValue {
|
|
152
158
|
return { nullValue: RichValue_NullValue.UNRECOGNIZED }
|
153
159
|
}
|
154
160
|
if (typeof value === 'object') {
|
161
|
+
const tokenAmount = toTokenAmount(value)
|
162
|
+
if (tokenAmount) {
|
163
|
+
return { tokenValue: tokenAmount }
|
164
|
+
}
|
165
|
+
|
155
166
|
return {
|
156
167
|
structValue: normalizeToRichStruct(value)
|
157
168
|
}
|
158
169
|
}
|
159
170
|
|
160
|
-
// todo: support token value
|
161
|
-
|
162
171
|
console.warn('Cannot submit unsupported type ' + typeof value)
|
163
172
|
return { nullValue: RichValue_NullValue.UNRECOGNIZED }
|
164
173
|
}
|
@@ -170,8 +179,64 @@ export function normalizeToRichStruct(...objs: any[]): RichStruct {
|
|
170
179
|
}
|
171
180
|
for (const obj of objs) {
|
172
181
|
for (const [key, value] of Object.entries(obj)) {
|
173
|
-
|
182
|
+
try {
|
183
|
+
ret.fields[key] = normalizeToRichValue(value)
|
184
|
+
} catch (e) {
|
185
|
+
throw new Error("error when converting data for key '" + key + "': " + e.message)
|
186
|
+
}
|
187
|
+
}
|
188
|
+
}
|
189
|
+
return ret
|
190
|
+
}
|
191
|
+
|
192
|
+
function toTokenAmount(value: any): TokenAmount | undefined {
|
193
|
+
const ret = TokenAmount.create()
|
194
|
+
|
195
|
+
for (const key of Object.getOwnPropertyNames(value)) {
|
196
|
+
switch (key) {
|
197
|
+
case 'token':
|
198
|
+
const token = toCoinID(value.token)
|
199
|
+
if (!token) {
|
200
|
+
return undefined
|
201
|
+
}
|
202
|
+
ret.token = token
|
203
|
+
break
|
204
|
+
case 'amount':
|
205
|
+
if (value.amount instanceof BigDecimal) {
|
206
|
+
ret.amount = toBigDecimal(value)
|
207
|
+
} else if (typeof value.amount == 'string' || typeof value.amount == 'number') {
|
208
|
+
ret.amount = toBigDecimal(new BigDecimal(value.amount))
|
209
|
+
} else {
|
210
|
+
return undefined
|
211
|
+
}
|
212
|
+
break
|
213
|
+
case 'specifiedAt':
|
214
|
+
if (value.specifiedAt instanceof Date) {
|
215
|
+
ret.specifiedAt = value.specifiedAt
|
216
|
+
} else {
|
217
|
+
return undefined
|
218
|
+
}
|
219
|
+
break
|
220
|
+
default:
|
221
|
+
return undefined
|
174
222
|
}
|
175
223
|
}
|
224
|
+
|
225
|
+
return ret.amount && ret.token ? ret : undefined
|
226
|
+
}
|
227
|
+
|
228
|
+
function toCoinID(coin: any): CoinID | undefined {
|
229
|
+
const ret = CoinID.create()
|
230
|
+
if (typeof coin.symbol === 'string') {
|
231
|
+
return (ret.symbol = coin.symbol)
|
232
|
+
} else if (coin.hasOwnProperty('address')) {
|
233
|
+
ret.address = {
|
234
|
+
address: coin.address.address,
|
235
|
+
chain: coin.address.chain
|
236
|
+
}
|
237
|
+
} else {
|
238
|
+
return undefined
|
239
|
+
}
|
240
|
+
|
176
241
|
return ret
|
177
242
|
}
|
@@ -0,0 +1,85 @@
|
|
1
|
+
import { Interface, LogDescription, LogParams, ParamType, Result } from 'ethers'
|
2
|
+
import { Piscina } from 'piscina'
|
3
|
+
import { ServerError, Status } from 'nice-grpc'
|
4
|
+
|
5
|
+
export interface IResult {
|
6
|
+
array?: any[]
|
7
|
+
keys: string[]
|
8
|
+
}
|
9
|
+
|
10
|
+
export function decodeTraceInline(contractViewInterface: any, inputs: readonly ParamType[], traceData: string): Result {
|
11
|
+
return contractViewInterface.getAbiCoder().decode(inputs, traceData, true)
|
12
|
+
}
|
13
|
+
|
14
|
+
export function decodeTrace({ inputs, traceData }: { inputs: ParamType[]; traceData: string }): IResult | null {
|
15
|
+
const fragments = Piscina['workerData']
|
16
|
+
const contractViewInterface = new Interface(fragments)
|
17
|
+
const result = decodeTraceInline(contractViewInterface, inputs, traceData)
|
18
|
+
|
19
|
+
const argsObj = result?.args.toObject(true)
|
20
|
+
const argsArray: any[] = []
|
21
|
+
const keys: string[] = []
|
22
|
+
for (const [key, value] of Object.entries(argsObj)) {
|
23
|
+
keys.push(key)
|
24
|
+
argsArray.push(value)
|
25
|
+
}
|
26
|
+
|
27
|
+
return {
|
28
|
+
array: argsArray,
|
29
|
+
keys: keys
|
30
|
+
}
|
31
|
+
}
|
32
|
+
|
33
|
+
export interface ILogDescription {
|
34
|
+
topic: string
|
35
|
+
args: {
|
36
|
+
array?: any[]
|
37
|
+
keys: string[]
|
38
|
+
} | null
|
39
|
+
}
|
40
|
+
|
41
|
+
export function parseLogInline(contractViewInterface: any, log: LogParams): LogDescription | null {
|
42
|
+
if (!log) {
|
43
|
+
throw new ServerError(Status.INVALID_ARGUMENT, 'Log is empty')
|
44
|
+
}
|
45
|
+
const logParam = log as any as { topics: Array<string>; data: string }
|
46
|
+
return contractViewInterface.parseLog(logParam)
|
47
|
+
}
|
48
|
+
|
49
|
+
export function parseLog({ log }: { log: LogParams }): ILogDescription | null {
|
50
|
+
const fragments = Piscina['workerData']
|
51
|
+
const contractViewInterface = new Interface(fragments)
|
52
|
+
const result = parseLogInline(contractViewInterface, log)
|
53
|
+
if (!result) {
|
54
|
+
return null
|
55
|
+
}
|
56
|
+
|
57
|
+
// can't serialize LogDescription, so return args and topics only
|
58
|
+
if (result?.args == null) {
|
59
|
+
return {
|
60
|
+
args: null,
|
61
|
+
topic: result.topic
|
62
|
+
}
|
63
|
+
}
|
64
|
+
|
65
|
+
const argsObj = result?.args.toObject(true)
|
66
|
+
const argsArray: any[] = []
|
67
|
+
const keys: string[] = []
|
68
|
+
for (const [key, value] of Object.entries(argsObj)) {
|
69
|
+
keys.push(key)
|
70
|
+
argsArray.push(value)
|
71
|
+
}
|
72
|
+
|
73
|
+
return {
|
74
|
+
args: {
|
75
|
+
array: argsArray,
|
76
|
+
keys: keys
|
77
|
+
},
|
78
|
+
topic: result.topic
|
79
|
+
}
|
80
|
+
}
|
81
|
+
|
82
|
+
export default {
|
83
|
+
parseLog,
|
84
|
+
decodeTrace
|
85
|
+
}
|
@@ -0,0 +1,133 @@
|
|
1
|
+
import { LogDescription, LogParams, Result, ParamType } from 'ethers'
|
2
|
+
import { GLOBAL_CONFIG, processMetrics } from '@sentio/runtime'
|
3
|
+
import { Piscina } from 'piscina'
|
4
|
+
|
5
|
+
import { decodeTraceInline, parseLogInline, IResult } from './decode-worker.js'
|
6
|
+
|
7
|
+
function createOptions() {
|
8
|
+
const options: any = {
|
9
|
+
filename: findWorkFile(),
|
10
|
+
recordTiming: true
|
11
|
+
}
|
12
|
+
if (GLOBAL_CONFIG.execution.ethAbiDecoderConfig?.workerCount) {
|
13
|
+
try {
|
14
|
+
const workerNum = GLOBAL_CONFIG.execution.ethAbiDecoderConfig?.workerCount
|
15
|
+
options.maxThreads = workerNum
|
16
|
+
options.minThreads = workerNum
|
17
|
+
} catch (e) {}
|
18
|
+
}
|
19
|
+
return options
|
20
|
+
}
|
21
|
+
|
22
|
+
function findWorkFile() {
|
23
|
+
let baseUrl = import.meta.url
|
24
|
+
// find the base from @sentio/sdk
|
25
|
+
const index = baseUrl.indexOf('/@sentio/sdk/')
|
26
|
+
if (index > 0) {
|
27
|
+
baseUrl = baseUrl.substring(0, index + 13)
|
28
|
+
} else {
|
29
|
+
// dev environment, path is .../packages/sdk/src/eth/abi-decoder/parse-log-worker.ts
|
30
|
+
const index = baseUrl.indexOf('packages/sdk/')
|
31
|
+
if (index > 0) {
|
32
|
+
baseUrl = baseUrl.substring(0, index + 13)
|
33
|
+
}
|
34
|
+
}
|
35
|
+
return new URL('./lib/eth/abi-decoder/decode-worker.js', baseUrl).href
|
36
|
+
}
|
37
|
+
|
38
|
+
export async function parseLog(processor: any, log: LogParams) {
|
39
|
+
if (GLOBAL_CONFIG.execution.ethAbiDecoderConfig?.enabled) {
|
40
|
+
let workerPool = processor._logWorkerPool as Piscina
|
41
|
+
const contractView = processor.CreateBoundContractView()
|
42
|
+
const contractViewInterface = contractView.rawContract.interface
|
43
|
+
if (!workerPool) {
|
44
|
+
const fragments = contractViewInterface.fragments
|
45
|
+
const options = createOptions()
|
46
|
+
options.workerData = fragments
|
47
|
+
|
48
|
+
workerPool = new Piscina(options)
|
49
|
+
processor._logWorkerPool = workerPool
|
50
|
+
}
|
51
|
+
try {
|
52
|
+
const result = (await workerPool.run({ log }, { name: 'parseLog' })) as any
|
53
|
+
if (result) {
|
54
|
+
const fragment = contractViewInterface.getEvent(result.topic)
|
55
|
+
|
56
|
+
if (!fragment || fragment.anonymous) {
|
57
|
+
return null
|
58
|
+
}
|
59
|
+
return new LogDescription(fragment, result.topic, Result.fromItems(result.args?.array ?? [], result.args?.keys))
|
60
|
+
}
|
61
|
+
} catch (e) {
|
62
|
+
const skipWhenDecodeFailed = GLOBAL_CONFIG.execution.ethAbiDecoderConfig?.skipWhenDecodeFailed
|
63
|
+
console.error(`parseLog worker failed, skip: ${!!skipWhenDecodeFailed}, the error is:`, e)
|
64
|
+
if (!skipWhenDecodeFailed) {
|
65
|
+
throw e
|
66
|
+
}
|
67
|
+
} finally {
|
68
|
+
if (workerPool.waitTime && workerPool.runTime) {
|
69
|
+
const labels = {
|
70
|
+
chain_id: processor.config?.network,
|
71
|
+
processor: processor.config?.name,
|
72
|
+
workerPool: 'parseLog'
|
73
|
+
}
|
74
|
+
processMetrics.processor_worker_wait_time.record(workerPool.waitTime.average, labels)
|
75
|
+
processMetrics.processor_worker_run_time.record(workerPool.runTime?.average, labels)
|
76
|
+
processMetrics.processor_worker_utilization.record(workerPool.utilization, labels)
|
77
|
+
processMetrics.processor_worker_queue_size.record(workerPool.queueSize, labels)
|
78
|
+
processMetrics.processor_worker_completed.record(workerPool.completed, labels)
|
79
|
+
}
|
80
|
+
}
|
81
|
+
return null
|
82
|
+
} else {
|
83
|
+
const contractView = processor.CreateBoundContractView()
|
84
|
+
const contractViewInterface = contractView.rawContract.interface
|
85
|
+
return parseLogInline(contractViewInterface, log)
|
86
|
+
}
|
87
|
+
}
|
88
|
+
|
89
|
+
export async function decodeTrace(processor: any, inputs: readonly ParamType[], traceData: string) {
|
90
|
+
if (GLOBAL_CONFIG.execution.ethAbiDecoderConfig?.enabled) {
|
91
|
+
let workerPool = processor._traceWorkerPool
|
92
|
+
if (!workerPool) {
|
93
|
+
const contractView = processor.CreateBoundContractView()
|
94
|
+
const contractViewInterface = contractView.rawContract.interface
|
95
|
+
const fragments = contractViewInterface.fragments
|
96
|
+
const options = createOptions()
|
97
|
+
options.workerData = fragments
|
98
|
+
|
99
|
+
workerPool = new Piscina(options)
|
100
|
+
processor._traceWorkerPool = workerPool
|
101
|
+
}
|
102
|
+
try {
|
103
|
+
const result = (await workerPool.run({ inputs, traceData }, { name: 'decodeTrace' })) as IResult
|
104
|
+
if (result) {
|
105
|
+
return Result.fromItems(result.array ?? [], result.keys)
|
106
|
+
}
|
107
|
+
} catch (e) {
|
108
|
+
const skipWhenDecodeFailed = GLOBAL_CONFIG.execution.ethAbiDecoderConfig?.skipWhenDecodeFailed
|
109
|
+
console.error(`decode trace worker failed, skip: ${!!skipWhenDecodeFailed}, the error is:`, e)
|
110
|
+
if (!skipWhenDecodeFailed) {
|
111
|
+
throw e
|
112
|
+
}
|
113
|
+
} finally {
|
114
|
+
if (workerPool.waitTime && workerPool.runTime) {
|
115
|
+
const labels = {
|
116
|
+
chain_id: processor.config?.network,
|
117
|
+
processor: processor.config?.name,
|
118
|
+
workerPool: 'parseLog'
|
119
|
+
}
|
120
|
+
processMetrics.processor_worker_wait_time.record(workerPool.waitTime.average, labels)
|
121
|
+
processMetrics.processor_worker_run_time.record(workerPool.runTime?.average, labels)
|
122
|
+
processMetrics.processor_worker_utilization.record(workerPool.utilization, labels)
|
123
|
+
processMetrics.processor_worker_queue_size.record(workerPool.queueSize, labels)
|
124
|
+
processMetrics.processor_worker_completed.record(workerPool.completed, labels)
|
125
|
+
}
|
126
|
+
}
|
127
|
+
return null
|
128
|
+
} else {
|
129
|
+
const contractView = processor.CreateBoundContractView()
|
130
|
+
const contractViewInterface = contractView.rawContract.interface
|
131
|
+
return decodeTraceInline(contractViewInterface, inputs, traceData)
|
132
|
+
}
|
133
|
+
}
|
@@ -22,6 +22,7 @@ import { ListStateStorage } from '@sentio/runtime'
|
|
22
22
|
import { EthChainId } from '@sentio/chain'
|
23
23
|
import { getHandlerName, proxyHandlers, proxyProcessor } from '../utils/metrics.js'
|
24
24
|
import { ALL_ADDRESS } from '../core/index.js'
|
25
|
+
import { parseLog, decodeTrace } from './abi-decoder/index.js'
|
25
26
|
|
26
27
|
export interface AddressOrTypeEventFilter extends DeferredTopicFilter {
|
27
28
|
addressType?: AddressType
|
@@ -463,24 +464,9 @@ export abstract class BaseProcessor<
|
|
463
464
|
contractView.address = log.address
|
464
465
|
}
|
465
466
|
|
466
|
-
const ctx = new ContractContext<TContract, TBoundContractView>(
|
467
|
-
contractName,
|
468
|
-
contractView,
|
469
|
-
chainId,
|
470
|
-
data.timestamp,
|
471
|
-
block,
|
472
|
-
log,
|
473
|
-
undefined,
|
474
|
-
transaction,
|
475
|
-
transactionReceipt,
|
476
|
-
processor.config.baseLabels,
|
477
|
-
preparedData
|
478
|
-
)
|
479
|
-
const logParam = log as any as { topics: Array<string>; data: string }
|
480
|
-
|
481
467
|
let parsed: LogDescription | null = null
|
482
468
|
try {
|
483
|
-
parsed =
|
469
|
+
parsed = await parseLog(processor, log)
|
484
470
|
} catch (e) {
|
485
471
|
// RangeError data out-of-bounds
|
486
472
|
if (e instanceof Error) {
|
@@ -492,6 +478,19 @@ export abstract class BaseProcessor<
|
|
492
478
|
throw e
|
493
479
|
}
|
494
480
|
if (parsed) {
|
481
|
+
const ctx = new ContractContext<TContract, TBoundContractView>(
|
482
|
+
contractName,
|
483
|
+
contractView,
|
484
|
+
chainId,
|
485
|
+
data.timestamp,
|
486
|
+
block,
|
487
|
+
log,
|
488
|
+
undefined,
|
489
|
+
transaction,
|
490
|
+
transactionReceipt,
|
491
|
+
processor.config.baseLabels,
|
492
|
+
preparedData
|
493
|
+
)
|
495
494
|
const event: TypedEvent = { ...log, name: parsed.name, args: fixEmptyKey(parsed) }
|
496
495
|
await handler(event, ctx)
|
497
496
|
return ctx.stopAndGetResult()
|
@@ -529,11 +528,10 @@ export abstract class BaseProcessor<
|
|
529
528
|
transactionReceipt,
|
530
529
|
processor.config.baseLabels
|
531
530
|
)
|
532
|
-
const logParam = log as any as { topics: Array<string>; data: string }
|
533
531
|
|
534
532
|
let parsed: LogDescription | null = null
|
535
533
|
try {
|
536
|
-
parsed =
|
534
|
+
parsed = await parseLog(processor, log)
|
537
535
|
} catch (e) {
|
538
536
|
// RangeError data out-of-bounds
|
539
537
|
if (e instanceof Error) {
|
@@ -714,7 +712,8 @@ export abstract class BaseProcessor<
|
|
714
712
|
}
|
715
713
|
const traceData = '0x' + trace.action.input.slice(10)
|
716
714
|
try {
|
717
|
-
typedTrace.args =
|
715
|
+
typedTrace.args = await decodeTrace(processor, fragment.inputs, traceData)
|
716
|
+
// typedTrace.args = contractInterface.getAbiCoder().decode(fragment.inputs, traceData, true)
|
718
717
|
} catch (e) {
|
719
718
|
if (!trace.error) {
|
720
719
|
throw e
|
@@ -759,7 +758,7 @@ export abstract class BaseProcessor<
|
|
759
758
|
}
|
760
759
|
const traceData = '0x' + trace.action.input.slice(10)
|
761
760
|
try {
|
762
|
-
typedTrace.args =
|
761
|
+
typedTrace.args = await decodeTrace(processor, fragment.inputs, traceData)
|
763
762
|
} catch (e) {
|
764
763
|
if (!trace.error) {
|
765
764
|
throw e
|
package/src/move/filter.ts
CHANGED
@@ -113,8 +113,8 @@ export abstract class SharedNetworkCodegen<NetworkType, ModuleTypes, StructType>
|
|
113
113
|
const source = `
|
114
114
|
onEvent${struct.name}(func: (event: ${moduleName}.${normalizeToJSName(struct.name)}Instance, ctx: ${
|
115
115
|
this.PREFIX
|
116
|
-
}Context) => void, fetchConfig?: Partial<MoveFetchConfig>): ${moduleName} {
|
117
|
-
this.onMoveEvent(func, { type: '${module.name}::${struct.name}' }, fetchConfig)
|
116
|
+
}Context) => void, fetchConfig?: Partial<MoveFetchConfig>, eventFilter?: Omit<EventFilter, "type"|"account">): ${moduleName} {
|
117
|
+
this.onMoveEvent(func, {...eventFilter ?? {}, type: '${module.name}::${struct.name}' }, fetchConfig)
|
118
118
|
return this
|
119
119
|
}`
|
120
120
|
return source
|
@@ -122,7 +122,7 @@ onEvent${struct.name}(func: (event: ${moduleName}.${normalizeToJSName(struct.nam
|
|
122
122
|
|
123
123
|
generateImports() {
|
124
124
|
return `
|
125
|
-
import { CallFilter, MoveFetchConfig } from "@sentio/sdk/move"
|
125
|
+
import { CallFilter, MoveFetchConfig, EventFilter } from "@sentio/sdk/move"
|
126
126
|
import {
|
127
127
|
${this.PREFIX}BindOptions, ${this.PREFIX}BaseProcessor,
|
128
128
|
${this.PREFIX}Network, TypedFunctionPayload,
|
package/src/store/codegen.ts
CHANGED
@@ -106,7 +106,7 @@ async function codegenInternal(schema: GraphQLSchema, source: string, target: st
|
|
106
106
|
const imports: Import[] = [
|
107
107
|
{
|
108
108
|
module: '@sentio/sdk/store',
|
109
|
-
types: ['String', 'Int', 'BigInt', 'Float', 'ID', 'Bytes', 'Timestamp', 'Boolean'],
|
109
|
+
types: ['String', 'Int', 'BigInt', 'Float', 'ID', 'Bytes', 'Timestamp', 'Boolean', 'Int8'],
|
110
110
|
importType: true
|
111
111
|
},
|
112
112
|
{
|
package/src/store/convert.ts
CHANGED
@@ -134,6 +134,22 @@ export const IntConverter: ValueConverter<Int | undefined> = {
|
|
134
134
|
}
|
135
135
|
}
|
136
136
|
|
137
|
+
export const Int8Converter: ValueConverter<bigint | undefined> = {
|
138
|
+
from: (value?: bigint) => {
|
139
|
+
if (value == null) {
|
140
|
+
return {
|
141
|
+
nullValue: RichValue_NullValue.NULL_VALUE
|
142
|
+
}
|
143
|
+
}
|
144
|
+
return {
|
145
|
+
int64Value: BigInt(value)
|
146
|
+
}
|
147
|
+
},
|
148
|
+
to(v) {
|
149
|
+
return v.int64Value
|
150
|
+
}
|
151
|
+
}
|
152
|
+
|
137
153
|
export const FloatConverter: ValueConverter<Float | undefined> = {
|
138
154
|
from: (value?: Float) => {
|
139
155
|
if (value == null) {
|
@@ -291,6 +307,7 @@ export const TypeConverters: Record<string, ValueConverter<any>> = {
|
|
291
307
|
ID: IDConverter,
|
292
308
|
Bytes: BytesConverter,
|
293
309
|
Int: IntConverter,
|
310
|
+
Int8: Int8Converter,
|
294
311
|
Float: FloatConverter,
|
295
312
|
Timestamp: TimestampConverter
|
296
313
|
}
|
package/src/store/decorators.ts
CHANGED
@@ -7,6 +7,7 @@ import {
|
|
7
7
|
BytesConverter,
|
8
8
|
FloatConverter,
|
9
9
|
IDConverter,
|
10
|
+
Int8Converter,
|
10
11
|
IntConverter,
|
11
12
|
objectId_,
|
12
13
|
required_,
|
@@ -161,6 +162,7 @@ export function column(type?: ValueConverter<any>) {
|
|
161
162
|
|
162
163
|
export const IDColumn = column(IDConverter)
|
163
164
|
export const IntColumn = column(IntConverter)
|
165
|
+
export const Int8Column = column(Int8Converter)
|
164
166
|
export const FloatColumn = column(FloatConverter)
|
165
167
|
export const BigDecimalColumn = column(BigDecimalConverter)
|
166
168
|
export const BigIntColumn = column(BigIntConverter)
|
package/src/store/schema.ts
CHANGED
@@ -2,7 +2,7 @@ import { buildASTSchema, DocumentNode, extendSchema, GraphQLSchema, parse, valid
|
|
2
2
|
import * as fs from 'node:fs'
|
3
3
|
import { GraphQLObjectType, GraphQLOutputType, isListType, isNonNullType } from 'graphql'
|
4
4
|
|
5
|
-
const customScalars = ['BigInt', 'BigDecimal', 'Timestamp', 'JSON', 'Bytes', 'ID']
|
5
|
+
const customScalars = ['BigInt', 'BigDecimal', 'Timestamp', 'JSON', 'Bytes', 'ID', 'Int8']
|
6
6
|
|
7
7
|
const baseSchema = buildASTSchema(
|
8
8
|
parse(`
|