@theqrl/wallet.js 0.2.2 → 1.0.1
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/dist/cjs/wallet.js
CHANGED
|
@@ -305,15 +305,17 @@ class ExtendedSeed {
|
|
|
305
305
|
/**
|
|
306
306
|
* Layout: [3 bytes descriptor] || [48 bytes seed].
|
|
307
307
|
* @param {Uint8Array} bytes Exactly 51 bytes.
|
|
308
|
+
* @param {{ skipValidation?: boolean }} [options]
|
|
308
309
|
* @throws {Error} If size mismatch.
|
|
309
310
|
*/
|
|
310
|
-
constructor(bytes) {
|
|
311
|
+
constructor(bytes, options = {}) {
|
|
311
312
|
if (!bytes || bytes.length !== EXTENDED_SEED_SIZE) {
|
|
312
313
|
throw new Error(`ExtendedSeed must be ${EXTENDED_SEED_SIZE} bytes`);
|
|
313
314
|
}
|
|
315
|
+
const { skipValidation = false } = options;
|
|
314
316
|
/** @private @type {Uint8Array} */
|
|
315
317
|
this.bytes = Uint8Array.from(bytes);
|
|
316
|
-
if (!isValidWalletType(this.bytes[0])) {
|
|
318
|
+
if (!skipValidation && !isValidWalletType(this.bytes[0])) {
|
|
317
319
|
throw new Error('Invalid wallet type in descriptor');
|
|
318
320
|
}
|
|
319
321
|
}
|
|
@@ -375,6 +377,17 @@ class ExtendedSeed {
|
|
|
375
377
|
static from(input) {
|
|
376
378
|
return new ExtendedSeed(toFixedU8(input, EXTENDED_SEED_SIZE, 'ExtendedSeed'));
|
|
377
379
|
}
|
|
380
|
+
|
|
381
|
+
/**
|
|
382
|
+
* Internal helper: construct without wallet type validation.
|
|
383
|
+
* @param {string|Uint8Array|Buffer|number[]} input
|
|
384
|
+
* @returns {ExtendedSeed}
|
|
385
|
+
*/
|
|
386
|
+
static fromUnchecked(input) {
|
|
387
|
+
return new ExtendedSeed(toFixedU8(input, EXTENDED_SEED_SIZE, 'ExtendedSeed'), {
|
|
388
|
+
skipValidation: true,
|
|
389
|
+
});
|
|
390
|
+
}
|
|
378
391
|
}
|
|
379
392
|
|
|
380
393
|
/**
|
|
@@ -4526,12 +4539,10 @@ function binToMnemonic(input) {
|
|
|
4526
4539
|
for (let nibble = 0; nibble < input.length * 2; nibble += 3) {
|
|
4527
4540
|
const p = nibble >> 1;
|
|
4528
4541
|
const b1 = input[p];
|
|
4542
|
+
/* c8 ignore next -- fallback unreachable for valid (multiple of 3) input */
|
|
4529
4543
|
const b2 = p + 1 < input.length ? input[p + 1] : 0;
|
|
4530
4544
|
const idx = nibble % 2 === 0 ? (b1 << 4) + (b2 >> 4) : ((b1 & 0x0f) << 8) + b2;
|
|
4531
4545
|
|
|
4532
|
-
if (idx >= WordList.length) {
|
|
4533
|
-
throw new Error('mnemonic index out of range');
|
|
4534
|
-
}
|
|
4535
4546
|
words.push(WordList[idx]);
|
|
4536
4547
|
}
|
|
4537
4548
|
|
|
@@ -4732,17 +4743,22 @@ class Wallet {
|
|
|
4732
4743
|
|
|
4733
4744
|
/** @returns {Descriptor} */
|
|
4734
4745
|
getDescriptor() {
|
|
4735
|
-
return this.descriptor;
|
|
4746
|
+
return new Descriptor(this.descriptor.toBytes());
|
|
4736
4747
|
}
|
|
4737
4748
|
|
|
4738
4749
|
/** @returns {ExtendedSeed} */
|
|
4739
4750
|
getExtendedSeed() {
|
|
4740
|
-
|
|
4751
|
+
const bytes = this.extendedSeed.toBytes();
|
|
4752
|
+
try {
|
|
4753
|
+
return ExtendedSeed.from(bytes);
|
|
4754
|
+
} catch {
|
|
4755
|
+
return ExtendedSeed.fromUnchecked(bytes);
|
|
4756
|
+
}
|
|
4741
4757
|
}
|
|
4742
4758
|
|
|
4743
4759
|
/** @returns {Seed} */
|
|
4744
4760
|
getSeed() {
|
|
4745
|
-
return this.seed;
|
|
4761
|
+
return new Seed(this.seed.toBytes());
|
|
4746
4762
|
}
|
|
4747
4763
|
|
|
4748
4764
|
/** @returns {string} hex(ExtendedSeed) */
|
|
@@ -4835,6 +4851,7 @@ function newWalletFromExtendedSeed(extendedSeed) {
|
|
|
4835
4851
|
return Wallet.newWalletFromExtendedSeed(ext);
|
|
4836
4852
|
// case WalletType.SPHINCSPLUS_256S:
|
|
4837
4853
|
// Not yet implemented - reserved for future use
|
|
4854
|
+
/* c8 ignore next 2 */
|
|
4838
4855
|
default:
|
|
4839
4856
|
throw new Error(`Unsupported wallet type: ${desc.type()}`);
|
|
4840
4857
|
}
|
package/dist/mjs/wallet.js
CHANGED
|
@@ -303,15 +303,17 @@ class ExtendedSeed {
|
|
|
303
303
|
/**
|
|
304
304
|
* Layout: [3 bytes descriptor] || [48 bytes seed].
|
|
305
305
|
* @param {Uint8Array} bytes Exactly 51 bytes.
|
|
306
|
+
* @param {{ skipValidation?: boolean }} [options]
|
|
306
307
|
* @throws {Error} If size mismatch.
|
|
307
308
|
*/
|
|
308
|
-
constructor(bytes) {
|
|
309
|
+
constructor(bytes, options = {}) {
|
|
309
310
|
if (!bytes || bytes.length !== EXTENDED_SEED_SIZE) {
|
|
310
311
|
throw new Error(`ExtendedSeed must be ${EXTENDED_SEED_SIZE} bytes`);
|
|
311
312
|
}
|
|
313
|
+
const { skipValidation = false } = options;
|
|
312
314
|
/** @private @type {Uint8Array} */
|
|
313
315
|
this.bytes = Uint8Array.from(bytes);
|
|
314
|
-
if (!isValidWalletType(this.bytes[0])) {
|
|
316
|
+
if (!skipValidation && !isValidWalletType(this.bytes[0])) {
|
|
315
317
|
throw new Error('Invalid wallet type in descriptor');
|
|
316
318
|
}
|
|
317
319
|
}
|
|
@@ -373,6 +375,17 @@ class ExtendedSeed {
|
|
|
373
375
|
static from(input) {
|
|
374
376
|
return new ExtendedSeed(toFixedU8(input, EXTENDED_SEED_SIZE, 'ExtendedSeed'));
|
|
375
377
|
}
|
|
378
|
+
|
|
379
|
+
/**
|
|
380
|
+
* Internal helper: construct without wallet type validation.
|
|
381
|
+
* @param {string|Uint8Array|Buffer|number[]} input
|
|
382
|
+
* @returns {ExtendedSeed}
|
|
383
|
+
*/
|
|
384
|
+
static fromUnchecked(input) {
|
|
385
|
+
return new ExtendedSeed(toFixedU8(input, EXTENDED_SEED_SIZE, 'ExtendedSeed'), {
|
|
386
|
+
skipValidation: true,
|
|
387
|
+
});
|
|
388
|
+
}
|
|
376
389
|
}
|
|
377
390
|
|
|
378
391
|
/**
|
|
@@ -4524,12 +4537,10 @@ function binToMnemonic(input) {
|
|
|
4524
4537
|
for (let nibble = 0; nibble < input.length * 2; nibble += 3) {
|
|
4525
4538
|
const p = nibble >> 1;
|
|
4526
4539
|
const b1 = input[p];
|
|
4540
|
+
/* c8 ignore next -- fallback unreachable for valid (multiple of 3) input */
|
|
4527
4541
|
const b2 = p + 1 < input.length ? input[p + 1] : 0;
|
|
4528
4542
|
const idx = nibble % 2 === 0 ? (b1 << 4) + (b2 >> 4) : ((b1 & 0x0f) << 8) + b2;
|
|
4529
4543
|
|
|
4530
|
-
if (idx >= WordList.length) {
|
|
4531
|
-
throw new Error('mnemonic index out of range');
|
|
4532
|
-
}
|
|
4533
4544
|
words.push(WordList[idx]);
|
|
4534
4545
|
}
|
|
4535
4546
|
|
|
@@ -4730,17 +4741,22 @@ class Wallet {
|
|
|
4730
4741
|
|
|
4731
4742
|
/** @returns {Descriptor} */
|
|
4732
4743
|
getDescriptor() {
|
|
4733
|
-
return this.descriptor;
|
|
4744
|
+
return new Descriptor(this.descriptor.toBytes());
|
|
4734
4745
|
}
|
|
4735
4746
|
|
|
4736
4747
|
/** @returns {ExtendedSeed} */
|
|
4737
4748
|
getExtendedSeed() {
|
|
4738
|
-
|
|
4749
|
+
const bytes = this.extendedSeed.toBytes();
|
|
4750
|
+
try {
|
|
4751
|
+
return ExtendedSeed.from(bytes);
|
|
4752
|
+
} catch {
|
|
4753
|
+
return ExtendedSeed.fromUnchecked(bytes);
|
|
4754
|
+
}
|
|
4739
4755
|
}
|
|
4740
4756
|
|
|
4741
4757
|
/** @returns {Seed} */
|
|
4742
4758
|
getSeed() {
|
|
4743
|
-
return this.seed;
|
|
4759
|
+
return new Seed(this.seed.toBytes());
|
|
4744
4760
|
}
|
|
4745
4761
|
|
|
4746
4762
|
/** @returns {string} hex(ExtendedSeed) */
|
|
@@ -4833,6 +4849,7 @@ function newWalletFromExtendedSeed(extendedSeed) {
|
|
|
4833
4849
|
return Wallet.newWalletFromExtendedSeed(ext);
|
|
4834
4850
|
// case WalletType.SPHINCSPLUS_256S:
|
|
4835
4851
|
// Not yet implemented - reserved for future use
|
|
4852
|
+
/* c8 ignore next 2 */
|
|
4836
4853
|
default:
|
|
4837
4854
|
throw new Error(`Unsupported wallet type: ${desc.type()}`);
|
|
4838
4855
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@theqrl/wallet.js",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"description": "Quantum-resistant wallet library for The QRL using ML-DSA-87 (FIPS 204)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/cjs/wallet.js",
|
|
@@ -49,6 +49,7 @@
|
|
|
49
49
|
"@types/node": "^20.14.12",
|
|
50
50
|
"c8": "^7.13.0",
|
|
51
51
|
"chai": "^4.3.7",
|
|
52
|
+
"conventional-changelog-conventionalcommits": "^9.1.0",
|
|
52
53
|
"eslint": "^8.37.0",
|
|
53
54
|
"eslint-config-airbnb": "^19.0.4",
|
|
54
55
|
"eslint-config-prettier": "^8.8.0",
|
|
@@ -48,15 +48,17 @@ class ExtendedSeed {
|
|
|
48
48
|
/**
|
|
49
49
|
* Layout: [3 bytes descriptor] || [48 bytes seed].
|
|
50
50
|
* @param {Uint8Array} bytes Exactly 51 bytes.
|
|
51
|
+
* @param {{ skipValidation?: boolean }} [options]
|
|
51
52
|
* @throws {Error} If size mismatch.
|
|
52
53
|
*/
|
|
53
|
-
constructor(bytes) {
|
|
54
|
+
constructor(bytes, options = {}) {
|
|
54
55
|
if (!bytes || bytes.length !== EXTENDED_SEED_SIZE) {
|
|
55
56
|
throw new Error(`ExtendedSeed must be ${EXTENDED_SEED_SIZE} bytes`);
|
|
56
57
|
}
|
|
58
|
+
const { skipValidation = false } = options;
|
|
57
59
|
/** @private @type {Uint8Array} */
|
|
58
60
|
this.bytes = Uint8Array.from(bytes);
|
|
59
|
-
if (!isValidWalletType(this.bytes[0])) {
|
|
61
|
+
if (!skipValidation && !isValidWalletType(this.bytes[0])) {
|
|
60
62
|
throw new Error('Invalid wallet type in descriptor');
|
|
61
63
|
}
|
|
62
64
|
}
|
|
@@ -118,6 +120,17 @@ class ExtendedSeed {
|
|
|
118
120
|
static from(input) {
|
|
119
121
|
return new ExtendedSeed(toFixedU8(input, EXTENDED_SEED_SIZE, 'ExtendedSeed'));
|
|
120
122
|
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Internal helper: construct without wallet type validation.
|
|
126
|
+
* @param {string|Uint8Array|Buffer|number[]} input
|
|
127
|
+
* @returns {ExtendedSeed}
|
|
128
|
+
*/
|
|
129
|
+
static fromUnchecked(input) {
|
|
130
|
+
return new ExtendedSeed(toFixedU8(input, EXTENDED_SEED_SIZE, 'ExtendedSeed'), {
|
|
131
|
+
skipValidation: true,
|
|
132
|
+
});
|
|
133
|
+
}
|
|
121
134
|
}
|
|
122
135
|
|
|
123
136
|
export { Seed, ExtendedSeed };
|
package/src/wallet/factory.js
CHANGED
|
@@ -31,6 +31,7 @@ function newWalletFromExtendedSeed(extendedSeed) {
|
|
|
31
31
|
return MLDSA87.newWalletFromExtendedSeed(ext);
|
|
32
32
|
// case WalletType.SPHINCSPLUS_256S:
|
|
33
33
|
// Not yet implemented - reserved for future use
|
|
34
|
+
/* c8 ignore next 2 */
|
|
34
35
|
default:
|
|
35
36
|
throw new Error(`Unsupported wallet type: ${desc.type()}`);
|
|
36
37
|
}
|
|
@@ -24,12 +24,10 @@ function binToMnemonic(input) {
|
|
|
24
24
|
for (let nibble = 0; nibble < input.length * 2; nibble += 3) {
|
|
25
25
|
const p = nibble >> 1;
|
|
26
26
|
const b1 = input[p];
|
|
27
|
+
/* c8 ignore next -- fallback unreachable for valid (multiple of 3) input */
|
|
27
28
|
const b2 = p + 1 < input.length ? input[p + 1] : 0;
|
|
28
29
|
const idx = nibble % 2 === 0 ? (b1 << 4) + (b2 >> 4) : ((b1 & 0x0f) << 8) + b2;
|
|
29
30
|
|
|
30
|
-
if (idx >= WordList.length) {
|
|
31
|
-
throw new Error('mnemonic index out of range');
|
|
32
|
-
}
|
|
33
31
|
words.push(WordList[idx]);
|
|
34
32
|
}
|
|
35
33
|
|
|
@@ -8,6 +8,7 @@ import randomBytes from 'randombytes';
|
|
|
8
8
|
import { bytesToHex } from '@noble/hashes/utils.js';
|
|
9
9
|
import { mnemonicToBin, binToMnemonic } from '../misc/mnemonic.js';
|
|
10
10
|
import { getAddressFromPKAndDescriptor, addressToString } from '../common/address.js';
|
|
11
|
+
import { Descriptor } from '../common/descriptor.js';
|
|
11
12
|
import { Seed, ExtendedSeed } from '../common/seed.js';
|
|
12
13
|
import { newMLDSA87Descriptor } from './descriptor.js';
|
|
13
14
|
import { keygen, sign, verify } from './crypto.js';
|
|
@@ -81,17 +82,22 @@ class Wallet {
|
|
|
81
82
|
|
|
82
83
|
/** @returns {Descriptor} */
|
|
83
84
|
getDescriptor() {
|
|
84
|
-
return this.descriptor;
|
|
85
|
+
return new Descriptor(this.descriptor.toBytes());
|
|
85
86
|
}
|
|
86
87
|
|
|
87
88
|
/** @returns {ExtendedSeed} */
|
|
88
89
|
getExtendedSeed() {
|
|
89
|
-
|
|
90
|
+
const bytes = this.extendedSeed.toBytes();
|
|
91
|
+
try {
|
|
92
|
+
return ExtendedSeed.from(bytes);
|
|
93
|
+
} catch {
|
|
94
|
+
return ExtendedSeed.fromUnchecked(bytes);
|
|
95
|
+
}
|
|
90
96
|
}
|
|
91
97
|
|
|
92
98
|
/** @returns {Seed} */
|
|
93
99
|
getSeed() {
|
|
94
|
-
return this.seed;
|
|
100
|
+
return new Seed(this.seed.toBytes());
|
|
95
101
|
}
|
|
96
102
|
|
|
97
103
|
/** @returns {string} hex(ExtendedSeed) */
|