trac-msb 0.2.17 → 0.2.19

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 (365) hide show
  1. package/README.md +62 -2
  2. package/SECURITY.md +9 -6
  3. package/cli/commandHandler.js +272 -0
  4. package/cli/handlers.js +210 -0
  5. package/cli/interactive.js +182 -0
  6. package/msb.mjs +7 -8
  7. package/package.json +33 -11
  8. package/rpc/create_server.js +44 -44
  9. package/rpc/handlers.js +43 -56
  10. package/rpc/routes/index.js +8 -8
  11. package/rpc/rpc_server.js +6 -2
  12. package/rpc/utils/helpers.js +46 -66
  13. package/scripts/pear-runner.js +170 -0
  14. package/src/config/args.js +60 -13
  15. package/src/config/config.js +163 -14
  16. package/src/config/env.js +57 -25
  17. package/src/core/network/Network.js +121 -56
  18. package/src/core/network/protocols/LegacyProtocol.js +21 -11
  19. package/src/core/network/protocols/NetworkMessages.js +38 -17
  20. package/src/core/network/protocols/ProtocolInterface.js +15 -3
  21. package/src/core/network/protocols/ProtocolSession.js +144 -17
  22. package/src/core/network/protocols/V1Protocol.js +37 -18
  23. package/src/core/network/protocols/connectionPolicies.js +174 -0
  24. package/src/core/network/protocols/legacy/NetworkMessageRouter.js +26 -20
  25. package/src/core/network/protocols/{shared/handlers/base/BaseOperationHandler.js → legacy/handlers/BaseStateOperationHandler.js} +25 -14
  26. package/src/core/network/protocols/legacy/handlers/{GetRequestHandler.js → LegacyGetRequestHandler.js} +9 -9
  27. package/src/core/network/protocols/legacy/handlers/LegacyResponseHandler.js +23 -0
  28. package/src/core/network/protocols/{shared/handlers/RoleOperationHandler.js → legacy/handlers/LegacyRoleOperationHandler.js} +19 -12
  29. package/src/core/network/protocols/{shared/handlers/SubnetworkOperationHandler.js → legacy/handlers/LegacySubnetworkOperationHandler.js} +29 -18
  30. package/src/core/network/protocols/{shared/handlers/TransferOperationHandler.js → legacy/handlers/LegacyTransferOperationHandler.js} +18 -12
  31. package/src/core/network/protocols/legacy/validators/base/BaseResponse.js +7 -10
  32. package/src/core/network/protocols/shared/validators/{PartialBootstrapDeployment.js → PartialBootstrapDeploymentValidator.js} +9 -4
  33. package/src/core/network/protocols/shared/validators/{base/PartialOperation.js → PartialOperationValidator.js} +53 -31
  34. package/src/core/network/protocols/shared/validators/{PartialRoleAccess.js → PartialRoleAccessValidator.js} +51 -17
  35. package/src/core/network/protocols/shared/validators/{PartialTransaction.js → PartialTransactionValidator.js} +21 -7
  36. package/src/core/network/protocols/shared/validators/{PartialTransfer.js → PartialTransferValidator.js} +32 -14
  37. package/src/core/network/protocols/v1/NetworkMessageRouter.js +91 -7
  38. package/src/core/network/protocols/v1/V1ProtocolError.js +27 -0
  39. package/src/core/network/protocols/v1/handlers/V1BaseOperationHandler.js +66 -0
  40. package/src/core/network/protocols/v1/handlers/V1BroadcastTransactionOperationHandler.js +272 -0
  41. package/src/core/network/protocols/v1/handlers/V1LivenessOperationHandler.js +88 -0
  42. package/src/core/network/protocols/v1/handlers/broadcastTransaction/BroadcastTransactionErrorMapper.js +84 -0
  43. package/src/core/network/protocols/v1/handlers/broadcastTransaction/BroadcastTransactionOperationStrategies.js +128 -0
  44. package/src/core/network/protocols/v1/handlers/broadcastTransaction/BroadcastTransactionPayloadUtils.js +26 -0
  45. package/src/core/network/protocols/v1/validators/V1BaseOperation.js +212 -0
  46. package/src/core/network/protocols/v1/validators/V1BroadcastTransactionRequest.js +28 -0
  47. package/src/core/network/protocols/v1/validators/V1BroadcastTransactionResponse.js +260 -0
  48. package/src/core/network/protocols/v1/validators/V1LivenessRequest.js +15 -0
  49. package/src/core/network/protocols/v1/validators/V1LivenessResponse.js +17 -0
  50. package/src/core/network/protocols/v1/validators/V1ValidationSchema.js +210 -0
  51. package/src/core/network/services/ConnectionManager.js +149 -96
  52. package/src/core/network/services/MessageOrchestrator.js +197 -37
  53. package/src/core/network/services/PendingRequestService.js +175 -0
  54. package/src/core/network/services/TransactionCommitService.js +149 -0
  55. package/src/core/network/services/TransactionPoolService.js +129 -18
  56. package/src/core/network/services/TransactionRateLimiterService.js +57 -35
  57. package/src/core/network/services/ValidatorHealthCheckService.js +127 -0
  58. package/src/core/network/services/ValidatorObserverService.js +400 -121
  59. package/src/core/state/State.js +259 -156
  60. package/src/core/state/utils/address.js +4 -9
  61. package/src/core/state/utils/balance.js +7 -7
  62. package/src/core/state/utils/roles.js +1 -1
  63. package/src/index.js +320 -278
  64. package/src/messages/network/v1/NetworkMessageBuilder.js +71 -100
  65. package/src/messages/network/v1/NetworkMessageDirector.js +16 -50
  66. package/src/messages/network/v1/networkMessageFactory.js +1 -1
  67. package/src/messages/state/ApplyStateMessageBuilder.js +6 -6
  68. package/src/messages/state/applyStateMessageFactory.js +1 -1
  69. package/src/utils/Scheduler.js +0 -8
  70. package/src/utils/buffer.js +1 -1
  71. package/src/utils/check.js +12 -13
  72. package/src/utils/constants.js +78 -5
  73. package/src/utils/deepEqualApplyPayload.js +40 -0
  74. package/src/utils/errors.js +20 -0
  75. package/src/utils/fileUtils.js +12 -3
  76. package/src/utils/helpers.js +10 -1
  77. package/src/utils/logger.js +25 -0
  78. package/src/utils/migrationUtils.js +3 -3
  79. package/src/utils/normalizers.js +38 -0
  80. package/src/utils/protobuf/networkV1.generated.cjs +2460 -0
  81. package/src/utils/protobuf/operationHelpers.js +24 -3
  82. package/.dockerignore +0 -16
  83. package/.github/workflows/acceptance-tests.yml +0 -38
  84. package/.github/workflows/lint-pr-title.yml +0 -26
  85. package/.github/workflows/publish.yml +0 -33
  86. package/.github/workflows/unit-tests.yml +0 -34
  87. package/CODE_OF_CONDUCT.md +0 -128
  88. package/docker-compose.yml +0 -17
  89. package/dockerfile +0 -41
  90. package/docs/fee_distribution.md +0 -89
  91. package/docs/trac_network_http_api.openapi.yaml +0 -889
  92. package/migration/.gitkeep +0 -0
  93. package/proto/applyOperations.proto +0 -117
  94. package/proto/network.proto +0 -74
  95. package/rpc/rpc_services.js +0 -163
  96. package/scripts/generate-protobufs.js +0 -42
  97. package/src/core/network/identity/NetworkWalletFactory.js +0 -77
  98. package/src/core/network/protocols/legacy/handlers/ResponseHandler.js +0 -37
  99. package/src/utils/cli.js +0 -130
  100. package/src/utils/cliCommands.js +0 -280
  101. package/src/utils/protobuf/network.cjs +0 -840
  102. package/tests/acceptance/v1/account/account.test.mjs +0 -123
  103. package/tests/acceptance/v1/balance/balance.test.mjs +0 -54
  104. package/tests/acceptance/v1/broadcast-transaction/broadcast-transaction.test.mjs +0 -116
  105. package/tests/acceptance/v1/confirmed-length/confirmed-length.test.mjs +0 -19
  106. package/tests/acceptance/v1/fee/fee.test.mjs +0 -11
  107. package/tests/acceptance/v1/health/health.test.mjs +0 -33
  108. package/tests/acceptance/v1/rpc.test.mjs +0 -95
  109. package/tests/acceptance/v1/tx/tx.test.mjs +0 -111
  110. package/tests/acceptance/v1/tx-details/tx-details.test.mjs +0 -213
  111. package/tests/acceptance/v1/tx-hashes/tx-hashes.test.mjs +0 -72
  112. package/tests/acceptance/v1/tx-payloads-bulk/tx-payloads-bulk.test.mjs +0 -27
  113. package/tests/acceptance/v1/txv/txv.test.mjs +0 -11
  114. package/tests/acceptance/v1/unconfirmed-length/unconfirmed-length.test.mjs +0 -11
  115. package/tests/fixtures/apply.fixtures.js +0 -77
  116. package/tests/fixtures/assembleMessage.fixtures.js +0 -41
  117. package/tests/fixtures/check.fixtures.js +0 -428
  118. package/tests/fixtures/networkV1.fixtures.js +0 -85
  119. package/tests/fixtures/protobuf.fixtures.js +0 -388
  120. package/tests/helpers/StateNetworkFactory.js +0 -155
  121. package/tests/helpers/address.js +0 -6
  122. package/tests/helpers/autobaseTestHelpers.js +0 -419
  123. package/tests/helpers/config.js +0 -4
  124. package/tests/helpers/createTestSignature.js +0 -13
  125. package/tests/helpers/regexHelper.js +0 -3
  126. package/tests/helpers/setupApplyTests.js +0 -587
  127. package/tests/helpers/transactionPayloads.mjs +0 -92
  128. package/tests/helpers/wrapper.js +0 -28
  129. package/tests/unit/messages/messages.test.js +0 -12
  130. package/tests/unit/messages/network/NetworkMessageBuilder.test.js +0 -276
  131. package/tests/unit/messages/network/NetworkMessageDirector.test.js +0 -201
  132. package/tests/unit/messages/state/applyStateMessageBuilder.complete.test.js +0 -525
  133. package/tests/unit/messages/state/applyStateMessageBuilder.partial.test.js +0 -237
  134. package/tests/unit/network/ConnectionManager.test.js +0 -191
  135. package/tests/unit/network/NetworkWalletFactory.test.js +0 -156
  136. package/tests/unit/network/networkModule.test.js +0 -10
  137. package/tests/unit/state/State.test.js +0 -80
  138. package/tests/unit/state/apply/addAdmin/addAdminHappyPathScenario.js +0 -42
  139. package/tests/unit/state/apply/addAdmin/addAdminScenarioHelpers.js +0 -276
  140. package/tests/unit/state/apply/addAdmin/adminEntryEncodingFailureScenario.js +0 -30
  141. package/tests/unit/state/apply/addAdmin/adminEntryExistsScenario.js +0 -78
  142. package/tests/unit/state/apply/addAdmin/nodeEntryInitializationFailureScenario.js +0 -30
  143. package/tests/unit/state/apply/addAdmin/nonBootstrapNodeScenario.js +0 -68
  144. package/tests/unit/state/apply/addAdmin/state.apply.addAdmin.test.js +0 -159
  145. package/tests/unit/state/apply/addIndexer/addIndexerHappyPathScenario.js +0 -39
  146. package/tests/unit/state/apply/addIndexer/addIndexerMultipleIndexersInTheNetworkScenario.js +0 -167
  147. package/tests/unit/state/apply/addIndexer/addIndexerPretenderAlreadyIndexerScenario.js +0 -21
  148. package/tests/unit/state/apply/addIndexer/addIndexerPretenderNotWriterScenario.js +0 -21
  149. package/tests/unit/state/apply/addIndexer/addIndexerRemoveAndReAddScenario.js +0 -186
  150. package/tests/unit/state/apply/addIndexer/addIndexerScenarioHelpers.js +0 -443
  151. package/tests/unit/state/apply/addIndexer/addIndexerWriterKeyAlreadyRegisteredScenario.js +0 -32
  152. package/tests/unit/state/apply/addIndexer/state.apply.addIndexer.test.js +0 -297
  153. package/tests/unit/state/apply/addWriter/addWriterHappyPathScenario.js +0 -41
  154. package/tests/unit/state/apply/addWriter/addWriterInvalidValidatorSignatureScenario.js +0 -32
  155. package/tests/unit/state/apply/addWriter/addWriterNewWkScenario.js +0 -149
  156. package/tests/unit/state/apply/addWriter/addWriterRequesterAlreadyWriterScenario.js +0 -21
  157. package/tests/unit/state/apply/addWriter/addWriterRequesterBalanceInsufficientScenario.js +0 -21
  158. package/tests/unit/state/apply/addWriter/addWriterRequesterEntryDecodeFailureScenario.js +0 -19
  159. package/tests/unit/state/apply/addWriter/addWriterRequesterEntryMissingScenario.js +0 -19
  160. package/tests/unit/state/apply/addWriter/addWriterRequesterIndexerScenario.js +0 -21
  161. package/tests/unit/state/apply/addWriter/addWriterRequesterNotWhitelistedScenario.js +0 -21
  162. package/tests/unit/state/apply/addWriter/addWriterScenarioHelpers.js +0 -766
  163. package/tests/unit/state/apply/addWriter/addWriterStakeBalanceUpdateFailureScenario.js +0 -50
  164. package/tests/unit/state/apply/addWriter/addWriterStakeInsufficientBalanceScenario.js +0 -29
  165. package/tests/unit/state/apply/addWriter/addWriterStakeInvalidBalanceScenario.js +0 -29
  166. package/tests/unit/state/apply/addWriter/addWriterStakeInvalidEntryScenario.js +0 -21
  167. package/tests/unit/state/apply/addWriter/addWriterStakeStakedBalanceFailureScenario.js +0 -37
  168. package/tests/unit/state/apply/addWriter/addWriterStakeSubtractFailureScenario.js +0 -42
  169. package/tests/unit/state/apply/addWriter/addWriterValidatorRewardScenario.js +0 -106
  170. package/tests/unit/state/apply/addWriter/addWriterWriterKeyMismatchScenario.js +0 -54
  171. package/tests/unit/state/apply/addWriter/addWriterWriterKeyOwnershipScenario.js +0 -54
  172. package/tests/unit/state/apply/addWriter/addWriterZeroWriterKeyScenario.js +0 -29
  173. package/tests/unit/state/apply/addWriter/state.apply.addWriter.test.js +0 -309
  174. package/tests/unit/state/apply/adminRecovery/adminRecoveryHappyPathScenario.js +0 -30
  175. package/tests/unit/state/apply/adminRecovery/adminRecoveryScenarioHelpers.js +0 -881
  176. package/tests/unit/state/apply/adminRecovery/state.apply.adminRecovery.test.js +0 -435
  177. package/tests/unit/state/apply/appendWhitelist/appendWhitelistBanAndReapplyScenario.js +0 -78
  178. package/tests/unit/state/apply/appendWhitelist/appendWhitelistExistingReaderHappyPathScenario.js +0 -98
  179. package/tests/unit/state/apply/appendWhitelist/appendWhitelistFeeAfterDisableScenario.js +0 -66
  180. package/tests/unit/state/apply/appendWhitelist/appendWhitelistHappyPathScenario.js +0 -55
  181. package/tests/unit/state/apply/appendWhitelist/appendWhitelistInsufficientAdminBalanceScenario.js +0 -103
  182. package/tests/unit/state/apply/appendWhitelist/appendWhitelistNodeAlreadyWhitelistedScenario.js +0 -60
  183. package/tests/unit/state/apply/appendWhitelist/appendWhitelistScenarioHelpers.js +0 -189
  184. package/tests/unit/state/apply/appendWhitelist/state.apply.appendWhitelist.test.js +0 -220
  185. package/tests/unit/state/apply/balanceInitialization/balanceInitializationHappyPathScenario.js +0 -82
  186. package/tests/unit/state/apply/balanceInitialization/balanceInitializationScenarioHelpers.js +0 -111
  187. package/tests/unit/state/apply/balanceInitialization/invalidAmountScenario.js +0 -45
  188. package/tests/unit/state/apply/balanceInitialization/nodeEntryBalanceUpdateFailureScenario.js +0 -82
  189. package/tests/unit/state/apply/balanceInitialization/state.apply.balanceInitialization.test.js +0 -189
  190. package/tests/unit/state/apply/banValidator/banValidatorBanAndReWhitelistScenario.js +0 -156
  191. package/tests/unit/state/apply/banValidator/banValidatorHappyPathScenario.js +0 -36
  192. package/tests/unit/state/apply/banValidator/banValidatorScenarioHelpers.js +0 -531
  193. package/tests/unit/state/apply/banValidator/banValidatorSequentialBansScenario.js +0 -74
  194. package/tests/unit/state/apply/banValidator/banValidatorTargetDecodeFailureScenario.js +0 -19
  195. package/tests/unit/state/apply/banValidator/banValidatorTargetIndexerScenario.js +0 -32
  196. package/tests/unit/state/apply/banValidator/banValidatorTargetNodeEntryMissingScenario.js +0 -19
  197. package/tests/unit/state/apply/banValidator/banValidatorTargetRoleUpdateFailureScenario.js +0 -19
  198. package/tests/unit/state/apply/banValidator/banValidatorWhitelistedNonWriterScenario.js +0 -38
  199. package/tests/unit/state/apply/banValidator/banValidatorWhitelistedZeroBalanceScenario.js +0 -91
  200. package/tests/unit/state/apply/banValidator/banValidatorWithdrawFailureScenario.js +0 -19
  201. package/tests/unit/state/apply/banValidator/state.apply.banValidator.test.js +0 -266
  202. package/tests/unit/state/apply/bootstrapDeployment/bootstrapDeploymentDuplicateRegistrationScenario.js +0 -143
  203. package/tests/unit/state/apply/bootstrapDeployment/bootstrapDeploymentHappyPathScenario.js +0 -26
  204. package/tests/unit/state/apply/bootstrapDeployment/bootstrapDeploymentIncompleteOperationScenario.js +0 -94
  205. package/tests/unit/state/apply/bootstrapDeployment/bootstrapDeploymentInvalidDeploymentEntryScenario.js +0 -37
  206. package/tests/unit/state/apply/bootstrapDeployment/bootstrapDeploymentMultipleBootstrapScenario.js +0 -86
  207. package/tests/unit/state/apply/bootstrapDeployment/bootstrapDeploymentScenarioHelpers.js +0 -347
  208. package/tests/unit/state/apply/bootstrapDeployment/invalidValidatorNodeEntryScenario.js +0 -57
  209. package/tests/unit/state/apply/bootstrapDeployment/state.apply.bootstrapDeployment.test.js +0 -429
  210. package/tests/unit/state/apply/common/access-control/adminConsistencyMismatchScenario.js +0 -120
  211. package/tests/unit/state/apply/common/access-control/adminEntryDecodeFailureScenario.js +0 -130
  212. package/tests/unit/state/apply/common/access-control/adminEntryExistsScenario.js +0 -93
  213. package/tests/unit/state/apply/common/access-control/adminEntryMissingScenario.js +0 -108
  214. package/tests/unit/state/apply/common/access-control/adminOnlyGuardScenario.js +0 -126
  215. package/tests/unit/state/apply/common/access-control/adminPublicKeyDecodeFailureScenario.js +0 -121
  216. package/tests/unit/state/apply/common/access-control/roleAccessOperationValidationScenario.js +0 -50
  217. package/tests/unit/state/apply/common/adminControlOperationValidationScenario.js +0 -56
  218. package/tests/unit/state/apply/common/balances/adminEntryUpdateFailureScenario.js +0 -52
  219. package/tests/unit/state/apply/common/balances/base/requesterBalanceScenarioBase.js +0 -198
  220. package/tests/unit/state/apply/common/balances/feeDecodeFailureScenario.js +0 -52
  221. package/tests/unit/state/apply/common/balances/requesterBalanceDecodeFailureScenario.js +0 -15
  222. package/tests/unit/state/apply/common/balances/requesterBalanceFeeApplicationFailureScenario.js +0 -11
  223. package/tests/unit/state/apply/common/balances/requesterBalanceInsufficientScenario.js +0 -15
  224. package/tests/unit/state/apply/common/balances/requesterBalanceUpdateFailureScenario.js +0 -11
  225. package/tests/unit/state/apply/common/balances/validatorEntryRewardFailureScenario.js +0 -11
  226. package/tests/unit/state/apply/common/balances/validatorEntryUpdateFailureScenario.js +0 -11
  227. package/tests/unit/state/apply/common/balances/validatorNodeEntryDecodeFailureScenario.js +0 -40
  228. package/tests/unit/state/apply/common/base/OperationValidationScenarioBase.js +0 -114
  229. package/tests/unit/state/apply/common/commonScenarioHelper.js +0 -103
  230. package/tests/unit/state/apply/common/indexer/indexerNodeEntryDecodeFailureScenario.js +0 -36
  231. package/tests/unit/state/apply/common/indexer/indexerNodeEntryMissingScenario.js +0 -36
  232. package/tests/unit/state/apply/common/indexer/indexerRoleUpdateFailureScenario.js +0 -29
  233. package/tests/unit/state/apply/common/indexer/indexerSequenceStateInvalidScenario.js +0 -66
  234. package/tests/unit/state/apply/common/invalidMessageComponentValidationScenario.js +0 -84
  235. package/tests/unit/state/apply/common/nodeEntryInitializationFailureScenario.js +0 -47
  236. package/tests/unit/state/apply/common/operationAlreadyAppliedScenario.js +0 -85
  237. package/tests/unit/state/apply/common/payload-structure/addressWithInvalidPublicKeyScenario.js +0 -52
  238. package/tests/unit/state/apply/common/payload-structure/initializationDisabledScenario.js +0 -54
  239. package/tests/unit/state/apply/common/payload-structure/invalidAddressValidationScenario.js +0 -73
  240. package/tests/unit/state/apply/common/payload-structure/invalidHashValidationScenario.js +0 -71
  241. package/tests/unit/state/apply/common/payload-structure/invalidPayloadValidationScenario.js +0 -31
  242. package/tests/unit/state/apply/common/payload-structure/invalidSignatureValidationScenario.js +0 -142
  243. package/tests/unit/state/apply/common/payload-structure/partialOperationValidationScenario.js +0 -87
  244. package/tests/unit/state/apply/common/requester/requesterNodeEntryBufferMissingScenario.js +0 -71
  245. package/tests/unit/state/apply/common/requester/requesterNodeEntryDecodeFailureScenario.js +0 -73
  246. package/tests/unit/state/apply/common/requester/requesterNodeEntryMissingScenario.js +0 -36
  247. package/tests/unit/state/apply/common/requesterAddressValidationScenario.js +0 -44
  248. package/tests/unit/state/apply/common/requesterPublicKeyValidationScenario.js +0 -25
  249. package/tests/unit/state/apply/common/transactionValidityMismatchScenario.js +0 -98
  250. package/tests/unit/state/apply/common/validatorConsistency/base/validatorConsistencyScenarioBase.js +0 -202
  251. package/tests/unit/state/apply/common/validatorConsistency/validatorEntryDecodeFailureScenario.js +0 -17
  252. package/tests/unit/state/apply/common/validatorConsistency/validatorEntryMissingScenario.js +0 -44
  253. package/tests/unit/state/apply/common/validatorConsistency/validatorInactiveScenario.js +0 -19
  254. package/tests/unit/state/apply/common/validatorConsistency/validatorWriterKeyMismatchScenario.js +0 -18
  255. package/tests/unit/state/apply/common/validatorEntryValidation/base/validatorEntryValidationScenarioBase.js +0 -315
  256. package/tests/unit/state/apply/common/validatorEntryValidation/validatorEntryInvalidBalanceScenario.js +0 -18
  257. package/tests/unit/state/apply/common/writerKeyExistsValidationScenario.js +0 -43
  258. package/tests/unit/state/apply/disableInitialization/disableInitializationAlreadyDisabledScenario.js +0 -53
  259. package/tests/unit/state/apply/disableInitialization/disableInitializationHappyPathScenario.js +0 -24
  260. package/tests/unit/state/apply/disableInitialization/disableInitializationScenarioHelpers.js +0 -204
  261. package/tests/unit/state/apply/disableInitialization/state.apply.disableInitialization.test.js +0 -161
  262. package/tests/unit/state/apply/missing-tests.md +0 -18
  263. package/tests/unit/state/apply/removeIndexer/removeIndexerHappyPathScenario.js +0 -58
  264. package/tests/unit/state/apply/removeIndexer/removeIndexerReAddAndRemoveAgainScenario.js +0 -98
  265. package/tests/unit/state/apply/removeIndexer/removeIndexerRemoveMultipleIndexersScenario.js +0 -167
  266. package/tests/unit/state/apply/removeIndexer/removeIndexerScenarioHelpers.js +0 -429
  267. package/tests/unit/state/apply/removeIndexer/removeIndexerTargetNotIndexerScenario.js +0 -22
  268. package/tests/unit/state/apply/removeIndexer/removeIndexerWriterKeyMissingScenario.js +0 -20
  269. package/tests/unit/state/apply/removeIndexer/state.apply.removeIndexer.test.js +0 -291
  270. package/tests/unit/state/apply/removeWriter/removeWriterAndAddWriterAgainScenario.js +0 -87
  271. package/tests/unit/state/apply/removeWriter/removeWriterHappyPathScenario.js +0 -38
  272. package/tests/unit/state/apply/removeWriter/removeWriterInvalidValidatorSignatureScenario.js +0 -32
  273. package/tests/unit/state/apply/removeWriter/removeWriterRequesterBalanceInsufficientScenario.js +0 -21
  274. package/tests/unit/state/apply/removeWriter/removeWriterRequesterEntryDecodeFailureScenario.js +0 -19
  275. package/tests/unit/state/apply/removeWriter/removeWriterRequesterEntryMissingScenario.js +0 -19
  276. package/tests/unit/state/apply/removeWriter/removeWriterRequesterIndexerScenario.js +0 -21
  277. package/tests/unit/state/apply/removeWriter/removeWriterRequesterNotWriterScenario.js +0 -21
  278. package/tests/unit/state/apply/removeWriter/removeWriterRequesterRoleUpdateFailureScenario.js +0 -19
  279. package/tests/unit/state/apply/removeWriter/removeWriterScenarioHelpers.js +0 -348
  280. package/tests/unit/state/apply/removeWriter/removeWriterThroughWriterValidatorScenario.js +0 -113
  281. package/tests/unit/state/apply/removeWriter/removeWriterUnstakeFailureScenario.js +0 -33
  282. package/tests/unit/state/apply/removeWriter/removeWriterWriterKeyMismatchScenario.js +0 -21
  283. package/tests/unit/state/apply/removeWriter/removeWriterWriterKeyOwnershipScenario.js +0 -26
  284. package/tests/unit/state/apply/removeWriter/removeWriterWriterKeyRegistryMissingScenario.js +0 -22
  285. package/tests/unit/state/apply/removeWriter/state.apply.removeWriter.test.js +0 -307
  286. package/tests/unit/state/apply/state.apply.test.js +0 -24
  287. package/tests/unit/state/apply/transfer/state.apply.transfer.test.js +0 -819
  288. package/tests/unit/state/apply/transfer/transferContractSchemaValidationScenario.js +0 -22
  289. package/tests/unit/state/apply/transfer/transferDoubleSpendAcrossValidatorsScenario.js +0 -146
  290. package/tests/unit/state/apply/transfer/transferDoubleSpendSameBatchScenario.js +0 -63
  291. package/tests/unit/state/apply/transfer/transferDoubleSpendSingleValidatorScenario.js +0 -67
  292. package/tests/unit/state/apply/transfer/transferExistingRecipientAmountScenario.js +0 -31
  293. package/tests/unit/state/apply/transfer/transferExistingRecipientZeroAmountScenario.js +0 -31
  294. package/tests/unit/state/apply/transfer/transferHandlerGuardScenarios.js +0 -22
  295. package/tests/unit/state/apply/transfer/transferHappyPathScenario.js +0 -8
  296. package/tests/unit/state/apply/transfer/transferInvalidIncomingDataScenario.js +0 -66
  297. package/tests/unit/state/apply/transfer/transferNewRecipientAmountScenario.js +0 -31
  298. package/tests/unit/state/apply/transfer/transferNewRecipientZeroAmountScenario.js +0 -31
  299. package/tests/unit/state/apply/transfer/transferScenarioHelpers.js +0 -1170
  300. package/tests/unit/state/apply/transfer/transferSelfTransferAmountScenario.js +0 -38
  301. package/tests/unit/state/apply/transfer/transferSelfTransferZeroAmountScenario.js +0 -38
  302. package/tests/unit/state/apply/transfer/transferValidatorRecipientAmountScenario.js +0 -38
  303. package/tests/unit/state/apply/transfer/transferValidatorRecipientZeroAmountScenario.js +0 -38
  304. package/tests/unit/state/apply/txOperation/state.apply.txOperation.test.js +0 -318
  305. package/tests/unit/state/apply/txOperation/txOperationBootstrapNotRegisteredScenario.js +0 -70
  306. package/tests/unit/state/apply/txOperation/txOperationDifferentValidatorCreatorHappyPathScenario.js +0 -23
  307. package/tests/unit/state/apply/txOperation/txOperationInvalidDeploymentEntryScenario.js +0 -48
  308. package/tests/unit/state/apply/txOperation/txOperationInvalidFeeAmountScenario.js +0 -39
  309. package/tests/unit/state/apply/txOperation/txOperationInvalidSubnetCreatorAddressScenario.js +0 -46
  310. package/tests/unit/state/apply/txOperation/txOperationRequesterCreatorHappyPathScenario.js +0 -21
  311. package/tests/unit/state/apply/txOperation/txOperationScenarioHelpers.js +0 -432
  312. package/tests/unit/state/apply/txOperation/txOperationStandardHappyPathScenario.js +0 -21
  313. package/tests/unit/state/apply/txOperation/txOperationTransferFeeAddCreatorBalanceFailureScenario.js +0 -26
  314. package/tests/unit/state/apply/txOperation/txOperationTransferFeeAddValidatorBalanceFailureScenario.js +0 -25
  315. package/tests/unit/state/apply/txOperation/txOperationTransferFeeAddValidatorBonusFailureScenario.js +0 -27
  316. package/tests/unit/state/apply/txOperation/txOperationTransferFeeDecodeCreatorEntryScenario.js +0 -18
  317. package/tests/unit/state/apply/txOperation/txOperationTransferFeeDecodeRequesterEntryScenario.js +0 -17
  318. package/tests/unit/state/apply/txOperation/txOperationTransferFeeDecodeValidatorEntryScenario.js +0 -31
  319. package/tests/unit/state/apply/txOperation/txOperationTransferFeeGuardBypassScenario.js +0 -49
  320. package/tests/unit/state/apply/txOperation/txOperationTransferFeeGuardScenarioFactory.js +0 -93
  321. package/tests/unit/state/apply/txOperation/txOperationTransferFeeInsufficientRequesterBalanceScenario.js +0 -28
  322. package/tests/unit/state/apply/txOperation/txOperationTransferFeeInvalidCreatorBalanceScenario.js +0 -29
  323. package/tests/unit/state/apply/txOperation/txOperationTransferFeeInvalidRequesterBalanceScenario.js +0 -28
  324. package/tests/unit/state/apply/txOperation/txOperationTransferFeeInvalidRequesterEntryScenario.js +0 -17
  325. package/tests/unit/state/apply/txOperation/txOperationTransferFeeInvalidValidatorBalanceScenario.js +0 -33
  326. package/tests/unit/state/apply/txOperation/txOperationTransferFeeMissingCreatorEntryScenario.js +0 -18
  327. package/tests/unit/state/apply/txOperation/txOperationTransferFeeSubtractFailureScenario.js +0 -25
  328. package/tests/unit/state/apply/txOperation/txOperationTransferFeeUpdateCreatorBalanceFailureScenario.js +0 -26
  329. package/tests/unit/state/apply/txOperation/txOperationTransferFeeUpdateFailureScenario.js +0 -25
  330. package/tests/unit/state/apply/txOperation/txOperationTransferFeeUpdateValidatorBalanceFailureScenario.js +0 -26
  331. package/tests/unit/state/apply/txOperation/txOperationTransferFeeUpdateValidatorBonusFailureScenario.js +0 -27
  332. package/tests/unit/state/apply/txOperation/txOperationValidatorCreatorHappyPathScenario.js +0 -21
  333. package/tests/unit/state/stateModule.test.js +0 -23
  334. package/tests/unit/state/stateTestUtils.js +0 -32
  335. package/tests/unit/state/utils/address.test.js +0 -63
  336. package/tests/unit/state/utils/adminEntry.test.js +0 -52
  337. package/tests/unit/state/utils/balance.test.js +0 -320
  338. package/tests/unit/state/utils/lengthEntry.test.js +0 -54
  339. package/tests/unit/state/utils/nodeEntry.test.js +0 -298
  340. package/tests/unit/state/utils/roles.test.js +0 -44
  341. package/tests/unit/unit.test.js +0 -14
  342. package/tests/unit/utils/amountSerialization/amountSerialization.test.js +0 -237
  343. package/tests/unit/utils/buffer/buffer.test.js +0 -251
  344. package/tests/unit/utils/check/adminControlOperation.test.js +0 -156
  345. package/tests/unit/utils/check/balanceInitializationOperation.test.js +0 -54
  346. package/tests/unit/utils/check/bootstrapDeploymentOperation.test.js +0 -104
  347. package/tests/unit/utils/check/check.test.js +0 -17
  348. package/tests/unit/utils/check/common.test.js +0 -419
  349. package/tests/unit/utils/check/coreAdminOperation.test.js +0 -95
  350. package/tests/unit/utils/check/roleAccessOperation.test.js +0 -255
  351. package/tests/unit/utils/check/transactionOperation.test.js +0 -107
  352. package/tests/unit/utils/check/transferOperation.test.js +0 -102
  353. package/tests/unit/utils/fileUtils/readAddressesFromWhitelistFile.test.js +0 -95
  354. package/tests/unit/utils/fileUtils/readBalanceMigrationFile.test.js +0 -149
  355. package/tests/unit/utils/helpers/helpers.test.js +0 -11
  356. package/tests/unit/utils/helpers/isHexString.test.js +0 -12
  357. package/tests/unit/utils/helpers/normalizeHex.test.js +0 -82
  358. package/tests/unit/utils/migrationUtils/validateAddressFromIncomingFile.test.js +0 -100
  359. package/tests/unit/utils/normalizers/normalizers.test.js +0 -469
  360. package/tests/unit/utils/protobuf/applyOperations.test.js +0 -91
  361. package/tests/unit/utils/protobuf/operationHelpers.test.js +0 -305
  362. package/tests/unit/utils/protobuf/protobuf.test.js +0 -12
  363. package/tests/unit/utils/type/type.test.js +0 -25
  364. package/tests/unit/utils/utils.test.js +0 -20
  365. package/whitelist/.gitkeep +0 -0
