@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.
- package/browser/index.js +1 -1
- package/browser/src/_version.d.ts +1 -1
- package/browser/src/mnemonic/BIPStandard.d.ts +8 -0
- package/browser/src/mnemonic/Mnemonic.d.ts +7 -2
- package/browser/src/opnet.d.ts +1 -0
- package/build/_version.d.ts +1 -1
- package/build/_version.js +1 -1
- package/build/mnemonic/BIPStandard.d.ts +8 -0
- package/build/mnemonic/BIPStandard.js +24 -0
- package/build/mnemonic/Mnemonic.d.ts +7 -2
- package/build/mnemonic/Mnemonic.js +48 -6
- package/build/opnet.d.ts +1 -0
- package/build/opnet.js +1 -0
- package/documentation/README.md +32 -0
- package/documentation/quantum-support/01-introduction.md +88 -0
- package/documentation/quantum-support/02-mnemonic-and-wallet.md +445 -0
- package/documentation/quantum-support/03-address-generation.md +329 -0
- package/documentation/quantum-support/04-message-signing.md +623 -0
- package/documentation/quantum-support/05-address-verification.md +307 -0
- package/documentation/quantum-support/README.md +65 -0
- package/package.json +1 -1
- package/src/_version.ts +1 -1
- package/src/mnemonic/BIPStandard.ts +92 -0
- package/src/mnemonic/Mnemonic.ts +133 -8
- package/src/opnet.ts +1 -0
- package/test/derivePath.test.ts +280 -1
- package/doc/README.md +0 -0
- /package/{doc → documentation}/addresses/P2OP.md +0 -0
- /package/{doc → documentation}/addresses/P2WDA.md +0 -0
package/test/derivePath.test.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { describe, expect, it } from 'vitest';
|
|
2
|
-
import { MLDSASecurityLevel, Mnemonic } from '../build/opnet.js';
|
|
2
|
+
import { AddressTypes, MLDSASecurityLevel, Mnemonic } from '../build/opnet.js';
|
|
3
3
|
import { networks } from '@btc-vision/bitcoin';
|
|
4
4
|
|
|
5
5
|
describe('Wallet.derivePath', () => {
|
|
@@ -232,3 +232,282 @@ describe('Wallet.derivePath', () => {
|
|
|
232
232
|
});
|
|
233
233
|
});
|
|
234
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
|
+
});
|
package/doc/README.md
DELETED
|
File without changes
|
|
File without changes
|
|
File without changes
|