trac-msb 0.2.8 → 0.2.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (151) hide show
  1. package/.github/workflows/acceptance-tests.yml +7 -11
  2. package/.github/workflows/lint-pr-title.yml +26 -0
  3. package/.github/workflows/unit-tests.yml +2 -8
  4. package/CODE_OF_CONDUCT.md +128 -0
  5. package/README.md +33 -18
  6. package/docker-compose.yml +1 -0
  7. package/docs/trac_network_http_api.openapi.yaml +889 -0
  8. package/msb.mjs +5 -22
  9. package/package.json +14 -10
  10. package/proto/network.proto +74 -0
  11. package/rpc/create_server.js +2 -2
  12. package/rpc/handlers.js +165 -92
  13. package/rpc/routes/v1.js +3 -1
  14. package/rpc/rpc_server.js +4 -4
  15. package/rpc/rpc_services.js +62 -25
  16. package/rpc/utils/helpers.js +83 -52
  17. package/src/config/args.js +46 -0
  18. package/src/config/config.js +78 -5
  19. package/src/config/env.js +70 -3
  20. package/src/core/network/Network.js +34 -70
  21. package/src/core/network/identity/NetworkWalletFactory.js +2 -2
  22. package/src/core/network/protocols/LegacyProtocol.js +67 -0
  23. package/src/core/network/protocols/NetworkMessages.js +48 -0
  24. package/src/core/network/protocols/ProtocolInterface.js +31 -0
  25. package/src/core/network/protocols/ProtocolSession.js +59 -0
  26. package/src/core/network/protocols/V1Protocol.js +64 -0
  27. package/src/core/network/protocols/legacy/NetworkMessageRouter.js +84 -0
  28. package/src/core/network/protocols/legacy/handlers/GetRequestHandler.js +53 -0
  29. package/src/core/network/protocols/legacy/handlers/ResponseHandler.js +37 -0
  30. package/src/core/network/{messaging → protocols/legacy}/validators/base/BaseResponse.js +2 -3
  31. package/src/core/network/protocols/shared/handlers/RoleOperationHandler.js +88 -0
  32. package/src/core/network/protocols/shared/handlers/SubnetworkOperationHandler.js +93 -0
  33. package/src/core/network/{messaging → protocols/shared}/handlers/TransferOperationHandler.js +17 -16
  34. package/src/core/network/{messaging → protocols/shared}/handlers/base/BaseOperationHandler.js +10 -15
  35. package/src/core/network/{messaging → protocols/shared}/validators/PartialBootstrapDeployment.js +2 -2
  36. package/src/core/network/{messaging → protocols/shared}/validators/PartialRoleAccess.js +5 -5
  37. package/src/core/network/{messaging → protocols/shared}/validators/PartialTransaction.js +4 -4
  38. package/src/core/network/{messaging → protocols/shared}/validators/PartialTransfer.js +4 -4
  39. package/src/core/network/{messaging → protocols/shared}/validators/base/PartialOperation.js +14 -12
  40. package/src/core/network/protocols/v1/NetworkMessageRouter.js +15 -0
  41. package/src/core/network/services/ConnectionManager.js +5 -5
  42. package/src/core/network/services/MessageOrchestrator.js +2 -2
  43. package/src/core/network/services/TransactionPoolService.js +5 -6
  44. package/src/core/network/services/TransactionRateLimiterService.js +12 -13
  45. package/src/core/network/services/ValidatorObserverService.js +5 -6
  46. package/src/core/state/State.js +3 -5
  47. package/src/index.js +156 -181
  48. package/src/messages/network/v1/NetworkMessageBuilder.js +325 -0
  49. package/src/messages/network/v1/NetworkMessageDirector.js +137 -0
  50. package/src/messages/network/v1/networkMessageFactory.js +12 -0
  51. package/src/messages/state/ApplyStateMessageBuilder.js +661 -0
  52. package/src/messages/state/ApplyStateMessageDirector.js +516 -0
  53. package/src/messages/state/applyStateMessageFactory.js +12 -0
  54. package/src/utils/buffer.js +53 -1
  55. package/src/utils/check.js +1 -1
  56. package/src/utils/cli.js +0 -8
  57. package/src/utils/constants.js +33 -30
  58. package/src/utils/fileUtils.js +13 -0
  59. package/src/utils/normalizers.js +84 -2
  60. package/src/utils/protobuf/network.cjs +840 -0
  61. package/src/utils/protobuf/operationHelpers.js +10 -0
  62. package/src/utils/type.js +26 -0
  63. package/tests/acceptance/v1/balance/balance.test.mjs +1 -2
  64. package/tests/acceptance/v1/broadcast-transaction/broadcast-transaction.test.mjs +26 -30
  65. package/tests/acceptance/v1/health/health.test.mjs +33 -0
  66. package/tests/acceptance/v1/rpc.test.mjs +4 -3
  67. package/tests/acceptance/v1/tx/tx.test.mjs +27 -16
  68. package/tests/acceptance/v1/tx-details/tx-details.test.mjs +26 -12
  69. package/tests/fixtures/check.fixtures.js +33 -32
  70. package/tests/fixtures/networkV1.fixtures.js +85 -0
  71. package/tests/fixtures/protobuf.fixtures.js +109 -25
  72. package/tests/helpers/StateNetworkFactory.js +2 -2
  73. package/tests/helpers/address.js +6 -0
  74. package/tests/helpers/autobaseTestHelpers.js +2 -1
  75. package/tests/helpers/config.js +2 -1
  76. package/tests/helpers/setupApplyTests.js +59 -56
  77. package/tests/unit/messages/messages.test.js +12 -0
  78. package/tests/unit/messages/network/NetworkMessageBuilder.test.js +276 -0
  79. package/tests/unit/messages/network/NetworkMessageDirector.test.js +201 -0
  80. package/tests/unit/messages/state/applyStateMessageBuilder.complete.test.js +521 -0
  81. package/tests/unit/messages/state/applyStateMessageBuilder.partial.test.js +233 -0
  82. package/tests/unit/network/ConnectionManager.test.js +6 -5
  83. package/tests/unit/network/networkModule.test.js +3 -2
  84. package/tests/unit/state/apply/addAdmin/addAdminHappyPathScenario.js +10 -6
  85. package/tests/unit/state/apply/addAdmin/addAdminScenarioHelpers.js +9 -6
  86. package/tests/unit/state/apply/addAdmin/state.apply.addAdmin.test.js +10 -7
  87. package/tests/unit/state/apply/addIndexer/addIndexerScenarioHelpers.js +18 -21
  88. package/tests/unit/state/apply/addWriter/addWriterScenarioHelpers.js +53 -38
  89. package/tests/unit/state/apply/adminRecovery/adminRecoveryScenarioHelpers.js +46 -35
  90. package/tests/unit/state/apply/appendWhitelist/appendWhitelistScenarioHelpers.js +13 -16
  91. package/tests/unit/state/apply/balanceInitialization/balanceInitializationScenarioHelpers.js +17 -11
  92. package/tests/unit/state/apply/banValidator/banValidatorScenarioHelpers.js +11 -12
  93. package/tests/unit/state/apply/bootstrapDeployment/bootstrapDeploymentScenarioHelpers.js +9 -7
  94. package/tests/unit/state/apply/common/commonScenarioHelper.js +15 -14
  95. package/tests/unit/state/apply/common/payload-structure/initializationDisabledScenario.js +9 -4
  96. package/tests/unit/state/apply/disableInitialization/disableInitializationScenarioHelpers.js +17 -11
  97. package/tests/unit/state/apply/removeWriter/removeWriterScenarioHelpers.js +19 -14
  98. package/tests/unit/state/apply/transfer/transferDoubleSpendAcrossValidatorsScenario.js +37 -29
  99. package/tests/unit/state/apply/transfer/transferScenarioHelpers.js +9 -7
  100. package/tests/unit/state/apply/txOperation/txOperationScenarioHelpers.js +11 -9
  101. package/tests/unit/unit.test.js +1 -1
  102. package/tests/unit/utils/buffer/buffer.test.js +62 -1
  103. package/tests/unit/utils/fileUtils/readAddressesFromWhitelistFile.test.js +4 -3
  104. package/tests/unit/utils/fileUtils/readBalanceMigrationFile.test.js +3 -2
  105. package/tests/unit/utils/migrationUtils/validateAddressFromIncomingFile.test.js +3 -2
  106. package/tests/unit/utils/normalizers/normalizers.test.js +469 -0
  107. package/tests/unit/utils/protobuf/operationHelpers.test.js +120 -2
  108. package/tests/unit/utils/type/type.test.js +25 -0
  109. package/tests/unit/utils/utils.test.js +1 -0
  110. package/docs/networking-dualstack-plan.md +0 -75
  111. package/docs/networking-layer-redesign.md +0 -155
  112. package/src/core/network/messaging/NetworkMessages.js +0 -64
  113. package/src/core/network/messaging/handlers/GetRequestHandler.js +0 -113
  114. package/src/core/network/messaging/handlers/ResponseHandler.js +0 -107
  115. package/src/core/network/messaging/handlers/RoleOperationHandler.js +0 -114
  116. package/src/core/network/messaging/handlers/SubnetworkOperationHandler.js +0 -149
  117. package/src/core/network/messaging/routes/NetworkMessageRouter.js +0 -98
  118. package/src/core/network/messaging/validators/AdminResponse.js +0 -58
  119. package/src/core/network/messaging/validators/CustomNodeResponse.js +0 -46
  120. package/src/messages/base/StateBuilder.js +0 -25
  121. package/src/messages/completeStateMessages/CompleteStateMessageBuilder.js +0 -425
  122. package/src/messages/completeStateMessages/CompleteStateMessageDirector.js +0 -252
  123. package/src/messages/completeStateMessages/CompleteStateMessageOperations.js +0 -296
  124. package/src/messages/partialStateMessages/PartialStateMessageBuilder.js +0 -272
  125. package/src/messages/partialStateMessages/PartialStateMessageDirector.js +0 -137
  126. package/src/messages/partialStateMessages/PartialStateMessageOperations.js +0 -138
  127. package/tests/integration/apply/addAdmin/addAdminBasic.test.js +0 -69
  128. package/tests/integration/apply/addAdmin/addAdminRecovery.test.js +0 -126
  129. package/tests/integration/apply/addIndexer.test.js +0 -239
  130. package/tests/integration/apply/addWhitelist.test.js +0 -53
  131. package/tests/integration/apply/addWriter.test.js +0 -245
  132. package/tests/integration/apply/apply.test.js +0 -19
  133. package/tests/integration/apply/banValidator.test.js +0 -116
  134. package/tests/integration/apply/postTx/invalidSubValues.test.js +0 -103
  135. package/tests/integration/apply/postTx/postTx.test.js +0 -196
  136. package/tests/integration/apply/removeIndexer.test.js +0 -132
  137. package/tests/integration/apply/removeWriter.test.js +0 -168
  138. package/tests/integration/apply/transfer.test.js +0 -83
  139. package/tests/integration/integration.test.js +0 -9
  140. package/tests/unit/messageOperations/assembleAddIndexerMessage.test.js +0 -21
  141. package/tests/unit/messageOperations/assembleAddWriterMessage.test.js +0 -17
  142. package/tests/unit/messageOperations/assembleAdminMessage.test.js +0 -68
  143. package/tests/unit/messageOperations/assembleBanWriterMessage.test.js +0 -17
  144. package/tests/unit/messageOperations/assemblePostTransaction.test.js +0 -424
  145. package/tests/unit/messageOperations/assembleRemoveIndexerMessage.test.js +0 -19
  146. package/tests/unit/messageOperations/assembleRemoveWriterMessage.test.js +0 -17
  147. package/tests/unit/messageOperations/assembleWhitelistMessages.test.js +0 -59
  148. package/tests/unit/messageOperations/commonsStateMessageOperationsTest.js +0 -278
  149. package/tests/unit/messageOperations/stateMessageOperations.test.js +0 -19
  150. /package/src/core/network/{messaging → protocols/legacy}/validators/ValidatorResponse.js +0 -0
  151. /package/src/utils/{operations.js → applyOperations.js} +0 -0