@@ -0,0 +1,182 @@
1
+ import ReadyResource from "ready-resource";
2
+ import process from "process";
3
+ import readline from "readline";
4
+ import { WalletProvider, exportWallet, importFromFile } from "trac-wallet";
5
+ import { MainSettlementBus } from "../src/index.js";
6
+ import { sleep } from "../src/utils/helpers.js";
7
+ import fileUtils from "../src/utils/fileUtils.js";
8
+ import { COMMANDS, CommandHandler } from "./commandHandler.js";
9
+
10
+ class Cli extends ReadyResource {
11
+ #msb;
12
+ #config;
13
+ #commandHandlers;
14
+ #readlineInstance;
15
+ #wallet
16
+
17
+ constructor(config) {
18
+ super();
19
+ this.#config = config;
20
+ }
21
+
22
+ async _open() {
23
+ this.#readlineInstance = readline.createInterface({
24
+ input: process.stdin,
25
+ output: process.stdout,
26
+ completer: line => this.#completeCommand(line) // This only works without Pear.
27
+ });
28
+
29
+ if (this.#config.enableWallet) {
30
+ await fileUtils.ensureKeyPathDir(this.#config);
31
+ await this.#initKeyPair()
32
+ }
33
+
34
+ this.#msb = new MainSettlementBus(this.#config, this.#wallet);
35
+ await this.#msb.ready();
36
+ }
37
+
38
+ async _close() {
39
+ if (this.#readlineInstance) {
40
+ const inputClosed = new Promise((resolve) =>
41
+ this.#readlineInstance.input.once("close", resolve)
42
+ );
43
+ const outputClosed = new Promise((resolve) =>
44
+ this.#readlineInstance.output.once("close", resolve)
45
+ );
46
+
47
+ this.#readlineInstance.close();
48
+ this.#readlineInstance.input.destroy();
49
+ this.#readlineInstance.output.destroy();
50
+
51
+ // Do not remove this. Without it, readline may close too quickly and still hang.
52
+ await Promise.all([inputClosed, outputClosed]).catch((e) =>
53
+ console.log("Error during closing readline stream:", e)
54
+ );
55
+ }
56
+
57
+ await sleep(100);
58
+ }
59
+
60
+ startInteractiveMode() {
61
+ console.log('RPC server will not be started.');
62
+
63
+ this.#commandHandlers = new CommandHandler({
64
+ config: this.#config,
65
+ msb: this.#msb,
66
+ handleClose: () => this.close(),
67
+ wallet: this.#wallet
68
+ });
69
+
70
+ this.#msb.printHelp();
71
+
72
+ this.#readlineInstance.on("line", async (input) => {
73
+ try {
74
+ await this.#handleCommand(input.trim());
75
+ } catch (err) {
76
+ console.error(`${err}`);
77
+ }
78
+ this.#readlineInstance.prompt();
79
+ });
80
+
81
+ this.#readlineInstance.prompt();
82
+ }
83
+
84
+ async #handleCommand(input) {
85
+ return this.#commandHandlers.handle(input);
86
+ }
87
+
88
+ #completeCommand(line) {
89
+ const commands = Object.values(COMMANDS);
90
+ const hits = line
91
+ ? commands.filter(command => command.startsWith(line))
92
+ : commands;
93
+
94
+ return [hits.length ? hits : commands, line];
95
+ }
96
+
97
+ async #initKeyPair() {
98
+ try {
99
+ if (fileUtils.verifyWalletPath(this.#config)) {
100
+ this.#wallet = await importFromFile(this.#config.keyPairPath, undefined, this.#config.addressPrefix)
101
+ } else {
102
+ console.log("Key file was not found. How do you wish to proceed?")
103
+ const wallet = await this.#setupKeypairInteractiveMode()
104
+ if (!wallet) {
105
+ console.error("Invalid response type from keypair setup interactive menu")
106
+ } else {
107
+ this.#wallet = wallet
108
+ }
109
+ }
110
+ } catch (err) {
111
+ console.error(err);
112
+ }
113
+ }
114
+
115
+ async #setupKeypairInteractiveMode() {
116
+ // this would be enable interactive mode (but there is an exception being swallowed so its better to act against the code)
117
+ if (this.#readlineInstance !== null) {
118
+ console.log([
119
+ "[1]. Generate new keypair",
120
+ "[2]. Restore keypair from 12 or 24-word mnemonic",
121
+ "Your choice(1/ 2/):"
122
+ ].join("\n"));
123
+
124
+ let choice = await this.#awaitInput()
125
+
126
+ try {
127
+ switch (choice) {
128
+ case '1':
129
+ const wallet = await new WalletProvider(this.#config).generate({
130
+ derivationPath: this.#config.derivationPath
131
+ })
132
+ console.log([
133
+ "This is your mnemonic:",
134
+ wallet.mnemonic,
135
+ "Please back it up in a safe location"
136
+
137
+ ].join("\n"))
138
+ exportWallet(wallet, this.#config.keyPairPath)
139
+ return wallet
140
+ case '2':
141
+ console.log("Enter your mnemonic phrase:");
142
+
143
+ let mnemonic = await this.#awaitInput()
144
+ try {
145
+ const wallet = await new WalletProvider(this.#config).fromMnemonic({
146
+ mnemonic,
147
+ derivationPath: this.#config.derivationPath
148
+ })
149
+ exportWallet(wallet, this.#config.keyPairPath)
150
+ return wallet
151
+ } catch {
152
+ console.log("Invalid mnemonic. Please check your 12 or 24 words and try again.");
153
+ return this.#setupKeypairInteractiveMode();
154
+ }
155
+ default:
156
+ console.log("Invalid choice. Please select again.");
157
+ return this.#setupKeypairInteractiveMode();
158
+ }
159
+ } catch {
160
+ console.log("Invalid input. Please try again.");
161
+ return this.#setupKeypairInteractiveMode();
162
+ }
163
+ }
164
+ }
165
+
166
+ async #awaitInput() {
167
+ let choice = '';
168
+ const anAction = async input => choice = input
169
+
170
+ this.#readlineInstance.on('line', anAction)
171
+ while ('' === choice) await sleep(1000);
172
+ this.#readlineInstance.off('line', anAction);
173
+
174
+ return choice
175
+ }
176
+ }
177
+
178
+ export const startInteractiveMode = async (config) => {
179
+ const cli = new Cli(config);
180
+ await cli.ready();
181
+ cli.startInteractiveMode();
182
+ };
package/msb.mjs CHANGED
@@ -1,16 +1,15 @@
1
- import { MainSettlementBus } from './src/index.js';
2
1
  import { startRpcServer } from './rpc/rpc_server.js';
