envio 3.3.0-alpha.1 → 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 (143) hide show
  1. package/evm.schema.json +10 -0
  2. package/index.d.ts +45 -25
  3. package/licenses/CLA.md +35 -0
  4. package/licenses/EULA.md +67 -0
  5. package/licenses/LICENSE.md +45 -0
  6. package/licenses/README.md +35 -0
  7. package/package.json +10 -9
  8. package/src/Address.res +5 -2
  9. package/src/Address.res.mjs +3 -1
  10. package/src/Api.res +1 -1
  11. package/src/Api.res.mjs +1 -1
  12. package/src/Batch.res +0 -6
  13. package/src/Batch.res.mjs +1 -12
  14. package/src/BatchProcessing.res +7 -12
  15. package/src/BatchProcessing.res.mjs +8 -7
  16. package/src/Bin.res +3 -0
  17. package/src/Bin.res.mjs +4 -0
  18. package/src/ChainFetching.res +53 -16
  19. package/src/ChainFetching.res.mjs +37 -19
  20. package/src/ChainMetadata.res +1 -11
  21. package/src/ChainMetadata.res.mjs +1 -10
  22. package/src/ChainState.res +630 -161
  23. package/src/ChainState.res.mjs +438 -101
  24. package/src/ChainState.resi +77 -4
  25. package/src/Config.res +70 -38
  26. package/src/Config.res.mjs +52 -12
  27. package/src/ContractRegisterContext.res +2 -12
  28. package/src/ContractRegisterContext.res.mjs +3 -5
  29. package/src/Core.res +34 -3
  30. package/src/Core.res.mjs +12 -0
  31. package/src/CrossChainState.res +130 -89
  32. package/src/CrossChainState.res.mjs +66 -61
  33. package/src/CrossChainState.resi +1 -1
  34. package/src/Ecosystem.res +5 -6
  35. package/src/Ecosystem.res.mjs +3 -3
  36. package/src/Envio.res +17 -11
  37. package/src/EnvioGlobal.res +53 -0
  38. package/src/EnvioGlobal.res.mjs +31 -0
  39. package/src/EventConfigBuilder.res +191 -127
  40. package/src/EventConfigBuilder.res.mjs +116 -66
  41. package/src/EventProcessing.res +77 -28
  42. package/src/EventProcessing.res.mjs +56 -29
  43. package/src/ExitOnCaughtUp.res +10 -2
  44. package/src/ExitOnCaughtUp.res.mjs +10 -1
  45. package/src/FetchState.res +684 -415
  46. package/src/FetchState.res.mjs +505 -486
  47. package/src/HandlerLoader.res +8 -104
  48. package/src/HandlerLoader.res.mjs +2 -81
  49. package/src/HandlerRegister.res +520 -144
  50. package/src/HandlerRegister.res.mjs +286 -133
  51. package/src/HandlerRegister.resi +24 -8
  52. package/src/IndexerState.res +10 -3
  53. package/src/IndexerState.res.mjs +11 -4
  54. package/src/IndexerState.resi +2 -1
  55. package/src/IndexingAddresses.res +108 -0
  56. package/src/IndexingAddresses.res.mjs +101 -0
  57. package/src/IndexingAddresses.resi +34 -0
  58. package/src/Internal.res +166 -48
  59. package/src/Internal.res.mjs +30 -2
  60. package/src/LoadLayer.res +5 -5
  61. package/src/LoadLayer.res.mjs +6 -6
  62. package/src/LogSelection.res +92 -217
  63. package/src/LogSelection.res.mjs +95 -184
  64. package/src/Main.res +71 -236
  65. package/src/Main.res.mjs +60 -145
  66. package/src/Metrics.res +74 -0
  67. package/src/Metrics.res.mjs +75 -0
  68. package/src/PgStorage.res +4 -4
  69. package/src/PgStorage.res.mjs +5 -5
  70. package/src/Prometheus.res +10 -63
  71. package/src/Prometheus.res.mjs +124 -171
  72. package/src/PruneStaleHistory.res +2 -2
  73. package/src/PruneStaleHistory.res.mjs +3 -3
  74. package/src/RawEvent.res +7 -2
  75. package/src/RawEvent.res.mjs +4 -4
  76. package/src/Rollback.res +3 -3
  77. package/src/Rollback.res.mjs +4 -4
  78. package/src/RollbackCommit.res +4 -1
  79. package/src/RollbackCommit.res.mjs +3 -2
  80. package/src/SimulateDeadInputTracker.res +85 -0
  81. package/src/SimulateDeadInputTracker.res.mjs +73 -0
  82. package/src/SimulateDeadInputTracker.resi +12 -0
  83. package/src/SimulateItems.res +128 -28
  84. package/src/SimulateItems.res.mjs +82 -40
  85. package/src/TestIndexer.res +55 -41
  86. package/src/TestIndexer.res.mjs +39 -32
  87. package/src/TopicFilter.res +1 -25
  88. package/src/TopicFilter.res.mjs +0 -74
  89. package/src/bindings/Performance.res +7 -0
  90. package/src/bindings/Performance.res.mjs +21 -0
  91. package/src/bindings/Performance.resi +7 -0
  92. package/src/bindings/Viem.res +0 -46
  93. package/src/bindings/Viem.res.mjs +1 -43
  94. package/src/sources/BlockStore.res +46 -0
  95. package/src/sources/BlockStore.res.mjs +24 -0
  96. package/src/sources/EventRouter.res +31 -49
  97. package/src/sources/EventRouter.res.mjs +12 -25
  98. package/src/sources/Evm.res +83 -72
  99. package/src/sources/Evm.res.mjs +53 -69
  100. package/src/sources/EvmChain.res +7 -34
  101. package/src/sources/EvmChain.res.mjs +6 -27
  102. package/src/sources/EvmRpcClient.res +71 -5
  103. package/src/sources/EvmRpcClient.res.mjs +13 -4
  104. package/src/sources/FieldMask.res +39 -0
  105. package/src/sources/FieldMask.res.mjs +42 -0
  106. package/src/sources/Fuel.res +9 -6
  107. package/src/sources/Fuel.res.mjs +5 -10
  108. package/src/sources/HyperFuelSource.res +46 -50
  109. package/src/sources/HyperFuelSource.res.mjs +64 -54
  110. package/src/sources/HyperSync.res +45 -42
  111. package/src/sources/HyperSync.res.mjs +68 -60
  112. package/src/sources/HyperSync.resi +14 -4
  113. package/src/sources/HyperSyncClient.res +107 -119
  114. package/src/sources/HyperSyncClient.res.mjs +36 -31
  115. package/src/sources/HyperSyncHeightStream.res +1 -8
  116. package/src/sources/HyperSyncHeightStream.res.mjs +0 -2
  117. package/src/sources/HyperSyncSource.res +60 -254
  118. package/src/sources/HyperSyncSource.res.mjs +57 -180
  119. package/src/sources/Rpc.res +15 -79
  120. package/src/sources/Rpc.res.mjs +25 -101
  121. package/src/sources/RpcSource.res +221 -514
  122. package/src/sources/RpcSource.res.mjs +216 -411
  123. package/src/sources/RpcWebSocketHeightStream.res +0 -5
  124. package/src/sources/RpcWebSocketHeightStream.res.mjs +0 -2
  125. package/src/sources/SimulateSource.res +44 -20
  126. package/src/sources/SimulateSource.res.mjs +41 -14
  127. package/src/sources/Source.res +34 -6
  128. package/src/sources/SourceManager.res +77 -19
  129. package/src/sources/SourceManager.res.mjs +63 -21
  130. package/src/sources/SourceManager.resi +10 -0
  131. package/src/sources/Svm.res +31 -16
  132. package/src/sources/Svm.res.mjs +36 -13
  133. package/src/sources/SvmHyperSyncClient.res +5 -32
  134. package/src/sources/SvmHyperSyncSource.res +159 -134
  135. package/src/sources/SvmHyperSyncSource.res.mjs +164 -129
  136. package/src/sources/TransactionStore.res +49 -0
  137. package/src/sources/TransactionStore.res.mjs +30 -0
  138. package/src/tui/Tui.res +13 -16
  139. package/src/tui/Tui.res.mjs +12 -14
  140. package/svm.schema.json +49 -37
  141. package/src/bindings/Hrtime.res +0 -58
  142. package/src/bindings/Hrtime.res.mjs +0 -90
  143. package/src/bindings/Hrtime.resi +0 -30
