@@ -595,7 +595,7 @@ func newBTCTxFromPSBT(
595595}
596596
597597// BTCSignPSBT signs a PSBT. If `options` is nil, the default options are used. The PSBT input signatures will be
598- // populated.
598+ // populated. If a (partial) signature for the public key of the device already exists, it will be overwritten.
599599func (device * Device ) BTCSignPSBT (
600600 coin messages.BTCCoin ,
601601 psbt_ * psbt.Packet ,
@@ -630,12 +630,16 @@ func (device *Device) BTCSignPSBT(
630630 ourKey := txResult .ourKeys [inputIndex ]
631631 switch {
632632 case ourKey .segwit != nil :
633- psbtInput .PartialSigs = []* psbt.PartialSig {
634- {
635- PubKey : ourKey .segwit .PubKey ,
636- Signature : append (signatureDER , byte (txscript .SigHashAll )),
637- },
638- }
633+ // Check if we already have a partial signature for this
634+ // public key. If we do, we overwrite it. Duplicate
635+ // entries would lead to an invalid PSBT. Erroring out
636+ // is suboptimal as well, since we've already gone
637+ // through the signing process. It's the caller's
638+ // responsibility to check if this device has already
639+ // signed the PSBT to avoid this behavior.
640+ setPartialSig (
641+ signatureDER , psbtInput , ourKey .segwit .PubKey ,
642+ txscript .SigHashAll )
639643 case ourKey .taprootInternal != nil :
640644 psbtInput .TaprootKeySpendSig = signatureCompact
641645 case ourKey .taprootScript != nil :
@@ -659,6 +663,32 @@ func (device *Device) BTCSignPSBT(
659663 return nil
660664}
661665
666+ // setPartialSig replaces or adds a partial signature for the given public key,
667+ // depending on whether a partial signature already exists for the key or not.
668+ func setPartialSig (
669+ sig []byte ,
670+ psbtInput * psbt.PInput ,
671+ pubKey []byte ,
672+ sigHash txscript.SigHashType ,
673+ ) {
674+ for idx , partialSig := range psbtInput .PartialSigs {
675+ if bytes .Equal (partialSig .PubKey , pubKey ) {
676+ psbtInput .PartialSigs [idx ] = & psbt.PartialSig {
677+ PubKey : pubKey ,
678+ Signature : append (sig , byte (sigHash )),
679+ }
680+
681+ return
682+ }
683+ }
684+ psbtInput .PartialSigs = append (
685+ psbtInput .PartialSigs , & psbt.PartialSig {
686+ PubKey : pubKey ,
687+ Signature : append (sig , byte (sigHash )),
688+ },
689+ )
690+ }
691+
662692// BTCSignNeedsNonWitnessUTXOs returns true if the BitBox requires the NON_WITNESS_UTXO fields of
663693// each PSBT input to be present. They are the previous transactions of the inputs, and the BitBox
664694// needs them to validate the input amount, unless all inputs are Taproot. This helper function
0 commit comments