envio 3.3.0-alpha.10 → 3.3.0-alpha.11

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 (57) hide show
  1. package/licenses/CLA.md +35 -0
  2. package/licenses/EULA.md +67 -0
  3. package/licenses/LICENSE.md +45 -0
  4. package/licenses/README.md +35 -0
  5. package/package.json +9 -8
  6. package/src/Batch.res.mjs +1 -1
  7. package/src/ChainFetching.res +13 -10
  8. package/src/ChainFetching.res.mjs +3 -4
  9. package/src/ChainState.res +45 -30
  10. package/src/ChainState.res.mjs +22 -8
  11. package/src/ChainState.resi +5 -0
  12. package/src/Config.res +9 -5
  13. package/src/Config.res.mjs +2 -2
  14. package/src/Core.res +20 -0
  15. package/src/Core.res.mjs +12 -0
  16. package/src/CrossChainState.res +18 -1
  17. package/src/CrossChainState.res.mjs +2 -1
  18. package/src/EventConfigBuilder.res +21 -46
  19. package/src/EventConfigBuilder.res.mjs +18 -25
  20. package/src/EventProcessing.res +8 -5
  21. package/src/EventProcessing.res.mjs +2 -1
  22. package/src/FetchState.res +344 -263
  23. package/src/FetchState.res.mjs +209 -131
  24. package/src/HandlerRegister.res +3 -1
  25. package/src/HandlerRegister.res.mjs +3 -2
  26. package/src/Internal.res +11 -2
  27. package/src/LogSelection.res +0 -62
  28. package/src/LogSelection.res.mjs +0 -74
  29. package/src/RawEvent.res +2 -2
  30. package/src/SimulateDeadInputTracker.res +1 -1
  31. package/src/SimulateItems.res +38 -6
  32. package/src/SimulateItems.res.mjs +28 -9
  33. package/src/TestIndexer.res +2 -2
  34. package/src/TestIndexer.res.mjs +2 -2
  35. package/src/TopicFilter.res +1 -25
  36. package/src/TopicFilter.res.mjs +0 -74
  37. package/src/bindings/Viem.res +0 -5
  38. package/src/sources/EventRouter.res +0 -21
  39. package/src/sources/EventRouter.res.mjs +0 -12
  40. package/src/sources/EvmChain.res +2 -27
  41. package/src/sources/EvmChain.res.mjs +2 -23
  42. package/src/sources/EvmRpcClient.res +12 -15
  43. package/src/sources/EvmRpcClient.res.mjs +3 -3
  44. package/src/sources/HyperSync.res +9 -38
  45. package/src/sources/HyperSync.res.mjs +16 -28
  46. package/src/sources/HyperSync.resi +2 -2
  47. package/src/sources/HyperSyncClient.res +88 -11
  48. package/src/sources/HyperSyncClient.res.mjs +39 -6
  49. package/src/sources/HyperSyncSource.res +18 -199
  50. package/src/sources/HyperSyncSource.res.mjs +9 -128
  51. package/src/sources/Rpc.res +0 -32
  52. package/src/sources/Rpc.res.mjs +1 -46
  53. package/src/sources/RpcSource.res +29 -175
  54. package/src/sources/RpcSource.res.mjs +32 -110
  55. package/src/sources/SimulateSource.res +37 -19
  56. package/src/sources/SimulateSource.res.mjs +27 -10
  57. package/src/sources/SvmHyperSyncSource.res +3 -3
@@ -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 eventRouter = param.eventRouter;
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, param.allEventParams, !param.lowercaseAddresses, param.serializationFormat, param.enableQueryCaching, undefined, undefined, undefined, param.logLevel);
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 UndefinedValue = /* @__PURE__ */Primitive_exceptions.create("UndefinedValue");
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, contractNameByAddress, knownHeight, param, selection, itemsTarget, retry, logger) => {
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, logSelections, selectionConfig.fieldSelection, itemsTarget);
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 maybeEventConfig = EventRouter.get(eventRouter, EventRouter.getEvmEventId(item.topic0, item.topicCount), item.srcAddress, contractNameByAddress);
216
- if (maybeEventConfig === undefined) {
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
- /* Utils Not a pure module */
235
+ /* Logging Not a pure module */
@@ -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>,
@@ -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
- function makeTopicQuery(topic0Opt, topic1Opt, topic2Opt, topic3Opt) {
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)),
@@ -97,10 +97,6 @@ let getErrorMessage = (exn: exn): option<string> =>
97
97
  | _ => None
