@@ -335,6 +335,131 @@ func TestSimulatorBTCPSBTTaprootKeySpend(t *testing.T) {
335335 Bip32Path : changePath ,
336336 }}
337337
338+ needsPrevTxs , err := device .BTCSignNeedsNonWitnessUTXOs (psbt_ , nil )
339+ require .NoError (t , err )
340+ require .False (t , needsPrevTxs )
341+
342+ // Sign & validate.
343+ require .NoError (t , device .BTCSignPSBT (messages .BTCCoin_TBTC , psbt_ , nil ))
344+ require .NoError (t , psbt .MaybeFinalizeAll (psbt_ ))
345+ require .NoError (t , txValidityCheck (psbt_ ))
346+ })
347+ }
348+
349+ // All inputs are Taproot, but the change output is not Taproot. Some BitBox firmwares erroneously
350+ // also request the previous transactions in this case.
351+ func TestSimulatorBTCPSBTTaprootSpendsToNonTaproot (t * testing.T ) {
352+ testInitializedSimulators (t , func (t * testing.T , device * Device , stdOut * bytes.Buffer ) {
353+ t .Helper ()
354+
355+ fingerprint , err := device .RootFingerprint ()
356+ require .NoError (t , err )
357+
358+ changePath := []uint32 {84 + HARDENED , 1 + HARDENED , 0 + HARDENED , 1 , 0 }
359+ changePubKey := simulatorPub (t , device , changePath ... )
360+ changePkScript := p2wpkhPkScript (changePubKey )
361+
362+ input0Path := []uint32 {86 + HARDENED , 1 + HARDENED , 0 + HARDENED , 0 , 0 }
363+ input0Pubkey := simulatorPub (t , device , input0Path ... )
364+ _ , input0PkScript := makeTaprootOutput (t , input0Pubkey )
365+
366+ input1Path := []uint32 {86 + HARDENED , 1 + HARDENED , 0 + HARDENED , 0 , 1 }
367+ input1PubKey := simulatorPub (t , device , input1Path ... )
368+ _ , input1PkScript := makeTaprootOutput (t , input1PubKey )
369+
370+ // A previous tx which creates some UTXOs we can reference later.
371+ prevTx := & wire.MsgTx {
372+ Version : 2 ,
373+ LockTime : 0 ,
374+ TxIn : []* wire.TxIn {
375+ {
376+ PreviousOutPoint : * mustOutpoint ("3131313131313131313131313131313131313131313131313131313131313131:0" ),
377+ SignatureScript : nil ,
378+ Sequence : 0xFFFFFFFF ,
379+ Witness : nil ,
380+ },
381+ },
382+ TxOut : []* wire.TxOut {
383+ {
384+ Value : 100_000_000 ,
385+ PkScript : input0PkScript ,
386+ },
387+ {
388+ Value : 100_000_000 ,
389+ PkScript : input1PkScript ,
390+ },
391+ },
392+ }
393+
394+ tx := & wire.MsgTx {
395+ Version : 2 ,
396+ LockTime : 0 ,
397+ TxIn : []* wire.TxIn {
398+ {
399+ PreviousOutPoint : wire.OutPoint {
400+ Hash : prevTx .TxHash (),
401+ Index : 0 ,
402+ },
403+ SignatureScript : nil ,
404+ Sequence : 0xFFFFFFFF ,
405+ Witness : nil ,
406+ },
407+ {
408+ PreviousOutPoint : wire.OutPoint {
409+ Hash : prevTx .TxHash (),
410+ Index : 1 ,
411+ },
412+ SignatureScript : nil ,
413+ Sequence : 0xFFFFFFFF ,
414+ Witness : nil ,
415+ },
416+ },
417+ TxOut : []* wire.TxOut {
418+ {
419+ Value : 100_000_000 ,
420+ PkScript : changePkScript ,
421+ },
422+ {
423+ Value : 20_000_000 ,
424+ // random private key:
425+ // 9dbb534622a6100a39b73dece43c6d4db14b9a612eb46a6c64c2bb849e283ce8
426+ PkScript : p2trPkScript (unhex ("e4adbb12c3426ec71ebb10688d8ae69d531ca822a2b790acee216a7f1b95b576" )),
427+ },
428+ },
429+ }
430+ psbt_ , err := psbt .NewFromUnsignedTx (tx )
431+ require .NoError (t , err )
432+
433+ // Add input and change infos.
434+ psbt_ .Inputs [0 ].WitnessUtxo = prevTx .TxOut [0 ]
435+ psbt_ .Inputs [0 ].TaprootInternalKey = schnorr .SerializePubKey (input0Pubkey )
436+ psbt_ .Inputs [0 ].TaprootBip32Derivation = []* psbt.TaprootBip32Derivation {{
437+ XOnlyPubKey : psbt_ .Inputs [0 ].TaprootInternalKey ,
438+ MasterKeyFingerprint : binary .LittleEndian .Uint32 (fingerprint ),
439+ Bip32Path : input0Path ,
440+ }}
441+
442+ psbt_ .Inputs [1 ].WitnessUtxo = prevTx .TxOut [1 ]
443+ psbt_ .Inputs [1 ].TaprootInternalKey = schnorr .SerializePubKey (input1PubKey )
444+ psbt_ .Inputs [1 ].TaprootBip32Derivation = []* psbt.TaprootBip32Derivation {{
445+ XOnlyPubKey : psbt_ .Inputs [1 ].TaprootInternalKey ,
446+ MasterKeyFingerprint : binary .LittleEndian .Uint32 (fingerprint ),
447+ Bip32Path : input1Path ,
448+ }}
449+
450+ psbt_ .Outputs [0 ].TaprootInternalKey = schnorr .SerializePubKey (changePubKey )
451+ psbt_ .Outputs [0 ].TaprootBip32Derivation = []* psbt.TaprootBip32Derivation {{
452+ XOnlyPubKey : psbt_ .Outputs [0 ].TaprootInternalKey ,
453+ MasterKeyFingerprint : binary .LittleEndian .Uint32 (fingerprint ),
454+ Bip32Path : changePath ,
455+ }}
456+
457+ needsPrevTxs , err := device .BTCSignNeedsNonWitnessUTXOs (psbt_ , nil )
458+ require .NoError (t , err )
459+ require .True (t , needsPrevTxs )
460+ psbt_ .Inputs [0 ].NonWitnessUtxo = prevTx
461+ psbt_ .Inputs [1 ].NonWitnessUtxo = prevTx
462+
338463 // Sign & validate.
339464 require .NoError (t , device .BTCSignPSBT (messages .BTCCoin_TBTC , psbt_ , nil ))
340465 require .NoError (t , psbt .MaybeFinalizeAll (psbt_ ))
@@ -457,6 +582,10 @@ func TestSimulatorBTCPSBTMixedSpend(t *testing.T) {
457582 Bip32Path : changePath ,
458583 }}
459584
585+ needsPrevTxs , err := device .BTCSignNeedsNonWitnessUTXOs (psbt_ , nil )
586+ require .NoError (t , err )
587+ require .True (t , needsPrevTxs )
588+
460589 // Sign & validate
461590 require .NoError (t , device .BTCSignPSBT (messages .BTCCoin_TBTC , psbt_ , nil ))
462591 require .NoError (t , psbt .MaybeFinalizeAll (psbt_ ))
@@ -578,14 +707,19 @@ func TestSimulatorBTCPSBTSilentPayment(t *testing.T) {
578707 Bip32Path : changePath ,
579708 }}
580709
581- // Sign & validate
582710 signOptions := & PSBTSignOptions {
583711 Outputs : map [int ]* PSBTSignOutputOptions {
584712 1 : {
585713 SilentPaymentAddress : "sp1qqgste7k9hx0qftg6qmwlkqtwuy6cycyavzmzj85c6qdfhjdpdjtdgqjuexzk6murw56suy3e0rd2cgqvycxttddwsvgxe2usfpxumr70xc9pkqwv" ,
586714 },
587715 },
588716 }
717+
718+ needsPrevTxs , err := device .BTCSignNeedsNonWitnessUTXOs (psbt_ , signOptions )
719+ require .NoError (t , err )
720+ require .True (t , needsPrevTxs )
721+
722+ // Sign & validate
589723 err = device .BTCSignPSBT (messages .BTCCoin_BTC , psbt_ , signOptions )
590724 if ! device .version .AtLeast (semver .NewSemVer (9 , 21 , 0 )) {
591725 require .EqualError (t , err , UnsupportedError ("9.21.0" ).Error ())
@@ -709,6 +843,10 @@ func TestSimulatorBTCPSBTSendSelfSameAccount(t *testing.T) {
709843 Bip32Path : sendSelfPath ,
710844 }}
711845
846+ needsPrevTxs , err := device .BTCSignNeedsNonWitnessUTXOs (psbt_ , nil )
847+ require .NoError (t , err )
848+ require .True (t , needsPrevTxs )
849+
712850 // Sign & validate
713851 require .NoError (t , device .BTCSignPSBT (messages .BTCCoin_TBTC , psbt_ , nil ))
714852 require .NoError (t , psbt .MaybeFinalizeAll (psbt_ ))
@@ -844,7 +982,6 @@ func TestSimulatorBTCPSBTPaymentRequest(t *testing.T) {
844982 }}
845983 psbt_ .Outputs [0 ].RedeemScript = changeRedeemScript
846984
847- // Sign & validate
848985 paymentRequestIndex := uint32 (0 )
849986 signOptions := & PSBTSignOptions {
850987 PaymentRequests : []* messages.BTCPaymentRequestRequest {paymentRequest },
@@ -854,6 +991,12 @@ func TestSimulatorBTCPSBTPaymentRequest(t *testing.T) {
854991 },
855992 },
856993 }
994+
995+ needsPrevTxs , err := device .BTCSignNeedsNonWitnessUTXOs (psbt_ , signOptions )
996+ require .NoError (t , err )
997+ require .False (t , needsPrevTxs )
998+
999+ // Sign & validate
8571000 require .NoError (t , device .BTCSignPSBT (messages .BTCCoin_TBTC , psbt_ , signOptions ))
8581001 require .NoError (t , psbt .MaybeFinalizeAll (psbt_ ))
8591002 require .NoError (t , txValidityCheck (psbt_ ))
0 commit comments