@@ -36,6 +36,7 @@ import {
3636 WalletUnspent ,
3737 getDefaultSigHash ,
3838 isPsbtLite ,
39+ UnspentWithPrevTx ,
3940} from '../../../src/bitgo' ;
4041import {
4142 createOutputScript2of3 ,
@@ -745,47 +746,67 @@ describe('Update incomplete psbt', function () {
745746 signAllInputs ( psbt ) ;
746747 } ) ;
747748
748- const componentsOnEachInputScriptType = {
749- p2sh : [ 'nonWitnessUtxo' , 'redeemScript' , 'bip32Derivation' ] ,
750- p2shP2wsh : [ 'witnessUtxo' , 'bip32Derivation' , 'redeemScript' , 'witnessScript' ] ,
751- p2wsh : [ 'witnessUtxo' , 'witnessScript' , 'bip32Derivation' ] ,
752- p2tr : [ 'witnessUtxo' , 'tapLeafScript' , 'tapBip32Derivation' ] ,
753- p2trMusig2 : [ 'witnessUtxo' , 'tapBip32Derivation' , 'tapInternalKey' , 'tapMerkleRoot' , 'unknownKeyVals' ] ,
754- p2shP2pk : [ 'redeemScript' , 'nonWitnessUtxo' ] ,
755- } ;
756-
757- const p2trComponents = [ 'tapTree' , 'tapInternalKey' , 'tapBip32Derivation' ] ;
758- const componentsOnEachOutputScriptType = {
759- p2sh : [ 'bip32Derivation' , 'redeemScript' ] ,
760- p2shP2wsh : [ 'bip32Derivation' , 'witnessScript' , 'redeemScript' ] ,
761- p2wsh : [ 'bip32Derivation' , 'witnessScript' ] ,
762- p2tr : p2trComponents ,
763- p2trMusig2 : p2trComponents ,
764- p2shP2pk : [ ] ,
765- } ;
766- scriptTypes . forEach ( ( scriptType , i ) => {
767- componentsOnEachInputScriptType [ scriptType ] . forEach ( ( inputComponent ) => {
768- it ( `[${ scriptType } ] missing ${ inputComponent } on input should succeed in fully signing unsigned psbt after update` , function ( ) {
769- const psbt = removeFromPsbt ( psbtHex , network , { input : { index : i , fieldToRemove : inputComponent } } ) ;
770- const unspent = unspents [ i ] ;
771- if ( isWalletUnspent ( unspent ) ) {
772- updateWalletUnspentForPsbt ( psbt , i , unspent , rootWalletKeys , signer , cosigner ) ;
773- } else {
774- const { redeemScript } = createOutputScriptP2shP2pk ( replayProtectionKeyPair . publicKey ) ;
775- assert . ok ( redeemScript ) ;
776- updateReplayProtectionUnspentToPsbt ( psbt , i , unspent , redeemScript ) ;
777- }
778- signAllInputs ( psbt ) ;
779- } ) ;
780- } ) ;
749+ function runTest ( txFormat : 'psbt' | 'psbt-lite' ) {
750+ describe ( `txFormat=${ txFormat } ` , function ( ) {
751+ const componentsOnEachInputScriptType = {
752+ p2sh : [ txFormat === 'psbt' ? 'nonWitnessUtxo' : 'witnessUtxo' , 'redeemScript' , 'bip32Derivation' ] ,
753+ p2shP2wsh : [ 'witnessUtxo' , 'bip32Derivation' , 'redeemScript' , 'witnessScript' ] ,
754+ p2wsh : [ 'witnessUtxo' , 'witnessScript' , 'bip32Derivation' ] ,
755+ p2tr : [ 'witnessUtxo' , 'tapLeafScript' , 'tapBip32Derivation' ] ,
756+ p2trMusig2 : [ 'witnessUtxo' , 'tapBip32Derivation' , 'tapInternalKey' , 'tapMerkleRoot' , 'unknownKeyVals' ] ,
757+ p2shP2pk : [ 'redeemScript' , txFormat === 'psbt' ? 'nonWitnessUtxo' : 'witnessUtxo' ] ,
758+ } ;
781759
782- componentsOnEachOutputScriptType [ scriptType ] . forEach ( ( outputComponent ) => {
783- it ( `[${ scriptType } ] missing ${ outputComponent } on output should produce same hex as fully hydrated after update` , function ( ) {
784- const psbt = removeFromPsbt ( psbtHex , network , { output : { index : i , fieldToRemove : outputComponent } } ) ;
785- updateWalletOutputForPsbt ( psbt , rootWalletKeys , i , outputs [ i ] . chain , outputs [ i ] . index ) ;
786- assert . strictEqual ( psbt . toHex ( ) , psbtHex ) ;
760+ const p2trComponents = [ 'tapTree' , 'tapInternalKey' , 'tapBip32Derivation' ] ;
761+ const componentsOnEachOutputScriptType = {
762+ p2sh : [ 'bip32Derivation' , 'redeemScript' ] ,
763+ p2shP2wsh : [ 'bip32Derivation' , 'witnessScript' , 'redeemScript' ] ,
764+ p2wsh : [ 'bip32Derivation' , 'witnessScript' ] ,
765+ p2tr : p2trComponents ,
766+ p2trMusig2 : p2trComponents ,
767+ p2shP2pk : [ ] ,
768+ } ;
769+ scriptTypes . forEach ( ( scriptType , i ) => {
770+ componentsOnEachInputScriptType [ scriptType ] . forEach ( ( inputComponent ) => {
771+ it ( `[${ scriptType } ] missing ${ inputComponent } on input should succeed in fully signing unsigned psbt after update` , function ( ) {
772+ const psbt = removeFromPsbt ( psbtHex , network , {
773+ input : { index : i , fieldToRemove : inputComponent } ,
774+ } ) ;
775+ const unspent = unspents [ i ] ;
776+ if ( txFormat === 'psbt-lite' ) {
777+ // remove the prevTx for the unspent
778+ delete ( unspent as UnspentWithPrevTx ) . prevTx ;
779+ }
780+ if ( isWalletUnspent ( unspent ) ) {
781+ updateWalletUnspentForPsbt ( psbt , i , unspent , rootWalletKeys , signer , cosigner , {
782+ skipNonWitnessUtxo : txFormat === 'psbt-lite' ,
783+ } ) ;
784+ } else {
785+ const { redeemScript } = createOutputScriptP2shP2pk ( replayProtectionKeyPair . publicKey ) ;
786+ assert . ok ( redeemScript ) ;
787+ updateReplayProtectionUnspentToPsbt ( psbt , i , unspent , redeemScript , {
788+ skipNonWitnessUtxo : txFormat === 'psbt-lite' ,
789+ } ) ;
790+ }
791+ signAllInputs ( psbt ) ;
792+ } ) ;
793+ } ) ;
794+
795+ componentsOnEachOutputScriptType [ scriptType ] . forEach ( ( outputComponent ) => {
796+ it ( `[${ scriptType } ] missing ${ outputComponent } on output should produce same hex as fully hydrated after update` , function ( ) {
797+ const psbt = removeFromPsbt ( psbtHex , network , {
798+ output : { index : i , fieldToRemove : outputComponent } ,
799+ } ) ;
800+ updateWalletOutputForPsbt ( psbt , rootWalletKeys , i , outputs [ i ] . chain , outputs [ i ] . index ) ;
801+ assert . strictEqual ( psbt . toHex ( ) , psbtHex ) ;
802+ } ) ;
803+ } ) ;
787804 } ) ;
788805 } ) ;
806+ }
807+
808+ [ 'psbt' , 'psbt-lite' ] . forEach ( ( txFormat ) => {
809+ runTest ( txFormat as 'psbt' | 'psbt-lite' ) ;
789810 } ) ;
790811} ) ;
791812
0 commit comments