@btc-vision/transaction 1.6.19 → 1.7.0

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 (141) hide show
  1. package/browser/index.js +1 -1
  2. package/browser/index.js.LICENSE.txt +2 -0
  3. package/browser/src/_version.d.ts +1 -0
  4. package/browser/{epoch → src/epoch}/interfaces/IChallengeSolution.d.ts +2 -0
  5. package/browser/{keypair → src/keypair}/Address.d.ts +7 -4
  6. package/browser/{keypair → src/keypair}/AddressVerificator.d.ts +3 -0
  7. package/browser/{keypair → src/keypair}/EcKeyPair.d.ts +3 -2
  8. package/browser/{keypair → src/keypair}/MessageSigner.d.ts +9 -0
  9. package/browser/src/keypair/Wallet.d.ts +47 -0
  10. package/browser/{keypair → src/keypair}/interfaces/IWallet.d.ts +2 -0
  11. package/browser/src/mnemonic/Mnemonic.d.ts +29 -0
  12. package/browser/src/mnemonic/MnemonicStrength.d.ts +7 -0
  13. package/browser/{opnet.d.ts → src/opnet.d.ts} +4 -0
  14. package/browser/src/transaction/browser/types/OPWallet.d.ts +14 -0
  15. package/browser/test/address.test.d.ts +1 -0
  16. package/browser/test/addressverificator-mldsa.test.d.ts +1 -0
  17. package/browser/test/derivePath.test.d.ts +1 -0
  18. package/browser/test/messagesigner-mldsa.test.d.ts +1 -0
  19. package/browser/test/messagesigner-schnorr.test.d.ts +1 -0
  20. package/browser/test/network-awareness.test.d.ts +1 -0
  21. package/build/_version.d.ts +1 -1
  22. package/build/_version.js +1 -1
  23. package/build/crypto/crypto-browser.d.ts +11 -0
  24. package/build/crypto/crypto-browser.js +56 -0
  25. package/build/epoch/ChallengeSolution.js +3 -2
  26. package/build/epoch/interfaces/IChallengeSolution.d.ts +2 -0
  27. package/build/keypair/Address.d.ts +7 -4
  28. package/build/keypair/Address.js +88 -37
  29. package/build/keypair/AddressVerificator.d.ts +3 -0
  30. package/build/keypair/AddressVerificator.js +49 -1
  31. package/build/keypair/EcKeyPair.d.ts +3 -2
  32. package/build/keypair/EcKeyPair.js +17 -3
  33. package/build/keypair/MessageSigner.d.ts +9 -0
  34. package/build/keypair/MessageSigner.js +23 -0
  35. package/build/keypair/Wallet.d.ts +20 -3
  36. package/build/keypair/Wallet.js +108 -9
  37. package/build/keypair/interfaces/IWallet.d.ts +2 -0
  38. package/build/mnemonic/Mnemonic.d.ts +29 -0
  39. package/build/mnemonic/Mnemonic.js +98 -0
  40. package/build/mnemonic/MnemonicStrength.d.ts +7 -0
  41. package/build/mnemonic/MnemonicStrength.js +8 -0
  42. package/build/opnet.d.ts +4 -0
  43. package/build/opnet.js +4 -0
  44. package/build/transaction/browser/types/OPWallet.d.ts +14 -0
  45. package/build/transaction/browser/types/OPWallet.js +6 -0
  46. package/gulpfile.js +2 -2
  47. package/package.json +25 -17
  48. package/src/_version.ts +1 -1
  49. package/src/epoch/ChallengeSolution.ts +3 -2
  50. package/src/epoch/interfaces/IChallengeSolution.ts +2 -0
  51. package/src/keypair/Address.ts +145 -43
  52. package/src/keypair/AddressVerificator.ts +87 -2
  53. package/src/keypair/EcKeyPair.ts +58 -6
  54. package/src/keypair/MessageSigner.ts +58 -0
  55. package/src/keypair/Wallet.ts +339 -57
  56. package/src/keypair/interfaces/IWallet.ts +13 -3
  57. package/src/mnemonic/Mnemonic.ts +340 -0
  58. package/src/mnemonic/MnemonicStrength.ts +12 -0
  59. package/src/network/ChainId.ts +1 -4
  60. package/src/opnet.ts +16 -0
  61. package/src/transaction/browser/types/OPWallet.ts +73 -0
  62. package/test/address.test.ts +1068 -0
  63. package/test/addressverificator-mldsa.test.ts +473 -0
  64. package/test/derivePath.test.ts +234 -0
  65. package/test/messagesigner-mldsa.test.ts +1060 -0
  66. package/test/messagesigner-schnorr.test.ts +1011 -0
  67. package/test/network-awareness.test.ts +163 -0
  68. package/tsconfig.json +1 -1
  69. package/vitest.config.ts +21 -0
  70. package/browser/_version.d.ts +0 -1
  71. package/browser/keypair/Wallet.d.ts +0 -30
  72. /package/browser/{abi → src/abi}/ABICoder.d.ts +0 -0
  73. /package/browser/{buffer → src/buffer}/BinaryReader.d.ts +0 -0
  74. /package/browser/{buffer → src/buffer}/BinaryWriter.d.ts +0 -0
  75. /package/browser/{bytecode → src/bytecode}/Compressor.d.ts +0 -0
  76. /package/browser/{consensus → src/consensus}/Consensus.d.ts +0 -0
  77. /package/browser/{consensus → src/consensus}/ConsensusConfig.d.ts +0 -0
  78. /package/browser/{consensus → src/consensus}/metadata/RoswellConsensus.d.ts +0 -0
  79. /package/browser/{crypto → src/crypto}/crypto-browser.d.ts +0 -0
  80. /package/browser/{crypto → src/crypto}/crypto.d.ts +0 -0
  81. /package/browser/{deterministic → src/deterministic}/AddressMap.d.ts +0 -0
  82. /package/browser/{deterministic → src/deterministic}/AddressSet.d.ts +0 -0
  83. /package/browser/{deterministic → src/deterministic}/DeterministicMap.d.ts +0 -0
  84. /package/browser/{deterministic → src/deterministic}/DeterministicSet.d.ts +0 -0
  85. /package/browser/{deterministic → src/deterministic}/Map.d.ts +0 -0
  86. /package/browser/{epoch → src/epoch}/ChallengeSolution.d.ts +0 -0
  87. /package/browser/{epoch → src/epoch}/validator/EpochValidator.d.ts +0 -0
  88. /package/browser/{event → src/event}/NetEvent.d.ts +0 -0
  89. /package/browser/{generators → src/generators}/AddressGenerator.d.ts +0 -0
  90. /package/browser/{generators → src/generators}/Features.d.ts +0 -0
  91. /package/browser/{generators → src/generators}/Generator.d.ts +0 -0
  92. /package/browser/{generators → src/generators}/builders/CalldataGenerator.d.ts +0 -0
  93. /package/browser/{generators → src/generators}/builders/CustomGenerator.d.ts +0 -0
  94. /package/browser/{generators → src/generators}/builders/DeploymentGenerator.d.ts +0 -0
  95. /package/browser/{generators → src/generators}/builders/LegacyCalldataGenerator.d.ts +0 -0
  96. /package/browser/{generators → src/generators}/builders/MultiSignGenerator.d.ts +0 -0
  97. /package/browser/{generators → src/generators}/builders/P2WDAGenerator.d.ts +0 -0
  98. /package/browser/{index.d.ts → src/index.d.ts} +0 -0
  99. /package/browser/{keypair → src/keypair}/Secp256k1PointDeriver.d.ts +0 -0
  100. /package/browser/{metadata → src/metadata}/ContractBaseMetadata.d.ts +0 -0
  101. /package/browser/{metadata → src/metadata}/tokens.d.ts +0 -0
  102. /package/browser/{network → src/network}/ChainId.d.ts +0 -0
  103. /package/browser/{p2wda → src/p2wda}/P2WDADetector.d.ts +0 -0
  104. /package/browser/{signer → src/signer}/SignerUtils.d.ts +0 -0
  105. /package/browser/{signer → src/signer}/TweakedSigner.d.ts +0 -0
  106. /package/browser/{transaction → src/transaction}/ContractAddress.d.ts +0 -0
  107. /package/browser/{transaction → src/transaction}/TransactionFactory.d.ts +0 -0
  108. /package/browser/{transaction → src/transaction}/browser/BrowserSignerBase.d.ts +0 -0
  109. /package/browser/{transaction → src/transaction}/browser/Web3Provider.d.ts +0 -0
  110. /package/browser/{transaction → src/transaction}/browser/extensions/UnisatSigner.d.ts +0 -0
  111. /package/browser/{transaction → src/transaction}/browser/extensions/XverseSigner.d.ts +0 -0
  112. /package/browser/{transaction → src/transaction}/browser/types/Unisat.d.ts +0 -0
  113. /package/browser/{transaction → src/transaction}/browser/types/Xverse.d.ts +0 -0
  114. /package/browser/{transaction → src/transaction}/builders/CancelTransaction.d.ts +0 -0
  115. /package/browser/{transaction → src/transaction}/builders/ChallengeSolutionTransaction.d.ts +0 -0
  116. /package/browser/{transaction → src/transaction}/builders/CustomScriptTransaction.d.ts +0 -0
  117. /package/browser/{transaction → src/transaction}/builders/DeploymentTransaction.d.ts +0 -0
  118. /package/browser/{transaction → src/transaction}/builders/FundingTransaction.d.ts +0 -0
  119. /package/browser/{transaction → src/transaction}/builders/InteractionTransaction.d.ts +0 -0
  120. /package/browser/{transaction → src/transaction}/builders/InteractionTransactionP2WDA.d.ts +0 -0
  121. /package/browser/{transaction → src/transaction}/builders/MultiSignTransaction.d.ts +0 -0
  122. /package/browser/{transaction → src/transaction}/builders/SharedInteractionTransaction.d.ts +0 -0
  123. /package/browser/{transaction → src/transaction}/builders/TransactionBuilder.d.ts +0 -0
  124. /package/browser/{transaction → src/transaction}/enums/TransactionType.d.ts +0 -0
  125. /package/browser/{transaction → src/transaction}/interfaces/ITransactionParameters.d.ts +0 -0
  126. /package/browser/{transaction → src/transaction}/interfaces/Tap.d.ts +0 -0
  127. /package/browser/{transaction → src/transaction}/mineable/IP2WSHAddress.d.ts +0 -0
  128. /package/browser/{transaction → src/transaction}/mineable/TimelockGenerator.d.ts +0 -0
  129. /package/browser/{transaction → src/transaction}/processor/PsbtTransaction.d.ts +0 -0
  130. /package/browser/{transaction → src/transaction}/psbt/PSBTTypes.d.ts +0 -0
  131. /package/browser/{transaction → src/transaction}/shared/P2TR_MS.d.ts +0 -0
  132. /package/browser/{transaction → src/transaction}/shared/TweakedTransaction.d.ts +0 -0
  133. /package/browser/{utils → src/utils}/BitcoinUtils.d.ts +0 -0
  134. /package/browser/{utils → src/utils}/BufferHelper.d.ts +0 -0
  135. /package/browser/{utils → src/utils}/StringToBuffer.d.ts +0 -0
  136. /package/browser/{utils → src/utils}/lengths.d.ts +0 -0
  137. /package/browser/{utils → src/utils}/types.d.ts +0 -0
  138. /package/browser/{utxo → src/utxo}/OPNetLimitedProvider.d.ts +0 -0
  139. /package/browser/{utxo → src/utxo}/interfaces/BroadcastResponse.d.ts +0 -0
  140. /package/browser/{utxo → src/utxo}/interfaces/IUTXO.d.ts +0 -0
  141. /package/browser/{verification → src/verification}/TapscriptVerificator.d.ts +0 -0
