@btc-vision/transaction 1.6.19 → 1.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (141) hide show
  1. package/browser/index.js +1 -1
  2. package/browser/index.js.LICENSE.txt +2 -0
  3. package/browser/src/_version.d.ts +1 -0
  4. package/browser/{epoch → src/epoch}/interfaces/IChallengeSolution.d.ts +2 -0
  5. package/browser/{keypair → src/keypair}/Address.d.ts +7 -4
  6. package/browser/{keypair → src/keypair}/AddressVerificator.d.ts +3 -0
  7. package/browser/{keypair → src/keypair}/EcKeyPair.d.ts +3 -2
  8. package/browser/{keypair → src/keypair}/MessageSigner.d.ts +9 -0
  9. package/browser/src/keypair/Wallet.d.ts +47 -0
  10. package/browser/{keypair → src/keypair}/interfaces/IWallet.d.ts +2 -0
  11. package/browser/src/mnemonic/Mnemonic.d.ts +29 -0
  12. package/browser/src/mnemonic/MnemonicStrength.d.ts +7 -0
  13. package/browser/{opnet.d.ts → src/opnet.d.ts} +4 -0
  14. package/browser/src/transaction/browser/types/OPWallet.d.ts +14 -0
  15. package/browser/test/address.test.d.ts +1 -0
  16. package/browser/test/addressverificator-mldsa.test.d.ts +1 -0
  17. package/browser/test/derivePath.test.d.ts +1 -0
  18. package/browser/test/messagesigner-mldsa.test.d.ts +1 -0
  19. package/browser/test/messagesigner-schnorr.test.d.ts +1 -0
  20. package/browser/test/network-awareness.test.d.ts +1 -0
  21. package/build/_version.d.ts +1 -1
  22. package/build/_version.js +1 -1
  23. package/build/crypto/crypto-browser.d.ts +11 -0
  24. package/build/crypto/crypto-browser.js +56 -0
  25. package/build/epoch/ChallengeSolution.js +3 -2
  26. package/build/epoch/interfaces/IChallengeSolution.d.ts +2 -0
  27. package/build/keypair/Address.d.ts +7 -4
  28. package/build/keypair/Address.js +88 -37
  29. package/build/keypair/AddressVerificator.d.ts +3 -0
  30. package/build/keypair/AddressVerificator.js +49 -1
  31. package/build/keypair/EcKeyPair.d.ts +3 -2
  32. package/build/keypair/EcKeyPair.js +17 -3
  33. package/build/keypair/MessageSigner.d.ts +9 -0
  34. package/build/keypair/MessageSigner.js +23 -0
  35. package/build/keypair/Wallet.d.ts +20 -3
  36. package/build/keypair/Wallet.js +108 -9
  37. package/build/keypair/interfaces/IWallet.d.ts +2 -0
  38. package/build/mnemonic/Mnemonic.d.ts +29 -0
  39. package/build/mnemonic/Mnemonic.js +98 -0
  40. package/build/mnemonic/MnemonicStrength.d.ts +7 -0
  41. package/build/mnemonic/MnemonicStrength.js +8 -0
  42. package/build/opnet.d.ts +4 -0
  43. package/build/opnet.js +4 -0
  44. package/build/transaction/browser/types/OPWallet.d.ts +14 -0
  45. package/build/transaction/browser/types/OPWallet.js +6 -0
  46. package/gulpfile.js +2 -2
  47. package/package.json +25 -17
  48. package/src/_version.ts +1 -1
  49. package/src/epoch/ChallengeSolution.ts +3 -2
  50. package/src/epoch/interfaces/IChallengeSolution.ts +2 -0
  51. package/src/keypair/Address.ts +145 -43
  52. package/src/keypair/AddressVerificator.ts +87 -2
  53. package/src/keypair/EcKeyPair.ts +58 -6
  54. package/src/keypair/MessageSigner.ts +58 -0
  55. package/src/keypair/Wallet.ts +339 -57
  56. package/src/keypair/interfaces/IWallet.ts +13 -3
  57. package/src/mnemonic/Mnemonic.ts +340 -0
  58. package/src/mnemonic/MnemonicStrength.ts +12 -0
  59. package/src/network/ChainId.ts +1 -4
  60. package/src/opnet.ts +16 -0
  61. package/src/transaction/browser/types/OPWallet.ts +73 -0
  62. package/test/address.test.ts +1068 -0
  63. package/test/addressverificator-mldsa.test.ts +473 -0
  64. package/test/derivePath.test.ts +234 -0
  65. package/test/messagesigner-mldsa.test.ts +1060 -0
  66. package/test/messagesigner-schnorr.test.ts +1011 -0
  67. package/test/network-awareness.test.ts +163 -0
  68. package/tsconfig.json +1 -1
  69. package/vitest.config.ts +21 -0
  70. package/browser/_version.d.ts +0 -1
  71. package/browser/keypair/Wallet.d.ts +0 -30
  72. /package/browser/{abi → src/abi}/ABICoder.d.ts +0 -0
  73. /package/browser/{buffer → src/buffer}/BinaryReader.d.ts +0 -0
  74. /package/browser/{buffer → src/buffer}/BinaryWriter.d.ts +0 -0
  75. /package/browser/{bytecode → src/bytecode}/Compressor.d.ts +0 -0
  76. /package/browser/{consensus → src/consensus}/Consensus.d.ts +0 -0
  77. /package/browser/{consensus → src/consensus}/ConsensusConfig.d.ts +0 -0
  78. /package/browser/{consensus → src/consensus}/metadata/RoswellConsensus.d.ts +0 -0
  79. /package/browser/{crypto → src/crypto}/crypto-browser.d.ts +0 -0
  80. /package/browser/{crypto → src/crypto}/crypto.d.ts +0 -0
  81. /package/browser/{deterministic → src/deterministic}/AddressMap.d.ts +0 -0
  82. /package/browser/{deterministic → src/deterministic}/AddressSet.d.ts +0 -0
  83. /package/browser/{deterministic → src/deterministic}/DeterministicMap.d.ts +0 -0
  84. /package/browser/{deterministic → src/deterministic}/DeterministicSet.d.ts +0 -0
  85. /package/browser/{deterministic → src/deterministic}/Map.d.ts +0 -0
  86. /package/browser/{epoch → src/epoch}/ChallengeSolution.d.ts +0 -0
  87. /package/browser/{epoch → src/epoch}/validator/EpochValidator.d.ts +0 -0
  88. /package/browser/{event → src/event}/NetEvent.d.ts +0 -0
  89. /package/browser/{generators → src/generators}/AddressGenerator.d.ts +0 -0
  90. /package/browser/{generators → src/generators}/Features.d.ts +0 -0
  91. /package/browser/{generators → src/generators}/Generator.d.ts +0 -0
  92. /package/browser/{generators → src/generators}/builders/CalldataGenerator.d.ts +0 -0
  93. /package/browser/{generators → src/generators}/builders/CustomGenerator.d.ts +0 -0
  94. /package/browser/{generators → src/generators}/builders/DeploymentGenerator.d.ts +0 -0
  95. /package/browser/{generators → src/generators}/builders/LegacyCalldataGenerator.d.ts +0 -0
  96. /package/browser/{generators → src/generators}/builders/MultiSignGenerator.d.ts +0 -0
  97. /package/browser/{generators → src/generators}/builders/P2WDAGenerator.d.ts +0 -0
  98. /package/browser/{index.d.ts → src/index.d.ts} +0 -0
  99. /package/browser/{keypair → src/keypair}/Secp256k1PointDeriver.d.ts +0 -0
  100. /package/browser/{metadata → src/metadata}/ContractBaseMetadata.d.ts +0 -0
  101. /package/browser/{metadata → src/metadata}/tokens.d.ts +0 -0
  102. /package/browser/{network → src/network}/ChainId.d.ts +0 -0
  103. /package/browser/{p2wda → src/p2wda}/P2WDADetector.d.ts +0 -0
  104. /package/browser/{signer → src/signer}/SignerUtils.d.ts +0 -0
  105. /package/browser/{signer → src/signer}/TweakedSigner.d.ts +0 -0
  106. /package/browser/{transaction → src/transaction}/ContractAddress.d.ts +0 -0
  107. /package/browser/{transaction → src/transaction}/TransactionFactory.d.ts +0 -0
  108. /package/browser/{transaction → src/transaction}/browser/BrowserSignerBase.d.ts +0 -0
  109. /package/browser/{transaction → src/transaction}/browser/Web3Provider.d.ts +0 -0
  110. /package/browser/{transaction → src/transaction}/browser/extensions/UnisatSigner.d.ts +0 -0
  111. /package/browser/{transaction → src/transaction}/browser/extensions/XverseSigner.d.ts +0 -0
  112. /package/browser/{transaction → src/transaction}/browser/types/Unisat.d.ts +0 -0
  113. /package/browser/{transaction → src/transaction}/browser/types/Xverse.d.ts +0 -0
  114. /package/browser/{transaction → src/transaction}/builders/CancelTransaction.d.ts +0 -0
  115. /package/browser/{transaction → src/transaction}/builders/ChallengeSolutionTransaction.d.ts +0 -0
  116. /package/browser/{transaction → src/transaction}/builders/CustomScriptTransaction.d.ts +0 -0
  117. /package/browser/{transaction → src/transaction}/builders/DeploymentTransaction.d.ts +0 -0
  118. /package/browser/{transaction → src/transaction}/builders/FundingTransaction.d.ts +0 -0
  119. /package/browser/{transaction → src/transaction}/builders/InteractionTransaction.d.ts +0 -0
  120. /package/browser/{transaction → src/transaction}/builders/InteractionTransactionP2WDA.d.ts +0 -0
  121. /package/browser/{transaction → src/transaction}/builders/MultiSignTransaction.d.ts +0 -0
  122. /package/browser/{transaction → src/transaction}/builders/SharedInteractionTransaction.d.ts +0 -0
  123. /package/browser/{transaction → src/transaction}/builders/TransactionBuilder.d.ts +0 -0
  124. /package/browser/{transaction → src/transaction}/enums/TransactionType.d.ts +0 -0
  125. /package/browser/{transaction → src/transaction}/interfaces/ITransactionParameters.d.ts +0 -0
  126. /package/browser/{transaction → src/transaction}/interfaces/Tap.d.ts +0 -0
  127. /package/browser/{transaction → src/transaction}/mineable/IP2WSHAddress.d.ts +0 -0
  128. /package/browser/{transaction → src/transaction}/mineable/TimelockGenerator.d.ts +0 -0
  129. /package/browser/{transaction → src/transaction}/processor/PsbtTransaction.d.ts +0 -0
  130. /package/browser/{transaction → src/transaction}/psbt/PSBTTypes.d.ts +0 -0
  131. /package/browser/{transaction → src/transaction}/shared/P2TR_MS.d.ts +0 -0
  132. /package/browser/{transaction → src/transaction}/shared/TweakedTransaction.d.ts +0 -0
  133. /package/browser/{utils → src/utils}/BitcoinUtils.d.ts +0 -0
  134. /package/browser/{utils → src/utils}/BufferHelper.d.ts +0 -0
  135. /package/browser/{utils → src/utils}/StringToBuffer.d.ts +0 -0
  136. /package/browser/{utils → src/utils}/lengths.d.ts +0 -0
  137. /package/browser/{utils → src/utils}/types.d.ts +0 -0
  138. /package/browser/{utxo → src/utxo}/OPNetLimitedProvider.d.ts +0 -0
  139. /package/browser/{utxo → src/utxo}/interfaces/BroadcastResponse.d.ts +0 -0
  140. /package/browser/{utxo → src/utxo}/interfaces/IUTXO.d.ts +0 -0
  141. /package/browser/{verification → src/verification}/TapscriptVerificator.d.ts +0 -0
