@sentio/sdk 1.7.13 → 1.7.16

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 (299) hide show
  1. package/{base-processor-template.d.ts → lib/base-processor-template.d.ts} +0 -0
  2. package/{base-processor-template.js → lib/base-processor-template.js} +0 -0
  3. package/lib/base-processor-template.js.map +1 -0
  4. package/{base-processor.d.ts → lib/base-processor.d.ts} +0 -0
  5. package/{base-processor.js → lib/base-processor.js} +0 -0
  6. package/lib/base-processor.js.map +1 -0
  7. package/{bind-options.d.ts → lib/bind-options.d.ts} +0 -0
  8. package/{bind-options.js → lib/bind-options.js} +0 -0
  9. package/lib/bind-options.js.map +1 -0
  10. package/{binds.d.ts → lib/binds.d.ts} +0 -0
  11. package/{binds.js → lib/binds.js} +0 -0
  12. package/lib/binds.js.map +1 -0
  13. package/{builtin → lib/builtin}/erc20/index.d.ts +0 -0
  14. package/{builtin → lib/builtin}/erc20/index.js +0 -0
  15. package/lib/builtin/erc20/index.js.map +1 -0
  16. package/{builtin → lib/builtin}/erc20/test-utils.d.ts +0 -0
  17. package/{builtin → lib/builtin}/erc20/test-utils.js +0 -0
  18. package/lib/builtin/erc20/test-utils.js.map +1 -0
  19. package/{builtin → lib/builtin}/internal/Erc20.d.ts +0 -0
  20. package/{builtin → lib/builtin}/internal/Erc20.js +0 -0
  21. package/lib/builtin/internal/Erc20.js.map +1 -0
  22. package/{builtin → lib/builtin}/internal/common.d.ts +0 -0
  23. package/{builtin → lib/builtin}/internal/common.js +0 -0
  24. package/lib/builtin/internal/common.js.map +1 -0
  25. package/{builtin → lib/builtin}/internal/erc20_processor.d.ts +0 -0
  26. package/{builtin → lib/builtin}/internal/erc20_processor.js +0 -0
  27. package/lib/builtin/internal/erc20_processor.js.map +1 -0
  28. package/{builtin → lib/builtin}/internal/factories/Erc20__factory.d.ts +0 -0
  29. package/{builtin → lib/builtin}/internal/factories/Erc20__factory.js +0 -0
  30. package/lib/builtin/internal/factories/Erc20__factory.js.map +1 -0
  31. package/{builtin → lib/builtin}/internal/factories/index.d.ts +0 -0
  32. package/{builtin → lib/builtin}/internal/factories/index.js +0 -0
  33. package/{builtin → lib/builtin}/internal/factories/index.js.map +1 -1
  34. package/{builtin → lib/builtin}/internal/index.d.ts +0 -0
  35. package/{builtin → lib/builtin}/internal/index.js +0 -0
  36. package/lib/builtin/internal/index.js.map +1 -0
  37. package/{chain-config.d.ts → lib/chain-config.d.ts} +0 -0
  38. package/{chain-config.js → lib/chain-config.js} +0 -0
  39. package/lib/chain-config.js.map +1 -0
  40. package/{cli → lib/cli}/build.d.ts +0 -0
  41. package/{cli → lib/cli}/build.js +0 -0
  42. package/lib/cli/build.js.map +1 -0
  43. package/{cli → lib/cli}/cli.d.ts +0 -0
  44. package/{cli → lib/cli}/cli.js +0 -0
  45. package/lib/cli/cli.js.map +1 -0
  46. package/{cli → lib/cli}/config.d.ts +0 -0
  47. package/{cli → lib/cli}/config.js +0 -0
  48. package/lib/cli/config.js.map +1 -0
  49. package/{cli → lib/cli}/key.d.ts +0 -0
  50. package/{cli → lib/cli}/key.js +0 -0
  51. package/{cli → lib/cli}/key.js.map +1 -1
  52. package/{cli → lib/cli}/solana-code-gen.d.ts +0 -0
  53. package/{cli → lib/cli}/solana-code-gen.js +0 -0
  54. package/{cli → lib/cli}/solana-code-gen.js.map +1 -1
  55. package/{cli → lib/cli}/upload.d.ts +0 -0
  56. package/{cli → lib/cli}/upload.js +0 -0
  57. package/{cli → lib/cli}/upload.js.map +1 -1
  58. package/{cli → lib/cli}/webpack.config.js +0 -0
  59. package/{context.d.ts → lib/context.d.ts} +0 -0
  60. package/{context.js → lib/context.js} +0 -0
  61. package/lib/context.js.map +1 -0
  62. package/{contract-namer.d.ts → lib/contract-namer.d.ts} +0 -0
  63. package/{contract-namer.js → lib/contract-namer.js} +0 -0
  64. package/{contract-namer.js.map → lib/contract-namer.js.map} +1 -1
  65. package/{error.d.ts → lib/error.d.ts} +0 -0
  66. package/{error.js → lib/error.js} +0 -0
  67. package/lib/error.js.map +1 -0
  68. package/{gen → lib/gen}/builtin.d.ts +0 -0
  69. package/{gen → lib/gen}/builtin.js +0 -0
  70. package/lib/gen/builtin.js.map +1 -0
  71. package/{gen → lib/gen}/google/protobuf/empty.d.ts +0 -0
  72. package/{gen → lib/gen}/google/protobuf/empty.js +0 -0
  73. package/lib/gen/google/protobuf/empty.js.map +1 -0
  74. package/{gen → lib/gen}/processor/protos/processor.d.ts +0 -0
  75. package/{gen → lib/gen}/processor/protos/processor.js +0 -0
  76. package/lib/gen/processor/protos/processor.js.map +1 -0
  77. package/{generic-processor.d.ts → lib/generic-processor.d.ts} +0 -0
  78. package/{generic-processor.js → lib/generic-processor.js} +0 -0
  79. package/lib/generic-processor.js.map +1 -0
  80. package/{index.d.ts → lib/index.d.ts} +0 -0
  81. package/{index.js → lib/index.js} +0 -0
  82. package/lib/index.js.map +1 -0
  83. package/lib/loader.d.ts +5 -0
  84. package/lib/loader.js +30 -0
  85. package/lib/loader.js.map +1 -0
  86. package/{meter.d.ts → lib/meter.d.ts} +0 -0
  87. package/{meter.js → lib/meter.js} +0 -0
  88. package/lib/meter.js.map +1 -0
  89. package/{numberish.d.ts → lib/numberish.d.ts} +0 -0
  90. package/{numberish.js → lib/numberish.js} +0 -0
  91. package/lib/numberish.js.map +1 -0
  92. package/{numberish.test.d.ts → lib/numberish.test.d.ts} +0 -0
  93. package/{numberish.test.js → lib/numberish.test.js} +0 -0
  94. package/{numberish.test.js.map → lib/numberish.test.js.map} +1 -1
  95. package/{processor-runner.d.ts → lib/processor-runner.d.ts} +0 -0
  96. package/{processor-runner.js → lib/processor-runner.js} +2 -27
  97. package/lib/processor-runner.js.map +1 -0
  98. package/{processor-state.d.ts → lib/processor-state.d.ts} +0 -0
  99. package/{processor-state.js → lib/processor-state.js} +0 -0
  100. package/lib/processor-state.js.map +1 -0
  101. package/{promise-or-void.d.ts → lib/promise-or-void.d.ts} +0 -0
  102. package/{promise-or-void.js → lib/promise-or-void.js} +0 -0
  103. package/lib/promise-or-void.js.map +1 -0
  104. package/{provider.d.ts → lib/provider.d.ts} +0 -0
  105. package/{provider.js → lib/provider.js} +0 -0
  106. package/lib/provider.js.map +1 -0
  107. package/{release.config.js → lib/release.config.js} +0 -0
  108. package/{service.d.ts → lib/service.d.ts} +2 -1
  109. package/{service.js → lib/service.js} +6 -3
  110. package/lib/service.js.map +1 -0
  111. package/{solana → lib/solana}/builtin/index.d.ts +0 -0
  112. package/{solana → lib/solana}/builtin/index.js +0 -0
  113. package/lib/solana/builtin/index.js.map +1 -0
  114. package/{solana → lib/solana}/builtin/spl-token-processor.d.ts +0 -0
  115. package/{solana → lib/solana}/builtin/spl-token-processor.js +0 -0
  116. package/lib/solana/builtin/spl-token-processor.js.map +1 -0
  117. package/{solana → lib/solana}/builtin/types.d.ts +0 -0
  118. package/{solana → lib/solana}/builtin/types.js +0 -0
  119. package/lib/solana/builtin/types.js.map +1 -0
  120. package/{solana → lib/solana}/builtin/wormhole-processor.d.ts +0 -0
  121. package/{solana → lib/solana}/builtin/wormhole-processor.js +0 -0
  122. package/lib/solana/builtin/wormhole-processor.js.map +1 -0
  123. package/{solana-processor.d.ts → lib/solana-processor.d.ts} +0 -0
  124. package/{solana-processor.js → lib/solana-processor.js} +0 -0
  125. package/lib/solana-processor.js.map +1 -0
  126. package/{target-ethers-sentio → lib/target-ethers-sentio}/codegen.d.ts +0 -0
  127. package/{target-ethers-sentio → lib/target-ethers-sentio}/codegen.js +0 -0
  128. package/{target-ethers-sentio → lib/target-ethers-sentio}/codegen.js.map +0 -0
  129. package/{target-ethers-sentio → lib/target-ethers-sentio}/index.d.ts +0 -0
  130. package/{target-ethers-sentio → lib/target-ethers-sentio}/index.js +0 -0
  131. package/{target-ethers-sentio → lib/target-ethers-sentio}/index.js.map +0 -0
  132. package/{test → lib/test}/codegen.test.d.ts +0 -0
  133. package/{test → lib/test}/codegen.test.js +1 -1
  134. package/lib/test/codegen.test.js.map +1 -0
  135. package/{test → lib/test}/erc20-template.d.ts +0 -0
  136. package/{test → lib/test}/erc20-template.js +0 -0
  137. package/lib/test/erc20-template.js.map +1 -0
  138. package/{test → lib/test}/erc20-template.test.d.ts +0 -0
  139. package/{test → lib/test}/erc20-template.test.js +1 -3
  140. package/lib/test/erc20-template.test.js.map +1 -0
  141. package/{test → lib/test}/erc20.d.ts +0 -0
  142. package/{test → lib/test}/erc20.js +0 -0
  143. package/lib/test/erc20.js.map +1 -0
  144. package/{test → lib/test}/erc20.test.d.ts +0 -0
  145. package/{test → lib/test}/erc20.test.js +1 -3
  146. package/lib/test/erc20.test.js.map +1 -0
  147. package/{test → lib/test}/generic-processor.test.d.ts +0 -0
  148. package/{test → lib/test}/generic-processor.test.js +14 -4
  149. package/lib/test/generic-processor.test.js.map +1 -0
  150. package/{test → lib/test}/index.d.ts +0 -0
  151. package/{test → lib/test}/index.js +0 -0
  152. package/{test → lib/test}/index.js.map +1 -1
  153. package/{test → lib/test}/metric-utils.d.ts +0 -0
  154. package/{test → lib/test}/metric-utils.js +0 -0
  155. package/lib/test/metric-utils.js.map +1 -0
  156. package/{test → lib/test}/mirrorworld.d.ts +0 -0
  157. package/{test → lib/test}/mirrorworld.js +0 -0
  158. package/{test → lib/test}/mirrorworld.js.map +1 -1
  159. package/{test → lib/test}/solana.test.d.ts +0 -0
  160. package/{test → lib/test}/solana.test.js +3 -3
  161. package/lib/test/solana.test.js.map +1 -0
  162. package/{test → lib/test}/test-processor-server.d.ts +1 -1
  163. package/{test → lib/test}/test-processor-server.js +3 -8
  164. package/lib/test/test-processor-server.js.map +1 -0
  165. package/{test → lib/test}/types/game_wallet.d.ts +0 -0
  166. package/{test → lib/test}/types/game_wallet.js +0 -0
  167. package/lib/test/types/game_wallet.js.map +1 -0
  168. package/{test → lib/test}/types/game_wallet_processor.d.ts +0 -0
  169. package/{test → lib/test}/types/game_wallet_processor.js +0 -0
  170. package/lib/test/types/game_wallet_processor.js.map +1 -0
  171. package/{test → lib/test}/wormhole-token-bridge.d.ts +0 -0
  172. package/{test → lib/test}/wormhole-token-bridge.js +0 -0
  173. package/lib/test/wormhole-token-bridge.js.map +1 -0
  174. package/{utils → lib/utils}/chainmap.d.ts +0 -0
  175. package/{utils → lib/utils}/chainmap.js +0 -0
  176. package/lib/utils/chainmap.js.map +1 -0
  177. package/{utils → lib/utils}/convert.d.ts +0 -0
  178. package/{utils → lib/utils}/convert.js +0 -0
  179. package/lib/utils/convert.js.map +1 -0
  180. package/{utils → lib/utils}/index.d.ts +0 -0
  181. package/{utils → lib/utils}/index.js +0 -0
  182. package/lib/utils/index.js.map +1 -0
  183. package/package.json +47 -6
  184. package/src/abis/erc20.json +198 -0
  185. package/src/base-processor-template.ts +92 -0
  186. package/src/base-processor.ts +128 -0
  187. package/src/bind-options.ts +41 -0
  188. package/src/binds.ts +73 -0
  189. package/src/builtin/erc20/index.ts +6 -0
  190. package/src/builtin/erc20/test-utils.ts +49 -0
  191. package/src/builtin/internal/Erc20.ts +356 -0
  192. package/src/builtin/internal/common.ts +46 -0
  193. package/src/builtin/internal/erc20_processor.ts +295 -0
  194. package/src/builtin/internal/factories/Erc20__factory.ts +216 -0
  195. package/src/builtin/internal/factories/index.ts +4 -0
  196. package/src/builtin/internal/index.ts +6 -0
  197. package/src/chain-config.ts +6 -0
  198. package/src/cli/build.ts +180 -0
  199. package/src/cli/cli.ts +217 -0
  200. package/src/cli/config.ts +43 -0
  201. package/src/cli/key.ts +43 -0
  202. package/src/cli/solana-code-gen.ts +16 -0
  203. package/src/cli/upload.ts +86 -0
  204. package/src/cli/webpack.config.js +42 -0
  205. package/src/context.ts +93 -0
  206. package/src/contract-namer.ts +17 -0
  207. package/src/error.ts +43 -0
  208. package/src/gen/builtin.ts +22 -0
  209. package/src/gen/google/protobuf/empty.ts +70 -0
  210. package/src/gen/processor/protos/processor.ts +3071 -0
  211. package/src/generic-processor.ts +38 -0
  212. package/src/index.ts +19 -0
  213. package/src/loader.ts +24 -0
  214. package/src/meter.ts +122 -0
  215. package/src/numberish.test.ts +82 -0
  216. package/src/numberish.ts +99 -0
  217. package/src/processor-runner.ts +49 -0
  218. package/src/processor-state.ts +24 -0
  219. package/src/promise-or-void.ts +1 -0
  220. package/src/provider.ts +74 -0
  221. package/src/service.ts +439 -0
  222. package/src/solana/builtin/index.ts +2 -0
  223. package/src/solana/builtin/spl-token-processor.ts +164 -0
  224. package/src/solana/builtin/types.ts +268 -0
  225. package/src/solana/builtin/wormhole-processor.ts +178 -0
  226. package/src/solana-processor.ts +105 -0
  227. package/src/target-ethers-sentio/codegen.ts +289 -0
  228. package/src/target-ethers-sentio/index.ts +50 -0
  229. package/src/target-ethers-sentio/tsconfig.json +9 -0
  230. package/src/test/abis/evm/anyswapRouter.json +490 -0
  231. package/src/test/abis/solana/mirrorworld.json +1392 -0
  232. package/src/test/codegen.test.ts +26 -0
  233. package/src/test/erc20-template.test.ts +37 -0
  234. package/src/test/erc20-template.ts +25 -0
  235. package/src/test/erc20.test.ts +90 -0
  236. package/src/test/erc20.ts +48 -0
  237. package/src/test/generic-processor.test.ts +70 -0
  238. package/src/test/index.ts +1 -0
  239. package/src/test/metric-utils.ts +49 -0
  240. package/src/test/mirrorworld.ts +40 -0
  241. package/src/test/sentio.yaml +4 -0
  242. package/src/test/solana.test.ts +93 -0
  243. package/src/test/test-processor-server.ts +205 -0
  244. package/src/test/types/game_wallet.ts +1392 -0
  245. package/src/test/types/game_wallet_processor.ts +113 -0
  246. package/src/test/wormhole-token-bridge.ts +21 -0
  247. package/src/types/global.d.ts +17 -0
  248. package/src/utils/chainmap.ts +95 -0
  249. package/src/utils/convert.ts +6 -0
  250. package/src/utils/index.ts +2 -0
  251. package/base-processor-template.js.map +0 -1
  252. package/base-processor.js.map +0 -1
  253. package/bind-options.js.map +0 -1
  254. package/binds.js.map +0 -1
  255. package/builtin/erc20/index.js.map +0 -1
  256. package/builtin/erc20/test-utils.js.map +0 -1
  257. package/builtin/internal/Erc20.js.map +0 -1
  258. package/builtin/internal/common.js.map +0 -1
  259. package/builtin/internal/erc20_processor.js.map +0 -1
  260. package/builtin/internal/factories/Erc20__factory.js.map +0 -1
  261. package/builtin/internal/index.js.map +0 -1
  262. package/chain-config.js.map +0 -1
  263. package/cli/build.js.map +0 -1
  264. package/cli/cli.js.map +0 -1
  265. package/cli/config.js.map +0 -1
  266. package/context.js.map +0 -1
  267. package/error.js.map +0 -1
  268. package/gen/builtin.js.map +0 -1
  269. package/gen/google/protobuf/empty.js.map +0 -1
  270. package/gen/processor/protos/processor.js.map +0 -1
  271. package/generic-processor.js.map +0 -1
  272. package/index.js.map +0 -1
  273. package/meter.js.map +0 -1
  274. package/numberish.js.map +0 -1
  275. package/processor-runner.js.map +0 -1
  276. package/processor-state.js.map +0 -1
  277. package/promise-or-void.js.map +0 -1
  278. package/provider.js.map +0 -1
  279. package/service.js.map +0 -1
  280. package/solana/builtin/index.js.map +0 -1
  281. package/solana/builtin/spl-token-processor.js.map +0 -1
  282. package/solana/builtin/types.js.map +0 -1
  283. package/solana/builtin/wormhole-processor.js.map +0 -1
  284. package/solana-processor.js.map +0 -1
  285. package/test/codegen.test.js.map +0 -1
  286. package/test/erc20-template.js.map +0 -1
  287. package/test/erc20-template.test.js.map +0 -1
  288. package/test/erc20.js.map +0 -1
  289. package/test/erc20.test.js.map +0 -1
  290. package/test/generic-processor.test.js.map +0 -1
  291. package/test/metric-utils.js.map +0 -1
  292. package/test/solana.test.js.map +0 -1
  293. package/test/test-processor-server.js.map +0 -1
  294. package/test/types/game_wallet.js.map +0 -1
  295. package/test/types/game_wallet_processor.js.map +0 -1
  296. package/test/wormhole-token-bridge.js.map +0 -1
  297. package/utils/chainmap.js.map +0 -1
  298. package/utils/convert.js.map +0 -1
  299. package/utils/index.js.map +0 -1
