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
package/src/index.js CHANGED
@@ -1,12 +1,8 @@
1
- /** @typedef {import('pear-interface')} */ /* global Pear */
2
1
  import ReadyResource from "ready-resource";
3
2
  import Corestore from "corestore";
4
- import PeerWallet from "trac-wallet";
3
+ import tracCryptoApi from "trac-crypto-api";
5
4
  import b4a from "b4a";
6
- import readline from "readline";
7
- import tty from "tty";
8
5
  import { sleep, isHexString } from "./utils/helpers.js";
9
- import { verifyDag, printHelp, printWalletInfo, printBalance } from "./utils/cli.js";
10
6
  import { applyStateMessageFactory } from "./messages/state/applyStateMessageFactory.js";
11
7
  import { isAddressValid } from "./core/state/utils/address.js";
12
8
  import Network from "./core/network/Network.js";
@@ -18,65 +14,39 @@ import {
18
14
  BOOTSTRAP_HEXSTRING_LENGTH,
19
15
  CustomEventType,
20
16
  BALANCE_MIGRATION_SLEEP_INTERVAL,
21
- WHITELIST_MIGRATION_DIR
17
+ WHITELIST_MIGRATION_DIR,
18
+ OperationType
22
19
  } from "./utils/constants.js";
23
- import { randomBytes } from "hypercore-crypto";
24
20
  import { decimalStringToBigInt, bigIntTo16ByteBuffer, bufferToBigInt, bigIntToDecimalString } from "./utils/amountSerialization.js"
21
+ import {
22
+ normalizeDecodedPayloadForJson,
23
+ normalizeTransactionOperation,
24
+ normalizeTransferOperation
25
+ } from "./utils/normalizers.js";
25
26
  import fileUtils from './utils/fileUtils.js';
26
27
  import migrationUtils from './utils/migrationUtils.js';
27
- import {
28
- getBalanceCommand,
29
- getTxvCommand,
30
- getFeeCommand,
31
- getConfirmedLengthCommand,
32
- getUnconfirmedLengthCommand,
33
- getTxPayloadsBulkCommand,
34
- getTxHashesCommand,
35
- getTxDetailsCommand,
36
- getExtendedTxDetailsCommand,
37
- nodeStatusCommand,
38
- coreInfoCommand,
39
- getValidatorAddressCommand,
40
- getDeploymentCommand,
41
- getTxInfoCommand,
42
- getLicenseNumberCommand,
43
- getLicenseAddressCommand,
44
- getLicenseCountCommand
45
- } from "./utils/cliCommands.js";
46
- import {safeEncodeApplyOperation} from "./utils/protobuf/operationHelpers.js";
47
- import {Config} from "./config/config.js";
28
+ import {safeDecodeApplyOperation, safeEncodeApplyOperation} from "./utils/protobuf/operationHelpers.js";
29
+ import PartialTransactionValidator from "./core/network/protocols/shared/validators/PartialTransactionValidator.js";
30
+ import PartialTransferValidator from "./core/network/protocols/shared/validators/PartialTransferValidator.js";
31
+ import { BroadcastError, ValidationError } from "./utils/errors.js";
48
32
 
49
33
  export class MainSettlementBus extends ReadyResource {
50
34
  #store;
51
35
  #wallet;
52
36
  #network;
53
- #readline_instance;
54
37
  #state;
55
38
  #isClosing = false;
56
39
  #config
57
40
 
58
41
  /**
59
- * @param {Config} config
42
+ * @param {import("./config/config.js").Config} config
43
+ * @param {import("trac-wallet").Wallet | undefined} wallet
60
44
  **/
61
- constructor(config) {
45
+ constructor(config, wallet = undefined) {
62
46
  super();
63
47
  this.#config = config
48
+ this.#wallet = wallet;
64
49
  this.#store = new Corestore(this.#config.storesFullPath);
65
- this.#wallet = new PeerWallet({
66
- networkPrefix: this.#config.addressPrefix,
67
- derivationPath: this.#config.derivationPath
68
- });
69
- this.#readline_instance = null;
70
-
71
- if (this.#config.enableInteractiveMode) {
72
- try {
73
- this.#readline_instance = readline.createInterface({
74
- input: new tty.ReadStream(0),
75
- output: new tty.WriteStream(1),
76
- });
77
- } catch (_ignored) {}
78
- }
79
-
80
50
  this.check = new Check(this.#config);
81
51
  }
82
52
 
@@ -100,23 +70,15 @@ export class MainSettlementBus extends ReadyResource {
100
70
  }
101
71
 
