envio 3.0.0-alpha.2 → 3.0.0-alpha.4

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 (74) hide show
  1. package/README.md +2 -2
  2. package/evm.schema.json +44 -34
  3. package/fuel.schema.json +32 -21
  4. package/index.d.ts +4 -1
  5. package/index.js +1 -0
  6. package/package.json +7 -6
  7. package/src/Batch.res.mjs +1 -1
  8. package/src/Benchmark.res +394 -0
  9. package/src/Benchmark.res.mjs +398 -0
  10. package/src/ChainFetcher.res +459 -0
  11. package/src/ChainFetcher.res.mjs +281 -0
  12. package/src/ChainManager.res +179 -0
  13. package/src/ChainManager.res.mjs +139 -0
  14. package/src/Config.res +15 -1
  15. package/src/Config.res.mjs +28 -5
  16. package/src/Ecosystem.res +9 -124
  17. package/src/Ecosystem.res.mjs +19 -160
  18. package/src/Env.res +0 -1
  19. package/src/Env.res.mjs +0 -3
  20. package/src/Envio.gen.ts +9 -1
  21. package/src/Envio.res +12 -9
  22. package/src/EventProcessing.res +476 -0
  23. package/src/EventProcessing.res.mjs +341 -0
  24. package/src/FetchState.res +54 -29
  25. package/src/FetchState.res.mjs +62 -35
  26. package/src/GlobalState.res +1169 -0
  27. package/src/GlobalState.res.mjs +1196 -0
  28. package/src/Internal.res +43 -1
  29. package/src/LoadLayer.res +444 -0
  30. package/src/LoadLayer.res.mjs +296 -0
  31. package/src/LoadLayer.resi +32 -0
  32. package/src/Prometheus.res +8 -8
  33. package/src/Prometheus.res.mjs +10 -10
  34. package/src/ReorgDetection.res +6 -10
  35. package/src/ReorgDetection.res.mjs +6 -6
  36. package/src/Types.ts +1 -1
  37. package/src/UserContext.res +356 -0
  38. package/src/UserContext.res.mjs +238 -0
  39. package/src/Utils.res +15 -0
  40. package/src/Utils.res.mjs +18 -0
  41. package/src/bindings/ClickHouse.res +31 -1
  42. package/src/bindings/ClickHouse.res.mjs +27 -1
  43. package/src/bindings/DateFns.res +71 -0
  44. package/src/bindings/DateFns.res.mjs +22 -0
  45. package/src/bindings/Ethers.res +27 -63
  46. package/src/bindings/Ethers.res.mjs +18 -65
  47. package/src/sources/Evm.res +87 -0
  48. package/src/sources/Evm.res.mjs +105 -0
  49. package/src/sources/EvmChain.res +95 -0
  50. package/src/sources/EvmChain.res.mjs +61 -0
  51. package/src/sources/Fuel.res +19 -34
  52. package/src/sources/Fuel.res.mjs +34 -16
  53. package/src/sources/FuelSDK.res +37 -0
  54. package/src/sources/FuelSDK.res.mjs +29 -0
  55. package/src/sources/HyperFuel.res +2 -2
  56. package/src/sources/HyperFuel.resi +1 -1
  57. package/src/sources/HyperFuelClient.res +2 -2
  58. package/src/sources/HyperFuelSource.res +8 -8
  59. package/src/sources/HyperFuelSource.res.mjs +5 -5
  60. package/src/sources/HyperSyncHeightStream.res +28 -110
  61. package/src/sources/HyperSyncHeightStream.res.mjs +30 -63
  62. package/src/sources/HyperSyncSource.res +16 -18
  63. package/src/sources/HyperSyncSource.res.mjs +25 -25
  64. package/src/sources/Rpc.res +43 -0
  65. package/src/sources/Rpc.res.mjs +31 -0
  66. package/src/sources/RpcSource.res +13 -8
  67. package/src/sources/RpcSource.res.mjs +12 -7
  68. package/src/sources/Source.res +3 -2
  69. package/src/sources/SourceManager.res +183 -108
  70. package/src/sources/SourceManager.res.mjs +162 -99
  71. package/src/sources/SourceManager.resi +4 -5
  72. package/src/sources/Svm.res +59 -0
  73. package/src/sources/Svm.res.mjs +79 -0
  74. package/src/bindings/Ethers.gen.ts +0 -14
