envio 3.0.0-alpha.2 → 3.0.0-alpha.20

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 (175) hide show
  1. package/README.md +164 -30
  2. package/bin.mjs +49 -0
  3. package/evm.schema.json +79 -169
  4. package/fuel.schema.json +50 -21
  5. package/index.d.ts +497 -1
  6. package/index.js +4 -0
  7. package/package.json +42 -31
  8. package/rescript.json +4 -1
  9. package/src/Batch.res +11 -8
  10. package/src/Batch.res.mjs +11 -9
  11. package/src/ChainFetcher.res +531 -0
  12. package/src/ChainFetcher.res.mjs +339 -0
  13. package/src/ChainManager.res +190 -0
  14. package/src/ChainManager.res.mjs +166 -0
  15. package/src/Change.res +3 -3
  16. package/src/Config.gen.ts +19 -0
  17. package/src/Config.res +737 -22
  18. package/src/Config.res.mjs +703 -26
  19. package/src/{Indexer.res → Ctx.res} +1 -1
  20. package/src/Ecosystem.res +9 -124
  21. package/src/Ecosystem.res.mjs +19 -160
  22. package/src/Env.res +30 -74
  23. package/src/Env.res.mjs +25 -87
  24. package/src/Envio.gen.ts +3 -1
  25. package/src/Envio.res +20 -9
  26. package/src/EventProcessing.res +469 -0
  27. package/src/EventProcessing.res.mjs +337 -0
  28. package/src/EvmTypes.gen.ts +6 -0
  29. package/src/EvmTypes.res +1 -0
  30. package/src/FetchState.res +1256 -639
  31. package/src/FetchState.res.mjs +1135 -612
  32. package/src/GlobalState.res +1190 -0
  33. package/src/GlobalState.res.mjs +1183 -0
  34. package/src/GlobalStateManager.res +68 -0
  35. package/src/GlobalStateManager.res.mjs +75 -0
  36. package/src/GlobalStateManager.resi +7 -0
  37. package/src/HandlerLoader.res +89 -0
  38. package/src/HandlerLoader.res.mjs +79 -0
  39. package/src/HandlerRegister.res +357 -0
  40. package/src/HandlerRegister.res.mjs +299 -0
  41. package/src/{EventRegister.resi → HandlerRegister.resi} +13 -13
  42. package/src/Hasura.res +111 -175
  43. package/src/Hasura.res.mjs +88 -150
  44. package/src/InMemoryStore.res +1 -1
  45. package/src/InMemoryStore.res.mjs +3 -3
  46. package/src/InMemoryTable.res +1 -1
  47. package/src/InMemoryTable.res.mjs +1 -1
  48. package/src/Internal.gen.ts +4 -0
  49. package/src/Internal.res +230 -12
  50. package/src/Internal.res.mjs +115 -1
  51. package/src/LoadLayer.res +444 -0
  52. package/src/LoadLayer.res.mjs +296 -0
  53. package/src/LoadLayer.resi +32 -0
  54. package/src/LogSelection.res +33 -27
  55. package/src/LogSelection.res.mjs +6 -0
  56. package/src/Logging.res +21 -7
  57. package/src/Logging.res.mjs +16 -8
  58. package/src/Main.res +377 -0
  59. package/src/Main.res.mjs +339 -0
  60. package/src/Persistence.res +7 -21
  61. package/src/Persistence.res.mjs +3 -3
  62. package/src/PgStorage.gen.ts +10 -0
  63. package/src/PgStorage.res +116 -69
  64. package/src/PgStorage.res.d.mts +5 -0
  65. package/src/PgStorage.res.mjs +93 -50
  66. package/src/Prometheus.res +294 -224
  67. package/src/Prometheus.res.mjs +353 -340
  68. package/src/ReorgDetection.res +6 -10
  69. package/src/ReorgDetection.res.mjs +6 -6
  70. package/src/SafeCheckpointTracking.res +4 -4
  71. package/src/SafeCheckpointTracking.res.mjs +2 -2
  72. package/src/Sink.res +4 -2
  73. package/src/Sink.res.mjs +2 -1
  74. package/src/TableIndices.res +0 -1
  75. package/src/TestIndexer.res +692 -0
  76. package/src/TestIndexer.res.mjs +527 -0
  77. package/src/TestIndexerProxyStorage.res +205 -0
  78. package/src/TestIndexerProxyStorage.res.mjs +151 -0
  79. package/src/TopicFilter.res +1 -1
  80. package/src/Types.ts +1 -1
  81. package/src/UserContext.res +424 -0
  82. package/src/UserContext.res.mjs +279 -0
  83. package/src/Utils.res +97 -26
  84. package/src/Utils.res.mjs +91 -44
  85. package/src/bindings/BigInt.res +10 -0
  86. package/src/bindings/BigInt.res.mjs +15 -0
  87. package/src/bindings/ClickHouse.res +120 -23
  88. package/src/bindings/ClickHouse.res.mjs +118 -28
  89. package/src/bindings/DateFns.res +74 -0
  90. package/src/bindings/DateFns.res.mjs +22 -0
  91. package/src/bindings/EventSource.res +8 -1
  92. package/src/bindings/EventSource.res.mjs +8 -1
  93. package/src/bindings/Express.res +1 -0
  94. package/src/bindings/Hrtime.res +14 -1
  95. package/src/bindings/Hrtime.res.mjs +22 -2
  96. package/src/bindings/Hrtime.resi +4 -0
  97. package/src/bindings/Lodash.res +0 -1
  98. package/src/bindings/NodeJs.res +49 -3
  99. package/src/bindings/NodeJs.res.mjs +11 -3
  100. package/src/bindings/Pino.res +24 -10
  101. package/src/bindings/Pino.res.mjs +14 -8
  102. package/src/bindings/Postgres.gen.ts +8 -0
  103. package/src/bindings/Postgres.res +5 -1
  104. package/src/bindings/Postgres.res.d.mts +5 -0
  105. package/src/bindings/PromClient.res +0 -10
  106. package/src/bindings/PromClient.res.mjs +0 -3
  107. package/src/bindings/Vitest.res +142 -0
  108. package/src/bindings/Vitest.res.mjs +9 -0
  109. package/src/bindings/WebSocket.res +27 -0
  110. package/src/bindings/WebSocket.res.mjs +2 -0
  111. package/src/bindings/Yargs.res +8 -0
  112. package/src/bindings/Yargs.res.mjs +2 -0
  113. package/src/db/EntityHistory.res +7 -7
  114. package/src/db/EntityHistory.res.mjs +9 -9
  115. package/src/db/InternalTable.res +59 -111
  116. package/src/db/InternalTable.res.mjs +73 -104
  117. package/src/db/Table.res +27 -8
  118. package/src/db/Table.res.mjs +25 -14
  119. package/src/sources/Evm.res +84 -0
  120. package/src/sources/Evm.res.mjs +105 -0
  121. package/src/sources/EvmChain.res +94 -0
  122. package/src/sources/EvmChain.res.mjs +60 -0
  123. package/src/sources/Fuel.res +19 -34
  124. package/src/sources/Fuel.res.mjs +34 -16
  125. package/src/sources/FuelSDK.res +38 -0
  126. package/src/sources/FuelSDK.res.mjs +29 -0
  127. package/src/sources/HyperFuel.res +2 -2
  128. package/src/sources/HyperFuel.resi +1 -1
  129. package/src/sources/HyperFuelClient.res +2 -2
  130. package/src/sources/HyperFuelSource.res +33 -13
  131. package/src/sources/HyperFuelSource.res.mjs +24 -16
  132. package/src/sources/HyperSync.res +36 -6
  133. package/src/sources/HyperSync.res.mjs +9 -7
  134. package/src/sources/HyperSync.resi +4 -0
  135. package/src/sources/HyperSyncClient.res +1 -1
  136. package/src/sources/HyperSyncHeightStream.res +47 -116
  137. package/src/sources/HyperSyncHeightStream.res.mjs +46 -73
  138. package/src/sources/HyperSyncSource.res +118 -139
  139. package/src/sources/HyperSyncSource.res.mjs +104 -121
  140. package/src/sources/Rpc.res +86 -14
  141. package/src/sources/Rpc.res.mjs +101 -9
  142. package/src/sources/RpcSource.res +621 -364
  143. package/src/sources/RpcSource.res.mjs +843 -410
  144. package/src/sources/RpcWebSocketHeightStream.res +181 -0
  145. package/src/sources/RpcWebSocketHeightStream.res.mjs +196 -0
  146. package/src/sources/Source.res +7 -5
  147. package/src/sources/SourceManager.res +325 -225
  148. package/src/sources/SourceManager.res.mjs +314 -171
  149. package/src/sources/SourceManager.resi +17 -6
  150. package/src/sources/Svm.res +81 -0
  151. package/src/sources/Svm.res.mjs +90 -0
  152. package/src/tui/Tui.res +247 -0
  153. package/src/tui/Tui.res.mjs +337 -0
  154. package/src/tui/bindings/Ink.res +371 -0
  155. package/src/tui/bindings/Ink.res.mjs +72 -0
  156. package/src/tui/bindings/Style.res +123 -0
  157. package/src/tui/bindings/Style.res.mjs +2 -0
  158. package/src/tui/components/BufferedProgressBar.res +40 -0
  159. package/src/tui/components/BufferedProgressBar.res.mjs +57 -0
  160. package/src/tui/components/CustomHooks.res +122 -0
  161. package/src/tui/components/CustomHooks.res.mjs +179 -0
  162. package/src/tui/components/Messages.res +41 -0
  163. package/src/tui/components/Messages.res.mjs +75 -0
  164. package/src/tui/components/SyncETA.res +174 -0
  165. package/src/tui/components/SyncETA.res.mjs +263 -0
  166. package/src/tui/components/TuiData.res +47 -0
  167. package/src/tui/components/TuiData.res.mjs +34 -0
  168. package/svm.schema.json +112 -0
  169. package/bin.js +0 -48
  170. package/src/EventRegister.res +0 -241
  171. package/src/EventRegister.res.mjs +0 -240
  172. package/src/bindings/Ethers.gen.ts +0 -14
  173. package/src/bindings/Ethers.res +0 -204
  174. package/src/bindings/Ethers.res.mjs +0 -130
  175. /package/src/{Indexer.res.mjs → Ctx.res.mjs} +0 -0
