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
package/evm.schema.json CHANGED
@@ -548,6 +548,16 @@
548
548
  "null"
549
549
  ]
550
550
  },
551
+ "headers": {
552
+ "description": "Optional HTTP headers sent with every request to this RPC endpoint, e.g. an Authorization bearer token for gated endpoints. Values support ${ENV_VAR} interpolation.",
553
+ "type": [
554
+ "object",
555
+ "null"
556
+ ],
557
+ "additionalProperties": {
558
+ "type": "string"
559
+ }
560
+ },
551
561
  "initial_block_interval": {
552
562
  "description": "The starting interval in range of blocks per query",
553
563
  "type": [
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 = {
@@ -997,24 +1008,6 @@ export type SvmTokenBalance = {
997
1008
  readonly postAmount?: string;
998
1009
  };
999
1010
 
1000
- /** Parent transaction surfaced when an instruction's
1001
- * `include_transaction` flag is `true`. */
1002
- export type SvmTransaction = {
1003
- readonly signatures: readonly string[];
1004
- readonly feePayer?: string;
1005
- readonly success?: boolean;
1006
- readonly err?: string;
1007
- /** Lamports. */
1008
- readonly fee?: bigint;
1009
- readonly computeUnitsConsumed?: bigint;
1010
- readonly accountKeys: readonly string[];
1011
- readonly recentBlockhash?: string;
1012
- readonly version?: string;
1013
- /** SPL Token / Token-2022 balance snapshots for this transaction.
1014
- * Present when `include_token_balances` is `true`. */
1015
- readonly tokenBalances?: readonly SvmTokenBalance[];
1016
- };
1017
-
1018
1011
  export type SvmLog = {
1019
1012
  readonly kind: string;
1020
1013
  readonly message: string;
@@ -1033,6 +1026,8 @@ export type SvmLog = {
1033
1026
  * are base58 strings. */
1034
1027
  export type SvmInstruction<
1035
1028
  Params extends SvmInstructionParams = SvmInstructionParams,
1029
+ Tx = SvmTransaction,
1030
+ Block = SvmInstructionBlock,
1036
1031
  > = {
1037
1032
  /** Program name as declared under `programs[].name` in `config.yaml`. */
1038
1033
  readonly programName: string;
@@ -1050,12 +1045,20 @@ export type SvmInstruction<
1050
1045
  readonly d8?: string;
1051
1046
  /** Borsh-decoded params. Present when a schema is configured and matched. */
1052
1047
  readonly params?: Params;
1053
- /** Present when the instruction's `include_transaction` is `true`. */
1054
- readonly transaction?: SvmTransaction;
1048
+ /** Parent transaction. Carries only the fields selected via this
1049
+ * instruction's `field_selection`; unselected fields are typed as
1050
+ * `FieldNotSelected<...>` so reading them is a compile error. Always present
1051
+ * (`{}` when no fields are selected). */
1052
+ readonly transaction: Tx;
1055
1053
  /** Present when the instruction's `include_logs` is `true`; only logs
1056
1054
  * scoped to this exact instruction (matching `instruction_address`). */
1057
1055
  readonly logs?: readonly SvmLog[];
1058
- 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;
1059
1062
  };
1060
1063
 
1061
1064
  /** Arguments passed to handlers registered via `indexer.onInstruction`. */
@@ -1327,7 +1330,11 @@ type SvmEcosystem<Config extends IndexerConfigTypes = GlobalConfig> =
1327
1330
  handler: (
1328
1331
  args: SvmOnInstructionHandlerArgs<
1329
1332
  Config,
1330
- SvmInstruction<SvmParamsFromProgramTable<Programs[P][I]>>
1333
+ SvmInstruction<
1334
+ SvmParamsFromProgramTable<Programs[P][I]>,
1335
+ Programs[P][I]["transaction"],
1336
+ Programs[P][I]["block"]
1337
+ >
1331
1338
  >,
1332
1339
  ) => Promise<void>,
1333
1340
  ) => void;
@@ -1695,6 +1702,7 @@ type EvmContractsT = GlobalConfig extends { evm: { contracts: infer X extends
1695
1702
  type FuelChainsT = GlobalConfig extends { fuel: { chains: infer X extends Record<string, { id: number }> } } ? X : {};
1696
1703
  type FuelContractsT = GlobalConfig extends { fuel: { contracts: infer X extends Record<string, Record<string, any>> } } ? X : {};
1697
1704
  type SvmChainsT = GlobalConfig extends { svm: { chains: infer X extends Record<string, { id: number }> } } ? X : {};
1705
+ type SvmProgramsT = GlobalConfig extends { svm: { programs: infer X extends Record<string, Record<string, any>> } } ? X : {};
1698
1706
  type EntitiesT = GlobalConfig extends { entities: infer X extends Record<string, object> } ? X : {};
1699
1707
  type EnumsT = GlobalConfig extends { enums: infer X extends Record<string, any> } ? X : {};
1700
1708
 
@@ -1716,6 +1724,18 @@ export type FuelChainId = IsEmptyObject<FuelChainsT> extends true ? NotConfigure
1716
1724
  /** Union of all configured SVM chain IDs. */
1717
1725
  export type SvmChainId = IsEmptyObject<SvmChainsT> extends true ? NotConfigured<"SvmChainId", "Configure SVM chains"> : SvmChainsT [keyof SvmChainsT ]["id"];
1718
1726
 
1727
+ /** The SVM parent-transaction type generated from this project's
1728
+ * `field_selection`: the union of every instruction's `transaction` shape,
1729
+ * with unselected fields typed as `FieldNotSelected<...>`. Resolves to a
1730
+ * `NotConfigured` hint until `envio codegen` augments {@link Global}. */
1731
+ export type SvmTransaction = IsEmptyObject<SvmProgramsT> extends true
1732
+ ? NotConfigured<"SvmTransaction", "Configure SVM programs">
1733
+ : {
1734
+ [P in keyof SvmProgramsT]: {
1735
+ [I in keyof SvmProgramsT[P]]: SvmProgramsT[P][I]["transaction"];
1736
+ }[keyof SvmProgramsT[P]];
1737
+ }[keyof SvmProgramsT];
1738
+
1719
1739
  /** Lookup an EVM event type by contract and event name. Without generics,
1720
1740
  * resolves to the discriminated union of every EVM event in the project. */
1721
1741
  export type EvmEvent<
@@ -0,0 +1,35 @@
1
+ # Contributor License Agreement (CLA)
2
+
3
+ ## 1. Introduction
4
+
5
+ Thank you for your interest in contributing to this project ("Project"). We value your time and effort, and we appreciate all contributions made by the community. By submitting any work (a "Contribution"), you agree to the terms below.
6
+
7
+ ## 2. Automatic Acceptance
8
+
9
+ By submitting a Pull Request or making any contribution to this project, you automatically agree to and accept all terms outlined in this Contributor License Agreement. This includes all future contributions you may make to the project.
10
+
11
+ ## 3. Your Contributions
12
+
13
+ 3.1 A "Contribution" includes any original work you share with the Project, such as code, documentation, or other creative content.
14
+
15
+ 3.2 You confirm that each Contribution is either your own original work or that you have all necessary rights and permissions to submit it under this CLA.
16
+
17
+ ## 4. License Grant
18
+
19
+ 4.1 By submitting a Contribution, you grant Envio (the "Maintainer") an irrevocable, worldwide, non-exclusive, royalty-free, perpetual license to use, reproduce, modify, distribute, prepare derivative works of, publicly display, perform, sublicense, and otherwise exploit your Contribution as part of the Project.
20
+
21
+ 4.2 You agree that the Maintainer may license or re-license your Contribution under terms compatible with those of the Project.
22
+
23
+ ## 5. Ongoing Use
24
+
25
+ 5.1 Once provided, Contributions cannot be retracted; however, the Maintainer is not obligated to include or continue using your Contribution.
26
+
27
+ 5.2 You understand that this CLA helps ensure your work remains compatible with the Project's licensing, now and in the future.
28
+
29
+ ## 6. Disclaimer
30
+
31
+ 6.1 You provide your Contributions on an "as is" basis, without warranties of any kind. This includes, but is not limited to, warranties of merchantability, fitness for a particular purpose, and non-infringement.
32
+
33
+ ## 7. Governing Law
34
+
35
+ 7.1 This CLA is governed by and construed in accordance with the laws of England. Any disputes will be subject to the exclusive jurisdiction of the English courts.
@@ -0,0 +1,67 @@
1
+ ## HyperIndex End-User License Agreement (EULA)
2
+
3
+ This agreement describes the users' rights and the conditions upon which the Software and Generated Code may be used. The user should review the entire agreement, including any supplemental license terms that accompany the Software, since all of the terms are important and together create this agreement that applies to them.
4
+
5
+ ### 1. Definitions
6
+
7
+ **Software:** HyperIndex, a copyrightable work created by Envio and licensed under this End User License Agreement (“EULA”).
8
+
9
+ **Generated Code:** In the context of this license agreement, the term "generated code" refers to computer programming code that is produced automatically by the Software based on input provided by the user.
10
+
11
+ **Licensed Material:** The Software and Generated Code defined here will be collectively referred to as “Licensed Material”.
12
+
13
+ ### 2. Installation and User Rights
14
+
15
+ **License:** The Software is provided under this EULA. By agreeing to the EULA terms, you are granted the right to install and operate one instance of the Software on your device (referred to as the licensed device), for the use of one individual at a time, on the condition that you adhere to all terms outlined in this agreement.
16
+ The licensor provides you with a non-exclusive, royalty-free, worldwide license that is non-sublicensable and non-transferable. This license allows you to use the Software subject to the limitations and conditions outlined in this EULA.
17
+ With one license, the user can only use the Software on a single device.
18
+
19
+ **Device:** In this agreement, "device" refers to a hardware system, whether physical or virtual, equipped with an internal storage device capable of executing the Software. This includes hardware partitions, which are considered as individual devices for the purposes of this agreement. Updates may be provided to the Software, and these updates may alter the minimum hardware requirements necessary for the Software. It is the responsibility of users to comply with any changing hardware requirements.
20
+
21
+ **Updates:** The Software may be updated automatically. With each update, the EULA may be amended, and it is the users' responsibility to comply with the amendments.
22
+
23
+ **Limitations:** Envio reserves all rights, including those under intellectual property laws, not expressly granted in this agreement. For instance, this license does not confer upon you the right to, and you are prohibited from:
24
+
25
+ (i) Publishing, copying (other than the permitted backup copy), renting, leasing, or lending the Software;
26
+
27
+ (ii) Transferring the Software (except as permitted by this agreement);
28
+
29
+ (iii) Circumventing any technical restrictions or limitations in the Software;
30
+
31
+ (iv) Using the Software as server Software, for commercial hosting, making the Software available for simultaneous use by multiple users over a network, installing the Software on a server and allowing users to access it remotely, or installing the Software on a device solely for remote user use;
32
+
33
+ (v) Reverse engineering, decompiling, or disassembling the Software, or attempting to do so, except and only to the extent that the foregoing restriction is (a) permitted by applicable law; (b) permitted by licensing terms governing the use of open-source components that may be included with the Software and
34
+
35
+ (vi) When using the Software, you may not use any features in any manner that could interfere with anyone else's use of them, or attempt to gain unauthorized access to or use of any service, data, account, or network.
36
+
37
+ These limitations apply specifically to the Software and do not extend to the Generated Code. Details regarding the use of the Generated Code, including associated limitations, are provided below.
38
+
39
+ ### 3. Use of the Generated Code
40
+
41
+ **Limitations:** Users can use, copy, distribute, make available, and create derivative works of the Generated Code freely, subject to the limitations and conditions specified below.
42
+
43
+ (i) The user is prohibited from offering the Generated Code or any software that includes the Generated Code to third parties as a hosted or managed service, where the service grants users access to a significant portion of the Software's features or functionality.
44
+
45
+ (ii) The user is not permitted to tamper with, alter, disable, or bypass the functionality of the license key in the Software. Additionally, the user may not eliminate or conceal any functionality within the Software that is safeguarded by the license key.
46
+
47
+ (iii) Any modification, removal, or concealment of licensing, copyright, or other notices belonging to the licensor in the Software is strictly forbidden. The use of the licensor's trademarks is subject to relevant laws.
48
+
49
+ **Credit:** If the user utilizes the Generated Code to develop and release a new software, product or service, the license agreement for said software, product or service must include proper credit to HyperIndex.
50
+
51
+ **Liability:** Envio does not provide any assurance that the Generated Code functions correctly, nor does it assume any responsibility in this regard.
52
+
53
+ Additionally, it will be the responsibility of the user to assess whether the Generated Code is suitable for the products and services provided by the user. Envio will not bear any responsibility if the Generated Code is found unsuitable for the products and services provided by the user.
54
+
55
+ ### 4. Additional Terms
56
+
57
+ **Disclaimer of Warranties and Limitation of Liability:**
58
+
59
+ (i) Unless expressly undertaken by the Licensor separately, the Licensed Material is provided on an as-is, as-available basis, and the Licensor makes no representations or warranties of any kind regarding the Licensed Material, whether express, implied, statutory, or otherwise. This encompasses, without limitation, warranties of title, merchantability, fitness for a particular purpose, non-infringement, absence of latent or other defects, accuracy, or the presence or absence of errors, whether known or discoverable. If disclaimers of warranties are not permitted in whole or in part, this disclaimer may not apply to You.
60
+
61
+ (ii) To the fullest extent permitted by law, under no circumstances shall the Licensor be liable to You under any legal theory (including, but not limited to, negligence) for any direct, special, indirect, incidental, consequential, punitive, exemplary, or other losses, costs, expenses, or damages arising from the use of the Licensed Material, even if the Licensor has been advised of the possibility of such losses, costs, expenses, or damages. If limitations of liability are not permitted in whole or in part, this limitation may not apply to You.
62
+
63
+ (iii) The disclaimers of warranties and limitations of liability outlined above shall be construed in a manner that most closely approximates an absolute disclaimer and waiver of all liability, to the fullest extent permitted by law.
64
+
65
+ **Applicable Law and Competent Courts:** This EULA and shall be governed by and construed in accordance with the laws of England. The courts of England shall have exclusive jurisdiction to settle any dispute arising out of or in connection with this EULA.
66
+
67
+ **Additional Agreements:** If the user chooses to use the Software, it may be required to agree to additional terms or agreements outside of this EULA.
@@ -0,0 +1,45 @@
1
+ # Standard SaaS End User License Agreement (EULA)
2
+
3
+ ## End User License Agreement (EULA)
4
+
5
+ This End User License Agreement ("Agreement") is between Envio ("Company") and the user ("User") who downloads, installs, or uses the Software as a Service (SaaS) provided by the Company.
6
+
7
+ ### 1. License Grant
8
+
9
+ 1.1 Company grants User a non-exclusive, non-transferable, limited license to access and use the SaaS for business or personal purposes in accordance with this Agreement.
10
+
11
+ ### 2. Restrictions
12
+
13
+ 2.1 User shall not:
14
+
15
+ - Modify, copy, or create derivative works based on the SaaS.
16
+ - Reverse engineer, decompile, or disassemble the SaaS.
17
+ - Rent, lease, lend, sell, redistribute, or sublicense the SaaS.
18
+ - Use the SaaS for any unlawful purpose.
19
+
20
+ ### 3. Ownership
21
+
22
+ 3.1 The Company retains all rights, title, and interest in and to the SaaS, including all intellectual property rights.
23
+
24
+ ### 4. Term and Termination
25
+
26
+ 4.1 This Agreement is effective until terminated. User’s rights under this Agreement will terminate automatically without notice if User fails to comply with any term(s) of this Agreement.
27
+ 4.2 Upon termination, User must cease all use of the SaaS and destroy all copies of any related documentation.
28
+
29
+ ### 5. Disclaimer of Warranties
30
+
31
+ 5.1 The SaaS is provided "AS IS" without warranty of any kind, either express or implied, including, but not limited to, implied warranties of merchantability and fitness for a particular purpose.
32
+
33
+ ### 6. Limitation of Liability
34
+
35
+ 6.1 In no event shall Company be liable for any special, incidental, indirect, or consequential damages whatsoever arising out of the use of or inability to use the SaaS.
36
+
37
+ ### 7. Governing Law
38
+
39
+ 7.1 This Agreement shall be governed by and construed in accordance with the laws of the United Kingdom.
40
+
41
+ ### 8. Entire Agreement
42
+
43
+ 8.1 This Agreement constitutes the entire agreement between the parties with respect to the use of the SaaS and supersedes all prior or contemporaneous understandings regarding such subject matter.
44
+
45
+ **By using the SaaS, the User agrees to be bound by this Agreement.**
@@ -0,0 +1,35 @@
1
+ # Licensing Information
2
+
3
+ ## Overview
4
+
5
+ Envio's licensing reflects open source ethos but is not OSI recognized. Developers can use Envio's services without vendor lock-in, either by self-hosting or specifying an RPC URL. The generated code is open and public and so is this repository that generates the generated code.
6
+
7
+ Our licenses allows self-hosting but restricts third-party hosting with Envio's hosted service. Envio may consider open-sourcing in the future but prioritizes stakeholder interests and market traction. Please reach out to us on discord if you would like to explore hosting indexers as a third-party.
8
+
9
+ ## TL;DR
10
+
11
+ - **Envio's licensing** mirrors open source benefits but is not OSI recognized.
12
+ - **Developers** can use Envio's services without vendor lock-in by:
13
+ - Self-hosting.
14
+ - Specifying an RPC URL.
15
+ - **Code** is open and public.
16
+ - **Generated license** allows self-hosting but restricts third-party competition.
17
+ - **Code generator license** is a commercial license.
18
+ - **non-comercial use** is allowed.
19
+ - **forking and modifying code** is not allowed. However, if you have specific needs or use cases, please contact us to discuss potential exceptions.
20
+ - **Future considerations** for open-sourcing are dependent on market traction and stakeholder interests.
21
+ - **Contributors** must agree to our Contributor License Agreement (CLA).
22
+
23
+ ## Our Position
24
+
25
+ We're developers who value the open source ethos, which is why our licensing mirrors many benefits of open source licensing. However, Envio and its products do not use a recognized open source license by the OSI. We are public and open, and our licensing reflects this.
26
+
27
+ Our future business model lies in our hosted service and HyperSync requests, and we are protecting this. To ensure continuity and avoid vendor lock-in, developers can run and develop on their indexer without our hosted service. This can be achieved either by self-hosting, which our license permits, or by specifying an RPC URL in their indexer configuration, thus bypassing HyperSync.
28
+
29
+ Envio is in its formative stages. Although we may consider open-sourcing the software in the future, we are committed to ensuring the best interests of all stakeholders. Going open source is somewhat of a one-way function; it's easier to open source than to go "closed source." Once we have gained more market traction, we will review our position on going open source.
30
+
31
+ ## Our Licenses
32
+
33
+ - [EULA](./EULA.md) - The license in your indexer pertaining to the generated code
34
+ - [LICENSE](./LICENSE.md) - The non-commercial use license pertaining to this code base which is used to template & generate the indexing code
35
+ - [CLA](./CLA.md) - The Contributor License Agreement for those who wish to contribute to the project
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "envio",
3
- "version": "3.3.0-alpha.1",
3
+ "version": "3.3.0-alpha.11",
4
4
  "type": "module",
5
5
  "description": "A latency and sync speed optimized, developer friendly blockchain data indexer.",
6
6
  "bin": "./bin.mjs",
@@ -11,7 +11,7 @@
11
11
  "url": "git+https://github.com/enviodev/hyperindex.git"
12
12
  },
13
13
  "author": "envio contributors <about@envio.dev>",
14
- "license": "GPL-3.0",
14
+ "license": "SEE LICENSE IN licenses/README.md",
15
15
  "bugs": {
16
16
  "url": "https://github.com/enviodev/hyperindex/issues"
17
17
  },
@@ -37,7 +37,8 @@
37
37
  "rescript.json",
38
38
  "index.d.ts",
39
39
  "index.js",
40
- "src"
40
+ "src",
41
+ "licenses"
41
42
  ],
42
43
  "dependencies": {
43
44
  "@clickhouse/client": "1.17.0",
@@ -57,7 +58,7 @@
57
58
  "yargs": "17.7.2",
58
59
  "@rescript/runtime": "12.2.0",
59
60
  "rescript-schema": "9.5.1",
60
- "viem": "2.46.2",
61
+ "viem": "2.54.0",
61
62
  "dotenv": "16.4.5",
62
63
  "date-fns": "3.3.1",
63
64
  "@rescript/react": "0.14.1",
@@ -69,10 +70,10 @@
69
70
  "tsx": "4.21.0"
70
71
  },
71
72
  "optionalDependencies": {
72
- "envio-linux-x64": "3.3.0-alpha.1",
73
- "envio-linux-x64-musl": "3.3.0-alpha.1",
74
- "envio-linux-arm64": "3.3.0-alpha.1",
75
- "envio-darwin-x64": "3.3.0-alpha.1",
76
- "envio-darwin-arm64": "3.3.0-alpha.1"
73
+ "envio-linux-x64": "3.3.0-alpha.11",
74
+ "envio-linux-x64-musl": "3.3.0-alpha.11",
75
+ "envio-linux-arm64": "3.3.0-alpha.11",
76
+ "envio-darwin-x64": "3.3.0-alpha.11",
77
+ "envio-darwin-arm64": "3.3.0-alpha.11"
77
78
  }
78
79
  }
package/src/Address.res CHANGED
@@ -11,8 +11,11 @@ module Evm = {
11
11
  external fromStringOrThrow: string => t = "getAddress"
12
12
 
13
13
  // NOTE: the function is named to be overshadowed by the one below, so that we don't have to import viem in the handler code
14
+ // strict:false checks only the 20-byte hex shape, not EIP-55 checksum casing —
15
+ // since we're about to lowercase it anyway, an all-uppercase or wrongly-cased
16
+ // input address is just as valid as one that's already lowercase.
14
17
  @module("viem")
15
- external fromStringLowercaseOrThrow: string => bool = "isAddress"
18
+ external fromStringLowercaseOrThrow: (string, {"strict": bool}) => bool = "isAddress"
16
19
 
17
20
  // Reassign since the function might be used in the handler code
18
21
  // and we don't want to have a "viem" import there. It's needed to keep "viem" a dependency
@@ -20,7 +23,7 @@ module Evm = {
20
23
  // Also, we want a custom error message, which is searchable in our codebase.
21
24
  // Validate that the string is a proper address but return a lowercased value
22
25
  let fromStringLowercaseOrThrow = string => {
23
- if fromStringLowercaseOrThrow(string) {
26
+ if fromStringLowercaseOrThrow(string, {"strict": false}) {
24
27
  unsafeFromString(string->String.toLowerCase)
25
28
  } else {
26
29
  JsError.throwWithMessage(
@@ -7,7 +7,9 @@ import * as S$RescriptSchema from "rescript-schema/src/S.res.mjs";
7
7
  let schema = S$RescriptSchema.setName(S$RescriptSchema.string, "Address");
8
8
 
9
9
  function fromStringLowercaseOrThrow(string) {
10
- if (Viem.isAddress(string)) {
10
+ if (Viem.isAddress(string, {
11
+ strict: false
12
+ })) {
11
13
  return string.toLowerCase();
12
14
  } else {
13
15
  return Stdlib_JsError.throwWithMessage(`Address "` + string + `" is invalid. Expected a 20-byte hex string starting with 0x.`);
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 {
package/src/Batch.res CHANGED
@@ -34,12 +34,6 @@ type t = {
34
34
  checkpointEventsProcessed: array<int>,
35
35
  }
36
36
 
37
- let hasReadyItem = (fetchStates: array<FetchState.t>) => {
38
- fetchStates->Array.some(fetchState => {
39
- fetchState->FetchState.isActivelyIndexing && fetchState->FetchState.hasReadyItem
40
- })
41
- }
42
-
43
37
  let getProgressedChainsById = {
44
38
  let getChainAfterBatchIfProgressed = (
45
39
  ~chainBeforeBatch: chainBeforeBatch,
package/src/Batch.res.mjs CHANGED
@@ -4,16 +4,6 @@ import * as Utils from "./Utils.res.mjs";
4
4
  import * as FetchState from "./FetchState.res.mjs";
5
5
  import * as ReorgDetection from "./ReorgDetection.res.mjs";
6
6
 
7
- function hasReadyItem(fetchStates) {
8
- return fetchStates.some(fetchState => {
9
- if (FetchState.isActivelyIndexing(fetchState)) {
10
- return FetchState.hasReadyItem(fetchState);
11
- } else {
12
- return false;
13
- }
14
- });
15
- }
16
-
17
7
  function getChainAfterBatchIfProgressed(chainBeforeBatch, progressBlockNumberAfterBatch, fetchStateAfterBatch, batchSize) {
18
8
  if (chainBeforeBatch.progressBlockNumber < progressBlockNumberAfterBatch) {
19
9
  return {
@@ -37,7 +27,7 @@ function getProgressedChainsById(chainsBeforeBatch, batchSizePerChain, progressB
37
27
  let progressedChain;
38
28
  if (batchSize !== undefined) {
39
29
  let leftItems = fetchState.buffer.slice(batchSize);
40
- progressedChain = getChainAfterBatchIfProgressed(chainBeforeBatch, progressBlockNumberAfterBatch, FetchState.updateInternal(fetchState, undefined, undefined, leftItems, undefined, undefined), batchSize);
30
+ progressedChain = getChainAfterBatchIfProgressed(chainBeforeBatch, progressBlockNumberAfterBatch, FetchState.updateInternal(fetchState, undefined, leftItems, undefined, undefined, undefined), batchSize);
41
31
  } else {
42
32
  progressedChain = getChainAfterBatchIfProgressed(chainBeforeBatch, progressBlockNumberAfterBatch, chainBeforeBatch.fetchState, 0);
43
33
  }
@@ -208,7 +198,6 @@ function findLastEventItem(batch, chainId) {
208
198
  }
209
199
 
210
200
  export {
211
- hasReadyItem,
212
201
  getProgressedChainsById,
213
202
  addReorgCheckpoints,
214
203
  prepareBatch,
@@ -77,15 +77,7 @@ and processNextBatch = async (state: IndexerState.t, ~scheduleFetch): unit => {
77
77
  state
78
78
  ->IndexerState.chainStates
79
79
  ->Dict.valuesToArray
80
- ->Array.every(cs => {
81
- let fetchState = switch progressedChainsById->Utils.Dict.dangerouslyGetByIntNonOption(
82
- (cs->ChainState.fetchState).chainId,
83
- ) {
84
- | Some(chainAfterBatch) => chainAfterBatch.fetchState
85
- | None => cs->ChainState.fetchState
86
- }
87
- fetchState->FetchState.isReadyToEnterReorgThreshold
88
- })
80
+ ->Array.every(cs => cs->ChainState.isReadyToEnterReorgThresholdAfterBatch(~batch))
89
81
 
90
82
  if shouldEnterReorgThreshold {
91
83
  IndexerState.enterReorgThreshold(state)
@@ -135,6 +127,11 @@ and processNextBatch = async (state: IndexerState.t, ~scheduleFetch): unit => {
135
127
  | Ok() =>
136
128
  state->IndexerState.recordProcessedBatch
137
129
 
130
+ switch state->IndexerState.simulateDeadInputTracker {
131
+ | Some(tracker) => tracker->SimulateDeadInputTracker.recordProcessed(~batch)
132
+ | None => ()
133
+ }
134
+
138
135
  if state->IndexerState.isResolvingReorg {
139
136
  // A reorg landed while this batch was processing. Apply its progress so
140
137
  // the rollback diff is computed against up-to-date chain progress, but
@@ -171,9 +168,7 @@ and processNextBatch = async (state: IndexerState.t, ~scheduleFetch): unit => {
171
168
  state
172
169
  ->IndexerState.chainStates
173
170
  ->Dict.valuesToArray
174
- ->Array.every(cs =>
175
- cs->ChainState.isProgressAtHead && (cs->ChainState.fetchState).endBlock->Option.isNone
176
- )
171
+ ->Array.every(ChainState.isAtHeadWithoutEndBlock)
177
172
  ) {
178
173
  IndexerState.errorExit(
179
174
  state,
@@ -4,16 +4,16 @@ import * as Utils from "./Utils.res.mjs";
4
4
  import * as Config from "./Config.res.mjs";
5
5
  import * as Logging from "./Logging.res.mjs";
6
6
  import * as ChainState from "./ChainState.res.mjs";
7
- import * as FetchState from "./FetchState.res.mjs";
8
7
  import * as IndexerState from "./IndexerState.res.mjs";
9
8
  import * as ChainMetadata from "./ChainMetadata.res.mjs";
10
9
  import * as ErrorHandling from "./ErrorHandling.res.mjs";
11
10
  import * as InMemoryStore from "./InMemoryStore.res.mjs";
12
- import * as Stdlib_Option from "@rescript/runtime/lib/es6/Stdlib_Option.js";
13
11
  import * as ExitOnCaughtUp from "./ExitOnCaughtUp.res.mjs";
14
12
  import * as EventProcessing from "./EventProcessing.res.mjs";
13
+ import * as Primitive_option from "@rescript/runtime/lib/es6/Primitive_option.js";
15
14
  import * as PruneStaleHistory from "./PruneStaleHistory.res.mjs";
16
15
  import * as Primitive_exceptions from "@rescript/runtime/lib/es6/Primitive_exceptions.js";
16
+ import * as SimulateDeadInputTracker from "./SimulateDeadInputTracker.res.mjs";
17
17
 
18
18
  function yieldTick() {
19
19
  return new Promise((resolve, param) => {
@@ -30,10 +30,7 @@ async function processNextBatch(state, scheduleFetch) {
30
30
  let batch = IndexerState.createBatch(state, IndexerState.processedCheckpointId(state), IndexerState.config(state).batchSize, isRollbackBatch);
31
31
  let progressedChainsById = batch.progressedChainsById;
32
32
  let isBelowReorgThreshold = !isInReorgThresholdBeforeUpdate && IndexerState.config(state).shouldRollbackOnReorg;
33
- let shouldEnterReorgThreshold = isBelowReorgThreshold && Object.values(IndexerState.chainStates(state)).every(cs => {
34
- let chainAfterBatch = progressedChainsById[ChainState.fetchState(cs).chainId];
35
- return FetchState.isReadyToEnterReorgThreshold(chainAfterBatch !== undefined ? chainAfterBatch.fetchState : ChainState.fetchState(cs));
36
- });
33
+ let shouldEnterReorgThreshold = isBelowReorgThreshold && Object.values(IndexerState.chainStates(state)).every(cs => ChainState.isReadyToEnterReorgThresholdAfterBatch(cs, batch));
37
34
  if (shouldEnterReorgThreshold) {
38
35
  IndexerState.enterReorgThreshold(state);
39
36
  }
@@ -60,6 +57,10 @@ async function processNextBatch(state, scheduleFetch) {
60
57
  return IndexerState.errorExit(state, errHandler._0);
61
58
  }
62
59
  IndexerState.recordProcessedBatch(state);
60
+ let tracker = IndexerState.simulateDeadInputTracker(state);
61
+ if (tracker !== undefined) {
62
+ SimulateDeadInputTracker.recordProcessed(Primitive_option.valFromOption(tracker), batch);
63
+ }
63
64
  if (IndexerState.isResolvingReorg(state)) {
64
65
  return IndexerState.applyBatchProgress(state, batch);
65
66
  }
@@ -75,7 +76,7 @@ async function processNextBatch(state, scheduleFetch) {
75
76
  }
76
77
  if (allCaughtUp && !IndexerState.keepProcessAlive(state)) {
77
78
  return await ExitOnCaughtUp.run(state);
78
- } else if (!allCaughtUp && IndexerState.exitAfterFirstEventBlock(state) && Object.values(IndexerState.chainStates(state)).every(cs => ChainState.isProgressAtHead(cs) ? Stdlib_Option.isNone(ChainState.fetchState(cs).endBlock) : false)) {
79
+ } else if (!allCaughtUp && IndexerState.exitAfterFirstEventBlock(state) && Object.values(IndexerState.chainStates(state)).every(ChainState.isAtHeadWithoutEndBlock)) {
79
80
  return IndexerState.errorExit(state, ErrorHandling.make(new Error("No events found between startBlock and chain head. Cannot auto-detect endBlock."), undefined, undefined));
80
81
  } else {
81
82
  ChainMetadata.stage(state);
package/src/Bin.res CHANGED
@@ -71,6 +71,9 @@ let run = async args => {
71
71
  }
72
72
  }
73
73
  } catch {
74
+ | Main.FatalError(_) =>
75
+ // Already logged with full context by Main.start's onError; just exit.
76
+ NodeJs.process->NodeJs.exitWithCode(Failure)
74
77
  | exn =>
75
78
  // Log just the exception's own message — wrapping it in "Failed at
76
79
  // initialization" and pino's err serializer buries the real cause under
package/src/Bin.res.mjs CHANGED
@@ -79,6 +79,10 @@ async function run(args) {
79
79
  }
80
80
  } catch (raw_exn) {
81
81
  let exn = Primitive_exceptions.internalToException(raw_exn);
82
+ if (exn.RE_EXN_ID === Main.FatalError) {
83
+ Process.exit(1);
84
+ return;
85
+ }
82
86
  let e = Primitive_exceptions.internalToException(exn);
83
87
  let message = e.RE_EXN_ID === "JsExn" ? Stdlib_Option.getOr(Stdlib_JsExn.message(e._1), "Failed at initialization") : "Failed at initialization";
84
88
  Logging.error(message);