trac-msb 0.2.7 → 0.2.9

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 (187) hide show
  1. package/.github/workflows/publish.yml +8 -16
  2. package/msb.mjs +13 -25
  3. package/package.json +8 -4
  4. package/proto/network.proto +74 -0
  5. package/rpc/{create_server.mjs → create_server.js} +4 -4
  6. package/rpc/{handlers.mjs → handlers.js} +7 -7
  7. package/rpc/routes/{index.mjs → index.js} +1 -1
  8. package/rpc/routes/{v1.mjs → v1.js} +1 -1
  9. package/rpc/rpc_server.js +10 -0
  10. package/rpc/rpc_services.js +48 -7
  11. package/rpc/utils/{helpers.mjs → helpers.js} +1 -1
  12. package/src/config/config.js +137 -0
  13. package/src/config/env.js +63 -0
  14. package/src/core/network/Network.js +133 -119
  15. package/src/core/network/identity/NetworkWalletFactory.js +5 -6
  16. package/src/core/network/protocols/LegacyProtocol.js +67 -0
  17. package/src/core/network/protocols/NetworkMessages.js +48 -0
  18. package/src/core/network/protocols/ProtocolInterface.js +31 -0
  19. package/src/core/network/protocols/ProtocolSession.js +59 -0
  20. package/src/core/network/protocols/V1Protocol.js +64 -0
  21. package/src/core/network/protocols/legacy/NetworkMessageRouter.js +84 -0
  22. package/src/core/network/protocols/legacy/handlers/GetRequestHandler.js +53 -0
  23. package/src/core/network/protocols/legacy/handlers/ResponseHandler.js +37 -0
  24. package/src/core/network/{messaging → protocols/legacy}/validators/ValidatorResponse.js +2 -2
  25. package/src/core/network/{messaging → protocols/legacy}/validators/base/BaseResponse.js +13 -6
  26. package/src/core/network/protocols/shared/handlers/RoleOperationHandler.js +88 -0
  27. package/src/core/network/protocols/shared/handlers/SubnetworkOperationHandler.js +93 -0
  28. package/src/core/network/protocols/shared/handlers/TransferOperationHandler.js +57 -0
  29. package/src/core/network/{messaging → protocols/shared}/handlers/base/BaseOperationHandler.js +21 -26
  30. package/src/core/network/{messaging → protocols/shared}/validators/PartialBootstrapDeployment.js +3 -3
  31. package/src/core/network/{messaging → protocols/shared}/validators/PartialRoleAccess.js +15 -12
  32. package/src/core/network/{messaging → protocols/shared}/validators/PartialTransaction.js +10 -11
  33. package/src/core/network/{messaging → protocols/shared}/validators/PartialTransfer.js +10 -7
  34. package/src/core/network/{messaging → protocols/shared}/validators/base/PartialOperation.js +40 -22
  35. package/src/core/network/protocols/v1/NetworkMessageRouter.js +15 -0
  36. package/src/core/network/services/ConnectionManager.js +13 -19
  37. package/src/core/network/services/MessageOrchestrator.js +10 -22
  38. package/src/core/network/services/TransactionPoolService.js +10 -10
  39. package/src/core/network/services/TransactionRateLimiterService.js +5 -3
  40. package/src/core/network/services/ValidatorObserverService.js +46 -21
  41. package/src/core/state/State.js +137 -141
  42. package/src/core/state/utils/address.js +18 -16
  43. package/src/core/state/utils/adminEntry.js +17 -16
  44. package/src/core/state/utils/deploymentEntry.js +15 -15
  45. package/src/core/state/utils/transaction.js +3 -95
  46. package/src/index.js +250 -325
  47. package/src/messages/network/v1/NetworkMessageBuilder.js +325 -0
  48. package/src/messages/network/v1/NetworkMessageDirector.js +137 -0
  49. package/src/messages/network/v1/networkMessageFactory.js +12 -0
  50. package/src/messages/state/ApplyStateMessageBuilder.js +661 -0
  51. package/src/messages/state/ApplyStateMessageDirector.js +516 -0
  52. package/src/messages/state/applyStateMessageFactory.js +12 -0
  53. package/src/utils/buffer.js +53 -1
  54. package/src/utils/check.js +21 -17
  55. package/src/utils/cli.js +0 -8
  56. package/src/utils/cliCommands.js +11 -11
  57. package/src/utils/constants.js +36 -24
  58. package/src/utils/fileUtils.js +1 -4
  59. package/src/utils/helpers.js +9 -20
  60. package/src/utils/migrationUtils.js +2 -2
  61. package/src/utils/normalizers.js +94 -11
  62. package/src/utils/protobuf/network.cjs +840 -0
  63. package/src/utils/protobuf/operationHelpers.js +10 -0
  64. package/tests/acceptance/v1/account/account.test.mjs +2 -2
  65. package/tests/acceptance/v1/balance/balance.test.mjs +1 -1
  66. package/tests/acceptance/v1/broadcast-transaction/broadcast-transaction.test.mjs +11 -2
  67. package/tests/acceptance/v1/rpc.test.mjs +10 -10
  68. package/tests/acceptance/v1/tx/tx.test.mjs +4 -2
  69. package/tests/acceptance/v1/tx-details/tx-details.test.mjs +7 -3
  70. package/tests/fixtures/check.fixtures.js +42 -42
  71. package/tests/fixtures/networkV1.fixtures.js +84 -0
  72. package/tests/fixtures/protobuf.fixtures.js +110 -26
  73. package/tests/helpers/StateNetworkFactory.js +3 -5
  74. package/tests/helpers/autobaseTestHelpers.js +1 -2
  75. package/tests/helpers/config.js +3 -0
  76. package/tests/helpers/setupApplyTests.js +113 -99
  77. package/tests/helpers/transactionPayloads.mjs +26 -12
  78. package/tests/unit/messages/messages.test.js +12 -0
  79. package/tests/unit/messages/network/NetworkMessageBuilder.test.js +276 -0
  80. package/tests/unit/messages/network/NetworkMessageDirector.test.js +203 -0
  81. package/tests/unit/messages/state/applyStateMessageBuilder.complete.test.js +521 -0
  82. package/tests/unit/messages/state/applyStateMessageBuilder.partial.test.js +233 -0
  83. package/tests/unit/network/ConnectionManager.test.js +10 -7
  84. package/tests/unit/network/NetworkWalletFactory.test.js +14 -14
  85. package/tests/unit/network/networkModule.test.js +3 -2
  86. package/tests/unit/state/apply/addAdmin/addAdminHappyPathScenario.js +10 -6
  87. package/tests/unit/state/apply/addAdmin/addAdminScenarioHelpers.js +11 -8
  88. package/tests/unit/state/apply/addAdmin/state.apply.addAdmin.test.js +11 -7
  89. package/tests/unit/state/apply/addIndexer/addIndexerScenarioHelpers.js +18 -20
  90. package/tests/unit/state/apply/addWriter/addWriterScenarioHelpers.js +57 -48
  91. package/tests/unit/state/apply/addWriter/addWriterValidatorRewardScenario.js +2 -1
  92. package/tests/unit/state/apply/adminRecovery/adminRecoveryScenarioHelpers.js +72 -57
  93. package/tests/unit/state/apply/adminRecovery/state.apply.adminRecovery.test.js +3 -7
  94. package/tests/unit/state/apply/appendWhitelist/appendWhitelistScenarioHelpers.js +12 -14
  95. package/tests/unit/state/apply/balanceInitialization/balanceInitializationScenarioHelpers.js +18 -13
  96. package/tests/unit/state/apply/balanceInitialization/nodeEntryBalanceUpdateFailureScenario.js +2 -1
  97. package/tests/unit/state/apply/banValidator/banValidatorBanAndReWhitelistScenario.js +2 -1
  98. package/tests/unit/state/apply/banValidator/banValidatorScenarioHelpers.js +27 -30
  99. package/tests/unit/state/apply/bootstrapDeployment/bootstrapDeploymentDuplicateRegistrationScenario.js +2 -1
  100. package/tests/unit/state/apply/bootstrapDeployment/bootstrapDeploymentScenarioHelpers.js +24 -21
  101. package/tests/unit/state/apply/common/access-control/adminConsistencyMismatchScenario.js +5 -4
  102. package/tests/unit/state/apply/common/access-control/adminPublicKeyDecodeFailureScenario.js +4 -3
  103. package/tests/unit/state/apply/common/balances/base/requesterBalanceScenarioBase.js +2 -1
  104. package/tests/unit/state/apply/common/commonScenarioHelper.js +16 -16
  105. package/tests/unit/state/apply/common/payload-structure/initializationDisabledScenario.js +10 -5
  106. package/tests/unit/state/apply/common/payload-structure/invalidHashValidationScenario.js +2 -2
  107. package/tests/unit/state/apply/common/requester/requesterNodeEntryBufferMissingScenario.js +2 -1
  108. package/tests/unit/state/apply/common/requester/requesterNodeEntryDecodeFailureScenario.js +2 -1
  109. package/tests/unit/state/apply/common/validatorConsistency/base/validatorConsistencyScenarioBase.js +2 -1
  110. package/tests/unit/state/apply/common/validatorEntryValidation/base/validatorEntryValidationScenarioBase.js +2 -1
  111. package/tests/unit/state/apply/disableInitialization/disableInitializationScenarioHelpers.js +16 -9
  112. package/tests/unit/state/apply/removeIndexer/removeIndexerScenarioHelpers.js +6 -5
  113. package/tests/unit/state/apply/removeWriter/removeWriterScenarioHelpers.js +23 -19
  114. package/tests/unit/state/apply/transfer/transferDoubleSpendAcrossValidatorsScenario.js +45 -36
  115. package/tests/unit/state/apply/transfer/transferScenarioHelpers.js +48 -45
  116. package/tests/unit/state/apply/txOperation/txOperationScenarioHelpers.js +32 -29
  117. package/tests/unit/state/apply/txOperation/txOperationTransferFeeGuardScenarioFactory.js +2 -1
  118. package/tests/unit/state/stateModule.test.js +0 -1
  119. package/tests/unit/state/stateTestUtils.js +7 -3
  120. package/tests/unit/state/utils/address.test.js +3 -3
  121. package/tests/unit/state/utils/adminEntry.test.js +10 -9
  122. package/tests/unit/unit.test.js +1 -1
  123. package/tests/unit/utils/buffer/buffer.test.js +62 -1
  124. package/tests/unit/utils/check/adminControlOperation.test.js +3 -3
  125. package/tests/unit/utils/check/balanceInitializationOperation.test.js +2 -2
  126. package/tests/unit/utils/check/bootstrapDeploymentOperation.test.js +2 -3
  127. package/tests/unit/utils/check/common.test.js +7 -6
  128. package/tests/unit/utils/check/coreAdminOperation.test.js +3 -3
  129. package/tests/unit/utils/check/roleAccessOperation.test.js +3 -2
  130. package/tests/unit/utils/check/transactionOperation.test.js +3 -3
  131. package/tests/unit/utils/check/transferOperation.test.js +3 -3
  132. package/tests/unit/utils/fileUtils/readAddressesFromWhitelistFile.test.js +2 -1
  133. package/tests/unit/utils/fileUtils/readBalanceMigrationFile.test.js +2 -1
  134. package/tests/unit/utils/migrationUtils/validateAddressFromIncomingFile.test.js +7 -0
  135. package/tests/unit/utils/normalizers/normalizers.test.js +469 -0
  136. package/tests/unit/utils/protobuf/operationHelpers.test.js +120 -2
  137. package/tests/unit/utils/utils.test.js +0 -1
  138. package/rpc/rpc_server.mjs +0 -10
  139. package/src/core/network/messaging/NetworkMessages.js +0 -63
  140. package/src/core/network/messaging/handlers/GetRequestHandler.js +0 -112
  141. package/src/core/network/messaging/handlers/ResponseHandler.js +0 -108
  142. package/src/core/network/messaging/handlers/RoleOperationHandler.js +0 -116
  143. package/src/core/network/messaging/handlers/SubnetworkOperationHandler.js +0 -143
  144. package/src/core/network/messaging/handlers/TransferOperationHandler.js +0 -52
  145. package/src/core/network/messaging/routes/NetworkMessageRouter.js +0 -94
  146. package/src/core/network/messaging/validators/AdminResponse.js +0 -58
  147. package/src/core/network/messaging/validators/CustomNodeResponse.js +0 -46
  148. package/src/core/state/utils/indexerEntry.js +0 -105
  149. package/src/messages/base/StateBuilder.js +0 -25
  150. package/src/messages/completeStateMessages/CompleteStateMessageBuilder.js +0 -421
  151. package/src/messages/completeStateMessages/CompleteStateMessageDirector.js +0 -252
  152. package/src/messages/completeStateMessages/CompleteStateMessageOperations.js +0 -299
  153. package/src/messages/partialStateMessages/PartialStateMessageBuilder.js +0 -272
  154. package/src/messages/partialStateMessages/PartialStateMessageDirector.js +0 -137
  155. package/src/messages/partialStateMessages/PartialStateMessageOperations.js +0 -131
  156. package/src/utils/crypto.js +0 -11
  157. package/tests/integration/apply/addAdmin/addAdminBasic.test.js +0 -68
  158. package/tests/integration/apply/addAdmin/addAdminRecovery.test.js +0 -125
  159. package/tests/integration/apply/addIndexer.test.js +0 -237
  160. package/tests/integration/apply/addWhitelist.test.js +0 -53
  161. package/tests/integration/apply/addWriter.test.js +0 -244
  162. package/tests/integration/apply/apply.test.js +0 -19
  163. package/tests/integration/apply/banValidator.test.js +0 -109
  164. package/tests/integration/apply/postTx/invalidSubValues.test.js +0 -103
  165. package/tests/integration/apply/postTx/postTx.test.js +0 -222
  166. package/tests/integration/apply/removeIndexer.test.js +0 -128
  167. package/tests/integration/apply/removeWriter.test.js +0 -167
  168. package/tests/integration/apply/transfer.test.js +0 -81
  169. package/tests/integration/integration.test.js +0 -9
  170. package/tests/unit/messageOperations/assembleAddIndexerMessage.test.js +0 -21
  171. package/tests/unit/messageOperations/assembleAddWriterMessage.test.js +0 -16
  172. package/tests/unit/messageOperations/assembleAdminMessage.test.js +0 -69
  173. package/tests/unit/messageOperations/assembleBanWriterMessage.test.js +0 -16
  174. package/tests/unit/messageOperations/assemblePostTransaction.test.js +0 -442
  175. package/tests/unit/messageOperations/assembleRemoveIndexerMessage.test.js +0 -19
  176. package/tests/unit/messageOperations/assembleRemoveWriterMessage.test.js +0 -17
  177. package/tests/unit/messageOperations/assembleWhitelistMessages.test.js +0 -58
  178. package/tests/unit/messageOperations/commonsStateMessageOperationsTest.js +0 -277
  179. package/tests/unit/messageOperations/stateMessageOperations.test.js +0 -19
  180. package/tests/unit/state/utils/indexerEntry.test.js +0 -83
  181. package/tests/unit/state/utils/transaction.test.js +0 -97
  182. package/tests/unit/utils/crypto/createHash.test.js +0 -15
  183. /package/rpc/{constants.mjs → constants.js} +0 -0
  184. /package/rpc/{cors.mjs → cors.js} +0 -0
  185. /package/rpc/utils/{confirmedParameter.mjs → confirmedParameter.js} +0 -0
  186. /package/rpc/utils/{url.mjs → url.js} +0 -0
  187. /package/src/utils/{operations.js → applyOperations.js} +0 -0