@@ -21,6 +21,16 @@ let make: (
21
21
 
22
22
  let getActiveSource: t => Source.t
23
23
 
24
+ type requestStatSample = {
25
+ sourceName: string,
26
+ chainId: int,
27
+ method: string,
28
+ count: int,
29
+ seconds: float,
30
+ }
31
+
32
+ let getRequestStatSamples: t => array<requestStatSample>
33
+
24
34
  let inFlightCount: t => int
25
35
 
26
36
  let onReorg: (t, ~rollbackTargetBlock: int) => unit
@@ -4,10 +4,31 @@ let cleanUpRawEventFieldsInPlace: JSON.t => unit = %raw(`fields => {
4
4
  delete fields.time
5
5
  }`)
6
6
 
7
+ // Ordered transaction field names, the field codes shared with the Rust store
8
+ // (`SvmTxField`). Derived from the typed field list so the two can't drift;
9
+ // `Internal.allSvmTransactionFields` is pinned to the Rust ordinal order by a test.
10
+ let transactionFields =
11
+ Internal.allSvmTransactionFields->(
12
+ Utils.magic: array<Internal.svmTransactionField> => array<string>
13
+ )
14
+
15
+ // One instruction's selected transaction fields → store selection bitmask.
16
+ // Computed per event at config build and cached on the event config.
17
+ let eventTransactionFieldMask = TransactionStore.makeMaskFn(transactionFields)
18
+
19
+ // Ordered block field names. The index of each is the field code shared with the
20
+ // Rust store (`SvmBlockField`) — keep this order in sync.
21
+ let blockFields = ["slot", "time", "hash", "height", "parentSlot", "parentHash"]
22
+
23
+ // `slot`/`time`/`hash` are always included; every other block field is opt-in
24
+ // via `field_selection.block_fields`. All are materialised from the store.
25
+ //
26
+ // One instruction's selected block fields → store selection bitmask. Computed per
27
+ // event at config build and cached on the event config.
28
+ let eventBlockFieldMask = BlockStore.makeMaskFn(blockFields)
29
+
7
30
  let make = (~logger: Pino.t): Ecosystem.t => {
8
31
  name: Svm,
9
- blockFields: ["slot"],
10
- transactionFields: [],
11
32
  blockNumberName: "height",
12
33
  blockTimestampName: "time",
13
34
  blockHashName: "hash",
@@ -20,15 +41,15 @@ let make = (~logger: Pino.t): Ecosystem.t => {
20
41
  // parse. The schema is a no-op object that always surfaces `None`.
21
42
  onEventBlockFilterSchema: S.object(_ => None),
22
43
  logger,
23
- toEvent: eventItem => eventItem.payload->Internal.payloadToEvent,
44
+ toEvent: eventItem => eventItem.payload->(Utils.magic: Internal.eventPayload => Internal.event),
24
45
  toEventLogger: eventItem => {
25
46
  let instruction =
26
47
  eventItem.payload->(Utils.magic: Internal.eventPayload => Envio.svmInstruction)
27
48
  Logging.createChildFrom(
28
49
  ~logger,
29
50
  ~params={
30
- "program": eventItem.eventConfig.contractName,
31
- "instruction": eventItem.eventConfig.name,
51
+ "program": eventItem.onEventRegistration.eventConfig.contractName,
52
+ "instruction": eventItem.onEventRegistration.eventConfig.name,
32
53
  "chainId": eventItem.chain->ChainMap.Chain.toChainId,
33
54
  "slot": eventItem.blockNumber,
34
55
  "programId": instruction.programId,
@@ -71,26 +92,20 @@ let makeRPCSource = (~chain, ~rpc: string, ~sourceFor: Source.sourceFor=Sync): S
71
92
  getBlockHashes: (~blockNumbers as _, ~logger as _) =>
72
93
  JsError.throwWithMessage("Svm does not support getting block hashes"),
73
94
  getHeightOrThrow: async () => {
74
- let timerRef = Hrtime.makeTimer()
95
+ let timerRef = Performance.now()
75
96
  let height = await GetFinalizedSlot.route->Rest.fetch((), ~client)
76
- let seconds = timerRef->Hrtime.timeSince->Hrtime.toSecondsFloat
77
- Prometheus.SourceRequestCount.increment(~sourceName=name, ~chainId, ~method="getSlot")
78
- Prometheus.SourceRequestCount.addSeconds(
79
- ~sourceName=name,
80
- ~chainId,
81
- ~method="getSlot",
82
- ~seconds,
83
- )
84
- height
97
+ let seconds = timerRef->Performance.secondsSince
98
+ {Source.height, requestStats: [{Source.method: "getSlot", seconds}]}
85
99
  },
86
100
  getItemsOrThrow: (
87
101
  ~fromBlock as _,
88
102
  ~toBlock as _,
89
103
  ~addressesByContractName as _,
90
- ~indexingAddresses as _,
104
+ ~contractNameByAddress as _,
91
105
  ~knownHeight as _,
92
106
  ~partitionId as _,
93
107
  ~selection as _,
108
+ ~itemsTarget as _,
94
109
  ~retry as _,
95
110
  ~logger as _,
96
111
  ) => JsError.throwWithMessage("Svm does not support getting items"),
@@ -3,11 +3,13 @@
3
3
  import * as Rpc from "./Rpc.res.mjs";
4
4
  import * as Rest from "../vendored/Rest.res.mjs";
5
5
  import * as Utils from "../Utils.res.mjs";
6
- import * as Hrtime from "../bindings/Hrtime.res.mjs";
7
6
  import * as Logging from "../Logging.res.mjs";
8
- import * as Prometheus from "../Prometheus.res.mjs";
7
+ import * as Internal from "../Internal.res.mjs";
8
+ import * as BlockStore from "./BlockStore.res.mjs";
9
+ import * as Performance from "../bindings/Performance.res.mjs";
9
10
  import * as Stdlib_JsError from "@rescript/runtime/lib/es6/Stdlib_JsError.js";
10
11
  import * as S$RescriptSchema from "rescript-schema/src/S.res.mjs";
12
+ import * as TransactionStore from "./TransactionStore.res.mjs";
11
13
 
12
14
  let cleanUpRawEventFieldsInPlace = (fields => {
13
15
  delete fields.hash
@@ -15,11 +17,22 @@ let cleanUpRawEventFieldsInPlace = (fields => {
15
17
  delete fields.time
16
18
  });
17
19
 
20
+ let eventTransactionFieldMask = TransactionStore.makeMaskFn(Internal.allSvmTransactionFields);
21
+
22
+ let blockFields = [
23
+ "slot",
24
+ "time",
25
+ "hash",
26
+ "height",
27
+ "parentSlot",
28
+ "parentHash"
29
+ ];
30
+
31
+ let eventBlockFieldMask = BlockStore.makeMaskFn(blockFields);
32
+
18
33
  function make(logger) {
19
34
  return {
20
35
  name: "svm",
21
- blockFields: ["slot"],
22
- transactionFields: [],
23
36
  blockNumberName: "height",
24
37
  blockTimestampName: "time",
25
38
  blockHashName: "hash",
@@ -32,8 +45,8 @@ function make(logger) {
32
45
  toEventLogger: eventItem => {
33
46
  let instruction = eventItem.payload;
34
47
  return Logging.createChildFrom(logger, {
35
- program: eventItem.eventConfig.contractName,
36
- instruction: eventItem.eventConfig.name,
48
+ program: eventItem.onEventRegistration.eventConfig.contractName,
49
+ instruction: eventItem.onEventRegistration.eventConfig.name,
37
50
  chainId: eventItem.chain,
38
51
  slot: eventItem.blockNumber,
39
52
  programId: instruction.programId
@@ -67,21 +80,31 @@ function makeRPCSource(chain, rpc, sourceForOpt) {
67
80
  pollingInterval: 10000,
68
81
  getBlockHashes: (param, param$1) => Stdlib_JsError.throwWithMessage("Svm does not support getting block hashes"),
69
82
  getHeightOrThrow: async () => {
70
- let timerRef = Hrtime.makeTimer();
83
+ let timerRef = Performance.now();
71
84
  let height = await Rest.fetch(route, undefined, client);
72
- let seconds = Hrtime.toSecondsFloat(Hrtime.timeSince(timerRef));
73
- Prometheus.SourceRequestCount.increment(name, chain, "getSlot");
74
- Prometheus.SourceRequestCount.addSeconds(name, chain, "getSlot", seconds);
75
- return height;
85
+ let seconds = Performance.secondsSince(timerRef);
86
+ return {
87
+ height: height,
88
+ requestStats: [{
89
+ method: "getSlot",
90
+ seconds: seconds
91
+ }]
92
+ };
76
93
  },
77
- getItemsOrThrow: (param, param$1, param$2, param$3, param$4, param$5, param$6, param$7, param$8) => Stdlib_JsError.throwWithMessage("Svm does not support getting items")
94
+ getItemsOrThrow: (param, param$1, param$2, param$3, param$4, param$5, param$6, param$7, param$8, param$9) => Stdlib_JsError.throwWithMessage("Svm does not support getting items")
78
95
  };
79
96
  }
80
97
 
98
+ let transactionFields = Internal.allSvmTransactionFields;
99
+
81
100
  export {
82
101
  cleanUpRawEventFieldsInPlace,
102
+ transactionFields,
103
+ eventTransactionFieldMask,
104
+ blockFields,
105
+ eventBlockFieldMask,
83
106
  make,
84
107
  GetFinalizedSlot,
85
108
  makeRPCSource,
86
109
  }
87
- /* route Not a pure module */
110
+ /* eventTransactionFieldMask Not a pure module */
@@ -138,29 +138,12 @@ module QueryTypes = {
138
138
  }
139
139
 
140
140
  module ResponseTypes = {
141
+ // Lean per-slot header for reorg detection and each item's slot/time; the
142
+ // selectable fields live in the block store and are materialised on demand.
141
143
  type block = {
142
144
  slot: int,
143
145
  blockhash: string,
144
- parentSlot?: int,
145
- parentBlockhash?: string,
146
146
  blockTime?: int,
147
- blockHeight?: int,
148
- }
149
-
150
- type transaction = {
151
- slot: int,
152
- transactionIndex: int,
153
- signatures: array<string>,
154
- feePayer?: string,
155
- success?: bool,
156
- err?: string,
157
- fee?: int,
158
- computeUnitsConsumed?: int,
159
- accountKeys: array<string>,
160
- recentBlockhash?: string,
161
- version?: string,
162
- loadedAddressesWritable: array<string>,
163
- loadedAddressesReadonly: array<string>,
164
147
  }
165
148
 
166
149
  /// Borsh-decoded view attached by the Rust client. `argsJson`/`accountsJson`
@@ -204,22 +187,10 @@ module ResponseTypes = {
204
187
  message?: string,
205
188
  }
206
189
 
207
- type tokenBalance = {
208
- slot: int,
209
- transactionIndex?: int,
210
- account?: string,
211
- mint?: string,
212
- owner?: string,
213
- preAmount?: string,
214
- postAmount?: string,
215
- }
216
-
217
190
  type queryResponseData = {
218
191
  blocks: array<block>,
219
- transactions: array<transaction>,
220
192
  instructions: array<instruction>,
221
193
  logs: array<log>,
222
- tokenBalances: array<tokenBalance>,
223
194
  }
224
195
 
225
196
  type queryResponse = {
@@ -234,7 +205,9 @@ type queryResponse = ResponseTypes.queryResponse
234
205
 
235
206
  type t = {
236
207
  getHeight: unit => promise<int>,
237
- get: (~query: query) => promise<queryResponse>,
208
+ // Returns the response plus pages of raw transactions and blocks (kept in
209
+ // Rust), keyed by (slot, transactionIndex) / slot, materialised at batch prep.
210
+ get: (~query: query) => promise<(queryResponse, TransactionStore.t, BlockStore.t)>,
238
211
  }
239
212
 
240
213
  @send