@sentio/sdk 2.40.0-rc.4 → 2.40.0-rc.41

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 (224) hide show
  1. package/lib/aptos/aptos-processor.d.ts +1 -1
  2. package/lib/aptos/aptos-processor.d.ts.map +1 -1
  3. package/lib/aptos/aptos-processor.js +1 -1
  4. package/lib/aptos/aptos-processor.js.map +1 -1
  5. package/lib/aptos/context.d.ts +2 -2
  6. package/lib/aptos/context.d.ts.map +1 -1
  7. package/lib/aptos/context.js +1 -1
  8. package/lib/aptos/ext/aptos-dex.d.ts +1 -1
  9. package/lib/aptos/ext/aptos-dex.d.ts.map +1 -1
  10. package/lib/aptos/ext/aptos-dex.js +1 -1
  11. package/lib/aptos/ext/aptos-dex.js.map +1 -1
  12. package/lib/aptos/ext/coin-event.d.ts +1 -1
  13. package/lib/aptos/ext/coin-event.d.ts.map +1 -1
  14. package/lib/aptos/ext/coin.js +2 -2
  15. package/lib/aptos/ext/coin.js.map +1 -1
  16. package/lib/aptos/move-coder.d.ts.map +1 -1
  17. package/lib/aptos/move-coder.js +6 -5
  18. package/lib/aptos/move-coder.js.map +1 -1
  19. package/lib/aptos/network.d.ts +2 -0
  20. package/lib/aptos/network.d.ts.map +1 -1
  21. package/lib/aptos/network.js +7 -1
  22. package/lib/aptos/network.js.map +1 -1
  23. package/lib/eth/account-processor.d.ts +21 -7
  24. package/lib/eth/account-processor.d.ts.map +1 -1
  25. package/lib/eth/account-processor.js +2 -2
  26. package/lib/eth/account-processor.js.map +1 -1
  27. package/lib/eth/base-processor-template.d.ts +24 -8
  28. package/lib/eth/base-processor-template.d.ts.map +1 -1
  29. package/lib/eth/base-processor-template.js.map +1 -1
  30. package/lib/eth/base-processor.d.ts +30 -10
  31. package/lib/eth/base-processor.d.ts.map +1 -1
  32. package/lib/eth/base-processor.js +6 -6
  33. package/lib/eth/base-processor.js.map +1 -1
  34. package/lib/eth/builtin/internal/eacaggregatorproxy-processor.d.ts +100 -31
  35. package/lib/eth/builtin/internal/eacaggregatorproxy-processor.d.ts.map +1 -1
  36. package/lib/eth/builtin/internal/eacaggregatorproxy-processor.js +1226 -46
  37. package/lib/eth/builtin/internal/eacaggregatorproxy-processor.js.map +1 -1
  38. package/lib/eth/builtin/internal/erc1155-processor.d.ts +55 -16
  39. package/lib/eth/builtin/internal/erc1155-processor.d.ts.map +1 -1
  40. package/lib/eth/builtin/internal/erc1155-processor.js +486 -16
  41. package/lib/eth/builtin/internal/erc1155-processor.js.map +1 -1
  42. package/lib/eth/builtin/internal/erc20-processor.d.ts +79 -24
  43. package/lib/eth/builtin/internal/erc20-processor.d.ts.map +1 -1
  44. package/lib/eth/builtin/internal/erc20-processor.js +985 -36
  45. package/lib/eth/builtin/internal/erc20-processor.js.map +1 -1
  46. package/lib/eth/builtin/internal/erc20bytes-processor.d.ts +46 -13
  47. package/lib/eth/builtin/internal/erc20bytes-processor.d.ts.map +1 -1
  48. package/lib/eth/builtin/internal/erc20bytes-processor.js +485 -18
  49. package/lib/eth/builtin/internal/erc20bytes-processor.js.map +1 -1
  50. package/lib/eth/builtin/internal/erc721-processor.d.ts +67 -20
  51. package/lib/eth/builtin/internal/erc721-processor.d.ts.map +1 -1
  52. package/lib/eth/builtin/internal/erc721-processor.js +784 -28
  53. package/lib/eth/builtin/internal/erc721-processor.js.map +1 -1
  54. package/lib/eth/builtin/internal/weth9-processor.d.ts +64 -19
  55. package/lib/eth/builtin/internal/weth9-processor.d.ts.map +1 -1
  56. package/lib/eth/builtin/internal/weth9-processor.js +574 -22
  57. package/lib/eth/builtin/internal/weth9-processor.js.map +1 -1
  58. package/lib/eth/codegen/event-handler.js +1 -1
  59. package/lib/eth/codegen/file.d.ts.map +1 -1
  60. package/lib/eth/codegen/file.js +21 -3
  61. package/lib/eth/codegen/file.js.map +1 -1
  62. package/lib/eth/codegen/function-calls.d.ts +4 -0
  63. package/lib/eth/codegen/function-calls.d.ts.map +1 -1
  64. package/lib/eth/codegen/function-calls.js +80 -5
  65. package/lib/eth/codegen/function-calls.js.map +1 -1
  66. package/lib/eth/codegen/types.d.ts +1 -0
  67. package/lib/eth/codegen/types.d.ts.map +1 -1
  68. package/lib/eth/codegen/types.js +13 -0
  69. package/lib/eth/codegen/types.js.map +1 -1
  70. package/lib/eth/context.d.ts +4 -0
  71. package/lib/eth/context.d.ts.map +1 -1
  72. package/lib/eth/context.js +4 -0
  73. package/lib/eth/context.js.map +1 -1
  74. package/lib/eth/eth-plugin.d.ts +27 -9
  75. package/lib/eth/eth-plugin.d.ts.map +1 -1
  76. package/lib/eth/eth-plugin.js +20 -17
  77. package/lib/eth/eth-plugin.js.map +1 -1
  78. package/lib/eth/eth.d.ts.map +1 -1
  79. package/lib/eth/eth.js +1 -1
  80. package/lib/eth/eth.js.map +1 -1
  81. package/lib/eth/generic-processor.js +1 -1
  82. package/lib/eth/generic-processor.js.map +1 -1
  83. package/lib/eth/generic-processor.test.js.map +1 -1
  84. package/lib/eth/index.d.ts +2 -1
  85. package/lib/eth/index.d.ts.map +1 -1
  86. package/lib/eth/index.js +2 -1
  87. package/lib/eth/index.js.map +1 -1
  88. package/lib/solana/builtin/spl-token-processor.d.ts +1 -1
  89. package/lib/solana/builtin/spl-token-processor.d.ts.map +1 -1
  90. package/lib/solana/builtin/spl-token-processor.js +1 -1
  91. package/lib/solana/builtin/spl-token-processor.js.map +1 -1
  92. package/lib/solana/solana-context.d.ts +1 -1
  93. package/lib/solana/solana-context.js +2 -2
  94. package/lib/stark/codegen/codegen.d.ts +2 -0
  95. package/lib/stark/codegen/codegen.d.ts.map +1 -0
  96. package/lib/stark/codegen/codegen.js +109 -0
  97. package/lib/stark/codegen/codegen.js.map +1 -0
  98. package/lib/stark/codegen/index.d.ts +2 -0
  99. package/lib/stark/codegen/index.d.ts.map +1 -0
  100. package/lib/stark/codegen/index.js +2 -0
  101. package/lib/stark/codegen/index.js.map +1 -0
  102. package/lib/stark/codegen/run.d.ts +2 -0
  103. package/lib/stark/codegen/run.d.ts.map +1 -0
  104. package/lib/stark/codegen/run.js +11 -0
  105. package/lib/stark/codegen/run.js.map +1 -0
  106. package/lib/stark/codegen/utils.d.ts +2 -0
  107. package/lib/stark/codegen/utils.d.ts.map +1 -0
  108. package/lib/stark/codegen/utils.js +4 -0
  109. package/lib/stark/codegen/utils.js.map +1 -0
  110. package/lib/stark/context.d.ts +28 -0
  111. package/lib/stark/context.d.ts.map +1 -0
  112. package/lib/stark/context.js +59 -0
  113. package/lib/stark/context.js.map +1 -0
  114. package/lib/stark/contract.d.ts +12 -0
  115. package/lib/stark/contract.d.ts.map +1 -0
  116. package/lib/stark/contract.js +43 -0
  117. package/lib/stark/contract.js.map +1 -0
  118. package/lib/stark/event.d.ts +7 -0
  119. package/lib/stark/event.d.ts.map +1 -0
  120. package/lib/stark/event.js +11 -0
  121. package/lib/stark/event.js.map +1 -0
  122. package/lib/stark/index.d.ts +7 -0
  123. package/lib/stark/index.d.ts.map +1 -0
  124. package/lib/stark/index.js +7 -0
  125. package/lib/stark/index.js.map +1 -0
  126. package/lib/stark/starknet-plugin.d.ts +17 -0
  127. package/lib/stark/starknet-plugin.d.ts.map +1 -0
  128. package/lib/stark/starknet-plugin.js +78 -0
  129. package/lib/stark/starknet-plugin.js.map +1 -0
  130. package/lib/stark/starknet-processor.d.ts +32 -0
  131. package/lib/stark/starknet-processor.d.ts.map +1 -0
  132. package/lib/stark/starknet-processor.js +111 -0
  133. package/lib/stark/starknet-processor.js.map +1 -0
  134. package/lib/stark/types.d.ts +11 -0
  135. package/lib/stark/types.d.ts.map +1 -0
  136. package/lib/stark/types.js +2 -0
  137. package/lib/stark/types.js.map +1 -0
  138. package/lib/store/cache.d.ts +14 -0
  139. package/lib/store/cache.d.ts.map +1 -0
  140. package/lib/store/cache.js +35 -0
  141. package/lib/store/cache.js.map +1 -0
  142. package/lib/store/store.d.ts +2 -3
  143. package/lib/store/store.d.ts.map +1 -1
  144. package/lib/store/store.js +34 -9
  145. package/lib/store/store.js.map +1 -1
  146. package/lib/sui/context.d.ts +1 -1
  147. package/lib/sui/context.d.ts.map +1 -1
  148. package/lib/sui/sui-processor.d.ts +1 -1
  149. package/lib/sui/sui-processor.d.ts.map +1 -1
  150. package/lib/sui/sui-processor.js +1 -1
  151. package/lib/sui/sui-processor.js.map +1 -1
  152. package/lib/testing/aptos-facet.d.ts +1 -1
  153. package/lib/testing/aptos-facet.js +2 -2
  154. package/lib/testing/starknet-facet.d.ts +9 -0
  155. package/lib/testing/starknet-facet.d.ts.map +1 -0
  156. package/lib/testing/starknet-facet.js +52 -0
  157. package/lib/testing/starknet-facet.js.map +1 -0
  158. package/lib/testing/sui-facet.js +1 -1
  159. package/lib/testing/test-processor-server.d.ts +2 -0
  160. package/lib/testing/test-processor-server.d.ts.map +1 -1
  161. package/lib/testing/test-processor-server.js +3 -0
  162. package/lib/testing/test-processor-server.js.map +1 -1
  163. package/lib/tsup.config.ts +3 -15
  164. package/lib/utils/dex-price.d.ts +1 -0
  165. package/lib/utils/dex-price.d.ts.map +1 -1
  166. package/lib/utils/dex-price.js +13 -2
  167. package/lib/utils/dex-price.js.map +1 -1
  168. package/package.json +21 -10
  169. package/src/aptos/aptos-processor.ts +1 -1
  170. package/src/aptos/context.ts +2 -2
  171. package/src/aptos/ext/aptos-dex.ts +1 -1
  172. package/src/aptos/ext/coin-event.ts +1 -1
  173. package/src/aptos/ext/coin.ts +2 -2
  174. package/src/aptos/move-coder.ts +7 -5
  175. package/src/aptos/network.ts +7 -1
  176. package/src/bundle.config.ts +23 -0
  177. package/src/eth/account-processor.ts +28 -12
  178. package/src/eth/base-processor-template.ts +16 -8
  179. package/src/eth/base-processor.ts +25 -16
  180. package/src/eth/builtin/internal/eacaggregatorproxy-processor.ts +1554 -123
  181. package/src/eth/builtin/internal/erc1155-processor.ts +659 -42
  182. package/src/eth/builtin/internal/erc20-processor.ts +1266 -90
  183. package/src/eth/builtin/internal/erc20bytes-processor.ts +639 -49
  184. package/src/eth/builtin/internal/erc721-processor.ts +1035 -70
  185. package/src/eth/builtin/internal/weth9-processor.ts +758 -63
  186. package/src/eth/codegen/event-handler.ts +1 -1
  187. package/src/eth/codegen/file.ts +26 -3
  188. package/src/eth/codegen/function-calls.ts +96 -8
  189. package/src/eth/codegen/types.ts +22 -1
  190. package/src/eth/context.ts +7 -0
  191. package/src/eth/eth-plugin.ts +34 -26
  192. package/src/eth/eth.ts +1 -2
  193. package/src/eth/generic-processor.ts +1 -1
  194. package/src/eth/index.ts +5 -1
  195. package/src/solana/builtin/spl-token-processor.ts +1 -1
  196. package/src/solana/solana-context.ts +2 -2
  197. package/src/stark/codegen/codegen.ts +124 -0
  198. package/src/stark/codegen/index.ts +1 -0
  199. package/src/stark/codegen/run.ts +10 -0
  200. package/src/stark/codegen/utils.ts +3 -0
  201. package/src/stark/context.ts +78 -0
  202. package/src/stark/contract.ts +55 -0
  203. package/src/stark/event.ts +7 -0
  204. package/src/stark/index.ts +9 -0
  205. package/src/stark/starknet-plugin.ts +108 -0
  206. package/src/stark/starknet-processor.ts +140 -0
  207. package/src/stark/types.ts +11 -0
  208. package/src/store/cache.ts +46 -0
  209. package/src/store/store.ts +40 -22
  210. package/src/sui/context.ts +1 -1
  211. package/src/sui/sui-processor.ts +1 -1
  212. package/src/testing/aptos-facet.ts +2 -2
  213. package/src/testing/starknet-facet.ts +61 -0
  214. package/src/testing/sui-facet.ts +1 -1
  215. package/src/testing/test-processor-server.ts +3 -0
  216. package/src/tsup.config.ts +3 -15
  217. package/src/utils/dex-price.ts +15 -2
  218. package/lib/eth/provider.d.ts +0 -5
  219. package/lib/eth/provider.d.ts.map +0 -1
  220. package/lib/eth/provider.js +0 -134
  221. package/lib/eth/provider.js.map +0 -1
  222. package/lib/utils/chainlink-oracles-sepolia.csv +0 -19
  223. package/lib/utils/chainlink-oracles.csv +0 -217
  224. package/src/eth/provider.ts +0 -163
