envio 3.3.0-alpha.7 → 3.3.0-alpha.9
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/index.d.ts +23 -5
- package/package.json +6 -6
- package/src/Api.res +1 -1
- package/src/Api.res.mjs +1 -1
- package/src/ChainFetching.res +21 -10
- package/src/ChainFetching.res.mjs +11 -10
- package/src/ChainState.res +401 -171
- package/src/ChainState.res.mjs +270 -104
- package/src/ChainState.resi +19 -7
- package/src/Config.res +11 -27
- package/src/Config.res.mjs +8 -7
- package/src/Core.res +7 -0
- package/src/CrossChainState.res +82 -82
- package/src/CrossChainState.res.mjs +52 -59
- package/src/CrossChainState.resi +1 -1
- package/src/Ecosystem.res +3 -3
- package/src/Ecosystem.res.mjs +3 -3
- package/src/Envio.res +14 -9
- package/src/EnvioGlobal.res +53 -0
- package/src/EnvioGlobal.res.mjs +31 -0
- package/src/EventConfigBuilder.res +117 -69
- package/src/EventConfigBuilder.res.mjs +71 -34
- package/src/EventProcessing.res +19 -15
- package/src/EventProcessing.res.mjs +13 -12
- package/src/FetchState.res +410 -185
- package/src/FetchState.res.mjs +268 -253
- package/src/HandlerLoader.res +8 -113
- package/src/HandlerLoader.res.mjs +2 -88
- package/src/HandlerRegister.res +518 -144
- package/src/HandlerRegister.res.mjs +285 -133
- package/src/HandlerRegister.resi +24 -8
- package/src/IndexerState.res +6 -3
- package/src/IndexerState.res.mjs +3 -3
- package/src/IndexerState.resi +1 -1
- package/src/IndexingAddresses.res +10 -7
- package/src/IndexingAddresses.res.mjs +8 -7
- package/src/IndexingAddresses.resi +3 -1
- package/src/Internal.res +104 -39
- package/src/Internal.res.mjs +11 -1
- package/src/LogSelection.res +102 -165
- package/src/LogSelection.res.mjs +101 -116
- package/src/Main.res +49 -164
- package/src/Main.res.mjs +39 -104
- package/src/Metrics.res +43 -2
- package/src/Metrics.res.mjs +39 -3
- package/src/Prometheus.res +0 -35
- package/src/Prometheus.res.mjs +33 -68
- package/src/RawEvent.res +7 -2
- package/src/RawEvent.res.mjs +4 -4
- package/src/RollbackCommit.res +4 -1
- package/src/RollbackCommit.res.mjs +3 -2
- package/src/SimulateItems.res +20 -7
- package/src/SimulateItems.res.mjs +7 -11
- package/src/TestIndexer.res +1 -1
- package/src/TestIndexer.res.mjs +1 -1
- package/src/sources/BlockStore.res +46 -0
- package/src/sources/BlockStore.res.mjs +24 -0
- package/src/sources/EventRouter.res +19 -12
- package/src/sources/EventRouter.res.mjs +7 -5
- package/src/sources/Evm.res +58 -5
- package/src/sources/Evm.res.mjs +44 -5
- package/src/sources/EvmChain.res +14 -18
- package/src/sources/EvmChain.res.mjs +12 -13
- package/src/sources/FieldMask.res +39 -0
- package/src/sources/FieldMask.res.mjs +42 -0
- package/src/sources/Fuel.res +8 -3
- package/src/sources/Fuel.res.mjs +5 -4
- package/src/sources/HyperFuelSource.res +31 -40
- package/src/sources/HyperFuelSource.res.mjs +52 -44
- package/src/sources/HyperSync.res +31 -9
- package/src/sources/HyperSync.res.mjs +47 -31
- package/src/sources/HyperSync.resi +10 -3
- package/src/sources/HyperSyncClient.res +15 -4
- package/src/sources/HyperSyncHeightStream.res +1 -8
- package/src/sources/HyperSyncHeightStream.res.mjs +0 -2
- package/src/sources/HyperSyncSource.res +58 -90
- package/src/sources/HyperSyncSource.res.mjs +57 -66
- package/src/sources/RpcSource.res +118 -120
- package/src/sources/RpcSource.res.mjs +92 -74
- package/src/sources/RpcWebSocketHeightStream.res +0 -5
- package/src/sources/RpcWebSocketHeightStream.res.mjs +0 -2
- package/src/sources/SimulateSource.res +5 -3
- package/src/sources/SimulateSource.res.mjs +12 -4
- package/src/sources/Source.res +19 -5
- package/src/sources/SourceManager.res +60 -10
- package/src/sources/SourceManager.res.mjs +54 -8
- package/src/sources/SourceManager.resi +10 -0
- package/src/sources/Svm.res +14 -10
- package/src/sources/Svm.res.mjs +23 -6
- package/src/sources/SvmHyperSyncClient.res +5 -6
- package/src/sources/SvmHyperSyncSource.res +82 -41
- package/src/sources/SvmHyperSyncSource.res.mjs +86 -41
- package/src/sources/TransactionStore.res +6 -107
- package/src/sources/TransactionStore.res.mjs +5 -86
- package/svm.schema.json +19 -0
|
@@ -35,8 +35,7 @@ let subscribe = (~hyperSyncUrl, ~apiToken, ~chainId, ~onHeight: int => unit): (u
|
|
|
35
35
|
and scheduleReconnect = () => {
|
|
36
36
|
// Clear any pending stale/reconnect timeout to avoid double reconnect
|
|
37
37
|
timeoutIdRef.contents->clearTimeout
|
|
38
|
-
let delay =
|
|
39
|
-
baseDuration * Math.pow(2.0, ~exp=errorCount.contents->Int.toFloat)->Float.toInt
|
|
38
|
+
let delay = baseDuration * Math.pow(2.0, ~exp=errorCount.contents->Int.toFloat)->Float.toInt
|
|
40
39
|
timeoutIdRef := setTimeout(() => refreshEventSource(), Pervasives.min(delay, 60_000))
|
|
41
40
|
}
|
|
42
41
|
and refreshEventSource = () => {
|
|
@@ -102,12 +101,6 @@ let subscribe = (~hyperSyncUrl, ~apiToken, ~chainId, ~onHeight: int => unit): (u
|
|
|
102
101
|
es->EventSource.addEventListener("height", event => {
|
|
103
102
|
switch event.data->Int.fromString {
|
|
104
103
|
| Some(height) =>
|
|
105
|
-
// Track the SSE height event
|
|
106
|
-
Prometheus.SourceRequestCount.increment(
|
|
107
|
-
~sourceName="HyperSync",
|
|
108
|
-
~chainId,
|
|
109
|
-
~method="heightStream",
|
|
110
|
-
)
|
|
111
104
|
// On a successful height event, update the timeout
|
|
112
105
|
updateTimeoutId()
|
|
113
106
|
// Call the callback with the new height
|
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
import * as Utils from "../Utils.res.mjs";
|
|
4
4
|
import * as Logging from "../Logging.res.mjs";
|
|
5
|
-
import * as Prometheus from "../Prometheus.res.mjs";
|
|
6
5
|
import * as Stdlib_Int from "@rescript/runtime/lib/es6/Stdlib_Int.js";
|
|
7
6
|
import * as Eventsource from "eventsource";
|
|
8
7
|
import * as Primitive_int from "@rescript/runtime/lib/es6/Primitive_int.js";
|
|
@@ -83,7 +82,6 @@ function subscribe(hyperSyncUrl, apiToken, chainId, onHeight) {
|
|
|
83
82
|
es$1.addEventListener("height", event => {
|
|
84
83
|
let height = Stdlib_Int.fromString(event.data, undefined);
|
|
85
84
|
if (height !== undefined) {
|
|
86
|
-
Prometheus.SourceRequestCount.increment("HyperSync", chainId, "heightStream");
|
|
87
85
|
updateTimeoutId();
|
|
88
86
|
return onHeight(height);
|
|
89
87
|
} else {
|
|
@@ -7,26 +7,23 @@ type selectionConfig = {
|
|
|
7
7
|
fieldSelection: HyperSyncClient.QueryTypes.fieldSelection,
|
|
8
8
|
}
|
|
9
9
|
|
|
10
|
-
let getSelectionConfig = (selection: FetchState.selection
|
|
10
|
+
let getSelectionConfig = (selection: FetchState.selection) => {
|
|
11
11
|
let capitalizedBlockFields = Utils.Set.make()
|
|
12
12
|
let capitalizedTransactionFields = Utils.Set.make()
|
|
13
13
|
|
|
14
|
-
let
|
|
15
|
-
let
|
|
16
|
-
let dynamicWildcardEventFiltersByContract = Dict.make()
|
|
14
|
+
let topicSelectionsByContract = Dict.make()
|
|
15
|
+
let wildcardTopicSelectionsByContract = Dict.make()
|
|
17
16
|
let noAddressesTopicSelections = []
|
|
18
17
|
let contractNames = Utils.Set.make()
|
|
19
18
|
|
|
20
|
-
selection.
|
|
21
|
-
->(Utils.magic: array<Internal.
|
|
22
|
-
->Array.forEach(
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
selectedBlockFields,
|
|
27
|
-
|
|
28
|
-
isWildcard,
|
|
29
|
-
}) => {
|
|
19
|
+
selection.onEventRegistrations
|
|
20
|
+
->(Utils.magic: array<Internal.onEventRegistration> => array<Internal.evmOnEventRegistration>)
|
|
21
|
+
->Array.forEach(reg => {
|
|
22
|
+
let eventConfig =
|
|
23
|
+
reg.eventConfig->(Utils.magic: Internal.eventConfig => Internal.evmEventConfig)
|
|
24
|
+
let contractName = eventConfig.contractName
|
|
25
|
+
let {selectedBlockFields, selectedTransactionFields} = eventConfig
|
|
26
|
+
let {dependsOnAddresses, resolvedWhere, isWildcard} = reg
|
|
30
27
|
selectedBlockFields
|
|
31
28
|
->Utils.Set.toArray
|
|
32
29
|
->Array.forEach(name =>
|
|
@@ -46,24 +43,16 @@ let getSelectionConfig = (selection: FetchState.selection, ~chain) => {
|
|
|
46
43
|
}
|
|
47
44
|
})
|
|
48
45
|
|
|
49
|
-
let eventFilters = getEventFiltersOrThrow(chain)
|
|
50
46
|
if dependsOnAddresses {
|
|
51
47
|
let _ = contractNames->Utils.Set.add(contractName)
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
(
|
|
57
|
-
isWildcard ? dynamicWildcardEventFiltersByContract : dynamicEventFiltersByContract
|
|
58
|
-
)->Utils.Dict.push(contractName, fn)
|
|
59
|
-
}
|
|
48
|
+
|
|
49
|
+
(
|
|
50
|
+
isWildcard ? wildcardTopicSelectionsByContract : topicSelectionsByContract
|
|
51
|
+
)->Utils.Dict.pushMany(contractName, resolvedWhere.topicSelections)
|
|
60
52
|
} else {
|
|
61
53
|
noAddressesTopicSelections
|
|
62
54
|
->Array.pushMany(
|
|
63
|
-
|
|
64
|
-
| Static(s) => s
|
|
65
|
-
| Dynamic(fn) => fn([])
|
|
66
|
-
},
|
|
55
|
+
resolvedWhere.topicSelections->LogSelection.materializeTopicSelections(~addresses=[]),
|
|
67
56
|
)
|
|
68
57
|
->ignore
|
|
69
58
|
}
|
|
@@ -94,27 +83,26 @@ let getSelectionConfig = (selection: FetchState.selection, ~chain) => {
|
|
|
94
83
|
| None
|
|
95
84
|
| Some([]) => ()
|
|
96
85
|
| Some(addresses) =>
|
|
97
|
-
switch
|
|
86
|
+
switch topicSelectionsByContract->Utils.Dict.dangerouslyGetNonOption(contractName) {
|
|
98
87
|
| None => ()
|
|
99
88
|
| Some(topicSelections) =>
|
|
100
|
-
logSelections->Array.push(LogSelection.make(~addresses, ~topicSelections))
|
|
101
|
-
}
|
|
102
|
-
switch dynamicEventFiltersByContract->Utils.Dict.dangerouslyGetNonOption(contractName) {
|
|
103
|
-
| None => ()
|
|
104
|
-
| Some(fns) =>
|
|
105
89
|
logSelections->Array.push(
|
|
106
|
-
LogSelection.make(
|
|
90
|
+
LogSelection.make(
|
|
91
|
+
~addresses,
|
|
92
|
+
~topicSelections=topicSelections->LogSelection.materializeTopicSelections(~addresses),
|
|
93
|
+
),
|
|
107
94
|
)
|
|
108
95
|
}
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
96
|
+
// Wildcard events that filter an indexed param by registered addresses:
|
|
97
|
+
// the addresses fold into the topics, so the query itself stays
|
|
98
|
+
// address-unbound.
|
|
99
|
+
switch wildcardTopicSelectionsByContract->Utils.Dict.dangerouslyGetNonOption(contractName) {
|
|
112
100
|
| None => ()
|
|
113
|
-
| Some(
|
|
101
|
+
| Some(topicSelections) =>
|
|
114
102
|
logSelections->Array.push(
|
|
115
103
|
LogSelection.make(
|
|
116
104
|
~addresses=[],
|
|
117
|
-
~topicSelections=
|
|
105
|
+
~topicSelections=topicSelections->LogSelection.materializeTopicSelections(~addresses),
|
|
118
106
|
),
|
|
119
107
|
)
|
|
120
108
|
}
|
|
@@ -129,8 +117,7 @@ let getSelectionConfig = (selection: FetchState.selection, ~chain) => {
|
|
|
129
117
|
}
|
|
130
118
|
}
|
|
131
119
|
|
|
132
|
-
let memoGetSelectionConfig = (
|
|
133
|
-
Utils.WeakMap.memoize(selection => selection->getSelectionConfig(~chain))
|
|
120
|
+
let memoGetSelectionConfig = () => Utils.WeakMap.memoize(getSelectionConfig)
|
|
134
121
|
|
|
135
122
|
// Surfaced by HyperSyncClient.getHeight (Rust) when HyperSync rejects the API
|
|
136
123
|
// token. The corrupted-token test feeds the real server error through this
|
|
@@ -141,7 +128,7 @@ type options = {
|
|
|
141
128
|
chain: ChainMap.Chain.t,
|
|
142
129
|
endpointUrl: string,
|
|
143
130
|
allEventParams: array<HyperSyncClient.Decoder.eventParamsInput>,
|
|
144
|
-
eventRouter: EventRouter.t<Internal.
|
|
131
|
+
eventRouter: EventRouter.t<Internal.evmOnEventRegistration>,
|
|
145
132
|
apiToken: option<string>,
|
|
146
133
|
clientTimeoutMillis: int,
|
|
147
134
|
lowercaseAddresses: bool,
|
|
@@ -166,7 +153,7 @@ let make = (
|
|
|
166
153
|
): t => {
|
|
167
154
|
let name = "HyperSync"
|
|
168
155
|
|
|
169
|
-
let getSelectionConfig = memoGetSelectionConfig(
|
|
156
|
+
let getSelectionConfig = memoGetSelectionConfig()
|
|
170
157
|
|
|
171
158
|
let apiToken = switch apiToken {
|
|
172
159
|
| Some(token) => token
|
|
@@ -197,27 +184,25 @@ Learn more or get a free Envio API token at: https://envio.dev/app/api-tokens`)
|
|
|
197
184
|
|
|
198
185
|
let makeEventBatchQueueItem = (
|
|
199
186
|
item: HyperSyncClient.EventItems.item,
|
|
200
|
-
~block: HyperSyncClient.ResponseTypes.block,
|
|
201
187
|
~params: Internal.eventParams,
|
|
202
|
-
~
|
|
188
|
+
~onEventRegistration: Internal.evmOnEventRegistration,
|
|
203
189
|
): Internal.item => {
|
|
204
190
|
let {transactionIndex, logIndex, srcAddress} = item
|
|
205
191
|
let chainId = chain->ChainMap.Chain.toChainId
|
|
206
192
|
|
|
207
193
|
Internal.Event({
|
|
208
|
-
|
|
209
|
-
timestamp: block.timestamp->Option.getUnsafe,
|
|
194
|
+
onEventRegistration: (onEventRegistration :> Internal.onEventRegistration),
|
|
210
195
|
chain,
|
|
211
196
|
blockNumber: item.blockNumber,
|
|
212
|
-
blockHash: block.hash->Option.getUnsafe,
|
|
213
197
|
logIndex,
|
|
214
198
|
transactionIndex,
|
|
199
|
+
// `block` and `transaction` are omitted; they're materialised from the
|
|
200
|
+
// per-chain stores onto the payload at batch prep.
|
|
215
201
|
payload: {
|
|
216
|
-
contractName: eventConfig.contractName,
|
|
217
|
-
eventName: eventConfig.name,
|
|
202
|
+
contractName: onEventRegistration.eventConfig.contractName,
|
|
203
|
+
eventName: onEventRegistration.eventConfig.name,
|
|
218
204
|
chainId,
|
|
219
205
|
params,
|
|
220
|
-
block: block->(Utils.magic: HyperSyncClient.ResponseTypes.block => Internal.eventBlock),
|
|
221
206
|
srcAddress,
|
|
222
207
|
logIndex,
|
|
223
208
|
}->Evm.fromPayload,
|
|
@@ -248,11 +233,6 @@ Learn more or get a free Envio API token at: https://envio.dev/app/api-tokens`)
|
|
|
248
233
|
let startFetchingBatchTimeRef = Performance.now()
|
|
249
234
|
|
|
250
235
|
//fetch batch
|
|
251
|
-
Prometheus.SourceRequestCount.increment(
|
|
252
|
-
~sourceName=name,
|
|
253
|
-
~chainId=chain->ChainMap.Chain.toChainId,
|
|
254
|
-
~method="getLogs",
|
|
255
|
-
)
|
|
256
236
|
let pageUnsafe = try await HyperSync.GetLogs.query(
|
|
257
237
|
~client,
|
|
258
238
|
~fromBlock,
|
|
@@ -307,6 +287,7 @@ Learn more or get a free Envio API token at: https://envio.dev/app/api-tokens`)
|
|
|
307
287
|
}
|
|
308
288
|
|
|
309
289
|
let pageFetchTime = startFetchingBatchTimeRef->Performance.secondsSince
|
|
290
|
+
let requestStats = [{Source.method: "getLogs", seconds: pageFetchTime}]
|
|
310
291
|
|
|
311
292
|
//set height and next from block
|
|
312
293
|
let knownHeight = pageUnsafe.archiveHeight
|
|
@@ -321,28 +302,25 @@ Learn more or get a free Envio API token at: https://envio.dev/app/api-tokens`)
|
|
|
321
302
|
//Parse page items into queue items
|
|
322
303
|
let parsedQueueItems = []
|
|
323
304
|
|
|
324
|
-
//
|
|
305
|
+
// Block headers are returned once per number; items reference them by blockNumber.
|
|
325
306
|
let blocksByNumber = Utils.Map.make()
|
|
326
307
|
pageUnsafe.blocks->Array.forEach(block => {
|
|
327
|
-
|
|
328
|
-
| Some(number) => blocksByNumber->Utils.Map.set(number, block)->ignore
|
|
329
|
-
| None => ()
|
|
330
|
-
}
|
|
308
|
+
blocksByNumber->Utils.Map.set(block.number, block)->ignore
|
|
331
309
|
})
|
|
332
310
|
let getBlock = blockNumber => blocksByNumber->Utils.Map.unsafeGet(blockNumber)
|
|
333
311
|
|
|
334
312
|
let handleDecodeFailure = (
|
|
335
|
-
~
|
|
313
|
+
~onEventRegistration: Internal.evmOnEventRegistration,
|
|
336
314
|
~logIndex,
|
|
337
315
|
~blockNumber,
|
|
338
316
|
~chainId,
|
|
339
317
|
~exn,
|
|
340
318
|
) => {
|
|
341
|
-
if !
|
|
319
|
+
if !onEventRegistration.isWildcard {
|
|
342
320
|
//Wildcard events can be parsed as undefined if the number of topics
|
|
343
321
|
//don't match the event with the given topic0
|
|
344
322
|
//Non wildcard events should be expected to be parsed
|
|
345
|
-
let msg = `Event ${eventConfig.name} was unexpectedly parsed as undefined`
|
|
323
|
+
let msg = `Event ${onEventRegistration.eventConfig.name} was unexpectedly parsed as undefined`
|
|
346
324
|
let logger = Logging.createChildFrom(
|
|
347
325
|
~logger,
|
|
348
326
|
~params={
|
|
@@ -370,19 +348,17 @@ Learn more or get a free Envio API token at: https://envio.dev/app/api-tokens`)
|
|
|
370
348
|
|
|
371
349
|
switch maybeEventConfig {
|
|
372
350
|
| None => () //ignore events that aren't registered
|
|
373
|
-
| Some(
|
|
351
|
+
| Some(onEventRegistration) =>
|
|
374
352
|
switch item.params
|
|
375
353
|
->Nullable.toOption
|
|
376
|
-
->Option.flatMap(Dict.get(_, eventConfig.contractName)) {
|
|
354
|
+
->Option.flatMap(Dict.get(_, onEventRegistration.eventConfig.contractName)) {
|
|
377
355
|
| Some(params) =>
|
|
378
356
|
parsedQueueItems
|
|
379
|
-
->Array.push(
|
|
380
|
-
makeEventBatchQueueItem(item, ~block=getBlock(item.blockNumber), ~params, ~eventConfig),
|
|
381
|
-
)
|
|
357
|
+
->Array.push(makeEventBatchQueueItem(item, ~params, ~onEventRegistration))
|
|
382
358
|
->ignore
|
|
383
359
|
| None =>
|
|
384
360
|
handleDecodeFailure(
|
|
385
|
-
~
|
|
361
|
+
~onEventRegistration,
|
|
386
362
|
~logIndex=item.logIndex,
|
|
387
363
|
~blockNumber=item.blockNumber,
|
|
388
364
|
~chainId,
|
|
@@ -400,11 +376,9 @@ Learn more or get a free Envio API token at: https://envio.dev/app/api-tokens`)
|
|
|
400
376
|
// detection notices same-block-number-different-hash collisions itself.
|
|
401
377
|
let blockHashes = []
|
|
402
378
|
pageUnsafe.blocks->Array.forEach(block => {
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
| _ => ()
|
|
407
|
-
}
|
|
379
|
+
blockHashes
|
|
380
|
+
->Array.push({ReorgDetection.blockNumber: block.number, blockHash: block.hash})
|
|
381
|
+
->ignore
|
|
408
382
|
})
|
|
409
383
|
switch pageUnsafe.rollbackGuard {
|
|
410
384
|
| None => ()
|
|
@@ -428,7 +402,7 @@ Learn more or get a free Envio API token at: https://envio.dev/app/api-tokens`)
|
|
|
428
402
|
| None =>
|
|
429
403
|
switch pageUnsafe.items->Array.get(pageUnsafe.items->Array.length - 1) {
|
|
430
404
|
| Some(item) if item.blockNumber == heighestBlockQueried =>
|
|
431
|
-
getBlock(item.blockNumber).timestamp
|
|
405
|
+
getBlock(item.blockNumber).timestamp
|
|
432
406
|
| _ => 0
|
|
433
407
|
}
|
|
434
408
|
}
|
|
@@ -445,11 +419,13 @@ Learn more or get a free Envio API token at: https://envio.dev/app/api-tokens`)
|
|
|
445
419
|
latestFetchedBlockTimestamp,
|
|
446
420
|
parsedQueueItems,
|
|
447
421
|
transactionStore: Some(pageUnsafe.transactionStore),
|
|
422
|
+
blockStore: Some(pageUnsafe.blockStore),
|
|
448
423
|
latestFetchedBlockNumber: heighestBlockQueried,
|
|
449
424
|
stats,
|
|
450
425
|
knownHeight,
|
|
451
426
|
blockHashes,
|
|
452
427
|
fromBlockQueried: fromBlock,
|
|
428
|
+
requestStats,
|
|
453
429
|
}
|
|
454
430
|
}
|
|
455
431
|
|
|
@@ -460,7 +436,10 @@ Learn more or get a free Envio API token at: https://envio.dev/app/api-tokens`)
|
|
|
460
436
|
~sourceName=name,
|
|
461
437
|
~chainId=chain->ChainMap.Chain.toChainId,
|
|
462
438
|
~logger,
|
|
463
|
-
)->Promise.thenResolve(
|
|
439
|
+
)->Promise.thenResolve(((queryRes, requestStats)) => {
|
|
440
|
+
Source.result: queryRes->HyperSync.mapExn,
|
|
441
|
+
requestStats,
|
|
442
|
+
})
|
|
464
443
|
|
|
465
444
|
{
|
|
466
445
|
name,
|
|
@@ -471,7 +450,7 @@ Learn more or get a free Envio API token at: https://envio.dev/app/api-tokens`)
|
|
|
471
450
|
getBlockHashes,
|
|
472
451
|
getHeightOrThrow: async () => {
|
|
473
452
|
let timerRef = Performance.now()
|
|
474
|
-
let
|
|
453
|
+
let height = try {
|
|
475
454
|
await client.getHeight()
|
|
476
455
|
} catch {
|
|
477
456
|
| JsExn(e) =>
|
|
@@ -485,18 +464,7 @@ Learn more or get a free Envio API token at: https://envio.dev/app/api-tokens`)
|
|
|
485
464
|
}
|
|
486
465
|
}
|
|
487
466
|
let seconds = timerRef->Performance.secondsSince
|
|
488
|
-
|
|
489
|
-
~sourceName=name,
|
|
490
|
-
~chainId=chain->ChainMap.Chain.toChainId,
|
|
491
|
-
~method="getHeight",
|
|
492
|
-
)
|
|
493
|
-
Prometheus.SourceRequestCount.addSeconds(
|
|
494
|
-
~sourceName=name,
|
|
495
|
-
~chainId=chain->ChainMap.Chain.toChainId,
|
|
496
|
-
~method="getHeight",
|
|
497
|
-
~seconds,
|
|
498
|
-
)
|
|
499
|
-
result
|
|
467
|
+
{height, requestStats: [{method: "getHeight", seconds}]}
|
|
500
468
|
},
|
|
501
469
|
getItemsOrThrow,
|
|
502
470
|
createHeightSubscription: (~onHeight) =>
|
|
@@ -4,7 +4,6 @@ import * as Utils from "../Utils.res.mjs";
|
|
|
4
4
|
import * as Source from "./Source.res.mjs";
|
|
5
5
|
import * as Logging from "../Logging.res.mjs";
|
|
6
6
|
import * as HyperSync from "./HyperSync.res.mjs";
|
|
7
|
-
import * as Prometheus from "../Prometheus.res.mjs";
|
|
8
7
|
import * as EventRouter from "./EventRouter.res.mjs";
|
|
9
8
|
import * as Performance from "../bindings/Performance.res.mjs";
|
|
10
9
|
import * as LogSelection from "../LogSelection.res.mjs";
|
|
@@ -17,37 +16,33 @@ import * as Primitive_option from "@rescript/runtime/lib/es6/Primitive_option.js
|
|
|
17
16
|
import * as Primitive_exceptions from "@rescript/runtime/lib/es6/Primitive_exceptions.js";
|
|
18
17
|
import * as HyperSyncHeightStream from "./HyperSyncHeightStream.res.mjs";
|
|
19
18
|
|
|
20
|
-
function getSelectionConfig(selection
|
|
19
|
+
function getSelectionConfig(selection) {
|
|
21
20
|
let capitalizedBlockFields = new Set();
|
|
22
21
|
let capitalizedTransactionFields = new Set();
|
|
23
|
-
let
|
|
24
|
-
let
|
|
25
|
-
let dynamicWildcardEventFiltersByContract = {};
|
|
22
|
+
let topicSelectionsByContract = {};
|
|
23
|
+
let wildcardTopicSelectionsByContract = {};
|
|
26
24
|
let noAddressesTopicSelections = [];
|
|
27
25
|
let contractNames = new Set();
|
|
28
|
-
selection.
|
|
29
|
-
let
|
|
30
|
-
|
|
26
|
+
selection.onEventRegistrations.forEach(reg => {
|
|
27
|
+
let eventConfig = reg.eventConfig;
|
|
28
|
+
let contractName = eventConfig.contractName;
|
|
29
|
+
let resolvedWhere = reg.resolvedWhere;
|
|
30
|
+
Array.from(eventConfig.selectedBlockFields).forEach(name => {
|
|
31
31
|
capitalizedBlockFields.add(Utils.$$String.capitalize(name));
|
|
32
32
|
});
|
|
33
|
-
Array.from(
|
|
33
|
+
Array.from(eventConfig.selectedTransactionFields).forEach(name => {
|
|
34
34
|
if (name !== "transactionIndex") {
|
|
35
35
|
capitalizedTransactionFields.add(Utils.$$String.capitalize(name));
|
|
36
36
|
return;
|
|
37
37
|
}
|
|
38
38
|
});
|
|
39
|
-
|
|
40
|
-
if (param.dependsOnAddresses) {
|
|
39
|
+
if (reg.dependsOnAddresses) {
|
|
41
40
|
contractNames.add(contractName);
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
}
|
|
41
|
+
return Utils.Dict.pushMany(reg.isWildcard ? wildcardTopicSelectionsByContract : topicSelectionsByContract, contractName, resolvedWhere.topicSelections);
|
|
42
|
+
} else {
|
|
43
|
+
noAddressesTopicSelections.push(...LogSelection.materializeTopicSelections(resolvedWhere.topicSelections, []));
|
|
44
|
+
return;
|
|
47
45
|
}
|
|
48
|
-
let tmp;
|
|
49
|
-
tmp = eventFilters.TAG === "Static" ? eventFilters._0 : eventFilters._0([]);
|
|
50
|
-
noAddressesTopicSelections.push(...tmp);
|
|
51
46
|
});
|
|
52
47
|
let fieldSelection_block = Array.from(capitalizedBlockFields);
|
|
53
48
|
let fieldSelection_transaction = Array.from(capitalizedTransactionFields);
|
|
@@ -79,17 +74,13 @@ function getSelectionConfig(selection, chain) {
|
|
|
79
74
|
if (addresses.length === 0) {
|
|
80
75
|
return;
|
|
81
76
|
}
|
|
82
|
-
let topicSelections =
|
|
77
|
+
let topicSelections = topicSelectionsByContract[contractName];
|
|
83
78
|
if (topicSelections !== undefined) {
|
|
84
|
-
logSelections.push(LogSelection.make(addresses, topicSelections));
|
|
79
|
+
logSelections.push(LogSelection.make(addresses, LogSelection.materializeTopicSelections(topicSelections, addresses)));
|
|
85
80
|
}
|
|
86
|
-
let
|
|
87
|
-
if (
|
|
88
|
-
logSelections.push(LogSelection.make(
|
|
89
|
-
}
|
|
90
|
-
let fns$1 = dynamicWildcardEventFiltersByContract[contractName];
|
|
91
|
-
if (fns$1 !== undefined) {
|
|
92
|
-
logSelections.push(LogSelection.make([], fns$1.flatMap(fn => fn(addresses))));
|
|
81
|
+
let topicSelections$1 = wildcardTopicSelectionsByContract[contractName];
|
|
82
|
+
if (topicSelections$1 !== undefined) {
|
|
83
|
+
logSelections.push(LogSelection.make([], LogSelection.materializeTopicSelections(topicSelections$1, addresses)));
|
|
93
84
|
return;
|
|
94
85
|
}
|
|
95
86
|
});
|
|
@@ -101,8 +92,8 @@ function getSelectionConfig(selection, chain) {
|
|
|
101
92
|
};
|
|
102
93
|
}
|
|
103
94
|
|
|
104
|
-
function memoGetSelectionConfig(
|
|
105
|
-
return Utils.$$WeakMap.memoize(
|
|
95
|
+
function memoGetSelectionConfig() {
|
|
96
|
+
return Utils.$$WeakMap.memoize(getSelectionConfig);
|
|
106
97
|
}
|
|
107
98
|
|
|
108
99
|
function isUnauthorizedError(message) {
|
|
@@ -115,7 +106,7 @@ function make(param) {
|
|
|
115
106
|
let endpointUrl = param.endpointUrl;
|
|
116
107
|
let chain = param.chain;
|
|
117
108
|
let name = "HyperSync";
|
|
118
|
-
let getSelectionConfig =
|
|
109
|
+
let getSelectionConfig$1 = Utils.$$WeakMap.memoize(getSelectionConfig);
|
|
119
110
|
let apiToken$1 = apiToken !== undefined ? apiToken : Stdlib_JsError.throwWithMessage(`An Envio API token is required for using HyperSync as a data-source.
|
|
120
111
|
Set the ENVIO_API_TOKEN environment variable in your .env file.
|
|
121
112
|
Learn more or get a free Envio API token at: https://envio.dev/app/api-tokens`);
|
|
@@ -127,31 +118,28 @@ Learn more or get a free Envio API token at: https://envio.dev/app/api-tokens`);
|
|
|
127
118
|
client = ErrorHandling.mkLogAndRaise(undefined, "Failed to instantiate the hypersync client, please double check your ABI", exn);
|
|
128
119
|
}
|
|
129
120
|
let UndefinedValue = /* @__PURE__ */Primitive_exceptions.create("UndefinedValue");
|
|
130
|
-
let makeEventBatchQueueItem = (item,
|
|
121
|
+
let makeEventBatchQueueItem = (item, params, onEventRegistration) => {
|
|
131
122
|
let logIndex = item.logIndex;
|
|
132
123
|
return {
|
|
133
124
|
kind: 0,
|
|
134
|
-
|
|
135
|
-
timestamp: block.timestamp,
|
|
125
|
+
onEventRegistration: onEventRegistration,
|
|
136
126
|
chain: chain,
|
|
137
127
|
blockNumber: item.blockNumber,
|
|
138
|
-
blockHash: block.hash,
|
|
139
128
|
logIndex: logIndex,
|
|
140
129
|
transactionIndex: item.transactionIndex,
|
|
141
130
|
payload: {
|
|
142
|
-
contractName: eventConfig.contractName,
|
|
143
|
-
eventName: eventConfig.name,
|
|
131
|
+
contractName: onEventRegistration.eventConfig.contractName,
|
|
132
|
+
eventName: onEventRegistration.eventConfig.name,
|
|
144
133
|
params: params,
|
|
145
134
|
chainId: chain,
|
|
146
135
|
srcAddress: item.srcAddress,
|
|
147
|
-
logIndex: logIndex
|
|
148
|
-
block: block
|
|
136
|
+
logIndex: logIndex
|
|
149
137
|
}
|
|
150
138
|
};
|
|
151
139
|
};
|
|
152
140
|
let getItemsOrThrow = async (fromBlock, toBlock, addressesByContractName, contractNameByAddress, knownHeight, param, selection, itemsTarget, retry, logger) => {
|
|
153
141
|
let totalTimeRef = Performance.now();
|
|
154
|
-
let selectionConfig = getSelectionConfig(selection);
|
|
142
|
+
let selectionConfig = getSelectionConfig$1(selection);
|
|
155
143
|
let logSelections;
|
|
156
144
|
try {
|
|
157
145
|
logSelections = selectionConfig.getLogSelectionOrThrow(addressesByContractName);
|
|
@@ -160,7 +148,6 @@ Learn more or get a free Envio API token at: https://envio.dev/app/api-tokens`);
|
|
|
160
148
|
logSelections = ErrorHandling.mkLogAndRaise(logger, "Failed getting log selection for the query", exn);
|
|
161
149
|
}
|
|
162
150
|
let startFetchingBatchTimeRef = Performance.now();
|
|
163
|
-
Prometheus.SourceRequestCount.increment(name, chain, "getLogs");
|
|
164
151
|
let pageUnsafe;
|
|
165
152
|
try {
|
|
166
153
|
pageUnsafe = await HyperSync.GetLogs.query(client, fromBlock, toBlock, logSelections, selectionConfig.fieldSelection, itemsTarget);
|
|
@@ -212,26 +199,26 @@ Learn more or get a free Envio API token at: https://envio.dev/app/api-tokens`);
|
|
|
212
199
|
};
|
|
213
200
|
}
|
|
214
201
|
let pageFetchTime = Performance.secondsSince(startFetchingBatchTimeRef);
|
|
202
|
+
let requestStats = [{
|
|
203
|
+
method: "getLogs",
|
|
204
|
+
seconds: pageFetchTime
|
|
205
|
+
}];
|
|
215
206
|
let knownHeight$1 = pageUnsafe.archiveHeight;
|
|
216
207
|
let heighestBlockQueried = pageUnsafe.nextBlock - 1 | 0;
|
|
217
208
|
let parsingTimeRef = Performance.now();
|
|
218
209
|
let parsedQueueItems = [];
|
|
219
210
|
let blocksByNumber = new Map();
|
|
220
211
|
pageUnsafe.blocks.forEach(block => {
|
|
221
|
-
|
|
222
|
-
if (number !== undefined) {
|
|
223
|
-
blocksByNumber.set(number, block);
|
|
224
|
-
return;
|
|
225
|
-
}
|
|
212
|
+
blocksByNumber.set(block.number, block);
|
|
226
213
|
});
|
|
227
214
|
pageUnsafe.items.forEach(item => {
|
|
228
215
|
let maybeEventConfig = EventRouter.get(eventRouter, EventRouter.getEvmEventId(item.topic0, item.topicCount), item.srcAddress, contractNameByAddress);
|
|
229
216
|
if (maybeEventConfig === undefined) {
|
|
230
217
|
return;
|
|
231
218
|
}
|
|
232
|
-
let params = Stdlib_Option.flatMap(Primitive_option.fromNullable(item.params), __x => __x[maybeEventConfig.contractName]);
|
|
219
|
+
let params = Stdlib_Option.flatMap(Primitive_option.fromNullable(item.params), __x => __x[maybeEventConfig.eventConfig.contractName]);
|
|
233
220
|
if (params !== undefined) {
|
|
234
|
-
parsedQueueItems.push(makeEventBatchQueueItem(item,
|
|
221
|
+
parsedQueueItems.push(makeEventBatchQueueItem(item, Primitive_option.valFromOption(params), maybeEventConfig));
|
|
235
222
|
return;
|
|
236
223
|
} else {
|
|
237
224
|
let logIndex = item.logIndex;
|
|
@@ -242,7 +229,7 @@ Learn more or get a free Envio API token at: https://envio.dev/app/api-tokens`);
|
|
|
242
229
|
if (maybeEventConfig.isWildcard) {
|
|
243
230
|
return;
|
|
244
231
|
}
|
|
245
|
-
let msg = `Event ` + maybeEventConfig.name + ` was unexpectedly parsed as undefined`;
|
|
232
|
+
let msg = `Event ` + maybeEventConfig.eventConfig.name + ` was unexpectedly parsed as undefined`;
|
|
246
233
|
let logger$1 = Logging.createChildFrom(logger, {
|
|
247
234
|
chainId: chain,
|
|
248
235
|
blockNumber: blockNumber,
|
|
@@ -255,15 +242,10 @@ Learn more or get a free Envio API token at: https://envio.dev/app/api-tokens`);
|
|
|
255
242
|
let parsingTimeElapsed = Performance.secondsSince(parsingTimeRef);
|
|
256
243
|
let blockHashes = [];
|
|
257
244
|
pageUnsafe.blocks.forEach(block => {
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
blockHash: match$1,
|
|
263
|
-
blockNumber: match
|
|
264
|
-
});
|
|
265
|
-
return;
|
|
266
|
-
}
|
|
245
|
+
blockHashes.push({
|
|
246
|
+
blockHash: block.hash,
|
|
247
|
+
blockNumber: block.number
|
|
248
|
+
});
|
|
267
249
|
});
|
|
268
250
|
let match = pageUnsafe.rollbackGuard;
|
|
269
251
|
if (match !== undefined) {
|
|
@@ -297,13 +279,18 @@ Learn more or get a free Envio API token at: https://envio.dev/app/api-tokens`);
|
|
|
297
279
|
blockHashes: blockHashes,
|
|
298
280
|
parsedQueueItems: parsedQueueItems,
|
|
299
281
|
transactionStore: Primitive_option.some(pageUnsafe.transactionStore),
|
|
282
|
+
blockStore: Primitive_option.some(pageUnsafe.blockStore),
|
|
300
283
|
fromBlockQueried: fromBlock,
|
|
301
284
|
latestFetchedBlockNumber: heighestBlockQueried,
|
|
302
285
|
latestFetchedBlockTimestamp: latestFetchedBlockTimestamp,
|
|
303
|
-
stats: stats
|
|
286
|
+
stats: stats,
|
|
287
|
+
requestStats: requestStats
|
|
304
288
|
};
|
|
305
289
|
};
|
|
306
|
-
let getBlockHashes = (blockNumbers, logger) => HyperSync.queryBlockDataMulti(client, blockNumbers, name, chain, logger).then(
|
|
290
|
+
let getBlockHashes = (blockNumbers, logger) => HyperSync.queryBlockDataMulti(client, blockNumbers, name, chain, logger).then(param => ({
|
|
291
|
+
result: HyperSync.mapExn(param[0]),
|
|
292
|
+
requestStats: param[1]
|
|
293
|
+
}));
|
|
307
294
|
return {
|
|
308
295
|
name: name,
|
|
309
296
|
sourceFor: "Sync",
|
|
@@ -313,9 +300,9 @@ Learn more or get a free Envio API token at: https://envio.dev/app/api-tokens`);
|
|
|
313
300
|
getBlockHashes: getBlockHashes,
|
|
314
301
|
getHeightOrThrow: async () => {
|
|
315
302
|
let timerRef = Performance.now();
|
|
316
|
-
let
|
|
303
|
+
let height;
|
|
317
304
|
try {
|
|
318
|
-
|
|
305
|
+
height = await client.getHeight();
|
|
319
306
|
} catch (raw_e) {
|
|
320
307
|
let e = Primitive_exceptions.internalToException(raw_e);
|
|
321
308
|
if (e.RE_EXN_ID === "JsExn") {
|
|
@@ -325,7 +312,7 @@ Learn more or get a free Envio API token at: https://envio.dev/app/api-tokens`);
|
|
|
325
312
|
if (message.includes("401 Unauthorized")) {
|
|
326
313
|
Logging.error(`Your ENVIO_API_TOKEN was rejected by HyperSync (401 Unauthorized). The indexer will not be able to fetch events. Update the token and try again using 'envio start' or 'envio dev'. For more info: https://docs.envio.dev/docs/HyperSync/api-tokens`);
|
|
327
314
|
await new Promise((param, param$1) => {});
|
|
328
|
-
|
|
315
|
+
height = 0;
|
|
329
316
|
} else {
|
|
330
317
|
throw {
|
|
331
318
|
RE_EXN_ID: "JsExn",
|
|
@@ -345,9 +332,13 @@ Learn more or get a free Envio API token at: https://envio.dev/app/api-tokens`);
|
|
|
345
332
|
}
|
|
346
333
|
}
|
|
347
334
|
let seconds = Performance.secondsSince(timerRef);
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
335
|
+
return {
|
|
336
|
+
height: height,
|
|
337
|
+
requestStats: [{
|
|
338
|
+
method: "getHeight",
|
|
339
|
+
seconds: seconds
|
|
340
|
+
}]
|
|
341
|
+
};
|
|
351
342
|
},
|
|
352
343
|
getItemsOrThrow: getItemsOrThrow,
|
|
353
344
|
createHeightSubscription: onHeight => HyperSyncHeightStream.subscribe(endpointUrl, apiToken$1, chain, onHeight)
|