@btc-vision/transaction 1.6.19 → 1.7.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.
Files changed (155) 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/BIPStandard.d.ts +8 -0
  12. package/browser/src/mnemonic/Mnemonic.d.ts +34 -0
  13. package/browser/src/mnemonic/MnemonicStrength.d.ts +7 -0
  14. package/browser/{opnet.d.ts → src/opnet.d.ts} +5 -0
  15. package/browser/src/transaction/browser/types/OPWallet.d.ts +14 -0
  16. package/browser/test/address.test.d.ts +1 -0
  17. package/browser/test/addressverificator-mldsa.test.d.ts +1 -0
  18. package/browser/test/derivePath.test.d.ts +1 -0
  19. package/browser/test/messagesigner-mldsa.test.d.ts +1 -0
  20. package/browser/test/messagesigner-schnorr.test.d.ts +1 -0
  21. package/browser/test/network-awareness.test.d.ts +1 -0
  22. package/build/_version.d.ts +1 -1
  23. package/build/_version.js +1 -1
  24. package/build/crypto/crypto-browser.d.ts +11 -0
  25. package/build/crypto/crypto-browser.js +56 -0
  26. package/build/epoch/ChallengeSolution.js +3 -2
  27. package/build/epoch/interfaces/IChallengeSolution.d.ts +2 -0
  28. package/build/keypair/Address.d.ts +7 -4
  29. package/build/keypair/Address.js +88 -37
  30. package/build/keypair/AddressVerificator.d.ts +3 -0
  31. package/build/keypair/AddressVerificator.js +49 -1
  32. package/build/keypair/EcKeyPair.d.ts +3 -2
  33. package/build/keypair/EcKeyPair.js +17 -3
  34. package/build/keypair/MessageSigner.d.ts +9 -0
  35. package/build/keypair/MessageSigner.js +23 -0
  36. package/build/keypair/Wallet.d.ts +20 -3
  37. package/build/keypair/Wallet.js +108 -9
  38. package/build/keypair/interfaces/IWallet.d.ts +2 -0
  39. package/build/mnemonic/BIPStandard.d.ts +8 -0
  40. package/build/mnemonic/BIPStandard.js +24 -0
  41. package/build/mnemonic/Mnemonic.d.ts +34 -0
  42. package/build/mnemonic/Mnemonic.js +140 -0
  43. package/build/mnemonic/MnemonicStrength.d.ts +7 -0
  44. package/build/mnemonic/MnemonicStrength.js +8 -0
  45. package/build/opnet.d.ts +5 -0
  46. package/build/opnet.js +5 -0
  47. package/build/transaction/browser/types/OPWallet.d.ts +14 -0
  48. package/build/transaction/browser/types/OPWallet.js +6 -0
  49. package/documentation/README.md +32 -0
  50. package/documentation/quantum-support/01-introduction.md +88 -0
  51. package/documentation/quantum-support/02-mnemonic-and-wallet.md +445 -0
  52. package/documentation/quantum-support/03-address-generation.md +329 -0
  53. package/documentation/quantum-support/04-message-signing.md +623 -0
  54. package/documentation/quantum-support/05-address-verification.md +307 -0
  55. package/documentation/quantum-support/README.md +65 -0
  56. package/gulpfile.js +2 -2
  57. package/package.json +25 -17
  58. package/src/_version.ts +1 -1
  59. package/src/epoch/ChallengeSolution.ts +3 -2
  60. package/src/epoch/interfaces/IChallengeSolution.ts +2 -0
  61. package/src/keypair/Address.ts +145 -43
  62. package/src/keypair/AddressVerificator.ts +87 -2
  63. package/src/keypair/EcKeyPair.ts +58 -6
  64. package/src/keypair/MessageSigner.ts +58 -0
  65. package/src/keypair/Wallet.ts +339 -57
  66. package/src/keypair/interfaces/IWallet.ts +13 -3
  67. package/src/mnemonic/BIPStandard.ts +92 -0
  68. package/src/mnemonic/Mnemonic.ts +465 -0
  69. package/src/mnemonic/MnemonicStrength.ts +12 -0
  70. package/src/network/ChainId.ts +1 -4
  71. package/src/opnet.ts +17 -0
  72. package/src/transaction/browser/types/OPWallet.ts +73 -0
  73. package/test/address.test.ts +1068 -0
  74. package/test/addressverificator-mldsa.test.ts +473 -0
  75. package/test/derivePath.test.ts +513 -0
  76. package/test/messagesigner-mldsa.test.ts +1060 -0
  77. package/test/messagesigner-schnorr.test.ts +1011 -0
  78. package/test/network-awareness.test.ts +163 -0
  79. package/tsconfig.json +1 -1
  80. package/vitest.config.ts +21 -0
  81. package/browser/_version.d.ts +0 -1
  82. package/browser/keypair/Wallet.d.ts +0 -30
  83. package/doc/README.md +0 -0
  84. /package/browser/{abi → src/abi}/ABICoder.d.ts +0 -0
  85. /package/browser/{buffer → src/buffer}/BinaryReader.d.ts +0 -0
  86. /package/browser/{buffer → src/buffer}/BinaryWriter.d.ts +0 -0
  87. /package/browser/{bytecode → src/bytecode}/Compressor.d.ts +0 -0
  88. /package/browser/{consensus → src/consensus}/Consensus.d.ts +0 -0
  89. /package/browser/{consensus → src/consensus}/ConsensusConfig.d.ts +0 -0
  90. /package/browser/{consensus → src/consensus}/metadata/RoswellConsensus.d.ts +0 -0
  91. /package/browser/{crypto → src/crypto}/crypto-browser.d.ts +0 -0
  92. /package/browser/{crypto → src/crypto}/crypto.d.ts +0 -0
  93. /package/browser/{deterministic → src/deterministic}/AddressMap.d.ts +0 -0
  94. /package/browser/{deterministic → src/deterministic}/AddressSet.d.ts +0 -0
  95. /package/browser/{deterministic → src/deterministic}/DeterministicMap.d.ts +0 -0
  96. /package/browser/{deterministic → src/deterministic}/DeterministicSet.d.ts +0 -0
  97. /package/browser/{deterministic → src/deterministic}/Map.d.ts +0 -0
  98. /package/browser/{epoch → src/epoch}/ChallengeSolution.d.ts +0 -0
  99. /package/browser/{epoch → src/epoch}/validator/EpochValidator.d.ts +0 -0
  100. /package/browser/{event → src/event}/NetEvent.d.ts +0 -0
  101. /package/browser/{generators → src/generators}/AddressGenerator.d.ts +0 -0
  102. /package/browser/{generators → src/generators}/Features.d.ts +0 -0
  103. /package/browser/{generators → src/generators}/Generator.d.ts +0 -0
  104. /package/browser/{generators → src/generators}/builders/CalldataGenerator.d.ts +0 -0
  105. /package/browser/{generators → src/generators}/builders/CustomGenerator.d.ts +0 -0
  106. /package/browser/{generators → src/generators}/builders/DeploymentGenerator.d.ts +0 -0
  107. /package/browser/{generators → src/generators}/builders/LegacyCalldataGenerator.d.ts +0 -0
  108. /package/browser/{generators → src/generators}/builders/MultiSignGenerator.d.ts +0 -0
  109. /package/browser/{generators → src/generators}/builders/P2WDAGenerator.d.ts +0 -0
  110. /package/browser/{index.d.ts → src/index.d.ts} +0 -0
  111. /package/browser/{keypair → src/keypair}/Secp256k1PointDeriver.d.ts +0 -0
  112. /package/browser/{metadata → src/metadata}/ContractBaseMetadata.d.ts +0 -0
  113. /package/browser/{metadata → src/metadata}/tokens.d.ts +0 -0
  114. /package/browser/{network → src/network}/ChainId.d.ts +0 -0
  115. /package/browser/{p2wda → src/p2wda}/P2WDADetector.d.ts +0 -0
  116. /package/browser/{signer → src/signer}/SignerUtils.d.ts +0 -0
  117. /package/browser/{signer → src/signer}/TweakedSigner.d.ts +0 -0
  118. /package/browser/{transaction → src/transaction}/ContractAddress.d.ts +0 -0
  119. /package/browser/{transaction → src/transaction}/TransactionFactory.d.ts +0 -0
  120. /package/browser/{transaction → src/transaction}/browser/BrowserSignerBase.d.ts +0 -0
  121. /package/browser/{transaction → src/transaction}/browser/Web3Provider.d.ts +0 -0
  122. /package/browser/{transaction → src/transaction}/browser/extensions/UnisatSigner.d.ts +0 -0
  123. /package/browser/{transaction → src/transaction}/browser/extensions/XverseSigner.d.ts +0 -0
  124. /package/browser/{transaction → src/transaction}/browser/types/Unisat.d.ts +0 -0
  125. /package/browser/{transaction → src/transaction}/browser/types/Xverse.d.ts +0 -0
  126. /package/browser/{transaction → src/transaction}/builders/CancelTransaction.d.ts +0 -0
  127. /package/browser/{transaction → src/transaction}/builders/ChallengeSolutionTransaction.d.ts +0 -0
  128. /package/browser/{transaction → src/transaction}/builders/CustomScriptTransaction.d.ts +0 -0
  129. /package/browser/{transaction → src/transaction}/builders/DeploymentTransaction.d.ts +0 -0
  130. /package/browser/{transaction → src/transaction}/builders/FundingTransaction.d.ts +0 -0
  131. /package/browser/{transaction → src/transaction}/builders/InteractionTransaction.d.ts +0 -0
  132. /package/browser/{transaction → src/transaction}/builders/InteractionTransactionP2WDA.d.ts +0 -0
  133. /package/browser/{transaction → src/transaction}/builders/MultiSignTransaction.d.ts +0 -0
  134. /package/browser/{transaction → src/transaction}/builders/SharedInteractionTransaction.d.ts +0 -0
  135. /package/browser/{transaction → src/transaction}/builders/TransactionBuilder.d.ts +0 -0
  136. /package/browser/{transaction → src/transaction}/enums/TransactionType.d.ts +0 -0
  137. /package/browser/{transaction → src/transaction}/interfaces/ITransactionParameters.d.ts +0 -0
  138. /package/browser/{transaction → src/transaction}/interfaces/Tap.d.ts +0 -0
  139. /package/browser/{transaction → src/transaction}/mineable/IP2WSHAddress.d.ts +0 -0
  140. /package/browser/{transaction → src/transaction}/mineable/TimelockGenerator.d.ts +0 -0
  141. /package/browser/{transaction → src/transaction}/processor/PsbtTransaction.d.ts +0 -0
  142. /package/browser/{transaction → src/transaction}/psbt/PSBTTypes.d.ts +0 -0
  143. /package/browser/{transaction → src/transaction}/shared/P2TR_MS.d.ts +0 -0
  144. /package/browser/{transaction → src/transaction}/shared/TweakedTransaction.d.ts +0 -0
  145. /package/browser/{utils → src/utils}/BitcoinUtils.d.ts +0 -0
  146. /package/browser/{utils → src/utils}/BufferHelper.d.ts +0 -0
  147. /package/browser/{utils → src/utils}/StringToBuffer.d.ts +0 -0
  148. /package/browser/{utils → src/utils}/lengths.d.ts +0 -0
  149. /package/browser/{utils → src/utils}/types.d.ts +0 -0
  150. /package/browser/{utxo → src/utxo}/OPNetLimitedProvider.d.ts +0 -0
  151. /package/browser/{utxo → src/utxo}/interfaces/BroadcastResponse.d.ts +0 -0
  152. /package/browser/{utxo → src/utxo}/interfaces/IUTXO.d.ts +0 -0
  153. /package/browser/{verification → src/verification}/TapscriptVerificator.d.ts +0 -0
  154. /package/{doc → documentation}/addresses/P2OP.md +0 -0
  155. /package/{doc → documentation}/addresses/P2WDA.md +0 -0
