trac-msb 0.2.4 → 0.2.6

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 (239) hide show
  1. package/.dockerignore +16 -0
  2. package/.github/workflows/acceptance-tests.yml +7 -0
  3. package/.github/workflows/publish.yml +40 -0
  4. package/.github/workflows/{CI.yml → unit-tests.yml} +1 -1
  5. package/README.md +175 -50
  6. package/docker-compose.yml +16 -0
  7. package/dockerfile +41 -0
  8. package/docs/fee_distribution.md +89 -0
  9. package/msb.mjs +12 -14
  10. package/package.json +8 -4
  11. package/rpc/constants.mjs +4 -1
  12. package/rpc/handlers.mjs +109 -66
  13. package/rpc/routes/v1.mjs +3 -1
  14. package/rpc/rpc_services.js +126 -0
  15. package/rpc/utils/confirmedParameter.mjs +17 -0
  16. package/rpc/utils/url.mjs +38 -0
  17. package/src/core/network/Network.js +27 -10
  18. package/src/core/network/identity/NetworkWalletFactory.js +78 -0
  19. package/src/core/network/services/ConnectionManager.js +2 -2
  20. package/src/core/network/services/ValidatorObserverService.js +7 -4
  21. package/src/core/state/State.js +28 -22
  22. package/src/index.js +197 -385
  23. package/src/utils/cliCommands.js +280 -0
  24. package/src/utils/constants.js +3 -1
  25. package/tests/acceptance/v1/account/account.test.mjs +123 -0
  26. package/tests/acceptance/v1/balance/balance.test.mjs +55 -0
  27. package/tests/acceptance/v1/broadcast-transaction/broadcast-transaction.test.mjs +111 -0
  28. package/tests/acceptance/v1/confirmed-length/confirmed-length.test.mjs +19 -0
  29. package/tests/acceptance/v1/fee/fee.test.mjs +11 -0
  30. package/tests/acceptance/v1/rpc.test.mjs +62 -291
  31. package/tests/acceptance/v1/tx/tx.test.mjs +98 -0
  32. package/tests/acceptance/v1/tx-details/tx-details.test.mjs +195 -0
  33. package/tests/acceptance/v1/tx-hashes/tx-hashes.test.mjs +72 -0
  34. package/tests/acceptance/v1/tx-payloads-bulk/tx-payloads-bulk.test.mjs +27 -0
  35. package/tests/acceptance/v1/txv/txv.test.mjs +11 -0
  36. package/tests/acceptance/v1/unconfirmed-length/unconfirmed-length.test.mjs +11 -0
  37. package/tests/helpers/StateNetworkFactory.js +157 -0
  38. package/tests/helpers/autobaseTestHelpers.js +369 -0
  39. package/tests/helpers/createTestSignature.js +12 -0
  40. package/tests/helpers/transactionPayloads.mjs +78 -0
  41. package/tests/unit/network/NetworkWalletFactory.test.js +156 -0
  42. package/tests/unit/state/apply/addAdmin/addAdminHappyPathScenario.js +38 -0
  43. package/tests/unit/state/apply/addAdmin/addAdminScenarioHelpers.js +273 -0
  44. package/tests/unit/state/apply/addAdmin/adminEntryEncodingFailureScenario.js +30 -0
  45. package/tests/unit/state/apply/addAdmin/adminEntryExistsScenario.js +78 -0
  46. package/tests/unit/state/apply/addAdmin/nodeEntryInitializationFailureScenario.js +30 -0
  47. package/tests/unit/state/apply/addAdmin/nonBootstrapNodeScenario.js +68 -0
  48. package/tests/unit/state/apply/addAdmin/state.apply.addAdmin.test.js +155 -0
  49. package/tests/unit/state/apply/addIndexer/addIndexerHappyPathScenario.js +39 -0
  50. package/tests/unit/state/apply/addIndexer/addIndexerMultipleIndexersInTheNetworkScenario.js +167 -0
  51. package/tests/unit/state/apply/addIndexer/addIndexerPretenderAlreadyIndexerScenario.js +21 -0
  52. package/tests/unit/state/apply/addIndexer/addIndexerPretenderNotWriterScenario.js +21 -0
  53. package/tests/unit/state/apply/addIndexer/addIndexerRemoveAndReAddScenario.js +186 -0
  54. package/tests/unit/state/apply/addIndexer/addIndexerScenarioHelpers.js +445 -0
  55. package/tests/unit/state/apply/addIndexer/addIndexerWriterKeyAlreadyRegisteredScenario.js +32 -0
  56. package/tests/unit/state/apply/addIndexer/state.apply.addIndexer.test.js +297 -0
  57. package/tests/unit/state/apply/addWriter/addWriterHappyPathScenario.js +41 -0
  58. package/tests/unit/state/apply/addWriter/addWriterInvalidValidatorSignatureScenario.js +32 -0
  59. package/tests/unit/state/apply/addWriter/addWriterNewWkScenario.js +149 -0
  60. package/tests/unit/state/apply/addWriter/addWriterRequesterAlreadyWriterScenario.js +21 -0
  61. package/tests/unit/state/apply/addWriter/addWriterRequesterBalanceInsufficientScenario.js +21 -0
  62. package/tests/unit/state/apply/addWriter/addWriterRequesterEntryDecodeFailureScenario.js +19 -0
  63. package/tests/unit/state/apply/addWriter/addWriterRequesterEntryMissingScenario.js +19 -0
  64. package/tests/unit/state/apply/addWriter/addWriterRequesterIndexerScenario.js +21 -0
  65. package/tests/unit/state/apply/addWriter/addWriterRequesterNotWhitelistedScenario.js +21 -0
  66. package/tests/unit/state/apply/addWriter/addWriterScenarioHelpers.js +757 -0
  67. package/tests/unit/state/apply/addWriter/addWriterStakeBalanceUpdateFailureScenario.js +50 -0
  68. package/tests/unit/state/apply/addWriter/addWriterStakeInsufficientBalanceScenario.js +29 -0
  69. package/tests/unit/state/apply/addWriter/addWriterStakeInvalidBalanceScenario.js +29 -0
  70. package/tests/unit/state/apply/addWriter/addWriterStakeInvalidEntryScenario.js +21 -0
  71. package/tests/unit/state/apply/addWriter/addWriterStakeStakedBalanceFailureScenario.js +37 -0
  72. package/tests/unit/state/apply/addWriter/addWriterStakeSubtractFailureScenario.js +42 -0
  73. package/tests/unit/state/apply/addWriter/addWriterValidatorRewardScenario.js +105 -0
  74. package/tests/unit/state/apply/addWriter/addWriterWriterKeyMismatchScenario.js +54 -0
  75. package/tests/unit/state/apply/addWriter/addWriterWriterKeyOwnershipScenario.js +54 -0
  76. package/tests/unit/state/apply/addWriter/addWriterZeroWriterKeyScenario.js +29 -0
  77. package/tests/unit/state/apply/addWriter/state.apply.addWriter.test.js +309 -0
  78. package/tests/unit/state/apply/adminRecovery/adminRecoveryHappyPathScenario.js +30 -0
  79. package/tests/unit/state/apply/adminRecovery/adminRecoveryScenarioHelpers.js +866 -0
  80. package/tests/unit/state/apply/adminRecovery/state.apply.adminRecovery.test.js +439 -0
  81. package/tests/unit/state/apply/appendWhitelist/appendWhitelistBanAndReapplyScenario.js +78 -0
  82. package/tests/unit/state/apply/appendWhitelist/appendWhitelistExistingReaderHappyPathScenario.js +98 -0
  83. package/tests/unit/state/apply/appendWhitelist/appendWhitelistFeeAfterDisableScenario.js +66 -0
  84. package/tests/unit/state/apply/appendWhitelist/appendWhitelistHappyPathScenario.js +55 -0
  85. package/tests/unit/state/apply/appendWhitelist/appendWhitelistInsufficientAdminBalanceScenario.js +103 -0
  86. package/tests/unit/state/apply/appendWhitelist/appendWhitelistNodeAlreadyWhitelistedScenario.js +60 -0
  87. package/tests/unit/state/apply/appendWhitelist/appendWhitelistScenarioHelpers.js +191 -0
  88. package/tests/unit/state/apply/appendWhitelist/state.apply.appendWhitelist.test.js +220 -0
  89. package/tests/unit/state/apply/balanceInitialization/balanceInitializationHappyPathScenario.js +82 -0
  90. package/tests/unit/state/apply/balanceInitialization/balanceInitializationScenarioHelpers.js +106 -0
  91. package/tests/unit/state/apply/balanceInitialization/invalidAmountScenario.js +45 -0
  92. package/tests/unit/state/apply/balanceInitialization/nodeEntryBalanceUpdateFailureScenario.js +81 -0
  93. package/tests/unit/state/apply/balanceInitialization/state.apply.balanceInitialization.test.js +189 -0
  94. package/tests/unit/state/apply/banValidator/banValidatorBanAndReWhitelistScenario.js +155 -0
  95. package/tests/unit/state/apply/banValidator/banValidatorHappyPathScenario.js +36 -0
  96. package/tests/unit/state/apply/banValidator/banValidatorScenarioHelpers.js +534 -0
  97. package/tests/unit/state/apply/banValidator/banValidatorSequentialBansScenario.js +74 -0
  98. package/tests/unit/state/apply/banValidator/banValidatorTargetDecodeFailureScenario.js +19 -0
  99. package/tests/unit/state/apply/banValidator/banValidatorTargetIndexerScenario.js +32 -0
  100. package/tests/unit/state/apply/banValidator/banValidatorTargetNodeEntryMissingScenario.js +19 -0
  101. package/tests/unit/state/apply/banValidator/banValidatorTargetRoleUpdateFailureScenario.js +19 -0
  102. package/tests/unit/state/apply/banValidator/banValidatorWhitelistedNonWriterScenario.js +38 -0
  103. package/tests/unit/state/apply/banValidator/banValidatorWhitelistedZeroBalanceScenario.js +91 -0
  104. package/tests/unit/state/apply/banValidator/banValidatorWithdrawFailureScenario.js +19 -0
  105. package/tests/unit/state/apply/banValidator/state.apply.banValidator.test.js +266 -0
  106. package/tests/unit/state/apply/bootstrapDeployment/bootstrapDeploymentDuplicateRegistrationScenario.js +142 -0
  107. package/tests/unit/state/apply/bootstrapDeployment/bootstrapDeploymentHappyPathScenario.js +26 -0
  108. package/tests/unit/state/apply/bootstrapDeployment/bootstrapDeploymentIncompleteOperationScenario.js +94 -0
  109. package/tests/unit/state/apply/bootstrapDeployment/bootstrapDeploymentInvalidDeploymentEntryScenario.js +37 -0
  110. package/tests/unit/state/apply/bootstrapDeployment/bootstrapDeploymentMultipleBootstrapScenario.js +86 -0
  111. package/tests/unit/state/apply/bootstrapDeployment/bootstrapDeploymentScenarioHelpers.js +344 -0
  112. package/tests/unit/state/apply/bootstrapDeployment/invalidValidatorNodeEntryScenario.js +57 -0
  113. package/tests/unit/state/apply/bootstrapDeployment/state.apply.bootstrapDeployment.test.js +429 -0
  114. package/tests/unit/state/apply/common/access-control/adminConsistencyMismatchScenario.js +119 -0
  115. package/tests/unit/state/apply/common/access-control/adminEntryDecodeFailureScenario.js +130 -0
  116. package/tests/unit/state/apply/common/access-control/adminEntryExistsScenario.js +93 -0
  117. package/tests/unit/state/apply/common/access-control/adminEntryMissingScenario.js +108 -0
  118. package/tests/unit/state/apply/common/access-control/adminOnlyGuardScenario.js +126 -0
  119. package/tests/unit/state/apply/common/access-control/adminPublicKeyDecodeFailureScenario.js +120 -0
  120. package/tests/unit/state/apply/common/access-control/roleAccessOperationValidationScenario.js +50 -0
  121. package/tests/unit/state/apply/common/adminControlOperationValidationScenario.js +56 -0
  122. package/tests/unit/state/apply/common/balances/adminEntryUpdateFailureScenario.js +52 -0
  123. package/tests/unit/state/apply/common/balances/base/requesterBalanceScenarioBase.js +197 -0
  124. package/tests/unit/state/apply/common/balances/feeDecodeFailureScenario.js +52 -0
  125. package/tests/unit/state/apply/common/balances/requesterBalanceDecodeFailureScenario.js +15 -0
  126. package/tests/unit/state/apply/common/balances/requesterBalanceFeeApplicationFailureScenario.js +11 -0
  127. package/tests/unit/state/apply/common/balances/requesterBalanceInsufficientScenario.js +15 -0
  128. package/tests/unit/state/apply/common/balances/requesterBalanceUpdateFailureScenario.js +11 -0
  129. package/tests/unit/state/apply/common/balances/validatorEntryRewardFailureScenario.js +11 -0
  130. package/tests/unit/state/apply/common/balances/validatorEntryUpdateFailureScenario.js +11 -0
  131. package/tests/unit/state/apply/common/balances/validatorNodeEntryDecodeFailureScenario.js +40 -0
  132. package/tests/unit/state/apply/common/base/OperationValidationScenarioBase.js +114 -0
  133. package/tests/unit/state/apply/common/commonScenarioHelper.js +103 -0
  134. package/tests/unit/state/apply/common/indexer/indexerNodeEntryDecodeFailureScenario.js +36 -0
  135. package/tests/unit/state/apply/common/indexer/indexerNodeEntryMissingScenario.js +36 -0
  136. package/tests/unit/state/apply/common/indexer/indexerRoleUpdateFailureScenario.js +29 -0
  137. package/tests/unit/state/apply/common/indexer/indexerSequenceStateInvalidScenario.js +66 -0
  138. package/tests/unit/state/apply/common/invalidMessageComponentValidationScenario.js +84 -0
  139. package/tests/unit/state/apply/common/nodeEntryInitializationFailureScenario.js +47 -0
  140. package/tests/unit/state/apply/common/operationAlreadyAppliedScenario.js +85 -0
  141. package/tests/unit/state/apply/common/payload-structure/addressWithInvalidPublicKeyScenario.js +52 -0
  142. package/tests/unit/state/apply/common/payload-structure/initializationDisabledScenario.js +49 -0
  143. package/tests/unit/state/apply/common/payload-structure/invalidAddressValidationScenario.js +73 -0
  144. package/tests/unit/state/apply/common/payload-structure/invalidHashValidationScenario.js +71 -0
  145. package/tests/unit/state/apply/common/payload-structure/invalidPayloadValidationScenario.js +31 -0
  146. package/tests/unit/state/apply/common/payload-structure/invalidSignatureValidationScenario.js +142 -0
  147. package/tests/unit/state/apply/common/payload-structure/partialOperationValidationScenario.js +87 -0
  148. package/tests/unit/state/apply/common/requester/requesterNodeEntryBufferMissingScenario.js +70 -0
  149. package/tests/unit/state/apply/common/requester/requesterNodeEntryDecodeFailureScenario.js +72 -0
  150. package/tests/unit/state/apply/common/requester/requesterNodeEntryMissingScenario.js +36 -0
  151. package/tests/unit/state/apply/common/requesterAddressValidationScenario.js +44 -0
  152. package/tests/unit/state/apply/common/requesterPublicKeyValidationScenario.js +25 -0
  153. package/tests/unit/state/apply/common/transactionValidityMismatchScenario.js +98 -0
  154. package/tests/unit/state/apply/common/validatorConsistency/base/validatorConsistencyScenarioBase.js +201 -0
  155. package/tests/unit/state/apply/common/validatorConsistency/validatorEntryDecodeFailureScenario.js +17 -0
  156. package/tests/unit/state/apply/common/validatorConsistency/validatorEntryMissingScenario.js +44 -0
  157. package/tests/unit/state/apply/common/validatorConsistency/validatorInactiveScenario.js +19 -0
  158. package/tests/unit/state/apply/common/validatorConsistency/validatorWriterKeyMismatchScenario.js +18 -0
  159. package/tests/unit/state/apply/common/validatorEntryValidation/base/validatorEntryValidationScenarioBase.js +314 -0
  160. package/tests/unit/state/apply/common/validatorEntryValidation/validatorEntryInvalidBalanceScenario.js +18 -0
  161. package/tests/unit/state/apply/common/writerKeyExistsValidationScenario.js +43 -0
  162. package/tests/unit/state/apply/disableInitialization/disableInitializationAlreadyDisabledScenario.js +53 -0
  163. package/tests/unit/state/apply/disableInitialization/disableInitializationHappyPathScenario.js +24 -0
  164. package/tests/unit/state/apply/disableInitialization/disableInitializationScenarioHelpers.js +197 -0
  165. package/tests/unit/state/apply/disableInitialization/state.apply.disableInitialization.test.js +161 -0
  166. package/tests/unit/state/apply/missing-tests.md +18 -0
  167. package/tests/unit/state/apply/removeIndexer/removeIndexerHappyPathScenario.js +58 -0
  168. package/tests/unit/state/apply/removeIndexer/removeIndexerReAddAndRemoveAgainScenario.js +98 -0
  169. package/tests/unit/state/apply/removeIndexer/removeIndexerRemoveMultipleIndexersScenario.js +167 -0
  170. package/tests/unit/state/apply/removeIndexer/removeIndexerScenarioHelpers.js +428 -0
  171. package/tests/unit/state/apply/removeIndexer/removeIndexerTargetNotIndexerScenario.js +22 -0
  172. package/tests/unit/state/apply/removeIndexer/removeIndexerWriterKeyMissingScenario.js +20 -0
  173. package/tests/unit/state/apply/removeIndexer/state.apply.removeIndexer.test.js +291 -0
  174. package/tests/unit/state/apply/removeWriter/removeWriterAndAddWriterAgainScenario.js +87 -0
  175. package/tests/unit/state/apply/removeWriter/removeWriterHappyPathScenario.js +38 -0
  176. package/tests/unit/state/apply/removeWriter/removeWriterInvalidValidatorSignatureScenario.js +32 -0
  177. package/tests/unit/state/apply/removeWriter/removeWriterRequesterBalanceInsufficientScenario.js +21 -0
  178. package/tests/unit/state/apply/removeWriter/removeWriterRequesterEntryDecodeFailureScenario.js +19 -0
  179. package/tests/unit/state/apply/removeWriter/removeWriterRequesterEntryMissingScenario.js +19 -0
  180. package/tests/unit/state/apply/removeWriter/removeWriterRequesterIndexerScenario.js +21 -0
  181. package/tests/unit/state/apply/removeWriter/removeWriterRequesterNotWriterScenario.js +21 -0
  182. package/tests/unit/state/apply/removeWriter/removeWriterRequesterRoleUpdateFailureScenario.js +19 -0
  183. package/tests/unit/state/apply/removeWriter/removeWriterScenarioHelpers.js +344 -0
  184. package/tests/unit/state/apply/removeWriter/removeWriterThroughWriterValidatorScenario.js +113 -0
  185. package/tests/unit/state/apply/removeWriter/removeWriterUnstakeFailureScenario.js +33 -0
  186. package/tests/unit/state/apply/removeWriter/removeWriterWriterKeyMismatchScenario.js +21 -0
  187. package/tests/unit/state/apply/removeWriter/removeWriterWriterKeyOwnershipScenario.js +26 -0
  188. package/tests/unit/state/apply/removeWriter/removeWriterWriterKeyRegistryMissingScenario.js +22 -0
  189. package/tests/unit/state/apply/removeWriter/state.apply.removeWriter.test.js +307 -0
  190. package/tests/unit/state/apply/state.apply.test.js +24 -0
  191. package/tests/unit/state/apply/transfer/state.apply.transfer.test.js +819 -0
  192. package/tests/unit/state/apply/transfer/transferContractSchemaValidationScenario.js +22 -0
  193. package/tests/unit/state/apply/transfer/transferDoubleSpendAcrossValidatorsScenario.js +137 -0
  194. package/tests/unit/state/apply/transfer/transferDoubleSpendSameBatchScenario.js +63 -0
  195. package/tests/unit/state/apply/transfer/transferDoubleSpendSingleValidatorScenario.js +67 -0
  196. package/tests/unit/state/apply/transfer/transferExistingRecipientAmountScenario.js +31 -0
  197. package/tests/unit/state/apply/transfer/transferExistingRecipientZeroAmountScenario.js +31 -0
  198. package/tests/unit/state/apply/transfer/transferHandlerGuardScenarios.js +22 -0
  199. package/tests/unit/state/apply/transfer/transferHappyPathScenario.js +8 -0
  200. package/tests/unit/state/apply/transfer/transferInvalidIncomingDataScenario.js +66 -0
  201. package/tests/unit/state/apply/transfer/transferNewRecipientAmountScenario.js +31 -0
  202. package/tests/unit/state/apply/transfer/transferNewRecipientZeroAmountScenario.js +31 -0
  203. package/tests/unit/state/apply/transfer/transferScenarioHelpers.js +1167 -0
  204. package/tests/unit/state/apply/transfer/transferSelfTransferAmountScenario.js +38 -0
  205. package/tests/unit/state/apply/transfer/transferSelfTransferZeroAmountScenario.js +38 -0
  206. package/tests/unit/state/apply/transfer/transferValidatorRecipientAmountScenario.js +38 -0
  207. package/tests/unit/state/apply/transfer/transferValidatorRecipientZeroAmountScenario.js +38 -0
  208. package/tests/unit/state/apply/txOperation/state.apply.txOperation.test.js +318 -0
  209. package/tests/unit/state/apply/txOperation/txOperationBootstrapNotRegisteredScenario.js +70 -0
  210. package/tests/unit/state/apply/txOperation/txOperationDifferentValidatorCreatorHappyPathScenario.js +23 -0
  211. package/tests/unit/state/apply/txOperation/txOperationInvalidDeploymentEntryScenario.js +48 -0
  212. package/tests/unit/state/apply/txOperation/txOperationInvalidFeeAmountScenario.js +39 -0
  213. package/tests/unit/state/apply/txOperation/txOperationInvalidSubnetCreatorAddressScenario.js +46 -0
  214. package/tests/unit/state/apply/txOperation/txOperationRequesterCreatorHappyPathScenario.js +21 -0
  215. package/tests/unit/state/apply/txOperation/txOperationScenarioHelpers.js +429 -0
  216. package/tests/unit/state/apply/txOperation/txOperationStandardHappyPathScenario.js +21 -0
  217. package/tests/unit/state/apply/txOperation/txOperationTransferFeeAddCreatorBalanceFailureScenario.js +26 -0
  218. package/tests/unit/state/apply/txOperation/txOperationTransferFeeAddValidatorBalanceFailureScenario.js +25 -0
  219. package/tests/unit/state/apply/txOperation/txOperationTransferFeeAddValidatorBonusFailureScenario.js +27 -0
  220. package/tests/unit/state/apply/txOperation/txOperationTransferFeeDecodeCreatorEntryScenario.js +18 -0
  221. package/tests/unit/state/apply/txOperation/txOperationTransferFeeDecodeRequesterEntryScenario.js +17 -0
  222. package/tests/unit/state/apply/txOperation/txOperationTransferFeeDecodeValidatorEntryScenario.js +31 -0
  223. package/tests/unit/state/apply/txOperation/txOperationTransferFeeGuardBypassScenario.js +49 -0
  224. package/tests/unit/state/apply/txOperation/txOperationTransferFeeGuardScenarioFactory.js +92 -0
  225. package/tests/unit/state/apply/txOperation/txOperationTransferFeeInsufficientRequesterBalanceScenario.js +28 -0
  226. package/tests/unit/state/apply/txOperation/txOperationTransferFeeInvalidCreatorBalanceScenario.js +29 -0
  227. package/tests/unit/state/apply/txOperation/txOperationTransferFeeInvalidRequesterBalanceScenario.js +28 -0
  228. package/tests/unit/state/apply/txOperation/txOperationTransferFeeInvalidRequesterEntryScenario.js +17 -0
  229. package/tests/unit/state/apply/txOperation/txOperationTransferFeeInvalidValidatorBalanceScenario.js +33 -0
  230. package/tests/unit/state/apply/txOperation/txOperationTransferFeeMissingCreatorEntryScenario.js +18 -0
  231. package/tests/unit/state/apply/txOperation/txOperationTransferFeeSubtractFailureScenario.js +25 -0
  232. package/tests/unit/state/apply/txOperation/txOperationTransferFeeUpdateCreatorBalanceFailureScenario.js +26 -0
  233. package/tests/unit/state/apply/txOperation/txOperationTransferFeeUpdateFailureScenario.js +25 -0
  234. package/tests/unit/state/apply/txOperation/txOperationTransferFeeUpdateValidatorBalanceFailureScenario.js +26 -0
  235. package/tests/unit/state/apply/txOperation/txOperationTransferFeeUpdateValidatorBonusFailureScenario.js +27 -0
  236. package/tests/unit/state/apply/txOperation/txOperationValidatorCreatorHappyPathScenario.js +21 -0
  237. package/tests/unit/state/stateModule.test.js +1 -0
  238. package/tests/unit/state/stateTestUtils.js +5 -1
  239. package/.env +0 -3
