envio 3.3.0-alpha.0 → 3.3.0-alpha.10

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 (140) hide show
  1. package/evm.schema.json +10 -0
  2. package/index.d.ts +45 -25
  3. package/package.json +7 -7
  4. package/src/Address.res +5 -2
  5. package/src/Address.res.mjs +3 -1
  6. package/src/Api.res +1 -1
  7. package/src/Api.res.mjs +1 -1
  8. package/src/Batch.res +0 -6
  9. package/src/Batch.res.mjs +1 -12
  10. package/src/BatchProcessing.res +7 -12
  11. package/src/BatchProcessing.res.mjs +8 -7
  12. package/src/Bin.res +3 -0
  13. package/src/Bin.res.mjs +4 -0
  14. package/src/ChainFetching.res +48 -16
  15. package/src/ChainFetching.res.mjs +36 -17
  16. package/src/ChainMetadata.res +1 -11
  17. package/src/ChainMetadata.res.mjs +1 -10
  18. package/src/ChainState.res +628 -149
  19. package/src/ChainState.res.mjs +440 -102
  20. package/src/ChainState.resi +74 -4
  21. package/src/Config.res +61 -33
  22. package/src/Config.res.mjs +50 -10
  23. package/src/ContractRegisterContext.res +2 -12
  24. package/src/ContractRegisterContext.res.mjs +3 -5
  25. package/src/Core.res +14 -3
  26. package/src/CrossChainState.res +142 -93
  27. package/src/CrossChainState.res.mjs +88 -60
  28. package/src/CrossChainState.resi +2 -10
  29. package/src/Ecosystem.res +5 -6
  30. package/src/Ecosystem.res.mjs +3 -3
  31. package/src/Env.res +0 -7
  32. package/src/Env.res.mjs +0 -6
  33. package/src/Envio.res +17 -11
  34. package/src/EnvioGlobal.res +53 -0
  35. package/src/EnvioGlobal.res.mjs +31 -0
  36. package/src/EventConfigBuilder.res +177 -88
  37. package/src/EventConfigBuilder.res.mjs +99 -42
  38. package/src/EventProcessing.res +74 -28
  39. package/src/EventProcessing.res.mjs +55 -29
  40. package/src/ExitOnCaughtUp.res +10 -2
  41. package/src/ExitOnCaughtUp.res.mjs +10 -1
  42. package/src/FetchState.res +558 -300
  43. package/src/FetchState.res.mjs +437 -423
  44. package/src/HandlerLoader.res +8 -104
  45. package/src/HandlerLoader.res.mjs +2 -81
  46. package/src/HandlerRegister.res +518 -144
  47. package/src/HandlerRegister.res.mjs +285 -133
  48. package/src/HandlerRegister.resi +24 -8
  49. package/src/IndexerLoop.res +2 -3
  50. package/src/IndexerLoop.res.mjs +1 -1
  51. package/src/IndexerState.res +10 -11
  52. package/src/IndexerState.res.mjs +14 -11
  53. package/src/IndexerState.resi +2 -5
  54. package/src/IndexingAddresses.res +108 -0
  55. package/src/IndexingAddresses.res.mjs +101 -0
  56. package/src/IndexingAddresses.resi +34 -0
  57. package/src/Internal.res +155 -46
  58. package/src/Internal.res.mjs +30 -2
  59. package/src/LoadLayer.res +5 -5
  60. package/src/LoadLayer.res.mjs +6 -6
  61. package/src/LogSelection.res +102 -165
  62. package/src/LogSelection.res.mjs +101 -116
  63. package/src/Main.res +71 -236
  64. package/src/Main.res.mjs +60 -145
  65. package/src/Metrics.res +74 -0
  66. package/src/Metrics.res.mjs +75 -0
  67. package/src/PgStorage.res +4 -4
  68. package/src/PgStorage.res.mjs +5 -5
  69. package/src/Prometheus.res +10 -74
  70. package/src/Prometheus.res.mjs +124 -186
  71. package/src/PruneStaleHistory.res +2 -2
  72. package/src/PruneStaleHistory.res.mjs +3 -3
  73. package/src/RawEvent.res +7 -2
  74. package/src/RawEvent.res.mjs +4 -4
  75. package/src/Rollback.res +3 -3
  76. package/src/Rollback.res.mjs +4 -4
  77. package/src/RollbackCommit.res +4 -1
  78. package/src/RollbackCommit.res.mjs +3 -2
  79. package/src/SimulateDeadInputTracker.res +85 -0
  80. package/src/SimulateDeadInputTracker.res.mjs +73 -0
  81. package/src/SimulateDeadInputTracker.resi +12 -0
  82. package/src/SimulateItems.res +91 -23
  83. package/src/SimulateItems.res.mjs +55 -32
  84. package/src/TestIndexer.res +54 -40
  85. package/src/TestIndexer.res.mjs +37 -30
  86. package/src/bindings/Performance.res +7 -0
  87. package/src/bindings/Performance.res.mjs +21 -0
  88. package/src/bindings/Performance.resi +7 -0
  89. package/src/bindings/Viem.res +0 -41
  90. package/src/bindings/Viem.res.mjs +1 -43
  91. package/src/sources/BlockStore.res +46 -0
  92. package/src/sources/BlockStore.res.mjs +24 -0
  93. package/src/sources/EventRouter.res +36 -33
  94. package/src/sources/EventRouter.res.mjs +13 -14
  95. package/src/sources/Evm.res +83 -72
  96. package/src/sources/Evm.res.mjs +53 -69
  97. package/src/sources/EvmChain.res +18 -20
  98. package/src/sources/EvmChain.res.mjs +15 -15
  99. package/src/sources/EvmRpcClient.res +74 -5
  100. package/src/sources/EvmRpcClient.res.mjs +13 -4
  101. package/src/sources/FieldMask.res +39 -0
  102. package/src/sources/FieldMask.res.mjs +42 -0
  103. package/src/sources/Fuel.res +9 -6
  104. package/src/sources/Fuel.res.mjs +5 -10
  105. package/src/sources/HyperFuelSource.res +46 -50
  106. package/src/sources/HyperFuelSource.res.mjs +64 -54
  107. package/src/sources/HyperSync.res +39 -7
  108. package/src/sources/HyperSync.res.mjs +57 -37
  109. package/src/sources/HyperSync.resi +12 -2
  110. package/src/sources/HyperSyncClient.res +22 -111
  111. package/src/sources/HyperSyncClient.res.mjs +2 -30
  112. package/src/sources/HyperSyncHeightStream.res +1 -8
  113. package/src/sources/HyperSyncHeightStream.res.mjs +0 -2
  114. package/src/sources/HyperSyncSource.res +94 -107
  115. package/src/sources/HyperSyncSource.res.mjs +82 -86
  116. package/src/sources/Rpc.res +15 -47
  117. package/src/sources/Rpc.res.mjs +25 -56
  118. package/src/sources/RpcSource.res +320 -467
  119. package/src/sources/RpcSource.res.mjs +268 -385
  120. package/src/sources/RpcWebSocketHeightStream.res +0 -5
  121. package/src/sources/RpcWebSocketHeightStream.res.mjs +0 -2
  122. package/src/sources/SimulateSource.res +10 -4
  123. package/src/sources/SimulateSource.res.mjs +16 -6
  124. package/src/sources/Source.res +34 -6
  125. package/src/sources/SourceManager.res +86 -27
  126. package/src/sources/SourceManager.res.mjs +84 -47
  127. package/src/sources/SourceManager.resi +12 -3
  128. package/src/sources/Svm.res +31 -16
  129. package/src/sources/Svm.res.mjs +36 -13
  130. package/src/sources/SvmHyperSyncClient.res +5 -32
  131. package/src/sources/SvmHyperSyncSource.res +159 -134
  132. package/src/sources/SvmHyperSyncSource.res.mjs +164 -129
  133. package/src/sources/TransactionStore.res +49 -0
  134. package/src/sources/TransactionStore.res.mjs +30 -0
  135. package/src/tui/Tui.res +13 -16
  136. package/src/tui/Tui.res.mjs +12 -14
  137. package/svm.schema.json +49 -37
  138. package/src/bindings/Hrtime.res +0 -58
  139. package/src/bindings/Hrtime.res.mjs +0 -90
  140. package/src/bindings/Hrtime.resi +0 -30
