trac-msb 0.2.18 → 0.2.20

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 (381) 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 +25 -8
  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 +138 -10
  16. package/src/config/env.js +36 -18
  17. package/src/core/network/Network.js +130 -34
  18. package/src/core/network/protocols/ProtocolInterface.js +5 -5
  19. package/src/core/network/protocols/connectionPolicies.js +86 -0
  20. package/src/core/network/protocols/legacy/NetworkMessageRouter.js +1 -1
  21. package/src/core/network/protocols/legacy/handlers/BaseStateOperationHandler.js +2 -2
  22. package/src/core/network/protocols/legacy/handlers/LegacyGetRequestHandler.js +3 -3
  23. package/src/core/network/protocols/legacy/handlers/LegacyRoleOperationHandler.js +1 -1
  24. package/src/core/network/protocols/legacy/handlers/LegacySubnetworkOperationHandler.js +1 -1
  25. package/src/core/network/protocols/legacy/handlers/LegacyTransferOperationHandler.js +1 -1
  26. package/src/core/network/protocols/legacy/validators/base/BaseResponse.js +7 -10
  27. package/src/core/network/protocols/shared/validators/PartialBootstrapDeploymentValidator.js +2 -2
  28. package/src/core/network/protocols/shared/validators/PartialOperationValidator.js +23 -23
  29. package/src/core/network/protocols/shared/validators/PartialRoleAccessValidator.js +14 -14
  30. package/src/core/network/protocols/shared/validators/PartialTransactionValidator.js +5 -5
  31. package/src/core/network/protocols/shared/validators/PartialTransferValidator.js +12 -11
  32. package/src/core/network/protocols/v1/V1ProtocolError.js +5 -69
  33. package/src/core/network/protocols/v1/handlers/V1BaseOperationHandler.js +3 -2
  34. package/src/core/network/protocols/v1/handlers/V1BroadcastTransactionOperationHandler.js +130 -247
  35. package/src/core/network/protocols/v1/handlers/V1LivenessOperationHandler.js +6 -5
  36. package/src/core/network/protocols/v1/handlers/broadcastTransaction/BroadcastTransactionErrorMapper.js +84 -0
  37. package/src/core/network/protocols/v1/handlers/broadcastTransaction/BroadcastTransactionOperationStrategies.js +128 -0
  38. package/src/core/network/protocols/v1/handlers/broadcastTransaction/BroadcastTransactionPayloadUtils.js +26 -0
  39. package/src/core/network/protocols/v1/validators/V1BaseOperation.js +32 -31
  40. package/src/core/network/protocols/v1/validators/V1BroadcastTransactionRequest.js +5 -3
  41. package/src/core/network/protocols/v1/validators/V1BroadcastTransactionResponse.js +34 -50
  42. package/src/core/network/protocols/v1/validators/V1ValidationSchema.js +1 -1
  43. package/src/core/network/services/ConnectionManager.js +11 -10
  44. package/src/core/network/services/MessageOrchestrator.js +53 -17
  45. package/src/core/network/services/PendingRequestService.js +22 -19
  46. package/src/core/network/services/TransactionCommitService.js +36 -36
  47. package/src/core/network/services/TransactionPoolService.js +39 -39
  48. package/src/core/network/services/TransactionRateLimiterService.js +8 -4
  49. package/src/core/network/services/ValidatorObserverService.js +397 -110
  50. package/src/core/state/State.js +190 -138
  51. package/src/core/state/utils/address.js +4 -9
  52. package/src/core/state/utils/balance.js +7 -7
  53. package/src/core/state/utils/roles.js +1 -1
  54. package/src/index.js +316 -275
  55. package/src/messages/network/v1/NetworkMessageBuilder.js +12 -21
  56. package/src/messages/network/v1/networkMessageFactory.js +1 -1
  57. package/src/messages/state/ApplyStateMessageBuilder.js +6 -6
  58. package/src/messages/state/applyStateMessageFactory.js +1 -1
  59. package/src/utils/buffer.js +1 -1
  60. package/src/utils/check.js +12 -13
  61. package/src/utils/constants.js +7 -0
  62. package/src/utils/errors.js +20 -0
  63. package/src/utils/fileUtils.js +12 -3
  64. package/src/utils/helpers.js +2 -2
  65. package/src/utils/migrationUtils.js +3 -3
  66. package/.dockerignore +0 -16
  67. package/CODE_OF_CONDUCT.md +0 -128
  68. package/docker-compose.yml +0 -17
  69. package/dockerfile +0 -41
  70. package/docs/fee_distribution.md +0 -89
  71. package/docs/trac_network_http_api.openapi.yaml +0 -889
  72. package/migration/.gitkeep +0 -0
  73. package/proto/applyOperations.proto +0 -117
  74. package/proto/network/v1/enums/message_type.proto +0 -16
  75. package/proto/network/v1/enums/result_code.proto +0 -84
  76. package/proto/network/v1/messages/broadcast_transaction_request.proto +0 -9
  77. package/proto/network/v1/messages/broadcast_transaction_response.proto +0 -13
  78. package/proto/network/v1/messages/liveness_request.proto +0 -8
  79. package/proto/network/v1/messages/liveness_response.proto +0 -11
  80. package/proto/network/v1/network_message.proto +0 -22
  81. package/rpc/rpc_services.js +0 -181
  82. package/scripts/generate-protobufs.js +0 -67
  83. package/src/core/network/identity/NetworkWalletFactory.js +0 -77
  84. package/src/core/network/protocols/shared/errors/SharedValidatorRejectionError.js +0 -27
  85. package/src/utils/cli.js +0 -130
  86. package/src/utils/cliCommands.js +0 -280
  87. package/tests/acceptance/v1/account/account.test.mjs +0 -129
  88. package/tests/acceptance/v1/balance/balance.test.mjs +0 -54
  89. package/tests/acceptance/v1/broadcast-transaction/broadcast-transaction.test.mjs +0 -116
  90. package/tests/acceptance/v1/confirmed-length/confirmed-length.test.mjs +0 -19
  91. package/tests/acceptance/v1/fee/fee.test.mjs +0 -11
  92. package/tests/acceptance/v1/health/health.test.mjs +0 -33
  93. package/tests/acceptance/v1/rpc.test.mjs +0 -95
  94. package/tests/acceptance/v1/tx/tx.test.mjs +0 -133
  95. package/tests/acceptance/v1/tx-details/tx-details.test.mjs +0 -241
  96. package/tests/acceptance/v1/tx-hashes/tx-hashes.test.mjs +0 -72
  97. package/tests/acceptance/v1/tx-payloads-bulk/tx-payloads-bulk.test.mjs +0 -27
  98. package/tests/acceptance/v1/txv/txv.test.mjs +0 -11
  99. package/tests/acceptance/v1/unconfirmed-length/unconfirmed-length.test.mjs +0 -11
  100. package/tests/fixtures/apply.fixtures.js +0 -77
  101. package/tests/fixtures/assembleMessage.fixtures.js +0 -41
  102. package/tests/fixtures/check.fixtures.js +0 -428
  103. package/tests/fixtures/networkV1.fixtures.js +0 -59
  104. package/tests/fixtures/protobuf.fixtures.js +0 -388
  105. package/tests/helpers/StateNetworkFactory.js +0 -155
  106. package/tests/helpers/address.js +0 -6
  107. package/tests/helpers/autobaseTestHelpers.js +0 -419
  108. package/tests/helpers/config.js +0 -4
  109. package/tests/helpers/createTestSignature.js +0 -13
  110. package/tests/helpers/regexHelper.js +0 -3
  111. package/tests/helpers/setupApplyTests.js +0 -587
  112. package/tests/helpers/transactionPayloads.mjs +0 -92
  113. package/tests/helpers/wrapper.js +0 -28
  114. package/tests/unit/messages/messages.test.js +0 -12
  115. package/tests/unit/messages/network/NetworkMessageBuilder.test.js +0 -436
  116. package/tests/unit/messages/network/NetworkMessageDirector.test.js +0 -347
  117. package/tests/unit/messages/state/applyStateMessageBuilder.complete.test.js +0 -525
  118. package/tests/unit/messages/state/applyStateMessageBuilder.partial.test.js +0 -237
  119. package/tests/unit/network/LegacyNetworkMessageRouter.test.js +0 -54
  120. package/tests/unit/network/NetworkWalletFactory.test.js +0 -156
  121. package/tests/unit/network/ProtocolSession.test.js +0 -127
  122. package/tests/unit/network/networkModule.test.js +0 -13
  123. package/tests/unit/network/services/ConnectionManager.test.js +0 -450
  124. package/tests/unit/network/services/MessageOrchestrator.test.js +0 -445
  125. package/tests/unit/network/services/PendingRequestService.test.js +0 -431
  126. package/tests/unit/network/services/TransactionCommitService.test.js +0 -246
  127. package/tests/unit/network/services/TransactionPoolService.test.js +0 -489
  128. package/tests/unit/network/services/TransactionRateLimiterService.test.js +0 -139
  129. package/tests/unit/network/services/ValidatorHealthCheckService.test.js +0 -115
  130. package/tests/unit/network/services/services.test.js +0 -17
  131. package/tests/unit/network/utils/v1TestUtils.js +0 -153
  132. package/tests/unit/network/v1/NetworkMessageRouterV1.test.js +0 -151
  133. package/tests/unit/network/v1/V1BaseOperation.test.js +0 -356
  134. package/tests/unit/network/v1/V1BroadcastTransactionOperationHandler.test.js +0 -129
  135. package/tests/unit/network/v1/V1BroadcastTransactionRequest.test.js +0 -53
  136. package/tests/unit/network/v1/V1BroadcastTransactionResponse.test.js +0 -512
  137. package/tests/unit/network/v1/V1LivenessRequest.test.js +0 -32
  138. package/tests/unit/network/v1/V1LivenessResponse.test.js +0 -45
  139. package/tests/unit/network/v1/V1ResultCode.test.js +0 -84
  140. package/tests/unit/network/v1/V1ValidationSchema.test.js +0 -13
  141. package/tests/unit/network/v1/connectionPolicies.test.js +0 -49
  142. package/tests/unit/network/v1/handlers/V1BaseOperationHandler.test.js +0 -284
  143. package/tests/unit/network/v1/handlers/V1BroadcastTransactionOperationHandler.test.js +0 -794
  144. package/tests/unit/network/v1/handlers/V1LivenessOperationHandler.test.js +0 -193
  145. package/tests/unit/network/v1/v1.handlers.test.js +0 -15
  146. package/tests/unit/network/v1/v1.test.js +0 -19
  147. package/tests/unit/network/v1/v1ValidationSchema/broadcastTransactionRequest.test.js +0 -119
  148. package/tests/unit/network/v1/v1ValidationSchema/broadcastTransactionResponse.test.js +0 -136
  149. package/tests/unit/network/v1/v1ValidationSchema/common.test.js +0 -308
  150. package/tests/unit/network/v1/v1ValidationSchema/livenessRequest.test.js +0 -90
  151. package/tests/unit/network/v1/v1ValidationSchema/livenessResponse.test.js +0 -133
  152. package/tests/unit/state/State.test.js +0 -80
  153. package/tests/unit/state/apply/addAdmin/addAdminHappyPathScenario.js +0 -42
  154. package/tests/unit/state/apply/addAdmin/addAdminScenarioHelpers.js +0 -276
  155. package/tests/unit/state/apply/addAdmin/adminEntryEncodingFailureScenario.js +0 -30
  156. package/tests/unit/state/apply/addAdmin/adminEntryExistsScenario.js +0 -78
  157. package/tests/unit/state/apply/addAdmin/nodeEntryInitializationFailureScenario.js +0 -30
  158. package/tests/unit/state/apply/addAdmin/nonBootstrapNodeScenario.js +0 -68
  159. package/tests/unit/state/apply/addAdmin/state.apply.addAdmin.test.js +0 -159
  160. package/tests/unit/state/apply/addIndexer/addIndexerHappyPathScenario.js +0 -39
  161. package/tests/unit/state/apply/addIndexer/addIndexerMultipleIndexersInTheNetworkScenario.js +0 -167
  162. package/tests/unit/state/apply/addIndexer/addIndexerPretenderAlreadyIndexerScenario.js +0 -21
  163. package/tests/unit/state/apply/addIndexer/addIndexerPretenderNotWriterScenario.js +0 -21
  164. package/tests/unit/state/apply/addIndexer/addIndexerRemoveAndReAddScenario.js +0 -186
  165. package/tests/unit/state/apply/addIndexer/addIndexerScenarioHelpers.js +0 -443
  166. package/tests/unit/state/apply/addIndexer/addIndexerWriterKeyAlreadyRegisteredScenario.js +0 -32
  167. package/tests/unit/state/apply/addIndexer/state.apply.addIndexer.test.js +0 -297
  168. package/tests/unit/state/apply/addWriter/addWriterHappyPathScenario.js +0 -41
  169. package/tests/unit/state/apply/addWriter/addWriterInvalidValidatorSignatureScenario.js +0 -32
  170. package/tests/unit/state/apply/addWriter/addWriterNewWkScenario.js +0 -149
  171. package/tests/unit/state/apply/addWriter/addWriterRequesterAlreadyWriterScenario.js +0 -21
  172. package/tests/unit/state/apply/addWriter/addWriterRequesterBalanceInsufficientScenario.js +0 -21
  173. package/tests/unit/state/apply/addWriter/addWriterRequesterEntryDecodeFailureScenario.js +0 -19
  174. package/tests/unit/state/apply/addWriter/addWriterRequesterEntryMissingScenario.js +0 -19
  175. package/tests/unit/state/apply/addWriter/addWriterRequesterIndexerScenario.js +0 -21
  176. package/tests/unit/state/apply/addWriter/addWriterRequesterNotWhitelistedScenario.js +0 -21
  177. package/tests/unit/state/apply/addWriter/addWriterScenarioHelpers.js +0 -766
  178. package/tests/unit/state/apply/addWriter/addWriterStakeBalanceUpdateFailureScenario.js +0 -50
  179. package/tests/unit/state/apply/addWriter/addWriterStakeInsufficientBalanceScenario.js +0 -29
  180. package/tests/unit/state/apply/addWriter/addWriterStakeInvalidBalanceScenario.js +0 -29
  181. package/tests/unit/state/apply/addWriter/addWriterStakeInvalidEntryScenario.js +0 -21
  182. package/tests/unit/state/apply/addWriter/addWriterStakeStakedBalanceFailureScenario.js +0 -37
  183. package/tests/unit/state/apply/addWriter/addWriterStakeSubtractFailureScenario.js +0 -42
  184. package/tests/unit/state/apply/addWriter/addWriterValidatorRewardScenario.js +0 -106
  185. package/tests/unit/state/apply/addWriter/addWriterWriterKeyMismatchScenario.js +0 -54
  186. package/tests/unit/state/apply/addWriter/addWriterWriterKeyOwnershipScenario.js +0 -54
  187. package/tests/unit/state/apply/addWriter/addWriterZeroWriterKeyScenario.js +0 -29
  188. package/tests/unit/state/apply/addWriter/state.apply.addWriter.test.js +0 -309
  189. package/tests/unit/state/apply/adminRecovery/adminRecoveryHappyPathScenario.js +0 -30
  190. package/tests/unit/state/apply/adminRecovery/adminRecoveryScenarioHelpers.js +0 -881
  191. package/tests/unit/state/apply/adminRecovery/state.apply.adminRecovery.test.js +0 -435
  192. package/tests/unit/state/apply/appendWhitelist/appendWhitelistBanAndReapplyScenario.js +0 -78
  193. package/tests/unit/state/apply/appendWhitelist/appendWhitelistExistingReaderHappyPathScenario.js +0 -98
  194. package/tests/unit/state/apply/appendWhitelist/appendWhitelistFeeAfterDisableScenario.js +0 -66
  195. package/tests/unit/state/apply/appendWhitelist/appendWhitelistHappyPathScenario.js +0 -55
  196. package/tests/unit/state/apply/appendWhitelist/appendWhitelistInsufficientAdminBalanceScenario.js +0 -103
  197. package/tests/unit/state/apply/appendWhitelist/appendWhitelistNodeAlreadyWhitelistedScenario.js +0 -60
  198. package/tests/unit/state/apply/appendWhitelist/appendWhitelistScenarioHelpers.js +0 -189
  199. package/tests/unit/state/apply/appendWhitelist/state.apply.appendWhitelist.test.js +0 -220
  200. package/tests/unit/state/apply/balanceInitialization/balanceInitializationHappyPathScenario.js +0 -82
  201. package/tests/unit/state/apply/balanceInitialization/balanceInitializationScenarioHelpers.js +0 -111
  202. package/tests/unit/state/apply/balanceInitialization/invalidAmountScenario.js +0 -45
  203. package/tests/unit/state/apply/balanceInitialization/nodeEntryBalanceUpdateFailureScenario.js +0 -82
  204. package/tests/unit/state/apply/balanceInitialization/state.apply.balanceInitialization.test.js +0 -189
  205. package/tests/unit/state/apply/banValidator/banValidatorBanAndReWhitelistScenario.js +0 -156
  206. package/tests/unit/state/apply/banValidator/banValidatorHappyPathScenario.js +0 -36
  207. package/tests/unit/state/apply/banValidator/banValidatorScenarioHelpers.js +0 -531
  208. package/tests/unit/state/apply/banValidator/banValidatorSequentialBansScenario.js +0 -74
  209. package/tests/unit/state/apply/banValidator/banValidatorTargetDecodeFailureScenario.js +0 -19
  210. package/tests/unit/state/apply/banValidator/banValidatorTargetIndexerScenario.js +0 -32
  211. package/tests/unit/state/apply/banValidator/banValidatorTargetNodeEntryMissingScenario.js +0 -19
  212. package/tests/unit/state/apply/banValidator/banValidatorTargetRoleUpdateFailureScenario.js +0 -19
  213. package/tests/unit/state/apply/banValidator/banValidatorWhitelistedNonWriterScenario.js +0 -38
  214. package/tests/unit/state/apply/banValidator/banValidatorWhitelistedZeroBalanceScenario.js +0 -91
  215. package/tests/unit/state/apply/banValidator/banValidatorWithdrawFailureScenario.js +0 -19
  216. package/tests/unit/state/apply/banValidator/state.apply.banValidator.test.js +0 -266
  217. package/tests/unit/state/apply/bootstrapDeployment/bootstrapDeploymentDuplicateRegistrationScenario.js +0 -143
  218. package/tests/unit/state/apply/bootstrapDeployment/bootstrapDeploymentHappyPathScenario.js +0 -26
  219. package/tests/unit/state/apply/bootstrapDeployment/bootstrapDeploymentIncompleteOperationScenario.js +0 -94
  220. package/tests/unit/state/apply/bootstrapDeployment/bootstrapDeploymentInvalidDeploymentEntryScenario.js +0 -37
  221. package/tests/unit/state/apply/bootstrapDeployment/bootstrapDeploymentMultipleBootstrapScenario.js +0 -86
  222. package/tests/unit/state/apply/bootstrapDeployment/bootstrapDeploymentScenarioHelpers.js +0 -347
  223. package/tests/unit/state/apply/bootstrapDeployment/invalidValidatorNodeEntryScenario.js +0 -57
  224. package/tests/unit/state/apply/bootstrapDeployment/state.apply.bootstrapDeployment.test.js +0 -429
  225. package/tests/unit/state/apply/common/access-control/adminConsistencyMismatchScenario.js +0 -120
  226. package/tests/unit/state/apply/common/access-control/adminEntryDecodeFailureScenario.js +0 -130
  227. package/tests/unit/state/apply/common/access-control/adminEntryExistsScenario.js +0 -93
  228. package/tests/unit/state/apply/common/access-control/adminEntryMissingScenario.js +0 -108
  229. package/tests/unit/state/apply/common/access-control/adminOnlyGuardScenario.js +0 -126
  230. package/tests/unit/state/apply/common/access-control/adminPublicKeyDecodeFailureScenario.js +0 -121
  231. package/tests/unit/state/apply/common/access-control/roleAccessOperationValidationScenario.js +0 -50
  232. package/tests/unit/state/apply/common/adminControlOperationValidationScenario.js +0 -56
  233. package/tests/unit/state/apply/common/balances/adminEntryUpdateFailureScenario.js +0 -52
  234. package/tests/unit/state/apply/common/balances/base/requesterBalanceScenarioBase.js +0 -198
  235. package/tests/unit/state/apply/common/balances/feeDecodeFailureScenario.js +0 -52
  236. package/tests/unit/state/apply/common/balances/requesterBalanceDecodeFailureScenario.js +0 -15
  237. package/tests/unit/state/apply/common/balances/requesterBalanceFeeApplicationFailureScenario.js +0 -11
  238. package/tests/unit/state/apply/common/balances/requesterBalanceInsufficientScenario.js +0 -15
  239. package/tests/unit/state/apply/common/balances/requesterBalanceUpdateFailureScenario.js +0 -11
  240. package/tests/unit/state/apply/common/balances/validatorEntryRewardFailureScenario.js +0 -11
  241. package/tests/unit/state/apply/common/balances/validatorEntryUpdateFailureScenario.js +0 -11
  242. package/tests/unit/state/apply/common/balances/validatorNodeEntryDecodeFailureScenario.js +0 -40
  243. package/tests/unit/state/apply/common/base/OperationValidationScenarioBase.js +0 -114
  244. package/tests/unit/state/apply/common/commonScenarioHelper.js +0 -103
  245. package/tests/unit/state/apply/common/indexer/indexerNodeEntryDecodeFailureScenario.js +0 -36
  246. package/tests/unit/state/apply/common/indexer/indexerNodeEntryMissingScenario.js +0 -36
  247. package/tests/unit/state/apply/common/indexer/indexerRoleUpdateFailureScenario.js +0 -29
  248. package/tests/unit/state/apply/common/indexer/indexerSequenceStateInvalidScenario.js +0 -66
  249. package/tests/unit/state/apply/common/invalidMessageComponentValidationScenario.js +0 -84
  250. package/tests/unit/state/apply/common/nodeEntryInitializationFailureScenario.js +0 -47
  251. package/tests/unit/state/apply/common/operationAlreadyAppliedScenario.js +0 -85
  252. package/tests/unit/state/apply/common/payload-structure/addressWithInvalidPublicKeyScenario.js +0 -52
  253. package/tests/unit/state/apply/common/payload-structure/initializationDisabledScenario.js +0 -54
  254. package/tests/unit/state/apply/common/payload-structure/invalidAddressValidationScenario.js +0 -73
  255. package/tests/unit/state/apply/common/payload-structure/invalidHashValidationScenario.js +0 -71
  256. package/tests/unit/state/apply/common/payload-structure/invalidPayloadValidationScenario.js +0 -31
  257. package/tests/unit/state/apply/common/payload-structure/invalidSignatureValidationScenario.js +0 -142
  258. package/tests/unit/state/apply/common/payload-structure/partialOperationValidationScenario.js +0 -87
  259. package/tests/unit/state/apply/common/requester/requesterNodeEntryBufferMissingScenario.js +0 -71
  260. package/tests/unit/state/apply/common/requester/requesterNodeEntryDecodeFailureScenario.js +0 -73
  261. package/tests/unit/state/apply/common/requester/requesterNodeEntryMissingScenario.js +0 -36
  262. package/tests/unit/state/apply/common/requesterAddressValidationScenario.js +0 -44
  263. package/tests/unit/state/apply/common/requesterPublicKeyValidationScenario.js +0 -25
  264. package/tests/unit/state/apply/common/transactionValidityMismatchScenario.js +0 -98
  265. package/tests/unit/state/apply/common/validatorConsistency/base/validatorConsistencyScenarioBase.js +0 -202
  266. package/tests/unit/state/apply/common/validatorConsistency/validatorEntryDecodeFailureScenario.js +0 -17
  267. package/tests/unit/state/apply/common/validatorConsistency/validatorEntryMissingScenario.js +0 -44
  268. package/tests/unit/state/apply/common/validatorConsistency/validatorInactiveScenario.js +0 -19
  269. package/tests/unit/state/apply/common/validatorConsistency/validatorWriterKeyMismatchScenario.js +0 -18
  270. package/tests/unit/state/apply/common/validatorEntryValidation/base/validatorEntryValidationScenarioBase.js +0 -315
  271. package/tests/unit/state/apply/common/validatorEntryValidation/validatorEntryInvalidBalanceScenario.js +0 -18
  272. package/tests/unit/state/apply/common/writerKeyExistsValidationScenario.js +0 -43
  273. package/tests/unit/state/apply/disableInitialization/disableInitializationAlreadyDisabledScenario.js +0 -53
  274. package/tests/unit/state/apply/disableInitialization/disableInitializationHappyPathScenario.js +0 -24
  275. package/tests/unit/state/apply/disableInitialization/disableInitializationScenarioHelpers.js +0 -204
  276. package/tests/unit/state/apply/disableInitialization/state.apply.disableInitialization.test.js +0 -161
  277. package/tests/unit/state/apply/missing-tests.md +0 -18
  278. package/tests/unit/state/apply/removeIndexer/removeIndexerHappyPathScenario.js +0 -58
  279. package/tests/unit/state/apply/removeIndexer/removeIndexerReAddAndRemoveAgainScenario.js +0 -98
  280. package/tests/unit/state/apply/removeIndexer/removeIndexerRemoveMultipleIndexersScenario.js +0 -167
  281. package/tests/unit/state/apply/removeIndexer/removeIndexerScenarioHelpers.js +0 -429
  282. package/tests/unit/state/apply/removeIndexer/removeIndexerTargetNotIndexerScenario.js +0 -22
  283. package/tests/unit/state/apply/removeIndexer/removeIndexerWriterKeyMissingScenario.js +0 -20
  284. package/tests/unit/state/apply/removeIndexer/state.apply.removeIndexer.test.js +0 -291
  285. package/tests/unit/state/apply/removeWriter/removeWriterAndAddWriterAgainScenario.js +0 -87
  286. package/tests/unit/state/apply/removeWriter/removeWriterHappyPathScenario.js +0 -38
  287. package/tests/unit/state/apply/removeWriter/removeWriterInvalidValidatorSignatureScenario.js +0 -32
  288. package/tests/unit/state/apply/removeWriter/removeWriterRequesterBalanceInsufficientScenario.js +0 -21
  289. package/tests/unit/state/apply/removeWriter/removeWriterRequesterEntryDecodeFailureScenario.js +0 -19
  290. package/tests/unit/state/apply/removeWriter/removeWriterRequesterEntryMissingScenario.js +0 -19
  291. package/tests/unit/state/apply/removeWriter/removeWriterRequesterIndexerScenario.js +0 -21
  292. package/tests/unit/state/apply/removeWriter/removeWriterRequesterNotWriterScenario.js +0 -21
  293. package/tests/unit/state/apply/removeWriter/removeWriterRequesterRoleUpdateFailureScenario.js +0 -19
  294. package/tests/unit/state/apply/removeWriter/removeWriterScenarioHelpers.js +0 -348
  295. package/tests/unit/state/apply/removeWriter/removeWriterThroughWriterValidatorScenario.js +0 -113
  296. package/tests/unit/state/apply/removeWriter/removeWriterUnstakeFailureScenario.js +0 -33
  297. package/tests/unit/state/apply/removeWriter/removeWriterWriterKeyMismatchScenario.js +0 -21
  298. package/tests/unit/state/apply/removeWriter/removeWriterWriterKeyOwnershipScenario.js +0 -26
  299. package/tests/unit/state/apply/removeWriter/removeWriterWriterKeyRegistryMissingScenario.js +0 -22
  300. package/tests/unit/state/apply/removeWriter/state.apply.removeWriter.test.js +0 -307
  301. package/tests/unit/state/apply/state.apply.test.js +0 -24
  302. package/tests/unit/state/apply/transfer/state.apply.transfer.test.js +0 -819
  303. package/tests/unit/state/apply/transfer/transferContractSchemaValidationScenario.js +0 -22
  304. package/tests/unit/state/apply/transfer/transferDoubleSpendAcrossValidatorsScenario.js +0 -146
  305. package/tests/unit/state/apply/transfer/transferDoubleSpendSameBatchScenario.js +0 -63
  306. package/tests/unit/state/apply/transfer/transferDoubleSpendSingleValidatorScenario.js +0 -67
  307. package/tests/unit/state/apply/transfer/transferExistingRecipientAmountScenario.js +0 -31
  308. package/tests/unit/state/apply/transfer/transferExistingRecipientZeroAmountScenario.js +0 -31
  309. package/tests/unit/state/apply/transfer/transferHandlerGuardScenarios.js +0 -22
  310. package/tests/unit/state/apply/transfer/transferHappyPathScenario.js +0 -8
  311. package/tests/unit/state/apply/transfer/transferInvalidIncomingDataScenario.js +0 -66
  312. package/tests/unit/state/apply/transfer/transferNewRecipientAmountScenario.js +0 -31
  313. package/tests/unit/state/apply/transfer/transferNewRecipientZeroAmountScenario.js +0 -31
  314. package/tests/unit/state/apply/transfer/transferScenarioHelpers.js +0 -1170
  315. package/tests/unit/state/apply/transfer/transferSelfTransferAmountScenario.js +0 -38
  316. package/tests/unit/state/apply/transfer/transferSelfTransferZeroAmountScenario.js +0 -38
  317. package/tests/unit/state/apply/transfer/transferValidatorRecipientAmountScenario.js +0 -38
  318. package/tests/unit/state/apply/transfer/transferValidatorRecipientZeroAmountScenario.js +0 -38
  319. package/tests/unit/state/apply/txOperation/state.apply.txOperation.test.js +0 -318
  320. package/tests/unit/state/apply/txOperation/txOperationBootstrapNotRegisteredScenario.js +0 -70
  321. package/tests/unit/state/apply/txOperation/txOperationDifferentValidatorCreatorHappyPathScenario.js +0 -23
  322. package/tests/unit/state/apply/txOperation/txOperationInvalidDeploymentEntryScenario.js +0 -48
  323. package/tests/unit/state/apply/txOperation/txOperationInvalidFeeAmountScenario.js +0 -39
  324. package/tests/unit/state/apply/txOperation/txOperationInvalidSubnetCreatorAddressScenario.js +0 -46
  325. package/tests/unit/state/apply/txOperation/txOperationRequesterCreatorHappyPathScenario.js +0 -21
  326. package/tests/unit/state/apply/txOperation/txOperationScenarioHelpers.js +0 -432
  327. package/tests/unit/state/apply/txOperation/txOperationStandardHappyPathScenario.js +0 -21
  328. package/tests/unit/state/apply/txOperation/txOperationTransferFeeAddCreatorBalanceFailureScenario.js +0 -26
  329. package/tests/unit/state/apply/txOperation/txOperationTransferFeeAddValidatorBalanceFailureScenario.js +0 -25
  330. package/tests/unit/state/apply/txOperation/txOperationTransferFeeAddValidatorBonusFailureScenario.js +0 -27
  331. package/tests/unit/state/apply/txOperation/txOperationTransferFeeDecodeCreatorEntryScenario.js +0 -18
  332. package/tests/unit/state/apply/txOperation/txOperationTransferFeeDecodeRequesterEntryScenario.js +0 -17
  333. package/tests/unit/state/apply/txOperation/txOperationTransferFeeDecodeValidatorEntryScenario.js +0 -31
  334. package/tests/unit/state/apply/txOperation/txOperationTransferFeeGuardBypassScenario.js +0 -49
  335. package/tests/unit/state/apply/txOperation/txOperationTransferFeeGuardScenarioFactory.js +0 -93
  336. package/tests/unit/state/apply/txOperation/txOperationTransferFeeInsufficientRequesterBalanceScenario.js +0 -28
  337. package/tests/unit/state/apply/txOperation/txOperationTransferFeeInvalidCreatorBalanceScenario.js +0 -29
  338. package/tests/unit/state/apply/txOperation/txOperationTransferFeeInvalidRequesterBalanceScenario.js +0 -28
  339. package/tests/unit/state/apply/txOperation/txOperationTransferFeeInvalidRequesterEntryScenario.js +0 -17
  340. package/tests/unit/state/apply/txOperation/txOperationTransferFeeInvalidValidatorBalanceScenario.js +0 -33
  341. package/tests/unit/state/apply/txOperation/txOperationTransferFeeMissingCreatorEntryScenario.js +0 -18
  342. package/tests/unit/state/apply/txOperation/txOperationTransferFeeSubtractFailureScenario.js +0 -25
  343. package/tests/unit/state/apply/txOperation/txOperationTransferFeeUpdateCreatorBalanceFailureScenario.js +0 -26
  344. package/tests/unit/state/apply/txOperation/txOperationTransferFeeUpdateFailureScenario.js +0 -25
  345. package/tests/unit/state/apply/txOperation/txOperationTransferFeeUpdateValidatorBalanceFailureScenario.js +0 -26
  346. package/tests/unit/state/apply/txOperation/txOperationTransferFeeUpdateValidatorBonusFailureScenario.js +0 -27
  347. package/tests/unit/state/apply/txOperation/txOperationValidatorCreatorHappyPathScenario.js +0 -21
  348. package/tests/unit/state/stateModule.test.js +0 -23
  349. package/tests/unit/state/stateTestUtils.js +0 -32
  350. package/tests/unit/state/utils/address.test.js +0 -63
  351. package/tests/unit/state/utils/adminEntry.test.js +0 -52
  352. package/tests/unit/state/utils/balance.test.js +0 -320
  353. package/tests/unit/state/utils/lengthEntry.test.js +0 -54
  354. package/tests/unit/state/utils/nodeEntry.test.js +0 -298
  355. package/tests/unit/state/utils/roles.test.js +0 -44
  356. package/tests/unit/unit.test.js +0 -14
  357. package/tests/unit/utils/amountSerialization/amountSerialization.test.js +0 -237
  358. package/tests/unit/utils/buffer/buffer.test.js +0 -251
  359. package/tests/unit/utils/check/adminControlOperation.test.js +0 -156
  360. package/tests/unit/utils/check/balanceInitializationOperation.test.js +0 -54
  361. package/tests/unit/utils/check/bootstrapDeploymentOperation.test.js +0 -104
  362. package/tests/unit/utils/check/check.test.js +0 -17
  363. package/tests/unit/utils/check/common.test.js +0 -419
  364. package/tests/unit/utils/check/coreAdminOperation.test.js +0 -95
  365. package/tests/unit/utils/check/roleAccessOperation.test.js +0 -255
  366. package/tests/unit/utils/check/transactionOperation.test.js +0 -107
  367. package/tests/unit/utils/check/transferOperation.test.js +0 -102
  368. package/tests/unit/utils/deepEqualApplyPayload/deepEqualApplyPayload.test.js +0 -102
  369. package/tests/unit/utils/fileUtils/readAddressesFromWhitelistFile.test.js +0 -95
  370. package/tests/unit/utils/fileUtils/readBalanceMigrationFile.test.js +0 -149
  371. package/tests/unit/utils/helpers/helpers.test.js +0 -11
  372. package/tests/unit/utils/helpers/isHexString.test.js +0 -12
  373. package/tests/unit/utils/helpers/normalizeHex.test.js +0 -82
  374. package/tests/unit/utils/migrationUtils/validateAddressFromIncomingFile.test.js +0 -100
  375. package/tests/unit/utils/normalizers/normalizers.test.js +0 -469
  376. package/tests/unit/utils/protobuf/applyOperations.test.js +0 -91
  377. package/tests/unit/utils/protobuf/operationHelpers.test.js +0 -303
  378. package/tests/unit/utils/protobuf/protobuf.test.js +0 -12
  379. package/tests/unit/utils/type/type.test.js +0 -25
  380. package/tests/unit/utils/utils.test.js +0 -21
  381. 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,25 +1,38 @@