package/src/index.js CHANGED
@@ -38,6 +38,25 @@ import deploymentEntryUtils from "./core/state/utils/deploymentEntry.js";
38
38
  import PartialTransaction from "./core/network/messaging/validators/PartialTransaction.js";
39
39
  import fileUtils from './utils/fileUtils.js';
40
40
  import migrationUtils from './utils/migrationUtils.js';
41
+ import {
42
+ getBalanceCommand,
43
+ getTxvCommand,
44
+ getFeeCommand,
45
+ getConfirmedLengthCommand,
46
+ getUnconfirmedLengthCommand,
47
+ getTxPayloadsBulkCommand,
48
+ getTxHashesCommand,
49
+ getTxDetailsCommand,
50
+ getExtendedTxDetailsCommand,
51
+ nodeStatusCommand,
52
+ coreInfoCommand,
53
+ getValidatorAddressCommand,
54
+ getDeploymentCommand,
55
+ getTxInfoCommand,
56
+ getLicenseNumberCommand,
57
+ getLicenseAddressCommand,
58
+ getLicenseCountCommand
59
+ } from "./utils/cliCommands.js";
41
60
  export class MainSettlementBus extends ReadyResource {
42
61
  // internal attributes
43
62
  #options;
@@ -223,6 +242,51 @@ export class MainSettlementBus extends ReadyResource {
223
242
  await this.#network.validatorConnectionManager.send(partialTransactionPayload);
224
243
  }
225
244
 
245
+ async broadcastTransactionCommand(payload) {
246
+ if (!payload) {
247
+ throw new Error("Transaction payload is required for broadcast_transaction command.");
248
+ }
249
+
250
+ let normalizedPayload;
251
+ let isValid = false;
252
+ let hash;
253
+
254
+ if (payload.type === OperationType.TRANSFER) {
255
+ normalizedPayload = normalizeTransferOperation(payload);
256
+ isValid = await this.#partialTransferValidator.validate(normalizedPayload);
257
+ hash = b4a.toString(normalizedPayload.tro.tx, "hex");
258
+ } else if (payload.type === OperationType.TX) {
259
+ normalizedPayload = normalizeTransactionOperation(payload);
260
+ isValid = await this.#partialTransactionValidator.validate(normalizedPayload);
261
+ hash = b4a.toString(normalizedPayload.txo.tx, "hex");
262
+ }
263
+
264
+ if (!isValid) {
265
+ throw new Error("Invalid transaction payload.");
266
+ }
267
+
268
+ const signedLength = this.#state.getSignedLength();
269
+ const unsignedLength = this.#state.getUnsignedLength();
270
+
271
+ for (let attempt = 0; attempt <= this.#maxRetries; attempt++) { // should iterate once if maxRetries === 0
272
+ await this.broadcastPartialTransaction(payload);
273
+ await sleep(1000 * (attempt + 1)); // linear backoff wait time
274
+ const tx = await this.#state.get(hash);
275
+
276
+ if (tx !== null) {
277
+ break;
278
+ }
279
+
280
+ this.network.validatorConnectionManager.rotate(); // force change connection rotation for the next retry
281
+ }
282
+
283
+ if (await this.#state.get(hash) === null) {
284
+ throw new Error("Failed to broadcast transaction after multiple attempts.");
285
+ }
286
+
287
+ return { message: "Transaction broadcasted successfully.", signedLength, unsignedLength, tx: hash };
288
+ }
289
+
226
290
  async #setUpRoleAutomatically() {
227
291
  if (!this.#state.isWritable() && this.#enable_role_requester) {
228
292
  console.log("Requesting writer role... This may take a moment.");
@@ -924,396 +988,144 @@ export class MainSettlementBus extends ReadyResource {
924
988
  }
925
989
 
926
990
  async handleCommand(input, rl = null, payload = null) {
927
- switch (input) {
928
- case "/help":
991
+ const [command, ...parts] = input.split(" ");
992
+
993
+ const exactHandlers = {
994
+ "/help": async () => {
929
995
  printHelp(this.#is_admin_mode);
930
- break;
931
- case "/exit":
996
+ },
997
+ "/exit": async () => {
932
998
  if (rl) rl.close();
933
999
  await this.close();
934
- break;
935
- case "/add_admin":
936
- await this.#handleAdminCreation();
937
- break;
938
- case "/add_admin --recovery":
939
- await this.#handleAdminRecovery();
940
- break;
941
- case "/add_whitelist":
942
- await this.#handleWhitelistOperations();
943
- break;
944
- case "/add_writer":
945
- await this.#handleAddWriterOperation();
946
- break;
947
- case "/remove_writer":
948
- await this.#handleRemoveWriterOperation();
949
- break;
950
- case "/core":
951
- const admin = await this.#state.getAdminEntry();
952
- console.log("Admin:", admin ? {
953
- address: admin.address,
954
- writingKey: admin.wk.toString("hex")
955
- } : null);
956
- const formattedIndexers = await getFormattedIndexersWithAddresses(this.#state);
957
- if (formattedIndexers.length === 0) {
958
- console.log("Indexers: no indexers");
959
- } else {
960
- console.log("Indexers:", formattedIndexers);
961
- }
962
- break;
963
- case "/indexers_list":
1000
+ },
1001
+ "/add_admin": () => this.#handleAdminCreation(),
1002
+ "/add_admin --recovery": () => this.#handleAdminRecovery(),
1003
+ "/add_whitelist": () => this.#handleWhitelistOperations(),
1004
+ "/add_writer": () => this.#handleAddWriterOperation(),
1005
+ "/remove_writer": () => this.#handleRemoveWriterOperation(),
1006
+ "/core": () => coreInfoCommand(this.#state),
1007
+ "/indexers_list": async () => {
964
1008
  console.log(await this.#state.getIndexersEntry());
965
- break;
966
- case "/validator_pool":
967
- this.network.validatorConnectionManager.prettyPrint()
968
- break;
969
- case "/stats":
970
- await verifyDag(
971
- this.#state,
972
- this.#network,
973
- this.#wallet,
974
- this.#state.writingKey,
975
- );
976
- break;
977
- case '/balance_migration':
978
- await this.#handleBalanceMigrationOperation();
979
- break;
980
- case '/disable_initialization':
981
- await this.#disableInitialization();
982
- break;
983
- default:
984
- if (input.startsWith('/node_status')) {
985
- const splitted = input.split(' ')
986
- const address = splitted[1]
987
- const nodeEntry = await this.#state.getNodeEntry(address)
988
- if (nodeEntry) {
989
- const licenseValue = nodeEntry.license.readUInt32BE(0);
990
- const licenseDisplay = licenseValue === 0 ? 'N/A' : licenseValue.toString();
991
- console.log('Node Status:', {
992
- Address: address,
993
- WritingKey: nodeEntry.wk.toString('hex'),
994
- IsWhitelisted: nodeEntry.isWhitelisted,
995
- IsWriter: nodeEntry.isWriter,
996
- IsIndexer: nodeEntry.isIndexer,
997
- License: licenseDisplay,
998
- StakedBalance: bigIntToDecimalString(bufferToBigInt(nodeEntry.stakedBalance)),
999
- Balance: bigIntToDecimalString(bufferToBigInt(nodeEntry.balance))
1000
- })
1001
- return {
1002
- address: address,
1003
- writingKey: nodeEntry.wk.toString('hex'),
1004
- isWhitelisted: nodeEntry.isWhitelisted,
1005
- isWriter: nodeEntry.isWriter,
1006
- isIndexer: nodeEntry.isIndexer,
1007
- license: licenseDisplay,
1008
- stakedBalance: bigIntToDecimalString(bufferToBigInt(nodeEntry.stakedBalance))
1009
- }
1010
- } else {
1011
- console.log('Node Status:', {
1012
- WritingKey: ZERO_WK.toString('hex'),
1013
- IsWhitelisted: false,
1014
- IsWriter: false,
1015
- IsIndexer: false,
1016
- license: 'N/A',
1017
- stakedBalance: '0'
1018
- })
1019
- }
1020
- } else if (input.startsWith("/add_indexer")) {
1021
- const splitted = input.split(" ");
1022
- const address = splitted[1];
1023
- await this.#handleAddIndexerOperation(address);
1024
- } else if (input.startsWith("/remove_indexer")) {
1025
- const splitted = input.split(" ");
1026
- const address = splitted[1];
1027
- await this.#handleRemoveIndexerOperation(address);
1028
- } else if (input.startsWith("/ban_writer")) {
1029
- const splitted = input.split(" ");
1030
- const address = splitted[1];
1031
- await this.#handleBanValidatorOperation(address);
1032
- } else if (input.startsWith("/deployment")) {
1033
- const splitted = input.split(" ");
1034
- const bootstrap_to_deploy = splitted[1];
1035
- const channel = splitted[2] || randomBytes(32).toString('hex');
1036
- if (channel.length !== 64 || !isHexString(channel)) {
1037
- throw new Error("Channel must be a 32-byte hex string");
1038
- }
1039
- await this.#handleBootstrapDeploymentOperation(bootstrap_to_deploy, channel);
1040
- }
1041
- else if (input.startsWith("/get_validator_addr")) {
1042
- const splitted = input.split(" ");
1043
- const wkHexString = splitted[1];
1044
- const payload = await this.#state.getSigned(EntryType.WRITER_ADDRESS + wkHexString);
1045
- if (payload === null) {
1046
- console.log(`No address assigned to the writer key: ${wkHexString}`);
1047
- } else {
1048
- console.log(`Address assigned to the writer key: ${wkHexString} - ${bufferToAddress(payload)}`)
1049
- }
1050
- }
1051
- else if (input.startsWith("/get_deployment")) {
1052
- const splitted = input.split(" ");
1053
- const bootstrapHex = splitted[1];
1054
- const deploymentEntry = await this.#state.getRegisteredBootstrapEntry(bootstrapHex);
1055
- console.log(`Searching deployment for bootstrap: ${bootstrapHex}`);
1056
- if (deploymentEntry) {
1057
- const decodedDeploymentEntry = deploymentEntryUtils.decode(deploymentEntry)
1058
- const txhash = decodedDeploymentEntry.txHash.toString('hex');
1059
- console.log(`Bootstrap deployed under transaction hash: ${txhash}`);
1060
- const payload = await this.#state.getSigned(txhash);
1061
- if (payload) {
1062
- const decoded = safeDecodeApplyOperation(payload);
1063
- console.log('Decoded Bootstrap Deployment Payload:', decoded);
1064
- } else {
1065
- console.log(`No payload found for transaction hash: ${txhash}`);
1066
- }
1067
- } else {
1068
- console.log(`No deployment found for bootstrap: ${bootstrapHex}`);
1069
- }
1070
- } else if (input.startsWith("/get_tx_info")) {
1071
- const splitted = input.split(" ");
1072
- const txHash = splitted[1];
1073
- const txInfo = await get_confirmed_tx_info(this.#state, txHash);
1074
- if (txInfo) {
1075
- console.log(`Payload for transaction hash ${txHash}:`);
1076
- console.log(txInfo.decoded);
1077
- } else {
1078
- console.log(`No information found for transaction hash: ${txHash}`);
1079
- }
1080
- } else if (input.startsWith("/transfer")) {
1081
- const splitted = input.split(" ");
1082
- const address = splitted[1];
1083
- const amount = splitted[2];
1084
- await this.#handleTransferOperation(address, amount);
1085
- } else if (input.startsWith("/get_balance")) {
1086
- const splitted = input.split(" ");
1087
- const address = splitted[1];
1088
- const confirmedFlag = splitted[2];
1089
- let unconfirmedBalance = confirmedFlag === 'false'
1090
- let nodeEntry = unconfirmedBalance ? await this.#state.getNodeEntryUnsigned(address) : await this.#state.getNodeEntry(address)
1091
- if (nodeEntry) {
1092
- console.log({
1093
- Address: address,
1094
- Balance: bigIntToDecimalString(bufferToBigInt(nodeEntry.balance))
1095
- })
1096
- return {
1097
- address: address,
1098
- balance: bufferToBigInt(nodeEntry.balance).toString(),
1099
- }
1100
- } else {
1101
- console.log('Node Entry:', {
1102
- WritingKey: ZERO_WK.toString('hex'),
1103
- IsWhitelisted: false,
1104
- IsWriter: false,
1105
- IsIndexer: false,
1106
- balance: bigIntToDecimalString(0n)
1107
- })
1108
- }
1109
-
1110
- } else if (input.startsWith("/get_license_number")) {
1111
- const splitted = input.split(" ");
1112
- const address = splitted[1];
1113
- let nodeEntry = await this.#state.getNodeEntry(address)
1114
- if (nodeEntry) {
1115
- console.log({
1116
- Address: address,
1117
- License: licenseBufferToBigInt(nodeEntry.license).toString()
1118
- })
1119
- }
1120
-
1121
- } else if (input.startsWith("/get_license_address")) {
1122
- const splitted = input.split(" ");
1123
- const licenseId = parseInt(splitted[1]);
1124
-
1125
- if (isNaN(licenseId) || licenseId < 0) {
1126
- console.log('Invalid license ID. Please provide a valid non-negative number.');
1127
- return;
1128
- }
1129
-
1130
- const address = await this.#state.getAddressByLicenseId(licenseId);
1131
- if (address) {
1132
- console.log({
1133
- LicenseId: licenseId,
1134
- Address: address
1135
- });
1136
- } else {
1137
- console.log(`No address found for license ID: ${licenseId}`);
1138
- }
1139
-
1140
- } else if (input.startsWith("/get_license_count")) {
1141
- const adminEntry = await this.#state.getAdminEntry();
1142
-
1143
- if (!adminEntry) {
1144
- throw new Error("Cannot read license count. Admin does not exist");
1145
- }
1146
-
1147
- if (!this.#isAdmin(adminEntry)) {
1148
- throw new Error('Cannot perform this operation - you are not the admin!.');
1149
- }
1150
-
1151
- let licenseCount = await this.#state.getLicenseCount()
1152
-
1153
- console.log({
1154
- LicensesCount: licenseCount
1155
- })
1156
- } else if (input.startsWith("/get_txv")) {
1157
- const txv = await this.#state.getIndexerSequenceState();
1158
- console.log('Current TXV:', txv.toString('hex'));
1159
- return txv
1160
- } else if (input.startsWith("/get_fee")) {
1161
- const fee = this.#state.getFee();
1162
- console.log('Current FEE:', bigIntToDecimalString(bufferToBigInt(fee)));
1163
- return bufferToBigInt(fee).toString();
1164
- } else if (input.startsWith("/confirmed_length")) {
1165
- const confirmed_length = this.#state.getSignedLength();
1166
- console.log('Confirmed_length:', confirmed_length);
1167
- return confirmed_length;
1168
- } else if (input.startsWith("/unconfirmed_length")) {
1169
- const unconfirmed_length = this.#state.getUnsignedLength();
1170
- console.log('Unconfirmed_length:', unconfirmed_length);
1171
- return unconfirmed_length;
1172
- } else if (input.startsWith("/broadcast_transaction")) {
1173
- if (payload) {
1174
- let normalizedPayload;
1175
- let isValid = false;
1176
- let hash
1177
- if (payload.type === OperationType.TRANSFER) {
1178
- normalizedPayload = normalizeTransferOperation(payload);
1179
- isValid = await this.#partialTransferValidator.validate(normalizedPayload);
1180
- hash = b4a.toString(normalizedPayload.tro.tx, 'hex')
1181
- } else if (payload.type === OperationType.TX) {
1182
- normalizedPayload = normalizeTransactionOperation(payload);
1183
- isValid = await this.#partialTransactionValidator.validate(normalizedPayload);
1184
- hash = b4a.toString(normalizedPayload.txo.tx, 'hex')
1185
- }
1186
-
1187
- if (!isValid) throw new Error("Invalid transaction payload.");
1188
-
1189
- const signedLength = this.#state.getSignedLength();
1190
- const unsignedLength = this.#state.getUnsignedLength();
1191
-
1192
- for (let retry = 0; retry <= this.#maxRetries; retry++) { // should iterate once if maxRetries === 0
1193
- await this.broadcastPartialTransaction(payload);
1194
- await sleep(1000 * (retry + 1)); // linear backoff wait time
1195
- const tx = await this.#state.get(hash)
1196
- if (tx !== null) {
1197
- break;
1198
- }
1199
- this.network.validatorConnectionManager.rotate() // force change connection rotation for the next retry
1200
- }
1201
-
1202
- if (await this.#state.get(hash) === null) {
1203
- throw new Error("Failed to broadcast transaction after multiple attempts.");
1204
- }
1205
-
1206
- return { message: "Transaction broadcasted successfully.", signedLength, unsignedLength, tx: hash };
1207
- } else {
1208
- // Handle case where payload is missing if called internally without one.
1209
- throw new Error("Transaction payload is required for broadcast_transaction command.");
1210
- }
1211
- } else if (input.startsWith("/get_tx_payloads_bulk")) {
1212
- if (payload) {
1213
- const hashes = payload;
1214
-
1215
- if (!Array.isArray(hashes) || hashes.length === 0) {
1216
- throw new Error("Missing hash list.");
1217
- }
1218
-
1219
- let res = { results: [], missing: [] }
1220
-
1221
- if (hashes.length > 1500) {
1222
- throw new Error("Length of input tx hashes exceeded.");
1223
- }
1224
-
1225
- const promises = hashes.map(hash => get_confirmed_tx_info(this.#state, hash));
1226
- const results = await Promise.all(promises);
1227
-
1228
- // Iterate and categorize
1229
- results.forEach((result, index) => {
1230
- const hash = hashes[index];
1231
- if (result === null || result === undefined) {
1232
- res.missing.push(hash);
1233
- } else {
1234
- const decodedResult = normalizeDecodedPayloadForJson(result.decoded)
1235
- res.results.push({ hash: hash, payload: decodedResult });
1236
- }
1237
- });
1238
-
1239
- return res;
1240
-
1241
- } else {
1242
- throw new Error("Missing payload for fetching tx payloads.")
1243
- }
1244
- } else if (input.startsWith("/get_txs_hashes")) {
1245
- const splitted = input.split(' ')
1246
- const start = parseInt(splitted[1]);
1247
- const end = parseInt(splitted[2]);
1248
-
1249
- try {
1250
- const hashes = await this.#state.confirmedTransactionsBetween(start, end);
1251
- return { hashes }
1252
- } catch (error) {
1253
- throw new Error("Invalid params to perform the request.", error.message);
1254
- }
1255
- } else if (input.startsWith("/get_tx_details")) {
1256
- const splitted = input.split(' ')
1257
- const hash = splitted[1];
1258
- try {
1259
- const rawPayload = await get_confirmed_tx_info(this.#state, hash);
1260
- if (!rawPayload) {
1261
- console.log(`No payload found for tx hash: ${hash}`)
1262
- return null
1263
- }
1264
- const normalizedPayload = normalizeDecodedPayloadForJson(rawPayload.decoded);
1265
- return normalizedPayload
1266
- } catch (error) {
1267
- throw new Error("Invalid params to perform the request.", error.message);
1268
- }
1269
- }
1270
- else if (input.startsWith("/get_extended_tx_details")) {
1271
- const splitted = input.split(' ');
1272
- const hash = splitted[1];
1273
- const confirmed = splitted[2] === 'true';
1274
-
1275
- if (confirmed) {
1276
- const rawPayload = await get_confirmed_tx_info(this.#state, hash);
1277
- if (!rawPayload) {
1278
- throw new Error(`No payload found for tx hash: ${hash}`);
1279
- }
1280
- const confirmedLength = await this.#state.getTransactionConfirmedLength(hash);
1281
- const normalizedPayload = normalizeDecodedPayloadForJson(rawPayload.decoded, true);
1282
- if (confirmedLength === null) {
1283
- throw new Error(`No confirmed length found for tx hash: ${hash} in confirmed mode`);
1284
- }
1285
- const fee = this.#state.getFee();
1286
- return {
1287
- txDetails: normalizedPayload,
1288
- confirmed_length: confirmedLength,
1289
- fee: bufferToBigInt(fee).toString()
1290
- }
1291
- }
1292
- else {
1293
- const rawPayload = await get_unconfirmed_tx_info(this.#state, hash);
1294
- if (!rawPayload) {
1295
- throw new Error(`No payload found for tx hash: ${hash}`);
1296
- }
1297
- const normalizedPayload = normalizeDecodedPayloadForJson(rawPayload.decoded, true);
1298
- const length = await this.#state.getTransactionConfirmedLength(hash)
1299
- if (length === null) {
1300
- return {
1301
- txDetails: normalizedPayload,
1302
- confirmed_length: 0,
1303
- fee: '0'
1304
- }
1305
- }
1306
-
1307
- const fee = this.#state.getFee();
1308
- return {
1309
- txDetails: normalizedPayload,
1310
- confirmed_length: length,
1311
- fee: bufferToBigInt(fee).toString()
1312
- }
1313
-
1314
- }
1315
- }
1009
+ },
1010
+ "/validator_pool": () => {
1011
+ this.network.validatorConnectionManager.prettyPrint();
1012
+ },
1013
+ "/stats": () => verifyDag(
1014
+ this.#state,
1015
+ this.#network,
1016
+ this.#wallet,
1017
+ this.#state.writingKey
1018
+ ),
1019
+ "/balance_migration": () => this.#handleBalanceMigrationOperation(),
1020
+ "/disable_initialization": () => this.#disableInitialization()
1021
+ };
1022
+
1023
+ if (exactHandlers[command]) {
1024
+ const result = await exactHandlers[command]();
1025
+ if (rl) rl.prompt();
1026
+ return result;
1027
+ }
1028
+
1029
+ if (input.startsWith("/node_status")) {
1030
+ const address = parts[0];
1031
+ const result = await nodeStatusCommand(this.#state, address);
1032
+ if (rl) rl.prompt();
1033
+ return result;
1034
+ }
1035
+
1036
+ if (input.startsWith("/add_indexer")) {
1037
+ const address = parts[0];
1038
+ await this.#handleAddIndexerOperation(address);
1039
+ } else if (input.startsWith("/remove_indexer")) {
1040
+ const address = parts[0];
1041
+ await this.#handleRemoveIndexerOperation(address);
1042
+ } else if (input.startsWith("/ban_writer")) {
1043
+ const address = parts[0];
1044
+ await this.#handleBanValidatorOperation(address);
1045
+ } else if (input.startsWith("/deployment")) {
1046
+ const bootstrapToDeploy = parts[0];
1047
+ const channel = parts[1] || randomBytes(32).toString("hex");
1048
+ if (channel.length !== 64 || !isHexString(channel)) {
1049
+ throw new Error("Channel must be a 32-byte hex string");
1050
+ }
1051
+ await this.#handleBootstrapDeploymentOperation(bootstrapToDeploy, channel);
1052
+ } else if (input.startsWith("/get_validator_addr")) {
1053
+ const wkHexString = parts[0];
1054
+ await getValidatorAddressCommand(this.#state, wkHexString);
1055
+ } else if (input.startsWith("/get_deployment")) {
1056
+ const bootstrapHex = parts[0];
1057
+ await getDeploymentCommand(this.#state, bootstrapHex);
1058
+ } else if (input.startsWith("/get_tx_info")) {
1059
+ const txHash = parts[0];
1060
+ await getTxInfoCommand(this.#state, txHash);
1061
+ } else if (input.startsWith("/transfer")) {
1062
+ const address = parts[0];
1063
+ const amount = parts[1];
1064
+ await this.#handleTransferOperation(address, amount);
1065
+ } else if (input.startsWith("/get_balance")) {
1066
+ const address = parts[0];
1067
+ const confirmedFlag = parts[1];
1068
+ const result = await getBalanceCommand(this.#state, address, confirmedFlag);
1069
+ if (rl) rl.prompt();
1070
+ return result;
1071
+ } else if (input.startsWith("/get_license_number")) {
1072
+ const address = parts[0];
1073
+ await getLicenseNumberCommand(this.#state, address);
1074
+ } else if (input.startsWith("/get_license_address")) {
1075
+ const licenseId = parseInt(parts[0]);
1076
+ await getLicenseAddressCommand(this.#state, licenseId);
1077
+ } else if (input.startsWith("/get_license_count")) {
1078
+ await getLicenseCountCommand(this.#state, this.#isAdmin.bind(this));
1079
+ } else if (input.startsWith("/get_txv")) {
1080
+ const result = await getTxvCommand(this.#state);
1081
+ if (rl) rl.prompt();
1082
+ return result;
1083
+ } else if (input.startsWith("/get_fee")) {
1084
+ const result = getFeeCommand(this.#state);
1085
+ if (rl) rl.prompt();
1086
+ return result;
1087
+ } else if (input.startsWith("/confirmed_length")) {
1088
+ const result = getConfirmedLengthCommand(this.#state);
1089
+ if (rl) rl.prompt();
1090
+ return result;
1091
+ } else if (input.startsWith("/unconfirmed_length")) {
1092
+ const result = getUnconfirmedLengthCommand(this.#state);
1093
+ if (rl) rl.prompt();
1094
+ return result;
1095
+ } else if (input.startsWith("/broadcast_transaction")) {
1096
+ if (!payload) {
1097
+ throw new Error("Transaction payload is required for broadcast_transaction command.");
1098
+ }
1099
+ const result = await this.broadcastTransactionCommand(payload);
1100
+ if (rl) rl.prompt();
1101
+ return result;
1102
+ } else if (input.startsWith("/get_tx_payloads_bulk")) {
1103
+ if (!payload) {
1104
+ throw new Error("Missing payload for fetching tx payloads.");
1105
+ }
1106
+ const hashes = payload;
1107
+ const result = await getTxPayloadsBulkCommand(this.#state, hashes);
1108
+ if (rl) rl.prompt();
1109
+ return result;
1110
+ } else if (input.startsWith("/get_txs_hashes")) {
1111
+ const start = parseInt(parts[0]);
1112
+ const end = parseInt(parts[1]);
1113
+ const result = await getTxHashesCommand(this.#state, start, end);
1114
+ if (rl) rl.prompt();
1115
+ return result;
1116
+ } else if (input.startsWith("/get_tx_details")) {
1117
+ const hash = parts[0];
1118
+ const result = await getTxDetailsCommand(this.#state, hash);
1119
+ if (rl) rl.prompt();
1120
+ return result;
1121
+ } else if (input.startsWith("/get_extended_tx_details")) {
1122
+ const hash = parts[0];
1123
+ const confirmed = parts[1] === "true";
1124
+ const result = await getExtendedTxDetailsCommand(this.#state, hash, confirmed);
1125
+ if (rl) rl.prompt();
1126
+ return result;
1316
1127
  }
1128
+
1317
1129
  if (rl) rl.prompt();
1318
1130
  }
1319
1131
  }