envio 3.3.0-alpha.7 → 3.3.0-alpha.8

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 (89) hide show
  1. package/index.d.ts +23 -5
  2. package/package.json +6 -6
  3. package/src/Api.res +1 -1
  4. package/src/Api.res.mjs +1 -1
  5. package/src/ChainFetching.res +21 -10
  6. package/src/ChainFetching.res.mjs +11 -10
  7. package/src/ChainState.res +328 -165
  8. package/src/ChainState.res.mjs +205 -100
  9. package/src/ChainState.resi +16 -7
  10. package/src/Config.res +11 -27
  11. package/src/Config.res.mjs +8 -7
  12. package/src/Core.res +7 -0
  13. package/src/CrossChainState.res +53 -80
  14. package/src/CrossChainState.res.mjs +43 -59
  15. package/src/CrossChainState.resi +1 -1
  16. package/src/Ecosystem.res +3 -3
  17. package/src/Ecosystem.res.mjs +3 -3
  18. package/src/Envio.res +14 -9
  19. package/src/EventConfigBuilder.res +105 -56
  20. package/src/EventConfigBuilder.res.mjs +69 -33
  21. package/src/EventProcessing.res +19 -15
  22. package/src/EventProcessing.res.mjs +13 -12
  23. package/src/FetchState.res +375 -171
  24. package/src/FetchState.res.mjs +249 -251
  25. package/src/HandlerLoader.res +7 -112
  26. package/src/HandlerLoader.res.mjs +1 -87
  27. package/src/HandlerRegister.res +209 -6
  28. package/src/HandlerRegister.res.mjs +90 -5
  29. package/src/HandlerRegister.resi +13 -2
  30. package/src/IndexerState.res +6 -3
  31. package/src/IndexerState.res.mjs +3 -3
  32. package/src/IndexerState.resi +1 -1
  33. package/src/IndexingAddresses.res +10 -7
  34. package/src/IndexingAddresses.res.mjs +8 -7
  35. package/src/IndexingAddresses.resi +3 -1
  36. package/src/Internal.res +82 -36
  37. package/src/Internal.res.mjs +11 -1
  38. package/src/Main.res +22 -23
  39. package/src/Main.res.mjs +15 -17
  40. package/src/Metrics.res +43 -2
  41. package/src/Metrics.res.mjs +39 -3
  42. package/src/Prometheus.res +0 -35
  43. package/src/Prometheus.res.mjs +33 -68
  44. package/src/RawEvent.res +7 -2
  45. package/src/RawEvent.res.mjs +4 -4
  46. package/src/SimulateItems.res +20 -7
  47. package/src/SimulateItems.res.mjs +7 -11
  48. package/src/TestIndexer.res +1 -1
  49. package/src/TestIndexer.res.mjs +1 -1
  50. package/src/sources/BlockStore.res +46 -0
  51. package/src/sources/BlockStore.res.mjs +24 -0
  52. package/src/sources/EventRouter.res +19 -12
  53. package/src/sources/EventRouter.res.mjs +7 -5
  54. package/src/sources/Evm.res +54 -4
  55. package/src/sources/Evm.res.mjs +43 -4
  56. package/src/sources/EvmChain.res +14 -18
  57. package/src/sources/EvmChain.res.mjs +12 -13
  58. package/src/sources/FieldMask.res +39 -0
  59. package/src/sources/FieldMask.res.mjs +42 -0
  60. package/src/sources/Fuel.res +5 -2
  61. package/src/sources/Fuel.res.mjs +4 -3
  62. package/src/sources/HyperFuelSource.res +31 -40
  63. package/src/sources/HyperFuelSource.res.mjs +52 -44
  64. package/src/sources/HyperSync.res +31 -9
  65. package/src/sources/HyperSync.res.mjs +47 -31
  66. package/src/sources/HyperSync.resi +10 -3
  67. package/src/sources/HyperSyncClient.res +15 -4
  68. package/src/sources/HyperSyncHeightStream.res +1 -8
  69. package/src/sources/HyperSyncHeightStream.res.mjs +0 -2
  70. package/src/sources/HyperSyncSource.res +37 -58
  71. package/src/sources/HyperSyncSource.res.mjs +42 -42
  72. package/src/sources/RpcSource.res +91 -82
  73. package/src/sources/RpcSource.res.mjs +76 -45
  74. package/src/sources/RpcWebSocketHeightStream.res +0 -5
  75. package/src/sources/RpcWebSocketHeightStream.res.mjs +0 -2
  76. package/src/sources/SimulateSource.res +5 -3
  77. package/src/sources/SimulateSource.res.mjs +12 -4
  78. package/src/sources/Source.res +19 -5
  79. package/src/sources/SourceManager.res +62 -6
  80. package/src/sources/SourceManager.res.mjs +55 -8
  81. package/src/sources/SourceManager.resi +10 -0
  82. package/src/sources/Svm.res +14 -10
  83. package/src/sources/Svm.res.mjs +23 -6
  84. package/src/sources/SvmHyperSyncClient.res +5 -6
  85. package/src/sources/SvmHyperSyncSource.res +82 -41
  86. package/src/sources/SvmHyperSyncSource.res.mjs +86 -41
  87. package/src/sources/TransactionStore.res +6 -107
  88. package/src/sources/TransactionStore.res.mjs +5 -86
  89. package/svm.schema.json +19 -0
