Skip to content

Commit

Permalink
signpsbt+lnd: fix signing for P2WKH
Browse files Browse the repository at this point in the history
  • Loading branch information
guggero committed Apr 12, 2024
1 parent f062b53 commit 7f840cf
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 5 deletions.
19 changes: 14 additions & 5 deletions cmd/chantools/signpsbt.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"github.com/btcsuite/btcd/btcutil"
"github.com/btcsuite/btcd/btcutil/hdkeychain"
"github.com/btcsuite/btcd/btcutil/psbt"
"github.com/btcsuite/btcd/txscript"
"github.com/lightninglabs/chantools/lnd"
"github.com/spf13/cobra"
)
Expand Down Expand Up @@ -153,17 +154,25 @@ func signPsbt(rootKey *hdkeychain.ExtendedKey,
return fmt.Errorf("could not derive local key: %w", err)
}

if len(packet.Inputs[inputIndex].WitnessScript) == 0 {
return fmt.Errorf("invalid PSBT, input %d is missing witness "+
"script", inputIndex)
}
witnessScript := packet.Inputs[inputIndex].WitnessScript
if packet.Inputs[inputIndex].WitnessUtxo == nil {
return fmt.Errorf("invalid PSBT, input %d is missing witness "+
"UTXO", inputIndex)
}
utxo := packet.Inputs[inputIndex].WitnessUtxo

// The signing is a bit different for P2WPKH, we need to specify the
// pk script as the witness script.
var witnessScript []byte
if txscript.IsPayToWitnessPubKeyHash(utxo.PkScript) {
witnessScript = utxo.PkScript
} else {
if len(packet.Inputs[inputIndex].WitnessScript) == 0 {
return fmt.Errorf("invalid PSBT, input %d is missing "+
"witness script", inputIndex)
}
witnessScript = packet.Inputs[inputIndex].WitnessScript
}

localPrivateKey, err := localKey.ECPrivKey()
if err != nil {
return fmt.Errorf("error getting private key: %w", err)
Expand Down
8 changes: 8 additions & 0 deletions lnd/signer.go
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,14 @@ func (s *Signer) AddPartialSignatureForPrivateKey(packet *psbt.Packet,
if err != nil {
return fmt.Errorf("error creating PSBT updater: %w", err)
}

// If the witness script is the pk script for a P2WPKH output, then we
// need to blank it out for the PSBT code, otherwise it interprets it as
// a P2WSH.
if txscript.IsPayToWitnessPubKeyHash(utxo.PkScript) {
witnessScript = nil
}

status, err := updater.Sign(
inputIndex, ourSig, privateKey.PubKey().SerializeCompressed(),
nil, witnessScript,
Expand Down

0 comments on commit 7f840cf

Please sign in to comment.