envio 3.3.0-alpha.1 → 3.3.0-alpha.2

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 (58) hide show
  1. package/package.json +6 -6
  2. package/src/Batch.res +0 -6
  3. package/src/Batch.res.mjs +0 -11
  4. package/src/BatchProcessing.res +2 -12
  5. package/src/BatchProcessing.res.mjs +2 -7
  6. package/src/ChainFetching.res +17 -6
  7. package/src/ChainFetching.res.mjs +11 -11
  8. package/src/ChainMetadata.res +1 -11
  9. package/src/ChainMetadata.res.mjs +1 -10
  10. package/src/ChainState.res +150 -1
  11. package/src/ChainState.res.mjs +138 -9
  12. package/src/ChainState.resi +51 -1
  13. package/src/Config.res +3 -6
  14. package/src/Config.res.mjs +2 -3
  15. package/src/Core.res +7 -0
  16. package/src/CrossChainState.res +9 -26
  17. package/src/CrossChainState.res.mjs +7 -16
  18. package/src/Ecosystem.res +6 -1
  19. package/src/Envio.res +3 -2
  20. package/src/EventConfigBuilder.res +19 -5
  21. package/src/EventConfigBuilder.res.mjs +6 -4
  22. package/src/EventProcessing.res +26 -0
  23. package/src/EventProcessing.res.mjs +20 -0
  24. package/src/Internal.res +43 -4
  25. package/src/Internal.res.mjs +18 -0
  26. package/src/Main.res +3 -50
  27. package/src/Main.res.mjs +2 -23
  28. package/src/Rollback.res +1 -1
  29. package/src/Rollback.res.mjs +1 -1
  30. package/src/SimulateItems.res +3 -0
  31. package/src/SimulateItems.res.mjs +2 -1
  32. package/src/sources/Evm.res +52 -38
  33. package/src/sources/Evm.res.mjs +48 -36
  34. package/src/sources/Fuel.res +3 -1
  35. package/src/sources/Fuel.res.mjs +1 -0
  36. package/src/sources/HyperFuelSource.res +5 -0
  37. package/src/sources/HyperFuelSource.res.mjs +2 -0
  38. package/src/sources/HyperSync.res +4 -1
  39. package/src/sources/HyperSync.res.mjs +5 -3
  40. package/src/sources/HyperSync.resi +1 -0
  41. package/src/sources/HyperSyncClient.res +9 -78
  42. package/src/sources/HyperSyncClient.res.mjs +1 -22
  43. package/src/sources/HyperSyncSource.res +3 -4
  44. package/src/sources/HyperSyncSource.res.mjs +2 -1
  45. package/src/sources/RpcSource.res +7 -2
  46. package/src/sources/RpcSource.res.mjs +3 -1
  47. package/src/sources/SimulateSource.res +3 -1
  48. package/src/sources/SimulateSource.res.mjs +1 -0
  49. package/src/sources/Source.res +4 -0
  50. package/src/sources/Svm.res +25 -2
  51. package/src/sources/Svm.res.mjs +27 -2
  52. package/src/sources/SvmHyperSyncClient.res +3 -29
  53. package/src/sources/SvmHyperSyncSource.res +60 -84
  54. package/src/sources/SvmHyperSyncSource.res.mjs +59 -78
  55. package/src/sources/TransactionStore.res +111 -0
  56. package/src/sources/TransactionStore.res.mjs +77 -0
  57. package/src/tui/Tui.res +13 -16
  58. package/src/tui/Tui.res.mjs +12 -14