@@ -43,6 +43,33 @@ let toIndexingAddress = (dc: InternalTable.EnvioAddresses.t): Internal.indexingA
43
43
  registrationBlock: dc.registrationBlock,
44
44
  }
45
45
 
46
+ // All indexing addresses (config-seeded + dynamically registered) grouped by
47
+ // chain id string, derived from the envio_addresses entities.
48
+ let getIndexingAddressesByChain = (state: testIndexerState): dict<
49
+ array<Internal.indexingAddress>,
50
+ > => {
51
+ let byChain = Dict.make()
52
+ switch state.entities->Dict.get(InternalTable.EnvioAddresses.name) {
53
+ | Some(dcDict) =>
54
+ dcDict
55
+ ->Dict.valuesToArray
56
+ ->Array.forEach(entity => {
57
+ let dc = entity->castToEnvioAddresses
58
+ let chainIdStr = dc.chainId->Int.toString
59
+ let contracts = switch byChain->Dict.get(chainIdStr) {
60
+ | Some(arr) => arr
61
+ | None =>
62
+ let arr = []
63
+ byChain->Dict.set(chainIdStr, arr)
64
+ arr
65
+ }
66
+ contracts->Array.push(dc->toIndexingAddress)->ignore
67
+ })
68
+ | None => ()
69
+ }
70
+ byChain
71
+ }
72
+
46
73
  let handleLoad = (state: testIndexerState, ~tableName: string, ~filter: EntityFilter.t): JSON.t => {
47
74
  // Loads for non-entity tables (e.g. effect caches `envio_effect_<name>`) reach
48
75
  // here too. TestIndexer never persists those, so there's nothing to return —
@@ -566,22 +593,10 @@ let makeCreateTestIndexer = (~config: Config.t, ~workerPath: string): (
566
593
  `Cannot access ${contract.name}.addresses while indexer.process() is running. ` ++ "Wait for process() to complete before reading contract addresses.",
567
594
  )
568
595
  }
