11'use strict' ;
22Object . defineProperty ( exports , '__esModule' , { value : true } ) ;
3- exports . Psbt = void 0 ;
4- const ecc = require ( 'tiny-secp256k1' ) ; // TODO: extract
3+ exports . tweakSigner = exports . Psbt = void 0 ;
54const ecpair_1 = require ( 'ecpair' ) ;
65const bip174_1 = require ( 'bip174' ) ;
76const varuint = require ( 'bip174/src/lib/converter/varint' ) ;
@@ -81,6 +80,7 @@ class Psbt {
8180 // We will disable exporting the Psbt when unsafe sign is active.
8281 // because it is not BIP174 compliant.
8382 __UNSAFE_SIGN_NONSEGWIT : false ,
83+ __EC_LIB : opts . eccLib ,
8484 } ;
8585 if ( this . data . inputs . length === 0 ) this . setVersion ( 2 ) ;
8686 // Make data hidden when enumerating
@@ -106,39 +106,6 @@ class Psbt {
106106 checkTxForDupeIns ( psbt . __CACHE . __TX , psbt . __CACHE ) ;
107107 return psbt ;
108108 }
109- /**
110- * Helper method for converting a normal Signer into a Taproot Signer.
111- * Note that this helper method requires the Private Key of the Signer to be present.
112- * Steps:
113- * - if the Y coordinate of the Signer Public Key is odd then negate the Private Key
114- * - tweak the private key with the provided hash (should be empty for key-path spending)
115- * @param signer - a taproot signer object, the Private Key must be present
116- * @param opts - tweak options
117- * @returns a Signer having the Private and Public keys tweaked
118- */
119- static tweakSigner ( signer , opts = { } ) {
120- let privateKey = signer . privateKey ;
121- if ( ! privateKey ) {
122- throw new Error ( 'Private key is required for tweaking signer!' ) ;
123- }
124- if ( signer . publicKey [ 0 ] === 3 ) {
125- privateKey = ecc . privateNegate ( privateKey ) ;
126- }
127- const tweakedPrivateKey = ecc . privateAdd (
128- privateKey ,
129- ( 0 , taprootutils_1 . tapTweakHash ) (
130- signer . publicKey . slice ( 1 , 33 ) ,
131- opts . tweakHash ,
132- ) ,
133- ) ;
134- if ( ! tweakedPrivateKey ) {
135- throw new Error ( 'Invalid tweaked private key!' ) ;
136- }
137- const ECPair = ( 0 , ecpair_1 . ECPairFactory ) ( ecc ) ;
138- return ECPair . fromPrivateKey ( Buffer . from ( tweakedPrivateKey ) , {
139- network : opts . network ,
140- } ) ;
141- }
142109 get inputCount ( ) {
143110 return this . data . inputs . length ;
144111 }
@@ -307,7 +274,7 @@ class Psbt {
307274 range ( this . data . inputs . length ) . forEach ( idx => this . finalizeInput ( idx ) ) ;
308275 return this ;
309276 }
310- finalizeInput ( inputIndex , finalScriptsFunc = getFinalScripts ) {
277+ finalizeInput ( inputIndex , finalScriptsFunc ) {
311278 const input = ( 0 , utils_1 . checkForInput ) ( this . data . inputs , inputIndex ) ;
312279 const { script, isP2SH, isP2WSH, isSegwit } = getScriptFromInput (
313280 inputIndex ,
@@ -316,13 +283,15 @@ class Psbt {
316283 ) ;
317284 if ( ! script ) throw new Error ( `No script found for input #${ inputIndex } ` ) ;
318285 checkPartialSigSighashes ( input ) ;
319- const { finalScriptSig, finalScriptWitness } = finalScriptsFunc (
286+ const fn = finalScriptsFunc || getFinalScripts ;
287+ const { finalScriptSig, finalScriptWitness } = fn (
320288 inputIndex ,
321289 input ,
322290 script ,
323291 isSegwit ,
324292 isP2SH ,
325293 isP2WSH ,
294+ this . __CACHE . __EC_LIB ,
326295 ) ;
327296 if ( finalScriptSig ) this . data . updateInput ( inputIndex , { finalScriptSig } ) ;
328297 if ( finalScriptWitness )
@@ -348,7 +317,10 @@ class Psbt {
348317 redeemFromFinalWitnessScript ( input . finalScriptWitness ) ,
349318 ) ;
350319 const type = result . type === 'raw' ? '' : result . type + '-' ;
351- const mainType = classifyScript ( result . meaningfulScript ) ;
320+ const mainType = classifyScript (
321+ result . meaningfulScript ,
322+ this . __CACHE . __EC_LIB ,
323+ ) ;
352324 return type + mainType ;
353325 }
354326 inputHasPubkey ( inputIndex , pubkey ) {
@@ -676,6 +648,41 @@ class Psbt {
676648 }
677649}
678650exports . Psbt = Psbt ;
651+ /**
652+ * Helper method for converting a normal Signer into a Taproot Signer.
653+ * Note that this helper method requires the Private Key of the Signer to be present.
654+ * Steps:
655+ * - if the Y coordinate of the Signer Public Key is odd then negate the Private Key
656+ * - tweak the private key with the provided hash (should be empty for key-path spending)
657+ * @param signer - a taproot signer object, the Private Key must be present
658+ * @param opts - tweak options
659+ * @returns a Signer having the Private and Public keys tweaked
660+ */
661+ function tweakSigner ( signer , opts ) {
662+ // todo: test ecc??
663+ let privateKey = signer . privateKey ;
664+ if ( ! privateKey ) {
665+ throw new Error ( 'Private key is required for tweaking signer!' ) ;
666+ }
667+ if ( signer . publicKey [ 0 ] === 3 ) {
668+ privateKey = opts . eccLib . privateNegate ( privateKey ) ;
669+ }
670+ const tweakedPrivateKey = opts . eccLib . privateAdd (
671+ privateKey ,
672+ ( 0 , taprootutils_1 . tapTweakHash ) (
673+ signer . publicKey . slice ( 1 , 33 ) ,
674+ opts . tweakHash ,
675+ ) ,
676+ ) ;
677+ if ( ! tweakedPrivateKey ) {
678+ throw new Error ( 'Invalid tweaked private key!' ) ;
679+ }
680+ const ECPair = ( 0 , ecpair_1 . ECPairFactory ) ( opts . eccLib ) ;
681+ return ECPair . fromPrivateKey ( Buffer . from ( tweakedPrivateKey ) , {
682+ network : opts . network ,
683+ } ) ;
684+ }
685+ exports . tweakSigner = tweakSigner ;
679686/**
680687 * This function is needed to pass to the bip174 base class's fromBuffer.
681688 * It takes the "transaction buffer" portion of the psbt buffer and returns a
@@ -928,8 +935,16 @@ function getTxCacheValue(key, name, inputs, c) {
928935 if ( key === '__FEE_RATE' ) return c . __FEE_RATE ;
929936 else if ( key === '__FEE' ) return c . __FEE ;
930937}
931- function getFinalScripts ( inputIndex , input , script , isSegwit , isP2SH , isP2WSH ) {
932- const scriptType = classifyScript ( script ) ;
938+ function getFinalScripts (
939+ inputIndex ,
940+ input ,
941+ script ,
942+ isSegwit ,
943+ isP2SH ,
944+ isP2WSH ,
945+ eccLib ,
946+ ) {
947+ const scriptType = classifyScript ( script , eccLib ) ;
933948 if ( ! canFinalize ( input , script , scriptType ) )
934949 throw new Error ( `Can not finalize input #${ inputIndex } ` ) ;
935950 return prepareFinalScripts (
@@ -1063,7 +1078,7 @@ function getHashForSig(
10631078 prevout . value ,
10641079 sighashType ,
10651080 ) ;
1066- } else if ( isP2TR ( meaningfulScript , ecc ) ) {
1081+ } else if ( isP2TR ( meaningfulScript , cache . __EC_LIB ) ) {
10671082 const prevOuts = inputs . map ( ( i , index ) =>
10681083 getScriptAndAmountFromUtxo ( index , i , cache ) ,
10691084 ) ;
@@ -1143,7 +1158,7 @@ function getPayment(script, scriptType, partialSig) {
11431158 output : script ,
11441159 signature : partialSig [ 0 ] . signature ,
11451160 } ,
1146- { eccLib : ecc } ,
1161+ { validate : false } ,
11471162 ) ;
11481163 break ;
11491164 }
@@ -1190,7 +1205,11 @@ function getScriptFromInput(inputIndex, input, cache) {
11901205 res . script = input . witnessUtxo . script ;
11911206 }
11921207 }
1193- if ( input . witnessScript || isP2WPKH ( res . script ) || isP2TR ( res . script , ecc ) ) {
1208+ if (
1209+ input . witnessScript ||
1210+ isP2WPKH ( res . script ) ||
1211+ isP2TR ( res . script , cache . __EC_LIB )
1212+ ) {
11941213 res . isSegwit = true ;
11951214 }
11961215 return res ;
@@ -1504,12 +1523,12 @@ function pubkeyInScript(pubkey, script) {
15041523 ) ;
15051524 } ) ;
15061525}
1507- function classifyScript ( script ) {
1526+ function classifyScript ( script , eccLib ) {
15081527 if ( isP2WPKH ( script ) ) return 'witnesspubkeyhash' ;
15091528 if ( isP2PKH ( script ) ) return 'pubkeyhash' ;
15101529 if ( isP2MS ( script ) ) return 'multisig' ;
15111530 if ( isP2PK ( script ) ) return 'pubkey' ;
1512- if ( isP2TR ( script , ecc ) ) return 'taproot' ;
1531+ if ( isP2TR ( script , eccLib ) ) return 'taproot' ;
15131532 return 'nonstandard' ;
15141533}
15151534function range ( n ) {
0 commit comments