@@ -28,6 +28,7 @@ function make(logger) {
28
28
  onEventBlockFilterSchema: S$RescriptSchema.object(s => s.f("block", S$RescriptSchema.option(S$RescriptSchema.object(s2 => s2.f("height", S$RescriptSchema.unknown))))),
29
29
  logger: logger,
30
30
  toEvent: eventItem => eventItem.payload,
31
+ transactionFieldMask: param => 0,
31
32
  toEventLogger: eventItem => Logging.createChildFrom(logger, {
32
33
  contract: eventItem.eventConfig.contractName,
33
34
  event: eventItem.eventConfig.name,
@@ -414,6 +414,9 @@ Learn more or get a free Envio API token at: https://envio.dev/app/api-tokens`)
414
414
  blockNumber: block.height,
415
415
  blockHash: block.id,
416
416
  logIndex: receiptIndex,
417
+ // Fuel carries the transaction inline on the payload; the store key is
418
+ // unused (Fuel identifies transactions by hash, kept on the payload).
419
+ transactionIndex: 0,
417
420
  payload: {
418
421
  contractName: eventConfig.contractName,
419
422
  eventName: eventConfig.name,
@@ -456,6 +459,8 @@ Learn more or get a free Envio API token at: https://envio.dev/app/api-tokens`)
456
459
  {
457
460
  latestFetchedBlockTimestamp,
458
461
  parsedQueueItems,
462
+ // Fuel keeps transaction on the payload; no store page.
463
+ transactionStore: None,
459
464
  latestFetchedBlockNumber: heighestBlockQueried,
460
465
  stats,
461
466
  knownHeight,
@@ -355,6 +355,7 @@ Learn more or get a free Envio API token at: https://envio.dev/app/api-tokens`);
355
355
  blockNumber: block.height,
356
356
  blockHash: block.id,
357
357
  logIndex: receiptIndex,
358
+ transactionIndex: 0,
358
359
  payload: {
359
360
  contractName: eventConfig$1.contractName,
360
361
  eventName: eventConfig$1.name,
@@ -397,6 +398,7 @@ Learn more or get a free Envio API token at: https://envio.dev/app/api-tokens`);
397
398
  knownHeight: knownHeight$1,
398
399
  blockHashes: blockHashes,
399
400
  parsedQueueItems: parsedQueueItems,
401
+ transactionStore: undefined,
400
402
  fromBlockQueried: fromBlock,
401
403
  latestFetchedBlockNumber: heighestBlockQueried,
402
404
  latestFetchedBlockTimestamp: latestFetchedBlockTimestamp,
@@ -19,6 +19,8 @@ type logsQueryPage = {
19
19
  nextBlock: int,
20
20
  archiveHeight: int,
21
21
  rollbackGuard: option<HyperSyncClient.ResponseTypes.rollbackGuard>,
22
+ // Page store owning this page's raw transactions.
23
+ transactionStore: TransactionStore.t,
22
24
  }
23
25
 
24
26
  type missingParams = {
@@ -121,7 +123,7 @@ module GetLogs = {
121
123
  ~fieldSelection,
122
124
  )
123
125
 
124
- let res = switch await client.getEventItems(~query) {
126
+ let (res, transactionStore) = switch await client.getEventItems(~query) {
125
127
  | res => res
126
128
  | exception exn =>
127
129
  reraisIfRateLimited(exn)
@@ -140,6 +142,7 @@ module GetLogs = {
140
142
  nextBlock: res.nextBlock,
141
143
  archiveHeight: res.archiveHeight->Option.getOr(0), //Archive Height is only None if height is 0
142
144
  rollbackGuard: res.rollbackGuard,
145
+ transactionStore,
143
146
  }
144
147
  }
145
148
  }
@@ -101,9 +101,9 @@ async function query(client, fromBlock, toBlock, logSelections, fieldSelection)
101
101
  });
102
102
  });
103
103
  let query$1 = makeRequestBody(fromBlock, toBlock, addressesWithTopics, fieldSelection);
104
- let res;
104
+ let match;
105
105
  try {
106
- res = await client.getEventItems(query$1);
106
+ match = await client.getEventItems(query$1);
107
107
  } catch (raw_exn) {
108
108
  let exn = Primitive_exceptions.internalToException(raw_exn);
109
109
  reraisIfRateLimited(exn);
@@ -120,6 +120,7 @@ async function query(client, fromBlock, toBlock, logSelections, fieldSelection)
120
120
  }
121
121
  throw exn;
122
122
  }
123
+ let res = match[0];
123
124
  if (res.nextBlock <= fromBlock) {
124
125
  throw {
125
126
  RE_EXN_ID: $$Error,
@@ -131,7 +132,8 @@ async function query(client, fromBlock, toBlock, logSelections, fieldSelection)
131
132
  items: res.items,
132
133
  nextBlock: res.nextBlock,
133
134
  archiveHeight: Stdlib_Option.getOr(res.archiveHeight, 0),
134
- rollbackGuard: res.rollbackGuard
135
+ rollbackGuard: res.rollbackGuard,
136
+ transactionStore: match[1]
135
137
  };
136
138
  }
137
139
 
@@ -3,6 +3,7 @@ type logsQueryPage = {
3
3
  nextBlock: int,
4
4
  archiveHeight: int,
5
5
  rollbackGuard: option<HyperSyncClient.ResponseTypes.rollbackGuard>,
6
+ transactionStore: TransactionStore.t,
6
7
  }
7
8
 
8
9
  type missingParams = {
@@ -208,72 +208,6 @@ module ResponseTypes = {
208
208
  mixHash?: string,
209
209
  }
210
210
 
211
- type accessList = {
212
- address?: Address.t,
213
- storageKeys?: array<string>,
214
- }
215
-
216
- let accessListSchema = S.object(s => {
217
- address: ?s.field("address", S.option(Address.schema)),
218
- storageKeys: ?s.field("storageKeys", S.option(S.array(S.string))),
219
- })
220
-
221
- type authorizationList = {
222
- chainId: bigint,
223
- address: Address.t,
224
- nonce: int,
225
- yParity: [#0 | #1],
226
- r: string,
227
- s: string,
228
- }
229
-
230
- let authorizationListSchema = S.object(s => {
231
- chainId: s.field("chainId", S.bigint),
232
- address: s.field("address", Address.schema),
233
- nonce: s.field("nonce", S.int),
234
- yParity: s.field("yParity", S.enum([#0, #1])),
235
- r: s.field("r", S.string),
236
- s: s.field("s", S.string),
237
- })
238
-
239
- type transaction = {
240
- blockHash?: string,
241
- blockNumber?: int,
242
- from?: string,
243
- gas?: bigint,
244
- gasPrice?: bigint,
245
- hash?: string,
246
- input?: string,
247
- nonce?: bigint,
248
- to?: string,
249
- transactionIndex?: int,
250
- value?: bigint,
251
- v?: string,
252
- r?: string,
253
- s?: string,
254
- yParity?: string,
255
- maxPriorityFeePerGas?: bigint,
256
- maxFeePerGas?: bigint,
257
- chainId?: int,
258
- accessList?: array<accessList>,
259
- maxFeePerBlobGas?: bigint,
260
- blobVersionedHashes?: array<string>,
261
- cumulativeGasUsed?: bigint,
262
- effectiveGasPrice?: bigint,
263
- gasUsed?: bigint,
264
- contractAddress?: string,
265
- logsBloom?: string,
266
- @as("type") type_?: int,
267
- root?: string,
268
- status?: int,
269
- l1Fee?: bigint,
270
- l1GasPrice?: bigint,
271
- l1GasUsed?: bigint,
272
- l1FeeScalar?: float,
273
- gasUsedForL1?: bigint,
274
- authorizationList?: array<authorizationList>,
275
- }
276
-
277
211
  type log = {
278
212
  removed?: bool,
279
213
  @as("logIndex") index?: int,
@@ -286,11 +220,9 @@ module ResponseTypes = {
286
220
  topics?: array<Nullable.t<EvmTypes.Hex.t>>,
287
221
  }
288
222
 
289
- type event = {
290
- transaction?: transaction,
291
- block?: block,
292
- log: log,
293
- }
223
+ // Only the log is needed for decoding; the transaction/block are served from
224
+ // the store (event items) or unused (block-hash query).
225
+ type event = {log: log}
294
226
 
295
227
  type rollbackGuard = {
296
228
  blockNumber: int,
@@ -303,11 +235,7 @@ module ResponseTypes = {
303
235
 
304
236
  type query = QueryTypes.query
305
237
 
306
- type queryResponseData = {
307
- blocks: array<ResponseTypes.block>,
308
- transactions: array<ResponseTypes.transaction>,
309
- logs: array<ResponseTypes.log>,
310
- }
238
+ type queryResponseData = {blocks: array<ResponseTypes.block>}
311
239
 
312
240
  type queryResponse = {
313
241
  archiveHeight: option<int>,
@@ -353,7 +281,9 @@ module EventItems = {
353
281
  topic0: EvmTypes.Hex.t,
354
282
  topicCount: int,
355
283
  block: ResponseTypes.block,
356
- transaction: ResponseTypes.transaction,
284
+ // Key (with the block number) into the transaction store; the transaction
285
+ // is resolved from the store on demand.
286
+ transactionIndex: int,
357
287
  params: Nullable.t<dict<Internal.eventParams>>,
358
288
  }
359
289
 
@@ -367,7 +297,8 @@ module EventItems = {
367
297
 
368
298
  type t = {
369
299
  get: (~query: query) => promise<queryResponse>,
370
- getEventItems: (~query: query) => promise<EventItems.response>,
300
+ // Returns the response plus a page store owning this page's raw transactions.
301
+ getEventItems: (~query: query) => promise<(EventItems.response, TransactionStore.t)>,
371
302
  getHeight: unit => promise<int>,
372
303
  }
373
304
 
@@ -2,7 +2,6 @@
2
2
 
3
3
  import * as Core from "../Core.res.mjs";
4
4
  import * as Utils from "../Utils.res.mjs";
5
- import * as Address from "../Address.res.mjs";
6
5
  import * as Primitive_option from "@rescript/runtime/lib/es6/Primitive_option.js";
7
6
  import * as S$RescriptSchema from "rescript-schema/src/S.res.mjs";
8
7
 
@@ -36,27 +35,7 @@ let QueryTypes = {
36
35
  makeLogSelection: makeLogSelection
37
36
  };
38
37
 
39
- let accessListSchema = S$RescriptSchema.object(s => ({
40
- address: s.f("address", S$RescriptSchema.option(Address.schema)),
41
- storageKeys: s.f("storageKeys", S$RescriptSchema.option(S$RescriptSchema.array(S$RescriptSchema.string)))
42
- }));
43
-
44
- let authorizationListSchema = S$RescriptSchema.object(s => ({
45
- chainId: s.f("chainId", S$RescriptSchema.bigint),
46
- address: s.f("address", Address.schema),
47
- nonce: s.f("nonce", S$RescriptSchema.int),
48
- yParity: s.f("yParity", S$RescriptSchema.$$enum([
49
- 0,
50
- 1
51
- ])),
52
- r: s.f("r", S$RescriptSchema.string),
53
- s: s.f("s", S$RescriptSchema.string)
54
- }));
55
-
56
- let ResponseTypes = {
57
- accessListSchema: accessListSchema,
58
- authorizationListSchema: authorizationListSchema
59
- };
38
+ let ResponseTypes = {};
60
39
 
61
40
  function fromParams(eventParams, checksumAddresses) {
62
41
  return Core.getAddon().EvmDecoder.fromParams(eventParams, checksumAddresses !== undefined ? Primitive_option.valFromOption(checksumAddresses) : undefined);
@@ -196,7 +196,7 @@ Learn more or get a free Envio API token at: https://envio.dev/app/api-tokens`)
196
196
  ~params: Internal.eventParams,
197
197
  ~eventConfig: Internal.evmEventConfig,
198
198
  ): Internal.item => {
199
- let {block, transaction, logIndex, srcAddress} = item
199
+ let {block, transactionIndex, logIndex, srcAddress} = item
200
200
  let chainId = chain->ChainMap.Chain.toChainId
201
201
 
202
202
  Internal.Event({
@@ -206,14 +206,12 @@ Learn more or get a free Envio API token at: https://envio.dev/app/api-tokens`)
206
206
  blockNumber: block.number->Option.getUnsafe,
207
207
  blockHash: block.hash->Option.getUnsafe,
208
208
  logIndex,
209
+ transactionIndex,
209
210
  payload: {
210
211
  contractName: eventConfig.contractName,
211
212
  eventName: eventConfig.name,
212
213
  chainId,
213
214
  params,
214
- transaction: transaction->(
215
- Utils.magic: HyperSyncClient.ResponseTypes.transaction => Internal.eventTransaction
216
- ),
217
215
  block: block->(Utils.magic: HyperSyncClient.ResponseTypes.block => Internal.eventBlock),
218
216
  srcAddress,
219
217
  logIndex,
@@ -426,6 +424,7 @@ Learn more or get a free Envio API token at: https://envio.dev/app/api-tokens`)
426
424
  {
427
425
  latestFetchedBlockTimestamp,
428
426
  parsedQueueItems,
427
+ transactionStore: Some(pageUnsafe.transactionStore),
429
428
  latestFetchedBlockNumber: heighestBlockQueried,
430
429
  stats,
431
430
  knownHeight,
@@ -135,6 +135,7 @@ Learn more or get a free Envio API token at: https://envio.dev/app/api-tokens`);
135
135
  blockNumber: block.number,
136
136
  blockHash: block.hash,
137
137
  logIndex: logIndex,
138
+ transactionIndex: item.transactionIndex,
138
139
  payload: {
139
140
  contractName: eventConfig.contractName,
140
141
  eventName: eventConfig.name,
@@ -142,7 +143,6 @@ Learn more or get a free Envio API token at: https://envio.dev/app/api-tokens`);
142
143
  chainId: chain,
143
144
  srcAddress: item.srcAddress,
144
145
  logIndex: logIndex,
145
- transaction: item.transaction,
146
146
  block: block
147
147
  }
148
148
  };
@@ -292,6 +292,7 @@ Learn more or get a free Envio API token at: https://envio.dev/app/api-tokens`);
292
292
  knownHeight: knownHeight$1,
293
293
  blockHashes: blockHashes,
294
294
  parsedQueueItems: parsedQueueItems,
295
+ transactionStore: Primitive_option.some(pageUnsafe.transactionStore),
295
296
  fromBlockQueried: fromBlock,
296
297
  latestFetchedBlockNumber: heighestBlockQueried,
297
298
  latestFetchedBlockTimestamp: latestFetchedBlockTimestamp,
@@ -1160,7 +1160,9 @@ let make = (
1160
1160
  let (block, transaction) = try await Promise.all2((
1161
1161
  log->getEventBlockOrThrow(~selectedBlockFields=eventConfig.selectedBlockFields),
1162
1162
  log->getEventTransactionOrThrow(
1163
- ~selectedTransactionFields=eventConfig.selectedTransactionFields,
1163
+ ~selectedTransactionFields=eventConfig.selectedTransactionFields->(
1164
+ Utils.magic: Utils.Set.t<string> => Utils.Set.t<Internal.evmTransactionField>
1165
+ ),
1164
1166
  ),
1165
1167
  )) catch {
1166
1168
  | TransactionDataNotFound({message}) =>
@@ -1200,13 +1202,14 @@ let make = (
1200
1202
  blockHash: block->getBlockHash,
1201
1203
  chain,
1202
1204
  logIndex: log.logIndex,
1205
+ transactionIndex: log.transactionIndex,
1203
1206
  payload: {
1204
1207
  contractName: eventConfig.contractName,
1205
1208
  eventName: eventConfig.name,
1206
1209
  chainId: chain->ChainMap.Chain.toChainId,
1207
1210
  params: decoded,
1208
- transaction,
1209
1211
  block,
1212
+ transaction,
1210
1213
  srcAddress: routedAddress,
1211
1214
  logIndex: log.logIndex,
1212
1215
  }->Evm.fromPayload,
@@ -1250,6 +1253,8 @@ let make = (
1250
1253
  latestFetchedBlockTimestamp: latestFetchedBlockInfo.timestamp,
1251
1254
  latestFetchedBlockNumber: latestFetchedBlockInfo.number,
1252
1255
  parsedQueueItems,
1256
+ // RPC keeps the transaction inline on the payload; no store page.
1257
+ transactionStore: None,
1253
1258
  stats: {
1254
1259
  totalTimeElapsed: totalTimeElapsed,
1255
1260
  },
@@ -1131,6 +1131,7 @@ function make(param) {
1131
1131
  blockNumber: block.number,
1132
1132
  blockHash: block.hash,
1133
1133
  logIndex: log.logIndex,
1134
+ transactionIndex: log.transactionIndex,
1134
1135
  payload: {
1135
1136
  contractName: eventConfig.contractName,
1136
1137
  eventName: eventConfig.name,
@@ -1138,7 +1139,7 @@ function make(param) {
1138
1139
  chainId: chain,
1139
1140
  srcAddress: routedAddress,
1140
1141
  logIndex: log.logIndex,
1141
- transaction: match[1],
1142
+ transaction: Primitive_option.some(match[1]),
1142
1143
  block: block
1143
1144
  }
1144
1145
  };
@@ -1174,6 +1175,7 @@ function make(param) {
1174
1175
  knownHeight: knownHeight,
1175
1176
  blockHashes: blockHashes,
1176
1177
  parsedQueueItems: parsedQueueItems,
1178
+ transactionStore: undefined,
1177
1179
  fromBlockQueried: fromBlock,
1178
1180
  latestFetchedBlockNumber: latestFetchedBlockInfo.number,
1179
1181
  latestFetchedBlockTimestamp: latestFetchedBlockInfo.timestamp,
@@ -28,7 +28,7 @@ let make = (~items: array<Internal.item>, ~endBlock: int, ~chain: ChainMap.Chain
28
28
  ~retry as _,
29
29
  ~logger as _,
30
30
  ) => {
31
- // Return all items on first call, empty on subsequent calls
31
+ // Return all items on the first call, empty on subsequent.
32
32
  let result = if delivered.contents {
33
33
  []
34
34
  } else {
@@ -41,6 +41,8 @@ let make = (~items: array<Internal.item>, ~endBlock: int, ~chain: ChainMap.Chain
41
41
  Source.knownHeight: reportedHeight,
42
42
  blockHashes: [],
43
43
  parsedQueueItems: result,
44
+ // Simulate keeps the transaction inline on the payload; no store page.
45
+ transactionStore: None,
44
46
  fromBlockQueried: 0,
45
47
  latestFetchedBlockNumber: reportedHeight,
46
48
  latestFetchedBlockTimestamp: 0,
@@ -24,6 +24,7 @@ function make(items, endBlock, chain) {
24
24
  knownHeight: reportedHeight,
25
25
  blockHashes: [],
26
26
  parsedQueueItems: result,
27
+ transactionStore: undefined,
27
28
  fromBlockQueried: 0,
28
29
  latestFetchedBlockNumber: reportedHeight,
29
30
  latestFetchedBlockTimestamp: 0,
@@ -18,6 +18,10 @@ type blockRangeFetchResponse = {
18
18
  // a within-array hash mismatch on the same block number as a reorg.
19
19
  blockHashes: array<ReorgDetection.blockData>,
20
20
  parsedQueueItems: array<Internal.item>,
21
+ // Page of transactions for this response's items, keyed by (blockNumber,
22
+ // transactionIndex); merged into the chain's store on apply. `None` for
23
+ // sources that keep the transaction inline on the payload (RPC/Fuel/Simulate).
24
+ transactionStore: option<TransactionStore.t>,
21
25
  fromBlockQueried: int,
22
26
  latestFetchedBlockNumber: int,
23
27
  latestFetchedBlockTimestamp: int,
@@ -4,10 +4,32 @@ let cleanUpRawEventFieldsInPlace: JSON.t => unit = %raw(`fields => {
4
4
  delete fields.time
5
5
  }`)
6
6
 
7
+ // Ordered transaction field names. The index of each is the field code shared
8
+ // with the Rust store (`SvmTxField`) — keep this order in sync.
9
+ let transactionFields = [
10
+ "transactionIndex",
11
+ "signatures",
12
+ "feePayer",
13
+ "success",
14
+ "err",
15
+ "fee",
16
+ "computeUnitsConsumed",
17
+ "accountKeys",
18
+ "recentBlockhash",
19
+ "version",
20
+ "tokenBalances",
21
+ ]
22
+
23
+ // Field name → bit index (the code shared with the Rust store), built once.
24
+ let transactionFieldCodes = TransactionStore.fieldCodes(transactionFields)
25
+
26
+ let transactionFieldMask = (eventConfigs: array<Internal.eventConfig>): float =>
27
+ eventConfigs->TransactionStore.mask(~codes=transactionFieldCodes)
28
+
7
29
  let make = (~logger: Pino.t): Ecosystem.t => {
8
30
  name: Svm,
9
31
  blockFields: ["slot"],
10
- transactionFields: [],
32
+ transactionFields,
11
33
  blockNumberName: "height",
12
34
  blockTimestampName: "time",
13
35
  blockHashName: "hash",
@@ -20,7 +42,8 @@ let make = (~logger: Pino.t): Ecosystem.t => {
20
42
  // parse. The schema is a no-op object that always surfaces `None`.
21
43
  onEventBlockFilterSchema: S.object(_ => None),
22
44
  logger,
23
- toEvent: eventItem => eventItem.payload->Internal.payloadToEvent,
45
+ transactionFieldMask,
46
+ toEvent: eventItem => eventItem.payload->(Utils.magic: Internal.eventPayload => Internal.event),
24
47
  toEventLogger: eventItem => {
25
48
  let instruction =
26
49
  eventItem.payload->(Utils.magic: Internal.eventPayload => Envio.svmInstruction)
@@ -8,6 +8,7 @@ import * as Logging from "../Logging.res.mjs";
8
8
  import * as Prometheus from "../Prometheus.res.mjs";
9
9
  import * as Stdlib_JsError from "@rescript/runtime/lib/es6/Stdlib_JsError.js";
10
10
  import * as S$RescriptSchema from "rescript-schema/src/S.res.mjs";
11
+ import * as TransactionStore from "./TransactionStore.res.mjs";
11
12
 
12
13
  let cleanUpRawEventFieldsInPlace = (fields => {
13
14
  delete fields.hash
@@ -15,11 +16,31 @@ let cleanUpRawEventFieldsInPlace = (fields => {
15
16
  delete fields.time
16
17
  });
17
18
 
19
+ let transactionFields = [
20
+ "transactionIndex",
21
+ "signatures",
22
+ "feePayer",
23
+ "success",
24
+ "err",
25
+ "fee",
26
+ "computeUnitsConsumed",
27
+ "accountKeys",
28
+ "recentBlockhash",
29
+ "version",
30
+ "tokenBalances"
31
+ ];
32
+
33
+ let transactionFieldCodes = TransactionStore.fieldCodes(transactionFields);
34
+
35
+ function transactionFieldMask(eventConfigs) {
36
+ return TransactionStore.mask(eventConfigs, transactionFieldCodes);
37
+ }
38
+
18
39
  function make(logger) {
19
40
  return {
20
41
  name: "svm",
21
42
  blockFields: ["slot"],
22
- transactionFields: [],
43
+ transactionFields: transactionFields,
23
44
  blockNumberName: "height",
24
45
  blockTimestampName: "time",
25
46
  blockHashName: "hash",
@@ -29,6 +50,7 @@ function make(logger) {
29
50
  onEventBlockFilterSchema: S$RescriptSchema.object(param => {}),
30
51
  logger: logger,
31
52
  toEvent: eventItem => eventItem.payload,
53
+ transactionFieldMask: transactionFieldMask,
32
54
  toEventLogger: eventItem => {
33
55
  let instruction = eventItem.payload;
34
56
  return Logging.createChildFrom(logger, {
@@ -80,8 +102,11 @@ function makeRPCSource(chain, rpc, sourceForOpt) {
80
102
 
81
103
  export {
82
104
  cleanUpRawEventFieldsInPlace,
105
+ transactionFields,
106
+ transactionFieldCodes,
107
+ transactionFieldMask,
83
108
  make,
84
109
  GetFinalizedSlot,
85
110
  makeRPCSource,
86
111
  }
87
- /* route Not a pure module */
112
+ /* transactionFieldCodes Not a pure module */
@@ -147,22 +147,6 @@ module ResponseTypes = {
147
147
  blockHeight?: int,
148
148
  }
149
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
- }
165
-
166
150
  /// Borsh-decoded view attached by the Rust client. `argsJson`/`accountsJson`
167
151
  /// are stringified to side-step napi-rs's lack of native JSON passthrough.
168
152
  /** Solana instruction record.
@@ -204,22 +188,10 @@ module ResponseTypes = {
204
188
  message?: string,
205
189
  }
206
190
 
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
191
  type queryResponseData = {
218
192
  blocks: array<block>,
219
- transactions: array<transaction>,
220
193
  instructions: array<instruction>,
221
194
  logs: array<log>,
222
- tokenBalances: array<tokenBalance>,
223
195
  }
224
196
 
225
197
  type queryResponse = {
@@ -234,7 +206,9 @@ type queryResponse = ResponseTypes.queryResponse
234
206
 
235
207
  type t = {
236
208
  getHeight: unit => promise<int>,
237
- get: (~query: query) => promise<queryResponse>,
209
+ // Returns the response plus a page of raw transactions (kept in Rust),
210
+ // keyed by (slot, transactionIndex), materialised at batch prep.
211
+ get: (~query: query) => promise<(queryResponse, TransactionStore.t)>,
238
212
  }
239
213
 
240
214
  @send