569
- let addresses = []
570
- switch state.entities->Dict.get(InternalTable.EnvioAddresses.name) {
571
- | Some(dcDict) =>
572
- dcDict
573
- ->Dict.valuesToArray
574
- ->Array.forEach(
575
- entity => {
576
- let dc = entity->castToEnvioAddresses
577
- if dc.contractName === contract.name && dc.chainId === chainConfig.id {
578
- addresses->Array.push(dc->Config.EnvioAddresses.getAddress)->ignore
579
- }
580
- },
581
- )
582
- | None => ()
583
- }
584
- addresses
596
+ getIndexingAddressesByChain(state)
597
+ ->Dict.get(chainConfig.id->Int.toString)
598
+ ->Option.getOr([])
599
+ ->Array.filterMap(ia => ia.contractName === contract.name ? Some(ia.address) : None)
585
600
  },
586
601
  },
587
602
  )
@@ -652,7 +667,7 @@ let makeCreateTestIndexer = (~config: Config.t, ~workerPath: string): (
652
667
  Int.compare(aId, bId)
653
668
  })
654
669
 
655
- // Parse and validate all chain configs upfront before starting any workers
670
+ // Parse and validate the block ranges upfront before starting any workers.
656
671
  let chainEntries = sortedChainKeys->Array.map(chainIdStr => {
657
672
  let rawChainConfig = rawChains->Dict.getUnsafe(chainIdStr)
658
673
  let chainId = switch chainIdStr->Int.fromString {
@@ -684,26 +699,9 @@ let makeCreateTestIndexer = (~config: Config.t, ~workerPath: string): (
684
699
  let chains: dict<chainConfig> = Dict.make()
685
700
  chains->Dict.set(chainIdStr, processChainConfig)
686
701
 
687
- // Extract dynamic contracts from state.entities for each chain
688
- let indexingAddressesByChain: dict<array<Internal.indexingAddress>> = Dict.make()
689
- switch state.entities->Dict.get(InternalTable.EnvioAddresses.name) {
690
- | Some(dcDict) =>
691
- dcDict
692
- ->Dict.valuesToArray
693
- ->Array.forEach(entity => {
694
- let dc = entity->castToEnvioAddresses
695
- let dcChainIdStr = dc.chainId->Int.toString
696
- let contracts = switch indexingAddressesByChain->Dict.get(dcChainIdStr) {
697
- | Some(arr) => arr
698
- | None =>
699
- let arr = []
700
- indexingAddressesByChain->Dict.set(dcChainIdStr, arr)
701
- arr
702
- }
703
- contracts->Array.push(dc->toIndexingAddress)->ignore
704
- })
705
- | None => ()
706
- }
702
+ // Rebuilt per chain so workers see contracts registered by earlier
703
+ // chains in the same process() call.
704
+ let indexingAddressesByChain = getIndexingAddressesByChain(state)
707
705
 
708
706
  let initialState = makeInitialState(
709
707
  ~config,
@@ -852,7 +850,7 @@ let initTestWorker = () => {
852
850
  // Create proxy storage that communicates with main thread
853
851
  let proxy = TestIndexerProxyStorage.make(~parentPort, ~initialState)
854
852
  let storage = TestIndexerProxyStorage.makeStorage(proxy)
855
- let config = Config.loadWithoutRegistrations()
853
+ let config = Config.load()
856
854
  let persistence = Persistence.make(
857
855
  ~userEntities=config.userEntities,
858
856
  ~allEnums=config.allEnums,
@@ -865,7 +863,7 @@ let initTestWorker = () => {
865
863
  | Some(_) => ()
866
864
  }
867
865
 
868
- let patchConfig = (config, _registrations) => {
866
+ let patchConfig = (config: Config.t, _registrations) => {
869
867
  let config = SimulateItems.patchConfig(~config, ~processConfig)
870
868
 
871
869
  // In auto-exit mode, set batchSize=1 to process one block checkpoint at a time
@@ -875,7 +873,23 @@ let initTestWorker = () => {
875
873
  config
876
874
  }
877
875
  }
878
- Main.start(~persistence, ~isTest=true, ~patchConfig, ~exitAfterFirstEventBlock)->ignore
876
+ Main.start(~persistence, ~isTest=true, ~patchConfig, ~exitAfterFirstEventBlock)
877
+ ->Promise.catch(exn => {
878
+ // `Main.start` rejects on any fatal error: a runtime failure arrives wrapped
879
+ // in `Main.FatalError` (already logged), a setup throw (e.g. an invalid
880
+ // simulate item) arrives raw. The parent only learns of failures
881
+ // through the worker `error` event, which fires on an *uncaught* exception.
882
+ // Throwing synchronously in this catch would just reject the catch's own
883
+ // promise (swallowed by `ignore`); `setImmediate` re-throws outside the
884
+ // promise chain so it becomes uncaught and reaches the parent.
885
+ let toThrow = switch exn {
886
+ | Main.FatalError(inner) => inner
887
+ | _ => exn->Utils.prettifyExn
888
+ }
889
+ NodeJs.setImmediate(() => throw(toThrow))
890
+ Promise.resolve()
891
+ })
892
+ ->ignore
879
893
  | None =>
880
894
  Logging.error("TestIndexerWorker: No worker data provided")
881
895
  NodeJs.process->NodeJs.exitWithCode(Failure)
@@ -12,6 +12,7 @@ import * as Stdlib_Int from "@rescript/runtime/lib/es6/Stdlib_Int.js";
12
12
  import * as Persistence from "./Persistence.res.mjs";
13
13
  import * as Stdlib_Dict from "@rescript/runtime/lib/es6/Stdlib_Dict.js";
14
14
  import * as EntityFilter from "./db/EntityFilter.res.mjs";
15
+ import * as Stdlib_Array from "@rescript/runtime/lib/es6/Stdlib_Array.js";
15
16
  import * as InternalTable from "./db/InternalTable.res.mjs";
16
17
  import * as Primitive_int from "@rescript/runtime/lib/es6/Primitive_int.js";
17
18
  import * as SimulateItems from "./SimulateItems.res.mjs";
@@ -32,6 +33,27 @@ function toIndexingAddress(dc) {
32
33
  };
33
34
  }
34
35
 
36
+ function getIndexingAddressesByChain(state) {
37
+ let byChain = {};
38
+ let dcDict = state.entities[Config.EnvioAddresses.name];
39
+ if (dcDict !== undefined) {
40
+ Object.values(dcDict).forEach(entity => {
41
+ let chainIdStr = entity.chain_id.toString();
42
+ let arr = byChain[chainIdStr];
43
+ let contracts;
44
+ if (arr !== undefined) {
45
+ contracts = arr;
46
+ } else {
47
+ let arr$1 = [];
48
+ byChain[chainIdStr] = arr$1;
49
+ contracts = arr$1;
50
+ }
51
+ contracts.push(toIndexingAddress(entity));
52
+ });
53
+ }
54
+ return byChain;
55
+ }
56
+
35
57
  function handleLoad(state, tableName, filter) {
36
58
  let entityConfig = state.entityConfigs[tableName];
37
59
  if (entityConfig === undefined) {
@@ -403,17 +425,11 @@ function makeCreateTestIndexer(config, workerPath) {
403
425
  if (state.processInProgress) {
404
426
  Stdlib_JsError.throwWithMessage(`Cannot access ` + contract.name + `.addresses while indexer.process() is running. ` + "Wait for process() to complete before reading contract addresses.");
405
427
  }
406
- let addresses = [];
407
- let dcDict = state.entities[Config.EnvioAddresses.name];
408
- if (dcDict !== undefined) {
409
- Object.values(dcDict).forEach(entity => {
410
- if (entity.contract_name === contract.name && entity.chain_id === chainConfig.id) {
411
- addresses.push(Config.EnvioAddresses.getAddress(entity));
412
- return;
413
- }
414
- });
415
- }
416
- return addresses;
428
+ return Stdlib_Array.filterMap(Stdlib_Option.getOr(getIndexingAddressesByChain(state)[chainConfig.id.toString()], []), ia => {
429
+ if (ia.contractName === contract.name) {
430
+ return Primitive_option.some(ia.address);
431
+ }
432
+ });
417
433
  }
418
434
  });
419
435
  Object.defineProperty(chainObj, contract.name, {
@@ -484,23 +500,7 @@ function makeCreateTestIndexer(config, workerPath) {
484
500
  let chainId = param[1];
485
501
  let chains = {};
486
502
  chains[param[0]] = processChainConfig;
487
- let indexingAddressesByChain = {};
488
- let dcDict = state.entities[Config.EnvioAddresses.name];
489
- if (dcDict !== undefined) {
490
- Object.values(dcDict).forEach(entity => {
491
- let dcChainIdStr = entity.chain_id.toString();
492
- let arr = indexingAddressesByChain[dcChainIdStr];
493
- let contracts;
494
- if (arr !== undefined) {
495
- contracts = arr;
496
- } else {
497
- let arr$1 = [];
498
- indexingAddressesByChain[dcChainIdStr] = arr$1;
499
- contracts = arr$1;
500
- }
501
- contracts.push(toIndexingAddress(entity));
502
- });
503
- }
503
+ let indexingAddressesByChain = getIndexingAddressesByChain(state);
504
504
  let initialState = makeInitialState(config, chains, indexingAddressesByChain);
505
505
  return new Promise((resolve, reject) => {
506
506
  let workerData_startBlock = processChainConfig.startBlock;
@@ -605,7 +605,7 @@ function initTestWorker() {
605
605
  };
606
606
  let proxy = TestIndexerProxyStorage.make(parentPort, workerData.initialState);
607
607
  let storage = TestIndexerProxyStorage.makeStorage(proxy);
608
- let config = Config.loadWithoutRegistrations();
608
+ let config = Config.load();
609
609
  let persistence = Persistence.make(config.userEntities, config.allEnums, storage);
610
610
  if (Env.userLogLevel !== undefined) {
611
611
 
@@ -640,11 +640,18 @@ function initTestWorker() {
640
640
  return config$1;
641
641
  }
642
642
  };
643
- Main.start(persistence, undefined, true, exitAfterFirstEventBlock, patchConfig);
643
+ Stdlib_Promise.$$catch(Main.start(persistence, undefined, true, exitAfterFirstEventBlock, patchConfig), exn => {
644
+ let toThrow = exn.RE_EXN_ID === Main.FatalError ? exn._1 : Utils.prettifyExn(exn);
645
+ setImmediate(() => {
646
+ throw toThrow;
647
+ });
648
+ return Promise.resolve();
649
+ });
644
650
  }
645
651
 
646
652
  export {
647
653
  toIndexingAddress,
654
+ getIndexingAddressesByChain,
648
655
  handleLoad,
649
656
  handleWriteBatch,
650
657
  makeInitialState,
@@ -0,0 +1,7 @@
1
+ type timeRef = float
2
+
3
+ @val @scope("performance") external now: unit => timeRef = "now"
4
+
5
+ let secondsSince = (from: timeRef): float => (now() -. from) /. 1000.
6
+
7
+ let secondsBetween = (~from: timeRef, ~to: timeRef): float => (to -. from) /. 1000.
@@ -0,0 +1,21 @@
1
+ // Generated by ReScript, PLEASE EDIT WITH CARE
2
+
3
+
4
+ function secondsSince(from) {
5
+ return (performance.now() - from) / 1000;
6
+ }
7
+
8
+ function secondsBetween(from, to) {
9
+ return (to - from) / 1000;
10
+ }
11
+
12
+ function now(prim) {
13
+ return performance.now();
14
+ }
15
+
16
+ export {
17
+ now,
18
+ secondsSince,
19
+ secondsBetween,
20
+ }
21
+ /* No side effect */
@@ -0,0 +1,7 @@
1
+ type timeRef = float
2
+
3
+ let now: unit => timeRef
4
+
5
+ let secondsSince: timeRef => float
6
+
7
+ let secondsBetween: (~from: timeRef, ~to: timeRef) => float
@@ -1,52 +1,11 @@
1
- type eventLog = {
2
- abi: EvmTypes.Abi.t,
3
- data: string,
4
- topics: array<EvmTypes.Hex.t>,
5
- }
6
-
7
- type decodedEvent<'a> = {
8
- eventName: string,
9
- args: 'a,
10
- }
11
-
12
- @module("viem") external decodeEventLogOrThrow: eventLog => decodedEvent<'a> = "decodeEventLog"
13
-
14
1
  type hex = EvmTypes.Hex.t
15
2
  @module("viem") external toHex: 'a => hex = "toHex"
16
3
  @module("viem") external keccak256: hex => hex = "keccak256"
17
- @module("viem") external keccak256Bytes: Uint8Array.t => hex = "keccak256"
18
4
  @module("viem") external pad: hex => hex = "pad"
19
- @module("viem")
20
- external encodePacked: (~types: array<string>, ~values: array<'a>) => hex = "encodePacked"
21
5
 
22
6
  type sizeOptions = {size: int}
23
- @module("viem") external intToHex: (int, ~options: sizeOptions=?) => hex = "numberToHex"
24
7
  @module("viem") external bigintToHex: (bigint, ~options: sizeOptions=?) => hex = "numberToHex"
25
8
  @module("viem") external stringToHex: (string, ~options: sizeOptions=?) => hex = "stringToHex"
26
9
  @module("viem") external boolToHex: (bool, ~options: sizeOptions=?) => hex = "boolToHex"
27
10
  @module("viem") external bytesToHex: (Uint8Array.t, ~options: sizeOptions=?) => hex = "bytesToHex"
28
11
  @module("viem") external concat: array<hex> => hex = "concat"
29
-
30
- exception ParseError(exn)
31
- exception UnknownContractName({contractName: string})
32
-
33
- let parseLogOrThrow = (
34
- contractNameAbiMapping: dict<EvmTypes.Abi.t>,
35
- ~contractName,
36
- ~topics,
37
- ~data,
38
- ) => {
39
- switch contractNameAbiMapping->Utils.Dict.dangerouslyGetNonOption(contractName) {
40
- | None => throw(UnknownContractName({contractName: contractName}))
41
- | Some(abi) =>
42
- let viemLog: eventLog = {
43
- abi,
44
- data,
45
- topics,
46
- }
47
-
48
- try viemLog->decodeEventLogOrThrow catch {
49
- | exn => throw(ParseError(exn))
50
- }
51
- }
52
- }
@@ -1,44 +1,2 @@
1
1
  // Generated by ReScript, PLEASE EDIT WITH CARE
2
-
3
- import * as Viem from "viem";
4
- import * as Primitive_option from "@rescript/runtime/lib/es6/Primitive_option.js";
5
- import * as Primitive_exceptions from "@rescript/runtime/lib/es6/Primitive_exceptions.js";
6
-
7
- let ParseError = /* @__PURE__ */Primitive_exceptions.create("Viem.ParseError");
8
-
9
- let UnknownContractName = /* @__PURE__ */Primitive_exceptions.create("Viem.UnknownContractName");
10
-
11
- function parseLogOrThrow(contractNameAbiMapping, contractName, topics, data) {
12
- let abi = contractNameAbiMapping[contractName];
13
- if (abi !== undefined) {
14
- let viemLog_abi = Primitive_option.valFromOption(abi);
15
- let viemLog = {
16
- abi: viemLog_abi,
17
- data: data,
18
- topics: topics
19
- };
20
- try {
21
- return Viem.decodeEventLog(viemLog);
22
- } catch (raw_exn) {
23
- let exn = Primitive_exceptions.internalToException(raw_exn);
24
- throw {
25
- RE_EXN_ID: ParseError,
26
- _1: exn,
27
- Error: new Error()
28
- };
29
- }
30
- } else {
31
- throw {
32
- RE_EXN_ID: UnknownContractName,
33
- contractName: contractName,
34
- Error: new Error()
35
- };
36
- }
37
- }
38
-
39
- export {
40
- ParseError,
41
- UnknownContractName,
42
- parseLogOrThrow,
43
- }
44
- /* viem Not a pure module */
2
+ /* This output is empty. Its source's type definitions, externals and/or unused code got optimized away. */
@@ -0,0 +1,46 @@
1
+ // Binding to the Rust `BlockStore` napi class. Blocks are kept in Rust as raw
2
+ // structs (their large fields never enter JS until read) keyed by block number.
3
+ // One store lives per chain on `ChainState`; each fetch response contributes a
4
+ // page that is merged in. At batch preparation the selected fields are
5
+ // materialised in bulk, off the JS thread, in columnar form and zipped into
6
+ // plain JS objects on the main thread.
7
+ type t
8
+
9
+ @send external newEvm: (Core.blockStoreCtor, ~shouldChecksum: bool) => t = "newEvm"
10
+ @send external newSvm: Core.blockStoreCtor => t = "newSvm"
11
+ @send external newFuel: Core.blockStoreCtor => t = "newFuel"
12
+
13
+ // The store's ecosystem is fixed here, from the chain's config. EVM carries the
14
+ // chain's address-checksumming setting; SVM/Fuel need no extra data.
15
+ let make = (~ecosystem: Ecosystem.name, ~shouldChecksum: bool): t => {
16
+ let ctor = Core.getAddon().blockStore
17
+ switch ecosystem {
18
+ | Evm => ctor->newEvm(~shouldChecksum)
19
+ | Svm => ctor->newSvm
20
+ | Fuel => ctor->newFuel
21
+ }
22
+ }
23
+
24
+ // One event's selected block fields → store selection bitmask, built from the
25
+ // ecosystem's ordered field-name array (the bit index is the field code shared
26
+ // with the Rust store, `EvmBlockField`).
27
+ let makeMaskFn = FieldMask.makeMaskFn
28
+
29
+ // Drain another store (a fetch-response page) into this one.
30
+ @send external merge: (t, t) => unit = "merge"
31
+
32
+ // Bulk-materialise blocks off the JS thread, one row per `blockNumbers[i]` key,
33
+ // decoding only the fields set in that row's own `masks[i]`. Result is aligned
34
+ // with the input.
35
+ @send
36
+ external materialize: (
37
+ t,
38
+ ~blockNumbers: array<int>,
39
+ ~masks: array<float>,
40
+ ) => promise<array<Internal.eventBlock>> = "materialize"
41
+
42
+ // Drop blocks at or below the given block (already processed).
43
+ @send external prune: (t, int) => unit = "prune"
44
+
45
+ // Drop blocks above the given block (rolled back).
46
+ @send external rollback: (t, int) => unit = "rollback"
@@ -0,0 +1,24 @@
1
+ // Generated by ReScript, PLEASE EDIT WITH CARE
2
+
3
+ import * as Core from "../Core.res.mjs";
4
+ import * as FieldMask from "./FieldMask.res.mjs";
5
+
6
+ function make(ecosystem, shouldChecksum) {
7
+ let ctor = Core.getAddon().BlockStore;
8
+ switch (ecosystem) {
9
+ case "evm" :
10
+ return ctor.newEvm(shouldChecksum);
11
+ case "fuel" :
12
+ return ctor.newFuel();
13
+ case "svm" :
14
+ return ctor.newSvm();
15
+ }
16
+ }
17
+
18
+ let makeMaskFn = FieldMask.makeMaskFn;
19
+
20
+ export {
21
+ make,
22
+ makeMaskFn,
23
+ }
24
+ /* Core Not a pure module */
@@ -28,29 +28,25 @@ module Group = {
28
28
  }
29
29
  }
30
30
 
31
- let get = (
32
- group: t<'a>,
33
- ~contractAddress,
34
- ~blockNumber,
35
- ~indexingAddresses: dict<FetchState.indexingAddress>,
36
- ) =>
31
+ // Ownership only: resolve the owning contract from the partition's reverse
32
+ // index (the partition that fetched the log), not a chain-wide snapshot. The
33
+ // `effectiveStartBlock` temporal gate now lives in `clientAddressFilter`. The
34
+ // wildcard partition has an empty index → every log falls back to `wildcard`,
35
+ // so it can never claim an address-bound contract's logs.
36
+ let get = (group: t<'a>, ~contractAddress, ~contractNameByAddress: dict<string>) =>
37
37
  switch group {
38
38
  | {wildcard, byContractName} =>
39
- switch indexingAddresses->Utils.Dict.dangerouslyGetNonOption(
39
+ switch contractNameByAddress->Utils.Dict.dangerouslyGetNonOption(
40
40
  contractAddress->Address.toString,
41
41
  ) {
42
- | Some(indexingContract) =>
43
- if indexingContract.effectiveStartBlock <= blockNumber {
44
- switch byContractName->Utils.Dict.dangerouslyGetNonOption(indexingContract.contractName) {
45
- // Fall back to the wildcard handler when the indexed contract has no
46
- // matching event for this tag. This covers addresses registered for
47
- // contracts without events (persisted for future config changes) as
48
- // well as addresses whose contract has other events but not this one.
49
- | None => wildcard
50
- | Some(_) as event => event
51
- }
52
- } else {
53
- None
42
+ | Some(contractName) =>
43
+ switch byContractName->Utils.Dict.dangerouslyGetNonOption(contractName) {
44
+ // Fall back to the wildcard handler when the owning contract has no
45
+ // matching event for this tag. This covers addresses registered for
46
+ // contracts without events (persisted for future config changes) as
47
+ // well as addresses whose contract has other events but not this one.
48
+ | None => wildcard
49
+ | Some(_) as event => event
54
50
  }
55
51
  | None => wildcard
56
52
  }
@@ -89,10 +85,10 @@ let addOrThrow = (
89
85
  }
90
86
  }
91
87
 
92
- let get = (router: t<'a>, ~tag, ~contractAddress, ~blockNumber, ~indexingAddresses) => {
88
+ let get = (router: t<'a>, ~tag, ~contractAddress, ~contractNameByAddress) => {
93
89
  switch router->Utils.Dict.dangerouslyGetNonOption(tag) {
94
90
  | None => None
95
- | Some(group) => group->Group.get(~contractAddress, ~blockNumber, ~indexingAddresses)
91
+ | Some(group) => group->Group.get(~contractAddress, ~contractNameByAddress)
96
92
  }
97
93
  }
98
94
 
@@ -100,16 +96,16 @@ let getEvmEventId = (~sighash, ~topicCount) => {
100
96
  sighash ++ "_" ++ topicCount->Int.toString
101
97
  }
102
98
 
103
- let fromEvmEventModsOrThrow = (events: array<Internal.evmEventConfig>, ~chain): t<
104
- Internal.evmEventConfig,
99
+ let fromEvmEventModsOrThrow = (events: array<Internal.evmOnEventRegistration>, ~chain): t<
100
+ Internal.evmOnEventRegistration,
105
101
  > => {
106
102
  let router = empty()
107
103
  events->Array.forEach(config => {
108
104
  router->addOrThrow(
109
- config.id,
105
+ config.eventConfig.id,
110
106
  config,
111
- ~contractName=config.contractName,
112
- ~eventName=config.name,
107
+ ~contractName=config.eventConfig.contractName,
108
+ ~eventName=config.eventConfig.name,
113
109
  ~chain,
114
110
  ~isWildcard=config.isWildcard,
115
111
  )
@@ -135,21 +131,26 @@ type svmProgramOrdering = {
135
131
  byteLengthsDesc: array<int>,
136
132
  }
137
133
 
138
- let fromSvmEventConfigsOrThrow = (events: array<Internal.svmInstructionEventConfig>, ~chain): (
139
- t<Internal.svmInstructionEventConfig>,
134
+ let fromSvmEventConfigsOrThrow = (events: array<Internal.svmOnEventRegistration>, ~chain): (
135
+ t<Internal.svmOnEventRegistration>,
140
136
  array<svmProgramOrdering>,
141
137
  ) => {
142
138
  let router = empty()
143
139
  events->Array.forEach(config => {
140
+ let eventConfig =
141
+ config.eventConfig->(Utils.magic: Internal.eventConfig => Internal.svmInstructionEventConfig)
144
142
  // The router tag must include the programId so two programs declaring the
145
143
  // same discriminator coexist. The source-side lookup uses the same shape
146
144
  // via `getSvmEventId(~programId, ~discriminator)`.
147
- let routerTag = getSvmEventId(~programId=config.programId, ~discriminator=config.discriminator)
145
+ let routerTag = getSvmEventId(
146
+ ~programId=eventConfig.programId,
147
+ ~discriminator=eventConfig.discriminator,
148
+ )
148
149
  router->addOrThrow(
149
150
  routerTag,
150
151
  config,
151
- ~contractName=config.contractName,
152
- ~eventName=config.name,
152
+ ~contractName=eventConfig.contractName,
153
+ ~eventName=eventConfig.name,
153
154
  ~chain,
154
155
  ~isWildcard=config.isWildcard,
155
156
  )
@@ -158,7 +159,9 @@ let fromSvmEventConfigsOrThrow = (events: array<Internal.svmInstructionEventConf
158
159
  // Per-program list of declared discriminator byte lengths, sorted desc.
159
160
  let byProgram: dict<Utils.Set.t<int>> = Dict.make()
160
161
  events->Array.forEach(config => {
161
- let key = config.programId->SvmTypes.Pubkey.toString
162
+ let eventConfig =
163
+ config.eventConfig->(Utils.magic: Internal.eventConfig => Internal.svmInstructionEventConfig)
164
+ let key = eventConfig.programId->SvmTypes.Pubkey.toString
162
165
  let set = switch byProgram->Utils.Dict.dangerouslyGetNonOption(key) {
163
166
  | Some(s) => s
164
167
  | None =>
@@ -166,7 +169,7 @@ let fromSvmEventConfigsOrThrow = (events: array<Internal.svmInstructionEventConf
166
169
  byProgram->Dict.set(key, s)
167
170
  s
168
171
  }
169
- let _ = set->Utils.Set.add(config.discriminatorByteLen)
172
+ let _ = set->Utils.Set.add(eventConfig.discriminatorByteLen)
170
173
  })
171
174
  let ordering =
172
175
  byProgram
@@ -39,16 +39,13 @@ function addOrThrow(group, event, contractName, isWildcard) {
39
39
  byContractName[contractName] = event;
40
40
  }
41
41
 
42
- function get(group, contractAddress, blockNumber, indexingAddresses) {
42
+ function get(group, contractAddress, contractNameByAddress) {
43
43
  let wildcard = group.wildcard;
44
- let indexingContract = indexingAddresses[contractAddress];
45
- if (indexingContract === undefined) {
44
+ let contractName = contractNameByAddress[contractAddress];
45
+ if (contractName === undefined) {
46
46
  return wildcard;
47
47
  }
48
- if (indexingContract.effectiveStartBlock > blockNumber) {
49
- return;
50
- }
51
- let event = group.byContractName[indexingContract.contractName];
48
+ let event = group.byContractName[contractName];
52
49
  if (event !== undefined) {
53
50
  return event;
54
51
  } else {
@@ -93,10 +90,10 @@ function addOrThrow$1(router, eventId, event, contractName, isWildcard, eventNam
93
90
  }
94
91
  }
95
92
 
96
- function get$1(router, tag, contractAddress, blockNumber, indexingAddresses) {
93
+ function get$1(router, tag, contractAddress, contractNameByAddress) {
97
94
  let group = router[tag];
98
95
  if (group !== undefined) {
99
- return get(group, contractAddress, blockNumber, indexingAddresses);
96
+ return get(group, contractAddress, contractNameByAddress);
100
97
  }
101
98
  }
102
99
 
@@ -106,7 +103,7 @@ function getEvmEventId(sighash, topicCount) {
106
103
 
107
104
  function fromEvmEventModsOrThrow(events, chain) {
108
105
  let router = {};
109
- events.forEach(config => addOrThrow$1(router, config.id, config, config.contractName, config.isWildcard, config.name, chain));
106
+ events.forEach(config => addOrThrow$1(router, config.eventConfig.id, config, config.eventConfig.contractName, config.isWildcard, config.eventConfig.name, chain));
110
107
  return router;
111
108
  }
112
109
 
@@ -121,12 +118,14 @@ function getSvmEventId(programId, discriminator) {
121
118
  function fromSvmEventConfigsOrThrow(events, chain) {
122
119
  let router = {};
123
120
  events.forEach(config => {
124
- let routerTag = getSvmEventId(config.programId, config.discriminator);
125
- addOrThrow$1(router, routerTag, config, config.contractName, config.isWildcard, config.name, chain);
121
+ let eventConfig = config.eventConfig;
122
+ let routerTag = getSvmEventId(eventConfig.programId, eventConfig.discriminator);
123
+ addOrThrow$1(router, routerTag, config, eventConfig.contractName, config.isWildcard, eventConfig.name, chain);
126
124
  });
127
125
  let byProgram = {};
128
126
  events.forEach(config => {
129
- let key = config.programId;
127
+ let eventConfig = config.eventConfig;
128
+ let key = eventConfig.programId;
130
129
  let s = byProgram[key];
131
130
  let set;
132
131
  if (s !== undefined) {
@@ -136,7 +135,7 @@ function fromSvmEventConfigsOrThrow(events, chain) {
136
135
  byProgram[key] = s$1;
137
136
  set = s$1;
138
137
  }
139
- set.add(config.discriminatorByteLen);
138
+ set.add(eventConfig.discriminatorByteLen);
140
139
  });
141
140
  let ordering = Object.entries(byProgram).map(param => {
142
141
  let sorted = Array.from(param[1]).toSorted((a, b) => b - a | 0);