@sentio/sdk 2.40.0-rc.39 → 2.40.0-rc.40

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 (66) hide show
  1. package/lib/stark/codegen/codegen.d.ts +2 -0
  2. package/lib/stark/codegen/codegen.d.ts.map +1 -0
  3. package/lib/stark/codegen/codegen.js +109 -0
  4. package/lib/stark/codegen/codegen.js.map +1 -0
  5. package/lib/stark/codegen/index.d.ts +2 -0
  6. package/lib/stark/codegen/index.d.ts.map +1 -0
  7. package/lib/stark/codegen/index.js +2 -0
  8. package/lib/stark/codegen/index.js.map +1 -0
  9. package/lib/stark/codegen/run.d.ts +2 -0
  10. package/lib/stark/codegen/run.d.ts.map +1 -0
  11. package/lib/stark/codegen/run.js +11 -0
  12. package/lib/stark/codegen/run.js.map +1 -0
  13. package/lib/stark/codegen/utils.d.ts +2 -0
  14. package/lib/stark/codegen/utils.d.ts.map +1 -0
  15. package/lib/stark/codegen/utils.js +4 -0
  16. package/lib/stark/codegen/utils.js.map +1 -0
  17. package/lib/stark/context.d.ts +28 -0
  18. package/lib/stark/context.d.ts.map +1 -0
  19. package/lib/stark/context.js +59 -0
  20. package/lib/stark/context.js.map +1 -0
  21. package/lib/stark/contract.d.ts +12 -0
  22. package/lib/stark/contract.d.ts.map +1 -0
  23. package/lib/stark/contract.js +43 -0
  24. package/lib/stark/contract.js.map +1 -0
  25. package/lib/stark/event.d.ts +7 -0
  26. package/lib/stark/event.d.ts.map +1 -0
  27. package/lib/stark/event.js +11 -0
  28. package/lib/stark/event.js.map +1 -0
  29. package/lib/stark/index.d.ts +7 -0
  30. package/lib/stark/index.d.ts.map +1 -0
  31. package/lib/stark/index.js +7 -0
  32. package/lib/stark/index.js.map +1 -0
  33. package/lib/stark/starknet-plugin.d.ts +17 -0
  34. package/lib/stark/starknet-plugin.d.ts.map +1 -0
  35. package/lib/stark/starknet-plugin.js +78 -0
  36. package/lib/stark/starknet-plugin.js.map +1 -0
  37. package/lib/stark/starknet-processor.d.ts +32 -0
  38. package/lib/stark/starknet-processor.d.ts.map +1 -0
  39. package/lib/stark/starknet-processor.js +111 -0
  40. package/lib/stark/starknet-processor.js.map +1 -0
  41. package/lib/stark/types.d.ts +11 -0
  42. package/lib/stark/types.d.ts.map +1 -0
  43. package/lib/stark/types.js +2 -0
  44. package/lib/stark/types.js.map +1 -0
  45. package/lib/testing/starknet-facet.d.ts +9 -0
  46. package/lib/testing/starknet-facet.d.ts.map +1 -0
  47. package/lib/testing/starknet-facet.js +52 -0
  48. package/lib/testing/starknet-facet.js.map +1 -0
  49. package/lib/testing/test-processor-server.d.ts +2 -0
  50. package/lib/testing/test-processor-server.d.ts.map +1 -1
  51. package/lib/testing/test-processor-server.js +3 -0
  52. package/lib/testing/test-processor-server.js.map +1 -1
  53. package/package.json +13 -6
  54. package/src/stark/codegen/codegen.ts +124 -0
  55. package/src/stark/codegen/index.ts +1 -0
  56. package/src/stark/codegen/run.ts +10 -0
  57. package/src/stark/codegen/utils.ts +3 -0
  58. package/src/stark/context.ts +78 -0
  59. package/src/stark/contract.ts +55 -0
  60. package/src/stark/event.ts +7 -0
  61. package/src/stark/index.ts +9 -0
  62. package/src/stark/starknet-plugin.ts +108 -0
  63. package/src/stark/starknet-processor.ts +140 -0
  64. package/src/stark/types.ts +11 -0
  65. package/src/testing/starknet-facet.ts +61 -0
  66. package/src/testing/test-processor-server.ts +3 -0