@@ -1,296 +0,0 @@
1
- import CompleteStateMessageDirector from './CompleteStateMessageDirector.js';
2
- import CompleteStateMessageBuilder from './CompleteStateMessageBuilder.js';
3
- import { safeEncodeApplyOperation } from '../../utils/protobuf/operationHelpers.js';
4
-
5
- class CompleteStateMessageOperations {
6
- #config
7
- #wallet
8
- constructor(wallet, config) {
9
- this.#wallet = wallet
10
- this.#config = config
11
- }
12
-
13
- async assembleAddAdminMessage(writingKey, txValidity) {
14
- try {
15
- const builder = new CompleteStateMessageBuilder(this.#wallet, this.#config);
16
- const director = new CompleteStateMessageDirector();
17
- director.builder = builder;
18
-
19
- const payload = await director.buildAddAdminMessage(this.#wallet.address, writingKey, txValidity);
20
- return safeEncodeApplyOperation(payload);
21
- } catch (error) {
22
- throw new Error(`Failed to assemble admin message: ${error.message}`);
23
- }
24
- }
25
-
26
- async assembleDisableInitializationMessage(writingKey, txValidity) {
27
- const builder = new CompleteStateMessageBuilder(this.#wallet, this.#config);
28
- const director = new CompleteStateMessageDirector();
29
- director.builder = builder;
30
-
31
- const payload = await director.buildDisableInitializationMessage(this.#wallet.address, writingKey, txValidity);
32
- return safeEncodeApplyOperation(payload);
33
- }
34
-
35
- async assembleAddWriterMessage(
36
- invokerAddress,
37
- transactionHash,
38
- txValidity,
39
- incomingWritingKey,
40
- incomingNonce,
41
- incomingSignature
42
- ) {
43
- try {
44
- const builder = new CompleteStateMessageBuilder(this.#wallet, this.#config);
45
- const director = new CompleteStateMessageDirector();
46
- director.builder = builder;
47
-
48
- const payload = await director.buildAddWriterMessage(
49
- invokerAddress,
50
- transactionHash,
51
- txValidity,
52
- incomingWritingKey,
53
- incomingNonce,
54
- incomingSignature
55
- );
56
- return safeEncodeApplyOperation(payload);
57
-
58
- } catch (error) {
59
- throw new Error(`Failed to assemble add writer message: ${error.message}`);
60
- }
61
- }
62
-
63
- async assembleRemoveWriterMessage(
64
- invokerAddress,
65
- transactionHash,
66
- txValidity,
67
- incomingWritingKey,
68
- incomingNonce,
69
- incomingSignature
70
- ) {
71
- try {
72
- const builder = new CompleteStateMessageBuilder(this.#wallet, this.#config);
73
- const director = new CompleteStateMessageDirector();
74
- director.builder = builder;
75
-
76
- const payload = await director.buildRemoveWriterMessage(
77
- invokerAddress,
78
- transactionHash,
79
- txValidity,
80
- incomingWritingKey,
81
- incomingNonce,
82
- incomingSignature
83
- );
84
- return safeEncodeApplyOperation(payload);
85
-
86
- } catch (error) {
87
- throw new Error(`Failed to assemble remove writer message: ${error.message}`);
88
- }
89
- }
90
-
91
- async assembleAdminRecoveryMessage(
92
- invokerAddress,
93
- transactionHash,
94
- txValidity,
95
- incomingWritingKey,
96
- incomingNonce,
97
- incomingSignature
98
- ) {
99
- try {
100
- const builder = new CompleteStateMessageBuilder(this.#wallet, this.#config);
101
- const director = new CompleteStateMessageDirector();
102
- director.builder = builder;
103
-
104
- const payload = await director.buildAdminRecoveryMessage(
105
- invokerAddress,
106
- transactionHash,
107
- txValidity,
108
- incomingWritingKey,
109
- incomingNonce,
110
- incomingSignature
111
- );
112
- return safeEncodeApplyOperation(payload);
113
-
114
- } catch (error) {
115
- throw new Error(`Failed to assemble remove writer message: ${error.message}`);
116
- }
117
- }
118
-
119
- async assembleAddIndexerMessage(incomingAddress, txValidity) {
120
- try {
121
- const builder = new CompleteStateMessageBuilder(this.#wallet, this.#config);
122
- const director = new CompleteStateMessageDirector();
123
- director.builder = builder;
124
-
125
- const payload = await director.buildAddIndexerMessage(this.#wallet.address, incomingAddress, txValidity);
126
- return safeEncodeApplyOperation(payload);
127
-
128
- } catch (error) {
129
- throw new Error(`Failed to assemble addIndexerMessage: ${error.message}`);
130
- }
131
- }
132
-
133
-
134
-
135
- async assembleRemoveIndexerMessage(incomingAddress, txValidity) {
136
- try {
137
- const builder = new CompleteStateMessageBuilder(this.#wallet, this.#config);
138
- const director = new CompleteStateMessageDirector();
139
- director.builder = builder;
140
-
141
- const payload = await director.buildRemoveIndexerMessage(this.#wallet.address, incomingAddress, txValidity);
142
- return safeEncodeApplyOperation(payload);
143
-
144
- } catch (error) {
145
- throw new Error(`Failed to assemble removeIndexerMessage: ${error.message}`);
146
- }
147
- }
148
-
149
- async assembleAppendWhitelistMessages(txValidity, addressToWhitelist) {
150
- try {
151
- const builder = new CompleteStateMessageBuilder(this.#wallet, this.#config);
152
- const director = new CompleteStateMessageDirector();
153
- director.builder = builder;
154
-
155
- const payload = await director.buildAppendWhitelistMessage(this.#wallet.address, addressToWhitelist, txValidity);
156
-
157
- return safeEncodeApplyOperation(payload);;
158
- } catch (error) {
159
- throw new Error(`Failed to assemble appendWhitelistMessages: ${error.message}`);
160
- }
161
- }
162
-
163
- async assembleBalanceInitializationMessages(txValidity, addressBalancePair) {
164
- try {
165
- const builder = new CompleteStateMessageBuilder(this.#wallet, this.#config);
166
- const director = new CompleteStateMessageDirector();
167
- director.builder = builder;
168
-
169
- const messages = [];
170
-
171
- for (const [recipientAddress, balanceBuffer] of addressBalancePair) {
172
- const payload = await director.buildBalanceInitializationMessage(
173
- this.#wallet.address,
174
- recipientAddress,
175
- balanceBuffer,
176
- txValidity
177
- );
178
- messages.push(safeEncodeApplyOperation(payload));
179
- }
180
- return messages;
181
-
182
- } catch (error) {
183
- throw new Error(`Failed to assemble balance initialization messages: ${error.message}`);
184
- }
185
- }
186
-
187
- async assembleBanWriterMessage(incomingAddress, txValidity) {
188
- try {
189
- const builder = new CompleteStateMessageBuilder(this.#wallet, this.#config);
190
- const director = new CompleteStateMessageDirector();
191
- director.builder = builder;
192
-
193
- const payload = await director.buildBanWriterMessage(this.#wallet.address, incomingAddress, txValidity);
194
- return safeEncodeApplyOperation(payload);
195
-
196
- } catch (error) {
197
- throw new Error(`Failed to assemble ban writer message: ${error.message}`);
198
- }
199
- }
200
-
201
- async assembleCompleteTransactionOperationMessage(
202
- invokerAddress,
203
- txHash,
204
- txValidity,
205
- incomingWriterKey,
206
- incomingNonce,
207
- contentHash,
208
- incomingSignature,
209
- externalBootstrap,
210
- msbBootstrap
211
- ) {
212
- try {
213
- const builder = new CompleteStateMessageBuilder(this.#wallet, this.#config);
214
- const director = new CompleteStateMessageDirector();
215
- director.builder = builder;
216
- const payload = await director.buildTransactionOperationMessage(
217
- invokerAddress,
218
- txHash,
219
- txValidity,
220
- incomingWriterKey,
221
- incomingNonce,
222
- contentHash,
223
- incomingSignature,
224
- externalBootstrap,
225
- msbBootstrap,
226
- );
227
- return safeEncodeApplyOperation(payload);
228
-
229
- } catch (error) {
230
- throw new Error(`Failed to assemble transaction Operation: ${error.message}`);
231
- }
232
- }
233
-
234
- async assembleCompleteBootstrapDeployment(
235
- invokerAddress,
236
- transactionHash,
237
- txValidity,
238
- externalBootstrap,
239
- channel,
240
- incomingNonce,
241
- incomingSignature
242
- ) {
243
- try {
244
- const builder = new CompleteStateMessageBuilder(this.#wallet, this.#config);
245
- const director = new CompleteStateMessageDirector();
246
- director.builder = builder;
247
-
248
- const payload = await director.buildBootstrapDeploymentMessage(
249
- invokerAddress,
250
- transactionHash,
251
- txValidity,
252
- externalBootstrap,
253
- channel,
254
- incomingNonce,
255
- incomingSignature,
256
- );
257
- return safeEncodeApplyOperation(payload);
258
-
259
- } catch (error) {
260
- throw new Error(`Failed to assemble bootstrap deployment message: ${error.message}`);
261
- }
262
- }
263
-
264
- async assembleCompleteTransferOperationMessage(
265
- invokerAddress,
266
- transactionHash,
267
- txValidity,
268
- incomingNonce,
269
- recipientAddress,
270
- amount,
271
- incomingSignature
272
- ) {
273
- try {
274
- const builder = new CompleteStateMessageBuilder(this.#wallet, this.#config);
275
- const director = new CompleteStateMessageDirector();
276
- director.builder = builder;
277
-
278
- const payload = await director.buildTransferOperationMessage(
279
- invokerAddress,
280
- transactionHash,
281
- txValidity,
282
- incomingNonce,
283
- recipientAddress,
284
- amount,
285
- incomingSignature
286
- );
287
- return safeEncodeApplyOperation(payload);
288
-
289
- } catch (error) {
290
- throw new Error(`Failed to assemble transfer operation message: ${error.message}`);
291
- }
292
- }
293
-
294
- }
295
-
296
- export default CompleteStateMessageOperations;
@@ -1,272 +0,0 @@
1
- import PeerWallet from "trac-wallet";
2
- import b4a from "b4a";
3
-
4
- import StateBuilder from '../base/StateBuilder.js'
5
- import { OperationType } from '../../utils/constants.js';
6
- import { addressToBuffer, isAddressValid } from '../../core/state/utils/address.js';
7
- import { isHexString } from "../../utils/helpers.js";
8
- import { createMessage } from "../../utils/buffer.js";
9
- import { isTransaction, isRoleAccess, isBootstrapDeployment, isTransfer } from "../../utils/operations.js";
10
-
11
- class PartialStateMessageBuilder extends StateBuilder {
12
- #wallet;
13
- #operationType;
14
- #address;
15
- #writingKey;
16
- #txValidity;
17
- #contentHash;
18
- #externalBootstrap;
19
- #withMsbBootstrap;
20
- #channel;
21
- #incomingAddress;
22
- #amount;
23
- #payload;
24
- #config;
25
-
26
- /**
27
- * @param {PeerWallet} wallet
28
- * @param {object} config
29
- **/
30
- constructor(wallet, config) {
31
- super();
32
- this.#config = config;
33
- if (!wallet || typeof wallet !== 'object') {
34
- throw new Error('Wallet must be a valid wallet object');
35
- }
36
- if (!isAddressValid(wallet.address, this.#config.addressPrefix)) {
37
- throw new Error('Wallet should have a valid TRAC address.');
38
- }
39
-
40
- this.#wallet = wallet;
41
- this.reset();
42
- }
43
-
44
- reset() {
45
- this.#operationType = null;
46
- this.#address = null;
47
- this.#writingKey = null;
48
- this.#txValidity = null;
49
- this.#contentHash = null;
50
- this.#externalBootstrap = null;
51
- this.#withMsbBootstrap = false;
52
- this.#incomingAddress = null;
53
- this.#amount = null;
54
- this.#channel = null;
55
- this.#payload = {};
56
- }
57
-
58
- forOperationType(operationType) {
59
- if (!Object.values(OperationType).includes(operationType) || OperationType === OperationType.UNKNOWN) {
60
- throw new Error(`Invalid operation type: ${operationType}`);
61
- }
62
-
63
- this.#operationType = operationType;
64
- this.#payload.type = operationType;
65
- return this;
66
- }
67
-
68
- withAddress(address) {
69
- if (!isAddressValid(address, this.#config.addressPrefix)) {
70
- throw new Error(`Address field must be a valid TRAC bech32m address with length ${this.#config.addressLength}.`);
71
- }
72
-
73
- this.#address = address;
74
- this.#payload.address = this.#address;
75
- return this;
76
- }
77
-
78
- withContentHash(contentHash) {
79
- if (!isHexString(contentHash) || contentHash.length !== 64) {
80
- throw new Error('Content hash must be a 64-length hexstring.');
81
- }
82
- this.#contentHash = contentHash;
83
- return this;
84
- }
85
-
86
- withExternalBootstrap(bootstrap) {
87
- if (!isHexString(bootstrap) || bootstrap.length !== 64) {
88
- throw new Error('Bootstrap key must be a 64-length hexstring.');
89
- }
90
- this.#externalBootstrap = bootstrap;
91
- return this;
92
- }
93
-
94
- withMsbBootstrap(msbBootstrap) {
95
- if (!isHexString(msbBootstrap) || msbBootstrap.length !== 64) {
96
- throw new Error('MSB Bootstrap key must be a 64-length hexstring.');
97
- }
98
- this.#withMsbBootstrap = msbBootstrap;
99
- return this;
100
- }
101
-
102
- withWriterKey(writerKey) {
103
- if (!isHexString(writerKey) || writerKey.length !== 64) {
104
- throw new Error('Writer key must be a 64-length hexstring.');
105
- }
106
- this.#writingKey = writerKey;
107
- return this;
108
- }
109
-
110
- withTxValidity(txValidity) {
111
- if (!isHexString(txValidity) || txValidity.length !== 64) {
112
- throw new Error('txValidity must be a 64-length hexstring.');
113
- }
114
- this.#txValidity = txValidity;
115
- return this;
116
- }
117
-
118
- withIncomingAddress(address) {
119
- if (!isAddressValid(address, this.#config.addressPrefix)) {
120
- throw new Error(`Incoming address field must be a valid TRAC bech32m address with length ${this.#config.addressLength}.`);
121
- }
122
-
123
- this.#incomingAddress = address;
124
- return this;
125
- }
126
-
127
- withAmount(amount) {
128
- if (!isHexString(amount) || amount.length !== 32) {
129
- throw new Error('Amount must be a 32-length hexstring.');
130
- }
131
-
132
- this.#amount = amount;
133
- return this;
134
- }
135
-
136
- withChannel(channel) {
137
- if (!isHexString(channel) || channel.length !== 64) {
138
- throw new Error('Channel must be a 64-length hexstring.');
139
- }
140
-
141
- this.#channel = channel;
142
- return this;
143
- }
144
-
145
- async buildValueAndSign() {
146
- const nonce = PeerWallet.generateNonce();
147
- let txMsg = null;
148
- let tx = null;
149
- let signature = null;
150
-
151
- // Creating a message for signing based on operation type
152
- // ATTENTION REMEMBER THAT createMessage accept only BUFFER arguments and uint32
153
- switch (this.#operationType) {
154
- case OperationType.ADD_WRITER:
155
- case OperationType.REMOVE_WRITER:
156
- case OperationType.ADMIN_RECOVERY:
157
- txMsg = createMessage(
158
- this.#config.networkId,
159
- b4a.from(this.#txValidity, 'hex'),
160
- b4a.from(this.#writingKey, 'hex'),
161
- nonce,
162
- this.#operationType
163
- );
164
- break;
165
-
166
- case OperationType.BOOTSTRAP_DEPLOYMENT:
167
- if (!this.#externalBootstrap) {
168
- throw new Error('External bootstrap key must be set for BOOTSTRAP DEPLOYMENT operation.');
169
- }
170
- txMsg = createMessage(
171
- this.#config.networkId,
172
- b4a.from(this.#txValidity, 'hex'),
173
- b4a.from(this.#externalBootstrap, 'hex'),
174
- b4a.from(this.#channel, 'hex'),
175
- nonce,
176
- OperationType.BOOTSTRAP_DEPLOYMENT
177
- );
178
- break;
179
-
180
- case OperationType.TX:
181
- txMsg = createMessage(
182
- this.#config.networkId,
183
- b4a.from(this.#txValidity, 'hex'),
184
- b4a.from(this.#writingKey, 'hex'),
185
- b4a.from(this.#contentHash, 'hex'),
186
- b4a.from(this.#externalBootstrap, 'hex'),
187
- b4a.from(this.#withMsbBootstrap, 'hex'),
188
- nonce,
189
- OperationType.TX
190
- );
191
- break;
192
- case OperationType.TRANSFER:
193
- txMsg = createMessage(
194
- this.#config.networkId,
195
- b4a.from(this.#txValidity, 'hex'),
196
- addressToBuffer(this.#incomingAddress, this.#config.addressPrefix), // we need to sign address of the recipient as well
197
- b4a.from(this.#amount, 'hex'),
198
- nonce,
199
- OperationType.TRANSFER
200
- );
201
- break;
202
- default:
203
- throw new Error(`Unsupported operation type: ${this.#operationType}`);
204
- }
205
-
206
- // tx and signature
207
- tx = await PeerWallet.blake3(txMsg);
208
- signature = this.#wallet.sign(tx);
209
-
210
- // Build the payload based on operation type
211
- if (isBootstrapDeployment(this.#operationType)) {
212
- this.#payload.bdo = {
213
- tx: tx.toString('hex'),
214
- txv: this.#txValidity,
215
- bs: this.#externalBootstrap,
216
- ic: this.#channel,
217
- in: nonce.toString('hex'),
218
- is: signature.toString('hex')
219
- };
220
- } else if (isRoleAccess(this.#operationType)) {
221
- this.#payload.rao = {
222
- tx: tx.toString('hex'),
223
- txv: this.#txValidity,
224
- iw: this.#writingKey,
225
- in: nonce.toString('hex'),
226
- is: signature.toString('hex')
227
- };
228
- } else if (isTransaction(this.#operationType)) {
229
- this.#payload.txo = {
230
- tx: tx.toString('hex'),
231
- txv: this.#txValidity,
232
- iw: this.#writingKey,
233
- ch: this.#contentHash,
234
- bs: this.#externalBootstrap,
235
- mbs: this.#withMsbBootstrap,
236
- in: nonce.toString('hex'),
237
- is: signature.toString('hex'),
238
- };
239
- } else if (isTransfer(this.#operationType)) {
240
- this.#payload.tro = {
241
- tx: tx.toString('hex'),
242
- txv: this.#txValidity,
243
- to: this.#incomingAddress,
244
- am: this.#amount,
245
- in: nonce.toString('hex'),
246
- is: signature.toString('hex')
247
- }
248
- }
249
-
250
- return this;
251
- }
252
-
253
- getPayload() {
254
- if (
255
- !this.#payload.type ||
256
- !this.#payload.address ||
257
- (
258
- !this.#payload.bdo &&
259
- !this.#payload.rao &&
260
- !this.#payload.txo &&
261
- !this.#payload.tro
262
- )
263
- ) {
264
- throw new Error('Product is not fully assembled. Missing type, address, or value bdo/rao/txo/tro.');
265
- }
266
- const res = this.#payload;
267
- this.reset();
268
- return res;
269
- }
270
- }
271
-
272
- export default PartialStateMessageBuilder;
@@ -1,137 +0,0 @@
1
- import StateBuilder from '../base/StateBuilder.js'
2
- import {OperationType} from '../../utils/constants.js'
3
- import address from "../../core/state/utils/address.js";
4
-
5
- class PartialStateMessageDirector {
6
- #builder;
7
-
8
- set builder(builderInstance) {
9
- if (!(builderInstance instanceof StateBuilder)) {
10
- throw new Error('Director requires a Builder instance.');
11
- }
12
- this.#builder = builderInstance;
13
- }
14
-
15
- /**
16
- * Builds a PARTIAL bootstrap deployment operation message, which can be sent to a validator.
17
- * The validator can sign this operation to make it COMPLETE and broadcast it to the network.
18
- * Bootstrap deployment is required to register a subnetwork. The network will reject
19
- * TransactionOperation messages for external bootstraps that are not registered.
20
- * Do NOT attempt to register the MSB bootstrap key.
21
- *
22
- * @param {String} address - Trac address of the requester/invoker node that broadcasts the operation.
23
- * @param {String} bootstrap - Bootstrap key from the subnetwork to be registered.
24
- * MUST be different from the MSB bootstrap key.
25
- * BEFORE deploying, ensure the subnetwork bootstrap is not already deployed.
26
- * @param {String} txValidity - Transaction validity hash representing the current indexer combination.
27
- * The operation remains valid as long as indexer keys maintain their order.
28
- * Acts as protection against deferred execution attacks.
29
- * @returns {Promise<Object>} The built bootstrap deployment operation message.
30
- * @throws {Error} If the builder has not been set or message building fails.
31
- */
32
- async buildPartialBootstrapDeploymentMessage(address, bootstrap, channel, txValidity) {
33
- if (!this.#builder) throw new Error('Builder has not been set.');
34
-
35
- await this.#builder
36
- .forOperationType(OperationType.BOOTSTRAP_DEPLOYMENT)
37
- .withAddress(address)
38
- .withTxValidity(txValidity)
39
- .withExternalBootstrap(bootstrap)
40
- .withChannel(channel)
41
- .buildValueAndSign();
42
-
43
- return this.#builder.getPayload();
44
- }
45
-
46
- async buildAddWriterMessage(address, writingKey, txValidity) {
47
- if (!this.#builder) throw new Error('Builder has not been set.');
48
-
49
- await this.#builder
50
- .forOperationType(OperationType.ADD_WRITER)
51
- .withAddress(address)
52
- .withTxValidity(txValidity)
53
- .withWriterKey(writingKey)
54
- .buildValueAndSign();
55
-
56
- return this.#builder.getPayload();
57
- }
58
-
59
- async buildRemoveWriterMessage(address, writerKey, txValidity) {
60
- if (!this.#builder) throw new Error('Builder has not been set.');
61
-
62
- await this.#builder
63
- .forOperationType(OperationType.REMOVE_WRITER)
64
- .withAddress(address)
65
- .withTxValidity(txValidity)
66
- .withWriterKey(writerKey)
67
- .buildValueAndSign();
68
-
69
- return this.#builder.getPayload();
70
- }
71
-
72
- async buildAdminRecoveryMessage(address, writingKey, txValidity) {
73
- if (!this.#builder) throw new Error('Builder has not been set.');
74
-
75
- await this.#builder
76
- .forOperationType(OperationType.ADMIN_RECOVERY)
77
- .withAddress(address)
78
- .withTxValidity(txValidity)
79
- .withWriterKey(writingKey)
80
- .buildValueAndSign();
81
-
82
- return this.#builder.getPayload();
83
- }
84
-
85
- /**
86
- * Builds a transaction operation message for cross-network communication
87
- * @param {String} address - Trac address of the requester/invoker node that broadcasts the transaction
88
- * @param {String} incomingWritingKey - Writing key from the subnetwork, used for authentication of the requesting node
89
- * @param {String} txValidity - Transaction validity hash representing current indexer combination.
90
- * Transaction remains valid as long as indexer keys maintain their order.
91
- * Acts as protection against deferred execution attacks.
92
- * @param {String} contentHash - Hash of the contract content from the subnetwork,
93
- * ensures data integrity between networks
94
- * @param {String} externalBootstrap - Bootstrap key from the subnetwork,
95
- * used for cross-network communication verification.
96
- * MUST BE DIFFERENT from the MSB bootstrap key.
97
- * transaction will be rejected if external bootstrap won't be
98
- * deployed in the MSB (bootstrapDeploymentOperation).
99
- * @param {String} msbBootstrap - Main Settlement Bus bootstrap key,
100
- * used for internal network verification
101
- * @returns {Promise<Object>} The built transaction operation message
102
- * @throws {Error} If builder hasn't been set or if message building fails
103
- */
104
- async buildTransactionOperationMessage(
105
- address,
106
- incomingWritingKey,
107
- txValidity,
108
- contentHash,
109
- externalBootstrap,
110
- msbBootstrap,
111
- ) {
112
- if (!this.#builder) throw new Error('Builder has not been set.');
113
- await this.#builder
114
- .forOperationType(OperationType.TX)
115
- .withAddress(address)
116
- .withTxValidity(txValidity)
117
- .withWriterKey(incomingWritingKey)
118
- .withContentHash(contentHash)
119
- .withExternalBootstrap(externalBootstrap)
120
- .withMsbBootstrap(msbBootstrap)
121
- .buildValueAndSign();
122
- return this.#builder.getPayload();
123
- }
124
- async buildTransferOperationMessage(address, recipientAddress, amount, txValidity){
125
- if (!this.#builder) throw new Error('Builder has not been set.');
126
- await this.#builder
127
- .forOperationType(OperationType.TRANSFER)
128
- .withAddress(address)
129
- .withTxValidity(txValidity)
130
- .withIncomingAddress(recipientAddress)
131
- .withAmount(amount)
132
- .buildValueAndSign();
133
- return this.#builder.getPayload();
134
- }
135
- }
136
-
137
- export default PartialStateMessageDirector;