11import * as assert from 'assert' ;
22import BIP32Factory from 'bip32' ;
33import * as bip39 from 'bip39' ;
4- import ECPairFactory from 'ecpair' ;
54import * as ecc from 'tiny-secp256k1' ;
65import { describe , it } from 'mocha' ;
7- import { PsbtInput , TapLeafScript } from 'bip174/src/lib/interfaces' ;
6+ import { PsbtInput , TapLeaf , TapLeafScript } from 'bip174/src/lib/interfaces' ;
87import { regtestUtils } from './_regtest' ;
98import * as bitcoin from '../..' ;
109import { Taptree } from '../../src/types' ;
10+ import { LEAF_VERSION_TAPSCRIPT } from '../../src/payments/bip341' ;
1111import { toXOnly , tapTreeToList , tapTreeFromList } from '../../src/psbt/bip371' ;
1212import { witnessStackToScriptWitness } from '../../src/psbt/psbtutils' ;
13- import { TapLeaf } from 'bip174/src/lib/interfaces' ;
1413
1514const rng = require ( 'randombytes' ) ;
1615const regtest = regtestUtils . network ;
1716bitcoin . initEccLib ( ecc ) ;
1817const bip32 = BIP32Factory ( ecc ) ;
19- const ECPair = ECPairFactory ( ecc ) ;
2018
2119describe ( 'bitcoinjs-lib (transaction with taproot)' , ( ) => {
2220 it ( 'can verify the BIP86 HD wallet vectors for taproot single sig (& sending example)' , async ( ) => {
@@ -39,7 +37,7 @@ describe('bitcoinjs-lib (transaction with taproot)', () => {
3937 assert . strictEqual ( rootKey . toBase58 ( ) , xprv ) ;
4038 const childNode = rootKey . derivePath ( path ) ;
4139 // Since internalKey is an xOnly pubkey, we drop the DER header byte
42- const childNodeXOnlyPubkey = childNode . publicKey . slice ( 1 , 33 ) ;
40+ const childNodeXOnlyPubkey = toXOnly ( childNode . publicKey ) ;
4341 assert . deepEqual ( childNodeXOnlyPubkey , internalPubkey ) ;
4442
4543 // This is new for taproot
@@ -139,7 +137,9 @@ describe('bitcoinjs-lib (transaction with taproot)', () => {
139137 tapInternalKey : sendPubKey ,
140138 } ) ;
141139
142- const tweakedSigner = tweakSigner ( internalKey ! , { network : regtest } ) ;
140+ const tweakedSigner = internalKey . tweak (
141+ bitcoin . crypto . taggedHash ( 'TapTweak' , toXOnly ( internalKey . publicKey ) ) ,
142+ ) ;
143143 await psbt . signInputAsync ( 0 , tweakedSigner ) ;
144144 await psbt . signInputAsync ( 1 , p2pkhKey ) ;
145145
@@ -194,10 +194,12 @@ describe('bitcoinjs-lib (transaction with taproot)', () => {
194194 } ) ;
195195 psbt . addOutput ( { value : sendAmount , address : address ! } ) ;
196196
197- const tweakedSigner = tweakSigner ( internalKey ! , {
198- tweakHash : hash ,
199- network : regtest ,
200- } ) ;
197+ const tweakedSigner = internalKey . tweak (
198+ bitcoin . crypto . taggedHash (
199+ 'TapTweak' ,
200+ Buffer . concat ( [ toXOnly ( internalKey . publicKey ) , hash ! ] ) ,
201+ ) ,
202+ ) ;
201203 psbt . signInput ( 0 , tweakedSigner ) ;
202204
203205 psbt . finalizeAllInputs ( ) ;
@@ -271,7 +273,7 @@ describe('bitcoinjs-lib (transaction with taproot)', () => {
271273 ] ;
272274 const redeem = {
273275 output : leafScript ,
274- redeemVersion : 192 ,
276+ redeemVersion : LEAF_VERSION_TAPSCRIPT ,
275277 } ;
276278
277279 const { output, witness } = bitcoin . payments . p2tr ( {
@@ -361,7 +363,7 @@ describe('bitcoinjs-lib (transaction with taproot)', () => {
361363 ] ;
362364 const redeem = {
363365 output : leafScript ,
364- redeemVersion : 192 ,
366+ redeemVersion : LEAF_VERSION_TAPSCRIPT ,
365367 } ;
366368
367369 const { output, witness } = bitcoin . payments . p2tr ( {
@@ -472,7 +474,7 @@ describe('bitcoinjs-lib (transaction with taproot)', () => {
472474 ] ;
473475 const redeem = {
474476 output : leafScript ,
475- redeemVersion : 192 ,
477+ redeemVersion : LEAF_VERSION_TAPSCRIPT ,
476478 } ;
477479
478480 const { output, address, witness } = bitcoin . payments . p2tr ( {
@@ -532,7 +534,7 @@ describe('bitcoinjs-lib (transaction with taproot)', () => {
532534 ( _ , index ) =>
533535 ( {
534536 depth : 3 ,
535- leafVersion : 192 ,
537+ leafVersion : LEAF_VERSION_TAPSCRIPT ,
536538 script : bitcoin . script . fromASM ( `OP_ADD OP_${ index * 2 } OP_EQUAL` ) ,
537539 } as TapLeaf ) ,
538540 ) ;
@@ -541,7 +543,7 @@ describe('bitcoinjs-lib (transaction with taproot)', () => {
541543 for ( let leafIndex = 1 ; leafIndex < leafCount ; leafIndex ++ ) {
542544 const redeem = {
543545 output : bitcoin . script . fromASM ( `OP_ADD OP_${ leafIndex * 2 } OP_EQUAL` ) ,
544- redeemVersion : 192 ,
546+ redeemVersion : LEAF_VERSION_TAPSCRIPT ,
545547 } ;
546548
547549 const internalKey = bip32 . fromSeed ( rng ( 64 ) , regtest ) ;
@@ -691,35 +693,3 @@ function buildLeafIndexFinalizer(
691693 }
692694 } ;
693695}
694-
695- // This logic will be extracted to ecpair
696- function tweakSigner ( signer : bitcoin . Signer , opts : any = { } ) : bitcoin . Signer {
697- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
698- // @ts -ignore
699- let privateKey : Uint8Array | undefined = signer . privateKey ! ;
700- if ( ! privateKey ) {
701- throw new Error ( 'Private key is required for tweaking signer!' ) ;
702- }
703- if ( signer . publicKey [ 0 ] === 3 ) {
704- privateKey = ecc . privateNegate ( privateKey ) ;
705- }
706-
707- const tweakedPrivateKey = ecc . privateAdd (
708- privateKey ,
709- tapTweakHash ( toXOnly ( signer . publicKey ) , opts . tweakHash ) ,
710- ) ;
711- if ( ! tweakedPrivateKey ) {
712- throw new Error ( 'Invalid tweaked private key!' ) ;
713- }
714-
715- return ECPair . fromPrivateKey ( Buffer . from ( tweakedPrivateKey ) , {
716- network : opts . network ,
717- } ) ;
718- }
719-
720- function tapTweakHash ( pubKey : Buffer , h : Buffer | undefined ) : Buffer {
721- return bitcoin . crypto . taggedHash (
722- 'TapTweak' ,
723- Buffer . concat ( h ? [ pubKey , h ] : [ pubKey ] ) ,
724- ) ;
725- }
0 commit comments