@btc-vision/transaction 1.7.0 → 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.
@@ -0,0 +1,445 @@
1
+ # Mnemonic & Wallet Management
2
+
3
+ ## Table of Contents
4
+ - [Generating a Mnemonic](#generating-a-mnemonic)
5
+ - [Loading Existing Mnemonic](#loading-existing-mnemonic)
6
+ - [Deriving Wallets](#deriving-wallets)
7
+ - [Unisat Wallet Compatibility](#unisat-wallet-compatibility)
8
+ - [Wallet Properties](#wallet-properties)
9
+ - [Security Best Practices](#security-best-practices)
10
+ - [Advanced Usage](#advanced-usage)
11
+
12
+ ## Generating a Mnemonic
13
+
14
+ ### Basic Generation
15
+
16
+ Generate a new 12-word mnemonic with quantum support:
17
+
18
+ ```typescript
19
+ import { Mnemonic, MnemonicStrength, MLDSASecurityLevel } from '@btc-vision/transaction';
20
+ import { networks } from '@btc-vision/bitcoin';
21
+
22
+ // Generate with default 12 words and LEVEL2 security (BIP360 RECOMMENDED DEFAULT)
23
+ const mnemonic = Mnemonic.generate();
24
+
25
+ console.log('Mnemonic phrase:', mnemonic.phrase);
26
+ console.log('Security Level:', mnemonic.securityLevel); // LEVEL2 (default)
27
+ // Output: "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about"
28
+ ```
29
+
30
+ ### Custom Strength and Security Level
31
+
32
+ ```typescript
33
+ // RECOMMENDED: Use LEVEL2 (BIP360 default) for most applications
34
+ const recommendedMnemonic = Mnemonic.generate(
35
+ MnemonicStrength.MAXIMUM, // 24 words
36
+ '', // No passphrase
37
+ networks.bitcoin, // Mainnet
38
+ MLDSASecurityLevel.LEVEL2 // RECOMMENDED DEFAULT (BIP360)
39
+ );
40
+
41
+ console.log('Words:', recommendedMnemonic.phrase.split(' ').length); // 24
42
+ console.log('Security Level:', recommendedMnemonic.securityLevel); // LEVEL2
43
+
44
+ // OPTIONAL: Use LEVEL5 only for maximum security in high-value applications
45
+ const maxSecurityMnemonic = Mnemonic.generate(
46
+ MnemonicStrength.MAXIMUM, // 24 words
47
+ '', // No passphrase
48
+ networks.bitcoin, // Mainnet
49
+ MLDSASecurityLevel.LEVEL5 // Maximum quantum security (optional)
50
+ );
51
+
52
+ console.log('Security Level:', maxSecurityMnemonic.securityLevel); // LEVEL5
53
+ ```
54
+
55
+ ### Available Mnemonic Strengths
56
+
57
+ ```typescript
58
+ enum MnemonicStrength {
59
+ MINIMUM = 128, // 12 words - Standard
60
+ LOW = 160, // 15 words
61
+ MEDIUM = 192, // 18 words
62
+ HIGH = 224, // 21 words
63
+ MAXIMUM = 256 // 24 words - Maximum entropy
64
+ }
65
+ ```
66
+
67
+ ### With Network and Passphrase
68
+
69
+ ```typescript
70
+ // Generate for testnet with BIP39 passphrase
71
+ const testnetMnemonic = Mnemonic.generate(
72
+ MnemonicStrength.MINIMUM, // 12 words
73
+ 'my-secret-passphrase', // BIP39 passphrase (optional)
74
+ networks.testnet, // Testnet network
75
+ MLDSASecurityLevel.LEVEL2 // RECOMMENDED DEFAULT (BIP360)
76
+ );
77
+ ```
78
+
79
+ ## Loading Existing Mnemonic
80
+
81
+ ### From Phrase
82
+
83
+ ```typescript
84
+ const phrase = 'abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about';
85
+
86
+ const mnemonic = new Mnemonic(
87
+ phrase,
88
+ '', // Passphrase (use same as generation)
89
+ networks.bitcoin, // Network
90
+ MLDSASecurityLevel.LEVEL2 // RECOMMENDED DEFAULT (BIP360) - must match original
91
+ );
92
+
93
+ console.log('Network:', mnemonic.network.bech32); // 'bc'
94
+ console.log('Security:', mnemonic.securityLevel); // LEVEL2 (BIP360 default)
95
+ ```
96
+
97
+ ### Validating Mnemonic
98
+
99
+ ```typescript
100
+ import * as bip39 from 'bip39';
101
+
102
+ const phrase = 'abandon abandon abandon...';
103
+
104
+ // Validate BIP39 mnemonic
105
+ if (!bip39.validateMnemonic(phrase)) {
106
+ throw new Error('Invalid mnemonic phrase');
107
+ }
108
+
109
+ const mnemonic = new Mnemonic(phrase);
110
+ ```
111
+
112
+ ## Deriving Wallets
113
+
114
+ ### Single Wallet Derivation
115
+
116
+ ```typescript
117
+ const mnemonic = Mnemonic.generate();
118
+
119
+ // Derive wallet at index 0
120
+ const wallet0 = mnemonic.derive(0);
121
+
122
+ // Derive wallet at index 1
123
+ const wallet1 = mnemonic.derive(1);
124
+
125
+ // Each wallet has both classical and quantum keys
126
+ console.log('Classical Public Key:', wallet0.publicKey);
127
+ console.log('Quantum Public Key:', wallet0.quantumPublicKeyHex);
128
+ ```
129
+
130
+ ### Multiple Wallet Derivation
131
+
132
+ ```typescript
133
+ // Derive first 5 wallets
134
+ const wallets = mnemonic.deriveMultiple(5);
135
+
136
+ wallets.forEach((wallet, index) => {
137
+ console.log(`Wallet ${index}:`);
138
+ console.log(' P2TR:', wallet.p2tr);
139
+ console.log(' ML-DSA Hash:', wallet.address.toHex());
140
+ });
141
+ ```
142
+
143
+ ### Custom Derivation Path
144
+
145
+ ```typescript
146
+ // Custom BIP44/BIP84 path
147
+ const customWallet = mnemonic.deriveCustomPath(
148
+ "m/84'/0'/0'/0/5", // BIP84 path for account 0, index 5
149
+ "m/360'/0'/0'/0/5" // BIP360 quantum path (parallel)
150
+ );
151
+
152
+ console.log('Custom wallet address:', customWallet.p2wpkh);
153
+ ```
154
+
155
+ ### Unisat Wallet Compatibility
156
+
157
+ For compatibility with Unisat and other HD wallets, use `deriveUnisat()` which follows standard BIP derivation paths:
158
+
159
+ ```typescript
160
+ import { AddressTypes } from '@btc-vision/transaction';
161
+
162
+ const mnemonic = Mnemonic.generate();
163
+
164
+ // Derive P2TR (Taproot) - BIP86
165
+ const taprootWallet = mnemonic.deriveUnisat(AddressTypes.P2TR, 0);
166
+ console.log('Taproot:', taprootWallet.p2tr); // bc1p...
167
+
168
+ // Derive P2WPKH (Native SegWit) - BIP84
169
+ const segwitWallet = mnemonic.deriveUnisat(AddressTypes.P2WPKH, 0);
170
+ console.log('Native SegWit:', segwitWallet.p2wpkh); // bc1q...
171
+
172
+ // Derive P2PKH (Legacy) - BIP44
173
+ const legacyWallet = mnemonic.deriveUnisat(AddressTypes.P2PKH, 0);
174
+ console.log('Legacy:', legacyWallet.legacy); // 1...
175
+
176
+ // Derive P2SH (Nested SegWit) - BIP49
177
+ const nestedSegwitWallet = mnemonic.deriveUnisat(AddressTypes.P2SH_OR_P2SH_P2WPKH, 0);
178
+ console.log('Nested SegWit:', nestedSegwitWallet.segwitLegacy); // 3...
179
+ ```
180
+
181
+ #### BIP Standard Mapping
182
+
183
+ The `deriveUnisat()` method automatically maps address types to BIP standards:
184
+
185
+ | Address Type | BIP Standard | Path Format | Address Prefix |
186
+ |--------------|-------------|-------------|----------------|
187
+ | P2TR | BIP86 | `m/86'/0'/account'/change/index` | bc1p... (mainnet) |
188
+ | P2WPKH | BIP84 | `m/84'/0'/account'/change/index` | bc1q... (mainnet) |
189
+ | P2PKH | BIP44 | `m/44'/0'/account'/change/index` | 1... (mainnet) |
190
+ | P2SH | BIP49 | `m/49'/0'/account'/change/index` | 3... (mainnet) |
191
+
192
+ **Note**: Unisat-compatible paths always use coin type `0` for the purpose field, regardless of network.
193
+
194
+ #### Accounts and Change Addresses
195
+
196
+ ```typescript
197
+ // Main account (account 0), receiving addresses
198
+ const receiving0 = mnemonic.deriveUnisat(AddressTypes.P2TR, 0, 0, false);
199
+ const receiving1 = mnemonic.deriveUnisat(AddressTypes.P2TR, 1, 0, false);
200
+
201
+ // Main account (account 0), change addresses
202
+ const change0 = mnemonic.deriveUnisat(AddressTypes.P2TR, 0, 0, true);
203
+ const change1 = mnemonic.deriveUnisat(AddressTypes.P2TR, 1, 0, true);
204
+
205
+ // Second account (account 1), receiving addresses
206
+ const account1_0 = mnemonic.deriveUnisat(AddressTypes.P2TR, 0, 1, false);
207
+
208
+ console.log('Receiving 0:', receiving0.p2tr);
209
+ console.log('Receiving 1:', receiving1.p2tr);
210
+ console.log('Change 0:', change0.p2tr);
211
+ console.log('Account 1:', account1_0.p2tr);
212
+ ```
213
+
214
+ #### Bulk Derivation
215
+
216
+ Derive multiple Unisat-compatible wallets at once:
217
+
218
+ ```typescript
219
+ // Derive first 5 Taproot addresses
220
+ const taprootWallets = mnemonic.deriveMultipleUnisat(
221
+ AddressTypes.P2TR, // Address type
222
+ 5, // Count
223
+ 0, // Start index
224
+ 0, // Account
225
+ false // Not change addresses
226
+ );
227
+
228
+ taprootWallets.forEach((wallet, i) => {
229
+ console.log(`Address ${i}: ${wallet.p2tr}`);
230
+ });
231
+
232
+ // Derive 10 Native SegWit change addresses starting from index 5
233
+ const changeWallets = mnemonic.deriveMultipleUnisat(
234
+ AddressTypes.P2WPKH, // Native SegWit
235
+ 10, // Count
236
+ 5, // Start at index 5
237
+ 0, // Account 0
238
+ true // Change addresses
239
+ );
240
+ ```
241
+
242
+ #### Quantum Keys with Unisat Derivation
243
+
244
+ All Unisat-derived wallets include both classical and quantum keys:
245
+
246
+ ```typescript
247
+ const wallet = mnemonic.deriveUnisat(AddressTypes.P2TR, 0);
248
+
249
+ // Classical Taproot address (BIP86)
250
+ console.log('Classical P2TR:', wallet.p2tr);
251
+
252
+ // Quantum ML-DSA keys (BIP360: m/360'/0'/0'/0/0)
253
+ console.log('Quantum Public Key:', wallet.quantumPublicKeyHex);
254
+ console.log('Security Level:', wallet.securityLevel);
255
+
256
+ // Both keys are deterministically derived
257
+ console.log('Has quantum keypair:', wallet.mldsaKeypair !== undefined); // true
258
+ ```
259
+
260
+ ## Wallet Properties
261
+
262
+ ### Classical Keys
263
+
264
+ ```typescript
265
+ const wallet = mnemonic.derive(0);
266
+
267
+ // Public keys
268
+ console.log('Compressed:', wallet.publicKey); // 33 bytes
269
+ console.log('Hex:', wallet.toPublicKeyHex()); // 0x...
270
+ console.log('Uncompressed:', wallet.toUncompressedPublicKey()); // 65 bytes
271
+
272
+ // Private key (handle with care!)
273
+ console.log('Private key:', wallet.privateKey); // 32 bytes hex
274
+
275
+ // Key pair
276
+ console.log('EC Keypair:', wallet.keypair); // ECPairInterface
277
+ ```
278
+
279
+ ### Quantum Keys
280
+
281
+ ```typescript
282
+ // ML-DSA keypair
283
+ console.log('ML-DSA Keypair:', wallet.mldsaKeypair);
284
+ console.log('Security Level:', wallet.securityLevel); // LEVEL2, LEVEL3, or LEVEL5
285
+
286
+ // Quantum public keys
287
+ console.log('Public Key (hex):', wallet.quantumPublicKeyHex);
288
+ console.log('Public Key (buffer):', wallet.quantumPublicKey);
289
+ console.log('Public Key Size:', wallet.quantumPublicKey.length); // 1312, 1952, or 2592 bytes
290
+ ```
291
+
292
+ ### Addresses
293
+
294
+ ```typescript
295
+ // Classical addresses
296
+ console.log('P2TR:', wallet.p2tr); // bc1p...
297
+ console.log('P2WPKH:', wallet.p2wpkh); // bc1q...
298
+ console.log('Legacy (P2PKH):', wallet.legacy); // 1...
299
+
300
+ // Quantum address
301
+ console.log('Public Key:', wallet.address.toHex());
302
+
303
+ // Address object
304
+ const address = wallet.address;
305
+ console.log('ML-DSA Hash:', address.toHex()); // SHA256 of quantum key
306
+ console.log('Classical Key:', address.tweakedToHex()); // Classical public key
307
+ ```
308
+
309
+ ## Security Best Practices
310
+
311
+ ### ⚠️ Mnemonic Security
312
+
313
+ ```typescript
314
+ const mnemonic = Mnemonic.generate();
315
+
316
+ // ✅ GOOD: Store securely
317
+ // - Hardware wallets
318
+ // - Encrypted storage
319
+ // - Paper backup in secure location
320
+
321
+ // ❌ BAD: Don't do this!
322
+ // - console.log(mnemonic.phrase) // Never log in production
323
+ // - Save to file unencrypted
324
+ // - Transmit over network
325
+ // - Store in version control
326
+
327
+ // Access sensitive data only when needed
328
+ const phrase = mnemonic.phrase; // ⚠️ Warning: Highly sensitive
329
+ const seed = mnemonic.seed; // ⚠️ Warning: Highly sensitive
330
+ ```
331
+
332
+ ### Passphrase Protection
333
+
334
+ ```typescript
335
+ // Add extra security layer with passphrase
336
+ const passphrase = 'my-very-strong-passphrase-12345';
337
+
338
+ const mnemonic = Mnemonic.generate(
339
+ MnemonicStrength.MAXIMUM, // 24 words
340
+ passphrase, // Required to recover wallet
341
+ networks.bitcoin, // Mainnet
342
+ MLDSASecurityLevel.LEVEL3 // Security level
343
+ );
344
+
345
+ // ⚠️ IMPORTANT: You need BOTH mnemonic AND passphrase to recover!
346
+ // Losing either means permanent loss of funds
347
+ ```
348
+
349
+ ### Network Awareness
350
+
351
+ ```typescript
352
+ // Different networks generate different keys!
353
+ const mainnetMnemonic = new Mnemonic(phrase, '', networks.bitcoin);
354
+ const testnetMnemonic = new Mnemonic(phrase, '', networks.testnet);
355
+
356
+ const mainnetWallet = mainnetMnemonic.derive(0);
357
+ const testnetWallet = testnetMnemonic.derive(0);
358
+
359
+ // These will be DIFFERENT addresses even with same mnemonic
360
+ console.log('Mainnet:', mainnetWallet.p2tr); // bc1p...
361
+ console.log('Testnet:', testnetWallet.p2tr); // tb1p...
362
+ ```
363
+
364
+ ## Advanced Usage
365
+
366
+ ### Accessing Root Keys
367
+
368
+ ```typescript
369
+ const mnemonic = Mnemonic.generate();
370
+
371
+ // Classical BIP32 root
372
+ const classicalRoot = mnemonic.classicalRoot;
373
+ console.log('Classical xpub:', classicalRoot.toBase58());
374
+
375
+ // Quantum BIP32 root
376
+ const quantumRoot = mnemonic.quantumRoot;
377
+ console.log('Quantum key size:', quantumRoot.publicKey.length);
378
+ ```
379
+
380
+ ### Chain Codes
381
+
382
+ ```typescript
383
+ const mnemonic = Mnemonic.generate();
384
+ const wallet = mnemonic.derive(0);
385
+
386
+ // Chain codes for key derivation
387
+ console.log('Classical chain code:', wallet.keypair.chainCode?.toString('hex'));
388
+ console.log('Quantum chain code:', wallet.mldsaKeypair.chainCode.toString('hex'));
389
+ ```
390
+
391
+ ### Deterministic Derivation
392
+
393
+ ```typescript
394
+ // Same mnemonic always generates same wallets
395
+ const mnemonic1 = new Mnemonic('abandon abandon abandon...', '');
396
+ const mnemonic2 = new Mnemonic('abandon abandon abandon...', '');
397
+
398
+ const wallet1 = mnemonic1.derive(0);
399
+ const wallet2 = mnemonic2.derive(0);
400
+
401
+ console.log(wallet1.p2tr === wallet2.p2tr); // true - deterministic!
402
+ ```
403
+
404
+ ## Complete Example
405
+
406
+ ```typescript
407
+ import { Mnemonic, MnemonicStrength, MLDSASecurityLevel } from '@btc-vision/transaction';
408
+ import { networks } from '@btc-vision/bitcoin';
409
+
410
+ // Step 1: Generate mnemonic
411
+ console.log('Generating quantum-resistant wallet...');
412
+ const mnemonic = Mnemonic.generate(
413
+ MnemonicStrength.MAXIMUM, // 24 words
414
+ 'optional-passphrase', // BIP39 passphrase
415
+ networks.bitcoin, // Network
416
+ MLDSASecurityLevel.LEVEL2 // Security level
417
+ );
418
+
419
+ // Step 2: Securely store mnemonic phrase
420
+ const phrase = mnemonic.phrase;
421
+ console.log('⚠️ IMPORTANT: Backup these 24 words securely:');
422
+ console.log(phrase);
423
+
424
+ // Step 3: Derive wallets
425
+ const wallet = mnemonic.derive(0);
426
+
427
+ // Step 4: Get addresses
428
+ console.log('\nClassical Addresses:');
429
+ console.log('P2TR:', wallet.p2tr);
430
+ console.log('P2WPKH:', wallet.p2wpkh);
431
+
432
+ console.log('\nQuantum Address:');
433
+ console.log('Public Key:', wallet.address.toHex());
434
+
435
+ // Step 5: Display keys (for demonstration only!)
436
+ console.log('\nKey Information:');
437
+ console.log('Classical Public Key:', wallet.toPublicKeyHex());
438
+ console.log('Quantum Public Key Length:', wallet.quantumPublicKey.length, 'bytes');
439
+ console.log('Security Level:', wallet.securityLevel);
440
+ ```
441
+
442
+ ## Next Steps
443
+
444
+ - [Address Generation](./03-address-generation.md) - Generate classical and quantum addresses
445
+ - [Message Signing](./04-message-signing.md) - Sign messages with ML-DSA