Skip to content

Commit 567fdb2

Browse files
authored
Merge pull request #171 from lightninglabs/signpsbt-improvements
signpsbt: implement Taproot keyspend signing
2 parents 5011fd5 + 6a9addb commit 567fdb2

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+256
-165
lines changed

.github/workflows/main.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ env:
1616
# go needs absolute directories, using the $HOME variable doesn't work here.
1717
GOCACHE: /home/runner/work/go/pkg/build
1818
GOPATH: /home/runner/work/go
19-
GO_VERSION: 1.22.3
19+
GO_VERSION: 1.22.6
2020

2121
jobs:
2222
########################

cmd/chantools/derivekey.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212
const deriveKeyFormat = `
1313
Path: %s
1414
Network: %s
15+
Master Fingerprint: %x
1516
Public key: %x
1617
Extended public key (xpub): %v
1718
Address: %v
@@ -110,8 +111,13 @@ func deriveKey(extendedKey *hdkeychain.ExtendedKey, path string,
110111
privKey, xPriv = wif.String(), child.String()
111112
}
112113

114+
_, fingerPrintBytes, err := fingerprint(extendedKey)
115+
if err != nil {
116+
return fmt.Errorf("could not get fingerprint: %w", err)
117+
}
118+
113119
result := fmt.Sprintf(
114-
deriveKeyFormat, path, chainParams.Name,
120+
deriveKeyFormat, path, chainParams.Name, fingerPrintBytes,
115121
pubKey.SerializeCompressed(), neutered, addrP2WKH, addrP2PKH,
116122
addrP2TR, privKey, xPriv,
117123
)

cmd/chantools/root.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,13 @@ const (
3131
// version is the current version of the tool. It is set during build.
3232
// NOTE: When changing this, please also update the version in the
3333
// download link shown in the README.
34-
version = "0.13.4"
34+
version = "0.13.5"
3535
na = "n/a"
3636

3737
// lndVersion is the current version of lnd that we support. This is
3838
// shown in some commands that affect the database and its migrations.
3939
// Run "make docs" after changing this value.
40-
lndVersion = "v0.18.3-beta"
40+
lndVersion = "v0.18.4-beta"
4141

4242
Commit = ""
4343
)
@@ -162,7 +162,7 @@ func newRootKey(cmd *cobra.Command, desc string) *rootKey {
162162
)
163163
cmd.Flags().StringVar(
164164
&r.WalletDB, "walletdb", "", "read the seed/master root key "+
165-
"to use fro "+desc+" from an lnd wallet.db file "+
165+
"to use for "+desc+" from an lnd wallet.db file "+
166166
"instead of asking for a seed or providing the "+
167167
"--rootkey flag",
168168
)

cmd/chantools/signpsbt.go

Lines changed: 33 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -172,24 +172,37 @@ func signPsbt(rootKey *hdkeychain.ExtendedKey,
172172
}
173173
utxo := pIn.WitnessUtxo
174174

175+
localPrivateKey, err := localKey.ECPrivKey()
176+
if err != nil {
177+
return fmt.Errorf("error getting private key: %w", err)
178+
}
179+
175180
// The signing is a bit different for P2WPKH, we need to specify
176181
// the pk script as the witness script.
177182
var witnessScript []byte
178-
if txscript.IsPayToWitnessPubKeyHash(utxo.PkScript) {
183+
switch {
184+
case txscript.IsPayToWitnessPubKeyHash(utxo.PkScript):
179185
witnessScript = utxo.PkScript
180-
} else {
186+
187+
case txscript.IsPayToTaproot(utxo.PkScript):
188+
err := signer.AddTaprootSignature(
189+
packet, inputIndex, utxo, localPrivateKey,
190+
)
191+
if err != nil {
192+
return fmt.Errorf("error adding taproot "+
193+
"signature: %w", err)
194+
}
195+
196+
continue
197+
198+
default:
181199
if len(pIn.WitnessScript) == 0 {
182200
return fmt.Errorf("invalid PSBT, input %d is "+
183201
"missing witness script", inputIndex)
184202
}
185203
witnessScript = pIn.WitnessScript
186204
}
187205

188-
localPrivateKey, err := localKey.ECPrivKey()
189-
if err != nil {
190-
return fmt.Errorf("error getting private key: %w", err)
191-
}
192-
193206
// Do we already have a partial signature for our key?
194207
localPubKey := localPrivateKey.PubKey().SerializeCompressed()
195208
haveSig := false
@@ -221,14 +234,11 @@ func signPsbt(rootKey *hdkeychain.ExtendedKey,
221234
func findMatchingDerivationPath(rootKey *hdkeychain.ExtendedKey,
222235
pIn *psbt.PInput) ([]uint32, error) {
223236

224-
pubKey, err := rootKey.ECPubKey()
237+
masterFingerprint, _, err := fingerprint(rootKey)
225238
if err != nil {
226239
return nil, fmt.Errorf("error getting public key: %w", err)
227240
}
228241

229-
pubKeyHash := btcutil.Hash160(pubKey.SerializeCompressed())
230-
fingerprint := binary.LittleEndian.Uint32(pubKeyHash[:4])
231-
232242
if len(pIn.Bip32Derivation) == 0 {
233243
return nil, errNoPathFound
234244
}
@@ -246,10 +256,21 @@ func findMatchingDerivationPath(rootKey *hdkeychain.ExtendedKey,
246256

247257
// The normal case, where a derivation path has the master
248258
// fingerprint set.
249-
if derivation.MasterKeyFingerprint == fingerprint {
259+
if derivation.MasterKeyFingerprint == masterFingerprint {
250260
return derivation.Bip32Path, nil
251261
}
252262
}
253263

254264
return nil, errNoPathFound
255265
}
266+
267+
func fingerprint(rootKey *hdkeychain.ExtendedKey) (uint32, []byte, error) {
268+
pubKey, err := rootKey.ECPubKey()
269+
if err != nil {
270+
return 0, nil, fmt.Errorf("error getting public key: %w", err)
271+
}
272+
273+
pubKeyHash := btcutil.Hash160(pubKey.SerializeCompressed())
274+
fpBytes := pubKeyHash[:4]
275+
return binary.LittleEndian.Uint32(fpBytes), fpBytes, nil
276+
}

cmd/chantools/zombierecovery_makeoffer.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,12 @@ import (
2020
"github.com/btcsuite/btcd/btcutil/hdkeychain"
2121
"github.com/btcsuite/btcd/btcutil/psbt"
2222
"github.com/btcsuite/btcd/chaincfg"
23+
"github.com/btcsuite/btcd/chaincfg/chainhash"
2324
"github.com/btcsuite/btcd/txscript"
2425
"github.com/btcsuite/btcd/wire"
2526
"github.com/btcsuite/btcwallet/wallet"
2627
"github.com/lightninglabs/chantools/lnd"
28+
"github.com/lightningnetwork/lnd/fn"
2729
"github.com/lightningnetwork/lnd/input"
2830
"github.com/lightningnetwork/lnd/keychain"
2931
"github.com/lightningnetwork/lnd/lnwallet"
@@ -650,7 +652,9 @@ func matchScript(address string, key1, key2 *btcec.PublicKey,
650652
pkScript, nil
651653

652654
case *btcutil.AddressTaproot:
653-
pkScript, _, err := input.GenTaprootFundingScript(key1, key2, 0)
655+
pkScript, _, err := input.GenTaprootFundingScript(
656+
key1, key2, 0, fn.None[chainhash.Hash](),
657+
)
654658
if err != nil {
655659
return false, nil, nil, err
656660
}

doc/chantools_chanbackup.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ chantools chanbackup \
2727
-h, --help help for chanbackup
2828
--multi_file string lnd channel.backup file to create
2929
--rootkey string BIP32 HD root key of the wallet to use for creating the backup; leave empty to prompt for lnd 24 word aezeed
30-
--walletdb string read the seed/master root key to use fro creating the backup from an lnd wallet.db file instead of asking for a seed or providing the --rootkey flag
30+
--walletdb string read the seed/master root key to use for creating the backup from an lnd wallet.db file instead of asking for a seed or providing the --rootkey flag
3131
```
3232

