trac-msb 0.2.8 → 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 (123) hide show
  1. package/msb.mjs +3 -3
  2. package/package.json +8 -3
  3. package/proto/network.proto +74 -0
  4. package/rpc/create_server.js +2 -2
  5. package/rpc/handlers.js +2 -2
  6. package/rpc/rpc_server.js +2 -2
  7. package/rpc/rpc_services.js +44 -3
  8. package/rpc/utils/helpers.js +1 -1
  9. package/src/config/env.js +2 -0
  10. package/src/core/network/Network.js +29 -61
  11. package/src/core/network/identity/NetworkWalletFactory.js +2 -2
  12. package/src/core/network/protocols/LegacyProtocol.js +67 -0
  13. package/src/core/network/protocols/NetworkMessages.js +48 -0
  14. package/src/core/network/protocols/ProtocolInterface.js +31 -0
  15. package/src/core/network/protocols/ProtocolSession.js +59 -0
  16. package/src/core/network/protocols/V1Protocol.js +64 -0
  17. package/src/core/network/protocols/legacy/NetworkMessageRouter.js +84 -0
  18. package/src/core/network/protocols/legacy/handlers/GetRequestHandler.js +53 -0
  19. package/src/core/network/protocols/legacy/handlers/ResponseHandler.js +37 -0
  20. package/src/core/network/{messaging → protocols/legacy}/validators/base/BaseResponse.js +1 -2
  21. package/src/core/network/protocols/shared/handlers/RoleOperationHandler.js +88 -0
  22. package/src/core/network/protocols/shared/handlers/SubnetworkOperationHandler.js +93 -0
  23. package/src/core/network/{messaging → protocols/shared}/handlers/TransferOperationHandler.js +16 -15
  24. package/src/core/network/{messaging → protocols/shared}/handlers/base/BaseOperationHandler.js +7 -11
  25. package/src/core/network/{messaging → protocols/shared}/validators/PartialBootstrapDeployment.js +2 -2
  26. package/src/core/network/{messaging → protocols/shared}/validators/PartialRoleAccess.js +5 -5
  27. package/src/core/network/{messaging → protocols/shared}/validators/PartialTransaction.js +4 -4
  28. package/src/core/network/{messaging → protocols/shared}/validators/PartialTransfer.js +4 -4
  29. package/src/core/network/{messaging → protocols/shared}/validators/base/PartialOperation.js +14 -12
  30. package/src/core/network/protocols/v1/NetworkMessageRouter.js +15 -0
  31. package/src/core/network/services/ConnectionManager.js +4 -4
  32. package/src/core/network/services/MessageOrchestrator.js +1 -1
  33. package/src/core/network/services/TransactionPoolService.js +1 -2
  34. package/src/core/network/services/TransactionRateLimiterService.js +5 -3
  35. package/src/core/state/State.js +1 -2
  36. package/src/index.js +153 -180
  37. package/src/messages/network/v1/NetworkMessageBuilder.js +325 -0
  38. package/src/messages/network/v1/NetworkMessageDirector.js +137 -0
  39. package/src/messages/network/v1/networkMessageFactory.js +12 -0
  40. package/src/messages/state/ApplyStateMessageBuilder.js +661 -0
  41. package/src/messages/state/ApplyStateMessageDirector.js +516 -0
  42. package/src/messages/state/applyStateMessageFactory.js +12 -0
  43. package/src/utils/buffer.js +53 -1
  44. package/src/utils/cli.js +0 -8
  45. package/src/utils/constants.js +34 -14
  46. package/src/utils/normalizers.js +84 -2
  47. package/src/utils/protobuf/network.cjs +840 -0
  48. package/src/utils/protobuf/operationHelpers.js +10 -0
  49. package/tests/acceptance/v1/rpc.test.mjs +1 -1
  50. package/tests/fixtures/networkV1.fixtures.js +84 -0
  51. package/tests/fixtures/protobuf.fixtures.js +83 -0
  52. package/tests/helpers/config.js +1 -1
  53. package/tests/helpers/setupApplyTests.js +53 -46
  54. package/tests/unit/messages/messages.test.js +12 -0
  55. package/tests/unit/messages/network/NetworkMessageBuilder.test.js +276 -0
  56. package/tests/unit/messages/network/NetworkMessageDirector.test.js +203 -0
  57. package/tests/unit/messages/state/applyStateMessageBuilder.complete.test.js +521 -0
  58. package/tests/unit/messages/state/applyStateMessageBuilder.partial.test.js +233 -0
  59. package/tests/unit/network/ConnectionManager.test.js +6 -5
  60. package/tests/unit/network/networkModule.test.js +3 -2
  61. package/tests/unit/state/apply/addAdmin/addAdminHappyPathScenario.js +10 -6
  62. package/tests/unit/state/apply/addAdmin/addAdminScenarioHelpers.js +9 -6
  63. package/tests/unit/state/apply/addAdmin/state.apply.addAdmin.test.js +10 -7
  64. package/tests/unit/state/apply/addIndexer/addIndexerScenarioHelpers.js +18 -21
  65. package/tests/unit/state/apply/addWriter/addWriterScenarioHelpers.js +53 -38
  66. package/tests/unit/state/apply/adminRecovery/adminRecoveryScenarioHelpers.js +46 -35
  67. package/tests/unit/state/apply/appendWhitelist/appendWhitelistScenarioHelpers.js +13 -16
  68. package/tests/unit/state/apply/balanceInitialization/balanceInitializationScenarioHelpers.js +17 -11
  69. package/tests/unit/state/apply/banValidator/banValidatorScenarioHelpers.js +11 -12
  70. package/tests/unit/state/apply/bootstrapDeployment/bootstrapDeploymentScenarioHelpers.js +9 -7
  71. package/tests/unit/state/apply/common/commonScenarioHelper.js +15 -14
  72. package/tests/unit/state/apply/common/payload-structure/initializationDisabledScenario.js +9 -4
  73. package/tests/unit/state/apply/disableInitialization/disableInitializationScenarioHelpers.js +17 -11
  74. package/tests/unit/state/apply/removeWriter/removeWriterScenarioHelpers.js +19 -14
  75. package/tests/unit/state/apply/transfer/transferDoubleSpendAcrossValidatorsScenario.js +37 -29
  76. package/tests/unit/state/apply/transfer/transferScenarioHelpers.js +9 -7
  77. package/tests/unit/state/apply/txOperation/txOperationScenarioHelpers.js +11 -9
  78. package/tests/unit/unit.test.js +1 -1
  79. package/tests/unit/utils/buffer/buffer.test.js +62 -1
  80. package/tests/unit/utils/normalizers/normalizers.test.js +469 -0
  81. package/tests/unit/utils/protobuf/operationHelpers.test.js +120 -2
  82. package/docs/networking-dualstack-plan.md +0 -75
  83. package/docs/networking-layer-redesign.md +0 -155
  84. package/src/core/network/messaging/NetworkMessages.js +0 -64
  85. package/src/core/network/messaging/handlers/GetRequestHandler.js +0 -113
  86. package/src/core/network/messaging/handlers/ResponseHandler.js +0 -107
  87. package/src/core/network/messaging/handlers/RoleOperationHandler.js +0 -114
  88. package/src/core/network/messaging/handlers/SubnetworkOperationHandler.js +0 -149
  89. package/src/core/network/messaging/routes/NetworkMessageRouter.js +0 -98
  90. package/src/core/network/messaging/validators/AdminResponse.js +0 -58
  91. package/src/core/network/messaging/validators/CustomNodeResponse.js +0 -46
  92. package/src/messages/base/StateBuilder.js +0 -25
  93. package/src/messages/completeStateMessages/CompleteStateMessageBuilder.js +0 -425
  94. package/src/messages/completeStateMessages/CompleteStateMessageDirector.js +0 -252
  95. package/src/messages/completeStateMessages/CompleteStateMessageOperations.js +0 -296
  96. package/src/messages/partialStateMessages/PartialStateMessageBuilder.js +0 -272
  97. package/src/messages/partialStateMessages/PartialStateMessageDirector.js +0 -137
  98. package/src/messages/partialStateMessages/PartialStateMessageOperations.js +0 -138
  99. package/tests/integration/apply/addAdmin/addAdminBasic.test.js +0 -69
  100. package/tests/integration/apply/addAdmin/addAdminRecovery.test.js +0 -126
  101. package/tests/integration/apply/addIndexer.test.js +0 -239
  102. package/tests/integration/apply/addWhitelist.test.js +0 -53
  103. package/tests/integration/apply/addWriter.test.js +0 -245
  104. package/tests/integration/apply/apply.test.js +0 -19
  105. package/tests/integration/apply/banValidator.test.js +0 -116
  106. package/tests/integration/apply/postTx/invalidSubValues.test.js +0 -103
  107. package/tests/integration/apply/postTx/postTx.test.js +0 -196
  108. package/tests/integration/apply/removeIndexer.test.js +0 -132
  109. package/tests/integration/apply/removeWriter.test.js +0 -168
  110. package/tests/integration/apply/transfer.test.js +0 -83
  111. package/tests/integration/integration.test.js +0 -9
  112. package/tests/unit/messageOperations/assembleAddIndexerMessage.test.js +0 -21
  113. package/tests/unit/messageOperations/assembleAddWriterMessage.test.js +0 -17
  114. package/tests/unit/messageOperations/assembleAdminMessage.test.js +0 -68
  115. package/tests/unit/messageOperations/assembleBanWriterMessage.test.js +0 -17
  116. package/tests/unit/messageOperations/assemblePostTransaction.test.js +0 -424
  117. package/tests/unit/messageOperations/assembleRemoveIndexerMessage.test.js +0 -19
  118. package/tests/unit/messageOperations/assembleRemoveWriterMessage.test.js +0 -17
  119. package/tests/unit/messageOperations/assembleWhitelistMessages.test.js +0 -59
  120. package/tests/unit/messageOperations/commonsStateMessageOperationsTest.js +0 -278
  121. package/tests/unit/messageOperations/stateMessageOperations.test.js +0 -19
  122. /package/src/core/network/{messaging → protocols/legacy}/validators/ValidatorResponse.js +0 -0
  123. /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,16 +43,15 @@ 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
  /**
@@ -67,7 +60,6 @@ export class MainSettlementBus extends ReadyResource {
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,8 +88,10 @@ 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
 
@@ -113,15 +107,12 @@ export class MainSettlementBus extends ReadyResource {
113
107
 
114
108
  await this.#state.ready();
115
109
  await this.#network.ready();
116
- this.#stateEventsListener();
110
+ await this.#stateEventsListener();
117
111
 
118
112
  if (this.#config.enableWallet) {
119
113
  printWalletInfo(this.#wallet.address, this.#state.writingKey, this.#state, this.#config.enableWallet);
120
114
  }
121
115
 
122
- this.#partialTransferValidator = new PartialTransfer(this.state, this.#wallet, this.#config);
123
- this.#partialTransactionValidator = new PartialTransaction(this.state, this.#wallet ,this.#config);
124
-
125
116
  await this.#network.replicate(
126
117
  this.#state,
127
118
  this.#store,
@@ -131,6 +122,8 @@ export class MainSettlementBus extends ReadyResource {
131
122
  const adminEntry = await this.#state.getAdminEntry();
132
123
  await this.#setUpRoleAutomatically(adminEntry);
133
124
 
125
+
126
+
134
127
  console.log(`isIndexer: ${this.#state.isIndexer()}`);
135
128
  console.log(`isWriter: ${this.#state.isWritable()}`);
136
129
  console.log("MSB Unsigned Length:", this.#state.getUnsignedLength());
@@ -182,41 +175,6 @@ export class MainSettlementBus extends ReadyResource {
182
175
  return await this.#network.validatorMessageOrchestrator.send(partialTransactionPayload);
183
176
  }
184
177
 
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
178
  async #setUpRoleAutomatically() {
221
179
  if (!this.#state.isWritable() && this.#config.enableRoleRequester) {
222
180
  console.log("Requesting writer role... This may take a moment.");
@@ -296,14 +254,17 @@ export class MainSettlementBus extends ReadyResource {
296
254
  }
297
255
 
298
256
  const txValidity = await PeerWallet.blake3(this.#config.bootstrap);
299
- const addAdminMessage = await new CompleteStateMessageOperations(this.#wallet, this.#config)
300
- .assembleAddAdminMessage(
257
+ const addAdminMessage = await applyStateMessageFactory(this.#wallet, this.#config)
258
+ .buildCompleteAddAdminMessage(
259
+ this.#wallet.address,
301
260
  this.#state.writingKey,
302
- txValidity
303
- );
261
+ txValidity,
262
+ )
263
+ const encodedPayload = safeEncodeApplyOperation(addAdminMessage);
304
264
 
305
- await this.#state.append(addAdminMessage);
265
+ await this.#state.append(encodedPayload);
306
266
  }
267
+
307
268
  async #handleAdminRecovery() {
308
269
  if (!this.#config.enableWallet) {
309
270
  throw new Error("Can not initialize an admin - wallet is not enabled.");
@@ -329,10 +290,13 @@ export class MainSettlementBus extends ReadyResource {
329
290
  }
330
291
 
331
292
  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
- );
293
+ const adminRecoveryMessage = await applyStateMessageFactory(this.#wallet, this.#config)
294
+ .buildPartialAdminRecoveryMessage(
295
+ this.#wallet.address,
296
+ this.#state.writingKey,
297
+ txValidity,
298
+ "json"
299
+ )
336
300
 
337
301
  const success = await this.broadcastPartialTransaction(adminRecoveryMessage);
338
302
 
@@ -366,12 +330,13 @@ export class MainSettlementBus extends ReadyResource {
366
330
 
367
331
  for (const addressToWhitelist of addresses) {
368
332
  const txValidity = await this.#state.getIndexerSequenceState();
369
- const encodedPayload = await new CompleteStateMessageOperations(this.#wallet, this.#config)
370
- .assembleAppendWhitelistMessages(
333
+ const appendWhitelistMessage = await applyStateMessageFactory(this.#wallet, this.#config)
334
+ .buildCompleteAppendWhitelistMessage(
335
+ this.#wallet.address,
336
+ addressToWhitelist,
371
337
  txValidity,
372
- addressToWhitelist
373
- );
374
-
338
+ )
339
+ const encodedPayload = safeEncodeApplyOperation(appendWhitelistMessage)
375
340
  messages.set(addressToWhitelist, encodedPayload);
376
341
  }
377
342
 
@@ -445,10 +410,13 @@ export class MainSettlementBus extends ReadyResource {
445
410
  }
446
411
 
447
412
  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')
413
+
414
+ const assembledMessage = await applyStateMessageFactory(this.#wallet, this.#config)
415
+ .buildPartialAddWriterMessage(
416
+ this.#wallet.address,
417
+ this.#state.writingKey,
418
+ txValidity,
419
+ 'json'
452
420
  )
453
421
 
454
422
  const success = await this.broadcastPartialTransaction(assembledMessage);
@@ -477,10 +445,12 @@ export class MainSettlementBus extends ReadyResource {
477
445
  }
478
446
 
479
447
  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')
448
+ const assembledMessage = await applyStateMessageFactory(this.#wallet, this.#config)
449
+ .buildPartialRemoveWriterMessage(
450
+ this.#wallet.address,
451
+ nodeEntry.wk,
452
+ txValidity,
453
+ "json"
484
454
  )
485
455
 
486
456
  const success = await this.broadcastPartialTransaction(assembledMessage);
@@ -492,10 +462,10 @@ export class MainSettlementBus extends ReadyResource {
492
462
  console.info(`Transaction hash: ${assembledMessage.rao.tx}`);
493
463
  }
494
464
 
495
- async #updateIndexerRole(address, toAdd) {
465
+ async #updateWriterToIndexerRole(addressToUpdate, toAdd) {
496
466
  if (!this.#config.enableWallet) {
497
467
  throw new Error(
498
- `Can not request indexer role for: ${address} - wallet is not enabled.`
468
+ `Can not request indexer role for: ${addressToUpdate} - wallet is not enabled.`
499
469
  );
500
470
  }
501
471
 
@@ -503,29 +473,29 @@ export class MainSettlementBus extends ReadyResource {
503
473
 
504
474
  if (!adminEntry) {
505
475
  throw new Error(
506
- `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.`
507
477
  );
508
478
  }
509
479
 
510
- if (!isAddressValid(address, this.#config.addressPrefix)) {
480
+ if (!isAddressValid(addressToUpdate, this.#config.addressPrefix)) {
511
481
  throw new Error(
512
- `Can not request indexer role for: ${address} - invalid address.`
482
+ `Can not request indexer role for: ${addressToUpdate} - invalid address.`
513
483
  );
514
484
  }
515
485
 
516
486
  if (!this.#isAdmin(adminEntry) && !this.#state.isWritable()) {
517
487
  throw new Error(
518
- `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.`
519
489
  );
520
490
  }
521
- const nodeEntry = await this.#state.getNodeEntry(address);
491
+ const nodeEntry = await this.#state.getNodeEntry(addressToUpdate);
522
492
  if (!nodeEntry) {
523
493
  throw new Error(
524
- `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.`
525
495
  );
526
496
  }
527
497
 
528
- const indexerNodeEntry = await this.#state.getNodeEntry(address);
498
+ const indexerNodeEntry = await this.#state.getNodeEntry(addressToUpdate);
529
499
  const indexerListHasAddress = await this.#state.isWkInIndexersEntry(
530
500
  indexerNodeEntry.wk,
531
501
  );
@@ -533,7 +503,7 @@ export class MainSettlementBus extends ReadyResource {
533
503
  if (toAdd) {
534
504
  if (indexerListHasAddress) {
535
505
  throw new Error(
536
- `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.`
537
507
  );
538
508
  }
539
509
 
@@ -545,71 +515,86 @@ export class MainSettlementBus extends ReadyResource {
545
515
 
546
516
  if (!canAddIndexer) {
547
517
  throw new Error(
548
- `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.`
549
519
  );
550
520
  }
551
521
  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);
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);
555
533
  } else {
556
534
  const canRemoveIndexer =
557
535
  !toAdd && nodeEntry.isIndexer && indexerListHasAddress;
558
536
 
559
537
  if (!canRemoveIndexer) {
560
538
  throw new Error(
561
- `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.`
562
540
  );
563
541
  }
564
542
  const txValidity = await this.#state.getIndexerSequenceState();
565
- const assembledRemoveIndexer = await new CompleteStateMessageOperations(this.#wallet, this.#config)
566
- .assembleRemoveIndexerMessage(address, txValidity);
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);
567
550
 
568
- await this.#state.append(assembledRemoveIndexer);
551
+ await this.#state.append(encodedPayload);
569
552
  }
570
553
  }
571
554
 
572
- async #banValidator(address) {
555
+ async #banValidator(addresstToBan) {
573
556
  if (!this.#config.enableWallet) {
574
557
  throw new Error(
575
- `Can not ban writer with address: ${address} - wallet is not enabled.`
558
+ `Can not ban writer with address: ${addresstToBan} - wallet is not enabled.`
576
559
  );
577
560
  }
578
561
  const adminEntry = await this.#state.getAdminEntry();
579
562
 
580
563
  if (!adminEntry) {
581
564
  throw new Error(
582
- `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.`
583
566
  );
584
567
  }
585
568
 
586
- if (!isAddressValid(address, this.#config.addressPrefix)) {
569
+ if (!isAddressValid(addresstToBan, this.#config.addressPrefix)) {
587
570
  throw new Error(
588
- `Can not ban writer with address: ${address} - invalid address.`
571
+ `Can not ban writer with address: ${addresstToBan} - invalid address.`
589
572
  );
590
573
  }
591
574
 
592
575
  if (!this.#isAdmin(adminEntry)) {
593
576
  throw new Error(
594
- `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.`
595
578
  );
596
579
  }
597
580
 
598
- const isWhitelisted = await this.#state.isAddressWhitelisted(address);
599
- const nodeEntry = await this.#state.getNodeEntry(address);
581
+ const isWhitelisted = await this.#state.isAddressWhitelisted(addresstToBan);
582
+ const nodeEntry = await this.#state.getNodeEntry(addresstToBan);
600
583
 
601
584
  if (!isWhitelisted || null === nodeEntry || nodeEntry.isIndexer === true) {
602
585
  throw new Error(
603
- `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.`
604
587
  );
605
588
  }
606
589
  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);
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);
613
598
  }
614
599
 
615
600
  async #deployBootstrap(externalBootstrap, channel) {
@@ -682,12 +667,15 @@ export class MainSettlementBus extends ReadyResource {
682
667
  }
683
668
 
684
669
  const txValidity = await this.#state.getIndexerSequenceState();
685
- const payload = await new PartialStateMessageOperations(this.#wallet, this.#config)
686
- .assembleBootstrapDeploymentMessage(
670
+
671
+ const payload = await applyStateMessageFactory(this.#wallet, this.#config)
672
+ .buildPartialBootstrapDeploymentMessage(
673
+ this.#wallet.address,
687
674
  externalBootstrap,
688
675
  channel,
689
- txValidity.toString('hex')
690
- );
676
+ txValidity,
677
+ "json"
678
+ )
691
679
 
692
680
  const success = await this.broadcastPartialTransaction(payload);
693
681
 
@@ -703,31 +691,7 @@ export class MainSettlementBus extends ReadyResource {
703
691
 
704
692
  }
705
693
 
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) {
694
+ async #handleTransferOperation(recipientAddress, amount) {
731
695
  if (!this.#config.enableWallet) {
732
696
  throw new Error(
733
697
  "Can not perform transfer - wallet is not enabled."
@@ -740,7 +704,7 @@ export class MainSettlementBus extends ReadyResource {
740
704
  );
741
705
  }
742
706
 
743
- if (!isAddressValid(address, this.#config.addressPrefix)) {
707
+ if (!isAddressValid(recipientAddress, this.#config.addressPrefix)) {
744
708
  throw new Error("Invalid recipient address");
745
709
  }
746
710
 
@@ -765,7 +729,7 @@ export class MainSettlementBus extends ReadyResource {
765
729
  const fee = this.#state.getFee();
766
730
  const feeBigInt = bufferToBigInt(fee);
767
731
  const senderBalance = bufferToBigInt(senderEntry.balance);
768
- const isSelfTransfer = address === this.#wallet.address;
732
+ const isSelfTransfer = recipientAddress === this.#wallet.address;
769
733
  const totalDeductedAmount = isSelfTransfer ? feeBigInt : amountBigInt + feeBigInt;
770
734
 
771
735
  if (!(senderBalance >= totalDeductedAmount)) {
@@ -773,13 +737,14 @@ export class MainSettlementBus extends ReadyResource {
773
737
  }
774
738
 
775
739
  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
-
740
+ const payload = await applyStateMessageFactory(this.#wallet, this.#config)
741
+ .buildPartialTransferOperationMessage(
742
+ this.#wallet.address,
743
+ recipientAddress,
744
+ amountBuffer,
745
+ txValidity,
746
+ "json"
747
+ )
783
748
 
784
749
  const expectedNewBalance = senderBalance - totalDeductedAmount;
785
750
  console.info('Transfer Details:');
@@ -794,7 +759,6 @@ export class MainSettlementBus extends ReadyResource {
794
759
  console.info(`Total: ${bigIntToDecimalString(totalDeductedAmount)}`);
795
760
  }
796
761
  console.log(`Expected Balance After Transfer: ${bigIntToDecimalString(expectedNewBalance)}`);
797
-
798
762
  const success = await this.broadcastPartialTransaction(payload);
799
763
  if (!success) {
800
764
  throw new Error("Failed to broadcast transfer transaction after multiple attempts.");
@@ -804,7 +768,7 @@ export class MainSettlementBus extends ReadyResource {
804
768
 
805
769
  }
806
770
 
807
- async #handleBalanceMigrationOperation() {
771
+ async #balanceMigrationOperation() {
808
772
 
809
773
  const isInitDisabled = await this.#state.isInitalizationDisabled()
810
774
 
@@ -849,11 +813,18 @@ export class MainSettlementBus extends ReadyResource {
849
813
  await fileUtils.createMigrationEntryFile(addressBalancePair, migrationNumber);
850
814
 
851
815
  const txValidity = await this.#state.getIndexerSequenceState();
852
- const messages = await new CompleteStateMessageOperations(this.#wallet, this.#config)
853
- .assembleBalanceInitializationMessages(
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,
854
824
  txValidity,
855
- addressBalancePair,
856
- );
825
+ )
826
+ messages.push(safeEncodeApplyOperation(payload));
827
+ }
857
828
 
858
829
  console.log(`Total balance to migrate: ${bigIntToDecimalString(totalBalance)} across ${totalAddresses} addresses.`);
859
830
 
@@ -903,6 +874,10 @@ export class MainSettlementBus extends ReadyResource {
903
874
  if (!this.#config.enableWallet) {
904
875
  throw new Error("Can not initialize an admin - wallet is not enabled.");
905
876
  }
877
+ const isInitDisabled = await this.#state.isInitalizationDisabled();
878
+ if (isInitDisabled) {
879
+ throw new Error("Can not disable initialization - it is already disabled.");
880
+ }
906
881
  const adminEntry = await this.#state.getAdminEntry();
907
882
 
908
883
  if (!adminEntry) {
@@ -912,15 +887,24 @@ export class MainSettlementBus extends ReadyResource {
912
887
  if (!this.#isAdmin(adminEntry)) {
913
888
  throw new Error('Cannot perform whitelisting - you are not the admin!.');
914
889
  }
915
- // 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
+ }
916
896
  const txValidity = await this.#state.getIndexerSequenceState();
917
- const payload = await new CompleteStateMessageOperations(this.#wallet, this.#config)
918
- .assembleDisableInitializationMessage(
897
+
898
+
899
+ const payload = await applyStateMessageFactory(this.#wallet, this.#config)
900
+ .buildCompleteDisableInitializationMessage(
901
+ this.#wallet.address,
919
902
  this.#state.writingKey,
920
903
  txValidity,
921
904
  )
922
905
  console.log('Disabling initialization...');
923
- await this.#state.append(payload);
906
+ const encodedPayload = safeEncodeApplyOperation(payload);
907
+ await this.#state.append(encodedPayload);
924
908
  }
925
909
 
926
910
  async interactiveMode() {
@@ -951,26 +935,22 @@ export class MainSettlementBus extends ReadyResource {
951
935
  if (rl) rl.close();
952
936
  await this.close();
953
937
  },
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(
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(
967
947
  this.#state,
968
948
  this.#network,
969
949
  this.#wallet,
970
950
  this.#state.writingKey
971
951
  ),
972
- "/balance_migration": () => this.#handleBalanceMigrationOperation(),
973
- "/disable_initialization": () => this.#disableInitialization()
952
+ "/balance_migration": async () => await this.#balanceMigrationOperation(),
953
+ "/disable_initialization": async () => await this.#disableInitialization()
974
954
  };
975
955
 
976
956
  if (exactHandlers[command]) {
@@ -988,20 +968,20 @@ export class MainSettlementBus extends ReadyResource {
988
968
 
989
969
  if (input.startsWith("/add_indexer")) {
990
970
  const address = parts[0];
991
- await this.#handleAddIndexerOperation(address);
971
+ await this.#updateWriterToIndexerRole(address, true);
992
972
  } else if (input.startsWith("/remove_indexer")) {
993
973
  const address = parts[0];
994
- await this.#handleRemoveIndexerOperation(address);
974
+ await this.#updateWriterToIndexerRole(address, false);
995
975
  } else if (input.startsWith("/ban_writer")) {
996
976
  const address = parts[0];
997
- await this.#handleBanValidatorOperation(address);
977
+ await this.#banValidator(address);
998
978
  } else if (input.startsWith("/deployment")) {
999
979
  const bootstrapToDeploy = parts[0];
1000
980
  const channel = parts[1] || randomBytes(32).toString("hex");
1001
981
  if (channel.length !== 64 || !isHexString(channel)) {
1002
982
  throw new Error("Channel must be a 32-byte hex string");
1003
983
  }
1004
- await this.#handleBootstrapDeploymentOperation(bootstrapToDeploy, channel);
984
+ await this.#deployBootstrap(bootstrapToDeploy, channel);
1005
985
  } else if (input.startsWith("/get_validator_addr")) {
1006
986
  const wkHexString = parts[0];
1007
987
  await getValidatorAddressCommand(this.#state, wkHexString, this.#config.addressPrefix);
@@ -1045,13 +1025,6 @@ export class MainSettlementBus extends ReadyResource {
1045
1025
  const result = getUnconfirmedLengthCommand(this.#state);
1046
1026
  if (rl) rl.prompt();
1047
1027
  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
1028
  } else if (input.startsWith("/get_tx_payloads_bulk")) {
1056
1029
  if (!payload) {
1057
1030
  throw new Error("Missing payload for fetching tx payloads.");