@@ -0,0 +1,465 @@
1
+ import * as bip39 from 'bip39';
2
+ import {
3
+ BIP32Factory,
4
+ BIP32Interface,
5
+ MLDSASecurityLevel,
6
+ QuantumBIP32Factory,
7
+ QuantumBIP32Interface,
8
+ } from '@btc-vision/bip32';
9
+ import * as ecc from '@bitcoinerlab/secp256k1';
10
+ import { initEccLib, Network, networks } from '@btc-vision/bitcoin';
11
+ import { Wallet } from '../keypair/Wallet.js';
12
+ import { MnemonicStrength } from './MnemonicStrength.js';
13
+ import { BIPStandard, buildBIPPath } from './BIPStandard.js';
14
+ import { AddressTypes } from '../keypair/AddressVerificator.js';
15
+
16
+ initEccLib(ecc);
17
+
18
+ const bip32 = BIP32Factory(ecc);
19
+
20
+ export { BIPStandard, getBIPDescription } from './BIPStandard.js';
21
+
22
+ /**
23
+ * Mnemonic class for managing BIP39 mnemonic phrases with BIP360 quantum support
24
+ *
25
+ * This class provides methods to generate, validate, and derive wallets from mnemonic phrases.
26
+ * It supports both classical Bitcoin derivation paths (BIP44, BIP84, etc.) and quantum-resistant
27
+ * ML-DSA keys via BIP360.
28
+ *
29
+ * @example
30
+ * ```typescript
31
+ * // Generate a new mnemonic
32
+ * const mnemonic = Mnemonic.generate();
33
+ *
34
+ * // Derive a wallet at index 0
35
+ * const wallet = mnemonic.derive(0);
36
+ *
37
+ * // Derive multiple wallets
38
+ * const wallets = mnemonic.deriveMultiple(5);
39
+ *
40
+ * // Load from existing mnemonic
41
+ * const existingMnemonic = new Mnemonic('your twelve word mnemonic phrase here...');
42
+ * ```
43
+ */
44
+ export class Mnemonic {
45
+ /**
46
+ * The BIP39 mnemonic phrase
47
+ */
48
+ private readonly _phrase: string;
49
+
50
+ /**
51
+ * Optional BIP39 passphrase for additional security
52
+ */
53
+ private readonly _passphrase: string;
54
+
55
+ /**
56
+ * The network to use for derivation
57
+ */
58
+ private readonly _network: Network;
59
+
60
+ /**
61
+ * The ML-DSA security level for quantum keys
62
+ */
63
+ private readonly _securityLevel: MLDSASecurityLevel;
64
+
65
+ /**
66
+ * The seed derived from the mnemonic
67
+ */
68
+ private readonly _seed: Buffer;
69
+
70
+ /**
71
+ * The classical BIP32 root for Bitcoin keys
72
+ */
73
+ private readonly _classicalRoot: BIP32Interface;
74
+
75
+ /**
76
+ * The quantum BIP32 root for ML-DSA keys
77
+ */
78
+ private readonly _quantumRoot: QuantumBIP32Interface;
79
+
80
+ /**
81
+ * Create a new Mnemonic instance from an existing phrase
82
+ *
83
+ * @param phrase - The BIP39 mnemonic phrase (12, 15, 18, 21, or 24 words)
84
+ * @param passphrase - Optional BIP39 passphrase for additional security (default: '')
85
+ * @param network - The Bitcoin network to use (default: bitcoin mainnet)
86
+ * @param securityLevel - The ML-DSA security level for quantum keys (default: LEVEL2/44)
87
+ * @throws {Error} If the mnemonic phrase is invalid
88
+ */
89
+ constructor(
90
+ phrase: string,
91
+ passphrase: string = '',
92
+ network: Network = networks.bitcoin,
93
+ securityLevel: MLDSASecurityLevel = MLDSASecurityLevel.LEVEL2,
94
+ ) {
95
+ if (!bip39.validateMnemonic(phrase)) {
96
+ throw new Error('Invalid mnemonic phrase');
97
+ }
98
+
99
+ this._phrase = phrase;
100
+ this._passphrase = passphrase;
101
+ this._network = network;
102
+ this._securityLevel = securityLevel;
103
+
104
+ // Derive the seed from the mnemonic
105
+ this._seed = bip39.mnemonicToSeedSync(this._phrase, this._passphrase);
106
+
107
+ // Create the classical BIP32 root
108
+ this._classicalRoot = bip32.fromSeed(this._seed, this._network);
109
+
110
+ // Create the quantum BIP32 root with network parameter
111
+ this._quantumRoot = QuantumBIP32Factory.fromSeed(
112
+ this._seed,
113
+ this._network,
114
+ this._securityLevel,
115
+ );
116
+ }
117
+
118
+ /**
119
+ * Get the mnemonic phrase
120
+ *
121
+ * @warning This phrase is highly sensitive and can be used to derive all keys in the wallet.
122
+ * Handle with extreme care, never log or transmit insecurely, and store only in secure environments.
123
+ *
124
+ * @returns The BIP39 mnemonic phrase
125
+ */
126
+ public get phrase(): string {
127
+ return this._phrase;
128
+ }
129
+
130
+ /**
131
+ * Get the network
132
+ */
133
+ public get network(): Network {
134
+ return this._network;
135
+ }
136
+
137
+ /**
138
+ * Get the ML-DSA security level
139
+ */
140
+ public get securityLevel(): MLDSASecurityLevel {
141
+ return this._securityLevel;
142
+ }
143
+
144
+ /**
145
+ * Get the seed derived from the mnemonic phrase
146
+ *
147
+ * @warning This seed is highly sensitive and can be used to derive all keys in the wallet.
148
+ * Handle with extreme care, never log or transmit insecurely, and store only in secure environments.
149
+ *
150
+ * @returns A copy of the seed buffer to prevent external modification
151
+ */
152
+ public get seed(): Buffer {
153
+ return Buffer.from(this._seed);
154
+ }
155
+
156
+ /**
157
+ * Generate a new mnemonic phrase
158
+ *
159
+ * @param strength - The entropy strength in bits (default: 256 for 24 words)
160
+ * @returns A new random mnemonic phrase
161
+ */
162
+ public static generatePhrase(strength: MnemonicStrength = MnemonicStrength.MAXIMUM): string {
163
+ return bip39.generateMnemonic(strength);
164
+ }
165
+
166
+ /**
167
+ * Generate a new Mnemonic instance with a random phrase
168
+ *
169
+ * @param strength - The entropy strength in bits (default: 256 for 24 words)
170
+ * @param passphrase - Optional BIP39 passphrase for additional security (default: '')
171
+ * @param network - The Bitcoin network to use (default: bitcoin mainnet)
172
+ * @param securityLevel - The ML-DSA security level for quantum keys (default: LEVEL2/44)
173
+ * @returns A new Mnemonic instance
174
+ */
175
+ public static generate(
176
+ strength: MnemonicStrength = MnemonicStrength.MAXIMUM,
177
+ passphrase: string = '',
178
+ network: Network = networks.bitcoin,
179
+ securityLevel: MLDSASecurityLevel = MLDSASecurityLevel.LEVEL2,
180
+ ): Mnemonic {
181
+ const phrase = bip39.generateMnemonic(strength);
182
+ return new Mnemonic(phrase, passphrase, network, securityLevel);
183
+ }
184
+
185
+ /**
186
+ * Validate a mnemonic phrase
187
+ *
188
+ * @param phrase - The mnemonic phrase to validate
189
+ * @returns True if the phrase is valid, false otherwise
190
+ */
191
+ public static validate(phrase: string): boolean {
192
+ return bip39.validateMnemonic(phrase);
193
+ }
194
+
195
+ /**
196
+ * Derive a wallet at a specific index using BIP360 (quantum) and configurable BIP standard (classical) paths
197
+ *
198
+ * This method derives both classical ECDSA/Schnorr keys and quantum-resistant ML-DSA keys
199
+ * for the wallet, providing hybrid post-quantum security.
200
+ *
201
+ * @param index - The address index to derive (default: 0)
202
+ * @param account - The account index (default: 0)
203
+ * @param isChange - Whether this is a change address (default: false)
204
+ * @param bipStandard - The BIP standard to use for classical derivation (default: BIP84)
205
+ * @returns A Wallet instance with both classical and quantum keys
206
+ *
207
+ * @example
208
+ * ```typescript
209
+ * // Default: BIP84 (Native SegWit)
210
+ * const wallet1 = mnemonic.derive(0);
211
+ *
212
+ * // BIP44 (Compatible with Unisat)
213
+ * const wallet2 = mnemonic.derive(0, 0, false, BIPStandard.BIP44);
214
+ *
215
+ * // BIP86 (Taproot)
216
+ * const wallet3 = mnemonic.derive(0, 0, false, BIPStandard.BIP86);
217
+ * ```
218
+ */
219
+ public derive(
220
+ index: number = 0,
221
+ account: number = 0,
222
+ isChange: boolean = false,
223
+ bipStandard: BIPStandard = BIPStandard.BIP84,
224
+ ): Wallet {
225
+ // Derive classical key using specified BIP standard
226
+ const classicalPath = this.buildClassicalPath(account, index, isChange, bipStandard);
227
+ const classicalChild = this._classicalRoot.derivePath(classicalPath);
228
+
229
+ if (!classicalChild.privateKey) {
230
+ throw new Error(`Failed to derive classical private key at index ${index}`);
231
+ }
232
+
233
+ // Derive quantum key using BIP360
234
+ const quantumPath = this.buildQuantumPath(account, index, isChange);
235
+ const quantumChild = this._quantumRoot.derivePath(quantumPath);
236
+
237
+ if (!quantumChild.privateKey) {
238
+ throw new Error(`Failed to derive quantum private key at index ${index}`);
239
+ }
240
+
241
+ // Create a wallet with both keys
242
+ return new Wallet(
243
+ Buffer.from(classicalChild.privateKey).toString('hex'),
244
+ Buffer.from(quantumChild.privateKey).toString('hex'),
245
+ this._network,
246
+ this._securityLevel,
247
+ );
248
+ }
249
+
250
+ /**
251
+ * Derive a Unisat-compatible wallet
252
+ *
253
+ * Unisat uses different derivation paths based on address type:
254
+ * - Legacy (P2PKH): m/44'/coinType'/account'/change/index
255
+ * - Nested SegWit (P2SH-P2WPKH): m/49'/coinType'/account'/change/index
256
+ * - Native SegWit (P2WPKH): m/84'/coinType'/account'/change/index
257
+ * - Taproot (P2TR): m/86'/coinType'/account'/change/index
258
+ *
259
+ * @param addressType - The address type to generate
260
+ * @param index - The address index (default: 0)
261
+ * @param account - The account index (default: 0)
262
+ * @param isChange - Whether this is a change address (default: false)
263
+ * @returns A Wallet instance with both classical and quantum keys
264
+ */
265
+ public deriveUnisat(
266
+ addressType: AddressTypes = AddressTypes.P2TR,
267
+ index: number = 0,
268
+ account: number = 0,
269
+ isChange: boolean = false,
270
+ ): Wallet {
271
+ // Determine BIP purpose based on address type
272
+ let purpose: number;
273
+ switch (addressType) {
274
+ case AddressTypes.P2PKH:
275
+ purpose = 44;
276
+ break;
277
+ case AddressTypes.P2SH_OR_P2SH_P2WPKH:
278
+ purpose = 49;
279
+ break;
280
+ case AddressTypes.P2WPKH:
281
+ purpose = 84;
282
+ break;
283
+ case AddressTypes.P2TR:
284
+ purpose = 86;
285
+ break;
286
+ default:
287
+ throw new Error(`Unsupported address type: ${addressType}`);
288
+ }
289
+
290
+ // Build classical derivation path for Unisat
291
+ const coinType = this.getCoinType();
292
+ const change = isChange ? 1 : 0;
293
+ const classicalPath = `m/${purpose}'/0'/${account}'/${change}/${index}`;
294
+
295
+ // Derive classical key
296
+ const classicalChild = this._classicalRoot.derivePath(classicalPath);
297
+
298
+ if (!classicalChild.privateKey) {
299
+ throw new Error(`Failed to derive classical private key at path ${classicalPath}`);
300
+ }
301
+
302
+ // Derive quantum key using BIP360
303
+ const quantumPath = `m/360'/${coinType}'/${account}'/${change}/${index}`;
304
+ const quantumChild = this._quantumRoot.derivePath(quantumPath);
305
+
306
+ if (!quantumChild.privateKey) {
307
+ throw new Error(`Failed to derive quantum private key at path ${quantumPath}`);
308
+ }
309
+
310
+ // Create wallet with both classical and quantum keys
311
+ return new Wallet(
312
+ Buffer.from(classicalChild.privateKey).toString('hex'),
313
+ Buffer.from(quantumChild.privateKey).toString('hex'),
314
+ this._network,
315
+ this._securityLevel,
316
+ );
317
+ }
318
+
319
+ /**
320
+ * Derive multiple Unisat-compatible wallets
321
+ *
322
+ * @param addressType - The address type to generate
323
+ * @param count - Number of wallets to derive
324
+ * @param startIndex - Starting index (default: 0)
325
+ * @param account - The account index (default: 0)
326
+ * @param isChange - Whether these are change addresses (default: false)
327
+ * @returns Array of Wallet instances
328
+ */
329
+ public deriveMultipleUnisat(
330
+ addressType: AddressTypes = AddressTypes.P2TR,
331
+ count: number = 5,
332
+ startIndex: number = 0,
333
+ account: number = 0,
334
+ isChange: boolean = false,
335
+ ): Wallet[] {
336
+ const wallets: Wallet[] = [];
337
+
338
+ for (let i = 0; i < count; i++) {
339
+ wallets.push(this.deriveUnisat(addressType, startIndex + i, account, isChange));
340
+ }
341
+
342
+ return wallets;
343
+ }
344
+
345
+ /**
346
+ * Derive multiple wallets with sequential indices
347
+ *
348
+ * @param count - The number of wallets to derive
349
+ * @param startIndex - The starting address index (default: 0)
350
+ * @param account - The account index (default: 0)
351
+ * @param isChange - Whether these are change addresses (default: false)
352
+ * @param bipStandard - The BIP standard to use for classical derivation (default: BIP84)
353
+ * @returns An array of Wallet instances
354
+ */
355
+ public deriveMultiple(
356
+ count: number,
357
+ startIndex: number = 0,
358
+ account: number = 0,
359
+ isChange: boolean = false,
360
+ bipStandard: BIPStandard = BIPStandard.BIP84,
361
+ ): Wallet[] {
362
+ const wallets: Wallet[] = [];
363
+
364
+ for (let i = 0; i < count; i++) {
365
+ wallets.push(this.derive(startIndex + i, account, isChange, bipStandard));
366
+ }
367
+
368
+ return wallets;
369
+ }
370
+
371
+ /**
372
+ * Derive a wallet using a custom derivation path
373
+ *
374
+ * @param classicalPath - The BIP32 path for classical keys (e.g., "m/84'/0'/0'/0/0")
375
+ * @param quantumPath - The BIP360 path for quantum keys (e.g., "m/360'/0'/0'/0/0")
376
+ * @returns A Wallet instance
377
+ */
378
+ public deriveCustomPath(classicalPath: string, quantumPath: string): Wallet {
379
+ const classicalChild = this._classicalRoot.derivePath(classicalPath);
380
+ const quantumChild = this._quantumRoot.derivePath(quantumPath);
381
+
382
+ if (!classicalChild.privateKey) {
383
+ throw new Error(`Failed to derive classical private key at path ${classicalPath}`);
384
+ }
385
+
386
+ if (!quantumChild.privateKey) {
387
+ throw new Error(`Failed to derive quantum private key at path ${quantumPath}`);
388
+ }
389
+
390
+ // Create wallet with both classical and ML-DSA private keys
391
+ return new Wallet(
392
+ Buffer.from(classicalChild.privateKey).toString('hex'),
393
+ Buffer.from(quantumChild.privateKey).toString('hex'),
394
+ this._network,
395
+ this._securityLevel,
396
+ );
397
+ }
398
+
399
+ /**
400
+ * Get the classical BIP32 root
401
+ *
402
+ * @returns The classical BIP32Interface for manual derivation
403
+ */
404
+ public getClassicalRoot(): BIP32Interface {
405
+ return this._classicalRoot;
406
+ }
407
+
408
+ /**
409
+ * Get the quantum BIP32 root
410
+ *
411
+ * @returns The quantum BIP32Interface for manual derivation
412
+ */
413
+ public getQuantumRoot(): QuantumBIP32Interface {
414
+ return this._quantumRoot;
415
+ }
416
+
417
+ /**
418
+ * Build a classical derivation path using specified BIP standard
419
+ *
420
+ * @param account - The account index
421
+ * @param index - The address index
422
+ * @param isChange - Whether this is a change address
423
+ * @param bipStandard - The BIP standard to use (default: BIP84)
424
+ * @returns The derivation path string
425
+ */
426
+ private buildClassicalPath(
427
+ account: number,
428
+ index: number,
429
+ isChange: boolean,
430
+ bipStandard: BIPStandard = BIPStandard.BIP84,
431
+ ): string {
432
+ const coinType = this.getCoinType();
433
+ const change = isChange ? 1 : 0;
434
+ return buildBIPPath(bipStandard, coinType, account, change, index);
435
+ }
436
+
437
+ /**
438
+ * Build a quantum derivation path (BIP360)
439
+ *
440
+ * @param account - The account index
441
+ * @param index - The address index
442
+ * @param isChange - Whether this is a change address
443
+ * @returns The derivation path string
444
+ */
445
+ private buildQuantumPath(account: number, index: number, isChange: boolean): string {
446
+ const coinType = this.getCoinType();
447
+ const change = isChange ? 1 : 0;
448
+ return `m/360'/${coinType}'/${account}'/${change}/${index}`;
449
+ }
450
+
451
+ /**
452
+ * Get the coin type based on the network
453
+ *
454
+ * @returns The coin type (0 for mainnet, 1 for testnet/regtest)
455
+ */
456
+ private getCoinType(): number {
457
+ if (
458
+ this._network.bech32 === networks.testnet.bech32 ||
459
+ this._network.bech32 === networks.regtest.bech32
460
+ ) {
461
+ return 1;
462
+ }
463
+ return 0;
464
+ }
465
+ }
@@ -0,0 +1,12 @@
1
+ export enum MnemonicStrength {
2
+ /** 128 bits of entropy - 12 words */
3
+ MINIMUM = 128,
4
+ /** 160 bits of entropy - 15 words */
5
+ LOW = 160,
6
+ /** 192 bits of entropy - 18 words */
7
+ MEDIUM = 192,
8
+ /** 224 bits of entropy - 21 words */
9
+ HIGH = 224,
10
+ /** 256 bits of entropy - 24 words */
11
+ MAXIMUM = 256,
12
+ }
@@ -1,7 +1,4 @@
1
-
2
-
3
-
4
1
  export enum ChainId {
5
2
  Bitcoin = 0,
6
3
  Fractal = 1,
7
- }
4
+ }
package/src/opnet.ts CHANGED
@@ -30,6 +30,22 @@ export * from './keypair/interfaces/IWallet.js';
30
30
  export * from './keypair/MessageSigner.js';
