envio 3.3.0-alpha.10 → 3.3.0-alpha.12
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/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/ChainFetching.res +30 -18
- package/src/ChainFetching.res.mjs +23 -13
- package/src/ChainState.res +45 -30
- package/src/ChainState.res.mjs +22 -8
- package/src/ChainState.resi +5 -0
- 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 +64 -29
- package/src/CrossChainState.res.mjs +17 -8
- 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 +428 -322
- package/src/FetchState.res.mjs +316 -233
- package/src/HandlerRegister.res +3 -1
- package/src/HandlerRegister.res.mjs +3 -2
- package/src/Internal.res +11 -2
- package/src/LogSelection.res +0 -62
- package/src/LogSelection.res.mjs +0 -74
- 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/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 +12 -15
- package/src/sources/EvmRpcClient.res.mjs +3 -3
- 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 +29 -175
- package/src/sources/RpcSource.res.mjs +32 -110
- package/src/sources/SimulateSource.res +37 -19
- package/src/sources/SimulateSource.res.mjs +27 -10
- package/src/sources/SvmHyperSyncSource.res +13 -3
- package/src/sources/SvmHyperSyncSource.res.mjs +1 -1
|
@@ -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
|
|
@@ -1,12 +1,9 @@
|
|
|
1
1
|
// Generated by ReScript, PLEASE EDIT WITH CARE
|
|
2
2
|
|
|
3
|
-
import * as Utils from "../Utils.res.mjs";
|
|
4
3
|
import * as Source from "./Source.res.mjs";
|
|
5
4
|
import * as Logging from "../Logging.res.mjs";
|
|
6
5
|
import * as HyperSync from "./HyperSync.res.mjs";
|
|
7
|
-
import * as EventRouter from "./EventRouter.res.mjs";
|
|
8
6
|
import * as Performance from "../bindings/Performance.res.mjs";
|
|
9
|
-
import * as LogSelection from "../LogSelection.res.mjs";
|
|
10
7
|
import * as Stdlib_JsExn from "@rescript/runtime/lib/es6/Stdlib_JsExn.js";
|
|
11
8
|
import * as ErrorHandling from "../ErrorHandling.res.mjs";
|
|
12
9
|
import * as Stdlib_Option from "@rescript/runtime/lib/es6/Stdlib_Option.js";
|
|
@@ -16,109 +13,27 @@ import * as Primitive_option from "@rescript/runtime/lib/es6/Primitive_option.js
|
|
|
16
13
|
import * as Primitive_exceptions from "@rescript/runtime/lib/es6/Primitive_exceptions.js";
|
|
17
14
|
import * as HyperSyncHeightStream from "./HyperSyncHeightStream.res.mjs";
|
|
18
15
|
|
|
19
|
-
function getSelectionConfig(selection) {
|
|
20
|
-
let capitalizedBlockFields = new Set();
|
|
21
|
-
let capitalizedTransactionFields = new Set();
|
|
22
|
-
let topicSelectionsByContract = {};
|
|
23
|
-
let wildcardTopicSelectionsByContract = {};
|
|
24
|
-
let noAddressesTopicSelections = [];
|
|
25
|
-
let contractNames = new Set();
|
|
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
|
-
capitalizedBlockFields.add(Utils.$$String.capitalize(name));
|
|
32
|
-
});
|
|
33
|
-
Array.from(eventConfig.selectedTransactionFields).forEach(name => {
|
|
34
|
-
if (name !== "transactionIndex") {
|
|
35
|
-
capitalizedTransactionFields.add(Utils.$$String.capitalize(name));
|
|
36
|
-
return;
|
|
37
|
-
}
|
|
38
|
-
});
|
|
39
|
-
if (reg.dependsOnAddresses) {
|
|
40
|
-
contractNames.add(contractName);
|
|
41
|
-
return Utils.Dict.pushMany(reg.isWildcard ? wildcardTopicSelectionsByContract : topicSelectionsByContract, contractName, resolvedWhere.topicSelections);
|
|
42
|
-
} else {
|
|
43
|
-
noAddressesTopicSelections.push(...LogSelection.materializeTopicSelections(resolvedWhere.topicSelections, []));
|
|
44
|
-
return;
|
|
45
|
-
}
|
|
46
|
-
});
|
|
47
|
-
let fieldSelection_block = Array.from(capitalizedBlockFields);
|
|
48
|
-
let fieldSelection_transaction = Array.from(capitalizedTransactionFields);
|
|
49
|
-
let fieldSelection_log = [
|
|
50
|
-
"Address",
|
|
51
|
-
"Data",
|
|
52
|
-
"LogIndex",
|
|
53
|
-
"Topic0",
|
|
54
|
-
"Topic1",
|
|
55
|
-
"Topic2",
|
|
56
|
-
"Topic3"
|
|
57
|
-
];
|
|
58
|
-
let fieldSelection = {
|
|
59
|
-
block: fieldSelection_block,
|
|
60
|
-
transaction: fieldSelection_transaction,
|
|
61
|
-
log: fieldSelection_log
|
|
62
|
-
};
|
|
63
|
-
let noAddressesLogSelection = LogSelection.make([], noAddressesTopicSelections);
|
|
64
|
-
let getLogSelectionOrThrow = addressesByContractName => {
|
|
65
|
-
let logSelections = [];
|
|
66
|
-
if (!Utils.$$Array.isEmpty(noAddressesLogSelection.topicSelections)) {
|
|
67
|
-
logSelections.push(noAddressesLogSelection);
|
|
68
|
-
}
|
|
69
|
-
contractNames.forEach(contractName => {
|
|
70
|
-
let addresses = addressesByContractName[contractName];
|
|
71
|
-
if (addresses === undefined) {
|
|
72
|
-
return;
|
|
73
|
-
}
|
|
74
|
-
if (addresses.length === 0) {
|
|
75
|
-
return;
|
|
76
|
-
}
|
|
77
|
-
let topicSelections = topicSelectionsByContract[contractName];
|
|
78
|
-
if (topicSelections !== undefined) {
|
|
79
|
-
logSelections.push(LogSelection.make(addresses, LogSelection.materializeTopicSelections(topicSelections, addresses)));
|
|
80
|
-
}
|
|
81
|
-
let topicSelections$1 = wildcardTopicSelectionsByContract[contractName];
|
|
82
|
-
if (topicSelections$1 !== undefined) {
|
|
83
|
-
logSelections.push(LogSelection.make([], LogSelection.materializeTopicSelections(topicSelections$1, addresses)));
|
|
84
|
-
return;
|
|
85
|
-
}
|
|
86
|
-
});
|
|
87
|
-
return logSelections;
|
|
88
|
-
};
|
|
89
|
-
return {
|
|
90
|
-
getLogSelectionOrThrow: getLogSelectionOrThrow,
|
|
91
|
-
fieldSelection: fieldSelection
|
|
92
|
-
};
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
function memoGetSelectionConfig() {
|
|
96
|
-
return Utils.$$WeakMap.memoize(getSelectionConfig);
|
|
97
|
-
}
|
|
98
|
-
|
|
99
16
|
function isUnauthorizedError(message) {
|
|
100
17
|
return message.includes("401 Unauthorized");
|
|
101
18
|
}
|
|
102
19
|
|
|
103
20
|
function make(param) {
|
|
104
21
|
let apiToken = param.apiToken;
|
|
105
|
-
let
|
|
22
|
+
let onEventRegistrations = param.onEventRegistrations;
|
|
106
23
|
let endpointUrl = param.endpointUrl;
|
|
107
24
|
let chain = param.chain;
|
|
108
25
|
let name = "HyperSync";
|
|
109
|
-
let getSelectionConfig$1 = Utils.$$WeakMap.memoize(getSelectionConfig);
|
|
110
26
|
let apiToken$1 = apiToken !== undefined ? apiToken : Stdlib_JsError.throwWithMessage(`An Envio API token is required for using HyperSync as a data-source.
|
|
111
27
|
Set the ENVIO_API_TOKEN environment variable in your .env file.
|
|
112
28
|
Learn more or get a free Envio API token at: https://envio.dev/app/api-tokens`);
|
|
113
29
|
let client;
|
|
114
30
|
try {
|
|
115
|
-
client = HyperSyncClient.make(endpointUrl, apiToken$1, param.clientTimeoutMillis,
|
|
31
|
+
client = HyperSyncClient.make(endpointUrl, apiToken$1, param.clientTimeoutMillis, HyperSyncClient.Registration.fromOnEventRegistrations(onEventRegistrations), !param.lowercaseAddresses, param.serializationFormat, param.enableQueryCaching, undefined, undefined, undefined, param.logLevel);
|
|
116
32
|
} catch (raw_exn) {
|
|
117
33
|
let exn = Primitive_exceptions.internalToException(raw_exn);
|
|
118
34
|
client = ErrorHandling.mkLogAndRaise(undefined, "Failed to instantiate the hypersync client, please double check your ABI", exn);
|
|
119
35
|
}
|
|
120
|
-
let
|
|
121
|
-
let makeEventBatchQueueItem = (item, params, onEventRegistration) => {
|
|
36
|
+
let makeEventBatchQueueItem = (item, onEventRegistration) => {
|
|
122
37
|
let logIndex = item.logIndex;
|
|
123
38
|
return {
|
|
124
39
|
kind: 0,
|
|
@@ -130,27 +45,19 @@ Learn more or get a free Envio API token at: https://envio.dev/app/api-tokens`);
|
|
|
130
45
|
payload: {
|
|
131
46
|
contractName: onEventRegistration.eventConfig.contractName,
|
|
132
47
|
eventName: onEventRegistration.eventConfig.name,
|
|
133
|
-
params: params,
|
|
48
|
+
params: item.params,
|
|
134
49
|
chainId: chain,
|
|
135
50
|
srcAddress: item.srcAddress,
|
|
136
51
|
logIndex: logIndex
|
|
137
52
|
}
|
|
138
53
|
};
|
|
139
54
|
};
|
|
140
|
-
let getItemsOrThrow = async (fromBlock, toBlock, addressesByContractName,
|
|
55
|
+
let getItemsOrThrow = async (fromBlock, toBlock, addressesByContractName, param, knownHeight, param$1, selection, itemsTarget, retry, param$2) => {
|
|
141
56
|
let totalTimeRef = Performance.now();
|
|
142
|
-
let selectionConfig = getSelectionConfig$1(selection);
|
|
143
|
-
let logSelections;
|
|
144
|
-
try {
|
|
145
|
-
logSelections = selectionConfig.getLogSelectionOrThrow(addressesByContractName);
|
|
146
|
-
} catch (raw_exn) {
|
|
147
|
-
let exn = Primitive_exceptions.internalToException(raw_exn);
|
|
148
|
-
logSelections = ErrorHandling.mkLogAndRaise(logger, "Failed getting log selection for the query", exn);
|
|
149
|
-
}
|
|
150
57
|
let startFetchingBatchTimeRef = Performance.now();
|
|
151
58
|
let pageUnsafe;
|
|
152
59
|
try {
|
|
153
|
-
pageUnsafe = await HyperSync.GetLogs.query(client, fromBlock, toBlock,
|
|
60
|
+
pageUnsafe = await HyperSync.GetLogs.query(client, fromBlock, toBlock, itemsTarget, selection.onEventRegistrations.map(reg => reg.index), addressesByContractName);
|
|
154
61
|
} catch (raw_error) {
|
|
155
62
|
let error = Primitive_exceptions.internalToException(raw_error);
|
|
156
63
|
if (error.RE_EXN_ID === HyperSync.GetLogs.$$Error) {
|
|
@@ -212,32 +119,8 @@ Learn more or get a free Envio API token at: https://envio.dev/app/api-tokens`);
|
|
|
212
119
|
blocksByNumber.set(block.number, block);
|
|
213
120
|
});
|
|
214
121
|
pageUnsafe.items.forEach(item => {
|
|
215
|
-
let
|
|
216
|
-
|
|
217
|
-
return;
|
|
218
|
-
}
|
|
219
|
-
let params = Stdlib_Option.flatMap(Primitive_option.fromNullable(item.params), __x => __x[maybeEventConfig.eventConfig.contractName]);
|
|
220
|
-
if (params !== undefined) {
|
|
221
|
-
parsedQueueItems.push(makeEventBatchQueueItem(item, Primitive_option.valFromOption(params), maybeEventConfig));
|
|
222
|
-
return;
|
|
223
|
-
} else {
|
|
224
|
-
let logIndex = item.logIndex;
|
|
225
|
-
let blockNumber = item.blockNumber;
|
|
226
|
-
let exn = {
|
|
227
|
-
RE_EXN_ID: UndefinedValue
|
|
228
|
-
};
|
|
229
|
-
if (maybeEventConfig.isWildcard) {
|
|
230
|
-
return;
|
|
231
|
-
}
|
|
232
|
-
let msg = `Event ` + maybeEventConfig.eventConfig.name + ` was unexpectedly parsed as undefined`;
|
|
233
|
-
let logger$1 = Logging.createChildFrom(logger, {
|
|
234
|
-
chainId: chain,
|
|
235
|
-
blockNumber: blockNumber,
|
|
236
|
-
logIndex: logIndex,
|
|
237
|
-
decoder: "hypersync-client"
|
|
238
|
-
});
|
|
239
|
-
return ErrorHandling.mkLogAndRaise(logger$1, msg, exn);
|
|
240
|
-
}
|
|
122
|
+
let onEventRegistration = onEventRegistrations[item.onEventRegistrationIndex];
|
|
123
|
+
parsedQueueItems.push(makeEventBatchQueueItem(item, onEventRegistration));
|
|
241
124
|
});
|
|
242
125
|
let parsingTimeElapsed = Performance.secondsSince(parsingTimeRef);
|
|
243
126
|
let blockHashes = [];
|
|
@@ -346,9 +229,7 @@ Learn more or get a free Envio API token at: https://envio.dev/app/api-tokens`);
|
|
|
346
229
|
}
|
|
347
230
|
|
|
348
231
|
export {
|
|
349
|
-
getSelectionConfig,
|
|
350
|
-
memoGetSelectionConfig,
|
|
351
232
|
isUnauthorizedError,
|
|
352
233
|
make,
|
|
353
234
|
}
|
|
354
|
-
/*
|
|
235
|
+
/* Logging Not a pure module */
|
package/src/sources/Rpc.res
CHANGED
|
@@ -82,38 +82,6 @@ let decimalFloatSchema: S.schema<float> = S.string->S.transform(s => {
|
|
|
82
82
|
})
|
|
83
83
|
|
|
84
84
|
module GetLogs = {
|
|
85
|
-
@unboxed
|
|
86
|
-
type topicFilter = Single(hex) | Multiple(array<hex>) | @as(null) Null
|
|
87
|
-
type topicQuery = array<topicFilter>
|
|
88
|
-
|
|
89
|
-
let makeTopicQuery = (~topic0=[], ~topic1=[], ~topic2=[], ~topic3=[]) => {
|
|
90
|
-
let topics = [topic0, topic1, topic2, topic3]
|
|
91
|
-
|
|
92
|
-
let isLastTopicEmpty = () =>
|
|
93
|
-
switch topics->Utils.Array.last {
|
|
94
|
-
| Some([]) => true
|
|
95
|
-
| _ => false
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
//Remove all empty topics from the end of the array
|
|
99
|
-
while isLastTopicEmpty() {
|
|
100
|
-
topics->Array.pop->ignore
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
let toTopicFilter = topic => {
|
|
104
|
-
switch topic {
|
|
105
|
-
| [] => Null
|
|
106
|
-
| [single] => Single(single->EvmTypes.Hex.toString)
|
|
107
|
-
| multiple => Multiple(multiple->EvmTypes.Hex.toStrings)
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
topics->Array.map(toTopicFilter)
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
let mapTopicQuery = ({topic0, topic1, topic2, topic3}: Internal.topicSelection): topicQuery =>
|
|
115
|
-
makeTopicQuery(~topic0, ~topic1, ~topic2, ~topic3)
|
|
116
|
-
|
|
117
85
|
type log = {
|
|
118
86
|
address: Address.t,
|
|
119
87
|
topics: array<hex>,
|
package/src/sources/Rpc.res.mjs
CHANGED
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
import * as Rest from "../vendored/Rest.res.mjs";
|
|
4
4
|
import * as Viem from "viem";
|
|
5
|
-
import * as Utils from "../Utils.res.mjs";
|
|
6
5
|
import * as Address from "../Address.res.mjs";
|
|
7
6
|
import * as Stdlib_Dict from "@rescript/runtime/lib/es6/Stdlib_Dict.js";
|
|
8
7
|
import * as Stdlib_BigInt from "@rescript/runtime/lib/es6/Stdlib_BigInt.js";
|
|
@@ -95,51 +94,7 @@ let decimalFloatSchema = S$RescriptSchema.transform(S$RescriptSchema.string, s =
|
|
|
95
94
|
}
|
|
96
95
|
}));
|
|
97
96
|
|
|
98
|
-
|
|
99
|
-
let topic0 = topic0Opt !== undefined ? topic0Opt : [];
|
|
100
|
-
let topic1 = topic1Opt !== undefined ? topic1Opt : [];
|
|
101
|
-
let topic2 = topic2Opt !== undefined ? topic2Opt : [];
|
|
102
|
-
let topic3 = topic3Opt !== undefined ? topic3Opt : [];
|
|
103
|
-
let topics = [
|
|
104
|
-
topic0,
|
|
105
|
-
topic1,
|
|
106
|
-
topic2,
|
|
107
|
-
topic3
|
|
108
|
-
];
|
|
109
|
-
let isLastTopicEmpty = () => {
|
|
110
|
-
let match = Utils.$$Array.last(topics);
|
|
111
|
-
if (match !== undefined) {
|
|
112
|
-
return match.length === 0;
|
|
113
|
-
} else {
|
|
114
|
-
return false;
|
|
115
|
-
}
|
|
116
|
-
};
|
|
117
|
-
while (isLastTopicEmpty()) {
|
|
118
|
-
topics.pop();
|
|
119
|
-
};
|
|
120
|
-
let toTopicFilter = topic => {
|
|
121
|
-
let len = topic.length;
|
|
122
|
-
if (len !== 1) {
|
|
123
|
-
if (len !== 0) {
|
|
124
|
-
return topic;
|
|
125
|
-
} else {
|
|
126
|
-
return null;
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
let single = topic[0];
|
|
130
|
-
return single;
|
|
131
|
-
};
|
|
132
|
-
return topics.map(toTopicFilter);
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
function mapTopicQuery(param) {
|
|
136
|
-
return makeTopicQuery(param.topic0, param.topic1, param.topic2, param.topic3);
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
let GetLogs = {
|
|
140
|
-
makeTopicQuery: makeTopicQuery,
|
|
141
|
-
mapTopicQuery: mapTopicQuery
|
|
142
|
-
};
|
|
97
|
+
let GetLogs = {};
|
|
143
98
|
|
|
144
99
|
let blockSchema = S$RescriptSchema.object(s => ({
|
|
145
100
|
difficulty: s.f("difficulty", S$RescriptSchema.$$null(hexBigintSchema)),
|