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.
- package/.github/workflows/publish.yml +8 -16
- package/msb.mjs +13 -25
- package/package.json +8 -4
- package/proto/network.proto +74 -0
- package/rpc/{create_server.mjs → create_server.js} +4 -4
- package/rpc/{handlers.mjs → handlers.js} +7 -7
- package/rpc/routes/{index.mjs → index.js} +1 -1
- package/rpc/routes/{v1.mjs → v1.js} +1 -1
- package/rpc/rpc_server.js +10 -0
- package/rpc/rpc_services.js +48 -7
- package/rpc/utils/{helpers.mjs → helpers.js} +1 -1
- package/src/config/config.js +137 -0
- package/src/config/env.js +63 -0
- package/src/core/network/Network.js +133 -119
- package/src/core/network/identity/NetworkWalletFactory.js +5 -6
- package/src/core/network/protocols/LegacyProtocol.js +67 -0
- package/src/core/network/protocols/NetworkMessages.js +48 -0
- package/src/core/network/protocols/ProtocolInterface.js +31 -0
- package/src/core/network/protocols/ProtocolSession.js +59 -0
- package/src/core/network/protocols/V1Protocol.js +64 -0
- package/src/core/network/protocols/legacy/NetworkMessageRouter.js +84 -0
- package/src/core/network/protocols/legacy/handlers/GetRequestHandler.js +53 -0
- package/src/core/network/protocols/legacy/handlers/ResponseHandler.js +37 -0
- package/src/core/network/{messaging → protocols/legacy}/validators/ValidatorResponse.js +2 -2
- package/src/core/network/{messaging → protocols/legacy}/validators/base/BaseResponse.js +13 -6
- package/src/core/network/protocols/shared/handlers/RoleOperationHandler.js +88 -0
- package/src/core/network/protocols/shared/handlers/SubnetworkOperationHandler.js +93 -0
- package/src/core/network/protocols/shared/handlers/TransferOperationHandler.js +57 -0
- package/src/core/network/{messaging → protocols/shared}/handlers/base/BaseOperationHandler.js +21 -26
- package/src/core/network/{messaging → protocols/shared}/validators/PartialBootstrapDeployment.js +3 -3
- package/src/core/network/{messaging → protocols/shared}/validators/PartialRoleAccess.js +15 -12
- package/src/core/network/{messaging → protocols/shared}/validators/PartialTransaction.js +10 -11
- package/src/core/network/{messaging → protocols/shared}/validators/PartialTransfer.js +10 -7
- package/src/core/network/{messaging → protocols/shared}/validators/base/PartialOperation.js +40 -22
- package/src/core/network/protocols/v1/NetworkMessageRouter.js +15 -0
- package/src/core/network/services/ConnectionManager.js +13 -19
- package/src/core/network/services/MessageOrchestrator.js +10 -22
- package/src/core/network/services/TransactionPoolService.js +10 -10
- package/src/core/network/services/TransactionRateLimiterService.js +5 -3
- package/src/core/network/services/ValidatorObserverService.js +46 -21
- package/src/core/state/State.js +137 -141
- package/src/core/state/utils/address.js +18 -16
- package/src/core/state/utils/adminEntry.js +17 -16
- package/src/core/state/utils/deploymentEntry.js +15 -15
- package/src/core/state/utils/transaction.js +3 -95
- package/src/index.js +250 -325
- package/src/messages/network/v1/NetworkMessageBuilder.js +325 -0
- package/src/messages/network/v1/NetworkMessageDirector.js +137 -0
- package/src/messages/network/v1/networkMessageFactory.js +12 -0
- package/src/messages/state/ApplyStateMessageBuilder.js +661 -0
- package/src/messages/state/ApplyStateMessageDirector.js +516 -0
- package/src/messages/state/applyStateMessageFactory.js +12 -0
- package/src/utils/buffer.js +53 -1
- package/src/utils/check.js +21 -17
- package/src/utils/cli.js +0 -8
- package/src/utils/cliCommands.js +11 -11
- package/src/utils/constants.js +36 -24
- package/src/utils/fileUtils.js +1 -4
- package/src/utils/helpers.js +9 -20
- package/src/utils/migrationUtils.js +2 -2
- package/src/utils/normalizers.js +94 -11
- package/src/utils/protobuf/network.cjs +840 -0
- package/src/utils/protobuf/operationHelpers.js +10 -0
- package/tests/acceptance/v1/account/account.test.mjs +2 -2
- package/tests/acceptance/v1/balance/balance.test.mjs +1 -1
- package/tests/acceptance/v1/broadcast-transaction/broadcast-transaction.test.mjs +11 -2
- package/tests/acceptance/v1/rpc.test.mjs +10 -10
- package/tests/acceptance/v1/tx/tx.test.mjs +4 -2
- package/tests/acceptance/v1/tx-details/tx-details.test.mjs +7 -3
- package/tests/fixtures/check.fixtures.js +42 -42
- package/tests/fixtures/networkV1.fixtures.js +84 -0
- package/tests/fixtures/protobuf.fixtures.js +110 -26
- package/tests/helpers/StateNetworkFactory.js +3 -5
- package/tests/helpers/autobaseTestHelpers.js +1 -2
- package/tests/helpers/config.js +3 -0
- package/tests/helpers/setupApplyTests.js +113 -99
- package/tests/helpers/transactionPayloads.mjs +26 -12
- package/tests/unit/messages/messages.test.js +12 -0
- package/tests/unit/messages/network/NetworkMessageBuilder.test.js +276 -0
- package/tests/unit/messages/network/NetworkMessageDirector.test.js +203 -0
- package/tests/unit/messages/state/applyStateMessageBuilder.complete.test.js +521 -0
- package/tests/unit/messages/state/applyStateMessageBuilder.partial.test.js +233 -0
- package/tests/unit/network/ConnectionManager.test.js +10 -7
- package/tests/unit/network/NetworkWalletFactory.test.js +14 -14
- package/tests/unit/network/networkModule.test.js +3 -2
- package/tests/unit/state/apply/addAdmin/addAdminHappyPathScenario.js +10 -6
- package/tests/unit/state/apply/addAdmin/addAdminScenarioHelpers.js +11 -8
- package/tests/unit/state/apply/addAdmin/state.apply.addAdmin.test.js +11 -7
- package/tests/unit/state/apply/addIndexer/addIndexerScenarioHelpers.js +18 -20
- package/tests/unit/state/apply/addWriter/addWriterScenarioHelpers.js +57 -48
- package/tests/unit/state/apply/addWriter/addWriterValidatorRewardScenario.js +2 -1
- package/tests/unit/state/apply/adminRecovery/adminRecoveryScenarioHelpers.js +72 -57
- package/tests/unit/state/apply/adminRecovery/state.apply.adminRecovery.test.js +3 -7
- package/tests/unit/state/apply/appendWhitelist/appendWhitelistScenarioHelpers.js +12 -14
- package/tests/unit/state/apply/balanceInitialization/balanceInitializationScenarioHelpers.js +18 -13
- package/tests/unit/state/apply/balanceInitialization/nodeEntryBalanceUpdateFailureScenario.js +2 -1
- package/tests/unit/state/apply/banValidator/banValidatorBanAndReWhitelistScenario.js +2 -1
- package/tests/unit/state/apply/banValidator/banValidatorScenarioHelpers.js +27 -30
- package/tests/unit/state/apply/bootstrapDeployment/bootstrapDeploymentDuplicateRegistrationScenario.js +2 -1
- package/tests/unit/state/apply/bootstrapDeployment/bootstrapDeploymentScenarioHelpers.js +24 -21
- package/tests/unit/state/apply/common/access-control/adminConsistencyMismatchScenario.js +5 -4
- package/tests/unit/state/apply/common/access-control/adminPublicKeyDecodeFailureScenario.js +4 -3
- package/tests/unit/state/apply/common/balances/base/requesterBalanceScenarioBase.js +2 -1
- package/tests/unit/state/apply/common/commonScenarioHelper.js +16 -16
- package/tests/unit/state/apply/common/payload-structure/initializationDisabledScenario.js +10 -5
- package/tests/unit/state/apply/common/payload-structure/invalidHashValidationScenario.js +2 -2
- package/tests/unit/state/apply/common/requester/requesterNodeEntryBufferMissingScenario.js +2 -1
- package/tests/unit/state/apply/common/requester/requesterNodeEntryDecodeFailureScenario.js +2 -1
- package/tests/unit/state/apply/common/validatorConsistency/base/validatorConsistencyScenarioBase.js +2 -1
- package/tests/unit/state/apply/common/validatorEntryValidation/base/validatorEntryValidationScenarioBase.js +2 -1
- package/tests/unit/state/apply/disableInitialization/disableInitializationScenarioHelpers.js +16 -9
- package/tests/unit/state/apply/removeIndexer/removeIndexerScenarioHelpers.js +6 -5
- package/tests/unit/state/apply/removeWriter/removeWriterScenarioHelpers.js +23 -19
- package/tests/unit/state/apply/transfer/transferDoubleSpendAcrossValidatorsScenario.js +45 -36
- package/tests/unit/state/apply/transfer/transferScenarioHelpers.js +48 -45
- package/tests/unit/state/apply/txOperation/txOperationScenarioHelpers.js +32 -29
- package/tests/unit/state/apply/txOperation/txOperationTransferFeeGuardScenarioFactory.js +2 -1
- package/tests/unit/state/stateModule.test.js +0 -1
- package/tests/unit/state/stateTestUtils.js +7 -3
- package/tests/unit/state/utils/address.test.js +3 -3
- package/tests/unit/state/utils/adminEntry.test.js +10 -9
- package/tests/unit/unit.test.js +1 -1
- package/tests/unit/utils/buffer/buffer.test.js +62 -1
- package/tests/unit/utils/check/adminControlOperation.test.js +3 -3
- package/tests/unit/utils/check/balanceInitializationOperation.test.js +2 -2
- package/tests/unit/utils/check/bootstrapDeploymentOperation.test.js +2 -3
- package/tests/unit/utils/check/common.test.js +7 -6
- package/tests/unit/utils/check/coreAdminOperation.test.js +3 -3
- package/tests/unit/utils/check/roleAccessOperation.test.js +3 -2
- package/tests/unit/utils/check/transactionOperation.test.js +3 -3
- package/tests/unit/utils/check/transferOperation.test.js +3 -3
- package/tests/unit/utils/fileUtils/readAddressesFromWhitelistFile.test.js +2 -1
- package/tests/unit/utils/fileUtils/readBalanceMigrationFile.test.js +2 -1
- package/tests/unit/utils/migrationUtils/validateAddressFromIncomingFile.test.js +7 -0
- package/tests/unit/utils/normalizers/normalizers.test.js +469 -0
- package/tests/unit/utils/protobuf/operationHelpers.test.js +120 -2
- package/tests/unit/utils/utils.test.js +0 -1
- package/rpc/rpc_server.mjs +0 -10
- package/src/core/network/messaging/NetworkMessages.js +0 -63
- package/src/core/network/messaging/handlers/GetRequestHandler.js +0 -112
- package/src/core/network/messaging/handlers/ResponseHandler.js +0 -108
- package/src/core/network/messaging/handlers/RoleOperationHandler.js +0 -116
- package/src/core/network/messaging/handlers/SubnetworkOperationHandler.js +0 -143
- package/src/core/network/messaging/handlers/TransferOperationHandler.js +0 -52
- package/src/core/network/messaging/routes/NetworkMessageRouter.js +0 -94
- package/src/core/network/messaging/validators/AdminResponse.js +0 -58
- package/src/core/network/messaging/validators/CustomNodeResponse.js +0 -46
- package/src/core/state/utils/indexerEntry.js +0 -105
- package/src/messages/base/StateBuilder.js +0 -25
- package/src/messages/completeStateMessages/CompleteStateMessageBuilder.js +0 -421
- package/src/messages/completeStateMessages/CompleteStateMessageDirector.js +0 -252
- package/src/messages/completeStateMessages/CompleteStateMessageOperations.js +0 -299
- package/src/messages/partialStateMessages/PartialStateMessageBuilder.js +0 -272
- package/src/messages/partialStateMessages/PartialStateMessageDirector.js +0 -137
- package/src/messages/partialStateMessages/PartialStateMessageOperations.js +0 -131
- package/src/utils/crypto.js +0 -11
- package/tests/integration/apply/addAdmin/addAdminBasic.test.js +0 -68
- package/tests/integration/apply/addAdmin/addAdminRecovery.test.js +0 -125
- package/tests/integration/apply/addIndexer.test.js +0 -237
- package/tests/integration/apply/addWhitelist.test.js +0 -53
- package/tests/integration/apply/addWriter.test.js +0 -244
- package/tests/integration/apply/apply.test.js +0 -19
- package/tests/integration/apply/banValidator.test.js +0 -109
- package/tests/integration/apply/postTx/invalidSubValues.test.js +0 -103
- package/tests/integration/apply/postTx/postTx.test.js +0 -222
- package/tests/integration/apply/removeIndexer.test.js +0 -128
- package/tests/integration/apply/removeWriter.test.js +0 -167
- package/tests/integration/apply/transfer.test.js +0 -81
- package/tests/integration/integration.test.js +0 -9
- package/tests/unit/messageOperations/assembleAddIndexerMessage.test.js +0 -21
- package/tests/unit/messageOperations/assembleAddWriterMessage.test.js +0 -16
- package/tests/unit/messageOperations/assembleAdminMessage.test.js +0 -69
- package/tests/unit/messageOperations/assembleBanWriterMessage.test.js +0 -16
- package/tests/unit/messageOperations/assemblePostTransaction.test.js +0 -442
- package/tests/unit/messageOperations/assembleRemoveIndexerMessage.test.js +0 -19
- package/tests/unit/messageOperations/assembleRemoveWriterMessage.test.js +0 -17
- package/tests/unit/messageOperations/assembleWhitelistMessages.test.js +0 -58
- package/tests/unit/messageOperations/commonsStateMessageOperationsTest.js +0 -277
- package/tests/unit/messageOperations/stateMessageOperations.test.js +0 -19
- package/tests/unit/state/utils/indexerEntry.test.js +0 -83
- package/tests/unit/state/utils/transaction.test.js +0 -97
- package/tests/unit/utils/crypto/createHash.test.js +0 -15
- /package/rpc/{constants.mjs → constants.js} +0 -0
- /package/rpc/{cors.mjs → cors.js} +0 -0
- /package/rpc/utils/{confirmedParameter.mjs → confirmedParameter.js} +0 -0
- /package/rpc/utils/{url.mjs → url.js} +0 -0
- /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;
|