envio 3.3.0-alpha.9 → 3.3.0-rc.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
@@ -2,8 +2,10 @@
2
2
 
3
3
  import * as Env from "./Env.res.mjs";
4
4
  import * as Utils from "./Utils.res.mjs";
5
+ import * as Internal from "./Internal.res.mjs";
5
6
  import * as Throttler from "./Throttler.res.mjs";
6
7
  import * as Prometheus from "./Prometheus.res.mjs";
8
+ import * as EffectState from "./EffectState.res.mjs";
7
9
  import * as IndexerState from "./IndexerState.res.mjs";
8
10
  import * as Stdlib_Array from "@rescript/runtime/lib/es6/Stdlib_Array.js";
9
11
  import * as InMemoryStore from "./InMemoryStore.res.mjs";
@@ -11,6 +13,7 @@ import * as InMemoryTable from "./InMemoryTable.res.mjs";
11
13
  import * as Stdlib_Option from "@rescript/runtime/lib/es6/Stdlib_Option.js";
12
14
  import * as RollbackCommit from "./RollbackCommit.res.mjs";
13
15
  import * as Stdlib_JsError from "@rescript/runtime/lib/es6/Stdlib_JsError.js";
16
+ import * as PruneStaleHistory from "./PruneStaleHistory.res.mjs";
14
17
  import * as Primitive_exceptions from "@rescript/runtime/lib/es6/Primitive_exceptions.js";
15
18
 