package/index.d.ts CHANGED
@@ -979,13 +979,24 @@ export type SvmInstructionParams = {
979
979
  readonly extraAccounts: readonly string[];
980
980
  };
981
981
 
982
- /** Block context for a matched instruction. */
982
+ /** Permissive fallback shape for an instruction's `block`. The generated
983
+ * per-instruction type narrows this to `slot`/`hash` (always present) and
984
+ * `time` (always present but possibly `undefined`), plus the selected
985
+ * `field_selection.block_fields`. */
983
986
  export type SvmInstructionBlock = {
984
987
  /** Slot this instruction's block was matched in. */
985
988
  readonly slot: number;
986
- readonly time: number;
987
- /** Always empty for now — reserved for the future reorg-guard route. */
989
+ /** Unix block time (seconds). Absent when HyperSync/Solana doesn't report a
990
+ * block time for this slot. */
991
+ readonly time?: number;
992
+ /** Block hash. */
988
993
  readonly hash: string;
994
+ /** Block height. Select via `field_selection.block_fields`. */
995
+ readonly height?: number;
996
+ /** Parent slot. Select via `field_selection.block_fields`. */
997
+ readonly parentSlot?: number;
998
+ /** Parent block hash. Select via `field_selection.block_fields`. */
999
+ readonly parentHash?: string;
989
1000
  };
990
1001
 
991
1002
  export type SvmTokenBalance = {
@@ -1016,6 +1027,7 @@ export type SvmLog = {
1016
1027
  export type SvmInstruction<
1017
1028
  Params extends SvmInstructionParams = SvmInstructionParams,
1018
1029
  Tx = SvmTransaction,
1030
+ Block = SvmInstructionBlock,
1019
1031
  > = {
1020
1032
  /** Program name as declared under `programs[].name` in `config.yaml`. */
1021
1033
  readonly programName: string;
@@ -1041,7 +1053,12 @@ export type SvmInstruction<
1041
1053
  /** Present when the instruction's `include_logs` is `true`; only logs
1042
1054
  * scoped to this exact instruction (matching `instruction_address`). */
1043
1055
  readonly logs?: readonly SvmLog[];
1044
- readonly block: SvmInstructionBlock;
1056
+ /** The block this instruction's slot belongs to. Carries `slot`/`hash`
1057
+ * (always present) and `time` (always present but possibly `undefined`),
1058
+ * plus the fields selected via this instruction's
1059
+ * `field_selection.block_fields`; unselected fields are typed as
1060
+ * `FieldNotSelected<...>`. */
1061
+ readonly block: Block;
1045
1062
  };
1046
1063
 
1047
1064
  /** Arguments passed to handlers registered via `indexer.onInstruction`. */
@@ -1315,7 +1332,8 @@ type SvmEcosystem<Config extends IndexerConfigTypes = GlobalConfig> =
1315
1332
  Config,
1316
1333
  SvmInstruction<
1317
1334
  SvmParamsFromProgramTable<Programs[P][I]>,
1318
- Programs[P][I]["transaction"]
1335
+ Programs[P][I]["transaction"],
1336
+ Programs[P][I]["block"]
1319
1337
  >
1320
1338
  >,
1321
1339
  ) => Promise<void>,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "envio",
3
- "version": "3.3.0-alpha.7",
3
+ "version": "3.3.0-alpha.8",
4
4
  "type": "module",
5
5
  "description": "A latency and sync speed optimized, developer friendly blockchain data indexer.",
6
6
  "bin": "./bin.mjs",
@@ -69,10 +69,10 @@
69
69
  "tsx": "4.21.0"
70
70
  },