@@ -1,16 +1,24 @@
1
1
  // Generated by ReScript, PLEASE EDIT WITH CARE
2
2
 
3
3
  import * as Utils from "../Utils.res.mjs";
4
- import * as Js_exn from "rescript/lib/es6/js_exn.js";
5
4
  import * as Js_dict from "rescript/lib/es6/js_dict.js";
6
5
  import * as Logging from "../Logging.res.mjs";
7
6
  import * as Belt_Int from "rescript/lib/es6/belt_Int.js";
8
- import * as Belt_Option from "rescript/lib/es6/belt_Option.js";
7
+ import * as Caml_obj from "rescript/lib/es6/caml_obj.js";
8
+ import * as Prometheus from "../Prometheus.res.mjs";
9
9
  import * as Caml_option from "rescript/lib/es6/caml_option.js";
10
10
  import * as Eventsource from "eventsource";
11
11
 
12
- function make(hyperSyncUrl, apiToken) {
13
- var updateTimeoutId = function (eventsourceRef, timeoutIdRef, hyperSyncUrl, apiToken, heightRef, errorRef) {
12
+ function subscribe(hyperSyncUrl, apiToken, chainId, onHeight) {
13
+ var eventsourceRef = {
14
+ contents: undefined
15
+ };
16
+ var timeoutIdRef = {
17
+ contents: setTimeout((function () {
18
+
19
+ }), 0)
20
+ };
21
+ var updateTimeoutId = function () {
14
22
  clearTimeout(timeoutIdRef.contents);
15
23
  var newTimeoutId = setTimeout((function () {
16
24
  Logging.trace({
@@ -18,30 +26,33 @@ function make(hyperSyncUrl, apiToken) {
18
26
  url: hyperSyncUrl,
19
27
  staleTimeMillis: 15000
20
28
  });
21
- refreshEventSource(eventsourceRef, hyperSyncUrl, apiToken, heightRef, errorRef, timeoutIdRef);
29
+ refreshEventSource();
22
30
  }), 15000);
23
31
  timeoutIdRef.contents = newTimeoutId;
24
32
  };
25
- var refreshEventSource = function (eventsourceRef, hyperSyncUrl, apiToken, heightRef, errorRef, timeoutIdRef) {
33
+ var refreshEventSource = function () {
26
34
  var es = eventsourceRef.contents;
27
35
  if (es !== undefined) {
28
36
  Caml_option.valFromOption(es).close();
29
37
  }
30
38
  var userAgent = "hyperindex/" + Utils.EnvioPackage.value.version;
31
39
  var es$1 = new Eventsource.EventSource(hyperSyncUrl + "/height/sse", {
32
- headers: Js_dict.fromArray([
33
- [
34
- "Authorization",
35
- "Bearer " + apiToken
36
- ],
37
- [
38
- "User-Agent",
39
- userAgent
40
- ]
41
- ])
40
+ fetch: (function (url, args) {
41
+ var newrecord = Caml_obj.obj_dup(args);
42
+ return fetch(url, (newrecord.headers = Js_dict.fromArray([
43
+ [
44
+ "Authorization",
45
+ "Bearer " + apiToken
46
+ ],
47
+ [
48
+ "User-Agent",
49
+ userAgent
50
+ ]
51
+ ]), newrecord));
52
+ })
42
53
  });
43
54
  eventsourceRef.contents = Caml_option.some(es$1);
44
- updateTimeoutId(eventsourceRef, timeoutIdRef, hyperSyncUrl, apiToken, heightRef, errorRef);
55
+ updateTimeoutId();
45
56
  es$1.onopen = (function () {
46
57
  Logging.trace({
47
58
  msg: "SSE connection opened for height stream",
@@ -53,75 +64,37 @@ function make(hyperSyncUrl, apiToken) {
53
64
  msg: "EventSource error",
54
65
  error: error.message
55
66
  });
56
- errorRef.contents = Belt_Option.getWithDefault(error.message, "Unexpected no error.message");
57
67
  });
58
68
  es$1.addEventListener("ping", (function (_event) {
59
- updateTimeoutId(eventsourceRef, timeoutIdRef, hyperSyncUrl, apiToken, heightRef, errorRef);
60
- errorRef.contents = undefined;
69
+ updateTimeoutId();
61
70
  }));
62
71
  es$1.addEventListener("height", (function ($$event) {
63
72
  var height = Belt_Int.fromString($$event.data);
64
73
  if (height !== undefined) {
65
- updateTimeoutId(eventsourceRef, timeoutIdRef, hyperSyncUrl, apiToken, heightRef, errorRef);
66
- errorRef.contents = undefined;
67
- heightRef.contents = height;
74
+ Prometheus.SourceRequestCount.increment("HyperSync", chainId, "heightStream");
75
+ updateTimeoutId();
76
+ return onHeight(height);
68
77
  } else {
69
- Logging.trace({
70
- msg: "Height was not a number in event.data",
71
- data: $$event.data
72
- });
73
- errorRef.contents = "Height was not a number in event.data";
78
+ return Logging.trace({
79
+ msg: "Height was not a number in event.data",
80
+ data: $$event.data
81
+ });
74
82
  }
75
83
  }));
76
84
  };
77
- var heightRef = {
78
- contents: 0
79
- };
80
- var errorRef = {
81
- contents: undefined
82
- };
83
- var eventsourceRef = {
84
- contents: undefined
85
- };
86
- var timeoutIdRef = {
87
- contents: setTimeout((function () {
88
-
89
- }), 0)
90
- };
91
- refreshEventSource(eventsourceRef, hyperSyncUrl, apiToken, heightRef, errorRef, timeoutIdRef);
92
- return {
93
- heightRef: heightRef,
94
- errorRef: errorRef,
95
- timeoutIdRef: timeoutIdRef,
96
- eventsourceRef: eventsourceRef
97
- };
98
- }
99
-
100
- async function getHeight(t) {
101
- while(t.heightRef.contents === 0 && t.errorRef.contents === undefined) {
102
- await Utils.delay(200);
85
+ refreshEventSource();
86
+ return function () {
87
+ clearTimeout(timeoutIdRef.contents);
88
+ var es = eventsourceRef.contents;
89
+ if (es !== undefined) {
90
+ Caml_option.valFromOption(es).close();
91
+ return ;
92
+ }
93
+
103
94
  };
104
- var error = t.errorRef.contents;
105
- if (error !== undefined) {
106
- return Js_exn.raiseError(error);
107
- } else {
108
- return t.heightRef.contents;
109
- }
110
- }
111
-
112
- function close(t) {
113
- clearTimeout(t.timeoutIdRef.contents);
114
- var es = t.eventsourceRef.contents;
115
- if (es !== undefined) {
116
- Caml_option.valFromOption(es).close();
117
- return ;
118
- }
119
-
120
95
  }
121
96
 
122
97
  export {
123
- make ,
124
- getHeight ,
125
- close ,
98
+ subscribe ,
126
99
  }
127
100
  /* Utils Not a pure module */
@@ -28,20 +28,28 @@ let getSelectionConfig = (selection: FetchState.selection, ~chain) => {
28
28
  dependsOnAddresses,
29
29
  contractName,
30
30
  getEventFiltersOrThrow,
31
- blockSchema,
32
- transactionSchema,
31
+ selectedBlockFields,
32
+ selectedTransactionFields,
33
33
  isWildcard,
34
34
  }) => {
35
- nonOptionalBlockFieldNames->Utils.Set.addMany(
36
- blockSchema->Utils.Schema.getNonOptionalFieldNames,
37
- )
38
- nonOptionalTransactionFieldNames->Utils.Set.addMany(
39
- transactionSchema->Utils.Schema.getNonOptionalFieldNames,
40
- )
41
- capitalizedBlockFields->Utils.Set.addMany(blockSchema->Utils.Schema.getCapitalizedFieldNames)
42
- capitalizedTransactionFields->Utils.Set.addMany(
43
- transactionSchema->Utils.Schema.getCapitalizedFieldNames,
44
- )
35
+ selectedBlockFields
36
+ ->Utils.Set.toArray
37
+ ->Array.forEach(name => {
38
+ let nameStr = (name :> string)
39
+ if !(Internal.evmNullableBlockFields->Utils.Set.has(name)) {
40
+ nonOptionalBlockFieldNames->Utils.Set.add(nameStr)->ignore
41
+ }
42
+ capitalizedBlockFields->Utils.Set.add(nameStr->Utils.String.capitalize)->ignore
43
+ })
44
+ selectedTransactionFields
45
+ ->Utils.Set.toArray
46
+ ->Array.forEach(name => {
47
+ let nameStr = (name :> string)
48
+ if !(Internal.evmNullableTransactionFields->Utils.Set.has(name)) {
49
+ nonOptionalTransactionFieldNames->Utils.Set.add(nameStr)->ignore
50
+ }
51
+ capitalizedTransactionFields->Utils.Set.add(nameStr->Utils.String.capitalize)->ignore
52
+ })
45
53
 
46
54
  let eventFilters = getEventFiltersOrThrow(chain)
47
55
  if dependsOnAddresses {
@@ -131,25 +139,13 @@ let getSelectionConfig = (selection: FetchState.selection, ~chain) => {
131
139
  }
132
140
  }
133
141
 
134
- let memoGetSelectionConfig = (~chain) => {
135
- let cache = Utils.WeakMap.make()
136
- selection =>
137
- switch cache->Utils.WeakMap.get(selection) {
138
- | Some(c) => c
139
- | None => {
140
- let c = selection->getSelectionConfig(~chain)
141
- let _ = cache->Utils.WeakMap.set(selection, c)
142
- c
143
- }
144
- }
145
- }
142
+ let memoGetSelectionConfig = (~chain) =>
143
+ Utils.WeakMap.memoize(selection => selection->getSelectionConfig(~chain))
146
144
 
147
145
  type options = {
148
- contracts: array<Internal.evmContractConfig>,
149
146
  chain: ChainMap.Chain.t,
150
147
  endpointUrl: string,
151
148
  allEventSignatures: array<string>,
152
- shouldUseHypersyncClientDecoder: bool,
153
149
  eventRouter: EventRouter.t<Internal.evmEventConfig>,
154
150
  apiToken: option<string>,
155
151
  clientMaxRetries: int,
@@ -161,11 +157,9 @@ type options = {
161
157
 
162
158
  let make = (
163
159
  {
164
- contracts,
165
160
  chain,
166
161
  endpointUrl,
167
162
  allEventSignatures,
168
- shouldUseHypersyncClientDecoder,
169
163
  eventRouter,
170
164
  apiToken,
171
165
  clientMaxRetries,
@@ -179,7 +173,13 @@ let make = (
179
173
 
180
174
  let getSelectionConfig = memoGetSelectionConfig(~chain)
181
175
 
182
- let apiToken = apiToken->Belt.Option.getWithDefault("3dc856dd-b0ea-494f-b27e-017b8b6b7e07")
176
+ let apiToken = switch apiToken {
177
+ | Some(token) => token
178
+ | None =>
179
+ Js.Exn.raiseError(`An API token is required for using HyperSync as a data-source.
180
+ Set the ENVIO_API_TOKEN environment variable in your .env file.
181
+ Learn more or get a free API token at: https://envio.dev/app/api-tokens`)
182
+ }
183
183
 
184
184
  let client = HyperSyncClient.make(
185
185
  ~url=endpointUrl,
@@ -199,7 +199,7 @@ let make = (
199
199
  switch HyperSyncClient.Decoder.fromSignatures(allEventSignatures) {
200
200
  | exception exn =>
201
201
  exn->ErrorHandling.mkLogAndRaise(
202
- ~msg="Failed to instantiate a decoder from hypersync client, please double check your ABI or try using 'event_decoder: viem' config option",
202
+ ~msg="Failed to instantiate a decoder from hypersync client, please double check your ABI",
203
203
  )
204
204
  | decoder =>
205
205
  if lowercaseAddresses {
@@ -239,17 +239,12 @@ let make = (
239
239
  })
240
240
  }
241
241
 
242
- let contractNameAbiMapping = Js.Dict.empty()
243
- contracts->Belt.Array.forEach(contract => {
244
- contractNameAbiMapping->Js.Dict.set(contract.name, contract.abi)
245
- })
246
-
247
242
  let getItemsOrThrow = async (
248
243
  ~fromBlock,
249
244
  ~toBlock,
250
245
  ~addressesByContractName,
251
246
  ~indexingContracts,
252
- ~currentBlockHeight,
247
+ ~knownHeight,
253
248
  ~partitionId as _,
254
249
  ~selection,
255
250
  ~retry,
@@ -268,6 +263,11 @@ let make = (
268
263
  let startFetchingBatchTimeRef = Hrtime.makeTimer()
269
264
 
270
265
  //fetch batch
266
+ Prometheus.SourceRequestCount.increment(
267
+ ~sourceName=name,
268
+ ~chainId=chain->ChainMap.Chain.toChainId,
269
+ ~method="getLogs",
270
+ )
271
271
  let pageUnsafe = try await HyperSync.GetLogs.query(
272
272
  ~client,
273
273
  ~fromBlock,
@@ -282,7 +282,7 @@ let make = (
282
282
  Source.GetItemsError(
283
283
  Source.FailedGettingItems({
284
284
  exn: %raw(`null`),
285
- attemptedToBlock: toBlock->Option.getWithDefault(currentBlockHeight),
285
+ attemptedToBlock: toBlock->Option.getWithDefault(knownHeight),
286
286
  retry: switch error {
287
287
  | WrongInstance =>
288
288
  let backoffMillis = switch retry {
@@ -308,7 +308,7 @@ let make = (
308
308
  Source.GetItemsError(
309
309
  Source.FailedGettingItems({
310
310
  exn,
311
- attemptedToBlock: toBlock->Option.getWithDefault(currentBlockHeight),
311
+ attemptedToBlock: toBlock->Option.getWithDefault(knownHeight),
312
312
  retry: WithBackoff({
313
313
  message: `Unexpected issue while fetching events from HyperSync client. Attempt a retry.`,
314
314
  backoffMillis: switch retry {
@@ -321,11 +321,10 @@ let make = (
321
321
  )
322
322
  }
323
323
 
324
- let pageFetchTime =
325
- startFetchingBatchTimeRef->Hrtime.timeSince->Hrtime.toMillis->Hrtime.intFromMillis
324
+ let pageFetchTime = startFetchingBatchTimeRef->Hrtime.timeSince->Hrtime.toSecondsFloat
326
325
 
327
326
  //set height and next from block
328
- let currentBlockHeight = pageUnsafe.archiveHeight
327
+ let knownHeight = pageUnsafe.archiveHeight
329
328
 
330
329
  //The heighest (biggest) blocknumber that was accounted for in
331
330
  //Our query. Not necessarily the blocknumber of the last log returned
@@ -369,6 +368,8 @@ let make = (
369
368
  ~serverUrl=endpointUrl,
370
369
  ~apiToken,
371
370
  ~blockNumber=heighestBlockQueried,
371
+ ~sourceName=name,
372
+ ~chainId=chain->ChainMap.Chain.toChainId,
372
373
  ~logger,
373
374
  )->Promise.thenResolve(res =>
374
375
  switch res {
@@ -396,7 +397,6 @@ let make = (
396
397
 
397
398
  let handleDecodeFailure = (
398
399
  ~eventConfig: Internal.evmEventConfig,
399
- ~decoder,
400
400
  ~logIndex,
401
401
  ~blockNumber,
402
402
  ~chainId,
@@ -413,72 +413,28 @@ let make = (
413
413
  "chainId": chainId,
414
414
  "blockNumber": blockNumber,
415
415
  "logIndex": logIndex,
416
- "decoder": decoder,
416
+ "decoder": "hypersync-client",
417
417
  },
418
418
  )
419
419
  exn->ErrorHandling.mkLogAndRaise(~msg, ~logger)
420
420
  }
421
421
  }
422
- if shouldUseHypersyncClientDecoder {
423
- //Currently there are still issues with decoder for some cases so
424
- //this can only be activated with a flag
425
-
426
- //Parse page items into queue items
427
- let parsedEvents = switch await getHscDecoder().decodeEvents(pageUnsafe.events) {
428
- | exception exn =>
429
- exn->mkLogAndRaise(
430
- ~msg="Failed to parse events using hypersync client, please double check your ABI.",
431
- )
432
- | parsedEvents => parsedEvents
433
- }
434
422
 
435
- pageUnsafe.items->Belt.Array.forEachWithIndex((index, item) => {
436
- let {block, log} = item
437
- let chainId = chain->ChainMap.Chain.toChainId
438
- let topic0 = log.topics->Js.Array2.unsafe_get(0)
439
- let maybeEventConfig =
440
- eventRouter->EventRouter.get(
441
- ~tag=EventRouter.getEvmEventId(
442
- ~sighash=topic0->EvmTypes.Hex.toString,
443
- ~topicCount=log.topics->Array.length,
444
- ),
445
- ~indexingContracts,
446
- ~contractAddress=log.address,
447
- ~blockNumber=block.number->Belt.Option.getUnsafe,
448
- )
449
- let maybeDecodedEvent = parsedEvents->Js.Array2.unsafe_get(index)
450
-
451
- switch (maybeEventConfig, maybeDecodedEvent) {
452
- | (Some(eventConfig), Value(decoded)) =>
453
- parsedQueueItems
454
- ->Js.Array2.push(
455
- makeEventBatchQueueItem(
456
- item,
457
- ~params=decoded->eventConfig.convertHyperSyncEventArgs,
458
- ~eventConfig,
459
- ),
460
- )
461
- ->ignore
462
- | (Some(eventConfig), Null | Undefined) =>
463
- handleDecodeFailure(
464
- ~eventConfig,
465
- ~decoder="hypersync-client",
466
- ~logIndex=log.logIndex,
467
- ~blockNumber=block.number->Belt.Option.getUnsafe,
468
- ~chainId,
469
- ~exn=UndefinedValue,
470
- )
471
- | (None, _) => () //ignore events that aren't registered
472
- }
473
- })
474
- } else {
475
- //Parse with viem -> slower than the HyperSyncClient
476
- pageUnsafe.items->Array.forEach(item => {
477
- let {block, log} = item
478
- let chainId = chain->ChainMap.Chain.toChainId
479
- let topic0 = log.topics->Js.Array2.unsafe_get(0)
423
+ //Parse page items into queue items
424
+ let parsedEvents = switch await getHscDecoder().decodeEvents(pageUnsafe.events) {
425
+ | exception exn =>
426
+ exn->mkLogAndRaise(
427
+ ~msg="Failed to parse events using hypersync client, please double check your ABI.",
428
+ )
429
+ | parsedEvents => parsedEvents
430
+ }
480
431
 
481
- switch eventRouter->EventRouter.get(
432
+ pageUnsafe.items->Belt.Array.forEachWithIndex((index, item) => {
433
+ let {block, log} = item
434
+ let chainId = chain->ChainMap.Chain.toChainId
435
+ let topic0 = log.topics->Utils.Array.firstUnsafe
436
+ let maybeEventConfig =
437
+ eventRouter->EventRouter.get(
482
438
  ~tag=EventRouter.getEvmEventId(
483
439
  ~sighash=topic0->EvmTypes.Hex.toString,
484
440
  ~topicCount=log.topics->Array.length,
@@ -486,33 +442,33 @@ let make = (
486
442
  ~indexingContracts,
487
443
  ~contractAddress=log.address,
488
444
  ~blockNumber=block.number->Belt.Option.getUnsafe,
489
- ) {
490
- | Some(eventConfig) =>
491
- switch contractNameAbiMapping->Viem.parseLogOrThrow(
492
- ~contractName=eventConfig.contractName,
493
- ~topics=log.topics,
494
- ~data=log.data,
495
- ) {
496
- | exception exn =>
497
- handleDecodeFailure(
498
- ~eventConfig,
499
- ~decoder="viem",
500
- ~logIndex=log.logIndex,
501
- ~blockNumber=block.number->Belt.Option.getUnsafe,
502
- ~chainId,
503
- ~exn,
504
- )
505
- | decodedEvent =>
506
- parsedQueueItems
507
- ->Js.Array2.push(makeEventBatchQueueItem(item, ~params=decodedEvent.args, ~eventConfig))
508
- ->ignore
509
- }
510
- | None => () //Ignore events that aren't registered
511
- }
512
- })
513
- }
445
+ )
446
+ let maybeDecodedEvent = parsedEvents->Js.Array2.unsafe_get(index)
447
+
448
+ switch (maybeEventConfig, maybeDecodedEvent) {
449
+ | (Some(eventConfig), Value(decoded)) =>
450
+ parsedQueueItems
451
+ ->Js.Array2.push(
452
+ makeEventBatchQueueItem(
453
+ item,
454
+ ~params=decoded->eventConfig.convertHyperSyncEventArgs,
455
+ ~eventConfig,
456
+ ),
457
+ )
458
+ ->ignore
459
+ | (Some(eventConfig), Null | Undefined) =>
460
+ handleDecodeFailure(
461
+ ~eventConfig,
462
+ ~logIndex=log.logIndex,
463
+ ~blockNumber=block.number->Belt.Option.getUnsafe,
464
+ ~chainId,
465
+ ~exn=UndefinedValue,
466
+ )
467
+ | (None, _) => () //ignore events that aren't registered
468
+ }
469
+ })
514
470
 
515
- let parsingTimeElapsed = parsingTimeRef->Hrtime.timeSince->Hrtime.toMillis->Hrtime.intFromMillis
471
+ let parsingTimeElapsed = parsingTimeRef->Hrtime.timeSince->Hrtime.toSecondsFloat
516
472
 
517
473
  let rangeLastBlock = await lastBlockQueriedPromise
518
474
 
@@ -524,7 +480,7 @@ let make = (
524
480
  }),
525
481
  }
526
482
 
527
- let totalTimeElapsed = totalTimeRef->Hrtime.timeSince->Hrtime.toMillis->Hrtime.intFromMillis
483
+ let totalTimeElapsed = totalTimeRef->Hrtime.timeSince->Hrtime.toSecondsFloat
528
484
 
529
485
  let stats = {
530
486
  totalTimeElapsed,
@@ -537,7 +493,7 @@ let make = (
537
493
  parsedQueueItems,
538
494
  latestFetchedBlockNumber: rangeLastBlock.blockNumber,
539
495
  stats,
540
- currentBlockHeight,
496
+ knownHeight,
541
497
  reorgGuard,
542
498
  fromBlockQueried: fromBlock,
543
499
  }
@@ -548,35 +504,58 @@ let make = (
548
504
  ~serverUrl=endpointUrl,
549
505
  ~apiToken,
550
506
  ~blockNumbers,
507
+ ~sourceName=name,
508
+ ~chainId=chain->ChainMap.Chain.toChainId,
551
509
  ~logger,
552
510
  )->Promise.thenResolve(HyperSync.mapExn)
553
511
 
554
- let malformedTokenMessage = `Your token is malformed. For more info: https://docs.envio.dev/docs/HyperSync/api-tokens.`
512
+ let jsonApiClient = Rest.client(endpointUrl)
555
513
 
556
- let heightStream = HyperSyncHeightStream.make(~hyperSyncUrl=endpointUrl, ~apiToken)
514
+ let malformedTokenMessage = `Your token is malformed. For more info: https://docs.envio.dev/docs/HyperSync/api-tokens.`
557
515
 
558
516
  {
559
517
  name,
560
518
  sourceFor: Sync,
561
519
  chain,
562
- pollingInterval: 32, // purely internal state polling since we now stream the height to the state
520
+ pollingInterval: 100,
563
521
  poweredByHyperSync: true,
564
522
  getBlockHashes,
565
523
  getHeightOrThrow: async () => {
566
- try await heightStream->HyperSyncHeightStream.getHeight catch {
567
- | Js.Exn.Error(exn)
568
- if exn
569
- ->Js.Exn.message
570
- ->Option.getWithDefault("")
571
- ->Js.String2.includes(malformedTokenMessage) =>
524
+ let timerRef = Hrtime.makeTimer()
525
+ let result = switch await HyperSyncJsonApi.heightRoute->Rest.fetch(
526
+ apiToken,
527
+ ~client=jsonApiClient,
528
+ ) {
529
+ | Value(height) => height
530
+ | ErrorMessage(m) if m === malformedTokenMessage =>
572
531
  Logging.error(`Your ENVIO_API_TOKEN is malformed. The indexer will not be able to fetch events. Update the token and restart the indexer using 'pnpm envio start'. For more info: https://docs.envio.dev/docs/HyperSync/api-tokens`)
573
532
  // Don't want to retry if the token is malformed
574
533
  // So just block forever
575
534
  let _ = await Promise.make((_, _) => ())
576
535
  0
577
- | exn => raise(exn)
536
+ | ErrorMessage(m) => Js.Exn.raiseError(m)
578
537
  }
538
+ let seconds = timerRef->Hrtime.timeSince->Hrtime.toSecondsFloat
539
+ Prometheus.SourceRequestCount.increment(
540
+ ~sourceName=name,
541
+ ~chainId=chain->ChainMap.Chain.toChainId,
542
+ ~method="getHeight",
543
+ )
544
+ Prometheus.SourceRequestCount.addSeconds(
545
+ ~sourceName=name,
546
+ ~chainId=chain->ChainMap.Chain.toChainId,
547
+ ~method="getHeight",
548
+ ~seconds,
549
+ )
550
+ result
579
551
  },
580
552
  getItemsOrThrow,
553
+ createHeightSubscription: (~onHeight) =>
554
+ HyperSyncHeightStream.subscribe(
555
+ ~hyperSyncUrl=endpointUrl,
556
+ ~apiToken,
557
+ ~chainId=chain->ChainMap.Chain.toChainId,
558
+ ~onHeight,
559
+ ),
581
560
  }
582
561
  }