98
98
  }
99
99
 
100
- type logSelection = {
101
- addresses: option<array<Address.t>>,
102
- topicQuery: Rpc.GetLogs.topicQuery,
103
- }
104
100
 
105
101
  // `EvmRpcClient.getNextPage` throws a napi error whose message is a JSON
106
102
  // payload describing the retry decision:
@@ -161,122 +157,6 @@ let parseGetNextPageRetryError = (exn: exn): option<(
161
157
  | _ => None
162
158
  }
163
159
 
164
- type selectionConfig = {
165
- getLogSelectionsOrThrow: (
166
- ~addressesByContractName: dict<array<Address.t>>,
167
- ) => array<logSelection>,
168
- }
169
-
170
- let getSelectionConfig = (selection: FetchState.selection) => {
171
- let evmOnEventRegistrations =
172
- selection.onEventRegistrations->(
173
- Utils.magic: array<Internal.onEventRegistration> => array<Internal.evmOnEventRegistration>
174
- )
175
-
176
- if evmOnEventRegistrations->Utils.Array.isEmpty {
177
- throw(
178
- Source.GetItemsError(
179
- UnsupportedSelection({
180
- message: "Invalid events configuration for the partition. Nothing to fetch. Please, report to the Envio team.",
181
- }),
182
- ),
183
- )
184
- }
185
-
186
- // eth_getLogs takes one address list and one topic selection per request, so
187
- // fan out to one request per selection. Each address-bound event is grouped by
188
- // its contract and later scoped to that contract's own addresses — pooling all
189
- // contracts' addresses would let one contract's query fetch a sibling's logs,
190
- // which route back by address and bypass the sibling's filter (routing never
191
- // re-applies it). Pure-wildcard events carry no address constraint, so they're
192
- // pooled and resolved once.
193
- let noAddressTopicSelections = []
194
- let byContract = Dict.make()
195
- let wildcardByContract = Dict.make()
196
- let contractNames = Utils.Set.make()
197
-
198
- evmOnEventRegistrations->Array.forEach(reg => {
199
- let contractName = reg.eventConfig.contractName
200
- let {isWildcard, dependsOnAddresses, resolvedWhere} = reg
201
- if dependsOnAddresses {
202
- contractNames->Utils.Set.add(contractName)->ignore
203
- (isWildcard ? wildcardByContract : byContract)->Utils.Dict.pushMany(
204
- contractName,
205
- resolvedWhere.topicSelections,
206
- )
207
- } else {
208
- noAddressTopicSelections
209
- ->Array.pushMany(
210
- resolvedWhere.topicSelections->LogSelection.materializeTopicSelections(~addresses=[]),
211
- )
212
- ->ignore
213
- }
214
- })
215
-
216
- // `compressTopicSelections` folds the filter-less events into a single topic0
217
- // OR-set, keeping the common case at one request.
218
- let toLogSelections = (~addresses, topicSelections): array<logSelection> =>
219
- topicSelections
220
- ->LogSelection.compressTopicSelections
221
- ->Array.map(topicSelection => {
222
- addresses,
223
- topicQuery: topicSelection->Rpc.GetLogs.mapTopicQuery,
224
- })
225
-
226
- // Address-independent, so resolve once (the wildcard partition reuses this).
227
- let noAddressLogSelections = toLogSelections(~addresses=None, noAddressTopicSelections)
228
-
229
- let getLogSelectionsOrThrow = if contractNames->Utils.Set.size === 0 {
230
- (~addressesByContractName as _) => noAddressLogSelections
231
- } else {
232
- (~addressesByContractName): array<logSelection> => {
233
- let logSelections = noAddressLogSelections->Array.copy
234
- contractNames->Utils.Set.forEach(contractName => {
235
- switch addressesByContractName->Utils.Dict.dangerouslyGetNonOption(contractName) {
236
- | None
237
- | Some([]) => ()
238
- | Some(addresses) =>
239
- // Non-wildcard filters, scoped to this contract's addresses.
240
- switch byContract->Utils.Dict.dangerouslyGetNonOption(contractName) {
241
- | Some(topicSelections) =>
242
- logSelections
243
- ->Array.pushMany(
244
- toLogSelections(
245
- ~addresses=Some(addresses),
246
- topicSelections->LogSelection.materializeTopicSelections(~addresses),
247
- ),
248
- )
249
- ->ignore
250
- | None => ()
251
- }
252
-
253
- // Wildcard-by-address filters fold the address into the topics,
254
- // so they still match any address.
255
- switch wildcardByContract->Utils.Dict.dangerouslyGetNonOption(contractName) {
256
- | Some(topicSelections) =>
257
- logSelections
258
- ->Array.pushMany(
259
- toLogSelections(
260
- ~addresses=None,
261
- topicSelections->LogSelection.materializeTopicSelections(~addresses),
262
- ),
263
- )
264
- ->ignore
265
- | None => ()
266
- }
267
- }
268
- })
269
- logSelections
270
- }
271
- }
272
-
273
- {
274
- getLogSelectionsOrThrow: getLogSelectionsOrThrow,
275
- }
276
- }
277
-
278
- let memoGetSelectionConfig = () => Utils.WeakMap.memoize(getSelectionConfig)
279
-
280
160
  // Type-erase a schema for storage in the field registry