102
72
  async _open() {
103
- await fileUtils.ensureCoresStoreDir(this.#config);
104
-
105
- if (this.#config.enableWallet) {
106
- await this.#wallet.initKeyPair(
107
- this.#config.keyPairPath,
108
- this.#readline_instance
109
- );
110
- }
111
73
  this.#state = new State(this.#store, this.#wallet, this.#config);
112
- this.#network = new Network(this.#state, this.#config, this.#wallet.address);
74
+ this.#network = new Network(this.#state, this.#config, this.#wallet?.address ?? null);
113
75
 
114
76
  await this.#state.ready();
115
77
  await this.#network.ready();
116
78
  await this.#stateEventsListener();
117
79
 
118
- if (this.#config.enableWallet) {
119
- printWalletInfo(this.#wallet.address, this.#state.writingKey, this.#state, this.#config.enableWallet);
80
+ if (this.#wallet) {
81
+ this.#printWalletInfo();
120
82
  }
121
83
 
122
84
  await this.#network.replicate(
@@ -135,7 +97,9 @@ export class MainSettlementBus extends ReadyResource {
135
97
  console.log("MSB Unsigned Length:", this.#state.getUnsignedLength());
136
98
  console.log("MSB Signed Length:", this.#state.getSignedLength());
137
99
 
138
- await printBalance(this.#wallet.address, this.#state, this.#config.enableWallet);
100
+ if (this.#wallet) {
101
+ await this.#printBalance();
102
+ }
139
103
  }
140
104
 
141
105
  async _close() {
@@ -150,26 +114,6 @@ export class MainSettlementBus extends ReadyResource {
150
114
 
151
115
  await sleep(100);
152
116
 
153
- if (this.#readline_instance) {
154
- const inputClosed = new Promise((resolve) =>
155
- this.#readline_instance.input.once("close", resolve)
156
- );
157
- const outputClosed = new Promise((resolve) =>
158
- this.#readline_instance.output.once("close", resolve)
159
- );
160
-
161
- this.#readline_instance.close();
162
- this.#readline_instance.input.destroy();
163
- this.#readline_instance.output.destroy();
164
-
165
- // Do not remove this. Without it, readline may close too quickly and still hang.
166
- await Promise.all([inputClosed, outputClosed]).catch((e) =>
167
- console.log("Error during closing readline stream:", e)
168
- );
169
- }
170
-
171
- await sleep(100);
172
-
173
117
  if (this.#store !== null) {
174
118
  await this.#store.close();
175
119
  }
@@ -177,42 +121,98 @@ export class MainSettlementBus extends ReadyResource {
177
121
  await sleep(100);
178
122
  }
179
123
 
124
+ async destroy() {
125
+ return await this.close();
126
+ }
127
+
180
128
  async broadcastPartialTransaction(partialTransactionPayload) {
181
129
  return await this.#network.validatorMessageOrchestrator.send(partialTransactionPayload);
182
130
  }
183
131
 
132
+ async validateTransfer(payload) {
133
+ const partialTransferValidator = new PartialTransferValidator(this.#state, null, this.#config);
134
+ return await partialTransferValidator.validate(payload);
135
+ }
136
+
137
+ // Used by peer simulation
138
+ async validateTransaction(payload) {
139
+ const partialTransactionValidator = new PartialTransactionValidator(this.#state, null, this.#config);
140
+ return await partialTransactionValidator.validate(payload);
141
+ }
142
+
143
+ async broadcastTransaction(payload) {
144
+ if (!payload) {
145
+ throw new ValidationError("Transaction payload is required for broadcasting.");
146
+ }
147
+
148
+ let normalizedPayload;
149
+ let hash;
150
+
151
+ if (payload.type === OperationType.TRANSFER) {
152
+ normalizedPayload = normalizeTransferOperation(payload, this.#config);
153
+ await this.validateTransfer(normalizedPayload);
154
+ hash = b4a.toString(normalizedPayload.tro.tx, "hex");
155
+ } else if (payload.type === OperationType.TX) {
156
+ normalizedPayload = normalizeTransactionOperation(payload, this.#config);
157
+ try {
158
+ await this.validateTransaction(normalizedPayload);
159
+ } catch {
160
+ // We swap exceptions to keep compatibility
161
+ throw new ValidationError("Invalid transaction payload.");
162
+ }
163
+ hash = b4a.toString(normalizedPayload.txo.tx, "hex");
164
+ }
165
+
166
+ const success = await this.broadcastPartialTransaction(payload);
167
+ if (!success) {
168
+ throw new BroadcastError("Failed to broadcast transaction after multiple attempts.");
169
+ }
170
+
171
+ const isConfirmed = await this.#state.waitForUnsigned(
172
+ hash,
173
+ this.#config.messageValidatorResponseTimeout,
174
+ 100
175
+ );
176
+ if (!isConfirmed) {
177
+ throw new BroadcastError("Failed to broadcast transaction after multiple attempts.");
178
+ }
179
+
180
+ return {
181
+ signedLength: this.#state.getSignedLength(),
182
+ unsignedLength: this.#state.getUnsignedLength(),
183
+ tx: hash
184
+ };
185
+ }
186
+
184
187
  async #setUpRoleAutomatically() {
185
188
  if (!this.#state.isWritable() && this.#config.enableRoleRequester) {
186
- console.log("Requesting writer role... This may take a moment.");
187
- await this.#requestWriterRole(false);
188
189
  setTimeout(async () => {
189
- await this.#requestWriterRole(true);
190
+ await this.requestWriterRole(true);
190
191
  }, 5_000);
191
192
  await sleep(5_000);
192
193
  }
193
194
  }
194
195
 
195
- #isAdmin(adminEntry) {
196
+ isAdmin(adminEntry) {
196
197
  if (!adminEntry || !this.#config.enableWallet) return false;
197
198
  return this.#wallet.address === adminEntry.address && b4a.equals(adminEntry.wk, this.#state.writingKey)
198
199
  }
199
200
 
200
201
  async #isAllowedToRequestRole(adminEntry, nodeEntry) {
201
- return nodeEntry?.isWhitelisted && !this.#isAdmin(adminEntry);
202
+ return nodeEntry?.isWhitelisted && !this.isAdmin(adminEntry);
202
203
  }
203
204
 
204
205
  async #stateEventsListener() {
205
206
  this.#state.on(CustomEventType.IS_INDEXER, (publicKey) => {
206
- if (this.#network.validatorConnectionManager.exists(publicKey)) {
207
- this.#network.validatorConnectionManager.remove(publicKey)
208
- }
209
- })
207
+ if (this.#isClosing) return;
208
+ this.#network.disconnectValidatorPeer(publicKey, 'peer promoted to indexer');
209
+ });
210
210
 
211
211
  this.#state.on(CustomEventType.UNWRITABLE, (publicKey) => {
212
- if (this.#network.validatorConnectionManager.exists(publicKey)) {
213
- this.#network.validatorConnectionManager.remove(publicKey)
214
- }
215
- })
212
+ if (this.#isClosing) return;
213
+ this.#network.disconnectValidatorPeer(publicKey, 'peer became unwritable');
214
+ });
215
+
216
216
  this.#state.base.on(EventType.IS_INDEXER, () => {
217
217
  console.log("Current node is an indexer");
218
218
  });
@@ -233,7 +233,195 @@ export class MainSettlementBus extends ReadyResource {
233
233
  });
234
234
  }
