@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,513 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import { AddressTypes, MLDSASecurityLevel, Mnemonic } from '../build/opnet.js';
3
+ import { networks } from '@btc-vision/bitcoin';
4
+
5
+ describe('Wallet.derivePath', () => {
6
+ const testMnemonic =
7
+ 'abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about';
8
+
9
+ describe('Basic derivation', () => {
10
+ it('should derive child wallet with unique addresses', () => {
11
+ const mnemonic = new Mnemonic(
12
+ testMnemonic,
13
+ '',
14
+ networks.bitcoin,
15
+ MLDSASecurityLevel.LEVEL2,
16
+ );
17
+ const wallet = mnemonic.derive(0);
18
+ const child = wallet.derivePath('m/0');
19
+
20
+ // Addresses should be different
21
+ expect(child.p2tr).not.toBe(wallet.p2tr);
22
+ expect(child.p2wpkh).not.toBe(wallet.p2wpkh);
23
+
24
+ // Private keys should be different
25
+ expect(child.toPrivateKeyHex()).not.toBe(wallet.toPrivateKeyHex());
26
+ expect(child.quantumPrivateKeyHex).not.toBe(wallet.quantumPrivateKeyHex);
27
+ });
28
+
29
+ it('should derive wallet with correct address prefixes', () => {
30
+ const mnemonic = new Mnemonic(
31
+ testMnemonic,
32
+ '',
33
+ networks.bitcoin,
34
+ MLDSASecurityLevel.LEVEL2,
35
+ );
36
+ const wallet = mnemonic.derive(0);
37
+ const child = wallet.derivePath('m/0');
38
+
39
+ expect(child.p2tr).toMatch(/^bc1p/);
40
+ expect(child.p2wpkh).toMatch(/^bc1q/);
41
+ });
42
+ });
43
+
44
+ describe('Multiple child derivations', () => {
45
+ it('should derive multiple children with unique addresses', () => {
46
+ const mnemonic = new Mnemonic(
47
+ testMnemonic,
48
+ '',
49
+ networks.bitcoin,
50
+ MLDSASecurityLevel.LEVEL2,
51
+ );
52
+ const wallet = mnemonic.derive(0);
53
+
54
+ const child0 = wallet.derivePath('m/0');
55
+ const child1 = wallet.derivePath('m/1');
56
+ const child2 = wallet.derivePath('m/2');
57
+
58
+ // All addresses should be unique
59
+ const addresses = [child0.p2tr, child1.p2tr, child2.p2tr];
60
+ const uniqueAddresses = new Set(addresses);
61
+ expect(uniqueAddresses.size).toBe(3);
62
+
63
+ // All classical keys should be unique
64
+ const classicalKeys = [
65
+ child0.toPrivateKeyHex(),
66
+ child1.toPrivateKeyHex(),
67
+ child2.toPrivateKeyHex(),
68
+ ];
69
+ const uniqueClassicalKeys = new Set(classicalKeys);
70
+ expect(uniqueClassicalKeys.size).toBe(3);
71
+
72
+ // All quantum keys should be unique
73
+ const quantumKeys = [
74
+ child0.quantumPrivateKeyHex,
75
+ child1.quantumPrivateKeyHex,
76
+ child2.quantumPrivateKeyHex,
77
+ ];
78
+ const uniqueQuantumKeys = new Set(quantumKeys);
79
+ expect(uniqueQuantumKeys.size).toBe(3);
80
+ });
81
+ });
82
+
83
+ describe('Network preservation', () => {
84
+ it('should maintain mainnet network in derived wallet', () => {
85
+ const mnemonic = new Mnemonic(
86
+ testMnemonic,
87
+ '',
88
+ networks.bitcoin,
89
+ MLDSASecurityLevel.LEVEL2,
90
+ );
91
+ const wallet = mnemonic.derive(0);
92
+ const child = wallet.derivePath('m/0');
93
+
94
+ expect(child.network.bech32).toBe('bc');
95
+ expect(child.p2tr).toMatch(/^bc1/);
96
+ });
97
+
98
+ it('should maintain testnet network in derived wallet', () => {
99
+ const mnemonic = new Mnemonic(
100
+ testMnemonic,
101
+ '',
102
+ networks.testnet,
103
+ MLDSASecurityLevel.LEVEL2,
104
+ );
105
+ const wallet = mnemonic.derive(0);
106
+ const child = wallet.derivePath('m/0');
107
+
108
+ expect(child.network.bech32).toBe('tb');
109
+ expect(child.p2tr).toMatch(/^tb1/);
110
+ });
111
+
112
+ it('should maintain regtest network in derived wallet', () => {
113
+ const mnemonic = new Mnemonic(
114
+ testMnemonic,
115
+ '',
116
+ networks.regtest,
117
+ MLDSASecurityLevel.LEVEL2,
118
+ );
119
+ const wallet = mnemonic.derive(0);
120
+ const child = wallet.derivePath('m/0');
121
+
122
+ expect(child.network.bech32).toBe('bcrt');
123
+ expect(child.p2tr).toMatch(/^bcrt1/);
124
+ });
125
+ });
126
+
127
+ describe('Network-aware key derivation', () => {
128
+ it('should derive different classical keys for different networks', () => {
129
+ const mnemonicMainnet = new Mnemonic(
130
+ testMnemonic,
131
+ '',
132
+ networks.bitcoin,
133
+ MLDSASecurityLevel.LEVEL2,
134
+ );
135
+ const mnemonicTestnet = new Mnemonic(
136
+ testMnemonic,
137
+ '',
138
+ networks.testnet,
139
+ MLDSASecurityLevel.LEVEL2,
140
+ );
141
+
142
+ const mainnetParent = mnemonicMainnet.derive(0);
143
+ const testnetParent = mnemonicTestnet.derive(0);
144
+
145
+ const mainnetChild = mainnetParent.derivePath('m/0');
146
+ const testnetChild = testnetParent.derivePath('m/0');
147
+
148
+ // Classical keys should differ between networks
149
+ expect(mainnetChild.toPrivateKeyHex()).not.toBe(testnetChild.toPrivateKeyHex());
150
+ });
151
+
152
+ it('should derive different quantum keys for different networks', () => {
153
+ const mnemonicMainnet = new Mnemonic(
154
+ testMnemonic,
155
+ '',
156
+ networks.bitcoin,
157
+ MLDSASecurityLevel.LEVEL2,
158
+ );
159
+ const mnemonicTestnet = new Mnemonic(
160
+ testMnemonic,
161
+ '',
162
+ networks.testnet,
163
+ MLDSASecurityLevel.LEVEL2,
164
+ );
165
+
166
+ const mainnetParent = mnemonicMainnet.derive(0);
167
+ const testnetParent = mnemonicTestnet.derive(0);
168
+
169
+ const mainnetChild = mainnetParent.derivePath('m/0');
170
+ const testnetChild = testnetParent.derivePath('m/0');
171
+
172
+ // Quantum keys should differ between networks
173
+ expect(mainnetChild.quantumPrivateKeyHex).not.toBe(testnetChild.quantumPrivateKeyHex);
174
+ });
175
+ });
176
+
177
+ describe('Hardened paths', () => {
178
+ it('should support hardened derivation paths', () => {
179
+ const mnemonic = new Mnemonic(
180
+ testMnemonic,
181
+ '',
182
+ networks.bitcoin,
183
+ MLDSASecurityLevel.LEVEL2,
184
+ );
185
+ const wallet = mnemonic.derive(0);
186
+
187
+ const hardened1 = wallet.derivePath("m/0'");
188
+ const hardened2 = wallet.derivePath("m/44'/0'/0'");
189
+
190
+ expect(hardened1.p2tr).toBeDefined();
191
+ expect(hardened2.p2tr).toBeDefined();
192
+ expect(hardened1.p2tr).not.toBe(hardened2.p2tr);
193
+ });
194
+ });
195
+
196
+ describe('Deterministic derivation', () => {
197
+ it('should produce same results when using same mnemonic-derived wallet', () => {
198
+ const mnemonic = new Mnemonic(
199
+ testMnemonic,
200
+ '',
201
+ networks.bitcoin,
202
+ MLDSASecurityLevel.LEVEL2,
203
+ );
204
+ const wallet = mnemonic.derive(0);
205
+
206
+ // Derive the same path twice from the same wallet instance
207
+ const child1 = wallet.derivePath('m/0/1');
208
+ const child2 = wallet.derivePath('m/0/1');
209
+
210
+ // Should produce identical results (deterministic)
211
+ expect(child1.p2tr).toBe(child2.p2tr);
212
+ expect(child1.p2wpkh).toBe(child2.p2wpkh);
213
+ expect(child1.toPrivateKeyHex()).toBe(child2.toPrivateKeyHex());
214
+ expect(child1.quantumPrivateKeyHex).toBe(child2.quantumPrivateKeyHex);
215
+ });
216
+ });
217
+
218
+ describe('Deep path derivation', () => {
219
+ it('should support deep BIP44-style paths', () => {
220
+ const mnemonic = new Mnemonic(
221
+ testMnemonic,
222
+ '',
223
+ networks.bitcoin,
224
+ MLDSASecurityLevel.LEVEL2,
225
+ );
226
+ const wallet = mnemonic.derive(0);
227
+
228
+ const deepChild = wallet.derivePath("m/44'/0'/0'/0/5");
229
+
230
+ expect(deepChild.p2tr).toBeDefined();
231
+ expect(deepChild.p2tr).not.toBe(wallet.p2tr);
232
+ });
233
+ });
234
+ });
235
+
236
+ describe('Mnemonic.deriveUnisat', () => {
237
+ const testMnemonic =
238
+ 'episode frost someone page color giraffe match vanish sheriff veteran hub year pull save dizzy limb already turn reopen truth cradle rural wisdom change';
239
+ const unisatExpectedAddress = 'bcrt1phn6ej9ct038j722wdzkvsk7c6pmugtd5d3qnpwxc8g40zerf2ujs55tkz3';
240
+
241
+ describe('P2TR (Taproot) derivation', () => {
242
+ it('should match Unisat P2TR address for regtest', () => {
243
+ const mnemonic = new Mnemonic(
244
+ testMnemonic,
245
+ '',
246
+ networks.regtest,
247
+ MLDSASecurityLevel.LEVEL2,
248
+ );
249
+
250
+ const wallet = mnemonic.deriveUnisat(AddressTypes.P2TR, 0, 0, false);
251
+
252
+ expect(wallet.p2tr).toBe(unisatExpectedAddress);
253
+ });
254
+
255
+ it('should derive P2TR with correct network prefix for mainnet', () => {
256
+ const mnemonic = new Mnemonic(
257
+ testMnemonic,
258
+ '',
259
+ networks.bitcoin,
260
+ MLDSASecurityLevel.LEVEL2,
261
+ );
262
+
263
+ const wallet = mnemonic.deriveUnisat(AddressTypes.P2TR, 0);
264
+
265
+ expect(wallet.p2tr).toMatch(/^bc1p/);
266
+ });
267
+
268
+ it('should derive P2TR with correct network prefix for testnet', () => {
269
+ const mnemonic = new Mnemonic(
270
+ testMnemonic,
271
+ '',
272
+ networks.testnet,
273
+ MLDSASecurityLevel.LEVEL2,
274
+ );
275
+
276
+ const wallet = mnemonic.deriveUnisat(AddressTypes.P2TR, 0);
277
+
278
+ expect(wallet.p2tr).toMatch(/^tb1p/);
279
+ });
280
+ });
281
+
282
+ describe('P2WPKH (SegWit) derivation', () => {
283
+ it('should derive P2WPKH addresses', () => {
284
+ const mnemonic = new Mnemonic(
285
+ testMnemonic,
286
+ '',
287
+ networks.bitcoin,
288
+ MLDSASecurityLevel.LEVEL2,
289
+ );
290
+
291
+ const wallet = mnemonic.deriveUnisat(AddressTypes.P2WPKH, 0);
292
+
293
+ expect(wallet.p2wpkh).toBeDefined();
294
+ expect(wallet.p2wpkh).toMatch(/^bc1q/);
295
+ });
296
+
297
+ it('should use BIP84 path (m/84\'/0\'/0\'/0/0)', () => {
298
+ const mnemonic = new Mnemonic(
299
+ testMnemonic,
300
+ '',
301
+ networks.bitcoin,
302
+ MLDSASecurityLevel.LEVEL2,
303
+ );
304
+
305
+ const wallet = mnemonic.deriveUnisat(AddressTypes.P2WPKH, 0);
306
+ expect(wallet.p2wpkh).toBeDefined();
307
+ });
308
+ });
309
+
310
+ describe('P2PKH (Legacy) derivation', () => {
311
+ it('should derive legacy addresses', () => {
312
+ const mnemonic = new Mnemonic(
313
+ testMnemonic,
314
+ '',
315
+ networks.bitcoin,
316
+ MLDSASecurityLevel.LEVEL2,
317
+ );
318
+
319
+ const wallet = mnemonic.deriveUnisat(AddressTypes.P2PKH, 0);
320
+
321
+ expect(wallet.legacy).toBeDefined();
322
+ expect(wallet.legacy).toMatch(/^1/);
323
+ });
324
+ });
325
+
326
+ describe('Multiple address derivation', () => {
327
+ it('should derive unique addresses for different indices', () => {
328
+ const mnemonic = new Mnemonic(
329
+ testMnemonic,
330
+ '',
331
+ networks.bitcoin,
332
+ MLDSASecurityLevel.LEVEL2,
333
+ );
334
+
335
+ const wallet0 = mnemonic.deriveUnisat(AddressTypes.P2TR, 0);
336
+ const wallet1 = mnemonic.deriveUnisat(AddressTypes.P2TR, 1);
337
+ const wallet2 = mnemonic.deriveUnisat(AddressTypes.P2TR, 2);
338
+
339
+ expect(wallet0.p2tr).not.toBe(wallet1.p2tr);
340
+ expect(wallet1.p2tr).not.toBe(wallet2.p2tr);
341
+ expect(wallet0.p2tr).not.toBe(wallet2.p2tr);
342
+ });
343
+
344
+ it('should derive deterministic addresses', () => {
345
+ const mnemonic = new Mnemonic(
346
+ testMnemonic,
347
+ '',
348
+ networks.bitcoin,
349
+ MLDSASecurityLevel.LEVEL2,
350
+ );
351
+
352
+ const wallet1 = mnemonic.deriveUnisat(AddressTypes.P2TR, 5);
353
+ const wallet2 = mnemonic.deriveUnisat(AddressTypes.P2TR, 5);
354
+
355
+ expect(wallet1.p2tr).toBe(wallet2.p2tr);
356
+ expect(wallet1.toPublicKeyHex()).toBe(wallet2.toPublicKeyHex());
357
+ });
358
+ });
359
+
360
+ describe('Account and change address support', () => {
361
+ it('should derive different addresses for different accounts', () => {
362
+ const mnemonic = new Mnemonic(
363
+ testMnemonic,
364
+ '',
365
+ networks.bitcoin,
366
+ MLDSASecurityLevel.LEVEL2,
367
+ );
368
+
369
+ const account0 = mnemonic.deriveUnisat(AddressTypes.P2TR, 0, 0);
370
+ const account1 = mnemonic.deriveUnisat(AddressTypes.P2TR, 0, 1);
371
+
372
+ expect(account0.p2tr).not.toBe(account1.p2tr);
373
+ });
374
+
375
+ it('should derive different addresses for change vs receiving', () => {
376
+ const mnemonic = new Mnemonic(
377
+ testMnemonic,
378
+ '',
379
+ networks.bitcoin,
380
+ MLDSASecurityLevel.LEVEL2,
381
+ );
382
+
383
+ const receiving = mnemonic.deriveUnisat(AddressTypes.P2TR, 0, 0, false);
384
+ const change = mnemonic.deriveUnisat(AddressTypes.P2TR, 0, 0, true);
385
+
386
+ expect(receiving.p2tr).not.toBe(change.p2tr);
387
+ });
388
+ });
389
+
390
+ describe('Quantum key derivation', () => {
391
+ it('should include quantum keys', () => {
392
+ const mnemonic = new Mnemonic(
393
+ testMnemonic,
394
+ '',
395
+ networks.bitcoin,
396
+ MLDSASecurityLevel.LEVEL2,
397
+ );
398
+
399
+ const wallet = mnemonic.deriveUnisat(AddressTypes.P2TR, 0);
400
+
401
+ expect(wallet.quantumPublicKey).toBeDefined();
402
+ expect(wallet.quantumPublicKey.length).toBe(1312); // LEVEL2 size
403
+ expect(wallet.address.toHex()).toBeDefined();
404
+ });
405
+
406
+ it('should derive unique quantum keys for different indices', () => {
407
+ const mnemonic = new Mnemonic(
408
+ testMnemonic,
409
+ '',
410
+ networks.bitcoin,
411
+ MLDSASecurityLevel.LEVEL2,
412
+ );
413
+
414
+ const wallet0 = mnemonic.deriveUnisat(AddressTypes.P2TR, 0);
415
+ const wallet1 = mnemonic.deriveUnisat(AddressTypes.P2TR, 1);
416
+
417
+ expect(wallet0.address.toHex()).not.toBe(wallet1.address.toHex());
418
+ });
419
+ });
420
+
421
+ describe('deriveMultipleUnisat', () => {
422
+ it('should derive multiple wallets', () => {
423
+ const mnemonic = new Mnemonic(
424
+ testMnemonic,
425
+ '',
426
+ networks.bitcoin,
427
+ MLDSASecurityLevel.LEVEL2,
428
+ );
429
+
430
+ const wallets = mnemonic.deriveMultipleUnisat(AddressTypes.P2TR, 5);
431
+
432
+ expect(wallets.length).toBe(5);
433
+ expect(wallets[0].p2tr).toBeDefined();
434
+ expect(wallets[4].p2tr).toBeDefined();
435
+ });
436
+
437
+ it('should derive unique addresses for each wallet', () => {
438
+ const mnemonic = new Mnemonic(
439
+ testMnemonic,
440
+ '',
441
+ networks.bitcoin,
442
+ MLDSASecurityLevel.LEVEL2,
443
+ );
444
+
445
+ const wallets = mnemonic.deriveMultipleUnisat(AddressTypes.P2TR, 3);
446
+
447
+ const addresses = wallets.map((w) => w.p2tr);
448
+ const uniqueAddresses = new Set(addresses);
449
+
450
+ expect(uniqueAddresses.size).toBe(3);
451
+ });
452
+
453
+ it('should support custom start index', () => {
454
+ const mnemonic = new Mnemonic(
455
+ testMnemonic,
456
+ '',
457
+ networks.bitcoin,
458
+ MLDSASecurityLevel.LEVEL2,
459
+ );
460
+
461
+ const wallets = mnemonic.deriveMultipleUnisat(AddressTypes.P2TR, 2, 5);
462
+ const wallet5 = mnemonic.deriveUnisat(AddressTypes.P2TR, 5);
463
+
464
+ expect(wallets[0].p2tr).toBe(wallet5.p2tr);
465
+ });
466
+ });
467
+
468
+ describe('Error handling', () => {
469
+ it('should throw error for unsupported address type', () => {
470
+ const mnemonic = new Mnemonic(
471
+ testMnemonic,
472
+ '',
473
+ networks.bitcoin,
474
+ MLDSASecurityLevel.LEVEL2,
475
+ );
476
+
477
+ expect(() => {
478
+ mnemonic.deriveUnisat('INVALID_TYPE' as AddressTypes, 0);
479
+ }).toThrow('Unsupported address type');
480
+ });
481
+ });
482
+
483
+ describe('Network consistency', () => {
484
+ it('should preserve network in derived wallet', () => {
485
+ const mnemonic = new Mnemonic(
486
+ testMnemonic,
487
+ '',
488
+ networks.testnet,
489
+ MLDSASecurityLevel.LEVEL2,
490
+ );
491
+
492
+ const wallet = mnemonic.deriveUnisat(AddressTypes.P2TR, 0);
493
+
494
+ expect(wallet.network.bech32).toBe('tb');
495
+ });
496
+ });
497
+
498
+ describe('Security level preservation', () => {
499
+ it('should maintain security level in derived wallet', () => {
500
+ const mnemonic = new Mnemonic(
501
+ testMnemonic,
502
+ '',
503
+ networks.bitcoin,
504
+ MLDSASecurityLevel.LEVEL3,
505
+ );
506
+
507
+ const wallet = mnemonic.deriveUnisat(AddressTypes.P2TR, 0);
508
+
509
+ expect(wallet.securityLevel).toBe(MLDSASecurityLevel.LEVEL3);
510
+ expect(wallet.quantumPublicKey.length).toBe(1952); // LEVEL3 size
511
+ });
512
+ });
513
+ });