package/src/index.js CHANGED
@@ -1,4 +1,3 @@
1
-
2
1
  /** @typedef {import('pear-interface')} */ /* global Pear */
3
2
  import ReadyResource from "ready-resource";
4
3
  import Corestore from "corestore";
@@ -6,36 +5,23 @@ import PeerWallet from "trac-wallet";
6
5
  import b4a from "b4a";
7
6
  import readline from "readline";
8
7
  import tty from "tty";
9
-
10
- import { sleep, getFormattedIndexersWithAddresses, isHexString, convertAdminCoreOperationPayloadToHex } from "./utils/helpers.js";
11
- import { verifyDag, printHelp, printWalletInfo, get_confirmed_tx_info, printBalance, get_unconfirmed_tx_info } from "./utils/cli.js";
12
- import CompleteStateMessageOperations from "./messages/completeStateMessages/CompleteStateMessageOperations.js";
13
- import { safeDecodeApplyOperation } from "./utils/protobuf/operationHelpers.js";
14
- import { bufferToAddress, isAddressValid } from "./core/state/utils/address.js";
8
+ import { sleep, isHexString } from "./utils/helpers.js";
9
+ import { verifyDag, printHelp, printWalletInfo, printBalance } from "./utils/cli.js";
10
+ import { applyStateMessageFactory } from "./messages/state/applyStateMessageFactory.js";
11
+ import { isAddressValid } from "./core/state/utils/address.js";
15
12
  import Network from "./core/network/Network.js";
