envio 3.3.0-alpha.9 → 3.3.0
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 +19 -0
- package/licenses/CLA.md +35 -0
- package/licenses/EULA.md +67 -0
- package/licenses/LICENSE.md +45 -0
- package/licenses/README.md +35 -0
- package/package.json +9 -8
- package/src/Batch.res.mjs +1 -1
- package/src/BatchProcessing.res +0 -7
- package/src/BatchProcessing.res.mjs +1 -8
- package/src/ChainFetching.res +30 -18
- package/src/ChainFetching.res.mjs +23 -13
- package/src/ChainState.res +134 -55
- package/src/ChainState.res.mjs +78 -36
- package/src/ChainState.resi +14 -2
- package/src/Config.res +9 -5
- package/src/Config.res.mjs +2 -2
- package/src/Core.res +20 -0
- package/src/Core.res.mjs +12 -0
- package/src/CrossChainState.res +115 -34
- package/src/CrossChainState.res.mjs +37 -14
- package/src/EffectState.res +100 -0
- package/src/EffectState.res.mjs +74 -0
- package/src/EffectState.resi +32 -0
- package/src/Envio.res +25 -7
- package/src/Envio.res.mjs +15 -19
- package/src/EventConfigBuilder.res +21 -46
- package/src/EventConfigBuilder.res.mjs +18 -25
- package/src/EventProcessing.res +8 -5
- package/src/EventProcessing.res.mjs +2 -1
- package/src/FetchState.res +814 -467
- package/src/FetchState.res.mjs +541 -369
- package/src/HandlerRegister.res +3 -1
- package/src/HandlerRegister.res.mjs +3 -2
- package/src/InMemoryStore.res +14 -26
- package/src/InMemoryStore.res.mjs +6 -19
- package/src/IndexerState.res +15 -39
- package/src/IndexerState.res.mjs +18 -29
- package/src/IndexerState.resi +2 -10
- package/src/Internal.res +98 -14
- package/src/Internal.res.mjs +96 -2
- package/src/LoadLayer.res +44 -24
- package/src/LoadLayer.res.mjs +43 -20
- package/src/LoadLayer.resi +1 -0
- package/src/LogSelection.res +0 -62
- package/src/LogSelection.res.mjs +0 -74
- package/src/Metrics.res +1 -1
- package/src/Metrics.res.mjs +1 -1
- package/src/Persistence.res +12 -3
- package/src/PgStorage.res +155 -82
- package/src/PgStorage.res.mjs +130 -77
- package/src/Prometheus.res +20 -10
- package/src/Prometheus.res.mjs +22 -10
- package/src/PruneStaleHistory.res +146 -35
- package/src/PruneStaleHistory.res.mjs +114 -20
- package/src/RawEvent.res +2 -2
- package/src/Rollback.res +32 -13
- package/src/Rollback.res.mjs +24 -11
- package/src/SimulateDeadInputTracker.res +1 -1
- package/src/SimulateItems.res +38 -6
- package/src/SimulateItems.res.mjs +28 -9
- package/src/TestIndexer.res +2 -2
- package/src/TestIndexer.res.mjs +2 -2
- package/src/TopicFilter.res +1 -25
- package/src/TopicFilter.res.mjs +0 -74
- package/src/UserContext.res +62 -23
- package/src/UserContext.res.mjs +26 -6
- package/src/Writing.res +60 -21
- package/src/Writing.res.mjs +27 -9
- package/src/bindings/NodeJs.res +5 -0
- package/src/bindings/Viem.res +0 -5
- package/src/sources/EventRouter.res +0 -21
- package/src/sources/EventRouter.res.mjs +0 -12
- package/src/sources/EvmChain.res +2 -27
- package/src/sources/EvmChain.res.mjs +2 -23
- package/src/sources/EvmRpcClient.res +58 -23
- package/src/sources/EvmRpcClient.res.mjs +11 -5
- package/src/sources/HyperSync.res +9 -38
- package/src/sources/HyperSync.res.mjs +16 -28
- package/src/sources/HyperSync.resi +2 -2
- package/src/sources/HyperSyncClient.res +88 -11
- package/src/sources/HyperSyncClient.res.mjs +39 -6
- package/src/sources/HyperSyncSource.res +18 -199
- package/src/sources/HyperSyncSource.res.mjs +9 -128
- package/src/sources/Rpc.res +0 -32
- package/src/sources/Rpc.res.mjs +1 -46
- package/src/sources/RpcSource.res +129 -522
- package/src/sources/RpcSource.res.mjs +161 -366
- package/src/sources/SimulateSource.res +37 -19
- package/src/sources/SimulateSource.res.mjs +27 -10
- package/src/sources/SourceManager.res +3 -7
- package/src/sources/SourceManager.res.mjs +2 -7
- package/src/sources/SourceManager.resi +0 -2
- package/src/sources/SvmHyperSyncSource.res +13 -3
- package/src/sources/SvmHyperSyncSource.res.mjs +1 -1
|
@@ -229,29 +229,106 @@ type queryResponse = {
|
|
|
229
229
|
rollbackGuard: option<ResponseTypes.rollbackGuard>,
|
|
230
230
|
}
|
|
231
231
|
|
|
232
|
-
module
|
|
233
|
-
|
|
232
|
+
module Registration = {
|
|
233
|
+
// One topic position of the resolved `where`: static topic values, or
|
|
234
|
+
// `None` — the "currently registered addresses of this contract" marker,
|
|
235
|
+
// expanded to padded address topics when Rust builds a query.
|
|
236
|
+
type topicFilterInput = option<array<string>>
|
|
237
|
+
|
|
238
|
+
type topicSelectionInput = {
|
|
239
|
+
topic0: array<string>,
|
|
240
|
+
topic1: topicFilterInput,
|
|
241
|
+
topic2: topicFilterInput,
|
|
242
|
+
topic3: topicFilterInput,
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
// The full per-(event, chain) registration passed to the Rust clients at
|
|
246
|
+
// construction: decode metadata, routing identity, and the fetch state
|
|
247
|
+
// queries are built from.
|
|
248
|
+
type input = {
|
|
249
|
+
// Chain-scoped sequential registration index, echoed back on routed items.
|
|
250
|
+
index: int,
|
|
234
251
|
sighash: string,
|
|
235
252
|
topicCount: int,
|
|
236
253
|
eventName: string,
|
|
237
254
|
contractName: string,
|
|
255
|
+
isWildcard: bool,
|
|
256
|
+
dependsOnAddresses: bool,
|
|
238
257
|
params: array<Internal.paramMeta>,
|
|
258
|
+
topicSelections: array<topicSelectionInput>,
|
|
259
|
+
// Capitalized field names matching the Rust BlockField/TransactionField
|
|
260
|
+
// string enums.
|
|
261
|
+
blockFields: array<string>,
|
|
262
|
+
transactionFields: array<string>,
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
let toTopicFilterInput = (filter: Internal.topicFilter): topicFilterInput =>
|
|
266
|
+
switch filter {
|
|
267
|
+
| Values(values) => Some(values->EvmTypes.Hex.toStrings)
|
|
268
|
+
| ContractAddresses(_) => None
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
let fromOnEventRegistrations = (
|
|
272
|
+
onEventRegistrations: array<Internal.evmOnEventRegistration>,
|
|
273
|
+
): array<input> => {
|
|
274
|
+
onEventRegistrations->Array.map(reg => {
|
|
275
|
+
let event = reg.eventConfig->(Utils.magic: Internal.eventConfig => Internal.evmEventConfig)
|
|
276
|
+
{
|
|
277
|
+
index: reg.index,
|
|
278
|
+
sighash: event.sighash,
|
|
279
|
+
topicCount: event.topicCount,
|
|
280
|
+
eventName: event.name,
|
|
281
|
+
contractName: event.contractName,
|
|
282
|
+
isWildcard: reg.isWildcard,
|
|
283
|
+
dependsOnAddresses: reg.dependsOnAddresses,
|
|
284
|
+
params: event.paramsMetadata,
|
|
285
|
+
topicSelections: reg.resolvedWhere.topicSelections->Array.map((
|
|
286
|
+
ts
|
|
287
|
+
): topicSelectionInput => {
|
|
288
|
+
topic0: ts.topic0->EvmTypes.Hex.toStrings,
|
|
289
|
+
topic1: ts.topic1->toTopicFilterInput,
|
|
290
|
+
topic2: ts.topic2->toTopicFilterInput,
|
|
291
|
+
topic3: ts.topic3->toTopicFilterInput,
|
|
292
|
+
}),
|
|
293
|
+
// Capitalized to match the Rust BlockField/TransactionField string
|
|
294
|
+
// enums.
|
|
295
|
+
blockFields: event.selectedBlockFields
|
|
296
|
+
->Utils.Set.toArray
|
|
297
|
+
->Array.map(name => (name :> string)->Utils.String.capitalize),
|
|
298
|
+
transactionFields: event.selectedTransactionFields
|
|
299
|
+
->Utils.Set.toArray
|
|
300
|
+
->Array.map(name => (name :> string)->Utils.String.capitalize),
|
|
301
|
+
}
|
|
302
|
+
})
|
|
239
303
|
}
|
|
240
304
|
}
|
|
241
305
|
|
|
242
306
|
module EventItems = {
|
|
307
|
+
// The whole per-query input: block range, the partition's registration
|
|
308
|
+
// selection (by id), and its current addresses. Log selections, field
|
|
309
|
+
// selection, and the routing index are derived on the Rust side.
|
|
310
|
+
type query = {
|
|
311
|
+
fromBlock: int,
|
|
312
|
+
// Inclusive; None queries to the end of available data.
|
|
313
|
+
toBlock: option<int>,
|
|
314
|
+
maxNumLogs: int,
|
|
315
|
+
registrationIndexes: array<int>,
|
|
316
|
+
addressesByContractName: dict<array<Address.t>>,
|
|
317
|
+
}
|
|
318
|
+
|
|
243
319
|
type item = {
|
|
244
320
|
logIndex: int,
|
|
245
321
|
srcAddress: Address.t,
|
|
246
|
-
topic0: EvmTypes.Hex.t,
|
|
247
|
-
topicCount: int,
|
|
248
322
|
// Number of the block this log belongs to; the block itself is resolved from
|
|
249
323
|
// `response.blocks`, deduplicated across items sharing a block.
|
|
250
324
|
blockNumber: int,
|
|
251
325
|
// Key (with the block number) into the transaction store; the transaction
|
|
252
326
|
// is resolved from the store on demand.
|
|
253
327
|
transactionIndex: int,
|
|
254
|
-
|
|
328
|
+
// The registration this log routed to, by chain-scoped index. Logs that
|
|
329
|
+
// route to no registration never cross the boundary.
|
|
330
|
+
onEventRegistrationIndex: int,
|
|
331
|
+
params: Internal.eventParams,
|
|
255
332
|
}
|
|
256
333
|
|
|
257
334
|
// The always-needed block fields, one per block number. The block's remaining
|
|
@@ -277,7 +354,7 @@ type t = {
|
|
|
277
354
|
// Returns the response plus page stores owning this page's raw transactions
|
|
278
355
|
// and blocks.
|
|
279
356
|
getEventItems: (
|
|
280
|
-
~query: query,
|
|
357
|
+
~query: EventItems.query,
|
|
281
358
|
) => promise<(EventItems.response, TransactionStore.t, BlockStore.t)>,
|
|
282
359
|
getHeight: unit => promise<int>,
|
|
283
360
|
}
|
|
@@ -287,11 +364,11 @@ external classNew: (
|
|
|
287
364
|
Core.evmHypersyncClientCtor,
|
|
288
365
|
cfg,
|
|
289
366
|
string,
|
|
290
|
-
array<
|
|
367
|
+
array<Registration.input>,
|
|
291
368
|
) => t = "new"
|
|
292
369
|
|
|
293
|
-
let makeWithAgent = (cfg, ~userAgent, ~
|
|
294
|
-
Core.getAddon().evmHypersyncClient->classNew(cfg, userAgent,
|
|
370
|
+
let makeWithAgent = (cfg, ~userAgent, ~eventRegistrations) =>
|
|
371
|
+
Core.getAddon().evmHypersyncClient->classNew(cfg, userAgent, eventRegistrations)
|
|
295
372
|
|
|
296
373
|
type logLevel = [#trace | #debug | #info | #warn | #error]
|
|
297
374
|
let logLevelSchema: S.t<logLevel> = S.enum([#trace, #debug, #info, #warn, #error])
|
|
@@ -309,7 +386,7 @@ let make = (
|
|
|
309
386
|
~url,
|
|
310
387
|
~apiToken,
|
|
311
388
|
~httpReqTimeoutMillis,
|
|
312
|
-
~
|
|
389
|
+
~eventRegistrations,
|
|
313
390
|
~enableChecksumAddresses=true,
|
|
314
391
|
~serializationFormat=?,
|
|
315
392
|
~enableQueryCaching=?,
|
|
@@ -335,6 +412,6 @@ let make = (
|
|
|
335
412
|
logLevel: logLevelToString(logLevel),
|
|
336
413
|
},
|
|
337
414
|
~userAgent=`hyperindex/${envioVersion}`,
|
|
338
|
-
~
|
|
415
|
+
~eventRegistrations,
|
|
339
416
|
)
|
|
340
417
|
}
|
|
@@ -36,12 +36,45 @@ let QueryTypes = {
|
|
|
36
36
|
|
|
37
37
|
let ResponseTypes = {};
|
|
38
38
|
|
|
39
|
-
|
|
39
|
+
function toTopicFilterInput(filter) {
|
|
40
|
+
if (filter.TAG === "Values") {
|
|
41
|
+
return filter._0;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function fromOnEventRegistrations(onEventRegistrations) {
|
|
46
|
+
return onEventRegistrations.map(reg => {
|
|
47
|
+
let event = reg.eventConfig;
|
|
48
|
+
return {
|
|
49
|
+
index: reg.index,
|
|
50
|
+
sighash: event.sighash,
|
|
51
|
+
topicCount: event.topicCount,
|
|
52
|
+
eventName: event.name,
|
|
53
|
+
contractName: event.contractName,
|
|
54
|
+
isWildcard: reg.isWildcard,
|
|
55
|
+
dependsOnAddresses: reg.dependsOnAddresses,
|
|
56
|
+
params: event.paramsMetadata,
|
|
57
|
+
topicSelections: reg.resolvedWhere.topicSelections.map(ts => ({
|
|
58
|
+
topic0: ts.topic0,
|
|
59
|
+
topic1: toTopicFilterInput(ts.topic1),
|
|
60
|
+
topic2: toTopicFilterInput(ts.topic2),
|
|
61
|
+
topic3: toTopicFilterInput(ts.topic3)
|
|
62
|
+
})),
|
|
63
|
+
blockFields: Array.from(event.selectedBlockFields).map(name => Utils.$$String.capitalize(name)),
|
|
64
|
+
transactionFields: Array.from(event.selectedTransactionFields).map(name => Utils.$$String.capitalize(name))
|
|
65
|
+
};
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
let Registration = {
|
|
70
|
+
toTopicFilterInput: toTopicFilterInput,
|
|
71
|
+
fromOnEventRegistrations: fromOnEventRegistrations
|
|
72
|
+
};
|
|
40
73
|
|
|
41
74
|
let EventItems = {};
|
|
42
75
|
|
|
43
|
-
function makeWithAgent(cfg, userAgent,
|
|
44
|
-
return Core.getAddon().EvmHypersyncClient.new(cfg, userAgent,
|
|
76
|
+
function makeWithAgent(cfg, userAgent, eventRegistrations) {
|
|
77
|
+
return Core.getAddon().EvmHypersyncClient.new(cfg, userAgent, eventRegistrations);
|
|
45
78
|
}
|
|
46
79
|
|
|
47
80
|
let logLevelSchema = S$RescriptSchema.$$enum([
|
|
@@ -66,7 +99,7 @@ function logLevelToString(level) {
|
|
|
66
99
|
}
|
|
67
100
|
}
|
|
68
101
|
|
|
69
|
-
function make(url, apiToken, httpReqTimeoutMillis,
|
|
102
|
+
function make(url, apiToken, httpReqTimeoutMillis, eventRegistrations, enableChecksumAddressesOpt, serializationFormat, enableQueryCaching, retryBaseMs, retryBackoffMs, retryCeilingMs, logLevelOpt) {
|
|
70
103
|
let enableChecksumAddresses = enableChecksumAddressesOpt !== undefined ? enableChecksumAddressesOpt : true;
|
|
71
104
|
let logLevel = logLevelOpt !== undefined ? logLevelOpt : "info";
|
|
72
105
|
let envioVersion = Utils.EnvioPackage.value.version;
|
|
@@ -82,14 +115,14 @@ function make(url, apiToken, httpReqTimeoutMillis, eventParams, enableChecksumAd
|
|
|
82
115
|
serializationFormat: serializationFormat,
|
|
83
116
|
enableQueryCaching: enableQueryCaching,
|
|
84
117
|
logLevel: logLevelToString(logLevel)
|
|
85
|
-
}, `hyperindex/` + envioVersion,
|
|
118
|
+
}, `hyperindex/` + envioVersion, eventRegistrations);
|
|
86
119
|
}
|
|
87
120
|
|
|
88
121
|
export {
|
|
89
122
|
serializationFormatSchema,
|
|
90
123
|
QueryTypes,
|
|
91
124
|
ResponseTypes,
|
|
92
|
-
|
|
125
|
+
Registration,
|
|
93
126
|
EventItems,
|
|
94
127
|
makeWithAgent,
|
|
95
128
|
logLevelSchema,
|
|
@@ -1,123 +1,5 @@
|
|
|
1
1
|
open Source
|
|
2
2
|
|
|
3
|
-
type selectionConfig = {
|
|
4
|
-
getLogSelectionOrThrow: (
|
|
5
|
-
~addressesByContractName: dict<array<Address.t>>,
|
|
6
|
-
) => array<LogSelection.t>,
|
|
7
|
-
fieldSelection: HyperSyncClient.QueryTypes.fieldSelection,
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
let getSelectionConfig = (selection: FetchState.selection) => {
|
|
11
|
-
let capitalizedBlockFields = Utils.Set.make()
|
|
12
|
-
let capitalizedTransactionFields = Utils.Set.make()
|
|
13
|
-
|
|
14
|
-
let topicSelectionsByContract = Dict.make()
|
|
15
|
-
let wildcardTopicSelectionsByContract = Dict.make()
|
|
16
|
-
let noAddressesTopicSelections = []
|
|
17
|
-
let contractNames = Utils.Set.make()
|
|
18
|
-
|
|
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
|
|
27
|
-
selectedBlockFields
|
|
28
|
-
->Utils.Set.toArray
|
|
29
|
-
->Array.forEach(name =>
|
|
30
|
-
capitalizedBlockFields
|
|
31
|
-
->Utils.Set.add((name :> string)->Utils.String.capitalize)
|
|
32
|
-
->ignore
|
|
33
|
-
)
|
|
34
|
-
selectedTransactionFields
|
|
35
|
-
->Utils.Set.toArray
|
|
36
|
-
->Array.forEach(name => {
|
|
37
|
-
// transactionIndex is read off the log (the store key), so it never needs
|
|
38
|
-
// to be requested as a transaction column — and requesting it alone would
|
|
39
|
-
// pull the whole transaction table for nothing.
|
|
40
|
-
let fieldName = (name :> string)
|
|
41
|
-
if fieldName != "transactionIndex" {
|
|
42
|
-
capitalizedTransactionFields->Utils.Set.add(fieldName->Utils.String.capitalize)->ignore
|
|
43
|
-
}
|
|
44
|
-
})
|
|
45
|
-
|
|
46
|
-
if dependsOnAddresses {
|
|
47
|
-
let _ = contractNames->Utils.Set.add(contractName)
|
|
48
|
-
|
|
49
|
-
(
|
|
50
|
-
isWildcard ? wildcardTopicSelectionsByContract : topicSelectionsByContract
|
|
51
|
-
)->Utils.Dict.pushMany(contractName, resolvedWhere.topicSelections)
|
|
52
|
-
} else {
|
|
53
|
-
noAddressesTopicSelections
|
|
54
|
-
->Array.pushMany(
|
|
55
|
-
resolvedWhere.topicSelections->LogSelection.materializeTopicSelections(~addresses=[]),
|
|
56
|
-
)
|
|
57
|
-
->ignore
|
|
58
|
-
}
|
|
59
|
-
})
|
|
60
|
-
|
|
61
|
-
let fieldSelection: HyperSyncClient.QueryTypes.fieldSelection = {
|
|
62
|
-
log: [Address, Data, LogIndex, Topic0, Topic1, Topic2, Topic3],
|
|
63
|
-
block: capitalizedBlockFields
|
|
64
|
-
->Utils.Set.toArray
|
|
65
|
-
->(Utils.magic: array<string> => array<HyperSyncClient.QueryTypes.blockField>),
|
|
66
|
-
transaction: capitalizedTransactionFields
|
|
67
|
-
->Utils.Set.toArray
|
|
68
|
-
->(Utils.magic: array<string> => array<HyperSyncClient.QueryTypes.transactionField>),
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
let noAddressesLogSelection = LogSelection.make(
|
|
72
|
-
~addresses=[],
|
|
73
|
-
~topicSelections=noAddressesTopicSelections,
|
|
74
|
-
)
|
|
75
|
-
|
|
76
|
-
let getLogSelectionOrThrow = (~addressesByContractName): array<LogSelection.t> => {
|
|
77
|
-
let logSelections = []
|
|
78
|
-
if noAddressesLogSelection.topicSelections->Utils.Array.isEmpty->not {
|
|
79
|
-
logSelections->Array.push(noAddressesLogSelection)
|
|
80
|
-
}
|
|
81
|
-
contractNames->Utils.Set.forEach(contractName => {
|
|
82
|
-
switch addressesByContractName->Utils.Dict.dangerouslyGetNonOption(contractName) {
|
|
83
|
-
| None
|
|
84
|
-
| Some([]) => ()
|
|
85
|
-
| Some(addresses) =>
|
|
86
|
-
switch topicSelectionsByContract->Utils.Dict.dangerouslyGetNonOption(contractName) {
|
|
87
|
-
| None => ()
|
|
88
|
-
| Some(topicSelections) =>
|
|
89
|
-
logSelections->Array.push(
|
|
90
|
-
LogSelection.make(
|
|
91
|
-
~addresses,
|
|
92
|
-
~topicSelections=topicSelections->LogSelection.materializeTopicSelections(~addresses),
|
|
93
|
-
),
|
|
94
|
-
)
|
|
95
|
-
}
|
|
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) {
|
|
100
|
-
| None => ()
|
|
101
|
-
| Some(topicSelections) =>
|
|
102
|
-
logSelections->Array.push(
|
|
103
|
-
LogSelection.make(
|
|
104
|
-
~addresses=[],
|
|
105
|
-
~topicSelections=topicSelections->LogSelection.materializeTopicSelections(~addresses),
|
|
106
|
-
),
|
|
107
|
-
)
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
})
|
|
111
|
-
logSelections
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
{
|
|
115
|
-
getLogSelectionOrThrow,
|
|
116
|
-
fieldSelection,
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
let memoGetSelectionConfig = () => Utils.WeakMap.memoize(getSelectionConfig)
|
|
121
3
|
|
|
122
4
|
// Surfaced by HyperSyncClient.getHeight (Rust) when HyperSync rejects the API
|
|
123
5
|
// token. The corrupted-token test feeds the real server error through this
|
|
@@ -127,8 +9,8 @@ let isUnauthorizedError = (message: string) => message->String.includes("401 Una
|
|
|
127
9
|
type options = {
|
|
128
10
|
chain: ChainMap.Chain.t,
|
|
129
11
|
endpointUrl: string,
|
|
130
|
-
|
|
131
|
-
|
|
12
|
+
// The chain's registrations, indexed by their sequential `index`.
|
|
13
|
+
onEventRegistrations: array<Internal.evmOnEventRegistration>,
|
|
132
14
|
apiToken: option<string>,
|
|
133
15
|
clientTimeoutMillis: int,
|
|
134
16
|
lowercaseAddresses: bool,
|
|
@@ -141,8 +23,7 @@ let make = (
|
|
|
141
23
|
{
|
|
142
24
|
chain,
|
|
143
25
|
endpointUrl,
|
|
144
|
-
|
|
145
|
-
eventRouter,
|
|
26
|
+
onEventRegistrations,
|
|
146
27
|
apiToken,
|
|
147
28
|
clientTimeoutMillis,
|
|
148
29
|
lowercaseAddresses,
|
|
@@ -153,8 +34,6 @@ let make = (
|
|
|
153
34
|
): t => {
|
|
154
35
|
let name = "HyperSync"
|
|
155
36
|
|
|
156
|
-
let getSelectionConfig = memoGetSelectionConfig()
|
|
157
|
-
|
|
158
37
|
let apiToken = switch apiToken {
|
|
159
38
|
| Some(token) => token
|
|
160
39
|
| None =>
|
|
@@ -167,7 +46,9 @@ Learn more or get a free Envio API token at: https://envio.dev/app/api-tokens`)
|
|
|
167
46
|
~url=endpointUrl,
|
|
168
47
|
~apiToken,
|
|
169
48
|
~httpReqTimeoutMillis=clientTimeoutMillis,
|
|
170
|
-
~
|
|
49
|
+
~eventRegistrations=HyperSyncClient.Registration.fromOnEventRegistrations(
|
|
50
|
+
onEventRegistrations,
|
|
51
|
+
),
|
|
171
52
|
~enableChecksumAddresses=!lowercaseAddresses,
|
|
172
53
|
~serializationFormat,
|
|
173
54
|
~enableQueryCaching,
|
|
@@ -180,15 +61,11 @@ Learn more or get a free Envio API token at: https://envio.dev/app/api-tokens`)
|
|
|
180
61
|
)
|
|
181
62
|
}
|
|
182
63
|
|
|
183
|
-
exception UndefinedValue
|
|
184
|
-
|
|
185
64
|
let makeEventBatchQueueItem = (
|
|
186
65
|
item: HyperSyncClient.EventItems.item,
|
|
187
|
-
~params: Internal.eventParams,
|
|
188
66
|
~onEventRegistration: Internal.evmOnEventRegistration,
|
|
189
67
|
): Internal.item => {
|
|
190
68
|
let {transactionIndex, logIndex, srcAddress} = item
|
|
191
|
-
let chainId = chain->ChainMap.Chain.toChainId
|
|
192
69
|
|
|
193
70
|
Internal.Event({
|
|
194
71
|
onEventRegistration: (onEventRegistration :> Internal.onEventRegistration),
|
|
@@ -201,8 +78,8 @@ Learn more or get a free Envio API token at: https://envio.dev/app/api-tokens`)
|
|
|
201
78
|
payload: {
|
|
202
79
|
contractName: onEventRegistration.eventConfig.contractName,
|
|
203
80
|
eventName: onEventRegistration.eventConfig.name,
|
|
204
|
-
chainId,
|
|
205
|
-
params,
|
|
81
|
+
chainId: chain->ChainMap.Chain.toChainId,
|
|
82
|
+
params: item.params,
|
|
206
83
|
srcAddress,
|
|
207
84
|
logIndex,
|
|
208
85
|
}->Evm.fromPayload,
|
|
@@ -213,23 +90,16 @@ Learn more or get a free Envio API token at: https://envio.dev/app/api-tokens`)
|
|
|
213
90
|
~fromBlock,
|
|
214
91
|
~toBlock,
|
|
215
92
|
~addressesByContractName,
|
|
216
|
-
~contractNameByAddress,
|
|
93
|
+
~contractNameByAddress as _,
|
|
217
94
|
~knownHeight,
|
|
218
95
|
~partitionId as _,
|
|
219
|
-
~selection,
|
|
96
|
+
~selection: FetchState.selection,
|
|
220
97
|
~itemsTarget,
|
|
221
98
|
~retry,
|
|
222
|
-
~logger,
|
|
99
|
+
~logger as _,
|
|
223
100
|
) => {
|
|
224
101
|
let totalTimeRef = Performance.now()
|
|
225
102
|
|
|
226
|
-
let selectionConfig = selection->getSelectionConfig
|
|
227
|
-
|
|
228
|
-
let logSelections = try selectionConfig.getLogSelectionOrThrow(~addressesByContractName) catch {
|
|
229
|
-
| exn =>
|
|
230
|
-
exn->ErrorHandling.mkLogAndRaise(~logger, ~msg="Failed getting log selection for the query")
|
|
231
|
-
}
|
|
232
|
-
|
|
233
103
|
let startFetchingBatchTimeRef = Performance.now()
|
|
234
104
|
|
|
235
105
|
//fetch batch
|
|
@@ -237,9 +107,9 @@ Learn more or get a free Envio API token at: https://envio.dev/app/api-tokens`)
|
|
|
237
107
|
~client,
|
|
238
108
|
~fromBlock,
|
|
239
109
|
~toBlock,
|
|
240
|
-
~logSelections,
|
|
241
|
-
~fieldSelection=selectionConfig.fieldSelection,
|
|
242
110
|
~maxNumLogs=itemsTarget,
|
|
111
|
+
~registrationIndexes=selection.onEventRegistrations->Array.map(reg => reg.index),
|
|
112
|
+
~addressesByContractName,
|
|
243
113
|
) catch {
|
|
244
114
|
| HyperSync.GetLogs.Error(error) =>
|
|
245
115
|
throw(
|
|
@@ -309,63 +179,12 @@ Learn more or get a free Envio API token at: https://envio.dev/app/api-tokens`)
|
|
|
309
179
|
})
|
|
310
180
|
let getBlock = blockNumber => blocksByNumber->Utils.Map.unsafeGet(blockNumber)
|
|
311
181
|
|
|
312
|
-
let handleDecodeFailure = (
|
|
313
|
-
~onEventRegistration: Internal.evmOnEventRegistration,
|
|
314
|
-
~logIndex,
|
|
315
|
-
~blockNumber,
|
|
316
|
-
~chainId,
|
|
317
|
-
~exn,
|
|
318
|
-
) => {
|
|
319
|
-
if !onEventRegistration.isWildcard {
|
|
320
|
-
//Wildcard events can be parsed as undefined if the number of topics
|
|
321
|
-
//don't match the event with the given topic0
|
|
322
|
-
//Non wildcard events should be expected to be parsed
|
|
323
|
-
let msg = `Event ${onEventRegistration.eventConfig.name} was unexpectedly parsed as undefined`
|
|
324
|
-
let logger = Logging.createChildFrom(
|
|
325
|
-
~logger,
|
|
326
|
-
~params={
|
|
327
|
-
"chainId": chainId,
|
|
328
|
-
"blockNumber": blockNumber,
|
|
329
|
-
"logIndex": logIndex,
|
|
330
|
-
"decoder": "hypersync-client",
|
|
331
|
-
},
|
|
332
|
-
)
|
|
333
|
-
exn->ErrorHandling.mkLogAndRaise(~msg, ~logger)
|
|
334
|
-
}
|
|
335
|
-
}
|
|
336
|
-
|
|
337
182
|
pageUnsafe.items->Array.forEach(item => {
|
|
338
|
-
let
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
~topicCount=item.topicCount,
|
|
344
|
-
),
|
|
345
|
-
~contractNameByAddress,
|
|
346
|
-
~contractAddress=item.srcAddress,
|
|
347
|
-
)
|
|
348
|
-
|
|
349
|
-
switch maybeEventConfig {
|
|
350
|
-
| None => () //ignore events that aren't registered
|
|
351
|
-
| Some(onEventRegistration) =>
|
|
352
|
-
switch item.params
|
|
353
|
-
->Nullable.toOption
|
|
354
|
-
->Option.flatMap(Dict.get(_, onEventRegistration.eventConfig.contractName)) {
|
|
355
|
-
| Some(params) =>
|
|
356
|
-
parsedQueueItems
|
|
357
|
-
->Array.push(makeEventBatchQueueItem(item, ~params, ~onEventRegistration))
|
|
358
|
-
->ignore
|
|
359
|
-
| None =>
|
|
360
|
-
handleDecodeFailure(
|
|
361
|
-
~onEventRegistration,
|
|
362
|
-
~logIndex=item.logIndex,
|
|
363
|
-
~blockNumber=item.blockNumber,
|
|
364
|
-
~chainId,
|
|
365
|
-
~exn=UndefinedValue,
|
|
366
|
-
)
|
|
367
|
-
}
|
|
368
|
-
}
|
|
183
|
+
let onEventRegistration =
|
|
184
|
+
onEventRegistrations->Array.getUnsafe(item.onEventRegistrationIndex)
|
|
185
|
+
parsedQueueItems
|
|
186
|
+
->Array.push(makeEventBatchQueueItem(item, ~onEventRegistration))
|
|
187
|
+
->ignore
|
|
369
188
|
})
|
|
370
189
|
|
|
371
190
|
let parsingTimeElapsed = parsingTimeRef->Performance.secondsSince
|