@@ -9,7 +9,7 @@ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (
9
9
  if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
10
10
  return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
11
11
  };
12
- var _Address_p2tr, _Address_p2op, _Address_network, _Address_originalPublicKey, _Address_keyPair, _Address_uncompressed, _Address_tweakedUncompressed, _Address_p2wda;
12
+ var _Address_p2tr, _Address_p2op, _Address_network, _Address_originalPublicKey, _Address_keyPair, _Address_uncompressed, _Address_tweakedUncompressed, _Address_p2wda, _Address_mldsaPublicKey;
13
13
  import { decompressPublicKey, toXOnly } from '@btc-vision/bitcoin';
14
14
  import { ADDRESS_BYTE_LENGTH } from '../utils/lengths.js';
15
15
  import { AddressVerificator } from './AddressVerificator.js';
@@ -18,8 +18,9 @@ import { ContractAddress } from '../transaction/ContractAddress.js';
18
18
  import { BitcoinUtils } from '../utils/BitcoinUtils.js';
19
19
  import { TimeLockGenerator } from '../transaction/mineable/TimelockGenerator.js';
20
20
  import { P2WDADetector } from '../p2wda/P2WDADetector.js';
21
+ import { sha256 } from '@noble/hashes/sha2';
21
22
  export class Address extends Uint8Array {
22
- constructor(bytes) {
23
+ constructor(mldsaPublicKey, publicKeyOrTweak) {
23
24
  super(ADDRESS_BYTE_LENGTH);
24
25
  _Address_p2tr.set(this, void 0);
25
26
  _Address_p2op.set(this, void 0);
@@ -29,37 +30,52 @@ export class Address extends Uint8Array {
29
30
  _Address_uncompressed.set(this, void 0);
30
31
  _Address_tweakedUncompressed.set(this, void 0);
31
32
  _Address_p2wda.set(this, void 0);
32
- if (!bytes) {
33
+ _Address_mldsaPublicKey.set(this, void 0);
34
+ if (!mldsaPublicKey) {
33
35
  return;
34
36
  }
35
- this.set(bytes);
37
+ if (publicKeyOrTweak) {
38
+ this.classicPublicKey = new Uint8Array(publicKeyOrTweak.length);
39
+ this.classicPublicKey.set(publicKeyOrTweak);
40
+ }
41
+ this.set(mldsaPublicKey);
36
42
  }
37
43
  get originalPublicKey() {
38
44
  return __classPrivateFieldGet(this, _Address_originalPublicKey, "f");
39
45
  }
46
+ get mldsaPublicKey() {
47
+ return __classPrivateFieldGet(this, _Address_mldsaPublicKey, "f");
48
+ }
40
49
  get keyPair() {
41
50
  if (!__classPrivateFieldGet(this, _Address_keyPair, "f")) {
42
- throw new Error('Public key not set for address');
51
+ throw new Error('Classical public key not set for address');
43
52
  }
44
53
  return __classPrivateFieldGet(this, _Address_keyPair, "f");
45
54
  }
46
55
  static dead() {
47
- return Address.fromString('0x04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f');
56
+ return Address.fromString('0x0000000000000000000000000000000000000000000000000000000000000000', '0x04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f');
48
57
  }
49
- static zero() {
50
- return new Address();
51
- }
52
- static fromString(pubKey) {
53
- if (!pubKey) {
58
+ static fromString(mldsaPublicKey, classicPublicKey) {
59
+ if (!mldsaPublicKey) {
54
60
  throw new Error('Invalid public key');
55
61
  }
56
- if (pubKey.startsWith('0x')) {
57
- pubKey = pubKey.slice(2);
62
+ if (mldsaPublicKey.startsWith('0x')) {
63
+ mldsaPublicKey = mldsaPublicKey.slice(2);
58
64
  }
59
- if (!BitcoinUtils.isValidHex(pubKey)) {
65
+ if (!BitcoinUtils.isValidHex(mldsaPublicKey)) {
60
66
  throw new Error('You must only pass public keys in hexadecimal format. If you have an address such as bc1q... you must convert it to a public key first. Please refer to await provider.getPublicKeyInfo("bc1q..."). If the public key associated with the address is not found, you must force the user to enter the destination public key. It looks like: 0x020373626d317ae8788ce3280b491068610d840c23ecb64c14075bbb9f670af52c.');
61
67
  }
62
- return new Address(Buffer.from(pubKey, 'hex'));
68
+ let classicBuffer;
69
+ if (classicPublicKey) {
70
+ if (classicPublicKey.startsWith('0x')) {
71
+ classicPublicKey = classicPublicKey.slice(2);
72
+ }
73
+ if (!BitcoinUtils.isValidHex(classicPublicKey)) {
74
+ throw new Error('You must only pass classical public keys in hexadecimal format. If you have an address such as bc1q... you must convert it to a public key first. Please refer to await provider.getPublicKeyInfo("bc1q..."). If the public key associated with the address is not found, you must force the user to enter the destination public key. It looks like: 0x020373626d317ae8788ce3280b491068610d840c23ecb64c14075bbb9f670af52c.');
75
+ }
76
+ classicBuffer = Buffer.from(classicPublicKey, 'hex');
77
+ }
78
+ return new Address(Buffer.from(mldsaPublicKey, 'hex'), classicBuffer);
63
79
  }
64
80
  static wrap(bytes) {
65
81
  return new Address(bytes);
@@ -76,36 +92,48 @@ export class Address extends Uint8Array {
76
92
  toHex() {
77
93
  return '0x' + Buffer.from(this).toString('hex');
78
94
  }
95
+ tweakedToHex() {
96
+ if (!this.classicPublicKey) {
97
+ throw new Error('Classical public key not set');
98
+ }
99
+ return '0x' + Buffer.from(this.classicPublicKey).toString('hex');
100
+ }
79
101
  toBuffer() {
80
102
  return Buffer.from(this);
81
103
  }
104
+ tweakedPublicKeyToBuffer() {
105
+ if (!this.classicPublicKey) {
106
+ throw new Error('Classical public key not set');
107
+ }
108
+ return Buffer.from(this.classicPublicKey);
109
+ }
82
110
  toUncompressedHex() {
83
111
  if (!__classPrivateFieldGet(this, _Address_uncompressed, "f")) {
84
- throw new Error('Public key not set');
112
+ throw new Error('Classical public key not set');
85
113
  }
86
114
  return '0x' + __classPrivateFieldGet(this, _Address_uncompressed, "f").uncompressed.toString('hex');
87
115
  }
88
116
  toUncompressedBuffer() {
89
117
  if (!__classPrivateFieldGet(this, _Address_uncompressed, "f")) {
90
- throw new Error('Public key not set');
118
+ throw new Error('Classical public key not set');
91
119
  }
92
120
  return __classPrivateFieldGet(this, _Address_uncompressed, "f").uncompressed;
93
121
  }
94
122
  toHybridPublicKeyHex() {
95
123
  if (!__classPrivateFieldGet(this, _Address_uncompressed, "f")) {
96
- throw new Error('Public key not set');
124
+ throw new Error('Classical public key not set');
97
125
  }
98
126
  return '0x' + __classPrivateFieldGet(this, _Address_uncompressed, "f").hybrid.toString('hex');
99
127
  }
100
128
  toHybridPublicKeyBuffer() {
101
129
  if (!__classPrivateFieldGet(this, _Address_uncompressed, "f")) {
102
- throw new Error('Public key not set');
130
+ throw new Error('Classical public key not set');
103
131
  }
104
132
  return __classPrivateFieldGet(this, _Address_uncompressed, "f").hybrid;
105
133
  }
106
134
  originalPublicKeyBuffer() {
107
135
  if (!__classPrivateFieldGet(this, _Address_originalPublicKey, "f")) {
108
- throw new Error('Public key not set');
136
+ throw new Error('Classical public key not set');
109
137
  }
110
138
  return Buffer.from(__classPrivateFieldGet(this, _Address_originalPublicKey, "f"));
111
139
  }
@@ -149,19 +177,38 @@ export class Address extends Uint8Array {
149
177
  }
150
178
  return false;
151
179
  }
152
- set(publicKey) {
153
- const validLengths = [ADDRESS_BYTE_LENGTH, 33, 65];
154
- if (!validLengths.includes(publicKey.length)) {
155
- throw new Error(`Invalid public key length ${publicKey.length}`);
180
+ set(mldsaPublicKey) {
181
+ if (this.classicPublicKey) {
182
+ const validLengths = [ADDRESS_BYTE_LENGTH, 33, 65];
183
+ if (!validLengths.includes(this.classicPublicKey.length)) {
184
+ throw new Error(`Invalid public key length ${this.classicPublicKey.length}`);
185
+ }
186
+ if (this.classicPublicKey.length === ADDRESS_BYTE_LENGTH) {
187
+ const buf = Buffer.alloc(ADDRESS_BYTE_LENGTH);
188
+ buf.set(this.classicPublicKey);
189
+ __classPrivateFieldSet(this, _Address_tweakedUncompressed, ContractAddress.generateHybridKeyFromHash(buf), "f");
190
+ }
191
+ else {
192
+ this.autoFormat(this.classicPublicKey);
193
+ }
156
194
  }
157
- if (publicKey.length === ADDRESS_BYTE_LENGTH) {
158
- const buf = Buffer.alloc(ADDRESS_BYTE_LENGTH);
159
- buf.set(publicKey);
160
- __classPrivateFieldSet(this, _Address_tweakedUncompressed, ContractAddress.generateHybridKeyFromHash(buf), "f");
161
- super.set(publicKey);
195
+ if (mldsaPublicKey.length === ADDRESS_BYTE_LENGTH) {
196
+ const buf = new Uint8Array(ADDRESS_BYTE_LENGTH);
197
+ buf.set(mldsaPublicKey);
198
+ super.set(buf);
162
199
  }
163
200
  else {
164
- this.autoFormat(publicKey);
201
+ const validMLDSALengths = [1312, 1952, 2592];
202
+ if (!validMLDSALengths.includes(mldsaPublicKey.length)) {
203
+ throw new Error(`Invalid ML-DSA public key length: ${mldsaPublicKey.length}. ` +
204
+ `Expected 1312 (ML-DSA-44/LEVEL2), 1952 (ML-DSA-65/LEVEL3), or 2592 (ML-DSA-87/LEVEL5) bytes.`);
205
+ }
206
+ __classPrivateFieldSet(this, _Address_mldsaPublicKey, new Uint8Array(mldsaPublicKey.length), "f");
207
+ __classPrivateFieldGet(this, _Address_mldsaPublicKey, "f").set(mldsaPublicKey);
208
+ const hashedPublicKey = sha256(new Uint8Array(mldsaPublicKey));
209
+ const buf = new Uint8Array(ADDRESS_BYTE_LENGTH);
210
+ buf.set(hashedPublicKey);
211
+ super.set(buf);
165
212
  }
166
213
  }
167
214
  isValid(network) {
@@ -186,16 +233,19 @@ export class Address extends Uint8Array {
186
233
  return this.toHex();
187
234
  }
188
235
  p2tr(network) {
236
+ if (!this.classicPublicKey) {
237
+ throw new Error('Classical public key not set');
238
+ }
189
239
  if (__classPrivateFieldGet(this, _Address_p2tr, "f") && __classPrivateFieldGet(this, _Address_network, "f") === network) {
190
240
  return __classPrivateFieldGet(this, _Address_p2tr, "f");
191
241
  }
192
- const p2trAddy = EcKeyPair.tweakedPubKeyBufferToAddress(this, network);
242
+ const p2trAddy = EcKeyPair.tweakedPubKeyBufferToAddress(this.classicPublicKey, network);
193
243
  if (p2trAddy) {
194
244
  __classPrivateFieldSet(this, _Address_network, network, "f");
195
245
  __classPrivateFieldSet(this, _Address_p2tr, p2trAddy, "f");
196
246
  return p2trAddy;
197
247
  }
198
- throw new Error('Public key not set');
248
+ throw new Error('Classical public key not set');
199
249
  }
200
250
  p2wda(network) {
201
251
  if (__classPrivateFieldGet(this, _Address_p2wda, "f") && __classPrivateFieldGet(this, _Address_network, "f") === network) {
@@ -242,17 +292,17 @@ export class Address extends Uint8Array {
242
292
  __classPrivateFieldSet(this, _Address_p2op, p2opAddy, "f");
243
293
  return p2opAddy;
244
294
  }
245
- throw new Error('Public key not set');
295
+ throw new Error('ML-DSA public key not set');
246
296
  }
247
297
  toTweakedHybridPublicKeyHex() {
248
298
  if (!__classPrivateFieldGet(this, _Address_tweakedUncompressed, "f")) {
249
- throw new Error('Public key not set');
299
+ throw new Error('Classical public key not set');
250
300
  }
251
301
  return '0x' + __classPrivateFieldGet(this, _Address_tweakedUncompressed, "f").toString('hex');
252
302
  }
253
303
  toTweakedHybridPublicKeyBuffer() {
254
304
  if (!__classPrivateFieldGet(this, _Address_tweakedUncompressed, "f")) {
255
- throw new Error('Public key not set');
305
+ throw new Error('Classical public key not set');
256
306
  }
257
307
  return __classPrivateFieldGet(this, _Address_tweakedUncompressed, "f");
258
308
  }
@@ -268,7 +318,8 @@ export class Address extends Uint8Array {
268
318
  __classPrivateFieldSet(this, _Address_uncompressed, decompressPublicKey(__classPrivateFieldGet(this, _Address_originalPublicKey, "f")), "f");
269
319
  const tweakedBytes = toXOnly(EcKeyPair.tweakPublicKey(Buffer.from(__classPrivateFieldGet(this, _Address_originalPublicKey, "f"))));
270
320
  __classPrivateFieldSet(this, _Address_tweakedUncompressed, ContractAddress.generateHybridKeyFromHash(tweakedBytes), "f");
271
- super.set(tweakedBytes);
321
+ this.classicPublicKey = new Uint8Array(ADDRESS_BYTE_LENGTH);
322
+ this.classicPublicKey.set(tweakedBytes);
272
323
  }
273
324
  }
274
- _Address_p2tr = new WeakMap(), _Address_p2op = new WeakMap(), _Address_network = new WeakMap(), _Address_originalPublicKey = new WeakMap(), _Address_keyPair = new WeakMap(), _Address_uncompressed = new WeakMap(), _Address_tweakedUncompressed = new WeakMap(), _Address_p2wda = new WeakMap();
325
+ _Address_p2tr = new WeakMap(), _Address_p2op = new WeakMap(), _Address_network = new WeakMap(), _Address_originalPublicKey = new WeakMap(), _Address_keyPair = new WeakMap(), _Address_uncompressed = new WeakMap(), _Address_tweakedUncompressed = new WeakMap(), _Address_p2wda = new WeakMap(), _Address_mldsaPublicKey = new WeakMap();
@@ -1,4 +1,5 @@
1
1
  import { Network } from '@btc-vision/bitcoin';
2
+ import { MLDSASecurityLevel } from '@btc-vision/bip32';
2
3
  export declare enum AddressTypes {
3
4
  P2PKH = "P2PKH",
4
5
  P2OP = "P2OP",
@@ -22,6 +23,8 @@ export declare class AddressVerificator {
22
23
  static isP2WDAWitnessScript(witnessScript: Buffer): boolean;
23
24
  static isP2PKHOrP2SH(addy: string, network: Network): boolean;
24
25
  static isValidPublicKey(input: string, network: Network): boolean;
26
+ static isValidMLDSAPublicKey(input: string | Buffer | Uint8Array): MLDSASecurityLevel | null;
27
+ static isValidP2OPAddress(inAddress: string, network: Network): boolean;
25
28
  static requireRedeemScript(addy: string, network: Network): boolean;
26
29
  static detectAddressType(addy: string, network: Network): AddressTypes | null;
27
30
  static detectAddressTypeWithWitnessScript(addy: string, network: Network, witnessScript?: Buffer): AddressTypes | null;
@@ -3,6 +3,7 @@ import * as ecc from '@bitcoinerlab/secp256k1';
3
3
  import { EcKeyPair } from './EcKeyPair.js';
4
4
  import { BitcoinUtils } from '../utils/BitcoinUtils.js';
5
5
  import { P2WDADetector } from '../p2wda/P2WDADetector.js';
6
+ import { MLDSASecurityLevel } from '@btc-vision/bip32';
6
7
  initEccLib(ecc);
7
8
  export var AddressTypes;
8
9
  (function (AddressTypes) {
@@ -81,6 +82,52 @@ export class AddressVerificator {
81
82
  }
82
83
  return false;
83
84
  }
85
+ static isValidMLDSAPublicKey(input) {
86
+ try {
87
+ let byteLength;
88
+ if (Buffer.isBuffer(input) || input instanceof Uint8Array) {
89
+ byteLength = input.length;
90
+ }
91
+ else {
92
+ if (input.startsWith('0x')) {
93
+ input = input.slice(2);
94
+ }
95
+ if (!BitcoinUtils.isValidHex(input)) {
96
+ return null;
97
+ }
98
+ byteLength = input.length / 2;
99
+ }
100
+ switch (byteLength) {
101
+ case 1312:
102
+ return MLDSASecurityLevel.LEVEL2;
103
+ case 1952:
104
+ return MLDSASecurityLevel.LEVEL3;
105
+ case 2592:
106
+ return MLDSASecurityLevel.LEVEL5;
107
+ default:
108
+ return null;
109
+ }
110
+ }
111
+ catch (e) {
112
+ return null;
113
+ }
114
+ }
115
+ static isValidP2OPAddress(inAddress, network) {
116
+ if (!inAddress || inAddress.length < 20)
117
+ return false;
118
+ try {
119
+ const decodedAddress = address.fromBech32(inAddress);
120
+ const validPrefix = decodedAddress.prefix === network.bech32 ||
121
+ decodedAddress.prefix === network.bech32Opnet;
122
+ if (!validPrefix) {
123
+ return false;
124
+ }
125
+ return decodedAddress.version === 16 && decodedAddress.data.length === 21;
126
+ }
127
+ catch {
128
+ return false;
129
+ }
130
+ }
84
131
  static requireRedeemScript(addy, network) {
85
132
  try {
86
133
  const decodedBase58 = address.fromBase58Check(addy);
@@ -111,7 +158,8 @@ export class AddressVerificator {
111
158
  const decodedBech32 = address.fromBech32(addy);
112
159
  if ((decodedBech32.prefix === network.bech32Opnet ||
113
160
  decodedBech32.prefix === network.bech32) &&
114
- decodedBech32.version === 16) {
161
+ decodedBech32.version === 16 &&
162
+ decodedBech32.data.length === 21) {
115
163
  return AddressTypes.P2OP;
116
164
  }
117
165
  if (decodedBech32.prefix === network.bech32) {
@@ -1,4 +1,4 @@
1
- import { BIP32API, BIP32Interface } from 'bip32';
1
+ import { BIP32API, BIP32Interface, MLDSAKeyPair, MLDSASecurityLevel } from '@btc-vision/bip32';
2
2
  import { Network, Signer } from '@btc-vision/bitcoin';
3
3
  import { ECPairAPI, ECPairInterface } from 'ecpair';
4
4
  import { IWallet } from './interfaces/IWallet.js';
@@ -17,7 +17,8 @@ export declare class EcKeyPair {
17
17
  static xOnlyTweakedPubKeyToAddress(tweakedPubKeyHex: string, network: Network): string;
18
18
  static tweakPublicKey(pub: Uint8Array | Buffer | string): Buffer;
19
19
  static tweakBatchSharedT(pubkeys: readonly Uint8Array[], tweakScalar: bigint): Uint8Array[];
20
- static generateWallet(network?: Network): IWallet;
20
+ static generateWallet(network?: Network, securityLevel?: MLDSASecurityLevel): IWallet;
21
+ static generateQuantumKeyPair(securityLevel?: MLDSASecurityLevel, network?: Network): MLDSAKeyPair;
21
22
  static verifyContractAddress(contractAddress: string, network?: Network): boolean;
22
23
  static getLegacySegwitAddress(keyPair: ECPairInterface, network?: Network): string;
23
24
  static getLegacyAddress(keyPair: ECPairInterface, network?: Network): string;
@@ -1,11 +1,11 @@
1
1
  import * as ecc from '@bitcoinerlab/secp256k1';
2
- import bip32, { BIP32Factory } from 'bip32';
2
+ import bip32, { BIP32Factory, MLDSASecurityLevel, QuantumBIP32Factory, } from '@btc-vision/bip32';
3
3
  import bitcoin, { address, fromOutputScript, initEccLib, networks, opcodes, payments, script, toXOnly, } from '@btc-vision/bitcoin';
4
4
  import { ECPairFactory } from 'ecpair';
5
5
  import { secp256k1 } from '@noble/curves/secp256k1';
6
6
  import { mod } from '@noble/curves/abstract/modular';
7
7
  import { sha256 } from '@noble/hashes/sha2';
8
- import { bytesToNumberBE, concatBytes, utf8ToBytes } from '@noble/curves/utils.js';
8
+ import { bytesToNumberBE, concatBytes, randomBytes, utf8ToBytes } from '@noble/curves/utils.js';
9
9
  initEccLib(ecc);
10
10
  const BIP32factory = typeof bip32 === 'function' ? bip32 : BIP32Factory;
11
11
  if (!BIP32factory) {
@@ -128,7 +128,7 @@ export class EcKeyPair {
128
128
  return Q.toBytes(true);
129
129
  });
130
130
  }
131
- static generateWallet(network = networks.bitcoin) {
131
+ static generateWallet(network = networks.bitcoin, securityLevel = MLDSASecurityLevel.LEVEL2) {
132
132
  const keyPair = this.ECPair.makeRandom({
133
133
  network: network,
134
134
  });
@@ -136,10 +136,24 @@ export class EcKeyPair {
136
136
  if (!wallet) {
137
137
  throw new Error('Failed to generate wallet');
138
138
  }
139
+ const quantumKeyPair = this.generateQuantumKeyPair(securityLevel, network);
139
140
  return {
140
141
  address: wallet,
141
142
  privateKey: keyPair.toWIF(),
142
143
  publicKey: Buffer.from(keyPair.publicKey).toString('hex'),
144
+ quantumPrivateKey: Buffer.from(quantumKeyPair.privateKey).toString('hex'),
145
+ quantumPublicKey: Buffer.from(quantumKeyPair.publicKey).toString('hex'),
146
+ };
147
+ }
148
+ static generateQuantumKeyPair(securityLevel = MLDSASecurityLevel.LEVEL2, network = networks.bitcoin) {
149
+ const randomSeed = randomBytes(64);
150
+ const quantumRoot = QuantumBIP32Factory.fromSeed(Buffer.from(randomSeed), network, securityLevel);
151
+ if (!quantumRoot.privateKey || !quantumRoot.publicKey) {
152
+ throw new Error('Failed to generate quantum keypair');
153
+ }
154
+ return {
155
+ privateKey: Buffer.from(quantumRoot.privateKey),
156
+ publicKey: Buffer.from(quantumRoot.publicKey),
143
157
  };
144
158
  }
145
159
  static verifyContractAddress(contractAddress, network = networks.bitcoin) {
@@ -1,15 +1,24 @@
1
1
  import { ECPairInterface } from 'ecpair';
2
2
  import { Network } from '@btc-vision/bitcoin';
3
+ import { MLDSASecurityLevel, QuantumBIP32Interface } from '@btc-vision/bip32';
3
4
  export interface SignedMessage {
4
5
  readonly signature: Uint8Array;
5
6
  readonly message: Uint8Array;
6
7
  }
8
+ export interface MLDSASignedMessage {
9
+ readonly signature: Uint8Array;
10
+ readonly message: Uint8Array;
11
+ readonly publicKey: Uint8Array;
12
+ readonly securityLevel: MLDSASecurityLevel;
13
+ }
7
14
  declare class MessageSignerBase {
8
15
  sha256(message: Buffer | Uint8Array): Buffer;
9
16
  tweakAndSignMessage(keypair: ECPairInterface, message: Uint8Array | Buffer | string, network: Network): SignedMessage;
10
17
  signMessage(keypair: ECPairInterface, message: Uint8Array | Buffer | string): SignedMessage;
11
18
  verifySignature(publicKey: Uint8Array | Buffer, message: Uint8Array | Buffer | string, signature: Uint8Array | Buffer): boolean;
12
19
  tweakAndVerifySignature(publicKey: Uint8Array | Buffer, message: Uint8Array | Buffer | string, signature: Uint8Array | Buffer): boolean;
20
+ signMLDSAMessage(mldsaKeypair: QuantumBIP32Interface, message: Uint8Array | Buffer | string): MLDSASignedMessage;
21
+ verifyMLDSASignature(mldsaKeypair: QuantumBIP32Interface, message: Uint8Array | Buffer | string, signature: Uint8Array | Buffer): boolean;
13
22
  }
14
23
  export declare const MessageSigner: MessageSignerBase;
15
24
  export {};
@@ -39,5 +39,28 @@ class MessageSignerBase {
39
39
  const tweakedPublicKey = EcKeyPair.tweakPublicKey(Buffer.from(publicKey));
40
40
  return this.verifySignature(tweakedPublicKey, message, signature);
41
41
  }
42
+ signMLDSAMessage(mldsaKeypair, message) {
43
+ if (typeof message === 'string') {
44
+ message = Buffer.from(message, 'utf-8');
45
+ }
46
+ if (!mldsaKeypair.privateKey) {
47
+ throw new Error('ML-DSA private key not found in keypair.');
48
+ }
49
+ const hashedMessage = this.sha256(message);
50
+ const signature = mldsaKeypair.sign(hashedMessage);
51
+ return {
52
+ signature: Buffer.from(signature),
53
+ message: hashedMessage,
54
+ publicKey: Buffer.from(mldsaKeypair.publicKey),
55
+ securityLevel: mldsaKeypair.securityLevel,
56
+ };
57
+ }
58
+ verifyMLDSASignature(mldsaKeypair, message, signature) {
59
+ if (typeof message === 'string') {
60
+ message = Buffer.from(message, 'utf-8');
61
+ }
62
+ const hashedMessage = this.sha256(message);
63
+ return mldsaKeypair.verify(hashedMessage, signature);
64
+ }
42
65
  }
43
66
  export const MessageSigner = new MessageSignerBase();
@@ -2,9 +2,13 @@ import { ECPairInterface } from 'ecpair';
2
2
  import { Network } from '@btc-vision/bitcoin';
3
3
  import { Address } from './Address.js';
4
4
  import { IP2WSHAddress } from '../transaction/mineable/IP2WSHAddress.js';
5
+ import { MLDSASecurityLevel, QuantumBIP32Interface } from '@btc-vision/bip32';
5
6
  export declare class Wallet {
6
7
  readonly network: Network;
7
8
  private readonly _keypair;
9
+ private readonly _mldsaKeypair;
10
+ private readonly _securityLevel;
11
+ private readonly _chainCode;
8
12
  private readonly _p2wpkh;
9
13
  private readonly _p2tr;
10
14
  private readonly _p2wda;
@@ -13,10 +17,13 @@ export declare class Wallet {
13
17
  private readonly _bufferPubKey;
14
18
  private readonly _tweakedKey;
15
19
  private readonly _address;
16
- constructor(privateKeyOrWif: string, network?: Network);
20
+ constructor(privateKeyOrWif: string, mldsaPrivateKeyOrBase58: string, network?: Network, securityLevel?: MLDSASecurityLevel, chainCode?: Buffer);
17
21
  get address(): Address;
18
22
  get tweakedPubKeyKey(): Buffer;
19
23
  get keypair(): ECPairInterface;
24
+ get mldsaKeypair(): QuantumBIP32Interface;
25
+ get securityLevel(): MLDSASecurityLevel;
26
+ get chainCode(): Buffer;
20
27
  get p2wpkh(): string;
21
28
  get p2tr(): string;
22
29
  get p2wda(): IP2WSHAddress;
@@ -24,7 +31,17 @@ export declare class Wallet {
24
31
  get addresses(): string[];
25
32
  get segwitLegacy(): string;
26
33
  get publicKey(): Buffer;
34
+ get quantumPublicKey(): Buffer;
35
+ get quantumPrivateKey(): Buffer;
36
+ get quantumPublicKeyHex(): string;
37
+ get quantumPrivateKeyHex(): string;
27
38
  get xOnly(): Buffer;
28
- static fromWif(wif: string, network?: Network): Wallet;
29
- static new(network?: Network): Wallet;
39
+ static fromWif(wif: string, quantumPrivateKeyHex: string, network?: Network, securityLevel?: MLDSASecurityLevel, chainCode?: Buffer): Wallet;
40
+ static generate(network?: Network, securityLevel?: MLDSASecurityLevel): Wallet;
41
+ static fromPrivateKeys(privateKeyHexOrWif: string, mldsaPrivateKeyOrBase58: string, network?: Network, securityLevel?: MLDSASecurityLevel, chainCode?: Buffer): Wallet;
42
+ toWIF(): string;
43
+ toPrivateKeyHex(): string;
44
+ toPublicKeyHex(): string;
45
+ toQuantumBase58(): string;
46
+ derivePath(path: string): Wallet;
30
47
  }
@@ -1,10 +1,15 @@
1
1
  import { EcKeyPair } from './EcKeyPair.js';
2
- import { networks, toXOnly } from '@btc-vision/bitcoin';
2
+ import { initEccLib, networks, toXOnly } from '@btc-vision/bitcoin';
3
3
  import { Address } from './Address.js';
4
4
  import { BitcoinUtils } from '../utils/BitcoinUtils.js';
5
+ import * as ecc from '@bitcoinerlab/secp256k1';
6
+ import { getMLDSAConfig, MLDSASecurityLevel, QuantumBIP32Factory, } from '@btc-vision/bip32';
7
+ import { randomBytes } from 'crypto';
8
+ initEccLib(ecc);
5
9
  export class Wallet {
6
- constructor(privateKeyOrWif, network = networks.bitcoin) {
10
+ constructor(privateKeyOrWif, mldsaPrivateKeyOrBase58, network = networks.bitcoin, securityLevel = MLDSASecurityLevel.LEVEL2, chainCode) {
7
11
  this.network = network;
12
+ this._securityLevel = securityLevel;
8
13
  const parsedPrivateKey = privateKeyOrWif.startsWith('0x')
9
14
  ? privateKeyOrWif.replace('0x', '')
10
15
  : privateKeyOrWif;
@@ -14,14 +19,44 @@ export class Wallet {
14
19
  else {
15
20
  this._keypair = EcKeyPair.fromWIF(parsedPrivateKey, this.network);
16
21
  }
22
+ const parsedMLDSAKey = mldsaPrivateKeyOrBase58.startsWith('0x')
23
+ ? mldsaPrivateKeyOrBase58.replace('0x', '')
24
+ : mldsaPrivateKeyOrBase58;
25
+ if (BitcoinUtils.isValidHex(parsedMLDSAKey)) {
26
+ const mldsaBuffer = Buffer.from(parsedMLDSAKey, 'hex');
27
+ const config = getMLDSAConfig(securityLevel, this.network);
28
+ const privateKeySize = config.privateKeySize;
29
+ const publicKeySize = config.publicKeySize;
30
+ const combinedSize = privateKeySize + publicKeySize;
31
+ let mldsaPrivateKeyBuffer;
32
+ if (mldsaBuffer.length === privateKeySize) {
33
+ mldsaPrivateKeyBuffer = mldsaBuffer;
34
+ }
35
+ else if (mldsaBuffer.length === combinedSize) {
36
+ mldsaPrivateKeyBuffer = mldsaBuffer.subarray(0, privateKeySize);
37
+ }
38
+ else {
39
+ throw new Error(`Invalid ML-DSA key length for security level ${securityLevel}. Expected ${privateKeySize} bytes (private only) or ${combinedSize} bytes (private+public), got ${mldsaBuffer.length} bytes.`);
40
+ }
41
+ if (chainCode && chainCode.length !== 32) {
42
+ throw new Error('Chain code must be 32 bytes');
43
+ }
44
+ this._chainCode = chainCode || randomBytes(32);
45
+ this._mldsaKeypair = QuantumBIP32Factory.fromPrivateKey(mldsaPrivateKeyBuffer, this._chainCode, this.network, securityLevel);
46
+ }
47
+ else {
48
+ this._mldsaKeypair = QuantumBIP32Factory.fromBase58(parsedMLDSAKey);
49
+ this._chainCode = Buffer.from(this._mldsaKeypair.chainCode);
50
+ this._securityLevel = this._mldsaKeypair.securityLevel;
51
+ }
17
52
  this._bufferPubKey = this._keypair.publicKey;
18
- this._address = new Address(this._keypair.publicKey);
53
+ this._address = new Address(this._mldsaKeypair.publicKey, this._keypair.publicKey);
19
54
  this._p2tr = this._address.p2tr(this.network);
20
55
  this._p2wpkh = this._address.p2wpkh(this.network);
21
56
  this._legacy = this._address.p2pkh(this.network);
22
- this._segwitLegacy = this._address.p2wpkh(this.network);
57
+ this._segwitLegacy = this._address.p2shp2wpkh(this.network);
23
58
  this._p2wda = this._address.p2wda(this.network);
24
- this._tweakedKey = this._address.toBuffer();
59
+ this._tweakedKey = this._address.tweakedPublicKeyToBuffer();
25
60
  }
26
61
  get address() {
27
62
  return this._address;
@@ -34,6 +69,15 @@ export class Wallet {
34
69
  throw new Error('Keypair not set');
35
70
  return this._keypair;
36
71
  }
72
+ get mldsaKeypair() {
73
+ return this._mldsaKeypair;
74
+ }
75
+ get securityLevel() {
76
+ return this._securityLevel;
77
+ }
78
+ get chainCode() {
79
+ return this._chainCode;
80
+ }
37
81
  get p2wpkh() {
38
82
  return this._p2wpkh;
39
83
  }
@@ -57,15 +101,70 @@ export class Wallet {
57
101
  throw new Error('Public key not set');
58
102
  return this._bufferPubKey;
59
103
  }
104
+ get quantumPublicKey() {
105
+ return Buffer.from(this._mldsaKeypair.publicKey);
106
+ }
107
+ get quantumPrivateKey() {
108
+ if (!this._mldsaKeypair.privateKey) {
109
+ throw new Error('Quantum private key not set');
110
+ }
111
+ return Buffer.from(this._mldsaKeypair.privateKey);
112
+ }
113
+ get quantumPublicKeyHex() {
114
+ return Buffer.from(this._mldsaKeypair.publicKey).toString('hex');
115
+ }
116
+ get quantumPrivateKeyHex() {
117
+ if (!this._mldsaKeypair.privateKey) {
118
+ throw new Error('Quantum private key not set');
119
+ }
120
+ return Buffer.from(this._mldsaKeypair.privateKey).toString('hex');
121
+ }
60
122
  get xOnly() {
61
123
  if (!this.keypair)
62
124
  throw new Error('Keypair not set');
63
125
  return toXOnly(this._bufferPubKey);
64
126
  }
65
- static fromWif(wif, network = networks.bitcoin) {
66
- return new Wallet(wif, network);
127
+ static fromWif(wif, quantumPrivateKeyHex, network = networks.bitcoin, securityLevel = MLDSASecurityLevel.LEVEL2, chainCode) {
128
+ return new Wallet(wif, quantumPrivateKeyHex, network, securityLevel, chainCode);
67
129
  }
68
- static new(network = networks.bitcoin) {
69
- return new Wallet(EcKeyPair.generateWallet(network).privateKey, network);
130
+ static generate(network = networks.bitcoin, securityLevel = MLDSASecurityLevel.LEVEL2) {
131
+ const walletData = EcKeyPair.generateWallet(network, securityLevel);
132
+ if (!walletData.quantumPrivateKey) {
133
+ throw new Error('Failed to generate quantum keys');
134
+ }
135
+ return new Wallet(walletData.privateKey, walletData.quantumPrivateKey, network, securityLevel);
136
+ }
137
+ static fromPrivateKeys(privateKeyHexOrWif, mldsaPrivateKeyOrBase58, network = networks.bitcoin, securityLevel = MLDSASecurityLevel.LEVEL2, chainCode) {
138
+ return new Wallet(privateKeyHexOrWif, mldsaPrivateKeyOrBase58, network, securityLevel, chainCode);
139
+ }
140
+ toWIF() {
141
+ return this._keypair.toWIF();
142
+ }
143
+ toPrivateKeyHex() {
144
+ if (!this._keypair.privateKey) {
145
+ throw new Error('Private key not available');
146
+ }
147
+ return this._keypair.privateKey.toString('hex');
148
+ }
149
+ toPublicKeyHex() {
150
+ return this._bufferPubKey.toString('hex');
151
+ }
152
+ toQuantumBase58() {
153
+ return this._mldsaKeypair.toBase58();
154
+ }
155
+ derivePath(path) {
156
+ const derivedQuantum = this._mldsaKeypair.derivePath(path);
157
+ if (!this._keypair.privateKey) {
158
+ throw new Error('Cannot derive from a watch-only wallet (no private key available)');
159
+ }
160
+ const bip32Root = EcKeyPair.BIP32.fromPrivateKey(this._keypair.privateKey, this._chainCode, this.network);
161
+ const derivedClassical = bip32Root.derivePath(path);
162
+ if (!derivedClassical.privateKey) {
163
+ throw new Error('Failed to derive classical private key');
164
+ }
165
+ if (!derivedClassical.chainCode) {
166
+ throw new Error('Failed to derive classical chain code');
167
+ }
168
+ return new Wallet(Buffer.from(derivedClassical.privateKey).toString('hex'), derivedQuantum.toBase58(), this.network, this._securityLevel, Buffer.from(derivedClassical.chainCode));
70
169
  }
71
170
  }
@@ -2,4 +2,6 @@ export interface IWallet {
2
2
  readonly address: string;
3
3
  readonly privateKey: string;
4
4
  readonly publicKey: string;
5
+ readonly quantumPrivateKey: string;
6
+ readonly quantumPublicKey: string;
5
7
  }