281
161
  external toFieldSchema: S.t<'a> => S.t<JSON.t> = "%identity"
282
162
 
@@ -735,8 +615,8 @@ type options = {
735
615
  syncConfig: Config.sourceSync,
736
616
  url: string,
737
617
  chain: ChainMap.Chain.t,
738
- eventRouter: EventRouter.t<Internal.evmOnEventRegistration>,
739
- allEventParams: array<HyperSyncClient.Decoder.eventParamsInput>,
618
+ // The chain's registrations, indexed by their sequential `index`.
619
+ onEventRegistrations: array<Internal.evmOnEventRegistration>,
740
620
  lowercaseAddresses: bool,
741
621
  ws?: string,
742
622
  headers?: dict<string>,
@@ -748,8 +628,7 @@ let make = (
748
628
  syncConfig,
749
629
  url,
750
630
  chain,
751
- eventRouter,
752
- allEventParams,
631
+ onEventRegistrations,
753
632
  lowercaseAddresses,
754
633
  ?ws,
755
634
  ?headers,
@@ -765,12 +644,12 @@ let make = (
765
644
  }
766
645
  let name = `RPC (${urlHost})`
767
646
 
768
- let getSelectionConfig = memoGetSelectionConfig()
769
-
770
647
  let client = Rpc.makeClient(url, ~headers?)
771
648
  let rpcClient = EvmRpcClient.make(
772
649
  ~url,
773
- ~allEventParams,
650
+ ~eventRegistrations=HyperSyncClient.Registration.fromOnEventRegistrations(
651
+ onEventRegistrations,
652
+ ),
774
653
  ~checksumAddresses=!lowercaseAddresses,
775
654
  ~syncConfig,
776
655
  ~headers?,
@@ -921,7 +800,7 @@ let make = (
921
800
  ~fromBlock,
922
801
  ~toBlock,
923
802
  ~addressesByContractName,
924
- ~contractNameByAddress,
803
+ ~contractNameByAddress as _,
925
804
  ~knownHeight,
926
805
  ~partitionId,
927
806
  ~selection: FetchState.selection,
@@ -944,26 +823,22 @@ let make = (
944
823
  ->Promise.thenResolve(json => Some(parseBlockInfo(json)))
945
824
  : Promise.resolve(None)
946
825
 
947
- let {getLogSelectionsOrThrow} = getSelectionConfig(selection)
948
- let logSelections = getLogSelectionsOrThrow(~addressesByContractName)
826
+ if selection.onEventRegistrations->Utils.Array.isEmpty {
827
+ throw(
828
+ Source.GetItemsError(
829
+ UnsupportedSelection({
830
+ message: "Invalid events configuration for the partition. Nothing to fetch. Please, report to the Envio team.",
831
+ }),
832
+ ),
833
+ )
834
+ }
949
835
 
950
836
  let {items, toBlock: queriedToBlock, requestStats} = try await rpcClient.getNextPage({
951
837
  fromBlock,
952
838
  toBlockCeiling: toBlock,
953
- logSelections: logSelections->Array.map(({
954
- addresses,
955
- topicQuery,
956
- }): EvmRpcClient.logSelectionInput => {
957
- ?addresses,
958
- topics: topicQuery->Array.map(filter =>
959
- switch filter {
960
- | Rpc.GetLogs.Null => Nullable.null
961
- | Single(topic) => Nullable.make([topic])
962
- | Multiple(topics) => Nullable.make(topics)
963
- }
964
- ),
965
- }),
966
839
  partitionId,
840
+ registrationIndexes: selection.onEventRegistrations->Array.map(reg => reg.index),
841
+ addressesByContractName,
967
842
  }) catch {
968
843
  | exn =>
969
844
  switch exn->parseGetNextPageRetryError {
@@ -997,32 +872,15 @@ let make = (
997
872
  ->Promise.thenResolve(parseBlockInfo)
998
873
 
999
874
  let parsedQueueItems = await items
1000
- ->Array.filterMap(({log, params: maybeDecodedEvent}: EvmRpcClient.rpcEventItem) => {
1001
- let topic0 = log.topics[0]->Option.getOr("0x0")
1002
- let routedAddress = if lowercaseAddresses {
1003
- log.address->Address.Evm.fromAddressLowercaseOrThrow
1004
- } else {
1005
- log.address->Address.Evm.fromAddressOrThrow
1006
- }
1007
-
1008
- switch eventRouter->EventRouter.get(
1009
- ~tag=EventRouter.getEvmEventId(~sighash=topic0, ~topicCount=log.topics->Array.length),
1010
- ~contractNameByAddress,
1011
- ~contractAddress=routedAddress,
1012
- ) {
1013
- | None => None
1014
- | Some(onEventRegistration) =>
1015
- let eventConfig =
1016
- onEventRegistration.eventConfig->(
1017
- Utils.magic: Internal.eventConfig => Internal.evmEventConfig
1018
- )
1019
- switch maybeDecodedEvent
1020
- ->Nullable.toOption
1021
- ->Option.flatMap(Dict.get(_, eventConfig.contractName)) {
1022
- | Some(decoded) =>
1023
- Some(
1024
- (
1025
- async () => {
875
+ ->Array.map(({log, onEventRegistrationIndex, params: decoded}: EvmRpcClient.rpcEventItem) => {
876
+ // `log.address` comes back already normalized to the client's casing.
877
+ let onEventRegistration = onEventRegistrations->Array.getUnsafe(onEventRegistrationIndex)
878
+ let eventConfig =
879
+ onEventRegistration.eventConfig->(
880
+ Utils.magic: Internal.eventConfig => Internal.evmEventConfig
881
+ )
882
+ (
883
+ async () => {
1026
884
  let (block, transaction) = try await Promise.all2((
1027
885
  log->getEventBlockOrThrow(~selectedBlockFields=eventConfig.selectedBlockFields),
1028
886
  log->getEventTransactionOrThrow(
@@ -1074,16 +932,12 @@ let make = (
1074
932
  params: decoded,
1075
933
  block,
1076
934
  transaction,
1077
- srcAddress: routedAddress,
935
+ srcAddress: log.address,
1078
936
  logIndex: log.logIndex,
1079
937
  }->Evm.fromPayload,
1080
938
  })
1081
- }
1082
- )(),
1083
- )
1084
- | None => None
1085
939
  }
1086
- }
940
+ )()
1087
941
  })
1088
942
  ->Promise.all
1089
943