71
71
  "optionalDependencies": {
72
- "envio-linux-x64": "3.3.0-alpha.7",
73
- "envio-linux-x64-musl": "3.3.0-alpha.7",
74
- "envio-linux-arm64": "3.3.0-alpha.7",
75
- "envio-darwin-x64": "3.3.0-alpha.7",
76
- "envio-darwin-arm64": "3.3.0-alpha.7"
72
+ "envio-linux-x64": "3.3.0-alpha.8",
73
+ "envio-linux-x64-musl": "3.3.0-alpha.8",
74
+ "envio-linux-arm64": "3.3.0-alpha.8",
75
+ "envio-darwin-x64": "3.3.0-alpha.8",
76
+ "envio-darwin-arm64": "3.3.0-alpha.8"
77
77
  }
78
78
  }
package/src/Api.res CHANGED
@@ -9,7 +9,7 @@ let createTestIndexer: unit => unknown = () => {
9
9
  NodeJs.Path.getDirname(NodeJs.ImportMeta.importMeta),
10
10
  "TestIndexerWorker.res.mjs",
11
11
  )->NodeJs.Path.toString
12
- TestIndexer.makeCreateTestIndexer(~config=Config.loadWithoutRegistrations(), ~workerPath)()->(
12
+ TestIndexer.makeCreateTestIndexer(~config=Config.load(), ~workerPath)()->(
13
13
  Utils.magic: TestIndexer.t<'a> => unknown
14
14
  )
15
15
  }
package/src/Api.res.mjs CHANGED
@@ -10,7 +10,7 @@ let indexer = Main.getGlobalIndexer();
10
10
 
11
11
  function createTestIndexer() {
12
12
  let workerPath = Path.join(NodeJs.Path.getDirname(import.meta), "TestIndexerWorker.res.mjs");
13
- return TestIndexer.makeCreateTestIndexer(Config.loadWithoutRegistrations(), workerPath)();
13
+ return TestIndexer.makeCreateTestIndexer(Config.load(), workerPath)();
14
14
  }
15
15
 