16
19
  function getChangesCount(state) {
@@ -20,7 +23,7 @@ function getChangesCount(state) {
20
23
  IndexerState.allEntities(state).forEach(entityConfig => {
21
24
  total.contents = total.contents + InMemoryStore.getInMemTable(state, entityConfig).changesCount;
22
25
  });
23
- Utils.Dict.forEach(IndexerState.effects(state), inMemTable => {
26
+ EffectState.forEach(IndexerState.effectState(state), inMemTable => {
24
27
  total.contents = total.contents + inMemTable.changesCount;
25
28
  });
26
29
  IndexerState.processedBatches(state).forEach(batch => {
@@ -35,10 +38,12 @@ function waitForCommit(state) {
35
38
 
36
39
  function snapshotEffects(state, cache) {
37
40
  let acc = [];
38
- Utils.Dict.forEach(IndexerState.effects(state), inMemTable => {
41
+ EffectState.forEach(IndexerState.effectState(state), inMemTable => {
39
42
  let idsToStore = inMemTable.idsToStore;
40
43
  let invalidationsCount = inMemTable.invalidationsCount;
41
44
  let dict = inMemTable.dict;
45
+ let table = inMemTable.table;
46
+ let scope = inMemTable.scope;
42
47
  let effect = inMemTable.effect;
43
48
  if (idsToStore.length !== 0) {
44
49
  let items = Stdlib_Array.filterMap(idsToStore, id => {
@@ -51,23 +56,27 @@ function snapshotEffects(state, cache) {
51
56
  }
52
57
  });
53
58
  let effectName = effect.name;
54
- let c = cache[effectName];
59
+ let tableName = table.tableName;
60
+ let c = cache[tableName];
55
61
  let effectCacheRecord;
56
62
  if (c !== undefined) {
57
63
  effectCacheRecord = c;
58
64
  } else {
59
65
  let c$1 = {
60
66
  effectName: effectName,
67
+ scope: scope,
68
+ tableName: tableName,
61
69
  count: 0
62
70
  };
63
- cache[effectName] = c$1;
71
+ cache[tableName] = c$1;
64
72
  effectCacheRecord = c$1;
65
73
  }
66
74
  let shouldInitialize = effectCacheRecord.count === 0;
67
75
  effectCacheRecord.count = (effectCacheRecord.count + items.length | 0) - invalidationsCount | 0;
68
- Prometheus.EffectCacheCount.set(effectCacheRecord.count, effectName);
76
+ Prometheus.EffectCacheCount.set(effectCacheRecord.count, effectName, Internal.EffectCache.scopeToString(scope));
69
77
  acc.push({
70
- effect: effect,
78
+ table: table,
79
+ itemSchema: effect.storageMeta.itemSchema,
71
80
  items: items,
72
81
  shouldInitialize: shouldInitialize
73
82
  });
@@ -111,11 +120,20 @@ async function runOneWrite(state) {
111
120
  }
112
121
  });
113
122
  let updatedEffectsCache = snapshotEffects(state, cache);
114
- await persistence.storage.writeBatch(batch, rollback, batch.isInReorgThreshold, config, persistence.allEntities, updatedEffectsCache, updatedEntities, chainMetaData);
123
+ let writtenEntityNames = new Set();
124
+ updatedEntities.forEach(param => {
125
+ writtenEntityNames.add(param.entityConfig.name);
126
+ });
127
+ let pruneTargets = PruneStaleHistory.select(state, writtenEntityNames, Stdlib_Option.isSome(rollback));
128
+ await Promise.all([
129
+ persistence.storage.writeBatch(batch, rollback, batch.isInReorgThreshold, config, persistence.allEntities, updatedEffectsCache, updatedEntities, chainMetaData),
130
+ PruneStaleHistory.runConcurrent(state, pruneTargets)
131
+ ]);
115
132
  IndexerState.markCommitted(state, upToCheckpointId);
116
133
  if (rollback !== undefined && Utils.$$Array.notEmpty(RollbackCommit.callbacks)) {
117
- return await RollbackCommit.fire(rollback.progressBlockNumberByChainId);
134
+ await RollbackCommit.fire(rollback.progressBlockNumberByChainId);
118
135
  }
136
+ return await PruneStaleHistory.runForced(state, pruneTargets);
119
137
  }
120
138
 
121
139
  function hasPendingWrite(state) {
@@ -164,7 +182,7 @@ function commitBatch(state, batch) {
164
182
  function dropCommitted(state, keepLoadedFromDb) {
165
183
  let committedCheckpointId = IndexerState.committedCheckpointId(state);
166
184
  IndexerState.allEntities(state).forEach(entityConfig => InMemoryTable.Entity.dropCommittedChanges(InMemoryStore.getInMemTable(state, entityConfig), committedCheckpointId, keepLoadedFromDb));
167
- Utils.Dict.forEach(IndexerState.effects(state), inMemTable => InMemoryStore.dropCommittedEffects(inMemTable, committedCheckpointId, keepLoadedFromDb));
185
+ EffectState.forEach(IndexerState.effectState(state), inMemTable => InMemoryStore.dropCommittedEffects(inMemTable, committedCheckpointId, keepLoadedFromDb));
168
186
  }
169
187
 
170
188
  async function awaitCapacity(state) {
@@ -173,5 +173,10 @@ module Fs = {
173
173
 
174
174
  @module("fs") @scope("promises")
175
175
  external readdir: Path.t => promise<array<string>> = "readdir"
176
+
177
+ type stats
178
+ @module("fs") @scope("promises")
179
+ external stat: Path.t => promise<stats> = "stat"
180
+ @send external statsIsDirectory: stats => bool = "isDirectory"
176
181
  }
177
182
  }
@@ -1,11 +1,6 @@
1
1
  type hex = EvmTypes.Hex.t
2
2
  @module("viem") external toHex: 'a => hex = "toHex"
3
- @module("viem") external keccak256: hex => hex = "keccak256"
4
3
  @module("viem") external pad: hex => hex = "pad"
5
4
 
6
5
  type sizeOptions = {size: int}
7
6
  @module("viem") external bigintToHex: (bigint, ~options: sizeOptions=?) => hex = "numberToHex"
8
- @module("viem") external stringToHex: (string, ~options: sizeOptions=?) => hex = "stringToHex"
9
- @module("viem") external boolToHex: (bool, ~options: sizeOptions=?) => hex = "boolToHex"
10
- @module("viem") external bytesToHex: (Uint8Array.t, ~options: sizeOptions=?) => hex = "bytesToHex"
11
- @module("viem") external concat: array<hex> => hex = "concat"
@@ -92,27 +92,6 @@ let get = (router: t<'a>, ~tag, ~contractAddress, ~contractNameByAddress) => {
92
92
  }
93
93
  }
94
94
 
95
- let getEvmEventId = (~sighash, ~topicCount) => {
96
- sighash ++ "_" ++ topicCount->Int.toString
97
- }
98
-
99
- let fromEvmEventModsOrThrow = (events: array<Internal.evmOnEventRegistration>, ~chain): t<
100
- Internal.evmOnEventRegistration,
101
- > => {
102
- let router = empty()
103
- events->Array.forEach(config => {
104
- router->addOrThrow(
105
- config.eventConfig.id,
106
- config,
107
- ~contractName=config.eventConfig.contractName,
108
- ~eventName=config.eventConfig.name,
109
- ~chain,
110
- ~isWildcard=config.isWildcard,
111
- )
112
- })
113
- router
114
- }
115
-
116
95
  /** Dispatch key for SVM instructions. `None` matches any instruction in the
117
96
  program (lowest priority). */
118
97
  let getSvmEventId = (~programId: SvmTypes.Pubkey.t, ~discriminator: option<string>) =>
@@ -97,16 +97,6 @@ function get$1(router, tag, contractAddress, contractNameByAddress) {
97
97
  }
98
98
  }
99
99
 
100
- function getEvmEventId(sighash, topicCount) {
101
- return sighash + "_" + topicCount.toString();
102
- }
103
-
104
- function fromEvmEventModsOrThrow(events, chain) {
105
- let router = {};
106
- events.forEach(config => addOrThrow$1(router, config.eventConfig.id, config, config.eventConfig.contractName, config.isWildcard, config.eventConfig.name, chain));
107
- return router;
108
- }
109
-
110
100
  function getSvmEventId(programId, discriminator) {
111
101
  if (discriminator !== undefined) {
112
102
  return programId + "_" + discriminator;
@@ -157,8 +147,6 @@ export {
157
147
  empty$1 as empty,
158
148
  addOrThrow$1 as addOrThrow,
159
149
  get$1 as get,
160
- getEvmEventId,
161
- fromEvmEventModsOrThrow,
162
150
  getSvmEventId,
163
151
  fromSvmEventConfigsOrThrow,
164
152
  }
@@ -39,25 +39,6 @@ let getSyncConfig = (
39
39
  }
40
40
  }
41
41
 
42
- let collectEventParams = (onEventRegistrations: array<Internal.evmOnEventRegistration>): array<
43
- HyperSyncClient.Decoder.eventParamsInput,
44
- > => {
45
- let result = []
46
- onEventRegistrations->Array.forEach(reg => {
47
- let event = reg.eventConfig->(Utils.magic: Internal.eventConfig => Internal.evmEventConfig)
48
- result
49
- ->Array.push({
50
- HyperSyncClient.Decoder.sighash: event.sighash,
51
- topicCount: event.topicCount,
52
- eventName: event.name,
53
- contractName: event.contractName,
54
- params: event.paramsMetadata,
55
- })
56
- ->ignore
57
- })
58
- result
59
- }
60
-
61
42
  let makeSources = (
62
43
  ~chain,
63
44
  ~onEventRegistrations: array<Internal.evmOnEventRegistration>,
@@ -65,17 +46,12 @@ let makeSources = (
65
46
  ~rpcs: array<rpc>,
66
47
  ~lowercaseAddresses,
67
48
  ) => {
68
- let eventRouter = onEventRegistrations->EventRouter.fromEvmEventModsOrThrow(~chain)
69
-
70
- let allEventParams = collectEventParams(onEventRegistrations)
71
-
72
49
  let sources = switch hyperSync {
73
50
  | Some(endpointUrl) => [
74
51
  HyperSyncSource.make({
75
52
  chain,
76
53
  endpointUrl,
77
- allEventParams,
78
- eventRouter,
54
+ onEventRegistrations,
79
55
  apiToken: Env.envioApiToken,
80
56
  clientTimeoutMillis: Env.hyperSyncClientTimeoutMillis,
81
57
  lowercaseAddresses,
@@ -92,8 +68,7 @@ let makeSources = (
92
68
  sourceFor,
93
69
  syncConfig: getSyncConfig(syncConfig->Option.getOr({})),
94
70
  url,
95
- eventRouter,
96
- allEventParams,
71
+ onEventRegistrations,
97
72
  lowercaseAddresses,
98
73
  ?ws,
99
74
  ?headers,
@@ -2,7 +2,6 @@
2
2
 
3
3
  import * as Env from "../Env.res.mjs";
4
4
  import * as RpcSource from "./RpcSource.res.mjs";
5
- import * as EventRouter from "./EventRouter.res.mjs";
6
5
  import * as Stdlib_Option from "@rescript/runtime/lib/es6/Stdlib_Option.js";
7
6
  import * as HyperSyncSource from "./HyperSyncSource.res.mjs";
8
7
 
@@ -20,29 +19,11 @@ function getSyncConfig(param) {
20
19
  };
21
20
  }
22
21
 
23
- function collectEventParams(onEventRegistrations) {
24
- let result = [];
25
- onEventRegistrations.forEach(reg => {
26
- let event = reg.eventConfig;
27
- result.push({
28
- sighash: event.sighash,
29
- topicCount: event.topicCount,
30
- eventName: event.name,
31
- contractName: event.contractName,
32
- params: event.paramsMetadata
33
- });
34
- });
35
- return result;
36
- }
37
-
38
22
  function makeSources(chain, onEventRegistrations, hyperSync, rpcs, lowercaseAddresses) {
39
- let eventRouter = EventRouter.fromEvmEventModsOrThrow(onEventRegistrations, chain);
40
- let allEventParams = collectEventParams(onEventRegistrations);
41
23
  let sources = hyperSync !== undefined ? [HyperSyncSource.make({
42
24
  chain: chain,
43
25
  endpointUrl: hyperSync,
44
- allEventParams: allEventParams,
45
- eventRouter: eventRouter,
26
+ onEventRegistrations: onEventRegistrations,
46
27
  apiToken: Env.envioApiToken,
47
28
  clientTimeoutMillis: Env.hyperSyncClientTimeoutMillis,
48
29
  lowercaseAddresses: lowercaseAddresses,
@@ -56,8 +37,7 @@ function makeSources(chain, onEventRegistrations, hyperSync, rpcs, lowercaseAddr
56
37
  syncConfig: getSyncConfig(Stdlib_Option.getOr(param.syncConfig, {})),
57
38
  url: param.url,
58
39
  chain: chain,
59
- eventRouter: eventRouter,
60
- allEventParams: allEventParams,
40
+ onEventRegistrations: onEventRegistrations,
61
41
  lowercaseAddresses: lowercaseAddresses,
62
42
  ws: param.ws,
63
43
  headers: param.headers
@@ -69,7 +49,6 @@ function makeSources(chain, onEventRegistrations, hyperSync, rpcs, lowercaseAddr
69
49
 
70
50
  export {
71
51
  getSyncConfig,
72
- collectEventParams,
73
52
  makeSources,
74
53
  }
75
54
  /* Env Not a pure module */
@@ -1,32 +1,51 @@
1
- type cfg = {url: string, httpReqTimeoutMillis?: int, headers?: dict<string>}
2
-
3
- // `addresses` omitted matches any address (a wildcard selection). Each `topics`
4
- // position is `null` (match any) or a list of accepted topic hashes; the
5
- // single-match case is a one-element list.
6
- type getLogsParams = {
7
- fromBlock: int,
8
- toBlock: int,
9
- addresses?: array<Address.t>,
10
- topics: array<Nullable.t<array<string>>>,
1
+ type cfg = {
2
+ url: string,
3
+ httpReqTimeoutMillis?: int,
4
+ headers?: dict<string>,
5
+ initialBlockInterval: int,
6
+ backoffMultiplicative: float,
7
+ accelerationAdditive: int,
8
+ intervalCeiling: int,
9
+ backoffMillis: int,
10
+ queryTimeoutMillis: int,
11
11
  }
12
12
 
13
- // Decoded `params` keyed by contract name, matching the HyperSync decoder's
14
- // shape so the caller routes by address then picks its contract's params.
13
+ // Only logs that resolved to a registration cross the boundary, each carrying
14
+ // its registration's chain-scoped index.
15
15
  type rpcEventItem = {
16
16
  log: Rpc.GetLogs.log,
17
- params: Nullable.t<dict<Internal.eventParams>>,
17
+ onEventRegistrationIndex: int,
18
+ params: Internal.eventParams,
19
+ }
20
+
21
+ type nextPageParams = {
22
+ fromBlock: int,
23
+ toBlockCeiling: int,
24
+ partitionId: string,
25
+ // The partition's registration selection, by chain-scoped index. Log
26
+ // selections and the routing index are derived on the Rust side from the
27
+ // registrations passed at construction.
28
+ registrationIndexes: array<int>,
29
+ addressesByContractName: dict<array<Address.t>>,
30
+ }
31
+
32
+ type nextPageResponse = {
33
+ items: array<rpcEventItem>,
34
+ toBlock: int,
35
+ requestStats: array<Source.requestStat>,
18
36
  }
19
37
 
38
+ // The caller provides a range; Rust decides the actual `toBlock` and returns it.
20
39
  type t = {
21
40
  getHeight: unit => promise<int>,
22
- getLogs: getLogsParams => promise<array<rpcEventItem>>,
41
+ getNextPage: nextPageParams => promise<nextPageResponse>,
23
42
  }
24
43
 
25
44
  @send
26
45
  external classNew: (
27
46
  Core.evmRpcClientCtor,
28
47
  cfg,
29
- array<HyperSyncClient.Decoder.eventParamsInput>,
48
+ array<HyperSyncClient.Registration.input>,
30
49
  ~checksumAddresses: bool,
31
50
  ) => t = "new"
32
51
 
@@ -59,15 +78,31 @@ let coerceErrorOrThrow = exn =>
59
78
  | None => exn->throw
60
79
  }
61
80
 
62
- let make = (~url, ~checksumAddresses, ~httpReqTimeoutMillis=?, ~headers=?, ~allEventParams=[]) => {
63
- let client =
64
- Core.getAddon().evmRpcClient->classNew(
65
- {url, ?httpReqTimeoutMillis, ?headers},
66
- allEventParams,
67
- ~checksumAddresses,
68
- )
81
+ let make = (
82
+ ~url,
83
+ ~checksumAddresses,
84
+ ~syncConfig: Config.sourceSync,
85
+ ~httpReqTimeoutMillis=?,
86
+ ~headers=?,
87
+ ~eventRegistrations=[],
88
+ ) => {
89
+ let client = Core.getAddon().evmRpcClient->classNew(
90
+ {
91
+ url,
92
+ ?httpReqTimeoutMillis,
93
+ ?headers,
94
+ initialBlockInterval: syncConfig.initialBlockInterval,
95
+ backoffMultiplicative: syncConfig.backoffMultiplicative,
96
+ accelerationAdditive: syncConfig.accelerationAdditive,
97
+ intervalCeiling: syncConfig.intervalCeiling,
98
+ backoffMillis: syncConfig.backoffMillis,
99
+ queryTimeoutMillis: syncConfig.queryTimeoutMillis,
100
+ },
101
+ eventRegistrations,
102
+ ~checksumAddresses,
103
+ )
69
104
  {
70
105
  getHeight: () => client.getHeight()->Promise.catch(coerceErrorOrThrow),
71
- getLogs: params => client.getLogs(params)->Promise.catch(coerceErrorOrThrow),
106
+ getNextPage: params => client.getNextPage(params)->Promise.catch(coerceErrorOrThrow),
72
107
  }
73
108
  }
@@ -46,16 +46,22 @@ function coerceErrorOrThrow(exn) {
46
46
  throw exn;
47
47
  }
48
48
 
49
- function make(url, checksumAddresses, httpReqTimeoutMillis, headers, allEventParamsOpt) {
50
- let allEventParams = allEventParamsOpt !== undefined ? allEventParamsOpt : [];
49
+ function make(url, checksumAddresses, syncConfig, httpReqTimeoutMillis, headers, eventRegistrationsOpt) {
50
+ let eventRegistrations = eventRegistrationsOpt !== undefined ? eventRegistrationsOpt : [];
51
51
  let client = Core.getAddon().EvmRpcClient.new({
52
52
  url: url,
53
53
  httpReqTimeoutMillis: httpReqTimeoutMillis,
54
- headers: headers
55
- }, allEventParams, checksumAddresses);
54
+ headers: headers,
55
+ initialBlockInterval: syncConfig.initialBlockInterval,
56
+ backoffMultiplicative: syncConfig.backoffMultiplicative,
57
+ accelerationAdditive: syncConfig.accelerationAdditive,
58
+ intervalCeiling: syncConfig.intervalCeiling,
59
+ backoffMillis: syncConfig.backoffMillis,
60
+ queryTimeoutMillis: syncConfig.queryTimeoutMillis
61
+ }, eventRegistrations, checksumAddresses);
56
62
  return {
57
63
  getHeight: () => Stdlib_Promise.$$catch(client.getHeight(), coerceErrorOrThrow),
58
- getLogs: params => Stdlib_Promise.$$catch(client.getLogs(params), coerceErrorOrThrow)
64
+ getNextPage: params => Stdlib_Promise.$$catch(client.getNextPage(params), coerceErrorOrThrow)
59
65
  };
60
66
  }
61
67
 
@@ -61,23 +61,6 @@ module GetLogs = {
61
61
 
62
62
  exception Error(error)
63
63
 
64
- let makeRequestBody = (
65
- ~fromBlock,
66
- ~toBlockInclusive,
67
- ~addressesWithTopics,
68
- ~fieldSelection,
69
- ~maxNumLogs,
70
- ): HyperSyncClient.QueryTypes.query => {
71
- fromBlock,
72
- toBlockExclusive: ?switch toBlockInclusive {
73
- | Some(toBlockInclusive) => Some(toBlockInclusive + 1)
74
- | None => None
75
- },
76
- logs: addressesWithTopics,
77
- fieldSelection,
78
- maxNumLogs,
79
- }
80
-
81
64
  // Rust encodes structured failures as a JSON payload in the napi error's
82
65
  // message: `{"kind":"MissingFields","fields":["block.timestamp", ...]}`.
83
66
  // JSON.parse + shape check is the recovery protocol — no string-grepping
@@ -107,29 +90,17 @@ module GetLogs = {
107
90
  ~client: HyperSyncClient.t,
108
91
  ~fromBlock,
109
92
  ~toBlock,
110
- ~logSelections: array<LogSelection.t>,
111
- ~fieldSelection,
112
93
  ~maxNumLogs,
94
+ ~registrationIndexes,
95
+ ~addressesByContractName,
113
96
  ): logsQueryPage => {
114
- let addressesWithTopics = logSelections->Array.flatMap(({addresses, topicSelections}) =>
115
- topicSelections->Array.map(({topic0, topic1, topic2, topic3}) => {
116
- let topics = HyperSyncClient.QueryTypes.makeTopicSelection(
117
- ~topic0,
118
- ~topic1,
119
- ~topic2,
120
- ~topic3,
121
- )
122
- HyperSyncClient.QueryTypes.makeLogSelection(~address=addresses, ~topics)
123
- })
124
- )
125
-
126
- let query = makeRequestBody(
127
- ~fromBlock,
128
- ~toBlockInclusive=toBlock,
129
- ~addressesWithTopics,
130
- ~fieldSelection,
131
- ~maxNumLogs,
132
- )
97
+ let query: HyperSyncClient.EventItems.query = {
98
+ fromBlock,
99
+ toBlock,
100
+ maxNumLogs,
101
+ registrationIndexes,
102
+ addressesByContractName,
103
+ }
133
104
 
134
105
  let (res, transactionStore, blockStore) = switch await client.getEventItems(~query) {
135
106
  | res => res
@@ -12,7 +12,6 @@ import * as Stdlib_JsExn from "@rescript/runtime/lib/es6/Stdlib_JsExn.js";
12
12
  import * as Stdlib_Option from "@rescript/runtime/lib/es6/Stdlib_Option.js";
13
13
  import * as Stdlib_Result from "@rescript/runtime/lib/es6/Stdlib_Result.js";
14
14
  import * as Stdlib_JsError from "@rescript/runtime/lib/es6/Stdlib_JsError.js";
15
- import * as HyperSyncClient from "./HyperSyncClient.res.mjs";
16
15
  import * as Primitive_exceptions from "@rescript/runtime/lib/es6/Primitive_exceptions.js";
17
16
 
18
17
  function reraisIfRateLimited(exn) {
@@ -62,16 +61,6 @@ function mapExn(queryResponse) {
62
61
 
63
62
  let $$Error = /* @__PURE__ */Primitive_exceptions.create("HyperSync.GetLogs.Error");
64
63
 
65
- function makeRequestBody(fromBlock, toBlockInclusive, addressesWithTopics, fieldSelection, maxNumLogs) {
66
- return {
67
- fromBlock: fromBlock,
68
- toBlock: toBlockInclusive !== undefined ? toBlockInclusive + 1 | 0 : undefined,
69
- logs: addressesWithTopics,
70
- fieldSelection: fieldSelection,
71
- maxNumLogs: maxNumLogs
72
- };
73
- }
74
-
75
64
  function extractMissingParams(exn) {
76
65
  let message = exn.RE_EXN_ID === "JsExn" ? Stdlib_JsExn.message(exn._1) : undefined;
77
66
  if (message === undefined) {
@@ -93,15 +82,14 @@ function extractMissingParams(exn) {
93
82
  }
94
83
  }
95
84
 
96
- async function query(client, fromBlock, toBlock, logSelections, fieldSelection, maxNumLogs) {
97
- let addressesWithTopics = logSelections.flatMap(param => {
98
- let addresses = param.addresses;
99
- return param.topicSelections.map(param => {
100
- let topics = HyperSyncClient.QueryTypes.makeTopicSelection(param.topic0, param.topic1, param.topic2, param.topic3);
101
- return HyperSyncClient.QueryTypes.makeLogSelection(addresses, topics);
102
- });
103
- });
104
- let query$1 = makeRequestBody(fromBlock, toBlock, addressesWithTopics, fieldSelection, maxNumLogs);
85
+ async function query(client, fromBlock, toBlock, maxNumLogs, registrationIndexes, addressesByContractName) {
86
+ let query$1 = {
87
+ fromBlock: fromBlock,
88
+ toBlock: toBlock,
89
+ maxNumLogs: maxNumLogs,
90
+ registrationIndexes: registrationIndexes,
91
+ addressesByContractName: addressesByContractName
92
+ };
105
93
  let match;
106
94
  try {
107
95
  match = await client.getEventItems(query$1);
@@ -140,7 +128,13 @@ async function query(client, fromBlock, toBlock, logSelections, fieldSelection,
140
128
  };
141
129
  }
142
130
 
143
- function makeRequestBody$1(fromBlock, toBlock) {
131
+ let GetLogs = {
132
+ $$Error: $$Error,
133
+ extractMissingParams: extractMissingParams,
134
+ query: query
135
+ };
136
+
137
+ function makeRequestBody(fromBlock, toBlock) {
144
138
  return {
145
139
  fromBlock: fromBlock,
146
140
  toBlock: toBlock + 1 | 0,
@@ -193,7 +187,7 @@ function convertResponse(res) {
193
187
  }
194
188
 
195
189
  async function queryBlockData(client, fromBlock, toBlock, sourceName, chainId, logger, requestStats) {
196
- let body = makeRequestBody$1(fromBlock, toBlock);
190
+ let body = makeRequestBody(fromBlock, toBlock);
197
191
  let logger$1 = Logging.createChildFrom(logger, {
198
192
  logType: "HyperSync get block hash query",
199
193
  fromBlock: fromBlock,
@@ -282,12 +276,6 @@ function queryBlockData$1(client, blockNumber, sourceName, chainId, logger) {
282
276
  ]);
283
277
  }
284
278
 
285
- let GetLogs = {
286
- $$Error: $$Error,
287
- extractMissingParams: extractMissingParams,
288
- query: query
289
- };
290
-
291
279
  export {
292
280
  queryErrorToMsq,
293
281
  GetLogs,
@@ -32,9 +32,9 @@ module GetLogs: {
32
32
  ~client: HyperSyncClient.t,
33
33
  ~fromBlock: int,
34
34
  ~toBlock: option<int>,
35
- ~logSelections: array<LogSelection.t>,
36
- ~fieldSelection: HyperSyncClient.QueryTypes.fieldSelection,
37
35
  ~maxNumLogs: int,
36
+ ~registrationIndexes: array<int>,
37
+ ~addressesByContractName: dict<array<Address.t>>,
38
38
  ) => promise<logsQueryPage>
39
39
  }
40
40