@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,473 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import { AddressTypes, AddressVerificator, MLDSASecurityLevel, Mnemonic } from '../build/opnet.js';
3
+ import { networks } from '@btc-vision/bitcoin';
4
+
5
+ describe('AddressVerificator ML-DSA Support', () => {
6
+ const testMnemonic =
7
+ 'abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about';
8
+
9
+ describe('isValidMLDSAPublicKey', () => {
10
+ it('should validate ML-DSA-44 (Level 2) public key from hex string', () => {
11
+ const mnemonic = new Mnemonic(
12
+ testMnemonic,
13
+ '',
14
+ networks.bitcoin,
15
+ MLDSASecurityLevel.LEVEL2,
16
+ );
17
+ const wallet = mnemonic.derive(0);
18
+ const publicKeyHex = wallet.quantumPublicKeyHex;
19
+
20
+ const securityLevel = AddressVerificator.isValidMLDSAPublicKey(publicKeyHex);
21
+
22
+ expect(securityLevel).toBe(MLDSASecurityLevel.LEVEL2);
23
+ });
24
+
25
+ it('should validate ML-DSA-44 (Level 2) public key from hex string with 0x prefix', () => {
26
+ const mnemonic = new Mnemonic(
27
+ testMnemonic,
28
+ '',
29
+ networks.bitcoin,
30
+ MLDSASecurityLevel.LEVEL2,
31
+ );
32
+ const wallet = mnemonic.derive(0);
33
+ const publicKeyHex = '0x' + wallet.quantumPublicKeyHex;
34
+
35
+ const securityLevel = AddressVerificator.isValidMLDSAPublicKey(publicKeyHex);
36
+
37
+ expect(securityLevel).toBe(MLDSASecurityLevel.LEVEL2);
38
+ });
39
+
40
+ it('should validate ML-DSA-44 (Level 2) public key from Buffer', () => {
41
+ const mnemonic = new Mnemonic(
42
+ testMnemonic,
43
+ '',
44
+ networks.bitcoin,
45
+ MLDSASecurityLevel.LEVEL2,
46
+ );
47
+ const wallet = mnemonic.derive(0);
48
+ const publicKeyBuffer = wallet.quantumPublicKey;
49
+
50
+ const securityLevel = AddressVerificator.isValidMLDSAPublicKey(publicKeyBuffer);
51
+
52
+ expect(securityLevel).toBe(MLDSASecurityLevel.LEVEL2);
53
+ });
54
+
55
+ it('should validate ML-DSA-44 (Level 2) public key from Uint8Array', () => {
56
+ const mnemonic = new Mnemonic(
57
+ testMnemonic,
58
+ '',
59
+ networks.bitcoin,
60
+ MLDSASecurityLevel.LEVEL2,
61
+ );
62
+ const wallet = mnemonic.derive(0);
63
+ const publicKeyArray = new Uint8Array(wallet.quantumPublicKey);
64
+
65
+ const securityLevel = AddressVerificator.isValidMLDSAPublicKey(publicKeyArray);
66
+
67
+ expect(securityLevel).toBe(MLDSASecurityLevel.LEVEL2);
68
+ });
69
+
70
+ it('should validate ML-DSA-65 (Level 3) public key', () => {
71
+ const mnemonic = new Mnemonic(
72
+ testMnemonic,
73
+ '',
74
+ networks.bitcoin,
75
+ MLDSASecurityLevel.LEVEL3,
76
+ );
77
+ const wallet = mnemonic.derive(0);
78
+ const publicKeyHex = wallet.quantumPublicKeyHex;
79
+
80
+ const securityLevel = AddressVerificator.isValidMLDSAPublicKey(publicKeyHex);
81
+
82
+ expect(securityLevel).toBe(MLDSASecurityLevel.LEVEL3);
83
+ });
84
+
85
+ it('should validate ML-DSA-65 (Level 3) public key from Buffer', () => {
86
+ const mnemonic = new Mnemonic(
87
+ testMnemonic,
88
+ '',
89
+ networks.bitcoin,
90
+ MLDSASecurityLevel.LEVEL3,
91
+ );
92
+ const wallet = mnemonic.derive(0);
93
+ const publicKeyBuffer = wallet.quantumPublicKey;
94
+
95
+ const securityLevel = AddressVerificator.isValidMLDSAPublicKey(publicKeyBuffer);
96
+
97
+ expect(securityLevel).toBe(MLDSASecurityLevel.LEVEL3);
98
+ });
99
+
100
+ it('should validate ML-DSA-87 (Level 5) public key', () => {
101
+ const mnemonic = new Mnemonic(
102
+ testMnemonic,
103
+ '',
104
+ networks.bitcoin,
105
+ MLDSASecurityLevel.LEVEL5,
106
+ );
107
+ const wallet = mnemonic.derive(0);
108
+ const publicKeyHex = wallet.quantumPublicKeyHex;
109
+
110
+ const securityLevel = AddressVerificator.isValidMLDSAPublicKey(publicKeyHex);
111
+
112
+ expect(securityLevel).toBe(MLDSASecurityLevel.LEVEL5);
113
+ });
114
+
115
+ it('should validate ML-DSA-87 (Level 5) public key from Buffer', () => {
116
+ const mnemonic = new Mnemonic(
117
+ testMnemonic,
118
+ '',
119
+ networks.bitcoin,
120
+ MLDSASecurityLevel.LEVEL5,
121
+ );
122
+ const wallet = mnemonic.derive(0);
123
+ const publicKeyBuffer = wallet.quantumPublicKey;
124
+
125
+ const securityLevel = AddressVerificator.isValidMLDSAPublicKey(publicKeyBuffer);
126
+
127
+ expect(securityLevel).toBe(MLDSASecurityLevel.LEVEL5);
128
+ });
129
+
130
+ it('should reject invalid hex string', () => {
131
+ const invalidHex = 'not a valid hex string';
132
+ const securityLevel = AddressVerificator.isValidMLDSAPublicKey(invalidHex);
133
+
134
+ expect(securityLevel).toBeNull();
135
+ });
136
+
137
+ it('should reject public key with wrong length', () => {
138
+ const wrongLength = 'a'.repeat(100);
139
+ const securityLevel = AddressVerificator.isValidMLDSAPublicKey(wrongLength);
140
+
141
+ expect(securityLevel).toBeNull();
142
+ });
143
+
144
+ it('should reject empty string', () => {
145
+ const securityLevel = AddressVerificator.isValidMLDSAPublicKey('');
146
+
147
+ expect(securityLevel).toBeNull();
148
+ });
149
+
150
+ it('should reject empty Buffer', () => {
151
+ const securityLevel = AddressVerificator.isValidMLDSAPublicKey(Buffer.alloc(0));
152
+
153
+ expect(securityLevel).toBeNull();
154
+ });
155
+
156
+ it('should reject classical public key (33 bytes)', () => {
157
+ const mnemonic = new Mnemonic(
158
+ testMnemonic,
159
+ '',
160
+ networks.bitcoin,
161
+ MLDSASecurityLevel.LEVEL2,
162
+ );
163
+ const wallet = mnemonic.derive(0);
164
+ const classicalPublicKey = wallet.publicKey; // 33 bytes
165
+
166
+ const securityLevel = AddressVerificator.isValidMLDSAPublicKey(classicalPublicKey);
167
+
168
+ expect(securityLevel).toBeNull();
169
+ });
170
+
171
+ it('should verify all valid ML-DSA lengths', () => {
172
+ // Test all three security levels
173
+ const levels = [
174
+ MLDSASecurityLevel.LEVEL2,
175
+ MLDSASecurityLevel.LEVEL3,
176
+ MLDSASecurityLevel.LEVEL5,
177
+ ];
178
+
179
+ for (const level of levels) {
180
+ const mnemonic = new Mnemonic(testMnemonic, '', networks.bitcoin, level);
181
+ const wallet = mnemonic.derive(0);
182
+
183
+ const securityLevelHex = AddressVerificator.isValidMLDSAPublicKey(
184
+ wallet.quantumPublicKeyHex,
185
+ );
186
+ const securityLevelBuffer = AddressVerificator.isValidMLDSAPublicKey(
187
+ wallet.quantumPublicKey,
188
+ );
189
+
190
+ expect(securityLevelHex).toBe(level);
191
+ expect(securityLevelBuffer).toBe(level);
192
+ }
193
+ });
194
+ });
195
+
196
+ describe('isValidP2OPAddress', () => {
197
+ it('should validate mainnet P2OP address', () => {
198
+ const mnemonic = new Mnemonic(
199
+ testMnemonic,
200
+ '',
201
+ networks.bitcoin,
202
+ MLDSASecurityLevel.LEVEL2,
203
+ );
204
+ const wallet = mnemonic.derive(0);
205
+ const p2opAddress = wallet.address.p2op(networks.bitcoin);
206
+
207
+ const isValid = AddressVerificator.isValidP2OPAddress(p2opAddress, networks.bitcoin);
208
+
209
+ expect(isValid).toBe(true);
210
+ });
211
+
212
+ it('should validate testnet P2OP address', () => {
213
+ const mnemonic = new Mnemonic(
214
+ testMnemonic,
215
+ '',
216
+ networks.testnet,
217
+ MLDSASecurityLevel.LEVEL2,
218
+ );
219
+ const wallet = mnemonic.derive(0);
220
+ const p2opAddress = wallet.address.p2op(networks.testnet);
221
+
222
+ const isValid = AddressVerificator.isValidP2OPAddress(p2opAddress, networks.testnet);
223
+
224
+ expect(isValid).toBe(true);
225
+ });
226
+
227
+ it('should validate regtest P2OP address', () => {
228
+ const mnemonic = new Mnemonic(
229
+ testMnemonic,
230
+ '',
231
+ networks.regtest,
232
+ MLDSASecurityLevel.LEVEL2,
233
+ );
234
+ const wallet = mnemonic.derive(0);
235
+ const p2opAddress = wallet.address.p2op(networks.regtest);
236
+
237
+ const isValid = AddressVerificator.isValidP2OPAddress(p2opAddress, networks.regtest);
238
+
239
+ expect(isValid).toBe(true);
240
+ });
241
+
242
+ it('should reject P2TR address as P2OP', () => {
243
+ const mnemonic = new Mnemonic(
244
+ testMnemonic,
245
+ '',
246
+ networks.bitcoin,
247
+ MLDSASecurityLevel.LEVEL2,
248
+ );
249
+ const wallet = mnemonic.derive(0);
250
+ const p2trAddress = wallet.p2tr;
251
+
252
+ const isValid = AddressVerificator.isValidP2OPAddress(p2trAddress, networks.bitcoin);
253
+
254
+ expect(isValid).toBe(false);
255
+ });
256
+
257
+ it('should reject P2WPKH address as P2OP', () => {
258
+ const mnemonic = new Mnemonic(
259
+ testMnemonic,
260
+ '',
261
+ networks.bitcoin,
262
+ MLDSASecurityLevel.LEVEL2,
263
+ );
264
+ const wallet = mnemonic.derive(0);
265
+ const p2wpkhAddress = wallet.p2wpkh;
266
+
267
+ const isValid = AddressVerificator.isValidP2OPAddress(p2wpkhAddress, networks.bitcoin);
268
+
269
+ expect(isValid).toBe(false);
270
+ });
271
+
272
+ it('should reject invalid address string', () => {
273
+ const invalidAddress = 'not a valid address';
274
+ const isValid = AddressVerificator.isValidP2OPAddress(invalidAddress, networks.bitcoin);
275
+
276
+ expect(isValid).toBe(false);
277
+ });
278
+
279
+ it('should reject empty string', () => {
280
+ const isValid = AddressVerificator.isValidP2OPAddress('', networks.bitcoin);
281
+
282
+ expect(isValid).toBe(false);
283
+ });
284
+
285
+ it('should reject address on wrong network', () => {
286
+ const mnemonic = new Mnemonic(
287
+ testMnemonic,
288
+ '',
289
+ networks.bitcoin,
290
+ MLDSASecurityLevel.LEVEL2,
291
+ );
292
+ const wallet = mnemonic.derive(0);
293
+ const p2opAddress = wallet.address.p2op(networks.bitcoin);
294
+
295
+ // Try to validate mainnet address on testnet
296
+ const isValid = AddressVerificator.isValidP2OPAddress(p2opAddress, networks.testnet);
297
+
298
+ expect(isValid).toBe(false);
299
+ });
300
+ });
301
+
302
+ describe('detectAddressType - P2OP support', () => {
303
+ it('should detect mainnet P2OP address type', () => {
304
+ const mnemonic = new Mnemonic(
305
+ testMnemonic,
306
+ '',
307
+ networks.bitcoin,
308
+ MLDSASecurityLevel.LEVEL2,
309
+ );
310
+ const wallet = mnemonic.derive(0);
311
+ const p2opAddress = wallet.address.p2op(networks.bitcoin);
312
+
313
+ const addressType = AddressVerificator.detectAddressType(p2opAddress, networks.bitcoin);
314
+
315
+ expect(addressType).toBe(AddressTypes.P2OP);
316
+ });
317
+
318
+ it('should detect testnet P2OP address type', () => {
319
+ const mnemonic = new Mnemonic(
320
+ testMnemonic,
321
+ '',
322
+ networks.testnet,
323
+ MLDSASecurityLevel.LEVEL2,
324
+ );
325
+ const wallet = mnemonic.derive(0);
326
+ const p2opAddress = wallet.address.p2op(networks.testnet);
327
+
328
+ const addressType = AddressVerificator.detectAddressType(p2opAddress, networks.testnet);
329
+
330
+ expect(addressType).toBe(AddressTypes.P2OP);
331
+ });
332
+
333
+ it('should detect regtest P2OP address type', () => {
334
+ const mnemonic = new Mnemonic(
335
+ testMnemonic,
336
+ '',
337
+ networks.regtest,
338
+ MLDSASecurityLevel.LEVEL2,
339
+ );
340
+ const wallet = mnemonic.derive(0);
341
+ const p2opAddress = wallet.address.p2op(networks.regtest);
342
+
343
+ const addressType = AddressVerificator.detectAddressType(p2opAddress, networks.regtest);
344
+
345
+ expect(addressType).toBe(AddressTypes.P2OP);
346
+ });
347
+
348
+ it('should not confuse P2OP with P2TR', () => {
349
+ const mnemonic = new Mnemonic(
350
+ testMnemonic,
351
+ '',
352
+ networks.bitcoin,
353
+ MLDSASecurityLevel.LEVEL2,
354
+ );
355
+ const wallet = mnemonic.derive(0);
356
+
357
+ const p2opAddress = wallet.address.p2op(networks.bitcoin);
358
+ const p2trAddress = wallet.p2tr;
359
+
360
+ const p2opType = AddressVerificator.detectAddressType(p2opAddress, networks.bitcoin);
361
+ const p2trType = AddressVerificator.detectAddressType(p2trAddress, networks.bitcoin);
362
+
363
+ expect(p2opType).toBe(AddressTypes.P2OP);
364
+ expect(p2trType).toBe(AddressTypes.P2TR);
365
+ expect(p2opType).not.toBe(p2trType);
366
+ });
367
+
368
+ it('should not confuse P2OP with P2WPKH', () => {
369
+ const mnemonic = new Mnemonic(
370
+ testMnemonic,
371
+ '',
372
+ networks.bitcoin,
373
+ MLDSASecurityLevel.LEVEL2,
374
+ );
375
+ const wallet = mnemonic.derive(0);
376
+
377
+ const p2opAddress = wallet.address.p2op(networks.bitcoin);
378
+ const p2wpkhAddress = wallet.p2wpkh;
379
+
380
+ const p2opType = AddressVerificator.detectAddressType(p2opAddress, networks.bitcoin);
381
+ const p2wpkhType = AddressVerificator.detectAddressType(
382
+ p2wpkhAddress,
383
+ networks.bitcoin,
384
+ );
385
+
386
+ expect(p2opType).toBe(AddressTypes.P2OP);
387
+ expect(p2wpkhType).toBe(AddressTypes.P2WPKH);
388
+ expect(p2opType).not.toBe(p2wpkhType);
389
+ });
390
+
391
+ it('should detect P2OP for different security levels', () => {
392
+ const levels = [
393
+ MLDSASecurityLevel.LEVEL2,
394
+ MLDSASecurityLevel.LEVEL3,
395
+ MLDSASecurityLevel.LEVEL5,
396
+ ];
397
+
398
+ for (const level of levels) {
399
+ const mnemonic = new Mnemonic(testMnemonic, '', networks.bitcoin, level);
400
+ const wallet = mnemonic.derive(0);
401
+ const p2opAddress = wallet.address.p2op(networks.bitcoin);
402
+
403
+ const addressType = AddressVerificator.detectAddressType(
404
+ p2opAddress,
405
+ networks.bitcoin,
406
+ );
407
+
408
+ expect(addressType).toBe(AddressTypes.P2OP);
409
+ }
410
+ });
411
+
412
+ it('should return null for invalid P2OP address on wrong network', () => {
413
+ const mnemonic = new Mnemonic(
414
+ testMnemonic,
415
+ '',
416
+ networks.bitcoin,
417
+ MLDSASecurityLevel.LEVEL2,
418
+ );
419
+ const wallet = mnemonic.derive(0);
420
+ const p2opAddress = wallet.address.p2op(networks.bitcoin);
421
+
422
+ // Try to detect mainnet address on testnet
423
+ const addressType = AddressVerificator.detectAddressType(p2opAddress, networks.testnet);
424
+
425
+ expect(addressType).toBeNull();
426
+ });
427
+ });
428
+
429
+ describe('ML-DSA integration with other address types', () => {
430
+ it('should correctly identify different address types from same wallet', () => {
431
+ const mnemonic = new Mnemonic(
432
+ testMnemonic,
433
+ '',
434
+ networks.bitcoin,
435
+ MLDSASecurityLevel.LEVEL2,
436
+ );
437
+ const wallet = mnemonic.derive(0);
438
+
439
+ const p2trType = AddressVerificator.detectAddressType(wallet.p2tr, networks.bitcoin);
440
+ const p2wpkhType = AddressVerificator.detectAddressType(
441
+ wallet.p2wpkh,
442
+ networks.bitcoin,
443
+ );
444
+ const p2opType = AddressVerificator.detectAddressType(
445
+ wallet.address.p2op(networks.bitcoin),
446
+ networks.bitcoin,
447
+ );
448
+
449
+ expect(p2trType).toBe(AddressTypes.P2TR);
450
+ expect(p2wpkhType).toBe(AddressTypes.P2WPKH);
451
+ expect(p2opType).toBe(AddressTypes.P2OP);
452
+ });
453
+
454
+ it('should validate classical and ML-DSA public keys separately', () => {
455
+ const mnemonic = new Mnemonic(
456
+ testMnemonic,
457
+ '',
458
+ networks.bitcoin,
459
+ MLDSASecurityLevel.LEVEL2,
460
+ );
461
+ const wallet = mnemonic.derive(0);
462
+
463
+ const classicalValid = AddressVerificator.isValidPublicKey(
464
+ wallet.toPublicKeyHex(),
465
+ networks.bitcoin,
466
+ );
467
+ const mldsaLevel = AddressVerificator.isValidMLDSAPublicKey(wallet.quantumPublicKeyHex);
468
+
469
+ expect(classicalValid).toBe(true);
470
+ expect(mldsaLevel).toBe(MLDSASecurityLevel.LEVEL2);
471
+ });
472
+ });
473
+ });