@totemsdk/core 1.0.9 → 1.0.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.
- package/LICENSE +21 -0
- package/README.md +5 -5
- package/dist/Streamable.js +54 -31
- package/dist/adapters/index.js +18 -8
- package/dist/adapters/types.js +19 -8
- package/dist/binio.js +5 -1
- package/dist/bip39.js +24 -14
- package/dist/derive.js +11 -7
- package/dist/index.js +130 -22
- package/dist/javaStreamables.js +49 -30
- package/dist/lease/LeaseMonitor.js +7 -3
- package/dist/lease/LeaseStore.js +7 -3
- package/dist/lease/WatermarkStore.js +7 -3
- package/dist/lease/index.js +13 -4
- package/dist/lease-client.js +8 -3
- package/dist/minima32.js +22 -13
- package/dist/minimaWireSerializer.js +20 -14
- package/dist/mmr.js +35 -23
- package/dist/mx.js +10 -1
- package/dist/params.js +9 -5
- package/dist/script.js +12 -7
- package/dist/scripts/contract-helpers.js +37 -26
- package/dist/scripts/dapp-types.js +11 -6
- package/dist/scripts/index.js +38 -4
- package/dist/scripts/types.js +26 -12
- package/dist/scripts/witness-serializer.js +48 -30
- package/dist/transaction.js +55 -46
- package/dist/treekey.js +74 -58
- package/dist/tx/TransactionLifecycle.js +11 -5
- package/dist/tx/TransactionReceiptStore.js +7 -3
- package/dist/tx/TransactionService.js +14 -10
- package/dist/tx/index.js +11 -3
- package/dist/tx/types.js +2 -1
- package/dist/util.js +5 -1
- package/dist/utils.js +12 -5
- package/dist/verify.js +36 -25
- package/dist/version.js +5 -2
- package/dist/wots.js +94 -64
- package/package.json +31 -6
- package/src/Streamable.d.ts +0 -268
- package/src/Streamable.js +0 -416
- package/src/Streamable.ts +0 -567
- package/src/__tests__/Streamable.parity.test.ts +0 -422
- package/src/__tests__/perAddressDerivation.parity.test.ts +0 -152
- package/src/__tests__/roottree-prepare.test.ts +0 -101
- package/src/__tests__/wots-parity.test.ts +0 -289
- package/src/adapters/index.d.ts +0 -190
- package/src/adapters/index.js +0 -117
- package/src/adapters/index.ts +0 -301
- package/src/adapters/types.ts +0 -235
- package/src/addr.oracle.test.ts +0 -25
- package/src/address.test.ts +0 -55
- package/src/binio.ts +0 -21
- package/src/bip39.d.ts +0 -91
- package/src/bip39.js +0 -427
- package/src/bip39.ts +0 -432
- package/src/derive.d.ts +0 -2
- package/src/derive.js +0 -13
- package/src/derive.ts +0 -11
- package/src/index.d.ts +0 -26
- package/src/index.js +0 -128
- package/src/index.test.ts +0 -5
- package/src/index.ts +0 -221
- package/src/javaStreamables.d.ts +0 -233
- package/src/javaStreamables.js +0 -332
- package/src/javaStreamables.ts +0 -403
- package/src/lease/LeaseMonitor.d.ts +0 -44
- package/src/lease/LeaseMonitor.js +0 -111
- package/src/lease/LeaseMonitor.ts +0 -157
- package/src/lease/LeaseStore.d.ts +0 -57
- package/src/lease/LeaseStore.js +0 -148
- package/src/lease/LeaseStore.ts +0 -203
- package/src/lease/WatermarkStore.d.ts +0 -61
- package/src/lease/WatermarkStore.js +0 -206
- package/src/lease/WatermarkStore.ts +0 -270
- package/src/lease/index.d.ts +0 -14
- package/src/lease/index.js +0 -22
- package/src/lease/index.ts +0 -41
- package/src/lease-client.d.ts +0 -31
- package/src/lease-client.js +0 -44
- package/src/lease-client.ts +0 -69
- package/src/minima32.d.ts +0 -10
- package/src/minima32.js +0 -113
- package/src/minima32.test.ts +0 -11
- package/src/minima32.ts +0 -127
- package/src/minimaWireSerializer.d.ts +0 -189
- package/src/minimaWireSerializer.js +0 -311
- package/src/minimaWireSerializer.test.ts +0 -466
- package/src/minimaWireSerializer.ts +0 -117
- package/src/mmr.d.ts +0 -157
- package/src/mmr.js +0 -340
- package/src/mmr.oracle.test.ts +0 -28
- package/src/mmr.ts +0 -429
- package/src/mx.test.ts +0 -25
- package/src/mx.ts +0 -1
- package/src/params.d.ts +0 -29
- package/src/params.d.ts.map +0 -1
- package/src/params.js +0 -20
- package/src/params.js.map +0 -1
- package/src/params.ts +0 -44
- package/src/script.d.ts +0 -7
- package/src/script.js +0 -27
- package/src/script.ts +0 -24
- package/src/scripts/contract-helpers.ts +0 -609
- package/src/scripts/dapp-types.ts +0 -240
- package/src/scripts/index.ts +0 -22
- package/src/scripts/types.d.ts +0 -81
- package/src/scripts/types.js +0 -145
- package/src/scripts/types.ts +0 -247
- package/src/scripts/witness-serializer.ts +0 -384
- package/src/transaction.ts +0 -430
- package/src/treekey.d.ts +0 -383
- package/src/treekey.js +0 -774
- package/src/treekey.parity.test.ts +0 -459
- package/src/treekey.ts +0 -975
- package/src/tx/TransactionLifecycle.d.ts +0 -55
- package/src/tx/TransactionLifecycle.js +0 -188
- package/src/tx/TransactionLifecycle.ts +0 -280
- package/src/tx/TransactionReceiptStore.d.ts +0 -36
- package/src/tx/TransactionReceiptStore.js +0 -89
- package/src/tx/TransactionReceiptStore.ts +0 -112
- package/src/tx/TransactionService.d.ts +0 -31
- package/src/tx/TransactionService.js +0 -140
- package/src/tx/TransactionService.ts +0 -252
- package/src/tx/index.d.ts +0 -13
- package/src/tx/index.js +0 -20
- package/src/tx/index.ts +0 -44
- package/src/tx/types.d.ts +0 -80
- package/src/tx/types.js +0 -6
- package/src/tx/types.ts +0 -130
- package/src/util.d.ts +0 -1
- package/src/util.js +0 -5
- package/src/util.ts +0 -1
- package/src/utils.d.ts +0 -8
- package/src/utils.js +0 -42
- package/src/utils.ts +0 -38
- package/src/verify.ts +0 -210
- package/src/version.ts +0 -13
- package/src/wots.d.ts +0 -224
- package/src/wots.d.ts.map +0 -1
- package/src/wots.js +0 -565
- package/src/wots.js.map +0 -1
- package/src/wots.ts +0 -651
- package/test-vectors.json +0 -45
package/dist/treekey.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
"use strict";
|
|
1
2
|
/**
|
|
2
3
|
* TreeKey/TreeKeyNode Implementation matching Minima's TreeKey.java and TreeKeyNode.java
|
|
3
4
|
*
|
|
@@ -8,14 +9,27 @@
|
|
|
8
9
|
*
|
|
9
10
|
* Default structure: 3 levels x 64 keys = 64^3 = 262,144 one-time signatures
|
|
10
11
|
*/
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
12
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
exports.TreeKey = exports.TreeKeyNode = exports.DEFAULT_LEVELS = exports.DEFAULT_KEYS_PER_LEVEL = void 0;
|
|
14
|
+
exports.setTreeKeyLogger = setTreeKeyLogger;
|
|
15
|
+
exports.disableTreeKeyLogger = disableTreeKeyLogger;
|
|
16
|
+
exports.isTreeKeyDebugEnabled = isTreeKeyDebugEnabled;
|
|
17
|
+
exports.getRootPublicKey = getRootPublicKey;
|
|
18
|
+
exports.verifyTreeSignature = verifyTreeSignature;
|
|
19
|
+
exports.serializeTreeSignature = serializeTreeSignature;
|
|
20
|
+
exports.deserializeTreeSignature = deserializeTreeSignature;
|
|
21
|
+
exports.createPerAddressTreeKey = createPerAddressTreeKey;
|
|
22
|
+
exports.createPerAddressTreeKeyAsync = createPerAddressTreeKeyAsync;
|
|
23
|
+
exports.deriveAddressPublicKey = deriveAddressPublicKey;
|
|
24
|
+
exports.getPerAddressPublicKey = getPerAddressPublicKey;
|
|
25
|
+
const javaStreamables_js_1 = require("./javaStreamables.js");
|
|
26
|
+
const wots_js_1 = require("./wots.js");
|
|
27
|
+
const params_js_1 = require("./params.js");
|
|
28
|
+
const mmr_js_1 = require("./mmr.js");
|
|
29
|
+
const Streamable_js_1 = require("./Streamable.js");
|
|
30
|
+
const index_js_1 = require("./adapters/index.js");
|
|
17
31
|
// Module-level debug logger - can be set externally for parity testing
|
|
18
|
-
let treeKeyLogger = new NoopLogger();
|
|
32
|
+
let treeKeyLogger = new index_js_1.NoopLogger();
|
|
19
33
|
let treeKeyDebugEnabled = false;
|
|
20
34
|
/**
|
|
21
35
|
* Enable TreeKey debug logging with a custom logger
|
|
@@ -25,32 +39,32 @@ let treeKeyDebugEnabled = false;
|
|
|
25
39
|
* seeds and private key derivation. NEVER enable in production builds.
|
|
26
40
|
* This is intended for development/testing parity verification only.
|
|
27
41
|
*/
|
|
28
|
-
|
|
42
|
+
function setTreeKeyLogger(logger) {
|
|
29
43
|
treeKeyLogger = logger;
|
|
30
44
|
treeKeyDebugEnabled = true;
|
|
31
45
|
}
|
|
32
46
|
/**
|
|
33
47
|
* Disable TreeKey debug logging
|
|
34
48
|
*/
|
|
35
|
-
|
|
36
|
-
treeKeyLogger = new NoopLogger();
|
|
49
|
+
function disableTreeKeyLogger() {
|
|
50
|
+
treeKeyLogger = new index_js_1.NoopLogger();
|
|
37
51
|
treeKeyDebugEnabled = false;
|
|
38
52
|
}
|
|
39
53
|
/**
|
|
40
54
|
* Check if TreeKey debug logging is enabled
|
|
41
55
|
*/
|
|
42
|
-
|
|
56
|
+
function isTreeKeyDebugEnabled() {
|
|
43
57
|
return treeKeyDebugEnabled;
|
|
44
58
|
}
|
|
45
|
-
|
|
46
|
-
|
|
59
|
+
exports.DEFAULT_KEYS_PER_LEVEL = 64;
|
|
60
|
+
exports.DEFAULT_LEVELS = 3;
|
|
47
61
|
/**
|
|
48
62
|
* Compute root public key from a Winternitz signature proof
|
|
49
63
|
* Matches SignatureProof.getRootPublicKey() in Java
|
|
50
64
|
*/
|
|
51
|
-
|
|
52
|
-
const leafData = createMMRDataLeafNode(proof.leafPubkey, 0n);
|
|
53
|
-
return calculateProofRoot(leafData, proof.mmrProof);
|
|
65
|
+
function getRootPublicKey(proof) {
|
|
66
|
+
const leafData = (0, mmr_js_1.createMMRDataLeafNode)(proof.leafPubkey, 0n);
|
|
67
|
+
return (0, mmr_js_1.calculateProofRoot)(leafData, proof.mmrProof);
|
|
54
68
|
}
|
|
55
69
|
/**
|
|
56
70
|
* TreeKeyNode - One node in the key tree containing 64 Winternitz keys
|
|
@@ -75,15 +89,15 @@ export function getRootPublicKey(proof) {
|
|
|
75
89
|
* IMPORTANT: Minima NEVER stores the 1088-byte full WOTS public key.
|
|
76
90
|
* Only the 32-byte digest is stored and used for MMR construction.
|
|
77
91
|
*/
|
|
78
|
-
|
|
79
|
-
constructor(privateSeed, keysPerLevel = DEFAULT_KEYS_PER_LEVEL) {
|
|
92
|
+
class TreeKeyNode {
|
|
93
|
+
constructor(privateSeed, keysPerLevel = exports.DEFAULT_KEYS_PER_LEVEL) {
|
|
80
94
|
this.childCache = new Map();
|
|
81
95
|
if (privateSeed.length !== 32) {
|
|
82
96
|
throw new Error('Private seed must be 32 bytes');
|
|
83
97
|
}
|
|
84
98
|
if (treeKeyDebugEnabled) {
|
|
85
99
|
treeKeyLogger.debug(`[TreeKeyNode] ========== INIT START ==========`);
|
|
86
|
-
treeKeyLogger.debug(`[TreeKeyNode] Private seed: ${hex(privateSeed)}`);
|
|
100
|
+
treeKeyLogger.debug(`[TreeKeyNode] Private seed: ${(0, wots_js_1.hex)(privateSeed)}`);
|
|
87
101
|
treeKeyLogger.debug(`[TreeKeyNode] Keys per level: ${keysPerLevel}`);
|
|
88
102
|
}
|
|
89
103
|
this.seed = privateSeed;
|
|
@@ -91,9 +105,9 @@ export class TreeKeyNode {
|
|
|
91
105
|
// Hash the seed to create child seed (for deriving child nodes)
|
|
92
106
|
// From TreeKeyNode.java: mChildSeed = Crypto.getInstance().hashObject(zPrivateSeed);
|
|
93
107
|
// hashObject serializes as MiniData (length-prefixed) then hashes
|
|
94
|
-
this.childSeed = hashObject(privateSeed);
|
|
108
|
+
this.childSeed = (0, javaStreamables_js_1.hashObject)(privateSeed);
|
|
95
109
|
if (treeKeyDebugEnabled) {
|
|
96
|
-
treeKeyLogger.debug(`[TreeKeyNode] Child seed (hashObject): ${hex(this.childSeed)}`);
|
|
110
|
+
treeKeyLogger.debug(`[TreeKeyNode] Child seed (hashObject): ${(0, wots_js_1.hex)(this.childSeed)}`);
|
|
97
111
|
}
|
|
98
112
|
// Generate all Winternitz public key DIGESTS (32 bytes each)
|
|
99
113
|
// Java's Winternitz.getPublicKey() returns SHA3-256(full_key) = 32 bytes
|
|
@@ -103,22 +117,22 @@ export class TreeKeyNode {
|
|
|
103
117
|
this.publicKeyDigests = [];
|
|
104
118
|
for (let i = 0; i < keysPerLevel; i++) {
|
|
105
119
|
// Digest (32 bytes) - used for MMR tree, SignatureProof.leafPubkey, and address derivation
|
|
106
|
-
const pkDigest = derivePKdigest(privateSeed, i, getParamSet());
|
|
120
|
+
const pkDigest = (0, wots_js_1.derivePKdigest)(privateSeed, i, (0, params_js_1.getParamSet)());
|
|
107
121
|
this.publicKeyDigests.push(pkDigest);
|
|
108
122
|
// Log first few keys for debugging
|
|
109
123
|
if (treeKeyDebugEnabled && i < 3) {
|
|
110
|
-
treeKeyLogger.debug(`[TreeKeyNode] WOTS key[${i}] digest (32B): ${hex(pkDigest)}`);
|
|
124
|
+
treeKeyLogger.debug(`[TreeKeyNode] WOTS key[${i}] digest (32B): ${(0, wots_js_1.hex)(pkDigest)}`);
|
|
111
125
|
}
|
|
112
126
|
}
|
|
113
127
|
if (treeKeyDebugEnabled) {
|
|
114
128
|
treeKeyLogger.debug(`[TreeKeyNode] Generated ${this.publicKeyDigests.length} WOTS key digests`);
|
|
115
129
|
const lastIdx = this.publicKeyDigests.length - 1;
|
|
116
|
-
treeKeyLogger.debug(`[TreeKeyNode] WOTS key[${lastIdx}] digest: ${hex(this.publicKeyDigests[lastIdx])}`);
|
|
130
|
+
treeKeyLogger.debug(`[TreeKeyNode] WOTS key[${lastIdx}] digest: ${(0, wots_js_1.hex)(this.publicKeyDigests[lastIdx])}`);
|
|
117
131
|
}
|
|
118
132
|
// Build MMR tree from 32-byte PUBLIC KEY DIGESTS (Java-compatible)
|
|
119
133
|
// Java's TreeKeyNode: MMRData.CreateMMRDataLeafNode(wots.getPublicKey(), ZERO)
|
|
120
134
|
// where getPublicKey() returns SHA3-256(full_key) = 32-byte DIGEST
|
|
121
|
-
this.mmrTree = MMRTree.fromPublicKeys(this.publicKeyDigests);
|
|
135
|
+
this.mmrTree = mmr_js_1.MMRTree.fromPublicKeys(this.publicKeyDigests);
|
|
122
136
|
// Root public key = MMR root
|
|
123
137
|
const root = this.mmrTree.getRoot();
|
|
124
138
|
if (!root) {
|
|
@@ -126,7 +140,7 @@ export class TreeKeyNode {
|
|
|
126
140
|
}
|
|
127
141
|
this.rootPubkey = root.data;
|
|
128
142
|
if (treeKeyDebugEnabled) {
|
|
129
|
-
treeKeyLogger.debug(`[TreeKeyNode] MMR root (node public key): ${hex(this.rootPubkey)}`);
|
|
143
|
+
treeKeyLogger.debug(`[TreeKeyNode] MMR root (node public key): ${(0, wots_js_1.hex)(this.rootPubkey)}`);
|
|
130
144
|
treeKeyLogger.debug(`[TreeKeyNode] ========== INIT END ==========`);
|
|
131
145
|
}
|
|
132
146
|
}
|
|
@@ -134,14 +148,14 @@ export class TreeKeyNode {
|
|
|
134
148
|
* Async factory method for TreeKeyNode with progress reporting
|
|
135
149
|
* Yields to event loop every few keys to keep UI responsive
|
|
136
150
|
*/
|
|
137
|
-
static async createWithProgress(privateSeed, keysPerLevel = DEFAULT_KEYS_PER_LEVEL, onProgress) {
|
|
151
|
+
static async createWithProgress(privateSeed, keysPerLevel = exports.DEFAULT_KEYS_PER_LEVEL, onProgress) {
|
|
138
152
|
if (privateSeed.length !== 32) {
|
|
139
153
|
throw new Error('Private seed must be 32 bytes');
|
|
140
154
|
}
|
|
141
155
|
const node = Object.create(TreeKeyNode.prototype);
|
|
142
156
|
node.seed = privateSeed;
|
|
143
157
|
node.keysPerLevel = keysPerLevel;
|
|
144
|
-
node.childSeed = hashObject(privateSeed);
|
|
158
|
+
node.childSeed = (0, javaStreamables_js_1.hashObject)(privateSeed);
|
|
145
159
|
node.publicKeyDigests = [];
|
|
146
160
|
node.childCache = new Map();
|
|
147
161
|
// Generate Winternitz public key DIGESTS with progress (32 bytes each)
|
|
@@ -149,7 +163,7 @@ export class TreeKeyNode {
|
|
|
149
163
|
// See WinternitzOTSignature.getPublicKey() lines 103-121: hashes full 1088B key, returns 32B digest
|
|
150
164
|
for (let i = 0; i < keysPerLevel; i++) {
|
|
151
165
|
// Digest (32 bytes) - used for MMR tree, SignatureProof.leafPubkey, and address derivation
|
|
152
|
-
const pkDigest = derivePKdigest(privateSeed, i, getParamSet());
|
|
166
|
+
const pkDigest = (0, wots_js_1.derivePKdigest)(privateSeed, i, (0, params_js_1.getParamSet)());
|
|
153
167
|
node.publicKeyDigests.push(pkDigest);
|
|
154
168
|
// Report progress every 4 keys and yield to event loop
|
|
155
169
|
if (onProgress && (i + 1) % 4 === 0) {
|
|
@@ -175,7 +189,7 @@ export class TreeKeyNode {
|
|
|
175
189
|
// Build MMR tree from 32-byte PUBLIC KEY DIGESTS (Java-compatible)
|
|
176
190
|
// Java's TreeKeyNode: MMRData.CreateMMRDataLeafNode(wots.getPublicKey(), ZERO)
|
|
177
191
|
// where getPublicKey() returns SHA3-256(full_key) = 32-byte DIGEST
|
|
178
|
-
node.mmrTree = MMRTree.fromPublicKeys(node.publicKeyDigests);
|
|
192
|
+
node.mmrTree = mmr_js_1.MMRTree.fromPublicKeys(node.publicKeyDigests);
|
|
179
193
|
const root = node.mmrTree.getRoot();
|
|
180
194
|
if (!root) {
|
|
181
195
|
throw new Error('Failed to compute MMR root');
|
|
@@ -212,7 +226,7 @@ export class TreeKeyNode {
|
|
|
212
226
|
throw new Error(`Key index ${index} out of range [0, ${this.keysPerLevel})`);
|
|
213
227
|
}
|
|
214
228
|
// Derive on-demand - expensive but only used for tests
|
|
215
|
-
return deriveFullPublicKey(this.seed, index, getParamSet());
|
|
229
|
+
return (0, wots_js_1.deriveFullPublicKey)(this.seed, index, (0, params_js_1.getParamSet)());
|
|
216
230
|
}
|
|
217
231
|
/**
|
|
218
232
|
* Get the Winternitz public key digest at a specific index (0-63)
|
|
@@ -252,14 +266,14 @@ export class TreeKeyNode {
|
|
|
252
266
|
if (treeKeyDebugEnabled) {
|
|
253
267
|
treeKeyLogger.debug(`[TreeKeyNode.sign] ========== SIGN START ==========`);
|
|
254
268
|
treeKeyLogger.debug(`[TreeKeyNode.sign] keyIndex: ${keyIndex}`);
|
|
255
|
-
treeKeyLogger.debug(`[TreeKeyNode.sign] input data (${data.length}B): ${hex(data).substring(0, 64)}${data.length > 32 ? '...' : ''}`);
|
|
269
|
+
treeKeyLogger.debug(`[TreeKeyNode.sign] input data (${data.length}B): ${(0, wots_js_1.hex)(data).substring(0, 64)}${data.length > 32 ? '...' : ''}`);
|
|
256
270
|
}
|
|
257
271
|
// Get the 32-byte Winternitz public key DIGEST for SignatureProof
|
|
258
272
|
// CRITICAL FIX: Java's Winternitz.getPublicKey() returns SHA3-256(full_key) = 32 bytes!
|
|
259
273
|
// NOT the 1088-byte full key! This was the bug causing "allsignaturesvalid":false errors.
|
|
260
274
|
const leafPubkey = this.publicKeyDigests[keyIndex];
|
|
261
275
|
if (treeKeyDebugEnabled) {
|
|
262
|
-
treeKeyLogger.debug(`[TreeKeyNode.sign] leafPubkey (${leafPubkey.length}B DIGEST): ${hex(leafPubkey)}`);
|
|
276
|
+
treeKeyLogger.debug(`[TreeKeyNode.sign] leafPubkey (${leafPubkey.length}B DIGEST): ${(0, wots_js_1.hex)(leafPubkey)}`);
|
|
263
277
|
}
|
|
264
278
|
// CRITICAL: Do NOT pre-hash here! wotsSign() now handles internal hashing (matching Java/BouncyCastle).
|
|
265
279
|
// Java's WinternitzOTSignature.getSignature() hashes internally, so wotsSign() does too.
|
|
@@ -268,12 +282,12 @@ export class TreeKeyNode {
|
|
|
268
282
|
// - For parent→child: the 32-byte childRoot (MMR root of child proof)
|
|
269
283
|
// WOTS hashes once internally - this is by design for Minima compatibility.
|
|
270
284
|
if (treeKeyDebugEnabled) {
|
|
271
|
-
treeKeyLogger.debug(`[TreeKeyNode.sign] dataToSign (raw input, WOTS hashes internally): ${hex(data)}`);
|
|
285
|
+
treeKeyLogger.debug(`[TreeKeyNode.sign] dataToSign (raw input, WOTS hashes internally): ${(0, wots_js_1.hex)(data)}`);
|
|
272
286
|
}
|
|
273
287
|
// Sign data directly - wotsSign() handles internal hashing
|
|
274
|
-
const signature = wotsSign(this.seed, keyIndex, data, getParamSet());
|
|
288
|
+
const signature = (0, wots_js_1.wotsSign)(this.seed, keyIndex, data, (0, params_js_1.getParamSet)());
|
|
275
289
|
if (treeKeyDebugEnabled) {
|
|
276
|
-
treeKeyLogger.debug(`[TreeKeyNode.sign] signature (${signature.length}B): ${hex(signature).substring(0, 64)}...${hex(signature).substring(hex(signature).length - 32)}`);
|
|
290
|
+
treeKeyLogger.debug(`[TreeKeyNode.sign] signature (${signature.length}B): ${(0, wots_js_1.hex)(signature).substring(0, 64)}...${(0, wots_js_1.hex)(signature).substring((0, wots_js_1.hex)(signature).length - 32)}`);
|
|
277
291
|
}
|
|
278
292
|
// Get the MMR proof for this key
|
|
279
293
|
const mmrProof = this.getProof(keyIndex);
|
|
@@ -305,23 +319,24 @@ export class TreeKeyNode {
|
|
|
305
319
|
}
|
|
306
320
|
if (treeKeyDebugEnabled) {
|
|
307
321
|
treeKeyLogger.debug(`[TreeKeyNode.getChild] Creating child at index ${childIndex}`);
|
|
308
|
-
treeKeyLogger.debug(`[TreeKeyNode.getChild] Parent childSeed: ${hex(this.childSeed)}`);
|
|
322
|
+
treeKeyLogger.debug(`[TreeKeyNode.getChild] Parent childSeed: ${(0, wots_js_1.hex)(this.childSeed)}`);
|
|
309
323
|
}
|
|
310
324
|
// From TreeKeyNode.java:
|
|
311
325
|
// MiniData seed = Crypto.getInstance().hashAllObjects(new MiniNumber(zChild), mChildSeed);
|
|
312
|
-
const childSeed = deriveChainSeedJava(this.childSeed, childIndex);
|
|
326
|
+
const childSeed = (0, javaStreamables_js_1.deriveChainSeedJava)(this.childSeed, childIndex);
|
|
313
327
|
if (treeKeyDebugEnabled) {
|
|
314
|
-
treeKeyLogger.debug(`[TreeKeyNode.getChild] Derived childSeed: ${hex(childSeed)}`);
|
|
328
|
+
treeKeyLogger.debug(`[TreeKeyNode.getChild] Derived childSeed: ${(0, wots_js_1.hex)(childSeed)}`);
|
|
315
329
|
}
|
|
316
330
|
const child = new TreeKeyNode(childSeed, this.keysPerLevel);
|
|
317
331
|
if (treeKeyDebugEnabled) {
|
|
318
|
-
treeKeyLogger.debug(`[TreeKeyNode.getChild] Child public key: ${hex(child.getPublicKey())}`);
|
|
332
|
+
treeKeyLogger.debug(`[TreeKeyNode.getChild] Child public key: ${(0, wots_js_1.hex)(child.getPublicKey())}`);
|
|
319
333
|
}
|
|
320
334
|
// Cache for future use
|
|
321
335
|
this.childCache.set(childIndex, child);
|
|
322
336
|
return child;
|
|
323
337
|
}
|
|
324
338
|
}
|
|
339
|
+
exports.TreeKeyNode = TreeKeyNode;
|
|
325
340
|
/**
|
|
326
341
|
* TreeKey - Full hierarchical key tree with multiple levels
|
|
327
342
|
*
|
|
@@ -330,8 +345,8 @@ export class TreeKeyNode {
|
|
|
330
345
|
* - Tracks usage count to determine which key to use
|
|
331
346
|
* - Produces multi-level signatures
|
|
332
347
|
*/
|
|
333
|
-
|
|
334
|
-
constructor(privateSeed, keysPerLevel = DEFAULT_KEYS_PER_LEVEL, levels = DEFAULT_LEVELS) {
|
|
348
|
+
class TreeKey {
|
|
349
|
+
constructor(privateSeed, keysPerLevel = exports.DEFAULT_KEYS_PER_LEVEL, levels = exports.DEFAULT_LEVELS) {
|
|
335
350
|
this.uses = 0;
|
|
336
351
|
/**
|
|
337
352
|
* Parent-child signature cache for efficiency
|
|
@@ -344,7 +359,7 @@ export class TreeKey {
|
|
|
344
359
|
}
|
|
345
360
|
if (treeKeyDebugEnabled) {
|
|
346
361
|
treeKeyLogger.debug(`[TreeKey] ========== WALLET INIT START ==========`);
|
|
347
|
-
treeKeyLogger.debug(`[TreeKey] Private seed: ${hex(privateSeed)}`);
|
|
362
|
+
treeKeyLogger.debug(`[TreeKey] Private seed: ${(0, wots_js_1.hex)(privateSeed)}`);
|
|
348
363
|
treeKeyLogger.debug(`[TreeKey] Levels: ${levels}, Keys per level: ${keysPerLevel}`);
|
|
349
364
|
treeKeyLogger.debug(`[TreeKey] Total capacity: ${Math.pow(keysPerLevel, levels)} signatures`);
|
|
350
365
|
}
|
|
@@ -355,7 +370,7 @@ export class TreeKey {
|
|
|
355
370
|
this.root = new TreeKeyNode(privateSeed, keysPerLevel);
|
|
356
371
|
this.publicKey = this.root.getPublicKey();
|
|
357
372
|
if (treeKeyDebugEnabled) {
|
|
358
|
-
treeKeyLogger.debug(`[TreeKey] Root public key: ${hex(this.publicKey)}`);
|
|
373
|
+
treeKeyLogger.debug(`[TreeKey] Root public key: ${(0, wots_js_1.hex)(this.publicKey)}`);
|
|
359
374
|
treeKeyLogger.debug(`[TreeKey] ========== WALLET INIT END ==========`);
|
|
360
375
|
}
|
|
361
376
|
}
|
|
@@ -363,7 +378,7 @@ export class TreeKey {
|
|
|
363
378
|
* Async factory method for TreeKey with progress reporting
|
|
364
379
|
* Reports progress as the root TreeKeyNode generates its 64 signing keys
|
|
365
380
|
*/
|
|
366
|
-
static async createWithProgress(privateSeed, keysPerLevel = DEFAULT_KEYS_PER_LEVEL, levels = DEFAULT_LEVELS, onProgress) {
|
|
381
|
+
static async createWithProgress(privateSeed, keysPerLevel = exports.DEFAULT_KEYS_PER_LEVEL, levels = exports.DEFAULT_LEVELS, onProgress) {
|
|
367
382
|
if (privateSeed.length !== 32) {
|
|
368
383
|
throw new Error('Private seed must be 32 bytes');
|
|
369
384
|
}
|
|
@@ -582,6 +597,7 @@ export class TreeKey {
|
|
|
582
597
|
return level2Node.getPublicKey();
|
|
583
598
|
}
|
|
584
599
|
}
|
|
600
|
+
exports.TreeKey = TreeKey;
|
|
585
601
|
/**
|
|
586
602
|
* Verify a tree signature against expected public key and data
|
|
587
603
|
*
|
|
@@ -590,14 +606,14 @@ export class TreeKey {
|
|
|
590
606
|
* - Each intermediate proof must sign the next level's root
|
|
591
607
|
* - Final proof must verify against the actual data
|
|
592
608
|
*/
|
|
593
|
-
|
|
609
|
+
function verifyTreeSignature(expectedPubkey, data, signature) {
|
|
594
610
|
const { proofs } = signature;
|
|
595
611
|
if (proofs.length === 0) {
|
|
596
612
|
return false;
|
|
597
613
|
}
|
|
598
614
|
// Import wotsVerify for verification
|
|
599
615
|
// wotsVerify already imported at top of file
|
|
600
|
-
const paramSet = getParamSet();
|
|
616
|
+
const paramSet = (0, params_js_1.getParamSet)();
|
|
601
617
|
for (let depth = 0; depth < proofs.length; depth++) {
|
|
602
618
|
const proof = proofs[depth];
|
|
603
619
|
// Compute the root public key from this proof
|
|
@@ -622,7 +638,7 @@ export function verifyTreeSignature(expectedPubkey, data, signature) {
|
|
|
622
638
|
}
|
|
623
639
|
// Verify the Winternitz signature
|
|
624
640
|
// Use wotsVerifyDigest since leafPubkey is now a 32-byte digest (not 1088-byte full key)
|
|
625
|
-
if (!wotsVerifyDigest(proof.signature, signedData, proof.leafPubkey, paramSet)) {
|
|
641
|
+
if (!(0, wots_js_1.wotsVerifyDigest)(proof.signature, signedData, proof.leafPubkey, paramSet)) {
|
|
626
642
|
return false;
|
|
627
643
|
}
|
|
628
644
|
}
|
|
@@ -634,7 +650,7 @@ export function verifyTreeSignature(expectedPubkey, data, signature) {
|
|
|
634
650
|
* Uses Streamable.writeSignature() for byte-exact compatibility
|
|
635
651
|
* with Java's Signature.writeDataStream().
|
|
636
652
|
*/
|
|
637
|
-
|
|
653
|
+
function serializeTreeSignature(sig) {
|
|
638
654
|
// Convert to Streamable format (adds blockTime to MMRProof)
|
|
639
655
|
const streamableSig = {
|
|
640
656
|
proofs: sig.proofs.map(proof => ({
|
|
@@ -647,7 +663,7 @@ export function serializeTreeSignature(sig) {
|
|
|
647
663
|
}))
|
|
648
664
|
};
|
|
649
665
|
// Use canonical serializer for byte-exact Java compatibility
|
|
650
|
-
return writeSignature(streamableSig);
|
|
666
|
+
return (0, Streamable_js_1.writeSignature)(streamableSig);
|
|
651
667
|
}
|
|
652
668
|
/**
|
|
653
669
|
* Deserialize a TreeSignature from bytes
|
|
@@ -656,7 +672,7 @@ export function serializeTreeSignature(sig) {
|
|
|
656
672
|
* - Number of proofs: MiniNumber format
|
|
657
673
|
* - Each SignatureProof: MiniData(pubkey) + MiniData(signature) + MMRProof
|
|
658
674
|
*/
|
|
659
|
-
|
|
675
|
+
function deserializeTreeSignature(data) {
|
|
660
676
|
let offset = 0;
|
|
661
677
|
// Read MiniNumber for proof count
|
|
662
678
|
// Format: [scale: 1 byte] [length: 1 byte] [data: N bytes]
|
|
@@ -682,7 +698,7 @@ export function deserializeTreeSignature(data) {
|
|
|
682
698
|
const signature = data.slice(offset, offset + sigLen);
|
|
683
699
|
offset += sigLen;
|
|
684
700
|
// MMR proof - returns { proof, blockTime, bytesRead }
|
|
685
|
-
const { proof: mmrProof, bytesRead: mmrProofLen } = parseMMRProofFromHex(data.slice(offset));
|
|
701
|
+
const { proof: mmrProof, bytesRead: mmrProofLen } = (0, mmr_js_1.parseMMRProofFromHex)(data.slice(offset));
|
|
686
702
|
offset += mmrProofLen;
|
|
687
703
|
proofs.push({ leafPubkey, signature, mmrProof });
|
|
688
704
|
}
|
|
@@ -713,8 +729,8 @@ export function deserializeTreeSignature(data) {
|
|
|
713
729
|
* @param addressIndex - Address index (0-63)
|
|
714
730
|
* @returns TreeKey for this address with size=64, depth=3
|
|
715
731
|
*/
|
|
716
|
-
|
|
717
|
-
const addressSeed = derivePerAddressSeed(baseSeed, addressIndex);
|
|
732
|
+
function createPerAddressTreeKey(baseSeed, addressIndex) {
|
|
733
|
+
const addressSeed = (0, javaStreamables_js_1.derivePerAddressSeed)(baseSeed, addressIndex);
|
|
718
734
|
return new TreeKey(addressSeed, 64, 3);
|
|
719
735
|
}
|
|
720
736
|
/**
|
|
@@ -725,8 +741,8 @@ export function createPerAddressTreeKey(baseSeed, addressIndex) {
|
|
|
725
741
|
* @param onProgress - Optional progress callback
|
|
726
742
|
* @returns Promise resolving to TreeKey for this address
|
|
727
743
|
*/
|
|
728
|
-
|
|
729
|
-
const addressSeed = derivePerAddressSeed(baseSeed, addressIndex);
|
|
744
|
+
async function createPerAddressTreeKeyAsync(baseSeed, addressIndex, onProgress) {
|
|
745
|
+
const addressSeed = (0, javaStreamables_js_1.derivePerAddressSeed)(baseSeed, addressIndex);
|
|
730
746
|
return TreeKey.createWithProgress(addressSeed, 64, 3, onProgress);
|
|
731
747
|
}
|
|
732
748
|
/**
|
|
@@ -740,7 +756,7 @@ export async function createPerAddressTreeKeyAsync(baseSeed, addressIndex, onPro
|
|
|
740
756
|
* @param addressIndex - Address index (0-63)
|
|
741
757
|
* @returns 32-byte address public key (MMR root of per-address TreeKey)
|
|
742
758
|
*/
|
|
743
|
-
|
|
759
|
+
function deriveAddressPublicKey(baseSeed, addressIndex) {
|
|
744
760
|
const treeKey = createPerAddressTreeKey(baseSeed, addressIndex);
|
|
745
761
|
return treeKey.getPublicKey();
|
|
746
762
|
}
|
|
@@ -753,6 +769,6 @@ export function deriveAddressPublicKey(baseSeed, addressIndex) {
|
|
|
753
769
|
* @param treeKey - Per-address TreeKey
|
|
754
770
|
* @returns 32-byte address public key (TreeKey root)
|
|
755
771
|
*/
|
|
756
|
-
|
|
772
|
+
function getPerAddressPublicKey(treeKey) {
|
|
757
773
|
return treeKey.getPublicKey();
|
|
758
774
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
"use strict";
|
|
1
2
|
/**
|
|
2
3
|
* @module TransactionLifecycle
|
|
3
4
|
* Orchestrates the complete transaction flow with lease and watermark management
|
|
@@ -8,8 +9,10 @@
|
|
|
8
9
|
* - WatermarkStore for index tracking
|
|
9
10
|
* - TransactionReceiptStore for history
|
|
10
11
|
*/
|
|
11
|
-
|
|
12
|
-
|
|
12
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
exports.TransactionLifecycle = exports.WatermarkExhaustedError = exports.TransactionLifecycleError = void 0;
|
|
14
|
+
const index_js_1 = require("../adapters/index.js");
|
|
15
|
+
class TransactionLifecycleError extends Error {
|
|
13
16
|
constructor(message, code, userMessage) {
|
|
14
17
|
super(message);
|
|
15
18
|
this.code = code;
|
|
@@ -17,14 +20,16 @@ export class TransactionLifecycleError extends Error {
|
|
|
17
20
|
this.name = 'TransactionLifecycleError';
|
|
18
21
|
}
|
|
19
22
|
}
|
|
20
|
-
|
|
23
|
+
exports.TransactionLifecycleError = TransactionLifecycleError;
|
|
24
|
+
class WatermarkExhaustedError extends Error {
|
|
21
25
|
constructor() {
|
|
22
26
|
super('All WOTS signatures have been used. Please create a new wallet.');
|
|
23
27
|
this.name = 'WatermarkExhaustedError';
|
|
24
28
|
}
|
|
25
29
|
}
|
|
26
|
-
|
|
27
|
-
|
|
30
|
+
exports.WatermarkExhaustedError = WatermarkExhaustedError;
|
|
31
|
+
class TransactionLifecycle {
|
|
32
|
+
constructor(txService, leaseStore, watermarkStore, receiptStore, logger = new index_js_1.NoopLogger(), metrics = new index_js_1.NoopMetrics(), config = {}) {
|
|
28
33
|
this.txService = txService;
|
|
29
34
|
this.leaseStore = leaseStore;
|
|
30
35
|
this.watermarkStore = watermarkStore;
|
|
@@ -187,3 +192,4 @@ export class TransactionLifecycle {
|
|
|
187
192
|
};
|
|
188
193
|
}
|
|
189
194
|
}
|
|
195
|
+
exports.TransactionLifecycle = TransactionLifecycle;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
"use strict";
|
|
1
2
|
/**
|
|
2
3
|
* @module TransactionReceiptStore
|
|
3
4
|
* Persistent storage for transaction receipts
|
|
@@ -8,11 +9,13 @@
|
|
|
8
9
|
* - Sync getters read from memory cache (fast, no I/O)
|
|
9
10
|
* - Mutators update memory cache AND persist to storage
|
|
10
11
|
*/
|
|
11
|
-
|
|
12
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
exports.TransactionReceiptStore = void 0;
|
|
14
|
+
const index_js_1 = require("../adapters/index.js");
|
|
12
15
|
const DEFAULT_STORAGE_KEY = 'totem_transaction_receipts';
|
|
13
16
|
const DEFAULT_MAX_RECEIPTS = 1000;
|
|
14
|
-
|
|
15
|
-
constructor(storage, logger = new NoopLogger(), config = {}) {
|
|
17
|
+
class TransactionReceiptStore {
|
|
18
|
+
constructor(storage, logger = new index_js_1.NoopLogger(), config = {}) {
|
|
16
19
|
this.receipts = [];
|
|
17
20
|
this._initialized = false;
|
|
18
21
|
this.storage = storage;
|
|
@@ -83,3 +86,4 @@ export class TransactionReceiptStore {
|
|
|
83
86
|
return this.receipts.length;
|
|
84
87
|
}
|
|
85
88
|
}
|
|
89
|
+
exports.TransactionReceiptStore = TransactionReceiptStore;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
"use strict";
|
|
1
2
|
/**
|
|
2
3
|
* @module TransactionService
|
|
3
4
|
* Handles WOTS signing flow: prepare → sign → finalize
|
|
@@ -8,12 +9,14 @@
|
|
|
8
9
|
* matching Minima Wallet.java exactly. Each address has its own TreeKey derived
|
|
9
10
|
* from the wallet seed. Signing produces 3 proofs (Root→L1→L2→DATA).
|
|
10
11
|
*/
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
12
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
exports.TransactionService = void 0;
|
|
14
|
+
const index_js_1 = require("../adapters/index.js");
|
|
15
|
+
const treekey_js_1 = require("../treekey.js");
|
|
16
|
+
const mmr_js_1 = require("../mmr.js");
|
|
17
|
+
const wots_js_1 = require("../wots.js");
|
|
18
|
+
class TransactionService {
|
|
19
|
+
constructor(http, config, logger = new index_js_1.NoopLogger(), metrics = new index_js_1.NoopMetrics()) {
|
|
17
20
|
this.http = http;
|
|
18
21
|
this.config = config;
|
|
19
22
|
this.logger = logger;
|
|
@@ -99,13 +102,13 @@ export class TransactionService {
|
|
|
99
102
|
if (addressIndex < 0 || addressIndex >= 64) {
|
|
100
103
|
throw new Error(`Invalid addressIndex: ${addressIndex}. Must be 0-63.`);
|
|
101
104
|
}
|
|
102
|
-
const digestBytes = fromHex(digestTx);
|
|
105
|
+
const digestBytes = (0, wots_js_1.fromHex)(digestTx);
|
|
103
106
|
if (digestBytes.length !== 32) {
|
|
104
107
|
throw new Error(`Invalid digest length: ${digestBytes.length}, expected 32 bytes`);
|
|
105
108
|
}
|
|
106
109
|
// Derive per-address TreeKey matching Minima Wallet.java
|
|
107
110
|
this.logger.debug(` Deriving per-address TreeKey for index ${addressIndex}...`);
|
|
108
|
-
const treeKey = createPerAddressTreeKey(seed, addressIndex);
|
|
111
|
+
const treeKey = (0, treekey_js_1.createPerAddressTreeKey)(seed, addressIndex);
|
|
109
112
|
// Convert (l1, l2) to Java-compatible 'uses' counter
|
|
110
113
|
// Java's TreeKey.sign() uses baseConversion(uses) to compute path
|
|
111
114
|
const KEYS_PER_LEVEL = 64;
|
|
@@ -126,11 +129,11 @@ export class TransactionService {
|
|
|
126
129
|
proofs: treeSignature.proofs.map((proof) => ({
|
|
127
130
|
leafPubkey: `0x${this.bytesToHex(proof.leafPubkey)}`,
|
|
128
131
|
signature: `0x${this.bytesToHex(proof.signature)}`,
|
|
129
|
-
mmrProof: `0x${this.bytesToHex(serializeMMRProof(proof.mmrProof))}`,
|
|
132
|
+
mmrProof: `0x${this.bytesToHex((0, mmr_js_1.serializeMMRProof)(proof.mmrProof))}`,
|
|
130
133
|
})),
|
|
131
134
|
};
|
|
132
135
|
// Serialize to byte-exact Java-compatible wire format
|
|
133
|
-
const serializedBytes = serializeTreeSignature(treeSignature);
|
|
136
|
+
const serializedBytes = (0, treekey_js_1.serializeTreeSignature)(treeSignature);
|
|
134
137
|
const signedHex = `0x${this.bytesToHex(serializedBytes)}`;
|
|
135
138
|
const elapsed = Date.now() - startTime;
|
|
136
139
|
this.metrics.timing('tx_sign_duration_ms', elapsed);
|
|
@@ -178,3 +181,4 @@ export class TransactionService {
|
|
|
178
181
|
.join('');
|
|
179
182
|
}
|
|
180
183
|
}
|
|
184
|
+
exports.TransactionService = TransactionService;
|
package/dist/tx/index.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
"use strict";
|
|
1
2
|
/**
|
|
2
3
|
* @module @totemsdk/core/tx
|
|
3
4
|
* Transaction service and lifecycle management
|
|
@@ -7,6 +8,13 @@
|
|
|
7
8
|
* - TransactionLifecycle: Orchestrates flow with lease/watermark stores
|
|
8
9
|
* - TransactionReceiptStore: Persistent transaction history
|
|
9
10
|
*/
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.TransactionReceiptStore = exports.WatermarkExhaustedError = exports.TransactionLifecycleError = exports.TransactionLifecycle = exports.TransactionService = void 0;
|
|
13
|
+
var TransactionService_js_1 = require("./TransactionService.js");
|
|
14
|
+
Object.defineProperty(exports, "TransactionService", { enumerable: true, get: function () { return TransactionService_js_1.TransactionService; } });
|
|
15
|
+
var TransactionLifecycle_js_1 = require("./TransactionLifecycle.js");
|
|
16
|
+
Object.defineProperty(exports, "TransactionLifecycle", { enumerable: true, get: function () { return TransactionLifecycle_js_1.TransactionLifecycle; } });
|
|
17
|
+
Object.defineProperty(exports, "TransactionLifecycleError", { enumerable: true, get: function () { return TransactionLifecycle_js_1.TransactionLifecycleError; } });
|
|
18
|
+
Object.defineProperty(exports, "WatermarkExhaustedError", { enumerable: true, get: function () { return TransactionLifecycle_js_1.WatermarkExhaustedError; } });
|
|
19
|
+
var TransactionReceiptStore_js_1 = require("./TransactionReceiptStore.js");
|
|
20
|
+
Object.defineProperty(exports, "TransactionReceiptStore", { enumerable: true, get: function () { return TransactionReceiptStore_js_1.TransactionReceiptStore; } });
|
package/dist/tx/types.js
CHANGED
package/dist/util.js
CHANGED
|
@@ -1 +1,5 @@
|
|
|
1
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.bytesToHex = void 0;
|
|
4
|
+
const bytesToHex = (b) => Array.from(b).map(x => x.toString(16).padStart(2, "0")).join("").toUpperCase();
|
|
5
|
+
exports.bytesToHex = bytesToHex;
|
package/dist/utils.js
CHANGED
|
@@ -1,12 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
1
2
|
/**
|
|
2
3
|
* Utility functions for byte array manipulation
|
|
3
4
|
*/
|
|
4
|
-
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.bytesToHex = bytesToHex;
|
|
7
|
+
exports.hexToBytes = hexToBytes;
|
|
8
|
+
exports.concatBytes = concatBytes;
|
|
9
|
+
exports.utf8ToBytes = utf8ToBytes;
|
|
10
|
+
exports.bytesToUtf8 = bytesToUtf8;
|
|
11
|
+
function bytesToHex(bytes) {
|
|
5
12
|
return Array.from(bytes)
|
|
6
13
|
.map(b => b.toString(16).padStart(2, '0'))
|
|
7
14
|
.join('');
|
|
8
15
|
}
|
|
9
|
-
|
|
16
|
+
function hexToBytes(hex) {
|
|
10
17
|
if (hex.startsWith('0x'))
|
|
11
18
|
hex = hex.slice(2);
|
|
12
19
|
if (hex.length % 2 !== 0)
|
|
@@ -17,7 +24,7 @@ export function hexToBytes(hex) {
|
|
|
17
24
|
}
|
|
18
25
|
return bytes;
|
|
19
26
|
}
|
|
20
|
-
|
|
27
|
+
function concatBytes(...arrays) {
|
|
21
28
|
const totalLength = arrays.reduce((sum, arr) => sum + arr.length, 0);
|
|
22
29
|
const result = new Uint8Array(totalLength);
|
|
23
30
|
let offset = 0;
|
|
@@ -27,9 +34,9 @@ export function concatBytes(...arrays) {
|
|
|
27
34
|
}
|
|
28
35
|
return result;
|
|
29
36
|
}
|
|
30
|
-
|
|
37
|
+
function utf8ToBytes(str) {
|
|
31
38
|
return new TextEncoder().encode(str);
|
|
32
39
|
}
|
|
33
|
-
|
|
40
|
+
function bytesToUtf8(bytes) {
|
|
34
41
|
return new TextDecoder().decode(bytes);
|
|
35
42
|
}
|