@@ -1,28 +1,15 @@
1
1
  /*
2
- Pure js implementation of the HyperSync height stream.
2
+ Pure subscription-based implementation of the HyperSync height stream.
3
3
  */
4
4
 
5
- type t = {
6
- heightRef: ref<int>,
7
- errorRef: ref<option<string>>,
8
- timeoutIdRef: ref<Js.Global.timeoutId>,
9
- eventsourceRef: ref<option<EventSource.t>>,
10
- }
11
-
12
- let make = (~hyperSyncUrl, ~apiToken) => {
13
- /**
14
- On every successful ping or height event, clear the timeout and set a new one.
5
+ let subscribe = (~hyperSyncUrl, ~apiToken, ~onHeight: int => unit): (unit => unit) => {
6
+ let eventsourceRef = ref(None)
7
+ // Timeout doesn't do anything for initialization
8
+ let timeoutIdRef = ref(Js.Global.setTimeout(() => (), 0))
15
9
 
16
- if the timeout lapses, close and reconnect the EventSource.
17
- */
18
- let rec updateTimeoutId = (
19
- ~eventsourceRef: ref<option<EventSource.t>>,
20
- ~timeoutIdRef: ref<Js.Global.timeoutId>,
21
- ~hyperSyncUrl,
22
- ~apiToken,
23
- ~heightRef: ref<int>,
24
- ~errorRef: ref<option<string>>,
25
- ) => {
10
+ // On every successful ping or height event, clear the timeout and set a new one.
11
+ // If the timeout lapses, close and reconnect the EventSource.
12
+ let rec updateTimeoutId = () => {
26
13
  timeoutIdRef.contents->Js.Global.clearTimeout
27
14
 
28
15
  // Should receive a ping at least every 5s, so 15s is a safe margin
@@ -34,31 +21,15 @@ let make = (~hyperSyncUrl, ~apiToken) => {
34
21
  "url": hyperSyncUrl,
35
22
  "staleTimeMillis": staleTimeMillis,
36
23
  })
37
- refreshEventSource(
38
- ~eventsourceRef,
39
- ~hyperSyncUrl,
40
- ~apiToken,
41
- ~heightRef,
42
- ~errorRef,
43
- ~timeoutIdRef,
44
- )
24
+ refreshEventSource()
45
25
  }, staleTimeMillis)
46
26
 
47
27
  timeoutIdRef := newTimeoutId
48
28
  }