@@ -0,0 +1,78 @@
1
+ import { ChainId } from '@sentio/chain'
2
+ import { RecordMetaData } from '@sentio/protos'
3
+ import { BaseContext, Labels, normalizeLabels } from '../core/index.js'
4
+ import { Provider, RpcProvider } from 'starknet'
5
+ import { StarknetProcessorConfig } from './types.js'
6
+ import { Abi } from '@sentio/abi-wan-kanabi'
7
+ import { StarknetContractView } from './contract.js'
8
+
9
+ class AbstractContext extends BaseContext {
10
+ constructor(
11
+ readonly provider: Provider,
12
+ readonly contractAddress: string,
13
+ readonly chainId: ChainId | string,
14
+ readonly blockNumber: number,
15
+ readonly blockHash: string,
16
+ readonly transactionHash: string,
17
+ readonly logIndex: number = -1,
18
+ readonly contractName: string = '',
19
+ readonly abi?: Abi
20
+ ) {
21
+ super({})
22
+ }
23
+
24
+ protected getMetaDataInternal(name: string, labels: Labels): RecordMetaData {
25
+ return {
26
+ address: this.contractAddress,
27
+ contractName: '',
28
+ blockNumber: BigInt(this.blockNumber),
29
+ transactionIndex: 0,
30
+ transactionHash: this.transactionHash,
31
+ chainId: this.getChainId(),
32
+ name: name,
33
+ logIndex: this.logIndex,
34
+ labels: normalizeLabels(labels)
35
+ }
36
+ }
37
+
38
+ getChainId(): ChainId {
39
+ return this.chainId as ChainId
40
+ }
41
+ }
42
+
43
+ export class StarknetContext<CT> extends AbstractContext {
44
+ private _contract: any
45
+
46
+ constructor(
47
+ config: StarknetProcessorConfig,
48
+ provider: RpcProvider,
49
+ blockNumber: number,
50
+ blockHash: string,
51
+ transaction_hash: string,
52
+ logIndex: number,
53
+ readonly classHash: string
54
+ ) {
55
+ super(
56
+ provider,
57
+ config.address,
58
+ config.chainId,
59
+ blockNumber,
60
+ blockHash,
61
+ transaction_hash,
62
+ logIndex,
63
+ config.name ?? classHash.slice(0, 8),
64
+ config.abi
65
+ )
66
+ }
67
+
68
+ getContract(): CT {
69
+ if (!this.abi) {
70
+ throw new Error('abi not found')
71
+ }
72
+
73
+ if (!this._contract) {
74
+ this._contract = new StarknetContractView(this.abi, this.contractAddress, this.provider, this.blockNumber)
75
+ }
76
+ return this._contract as CT
77
+ }
78
+ }
@@ -0,0 +1,55 @@
1
+ import {
2
+ ArgsOrCalldata,
3
+ ArgsOrCalldataWithOptions,
4
+ AsyncContractFunction,
5
+ CallOptions,
6
+ Contract,
7
+ Result,
8
+ RpcProvider,
9
+ CallData,
10
+ splitArgsAndOptions
11
+ } from 'starknet'
12
+ import { Abi } from '@sentio/abi-wan-kanabi'
13
+
14
+ export class StarknetContractView {
15
+ private _contract: Contract
16
+
17
+ constructor(
18
+ readonly abi: Abi,
19
+ readonly address: string,
20
+ readonly provider: RpcProvider,
21
+ readonly blockNumber: number
22
+ ) {
23
+ this._contract = new Contract(abi, address, provider)
24
+ const callData = new CallData(abi)
25
+
26
+ for (const fn of callData.abi) {
27
+ if (fn.type == 'function' && fn.state_mutability == 'view') {
28
+ const signature = fn.name
29
+ Object.defineProperty(this, signature, {
30
+ enumerable: true,
31
+ writable: false,
32
+ value: buildCall(this, signature)
33
+ })
34
+ }
35
+ }
36
+ }
37
+
38
+ call(method: string, args?: ArgsOrCalldata, callOptions?: CallOptions): Promise<Result> {
39
+ return this._contract.call(method, args, {
40
+ ...callOptions,
41
+ blockIdentifier: this.blockNumber
42
+ })
43
+ }
44
+ }
45
+
46
+ function buildCall(contract: StarknetContractView, name: string): AsyncContractFunction {
47
+ return async function (...args: ArgsOrCalldataWithOptions): Promise<any> {
48
+ const params = splitArgsAndOptions(args)
49
+ return contract.call(name, params.args, {
50
+ parseRequest: true,
51
+ parseResponse: true,
52
+ ...params.options
53
+ })
54
+ }
55
+ }
@@ -0,0 +1,7 @@
1
+ export class StarknetEvent<T> {
2
+ constructor(
3
+ readonly caller: string,
4
+ readonly transactionHash: string,
5
+ readonly data: T
6
+ ) {}
7
+ }
@@ -0,0 +1,9 @@
1
+ export { StarknetPlugin } from './starknet-plugin.js'
2
+
3
+ export * from './starknet-processor.js'
4
+
5
+ export { StarknetChainId } from '@sentio/chain'
6
+
7
+ export * from './context.js'
8
+ export * from './event.js'
9
+ export * from './types.js'
@@ -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,46 @@
1
+ import { ID } from './types.js'
2
+ import type { Entity as EntityStruct } from '@sentio/protos'
3
+
4
+ export interface Entity {
5
+ id: ID
6
+ }
7
+
8
+ export class LocalCache {
9
+ private cache: Map<string, EntityStruct> = new Map()
10
+
11
+ getKey(entity: string, id: ID) {
12
+ return `${entity}-${id}`
13
+ }
14
+
15
+ has(entity: string, id: ID): boolean {
16
+ return this.cache.has(this.getKey(entity, id))
17
+ }
18
+
19
+ get(entity: string, id: ID): EntityStruct | undefined {
20
+ return this.cache.get(this.getKey(entity, id))
21
+ }
22
+
23
+ set(entity: EntityStruct) {
24
+ const id = entity.data?.fields['id'].stringValue
25
+ if (id) {
26
+ const key = this.getKey(entity.entity, id)
27
+ let fields = entity.data?.fields || {}
28
+ if (this.cache.has(key)) {
29
+ const existFields = this.cache.get(key)?.data?.fields || {}
30
+ fields = Object.assign(existFields, fields)
31
+ }
32
+ this.cache.set(key, {
33
+ ...entity,
34
+ data: {
35
+ fields
36
+ }
37
+ })
38
+ }
39
+ }
40
+
41
+ delete(entityName: string, id: string | undefined) {
42
+ if (id) {
43
+ this.cache.delete(this.getKey(entityName, id))
44
+ }
45
+ }
46
+ }
@@ -2,17 +2,12 @@ import { StoreContext } from './context.js'
2
2
  import { DatabaseSchema } from '../core/index.js'