@@ -0,0 +1,1011 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import { MessageSigner, MLDSASecurityLevel, Mnemonic } from '../build/opnet.js';
3
+ import { networks } from '@btc-vision/bitcoin';
4
+
5
+ describe('MessageSigner Schnorr', () => {
6
+ const testMnemonic =
7
+ 'abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about';
8
+
9
+ describe('sha256', () => {
10
+ it('should hash a string message', () => {
11
+ const message = 'Hello, OPNet!';
12
+ const hash = MessageSigner.sha256(Buffer.from(message, 'utf-8'));
13
+
14
+ expect(hash).toBeInstanceOf(Buffer);
15
+ expect(hash.length).toBe(32);
16
+ });
17
+
18
+ it('should hash a Buffer message', () => {
19
+ const message = Buffer.from('Hello, Buffer!', 'utf-8');
20
+ const hash = MessageSigner.sha256(message);
21
+
22
+ expect(hash).toBeInstanceOf(Buffer);
23
+ expect(hash.length).toBe(32);
24
+ });
25
+
26
+ it('should hash a Uint8Array message', () => {
27
+ const message = new Uint8Array([1, 2, 3, 4, 5]);
28
+ const hash = MessageSigner.sha256(message);
29
+
30
+ expect(hash).toBeInstanceOf(Buffer);
31
+ expect(hash.length).toBe(32);
32
+ });
33
+
34
+ it('should produce consistent hashes for same input', () => {
35
+ const message = 'Test message';
36
+ const hash1 = MessageSigner.sha256(Buffer.from(message, 'utf-8'));
37
+ const hash2 = MessageSigner.sha256(Buffer.from(message, 'utf-8'));
38
+
39
+ expect(hash1.toString('hex')).toBe(hash2.toString('hex'));
40
+ });
41
+
42
+ it('should produce different hashes for different inputs', () => {
43
+ const message1 = 'Message 1';
44
+ const message2 = 'Message 2';
45
+ const hash1 = MessageSigner.sha256(Buffer.from(message1, 'utf-8'));
46
+ const hash2 = MessageSigner.sha256(Buffer.from(message2, 'utf-8'));
47
+
48
+ expect(hash1.toString('hex')).not.toBe(hash2.toString('hex'));
49
+ });
50
+
51
+ it('should hash empty message', () => {
52
+ const message = Buffer.alloc(0);
53
+ const hash = MessageSigner.sha256(message);
54
+
55
+ expect(hash).toBeInstanceOf(Buffer);
56
+ expect(hash.length).toBe(32);
57
+ });
58
+ });
59
+
60
+ describe('signMessage - string input', () => {
61
+ it('should sign a UTF-8 string message', () => {
62
+ const mnemonic = new Mnemonic(
63
+ testMnemonic,
64
+ '',
65
+ networks.bitcoin,
66
+ MLDSASecurityLevel.LEVEL2,
67
+ );
68
+ const wallet = mnemonic.derive(0);
69
+
70
+ const message = 'Hello, OPNet!';
71
+ const signed = MessageSigner.signMessage(wallet.keypair, message);
72
+
73
+ expect(signed.signature).toBeInstanceOf(Uint8Array);
74
+ expect(signed.signature.length).toBe(64); // Schnorr signatures are 64 bytes
75
+ expect(signed.message).toBeInstanceOf(Uint8Array);
76
+ expect(signed.message.length).toBe(32); // SHA-256 hash
77
+ });
78
+
79
+ it('should sign an empty string', () => {
80
+ const mnemonic = new Mnemonic(
81
+ testMnemonic,
82
+ '',
83
+ networks.bitcoin,
84
+ MLDSASecurityLevel.LEVEL2,
85
+ );
86
+ const wallet = mnemonic.derive(0);
87
+
88
+ const message = '';
89
+ const signed = MessageSigner.signMessage(wallet.keypair, message);
90
+
91
+ expect(signed.signature.length).toBe(64);
92
+ expect(signed.message.length).toBe(32);
93
+ });
94
+
95
+ it('should sign a very long string', () => {
96
+ const mnemonic = new Mnemonic(
97
+ testMnemonic,
98
+ '',
99
+ networks.bitcoin,
100
+ MLDSASecurityLevel.LEVEL2,
101
+ );
102
+ const wallet = mnemonic.derive(0);
103
+
104
+ const message = 'A'.repeat(10000);
105
+ const signed = MessageSigner.signMessage(wallet.keypair, message);
106
+
107
+ expect(signed.signature.length).toBe(64);
108
+ expect(signed.message.length).toBe(32);
109
+ });
110
+
111
+ it('should sign a string with special characters', () => {
112
+ const mnemonic = new Mnemonic(
113
+ testMnemonic,
114
+ '',
115
+ networks.bitcoin,
116
+ MLDSASecurityLevel.LEVEL2,
117
+ );
118
+ const wallet = mnemonic.derive(0);
119
+
120
+ const message = '!@#$%^&*()_+-=[]{}|;:",.<>?/~`\n\t\r';
121
+ const signed = MessageSigner.signMessage(wallet.keypair, message);
122
+
123
+ expect(signed.signature.length).toBe(64);
124
+ expect(signed.message.length).toBe(32);
125
+ });
126
+
127
+ it('should sign a Unicode string', () => {
128
+ const mnemonic = new Mnemonic(
129
+ testMnemonic,
130
+ '',
131
+ networks.bitcoin,
132
+ MLDSASecurityLevel.LEVEL2,
133
+ );
134
+ const wallet = mnemonic.derive(0);
135
+
136
+ const message = '你好世界 🌍 مرحبا العالم';
137
+ const signed = MessageSigner.signMessage(wallet.keypair, message);
138
+
139
+ expect(signed.signature.length).toBe(64);
140
+ expect(signed.message.length).toBe(32);
141
+ });
142
+ });
143
+
144
+ describe('signMessage - Buffer input', () => {
145
+ it('should sign a Buffer message', () => {
146
+ const mnemonic = new Mnemonic(
147
+ testMnemonic,
148
+ '',
149
+ networks.bitcoin,
150
+ MLDSASecurityLevel.LEVEL2,
151
+ );
152
+ const wallet = mnemonic.derive(0);
153
+
154
+ const message = Buffer.from('Hello, Buffer!', 'utf-8');
155
+ const signed = MessageSigner.signMessage(wallet.keypair, message);
156
+
157
+ expect(signed.signature).toBeInstanceOf(Uint8Array);
158
+ expect(signed.signature.length).toBe(64);
159
+ expect(signed.message).toBeInstanceOf(Uint8Array);
160
+ expect(signed.message.length).toBe(32);
161
+ });
162
+
163
+ it('should sign a Buffer with binary data', () => {
164
+ const mnemonic = new Mnemonic(
165
+ testMnemonic,
166
+ '',
167
+ networks.bitcoin,
168
+ MLDSASecurityLevel.LEVEL2,
169
+ );
170
+ const wallet = mnemonic.derive(0);
171
+
172
+ const message = Buffer.from([0x00, 0x01, 0x02, 0xff, 0xfe, 0xfd]);
173
+ const signed = MessageSigner.signMessage(wallet.keypair, message);
174
+
175
+ expect(signed.signature.length).toBe(64);
176
+ expect(signed.message.length).toBe(32);
177
+ });
178
+
179
+ it('should sign a Buffer created from hex', () => {
180
+ const mnemonic = new Mnemonic(
181
+ testMnemonic,
182
+ '',
183
+ networks.bitcoin,
184
+ MLDSASecurityLevel.LEVEL2,
185
+ );
186
+ const wallet = mnemonic.derive(0);
187
+
188
+ const message = Buffer.from('deadbeef', 'hex');
189
+ const signed = MessageSigner.signMessage(wallet.keypair, message);
190
+
191
+ expect(signed.signature.length).toBe(64);
192
+ expect(signed.message.length).toBe(32);
193
+ });
194
+
195
+ it('should sign an empty Buffer', () => {
196
+ const mnemonic = new Mnemonic(
197
+ testMnemonic,
198
+ '',
199
+ networks.bitcoin,
200
+ MLDSASecurityLevel.LEVEL2,
201
+ );
202
+ const wallet = mnemonic.derive(0);
203
+
204
+ const message = Buffer.alloc(0);
205
+ const signed = MessageSigner.signMessage(wallet.keypair, message);
206
+
207
+ expect(signed.signature.length).toBe(64);
208
+ expect(signed.message.length).toBe(32);
209
+ });
210
+ });
211
+
212
+ describe('signMessage - Uint8Array input', () => {
213
+ it('should sign a Uint8Array message', () => {
214
+ const mnemonic = new Mnemonic(
215
+ testMnemonic,
216
+ '',
217
+ networks.bitcoin,
218
+ MLDSASecurityLevel.LEVEL2,
219
+ );
220
+ const wallet = mnemonic.derive(0);
221
+
222
+ const message = new Uint8Array([1, 2, 3, 4, 5]);
223
+ const signed = MessageSigner.signMessage(wallet.keypair, message);
224
+
225
+ expect(signed.signature).toBeInstanceOf(Uint8Array);
226
+ expect(signed.signature.length).toBe(64);
227
+ expect(signed.message).toBeInstanceOf(Uint8Array);
228
+ expect(signed.message.length).toBe(32);
229
+ });
230
+
231
+ it('should sign a Uint8Array with all byte values', () => {
232
+ const mnemonic = new Mnemonic(
233
+ testMnemonic,
234
+ '',
235
+ networks.bitcoin,
236
+ MLDSASecurityLevel.LEVEL2,
237
+ );
238
+ const wallet = mnemonic.derive(0);
239
+
240
+ const message = new Uint8Array(256);
241
+ for (let i = 0; i < 256; i++) {
242
+ message[i] = i;
243
+ }
244
+ const signed = MessageSigner.signMessage(wallet.keypair, message);
245
+
246
+ expect(signed.signature.length).toBe(64);
247
+ expect(signed.message.length).toBe(32);
248
+ });
249
+
250
+ it('should sign an empty Uint8Array', () => {
251
+ const mnemonic = new Mnemonic(
252
+ testMnemonic,
253
+ '',
254
+ networks.bitcoin,
255
+ MLDSASecurityLevel.LEVEL2,
256
+ );
257
+ const wallet = mnemonic.derive(0);
258
+
259
+ const message = new Uint8Array(0);
260
+ const signed = MessageSigner.signMessage(wallet.keypair, message);
261
+
262
+ expect(signed.signature.length).toBe(64);
263
+ expect(signed.message.length).toBe(32);
264
+ });
265
+ });
266
+
267
+ describe('signMessage - signature uniqueness', () => {
268
+ it('should produce different signatures for different messages', () => {
269
+ const mnemonic = new Mnemonic(
270
+ testMnemonic,
271
+ '',
272
+ networks.bitcoin,
273
+ MLDSASecurityLevel.LEVEL2,
274
+ );
275
+ const wallet = mnemonic.derive(0);
276
+
277
+ const message1 = 'First message';
278
+ const message2 = 'Second message';
279
+
280
+ const signed1 = MessageSigner.signMessage(wallet.keypair, message1);
281
+ const signed2 = MessageSigner.signMessage(wallet.keypair, message2);
282
+
283
+ expect(Buffer.from(signed1.signature).toString('hex')).not.toBe(
284
+ Buffer.from(signed2.signature).toString('hex'),
285
+ );
286
+ });
287
+
288
+ it('should produce different signatures for different keypairs', () => {
289
+ const mnemonic = new Mnemonic(
290
+ testMnemonic,
291
+ '',
292
+ networks.bitcoin,
293
+ MLDSASecurityLevel.LEVEL2,
294
+ );
295
+ const wallet1 = mnemonic.derive(0);
296
+ const wallet2 = mnemonic.derive(1);
297
+
298
+ const message = 'Same message';
299
+
300
+ const signed1 = MessageSigner.signMessage(wallet1.keypair, message);
301
+ const signed2 = MessageSigner.signMessage(wallet2.keypair, message);
302
+
303
+ expect(Buffer.from(signed1.signature).toString('hex')).not.toBe(
304
+ Buffer.from(signed2.signature).toString('hex'),
305
+ );
306
+ });
307
+
308
+ it('should hash the message before signing', () => {
309
+ const mnemonic = new Mnemonic(
310
+ testMnemonic,
311
+ '',
312
+ networks.bitcoin,
313
+ MLDSASecurityLevel.LEVEL2,
314
+ );
315
+ const wallet = mnemonic.derive(0);
316
+
317
+ const message = 'Test message';
318
+ const signed = MessageSigner.signMessage(wallet.keypair, message);
319
+
320
+ const expectedHash = MessageSigner.sha256(Buffer.from(message, 'utf-8'));
321
+ expect(Buffer.from(signed.message).toString('hex')).toBe(expectedHash.toString('hex'));
322
+ });
323
+ });
324
+
325
+ describe('verifySignature - string input', () => {
326
+ it('should verify a valid signature with string message', () => {
327
+ const mnemonic = new Mnemonic(
328
+ testMnemonic,
329
+ '',
330
+ networks.bitcoin,
331
+ MLDSASecurityLevel.LEVEL2,
332
+ );
333
+ const wallet = mnemonic.derive(0);
334
+
335
+ const message = 'Hello, OPNet!';
336
+ const signed = MessageSigner.signMessage(wallet.keypair, message);
337
+
338
+ const isValid = MessageSigner.verifySignature(
339
+ wallet.keypair.publicKey,
340
+ message,
341
+ signed.signature,
342
+ );
343
+
344
+ expect(isValid).toBe(true);
345
+ });
346
+
347
+ it('should verify signature with Unicode string', () => {
348
+ const mnemonic = new Mnemonic(
349
+ testMnemonic,
350
+ '',
351
+ networks.bitcoin,
352
+ MLDSASecurityLevel.LEVEL2,
353
+ );
354
+ const wallet = mnemonic.derive(0);
355
+
356
+ const message = '你好世界 🌍';
357
+ const signed = MessageSigner.signMessage(wallet.keypair, message);
358
+
359
+ const isValid = MessageSigner.verifySignature(
360
+ wallet.keypair.publicKey,
361
+ message,
362
+ signed.signature,
363
+ );
364
+
365
+ expect(isValid).toBe(true);
366
+ });
367
+
368
+ it('should fail verification with wrong message', () => {
369
+ const mnemonic = new Mnemonic(
370
+ testMnemonic,
371
+ '',
372
+ networks.bitcoin,
373
+ MLDSASecurityLevel.LEVEL2,
374
+ );
375
+ const wallet = mnemonic.derive(0);
376
+
377
+ const message = 'Hello, OPNet!';
378
+ const wrongMessage = 'Wrong message';
379
+ const signed = MessageSigner.signMessage(wallet.keypair, message);
380
+
381
+ const isValid = MessageSigner.verifySignature(
382
+ wallet.keypair.publicKey,
383
+ wrongMessage,
384
+ signed.signature,
385
+ );
386
+
387
+ expect(isValid).toBe(false);
388
+ });
389
+ });
390
+
391
+ describe('verifySignature - Buffer input', () => {
392
+ it('should verify a valid signature with Buffer message', () => {
393
+ const mnemonic = new Mnemonic(
394
+ testMnemonic,
395
+ '',
396
+ networks.bitcoin,
397
+ MLDSASecurityLevel.LEVEL2,
398
+ );
399
+ const wallet = mnemonic.derive(0);
400
+
401
+ const message = Buffer.from('Hello, Buffer!', 'utf-8');
402
+ const signed = MessageSigner.signMessage(wallet.keypair, message);
403
+
404
+ const isValid = MessageSigner.verifySignature(
405
+ wallet.keypair.publicKey,
406
+ message,
407
+ signed.signature,
408
+ );
409
+
410
+ expect(isValid).toBe(true);
411
+ });
412
+
413
+ it('should verify signature with binary Buffer', () => {
414
+ const mnemonic = new Mnemonic(
415
+ testMnemonic,
416
+ '',
417
+ networks.bitcoin,
418
+ MLDSASecurityLevel.LEVEL2,
419
+ );
420
+ const wallet = mnemonic.derive(0);
421
+
422
+ const message = Buffer.from([0x00, 0x01, 0x02, 0xff]);
423
+ const signed = MessageSigner.signMessage(wallet.keypair, message);
424
+
425
+ const isValid = MessageSigner.verifySignature(
426
+ wallet.keypair.publicKey,
427
+ message,
428
+ signed.signature,
429
+ );
430
+
431
+ expect(isValid).toBe(true);
432
+ });
433
+ });
434
+
435
+ describe('verifySignature - Uint8Array input', () => {
436
+ it('should verify a valid signature with Uint8Array message', () => {
437
+ const mnemonic = new Mnemonic(
438
+ testMnemonic,
439
+ '',
440
+ networks.bitcoin,
441
+ MLDSASecurityLevel.LEVEL2,
442
+ );
443
+ const wallet = mnemonic.derive(0);
444
+
445
+ const message = new Uint8Array([1, 2, 3, 4, 5]);
446
+ const signed = MessageSigner.signMessage(wallet.keypair, message);
447
+
448
+ const isValid = MessageSigner.verifySignature(
449
+ wallet.keypair.publicKey,
450
+ message,
451
+ signed.signature,
452
+ );
453
+
454
+ expect(isValid).toBe(true);
455
+ });
456
+
457
+ it('should verify signature with Uint8Array public key', () => {
458
+ const mnemonic = new Mnemonic(
459
+ testMnemonic,
460
+ '',
461
+ networks.bitcoin,
462
+ MLDSASecurityLevel.LEVEL2,
463
+ );
464
+ const wallet = mnemonic.derive(0);
465
+
466
+ const message = 'Test message';
467
+ const signed = MessageSigner.signMessage(wallet.keypair, message);
468
+
469
+ const publicKeyUint8 = new Uint8Array(wallet.keypair.publicKey);
470
+ const isValid = MessageSigner.verifySignature(
471
+ publicKeyUint8,
472
+ message,
473
+ signed.signature,
474
+ );
475
+
476
+ expect(isValid).toBe(true);
477
+ });
478
+ });
479
+
480
+ describe('verifySignature - error cases', () => {
481
+ it('should throw error for invalid signature length', () => {
482
+ const mnemonic = new Mnemonic(
483
+ testMnemonic,
484
+ '',
485
+ networks.bitcoin,
486
+ MLDSASecurityLevel.LEVEL2,
487
+ );
488
+ const wallet = mnemonic.derive(0);
489
+
490
+ const message = 'Test message';
491
+ const invalidSignature = Buffer.alloc(32); // Wrong length
492
+
493
+ expect(() => {
494
+ MessageSigner.verifySignature(wallet.keypair.publicKey, message, invalidSignature);
495
+ }).toThrow('Invalid signature length');
496
+ });
497
+
498
+ it('should fail verification with wrong public key', () => {
499
+ const mnemonic = new Mnemonic(
500
+ testMnemonic,
501
+ '',
502
+ networks.bitcoin,
503
+ MLDSASecurityLevel.LEVEL2,
504
+ );
505
+ const wallet1 = mnemonic.derive(0);
506
+ const wallet2 = mnemonic.derive(1);
507
+
508
+ const message = 'Test message';
509
+ const signed = MessageSigner.signMessage(wallet1.keypair, message);
510
+
511
+ const isValid = MessageSigner.verifySignature(
512
+ wallet2.keypair.publicKey,
513
+ message,
514
+ signed.signature,
515
+ );
516
+
517
+ expect(isValid).toBe(false);
518
+ });
519
+
520
+ it('should fail verification with corrupted signature', () => {
521
+ const mnemonic = new Mnemonic(
522
+ testMnemonic,
523
+ '',
524
+ networks.bitcoin,
525
+ MLDSASecurityLevel.LEVEL2,
526
+ );
527
+ const wallet = mnemonic.derive(0);
528
+
529
+ const message = 'Test message';
530
+ const signed = MessageSigner.signMessage(wallet.keypair, message);
531
+
532
+ const corruptedSignature = Buffer.from(signed.signature);
533
+ corruptedSignature[0] ^= 0xff;
534
+
535
+ const isValid = MessageSigner.verifySignature(
536
+ wallet.keypair.publicKey,
537
+ message,
538
+ corruptedSignature,
539
+ );
540
+
541
+ expect(isValid).toBe(false);
542
+ });
543
+ });
544
+
545
+ describe('tweakAndSignMessage', () => {
546
+ it('should sign a message with tweaked keypair', () => {
547
+ const mnemonic = new Mnemonic(
548
+ testMnemonic,
549
+ '',
550
+ networks.bitcoin,
551
+ MLDSASecurityLevel.LEVEL2,
552
+ );
553
+ const wallet = mnemonic.derive(0);
554
+
555
+ const message = 'Hello, Tweaked OPNet!';
556
+ const signed = MessageSigner.tweakAndSignMessage(
557
+ wallet.keypair,
558
+ message,
559
+ networks.bitcoin,
560
+ );
561
+
562
+ expect(signed.signature).toBeInstanceOf(Uint8Array);
563
+ expect(signed.signature.length).toBe(64);
564
+ expect(signed.message).toBeInstanceOf(Uint8Array);
565
+ expect(signed.message.length).toBe(32);
566
+ });
567
+
568
+ it('should sign with tweaked key - string message', () => {
569
+ const mnemonic = new Mnemonic(
570
+ testMnemonic,
571
+ '',
572
+ networks.bitcoin,
573
+ MLDSASecurityLevel.LEVEL2,
574
+ );
575
+ const wallet = mnemonic.derive(0);
576
+
577
+ const message = 'Test tweaked';
578
+ const signed = MessageSigner.tweakAndSignMessage(
579
+ wallet.keypair,
580
+ message,
581
+ networks.bitcoin,
582
+ );
583
+
584
+ expect(signed.signature.length).toBe(64);
585
+ expect(signed.message.length).toBe(32);
586
+ });
587
+
588
+ it('should sign with tweaked key - Buffer message', () => {
589
+ const mnemonic = new Mnemonic(
590
+ testMnemonic,
591
+ '',
592
+ networks.bitcoin,
593
+ MLDSASecurityLevel.LEVEL2,
594
+ );
595
+ const wallet = mnemonic.derive(0);
596
+
597
+ const message = Buffer.from('Test tweaked buffer', 'utf-8');
598
+ const signed = MessageSigner.tweakAndSignMessage(
599
+ wallet.keypair,
600
+ message,
601
+ networks.bitcoin,
602
+ );
603
+
604
+ expect(signed.signature.length).toBe(64);
605
+ expect(signed.message.length).toBe(32);
606
+ });
607
+
608
+ it('should sign with tweaked key - Uint8Array message', () => {
609
+ const mnemonic = new Mnemonic(
610
+ testMnemonic,
611
+ '',
612
+ networks.bitcoin,
613
+ MLDSASecurityLevel.LEVEL2,
614
+ );
615
+ const wallet = mnemonic.derive(0);
616
+
617
+ const message = new Uint8Array([1, 2, 3, 4, 5]);
618
+ const signed = MessageSigner.tweakAndSignMessage(
619
+ wallet.keypair,
620
+ message,
621
+ networks.bitcoin,
622
+ );
623
+
624
+ expect(signed.signature.length).toBe(64);
625
+ expect(signed.message.length).toBe(32);
626
+ });
627
+
628
+ it('should produce different signature than non-tweaked', () => {
629
+ const mnemonic = new Mnemonic(
630
+ testMnemonic,
631
+ '',
632
+ networks.bitcoin,
633
+ MLDSASecurityLevel.LEVEL2,
634
+ );
635
+ const wallet = mnemonic.derive(0);
636
+
637
+ const message = 'Compare tweaked vs non-tweaked';
638
+ const signed = MessageSigner.signMessage(wallet.keypair, message);
639
+ const tweakedSigned = MessageSigner.tweakAndSignMessage(
640
+ wallet.keypair,
641
+ message,
642
+ networks.bitcoin,
643
+ );
644
+
645
+ expect(Buffer.from(signed.signature).toString('hex')).not.toBe(
646
+ Buffer.from(tweakedSigned.signature).toString('hex'),
647
+ );
648
+ });
649
+
650
+ it('should work on different networks', () => {
651
+ const networks_list = [networks.bitcoin, networks.testnet, networks.regtest];
652
+
653
+ for (const network of networks_list) {
654
+ const mnemonic = new Mnemonic(testMnemonic, '', network, MLDSASecurityLevel.LEVEL2);
655
+ const wallet = mnemonic.derive(0);
656
+
657
+ const message = 'Test network ' + network.bech32;
658
+ const signed = MessageSigner.tweakAndSignMessage(wallet.keypair, message, network);
659
+
660
+ expect(signed.signature.length).toBe(64);
661
+ expect(signed.message.length).toBe(32);
662
+ }
663
+ });
664
+ });
665
+
666
+ describe('tweakAndVerifySignature', () => {
667
+ it('should verify a tweaked signature', () => {
668
+ const mnemonic = new Mnemonic(
669
+ testMnemonic,
670
+ '',
671
+ networks.bitcoin,
672
+ MLDSASecurityLevel.LEVEL2,
673
+ );
674
+ const wallet = mnemonic.derive(0);
675
+
676
+ const message = 'Test tweaked verification';
677
+ const signed = MessageSigner.tweakAndSignMessage(
678
+ wallet.keypair,
679
+ message,
680
+ networks.bitcoin,
681
+ );
682
+
683
+ const isValid = MessageSigner.tweakAndVerifySignature(
684
+ wallet.keypair.publicKey,
685
+ message,
686
+ signed.signature,
687
+ );
688
+
689
+ expect(isValid).toBe(true);
690
+ });
691
+
692
+ it('should verify tweaked signature with Buffer message', () => {
693
+ const mnemonic = new Mnemonic(
694
+ testMnemonic,
695
+ '',
696
+ networks.bitcoin,
697
+ MLDSASecurityLevel.LEVEL2,
698
+ );
699
+ const wallet = mnemonic.derive(0);
700
+
701
+ const message = Buffer.from('Test tweaked buffer', 'utf-8');
702
+ const signed = MessageSigner.tweakAndSignMessage(
703
+ wallet.keypair,
704
+ message,
705
+ networks.bitcoin,
706
+ );
707
+
708
+ const isValid = MessageSigner.tweakAndVerifySignature(
709
+ wallet.keypair.publicKey,
710
+ message,
711
+ signed.signature,
712
+ );
713
+
714
+ expect(isValid).toBe(true);
715
+ });
716
+
717
+ it('should verify tweaked signature with Uint8Array message', () => {
718
+ const mnemonic = new Mnemonic(
719
+ testMnemonic,
720
+ '',
721
+ networks.bitcoin,
722
+ MLDSASecurityLevel.LEVEL2,
723
+ );
724
+ const wallet = mnemonic.derive(0);
725
+
726
+ const message = new Uint8Array([5, 4, 3, 2, 1]);
727
+ const signed = MessageSigner.tweakAndSignMessage(
728
+ wallet.keypair,
729
+ message,
730
+ networks.bitcoin,
731
+ );
732
+
733
+ const isValid = MessageSigner.tweakAndVerifySignature(
734
+ wallet.keypair.publicKey,
735
+ message,
736
+ signed.signature,
737
+ );
738
+
739
+ expect(isValid).toBe(true);
740
+ });
741
+
742
+ it('should fail verification with wrong message', () => {
743
+ const mnemonic = new Mnemonic(
744
+ testMnemonic,
745
+ '',
746
+ networks.bitcoin,
747
+ MLDSASecurityLevel.LEVEL2,
748
+ );
749
+ const wallet = mnemonic.derive(0);
750
+
751
+ const message = 'Correct message';
752
+ const wrongMessage = 'Wrong message';
753
+ const signed = MessageSigner.tweakAndSignMessage(
754
+ wallet.keypair,
755
+ message,
756
+ networks.bitcoin,
757
+ );
758
+
759
+ const isValid = MessageSigner.tweakAndVerifySignature(
760
+ wallet.keypair.publicKey,
761
+ wrongMessage,
762
+ signed.signature,
763
+ );
764
+
765
+ expect(isValid).toBe(false);
766
+ });
767
+
768
+ it('should fail verification with wrong public key', () => {
769
+ const mnemonic = new Mnemonic(
770
+ testMnemonic,
771
+ '',
772
+ networks.bitcoin,
773
+ MLDSASecurityLevel.LEVEL2,
774
+ );
775
+ const wallet1 = mnemonic.derive(0);
776
+ const wallet2 = mnemonic.derive(1);
777
+
778
+ const message = 'Test message';
779
+ const signed = MessageSigner.tweakAndSignMessage(
780
+ wallet1.keypair,
781
+ message,
782
+ networks.bitcoin,
783
+ );
784
+
785
+ const isValid = MessageSigner.tweakAndVerifySignature(
786
+ wallet2.keypair.publicKey,
787
+ message,
788
+ signed.signature,
789
+ );
790
+
791
+ expect(isValid).toBe(false);
792
+ });
793
+
794
+ it('should not verify non-tweaked signature with tweakAndVerifySignature', () => {
795
+ const mnemonic = new Mnemonic(
796
+ testMnemonic,
797
+ '',
798
+ networks.bitcoin,
799
+ MLDSASecurityLevel.LEVEL2,
800
+ );
801
+ const wallet = mnemonic.derive(0);
802
+
803
+ const message = 'Test message';
804
+ const signed = MessageSigner.signMessage(wallet.keypair, message);
805
+
806
+ const isValid = MessageSigner.tweakAndVerifySignature(
807
+ wallet.keypair.publicKey,
808
+ message,
809
+ signed.signature,
810
+ );
811
+
812
+ expect(isValid).toBe(false);
813
+ });
814
+
815
+ it('should verify with Uint8Array public key', () => {
816
+ const mnemonic = new Mnemonic(
817
+ testMnemonic,
818
+ '',
819
+ networks.bitcoin,
820
+ MLDSASecurityLevel.LEVEL2,
821
+ );
822
+ const wallet = mnemonic.derive(0);
823
+
824
+ const message = 'Test message';
825
+ const signed = MessageSigner.tweakAndSignMessage(
826
+ wallet.keypair,
827
+ message,
828
+ networks.bitcoin,
829
+ );
830
+
831
+ const publicKeyUint8 = new Uint8Array(wallet.keypair.publicKey);
832
+ const isValid = MessageSigner.tweakAndVerifySignature(
833
+ publicKeyUint8,
834
+ message,
835
+ signed.signature,
836
+ );
837
+
838
+ expect(isValid).toBe(true);
839
+ });
840
+ });
841
+
842
+ describe('cross-validation between tweaked and non-tweaked', () => {
843
+ it('should not cross-verify tweaked signature with regular verify', () => {
844
+ const mnemonic = new Mnemonic(
845
+ testMnemonic,
846
+ '',
847
+ networks.bitcoin,
848
+ MLDSASecurityLevel.LEVEL2,
849
+ );
850
+ const wallet = mnemonic.derive(0);
851
+
852
+ const message = 'Test message';
853
+ const tweakedSigned = MessageSigner.tweakAndSignMessage(
854
+ wallet.keypair,
855
+ message,
856
+ networks.bitcoin,
857
+ );
858
+
859
+ const isValid = MessageSigner.verifySignature(
860
+ wallet.keypair.publicKey,
861
+ message,
862
+ tweakedSigned.signature,
863
+ );
864
+
865
+ expect(isValid).toBe(false);
866
+ });
867
+
868
+ it('should verify regular signature with regular verify, not with tweaked verify', () => {
869
+ const mnemonic = new Mnemonic(
870
+ testMnemonic,
871
+ '',
872
+ networks.bitcoin,
873
+ MLDSASecurityLevel.LEVEL2,
874
+ );
875
+ const wallet = mnemonic.derive(0);
876
+
877
+ const message = 'Test message';
878
+ const signed = MessageSigner.signMessage(wallet.keypair, message);
879
+
880
+ const isValidRegular = MessageSigner.verifySignature(
881
+ wallet.keypair.publicKey,
882
+ message,
883
+ signed.signature,
884
+ );
885
+ const isValidTweaked = MessageSigner.tweakAndVerifySignature(
886
+ wallet.keypair.publicKey,
887
+ message,
888
+ signed.signature,
889
+ );
890
+
891
+ expect(isValidRegular).toBe(true);
892
+ expect(isValidTweaked).toBe(false);
893
+ });
894
+ });
895
+
896
+ describe('network-specific tweaked signatures', () => {
897
+ it('should produce different tweaked signatures for different networks', () => {
898
+ const message = 'Network test';
899
+
900
+ const mnemonicMainnet = new Mnemonic(
901
+ testMnemonic,
902
+ '',
903
+ networks.bitcoin,
904
+ MLDSASecurityLevel.LEVEL2,
905
+ );
906
+ const mnemonicTestnet = new Mnemonic(
907
+ testMnemonic,
908
+ '',
909
+ networks.testnet,
910
+ MLDSASecurityLevel.LEVEL2,
911
+ );
912
+
913
+ const walletMainnet = mnemonicMainnet.derive(0);
914
+ const walletTestnet = mnemonicTestnet.derive(0);
915
+
916
+ const signedMainnet = MessageSigner.tweakAndSignMessage(
917
+ walletMainnet.keypair,
918
+ message,
919
+ networks.bitcoin,
920
+ );
921
+ const signedTestnet = MessageSigner.tweakAndSignMessage(
922
+ walletTestnet.keypair,
923
+ message,
924
+ networks.testnet,
925
+ );
926
+
927
+ // Signatures should be different
928
+ expect(Buffer.from(signedMainnet.signature).toString('hex')).not.toBe(
929
+ Buffer.from(signedTestnet.signature).toString('hex'),
930
+ );
931
+
932
+ // Each should verify with its own network's tweaked key
933
+ expect(
934
+ MessageSigner.tweakAndVerifySignature(
935
+ walletMainnet.keypair.publicKey,
936
+ message,
937
+ signedMainnet.signature,
938
+ ),
939
+ ).toBe(true);
940
+ expect(
941
+ MessageSigner.tweakAndVerifySignature(
942
+ walletTestnet.keypair.publicKey,
943
+ message,
944
+ signedTestnet.signature,
945
+ ),
946
+ ).toBe(true);
947
+ });
948
+ });
949
+
950
+ describe('message format edge cases', () => {
951
+ it('should handle messages with null bytes', () => {
952
+ const mnemonic = new Mnemonic(
953
+ testMnemonic,
954
+ '',
955
+ networks.bitcoin,
956
+ MLDSASecurityLevel.LEVEL2,
957
+ );
958
+ const wallet = mnemonic.derive(0);
959
+
960
+ const message = Buffer.from([0x00, 0x01, 0x00, 0x02, 0x00]);
961
+ const signed = MessageSigner.signMessage(wallet.keypair, message);
962
+ const isValid = MessageSigner.verifySignature(
963
+ wallet.keypair.publicKey,
964
+ message,
965
+ signed.signature,
966
+ );
967
+
968
+ expect(isValid).toBe(true);
969
+ });
970
+
971
+ it('should handle very long messages', () => {
972
+ const mnemonic = new Mnemonic(
973
+ testMnemonic,
974
+ '',
975
+ networks.bitcoin,
976
+ MLDSASecurityLevel.LEVEL2,
977
+ );
978
+ const wallet = mnemonic.derive(0);
979
+
980
+ const message = 'X'.repeat(100000);
981
+ const signed = MessageSigner.signMessage(wallet.keypair, message);
982
+ const isValid = MessageSigner.verifySignature(
983
+ wallet.keypair.publicKey,
984
+ message,
985
+ signed.signature,
986
+ );
987
+
988
+ expect(isValid).toBe(true);
989
+ });
990
+
991
+ it('should handle messages with emoji', () => {
992
+ const mnemonic = new Mnemonic(
993
+ testMnemonic,
994
+ '',
995
+ networks.bitcoin,
996
+ MLDSASecurityLevel.LEVEL2,
997
+ );
998
+ const wallet = mnemonic.derive(0);
999
+
1000
+ const message = '🚀🌙⭐🪐💫';
1001
+ const signed = MessageSigner.signMessage(wallet.keypair, message);
1002
+ const isValid = MessageSigner.verifySignature(
1003
+ wallet.keypair.publicKey,
1004
+ message,
1005
+ signed.signature,
1006
+ );
1007
+
1008
+ expect(isValid).toBe(true);
1009
+ });
1010
+ });
1011
+ });