trac-msb 0.2.8 → 0.2.10

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 (151) hide show
  1. package/.github/workflows/acceptance-tests.yml +7 -11
  2. package/.github/workflows/lint-pr-title.yml +26 -0
  3. package/.github/workflows/unit-tests.yml +2 -8
  4. package/CODE_OF_CONDUCT.md +128 -0
  5. package/README.md +33 -18
  6. package/docker-compose.yml +1 -0
  7. package/docs/trac_network_http_api.openapi.yaml +889 -0
  8. package/msb.mjs +5 -22
  9. package/package.json +14 -10
  10. package/proto/network.proto +74 -0
  11. package/rpc/create_server.js +2 -2
  12. package/rpc/handlers.js +165 -92
  13. package/rpc/routes/v1.js +3 -1
  14. package/rpc/rpc_server.js +4 -4
  15. package/rpc/rpc_services.js +62 -25
  16. package/rpc/utils/helpers.js +83 -52
  17. package/src/config/args.js +46 -0
  18. package/src/config/config.js +78 -5
  19. package/src/config/env.js +70 -3
  20. package/src/core/network/Network.js +34 -70
  21. package/src/core/network/identity/NetworkWalletFactory.js +2 -2
  22. package/src/core/network/protocols/LegacyProtocol.js +67 -0
  23. package/src/core/network/protocols/NetworkMessages.js +48 -0
  24. package/src/core/network/protocols/ProtocolInterface.js +31 -0
  25. package/src/core/network/protocols/ProtocolSession.js +59 -0
  26. package/src/core/network/protocols/V1Protocol.js +64 -0
  27. package/src/core/network/protocols/legacy/NetworkMessageRouter.js +84 -0
  28. package/src/core/network/protocols/legacy/handlers/GetRequestHandler.js +53 -0
  29. package/src/core/network/protocols/legacy/handlers/ResponseHandler.js +37 -0
  30. package/src/core/network/{messaging → protocols/legacy}/validators/base/BaseResponse.js +2 -3
  31. package/src/core/network/protocols/shared/handlers/RoleOperationHandler.js +88 -0
  32. package/src/core/network/protocols/shared/handlers/SubnetworkOperationHandler.js +93 -0
  33. package/src/core/network/{messaging → protocols/shared}/handlers/TransferOperationHandler.js +17 -16
  34. package/src/core/network/{messaging → protocols/shared}/handlers/base/BaseOperationHandler.js +10 -15
  35. package/src/core/network/{messaging → protocols/shared}/validators/PartialBootstrapDeployment.js +2 -2
  36. package/src/core/network/{messaging → protocols/shared}/validators/PartialRoleAccess.js +5 -5
  37. package/src/core/network/{messaging → protocols/shared}/validators/PartialTransaction.js +4 -4
  38. package/src/core/network/{messaging → protocols/shared}/validators/PartialTransfer.js +4 -4
  39. package/src/core/network/{messaging → protocols/shared}/validators/base/PartialOperation.js +14 -12
  40. package/src/core/network/protocols/v1/NetworkMessageRouter.js +15 -0
  41. package/src/core/network/services/ConnectionManager.js +5 -5
  42. package/src/core/network/services/MessageOrchestrator.js +2 -2
  43. package/src/core/network/services/TransactionPoolService.js +5 -6
  44. package/src/core/network/services/TransactionRateLimiterService.js +12 -13
  45. package/src/core/network/services/ValidatorObserverService.js +5 -6
  46. package/src/core/state/State.js +3 -5
  47. package/src/index.js +156 -181
  48. package/src/messages/network/v1/NetworkMessageBuilder.js +325 -0
  49. package/src/messages/network/v1/NetworkMessageDirector.js +137 -0
  50. package/src/messages/network/v1/networkMessageFactory.js +12 -0
  51. package/src/messages/state/ApplyStateMessageBuilder.js +661 -0
  52. package/src/messages/state/ApplyStateMessageDirector.js +516 -0
  53. package/src/messages/state/applyStateMessageFactory.js +12 -0
  54. package/src/utils/buffer.js +53 -1
  55. package/src/utils/check.js +1 -1
  56. package/src/utils/cli.js +0 -8
  57. package/src/utils/constants.js +33 -30
  58. package/src/utils/fileUtils.js +13 -0
  59. package/src/utils/normalizers.js +84 -2
  60. package/src/utils/protobuf/network.cjs +840 -0
  61. package/src/utils/protobuf/operationHelpers.js +10 -0
  62. package/src/utils/type.js +26 -0
  63. package/tests/acceptance/v1/balance/balance.test.mjs +1 -2
  64. package/tests/acceptance/v1/broadcast-transaction/broadcast-transaction.test.mjs +26 -30
  65. package/tests/acceptance/v1/health/health.test.mjs +33 -0
  66. package/tests/acceptance/v1/rpc.test.mjs +4 -3
  67. package/tests/acceptance/v1/tx/tx.test.mjs +27 -16
  68. package/tests/acceptance/v1/tx-details/tx-details.test.mjs +26 -12
  69. package/tests/fixtures/check.fixtures.js +33 -32
  70. package/tests/fixtures/networkV1.fixtures.js +85 -0
  71. package/tests/fixtures/protobuf.fixtures.js +109 -25
  72. package/tests/helpers/StateNetworkFactory.js +2 -2
  73. package/tests/helpers/address.js +6 -0
  74. package/tests/helpers/autobaseTestHelpers.js +2 -1
  75. package/tests/helpers/config.js +2 -1
  76. package/tests/helpers/setupApplyTests.js +59 -56
  77. package/tests/unit/messages/messages.test.js +12 -0
  78. package/tests/unit/messages/network/NetworkMessageBuilder.test.js +276 -0
  79. package/tests/unit/messages/network/NetworkMessageDirector.test.js +201 -0
  80. package/tests/unit/messages/state/applyStateMessageBuilder.complete.test.js +521 -0
  81. package/tests/unit/messages/state/applyStateMessageBuilder.partial.test.js +233 -0
  82. package/tests/unit/network/ConnectionManager.test.js +6 -5
  83. package/tests/unit/network/networkModule.test.js +3 -2
  84. package/tests/unit/state/apply/addAdmin/addAdminHappyPathScenario.js +10 -6
  85. package/tests/unit/state/apply/addAdmin/addAdminScenarioHelpers.js +9 -6
  86. package/tests/unit/state/apply/addAdmin/state.apply.addAdmin.test.js +10 -7
  87. package/tests/unit/state/apply/addIndexer/addIndexerScenarioHelpers.js +18 -21
  88. package/tests/unit/state/apply/addWriter/addWriterScenarioHelpers.js +53 -38
  89. package/tests/unit/state/apply/adminRecovery/adminRecoveryScenarioHelpers.js +46 -35
  90. package/tests/unit/state/apply/appendWhitelist/appendWhitelistScenarioHelpers.js +13 -16
  91. package/tests/unit/state/apply/balanceInitialization/balanceInitializationScenarioHelpers.js +17 -11
  92. package/tests/unit/state/apply/banValidator/banValidatorScenarioHelpers.js +11 -12
  93. package/tests/unit/state/apply/bootstrapDeployment/bootstrapDeploymentScenarioHelpers.js +9 -7
  94. package/tests/unit/state/apply/common/commonScenarioHelper.js +15 -14
  95. package/tests/unit/state/apply/common/payload-structure/initializationDisabledScenario.js +9 -4
  96. package/tests/unit/state/apply/disableInitialization/disableInitializationScenarioHelpers.js +17 -11
  97. package/tests/unit/state/apply/removeWriter/removeWriterScenarioHelpers.js +19 -14
  98. package/tests/unit/state/apply/transfer/transferDoubleSpendAcrossValidatorsScenario.js +37 -29
  99. package/tests/unit/state/apply/transfer/transferScenarioHelpers.js +9 -7
  100. package/tests/unit/state/apply/txOperation/txOperationScenarioHelpers.js +11 -9
  101. package/tests/unit/unit.test.js +1 -1
  102. package/tests/unit/utils/buffer/buffer.test.js +62 -1
  103. package/tests/unit/utils/fileUtils/readAddressesFromWhitelistFile.test.js +4 -3
  104. package/tests/unit/utils/fileUtils/readBalanceMigrationFile.test.js +3 -2
  105. package/tests/unit/utils/migrationUtils/validateAddressFromIncomingFile.test.js +3 -2
  106. package/tests/unit/utils/normalizers/normalizers.test.js +469 -0
  107. package/tests/unit/utils/protobuf/operationHelpers.test.js +120 -2
  108. package/tests/unit/utils/type/type.test.js +25 -0
  109. package/tests/unit/utils/utils.test.js +1 -0
  110. package/docs/networking-dualstack-plan.md +0 -75
  111. package/docs/networking-layer-redesign.md +0 -155
  112. package/src/core/network/messaging/NetworkMessages.js +0 -64
  113. package/src/core/network/messaging/handlers/GetRequestHandler.js +0 -113
  114. package/src/core/network/messaging/handlers/ResponseHandler.js +0 -107
  115. package/src/core/network/messaging/handlers/RoleOperationHandler.js +0 -114
  116. package/src/core/network/messaging/handlers/SubnetworkOperationHandler.js +0 -149
  117. package/src/core/network/messaging/routes/NetworkMessageRouter.js +0 -98
  118. package/src/core/network/messaging/validators/AdminResponse.js +0 -58
  119. package/src/core/network/messaging/validators/CustomNodeResponse.js +0 -46
  120. package/src/messages/base/StateBuilder.js +0 -25
  121. package/src/messages/completeStateMessages/CompleteStateMessageBuilder.js +0 -425
  122. package/src/messages/completeStateMessages/CompleteStateMessageDirector.js +0 -252
  123. package/src/messages/completeStateMessages/CompleteStateMessageOperations.js +0 -296
  124. package/src/messages/partialStateMessages/PartialStateMessageBuilder.js +0 -272
  125. package/src/messages/partialStateMessages/PartialStateMessageDirector.js +0 -137
  126. package/src/messages/partialStateMessages/PartialStateMessageOperations.js +0 -138
  127. package/tests/integration/apply/addAdmin/addAdminBasic.test.js +0 -69
  128. package/tests/integration/apply/addAdmin/addAdminRecovery.test.js +0 -126
  129. package/tests/integration/apply/addIndexer.test.js +0 -239
  130. package/tests/integration/apply/addWhitelist.test.js +0 -53
  131. package/tests/integration/apply/addWriter.test.js +0 -245
  132. package/tests/integration/apply/apply.test.js +0 -19
  133. package/tests/integration/apply/banValidator.test.js +0 -116
  134. package/tests/integration/apply/postTx/invalidSubValues.test.js +0 -103
  135. package/tests/integration/apply/postTx/postTx.test.js +0 -196
  136. package/tests/integration/apply/removeIndexer.test.js +0 -132
  137. package/tests/integration/apply/removeWriter.test.js +0 -168
  138. package/tests/integration/apply/transfer.test.js +0 -83
  139. package/tests/integration/integration.test.js +0 -9
  140. package/tests/unit/messageOperations/assembleAddIndexerMessage.test.js +0 -21
  141. package/tests/unit/messageOperations/assembleAddWriterMessage.test.js +0 -17
  142. package/tests/unit/messageOperations/assembleAdminMessage.test.js +0 -68
  143. package/tests/unit/messageOperations/assembleBanWriterMessage.test.js +0 -17
  144. package/tests/unit/messageOperations/assemblePostTransaction.test.js +0 -424
  145. package/tests/unit/messageOperations/assembleRemoveIndexerMessage.test.js +0 -19
  146. package/tests/unit/messageOperations/assembleRemoveWriterMessage.test.js +0 -17
  147. package/tests/unit/messageOperations/assembleWhitelistMessages.test.js +0 -59
  148. package/tests/unit/messageOperations/commonsStateMessageOperationsTest.js +0 -278
  149. package/tests/unit/messageOperations/stateMessageOperations.test.js +0 -19
  150. /package/src/core/network/{messaging → protocols/legacy}/validators/ValidatorResponse.js +0 -0
  151. /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";