3
3
  import { BigDecimal } from '@sentio/bigdecimal'
4
4
  import { Bytes, Float, ID, Int, Timestamp } from './types.js'
5
- import type { Entity as EntityStruct, RichValue } from '@sentio/protos'
5
+ import type { DBRequest, Entity as EntityStruct, RichValue } from '@sentio/protos'
6
6
  import { DBRequest_DBOperator, DBResponse } from '@sentio/protos'
7
7
  import { toBigInteger } from './convert.js'
8
8
  import { PluginManager } from '@sentio/runtime'
9
9
  import { Cursor } from './cursor.js'
10
-
11
- type Value = ID | string | Int | Float | boolean | Timestamp | Bytes | BigDecimal | bigint
12
-
13
- interface Entity {
14
- id: ID
15
- }
10
+ import { Entity, LocalCache } from './cache.js'
16
11
 
17
12
  export interface EntityClass<T> {
18
13
  new (data: Partial<T>): T
@@ -35,12 +30,20 @@ function getEntityName<T>(entity: EntityClass<T> | T | string): string {
35
30
  }
36
31
 
37
32
  export class Store {
33
+ private cache = new LocalCache()
34
+
38
35
  constructor(private readonly context: StoreContext) {}
39
36
 
40
37
  async get<T extends Entity>(entity: EntityClass<T> | string, id: ID): Promise<T | undefined> {
38
+ const entityName = getEntityName(entity)
39
+ const cachedData = this.cache.get(entityName, id)
40
+ if (cachedData) {
41
+ return Promise.resolve(this.newEntity(entity, cachedData))
42
+ }
43
+
41
44
  const promise = this.context.sendRequest({
42
45
  get: {
43
- entity: getEntityName(entity),
46
+ entity: entityName,
44
47
  id: id.toString()
45
48
  }
46
49
  })
@@ -59,21 +62,25 @@ export class Store {
59
62
  entity: [] as string[],
60
63
  id: [] as string[]
61
64
  }
65
+ const entityName = getEntityName(entity)
62
66
  if (id) {
63
67
  if (Array.isArray(id)) {
64
68
  for (const i of id) {
65
- request.entity.push(getEntityName(entity))
69
+ request.entity.push(entityName)
66
70
  request.id.push(i.toString())
71
+ this.cache.delete(entityName, i.toString())
67
72
  }
68
73
  } else {
69
- request.entity.push(getEntityName(entity))
74
+ request.entity.push(entityName)
70
75
  request.id.push(id)
76
+ this.cache.delete(entityName, id)
71
77
  }
72
78
  } else {
73
79
  const entities = Array.isArray(entity) ? entity : [entity]
74
80
  for (const e of entities) {
75
- request.entity.push(getEntityName(entity))
81
+ request.entity.push(entityName)
76
82
  request.id.push((e as Entity).id.toString())
83
+ this.cache.delete(entityName, id)
77
84
  }
78
85
  }
79
86
 
@@ -84,16 +91,27 @@ export class Store {
84
91
 
85
92
  async upsert<T extends Entity>(entity: T | T[]): Promise<void> {
86
93
  const entities = Array.isArray(entity) ? entity : [entity]
87
- const promise = this.context.sendRequest({
94
+ const request = {
88
95
  upsert: {
89
96
  entity: entities.map((e) => getEntityName(e)),
90
97
  // data: entities.map((e) => serialize(e.data)),
91
98
  id: entities.map((e) => e.id.toString()),
92
99
  entityData: entities.map((e: any) => e._data)
93
100
  }
101
+ } as DBRequest
102
+ const promise = this.context.sendRequest(request)
103
+
104
+ return promise.then((_data) => {
105
+ request.upsert?.entity.forEach((entity, i) => {
106
+ this.cache.set({
107
+ entity: entity,
108
+ data: request.upsert?.entityData[i],
109
+ genBlockChain: '',
110
+ genBlockTime: undefined,
111
+ genBlockNumber: 0n
112
+ })
113
+ })
94
114
  })
95
-
96
- await promise
97
115
  }
98
116
 
99
117
  async *listIterator<T extends Entity, P extends keyof T, O extends Operators<T[P]>>(
@@ -107,12 +125,6 @@ export class Store {
107
125
  for (const data of response.entityList?.entities || []) {
108
126
  yield this.newEntity(entity, data)
109
127
  }
110
- console.debug(
111
- 'list returned ',
112
- response.entityList?.entities?.length,
113
- ' entities, next cursor',
114
- response?.nextCursor
115
- )
116
128
  if (!response.nextCursor) {
117
129
  break
118
130
  }
@@ -144,7 +156,7 @@ export class Store {
144
156
  cursor: string | undefined,
145
157
  pageSize?: number
146
158
  ): Promise<DBResponse> {
147
- return (await this.context.sendRequest(
159
+ const response = (await this.context.sendRequest(
148
160
  {
149
161
  list: {
150
162
  entity: getEntityName(entity),
@@ -158,8 +170,14 @@ export class Store {
158
170
  })) || []
159
171
  }
160
172
  },
161
- 60
173
+ 3600
162
174
  )) as DBResponse
175
+
176
+ response.entityList?.entities?.forEach((entity) => {
177
+ this.cache.set(entity)
178
+ })
179
+
180
+ return response
163
181
  }
164
182
 
165
183
  async list<T extends Entity, P extends keyof T, O extends Operators<T[P]>>(
@@ -8,7 +8,7 @@ import {
8
8
  SuiMoveObject,
9
9
  SuiClient
10
10
  } from '@mysten/sui.js/client'
11
- import { MoveCoder } from '@sentio/sdk/sui'
11
+ import { MoveCoder } from './index.js'
12
12
  import { defaultMoveCoder } from './move-coder.js'
13
13
  import { MoveAccountContext, MoveContext } from '../move/index.js'
14
14
 
@@ -16,7 +16,7 @@ import {
16
16
  TransactionFilter
17
17
  } from '../move/index.js'
18
18
  import { getMoveCalls } from './utils.js'
19
- import { defaultMoveCoder, MoveCoder } from '@sentio/sdk/sui'
19
+ import { defaultMoveCoder, MoveCoder } from './index.js'
20
20
  import { Labels } from '../core/index.js'
21
21
  import { Required } from 'utility-types'
22
22
 
@@ -1,8 +1,8 @@
1
1
  import { UserTransactionResponse, EntryFunctionPayloadResponse } from '@aptos-labs/ts-sdk'
2
2
  import { DataBinding, HandlerType } from '@sentio/protos'
3
3
  import { TestProcessorServer } from './test-processor-server.js'
4
- import { AptosNetwork } from '@sentio/sdk/aptos'
5
- import { parseMoveType, accountTypeString } from '@sentio/sdk/move'
4
+ import { AptosNetwork } from '../aptos/index.js'
5
+ import { parseMoveType, accountTypeString } from '../move/index.js'
6
6
 
7
7
  export class AptosFacet {
8
8
  server: TestProcessorServer
@@ -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
+ }