49
- and /**
50
- Instantiate a new EventSource and set it to the shared refs.
51
- Add the necessary event listeners, handle errors
52
- and update the timeout.
53
- */
54
- refreshEventSource = (
55
- ~eventsourceRef: ref<option<EventSource.t>>,
56
- ~hyperSyncUrl,
57
- ~apiToken,
58
- ~heightRef: ref<int>,
59
- ~errorRef: ref<option<string>>,
60
- ~timeoutIdRef: ref<Js.Global.timeoutId>,
61
- ) => {
29
+ // Instantiate a new EventSource and set it to the shared refs.
30
+ // Add the necessary event listeners, handle errors
31
+ // and update the timeout.
32
+ and refreshEventSource = () => {
62
33
  // Close the old EventSource if it exists (on a new connection after timeout)
63
34
  switch eventsourceRef.contents {
64
35
  | Some(es) => es->EventSource.close
@@ -79,7 +50,7 @@ let make = (~hyperSyncUrl, ~apiToken) => {
79
50
  // Set the new EventSource to the shared ref
80
51
  eventsourceRef := Some(es)
81
52
  // Update the timeout in case connection goes stale
82
- updateTimeoutId(~eventsourceRef, ~timeoutIdRef, ~hyperSyncUrl, ~apiToken, ~heightRef, ~errorRef)
53
+ updateTimeoutId()
83
54
 
84
55
  es->EventSource.onopen(_ => {
85
56
  Logging.trace({"msg": "SSE connection opened for height stream", "url": hyperSyncUrl})
@@ -90,90 +61,37 @@ let make = (~hyperSyncUrl, ~apiToken) => {
90
61
  "msg": "EventSource error",
91
62
  "error": error->Js.Exn.message,
92
63
  })
93
- // On errors, set the error ref
94
- // so that getHeight can raise an error
95
- errorRef :=
96
- Some(error->Js.Exn.message->Belt.Option.getWithDefault("Unexpected no error.message"))
97
64
  })
98
65
 
99
66
  es->EventSource.addEventListener("ping", _event => {
100
67
  // ping lets us know from the server that the connection is still alive
101
- // and that the height hasn't updated for 5seconds
68
+ // and that the height hasn't updated for 5 seconds
102
69
  // update the timeout on each successful ping received
103
- updateTimeoutId(
104
- ~eventsourceRef,
105
- ~timeoutIdRef,
106
- ~hyperSyncUrl,
107
- ~apiToken,
108
- ~heightRef,
109
- ~errorRef,
110
- )
111
- // reset the error ref, since we had a successful ping
112
- errorRef := None
70
+ updateTimeoutId()
113
71
  })
114
72
 
115
73
  es->EventSource.addEventListener("height", event => {
116
74
  switch event.data->Belt.Int.fromString {
117
75
  | Some(height) =>
118
76
  // On a successful height event, update the timeout
119
- // and reset the error ref
120
- updateTimeoutId(
121
- ~eventsourceRef,
122
- ~timeoutIdRef,
123
- ~hyperSyncUrl,
124
- ~apiToken,
125
- ~heightRef,
126
- ~errorRef,
127
- )
128
- errorRef := None
129
- // Set the actual height ref
130
- heightRef := height
77
+ updateTimeoutId()
78
+ // Call the callback with the new height
79
+ onHeight(height)
131
80
  | None =>
132
81
  Logging.trace({"msg": "Height was not a number in event.data", "data": event.data})
133
- errorRef := Some("Height was not a number in event.data")
134
82
  }
135
83
  })
136
84
  }
137
85
 
138
- // Refs used between the functions
139
-
140
- let heightRef = ref(0)
141
- let errorRef = ref(None)
142
- let eventsourceRef = ref(None)
143
- // Timeout doesn't do anything for initalization
144
- let timeoutIdRef = ref(Js.Global.setTimeout(() => (), 0))
145
- refreshEventSource(
146
- ~eventsourceRef,
147
- ~hyperSyncUrl,
148
- ~apiToken,
149
- ~heightRef,
150
- ~errorRef,
151
- ~timeoutIdRef,
152
- )
153
-
154
- {
155
- heightRef,
156
- errorRef,
157
- timeoutIdRef,
158
- eventsourceRef,
159
- }
160
- }
86
+ // Start the EventSource connection
87
+ refreshEventSource()
161
88
 
162
- let getHeight = async (t: t) => {
163
- while t.heightRef.contents == 0 && t.errorRef.contents == None {
164
- // Poll internally until height is over 0
165
- await Utils.delay(200)
166
- }
167
- switch t.errorRef.contents {
168
- | None => t.heightRef.contents
169
- | Some(error) => Js.Exn.raiseError(error)
170
- }
171
- }
172
-
173
- let close = t => {
174
- t.timeoutIdRef.contents->Js.Global.clearTimeout
175
- switch t.eventsourceRef.contents {
176
- | Some(es) => es->EventSource.close
177
- | None => ()
89
+ // Return unsubscribe function
90
+ () => {
91
+ timeoutIdRef.contents->Js.Global.clearTimeout
92
+ switch eventsourceRef.contents {
93
+ | Some(es) => es->EventSource.close
94
+ | None => ()
95
+ }
178
96
  }
179
97
  }
@@ -1,16 +1,22 @@
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";
9
7
  import * as Caml_option from "rescript/lib/es6/caml_option.js";
10
8
  import * as Eventsource from "eventsource";
11
9
 
12
- function make(hyperSyncUrl, apiToken) {
13
- var updateTimeoutId = function (eventsourceRef, timeoutIdRef, hyperSyncUrl, apiToken, heightRef, errorRef) {
10
+ function subscribe(hyperSyncUrl, apiToken, onHeight) {
11
+ var eventsourceRef = {
12
+ contents: undefined
13
+ };
14
+ var timeoutIdRef = {
15
+ contents: setTimeout((function () {
16
+
17
+ }), 0)
18
+ };
19
+ var updateTimeoutId = function () {
14
20
  clearTimeout(timeoutIdRef.contents);
15
21
  var newTimeoutId = setTimeout((function () {
16
22
  Logging.trace({
@@ -18,11 +24,11 @@ function make(hyperSyncUrl, apiToken) {
18
24
  url: hyperSyncUrl,
19
25
  staleTimeMillis: 15000
20
26
  });
21
- refreshEventSource(eventsourceRef, hyperSyncUrl, apiToken, heightRef, errorRef, timeoutIdRef);
27
+ refreshEventSource();
22
28
  }), 15000);
23
29
  timeoutIdRef.contents = newTimeoutId;
24
30
  };
25
- var refreshEventSource = function (eventsourceRef, hyperSyncUrl, apiToken, heightRef, errorRef, timeoutIdRef) {
31
+ var refreshEventSource = function () {
26
32
  var es = eventsourceRef.contents;
27
33
  if (es !== undefined) {
28
34
  Caml_option.valFromOption(es).close();
@@ -41,7 +47,7 @@ function make(hyperSyncUrl, apiToken) {
41
47
  ])
42
48
  });
43
49
  eventsourceRef.contents = Caml_option.some(es$1);
44
- updateTimeoutId(eventsourceRef, timeoutIdRef, hyperSyncUrl, apiToken, heightRef, errorRef);
50
+ updateTimeoutId();
45
51
  es$1.onopen = (function () {
46
52
  Logging.trace({
47
53
  msg: "SSE connection opened for height stream",
@@ -53,75 +59,36 @@ function make(hyperSyncUrl, apiToken) {
53
59
  msg: "EventSource error",
54
60
  error: error.message
55
61
  });
56
- errorRef.contents = Belt_Option.getWithDefault(error.message, "Unexpected no error.message");
57
62
  });
58
63
  es$1.addEventListener("ping", (function (_event) {
59
- updateTimeoutId(eventsourceRef, timeoutIdRef, hyperSyncUrl, apiToken, heightRef, errorRef);
60
- errorRef.contents = undefined;
64
+ updateTimeoutId();
61
65
  }));
62
66
  es$1.addEventListener("height", (function ($$event) {
63
67
  var height = Belt_Int.fromString($$event.data);
64
68
  if (height !== undefined) {
65
- updateTimeoutId(eventsourceRef, timeoutIdRef, hyperSyncUrl, apiToken, heightRef, errorRef);
66
- errorRef.contents = undefined;
67
- heightRef.contents = height;
69
+ updateTimeoutId();
70
+ return onHeight(height);
68
71
  } 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";
72
+ return Logging.trace({
73
+ msg: "Height was not a number in event.data",
74
+ data: $$event.data
75
+ });
74
76
  }
75
77
  }));
76
78
  };
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);
79
+ refreshEventSource();
80
+ return function () {
81
+ clearTimeout(timeoutIdRef.contents);
82
+ var es = eventsourceRef.contents;
83
+ if (es !== undefined) {
84
+ Caml_option.valFromOption(es).close();
85
+ return ;
86
+ }
87
+
103
88
  };
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
89
  }
121
90
 
122
91
  export {
123
- make ,
124
- getHeight ,
125
- close ,
92
+ subscribe ,
126
93
  }
127
94
  /* Utils Not a pure module */
@@ -249,7 +249,7 @@ let make = (
249
249
  ~toBlock,
250
250
  ~addressesByContractName,
251
251
  ~indexingContracts,
252
- ~currentBlockHeight,
252
+ ~knownHeight,
253
253
  ~partitionId as _,
254
254
  ~selection,
255
255
  ~retry,
@@ -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 {
@@ -325,7 +325,7 @@ let make = (
325
325
  startFetchingBatchTimeRef->Hrtime.timeSince->Hrtime.toMillis->Hrtime.intFromMillis
326
326
 
327
327
  //set height and next from block
328
- let currentBlockHeight = pageUnsafe.archiveHeight
328
+ let knownHeight = pageUnsafe.archiveHeight
329
329
 
330
330
  //The heighest (biggest) blocknumber that was accounted for in
331
331
  //Our query. Not necessarily the blocknumber of the last log returned
@@ -537,7 +537,7 @@ let make = (
537
537
  parsedQueueItems,
538
538
  latestFetchedBlockNumber: rangeLastBlock.blockNumber,
539
539
  stats,
540
- currentBlockHeight,
540
+ knownHeight,
541
541
  reorgGuard,
542
542
  fromBlockQueried: fromBlock,
543
543
  }
@@ -551,32 +551,30 @@ let make = (
551
551
  ~logger,
552
552
  )->Promise.thenResolve(HyperSync.mapExn)
553
553
 
554
- let malformedTokenMessage = `Your token is malformed. For more info: https://docs.envio.dev/docs/HyperSync/api-tokens.`
554
+ let jsonApiClient = Rest.client(endpointUrl)
555
555
 
556
- let heightStream = HyperSyncHeightStream.make(~hyperSyncUrl=endpointUrl, ~apiToken)
556
+ let malformedTokenMessage = `Your token is malformed. For more info: https://docs.envio.dev/docs/HyperSync/api-tokens.`
557
557
 
558
558
  {
559
559
  name,
560
560
  sourceFor: Sync,
561
561
  chain,
562
- pollingInterval: 32, // purely internal state polling since we now stream the height to the state
562
+ pollingInterval: 100,
563
563
  poweredByHyperSync: true,
564
564
  getBlockHashes,
565
- 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) =>
565
+ getHeightOrThrow: async () =>
566
+ switch await HyperSyncJsonApi.heightRoute->Rest.fetch(apiToken, ~client=jsonApiClient) {
567
+ | Value(height) => height
568
+ | ErrorMessage(m) if m === malformedTokenMessage =>
572
569
  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
570
  // Don't want to retry if the token is malformed
574
571
  // So just block forever
575
572
  let _ = await Promise.make((_, _) => ())
576
573
  0
577
- | exn => raise(exn)
578
- }
579
- },
574
+ | ErrorMessage(m) => Js.Exn.raiseError(m)
575
+ },
580
576
  getItemsOrThrow,
577
+ createHeightSubscription: (~onHeight) =>
578
+ HyperSyncHeightStream.subscribe(~hyperSyncUrl=endpointUrl, ~apiToken, ~onHeight),
581
579
  }
582
580
  }
@@ -1,5 +1,6 @@
1
1
  // Generated by ReScript, PLEASE EDIT WITH CARE
2
2
 
3
+ import * as Rest from "../vendored/Rest.res.mjs";
3
4
  import * as Viem from "../bindings/Viem.res.mjs";
4
5
  import * as Utils from "../Utils.res.mjs";
5
6
  import * as Hrtime from "../bindings/Hrtime.res.mjs";
@@ -15,6 +16,7 @@ import * as ErrorHandling from "../ErrorHandling.res.mjs";
15
16
  import * as Caml_exceptions from "rescript/lib/es6/caml_exceptions.js";
16
17
  import * as HyperSyncClient from "./HyperSyncClient.res.mjs";
17
18
  import * as Caml_splice_call from "rescript/lib/es6/caml_splice_call.js";
19
+ import * as HyperSyncJsonApi from "./HyperSyncJsonApi.res.mjs";
18
20
  import * as Caml_js_exceptions from "rescript/lib/es6/caml_js_exceptions.js";
19
21
  import * as HyperSyncHeightStream from "./HyperSyncHeightStream.res.mjs";
20
22
 
@@ -179,7 +181,7 @@ function make(param) {
179
181
  Belt_Array.forEach(param.contracts, (function (contract) {
180
182
  contractNameAbiMapping[contract.name] = contract.abi;
181
183
  }));
182
- var getItemsOrThrow = async function (fromBlock, toBlock, addressesByContractName, indexingContracts, currentBlockHeight, param, selection, retry, logger) {
184
+ var getItemsOrThrow = async function (fromBlock, toBlock, addressesByContractName, indexingContracts, knownHeight, param, selection, retry, logger) {
183
185
  var mkLogAndRaise = function (extra, extra$1) {
184
186
  return ErrorHandling.mkLogAndRaise(logger, extra, extra$1);
185
187
  };
@@ -221,7 +223,7 @@ function make(param) {
221
223
  _1: {
222
224
  TAG: "FailedGettingItems",
223
225
  exn: null,
224
- attemptedToBlock: Belt_Option.getWithDefault(toBlock, currentBlockHeight),
226
+ attemptedToBlock: Belt_Option.getWithDefault(toBlock, knownHeight),
225
227
  retry: tmp
226
228
  },
227
229
  Error: new Error()
@@ -232,7 +234,7 @@ function make(param) {
232
234
  _1: {
233
235
  TAG: "FailedGettingItems",
234
236
  exn: error,
235
- attemptedToBlock: Belt_Option.getWithDefault(toBlock, currentBlockHeight),
237
+ attemptedToBlock: Belt_Option.getWithDefault(toBlock, knownHeight),
236
238
  retry: {
237
239
  TAG: "WithBackoff",
238
240
  message: "Unexpected issue while fetching events from HyperSync client. Attempt a retry.",
@@ -243,7 +245,7 @@ function make(param) {
243
245
  };
244
246
  }
245
247
  var pageFetchTime = Hrtime.intFromMillis(Hrtime.toMillis(Hrtime.timeSince(startFetchingBatchTimeRef)));
246
- var currentBlockHeight$1 = pageUnsafe.archiveHeight;
248
+ var knownHeight$1 = pageUnsafe.archiveHeight;
247
249
  var heighestBlockQueried = pageUnsafe.nextBlock - 1 | 0;
248
250
  var match = pageUnsafe.rollbackGuard;
249
251
  var lastBlockQueriedPromise;
@@ -371,7 +373,7 @@ function make(param) {
371
373
  "page fetch time (ms)": stats_page$unknownfetch$unknowntime$unknown$lparms$rpar
372
374
  };
373
375
  return {
374
- currentBlockHeight: currentBlockHeight$1,
376
+ knownHeight: knownHeight$1,
375
377
  reorgGuard: reorgGuard,
376
378
  parsedQueueItems: parsedQueueItems,
377
379
  fromBlockQueried: fromBlock,
@@ -383,34 +385,32 @@ function make(param) {
383
385
  var getBlockHashes = function (blockNumbers, logger) {
384
386
  return HyperSync.queryBlockDataMulti(endpointUrl, apiToken, blockNumbers, logger).then(HyperSync.mapExn);
385
387
  };
386
- var heightStream = HyperSyncHeightStream.make(endpointUrl, apiToken);
388
+ var jsonApiClient = Rest.client(endpointUrl, undefined);
387
389
  return {
388
390
  name: "HyperSync",
389
391
  sourceFor: "Sync",
390
392
  chain: chain,
391
393
  poweredByHyperSync: true,
392
- pollingInterval: 32,
394
+ pollingInterval: 100,
393
395
  getBlockHashes: getBlockHashes,
394
396
  getHeightOrThrow: (async function () {
395
- try {
396
- return await HyperSyncHeightStream.getHeight(heightStream);
397
- }
398
- catch (raw_exn){
399
- var exn = Caml_js_exceptions.internalToOCamlException(raw_exn);
400
- if (exn.RE_EXN_ID === Js_exn.$$Error) {
401
- if (Belt_Option.getWithDefault(exn._1.message, "").includes("Your token is malformed. For more info: https://docs.envio.dev/docs/HyperSync/api-tokens.")) {
402
- 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");
403
- await new Promise((function (param, param$1) {
404
-
405
- }));
406
- return 0;
407
- }
408
- throw exn;
409
- }
410
- throw exn;
397
+ var height = await Rest.$$fetch(HyperSyncJsonApi.heightRoute, apiToken, jsonApiClient);
398
+ if (typeof height === "number") {
399
+ return height;
400
+ } else if (height === "Your token is malformed. For more info: https://docs.envio.dev/docs/HyperSync/api-tokens.") {
401
+ 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");
402
+ await new Promise((function (param, param$1) {
403
+
404
+ }));
405
+ return 0;
406
+ } else {
407
+ return Js_exn.raiseError(height);
411
408
  }
412
409
  }),
413
- getItemsOrThrow: getItemsOrThrow
410
+ getItemsOrThrow: getItemsOrThrow,
411
+ createHeightSubscription: (function (onHeight) {
412
+ return HyperSyncHeightStream.subscribe(endpointUrl, apiToken, onHeight);
413
+ })
414
414
  };
415
415
  }
416
416
 
@@ -419,4 +419,4 @@ export {
419
419
  memoGetSelectionConfig ,
420
420
  make ,
421
421
  }
422
- /* Viem Not a pure module */
422
+ /* Rest Not a pure module */
@@ -179,3 +179,46 @@ module GetBlockByNumber = {
179
179
  module GetBlockHeight = {
180
180
  let route = makeRpcRoute("eth_blockNumber", S.tuple(_ => ()), hexIntSchema)
181
181
  }
182
+
183
+ module GetTransactionByHash = {
184
+ let transactionSchema = S.object((s): Internal.evmTransactionFields => {
185
+ // We already know the data so ignore the fields
186
+ // blockHash: ?s.field("blockHash", S.option(S.string)),
187
+ // blockNumber: ?s.field("blockNumber", S.option(hexIntSchema)),
188
+ // chainId: ?s.field("chainId", S.option(hexIntSchema)),
189
+ from: ?s.field("from", S.option(S.string->(Utils.magic: S.t<string> => S.t<Address.t>))),
190
+ to: ?s.field("to", S.option(S.string->(Utils.magic: S.t<string> => S.t<Address.t>))),
191
+ gas: ?s.field("gas", S.option(hexBigintSchema)),
192
+ gasPrice: ?s.field("gasPrice", S.option(hexBigintSchema)),
193
+ hash: ?s.field("hash", S.option(S.string)),
194
+ input: ?s.field("input", S.option(S.string)),
195
+ nonce: ?s.field("nonce", S.option(hexBigintSchema)),
196
+ transactionIndex: ?s.field("transactionIndex", S.option(hexIntSchema)),
197
+ value: ?s.field("value", S.option(hexBigintSchema)),
198
+ type_: ?s.field("type", S.option(hexIntSchema)),
199
+ // Signature fields - optional for ZKSync EIP-712 compatibility
200
+ v: ?s.field("v", S.option(S.string)),
201
+ r: ?s.field("r", S.option(S.string)),
202
+ s: ?s.field("s", S.option(S.string)),
203
+ yParity: ?s.field("yParity", S.option(S.string)),
204
+ // EIP-1559 fields
205
+ maxPriorityFeePerGas: ?s.field("maxPriorityFeePerGas", S.option(hexBigintSchema)),
206
+ maxFeePerGas: ?s.field("maxFeePerGas", S.option(hexBigintSchema)),
207
+ // EIP-4844 blob fields
208
+ maxFeePerBlobGas: ?s.field("maxFeePerBlobGas", S.option(hexBigintSchema)),
209
+ blobVersionedHashes: ?s.field("blobVersionedHashes", S.option(S.array(S.string))),
210
+ // TODO: Fields to add:
211
+ // pub access_list: Option<Vec<AccessList>>,
212
+ // pub authorization_list: Option<Vec<Authorization>>,
213
+ // // OP stack fields
214
+ // pub deposit_receipt_version: Option<Quantity>,
215
+ // pub mint: Option<Quantity>,
216
+ // pub source_hash: Option<Hash>,
217
+ })
218
+
219
+ let route = makeRpcRoute(
220
+ "eth_getTransactionByHash",
221
+ S.tuple1(S.string),
222
+ S.null(transactionSchema),
223
+ )
224
+ }
@@ -187,6 +187,36 @@ var GetBlockHeight = {
187
187
  route: route$2
188
188
  };
189
189
 
190
+ var transactionSchema = S$RescriptSchema.object(function (s) {
191
+ return {
192
+ from: s.f("from", S$RescriptSchema.option(S$RescriptSchema.string)),
193
+ to: s.f("to", S$RescriptSchema.option(S$RescriptSchema.string)),
194
+ gas: s.f("gas", S$RescriptSchema.option(hexBigintSchema)),
195
+ gasPrice: s.f("gasPrice", S$RescriptSchema.option(hexBigintSchema)),
196
+ hash: s.f("hash", S$RescriptSchema.option(S$RescriptSchema.string)),
197
+ input: s.f("input", S$RescriptSchema.option(S$RescriptSchema.string)),
198
+ nonce: s.f("nonce", S$RescriptSchema.option(hexBigintSchema)),
199
+ transactionIndex: s.f("transactionIndex", S$RescriptSchema.option(hexIntSchema)),
200
+ value: s.f("value", S$RescriptSchema.option(hexBigintSchema)),
201
+ v: s.f("v", S$RescriptSchema.option(S$RescriptSchema.string)),
202
+ r: s.f("r", S$RescriptSchema.option(S$RescriptSchema.string)),
203
+ s: s.f("s", S$RescriptSchema.option(S$RescriptSchema.string)),
204
+ yParity: s.f("yParity", S$RescriptSchema.option(S$RescriptSchema.string)),
205
+ maxPriorityFeePerGas: s.f("maxPriorityFeePerGas", S$RescriptSchema.option(hexBigintSchema)),
206
+ maxFeePerGas: s.f("maxFeePerGas", S$RescriptSchema.option(hexBigintSchema)),
207
+ maxFeePerBlobGas: s.f("maxFeePerBlobGas", S$RescriptSchema.option(hexBigintSchema)),
208
+ blobVersionedHashes: s.f("blobVersionedHashes", S$RescriptSchema.option(S$RescriptSchema.array(S$RescriptSchema.string))),
209
+ type: s.f("type", S$RescriptSchema.option(hexIntSchema))
210
+ };
211
+ });
212
+
213
+ var route$3 = makeRpcRoute("eth_getTransactionByHash", S$RescriptSchema.tuple1(S$RescriptSchema.string), S$RescriptSchema.$$null(transactionSchema));
214
+
215
+ var GetTransactionByHash = {
216
+ transactionSchema: transactionSchema,
217
+ route: route$3
218
+ };
219
+
190
220
  export {
191
221
  makeRpcRoute ,
192
222
  makeHexSchema ,
@@ -195,5 +225,6 @@ export {
195
225
  GetLogs ,
196
226
  GetBlockByNumber ,
197
227
  GetBlockHeight ,
228
+ GetTransactionByHash ,
198
229
  }
199
230
  /* hexBigintSchema Not a pure module */