@@ -8,26 +7,21 @@ import readline from "readline";
8
7
  import tty from "tty";
9
8
  import { sleep, isHexString } from "./utils/helpers.js";
10
9
  import { verifyDag, printHelp, printWalletInfo, printBalance } from "./utils/cli.js";
11
- import CompleteStateMessageOperations from "./messages/completeStateMessages/CompleteStateMessageOperations.js";
10
+ import { applyStateMessageFactory } from "./messages/state/applyStateMessageFactory.js";
12
11
  import { isAddressValid } from "./core/state/utils/address.js";
13
12
  import Network from "./core/network/Network.js";
14
13
  import Check from "./utils/check.js";
15
14
  import State from "./core/state/State.js";
16
- import PartialStateMessageOperations from "./messages/partialStateMessages/PartialStateMessageOperations.js";
17
15
  import {
18
16
  EventType,
19
17
  WHITELIST_SLEEP_INTERVAL,
20
18
  BOOTSTRAP_HEXSTRING_LENGTH,
21
- OperationType,
22
19
  CustomEventType,
23
20
  BALANCE_MIGRATION_SLEEP_INTERVAL,
24
21
  WHITELIST_MIGRATION_DIR
25
22
  } from "./utils/constants.js";
26
23
  import { randomBytes } from "hypercore-crypto";