235
235
 
236
- async #handleAdminCreation() {
236
+ async getConfirmedTxInfo(txHash) {
237
+ const payload = await this.#state.getSigned(txHash);
238
+ if (!payload) return null
239
+
240
+ const decoded = safeDecodeApplyOperation(payload);
241
+ if (!decoded) {
242
+ throw new Error(`Failed to decode payload for transaction hash: ${txHash}`);
243
+ }
244
+
245
+ return { payload, decoded }
246
+ }
247
+
248
+ async getUnconfirmedTxInfo(txHash) {
249
+ const payload = await this.#state.get(txHash);
250
+ if (!payload) return null
251
+
252
+ const decoded = safeDecodeApplyOperation(payload);
253
+ if (!decoded) {
254
+ throw new Error(`Failed to decode payload for transaction hash: ${txHash}`);
255
+ }
256
+
257
+ return { payload, decoded }
258
+ }
259
+
260
+ handleGetFee() {
261
+ const fee = this.#state.getFee();
262
+ return bufferToBigInt(fee);
263
+ }
264
+
265
+ async getBalance(address, confirmed = true) {
266
+ const nodeEntry = confirmed
267
+ ? await this.#state.getNodeEntry(address)
268
+ : await this.#state.getNodeEntryUnsigned(address);
269
+
270
+ if (!nodeEntry) {
271
+ return undefined;
272
+ }
273
+
274
+ return {
275
+ address,
276
+ balance: bufferToBigInt(nodeEntry.balance).toString(),
277
+ };
278
+ }
279
+
280
+ async getTxv() {
281
+ const txv = await this.#state.getIndexerSequenceState();
282
+ return txv.toString("hex");
283
+ }
284
+
285
+ getConfirmedLength() {
286
+ return this.#state.getSignedLength();
287
+ }
288
+
289
+ getUnconfirmedLength() {
290
+ return this.#state.getUnsignedLength();
291
+ }
292
+
293
+ async verifyDag() {
294
+ try {
295
+ let dagView = await this.#state.base.view.core.treeHash();
296
+ let lengthdagView = this.#state.base.view.core.length;
297
+ let dagSystem = await this.#state.base.system.core.treeHash();
298
+ let lengthdagSystem = this.#state.base.system.core.length;
299
+ const wl = await this.#state.getWriterLength();
300
+
301
+ console.log("---------- node & network stats ----------");
302
+ console.log("wallet.publicKey:", this.#wallet?.publicKey?.toString("hex") ?? "unset");
303
+ console.log("wallet.address:", this.#wallet?.address ?? "unset");
304
+ console.log("msb.writerKey:", this.#state?.writingKey ? this.#state.writingKey.toString("hex") : "unset");
305
+ console.log("swarm.connections.size:", this.#network?.swarm?.connections?.size || 0);
306
+ console.log("base.view.core.signedLength:", this.#state.base.view.core.signedLength ?? "unset");
307
+ console.log("base.view.core.length:", this.#state.base.view.core.length ?? "unset");
308
+ console.log("base.signedLength", this.#state.base.signedLength ?? "unset");
309
+ console.log("base.indexedLength", this.#state.base.indexedLength ?? "unset");
310
+ console.log("base.linearizer.indexers.length", this.#state.base.linearizer?.indexers?.length ?? "unset");
311
+ console.log(`base.key: ${this.#state.base.key ? this.#state.base.key.toString("hex") : "unset"}`);
312
+ console.log("discoveryKey:", this.#state.base.discoveryKey ? b4a.toString(this.#state.base.discoveryKey, "hex") : "unset");
313
+ console.log(`VIEW Dag: ${dagView ? dagView.toString("hex") : "unset"} (length: ${lengthdagView || 0})`);
314
+ console.log(`SYSTEM Dag: ${dagSystem ? dagSystem.toString("hex") : "unset"} (length: ${lengthdagSystem || 0})`);
315
+ console.log("Total Registered Writers:", wl !== null ? wl : 0);
316
+ console.log("---------- flags ----------");
317
+ console.log(`isIndexer: ${this.#state?.isIndexer?.() ?? "unset"}`);
318
+ console.log(`isWriter: ${this.#state?.isWritable?.() ?? "unset"}`);
319
+ } catch (error) {
320
+ console.error("Error during DAG monitoring:", error.message);
321
+ }
322
+ }
323
+
324
+ printHelp() {
325
+ if (this.#config.isAdminMode) {
326
+ console.log("🚨 WARNING: IF YOU ARE NOT AN ADMIN, DO NOT USE THE COMMANDS BELOW! YOU RISK LOSING YOUR FUNDS! 🚨");
327
+ console.log("\nAdmin commands:");
328
+ console.log("- /add_admin: Register admin entry with bootstrap key (initial setup), or use --recovery flag to recover admin role");
329
+ console.log("- /balance_migration: Perform balance migration with the given initial balances CSV file");
330
+ console.log("- /add_whitelist: Add all specified whitelist addresses. If initialization is enabled, no fee is required.");
331
+ console.log("- /disable_initialization: Disable further balance initializations and whitelisting");
332
+ console.log("- /add_indexer <address>: Change a role of the selected writer node to indexer role. Charges a fee.");
333
+ console.log("- /remove_indexer <address>: Change a role of the selected indexer node to default role. Charges a fee.");
334
+ console.log("- /ban_writer <address>: Demote a whitelisted writer to default role and remove it from the whitelist. Charges a fee.");
335
+ }
336
+ console.log("Available commands:");
337
+ console.log("- /add_writer: Add yourself as a validator to this MSB once whitelisted. Requires a fee + 10x the fee as a stake in $TNK.");
338
+ console.log("- /remove_writer: Remove yourself from this MSB. Requires a fee, and the stake will be refunded.");
339
+ console.log("- /node_status <address>: Get network information about a node with the given address.");
340
+ console.log("- /stats: Check system stats such as writing key, DAG, etc.");
341
+ console.log("- /deployment <subnetwork_bootstrap> <channel>: Deploy a subnetwork with the given bootstrap. If channel is not provided, a random one will be generated. Requires a fee.");
342
+ console.log("- /get_deployment <subnetwork_bootstrap>: Get information about a subnetwork deployment with the given bootstrap.");
343
+ console.log("- /transfer <to_address> <amount>: Transfer the specified amount to the given address. Requires a fee.");
344
+ console.log("- /get_tx_info <tx_hash>: Get information about a transaction with the given hash.");
345
+ console.log("- /get_validator_addr <writing_key>: Get the validator address mapped to the given writing key.");
346
+ console.log("- /get_balance <address> <confirmed>: Get the balance of the node with specified address (confirmed = true is default)");
347
+ console.log("- /exit: Exit the program.");
348
+ console.log("- /help: Display this help.");
349
+ }
350
+
351
+ #printWalletInfo() {
352
+ console.log("");
353
+ console.log("#####################################################################################");
354
+ console.log("# MSB Address: ", this.#wallet.address, " #");
355
+ console.log("# MSB Writer: ", this.#state.writingKey.toString("hex"), "#");
356
+ console.log("#####################################################################################");
357
+ }
358
+
359
+ async #printBalance() {
360
+ const nodeEntry = await this.#state.getNodeEntry(this.#wallet.address);
361
+ const balance = nodeEntry ? bigIntToDecimalString(bufferToBigInt(nodeEntry.balance)) : "0";
362
+ console.log(`Balance: ${balance}`);
363
+ }
364
+
365
+ async getTxHashes(start, end) {
366
+ const hashes = await this.#state.confirmedTransactionsBetween(start, end);
367
+ return { hashes };
368
+ }
369
+
370
+ async getTxDetails(hash) {
371
+ const rawPayload = await this.getConfirmedTxInfo(hash);
372
+ if (!rawPayload) {
373
+ return null;
374
+ }
375
+
376
+ return normalizeDecodedPayloadForJson(rawPayload.decoded, this.#config);
377
+ }
378
+
379
+ async fetchBulkTxPayloads(hashes) {
380
+ const response = { results: [], missing: [] };
381
+ const results = await Promise.all(hashes.map((hash) => this.getConfirmedTxInfo(hash)));
382
+
383
+ results.forEach((result, index) => {
384
+ const hash = hashes[index];
385
+ if (!result) {
386
+ response.missing.push(hash);
387
+ return;
388
+ }
389
+
390
+ const decodedResult = normalizeDecodedPayloadForJson(result.decoded, this.#config);
391
+ response.results.push({ hash, payload: decodedResult });
392
+ });
393
+
394
+ return response;
395
+ }
396
+
397
+ async getExtendedTxDetails(hash, confirmed) {
398
+ const rawPayload = confirmed
399
+ ? await this.getConfirmedTxInfo(hash)
400
+ : await this.getUnconfirmedTxInfo(hash);
401
+
402
+ if (!rawPayload) {
403
+ return null;
404
+ }
405
+
406
+ const txDetails = normalizeDecodedPayloadForJson(rawPayload.decoded, this.#config);
407
+ const confirmedLength = await this.#state.getTransactionConfirmedLength(hash);
408
+
409
+ if (confirmedLength === null) {
410
+ return {
411
+ txDetails,
412
+ confirmed_length: 0,
413
+ fee: "0",
414
+ };
415
+ }
416
+
417
+ return {
418
+ txDetails,
419
+ confirmed_length: confirmedLength,
420
+ fee: this.handleGetFee().toString(),
421
+ };
422
+ }
423
+
424
+ async handleAdminCreation() {
237
425
  if (!this.#config.enableWallet) {
238
426
  throw new Error("Can not initialize an admin - wallet is not enabled.");
239
427
  }
@@ -259,7 +447,7 @@ export class MainSettlementBus extends ReadyResource {
259
447
  );
260
448
  }
261
449
 
262
- const txValidity = await PeerWallet.blake3(this.#config.bootstrap);
450
+ const txValidity = await tracCryptoApi.hash.blake3(this.#config.bootstrap);
263
451
  const addAdminMessage = await applyStateMessageFactory(this.#wallet, this.#config)
264
452
  .buildCompleteAddAdminMessage(
265
453
  this.#wallet.address,
@@ -271,7 +459,7 @@ export class MainSettlementBus extends ReadyResource {
271
459
  await this.#state.append(encodedPayload);
272
460
  }
273
461
 
274
- async #handleAdminRecovery() {
462
+ async handleAdminRecovery() {
275
463
  if (!this.#config.enableWallet) {
276
464
  throw new Error("Can not initialize an admin - wallet is not enabled.");
277
465
  }
@@ -313,14 +501,14 @@ export class MainSettlementBus extends ReadyResource {
313
501
  console.info(`Transaction hash: ${adminRecoveryMessage.rao.tx}`);
314
502
  }
315
503
 
316
- async #handleWhitelistOperations() {
504
+ async handleWhitelistOperations() {
317
505
  if (!this.#config.enableWallet) {
318
506
  throw new Error("Cannot perform whitelisting - wallet is not enabled.");
319
507
  }
320
508
 
321
509
  const adminEntry = await this.#state.getAdminEntry();
322
510
 
323
- if (!this.#isAdmin(adminEntry)) {
511
+ if (!this.isAdmin(adminEntry)) {
324
512
  throw new Error('Cannot perform whitelisting - you are not the admin!.');
325
513
  }
326
514
 
@@ -375,7 +563,7 @@ export class MainSettlementBus extends ReadyResource {
375
563
  }
376
564
  }
377
565
 
378
- async #requestWriterRole(toAdd) {
566
+ async requestWriterRole(toAdd) {
379
567
  if (!this.#config.enableWallet) {
380
568
  throw new Error("Cannot request writer role - wallet is not enabled");
381
569
  }
@@ -468,7 +656,7 @@ export class MainSettlementBus extends ReadyResource {
468
656
  console.info(`Transaction hash: ${assembledMessage.rao.tx}`);
469
657
  }
470
658
 
471
- async #updateWriterToIndexerRole(addressToUpdate, toAdd) {
659
+ async updateWriterToIndexerRole(addressToUpdate, toAdd) {
472
660
  if (!this.#config.enableWallet) {
473
661
  throw new Error(
474
662
  `Can not request indexer role for: ${addressToUpdate} - wallet is not enabled.`
@@ -489,7 +677,7 @@ export class MainSettlementBus extends ReadyResource {
489
677
  );
490
678
  }
491
679
 
492
- if (!this.#isAdmin(adminEntry) && !this.#state.isWritable()) {
680
+ if (!this.isAdmin(adminEntry) && !this.#state.isWritable()) {
493
681
  throw new Error(
494
682
  `Can not request indexer role for: ${addressToUpdate} - You are not an admin or writer.`
495
683
  );
@@ -558,7 +746,7 @@ export class MainSettlementBus extends ReadyResource {
558
746
  }
559
747
  }
560
748
 
561
- async #banValidator(addresstToBan) {
749
+ async banValidator(addresstToBan) {
562
750
  if (!this.#config.enableWallet) {
563
751
  throw new Error(
564
752
  `Can not ban writer with address: ${addresstToBan} - wallet is not enabled.`
@@ -578,7 +766,7 @@ export class MainSettlementBus extends ReadyResource {
578
766
  );
579
767
  }
580
768
 
581
- if (!this.#isAdmin(adminEntry)) {
769
+ if (!this.isAdmin(adminEntry)) {
582
770
  throw new Error(
583
771
  `Can not ban writer with address: ${addresstToBan} - You are not an admin.`
584
772
  );
@@ -603,7 +791,7 @@ export class MainSettlementBus extends ReadyResource {
603
791
  await this.#state.append(encodedPayload);
604
792
  }
605
793
 
606
- async #deployBootstrap(externalBootstrap, channel) {
794
+ async deployBootstrap(externalBootstrap, channel) {
607
795
  if (!this.#config.enableWallet) {
608
796
  throw new Error(
609
797
  "Can not perform bootstrap deployment - wallet is not enabled."
@@ -697,7 +885,7 @@ export class MainSettlementBus extends ReadyResource {
697
885
 
698
886
  }
699
887
 
700
- async #handleTransferOperation(recipientAddress, amount) {
888
+ async prepareTransferOperation(recipientAddress, amount) {
701
889
  if (!this.#config.enableWallet) {
702
890
  throw new Error(
703
891
  "Can not perform transfer - wallet is not enabled."
@@ -745,37 +933,37 @@ export class MainSettlementBus extends ReadyResource {
745
933
  const txValidity = await this.#state.getIndexerSequenceState();
746
934
  const payload = await applyStateMessageFactory(this.#wallet, this.#config)
747
935
  .buildPartialTransferOperationMessage(
748
- this.#wallet.address,
749
- recipientAddress,
750
- amountBuffer,
751
- txValidity,
752
- "json"
753
- )
936
+ this.#wallet.address,
937
+ recipientAddress,
938
+ amountBuffer,
939
+ txValidity,
940
+ "json"
941
+ )
754
942
 
755
943
  const expectedNewBalance = senderBalance - totalDeductedAmount;
756
- console.info('Transfer Details:');
757
- console.info(`Transaction hash ${payload.tro.tx}`)
758
- if (isSelfTransfer) {
759
- console.info('Self transfer - only fee will be deducted');
760
- console.info(`Fee: ${bigIntToDecimalString(feeBigInt)}`);
761
- console.info(`Total amount to send: ${bigIntToDecimalString(totalDeductedAmount)}`);
762
- } else {
763
- console.info(`Amount: ${bigIntToDecimalString(amountBigInt)}`);
764
- console.info(`Fee: ${bigIntToDecimalString(feeBigInt)}`);
765
- console.info(`Total: ${bigIntToDecimalString(totalDeductedAmount)}`);
766
- }
767
- console.log(`Expected Balance After Transfer: ${bigIntToDecimalString(expectedNewBalance)}`);
768
- const success = await this.broadcastPartialTransaction(payload);
944
+ return {
945
+ payload,
946
+ amountBigInt,
947
+ feeBigInt,
948
+ senderBalance,
949
+ totalDeductedAmount,
950
+ expectedNewBalance,
951
+ isSelfTransfer
952
+ };
953
+ }
954
+
955
+ async submitPreparedTransferOperation(preparedTransfer) {
956
+ const success = await this.broadcastPartialTransaction(preparedTransfer.payload);
769
957
  if (!success) {
770
958
  throw new Error("Failed to broadcast transfer transaction after multiple attempts.");
771
959
  } else {
772
- console.log(`Transfer transaction broadcasted successfully. Tx hash: ${payload.tro.tx}`);
960
+ console.log(`Transfer transaction broadcasted successfully. Tx hash: ${preparedTransfer.payload.tro.tx}`);
773
961
  }
774
962
 
963
+ return preparedTransfer.payload.tro.tx;
775
964
  }
776
965
 
777
- async #balanceMigrationOperation() {
778
-
966
+ async balanceMigrationOperation() {
779
967
  const isInitDisabled = await this.#state.isInitalizationDisabled()
780
968
 
781
969
  if (isInitDisabled) {
@@ -792,7 +980,7 @@ export class MainSettlementBus extends ReadyResource {
792
980
  throw new Error("Can not initialize an admin - admin does not exist.");
793
981
  }
794
982
 
795
- if (!this.#isAdmin(adminEntry)) {
983
+ if (!this.isAdmin(adminEntry)) {
796
984
  throw new Error('Cannot perform balance migration - you are not the admin!.');
797
985
  }
798
986
 
@@ -876,7 +1064,7 @@ export class MainSettlementBus extends ReadyResource {
876
1064
  console.log(`${bigIntToDecimalString(totalBalance)} $TNK have been migrated across ${totalAddresses} addresses.`);
877
1065
  }
878
1066
 
879
- async #disableInitialization() {
1067
+ async disableInitialization() {
880
1068
  if (!this.#config.enableWallet) {
881
1069
  throw new Error("Can not initialize an admin - wallet is not enabled.");
882
1070
  }
@@ -890,7 +1078,7 @@ export class MainSettlementBus extends ReadyResource {
890
1078
  throw new Error("Can not initialize an admin - admin does not exist.");
891
1079
  }
892
1080
 
893
- if (!this.#isAdmin(adminEntry)) {
1081
+ if (!this.isAdmin(adminEntry)) {
894
1082
  throw new Error('Cannot perform whitelisting - you are not the admin!.');
895
1083
  }
896
1084
  if (!this.#wallet) {
@@ -912,153 +1100,6 @@ export class MainSettlementBus extends ReadyResource {
912
1100
  const encodedPayload = safeEncodeApplyOperation(payload);
913
1101
  await this.#state.append(encodedPayload);
914
1102
  }
915
-
916
- async interactiveMode() {
917
- if (this.#readline_instance === null) return;
918
- const rl = this.#readline_instance;
919
-
920
- printHelp(this.#config.isAdminMode);
921
-
922
- rl.on("line", async (input) => {
923
- try {
924
- await this.handleCommand(input.trim(), rl);
925
- } catch (err) {
926
- console.error(`${err}`);
927
- }
928
- rl.prompt();
929
- });
930
-
931
- rl.prompt();
932
- }
933
-
934
- async handleCommand(input, rl = null, payload = null) {
935
- const [command, ...parts] = input.split(" ");
936
- const exactHandlers = {
937
- "/help": async () => {
938
- printHelp(this.#config.isAdminMode);
939
- },
940
- "/exit": async () => {
941
- if (rl) rl.close();
942
- await this.close();
943
- },
944
- "/add_admin": async () => await this.#handleAdminCreation(),
945
- "/add_admin --recovery": async () => await this.#handleAdminRecovery(),
946
- "/add_whitelist": async () => await this.#handleWhitelistOperations(),
947
- "/add_writer": async () => await this.#requestWriterRole(true),
948
- "/remove_writer": async () => await this.#requestWriterRole(false),
949
- "/core": async () => await coreInfoCommand(this.#state),
950
- "/indexers_list": async () => console.log(await this.#state.getIndexersEntry()),
951
- "/validator_pool": () => this.#network.validatorConnectionManager.prettyPrint(),
952
- "/stats": async () => await verifyDag(
953
- this.#state,
954
- this.#network,
955
- this.#wallet,
956
- this.#state.writingKey
957
- ),
958
- "/balance_migration": async () => await this.#balanceMigrationOperation(),
959
- "/disable_initialization": async () => await this.#disableInitialization()
960
- };
961
-
962
- if (exactHandlers[command]) {
963
- const result = await exactHandlers[command]();
964
- if (rl) rl.prompt();
965
- return result;
966
- }
967
-
968
- if (input.startsWith("/node_status")) {
969
- const address = parts[0];
970
- const result = await nodeStatusCommand(this.#state, address);
971
- if (rl) rl.prompt();
972
- return result;
973
- }
974
-
975
- if (input.startsWith("/add_indexer")) {
976
- const address = parts[0];
977
- await this.#updateWriterToIndexerRole(address, true);
978
- } else if (input.startsWith("/remove_indexer")) {
979
- const address = parts[0];
980
- await this.#updateWriterToIndexerRole(address, false);
981
- } else if (input.startsWith("/ban_writer")) {
982
- const address = parts[0];
983
- await this.#banValidator(address);
984
- } else if (input.startsWith("/deployment")) {
985
- const bootstrapToDeploy = parts[0];
986
- const channel = parts[1] || randomBytes(32).toString("hex");
987
- if (channel.length !== 64 || !isHexString(channel)) {
988
- throw new Error("Channel must be a 32-byte hex string");
989
- }
990
- await this.#deployBootstrap(bootstrapToDeploy, channel);
991
- } else if (input.startsWith("/get_validator_addr")) {
992
- const wkHexString = parts[0];
993
- await getValidatorAddressCommand(this.#state, wkHexString, this.#config.addressPrefix);
994
- } else if (input.startsWith("/get_deployment")) {
995
- const bootstrapHex = parts[0];
996
- await getDeploymentCommand(this.#state, bootstrapHex, this.#config.addressLength);
997
- } else if (input.startsWith("/get_tx_info")) {
998
- const txHash = parts[0];
999
- await getTxInfoCommand(this.#state, txHash);
1000
- } else if (input.startsWith("/transfer")) {
1001
- const address = parts[0];
1002
- const amount = parts[1];
1003
- await this.#handleTransferOperation(address, amount);
1004
- } else if (input.startsWith("/get_balance")) {
1005
- const address = parts[0];
1006
- const confirmedFlag = parts[1];
1007
- const result = await getBalanceCommand(this.#state, address, confirmedFlag);
1008
- if (rl) rl.prompt();
1009
- return result;
1010
- } else if (input.startsWith("/get_license_number")) {
1011
- const address = parts[0];
1012
- await getLicenseNumberCommand(this.#state, address);
1013
- } else if (input.startsWith("/get_license_address")) {
1014
- const licenseId = parseInt(parts[0]);
1015
- await getLicenseAddressCommand(this.#state, licenseId);
1016
- } else if (input.startsWith("/get_license_count")) {
1017
- await getLicenseCountCommand(this.#state, this.#isAdmin.bind(this));
1018
- } else if (input.startsWith("/get_txv")) {
1019
- const result = await getTxvCommand(this.#state);
1020
- if (rl) rl.prompt();
1021
- return result;
1022
- } else if (input.startsWith("/get_fee")) {
1023
- const result = getFeeCommand(this.#state);
1024
- if (rl) rl.prompt();
1025
- return result;
1026
- } else if (input.startsWith("/confirmed_length")) {
1027
- const result = getConfirmedLengthCommand(this.#state);
1028
- if (rl) rl.prompt();
1029
- return result;
1030
- } else if (input.startsWith("/unconfirmed_length")) {
1031
- const result = getUnconfirmedLengthCommand(this.#state);
1032
- if (rl) rl.prompt();
1033
- return result;
1034
- } else if (input.startsWith("/get_tx_payloads_bulk")) {
1035
- if (!payload) {
1036
- throw new Error("Missing payload for fetching tx payloads.");
1037
- }
1038
- const result = await getTxPayloadsBulkCommand(this.#state, payload, this.#config);
1039
- if (rl) rl.prompt();
1040
- return result;
1041
- } else if (input.startsWith("/get_txs_hashes")) {
1042
- const start = parseInt(parts[0]);
1043
- const end = parseInt(parts[1]);
1044
- const result = await getTxHashesCommand(this.#state, start, end);
1045
- if (rl) rl.prompt();
1046
- return result;
1047
- } else if (input.startsWith("/get_tx_details")) {
1048
- const hash = parts[0];
1049
- const result = await getTxDetailsCommand(this.#state, hash, this.#config);
1050
- if (rl) rl.prompt();
1051
- return result;
1052
- } else if (input.startsWith("/get_extended_tx_details")) {
1053
- const hash = parts[0];
1054
- const confirmed = parts[1] === "true";
1055
- const result = await getExtendedTxDetailsCommand(this.#state, hash, confirmed, this.#config);
1056
- if (rl) rl.prompt();
1057
- return result;
1058
- }
1059
-
1060
- if (rl) rl.prompt();
1061
- }
1062
1103
  }
1063
1104
 
1064
1105
  export default MainSettlementBus;