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.
Files changed (94) hide show
  1. package/index.d.ts +19 -0
  2. package/licenses/CLA.md +35 -0
  3. package/licenses/EULA.md +67 -0
  4. package/licenses/LICENSE.md +45 -0
  5. package/licenses/README.md +35 -0
  6. package/package.json +9 -8
  7. package/src/Batch.res.mjs +1 -1
  8. package/src/BatchProcessing.res +0 -7
  9. package/src/BatchProcessing.res.mjs +1 -8
  10. package/src/ChainFetching.res +30 -18
  11. package/src/ChainFetching.res.mjs +23 -13
  12. package/src/ChainState.res +134 -55
  13. package/src/ChainState.res.mjs +78 -36
  14. package/src/ChainState.resi +14 -2
  15. package/src/Config.res +9 -5
  16. package/src/Config.res.mjs +2 -2
  17. package/src/Core.res +20 -0
  18. package/src/Core.res.mjs +12 -0
  19. package/src/CrossChainState.res +115 -34
  20. package/src/CrossChainState.res.mjs +37 -14
  21. package/src/EffectState.res +100 -0
  22. package/src/EffectState.res.mjs +74 -0
  23. package/src/EffectState.resi +32 -0
  24. package/src/Envio.res +25 -7
  25. package/src/Envio.res.mjs +15 -19
  26. package/src/EventConfigBuilder.res +21 -46
  27. package/src/EventConfigBuilder.res.mjs +18 -25
  28. package/src/EventProcessing.res +8 -5
  29. package/src/EventProcessing.res.mjs +2 -1
  30. package/src/FetchState.res +814 -467
  31. package/src/FetchState.res.mjs +541 -369
  32. package/src/HandlerRegister.res +3 -1
  33. package/src/HandlerRegister.res.mjs +3 -2
  34. package/src/InMemoryStore.res +14 -26
  35. package/src/InMemoryStore.res.mjs +6 -19
  36. package/src/IndexerState.res +15 -39
  37. package/src/IndexerState.res.mjs +18 -29
  38. package/src/IndexerState.resi +2 -10
  39. package/src/Internal.res +98 -14
  40. package/src/Internal.res.mjs +96 -2
  41. package/src/LoadLayer.res +44 -24
  42. package/src/LoadLayer.res.mjs +43 -20
  43. package/src/LoadLayer.resi +1 -0
  44. package/src/LogSelection.res +0 -62
  45. package/src/LogSelection.res.mjs +0 -74
  46. package/src/Metrics.res +1 -1
  47. package/src/Metrics.res.mjs +1 -1
  48. package/src/Persistence.res +12 -3
  49. package/src/PgStorage.res +155 -82
  50. package/src/PgStorage.res.mjs +130 -77
  51. package/src/Prometheus.res +20 -10
  52. package/src/Prometheus.res.mjs +22 -10
  53. package/src/PruneStaleHistory.res +146 -35
  54. package/src/PruneStaleHistory.res.mjs +114 -20
  55. package/src/RawEvent.res +2 -2
  56. package/src/Rollback.res +32 -13
  57. package/src/Rollback.res.mjs +24 -11
  58. package/src/SimulateDeadInputTracker.res +1 -1
  59. package/src/SimulateItems.res +38 -6
  60. package/src/SimulateItems.res.mjs +28 -9
  61. package/src/TestIndexer.res +2 -2
  62. package/src/TestIndexer.res.mjs +2 -2
  63. package/src/TopicFilter.res +1 -25
  64. package/src/TopicFilter.res.mjs +0 -74
  65. package/src/UserContext.res +62 -23
  66. package/src/UserContext.res.mjs +26 -6
  67. package/src/Writing.res +60 -21
  68. package/src/Writing.res.mjs +27 -9
  69. package/src/bindings/NodeJs.res +5 -0
  70. package/src/bindings/Viem.res +0 -5
  71. package/src/sources/EventRouter.res +0 -21
  72. package/src/sources/EventRouter.res.mjs +0 -12
  73. package/src/sources/EvmChain.res +2 -27
  74. package/src/sources/EvmChain.res.mjs +2 -23
  75. package/src/sources/EvmRpcClient.res +58 -23
  76. package/src/sources/EvmRpcClient.res.mjs +11 -5
  77. package/src/sources/HyperSync.res +9 -38
  78. package/src/sources/HyperSync.res.mjs +16 -28
  79. package/src/sources/HyperSync.resi +2 -2
  80. package/src/sources/HyperSyncClient.res +88 -11
  81. package/src/sources/HyperSyncClient.res.mjs +39 -6
  82. package/src/sources/HyperSyncSource.res +18 -199
  83. package/src/sources/HyperSyncSource.res.mjs +9 -128
  84. package/src/sources/Rpc.res +0 -32
  85. package/src/sources/Rpc.res.mjs +1 -46
  86. package/src/sources/RpcSource.res +129 -522
  87. package/src/sources/RpcSource.res.mjs +161 -366
  88. package/src/sources/SimulateSource.res +37 -19
  89. package/src/sources/SimulateSource.res.mjs +27 -10
  90. package/src/sources/SourceManager.res +3 -7
  91. package/src/sources/SourceManager.res.mjs +2 -7
  92. package/src/sources/SourceManager.resi +0 -2
  93. package/src/sources/SvmHyperSyncSource.res +13 -3
  94. 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 Decoder = {
233
- type eventParamsInput = {
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
- params: Nullable.t<dict<Internal.eventParams>>,
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<Decoder.eventParamsInput>,
367
+ array<Registration.input>,
291
368
  ) => t = "new"
292
369
 
293
- let makeWithAgent = (cfg, ~userAgent, ~eventParams) =>
294
- Core.getAddon().evmHypersyncClient->classNew(cfg, userAgent, eventParams)
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
- ~eventParams,
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
- ~eventParams,
415
+ ~eventRegistrations,
339
416
  )
340
417
  }
@@ -36,12 +36,45 @@ let QueryTypes = {
36
36
 
37
37
  let ResponseTypes = {};
38
38
 
39
- let Decoder = {};
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, eventParams) {
44
- return Core.getAddon().EvmHypersyncClient.new(cfg, userAgent, eventParams);
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, eventParams, enableChecksumAddressesOpt, serializationFormat, enableQueryCaching, retryBaseMs, retryBackoffMs, retryCeilingMs, logLevelOpt) {
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, eventParams);
118
+ }, `hyperindex/` + envioVersion, eventRegistrations);
86
119
  }
87
120
 
88
121
  export {
89
122
  serializationFormatSchema,
90
123
  QueryTypes,
91
124
  ResponseTypes,
92
- Decoder,
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
- allEventParams: array<HyperSyncClient.Decoder.eventParamsInput>,
131
- eventRouter: EventRouter.t<Internal.evmOnEventRegistration>,
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
- allEventParams,
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
- ~eventParams=allEventParams,
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 chainId = chain->ChainMap.Chain.toChainId
339
- let maybeEventConfig =
340
- eventRouter->EventRouter.get(
341
- ~tag=EventRouter.getEvmEventId(
342
- ~sighash=item.topic0->EvmTypes.Hex.toString,
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