envio 3.0.0-alpha.3 → 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.
@@ -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 */
@@ -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
 
@@ -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 */
@@ -503,10 +503,12 @@ let make = (
503
503
 
504
504
  let mutSuggestedBlockIntervals = Js.Dict.empty()
505
505
 
506
+ let client = Rest.client(url)
507
+
506
508
  let makeTransactionLoader = () =>
507
509
  LazyLoader.make(
508
510
  ~loaderFn=transactionHash =>
509
- provider->Ethers.JsonRpcProvider.getTransaction(~transactionHash),
511
+ Rpc.GetTransactionByHash.route->Rest.fetch(transactionHash, ~client),
510
512
  ~onError=(am, ~exn) => {
511
513
  Logging.error({
512
514
  "err": exn->Utils.prettifyExn,
@@ -560,7 +562,12 @@ let make = (
560
562
  )
561
563
  let getEventTransactionOrThrow = makeThrowingGetEventTransaction(
562
564
  ~getTransactionFields=Ethers.JsonRpcProvider.makeGetTransactionFields(
563
- ~getTransactionByHash=LazyLoader.get(transactionLoader.contents, _),
565
+ ~getTransactionByHash=async transactionHash => {
566
+ switch await transactionLoader.contents->LazyLoader.get(transactionHash) {
567
+ | Some(tx) => tx
568
+ | None => Js.Exn.raiseError(`Transaction not found for hash: ${transactionHash}`)
569
+ }
570
+ },
564
571
  ~lowercaseAddresses,
565
572
  ),
566
573
  )
@@ -902,8 +909,6 @@ let make = (
902
909
  ->Promise.catch(exn => exn->Error->Promise.resolve)
903
910
  }
904
911
 
905
- let client = Rest.client(url)
906
-
907
912
  {
908
913
  name,
909
914
  sourceFor,
@@ -518,9 +518,10 @@ function make(param) {
518
518
  var provider = Ethers.JsonRpcProvider.make(url, chain);
519
519
  var getSelectionConfig = memoGetSelectionConfig(chain);
520
520
  var mutSuggestedBlockIntervals = {};
521
+ var client = Rest.client(url, undefined);
521
522
  var makeTransactionLoader = function () {
522
523
  return LazyLoader.make((function (transactionHash) {
523
- return provider.getTransaction(transactionHash);
524
+ return Rest.$$fetch(Rpc.GetTransactionByHash.route, transactionHash, client);
524
525
  }), (function (am, exn) {
525
526
  Logging.error({
526
527
  err: Utils.prettifyExn(exn),
@@ -559,8 +560,13 @@ function make(param) {
559
560
  var getEventBlockOrThrow = makeThrowingGetEventBlock(function (blockNumber) {
560
561
  return LazyLoader.get(blockLoader.contents, blockNumber);
561
562
  });
562
- var getEventTransactionOrThrow = makeThrowingGetEventTransaction(Ethers.JsonRpcProvider.makeGetTransactionFields((function (__x) {
563
- return LazyLoader.get(transactionLoader.contents, __x);
563
+ var getEventTransactionOrThrow = makeThrowingGetEventTransaction(Ethers.JsonRpcProvider.makeGetTransactionFields((async function (transactionHash) {
564
+ var tx = await LazyLoader.get(transactionLoader.contents, transactionHash);
565
+ if (tx !== undefined) {
566
+ return tx;
567
+ } else {
568
+ return Js_exn.raiseError("Transaction not found for hash: " + transactionHash);
569
+ }
564
570
  }), lowercaseAddresses));
565
571
  var contractNameAbiMapping = {};
566
572
  Belt_Array.forEach(param.contracts, (function (contract) {
@@ -819,7 +825,6 @@ function make(param) {
819
825
  });
820
826
  }));
821
827
  };
822
- var client = Rest.client(url, undefined);
823
828
  return {
824
829
  name: name,
825
830
  sourceFor: param.sourceFor,
@@ -56,4 +56,5 @@ type t = {
56
56
  ~retry: int,
57
57
  ~logger: Pino.t,
58
58
  ) => promise<blockRangeFetchResponse>,
59
+ createHeightSubscription?: (~onHeight: int => unit) => unit => unit,
59
60
  }