2
+ import { startInteractiveMode } from './cli/interactive.js';
3
3
  import { isRpcEnabled, resolveConfig } from './src/config/args.js';
4
4
 
5
5
  const config = resolveConfig()
6
- const msb = new MainSettlementBus(config);
7
6
 
8
- msb.ready().then(async () => {
7
+ const start = async () => {
9
8
  if (isRpcEnabled()) {
10
- console.log('Starting RPC server...');
11
- startRpcServer(msb, config);
9
+ await startRpcServer(config)
12
10
  } else {
13
- console.log('RPC server will not be started.');
14
- msb.interactiveMode();
11
+ await startInteractiveMode(config)
15
12
  }
16
- });
13
+ }
14
+
15
+ start()
package/package.json CHANGED
@@ -1,26 +1,39 @@
1
1
  {
2
2
  "name": "trac-msb",
3
3
  "main": "msb.mjs",
4
- "version": "0.2.17",
4
+ "version": "0.2.19",
5
5
  "pear": {
6
6
  "name": "trac-msb",
7
7
  "type": "terminal"
8
8
  },
9
9
  "type": "module",
10
+ "files": [
11
+ "cli/",
12
+ "msb.mjs",
13
+ "NOTICE",
14
+ "rpc/",
15
+ "SECURITY.md",
16
+ "scripts/pear-runner.js",
17
+ "src/"
18
+ ],
10
19
  "scripts": {
11
- "start": "NODE_OPTIONS='--max-old-space-size=4096' pear run .",
12
- "rpc": "NODE_OPTIONS='--max-old-space-size=4096' pear run . --rpc --host ${npm_config_host} --port ${npm_config_port}",
13
- "env": "if [ -f .env ]; then set -a; . ./.env; set +a; fi; NODE_OPTIONS='--max-old-space-size=4096' pear run . --stores-directory ${STORES_DIRECTORY:-stores} --network ${NETWORK:-mainnet}",
14
- "env-rpc": "if [ -f .env ]; then set -a; . ./.env; set +a; fi; NODE_OPTIONS='--max-old-space-size=4096' pear run . --stores-directory ${STORES_DIRECTORY:-stores} --rpc --host ${MSB_HOST:-127.0.0.1} --port ${MSB_PORT:-5000} --network ${NETWORK:-mainnet}",
20
+ "start": "NODE_OPTIONS='--max-old-space-size=4096' node scripts/pear-runner.js",
21
+ "rpc": "NODE_OPTIONS='--max-old-space-size=4096' node scripts/pear-runner.js --rpc --host ${npm_config_host} --port ${npm_config_port}",
22
+ "env": "if [ -f .env ]; then set -a; . ./.env; set +a; fi; NODE_OPTIONS='--max-old-space-size=4096' node scripts/pear-runner.js --stores-directory ${STORES_DIRECTORY:-stores} --network ${NETWORK:-mainnet}",
23
+ "env-rpc": "if [ -f .env ]; then set -a; . ./.env; set +a; fi; NODE_OPTIONS='--max-old-space-size=4096' node scripts/pear-runner.js --stores-directory ${STORES_DIRECTORY:-stores} --rpc --host ${MSB_HOST:-127.0.0.1} --port ${MSB_PORT:-5000} --network ${NETWORK:-mainnet}",
15
24
  "env-rpc-docker": "if [ -f .env ]; then set -a; . ./.env; set +a; fi; NODE_OPTIONS='--max-old-space-size=4096' node msb.mjs --stores-directory ${STORES_DIRECTORY:-stores} --rpc --host 0.0.0.0 --port ${MSB_PORT:-5000} --network ${NETWORK:-mainnet}",
25
+ "lint": "eslint .",
26
+ "lint:fix": "eslint . --fix",
16
27
  "protobuf": "node scripts/generate-protobufs.js",
28
+ "docs:check": "node scripts/docs/docs-checker.js",
17
29
  "test:acceptance": "node --experimental-vm-modules node_modules/jest/bin/jest.js --testTimeout=200000 tests/acceptance/v1/rpc.test.mjs --runInBand",
18
30
  "test:integration": "brittle-node -t 1200000 tests/integration/integration.test.js",
19
31
  "test:unit:node": "brittle-node -t 60000 tests/unit/unit.test.js",
20
32
  "test:unit:bare": "brittle-bare -t 60000 tests/unit/unit.test.js",
21
- "test:unit:all": "(npm run test:unit:node && npm run test:unit:bare) || exit 1",
22
- "test:unit:node:cov": "brittle-node -c -t 60000 tests/unit/unit.test.js",
23
- "test:unit:bare:cov": "brittle-bare -c -t 60000 tests/unit/unit.test.js"
33
+ "test:unit:pear": "BRITTLE='-t 60000' brittle-pear tests/unit/unit.test.js",
34
+ "test:pear-runner": "node --test tests/runner/pear-runner.test.js",
35
+ "test:unit:all": "(npm run test:unit:node && npm run test:unit:bare && npm run test:pear-runner) || exit 1",
36
+ "test:unit:node:cov": "brittle-node -c -t 60000 tests/unit/unit.test.js"
24
37
  },
25
38
  "dependencies": {
26
39
  "autobase": "7.20.1",
@@ -35,6 +48,7 @@
35
48
  "compact-encoding": "2.18.0",
36
49
  "corestore": "7.5.0",
37
50
  "crypto": "npm:bare-node-crypto",
51
+ "denque": "^2.1.0",
38
52
  "fastest-validator": "1.19.0",
39
53
  "http": "npm:bare-node-http",
40
54
  "hyperbee": "2.26.5",
@@ -42,23 +56,31 @@
42
56
  "hypercore-crypto": "3.6.1",
43
57
  "hyperdht": "6.27.0",
44
58
  "hyperswarm": "4.14.2",
45
- "lodash": "^4.17.23",
59
+ "hyperschema": "1.17.1",
60
+ "lodash": "^4.18.1",
61
+ "p-queue": "^9.1.0",
62
+ "pear-runtime": "1.3.1",
63
+ "process": "npm:bare-process@4.2.2",
64
+ "protobufjs": "^7.5.4",
46
65
  "protocol-buffers-encodings": "1.2.0",
47
66
  "protomux": "3.10.1",
48
67
  "protomux-wakeup": "2.4.0",
49
68
  "readline": "npm:bare-node-readline",
50
69
  "ready-resource": "1.1.2",
51
70
  "trac-crypto-api": "0.1.5",
52
- "trac-wallet": "1.0.4",
71
+ "trac-wallet": "2.1.0",
53
72
  "tty": "npm:bare-node-tty",
54
73
  "uuid": "^13.0.0"
55
74
  },
56
75
  "devDependencies": {
76
+ "bare-module": "^6.1.3",
57
77
  "bare-os": "^3.6.1",
58
78
  "bip39-mnemonic": "^2.4.0",
59
- "brittle": "^3.17.1",
79
+ "brittle": "^3.19.1",
80
+ "eslint": "^9.39.4",
60
81
  "esmock": "^2.7.2",
61
82
  "jest": "^30.1.3",
83
+ "protobufjs-cli": "^1.2.0",
62
84
  "protocol-buffers": "^4.2.0",
63
85
  "sinon": "^21.0.0",
64
86
  "supertest": "^7.1.4"
@@ -4,69 +4,69 @@ import { applyCors } from './cors.js';
4
4
  import { routes } from './routes/index.js';
5
5
 
6
6
  export const createServer = (msbInstance, config) => {
7
- const server = http.createServer({}, async (req, res) => {
7
+ const server = http.createServer({}, async (req, res) => {
8
8
 
9
- // --- 1. Define safe 'respond' utility (Payload MUST be an object) ---
10
- const respond = (code, payload) => {
11
- // FIX: Prevent attempts to write headers if a response has already started
12
- if (res.headersSent) {
13
- console.warn(`Attempted to send response (Code: ${code}) after headers were already sent. payload:`, payload);
14
- return;
15
- }
9
+ // --- 1. Define safe 'respond' utility (Payload MUST be an object) ---
10
+ const respond = (code, payload) => {
11
+ // FIX: Prevent attempts to write headers if a response has already started
12
+ if (res.headersSent) {
13
+ console.warn(`Attempted to send response (Code: ${code}) after headers were already sent. payload:`, payload);
14
+ return;
15
+ }
16
16
 
17
- // Enforce JSON content type for all responses
18
- res.writeHead(code, { 'Content-Type': 'application/json' });
17
+ // Enforce JSON content type for all responses
18
+ res.writeHead(code, { 'Content-Type': 'application/json' });
19
19
 
20
- // CRITICAL: Always JSON.stringify the input object
21
- res.end(JSON.stringify(payload));
22
- }
20
+ // CRITICAL: Always JSON.stringify the input object
21
+ res.end(JSON.stringify(payload));
22
+ }
23
23
 
24
- // --- 2. Catch low-level request stream errors ---
25
- req.on('error', (err) => {
26
- console.error('Request stream error:', err);
27
- // Use the safe respond utility
28
- respond(500, { error: 'A stream-level request error occurred.' });
29
- });
24
+ // --- 2. Catch low-level request stream errors ---
25
+ req.on('error', (err) => {
26
+ console.error('Request stream error:', err);
27
+ // Use the safe respond utility
28
+ respond(500, { error: 'A stream-level request error occurred.' });
29
+ });
30
30
 
31
- if (applyCors(req, res)) return;
31
+ if (applyCors(req, res)) return;
32
32
 
33
- // Find the matching route
34
- let foundRoute = false;
33
+ // Find the matching route
34
+ let foundRoute = false;
35
35
 
36
- // Extract the path without query parameters
37
- const requestPath = req.url.split('?')[0];
36
+ // Extract the path without query parameters
37
+ const requestPath = req.url.split('?')[0];
38
38
 
39
- // Sort routes by path length (longest first) to ensure more specific routes match first
40
- const sortedRoutes = [...routes].sort((a, b) => b.path.length - a.path.length);
39
+ // Sort routes by path length (longest first) to ensure more specific routes match first
40
+ const sortedRoutes = [...routes].sort((a, b) => b.path.length - a.path.length);
41
41
 
42
- for (const route of sortedRoutes) {
42
+ for (const route of sortedRoutes) {
43
43
  // Exact path matching for base route, allow parameters after base path
44
- const routeBase = route.path.endsWith('/') ? route.path.slice(0, -1) : route.path;
45
- const requestParts = requestPath.split('/');
46
- const routeParts = routeBase.split('/');
44
+ const routeBase = route.path.endsWith('/') ? route.path.slice(0, -1) : route.path;
45
+ const requestParts = requestPath.split('/');
46
+ const routeParts = routeBase.split('/');
47
47
 
48
- if (req.method === route.method &&
48
+ if (req.method === route.method &&
49
49
  requestParts.length >= routeParts.length &&
50
50
  routeParts.every((part, i) => part === requestParts[i])) {
51
51
 
52
- foundRoute = true;
53
- try {
52
+ foundRoute = true;
53
+ try {
54
54
  // This try/catch covers synchronous errors and errors from awaited promises
55
55
  // within the route.handler function.
56
- await route.handler({ req, res, respond, msbInstance, config});
57
- } catch (error) {
56
+ await route.handler({ req, res, respond, msbInstance, config});
57
+ } catch (error) {
58
58
  // Catch errors thrown directly from the handler (or its awaited parts)
59
- console.error(`Error on ${route.path}:`, error);
60
- respond(500, { error: 'An error occurred processing the request.' });
59
+ console.error(`Error on ${route.path}:`, error);
60
+ respond(500, { error: 'An error occurred processing the request.' });
61
+ }
62
+ break;
61
63
  }
62
- break;
63
64
  }
64
- }
65
65
 
66
- if (!foundRoute) {
67
- respond(404, { error: 'Not Found' });
68
- }
69
- });
66
+ if (!foundRoute) {
67
+ respond(404, { error: 'Not Found' });
68
+ }
69
+ });
70
70
 
71
- return server
71
+ return server
72
72
  }
package/rpc/handlers.js CHANGED
@@ -5,35 +5,21 @@ import {
5
5
  sanitizeBulkPayloadsRequestBody,
6
6
  sanitizeTransferPayload,
7
7
  validatePayloadStructure,
8
- hasSpacesInUrl,
9
- BroadcastError,
10
- ValidationError,
11
- NotFoundError
8
+ hasSpacesInUrl
12
9
  } from "./utils/helpers.js"
13
10
  import { MAX_SIGNED_LENGTH, ZERO_WK } from "./constants.js";
14
11
  import { buildRequestUrl } from "./utils/url.js";
15
- import {
16
- getBalance,
17
- getTxv,
18
- getFee,
19
- getConfirmedLength,
20
- getUnconfirmedLength,
21
- broadcastTransaction,
22
- getTxHashes,
23
- getTxDetails,
24
- fetchBulkTxPayloads,
25
- getExtendedTxDetails,
26
- } from "./rpc_services.js";
27
12
  import { bufferToBigInt, licenseBufferToBigInt } from "../src/utils/amountSerialization.js";
28
13
  import { isAddressValid } from "../src/core/state/utils/address.js";
29
14
  import { getConfirmedParameter } from "./utils/confirmedParameter.js";
15
+ import { BroadcastError, ValidationError } from "../src/utils/errors.js";
30
16
 
31
17
  export async function handleHealth({ msbInstance, respond }) {
32
18
  try {
33
- const isReady = msbInstance && msbInstance.state;
19
+ const isReady = !!msbInstance?.opened
34
20
  if (isReady) return respond(200, { ok: true });
35
21
  throw new Error("RPC_OFFLINE");
36
- } catch (error) {
22
+ } catch {
37
23
  respond(503, { error: "Could not connect to RPC server" });
38
24
  }
39
25
  }
@@ -54,28 +40,28 @@ export async function handleBalance({ req, respond, msbInstance }) {
54
40
  return;
55
41
  }
56
42
 
57
- const nodeInfo = await getBalance(msbInstance, address, getConfirmedParameter(url) ?? false);
43
+ const nodeInfo = await msbInstance.getBalance(address, getConfirmedParameter(url, { defaultValue: false }));
58
44
  const balance = nodeInfo?.balance || "0";
59
45
 
60
46
  respond(200, { address, balance });
61
47
  }
62
48
 
63
49
  export async function handleTxv({ msbInstance, respond }) {
64
- const txv = await getTxv(msbInstance);
50
+ const txv = await msbInstance.getTxv();
65
51
  respond(200, { txv });
66
52
  }
67
53
 
68
54
  export async function handleFee({ msbInstance, respond }) {
69
- const fee = await getFee(msbInstance);
55
+ const fee = await msbInstance.handleGetFee().toString();
70
56
  respond(200, { fee });
71
57
  }
72
58
 
73
59
  export async function handleConfirmedLength({ msbInstance, respond }) {
74
- const confirmed_length = await getConfirmedLength(msbInstance);
60
+ const confirmed_length = await msbInstance.getConfirmedLength();
75
61
  respond(200, { confirmed_length });
76
62
  }
77
63
 
78
- export async function handleBroadcastTransaction({ msbInstance, config, respond, req }) {
64
+ export async function handleBroadcastTransaction({ msbInstance, respond, req }) {
79
65
  let body = '';
80
66
  const MAX_BODY_SIZE = 2_000_000;
81
67
  let limitExceeded = false;
@@ -101,7 +87,7 @@ export async function handleBroadcastTransaction({ msbInstance, config, respond,
101
87
  let parsedBody;
102
88
  try {
103
89
  parsedBody = JSON.parse(body);
104
- } catch (e) {
90
+ } catch {
105
91
  throw new ValidationError("Invalid JSON payload.");
106
92
  }
107
93
 
@@ -118,8 +104,8 @@ export async function handleBroadcastTransaction({ msbInstance, config, respond,
118
104
  validatePayloadStructure(decodedPayload);
119
105
  const sanitizedPayload = sanitizeTransferPayload(decodedPayload);
120
106
 
121
- const result = await broadcastTransaction(msbInstance, config, sanitizedPayload);
122
- respond(200, { result });
107
+ const result = await msbInstance.broadcastTransaction(sanitizedPayload);
108
+ respond(200, { result: { ...result, message: 'Transaction broadcasted successfully.' } });
123
109
 
124
110
  } catch (error) {
125
111
  let code = 500;
@@ -142,7 +128,7 @@ export async function handleBroadcastTransaction({ msbInstance, config, respond,
142
128
  }
143
129
  });
144
130
 
145
- req.on('error', (err) => {
131
+ req.on('error', () => {
146
132
  if (!limitExceeded) {
147
133
  respond(500, { error: 'Request stream failed during body transfer.' });
148
134
  }
@@ -174,15 +160,15 @@ export async function handleTxHashes({ msbInstance, respond, req }) {
174
160
  return respond(400, { error: `The max range for signedLength must be ${MAX_SIGNED_LENGTH}.` });
175
161
  }
176
162
 
177
- const currentConfirmedLength = await getConfirmedLength(msbInstance);
163
+ const currentConfirmedLength = await msbInstance.getConfirmedLength();
178
164
  const adjustedEndLength = Math.min(endSignedLength, currentConfirmedLength)
179
165
 
180
- const { hashes } = await getTxHashes(msbInstance, startSignedLength, adjustedEndLength);
166
+ const { hashes } = await msbInstance.getTxHashes(startSignedLength, adjustedEndLength);
181
167
  respond(200, { hashes });
182
168
  }
183
169
 
184
170
  export async function handleUnconfirmedLength({ msbInstance, respond }) {
185
- const unconfirmed_length = await getUnconfirmedLength(msbInstance);
171
+ const unconfirmed_length = await msbInstance.getUnconfirmedLength();
186
172
  respond(200, { unconfirmed_length });
187
173
  }
188
174
 
@@ -205,18 +191,14 @@ export async function handleTransactionDetails({ msbInstance, respond, req }) {
205
191
  }
206
192
 
207
193
  try {
208
- const txDetails = await getTxDetails(msbInstance, normalizedHash);
209
- respond(200, { txDetails });
210
- } catch (error) {
211
- let code = 500;
212
- let errorMsg = "Internal error";
213
-
214
- if (error instanceof NotFoundError) {
215
- code = 404;
216
- errorMsg = error.message;
194
+ const txDetails = await msbInstance.getTxDetails(normalizedHash);
195
+ if (!txDetails) {
196
+ return respond(404, { error: `Transaction ${normalizedHash} not found.` });
217
197
  }
218
198
 
219
- respond(code, { [code === 404 ? 'txDetails' : 'error']: code === 404 ? null : errorMsg });
199
+ respond(200, { txDetails });
200
+ } catch {
201
+ respond(500, { error: "Internal error" });
220
202
  }
221
203
  }
222
204
 
@@ -244,18 +226,14 @@ export async function handleTransactionExtendedDetails({ msbInstance, respond, r
244
226
  }
245
227
 
246
228
  try {
247
- const details = await getExtendedTxDetails(msbInstance, hash, confirmed);
248
- respond(200, details);
249
- } catch (error) {
250
- let code = 500;
251
- let errorMsg = 'An error occurred processing the request.';
252
-
253
- if (error instanceof NotFoundError) {
254
- code = 404;
255
- errorMsg = error.message;
229
+ const details = await msbInstance.getExtendedTxDetails(hash, confirmed);
230
+ if (!details) {
231
+ return respond(404, { error: `No payload found for tx hash: ${hash}` });
256
232
  }
257
233
 
258
- respond(code, { error: errorMsg });
234
+ respond(200, details);
235
+ } catch {
236
+ respond(500, { error: 'An error occurred processing the request.' });
259
237
  }
260
238
  }
261
239
 
@@ -282,17 +260,26 @@ export async function handleFetchBulkTxPayloads({ msbInstance, respond, req }) {
282
260
 
283
261
  try {
284
262
  if (!body) {
285
- throw new ValidationError("Missing payload.");
263
+ return respond(400, { error: "Missing payload." });
286
264
  }
287
265
 
288
266
  const sanitizedPayload = sanitizeBulkPayloadsRequestBody(body);
289
267
  if (!sanitizedPayload) {
290
- throw new ValidationError("Invalid payload.");
268
+ return respond(400, { error: "Invalid payload." });
291
269
  }
292
270
 
293
271
  const { hashes } = sanitizedPayload;
272
+
273
+ if (!Array.isArray(hashes) || hashes.length === 0) {
274
+ return respond(400, { error: "Missing hash list." });
275
+ }
276
+
294
277
  const uniqueHashes = [...new Set(hashes)];
295
- const commandResult = await fetchBulkTxPayloads(msbInstance, uniqueHashes);
278
+
279
+ if (uniqueHashes.length > 1500) {
280
+ return respond(400, { error: 'Length of input tx hashes exceeded.' });
281
+ }
282
+ const commandResult = await msbInstance.fetchBulkTxPayloads(uniqueHashes);
296
283
 
297
284
  const responseString = JSON.stringify(commandResult);
298
285
  if (Buffer.byteLength(responseString, 'utf8') > 2_000_000) {
@@ -304,7 +291,7 @@ export async function handleFetchBulkTxPayloads({ msbInstance, respond, req }) {
304
291
  let code = 500;
305
292
  let errorMsg = 'An internal error occurred.';
306
293
 
307
- if (error instanceof ValidationError || error instanceof SyntaxError) {
294
+ if (error instanceof SyntaxError) {
308
295
  code = 400;
309
296
  errorMsg = error instanceof SyntaxError ? 'Invalid request body format.' : error.message;
310
297
  }
@@ -313,7 +300,7 @@ export async function handleFetchBulkTxPayloads({ msbInstance, respond, req }) {
313
300
  }
314
301
  })
315
302
 
316
- req.on('error', (err) => {
303
+ req.on('error', () => {
317
304
  respond(500, { error: 'Request stream failed during body transfer.' });
318
305
  });
319
306
  }
@@ -365,4 +352,4 @@ export async function handleAccountDetails({ msbInstance, respond, req }) {
365
352
  balance: bufferToBigInt(nodeEntry.balance).toString(),
366
353
  stakedBalance: bufferToBigInt(nodeEntry.stakedBalance).toString(),
367
354
  });
368
- }
355
+ }
@@ -5,8 +5,8 @@ import { v1Routes } from './v1.js';
5
5
 
6
6
  // Map each version to its route list
7
7
  const routeMap = {
8
- v1: v1Routes,
9
- // v2: v2Routes
8
+ v1: v1Routes,
9
+ // v2: v2Routes
10
10
  };
11
11
 
12
12
  // Dynamically collect supported versions from routeMap
@@ -14,14 +14,14 @@ const supportedVersions = Object.keys(routeMap);
14
14
 
15
15
  // Helper to prefix all routes with version
16
16
  function prefixRoutes(prefix, routes) {
17
- return routes.map(route => ({
18
- ...route,
19
- path: `/${prefix}${route.path}`,
20
- }));
17
+ return routes.map(route => ({
18
+ ...route,
19
+ path: `/${prefix}${route.path}`,
20
+ }));
21
21
  }
22
22
 
23
23
  // Final route export
24
24
  export const routes = [
25
- // Prefix each version’s routes automatically
26
- ...supportedVersions.flatMap(v => prefixRoutes(v, routeMap[v])),
25
+ // Prefix each version’s routes automatically
26
+ ...supportedVersions.flatMap(v => prefixRoutes(v, routeMap[v])),
27
27
  ];