3333
### Options inherited from parent commands

doc/chantools_closepoolaccount.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ chantools closepoolaccount \
4242
--publish publish sweep TX to the chain API instead of just printing the TX
4343
--rootkey string BIP32 HD root key of the wallet to use for deriving keys; leave empty to prompt for lnd 24 word aezeed
4444
--sweepaddr string address to recover the funds to; specify 'fromseed' to derive a new address from the seed automatically
45-
--walletdb string read the seed/master root key to use fro deriving keys from an lnd wallet.db file instead of asking for a seed or providing the --rootkey flag
45+
--walletdb string read the seed/master root key to use for deriving keys from an lnd wallet.db file instead of asking for a seed or providing the --rootkey flag
4646
```
4747

4848
### Options inherited from parent commands

doc/chantools_createwallet.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ chantools createwallet \
2626
--generateseed generate a new seed instead of using an existing one
2727
-h, --help help for createwallet
2828
--rootkey string BIP32 HD root key of the wallet to use for creating the new wallet; leave empty to prompt for lnd 24 word aezeed
29-
--walletdb string read the seed/master root key to use fro creating the new wallet from an lnd wallet.db file instead of asking for a seed or providing the --rootkey flag
29+
--walletdb string read the seed/master root key to use for creating the new wallet from an lnd wallet.db file instead of asking for a seed or providing the --rootkey flag
3030
--walletdbdir string the folder to create the new wallet.db file in
3131
```
3232

doc/chantools_deletepayments.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ If only the failed payments should be deleted (and not the successful ones), the
1010

1111
CAUTION: Running this command will make it impossible to use the channel DB
1212
with an older version of lnd. Downgrading is not possible and you'll need to
13-
run lnd v0.18.3-beta or later after using this command!'
13+
run lnd v0.18.4-beta or later after using this command!'
1414

1515
```
1616
chantools deletepayments [flags]

doc/chantools_derivekey.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ chantools derivekey --identity
2929
--neuter don't output private key(s), only public key(s)
3030
--path string BIP32 derivation path to derive; must start with "m/"
3131
--rootkey string BIP32 HD root key of the wallet to use for decrypting the backup; leave empty to prompt for lnd 24 word aezeed
32-
--walletdb string read the seed/master root key to use fro decrypting the backup from an lnd wallet.db file instead of asking for a seed or providing the --rootkey flag
32+
--walletdb string read the seed/master root key to use for decrypting the backup from an lnd wallet.db file instead of asking for a seed or providing the --rootkey flag
3333
```
3434

3535
### Options inherited from parent commands

0 commit comments

Comments
 (0)