31
31
  export * from './keypair/Wallet.js';
32
32
 
33
+ /** Mnemonic */
34
+ export * from './mnemonic/Mnemonic.js';
35
+ export * from './mnemonic/MnemonicStrength.js';
36
+ export * from './mnemonic/BIPStandard.js';
37
+
38
+ /** Quantum (ML-DSA) */
39
+ export {
40
+ MLDSASecurityLevel,
41
+ MLDSAKeyPair,
42
+ QuantumBIP32Interface,
43
+ QuantumBIP32API,
44
+ QuantumSigner,
45
+ QuantumBIP32Factory,
46
+ QuantumDerivationPath,
47
+ } from '@btc-vision/bip32';
48
+
33
49
  /** Metadata */
34
50
  export * from './metadata/ContractBaseMetadata.js';
35
51
  export * from './network/ChainId.js';
@@ -101,6 +117,7 @@ export * from './transaction/browser/extensions/UnisatSigner.js';
101
117
  export * from './transaction/browser/extensions/XverseSigner.js';
102
118
  export * from './transaction/browser/types/Unisat.js';
103
119
  export * from './transaction/browser/types/Xverse.js';
120
+ export * from './transaction/browser/types/OPWallet.js';
104
121
 
105
122
  export * from './metadata/tokens.js';