@@ -0,0 +1,108 @@
1
+ import { errorString, GLOBAL_CONFIG, mergeProcessResults, Plugin, PluginManager, USER_PROCESSOR } from '@sentio/runtime'
2
+ import {
3
+ ContractConfig,
4
+ Data_StarknetEvent,
5
+ DataBinding,
6
+ HandlerType,
7
+ ProcessConfigResponse,
8
+ ProcessResult,
9
+ StartRequest
10
+ } from '@sentio/protos'
11
+
12
+ import { ServerError, Status } from 'nice-grpc'
13
+ import { TemplateInstanceState } from '../core/template.js'
14
+ import { StarknetProcessorState } from './starknet-processor.js'
15
+ import { hash } from 'starknet'
16
+
17
+ interface Handlers {
18
+ callHandlers: ((trace: Data_StarknetEvent) => Promise<ProcessResult>)[]
19
+ }
20
+
21
+ export class StarknetPlugin extends Plugin {
22
+ name: string = 'StarknetPlugin'
23
+ handlers: Handlers = {
24
+ callHandlers: []
25
+ }
26
+
27
+ async configure(config: ProcessConfigResponse) {
28
+ const handlers: Handlers = {
29
+ callHandlers: []
30
+ }
31
+
32
+ for (const processor of StarknetProcessorState.INSTANCE.getValues()) {
33
+ await processor.configure()
34
+ const contractConfig = ContractConfig.fromPartial({
35
+ processorType: USER_PROCESSOR,
36
+ contract: {
37
+ name: processor.config.name,
38
+ chainId: processor.config.chainId.toString(),
39
+ address: processor.config.address || '*',
40
+ abi: ''
41
+ },
42
+ startBlock: processor.config.startBlock,
43
+ endBlock: processor.config.endBlock
44
+ })
45
+ for (const callHandler of processor.callHandlers) {
46
+ const handlerId = handlers.callHandlers.push(callHandler.handler) - 1
47
+
48
+ if (callHandler.eventFilter) {
49
+ contractConfig.starknetEventConfigs.push({
50
+ filters: callHandler.eventFilter.map((e) => ({
51
+ address: processor.config.address,
52
+ keys: [hash.getSelectorFromName(e)]
53
+ })),
54
+ handlerId
55
+ })
56
+ }
57
+ }
58
+
59
+ // Finish up a contract
60
+ config.contractConfigs.push(contractConfig)
61
+ }
62
+
63
+ this.handlers = handlers
64
+ }
65
+
66
+ supportedHandlers = [HandlerType.STARKNET_EVENT]
67
+
68
+ processBinding(request: DataBinding): Promise<ProcessResult> {
69
+ switch (request.handlerType) {
70
+ case HandlerType.STARKNET_EVENT:
71
+ return this.processEvent(request)
72
+ default:
73
+ throw new ServerError(Status.INVALID_ARGUMENT, 'No handle type registered ' + request.handlerType)
74
+ }
75
+ }
76
+
77
+ async start(request: StartRequest) {}
78
+
79
+ stateDiff(config: ProcessConfigResponse): boolean {
80
+ return TemplateInstanceState.INSTANCE.getValues().length !== config.templateInstances.length
81
+ }
82
+
83
+ async processEvent(binding: DataBinding): Promise<ProcessResult> {
84
+ if (!binding.data?.starknetEvents?.result) {
85
+ throw new ServerError(Status.INVALID_ARGUMENT, "starknetEvents can't be null")
86
+ }
87
+
88
+ const promises: Promise<ProcessResult>[] = []
89
+
90
+ const result = binding.data?.starknetEvents?.result
91
+
92
+ for (const handlerId of binding.handlerIds) {
93
+ const promise = this.handlers.callHandlers[handlerId](binding.data?.starknetEvents).catch((e) => {
94
+ throw new ServerError(
95
+ Status.INTERNAL,
96
+ 'error processing transaction: ' + JSON.stringify(result) + '\n' + errorString(e)
97
+ )
98
+ })
99
+ if (GLOBAL_CONFIG.execution.sequential) {
100
+ await promise
101
+ }
102
+ promises.push(promise)
103
+ }
104
+ return mergeProcessResults(await Promise.all(promises))
105
+ }
106
+ }
107
+
108
+ PluginManager.INSTANCE.register(new StarknetPlugin())
@@ -0,0 +1,140 @@
1
+ import { Data_StarknetEvent, ProcessResult } from '@sentio/protos'
2
+ import { StarknetChainId } from '@sentio/chain'
3
+ import { CallData, constants, events, ParsedEvent, RpcProvider } from 'starknet'
4
+ import { StarknetContext } from './context.js'
5
+ import { StarknetEvent } from './event.js'
6
+ import { ListStateStorage, mergeProcessResults } from '@sentio/runtime'
7
+ import { StarknetProcessorConfig } from './types.js'
8
+ import { StarknetContractView } from './contract.js'
9
+
10
+ export class StarknetProcessor {
11
+ callHandlers: CallHandler<Data_StarknetEvent>[] = []
12
+
13
+ private provider: RpcProvider
14
+
15
+ static bind(config: StarknetProcessorConfig): StarknetProcessor {
16
+ const processor = new StarknetProcessor(config)
17
+ StarknetProcessorState.INSTANCE.addValue(processor)
18
+ return processor
19
+ }
20
+
21
+ classHash: string
22
+
23
+ constructor(readonly config: StarknetProcessorConfig) {}
24
+
25
+ async configure() {
26
+ this.provider = new RpcProvider({
27
+ nodeUrl: getRpcEndpoint(this.config.chainId)
28
+ })
29
+ const classHash = await this.provider.getClassHashAt(this.config.address)
30
+ if (!classHash) {
31
+ throw new Error("can't find the class hash defined at " + this.config.address)
32
+ }
33
+ this.classHash = classHash
34
+ if (!this.config.abi) {
35
+ const clazz = await this.provider.getClass(classHash, 'latest')
36
+ this.config.abi = clazz.abi
37
+ }
38
+ }
39
+
40
+ public onEvent(
41
+ event: string | string[],
42
+ handler: (events: StarknetEvent<ParsedEvent>, ctx: StarknetContext<StarknetContractView>) => void | Promise<void>
43
+ ) {
44
+ const eventFilter = Array.isArray(event) ? event : [event]
45
+ if (!this.config.abi) {
46
+ throw new Error('abi not found')
47
+ }
48
+ const abi = this.config.abi
49
+ const callHandler = {
50
+ handler: async (call: Data_StarknetEvent) => {
51
+ try {
52
+ const eventData = [call.result] as any[]
53
+ const abiEvents = events.getAbiEvents(abi)
54
+
55
+ const abiStructs = CallData.getAbiStruct(abi)
56
+ const abiEnums = CallData.getAbiEnum(abi)
57
+
58
+ const parsedEvents = events.parseEvents(eventData, abiEvents, abiStructs, abiEnums)
59
+ const results: ProcessResult[] = []
60
+ const { block_hash, block_number, transaction_hash, from_address } = call.result!
61
+ for (let i = 0; i < parsedEvents.length; i++) {
62
+ const ctx = new StarknetContext<StarknetContractView>(
63
+ this.config,
64
+ this.provider,
65
+ block_number,
66
+ block_hash,
67
+ transaction_hash,
68
+ i,
69
+ this.classHash
70
+ )
71
+ const e = new StarknetEvent(from_address, transaction_hash, parsedEvents[i])
72
+ try {
73
+ await handler(e, ctx)
74
+ } catch (e) {
75
+ console.error(e)
76
+ }
77
+ results.push(ctx.stopAndGetResult())
78
+ }
79
+ return mergeProcessResults(results)
80
+ } catch (e) {
81
+ console.error(e)
82
+ return {
83
+ gauges: [],
84
+ counters: [],
85
+ events: [],
86
+ exports: [],
87
+ states: {
88
+ configUpdated: false
89
+ }
90
+ }
91
+ }
92
+ },
93
+ eventFilter
94
+ }
95
+ this.callHandlers.push(callHandler)
96
+ return this
97
+ }
98
+ }
99
+
100
+ export type CallHandler<T> = {
101
+ handler: (call: T) => Promise<ProcessResult>
102
+ eventFilter?: string[]
103
+ }
104
+
105
+ function getRpcEndpoint(chainId: StarknetChainId | string) {
106
+ switch (chainId) {
107
+ case StarknetChainId.STARKNET_MAINNET:
108
+ return constants.NetworkName.SN_MAIN
109
+ default:
110
+ return constants.NetworkName.SN_SEPOLIA
111
+ }
112
+ }
113
+
114
+ export class StarknetProcessorState extends ListStateStorage<StarknetProcessor> {
115
+ static INSTANCE = new StarknetProcessorState()
116
+ }
117
+
118
+ export abstract class AbstractStarknetProcessor {
119
+ private readonly processor: StarknetProcessor
120
+ protected constructor(
121
+ readonly abi: any,
122
+ readonly config: StarknetProcessorConfig
123
+ ) {
124
+ this.processor = new StarknetProcessor(config)
125
+ StarknetProcessorState.INSTANCE.addValue(this.processor)
126
+ }
127
+
128
+ onEvent<T, C>(
129
+ eventName: string,
130
+ structName: string,
131
+ handler: (event: StarknetEvent<T>, ctx: StarknetContext<C>) => Promise<void>
132
+ ) {
133
+ this.processor.onEvent(eventName, async (events, ctx) => {
134
+ const eventData = events.data[structName] as T
135
+ const e = new StarknetEvent<T>(events.caller, events.transactionHash, eventData)
136
+ await handler(e, ctx as StarknetContext<C>)
137
+ })
138
+ return this
139
+ }
140
+ }
@@ -0,0 +1,11 @@
1
+ import { StarknetChainId } from '@sentio/chain'
2
+ import { Abi } from 'starknet'
3
+
4
+ export type StarknetProcessorConfig = {
5
+ address: string
6
+ name?: string
7
+ chainId: StarknetChainId | string
8
+ startBlock?: bigint
9
+ endBlock?: bigint
10
+ abi?: Abi
11
+ }
@@ -0,0 +1,61 @@
1
+ import { TestProcessorServer } from './test-processor-server.js'
2
+ import { DataBinding, HandlerType } from '@sentio/protos'
3
+ import { StarknetChainId } from '@sentio/chain'
4
+
5
+ export class StarknetFacet {
6
+ server: TestProcessorServer
7
+
8
+ constructor(server: TestProcessorServer) {
9
+ this.server = server
10
+ }
11
+
12
+ testOnEvents(events: any, network: StarknetChainId = StarknetChainId.STARKNET_SEPOLIA) {
13
+ const bindings = this.buildBinding(events, network)
14
+ if (!bindings) {
15
+ throw Error('Invalid test : ' + JSON.stringify(events))
16
+ }
17
+
18
+ return this.server.processBindings({
19
+ bindings
20
+ })
21
+ }
22
+
23
+ private buildBinding(events: any, network: StarknetChainId): DataBinding[] {
24
+ const res: DataBinding[] = []
25
+ const data = Array.isArray(events) ? events : [events]
26
+ for (const event of data) {
27
+ for (const config of this.server.contractConfigs) {
28
+ if (config.contract?.chainId !== network) {
29
+ continue
30
+ }
31
+
32
+ for (const logConfig of config.starknetEventConfigs) {
33
+ const binding = {
34
+ data: {
35
+ starknetEvents: {
36
+ result: event,
37
+ timestamp: new Date()
38
+ }
39
+ },
40
+ handlerIds: [logConfig.handlerId],
41
+ handlerType: HandlerType.STARKNET_EVENT
42
+ }
43
+
44
+ const logFilters = logConfig.filters
45
+ const keys = event.keys as string[]
46
+
47
+ for (const key of keys) {
48
+ for (const logFilter of logFilters) {
49
+ if (logFilter.keys.includes(key)) {
50
+ res.push(binding)
51
+ return res
52
+ }
53
+ }
54
+ }
55
+ }
56
+ }
57
+ }
58
+
59
+ return res
60
+ }
61
+ }
@@ -26,6 +26,7 @@ import { EthFacet } from './eth-facet.js'
26
26
  import { SuiFacet } from './sui-facet.js'
27
27
  import { FuelFacet } from './fuel-facet.js'
28
28
  import { CosmosFacet } from './cosmos-facet.js'
29
+ import { StarknetFacet } from './starknet-facet.js'
29
30
 
30
31
  export const TEST_CONTEXT: CallContext = <CallContext>{}
31
32
 
@@ -44,6 +45,7 @@ export class TestProcessorServer implements ProcessorServiceImplementation {
44
45
  sui: SuiFacet
45
46
  fuel: FuelFacet
46
47
  cosmos: CosmosFacet
48
+ starknet: StarknetFacet
47
49
 
48
50
  constructor(loader: () => Promise<any>, httpEndpoints: Record<string, string> = {}) {
49
51
  cleanTest()
@@ -55,6 +57,7 @@ export class TestProcessorServer implements ProcessorServiceImplementation {
55
57
  this.sui = new SuiFacet(this)
56
58
  this.fuel = new FuelFacet(this)
57
59
  this.cosmos = new CosmosFacet(this)
60
+ this.starknet = new StarknetFacet(this)
58
61
 
59
62
  for (const k in CHAIN_MAP) {
60
63
  const http = httpEndpoints[k] || ''