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.
- package/README.md +2 -2
- package/evm.schema.json +44 -34
- package/fuel.schema.json +32 -21
- package/index.d.ts +4 -1
- package/index.js +1 -0
- package/package.json +7 -6
- package/src/Batch.res.mjs +1 -1
- package/src/Benchmark.res +394 -0
- package/src/Benchmark.res.mjs +398 -0
- package/src/ChainFetcher.res +459 -0
- package/src/ChainFetcher.res.mjs +281 -0
- package/src/ChainManager.res +179 -0
- package/src/ChainManager.res.mjs +139 -0
- package/src/Config.res +15 -1
- package/src/Config.res.mjs +28 -5
- package/src/Ecosystem.res +9 -124
- package/src/Ecosystem.res.mjs +19 -160
- package/src/Env.res +0 -1
- package/src/Env.res.mjs +0 -3
- package/src/Envio.gen.ts +9 -1
- package/src/Envio.res +12 -9
- package/src/EventProcessing.res +476 -0
- package/src/EventProcessing.res.mjs +341 -0
- package/src/FetchState.res +54 -29
- package/src/FetchState.res.mjs +62 -35
- package/src/GlobalState.res +1169 -0
- package/src/GlobalState.res.mjs +1196 -0
- package/src/Internal.res +43 -1
- package/src/LoadLayer.res +444 -0
- package/src/LoadLayer.res.mjs +296 -0
- package/src/LoadLayer.resi +32 -0
- package/src/Prometheus.res +8 -8
- package/src/Prometheus.res.mjs +10 -10
- package/src/ReorgDetection.res +6 -10
- package/src/ReorgDetection.res.mjs +6 -6
- package/src/Types.ts +1 -1
- package/src/UserContext.res +356 -0
- package/src/UserContext.res.mjs +238 -0
- package/src/Utils.res +15 -0
- package/src/Utils.res.mjs +18 -0
- package/src/bindings/ClickHouse.res +31 -1
- package/src/bindings/ClickHouse.res.mjs +27 -1
- package/src/bindings/DateFns.res +71 -0
- package/src/bindings/DateFns.res.mjs +22 -0
- package/src/bindings/Ethers.res +27 -63
- package/src/bindings/Ethers.res.mjs +18 -65
- package/src/sources/Evm.res +87 -0
- package/src/sources/Evm.res.mjs +105 -0
- package/src/sources/EvmChain.res +95 -0
- package/src/sources/EvmChain.res.mjs +61 -0
- package/src/sources/Fuel.res +19 -34
- package/src/sources/Fuel.res.mjs +34 -16
- package/src/sources/FuelSDK.res +37 -0
- package/src/sources/FuelSDK.res.mjs +29 -0
- package/src/sources/HyperFuel.res +2 -2
- package/src/sources/HyperFuel.resi +1 -1
- package/src/sources/HyperFuelClient.res +2 -2
- package/src/sources/HyperFuelSource.res +8 -8
- package/src/sources/HyperFuelSource.res.mjs +5 -5
- package/src/sources/HyperSyncHeightStream.res +28 -110
- package/src/sources/HyperSyncHeightStream.res.mjs +30 -63
- package/src/sources/HyperSyncSource.res +16 -18
- package/src/sources/HyperSyncSource.res.mjs +25 -25
- package/src/sources/Rpc.res +43 -0
- package/src/sources/Rpc.res.mjs +31 -0
- package/src/sources/RpcSource.res +13 -8
- package/src/sources/RpcSource.res.mjs +12 -7
- package/src/sources/Source.res +3 -2
- package/src/sources/SourceManager.res +183 -108
- package/src/sources/SourceManager.res.mjs +162 -99
- package/src/sources/SourceManager.resi +4 -5
- package/src/sources/Svm.res +59 -0
- package/src/sources/Svm.res.mjs +79 -0
- package/src/bindings/Ethers.gen.ts +0 -14
|
@@ -1,28 +1,15 @@
|
|
|
1
1
|
/*
|
|
2
|
-
Pure
|
|
2
|
+
Pure subscription-based implementation of the HyperSync height stream.
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
timeoutIdRef
|
|
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
|
-
|
|
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
|
-
|
|
51
|
-
|
|
52
|
-
|
|
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(
|
|
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
|
|
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
|
-
|
|
120
|
-
|
|
121
|
-
|
|
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
|
-
//
|
|
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
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
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
|
|
13
|
-
var
|
|
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(
|
|
27
|
+
refreshEventSource();
|
|
22
28
|
}), 15000);
|
|
23
29
|
timeoutIdRef.contents = newTimeoutId;
|
|
24
30
|
};
|
|
25
|
-
var refreshEventSource = function (
|
|
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(
|
|
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(
|
|
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(
|
|
66
|
-
|
|
67
|
-
heightRef.contents = height;
|
|
69
|
+
updateTimeoutId();
|
|
70
|
+
return onHeight(height);
|
|
68
71
|
} else {
|
|
69
|
-
Logging.trace({
|
|
70
|
-
|
|
71
|
-
|
|
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
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
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
|
-
|
|
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
|
-
~
|
|
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(
|
|
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(
|
|
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
|
|
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
|
-
|
|
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
|
|
554
|
+
let jsonApiClient = Rest.client(endpointUrl)
|
|
555
555
|
|
|
556
|
-
let
|
|
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:
|
|
562
|
+
pollingInterval: 100,
|
|
563
563
|
poweredByHyperSync: true,
|
|
564
564
|
getBlockHashes,
|
|
565
|
-
getHeightOrThrow: async () =>
|
|
566
|
-
|
|
567
|
-
|
|
|
568
|
-
|
|
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
|
-
|
|
|
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,
|
|
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,
|
|
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,
|
|
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
|
|
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
|
-
|
|
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
|
|
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:
|
|
394
|
+
pollingInterval: 100,
|
|
393
395
|
getBlockHashes: getBlockHashes,
|
|
394
396
|
getHeightOrThrow: (async function () {
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
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
|
-
/*
|
|
422
|
+
/* Rest Not a pure module */
|
package/src/sources/Rpc.res
CHANGED
|
@@ -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
|
+
}
|
package/src/sources/Rpc.res.mjs
CHANGED
|
@@ -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 */
|