1
1
  {
2
2
  "name": "trac-msb",
3
3
  "main": "msb.mjs",
4
- "version": "0.2.18",
4
+ "version": "0.2.20",
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
33
  "test:unit:pear": "BRITTLE='-t 60000' brittle-pear tests/unit/unit.test.js",
22
- "test:unit:all": "(npm run test:unit:node && npm run test:unit:bare) || exit 1",
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",
23
36
  "test:unit:node:cov": "brittle-node -c -t 60000 tests/unit/unit.test.js"
24
37
  },
25
38
  "dependencies": {
@@ -43,8 +56,11 @@
43
56
  "hypercore-crypto": "3.6.1",
44
57
  "hyperdht": "6.27.0",
45
58
  "hyperswarm": "4.14.2",
46
- "lodash": "^4.17.23",
59
+ "hyperschema": "1.17.1",
60
+ "lodash": "^4.18.1",
47
61
  "p-queue": "^9.1.0",
62
+ "pear-runtime": "1.3.1",
63
+ "process": "npm:bare-process@4.2.2",
48
64
  "protobufjs": "^7.5.4",
49
65
  "protocol-buffers-encodings": "1.2.0",
50
66
  "protomux": "3.10.1",
@@ -52,7 +68,7 @@
52
68
  "readline": "npm:bare-node-readline",
53
69
  "ready-resource": "1.1.2",
54
70
  "trac-crypto-api": "0.1.5",
55
- "trac-wallet": "1.0.4",
71
+ "trac-wallet": "2.1.0",
56
72
  "tty": "npm:bare-node-tty",
57
73
  "uuid": "^13.0.0"
58
74
  },
@@ -61,6 +77,7 @@
61
77
  "bare-os": "^3.6.1",
62
78
  "bip39-mnemonic": "^2.4.0",
63
79
  "brittle": "^3.19.1",
80
+ "eslint": "^9.39.4",
64
81
  "esmock": "^2.7.2",
65
82
  "jest": "^30.1.3",
66
83
  "protobufjs-cli": "^1.2.0",
@@ -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
  ];
package/rpc/rpc_server.js CHANGED
@@ -1,8 +1,12 @@
1
1
  import { createServer } from "./create_server.js";
2
+ import { MainSettlementBus } from "../src/index.js";
2
3
 
3
4
  // Called by msb.mjs file
4
- export function startRpcServer(msbInstance, config) {
5
- const server = createServer(msbInstance, config)
5
+ export async function startRpcServer(config) {
6
+ console.log('Starting RPC server...');
7
+ const msb = new MainSettlementBus(config);
8
+ await msb.ready()
9
+ const server = createServer(msb, config)
6
10
 
7
11
  return server.listen(config.port, config.host, () => {
8
12
  console.log(`Running RPC with http at http://${config.host}:${config.port}`);