package/src/service.ts ADDED
@@ -0,0 +1,439 @@
1
+ import { Block, Log } from '@ethersproject/abstract-provider'
2
+ import { CallContext, ServerError, Status } from 'nice-grpc'
3
+
4
+ import {
5
+ BlockBinding,
6
+ ContractConfig,
7
+ HandlerType,
8
+ LogFilter,
9
+ LogHandlerConfig,
10
+ O11yResult,
11
+ ProcessBlocksRequest,
12
+ ProcessBlocksResponse,
13
+ ProcessConfigRequest,
14
+ ProcessConfigResponse,
15
+ ProcessInstructionsRequest,
16
+ ProcessInstructionsResponse,
17
+ ProcessLogsRequest,
18
+ ProcessLogsResponse,
19
+ ProcessorServiceImplementation,
20
+ ProcessTransactionsRequest,
21
+ ProcessTransactionsResponse,
22
+ StartRequest,
23
+ TemplateInstance,
24
+ } from './gen/processor/protos/processor'
25
+
26
+ import { Empty } from './gen/google/protobuf/empty'
27
+ import Long from 'long'
28
+ import { TextDecoder } from 'util'
29
+
30
+ const DEFAULT_MAX_BLOCK = Long.ZERO
31
+
32
+ export class ProcessorServiceImpl implements ProcessorServiceImplementation {
33
+ private eventHandlers: ((event: Log) => Promise<O11yResult>)[] = []
34
+ private blockHandlers: ((block: Block) => Promise<O11yResult>)[] = []
35
+
36
+ // map from chain id to list of processors
37
+ // private blockHandlers = new Map<string, ((block: Block) => Promise<O11yResult>)[]>()
38
+ // private processorsByChainId = new Map<string, BaseProcessor<BaseContract, BoundContractView<BaseContract, any>>>()
39
+
40
+ private started = false
41
+ private contractConfigs: ContractConfig[]
42
+ private templateInstances: TemplateInstance[]
43
+ private readonly loader: () => void
44
+
45
+ private readonly shutdownHandler?: () => void
46
+
47
+ constructor(loader: () => void, shutdownHandler?: () => void) {
48
+ this.loader = loader
49
+ this.shutdownHandler = shutdownHandler
50
+ }
51
+
52
+ async getConfig(request: ProcessConfigRequest, context: CallContext): Promise<ProcessConfigResponse> {
53
+ if (!this.started) {
54
+ throw new ServerError(Status.UNAVAILABLE, 'Service Not started.')
55
+ }
56
+ return {
57
+ // TODO project setting
58
+ config: undefined,
59
+ contractConfigs: this.contractConfigs,
60
+ templateInstances: this.templateInstances,
61
+ }
62
+ }
63
+
64
+ async configure() {
65
+ this.eventHandlers = []
66
+ this.templateInstances = []
67
+ // this.processorsByChainId.clear()
68
+ this.contractConfigs = []
69
+
70
+ this.templateInstances = [...global.PROCESSOR_STATE.templatesInstances]
71
+
72
+ // Part 1, prepare EVM processors
73
+ for (const processor of global.PROCESSOR_STATE.processors) {
74
+ // If server favor incremental update this need to change
75
+ // Start basic config for contract
76
+ const chainId = processor.getChainId()
77
+ // this.processorsByChainId.set(chainId, processor)
78
+
79
+ const contractConfig: ContractConfig = {
80
+ processorType: 'user_processor',
81
+ contract: {
82
+ name: processor.config.name,
83
+ chainId: chainId.toString(),
84
+ address: processor.config.address,
85
+ abi: '',
86
+ },
87
+ blockConfigs: [],
88
+ logConfigs: [],
89
+ startBlock: processor.config.startBlock,
90
+ endBlock: DEFAULT_MAX_BLOCK,
91
+ instructionConfig: undefined,
92
+ }
93
+ if (processor.config.endBlock) {
94
+ contractConfig.endBlock = processor.config.endBlock
95
+ }
96
+
97
+ // Step 1. Prepare all the block handlers
98
+ for (const blockHandler of processor.blockHandlers) {
99
+ const handlerId = this.blockHandlers.push(blockHandler) - 1
100
+ contractConfig.blockConfigs.push({
101
+ handlerId: handlerId,
102
+ })
103
+ }
104
+
105
+ // Step 2. Prepare all the event handlers
106
+ for (const eventsHandler of processor.eventHandlers) {
107
+ // associate id with filter
108
+ const handlerId = this.eventHandlers.push(eventsHandler.handler) - 1
109
+ const logConfig: LogHandlerConfig = {
110
+ handlerId: handlerId,
111
+ filters: [],
112
+ }
113
+
114
+ for (const filter of eventsHandler.filters) {
115
+ if (!filter.topics) {
116
+ throw new ServerError(Status.INVALID_ARGUMENT, 'Topic should not be null')
117
+ }
118
+ const logFilter: LogFilter = {
119
+ topics: [],
120
+ }
121
+
122
+ for (const ts of filter.topics) {
123
+ let hashes: string[] = []
124
+ if (Array.isArray(ts)) {
125
+ hashes = hashes.concat(ts)
126
+ } else if (ts) {
127
+ hashes.push(ts)
128
+ }
129
+ logFilter.topics.push({ hashes: hashes })
130
+ }
131
+ logConfig.filters.push(logFilter)
132
+ }
133
+ contractConfig.logConfigs.push(logConfig)
134
+ }
135
+
136
+ // Finish up a contract
137
+ this.contractConfigs.push(contractConfig)
138
+ }
139
+
140
+ // Part 2, prepare solana constractors
141
+ for (const solanaProcessor of global.PROCESSOR_STATE.solanaProcessors) {
142
+ const contractConfig: ContractConfig = {
143
+ processorType: 'user_processor',
144
+ contract: {
145
+ name: solanaProcessor.contractName,
146
+ chainId: 'SOL:mainnet', // TODO set in processor
147
+ address: solanaProcessor.address,
148
+ abi: '',
149
+ },
150
+ blockConfigs: [],
151
+ logConfigs: [],
152
+ startBlock: solanaProcessor.config.startSlot,
153
+ endBlock: DEFAULT_MAX_BLOCK,
154
+ instructionConfig: {
155
+ innerInstruction: solanaProcessor.processInnerInstruction,
156
+ parsedInstruction: solanaProcessor.fromParsedInstruction !== null,
157
+ rawDataInstruction: solanaProcessor.decodeInstruction !== null,
158
+ },
159
+ }
160
+ this.contractConfigs.push(contractConfig)
161
+ }
162
+ }
163
+
164
+ async start(request: StartRequest, context: CallContext): Promise<Empty> {
165
+ if (this.started) {
166
+ return {}
167
+ }
168
+
169
+ this.loader()
170
+
171
+ for (const instance of request.templateInstances) {
172
+ const template = global.PROCESSOR_STATE.templates[instance.templateId]
173
+ if (!template) {
174
+ throw new ServerError(Status.INVALID_ARGUMENT, 'Invalid template contract:' + instance)
175
+ }
176
+ if (!instance.contract) {
177
+ throw new ServerError(Status.INVALID_ARGUMENT, 'Contract Empty from:' + instance)
178
+ }
179
+ template.bind({
180
+ name: instance.contract.name,
181
+ address: instance.contract.address,
182
+ network: Number(instance.contract.chainId),
183
+ startBlock: instance.startBlock,
184
+ endBlock: instance.endBlock,
185
+ })
186
+ }
187
+ await this.configure()
188
+ this.started = true
189
+ return {}
190
+ }
191
+
192
+ async stop(request: Empty, context: CallContext): Promise<Empty> {
193
+ console.log('Server Shutting down in 5 seconds')
194
+ if (this.shutdownHandler) {
195
+ setTimeout(this.shutdownHandler, 5000)
196
+ }
197
+ return {}
198
+ }
199
+
200
+ async processLogs(request: ProcessLogsRequest, context: CallContext): Promise<ProcessLogsResponse> {
201
+ if (!this.started) {
202
+ throw new ServerError(Status.UNAVAILABLE, 'Service Not started.')
203
+ }
204
+
205
+ const resp: O11yResult = {
206
+ gauges: [],
207
+ counters: [],
208
+ }
209
+
210
+ const promises: Promise<O11yResult>[] = []
211
+ for (const l of request.logBindings) {
212
+ if (!l.log) {
213
+ throw new ServerError(Status.INVALID_ARGUMENT, "Log can't be null")
214
+ }
215
+ // const jsonString = Buffer.from(l.log.raw.buffer).toString("utf-8")
216
+ // const jsonString = String.fromCharCode.apply(null, l.log.raw)
217
+
218
+ try {
219
+ const jsonString = Utf8ArrayToStr(l.log.raw)
220
+ const log: Log = JSON.parse(jsonString)
221
+ const handler = this.eventHandlers[l.handlerId]
222
+ const promise = handler(log).catch((e) => {
223
+ throw new ServerError(Status.INTERNAL, 'error processing log: ' + jsonString + '\n' + e.toString())
224
+ })
225
+
226
+ promises.push(promise)
227
+ } catch (e) {
228
+ throw new ServerError(Status.INTERNAL, 'error parse log: ' + l)
229
+ }
230
+ }
231
+
232
+ const results = await Promise.all(promises)
233
+ for (const res of results) {
234
+ resp.counters = resp.counters.concat(res.counters)
235
+ resp.gauges = resp.gauges.concat(res.gauges)
236
+ }
237
+
238
+ let updated = false
239
+ if (
240
+ global.PROCESSOR_STATE.templatesInstances &&
241
+ this.templateInstances.length != global.PROCESSOR_STATE.templatesInstances.length
242
+ ) {
243
+ await this.configure()
244
+ updated = true
245
+ }
246
+
247
+ recordRuntimeInfo(resp, HandlerType.LOG)
248
+ return {
249
+ result: resp,
250
+ configUpdated: updated,
251
+ }
252
+ }
253
+
254
+ async processTransactions(
255
+ request: ProcessTransactionsRequest,
256
+ context: CallContext
257
+ ): Promise<ProcessTransactionsResponse> {
258
+ if (!this.started) {
259
+ throw new ServerError(Status.UNAVAILABLE, 'Service not started.')
260
+ }
261
+
262
+ throw new ServerError(Status.UNIMPLEMENTED, 'Processing transaction is not suppored.')
263
+ }
264
+
265
+ async processInstructions(
266
+ request: ProcessInstructionsRequest,
267
+ context: CallContext
268
+ ): Promise<ProcessInstructionsResponse> {
269
+ if (!this.started) {
270
+ throw new ServerError(Status.UNAVAILABLE, 'Service not started.')
271
+ }
272
+
273
+ const result: O11yResult = {
274
+ gauges: [],
275
+ counters: [],
276
+ }
277
+
278
+ // Only have instruction handlers for solana processors
279
+ if (global.PROCESSOR_STATE.solanaProcessors) {
280
+ const processorPromises: Promise<void>[] = []
281
+ for (const instruction of request.instructions) {
282
+ if (!instruction) {
283
+ throw new ServerError(Status.INVALID_ARGUMENT, 'instruction cannot be null')
284
+ }
285
+
286
+ processorPromises.push(
287
+ new Promise((resolve, _) => {
288
+ for (const processor of global.PROCESSOR_STATE.solanaProcessors) {
289
+ if (processor.address === instruction.programAccountId) {
290
+ let res: O11yResult | null
291
+ if (instruction.parsed) {
292
+ res = processor.handleInstruction(JSON.parse(new TextDecoder().decode(instruction.parsed)))
293
+ } else if (instruction.instructionData) {
294
+ res = processor.handleInstruction(instruction.instructionData)
295
+ } else {
296
+ continue
297
+ }
298
+ if (res) {
299
+ try {
300
+ res.gauges.forEach((g) => {
301
+ if (g.metadata) {
302
+ g.metadata.blockNumber = instruction.slot
303
+ }
304
+ result.gauges.push(g)
305
+ })
306
+ res.counters.forEach((c) => {
307
+ if (c.metadata) {
308
+ c.metadata.blockNumber = instruction.slot
309
+ }
310
+ result.counters.push(c)
311
+ })
312
+ } catch (e) {
313
+ console.error('error processing instruction ' + e.toString())
314
+ }
315
+ } else {
316
+ console.warn(
317
+ `Failed to decode the instruction: ${instruction.instructionData} with slot: ${instruction.slot}`
318
+ )
319
+ }
320
+ }
321
+ }
322
+ resolve()
323
+ })
324
+ )
325
+ }
326
+
327
+ await Promise.all(processorPromises)
328
+ }
329
+
330
+ recordRuntimeInfo(result, HandlerType.INSTRUCTION)
331
+ return {
332
+ result,
333
+ }
334
+ }
335
+
336
+ async processBlocks(request: ProcessBlocksRequest, context: CallContext): Promise<ProcessBlocksResponse> {
337
+ if (!this.started) {
338
+ throw new ServerError(Status.UNAVAILABLE, 'Service Not started.')
339
+ }
340
+
341
+ const promises = request.blockBindings.map((binding) => this.processBlock(binding))
342
+ const results = await Promise.all(promises)
343
+
344
+ const res = O11yResult.fromPartial({})
345
+
346
+ for (const r of results) {
347
+ res.counters = res.counters.concat(r.counters)
348
+ res.gauges = res.gauges.concat(r.gauges)
349
+ }
350
+
351
+ recordRuntimeInfo(res, HandlerType.BLOCK)
352
+ return {
353
+ result: res,
354
+ }
355
+ }
356
+
357
+ async processBlock(binding: BlockBinding): Promise<O11yResult> {
358
+ if (!binding.block) {
359
+ throw new ServerError(Status.INVALID_ARGUMENT, "Block can't be empty")
360
+ }
361
+ const jsonString = Utf8ArrayToStr(binding.block.raw)
362
+
363
+ const block: Block = JSON.parse(jsonString)
364
+
365
+ const resp: O11yResult = {
366
+ gauges: [],
367
+ counters: [],
368
+ }
369
+
370
+ const promises: Promise<O11yResult>[] = []
371
+ for (const handlerId of binding.handlerIds) {
372
+ const promise = this.blockHandlers[handlerId](block).catch((e) => {
373
+ throw new ServerError(Status.INTERNAL, 'error processing block: ' + block.number + '\n' + e.toString())
374
+ })
375
+ promises.push(promise)
376
+ }
377
+ const allRes = await Promise.all(promises)
378
+ for (const res of allRes) {
379
+ resp.counters = resp.counters.concat(res.counters)
380
+ resp.gauges = resp.gauges.concat(res.gauges)
381
+ }
382
+ return resp
383
+ }
384
+ }
385
+
386
+ // https://ourcodeworld.com/articles/read/164/how-to-convert-an-uint8array-to-string-in-javascript
387
+ /* eslint-disable */
388
+ function Utf8ArrayToStr(array: Uint8Array) {
389
+ let out, i, len, c
390
+ let char2, char3
391
+
392
+ out = ''
393
+ len = array.length
394
+ i = 0
395
+ while (i < len) {
396
+ c = array[i++]
397
+ switch (c >> 4) {
398
+ case 0:
399
+ case 1:
400
+ case 2:
401
+ case 3:
402
+ case 4:
403
+ case 5:
404
+ case 6:
405
+ case 7:
406
+ // 0xxxxxxx
407
+ out += String.fromCharCode(c)
408
+ break
409
+ case 12:
410
+ case 13:
411
+ // 110x xxxx 10xx xxxx
412
+ char2 = array[i++]
413
+ out += String.fromCharCode(((c & 0x1f) << 6) | (char2 & 0x3f))
414
+ break
415
+ case 14:
416
+ // 1110 xxxx 10xx xxxx 10xx xxxx
417
+ char2 = array[i++]
418
+ char3 = array[i++]
419
+ out += String.fromCharCode(((c & 0x0f) << 12) | ((char2 & 0x3f) << 6) | ((char3 & 0x3f) << 0))
420
+ break
421
+ }
422
+ }
423
+
424
+ return out
425
+ }
426
+
427
+ function recordRuntimeInfo(results: O11yResult, handlerType: HandlerType) {
428
+ results.gauges.forEach((e) => {
429
+ e.runtimeInfo = {
430
+ from: handlerType,
431
+ }
432
+ })
433
+
434
+ results.counters.forEach((e) => {
435
+ e.runtimeInfo = {
436
+ from: handlerType,
437
+ }
438
+ })
439
+ }
@@ -0,0 +1,2 @@
1
+ export * from './spl-token-processor'
2
+ export * from './wormhole-processor'
@@ -0,0 +1,164 @@
1
+ import { SolanaBaseProcessor } from '../../solana-processor'
2
+ import { SolanaContext } from '../../context'
3
+ import { Instruction } from '@project-serum/anchor'
4
+ import { Approve, Burn, CloseAccount, FreezeAccount, InitializeAccount, InitializeAccount2, InitializeAccount3, InitializeMint, InitializeMultisig, MintTo, Revoke, ThawAccount, Transfer } from './types';
5
+ import { SolanaBindOptions } from '../../bind-options';
6
+
7
+ export class SPLTokenProcessor extends SolanaBaseProcessor {
8
+ static bind(options: SolanaBindOptions): SPLTokenProcessor {
9
+ if (options && !options.name) {
10
+ options.name = 'SPL Token Program'
11
+ }
12
+ return new SPLTokenProcessor(options)
13
+ }
14
+
15
+ fromParsedInstruction: (instruction: { type: string, info: any }) => Instruction | null = (instruction: { type: string, info: any }) => {
16
+ const instructionType = instruction.type
17
+ if (!instructionType) {
18
+ return null
19
+ }
20
+ return {
21
+ name: instruction.type,
22
+ data: {
23
+ ...instruction.info,
24
+ },
25
+ }
26
+ }
27
+
28
+ public onInitializeMint(
29
+ handler: (data: InitializeMint, ctx: SolanaContext) => void
30
+ ): SPLTokenProcessor {
31
+ this.onInstruction('initializeMint', (ins: Instruction, ctx) => {
32
+ if (ins) {
33
+ handler(ins.data as InitializeMint, ctx)
34
+ }
35
+ })
36
+ return this
37
+ }
38
+
39
+ public onInitializeAccount(
40
+ hanlder: (data: InitializeAccount, ctx: SolanaContext) => void
41
+ ): SPLTokenProcessor {
42
+ this.onInstruction('initializeAccount', (ins: Instruction, ctx) => {
43
+ if (ins) {
44
+ hanlder(ins.data as InitializeAccount, ctx)
45
+ }
46
+ })
47
+ return this
48
+ }
49
+
50
+ public onInitializeAccount2(
51
+ hanlder: (data: InitializeAccount2, ctx: SolanaContext) => void
52
+ ): SPLTokenProcessor {
53
+ this.onInstruction('initializeAccount2', (ins: Instruction, ctx) => {
54
+ if (ins) {
55
+ hanlder(ins.data as InitializeAccount2, ctx)
56
+ }
57
+ })
58
+ return this
59
+ }
60
+
61
+ public onInitializeAccount3(
62
+ hanlder: (data: InitializeAccount3, ctx: SolanaContext) => void
63
+ ): SPLTokenProcessor {
64
+ this.onInstruction('initializeAccount3', (ins: Instruction, ctx) => {
65
+ if (ins) {
66
+ hanlder(ins.data as InitializeAccount3, ctx)
67
+ }
68
+ })
69
+ return this
70
+ }
71
+
72
+ public onInitializeMultisig(
73
+ handler: (data: InitializeMultisig, ctx: SolanaContext) => void
74
+ ): SPLTokenProcessor {
75
+ this.onInstruction('initializeMultisig', (ins: Instruction, ctx) => {
76
+ if (ins) {
77
+ handler(ins.data as InitializeMultisig, ctx)
78
+ }
79
+ })
80
+ return this
81
+ }
82
+
83
+ public onTransfer(handler: (data: Transfer, ctx: SolanaContext) => void): SPLTokenProcessor {
84
+ this.onInstruction('transfer', (ins: Instruction, ctx) => {
85
+ if (ins) {
86
+ handler(ins.data as Transfer, ctx)
87
+ }
88
+ })
89
+ return this
90
+ }
91
+
92
+ public onApprovend(handler: (data: Approve, ctx: SolanaContext) => void): SPLTokenProcessor {
93
+ this.onInstruction('approve', (ins: Instruction, ctx) => {
94
+ if (ins) {
95
+ handler(ins.data as Approve, ctx)
96
+ }
97
+ })
98
+ return this
99
+ }
100
+
101
+ public onRevoke(handler: (data: Revoke, ctx: SolanaContext) => void): SPLTokenProcessor {
102
+ this.onInstruction('revoke', (ins: Instruction, ctx) => {
103
+ if (ins) {
104
+ handler(ins.data as Revoke, ctx)
105
+ }
106
+ })
107
+ return this
108
+ }
109
+
110
+ public onSetAuthority(handler: (data: any, ctx: SolanaContext) => void): SPLTokenProcessor {
111
+ this.onInstruction('setAuthority', (ins: Instruction, ctx) => {
112
+ if (ins) {
113
+ handler(ins.data as any, ctx)
114
+ }
115
+ })
116
+ return this
117
+ }
118
+
119
+ public onMintTo(handler: (data: MintTo, ctx: SolanaContext) => void): SPLTokenProcessor {
120
+ this.onInstruction('mintTo', (ins: Instruction, ctx) => {
121
+ if (ins) {
122
+ handler(ins.data as MintTo, ctx)
123
+ }
124
+ })
125
+ return this
126
+ }
127
+
128
+ public onBurn(handler: (data: Burn, ctx: SolanaContext) => void): SPLTokenProcessor {
129
+ this.onInstruction('burn', (ins: Instruction, ctx) => {
130
+ if (ins) {
131
+ handler(ins.data as Burn, ctx)
132
+ }
133
+ })
134
+ return this
135
+ }
136
+
137
+ public onCloseAccount(handler: (data: CloseAccount, ctx: SolanaContext) => void): SPLTokenProcessor {
138
+ this.onInstruction('closeAccount', (ins: Instruction, ctx) => {
139
+ if (ins) {
140
+ handler(ins.data as CloseAccount, ctx)
141
+ }
142
+ })
143
+ return this
144
+ }
145
+
146
+ public onFreezeAccount(handler: (data: FreezeAccount, ctx: SolanaContext) => void): SPLTokenProcessor {
147
+ this.onInstruction('freezeAccount', (ins: Instruction, ctx) => {
148
+ if (ins) {
149
+ handler(ins.data as FreezeAccount, ctx)
150
+ }
151
+ })
152
+ return this
153
+ }
154
+
155
+ public onThawAccount(handler: (data: ThawAccount, ctx: SolanaContext) => void): SPLTokenProcessor {
156
+ this.onInstruction('thawAccount', (ins: Instruction, ctx) => {
157
+ if (ins) {
158
+ handler(ins.data as ThawAccount, ctx)
159
+ }
160
+ })
161
+ return this
162
+ }
163
+ // Todo(pcxu): auto gen this file
164
+ }