@theqrl/wallet.js 1.0.0 → 1.0.2

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/README.md CHANGED
@@ -1,5 +1,6 @@
1
1
  # wallet.js
2
2
 
3
+ [![npm version](https://img.shields.io/npm/v/@theqrl/wallet.js.svg)](https://www.npmjs.com/package/@theqrl/wallet.js)
3
4
  ![test](https://github.com/theQRL/wallet.js/actions/workflows/test.yml/badge.svg)
4
5
  [![codecov](https://codecov.io/gh/theQRL/wallet.js/branch/main/graph/badge.svg?token=HHVBFBVGFR)](https://codecov.io/gh/theQRL/wallet.js)
5
6
 
@@ -196,5 +197,5 @@ This library currently supports **ML-DSA-87** (FIPS 204), the NIST standardized
196
197
  - `randombytes` - Secure random generation
197
198
 
198
199
  ## License
199
-
200
+ [MIT](LICENSE)
200
201
  MIT
@@ -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
  /**
@@ -4730,17 +4743,22 @@ class Wallet {
4730
4743
 
4731
4744
  /** @returns {Descriptor} */
4732
4745
  getDescriptor() {
4733
- return this.descriptor;
4746
+ return new Descriptor(this.descriptor.toBytes());
4734
4747
  }
4735
4748
 
4736
4749
  /** @returns {ExtendedSeed} */
4737
4750
  getExtendedSeed() {
4738
- return this.extendedSeed;
4751
+ const bytes = this.extendedSeed.toBytes();
4752
+ try {
4753
+ return ExtendedSeed.from(bytes);
4754
+ } catch {
4755
+ return ExtendedSeed.fromUnchecked(bytes);
4756
+ }
4739
4757
  }
4740
4758
 
4741
4759
  /** @returns {Seed} */
4742
4760
  getSeed() {
4743
- return this.seed;
4761
+ return new Seed(this.seed.toBytes());
4744
4762
  }
4745
4763
 
4746
4764
  /** @returns {string} hex(ExtendedSeed) */
@@ -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
  /**
@@ -4728,17 +4741,22 @@ class Wallet {
4728
4741
 
4729
4742
  /** @returns {Descriptor} */
4730
4743
  getDescriptor() {
4731
- return this.descriptor;
4744
+ return new Descriptor(this.descriptor.toBytes());
4732
4745
  }
4733
4746
 
4734
4747
  /** @returns {ExtendedSeed} */
4735
4748
  getExtendedSeed() {
4736
- return this.extendedSeed;
4749
+ const bytes = this.extendedSeed.toBytes();
4750
+ try {
4751
+ return ExtendedSeed.from(bytes);
4752
+ } catch {
4753
+ return ExtendedSeed.fromUnchecked(bytes);
4754
+ }
4737
4755
  }
4738
4756
 
4739
4757
  /** @returns {Seed} */
4740
4758
  getSeed() {
4741
- return this.seed;
4759
+ return new Seed(this.seed.toBytes());
4742
4760
  }
4743
4761
 
4744
4762
  /** @returns {string} hex(ExtendedSeed) */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@theqrl/wallet.js",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
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",
@@ -30,7 +30,7 @@
30
30
  },
31
31
  "dependencies": {
32
32
  "@noble/hashes": "^1.8.0",
33
- "@theqrl/mldsa87": "^1.0.3",
33
+ "@theqrl/mldsa87": "^1.0.5",
34
34
  "randombytes": "^2.1.0"
35
35
  },
36
36
  "directories": {
@@ -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 };
@@ -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
- return this.extendedSeed;
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) */