16
13
  import Check from "./utils/check.js";
17
14
  import State from "./core/state/State.js";
18
- import PartialStateMessageOperations from "./messages/partialStateMessages/PartialStateMessageOperations.js";
19
15
  import {
20
16
  EventType,
21
17
  WHITELIST_SLEEP_INTERVAL,
22
18
  BOOTSTRAP_HEXSTRING_LENGTH,
23
- EntryType,
24
- OperationType,
25
- MAX_MESSAGE_SEND_ATTEMPTS,
26
19
  CustomEventType,
27
20
  BALANCE_MIGRATION_SLEEP_INTERVAL,
28
21
  WHITELIST_MIGRATION_DIR
29
22
  } from "./utils/constants.js";
30
- import partialStateMessageOperations from "./messages/partialStateMessages/PartialStateMessageOperations.js";
31
23
  import { randomBytes } from "hypercore-crypto";
32
- import { decimalStringToBigInt, bigIntTo16ByteBuffer, bufferToBigInt, bigIntToDecimalString, licenseBufferToBigInt } from "./utils/amountSerialization.js"
33
- import { ZERO_WK } from "./utils/buffer.js";
34
- import { normalizeDecodedPayloadForJson, normalizeTransferOperation, normalizeTransactionOperation } from "./utils/normalizers.js"
35
- import PartialTransfer from "./core/network/messaging/validators/PartialTransfer.js";
36
- import { blake3Hash } from "./utils/crypto.js";
37
- import deploymentEntryUtils from "./core/state/utils/deploymentEntry.js";
38
- import PartialTransaction from "./core/network/messaging/validators/PartialTransaction.js";
24
+ import { decimalStringToBigInt, bigIntTo16ByteBuffer, bufferToBigInt, bigIntToDecimalString } from "./utils/amountSerialization.js"
39
25
  import fileUtils from './utils/fileUtils.js';
40
26
  import migrationUtils from './utils/migrationUtils.js';