16
16
  export {
@@ -11,12 +11,18 @@ type partitionQueryResponse = {
11
11
  let runContractRegistersOrThrow = async (
12
12
  ~itemsWithContractRegister: array<Internal.item>,
13
13
  ~config: Config.t,
14
- ~page: option<TransactionStore.t>,
14
+ ~transactionStore: option<TransactionStore.t>,
15
+ ~blockStore: option<BlockStore.t>,
15
16
  ) => {
16
- // contractRegister handlers can read event.transaction, so materialise the
17
- // selected fields onto the payloads before running them. All items belong to
18
- // the chain being fetched, hence its single page store and mask.
19
- await ChainState.materializePageItems(~items=itemsWithContractRegister, ~page)
17
+ // contractRegister handlers can read event.transaction and event.block, so
18
+ // materialise the selected fields onto the payloads before running them. All
19
+ // items belong to the chain being fetched, hence its single page stores.
20
+ await ChainState.materializePageItems(
21
+ ~items=itemsWithContractRegister,
22
+ ~transactionStore,
23
+ ~blockStore,
24
+ ~ecosystem=config.ecosystem.name,
25
+ )
20
26
 
21
27
  let itemsWithDcs = []
22
28
 
@@ -44,8 +50,8 @@ let runContractRegistersOrThrow = async (
44
50
  let item = itemsWithContractRegister->Array.getUnsafe(idx)
45
51
  let eventItem = item->Internal.castUnsafeEventItem
46
52
  let contractRegister = switch eventItem {
47
- | {eventConfig: {contractRegister: Some(contractRegister)}} => contractRegister
48
- | {eventConfig: {contractRegister: None, name: eventName}} =>
53
+ | {onEventRegistration: {contractRegister: Some(contractRegister)}} => contractRegister
54
+ | {onEventRegistration: {contractRegister: None, eventConfig: {name: eventName}}} =>
49
55
  // Unexpected case, since we should pass only events with contract register to this function
50
56
  JsError.throwWithMessage("Contract register is not set for event " ++ eventName)
51
57
  }
@@ -113,6 +119,7 @@ let rec onQueryResponse = async (
113
119
  let {
114
120
  parsedQueueItems,
115
121
  transactionStore,
122
+ blockStore,
116
123
  latestFetchedBlockNumber,
117
124
  latestFetchedBlockTimestamp,
118
125
  stats,
@@ -142,7 +149,7 @@ let rec onQueryResponse = async (
142
149
 
143
150
  let numContractRegisterEvents = parsedQueueItems->Array.reduce(0, (count, item) => {
144
151
  let eventItem = item->Internal.castUnsafeEventItem
145
- eventItem.eventConfig.contractRegister !== None ? count + 1 : count
152
+ eventItem.onEventRegistration.contractRegister !== None ? count + 1 : count
146
153
  })
147
154
  Logging.trace({
148
155
  "msg": "Finished querying",
@@ -210,7 +217,7 @@ let rec onQueryResponse = async (
210
217
  for idx in 0 to parsedQueueItems->Array.length - 1 {
211
218
  let item = parsedQueueItems->Array.getUnsafe(idx)
212
219
  let eventItem = item->Internal.castUnsafeEventItem
213
- if eventItem.eventConfig.contractRegister !== None {
220
+ if eventItem.onEventRegistration.contractRegister !== None {
214
221
  itemsWithContractRegister->Array.push(item)
215
222
  }
216
223
  // TODO: Don't really need to keep it in the queue
@@ -234,6 +241,7 @@ let rec onQueryResponse = async (
234
241
  },
235
242
  ~query,
236
243
  ~transactionStore,
244
+ ~blockStore,
237
245
  )
238
246
  ChainMetadata.stage(state)
239
247
  scheduleFetch()
@@ -246,7 +254,8 @@ let rec onQueryResponse = async (
246
254
  switch await runContractRegistersOrThrow(
247
255
  ~itemsWithContractRegister,
248
256
  ~config=state->IndexerState.config,
249
- ~page=transactionStore,
257
+ ~transactionStore,
258
+ ~blockStore,
250
259
  ) {
251
260
  | exception exn => IndexerState.errorExit(state, exn->ErrorHandling.make)
252
261
  | newItemsWithDcs => proceed(~newItemsWithDcs)
@@ -264,6 +273,7 @@ and applyQueryResponse = (
264
273
  ~latestFetchedBlock,
265
274
  ~query,
266
275
  ~transactionStore,
276
+ ~blockStore,
267
277
  ) => {
268
278
  let chainState = state->IndexerState.getChainState(~chain)
269
279
  let wasFetchingAtHead = chainState->ChainState.isFetchingAtHead
@@ -275,6 +285,7 @@ and applyQueryResponse = (
275
285
  ~newItemsWithDcs,
276
286
  ~knownHeight,
277
287
  ~transactionStore,
288
+ ~blockStore,
278
289
  )
279
290
 
280
291
  // In auto-exit mode, set endBlock to the first event's block when events arrive.
@@ -17,8 +17,8 @@ import * as Stdlib_Promise from "@rescript/runtime/lib/es6/Stdlib_Promise.js";
17
17
  import * as Primitive_exceptions from "@rescript/runtime/lib/es6/Primitive_exceptions.js";
18
18
  import * as ContractRegisterContext from "./ContractRegisterContext.res.mjs";
19
19
 
20
- async function runContractRegistersOrThrow(itemsWithContractRegister, config, page) {
21
- await ChainState.materializePageItems(itemsWithContractRegister, page);
20
+ async function runContractRegistersOrThrow(itemsWithContractRegister, config, transactionStore, blockStore) {
21
+ await ChainState.materializePageItems(itemsWithContractRegister, transactionStore, blockStore, config.ecosystem.name);
22
22
  let itemsWithDcs = [];
23
23
  let onRegister = (item, contractAddress, contractName) => {
24
24
  let dc_registrationBlock = item.blockNumber;
@@ -38,9 +38,9 @@ async function runContractRegistersOrThrow(itemsWithContractRegister, config, pa
38
38
  let promises = [];
39
39
  for (let idx = 0, idx_finish = itemsWithContractRegister.length; idx < idx_finish; ++idx) {
40
40
  let item = itemsWithContractRegister[idx];
41
- let match = item.eventConfig;
41
+ let match = item.onEventRegistration;
42
42
  let contractRegister = match.contractRegister;
43
- let contractRegister$1 = contractRegister !== undefined ? contractRegister : Stdlib_JsError.throwWithMessage("Contract register is not set for event " + match.name);
43
+ let contractRegister$1 = contractRegister !== undefined ? contractRegister : Stdlib_JsError.throwWithMessage("Contract register is not set for event " + match.eventConfig.name);
44
44
  let errorMessage = "Event contractRegister failed, please fix the error to keep the indexer running smoothly";
45
45
  try {
46
46
  let params = {
@@ -72,10 +72,10 @@ async function runContractRegistersOrThrow(itemsWithContractRegister, config, pa
72
72
  return itemsWithDcs;
73
73
  }
74
74
 
75
- function applyQueryResponse(state, chain, newItems, newItemsWithDcs, knownHeight, latestFetchedBlock, query, transactionStore) {
75
+ function applyQueryResponse(state, chain, newItems, newItemsWithDcs, knownHeight, latestFetchedBlock, query, transactionStore, blockStore) {
76
76
  let chainState = IndexerState.getChainState(state, chain);
77
77
  let wasFetchingAtHead = ChainState.isFetchingAtHead(chainState);
78
- ChainState.handleQueryResult(chainState, query, newItems, newItemsWithDcs, latestFetchedBlock, knownHeight, transactionStore);
78
+ ChainState.handleQueryResult(chainState, query, newItems, newItemsWithDcs, latestFetchedBlock, knownHeight, transactionStore, blockStore);
79
79
  if (IndexerState.exitAfterFirstEventBlock(state) && newItems.length !== 0) {
80
80
  ChainState.setEndBlockToFirstEvent(chainState, newItems[0].blockNumber);
81
81
  }
@@ -96,6 +96,7 @@ async function onQueryResponse(state, param, stateId, scheduleFetch, schedulePro
96
96
  let latestFetchedBlockTimestamp = response.latestFetchedBlockTimestamp;
97
97
  let latestFetchedBlockNumber = response.latestFetchedBlockNumber;
98
98
  let fromBlockQueried = response.fromBlockQueried;
99
+ let blockStore = response.blockStore;
99
100
  let transactionStore = response.transactionStore;
100
101
  let parsedQueueItems = response.parsedQueueItems;
101
102
  let knownHeight = response.knownHeight;
@@ -104,7 +105,7 @@ async function onQueryResponse(state, param, stateId, scheduleFetch, schedulePro
104
105
  }
105
106
  Prometheus.FetchingBlockRange.increment(chain, stats["total time elapsed (s)"], Stdlib_Option.getOr(stats["parsing time (s)"], 0), parsedQueueItems.length, (latestFetchedBlockNumber - fromBlockQueried | 0) + 1 | 0);
106
107
  let numContractRegisterEvents = Stdlib_Array.reduce(parsedQueueItems, 0, (count, item) => {
107
- if (item.eventConfig.contractRegister !== undefined) {
108
+ if (item.onEventRegistration.contractRegister !== undefined) {
108
109
  return count + 1 | 0;
109
110
  } else {
110
111
  return count;
@@ -142,7 +143,7 @@ async function onQueryResponse(state, param, stateId, scheduleFetch, schedulePro
142
143
  let newItems = [];
143
144
  for (let idx = 0, idx_finish = parsedQueueItems.length; idx < idx_finish; ++idx) {
144
145
  let item = parsedQueueItems[idx];
145
- if (item.eventConfig.contractRegister !== undefined) {
146
+ if (item.onEventRegistration.contractRegister !== undefined) {
146
147
  itemsWithContractRegister.push(item);
147
148
  }
148
149
  newItems.push(item);
@@ -152,7 +153,7 @@ async function onQueryResponse(state, param, stateId, scheduleFetch, schedulePro
152
153
  applyQueryResponse(state, chain, newItems, newItemsWithDcs, knownHeight, {
153
154
  blockNumber: latestFetchedBlockNumber,
154
155
  blockTimestamp: latestFetchedBlockTimestamp
155
- }, query, transactionStore);
156
+ }, query, transactionStore, blockStore);
156
157
  ChainMetadata.stage(state);
157
158
  scheduleFetch();
158
159
  return scheduleProcessing();
@@ -163,7 +164,7 @@ async function onQueryResponse(state, param, stateId, scheduleFetch, schedulePro
163
164
  }
164
165
  let newItemsWithDcs;
165
166
  try {
166
- newItemsWithDcs = await runContractRegistersOrThrow(itemsWithContractRegister, IndexerState.config(state), transactionStore);
167
+ newItemsWithDcs = await runContractRegistersOrThrow(itemsWithContractRegister, IndexerState.config(state), transactionStore, blockStore);
167
168
  } catch (raw_exn) {
168
169
  let exn = Primitive_exceptions.internalToException(raw_exn);
169
170
  return IndexerState.errorExit(state, ErrorHandling.make(exn, undefined, undefined));