106
123
  export * from './transaction/browser/Web3Provider.js';
@@ -0,0 +1,73 @@
1
+ import { Unisat } from './Unisat.js';
2
+ import { MLDSASecurityLevel } from '@btc-vision/bip32';
3
+
4
+ /**
5
+ * ML-DSA signature result
6
+ */
7
+ export interface MLDSASignature {
8
+ /**
9
+ * The ML-DSA signature in hex format
10
+ */
11
+ readonly signature: string;
12
+
13
+ /**
14
+ * The ML-DSA public key used for signing in hex format
15
+ */
16
+ readonly publicKey: string;
17
+
18
+ /**
19
+ * The security level used (44, 65, or 87)
20
+ */
21
+ readonly securityLevel: MLDSASecurityLevel;
22
+
23
+ /**
24
+ * The message hash that was signed
25
+ */
26
+ readonly messageHash: string;
27
+ }
28
+
29
+ /**
30
+ * OPWallet interface extending Unisat with ML-DSA (FIPS 204) support
31
+ *
32
+ * SECURITY NOTE: All methods only expose public keys and signatures.
33
+ * Private keys are NEVER exposed through this interface.
34
+ */
35
+ export interface OPWallet extends Unisat {
36
+ /**
37
+ * Get the ML-DSA public key for the current account
38
+ *
39
+ * @returns The ML-DSA public key in hex format (never exposes private keys)
40
+ * @throws {Error} If the wallet is not connected
41
+ */
42
+ getMLDSAPublicKey(): Promise<string>;
43
+
44
+ /**
45
+ * Sign a message using ML-DSA signature
46
+ *
47
+ * @param message - The message to sign
48
+ * @returns The ML-DSA signature
49
+ * @throws {Error} If signing fails or wallet is not connected
50
+ */
51
+ signMLDSAMessage(message: string): Promise<MLDSASignature>;
52
+
53
+ /**
54
+ * Verify an ML-DSA signature
55
+ *
56
+ * @param message - The original message
57
+ * @param signature - The ML-DSA signature to verify
58
+ * @returns True if the signature is valid
59
+ */
60
+ verifyMLDSASignature(message: string, signature: MLDSASignature): Promise<boolean>;
61
+ }
62
+
63
+ /**
64
+ * Type guard to check if a wallet supports OPWallet features
65
+ */
66
+ export function isOPWallet(wallet: unknown): wallet is OPWallet {
67
+ return (
68
+ typeof wallet === 'object' &&
69
+ wallet !== null &&
70
+ 'getMLDSAPublicKey' in wallet &&
71
+ 'signMLDSAMessage' in wallet
72
+ );
73
+ }