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
@@ -1,58 +0,0 @@
1
- import b4a from 'b4a';
2
- import PeerWallet from 'trac-wallet';
3
- import BaseResponse from './base/BaseResponse.js';
4
-
5
- class AdminResponse extends BaseResponse {
6
-
7
- constructor(state, wallet) {
8
- super(state, wallet);
9
- }
10
-
11
- async validate(message, channelString) {
12
- if (
13
- !this.validatePayload(message) ||
14
- !this.validateIssuerPublicKey(message) ||
15
- !this.validateTimestamp(message) ||
16
- !await this.validateAdminData(message) ||
17
- !await this.validateSignature(message) ||
18
- !this.validateChannel(message, channelString)
19
- ) {
20
- throw new Error("Admin response validation failed");
21
- }
22
-
23
- return true;
24
- }
25
-
26
- validatePayload(message) {
27
- if (!message ||
28
- !message.op ||
29
- !message.wk ||
30
- !message.address ||
31
- !message.nonce ||
32
- !message.channel ||
33
- !message.issuer ||
34
- !message.timestamp) {
35
- throw new Error("Admin response is missing required fields.");
36
- }
37
- return true;
38
- }
39
-
40
- async validateAdminData(message) {
41
- const adminEntry = await this.state.getAdminEntry();
42
- if (!adminEntry) {
43
- throw new Error("Admin entry is null");
44
- }
45
-
46
- const adminPublicKey = PeerWallet.decodeBech32m(adminEntry.address);
47
- const receivedAdminPublicKey = PeerWallet.decodeBech32m(message.address);
48
- const adminWritingKey = b4a.from(message.wk, 'hex');
49
-
50
- if (!b4a.equals(adminPublicKey, receivedAdminPublicKey) || !b4a.equals(adminEntry.wk, adminWritingKey)) {
51
- throw new Error("Admin public key or writing key mismatch in response.");
52
- }
53
-
54
- return true;
55
- }
56
- }
57
-
58
- export default AdminResponse;
@@ -1,46 +0,0 @@
1
- import BaseResponse from './base/BaseResponse.js';
2
-
3
- class CustomNodeResponse extends BaseResponse {
4
-
5
- constructor(state, wallet) {
6
- super(state, wallet);
7
- }
8
-
9
- async validate(message, channelString) {
10
- if (
11
- !this.validatePayload(message) ||
12
- !this.validateIssuerPublicKey(message) ||
13
- !this.validateTimestamp(message) ||
14
- !await this.validateCustomNodeEntry(message) ||
15
- !await this.validateSignature(message) ||
16
- !this.validateChannel(message, channelString)
17
- ) {
18
- throw new Error("Custom node response validation failed");
19
- }
20
-
21
- return true;
22
- }
23
-
24
- validatePayload(message) {
25
- if (!message ||
26
- !message.op ||
27
- !message.address ||
28
- !message.nonce ||
29
- !message.channel ||
30
- !message.issuer ||
31
- !message.timestamp) {
32
- throw new Error("Custom node response is missing required fields.");
33
- }
34
- return true;
35
- }
36
-
37
- async validateCustomNodeEntry(message) {
38
- const customNodeAddressString = message.address;
39
- const customNodeEntry = await this.state.getNodeEntry(customNodeAddressString);
40
- if (customNodeEntry === null) {
41
- throw new Error("Custom node entry is null - entry is not initialized.");
42
- }
43
- return true;
44
- }
45
- }
46
- export default CustomNodeResponse;
@@ -1,105 +0,0 @@
1
- import b4a from 'b4a';
2
- import { TRAC_ADDRESS_SIZE } from '../../../utils/constants.js';
3
- import { isBufferValid } from '../../../utils/buffer.js';
4
-
5
- /**
6
- * Appends an indexer address to the indexers entry buffer.
7
- * The buffer format is: [count(1)][indexerAddr1][indexerAddr2]...[indexerAddrN]
8
- * Where count is the number of indexers.
9
- * If indexersEntry is null or invalid, a new buffer is created.
10
- * If indexerAddr is invalid, the original entry is returned unchanged.
11
- *
12
- * @param {Buffer} indexerAddr - The indexer address to append (must be TRAC_ADDRESS_SIZE bytes).
13
- * @param {Buffer|null} indexersEntry - The current indexers entry buffer, or null to create a new one.
14
- * @returns {Buffer} The updated indexers entry buffer or an empty buffer in case something goes wrong.
15
- */
16
- export function append(indexerAddr, indexersEntry = null) {
17
- if (!isBufferValid(indexerAddr, TRAC_ADDRESS_SIZE)) {
18
- return b4a.alloc(0);
19
- }
20
- // Append the indexer address to the IndexersEntry buffer
21
- try {
22
- let newIndexersEntry;
23
- if (!b4a.isBuffer(indexersEntry) || indexersEntry.length < TRAC_ADDRESS_SIZE + 1) {
24
- newIndexersEntry = b4a.concat([b4a.from([1]), indexerAddr]);
25
- }
26
- else {
27
- newIndexersEntry = b4a.concat([indexersEntry, indexerAddr]);
28
- newIndexersEntry[0]++;
29
- }
30
- return newIndexersEntry;
31
- }
32
- catch (error) {
33
- console.error("Error appending indexer:", error);
34
- return b4a.alloc(0); // If some error occurs, do nothing
35
- }
36
- }
37
-
38
- /**
39
- * Finds the index of a given indexer address within the indexers entry buffer.
40
- * The buffer format is: [count(1)][indexerAddr1][indexerAddr2]...[indexerAddrN]
41
- * Returns the zero-based index of the address if found, or -1 if not found.
42
- *
43
- * @param {Buffer} indexersEntry - The current indexers entry buffer.
44
- * @param {Buffer} indexerAddr - The indexer address to search for (must be TRAC_ADDRESS_SIZE bytes).
45
- * @returns {number} The index of the address if found, or -1 if not found.
46
- */
47
- export function getIndex(indexersEntry, indexerAddr) {
48
- if (
49
- !b4a.isBuffer(indexersEntry) ||
50
- !isBufferValid(indexerAddr, TRAC_ADDRESS_SIZE) ||
51
- indexersEntry.length < TRAC_ADDRESS_SIZE + 1 // it should ensure minimal length of the indexersEntry
52
- ) {
53
- return -1;
54
- }
55
- // step through the indexersEntry until we find indexerAddr
56
- for (let i = 0; i < indexersEntry[0]; i++) {
57
- if (b4a.equals(indexersEntry.subarray(1 + i * TRAC_ADDRESS_SIZE, 1 + (i + 1) * TRAC_ADDRESS_SIZE), indexerAddr)) {
58
- return i;
59
- }
60
- }
61
- return -1; // Not found
62
- }
63
-
64
- /**
65
- * Removes an indexer address from the indexers entry buffer.
66
- * The buffer format is: [count(1)][indexerAddr1][indexerAddr2]...[indexerAddrN]
67
- * If the indexer address is not found or input is invalid, returns an empty buffer.
68
- *
69
- * @param {Buffer} indexerAddr - The indexer address to remove (must be TRAC_ADDRESS_SIZE bytes).
70
- * @param {Buffer} indexersEntry - The current indexers entry buffer.
71
- * @returns {Buffer} The updated indexers entry buffer with the address removed,
72
- * or an empty buffer if the address is not found or input is invalid.
73
- */
74
- export function remove(indexerAddr, indexersEntry) {
75
- if (!b4a.isBuffer(indexersEntry) ||
76
- indexersEntry.length < TRAC_ADDRESS_SIZE + 1 ||
77
- !isBufferValid(indexerAddr, TRAC_ADDRESS_SIZE)) {
78
- return b4a.alloc(0); // If the indexer address is invalid, do nothing
79
- }
80
-
81
- try {
82
- const index = getIndex(indexersEntry, indexerAddr);
83
- if (index === -1) {
84
- return b4a.alloc(0); // If the indexer is not found, do nothing
85
- }
86
- // Remove the indexer address from the entry
87
- const newIndexersEntry = b4a.concat([
88
- indexersEntry.subarray(0, 1 + index * TRAC_ADDRESS_SIZE),
89
- indexersEntry.subarray(1 + (index + 1) * TRAC_ADDRESS_SIZE)
90
- ]);
91
-
92
- newIndexersEntry[0]--; // Decrease the count of indexers
93
- return newIndexersEntry;
94
- }
95
- catch (error) {
96
- console.error("Error removing indexer:", error);
97
- return b4a.alloc(0); // If some error occurs, do nothing
98
- }
99
- }
100
-
101
- export default {
102
- append,
103
- getIndex,
104
- remove
105
- };
@@ -1,25 +0,0 @@
1
- class StateBuilder {
2
-
3
- constructor() {
4
- if (this.constructor === StateBuilder) {
5
- throw new Error("Builder is an abstract class and cannot be instantiated directly.");
6
- }
7
- }
8
- reset() { throw new Error("Method 'reset()' must be implemented.");}
9
- forOperationType(operationType) {throw new Error("Method 'forOperationType()' must be implemented.");}
10
- withAddress(address) { throw new Error("Method 'withAddress()' must be implemented.");}
11
- withWriterKey(writerKey) { throw new Error("Method 'withWriterKey()' must be implemented.");}
12
- async buildValueAndSign() { throw new Error("Method 'buildValueAndSign()' must be implemented.");}
13
- withIncomingAddress(address) { throw new Error("Method 'withIncomingAddress()' must be implemented.");}
14
- withIncomingWriterKey(writerKey) { throw new Error("Method 'withIncomingWriterKey()' must be implemented.");}
15
- withIncomingNonce(nonce) { throw new Error("Method 'withIncomingNonce()' must be implemented.");}
16
- withContentHash(contentHash) { throw new Error("Method 'withContentHash()' must be implemented.");}
17
- withIncomingSignature(signature) { throw new Error("Method 'withIncomingSignature()' must be implemented.");}
18
- withExternalBootstrap(bootstrapKey) { throw new Error("Method 'withExternalBootstrap()' must be implemented.");}
19
- withMsbBootstrap(msbBootstrap) { throw new Error("Method 'withMsbBootstrap()' must be implemented.");}
20
- withTxHash(txHash) { throw new Error("Method 'withTxHash()' must be implemented.");}
21
- withTxValidity(txValidity) { throw new Error("Method 'withTxValidity()' must be implemented.");}
22
- withAmount(amount) { throw new Error("Method 'withAmount()' must be implemented.");}
23
- }
24
-
25
- export default StateBuilder;
@@ -1,421 +0,0 @@
1
- import b4a from 'b4a';
2
- import PeerWallet from 'trac-wallet';
3
-
4
- import StateBuilder from '../base/StateBuilder.js'
5
- import { createMessage } from '../../utils/buffer.js';
6
- import { OperationType } from '../../utils/protobuf/applyOperations.cjs'
7
- import { addressToBuffer, bufferToAddress } from '../../core/state/utils/address.js';
8
- import { TRAC_ADDRESS_SIZE, NETWORK_ID } from '../../utils/constants.js';
9
- import { isAddressValid } from "../../core/state/utils/address.js";
10
- import { blake3Hash } from '../../utils/crypto.js';
11
- import {
12
- isCoreAdmin,
13
- isAdminControl,
14
- isRoleAccess,
15
- isTransaction,
16
- isBootstrapDeployment,
17
- isTransfer,
18
- isBalanceInitialization
19
- } from '../../utils/operations.js';
20
-
21
- class CompleteStateMessageBuilder extends StateBuilder {
22
- #wallet;
23
- #operationType;
24
- #address;
25
- #writingKey;
26
- #payload;
27
- #txHash;
28
- #incomingAddress;
29
- #incomingWriterKey;
30
- #incomingNonce;
31
- #contentHash;
32
- #incomingSignature;
33
- #externalBootstrap;
34
- #channel;
35
- #msbBootstrap;
36
- #validatorNonce;
37
- #txValidity;
38
- #amount;
39
-
40
- constructor(wallet) {
41
- super();
42
- if (!wallet || typeof wallet !== 'object') {
43
- throw new Error('Wallet must be a valid wallet object');
44
- }
45
- if (!isAddressValid(wallet.address)) {
46
- throw new Error('Wallet should have a valid TRAC address.');
47
- }
48
-
49
-
50
- this.#wallet = wallet;
51
- this.reset();
52
- }
53
-
54
- reset() {
55
- this.#operationType = OperationType.UNKNOWN;
56
- this.#address = null;
57
- this.#writingKey = null;
58
- this.#payload = {};
59
- this.#txHash = null;
60
- this.#incomingAddress = null;
61
- this.#incomingWriterKey = null;
62
- this.#incomingNonce = null;
63
- this.#contentHash = null;
64
- this.#incomingSignature = null;
65
- this.#externalBootstrap = null;
66
- this.#channel = null;
67
- this.#msbBootstrap = null;
68
- this.#validatorNonce = null;
69
- this.#txValidity = null;
70
- this.#amount = null;
71
- }
72
-
73
- forOperationType(operationType) {
74
- if (!Object.values(OperationType).includes(operationType) || OperationType === OperationType.UNKNOWN) {
75
- throw new Error(`Invalid operation type: ${operationType}`);
76
- }
77
- this.#operationType = operationType;
78
- this.#payload.type = operationType;
79
- return this;
80
- }
81
-
82
- withAddress(address) {
83
- if (b4a.isBuffer(address) && address.length === TRAC_ADDRESS_SIZE) {
84
- address = bufferToAddress(address);
85
- }
86
-
87
- if (!isAddressValid(address)) {
88
- throw new Error(`Address field must be a valid TRAC bech32m address with length ${TRAC_ADDRESS_SIZE}.`);
89
- }
90
-
91
- this.#address = addressToBuffer(address);
92
- this.#payload.address = this.#address;
93
- return this;
94
- }
95
-
96
- withWriterKey(writingKey) {
97
- if (!b4a.isBuffer(writingKey) || writingKey.length !== 32) {
98
- throw new Error('Writer key must be a 32 length buffer.');
99
- }
100
- this.#writingKey = writingKey;
101
- return this;
102
- }
103
-
104
- withTxHash(txHash) {
105
- if (!b4a.isBuffer(txHash) || txHash.length !== 32) {
106
- throw new Error('Transaction hash must be a 32-byte buffer.');
107
- }
108
- this.#txHash = txHash;
109
- return this;
110
- }
111
-
112
- withIncomingAddress(address) {
113
- if (b4a.isBuffer(address) && address.length === TRAC_ADDRESS_SIZE) {
114
- address = bufferToAddress(address);
115
- }
116
-
117
- if (!isAddressValid(address)) {
118
- throw new Error(`Address field must be a valid TRAC bech32m address with length ${TRAC_ADDRESS_SIZE}.`);
119
- }
120
-
121
- this.#incomingAddress = addressToBuffer(address);
122
- return this;
123
- }
124
-
125
- withIncomingWriterKey(writerKey) {
126
- if (!b4a.isBuffer(writerKey) || writerKey.length !== 32) {
127
- throw new Error('Incoming writer key must be a 32-byte buffer.');
128
- }
129
- this.#incomingWriterKey = writerKey;
130
- return this;
131
- }
132
-
133
- withIncomingNonce(nonce) {
134
- if (!b4a.isBuffer(nonce) || nonce.length !== 32) {
135
- throw new Error('Incoming nonce must be a 32-byte buffer.');
136
- }
137
- this.#incomingNonce = nonce;
138
- return this;
139
- }
140
-
141
- withContentHash(contentHash) {
142
- if (!b4a.isBuffer(contentHash) || contentHash.length !== 32) {
143
- throw new Error('Content hash must be a 32-byte buffer.');
144
- }
145
- this.#contentHash = contentHash;
146
- return this;
147
- }
148
-
149
- withIncomingSignature(signature) {
150
- if (!b4a.isBuffer(signature) || signature.length !== 64) {
151
- throw new Error('Incoming signature must be a 64-byte buffer.');
152
- }
153
- this.#incomingSignature = signature;
154
- return this;
155
- }
156
-
157
- withExternalBootstrap(bootstrapKey) {
158
- if (!b4a.isBuffer(bootstrapKey) || bootstrapKey.length !== 32) {
159
- throw new Error('Bootstrap key must be a 32-byte buffer.');
160
- }
161
- this.#externalBootstrap = bootstrapKey;
162
- return this;
163
- }
164
-
165
- withMsbBootstrap(msbBootstrap) {
166
- if (!b4a.isBuffer(msbBootstrap) || msbBootstrap.length !== 32) {
167
- throw new Error('MSB bootstrap must be a 32-byte buffer.');
168
- }
169
- this.#msbBootstrap = msbBootstrap;
170
- return this;
171
- }
172
-
173
- withChannel(channel) {
174
- if (!b4a.isBuffer(channel) || channel.length !== 32) {
175
- throw new Error('Channel must be a 32-byte buffer.');
176
- }
177
- this.#channel = channel;
178
- return this;
179
- }
180
-
181
- withTxValidity(txValidity) {
182
- if (!b4a.isBuffer(txValidity) || txValidity.length !== 32) {
183
- throw new Error('Transaction validity must be a 32-byte buffer.');
184
- }
185
- this.#txValidity = txValidity;
186
- return this;
187
- }
188
-
189
- withAmount(amount) {
190
- if (!b4a.isBuffer(amount) || amount.length !== 16) {
191
- throw new Error('Amount must be a 16-byte buffer.');
192
- }
193
-
194
- this.#amount = amount;
195
- return this;
196
- }
197
-
198
- async buildValueAndSign() {
199
- if (!this.#operationType || !this.#address) {
200
- throw new Error('Operation type, address must be set before building the message.');
201
- }
202
-
203
- if (this.#operationType === OperationType.UNKNOWN) {
204
- throw new Error('UNKNOWN is not allowed to construct');
205
- }
206
-
207
- const nonce = PeerWallet.generateNonce();
208
-
209
- let msg = null;
210
- let tx = null;
211
- let signature = null;
212
-
213
- // all incoming data from setters should be as buffer data type, createMessage accept only buffer and uint32
214
- switch (this.#operationType) {
215
- // Complete by default
216
- case OperationType.ADD_ADMIN:
217
- case OperationType.DISABLE_INITIALIZATION:
218
- msg = createMessage(
219
- NETWORK_ID,
220
- this.#txValidity,
221
- this.#writingKey,
222
- nonce,
223
- this.#operationType);
224
- break;
225
- // Complete by default
226
- case OperationType.BALANCE_INITIALIZATION:
227
- if (!this.#incomingAddress || !this.#amount || !this.#txValidity || !this.#address) {
228
- throw new Error('All balance initialization fields must be set before building the message!');
229
- }
230
- msg = createMessage(
231
- NETWORK_ID,
232
- this.#txValidity,
233
- this.#incomingAddress,
234
- this.#amount,
235
- nonce,
236
- this.#operationType
237
- );
238
- break;
239
- // Partial need to be signed
240
- case OperationType.ADD_WRITER:
241
- case OperationType.REMOVE_WRITER:
242
- case OperationType.ADMIN_RECOVERY:
243
- msg = createMessage(
244
- NETWORK_ID,
245
- this.#txHash,
246
- nonce,
247
- this.#operationType
248
- );
249
- break;
250
- // Complete by default
251
- case OperationType.APPEND_WHITELIST:
252
- case OperationType.ADD_INDEXER:
253
- case OperationType.REMOVE_INDEXER:
254
- case OperationType.BAN_VALIDATOR:
255
- if (this.#wallet.address === bufferToAddress(this.#incomingAddress)) {
256
- throw new Error('Address must not be the same as the wallet address for basic operations.');
257
- }
258
-
259
- msg = createMessage(
260
- NETWORK_ID,
261
- this.#txValidity,
262
- this.#incomingAddress,
263
- nonce,
264
- this.#operationType
265
- );
266
-
267
- break;
268
- // Partial need to be signed
269
- case OperationType.BOOTSTRAP_DEPLOYMENT:
270
- if (!this.#txHash || !this.#externalBootstrap || !this.#channel || !this.#incomingNonce || !this.#incomingSignature) {
271
- throw new Error('All bootstrap deployment fields must be set before building the message!');
272
- }
273
- msg = createMessage(
274
- NETWORK_ID,
275
- this.#txHash,
276
- nonce,
277
- this.#operationType
278
- );
279
- break;
280
-
281
- // Partial need to be signed
282
- case OperationType.TX:
283
- if (!this.#txHash || !this.#txValidity || !this.#address || !this.#incomingWriterKey ||
284
- !this.#incomingNonce || !this.#contentHash || !this.#incomingSignature ||
285
- !this.#externalBootstrap || !this.#msbBootstrap) {
286
- throw new Error('All postTx fields must be set before building the message!');
287
- }
288
- msg = createMessage(
289
- NETWORK_ID,
290
- this.#txHash,
291
- nonce,
292
- this.#operationType
293
- );
294
- break;
295
-
296
- case OperationType.TRANSFER:
297
- if (!this.#txHash || !this.#txValidity || !this.#address || !this.#incomingNonce ||
298
- !this.#incomingSignature || !this.#amount || !this.#incomingAddress) {
299
- throw new Error('All transfer fields must be set before building the message!');
300
- }
301
- msg = createMessage(
302
- NETWORK_ID,
303
- this.#txHash,
304
- nonce,
305
- this.#operationType
306
- );
307
- break;
308
-
309
- default:
310
- throw new Error(`Unsupported operation type for building value: ${OperationType[this.#operationType]}.`);
311
- }
312
-
313
- tx = await blake3Hash(msg);
314
- signature = this.#wallet.sign(tx);
315
-
316
- if (isCoreAdmin(this.#operationType)) {
317
- this.#payload.cao = {
318
- tx: tx,
319
- txv: this.#txValidity,
320
- iw: this.#writingKey,
321
- in: nonce,
322
- is: signature
323
- };
324
- } else if (isAdminControl(this.#operationType)) {
325
- this.#payload.aco = {
326
- tx: tx,
327
- txv: this.#txValidity,
328
- ia: this.#incomingAddress,
329
- in: nonce,
330
- is: signature
331
- };
332
- }
333
- else if (isRoleAccess(this.#operationType)) {
334
- this.#payload.rao = {
335
- tx: this.#txHash,
336
- txv: this.#txValidity,
337
- iw: this.#incomingWriterKey,
338
- in: this.#incomingNonce,
339
- is: this.#incomingSignature,
340
- va: addressToBuffer(this.#wallet.address),
341
- vn: nonce,
342
- vs: signature,
343
- };
344
- } else if (isTransaction(this.#operationType)) {
345
- this.#payload.txo = {
346
- tx: this.#txHash,
347
- txv: this.#txValidity,
348
- iw: this.#incomingWriterKey,
349
- ch: this.#contentHash,
350
- bs: this.#externalBootstrap,
351
- mbs: this.#msbBootstrap,
352
- in: this.#incomingNonce,
353
- is: this.#incomingSignature,
354
- va: addressToBuffer(this.#wallet.address),
355
- vn: nonce,
356
- vs: signature,
357
- };
358
- } else if (isBootstrapDeployment(this.#operationType)) {
359
- this.#payload.bdo = {
360
- tx: this.#txHash,
361
- txv: this.#txValidity,
362
- bs: this.#externalBootstrap,
363
- ic: this.#channel,
364
- in: this.#incomingNonce,
365
- is: this.#incomingSignature,
366
- va: addressToBuffer(this.#wallet.address),
367
- vn: nonce,
368
- vs: signature
369
- }
370
- } else if (isTransfer(this.#operationType)) {
371
- this.#payload.tro = {
372
- tx: this.#txHash,
373
- txv: this.#txValidity,
374
- to: this.#incomingAddress,
375
- am: this.#amount,
376
- in: this.#incomingNonce,
377
- is: this.#incomingSignature,
378
- va: addressToBuffer(this.#wallet.address),
379
- vn: nonce,
380
- vs: signature
381
- }
382
- } else if (isBalanceInitialization(this.#operationType)) {
383
- this.#payload.bio = {
384
- tx: tx,
385
- txv: this.#txValidity,
386
- ia: this.#incomingAddress,
387
- am: this.#amount,
388
- in: nonce,
389
- is: signature
390
- }
391
- }
392
- else {
393
- throw new Error(`No corresponding value type for operation: ${OperationType[this.#operationType]}.`);
394
- }
395
-
396
- return this;
397
- }
398
-
399
- getPayload() {
400
- if (
401
- !this.#payload.type ||
402
- !this.#payload.address ||
403
- (
404
- !this.#payload.cao &&
405
- !this.#payload.aco &&
406
- !this.#payload.rao &&
407
- !this.#payload.txo &&
408
- !this.#payload.bdo &&
409
- !this.#payload.tro &&
410
- !this.#payload.bio
411
- )
412
- ) {
413
- throw new Error('Product is not fully assembled. Missing type, address, or value (cao/aco/rao/txo/bdo/tro/bio).');
414
- }
415
- const res = this.#payload;
416
- this.reset();
417
- return res;
418
- }
419
- }
420
-
421
- export default CompleteStateMessageBuilder;