41
27
  import {
@@ -57,131 +43,76 @@ import {
57
43
  getLicenseAddressCommand,
58
44
  getLicenseCountCommand
59
45
  } from "./utils/cliCommands.js";
46
+ import {safeEncodeApplyOperation} from "./utils/protobuf/operationHelpers.js";
47
+
60
48
  export class MainSettlementBus extends ReadyResource {
61
- // internal attributes
62
- #options;
63
- #stores_directory;
64
- #key_pair_path;
65
- #bootstrap;
66
- #channel;
67
49
  #store;
68
- #enable_wallet;
69
50
  #wallet;
70
51
  #network;
71
52
  #readline_instance;
72
- #enable_validator_observer;
73
- #enable_role_requester;
74
53
  #state;
75
54
  #isClosing = false;
76
- #is_admin_mode;
77
- #partialTransferValidator;
78
- #partialTransactionValidator;
79
- #maxRetries
55
+ #config
80
56
 
81
- constructor(options = {}) {
57
+ /**
58
+ * @param {object} config
59
+ **/
60
+ constructor(config) {
82
61
  super();
83
- this.#options = options;
84
- this.#stores_directory = options.stores_directory;
85
- this.#key_pair_path = `${this.#stores_directory}${options.store_name}/db/keypair.json`;
86
- this.#enable_wallet = options.enable_wallet !== false;
87
- this.enable_interactive_mode = options.enable_interactive_mode !== false;
88
- this.#is_admin_mode = options.store_name === 'admin';
89
- this.#enable_role_requester =
90
- options.enable_role_requester !== undefined
91
- ? options.enable_role_requester
92
- : false;
93
- this.#enable_validator_observer =
94
- options.enable_validator_observer !== undefined
95
- ? options.enable_validator_observer
96
- : true;
97
- this.#bootstrap = options.bootstrap
98
- ? b4a.from(options.bootstrap, "hex")
99
- : null;
100
-
101
- if (!options.channel) {
102
- throw new Error(
103
- "MainSettlementBus: Channel is required. Application cannot start without channel."
104
- );
105
- }
106
-
107
- this.#channel = b4a.alloc(32).fill(options.channel);
108
- this.#store = new Corestore(this.#stores_directory + options.store_name);
109
- this.#wallet = new PeerWallet(options);
62
+ this.#config = config
63
+ this.#store = new Corestore(this.#config.storesFullPath);
64
+ this.#wallet = new PeerWallet({ networkPrefix: this.#config.addressPrefix });
110
65
  this.#readline_instance = null;
111
- this.#maxRetries = Number(options.max_retries) ? options.max_retries : MAX_MESSAGE_SEND_ATTEMPTS
112
66
 
113
- if (this.enable_interactive_mode !== false) {
67
+ if (this.#config.enableInteractiveMode) {
114
68
  try {
115
69
  this.#readline_instance = readline.createInterface({
116
70
  input: new tty.ReadStream(0),
117
71
  output: new tty.WriteStream(1),
118
72
  });
119
- } catch (e) {
120
- }
73
+ } catch (_ignored) {}
121
74
  }
122
75
 
123
- this.check = new Check();
124
- }
125
-
126
- get options() {
127
- return this.#options;
128
- }
129
-
130
- get stores_directory() {
131
- return this.#stores_directory;
132
- }
133
-
134
- get key_pair_path() {
135
- return this.#key_pair_path;
76
+ this.check = new Check(this.#config);
136
77
  }
137
78
 
138
- get bootstrap() {
139
- return this.#bootstrap;
79
+ get config() {
80
+ return this.#config
140
81
  }
141
82
 
142
83
  get state() {
143
84
  return this.#state;
144
85
  }
145
86
 
146
- get channel() {
147
- return this.#channel;
148
- }
149
-
150
87
  get network() {
151
88
  return this.#network;
152
89
  }
153
90
 
154
- // This can be null if enable_wallet is false
155
91
  get wallet() {
92
+ if (!this.#config.enableWallet) {
93
+ return undefined;
94
+ }
156
95
  return this.#wallet;
157
96
  }
158
97
 
159
- get tracPublicKey() {
160
- if (!this.#wallet) return null;
161
- return this.#wallet.publicKey;
162
- }
163
-
164
98
  async _open() {
165
- if (this.#enable_wallet) {
99
+ if (this.#config.enableWallet) {
166
100
  await this.#wallet.initKeyPair(
167
- this.key_pair_path,
101
+ this.#config.keyPairPath,
168
102
  this.#readline_instance
169
103
  );
170
104
  }
171
- this.#state = new State(this.#store, this.bootstrap, this.#wallet, this.options);
172
- this.#network = new Network(this.#state, this.#channel, this.#wallet.address, this.options);
105
+ this.#state = new State(this.#store, this.#wallet, this.#config);
106
+ this.#network = new Network(this.#state, this.#config, this.#wallet.address);
173
107
 
174
108
  await this.#state.ready();
175
109
  await this.#network.ready();
176
- this.#stateEventsListener();
110
+ await this.#stateEventsListener();
177
111
 
178
- if (this.#enable_wallet) {
179
- printWalletInfo(this.#wallet.address, this.#state.writingKey, this.#state, this.#enable_wallet);
112
+ if (this.#config.enableWallet) {
113
+ printWalletInfo(this.#wallet.address, this.#state.writingKey, this.#state, this.#config.enableWallet);
180
114
  }
181
115
 
182
- this.#partialTransferValidator = new PartialTransfer(this.state);
183
- this.#partialTransactionValidator = new PartialTransaction(this.state);
184
-
185
116
  await this.#network.replicate(
186
117
  this.#state,
187
118
  this.#store,
@@ -191,12 +122,14 @@ export class MainSettlementBus extends ReadyResource {
191
122
  const adminEntry = await this.#state.getAdminEntry();
192
123
  await this.#setUpRoleAutomatically(adminEntry);
193
124
 
125
+
126
+
194
127
  console.log(`isIndexer: ${this.#state.isIndexer()}`);
195
128
  console.log(`isWriter: ${this.#state.isWritable()}`);
196
129
  console.log("MSB Unsigned Length:", this.#state.getUnsignedLength());
197
130
  console.log("MSB Signed Length:", this.#state.getSignedLength());
198
131
 
199
- await printBalance(this.#wallet.address, this.#state, this.#enable_wallet);
132
+ await printBalance(this.#wallet.address, this.#state, this.#config.enableWallet);
200
133
  }
201
134
 
202
135
  async _close() {
@@ -239,56 +172,11 @@ export class MainSettlementBus extends ReadyResource {
239
172
  }
240
173
 
241
174
  async broadcastPartialTransaction(partialTransactionPayload) {
242
- await this.#network.validatorMessageOrchestrator.send(partialTransactionPayload);
243
- }
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 };
175
+ return await this.#network.validatorMessageOrchestrator.send(partialTransactionPayload);
288
176
  }
289
177
 
290
178
  async #setUpRoleAutomatically() {
291
- if (!this.#state.isWritable() && this.#enable_role_requester) {
179
+ if (!this.#state.isWritable() && this.#config.enableRoleRequester) {
292
180
  console.log("Requesting writer role... This may take a moment.");
293
181
  await this.#requestWriterRole(false);
294
182
  setTimeout(async () => {
@@ -299,15 +187,12 @@ export class MainSettlementBus extends ReadyResource {
299
187
  }
300
188
 
301
189
  #isAdmin(adminEntry) {
302
- if (!adminEntry || this.#enable_wallet === false) return false;
303
- return !!(
304
- this.#wallet.address === adminEntry.address &&
305
- b4a.equals(adminEntry.wk, this.#state.writingKey)
306
- );
190
+ if (!adminEntry || !this.#config.enableWallet) return false;
191
+ return this.#wallet.address === adminEntry.address && b4a.equals(adminEntry.wk, this.#state.writingKey)
307
192
  }
308
193
 
309
194
  async #isAllowedToRequestRole(adminEntry, nodeEntry) {
310
- return nodeEntry && nodeEntry.isWhitelisted && !this.#isAdmin(adminEntry);
195
+ return nodeEntry?.isWhitelisted && !this.#isAdmin(adminEntry);
311
196
  }
312
197
 
313
198
  async #stateEventsListener() {
@@ -338,18 +223,15 @@ export class MainSettlementBus extends ReadyResource {
338
223
  });
339
224
 
340
225
  this.#state.base.on(EventType.UNWRITABLE, async () => {
341
- if (this.#enable_wallet === false) {
342
- console.log("Current node is unwritable");
343
- return;
344
- }
345
226
  console.log("Current node is unwritable");
346
227
  });
347
228
  }
348
229
 
349
230
  async #handleAdminCreation() {
350
- if (this.#enable_wallet === false) {
231
+ if (!this.#config.enableWallet) {
351
232
  throw new Error("Can not initialize an admin - wallet is not enabled.");
352
233
  }
234
+
353
235
  const adminEntry = await this.#state.getAdminEntry();
354
236
 
355
237
  if (adminEntry) {
@@ -365,25 +247,29 @@ export class MainSettlementBus extends ReadyResource {
365
247
  "Can not initialize an admin - writing key is not initialized."
366
248
  );
367
249
  }
368
- if (!b4a.equals(this.#state.writingKey, this.#bootstrap)) {
250
+ if (!b4a.equals(this.#state.writingKey, this.#config.bootstrap)) {
369
251
  throw new Error(
370
252
  "Can not initialize an admin - bootstrap is not equal to writing key."
371
253
  );
372
254
  }
373
255
 
374
- const txValidity = await blake3Hash(this.bootstrap);
375
- const addAdminMessage = await CompleteStateMessageOperations.assembleAddAdminMessage(
376
- this.#wallet,
377
- this.#state.writingKey,
378
- txValidity
379
- );
256
+ const txValidity = await PeerWallet.blake3(this.#config.bootstrap);
257
+ const addAdminMessage = await applyStateMessageFactory(this.#wallet, this.#config)
258
+ .buildCompleteAddAdminMessage(
259
+ this.#wallet.address,
260
+ this.#state.writingKey,
261
+ txValidity,
262
+ )
263
+ const encodedPayload = safeEncodeApplyOperation(addAdminMessage);
380
264
 
381
- await this.#state.append(addAdminMessage);
265
+ await this.#state.append(encodedPayload);
382
266
  }
267
+
383
268
  async #handleAdminRecovery() {
384
- if (this.#enable_wallet === false) {
269
+ if (!this.#config.enableWallet) {
385
270
  throw new Error("Can not initialize an admin - wallet is not enabled.");
386
271
  }
272
+
387
273
  const adminEntry = await this.#state.getAdminEntry();
388
274
 
389
275
  if (!adminEntry) {
@@ -404,22 +290,28 @@ export class MainSettlementBus extends ReadyResource {
404
290
  }
405
291
 
406
292
  const txValidity = await this.#state.getIndexerSequenceState();
407
- const adminRecoveryMessage = await partialStateMessageOperations.assembleAdminRecoveryMessage(
408
- this.#wallet,
409
- this.#state.writingKey.toString('hex'),
410
- txValidity.toString('hex')
411
- );
293
+ const adminRecoveryMessage = await applyStateMessageFactory(this.#wallet, this.#config)
294
+ .buildPartialAdminRecoveryMessage(
295
+ this.#wallet.address,
296
+ this.#state.writingKey,
297
+ txValidity,
298
+ "json"
299
+ )
300
+
301
+ const success = await this.broadcastPartialTransaction(adminRecoveryMessage);
302
+
303
+ if (!success) {
304
+ throw new Error("Failed to broadcast transaction after multiple attempts.");
305
+ }
412
306
 
413
- await this.broadcastPartialTransaction(adminRecoveryMessage);
414
307
  console.info(`Transaction hash: ${adminRecoveryMessage.rao.tx}`);
415
308
  }
416
309
 
417
310
  async #handleWhitelistOperations() {
418
- if (this.#enable_wallet === false) {
311
+ if (!this.#config.enableWallet) {
419
312
  throw new Error("Cannot perform whitelisting - wallet is not enabled.");
420
313
  }
421
314
 
422
- if (this.#enable_wallet === false) return;
423
315
  const adminEntry = await this.#state.getAdminEntry();
424
316
 
425
317
  if (!this.#isAdmin(adminEntry)) {
@@ -430,7 +322,7 @@ export class MainSettlementBus extends ReadyResource {
430
322
  const addresses = await fileUtils.readAddressesFromWhitelistFile();
431
323
 
432
324
  for (const address of addresses) {
433
- await migrationUtils.validateAddressFromIncomingFile(this.#state, address, adminEntry);
325
+ await migrationUtils.validateAddressFromIncomingFile(this.#state, this.#config, address, adminEntry);
434
326
  }
435
327
  await fileUtils.validateWhitelistMigrationData(addresses, WHITELIST_MIGRATION_DIR);
436
328
  const migrationNumber = await fileUtils.getNextMigrationNumber(WHITELIST_MIGRATION_DIR);
@@ -438,11 +330,13 @@ export class MainSettlementBus extends ReadyResource {
438
330
 
439
331
  for (const addressToWhitelist of addresses) {
440
332
  const txValidity = await this.#state.getIndexerSequenceState();
441
- const encodedPayload = await CompleteStateMessageOperations.assembleAppendWhitelistMessages(
442
- this.#wallet,
443
- txValidity,
444
- addressToWhitelist
445
- );
333
+ const appendWhitelistMessage = await applyStateMessageFactory(this.#wallet, this.#config)
334
+ .buildCompleteAppendWhitelistMessage(
335
+ this.#wallet.address,
336
+ addressToWhitelist,
337
+ txValidity,
338
+ )
339
+ const encodedPayload = safeEncodeApplyOperation(appendWhitelistMessage)
446
340
  messages.set(addressToWhitelist, encodedPayload);
447
341
  }
448
342
 
@@ -476,12 +370,13 @@ export class MainSettlementBus extends ReadyResource {
476
370
  }
477
371
 
478
372
  async #requestWriterRole(toAdd) {
479
- if (this.#enable_wallet === false) {
373
+ if (!this.#config.enableWallet) {
480
374
  throw new Error("Cannot request writer role - wallet is not enabled");
481
375
  }
376
+
482
377
  const adminEntry = await this.#state.getAdminEntry();
483
378
  const nodeEntry = await this.#state.getNodeEntry(this.#wallet.address);
484
- const isAlreadyWriter = !!(nodeEntry && nodeEntry.isWriter === true);
379
+ const isAlreadyWriter = !!nodeEntry?.isWriter;
485
380
 
486
381
  if (toAdd) {
487
382
  if (isAlreadyWriter) {
@@ -515,13 +410,21 @@ export class MainSettlementBus extends ReadyResource {
515
410
  }
516
411
 
517
412
  const txValidity = await this.#state.getIndexerSequenceState();
518
- const assembledMessage = await PartialStateMessageOperations.assembleAddWriterMessage(
519
- this.#wallet,
520
- this.#state.writingKey.toString('hex'),
521
- txValidity.toString('hex')
522
- )
523
413
 
524
- await this.broadcastPartialTransaction(assembledMessage);
414
+ const assembledMessage = await applyStateMessageFactory(this.#wallet, this.#config)
415
+ .buildPartialAddWriterMessage(
416
+ this.#wallet.address,
417
+ this.#state.writingKey,
418
+ txValidity,
419
+ 'json'
420
+ )
421
+
422
+ const success = await this.broadcastPartialTransaction(assembledMessage);
423
+
424
+ if (!success) {
425
+ throw new Error("Failed to broadcast transaction after multiple attempts.");
426
+ }
427
+
525
428
  console.info(`Transaction hash: ${assembledMessage.rao.tx}`);
526
429
  return;
527
430
  }
@@ -542,21 +445,27 @@ export class MainSettlementBus extends ReadyResource {
542
445
  }
543
446
 
544
447
  const txValidity = await this.#state.getIndexerSequenceState();
545
- const assembledMessage = await PartialStateMessageOperations.assembleRemoveWriterMessage(
546
- this.#wallet,
547
- nodeEntry.wk.toString('hex'),
548
- txValidity.toString('hex')
549
- )
448
+ const assembledMessage = await applyStateMessageFactory(this.#wallet, this.#config)
449
+ .buildPartialRemoveWriterMessage(
450
+ this.#wallet.address,
451
+ nodeEntry.wk,
452
+ txValidity,
453
+ "json"
454
+ )
455
+
456
+ const success = await this.broadcastPartialTransaction(assembledMessage);
457
+
458
+ if (!success) {
459
+ throw new Error("Failed to broadcast transaction after multiple attempts.");
460
+ }
550
461
 
551
- await this.broadcastPartialTransaction(assembledMessage);
552
462
  console.info(`Transaction hash: ${assembledMessage.rao.tx}`);
553
- return;
554
463
  }
555
464
 
556
- async #updateIndexerRole(address, toAdd) {
557
- if (this.#enable_wallet === false) {
465
+ async #updateWriterToIndexerRole(addressToUpdate, toAdd) {
466
+ if (!this.#config.enableWallet) {
558
467
  throw new Error(
559
- `Can not request indexer role for: ${address} - wallet is not enabled.`
468
+ `Can not request indexer role for: ${addressToUpdate} - wallet is not enabled.`
560
469
  );
561
470
  }
562
471
 
@@ -564,29 +473,29 @@ export class MainSettlementBus extends ReadyResource {
564
473
 
565
474
  if (!adminEntry) {
566
475
  throw new Error(
567
- `Can not request indexer role for: ${address} - admin entry has not been initialized.`
476
+ `Can not request indexer role for: ${addressToUpdate} - admin entry has not been initialized.`
568
477
  );
569
478
  }
570
479
 
571
- if (!isAddressValid(address)) {
480
+ if (!isAddressValid(addressToUpdate, this.#config.addressPrefix)) {
572
481
  throw new Error(
573
- `Can not request indexer role for: ${address} - invalid address.`
482
+ `Can not request indexer role for: ${addressToUpdate} - invalid address.`
574
483
  );
575
484
  }
576
485
 
577
486
  if (!this.#isAdmin(adminEntry) && !this.#state.isWritable()) {
578
487
  throw new Error(
579
- `Can not request indexer role for: ${address} - You are not an admin or writer.`
488
+ `Can not request indexer role for: ${addressToUpdate} - You are not an admin or writer.`
580
489
  );
581
490
  }
582
- const nodeEntry = await this.#state.getNodeEntry(address);
491
+ const nodeEntry = await this.#state.getNodeEntry(addressToUpdate);
583
492
  if (!nodeEntry) {
584
493
  throw new Error(
585
- `Can not request indexer role for: ${address} - node entry has not been not initialized.`
494
+ `Can not request indexer role for: ${addressToUpdate} - node entry has not been not initialized.`
586
495
  );
587
496
  }
588
497
 
589
- const indexerNodeEntry = await this.#state.getNodeEntry(address);
498
+ const indexerNodeEntry = await this.#state.getNodeEntry(addressToUpdate);
590
499
  const indexerListHasAddress = await this.#state.isWkInIndexersEntry(
591
500
  indexerNodeEntry.wk,
592
501
  );
@@ -594,7 +503,7 @@ export class MainSettlementBus extends ReadyResource {
594
503
  if (toAdd) {
595
504
  if (indexerListHasAddress) {
596
505
  throw new Error(
597
- `Cannot update indexer role for: ${address} - address is already in indexers list.`
506
+ `Cannot update indexer role for: ${addressToUpdate} - address is already in indexers list.`
598
507
  );
599
508
  }
600
509
 
@@ -606,72 +515,90 @@ export class MainSettlementBus extends ReadyResource {
606
515
 
607
516
  if (!canAddIndexer) {
608
517
  throw new Error(
609
- `Can not request indexer role for: ${address} - node is not whitelisted, not a writer or already an indexer.`
518
+ `Can not request indexer role for: ${addressToUpdate} - node is not whitelisted, not a writer or already an indexer.`
610
519
  );
611
520
  }
612
521
  const txValidity = await this.#state.getIndexerSequenceState();
613
- const assembledAddIndexerMessage = await CompleteStateMessageOperations.assembleAddIndexerMessage(this.#wallet, address, txValidity);
614
- await this.#state.append(assembledAddIndexerMessage);
522
+
523
+ const assembledAddIndexerMessage = await applyStateMessageFactory(this.#wallet, this.#config)
524
+ .buildCompleteAddIndexerMessage(
525
+ this.#wallet.address,
526
+ addressToUpdate,
527
+ txValidity,
528
+ )
529
+
530
+ const encodedPayload = safeEncodeApplyOperation(assembledAddIndexerMessage);
531
+
532
+ await this.#state.append(encodedPayload);
615
533
  } else {
616
534
  const canRemoveIndexer =
617
535
  !toAdd && nodeEntry.isIndexer && indexerListHasAddress;
618
536
 
619
537
  if (!canRemoveIndexer) {
620
538
  throw new Error(
621
- `Can not remove indexer role for: ${address} - node is not an indexer or address is not in indexers list.`
539
+ `Can not remove indexer role for: ${addressToUpdate} - node is not an indexer or address is not in indexers list.`
622
540
  );
623
541
  }
624
542
  const txValidity = await this.#state.getIndexerSequenceState();
625
- const assembledRemoveIndexer = await CompleteStateMessageOperations.assembleRemoveIndexerMessage(this.#wallet, address, txValidity);
626
- await this.#state.append(assembledRemoveIndexer);
543
+ const assembledRemoveIndexerMessage = await applyStateMessageFactory(this.#wallet, this.#config)
544
+ .buildCompleteRemoveIndexerMessage(
545
+ this.#wallet.address,
546
+ addressToUpdate,
547
+ txValidity,
548
+ )
549
+ const encodedPayload = safeEncodeApplyOperation(assembledRemoveIndexerMessage);
550
+
551
+ await this.#state.append(encodedPayload);
627
552
  }
628
553
  }
629
554
 
630
- async #banValidator(address) {
631
- if (this.#enable_wallet === false) {
555
+ async #banValidator(addresstToBan) {
556
+ if (!this.#config.enableWallet) {
632
557
  throw new Error(
633
- `Can not ban writer with address: ${address} - wallet is not enabled.`
558
+ `Can not ban writer with address: ${addresstToBan} - wallet is not enabled.`
634
559
  );
635
560
  }
636
561
  const adminEntry = await this.#state.getAdminEntry();
637
562
 
638
563
  if (!adminEntry) {
639
564
  throw new Error(
640
- `Can not ban writer with address: ${address} - admin entry has not been initialized.`
565
+ `Can not ban writer with address: ${addresstToBan} - admin entry has not been initialized.`
641
566
  );
642
567
  }
643
568
 
644
- if (!isAddressValid(address)) {
569
+ if (!isAddressValid(addresstToBan, this.#config.addressPrefix)) {
645
570
  throw new Error(
646
- `Can not ban writer with address: ${address} - invalid address.`
571
+ `Can not ban writer with address: ${addresstToBan} - invalid address.`
647
572
  );
648
573
  }
649
574
 
650
575
  if (!this.#isAdmin(adminEntry)) {
651
576
  throw new Error(
652
- `Can not ban writer with address: ${address} - You are not an admin.`
577
+ `Can not ban writer with address: ${addresstToBan} - You are not an admin.`
653
578
  );
654
579
  }
655
580
 
656
- const isWhitelisted = await this.#state.isAddressWhitelisted(address);
657
- const nodeEntry = await this.#state.getNodeEntry(address);
581
+ const isWhitelisted = await this.#state.isAddressWhitelisted(addresstToBan);
582
+ const nodeEntry = await this.#state.getNodeEntry(addresstToBan);
658
583
 
659
584
  if (!isWhitelisted || null === nodeEntry || nodeEntry.isIndexer === true) {
660
585
  throw new Error(
661
- `Can not ban writer with address: ${address} - node is not whitelisted or is an indexer.`
586
+ `Can not ban writer with address: ${addresstToBan} - node is not whitelisted or is an indexer.`
662
587
  );
663
588
  }
664
589
  const txValidity = await this.#state.getIndexerSequenceState();
665
- const assembledBanValidatorMessage = await CompleteStateMessageOperations.assembleBanWriterMessage(
666
- this.#wallet,
667
- address,
668
- txValidity
669
- );
670
- await this.#state.append(assembledBanValidatorMessage);
590
+ const assembledBanValidatorMessage = await applyStateMessageFactory(this.#wallet, this.#config)
591
+ .buildCompleteBanWriterMessage(
592
+ this.#wallet.address,
593
+ addresstToBan,
594
+ txValidity,
595
+ )
596
+ const encodedPayload = safeEncodeApplyOperation(assembledBanValidatorMessage)
597
+ await this.#state.append(encodedPayload);
671
598
  }
672
599
 
673
600
  async #deployBootstrap(externalBootstrap, channel) {
674
- if (this.#enable_wallet === false) {
601
+ if (!this.#config.enableWallet) {
675
602
  throw new Error(
676
603
  "Can not perform bootstrap deployment - wallet is not enabled."
677
604
  );
@@ -719,7 +646,7 @@ export class MainSettlementBus extends ReadyResource {
719
646
  );
720
647
  }
721
648
 
722
- if (externalBootstrap === this.bootstrap.toString("hex")) {
649
+ if (externalBootstrap === this.#config.bootstrap.toString("hex")) {
723
650
  throw new Error(
724
651
  `Can not perform bootstrap deployment - bootstrap ${externalBootstrap} is equal to MSB bootstrap!`
725
652
  );
@@ -740,14 +667,22 @@ export class MainSettlementBus extends ReadyResource {
740
667
  }
741
668
 
742
669
  const txValidity = await this.#state.getIndexerSequenceState();
743
- const payload = await PartialStateMessageOperations.assembleBootstrapDeploymentMessage(
744
- this.#wallet,
745
- externalBootstrap,
746
- channel,
747
- txValidity.toString('hex')
748
- );
749
670
 
750
- await this.broadcastPartialTransaction(payload);
671
+ const payload = await applyStateMessageFactory(this.#wallet, this.#config)
672
+ .buildPartialBootstrapDeploymentMessage(
673
+ this.#wallet.address,
674
+ externalBootstrap,
675
+ channel,
676
+ txValidity,
677
+ "json"
678
+ )
679
+
680
+ const success = await this.broadcastPartialTransaction(payload);
681
+
682
+ if (!success) {
683
+ throw new Error("Failed to broadcast transaction after multiple attempts.");
684
+ }
685
+
751
686
  console.info(`Transaction hash: ${payload.bdo.tx}`);
752
687
  console.log(`Bootstrap ${externalBootstrap} deployment requested on channel ${channel}`);
753
688
  console.log('Bootstrap Deployment Fee Details:');
@@ -756,32 +691,8 @@ export class MainSettlementBus extends ReadyResource {
756
691
 
757
692
  }
758
693
 
759
- async #handleAddIndexerOperation(address) {
760
- await this.#updateIndexerRole(address, true);
761
- }
762
-
763
- async #handleRemoveIndexerOperation(address) {
764
- await this.#updateIndexerRole(address, false);
765
- }
766
-
767
- async #handleAddWriterOperation() {
768
- await this.#requestWriterRole(true);
769
- }
770
-
771
- async #handleRemoveWriterOperation() {
772
- await this.#requestWriterRole(false);
773
- }
774
-
775
- async #handleBanValidatorOperation(address) {
776
- await this.#banValidator(address);
777
- }
778
-
779
- async #handleBootstrapDeploymentOperation(bootstrapHex, channel) {
780
- await this.#deployBootstrap(bootstrapHex, channel);
781
- }
782
-
783
- async #handleTransferOperation(address, amount) {
784
- if (this.#enable_wallet === false) {
694
+ async #handleTransferOperation(recipientAddress, amount) {
695
+ if (!this.#config.enableWallet) {
785
696
  throw new Error(
786
697
  "Can not perform transfer - wallet is not enabled."
787
698
  );
@@ -793,7 +704,7 @@ export class MainSettlementBus extends ReadyResource {
793
704
  );
794
705
  }
795
706
 
796
- if (!isAddressValid(address)) {
707
+ if (!isAddressValid(recipientAddress, this.#config.addressPrefix)) {
797
708
  throw new Error("Invalid recipient address");
798
709
  }
799
710
 
@@ -818,7 +729,7 @@ export class MainSettlementBus extends ReadyResource {
818
729
  const fee = this.#state.getFee();
819
730
  const feeBigInt = bufferToBigInt(fee);
820
731
  const senderBalance = bufferToBigInt(senderEntry.balance);
821
- const isSelfTransfer = address === this.#wallet.address;
732
+ const isSelfTransfer = recipientAddress === this.#wallet.address;
822
733
  const totalDeductedAmount = isSelfTransfer ? feeBigInt : amountBigInt + feeBigInt;
823
734
 
824
735
  if (!(senderBalance >= totalDeductedAmount)) {
@@ -826,15 +737,15 @@ export class MainSettlementBus extends ReadyResource {
826
737
  }
827
738
 
828
739
  const txValidity = await this.#state.getIndexerSequenceState();
829
- const payload = await PartialStateMessageOperations.assembleTransferOperationMessage(
830
- this.#wallet,
831
- address,
832
- amountBuffer.toString('hex'),
833
- txValidity.toString('hex'),
740
+ const payload = await applyStateMessageFactory(this.#wallet, this.#config)
741
+ .buildPartialTransferOperationMessage(
742
+ this.#wallet.address,
743
+ recipientAddress,
744
+ amountBuffer,
745
+ txValidity,
746
+ "json"
834
747
  )
835
748
 
836
- await this.broadcastPartialTransaction(payload);
837
-
838
749
  const expectedNewBalance = senderBalance - totalDeductedAmount;
839
750
  console.info('Transfer Details:');
840
751
  console.info(`Transaction hash ${payload.tro.tx}`)
@@ -848,9 +759,16 @@ export class MainSettlementBus extends ReadyResource {
848
759
  console.info(`Total: ${bigIntToDecimalString(totalDeductedAmount)}`);
849
760
  }
850
761
  console.log(`Expected Balance After Transfer: ${bigIntToDecimalString(expectedNewBalance)}`);
762
+ const success = await this.broadcastPartialTransaction(payload);
763
+ if (!success) {
764
+ throw new Error("Failed to broadcast transfer transaction after multiple attempts.");
765
+ } else {
766
+ console.log(`Transfer transaction broadcasted successfully. Tx hash: ${payload.tro.tx}`);
767
+ }
768
+
851
769
  }
852
770
 
853
- async #handleBalanceMigrationOperation() {
771
+ async #balanceMigrationOperation() {
854
772
 
855
773
  const isInitDisabled = await this.#state.isInitalizationDisabled()
856
774
 
@@ -858,7 +776,7 @@ export class MainSettlementBus extends ReadyResource {
858
776
  throw new Error("Can not initialize balance - balance initialization is disabled.");
859
777
  }
860
778
 
861
- if (this.#enable_wallet === false) {
779
+ if (!this.#config.enableWallet) {
862
780
  throw new Error("Can not initialize an admin - wallet is not enabled.");
863
781
  }
864
782
 
@@ -880,14 +798,14 @@ export class MainSettlementBus extends ReadyResource {
880
798
  throw new Error("Can not initialize an admin - writing key is not initialized.");
881
799
  }
882
800
 
883
- if (!b4a.equals(this.#state.writingKey, this.#bootstrap)) {
801
+ if (!b4a.equals(this.#state.writingKey, this.#config.bootstrap)) {
884
802
  throw new Error("Can not initialize an admin - bootstrap is not equal to writing key.");
885
803
  }
886
804
 
887
805
  const { addressBalancePair, totalBalance, totalAddresses, addresses } = await fileUtils.readBalanceMigrationFile();
888
806
 
889
807
  for (let i = 0; i < addresses.length; i++) {
890
- await migrationUtils.validateAddressFromIncomingFile(this.#state, addresses[i].address, adminEntry);
808
+ await migrationUtils.validateAddressFromIncomingFile(this.#state, this.#config, addresses[i].address, adminEntry);
891
809
  }
892
810
 
893
811
  await fileUtils.validateBalanceMigrationData(addresses);
@@ -895,11 +813,18 @@ export class MainSettlementBus extends ReadyResource {
895
813
  await fileUtils.createMigrationEntryFile(addressBalancePair, migrationNumber);
896
814
 
897
815
  const txValidity = await this.#state.getIndexerSequenceState();
898
- const messages = await CompleteStateMessageOperations.assembleBalanceInitializationMessages(
899
- this.#wallet,
900
- txValidity,
901
- addressBalancePair,
902
- );
816
+
817
+ let messages = [];
818
+
819
+ for (const [recipientAddress, amountBuffer] of addressBalancePair) {
820
+ const payload = await applyStateMessageFactory(this.#wallet, this.#config).buildCompleteBalanceInitializationMessage(
821
+ this.#wallet.address,
822
+ recipientAddress,
823
+ amountBuffer,
824
+ txValidity,
825
+ )
826
+ messages.push(safeEncodeApplyOperation(payload));
827
+ }
903
828
 
904
829
  console.log(`Total balance to migrate: ${bigIntToDecimalString(totalBalance)} across ${totalAddresses} addresses.`);
905
830
 
@@ -946,9 +871,13 @@ export class MainSettlementBus extends ReadyResource {
946
871
  }
947
872
 
948
873
  async #disableInitialization() {
949
- if (this.#enable_wallet === false) {
874
+ if (!this.#config.enableWallet) {
950
875
  throw new Error("Can not initialize an admin - wallet is not enabled.");
951
876
  }
877
+ const isInitDisabled = await this.#state.isInitalizationDisabled();
878
+ if (isInitDisabled) {
879
+ throw new Error("Can not disable initialization - it is already disabled.");
880
+ }
952
881
  const adminEntry = await this.#state.getAdminEntry();
953
882
 
954
883
  if (!adminEntry) {
@@ -958,22 +887,31 @@ export class MainSettlementBus extends ReadyResource {
958
887
  if (!this.#isAdmin(adminEntry)) {
959
888
  throw new Error('Cannot perform whitelisting - you are not the admin!.');
960
889
  }
961
- // add more checks
890
+ if (!this.#wallet) {
891
+ throw new Error("Can not initialize an admin - wallet is not initialized.");
892
+ }
893
+ if (!this.#state.writingKey) {
894
+ throw new Error("Can not initialize an admin - writing key is not initialized.");
895
+ }
962
896
  const txValidity = await this.#state.getIndexerSequenceState();
963
- const payload = await CompleteStateMessageOperations.assembleDisableInitializationMessage(
964
- this.#wallet,
965
- this.#state.writingKey,
966
- txValidity,
967
- )
897
+
898
+
899
+ const payload = await applyStateMessageFactory(this.#wallet, this.#config)
900
+ .buildCompleteDisableInitializationMessage(
901
+ this.#wallet.address,
902
+ this.#state.writingKey,
903
+ txValidity,
904
+ )
968
905
  console.log('Disabling initialization...');
969
- await this.#state.append(payload);
906
+ const encodedPayload = safeEncodeApplyOperation(payload);
907
+ await this.#state.append(encodedPayload);
970
908
  }
971
909
 
972
910
  async interactiveMode() {
973
911
  if (this.#readline_instance === null) return;
974
912
  const rl = this.#readline_instance;
975
913
 
976
- printHelp(this.#is_admin_mode);
914
+ printHelp(this.#config.isAdminMode);
977
915
 
978
916
  rl.on("line", async (input) => {
979
917
  try {
@@ -989,35 +927,30 @@ export class MainSettlementBus extends ReadyResource {
989
927
 
990
928
  async handleCommand(input, rl = null, payload = null) {
991
929
  const [command, ...parts] = input.split(" ");
992
-
993
930
  const exactHandlers = {
994
931
  "/help": async () => {
995
- printHelp(this.#is_admin_mode);
932
+ printHelp(this.#config.isAdminMode);
996
933
  },
997
934
  "/exit": async () => {
998
935
  if (rl) rl.close();
999
936
  await this.close();
1000
937
  },
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 () => {
1008
- console.log(await this.#state.getIndexersEntry());
1009
- },
1010
- "/validator_pool": () => {
1011
- this.network.validatorConnectionManager.prettyPrint();
1012
- },
1013
- "/stats": () => verifyDag(
938
+ "/add_admin": async () => await this.#handleAdminCreation(),
939
+ "/add_admin --recovery": async () => await this.#handleAdminRecovery(),
940
+ "/add_whitelist": async () => await this.#handleWhitelistOperations(),
941
+ "/add_writer": async () => await this.#requestWriterRole(true),
942
+ "/remove_writer": async () => await this.#requestWriterRole(false),
943
+ "/core": async () => await coreInfoCommand(this.#state),
944
+ "/indexers_list": async () => console.log(await this.#state.getIndexersEntry()),
945
+ "/validator_pool": () => this.#network.validatorConnectionManager.prettyPrint(),
946
+ "/stats": async () => await verifyDag(
1014
947
  this.#state,
1015
948
  this.#network,
1016
949
  this.#wallet,
1017
950
  this.#state.writingKey
1018
951
  ),
1019
- "/balance_migration": () => this.#handleBalanceMigrationOperation(),
1020
- "/disable_initialization": () => this.#disableInitialization()
952
+ "/balance_migration": async () => await this.#balanceMigrationOperation(),
953
+ "/disable_initialization": async () => await this.#disableInitialization()
1021
954
  };
1022
955
 
1023
956
  if (exactHandlers[command]) {
@@ -1035,26 +968,26 @@ export class MainSettlementBus extends ReadyResource {
1035
968
 
1036
969
  if (input.startsWith("/add_indexer")) {
1037
970
  const address = parts[0];
1038
- await this.#handleAddIndexerOperation(address);
971
+ await this.#updateWriterToIndexerRole(address, true);
1039
972
  } else if (input.startsWith("/remove_indexer")) {
1040
973
  const address = parts[0];
1041
- await this.#handleRemoveIndexerOperation(address);
974
+ await this.#updateWriterToIndexerRole(address, false);
1042
975
  } else if (input.startsWith("/ban_writer")) {
1043
976
  const address = parts[0];
1044
- await this.#handleBanValidatorOperation(address);
977
+ await this.#banValidator(address);
1045
978
  } else if (input.startsWith("/deployment")) {
1046
979
  const bootstrapToDeploy = parts[0];
1047
980
  const channel = parts[1] || randomBytes(32).toString("hex");
1048
981
  if (channel.length !== 64 || !isHexString(channel)) {
1049
982
  throw new Error("Channel must be a 32-byte hex string");
1050
983
  }
1051
- await this.#handleBootstrapDeploymentOperation(bootstrapToDeploy, channel);
984
+ await this.#deployBootstrap(bootstrapToDeploy, channel);
1052
985
  } else if (input.startsWith("/get_validator_addr")) {
1053
986
  const wkHexString = parts[0];
1054
- await getValidatorAddressCommand(this.#state, wkHexString);
987
+ await getValidatorAddressCommand(this.#state, wkHexString, this.#config.addressPrefix);
1055
988
  } else if (input.startsWith("/get_deployment")) {
1056
989
  const bootstrapHex = parts[0];
1057
- await getDeploymentCommand(this.#state, bootstrapHex);
990
+ await getDeploymentCommand(this.#state, bootstrapHex, this.#config.addressLength);
1058
991
  } else if (input.startsWith("/get_tx_info")) {
1059
992
  const txHash = parts[0];
1060
993
  await getTxInfoCommand(this.#state, txHash);
@@ -1092,19 +1025,11 @@ export class MainSettlementBus extends ReadyResource {
1092
1025
  const result = getUnconfirmedLengthCommand(this.#state);
1093
1026
  if (rl) rl.prompt();
1094
1027
  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
1028
  } else if (input.startsWith("/get_tx_payloads_bulk")) {
1103
1029
  if (!payload) {
1104
1030
  throw new Error("Missing payload for fetching tx payloads.");
1105
1031
  }
1106
- const hashes = payload;
1107
- const result = await getTxPayloadsBulkCommand(this.#state, hashes);
1032
+ const result = await getTxPayloadsBulkCommand(this.#state, payload, this.#config);
1108
1033
  if (rl) rl.prompt();
1109
1034
  return result;
1110
1035
  } else if (input.startsWith("/get_txs_hashes")) {
@@ -1115,13 +1040,13 @@ export class MainSettlementBus extends ReadyResource {
1115
1040
  return result;
1116
1041
  } else if (input.startsWith("/get_tx_details")) {
1117
1042
  const hash = parts[0];
1118
- const result = await getTxDetailsCommand(this.#state, hash);
1043
+ const result = await getTxDetailsCommand(this.#state, hash, this.#config);
1119
1044
  if (rl) rl.prompt();
1120
1045
  return result;
1121
1046
  } else if (input.startsWith("/get_extended_tx_details")) {
1122
1047
  const hash = parts[0];
1123
1048
  const confirmed = parts[1] === "true";
1124
- const result = await getExtendedTxDetailsCommand(this.#state, hash, confirmed);
1049
+ const result = await getExtendedTxDetailsCommand(this.#state, hash, confirmed, this.#config);
1125
1050
  if (rl) rl.prompt();
1126
1051
  return result;
1127
1052
  }