27
24
  import { decimalStringToBigInt, bigIntTo16ByteBuffer, bufferToBigInt, bigIntToDecimalString } from "./utils/amountSerialization.js"
28
- import { normalizeTransferOperation, normalizeTransactionOperation } from "./utils/normalizers.js"
29
- import PartialTransfer from "./core/network/messaging/validators/PartialTransfer.js";
30
- import PartialTransaction from "./core/network/messaging/validators/PartialTransaction.js";
31
25
  import fileUtils from './utils/fileUtils.js';
32
26
  import migrationUtils from './utils/migrationUtils.js';
33
27
  import {
@@ -49,25 +43,23 @@ import {
49
43
  getLicenseAddressCommand,
50
44
  getLicenseCountCommand
51
45
  } from "./utils/cliCommands.js";
46
+ import {safeEncodeApplyOperation} from "./utils/protobuf/operationHelpers.js";
47
+
52
48
  export class MainSettlementBus extends ReadyResource {
53
- // internal attributes
54
49
  #store;
55
50
  #wallet;
56
51
  #network;
57
52
  #readline_instance;
58
53
  #state;
59
54
  #isClosing = false;
60
- #partialTransferValidator;
61
- #partialTransactionValidator;
62
55
  #config
63
56
 
64
57
  /**
65
- * @param {object} config
58
+ * @param {Config} config
66
59
  **/
67
60
  constructor(config) {
68
61
  super();
69
62
  this.#config = config
70
-
71
63
  this.#store = new Corestore(this.#config.storesFullPath);
72
64
  this.#wallet = new PeerWallet({ networkPrefix: this.#config.addressPrefix });
73
65
  this.#readline_instance = null;
@@ -96,12 +88,16 @@ export class MainSettlementBus extends ReadyResource {
96
88
  return this.#network;
97
89
  }
98
90
 
99
- // This can be null if enable_wallet is false
100
91
  get wallet() {
92
+ if (!this.#config.enableWallet) {
93
+ return undefined;
94
+ }
101
95
  return this.#wallet;
102
96
  }
103
97
 
104
98
  async _open() {
99
+ await fileUtils.ensureCoresStoreDir(this.#config);
100
+
105
101
  if (this.#config.enableWallet) {
106
102
  await this.#wallet.initKeyPair(
107
103
  this.#config.keyPairPath,
@@ -113,15 +109,12 @@ export class MainSettlementBus extends ReadyResource {
113
109
 
114
110
  await this.#state.ready();
115
111
  await this.#network.ready();
116
- this.#stateEventsListener();
112
+ await this.#stateEventsListener();
117
113
 
118
114
  if (this.#config.enableWallet) {
119
115
  printWalletInfo(this.#wallet.address, this.#state.writingKey, this.#state, this.#config.enableWallet);
120
116
  }
121
117
 
122
- this.#partialTransferValidator = new PartialTransfer(this.state, this.#wallet, this.#config);
123
- this.#partialTransactionValidator = new PartialTransaction(this.state, this.#wallet ,this.#config);
124
-
125
118
  await this.#network.replicate(
126
119
  this.#state,
127
120
  this.#store,
@@ -131,6 +124,8 @@ export class MainSettlementBus extends ReadyResource {
131
124
  const adminEntry = await this.#state.getAdminEntry();
132
125
  await this.#setUpRoleAutomatically(adminEntry);
133
126
 
127
+
128
+
134
129
  console.log(`isIndexer: ${this.#state.isIndexer()}`);
135
130
  console.log(`isWriter: ${this.#state.isWritable()}`);
136
131
  console.log("MSB Unsigned Length:", this.#state.getUnsignedLength());
@@ -182,41 +177,6 @@ export class MainSettlementBus extends ReadyResource {
182
177
  return await this.#network.validatorMessageOrchestrator.send(partialTransactionPayload);
183
178
  }
184
179
 
185
- async broadcastTransactionCommand(payload) {
186
- if (!payload) {
187
- throw new Error("Transaction payload is required for broadcast_transaction command.");
188
- }
189
-
190
- let normalizedPayload;
191
- let isValid = false;
192
- let hash;
193
-
194
- if (payload.type === OperationType.TRANSFER) {
195
- normalizedPayload = normalizeTransferOperation(payload, this.#config);
196
- isValid = await this.#partialTransferValidator.validate(normalizedPayload);
197
- hash = b4a.toString(normalizedPayload.tro.tx, "hex");
198
- } else if (payload.type === OperationType.TX) {
199
- normalizedPayload = normalizeTransactionOperation(payload, this.#config);
200
- isValid = await this.#partialTransactionValidator.validate(normalizedPayload);
201
- hash = b4a.toString(normalizedPayload.txo.tx, "hex");
202
- }
203
-
204
- if (!isValid) {
205
- throw new Error("Invalid transaction payload.");
206
- }
207
-
208
- const signedLength = this.#state.getSignedLength();
209
- const unsignedLength = this.#state.getUnsignedLength();
210
-
211
- const success = await this.broadcastPartialTransaction(payload);
212
-
213
- if (!success) {
214
- throw new Error("Failed to broadcast transaction after multiple attempts.");
215
- }
216
-
217
- return { message: "Transaction broadcasted successfully.", signedLength, unsignedLength, tx: hash };
218
- }
219
-
220
180
  async #setUpRoleAutomatically() {
221
181
  if (!this.#state.isWritable() && this.#config.enableRoleRequester) {
222
182
  console.log("Requesting writer role... This may take a moment.");
@@ -296,14 +256,17 @@ export class MainSettlementBus extends ReadyResource {
296
256
  }
297
257
 
298
258
  const txValidity = await PeerWallet.blake3(this.#config.bootstrap);
299
- const addAdminMessage = await new CompleteStateMessageOperations(this.#wallet, this.#config)
300
- .assembleAddAdminMessage(
259
+ const addAdminMessage = await applyStateMessageFactory(this.#wallet, this.#config)
260
+ .buildCompleteAddAdminMessage(
261
+ this.#wallet.address,
301
262
  this.#state.writingKey,
302
- txValidity
303
- );
263
+ txValidity,
264
+ )
265
+ const encodedPayload = safeEncodeApplyOperation(addAdminMessage);
304
266
 
305
- await this.#state.append(addAdminMessage);
267
+ await this.#state.append(encodedPayload);
306
268
  }
269
+
307
270
  async #handleAdminRecovery() {
308
271
  if (!this.#config.enableWallet) {
309
272
  throw new Error("Can not initialize an admin - wallet is not enabled.");
@@ -329,10 +292,13 @@ export class MainSettlementBus extends ReadyResource {
329
292
  }
330
293
 
331
294
  const txValidity = await this.#state.getIndexerSequenceState();
332
- const adminRecoveryMessage = await new PartialStateMessageOperations(this.#wallet, this.#config).assembleAdminRecoveryMessage(
333
- this.#state.writingKey.toString('hex'),
334
- txValidity.toString('hex')
335
- );
295
+ const adminRecoveryMessage = await applyStateMessageFactory(this.#wallet, this.#config)
296
+ .buildPartialAdminRecoveryMessage(
297
+ this.#wallet.address,
298
+ this.#state.writingKey,
299
+ txValidity,
300
+ "json"
301
+ )
336
302
 
337
303
  const success = await this.broadcastPartialTransaction(adminRecoveryMessage);
338
304
 
@@ -366,12 +332,13 @@ export class MainSettlementBus extends ReadyResource {
366
332
 
367
333
  for (const addressToWhitelist of addresses) {
368
334
  const txValidity = await this.#state.getIndexerSequenceState();
369
- const encodedPayload = await new CompleteStateMessageOperations(this.#wallet, this.#config)
370
- .assembleAppendWhitelistMessages(
335
+ const appendWhitelistMessage = await applyStateMessageFactory(this.#wallet, this.#config)
336
+ .buildCompleteAppendWhitelistMessage(
337
+ this.#wallet.address,
338
+ addressToWhitelist,
371
339
  txValidity,
372
- addressToWhitelist
373
- );
374
-
340
+ )
341
+ const encodedPayload = safeEncodeApplyOperation(appendWhitelistMessage)
375
342
  messages.set(addressToWhitelist, encodedPayload);
376
343
  }
377
344
 
@@ -445,10 +412,13 @@ export class MainSettlementBus extends ReadyResource {
445
412
  }
446
413
 
447
414
  const txValidity = await this.#state.getIndexerSequenceState();
448
- const assembledMessage = await new PartialStateMessageOperations(this.#wallet, { networkId: this.#config.networkId, addressPrefix: this.#config.addressPrefix })
449
- .assembleAddWriterMessage(
450
- this.#state.writingKey.toString('hex'),
451
- txValidity.toString('hex')
415
+
416
+ const assembledMessage = await applyStateMessageFactory(this.#wallet, this.#config)
417
+ .buildPartialAddWriterMessage(
418
+ this.#wallet.address,
419
+ this.#state.writingKey,
420
+ txValidity,
421
+ 'json'
452
422
  )
453
423
 
454
424
  const success = await this.broadcastPartialTransaction(assembledMessage);
@@ -477,10 +447,12 @@ export class MainSettlementBus extends ReadyResource {
477
447
  }
478
448
 
479
449
  const txValidity = await this.#state.getIndexerSequenceState();
480
- const assembledMessage = await new PartialStateMessageOperations(this.#wallet, { networkId: this.#config.networkId, addressPrefix: this.#config.addressPrefix })
481
- .assembleRemoveWriterMessage(
482
- nodeEntry.wk.toString('hex'),
483
- txValidity.toString('hex')
450
+ const assembledMessage = await applyStateMessageFactory(this.#wallet, this.#config)
451
+ .buildPartialRemoveWriterMessage(
452
+ this.#wallet.address,
453
+ nodeEntry.wk,
454
+ txValidity,
455
+ "json"
484
456
  )
485
457
 
486
458
  const success = await this.broadcastPartialTransaction(assembledMessage);
@@ -492,10 +464,10 @@ export class MainSettlementBus extends ReadyResource {
492
464
  console.info(`Transaction hash: ${assembledMessage.rao.tx}`);
493
465
  }
494
466
 
495
- async #updateIndexerRole(address, toAdd) {
467
+ async #updateWriterToIndexerRole(addressToUpdate, toAdd) {
496
468
  if (!this.#config.enableWallet) {
497
469
  throw new Error(
498
- `Can not request indexer role for: ${address} - wallet is not enabled.`
470
+ `Can not request indexer role for: ${addressToUpdate} - wallet is not enabled.`
499
471
  );
500
472
  }
501
473
 
@@ -503,29 +475,29 @@ export class MainSettlementBus extends ReadyResource {
503
475
 
504
476
  if (!adminEntry) {
505
477
  throw new Error(
506
- `Can not request indexer role for: ${address} - admin entry has not been initialized.`
478
+ `Can not request indexer role for: ${addressToUpdate} - admin entry has not been initialized.`
507
479
  );
508
480
  }
509
481
 
510
- if (!isAddressValid(address, this.#config.addressPrefix)) {
482
+ if (!isAddressValid(addressToUpdate, this.#config.addressPrefix)) {
511
483
  throw new Error(
512
- `Can not request indexer role for: ${address} - invalid address.`
484
+ `Can not request indexer role for: ${addressToUpdate} - invalid address.`
513
485
  );
514
486
  }
515
487
 
516
488
  if (!this.#isAdmin(adminEntry) && !this.#state.isWritable()) {
517
489
  throw new Error(
518
- `Can not request indexer role for: ${address} - You are not an admin or writer.`
490
+ `Can not request indexer role for: ${addressToUpdate} - You are not an admin or writer.`
519
491
  );
520
492
  }
521
- const nodeEntry = await this.#state.getNodeEntry(address);
493
+ const nodeEntry = await this.#state.getNodeEntry(addressToUpdate);
522
494
  if (!nodeEntry) {
523
495
  throw new Error(
524
- `Can not request indexer role for: ${address} - node entry has not been not initialized.`
496
+ `Can not request indexer role for: ${addressToUpdate} - node entry has not been not initialized.`
525
497
  );
526
498
  }
527
499
 
528
- const indexerNodeEntry = await this.#state.getNodeEntry(address);
500
+ const indexerNodeEntry = await this.#state.getNodeEntry(addressToUpdate);
529
501
  const indexerListHasAddress = await this.#state.isWkInIndexersEntry(
530
502
  indexerNodeEntry.wk,
531
503
  );
@@ -533,7 +505,7 @@ export class MainSettlementBus extends ReadyResource {
533
505
  if (toAdd) {
534
506
  if (indexerListHasAddress) {
535
507
  throw new Error(
536
- `Cannot update indexer role for: ${address} - address is already in indexers list.`
508
+ `Cannot update indexer role for: ${addressToUpdate} - address is already in indexers list.`
537
509
  );
538
510
  }
539
511
 
@@ -545,71 +517,86 @@ export class MainSettlementBus extends ReadyResource {
545
517
 
546
518
  if (!canAddIndexer) {
547
519
  throw new Error(
548
- `Can not request indexer role for: ${address} - node is not whitelisted, not a writer or already an indexer.`
520
+ `Can not request indexer role for: ${addressToUpdate} - node is not whitelisted, not a writer or already an indexer.`
549
521
  );
550
522
  }
551
523
  const txValidity = await this.#state.getIndexerSequenceState();
552
- const assembledAddIndexerMessage = await new CompleteStateMessageOperations(this.#wallet, this.#config)
553
- .assembleAddIndexerMessage(address, txValidity);
554
- await this.#state.append(assembledAddIndexerMessage);
524
+
525
+ const assembledAddIndexerMessage = await applyStateMessageFactory(this.#wallet, this.#config)
526
+ .buildCompleteAddIndexerMessage(
527
+ this.#wallet.address,
528
+ addressToUpdate,
529
+ txValidity,
530
+ )
531
+
532
+ const encodedPayload = safeEncodeApplyOperation(assembledAddIndexerMessage);
533
+
534
+ await this.#state.append(encodedPayload);
555
535
  } else {
556
536
  const canRemoveIndexer =
557
537
  !toAdd && nodeEntry.isIndexer && indexerListHasAddress;
558
538
 
559
539
  if (!canRemoveIndexer) {
560
540
  throw new Error(
561
- `Can not remove indexer role for: ${address} - node is not an indexer or address is not in indexers list.`
541
+ `Can not remove indexer role for: ${addressToUpdate} - node is not an indexer or address is not in indexers list.`
562
542
  );
563
543
  }
564
544
  const txValidity = await this.#state.getIndexerSequenceState();
565
- const assembledRemoveIndexer = await new CompleteStateMessageOperations(this.#wallet, this.#config)
566
- .assembleRemoveIndexerMessage(address, txValidity);
545
+ const assembledRemoveIndexerMessage = await applyStateMessageFactory(this.#wallet, this.#config)
546
+ .buildCompleteRemoveIndexerMessage(
547
+ this.#wallet.address,
548
+ addressToUpdate,
549
+ txValidity,
550
+ )
551
+ const encodedPayload = safeEncodeApplyOperation(assembledRemoveIndexerMessage);
567
552
 
568
- await this.#state.append(assembledRemoveIndexer);
553
+ await this.#state.append(encodedPayload);
569
554
  }
570
555
  }
571
556
 
572
- async #banValidator(address) {
557
+ async #banValidator(addresstToBan) {
573
558
  if (!this.#config.enableWallet) {
574
559
  throw new Error(
575
- `Can not ban writer with address: ${address} - wallet is not enabled.`
560
+ `Can not ban writer with address: ${addresstToBan} - wallet is not enabled.`
576
561
  );
577
562
  }
578
563
  const adminEntry = await this.#state.getAdminEntry();
579
564
 
580
565
  if (!adminEntry) {
581
566
  throw new Error(
582
- `Can not ban writer with address: ${address} - admin entry has not been initialized.`
567
+ `Can not ban writer with address: ${addresstToBan} - admin entry has not been initialized.`
583
568
  );
584
569
  }
585
570
 
586
- if (!isAddressValid(address, this.#config.addressPrefix)) {
571
+ if (!isAddressValid(addresstToBan, this.#config.addressPrefix)) {
587
572
  throw new Error(
588
- `Can not ban writer with address: ${address} - invalid address.`
573
+ `Can not ban writer with address: ${addresstToBan} - invalid address.`
589
574
  );
590
575
  }
591
576
 
592
577
  if (!this.#isAdmin(adminEntry)) {
593
578
  throw new Error(
594
- `Can not ban writer with address: ${address} - You are not an admin.`
579
+ `Can not ban writer with address: ${addresstToBan} - You are not an admin.`
595
580
  );
596
581
  }
597
582
 
598
- const isWhitelisted = await this.#state.isAddressWhitelisted(address);
599
- const nodeEntry = await this.#state.getNodeEntry(address);
583
+ const isWhitelisted = await this.#state.isAddressWhitelisted(addresstToBan);
584
+ const nodeEntry = await this.#state.getNodeEntry(addresstToBan);
600
585
 
601
586
  if (!isWhitelisted || null === nodeEntry || nodeEntry.isIndexer === true) {
602
587
  throw new Error(
603
- `Can not ban writer with address: ${address} - node is not whitelisted or is an indexer.`
588
+ `Can not ban writer with address: ${addresstToBan} - node is not whitelisted or is an indexer.`
604
589
  );
605
590
  }
606
591
  const txValidity = await this.#state.getIndexerSequenceState();
607
- const assembledBanValidatorMessage = await new CompleteStateMessageOperations(this.#wallet, this.#config)
608
- .assembleBanWriterMessage(
609
- address,
610
- txValidity
611
- );
612
- await this.#state.append(assembledBanValidatorMessage);
592
+ const assembledBanValidatorMessage = await applyStateMessageFactory(this.#wallet, this.#config)
593
+ .buildCompleteBanWriterMessage(
594
+ this.#wallet.address,
595
+ addresstToBan,
596
+ txValidity,
597
+ )
598
+ const encodedPayload = safeEncodeApplyOperation(assembledBanValidatorMessage)
599
+ await this.#state.append(encodedPayload);
613
600
  }
614
601
 
615
602
  async #deployBootstrap(externalBootstrap, channel) {
@@ -682,12 +669,15 @@ export class MainSettlementBus extends ReadyResource {
682
669
  }
683
670
 
684
671
  const txValidity = await this.#state.getIndexerSequenceState();
685
- const payload = await new PartialStateMessageOperations(this.#wallet, this.#config)
686
- .assembleBootstrapDeploymentMessage(
672
+
673
+ const payload = await applyStateMessageFactory(this.#wallet, this.#config)
674
+ .buildPartialBootstrapDeploymentMessage(
675
+ this.#wallet.address,
687
676
  externalBootstrap,
688
677
  channel,
689
- txValidity.toString('hex')
690
- );
678
+ txValidity,
679
+ "json"
680
+ )
691
681
 
692
682
  const success = await this.broadcastPartialTransaction(payload);
693
683
 
@@ -703,31 +693,7 @@ export class MainSettlementBus extends ReadyResource {
703
693
 
704
694
  }
705
695
 
706
- async #handleAddIndexerOperation(address) {
707
- await this.#updateIndexerRole(address, true);
708
- }
709
-
710
- async #handleRemoveIndexerOperation(address) {
711
- await this.#updateIndexerRole(address, false);
712
- }
713
-
714
- async #handleAddWriterOperation() {
715
- await this.#requestWriterRole(true);
716
- }
717
-
718
- async #handleRemoveWriterOperation() {
719
- await this.#requestWriterRole(false);
720
- }
721
-
722
- async #handleBanValidatorOperation(address) {
723
- await this.#banValidator(address);
724
- }
725
-
726
- async #handleBootstrapDeploymentOperation(bootstrapHex, channel) {
727
- await this.#deployBootstrap(bootstrapHex, channel);
728
- }
729
-
730
- async #handleTransferOperation(address, amount) {
696
+ async #handleTransferOperation(recipientAddress, amount) {
731
697
  if (!this.#config.enableWallet) {
732
698
  throw new Error(
733
699
  "Can not perform transfer - wallet is not enabled."
@@ -740,7 +706,7 @@ export class MainSettlementBus extends ReadyResource {
740
706
  );
741
707
  }
742
708
 
743
- if (!isAddressValid(address, this.#config.addressPrefix)) {
709
+ if (!isAddressValid(recipientAddress, this.#config.addressPrefix)) {
744
710
  throw new Error("Invalid recipient address");
745
711
  }
746
712
 
@@ -765,7 +731,7 @@ export class MainSettlementBus extends ReadyResource {
765
731
  const fee = this.#state.getFee();
766
732
  const feeBigInt = bufferToBigInt(fee);
767
733
  const senderBalance = bufferToBigInt(senderEntry.balance);
768
- const isSelfTransfer = address === this.#wallet.address;
734
+ const isSelfTransfer = recipientAddress === this.#wallet.address;
769
735
  const totalDeductedAmount = isSelfTransfer ? feeBigInt : amountBigInt + feeBigInt;
770
736
 
771
737
  if (!(senderBalance >= totalDeductedAmount)) {
@@ -773,13 +739,14 @@ export class MainSettlementBus extends ReadyResource {
773
739
  }
774
740
 
775
741
  const txValidity = await this.#state.getIndexerSequenceState();
776
- const payload = await new PartialStateMessageOperations(this.#wallet, this.#config)
777
- .assembleTransferOperationMessage(
778
- address,
779
- amountBuffer.toString('hex'),
780
- txValidity.toString('hex'),
781
- )
782
-
742
+ const payload = await applyStateMessageFactory(this.#wallet, this.#config)
743
+ .buildPartialTransferOperationMessage(
744
+ this.#wallet.address,
745
+ recipientAddress,
746
+ amountBuffer,
747
+ txValidity,
748
+ "json"
749
+ )
783
750
 
784
751
  const expectedNewBalance = senderBalance - totalDeductedAmount;
785
752
  console.info('Transfer Details:');
@@ -794,7 +761,6 @@ export class MainSettlementBus extends ReadyResource {
794
761
  console.info(`Total: ${bigIntToDecimalString(totalDeductedAmount)}`);
795
762
  }
796
763
  console.log(`Expected Balance After Transfer: ${bigIntToDecimalString(expectedNewBalance)}`);
797
-
798
764
  const success = await this.broadcastPartialTransaction(payload);
799
765
  if (!success) {
800
766
  throw new Error("Failed to broadcast transfer transaction after multiple attempts.");
@@ -804,7 +770,7 @@ export class MainSettlementBus extends ReadyResource {
804
770
 
805
771
  }
806
772
 
807
- async #handleBalanceMigrationOperation() {
773
+ async #balanceMigrationOperation() {
808
774
 
809
775
  const isInitDisabled = await this.#state.isInitalizationDisabled()
810
776
 
@@ -849,11 +815,18 @@ export class MainSettlementBus extends ReadyResource {
849
815
  await fileUtils.createMigrationEntryFile(addressBalancePair, migrationNumber);
850
816
 
851
817
  const txValidity = await this.#state.getIndexerSequenceState();
852
- const messages = await new CompleteStateMessageOperations(this.#wallet, this.#config)
853
- .assembleBalanceInitializationMessages(
818
+
819
+ let messages = [];
820
+
821
+ for (const [recipientAddress, amountBuffer] of addressBalancePair) {
822
+ const payload = await applyStateMessageFactory(this.#wallet, this.#config).buildCompleteBalanceInitializationMessage(
823
+ this.#wallet.address,
824
+ recipientAddress,
825
+ amountBuffer,
854
826
  txValidity,
855
- addressBalancePair,
856
- );
827
+ )
828
+ messages.push(safeEncodeApplyOperation(payload));
829
+ }
857
830
 
858
831
  console.log(`Total balance to migrate: ${bigIntToDecimalString(totalBalance)} across ${totalAddresses} addresses.`);
859
832
 
@@ -903,6 +876,10 @@ export class MainSettlementBus extends ReadyResource {
903
876
  if (!this.#config.enableWallet) {
904
877
  throw new Error("Can not initialize an admin - wallet is not enabled.");
905
878
  }
879
+ const isInitDisabled = await this.#state.isInitalizationDisabled();
880
+ if (isInitDisabled) {
881
+ throw new Error("Can not disable initialization - it is already disabled.");
882
+ }
906
883
  const adminEntry = await this.#state.getAdminEntry();
907
884
 
908
885
  if (!adminEntry) {
@@ -912,15 +889,24 @@ export class MainSettlementBus extends ReadyResource {
912
889
  if (!this.#isAdmin(adminEntry)) {
913
890
  throw new Error('Cannot perform whitelisting - you are not the admin!.');
914
891
  }
915
- // add more checks
892
+ if (!this.#wallet) {
893
+ throw new Error("Can not initialize an admin - wallet is not initialized.");
894
+ }
895
+ if (!this.#state.writingKey) {
896
+ throw new Error("Can not initialize an admin - writing key is not initialized.");
897
+ }
916
898
  const txValidity = await this.#state.getIndexerSequenceState();
917
- const payload = await new CompleteStateMessageOperations(this.#wallet, this.#config)
918
- .assembleDisableInitializationMessage(
899
+
900
+
901
+ const payload = await applyStateMessageFactory(this.#wallet, this.#config)
902
+ .buildCompleteDisableInitializationMessage(
903
+ this.#wallet.address,
919
904
  this.#state.writingKey,
920
905
  txValidity,
921
906
  )
922
907
  console.log('Disabling initialization...');
923
- await this.#state.append(payload);
908
+ const encodedPayload = safeEncodeApplyOperation(payload);
909
+ await this.#state.append(encodedPayload);
924
910
  }
925
911
 
926
912
  async interactiveMode() {
@@ -951,26 +937,22 @@ export class MainSettlementBus extends ReadyResource {
951
937
  if (rl) rl.close();
952
938
  await this.close();
953
939
  },
954
- "/add_admin": () => this.#handleAdminCreation(),
955
- "/add_admin --recovery": () => this.#handleAdminRecovery(),
956
- "/add_whitelist": () => this.#handleWhitelistOperations(),
957
- "/add_writer": () => this.#handleAddWriterOperation(),
958
- "/remove_writer": () => this.#handleRemoveWriterOperation(),
959
- "/core": () => coreInfoCommand(this.#state),
960
- "/indexers_list": async () => {
961
- console.log(await this.#state.getIndexersEntry());
962
- },
963
- "/validator_pool": () => {
964
- this.#network.validatorConnectionManager.prettyPrint();
965
- },
966
- "/stats": () => verifyDag(
940
+ "/add_admin": async () => await this.#handleAdminCreation(),
941
+ "/add_admin --recovery": async () => await this.#handleAdminRecovery(),
942
+ "/add_whitelist": async () => await this.#handleWhitelistOperations(),
943
+ "/add_writer": async () => await this.#requestWriterRole(true),
944
+ "/remove_writer": async () => await this.#requestWriterRole(false),
945
+ "/core": async () => await coreInfoCommand(this.#state),
946
+ "/indexers_list": async () => console.log(await this.#state.getIndexersEntry()),
947
+ "/validator_pool": () => this.#network.validatorConnectionManager.prettyPrint(),
948
+ "/stats": async () => await verifyDag(
967
949
  this.#state,
968
950
  this.#network,
969
951
  this.#wallet,
970
952
  this.#state.writingKey
971
953
  ),
972
- "/balance_migration": () => this.#handleBalanceMigrationOperation(),
973
- "/disable_initialization": () => this.#disableInitialization()
954
+ "/balance_migration": async () => await this.#balanceMigrationOperation(),
955
+ "/disable_initialization": async () => await this.#disableInitialization()
974
956
  };
975
957
 
976
958
  if (exactHandlers[command]) {
@@ -988,20 +970,20 @@ export class MainSettlementBus extends ReadyResource {
988
970
 
989
971
  if (input.startsWith("/add_indexer")) {
990
972
  const address = parts[0];
991
- await this.#handleAddIndexerOperation(address);
973
+ await this.#updateWriterToIndexerRole(address, true);
992
974
  } else if (input.startsWith("/remove_indexer")) {
993
975
  const address = parts[0];
994
- await this.#handleRemoveIndexerOperation(address);
976
+ await this.#updateWriterToIndexerRole(address, false);
995
977
  } else if (input.startsWith("/ban_writer")) {
996
978
  const address = parts[0];
997
- await this.#handleBanValidatorOperation(address);
979
+ await this.#banValidator(address);
998
980
  } else if (input.startsWith("/deployment")) {
999
981
  const bootstrapToDeploy = parts[0];
1000
982
  const channel = parts[1] || randomBytes(32).toString("hex");
1001
983
  if (channel.length !== 64 || !isHexString(channel)) {
1002
984
  throw new Error("Channel must be a 32-byte hex string");
1003
985
  }
1004
- await this.#handleBootstrapDeploymentOperation(bootstrapToDeploy, channel);
986
+ await this.#deployBootstrap(bootstrapToDeploy, channel);
1005
987
  } else if (input.startsWith("/get_validator_addr")) {
1006
988
  const wkHexString = parts[0];
1007
989
  await getValidatorAddressCommand(this.#state, wkHexString, this.#config.addressPrefix);
@@ -1045,13 +1027,6 @@ export class MainSettlementBus extends ReadyResource {
1045
1027
  const result = getUnconfirmedLengthCommand(this.#state);
1046
1028
  if (rl) rl.prompt();
1047
1029
  return result;
1048
- } else if (input.startsWith("/broadcast_transaction")) {
1049
- if (!payload) {
1050
- throw new Error("Transaction payload is required for broadcast_transaction command.");
1051
- }
1052
- const result = await this.broadcastTransactionCommand(payload);
1053
- if (rl) rl.prompt();
1054
- return result;
1055
1030
  } else if (input.startsWith("/get_tx_payloads_bulk")) {
1056
1031
  if (!payload) {
1057
1032
  throw new Error("Missing payload for fetching tx payloads.");