multi: fix linter issues

pull/51/head
Oliver Gugger 2 years ago
parent a05d497f1c
commit abeca5fcd8
No known key found for this signature in database
GPG Key ID: 8E4256593F177720

@ -16,6 +16,9 @@ linters-settings:
case: case:
rules: rules:
json: snake json: snake
staticcheck:
go: "1.18"
checks: ["-SA1019"]
linters: linters:
enable-all: true enable-all: true
@ -30,6 +33,20 @@ linters:
- gomnd - gomnd
- goerr113 - goerr113
- exhaustruct - exhaustruct
- forbidigo
- gocognit
- nestif
- ifshort
- wsl
- cyclop
- gocyclo
- nlreturn
- stylecheck
- paralleltest
- ireturn
- maintidx
- noctx
- gofumpt
# deprecated # deprecated
- interfacer - interfacer

@ -16,11 +16,12 @@ import (
) )
var ( var (
// Some bitwise operands for working with big.Ints // Some bitwise operands for working with big.Ints.
shift11BitsMask = big.NewInt(2048) shift11BitsMask = big.NewInt(2048)
bigOne = big.NewInt(1) bigOne = big.NewInt(1)
// used to isolate the checksum bits from the entropy+checksum byte array // Used to isolate the checksum bits from the entropy+checksum byte
// array.
wordLengthChecksumMasksMapping = map[int]*big.Int{ wordLengthChecksumMasksMapping = map[int]*big.Int{
12: big.NewInt(15), 12: big.NewInt(15),
15: big.NewInt(31), 15: big.NewInt(31),
@ -28,10 +29,10 @@ var (
21: big.NewInt(127), 21: big.NewInt(127),
24: big.NewInt(255), 24: big.NewInt(255),
} }
// used to use only the desired x of 8 available checksum bits. // Used to use only the desired x of 8 available checksum bits.
// 256 bit (word length 24) requires all 8 bits of the checksum, // 256 bit (word length 24) requires all 8 bits of the checksum,
// and thus no shifting is needed for it (we would get a divByZero crash // and thus no shifting is needed for it (we would get a divByZero crash
// if we did) // if we did).
wordLengthChecksumShiftMapping = map[int]*big.Int{ wordLengthChecksumShiftMapping = map[int]*big.Int{
12: big.NewInt(16), 12: big.NewInt(16),
15: big.NewInt(8), 15: big.NewInt(8),
@ -41,10 +42,12 @@ var (
) )
var ( var (
// ErrInvalidMnemonic is returned when trying to use a malformed mnemonic. // ErrInvalidMnemonic is returned when trying to use a malformed
// mnemonic.
ErrInvalidMnemonic = errors.New("invalid mnenomic") ErrInvalidMnemonic = errors.New("invalid mnenomic")
// ErrChecksumIncorrect is returned when entropy has the incorrect checksum. // ErrChecksumIncorrect is returned when entropy has the incorrect
// checksum.
ErrChecksumIncorrect = errors.New("checksum incorrect") ErrChecksumIncorrect = errors.New("checksum incorrect")
) )
@ -89,7 +92,8 @@ func EntropyFromMnemonic(mnemonic string) ([]byte, error) {
entropy := b.Bytes() entropy := b.Bytes()
entropy = padByteSlice(entropy, len(mnemonicSlice)/3*4) entropy = padByteSlice(entropy, len(mnemonicSlice)/3*4)
// Generate the checksum and compare with the one we got from the mneomnic. // Generate the checksum and compare with the one we got from the
// mneomnic.
entropyChecksumBytes := computeChecksum(entropy) entropyChecksumBytes := computeChecksum(entropy)
entropyChecksum := big.NewInt(int64(entropyChecksumBytes[0])) entropyChecksum := big.NewInt(int64(entropyChecksumBytes[0]))
if l := len(mnemonicSlice); l != 24 { if l := len(mnemonicSlice); l != 24 {
@ -123,13 +127,13 @@ func padByteSlice(slice []byte, length int) []byte {
} }
func splitMnemonicWords(mnemonic string) ([]string, bool) { func splitMnemonicWords(mnemonic string) ([]string, bool) {
// Create a list of all the words in the mnemonic sentence // Create a list of all the words in the mnemonic sentence.
words := strings.Fields(mnemonic) words := strings.Fields(mnemonic)
// Get num of words // Get num of words.
numOfWords := len(words) numOfWords := len(words)
// The number of words should be 12, 15, 18, 21 or 24 // The number of words should be 12, 15, 18, 21 or 24.
if numOfWords%3 != 0 || numOfWords < 12 || numOfWords > 24 { if numOfWords%3 != 0 || numOfWords < 12 || numOfWords > 24 {
return nil, false return nil, false
} }

@ -34,7 +34,7 @@ func ReadMnemonicFromTerminal(params *chaincfg.Params) (*hdkeychain.ExtendedKey,
if mnemonicStr == "" { if mnemonicStr == "" {
// If there's no value in the environment, we'll now prompt the // If there's no value in the environment, we'll now prompt the
//user to enter in their 12 to 24 word mnemonic. // user to enter in their 12 to 24 word mnemonic.
fmt.Printf("Input your 12 to 24 word mnemonic separated by " + fmt.Printf("Input your 12 to 24 word mnemonic separated by " +
"spaces: ") "spaces: ")
mnemonicStr, err = reader.ReadString('\n') mnemonicStr, err = reader.ReadString('\n')
@ -146,7 +146,7 @@ func ReadMnemonicFromTerminal(params *chaincfg.Params) (*hdkeychain.ExtendedKey,
rootKey, err := hdkeychain.NewMaster(seed, params) rootKey, err := hdkeychain.NewMaster(seed, params)
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to derive master extended "+ return nil, fmt.Errorf("failed to derive master extended "+
"key: %v", err) "key: %w", err)
} }
return rootKey, nil return rootKey, nil
} }

@ -134,11 +134,11 @@ func (c *Cli) Format(hdKey *hdkeychain.ExtendedKey, params *chaincfg.Params,
privKey, err := hdKey.ECPrivKey() privKey, err := hdKey.ECPrivKey()
if err != nil { if err != nil {
return "", fmt.Errorf("could not derive private key: %v", err) return "", fmt.Errorf("could not derive private key: %w", err)
} }
wif, err := btcutil.NewWIF(privKey, params, true) wif, err := btcutil.NewWIF(privKey, params, true)
if err != nil { if err != nil {
return "", fmt.Errorf("could not encode WIF: %v", err) return "", fmt.Errorf("could not encode WIF: %w", err)
} }
flags := "" flags := ""
if params.Net == wire.TestNet || params.Net == wire.TestNet3 { if params.Net == wire.TestNet || params.Net == wire.TestNet3 {
@ -164,7 +164,7 @@ func (c *CliWatchOnly) Format(hdKey *hdkeychain.ExtendedKey,
pubKey, err := hdKey.ECPubKey() pubKey, err := hdKey.ECPubKey()
if err != nil { if err != nil {
return "", fmt.Errorf("could not derive private key: %v", err) return "", fmt.Errorf("could not derive private key: %w", err)
} }
flags := "" flags := ""
if params.Net == wire.TestNet || params.Net == wire.TestNet3 { if params.Net == wire.TestNet || params.Net == wire.TestNet3 {
@ -191,23 +191,23 @@ func (i *ImportWallet) Format(hdKey *hdkeychain.ExtendedKey,
privKey, err := hdKey.ECPrivKey() privKey, err := hdKey.ECPrivKey()
if err != nil { if err != nil {
return "", fmt.Errorf("could not derive private key: %v", err) return "", fmt.Errorf("could not derive private key: %w", err)
} }
wif, err := btcutil.NewWIF(privKey, params, true) wif, err := btcutil.NewWIF(privKey, params, true)
if err != nil { if err != nil {
return "", fmt.Errorf("could not encode WIF: %v", err) return "", fmt.Errorf("could not encode WIF: %w", err)
} }
addrP2PKH, err := lnd.P2PKHAddr(privKey.PubKey(), params) addrP2PKH, err := lnd.P2PKHAddr(privKey.PubKey(), params)
if err != nil { if err != nil {
return "", fmt.Errorf("could not create address: %v", err) return "", fmt.Errorf("could not create address: %w", err)
} }
addrP2WKH, err := lnd.P2WKHAddr(privKey.PubKey(), params) addrP2WKH, err := lnd.P2WKHAddr(privKey.PubKey(), params)
if err != nil { if err != nil {
return "", fmt.Errorf("could not create address: %v", err) return "", fmt.Errorf("could not create address: %w", err)
} }
addrNP2WKH, err := lnd.NP2WKHAddr(privKey.PubKey(), params) addrNP2WKH, err := lnd.NP2WKHAddr(privKey.PubKey(), params)
if err != nil { if err != nil {
return "", fmt.Errorf("could not create address: %v", err) return "", fmt.Errorf("could not create address: %w", err)
} }
return fmt.Sprintf("%s 1970-01-01T00:00:01Z label=%s/%d/%d/ "+ return fmt.Sprintf("%s 1970-01-01T00:00:01Z label=%s/%d/%d/ "+
@ -234,11 +234,11 @@ func (p *Electrum) Format(hdKey *hdkeychain.ExtendedKey,
privKey, err := hdKey.ECPrivKey() privKey, err := hdKey.ECPrivKey()
if err != nil { if err != nil {
return "", fmt.Errorf("could not derive private key: %v", err) return "", fmt.Errorf("could not derive private key: %w", err)
} }
wif, err := btcutil.NewWIF(privKey, params, true) wif, err := btcutil.NewWIF(privKey, params, true)
if err != nil { if err != nil {
return "", fmt.Errorf("could not encode WIF: %v", err) return "", fmt.Errorf("could not encode WIF: %w", err)
} }
prefix := "p2wpkh" prefix := "p2wpkh"

@ -1,6 +1,8 @@
package btc package btc
import ( import (
"errors"
"github.com/btcsuite/btclog" "github.com/btcsuite/btclog"
"github.com/guggero/chantools/dataformat" "github.com/guggero/chantools/dataformat"
) )
@ -15,7 +17,7 @@ func SummarizeChannels(apiURL string, channels []*dataformat.SummaryEntry,
for idx, channel := range channels { for idx, channel := range channels {
tx, err := api.Transaction(channel.FundingTXID) tx, err := api.Transaction(channel.FundingTXID)
if err == ErrTxNotFound { if errors.Is(err, ErrTxNotFound) {
log.Errorf("Funding TX %s not found. Ignoring.", log.Errorf("Funding TX %s not found. Ignoring.",
channel.FundingTXID) channel.FundingTXID)
channel.ChanExists = false channel.ChanExists = false

@ -45,7 +45,7 @@ channel.db file.`,
func (c *chanBackupCommand) Execute(_ *cobra.Command, _ []string) error { func (c *chanBackupCommand) Execute(_ *cobra.Command, _ []string) error {
extendedKey, err := c.rootKey.read() extendedKey, err := c.rootKey.read()
if err != nil { if err != nil {
return fmt.Errorf("error reading root key: %v", err) return fmt.Errorf("error reading root key: %w", err)
} }
// Check that we have a backup file. // Check that we have a backup file.
@ -59,7 +59,7 @@ func (c *chanBackupCommand) Execute(_ *cobra.Command, _ []string) error {
} }
db, err := lnd.OpenDB(c.ChannelDB, true) db, err := lnd.OpenDB(c.ChannelDB, true)
if err != nil { if err != nil {
return fmt.Errorf("error opening rescue DB: %v", err) return fmt.Errorf("error opening rescue DB: %w", err)
} }
multiFile := chanbackup.NewMultiFile(c.MultiFile) multiFile := chanbackup.NewMultiFile(c.MultiFile)
keyRing := &lnd.HDKeyRing{ keyRing := &lnd.HDKeyRing{

@ -121,7 +121,7 @@ obtained by running 'pool accounts list' `,
func (c *closePoolAccountCommand) Execute(_ *cobra.Command, _ []string) error { func (c *closePoolAccountCommand) Execute(_ *cobra.Command, _ []string) error {
extendedKey, err := c.rootKey.read() extendedKey, err := c.rootKey.read()
if err != nil { if err != nil {
return fmt.Errorf("error reading root key: %v", err) return fmt.Errorf("error reading root key: %w", err)
} }
// Make sure sweep addr is set. // Make sure sweep addr is set.
@ -132,17 +132,17 @@ func (c *closePoolAccountCommand) Execute(_ *cobra.Command, _ []string) error {
// Parse account outpoint and auctioneer key. // Parse account outpoint and auctioneer key.
outpoint, err := lnd.ParseOutpoint(c.Outpoint) outpoint, err := lnd.ParseOutpoint(c.Outpoint)
if err != nil { if err != nil {
return fmt.Errorf("error parsing account outpoint: %v", err) return fmt.Errorf("error parsing account outpoint: %w", err)
} }
auctioneerKeyBytes, err := hex.DecodeString(c.AuctioneerKey) auctioneerKeyBytes, err := hex.DecodeString(c.AuctioneerKey)
if err != nil { if err != nil {
return fmt.Errorf("error decoding auctioneer key: %v", err) return fmt.Errorf("error decoding auctioneer key: %w", err)
} }
auctioneerKey, err := btcec.ParsePubKey(auctioneerKeyBytes) auctioneerKey, err := btcec.ParsePubKey(auctioneerKeyBytes)
if err != nil { if err != nil {
return fmt.Errorf("error parsing auctioneer key: %v", err) return fmt.Errorf("error parsing auctioneer key: %w", err)
} }
// Set default values. // Set default values.
@ -169,7 +169,7 @@ func closePoolAccount(extendedKey *hdkeychain.ExtendedKey, apiURL string,
tx, err := api.Transaction(outpoint.Hash.String()) tx, err := api.Transaction(outpoint.Hash.String())
if err != nil { if err != nil {
return fmt.Errorf("error looking up TX %s: %v", return fmt.Errorf("error looking up TX %s: %w",
outpoint.Hash.String(), err) outpoint.Hash.String(), err)
} }
@ -180,7 +180,7 @@ func closePoolAccount(extendedKey *hdkeychain.ExtendedKey, apiURL string,
pkScript, err := hex.DecodeString(txOut.ScriptPubkey) pkScript, err := hex.DecodeString(txOut.ScriptPubkey)
if err != nil { if err != nil {
return fmt.Errorf("error decoding pk script %s: %v", return fmt.Errorf("error decoding pk script %s: %w",
txOut.ScriptPubkey, err) txOut.ScriptPubkey, err)
} }
log.Debugf("Brute forcing pk script %x for outpoint %v", pkScript, log.Debugf("Brute forcing pk script %x for outpoint %v", pkScript,
@ -195,7 +195,7 @@ func closePoolAccount(extendedKey *hdkeychain.ExtendedKey, apiURL string,
} }
accountBaseKey, err := lnd.DeriveChildren(extendedKey, path) accountBaseKey, err := lnd.DeriveChildren(extendedKey, path)
if err != nil { if err != nil {
return fmt.Errorf("error deriving account base key: %v", err) return fmt.Errorf("error deriving account base key: %w", err)
} }
// Try our luck. // Try our luck.
@ -204,7 +204,7 @@ func closePoolAccount(extendedKey *hdkeychain.ExtendedKey, apiURL string,
maxNumAccounts, maxNumBatchKeys, pkScript, maxNumAccounts, maxNumBatchKeys, pkScript,
) )
if err != nil { if err != nil {
return fmt.Errorf("error brute forcing account script: %v", err) return fmt.Errorf("error brute forcing account script: %w", err)
} }
log.Debugf("Found pool account %s", acct.String()) log.Debugf("Found pool account %s", acct.String())
@ -260,7 +260,7 @@ func closePoolAccount(extendedKey *hdkeychain.ExtendedKey, apiURL string,
} }
sig, err := signer.SignOutputRaw(sweepTx, signDesc) sig, err := signer.SignOutputRaw(sweepTx, signDesc)
if err != nil { if err != nil {
return fmt.Errorf("error signing sweep tx: %v", err) return fmt.Errorf("error signing sweep tx: %w", err)
} }
ourSig := append(sig.Serialize(), byte(signDesc.HashType)) ourSig := append(sig.Serialize(), byte(signDesc.HashType))
sweepTx.TxIn[0].Witness = poolscript.SpendExpiry( sweepTx.TxIn[0].Witness = poolscript.SpendExpiry(
@ -314,13 +314,13 @@ func bruteForceAccountScript(accountBaseKey *hdkeychain.ExtendedKey,
accountExtendedKey, err := accountBaseKey.DeriveNonStandard(i) accountExtendedKey, err := accountBaseKey.DeriveNonStandard(i)
if err != nil { if err != nil {
return nil, fmt.Errorf("error deriving account key: "+ return nil, fmt.Errorf("error deriving account key: "+
"%v", err) "%w", err)
} }
accountPrivKey, err := accountExtendedKey.ECPrivKey() accountPrivKey, err := accountExtendedKey.ECPrivKey()
if err != nil { if err != nil {
return nil, fmt.Errorf("error deriving private key: "+ return nil, fmt.Errorf("error deriving private key: "+
"%v", err) "%w", err)
} }
log.Debugf("Trying trader key %x...", log.Debugf("Trying trader key %x...",
accountPrivKey.PubKey().SerializeCompressed()) accountPrivKey.PubKey().SerializeCompressed())
@ -328,7 +328,7 @@ func bruteForceAccountScript(accountBaseKey *hdkeychain.ExtendedKey,
sharedKey, err := lnd.ECDH(accountPrivKey, auctioneerKey) sharedKey, err := lnd.ECDH(accountPrivKey, auctioneerKey)
if err != nil { if err != nil {
return nil, fmt.Errorf("error deriving shared key: "+ return nil, fmt.Errorf("error deriving shared key: "+
"%v", err) "%w", err)
} }
// The next loop is over the batch keys. // The next loop is over the batch keys.
@ -350,7 +350,7 @@ func bruteForceAccountScript(accountBaseKey *hdkeychain.ExtendedKey,
) )
if err != nil { if err != nil {
return nil, fmt.Errorf("error "+ return nil, fmt.Errorf("error "+
"deriving script: %v", err) "deriving script: %w", err)
} }
traderKeyTweak := poolscript.TraderKeyTweak( traderKeyTweak := poolscript.TraderKeyTweak(
@ -406,12 +406,12 @@ func fastScript(expiryFrom, expiryTo uint32, traderKey, auctioneerKey,
currentScript, err := builder.Script() currentScript, err := builder.Script()
if err != nil { if err != nil {
return 0, fmt.Errorf("error building script: %v", err) return 0, fmt.Errorf("error building script: %w", err)
} }
currentPkScript, err := input.WitnessScriptHash(currentScript) currentPkScript, err := input.WitnessScriptHash(currentScript)
if err != nil { if err != nil {
return 0, fmt.Errorf("error hashing script: %v", err) return 0, fmt.Errorf("error hashing script: %w", err)
} }
if bytes.Equal(currentPkScript, targetScript) { if bytes.Equal(currentPkScript, targetScript) {
return block, nil return block, nil

@ -62,19 +62,19 @@ func (c *compactDBCommand) Execute(_ *cobra.Command, _ []string) error {
} }
src, err := c.openDB(c.SourceDB, true) src, err := c.openDB(c.SourceDB, true)
if err != nil { if err != nil {
return fmt.Errorf("error opening source DB: %v", err) return fmt.Errorf("error opening source DB: %w", err)
} }
defer func() { _ = src.Close() }() defer func() { _ = src.Close() }()
dst, err := c.openDB(c.DestDB, false) dst, err := c.openDB(c.DestDB, false)
if err != nil { if err != nil {
return fmt.Errorf("error opening destination DB: %v", err) return fmt.Errorf("error opening destination DB: %w", err)
} }
defer func() { _ = dst.Close() }() defer func() { _ = dst.Close() }()
err = c.compact(dst, src) err = c.compact(dst, src)
if err != nil { if err != nil {
return fmt.Errorf("error compacting DB: %v", err) return fmt.Errorf("error compacting DB: %w", err)
} }
return nil return nil
} }

@ -49,7 +49,7 @@ func (c *deletePaymentsCommand) Execute(_ *cobra.Command, _ []string) error {
} }
db, err := lnd.OpenDB(c.ChannelDB, false) db, err := lnd.OpenDB(c.ChannelDB, false)
if err != nil { if err != nil {
return fmt.Errorf("error opening rescue DB: %v", err) return fmt.Errorf("error opening rescue DB: %w", err)
} }
defer func() { _ = db.Close() }() defer func() { _ = db.Close() }()

@ -63,7 +63,7 @@ chantools derivekey --identity`,
func (c *deriveKeyCommand) Execute(_ *cobra.Command, _ []string) error { func (c *deriveKeyCommand) Execute(_ *cobra.Command, _ []string) error {
extendedKey, err := c.rootKey.read() extendedKey, err := c.rootKey.read()
if err != nil { if err != nil {
return fmt.Errorf("error reading root key: %v", err) return fmt.Errorf("error reading root key: %w", err)
} }
if c.Identity { if c.Identity {
@ -79,24 +79,24 @@ func deriveKey(extendedKey *hdkeychain.ExtendedKey, path string,
child, pubKey, wif, err := lnd.DeriveKey(extendedKey, path, chainParams) child, pubKey, wif, err := lnd.DeriveKey(extendedKey, path, chainParams)
if err != nil { if err != nil {
return fmt.Errorf("could not derive keys: %v", err) return fmt.Errorf("could not derive keys: %w", err)
} }
neutered, err := child.Neuter() neutered, err := child.Neuter()
if err != nil { if err != nil {
return fmt.Errorf("could not neuter child key: %v", err) return fmt.Errorf("could not neuter child key: %w", err)
} }
// Print the address too. // Print the address too.
hash160 := btcutil.Hash160(pubKey.SerializeCompressed()) hash160 := btcutil.Hash160(pubKey.SerializeCompressed())
addrP2PKH, err := btcutil.NewAddressPubKeyHash(hash160, chainParams) addrP2PKH, err := btcutil.NewAddressPubKeyHash(hash160, chainParams)
if err != nil { if err != nil {
return fmt.Errorf("could not create address: %v", err) return fmt.Errorf("could not create address: %w", err)
} }
addrP2WKH, err := btcutil.NewAddressWitnessPubKeyHash( addrP2WKH, err := btcutil.NewAddressWitnessPubKeyHash(
hash160, chainParams, hash160, chainParams,
) )
if err != nil { if err != nil {
return fmt.Errorf("could not create address: %v", err) return fmt.Errorf("could not create address: %w", err)
} }
privKey, xPriv := na, na privKey, xPriv := na, na

@ -1,7 +1,6 @@
package main package main
import ( import (
"os"
"testing" "testing"
"github.com/guggero/chantools/btc" "github.com/guggero/chantools/btc"
@ -39,12 +38,10 @@ func TestDeriveKeyAezeedNoPassphrase(t *testing.T) {
rootKey: &rootKey{}, rootKey: &rootKey{},
} }
err := os.Setenv(lnd.MnemonicEnvName, seedAezeedNoPassphrase) t.Setenv(lnd.MnemonicEnvName, seedAezeedNoPassphrase)
require.NoError(t, err) t.Setenv(lnd.PassphraseEnvName, "-")
err = os.Setenv(lnd.PassphraseEnvName, "-")
require.NoError(t, err)
err = derive.Execute(nil, nil) err := derive.Execute(nil, nil)
require.NoError(t, err) require.NoError(t, err)
h.assertLogContains(keyContent) h.assertLogContains(keyContent)
@ -59,12 +56,10 @@ func TestDeriveKeyAezeedWithPassphrase(t *testing.T) {
rootKey: &rootKey{}, rootKey: &rootKey{},
} }
err := os.Setenv(lnd.MnemonicEnvName, seedAezeedWithPassphrase) t.Setenv(lnd.MnemonicEnvName, seedAezeedWithPassphrase)
require.NoError(t, err) t.Setenv(lnd.PassphraseEnvName, testPassPhrase)
err = os.Setenv(lnd.PassphraseEnvName, testPassPhrase)
require.NoError(t, err)
err = derive.Execute(nil, nil) err := derive.Execute(nil, nil)
require.NoError(t, err) require.NoError(t, err)
h.assertLogContains(keyContent) h.assertLogContains(keyContent)
@ -79,12 +74,10 @@ func TestDeriveKeySeedBip39(t *testing.T) {
rootKey: &rootKey{BIP39: true}, rootKey: &rootKey{BIP39: true},
} }
err := os.Setenv(btc.BIP39MnemonicEnvName, seedBip39) t.Setenv(btc.BIP39MnemonicEnvName, seedBip39)
require.NoError(t, err) t.Setenv(btc.BIP39PassphraseEnvName, "-")
err = os.Setenv(btc.BIP39PassphraseEnvName, "-")
require.NoError(t, err)
err = derive.Execute(nil, nil) err := derive.Execute(nil, nil)
require.NoError(t, err) require.NoError(t, err)
h.assertLogContains(keyContentBIP39) h.assertLogContains(keyContentBIP39)

@ -4,6 +4,8 @@ import (
"bytes" "bytes"
"encoding/hex" "encoding/hex"
"fmt" "fmt"
"time"
"github.com/btcsuite/btcd/btcec/v2" "github.com/btcsuite/btcd/btcec/v2"
"github.com/btcsuite/btcd/btcutil" "github.com/btcsuite/btcd/btcutil"
"github.com/btcsuite/btcd/wire" "github.com/btcsuite/btcd/wire"
@ -13,7 +15,6 @@ import (
"github.com/lightningnetwork/lnd/keychain" "github.com/lightningnetwork/lnd/keychain"
"github.com/lightningnetwork/lnd/lnwire" "github.com/lightningnetwork/lnd/lnwire"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"time"
) )
var ( var (
@ -84,7 +85,7 @@ func (c *dropChannelGraphCommand) Execute(_ *cobra.Command, _ []string) error {
} }
db, err := lnd.OpenDB(c.ChannelDB, false) db, err := lnd.OpenDB(c.ChannelDB, false)
if err != nil { if err != nil {
return fmt.Errorf("error opening rescue DB: %v", err) return fmt.Errorf("error opening rescue DB: %w", err)
} }
defer func() { _ = db.Close() }() defer func() { _ = db.Close() }()
@ -94,12 +95,12 @@ func (c *dropChannelGraphCommand) Execute(_ *cobra.Command, _ []string) error {
idKeyBytes, err := hex.DecodeString(c.NodeIdentityKey) idKeyBytes, err := hex.DecodeString(c.NodeIdentityKey)
if err != nil { if err != nil {
return fmt.Errorf("error hex decoding node identity key: %v", return fmt.Errorf("error hex decoding node identity key: %w",
err) err)
} }
idKey, err := btcec.ParsePubKey(idKeyBytes) idKey, err := btcec.ParsePubKey(idKeyBytes)
if err != nil { if err != nil {
return fmt.Errorf("error parsing node identity key: %v", err) return fmt.Errorf("error parsing node identity key: %w", err)
} }
if c.SingleChannel != 0 { if c.SingleChannel != 0 {
@ -138,7 +139,7 @@ func (c *dropChannelGraphCommand) Execute(_ *cobra.Command, _ []string) error {
func insertOwnNodeAndChannels(idKey *btcec.PublicKey, db *channeldb.DB) error { func insertOwnNodeAndChannels(idKey *btcec.PublicKey, db *channeldb.DB) error {
openChannels, err := db.ChannelStateDB().FetchAllOpenChannels() openChannels, err := db.ChannelStateDB().FetchAllOpenChannels()
if err != nil { if err != nil {
return fmt.Errorf("error fetching open channels: %v", err) return fmt.Errorf("error fetching open channels: %w", err)
} }
graph := db.ChannelGraph() graph := db.ChannelGraph()
@ -152,7 +153,7 @@ func insertOwnNodeAndChannels(idKey *btcec.PublicKey, db *channeldb.DB) error {
openChan.Capacity, openChan.FundingOutpoint, openChan.Capacity, openChan.FundingOutpoint,
) )
if err != nil { if err != nil {
return fmt.Errorf("error creating announcement: %v", return fmt.Errorf("error creating announcement: %w",
err) err)
} }
@ -221,7 +222,7 @@ func newChanAnnouncement(localPubKey, remotePubKey *btcec.PublicKey,
var featureBuf bytes.Buffer var featureBuf bytes.Buffer
if err := chanAnn.Features.Encode(&featureBuf); err != nil { if err := chanAnn.Features.Encode(&featureBuf); err != nil {
log.Errorf("unable to encode features: %v", err) log.Errorf("unable to encode features: %w", err)
return nil, nil, err return nil, nil, err
} }

@ -42,7 +42,7 @@ channel.backup file in a human readable format.`,
func (c *dumpBackupCommand) Execute(_ *cobra.Command, _ []string) error { func (c *dumpBackupCommand) Execute(_ *cobra.Command, _ []string) error {
extendedKey, err := c.rootKey.read() extendedKey, err := c.rootKey.read()
if err != nil { if err != nil {
return fmt.Errorf("error reading root key: %v", err) return fmt.Errorf("error reading root key: %w", err)
} }
// Check that we have a backup file. // Check that we have a backup file.
@ -62,7 +62,7 @@ func dumpChannelBackup(multiFile *chanbackup.MultiFile,
multi, err := multiFile.ExtractMulti(ring) multi, err := multiFile.ExtractMulti(ring)
if err != nil { if err != nil {
return fmt.Errorf("could not extract multi file: %v", err) return fmt.Errorf("could not extract multi file: %w", err)
} }
content := dump.BackupMulti{ content := dump.BackupMulti{
Version: multi.Version, Version: multi.Version,

@ -48,7 +48,7 @@ func (c *dumpChannelsCommand) Execute(_ *cobra.Command, _ []string) error {
} }
db, err := lnd.OpenDB(c.ChannelDB, true) db, err := lnd.OpenDB(c.ChannelDB, true)
if err != nil { if err != nil {
return fmt.Errorf("error opening rescue DB: %v", err) return fmt.Errorf("error opening rescue DB: %w", err)
} }
defer func() { _ = db.Close() }() defer func() { _ = db.Close() }()
@ -66,7 +66,7 @@ func dumpOpenChannelInfo(chanDb *channeldb.ChannelStateDB) error {
dumpChannels, err := dump.OpenChannelDump(channels, chainParams) dumpChannels, err := dump.OpenChannelDump(channels, chainParams)
if err != nil { if err != nil {
return fmt.Errorf("error converting to dump format: %v", err) return fmt.Errorf("error converting to dump format: %w", err)
} }
spew.Dump(dumpChannels) spew.Dump(dumpChannels)
@ -85,7 +85,7 @@ func dumpClosedChannelInfo(chanDb *channeldb.ChannelStateDB) error {
dumpChannels, err := dump.ClosedChannelDump(channels, chainParams) dumpChannels, err := dump.ClosedChannelDump(channels, chainParams)
if err != nil { if err != nil {
return fmt.Errorf("error converting to dump format: %v", err) return fmt.Errorf("error converting to dump format: %w", err)
} }
spew.Dump(dumpChannels) spew.Dump(dumpChannels)

@ -123,7 +123,7 @@ chantools fakechanbackup --from_channel_graph lncli_describegraph.json \
func (c *fakeChanBackupCommand) Execute(_ *cobra.Command, _ []string) error { func (c *fakeChanBackupCommand) Execute(_ *cobra.Command, _ []string) error {
extendedKey, err := c.rootKey.read() extendedKey, err := c.rootKey.read()
if err != nil { if err != nil {
return fmt.Errorf("error reading root key: %v", err) return fmt.Errorf("error reading root key: %w", err)
} }
multiFile := chanbackup.NewMultiFile(c.MultiFile) multiFile := chanbackup.NewMultiFile(c.MultiFile)
@ -141,7 +141,7 @@ func (c *fakeChanBackupCommand) Execute(_ *cobra.Command, _ []string) error {
graph := &lnrpc.ChannelGraph{} graph := &lnrpc.ChannelGraph{}
err = jsonpb.UnmarshalString(string(graphBytes), graph) err = jsonpb.UnmarshalString(string(graphBytes), graph)
if err != nil { if err != nil {
return fmt.Errorf("error parsing graph JSON: %v", err) return fmt.Errorf("error parsing graph JSON: %w", err)
} }
return backupFromGraph(graph, keyRing, multiFile) return backupFromGraph(graph, keyRing, multiFile)
@ -150,7 +150,7 @@ func (c *fakeChanBackupCommand) Execute(_ *cobra.Command, _ []string) error {
// Parse channel point of channel to fake. // Parse channel point of channel to fake.
chanOp, err := lnd.ParseOutpoint(c.ChannelPoint) chanOp, err := lnd.ParseOutpoint(c.ChannelPoint)
if err != nil { if err != nil {
return fmt.Errorf("error parsing channel point: %v", err) return fmt.Errorf("error parsing channel point: %w", err)
} }
// Now parse the remote node info. // Now parse the remote node info.
@ -161,23 +161,22 @@ func (c *fakeChanBackupCommand) Execute(_ *cobra.Command, _ []string) error {
} }
pubKeyBytes, err := hex.DecodeString(splitNodeInfo[0]) pubKeyBytes, err := hex.DecodeString(splitNodeInfo[0])
if err != nil { if err != nil {
return fmt.Errorf("could not parse pubkey hex string: %s", err) return fmt.Errorf("could not parse pubkey hex string: %w", err)
} }
nodePubkey, err := btcec.ParsePubKey(pubKeyBytes) nodePubkey, err := btcec.ParsePubKey(pubKeyBytes)
if err != nil { if err != nil {
return fmt.Errorf("could not parse pubkey: %s", err) return fmt.Errorf("could not parse pubkey: %w", err)
} }
host, portStr, err := net.SplitHostPort(splitNodeInfo[1]) host, portStr, err := net.SplitHostPort(splitNodeInfo[1])
if err != nil { if err != nil {
return fmt.Errorf("could not split host and port: %v", return fmt.Errorf("could not split host and port: %w", err)
err)
} }
var addr net.Addr var addr net.Addr
if tor.IsOnionHost(host) { if tor.IsOnionHost(host) {
port, err := strconv.Atoi(portStr) port, err := strconv.Atoi(portStr)
if err != nil { if err != nil {
return fmt.Errorf("could not parse port: %v", err) return fmt.Errorf("could not parse port: %w", err)
} }
addr = &tor.OnionAddr{ addr = &tor.OnionAddr{
OnionService: host, OnionService: host,
@ -186,7 +185,7 @@ func (c *fakeChanBackupCommand) Execute(_ *cobra.Command, _ []string) error {
} else { } else {
addr, err = net.ResolveTCPAddr("tcp", splitNodeInfo[1]) addr, err = net.ResolveTCPAddr("tcp", splitNodeInfo[1])
if err != nil { if err != nil {
return fmt.Errorf("could not parse addr: %s", err) return fmt.Errorf("could not parse addr: %w", err)
} }
} }
@ -199,15 +198,15 @@ func (c *fakeChanBackupCommand) Execute(_ *cobra.Command, _ []string) error {
} }
blockHeight, err := strconv.ParseInt(splitChanID[0], 10, 32) blockHeight, err := strconv.ParseInt(splitChanID[0], 10, 32)
if err != nil { if err != nil {
return fmt.Errorf("could not parse block height: %s", err) return fmt.Errorf("could not parse block height: %w", err)
} }
txIndex, err := strconv.ParseInt(splitChanID[1], 10, 32) txIndex, err := strconv.ParseInt(splitChanID[1], 10, 32)
if err != nil { if err != nil {
return fmt.Errorf("could not parse transaction index: %s", err) return fmt.Errorf("could not parse transaction index: %w", err)
} }
chanOutputIdx, err := strconv.ParseInt(splitChanID[2], 10, 32) chanOutputIdx, err := strconv.ParseInt(splitChanID[2], 10, 32)
if err != nil { if err != nil {
return fmt.Errorf("could not parse output index: %s", err) return fmt.Errorf("could not parse output index: %w", err)
} }
shortChanID := lnwire.ShortChannelID{ shortChanID := lnwire.ShortChannelID{
BlockHeight: uint32(blockHeight), BlockHeight: uint32(blockHeight),
@ -235,7 +234,7 @@ func backupFromGraph(graph *lnrpc.ChannelGraph, keyRing *lnd.HDKeyRing,
// identity pubkey by just deriving it. // identity pubkey by just deriving it.
nodePubKey, err := keyRing.NodePubKey() nodePubKey, err := keyRing.NodePubKey()
if err != nil { if err != nil {
return fmt.Errorf("error deriving node pubkey: %v", err) return fmt.Errorf("error deriving node pubkey: %w", err)
} }
nodePubKeyStr := hex.EncodeToString(nodePubKey.SerializeCompressed()) nodePubKeyStr := hex.EncodeToString(nodePubKey.SerializeCompressed())
@ -254,11 +253,11 @@ func backupFromGraph(graph *lnrpc.ChannelGraph, keyRing *lnd.HDKeyRing,
peerPubKeyBytes, err := hex.DecodeString(peerPubKeyStr) peerPubKeyBytes, err := hex.DecodeString(peerPubKeyStr)
if err != nil { if err != nil {
return fmt.Errorf("error parsing hex: %v", err) return fmt.Errorf("error parsing hex: %w", err)
} }
peerPubKey, err := btcec.ParsePubKey(peerPubKeyBytes) peerPubKey, err := btcec.ParsePubKey(peerPubKeyBytes)
if err != nil { if err != nil {
return fmt.Errorf("error parsing pubkey: %v", err) return fmt.Errorf("error parsing pubkey: %w", err)
} }
peer, err := lnd.FindNode(graph, peerPubKeyStr) peer, err := lnd.FindNode(graph, peerPubKeyStr)
@ -274,7 +273,7 @@ func backupFromGraph(graph *lnrpc.ChannelGraph, keyRing *lnd.HDKeyRing,
) )
if err != nil { if err != nil {
return fmt.Errorf("error parsing "+ return fmt.Errorf("error parsing "+
"tor address: %v", err) "tor address: %w", err)
} }
continue continue
@ -283,7 +282,7 @@ func backupFromGraph(graph *lnrpc.ChannelGraph, keyRing *lnd.HDKeyRing,
"tcp", peerAddr.Addr, "tcp", peerAddr.Addr,
) )
if err != nil { if err != nil {
return fmt.Errorf("could not parse addr: %s", return fmt.Errorf("could not parse addr: %w",
err) err)
} }
} }
@ -291,7 +290,7 @@ func backupFromGraph(graph *lnrpc.ChannelGraph, keyRing *lnd.HDKeyRing,
shortChanID := lnwire.NewShortChanIDFromInt(channel.ChannelId) shortChanID := lnwire.NewShortChanIDFromInt(channel.ChannelId)
chanOp, err := lnd.ParseOutpoint(channel.ChanPoint) chanOp, err := lnd.ParseOutpoint(channel.ChanPoint)
if err != nil { if err != nil {
return fmt.Errorf("error parsing channel point: %v", return fmt.Errorf("error parsing channel point: %w",
err) err)
} }
@ -314,7 +313,7 @@ func writeBackups(singles []chanbackup.Single, keyRing keychain.KeyRing,
var packed bytes.Buffer var packed bytes.Buffer
err := newMulti.PackToWriter(&packed, keyRing) err := newMulti.PackToWriter(&packed, keyRing)
if err != nil { if err != nil {
return fmt.Errorf("unable to multi-pack backups: %v", err) return fmt.Errorf("unable to multi-pack backups: %w", err)
} }
return multiFile.UpdateAndSwap(packed.Bytes()) return multiFile.UpdateAndSwap(packed.Bytes())

@ -51,7 +51,7 @@ channels (identified by their funding transaction outpoints).`,
func (c *filterBackupCommand) Execute(_ *cobra.Command, _ []string) error { func (c *filterBackupCommand) Execute(_ *cobra.Command, _ []string) error {
extendedKey, err := c.rootKey.read() extendedKey, err := c.rootKey.read()
if err != nil { if err != nil {
return fmt.Errorf("error reading root key: %v", err) return fmt.Errorf("error reading root key: %w", err)
} }
// Parse discard filter. // Parse discard filter.
@ -74,7 +74,7 @@ func filterChannelBackup(multiFile *chanbackup.MultiFile, ring keychain.KeyRing,
multi, err := multiFile.ExtractMulti(ring) multi, err := multiFile.ExtractMulti(ring)
if err != nil { if err != nil {
return fmt.Errorf("could not extract multi file: %v", err) return fmt.Errorf("could not extract multi file: %w", err)
} }
keep := make([]chanbackup.Single, 0, len(multi.StaticBackups)) keep := make([]chanbackup.Single, 0, len(multi.StaticBackups))

@ -1,6 +1,7 @@
package main package main
import ( import (
"errors"
"fmt" "fmt"
"os" "os"
"time" "time"
@ -47,7 +48,7 @@ derive private key</code>).`,
func (c *fixOldBackupCommand) Execute(_ *cobra.Command, _ []string) error { func (c *fixOldBackupCommand) Execute(_ *cobra.Command, _ []string) error {
extendedKey, err := c.rootKey.read() extendedKey, err := c.rootKey.read()
if err != nil { if err != nil {
return fmt.Errorf("error reading root key: %v", err) return fmt.Errorf("error reading root key: %w", err)
} }
// Check that we have a backup file. // Check that we have a backup file.
@ -67,7 +68,7 @@ func fixOldChannelBackup(multiFile *chanbackup.MultiFile,
multi, err := multiFile.ExtractMulti(ring) multi, err := multiFile.ExtractMulti(ring)
if err != nil { if err != nil {
return fmt.Errorf("could not extract multi file: %v", err) return fmt.Errorf("could not extract multi file: %w", err)
} }
log.Infof("Checking shachain root of %d channels, this might take a "+ log.Infof("Checking shachain root of %d channels, this might take a "+
@ -75,11 +76,11 @@ func fixOldChannelBackup(multiFile *chanbackup.MultiFile,
fixedChannels := 0 fixedChannels := 0
for idx, single := range multi.StaticBackups { for idx, single := range multi.StaticBackups {
err := ring.CheckDescriptor(single.ShaChainRootDesc) err := ring.CheckDescriptor(single.ShaChainRootDesc)
switch err { switch {
case nil: case err == nil:
continue continue
case keychain.ErrCannotDerivePrivKey: case errors.Is(err, keychain.ErrCannotDerivePrivKey):
// Fix the incorrect descriptor by deriving a default // Fix the incorrect descriptor by deriving a default
// one and overwriting it in the backup. // one and overwriting it in the backup.
log.Infof("The shachain root for channel %s could "+ log.Infof("The shachain root for channel %s could "+
@ -97,7 +98,7 @@ func fixOldChannelBackup(multiFile *chanbackup.MultiFile,
default: default:
return fmt.Errorf("could not check shachain root "+ return fmt.Errorf("could not check shachain root "+
"descriptor: %v", err) "descriptor: %w", err)
} }
} }
if fixedChannels == 0 { if fixedChannels == 0 {

@ -75,7 +75,7 @@ blocks) transaction *or* they have a watch tower looking out for them.
func (c *forceCloseCommand) Execute(_ *cobra.Command, _ []string) error { func (c *forceCloseCommand) Execute(_ *cobra.Command, _ []string) error {
extendedKey, err := c.rootKey.read() extendedKey, err := c.rootKey.read()
if err != nil { if err != nil {
return fmt.Errorf("error reading root key: %v", err) return fmt.Errorf("error reading root key: %w", err)
} }
// Check that we have a channel DB. // Check that we have a channel DB.
@ -84,7 +84,7 @@ func (c *forceCloseCommand) Execute(_ *cobra.Command, _ []string) error {
} }
db, err := lnd.OpenDB(c.ChannelDB, true) db, err := lnd.OpenDB(c.ChannelDB, true)
if err != nil { if err != nil {
return fmt.Errorf("error opening rescue DB: %v", err) return fmt.Errorf("error opening rescue DB: %w", err)
} }
// Parse channel entries from any of the possible input files. // Parse channel entries from any of the possible input files.
@ -132,6 +132,7 @@ func forceCloseChannels(apiURL string, extendedKey *hdkeychain.ExtendedKey,
if localCommitTx == nil { if localCommitTx == nil {
log.Errorf("Cannot force-close, no local commit TX "+ log.Errorf("Cannot force-close, no local commit TX "+
"for channel %s", channelEntry.ChannelPoint) "for channel %s", channelEntry.ChannelPoint)
continue continue
} }

@ -99,7 +99,7 @@ func (c *genImportScriptCommand) Execute(_ *cobra.Command, _ []string) error {
extendedKey, birthday, err := c.rootKey.readWithBirthday() extendedKey, birthday, err := c.rootKey.readWithBirthday()
if err != nil { if err != nil {
return fmt.Errorf("error reading root key: %v", err) return fmt.Errorf("error reading root key: %w", err)
} }
// The btcwallet gives the birthday a slack of 48 hours, let's do the // The btcwallet gives the birthday a slack of 48 hours, let's do the
@ -127,7 +127,7 @@ func (c *genImportScriptCommand) Execute(_ *cobra.Command, _ []string) error {
case c.DerivationPath != "": case c.DerivationPath != "":
derivationPath, err := lnd.ParsePath(c.DerivationPath) derivationPath, err := lnd.ParsePath(c.DerivationPath)
if err != nil { if err != nil {
return fmt.Errorf("error parsing path: %v", err) return fmt.Errorf("error parsing path: %w", err)
} }
strPaths = []string{c.DerivationPath} strPaths = []string{c.DerivationPath}
paths = [][]uint32{derivationPath} paths = [][]uint32{derivationPath}
@ -139,7 +139,7 @@ func (c *genImportScriptCommand) Execute(_ *cobra.Command, _ []string) error {
case c.LndPaths: case c.LndPaths:
strPaths, paths, err = lnd.AllDerivationPaths(chainParams) strPaths, paths, err = lnd.AllDerivationPaths(chainParams)
if err != nil { if err != nil {
return fmt.Errorf("error getting lnd paths: %v", err) return fmt.Errorf("error getting lnd paths: %w", err)
} }
} }
@ -153,7 +153,7 @@ func (c *genImportScriptCommand) Execute(_ *cobra.Command, _ []string) error {
var err error var err error
writer, err = os.Create(fileName) writer, err = os.Create(fileName)
if err != nil { if err != nil {
return fmt.Errorf("error creating result file %s: %v", return fmt.Errorf("error creating result file %s: %w",
fileName, err) fileName, err)
} }
} }
@ -164,7 +164,7 @@ func (c *genImportScriptCommand) Execute(_ *cobra.Command, _ []string) error {
c.RescanFrom, exporter, writer, c.RescanFrom, exporter, writer,
) )
if err != nil { if err != nil {
return fmt.Errorf("error exporting keys: %v", err) return fmt.Errorf("error exporting keys: %w", err)
} }
return nil return nil

@ -45,7 +45,7 @@ func (c *migrateDBCommand) Execute(_ *cobra.Command, _ []string) error {
} }
db, err := lnd.OpenDB(c.ChannelDB, false) db, err := lnd.OpenDB(c.ChannelDB, false)
if err != nil { if err != nil {
return fmt.Errorf("error opening DB: %v", err) return fmt.Errorf("error opening DB: %w", err)
} }
return db.Close() return db.Close()

@ -57,11 +57,11 @@ func (c *removeChannelCommand) Execute(_ *cobra.Command, _ []string) error {
} }
db, err := lnd.OpenDB(c.ChannelDB, false) db, err := lnd.OpenDB(c.ChannelDB, false)
if err != nil { if err != nil {
return fmt.Errorf("error opening channel DB: %v", err) return fmt.Errorf("error opening channel DB: %w", err)
} }
defer func() { defer func() {
if err := db.Close(); err != nil { if err := db.Close(); err != nil {
log.Errorf("Error closing DB: %v", err) log.Errorf("Error closing DB: %w", err)
} }
}() }()

@ -108,7 +108,7 @@ chantools rescueclosed --fromsummary results/summary-xxxxxx.json \
func (c *rescueClosedCommand) Execute(_ *cobra.Command, _ []string) error { func (c *rescueClosedCommand) Execute(_ *cobra.Command, _ []string) error {
extendedKey, err := c.rootKey.read() extendedKey, err := c.rootKey.read()
if err != nil { if err != nil {
return fmt.Errorf("error reading root key: %v", err) return fmt.Errorf("error reading root key: %w", err)
} }
// What way of recovery has the user chosen? From summary and DB or from // What way of recovery has the user chosen? From summary and DB or from
@ -117,7 +117,7 @@ func (c *rescueClosedCommand) Execute(_ *cobra.Command, _ []string) error {
case c.ChannelDB != "": case c.ChannelDB != "":
db, err := lnd.OpenDB(c.ChannelDB, true) db, err := lnd.OpenDB(c.ChannelDB, true)
if err != nil { if err != nil {
return fmt.Errorf("error opening rescue DB: %v", err) return fmt.Errorf("error opening rescue DB: %w", err)
} }
// Parse channel entries from any of the possible input files. // Parse channel entries from any of the possible input files.
@ -129,7 +129,7 @@ func (c *rescueClosedCommand) Execute(_ *cobra.Command, _ []string) error {
commitPoints, err := commitPointsFromDB(db.ChannelStateDB()) commitPoints, err := commitPointsFromDB(db.ChannelStateDB())
if err != nil { if err != nil {
return fmt.Errorf("error reading commit points from "+ return fmt.Errorf("error reading commit points from "+
"db: %v", err) "db: %w", err)
} }
return rescueClosedChannels(extendedKey, entries, commitPoints) return rescueClosedChannels(extendedKey, entries, commitPoints)
@ -137,18 +137,18 @@ func (c *rescueClosedCommand) Execute(_ *cobra.Command, _ []string) error {
// First parse address to get targetPubKeyHash from it later. // First parse address to get targetPubKeyHash from it later.
targetAddr, err := btcutil.DecodeAddress(c.Addr, chainParams) targetAddr, err := btcutil.DecodeAddress(c.Addr, chainParams)
if err != nil { if err != nil {
return fmt.Errorf("error parsing addr: %v", err) return fmt.Errorf("error parsing addr: %w", err)
} }
// Now parse the commit point. // Now parse the commit point.
commitPointRaw, err := hex.DecodeString(c.CommitPoint) commitPointRaw, err := hex.DecodeString(c.CommitPoint)
if err != nil { if err != nil {
return fmt.Errorf("error decoding commit point: %v", return fmt.Errorf("error decoding commit point: %w",
err) err)
} }
commitPoint, err := btcec.ParsePubKey(commitPointRaw) commitPoint, err := btcec.ParsePubKey(commitPointRaw)
if err != nil { if err != nil {
return fmt.Errorf("error parsing commit point: %v", err) return fmt.Errorf("error parsing commit point: %w", err)
} }
return rescueClosedChannel(extendedKey, targetAddr, commitPoint) return rescueClosedChannel(extendedKey, targetAddr, commitPoint)
@ -163,7 +163,7 @@ func (c *rescueClosedCommand) Execute(_ *cobra.Command, _ []string) error {
commitPoints, err := commitPointsFromLogFile(c.LndLog) commitPoints, err := commitPointsFromLogFile(c.LndLog)
if err != nil { if err != nil {
return fmt.Errorf("error parsing commit points from "+ return fmt.Errorf("error parsing commit points from "+
"log file: %v", err) "log file: %w", err)
} }
return rescueClosedChannels(extendedKey, entries, commitPoints) return rescueClosedChannels(extendedKey, entries, commitPoints)
@ -201,7 +201,7 @@ func commitPointsFromDB(chanDb *channeldb.ChannelStateDB) ([]*btcec.PublicKey,
func commitPointsFromLogFile(lndLog string) ([]*btcec.PublicKey, error) { func commitPointsFromLogFile(lndLog string) ([]*btcec.PublicKey, error) {
logFileBytes, err := ioutil.ReadFile(lndLog) logFileBytes, err := ioutil.ReadFile(lndLog)
if err != nil { if err != nil {
return nil, fmt.Errorf("error reading log file %s: %v", lndLog, return nil, fmt.Errorf("error reading log file %s: %w", lndLog,
err) err)
} }
@ -213,12 +213,12 @@ func commitPointsFromLogFile(lndLog string) ([]*btcec.PublicKey, error) {
commitPointBytes, err := hex.DecodeString(groups[1]) commitPointBytes, err := hex.DecodeString(groups[1])
if err != nil { if err != nil {
return nil, fmt.Errorf("error parsing commit point "+ return nil, fmt.Errorf("error parsing commit point "+
"hex: %v", err) "hex: %w", err)
} }
commitPoint, err := btcec.ParsePubKey(commitPointBytes) commitPoint, err := btcec.ParsePubKey(commitPointBytes)
if err != nil { if err != nil {
return nil, fmt.Errorf("error parsing commit point: %v", return nil, fmt.Errorf("error parsing commit point: %w",
err) err)
} }
@ -282,7 +282,7 @@ outer:
continue outer continue outer
case err == errAddrNotFound: case errors.Is(err, errAddrNotFound):
default: default:
return err return err
@ -343,7 +343,7 @@ func rescueClosedChannel(extendedKey *hdkeychain.ExtendedKey,
return nil return nil
case err == errAddrNotFound: case errors.Is(err, errAddrNotFound):
// Try again as a static_remote_key. // Try again as a static_remote_key.
default: default:
@ -358,7 +358,7 @@ func rescueClosedChannel(extendedKey *hdkeychain.ExtendedKey,
return nil return nil
case err == errAddrNotFound: case errors.Is(err, errAddrNotFound):
return fmt.Errorf("did not find private key for address %v", return fmt.Errorf("did not find private key for address %v",
addr) addr)
@ -372,7 +372,7 @@ func addrInCache(addr string, perCommitPoint *btcec.PublicKey) (string, error) {
addr, chainParams, addr, chainParams,
) )
if err != nil { if err != nil {
return "", fmt.Errorf("error parsing addr: %v", err) return "", fmt.Errorf("error parsing addr: %w", err)
} }
if scriptHash { if scriptHash {
return "", fmt.Errorf("address must be a P2WPKH address") return "", fmt.Errorf("address must be a P2WPKH address")
@ -473,7 +473,6 @@ func fillCache(extendedKey *hdkeychain.ExtendedKey) error {
fmt.Printf("Filled cache with %d of %d keys.\n", fmt.Printf("Filled cache with %d of %d keys.\n",
i, cacheSize) i, cacheSize)
} }
} }
return nil return nil
} }

@ -139,7 +139,7 @@ func (c *rescueFundingCommand) Execute(_ *cobra.Command, _ []string) error {
extendedKey, err := c.rootKey.read() extendedKey, err := c.rootKey.read()
if err != nil { if err != nil {
return fmt.Errorf("error reading root key: %v", err) return fmt.Errorf("error reading root key: %w", err)
} }
signer := &lnd.Signer{ signer := &lnd.Signer{
@ -158,13 +158,13 @@ func (c *rescueFundingCommand) Execute(_ *cobra.Command, _ []string) error {
case c.ChannelDB != "" && c.DBChannelPoint != "": case c.ChannelDB != "" && c.DBChannelPoint != "":
db, err := lnd.OpenDB(c.ChannelDB, true) db, err := lnd.OpenDB(c.ChannelDB, true)
if err != nil { if err != nil {
return fmt.Errorf("error opening rescue DB: %v", err) return fmt.Errorf("error opening rescue DB: %w", err)
} }
// Parse channel point of channel to rescue as known to the DB. // Parse channel point of channel to rescue as known to the DB.
databaseOp, err = lnd.ParseOutpoint(c.DBChannelPoint) databaseOp, err = lnd.ParseOutpoint(c.DBChannelPoint)
if err != nil { if err != nil {
return fmt.Errorf("error parsing channel point: %v", return fmt.Errorf("error parsing channel point: %w",
err) err)
} }
@ -174,7 +174,7 @@ func (c *rescueFundingCommand) Execute(_ *cobra.Command, _ []string) error {
) )
if err != nil { if err != nil {
return fmt.Errorf("error loading pending channel %s "+ return fmt.Errorf("error loading pending channel %s "+
"from DB: %v", databaseOp, err) "from DB: %w", databaseOp, err)
} }
if pendingChan.LocalChanCfg.MultiSigKey.PubKey == nil { if pendingChan.LocalChanCfg.MultiSigKey.PubKey == nil {
@ -193,12 +193,12 @@ func (c *rescueFundingCommand) Execute(_ *cobra.Command, _ []string) error {
remoteKeyBytes, err := hex.DecodeString(c.RemotePubKey) remoteKeyBytes, err := hex.DecodeString(c.RemotePubKey)
if err != nil { if err != nil {
return fmt.Errorf("error hex decoding remote pubkey: "+ return fmt.Errorf("error hex decoding remote pubkey: "+
"%v", err) "%w", err)
} }
remotePubKey, err = btcec.ParsePubKey(remoteKeyBytes) remotePubKey, err = btcec.ParsePubKey(remoteKeyBytes)
if err != nil { if err != nil {
return fmt.Errorf("error parsing remote pubkey: %v", return fmt.Errorf("error parsing remote pubkey: %w",
err) err)
} }
@ -210,7 +210,7 @@ func (c *rescueFundingCommand) Execute(_ *cobra.Command, _ []string) error {
} }
privKey, err := signer.FetchPrivKey(localKeyDesc) privKey, err := signer.FetchPrivKey(localKeyDesc)
if err != nil { if err != nil {
return fmt.Errorf("error deriving local key: %v", err) return fmt.Errorf("error deriving local key: %w", err)
} }
localKeyDesc.PubKey = privKey.PubKey() localKeyDesc.PubKey = privKey.PubKey()
} }
@ -223,7 +223,7 @@ func (c *rescueFundingCommand) Execute(_ *cobra.Command, _ []string) error {
chainOp, err = lnd.ParseOutpoint(c.ConfirmedOutPoint) chainOp, err = lnd.ParseOutpoint(c.ConfirmedOutPoint)
if err != nil { if err != nil {
return fmt.Errorf("error parsing confirmed channel "+ return fmt.Errorf("error parsing confirmed channel "+
"point: %v", err) "point: %w", err)
} }
} }
@ -231,7 +231,7 @@ func (c *rescueFundingCommand) Execute(_ *cobra.Command, _ []string) error {
// fee estimation. // fee estimation.
sweepScript, err := lnd.GetP2WPKHScript(c.SweepAddr, chainParams) sweepScript, err := lnd.GetP2WPKHScript(c.SweepAddr, chainParams)
if err != nil { if err != nil {
return fmt.Errorf("error parsing sweep addr: %v", err) return fmt.Errorf("error parsing sweep addr: %w", err)
} }
return rescueFunding( return rescueFunding(
@ -265,7 +265,7 @@ func rescueFunding(localKeyDesc *keychain.KeyDescriptor,
pkScript, err := hex.DecodeString(apiUtxo.ScriptPubkey) pkScript, err := hex.DecodeString(apiUtxo.ScriptPubkey)
if err != nil { if err != nil {
return fmt.Errorf("error decoding pk script %s: %v", return fmt.Errorf("error decoding pk script %s: %w",
apiUtxo.ScriptPubkey, err) apiUtxo.ScriptPubkey, err)
} }
utxo := &wire.TxOut{ utxo := &wire.TxOut{
@ -280,7 +280,7 @@ func rescueFunding(localKeyDesc *keychain.KeyDescriptor,
remoteKey.SerializeCompressed(), utxo.Value, remoteKey.SerializeCompressed(), utxo.Value,
) )
if err != nil { if err != nil {
return fmt.Errorf("could not derive funding script: %v", err) return fmt.Errorf("could not derive funding script: %w", err)
} }
// Some last sanity check that we're working with the correct data. // Some last sanity check that we're working with the correct data.
@ -317,7 +317,7 @@ func rescueFunding(localKeyDesc *keychain.KeyDescriptor,
} }
packet, err := psbt.NewFromUnsignedTx(wireTx) packet, err := psbt.NewFromUnsignedTx(wireTx)
if err != nil { if err != nil {
return fmt.Errorf("error creating PSBT: %v", err) return fmt.Errorf("error creating PSBT: %w", err)
} }
packet.Inputs[0] = pIn packet.Inputs[0] = pIn
@ -326,13 +326,13 @@ func rescueFunding(localKeyDesc *keychain.KeyDescriptor,
packet, *localKeyDesc, utxo, witnessScript, 0, packet, *localKeyDesc, utxo, witnessScript, 0,
) )
if err != nil { if err != nil {
return fmt.Errorf("error adding partial signature: %v", err) return fmt.Errorf("error adding partial signature: %w", err)
} }
// We're done, we can now output the finished PSBT. // We're done, we can now output the finished PSBT.
base64, err := packet.B64Encode() base64, err := packet.B64Encode()
if err != nil { if err != nil {
return fmt.Errorf("error encoding PSBT: %v", err) return fmt.Errorf("error encoding PSBT: %w", err)
} }
fmt.Printf("Partially signed transaction created. Send this to the "+ fmt.Printf("Partially signed transaction created. Send this to the "+

@ -209,7 +209,7 @@ func (f *inputFlags) parseInputType() ([]*dataformat.SummaryEntry, error) {
case f.FromChannelDB != "": case f.FromChannelDB != "":
db, err := lnd.OpenDB(f.FromChannelDB, true) db, err := lnd.OpenDB(f.FromChannelDB, true)
if err != nil { if err != nil {
return nil, fmt.Errorf("error opening channel DB: %v", return nil, fmt.Errorf("error opening channel DB: %w",
err) err)
} }
target = &dataformat.ChannelDBFile{DB: db.ChannelStateDB()} target = &dataformat.ChannelDBFile{DB: db.ChannelStateDB()}

@ -48,6 +48,8 @@ type harness struct {
} }
func newHarness(t *testing.T) *harness { func newHarness(t *testing.T) *harness {
t.Helper()
buf := &bytes.Buffer{} buf := &bytes.Buffer{}
logBackend := btclog.NewBackend(buf) logBackend := btclog.NewBackend(buf)
tempDir, err := ioutil.TempDir("", "chantools") tempDir, err := ioutil.TempDir("", "chantools")

@ -36,7 +36,7 @@ commands of this tool.`,
func (c *showRootKeyCommand) Execute(_ *cobra.Command, _ []string) error { func (c *showRootKeyCommand) Execute(_ *cobra.Command, _ []string) error {
extendedKey, err := c.rootKey.read() extendedKey, err := c.rootKey.read()
if err != nil { if err != nil {
return fmt.Errorf("error reading root key: %v", err) return fmt.Errorf("error reading root key: %w", err)
} }
result := fmt.Sprintf(showRootKeyFormat, extendedKey) result := fmt.Sprintf(showRootKeyFormat, extendedKey)

@ -1,7 +1,6 @@
package main package main
import ( import (
"os"
"testing" "testing"
"github.com/guggero/chantools/btc" "github.com/guggero/chantools/btc"
@ -17,12 +16,10 @@ func TestShowRootKey(t *testing.T) {
rootKey: &rootKey{}, rootKey: &rootKey{},
} }
err := os.Setenv(lnd.MnemonicEnvName, seedAezeedNoPassphrase) t.Setenv(lnd.MnemonicEnvName, seedAezeedNoPassphrase)
require.NoError(t, err) t.Setenv(lnd.PassphraseEnvName, "-")
err = os.Setenv(lnd.PassphraseEnvName, "-")
require.NoError(t, err)
err = show.Execute(nil, nil) err := show.Execute(nil, nil)
require.NoError(t, err) require.NoError(t, err)
h.assertLogContains(rootKeyAezeed) h.assertLogContains(rootKeyAezeed)
@ -36,18 +33,16 @@ func TestShowRootKeyBIP39(t *testing.T) {
rootKey: &rootKey{BIP39: true}, rootKey: &rootKey{BIP39: true},
} }
err := os.Setenv(btc.BIP39MnemonicEnvName, seedBip39) t.Setenv(btc.BIP39MnemonicEnvName, seedBip39)
require.NoError(t, err) t.Setenv(btc.BIP39PassphraseEnvName, "-")
err = os.Setenv(btc.BIP39PassphraseEnvName, "-")
require.NoError(t, err)
err = show.Execute(nil, nil) err := show.Execute(nil, nil)
require.NoError(t, err) require.NoError(t, err)
h.assertLogContains(rootKeyBip39) h.assertLogContains(rootKeyBip39)
} }
func TestShowRootKeyBIP39WithPassphre(t *testing.T) { func TestShowRootKeyBIP39WithPassphrase(t *testing.T) {
h := newHarness(t) h := newHarness(t)
// Derive the root key from the BIP39 seed. // Derive the root key from the BIP39 seed.
@ -55,12 +50,10 @@ func TestShowRootKeyBIP39WithPassphre(t *testing.T) {
rootKey: &rootKey{BIP39: true}, rootKey: &rootKey{BIP39: true},
} }
err := os.Setenv(btc.BIP39MnemonicEnvName, seedBip39) t.Setenv(btc.BIP39MnemonicEnvName, seedBip39)
require.NoError(t, err) t.Setenv(btc.BIP39PassphraseEnvName, testPassPhrase)
err = os.Setenv(btc.BIP39PassphraseEnvName, testPassPhrase)
require.NoError(t, err)
err = show.Execute(nil, nil) err := show.Execute(nil, nil)
require.NoError(t, err) require.NoError(t, err)
h.assertLogContains(rootKeyBip39Passphrase) h.assertLogContains(rootKeyBip39Passphrase)

@ -52,7 +52,7 @@ broadcast by any Bitcoin node.`,
func (c *signRescueFundingCommand) Execute(_ *cobra.Command, _ []string) error { func (c *signRescueFundingCommand) Execute(_ *cobra.Command, _ []string) error {
extendedKey, err := c.rootKey.read() extendedKey, err := c.rootKey.read()
if err != nil { if err != nil {
return fmt.Errorf("error reading root key: %v", err) return fmt.Errorf("error reading root key: %w", err)
} }
signer := &lnd.Signer{ signer := &lnd.Signer{
@ -65,7 +65,7 @@ func (c *signRescueFundingCommand) Execute(_ *cobra.Command, _ []string) error {
bytes.NewReader([]byte(c.Psbt)), true, bytes.NewReader([]byte(c.Psbt)), true,
) )
if err != nil { if err != nil {
return fmt.Errorf("error decoding PSBT: %v", err) return fmt.Errorf("error decoding PSBT: %w", err)
} }
return signRescueFunding(extendedKey, packet, signer) return signRescueFunding(extendedKey, packet, signer)
@ -82,7 +82,7 @@ func signRescueFunding(rootKey *hdkeychain.ExtendedKey,
0, 0,
}) })
if err != nil { if err != nil {
return fmt.Errorf("could not derive local multisig key: %v", return fmt.Errorf("could not derive local multisig key: %w",
err) err)
} }
@ -105,14 +105,14 @@ func signRescueFunding(rootKey *hdkeychain.ExtendedKey,
targetKey, err := btcec.ParsePubKey(unknown.Value) targetKey, err := btcec.ParsePubKey(unknown.Value)
if err != nil { if err != nil {
return fmt.Errorf("invalid PSBT, proprietary key has invalid "+ return fmt.Errorf("invalid PSBT, proprietary key has invalid "+
"pubkey: %v", err) "pubkey: %w", err)
} }
// Now we can look up the local key and check the PSBT further, then // Now we can look up the local key and check the PSBT further, then
// add our signature. // add our signature.
localKeyDesc, err := findLocalMultisigKey(localMultisig, targetKey) localKeyDesc, err := findLocalMultisigKey(localMultisig, targetKey)
if err != nil { if err != nil {
return fmt.Errorf("could not find local multisig key: %v", err) return fmt.Errorf("could not find local multisig key: %w", err)
} }
if len(packet.Inputs[0].WitnessScript) == 0 { if len(packet.Inputs[0].WitnessScript) == 0 {
return fmt.Errorf("invalid PSBT, missing witness script") return fmt.Errorf("invalid PSBT, missing witness script")
@ -127,23 +127,23 @@ func signRescueFunding(rootKey *hdkeychain.ExtendedKey,
packet, *localKeyDesc, utxo, witnessScript, 0, packet, *localKeyDesc, utxo, witnessScript, 0,
) )
if err != nil { if err != nil {
return fmt.Errorf("error adding partial signature: %v", err) return fmt.Errorf("error adding partial signature: %w", err)
} }
// We're almost done. Now we just need to make sure we can finalize and // We're almost done. Now we just need to make sure we can finalize and
// extract the final TX. // extract the final TX.
err = psbt.MaybeFinalizeAll(packet) err = psbt.MaybeFinalizeAll(packet)
if err != nil { if err != nil {
return fmt.Errorf("error finalizing PSBT: %v", err) return fmt.Errorf("error finalizing PSBT: %w", err)
} }
finalTx, err := psbt.Extract(packet) finalTx, err := psbt.Extract(packet)
if err != nil { if err != nil {
return fmt.Errorf("unable to extract final TX: %v", err) return fmt.Errorf("unable to extract final TX: %w", err)
} }
var buf bytes.Buffer var buf bytes.Buffer
err = finalTx.Serialize(&buf) err = finalTx.Serialize(&buf)
if err != nil { if err != nil {
return fmt.Errorf("unable to serialize final TX: %v", err) return fmt.Errorf("unable to serialize final TX: %w", err)
} }
fmt.Printf("Success, we counter signed the PSBT and extracted the "+ fmt.Printf("Success, we counter signed the PSBT and extracted the "+
@ -160,13 +160,13 @@ func findLocalMultisigKey(multisigBranch *hdkeychain.ExtendedKey,
for index := uint32(0); index < MaxChannelLookup; index++ { for index := uint32(0); index < MaxChannelLookup; index++ {
currentKey, err := multisigBranch.DeriveNonStandard(index) currentKey, err := multisigBranch.DeriveNonStandard(index)
if err != nil { if err != nil {
return nil, fmt.Errorf("error deriving child key: %v", return nil, fmt.Errorf("error deriving child key: %w",
err) err)
} }
currentPubkey, err := currentKey.ECPubKey() currentPubkey, err := currentKey.ECPubKey()
if err != nil { if err != nil {
return nil, fmt.Errorf("error deriving public key: %v", return nil, fmt.Errorf("error deriving public key: %w",
err) err)
} }

@ -55,7 +55,7 @@ func summarizeChannels(apiURL string,
summaryFile, err := btc.SummarizeChannels(apiURL, channels, log) summaryFile, err := btc.SummarizeChannels(apiURL, channels, log)
if err != nil { if err != nil {
return fmt.Errorf("error running summary: %v", err) return fmt.Errorf("error running summary: %w", err)
} }
log.Info("Finished scanning.") log.Info("Finished scanning.")

@ -90,7 +90,7 @@ Supported remote force-closed channel types are:
func (c *sweepRemoteClosedCommand) Execute(_ *cobra.Command, _ []string) error { func (c *sweepRemoteClosedCommand) Execute(_ *cobra.Command, _ []string) error {
extendedKey, err := c.rootKey.read() extendedKey, err := c.rootKey.read()
if err != nil { if err != nil {
return fmt.Errorf("error reading root key: %v", err) return fmt.Errorf("error reading root key: %w", err)
} }
// Make sure sweep addr is set. // Make sure sweep addr is set.
@ -135,21 +135,20 @@ func sweepRemoteClosed(extendedKey *hdkeychain.ExtendedKey, apiURL,
index) index)
parsedPath, err := lnd.ParsePath(path) parsedPath, err := lnd.ParsePath(path)
if err != nil { if err != nil {
return fmt.Errorf("error parsing path: %v", err) return fmt.Errorf("error parsing path: %w", err)
} }
hdKey, err := lnd.DeriveChildren( hdKey, err := lnd.DeriveChildren(
extendedKey, parsedPath, extendedKey, parsedPath,
) )
if err != nil { if err != nil {
return fmt.Errorf("eror deriving children: %v", return fmt.Errorf("eror deriving children: %w", err)
err)
} }
privKey, err := hdKey.ECPrivKey() privKey, err := hdKey.ECPrivKey()
if err != nil { if err != nil {
return fmt.Errorf("could not derive private "+ return fmt.Errorf("could not derive private "+
"key: %v", err) "key: %w", err)
} }
foundTargets, err := queryAddressBalances( foundTargets, err := queryAddressBalances(
@ -163,7 +162,7 @@ func sweepRemoteClosed(extendedKey *hdkeychain.ExtendedKey, apiURL,
) )
if err != nil { if err != nil {
return fmt.Errorf("could not query API for "+ return fmt.Errorf("could not query API for "+
"addresses with funds: %v", err) "addresses with funds: %w", err)
} }
targets = append(targets, foundTargets...) targets = append(targets, foundTargets...)
} }
@ -185,14 +184,14 @@ func sweepRemoteClosed(extendedKey *hdkeychain.ExtendedKey, apiURL,
vout.Outspend.Txid, vout.Outspend.Txid,
) )
if err != nil { if err != nil {
return fmt.Errorf("error parsing tx hash: %v", return fmt.Errorf("error parsing tx hash: %w",
err) err)
} }
pkScript, err := lnd.GetWitnessAddrScript( pkScript, err := lnd.GetWitnessAddrScript(
target.addr, chainParams, target.addr, chainParams,
) )
if err != nil { if err != nil {
return fmt.Errorf("error getting pk script: %v", return fmt.Errorf("error getting pk script: %w",
err) err)
} }
@ -319,7 +318,7 @@ func queryAddressBalances(pubKey *btcec.PublicKey, path string,
queryAddr := func(address btcutil.Address, script []byte) error { queryAddr := func(address btcutil.Address, script []byte) error {
unspent, err := api.Unspent(address.EncodeAddress()) unspent, err := api.Unspent(address.EncodeAddress())
if err != nil { if err != nil {
return fmt.Errorf("could not query unspent: %v", err) return fmt.Errorf("could not query unspent: %w", err)
} }
if len(unspent) > 0 { if len(unspent) > 0 {

@ -85,7 +85,7 @@ parameter to 144.`,
func (c *sweepTimeLockCommand) Execute(_ *cobra.Command, _ []string) error { func (c *sweepTimeLockCommand) Execute(_ *cobra.Command, _ []string) error {
extendedKey, err := c.rootKey.read() extendedKey, err := c.rootKey.read()
if err != nil { if err != nil {
return fmt.Errorf("error reading root key: %v", err) return fmt.Errorf("error reading root key: %w", err)
} }
// Make sure sweep addr is set. // Make sure sweep addr is set.
@ -136,6 +136,7 @@ func sweepTimeLockFromSummary(extendedKey *hdkeychain.ExtendedKey, apiURL string
log.Infof("Not sweeping %s, info missing or all spent", log.Infof("Not sweeping %s, info missing or all spent",
entry.ChannelPoint) entry.ChannelPoint)
continue continue
} }
@ -167,29 +168,29 @@ func sweepTimeLockFromSummary(extendedKey *hdkeychain.ExtendedKey, apiURL string
// Prepare sweep script parameters. // Prepare sweep script parameters.
commitPoint, err := pubKeyFromHex(fc.CommitPoint) commitPoint, err := pubKeyFromHex(fc.CommitPoint)
if err != nil { if err != nil {
return fmt.Errorf("error parsing commit point: %v", err) return fmt.Errorf("error parsing commit point: %w", err)
} }
revBase, err := pubKeyFromHex(fc.RevocationBasePoint.PubKey) revBase, err := pubKeyFromHex(fc.RevocationBasePoint.PubKey)
if err != nil { if err != nil {
return fmt.Errorf("error parsing revocation base "+ return fmt.Errorf("error parsing revocation base "+
"point: %v", err) "point: %w", err)
} }
delayDesc, err := fc.DelayBasePoint.Desc() delayDesc, err := fc.DelayBasePoint.Desc()
if err != nil { if err != nil {
return fmt.Errorf("error parsing delay base point: %v", return fmt.Errorf("error parsing delay base point: %w",
err) err)
} }
lockScript, err := hex.DecodeString(fc.Outs[txindex].Script) lockScript, err := hex.DecodeString(fc.Outs[txindex].Script)
if err != nil { if err != nil {
return fmt.Errorf("error parsing target script: %v", return fmt.Errorf("error parsing target script: %w",
err) err)
} }
// Create the transaction input. // Create the transaction input.
txHash, err := chainhash.NewHashFromStr(fc.TXID) txHash, err := chainhash.NewHashFromStr(fc.TXID)
if err != nil { if err != nil {
return fmt.Errorf("error parsing tx hash: %v", err) return fmt.Errorf("error parsing tx hash: %w", err)
} }
targets = append(targets, &sweepTarget{ targets = append(targets, &sweepTarget{
@ -240,7 +241,7 @@ func sweepTimeLock(extendedKey *hdkeychain.ExtendedKey, apiURL string,
) )
if err != nil { if err != nil {
log.Errorf("Could not create matching script for %s "+ log.Errorf("Could not create matching script for %s "+
"or csv too high: %v", target.channelPoint, err) "or csv too high: %w", target.channelPoint, err)
continue continue
} }
@ -333,7 +334,7 @@ func sweepTimeLock(extendedKey *hdkeychain.ExtendedKey, apiURL string,
func pubKeyFromHex(pubKeyHex string) (*btcec.PublicKey, error) { func pubKeyFromHex(pubKeyHex string) (*btcec.PublicKey, error) {
pointBytes, err := hex.DecodeString(pubKeyHex) pointBytes, err := hex.DecodeString(pubKeyHex)
if err != nil { if err != nil {
return nil, fmt.Errorf("error hex decoding pub key: %v", err) return nil, fmt.Errorf("error hex decoding pub key: %w", err)
} }
return btcec.ParsePubKey(pointBytes) return btcec.ParsePubKey(pointBytes)
} }
@ -352,12 +353,12 @@ func bruteForceDelay(delayPubkey, revocationPubkey *btcec.PublicKey,
) )
if err != nil { if err != nil {
return 0, nil, nil, fmt.Errorf("error creating "+ return 0, nil, nil, fmt.Errorf("error creating "+
"script: %v", err) "script: %w", err)
} }
sh, err := input.WitnessScriptHash(s) sh, err := input.WitnessScriptHash(s)
if err != nil { if err != nil {
return 0, nil, nil, fmt.Errorf("error hashing script: "+ return 0, nil, nil, fmt.Errorf("error hashing script: "+
"%v", err) "%w", err)
} }
if bytes.Equal(targetScript[0:8], sh[0:8]) { if bytes.Equal(targetScript[0:8], sh[0:8]) {
return int32(i), s, sh, nil return int32(i), s, sh, nil

@ -102,7 +102,7 @@ address is always the one that's longer (because it's P2WSH and not P2PKH).`,
func (c *sweepTimeLockManualCommand) Execute(_ *cobra.Command, _ []string) error { func (c *sweepTimeLockManualCommand) Execute(_ *cobra.Command, _ []string) error {
extendedKey, err := c.rootKey.read() extendedKey, err := c.rootKey.read()
if err != nil { if err != nil {
return fmt.Errorf("error reading root key: %v", err) return fmt.Errorf("error reading root key: %w", err)
} }
// Make sure the sweep and time lock addrs are set. // Make sure the sweep and time lock addrs are set.
@ -117,7 +117,7 @@ func (c *sweepTimeLockManualCommand) Execute(_ *cobra.Command, _ []string) error
// point. // point.
remoteRevPoint, err := pubKeyFromHex(c.RemoteRevocationBasePoint) remoteRevPoint, err := pubKeyFromHex(c.RemoteRevocationBasePoint)
if err != nil { if err != nil {
return fmt.Errorf("invalid remote revocation base point: %v", return fmt.Errorf("invalid remote revocation base point: %w",
err) err)
} }
@ -136,7 +136,7 @@ func sweepTimeLockManual(extendedKey *hdkeychain.ExtendedKey, apiURL string,
// continue anyway. // continue anyway.
lockScript, err := lnd.GetP2WSHScript(timeLockAddr, chainParams) lockScript, err := lnd.GetP2WSHScript(timeLockAddr, chainParams)
if err != nil { if err != nil {
return fmt.Errorf("invalid time lock addr: %v", err) return fmt.Errorf("invalid time lock addr: %w", err)
} }
// We need to go through a lot of our keys so it makes sense to // We need to go through a lot of our keys so it makes sense to
@ -145,11 +145,11 @@ func sweepTimeLockManual(extendedKey *hdkeychain.ExtendedKey, apiURL string,
keyBasePath, chainParams.HDCoinType, keyBasePath, chainParams.HDCoinType,
)) ))
if err != nil { if err != nil {
return fmt.Errorf("could not derive base path: %v", err) return fmt.Errorf("could not derive base path: %w", err)
} }
baseKey, err := lnd.DeriveChildren(extendedKey, basePath) baseKey, err := lnd.DeriveChildren(extendedKey, basePath)
if err != nil { if err != nil {
return fmt.Errorf("could not derive base key: %v", err) return fmt.Errorf("could not derive base key: %w", err)
} }
// Go through all our keys now and try to find the ones that can derive // Go through all our keys now and try to find the ones that can derive
@ -172,6 +172,7 @@ func sweepTimeLockManual(extendedKey *hdkeychain.ExtendedKey, apiURL string,
if err == nil { if err == nil {
log.Infof("Found keys at index %d with CSV timeout %d", log.Infof("Found keys at index %d with CSV timeout %d",
i, csvTimeout) i, csvTimeout)
break break
} }
@ -206,7 +207,7 @@ func sweepTimeLockManual(extendedKey *hdkeychain.ExtendedKey, apiURL string,
// Create the transaction input. // Create the transaction input.
txHash, err := chainhash.NewHashFromStr(tx.TXID) txHash, err := chainhash.NewHashFromStr(tx.TXID)
if err != nil { if err != nil {
return fmt.Errorf("error parsing tx hash: %v", err) return fmt.Errorf("error parsing tx hash: %w", err)
} }
sweepTx.TxIn = []*wire.TxIn{{ sweepTx.TxIn = []*wire.TxIn{{
PreviousOutPoint: wire.OutPoint{ PreviousOutPoint: wire.OutPoint{
@ -281,7 +282,6 @@ func sweepTimeLockManual(extendedKey *hdkeychain.ExtendedKey, apiURL string,
log.Infof("Transaction: %x", buf.Bytes()) log.Infof("Transaction: %x", buf.Bytes())
return nil return nil
} }
func tryKey(baseKey *hdkeychain.ExtendedKey, remoteRevPoint *btcec.PublicKey, func tryKey(baseKey *hdkeychain.ExtendedKey, remoteRevPoint *btcec.PublicKey,
@ -364,9 +364,10 @@ func tryKey(baseKey *hdkeychain.ExtendedKey, remoteRevPoint *btcec.PublicKey,
lnd.HardenedKey(uint32(keychain.KeyFamilyMultiSig)), lnd.HardenedKey(uint32(keychain.KeyFamilyMultiSig)),
0, idx, 0, idx,
} }
multiSigPrivKey, err := lnd.PrivKeyFromPath( multiSigPrivKey, err := lnd.PrivKeyFromPath(baseKey, multiSigPath)
baseKey, multiSigPath, if err != nil {
) return 0, nil, nil, nil, nil, err
}
revRoot3, err := lnd.ShaChainFromPath( revRoot3, err := lnd.ShaChainFromPath(
baseKey, revPath, multiSigPrivKey.PubKey(), baseKey, revPath, multiSigPrivKey.PubKey(),

@ -8,6 +8,7 @@ import (
"github.com/btcsuite/btcd/btcutil/hdkeychain" "github.com/btcsuite/btcd/btcutil/hdkeychain"
"github.com/btcsuite/btcd/chaincfg" "github.com/btcsuite/btcd/chaincfg"
"github.com/guggero/chantools/lnd" "github.com/guggero/chantools/lnd"
"github.com/stretchr/testify/require"
) )
var sweepTimeLockManualCases = []struct { var sweepTimeLockManualCases = []struct {
@ -43,14 +44,10 @@ func TestSweepTimeLockManual(t *testing.T) {
lockScript, err := lnd.GetP2WSHScript( lockScript, err := lnd.GetP2WSHScript(
tc.timeLockAddr, &chaincfg.RegressionNetParams, tc.timeLockAddr, &chaincfg.RegressionNetParams,
) )
if err != nil { require.NoError(t, err)
t.Fatalf("invalid time lock addr: %v", err)
}
baseKey, err := hdkeychain.NewKeyFromString(tc.baseKey) baseKey, err := hdkeychain.NewKeyFromString(tc.baseKey)
if err != nil { require.NoError(t, err)
t.Fatalf("couldn't derive base key: %v", err)
}
revPubKeyBytes, _ := hex.DecodeString(tc.remoteRevPubKey) revPubKeyBytes, _ := hex.DecodeString(tc.remoteRevPubKey)
revPubKey, _ := btcec.ParsePubKey(revPubKeyBytes) revPubKey, _ := btcec.ParsePubKey(revPubKeyBytes)
@ -59,8 +56,6 @@ func TestSweepTimeLockManual(t *testing.T) {
baseKey, revPubKey, defaultCsvLimit, lockScript, baseKey, revPubKey, defaultCsvLimit, lockScript,
tc.keyIndex, tc.keyIndex,
) )
if err != nil { require.NoError(t, err)
t.Fatalf("couldn't derive key: %v", err)
}
} }
} }

@ -67,7 +67,7 @@ phone]
func (c *vanityGenCommand) Execute(_ *cobra.Command, _ []string) error { func (c *vanityGenCommand) Execute(_ *cobra.Command, _ []string) error {
prefixBytes, err := hex.DecodeString(c.Prefix) prefixBytes, err := hex.DecodeString(c.Prefix)
if err != nil { if err != nil {
return fmt.Errorf("hex decoding of prefix failed: %v", err) return fmt.Errorf("hex decoding of prefix failed: %w", err)
} }
if len(prefixBytes) < 2 { if len(prefixBytes) < 2 {
@ -131,9 +131,7 @@ func (c *vanityGenCommand) Execute(_ *cobra.Command, _ []string) error {
} }
pubKeyBytes := rootKey.PubKeyBytes() pubKeyBytes := rootKey.PubKeyBytes()
if bytes.HasPrefix( if bytes.HasPrefix(pubKeyBytes, prefixBytes) {
pubKeyBytes, prefixBytes,
) {
seed, err := aezeed.New( seed, err := aezeed.New(
aezeed.CipherSeedVersion, aezeed.CipherSeedVersion,
&entropy, time.Now(), &entropy, time.Now(),

@ -1,6 +1,7 @@
package main package main
import ( import (
"errors"
"fmt" "fmt"
"os" "os"
"strings" "strings"
@ -10,18 +11,13 @@ import (
"github.com/btcsuite/btcwallet/waddrmgr" "github.com/btcsuite/btcwallet/waddrmgr"
"github.com/btcsuite/btcwallet/wallet" "github.com/btcsuite/btcwallet/wallet"
"github.com/btcsuite/btcwallet/walletdb" "github.com/btcsuite/btcwallet/walletdb"
_ "github.com/btcsuite/btcwallet/walletdb/bdb"
"github.com/guggero/chantools/lnd" "github.com/guggero/chantools/lnd"
"github.com/lightningnetwork/lnd/keychain" "github.com/lightningnetwork/lnd/keychain"
"github.com/lightningnetwork/lnd/lncfg" "github.com/lightningnetwork/lnd/lncfg"
"github.com/lightningnetwork/lnd/lnwallet" "github.com/lightningnetwork/lnd/lnwallet"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"go.etcd.io/bbolt" "go.etcd.io/bbolt"
// This is required to register bdb as a valid walletdb driver. In the
// init function of the package, it registers itself. The import is used
// to activate the side effects w/o actually binding the package name to
// a file-level variable.
_ "github.com/btcsuite/btcwallet/walletdb/bdb"
) )
const ( const (
@ -42,10 +38,10 @@ Scope: m/%d'/%d'
) )
var ( var (
// Namespace from github.com/btcsuite/btcwallet/wallet/wallet.go // Namespace from github.com/btcsuite/btcwallet/wallet/wallet.go.
waddrmgrNamespaceKey = []byte("waddrmgr") waddrmgrNamespaceKey = []byte("waddrmgr")
// Bucket names from github.com/btcsuite/btcwallet/waddrmgr/db.go // Bucket names from github.com/btcsuite/btcwallet/waddrmgr/db.go.
mainBucketName = []byte("main") mainBucketName = []byte("main")
masterPrivKeyName = []byte("mpriv") masterPrivKeyName = []byte("mpriv")
cryptoPrivKeyName = []byte("cpriv") cryptoPrivKeyName = []byte("cpriv")
@ -141,13 +137,13 @@ func (c *walletInfoCommand) Execute(_ *cobra.Command, _ []string) error {
"bdb", lncfg.CleanAndExpandPath(c.WalletDB), false, "bdb", lncfg.CleanAndExpandPath(c.WalletDB), false,
lnd.DefaultOpenTimeout, lnd.DefaultOpenTimeout,
) )
if err == bbolt.ErrTimeout { if errors.Is(err, bbolt.ErrTimeout) {
return fmt.Errorf("error opening wallet database, make sure " + return fmt.Errorf("error opening wallet database, make sure " +
"lnd is not running and holding the exclusive lock " + "lnd is not running and holding the exclusive lock " +
"on the wallet") "on the wallet")
} }
if err != nil { if err != nil {
return fmt.Errorf("error opening wallet database: %v", err) return fmt.Errorf("error opening wallet database: %w", err)
} }
defer func() { _ = db.Close() }() defer func() { _ = db.Close() }()
@ -233,7 +229,7 @@ func printScopeInfo(name string, w *wallet.Wallet,
props, err := w.AccountProperties(scope, defaultAccount) props, err := w.AccountProperties(scope, defaultAccount)
if err != nil { if err != nil {
return "", fmt.Errorf("error fetching account "+ return "", fmt.Errorf("error fetching account "+
"properties: %v", err) "properties: %w", err)
} }
scopeInfo += fmt.Sprintf( scopeInfo += fmt.Sprintf(
keyScopeformat, scope.Purpose, scope.Coin, name, keyScopeformat, scope.Purpose, scope.Coin, name,

@ -1,7 +1,6 @@
package main package main
import ( import (
"os"
"testing" "testing"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
@ -21,10 +20,9 @@ func TestWalletInfo(t *testing.T) {
WithRootKey: true, WithRootKey: true,
} }
err := os.Setenv(passwordEnvName, testPassPhrase) t.Setenv(passwordEnvName, testPassPhrase)
require.NoError(t, err)
err = info.Execute(nil, nil) err := info.Execute(nil, nil)
require.NoError(t, err) require.NoError(t, err)
h.assertLogContains(walletContent) h.assertLogContains(walletContent)

@ -116,7 +116,7 @@ func (c *zombieRecoveryFindMatchesCommand) Execute(_ *cobra.Command,
logFileBytes, err := ioutil.ReadFile(c.Registrations) logFileBytes, err := ioutil.ReadFile(c.Registrations)
if err != nil { if err != nil {
return fmt.Errorf("error reading registrations file %s: %v", return fmt.Errorf("error reading registrations file %s: %w",
c.Registrations, err) c.Registrations, err)
} }
@ -126,7 +126,7 @@ func (c *zombieRecoveryFindMatchesCommand) Execute(_ *cobra.Command,
registrations := make(map[string]string, len(allMatches)) registrations := make(map[string]string, len(allMatches))
for _, groups := range allMatches { for _, groups := range allMatches {
if _, err := pubKeyFromHex(groups[1]); err != nil { if _, err := pubKeyFromHex(groups[1]); err != nil {
return fmt.Errorf("error parsing node ID: %v", err) return fmt.Errorf("error parsing node ID: %w", err)
} }
registrations[groups[1]] = groups[2] registrations[groups[1]] = groups[2]
@ -142,20 +142,20 @@ func (c *zombieRecoveryFindMatchesCommand) Execute(_ *cobra.Command,
graph := &lnrpc.ChannelGraph{} graph := &lnrpc.ChannelGraph{}
err = jsonpb.UnmarshalString(string(graphBytes), graph) err = jsonpb.UnmarshalString(string(graphBytes), graph)
if err != nil { if err != nil {
return fmt.Errorf("error parsing graph JSON: %v", err) return fmt.Errorf("error parsing graph JSON: %w", err)
} }
var donePairs []*donePair var donePairs []*donePair
if c.PairsDone != "" { if c.PairsDone != "" {
donePairsBytes, err := readInput(c.PairsDone) donePairsBytes, err := readInput(c.PairsDone)
if err != nil { if err != nil {
return fmt.Errorf("error reading pairs JSON %s: %v", return fmt.Errorf("error reading pairs JSON %s: %w",
c.PairsDone, err) c.PairsDone, err)
} }
decoder := json.NewDecoder(bytes.NewReader(donePairsBytes)) decoder := json.NewDecoder(bytes.NewReader(donePairsBytes))
err = decoder.Decode(&donePairs) err = decoder.Decode(&donePairs)
if err != nil { if err != nil {
return fmt.Errorf("error parsing pairs JSON %s: %v", return fmt.Errorf("error parsing pairs JSON %s: %w",
c.PairsDone, err) c.PairsDone, err)
} }
} }

@ -70,12 +70,12 @@ a counter offer.`,
return cc.cmd return cc.cmd
} }
func (c *zombieRecoveryMakeOfferCommand) Execute(_ *cobra.Command, // nolint:gocyclo func (c *zombieRecoveryMakeOfferCommand) Execute(_ *cobra.Command,
_ []string) error { _ []string) error {
extendedKey, err := c.rootKey.read() extendedKey, err := c.rootKey.read()
if err != nil { if err != nil {
return fmt.Errorf("error reading root key: %v", err) return fmt.Errorf("error reading root key: %w", err)
} }
if c.FeeRate == 0 { if c.FeeRate == 0 {
@ -84,23 +84,23 @@ func (c *zombieRecoveryMakeOfferCommand) Execute(_ *cobra.Command, // nolint:goc
node1Bytes, err := ioutil.ReadFile(c.Node1) node1Bytes, err := ioutil.ReadFile(c.Node1)
if err != nil { if err != nil {
return fmt.Errorf("error reading node1 key file %s: %v", return fmt.Errorf("error reading node1 key file %s: %w",
c.Node1, err) c.Node1, err)
} }
node2Bytes, err := ioutil.ReadFile(c.Node2) node2Bytes, err := ioutil.ReadFile(c.Node2)
if err != nil { if err != nil {
return fmt.Errorf("error reading node2 key file %s: %v", return fmt.Errorf("error reading node2 key file %s: %w",
c.Node2, err) c.Node2, err)
} }
keys1, keys2 := &match{}, &match{} keys1, keys2 := &match{}, &match{}
decoder := json.NewDecoder(bytes.NewReader(node1Bytes)) decoder := json.NewDecoder(bytes.NewReader(node1Bytes))
if err := decoder.Decode(&keys1); err != nil { if err := decoder.Decode(&keys1); err != nil {
return fmt.Errorf("error decoding node1 key file %s: %v", return fmt.Errorf("error decoding node1 key file %s: %w",
c.Node1, err) c.Node1, err)
} }
decoder = json.NewDecoder(bytes.NewReader(node2Bytes)) decoder = json.NewDecoder(bytes.NewReader(node2Bytes))
if err := decoder.Decode(&keys2); err != nil { if err := decoder.Decode(&keys2); err != nil {
return fmt.Errorf("error decoding node2 key file %s: %v", return fmt.Errorf("error decoding node2 key file %s: %w",
c.Node2, err) c.Node2, err)
} }
@ -158,7 +158,7 @@ func (c *zombieRecoveryMakeOfferCommand) Execute(_ *cobra.Command, // nolint:goc
extendedKey, lnd.IdentityPath(chainParams), chainParams, extendedKey, lnd.IdentityPath(chainParams), chainParams,
) )
if err != nil { if err != nil {
return fmt.Errorf("error deriving identity pubkey: %v", err) return fmt.Errorf("error deriving identity pubkey: %w", err)
} }
pubKeyStr := hex.EncodeToString(pubKey.SerializeCompressed()) pubKeyStr := hex.EncodeToString(pubKey.SerializeCompressed())
@ -211,13 +211,13 @@ func (c *zombieRecoveryMakeOfferCommand) Execute(_ *cobra.Command, // nolint:goc
for idx, pubKeyHex := range ourKeys { for idx, pubKeyHex := range ourKeys {
ourPubKeys[idx], err = pubKeyFromHex(pubKeyHex) ourPubKeys[idx], err = pubKeyFromHex(pubKeyHex)
if err != nil { if err != nil {
return fmt.Errorf("error parsing our pubKey: %v", err) return fmt.Errorf("error parsing our pubKey: %w", err)
} }
} }
for idx, pubKeyHex := range theirKeys { for idx, pubKeyHex := range theirKeys {
theirPubKeys[idx], err = pubKeyFromHex(pubKeyHex) theirPubKeys[idx], err = pubKeyFromHex(pubKeyHex)
if err != nil { if err != nil {
return fmt.Errorf("error parsing their pubKey: %v", err) return fmt.Errorf("error parsing their pubKey: %w", err)
} }
} }
@ -233,7 +233,7 @@ channelLoop:
) )
if err != nil { if err != nil {
return fmt.Errorf("error matching "+ return fmt.Errorf("error matching "+
"keys to script: %v", err) "keys to script: %w", err)
} }
if match { if match {
@ -264,7 +264,7 @@ channelLoop:
for idx, channel := range keys1.Channels { for idx, channel := range keys1.Channels {
op, err := lnd.ParseOutpoint(channel.ChanPoint) op, err := lnd.ParseOutpoint(channel.ChanPoint)
if err != nil { if err != nil {
return fmt.Errorf("error parsing channel out point: %v", return fmt.Errorf("error parsing channel out point: %w",
err) err)
} }
channel.txid = op.Hash.String() channel.txid = op.Hash.String()
@ -333,7 +333,7 @@ channelLoop:
// Our output. // Our output.
pkScript, err := lnd.GetP2WPKHScript(ourPayoutAddr, chainParams) pkScript, err := lnd.GetP2WPKHScript(ourPayoutAddr, chainParams)
if err != nil { if err != nil {
return fmt.Errorf("error parsing our payout address: %v", err) return fmt.Errorf("error parsing our payout address: %w", err)
} }
ourTxOut := &wire.TxOut{ ourTxOut := &wire.TxOut{
PkScript: pkScript, PkScript: pkScript,
@ -343,7 +343,7 @@ channelLoop:
// Their output // Their output
pkScript, err = lnd.GetP2WPKHScript(theirPayoutAddr, chainParams) pkScript, err = lnd.GetP2WPKHScript(theirPayoutAddr, chainParams)
if err != nil { if err != nil {
return fmt.Errorf("error parsing their payout address: %v", err) return fmt.Errorf("error parsing their payout address: %w", err)
} }
theirTxOut := &wire.TxOut{ theirTxOut := &wire.TxOut{
PkScript: pkScript, PkScript: pkScript,
@ -378,7 +378,7 @@ channelLoop:
} }
packet, err := psbt.NewFromUnsignedTx(tx) packet, err := psbt.NewFromUnsignedTx(tx)
if err != nil { if err != nil {
return fmt.Errorf("error creating PSBT from TX: %v", err) return fmt.Errorf("error creating PSBT from TX: %w", err)
} }
signer := &lnd.Signer{ signer := &lnd.Signer{
@ -426,7 +426,7 @@ channelLoop:
packet, keyDesc, utxo, txIn.SignatureScript, idx, packet, keyDesc, utxo, txIn.SignatureScript, idx,
) )
if err != nil { if err != nil {
return fmt.Errorf("error signing input %d: %v", idx, return fmt.Errorf("error signing input %d: %w", idx,
err) err)
} }
} }
@ -434,7 +434,7 @@ channelLoop:
// Looks like we're done! // Looks like we're done!
base64, err := packet.B64Encode() base64, err := packet.B64Encode()
if err != nil { if err != nil {
return fmt.Errorf("error encoding PSBT: %v", err) return fmt.Errorf("error encoding PSBT: %w", err)
} }
fmt.Printf("Done creating offer, please send this PSBT string to \n"+ fmt.Printf("Done creating offer, please send this PSBT string to \n"+

@ -59,7 +59,7 @@ func (c *zombieRecoveryPrepareKeysCommand) Execute(_ *cobra.Command,
extendedKey, err := c.rootKey.read() extendedKey, err := c.rootKey.read()
if err != nil { if err != nil {
return fmt.Errorf("error reading root key: %v", err) return fmt.Errorf("error reading root key: %w", err)
} }
_, err = lnd.GetP2WPKHScript(c.PayoutAddr, chainParams) _, err = lnd.GetP2WPKHScript(c.PayoutAddr, chainParams)
@ -69,14 +69,14 @@ func (c *zombieRecoveryPrepareKeysCommand) Execute(_ *cobra.Command,
matchFileBytes, err := ioutil.ReadFile(c.MatchFile) matchFileBytes, err := ioutil.ReadFile(c.MatchFile)
if err != nil { if err != nil {
return fmt.Errorf("error reading match file %s: %v", return fmt.Errorf("error reading match file %s: %w",
c.MatchFile, err) c.MatchFile, err)
} }
decoder := json.NewDecoder(bytes.NewReader(matchFileBytes)) decoder := json.NewDecoder(bytes.NewReader(matchFileBytes))
match := &match{} match := &match{}
if err := decoder.Decode(&match); err != nil { if err := decoder.Decode(&match); err != nil {
return fmt.Errorf("error decoding match file %s: %v", return fmt.Errorf("error decoding match file %s: %w",
c.MatchFile, err) c.MatchFile, err)
} }
@ -89,7 +89,7 @@ func (c *zombieRecoveryPrepareKeysCommand) Execute(_ *cobra.Command,
extendedKey, lnd.IdentityPath(chainParams), chainParams, extendedKey, lnd.IdentityPath(chainParams), chainParams,
) )
if err != nil { if err != nil {
return fmt.Errorf("error deriving identity pubkey: %v", err) return fmt.Errorf("error deriving identity pubkey: %w", err)
} }
pubKeyStr := hex.EncodeToString(pubKey.SerializeCompressed()) pubKeyStr := hex.EncodeToString(pubKey.SerializeCompressed())
@ -114,7 +114,7 @@ func (c *zombieRecoveryPrepareKeysCommand) Execute(_ *cobra.Command,
chainParams, chainParams,
) )
if err != nil { if err != nil {
return fmt.Errorf("error deriving multisig pubkey: %v", return fmt.Errorf("error deriving multisig pubkey: %w",
err) err)
} }

@ -50,7 +50,7 @@ func (c *zombieRecoverySignOfferCommand) Execute(_ *cobra.Command,
extendedKey, err := c.rootKey.read() extendedKey, err := c.rootKey.read()
if err != nil { if err != nil {
return fmt.Errorf("error reading root key: %v", err) return fmt.Errorf("error reading root key: %w", err)
} }
signer := &lnd.Signer{ signer := &lnd.Signer{
@ -63,7 +63,7 @@ func (c *zombieRecoverySignOfferCommand) Execute(_ *cobra.Command,
bytes.NewReader([]byte(c.Psbt)), true, bytes.NewReader([]byte(c.Psbt)), true,
) )
if err != nil { if err != nil {
return fmt.Errorf("error decoding PSBT: %v", err) return fmt.Errorf("error decoding PSBT: %w", err)
} }
return signOffer(extendedKey, packet, signer) return signOffer(extendedKey, packet, signer)
@ -80,7 +80,7 @@ func signOffer(rootKey *hdkeychain.ExtendedKey,
0, 0,
}) })
if err != nil { if err != nil {
return fmt.Errorf("could not derive local multisig key: %v", return fmt.Errorf("could not derive local multisig key: %w",
err) err)
} }
@ -114,11 +114,11 @@ func signOffer(rootKey *hdkeychain.ExtendedKey,
totalOutput += txOut.Value totalOutput += txOut.Value
pkScript, err := txscript.ParsePkScript(txOut.PkScript) pkScript, err := txscript.ParsePkScript(txOut.PkScript)
if err != nil { if err != nil {
return fmt.Errorf("error parsing pk script: %v", err) return fmt.Errorf("error parsing pk script: %w", err)
} }
addr, err := pkScript.Address(chainParams) addr, err := pkScript.Address(chainParams)
if err != nil { if err != nil {
return fmt.Errorf("error parsing address: %v", err) return fmt.Errorf("error parsing address: %w", err)
} }
fmt.Printf("\tSend %d sats to address %s\n", txOut.Value, addr) fmt.Printf("\tSend %d sats to address %s\n", txOut.Value, addr)
} }
@ -138,7 +138,7 @@ func signOffer(rootKey *hdkeychain.ExtendedKey,
targetKey, err := btcec.ParsePubKey(unknown.Value) targetKey, err := btcec.ParsePubKey(unknown.Value)
if err != nil { if err != nil {
return fmt.Errorf("invalid PSBT, proprietary key has "+ return fmt.Errorf("invalid PSBT, proprietary key has "+
"invalid pubkey: %v", err) "invalid pubkey: %w", err)
} }
// Now we can look up the local key and check the PSBT further, // Now we can look up the local key and check the PSBT further,
@ -148,7 +148,7 @@ func signOffer(rootKey *hdkeychain.ExtendedKey,
) )
if err != nil { if err != nil {
return fmt.Errorf("could not find local multisig key: "+ return fmt.Errorf("could not find local multisig key: "+
"%v", err) "%w", err)
} }
if len(packet.Inputs[idx].WitnessScript) == 0 { if len(packet.Inputs[idx].WitnessScript) == 0 {
return fmt.Errorf("invalid PSBT, missing witness " + return fmt.Errorf("invalid PSBT, missing witness " +
@ -164,7 +164,7 @@ func signOffer(rootKey *hdkeychain.ExtendedKey,
packet, *localKeyDesc, utxo, witnessScript, idx, packet, *localKeyDesc, utxo, witnessScript, idx,
) )
if err != nil { if err != nil {
return fmt.Errorf("error adding partial signature: %v", return fmt.Errorf("error adding partial signature: %w",
err) err)
} }
} }
@ -173,16 +173,16 @@ func signOffer(rootKey *hdkeychain.ExtendedKey,
// extract the final TX. // extract the final TX.
err = psbt.MaybeFinalizeAll(packet) err = psbt.MaybeFinalizeAll(packet)
if err != nil { if err != nil {
return fmt.Errorf("error finalizing PSBT: %v", err) return fmt.Errorf("error finalizing PSBT: %w", err)
} }
finalTx, err := psbt.Extract(packet) finalTx, err := psbt.Extract(packet)
if err != nil { if err != nil {
return fmt.Errorf("unable to extract final TX: %v", err) return fmt.Errorf("unable to extract final TX: %w", err)
} }
var buf bytes.Buffer var buf bytes.Buffer
err = finalTx.Serialize(&buf) err = finalTx.Serialize(&buf)
if err != nil { if err != nil {
return fmt.Errorf("unable to serialize final TX: %v", err) return fmt.Errorf("unable to serialize final TX: %w", err)
} }
fmt.Printf("Success, we counter signed the PSBT and extracted the "+ fmt.Printf("Success, we counter signed the PSBT and extracted the "+

@ -131,7 +131,7 @@ type ChannelDBFile struct {
func (c *ChannelDBFile) AsSummaryEntries() ([]*SummaryEntry, error) { func (c *ChannelDBFile) AsSummaryEntries() ([]*SummaryEntry, error) {
channels, err := c.DB.FetchAllChannels() channels, err := c.DB.FetchAllChannels()
if err != nil { if err != nil {
return nil, fmt.Errorf("error fetching channels: %v", err) return nil, fmt.Errorf("error fetching channels: %w", err)
} }
result := make([]*SummaryEntry, len(channels)) result := make([]*SummaryEntry, len(channels))
for idx, channel := range channels { for idx, channel := range channels {
@ -180,7 +180,7 @@ func FundingTXIndex(chanPoint string) uint32 {
func parseInt(str string) uint64 { func parseInt(str string) uint64 {
index, err := strconv.Atoi(str) index, err := strconv.Atoi(str)
if err != nil { if err != nil {
panic(fmt.Errorf("error parsing '%s' as int: %v", str, err)) panic(fmt.Errorf("error parsing '%s' as int: %w", str, err))
} }
return uint64(index) return uint64(index)
} }

@ -27,12 +27,12 @@ type BasePoint struct {
func (b *BasePoint) Desc() (*keychain.KeyDescriptor, error) { func (b *BasePoint) Desc() (*keychain.KeyDescriptor, error) {
pubKeyHex, err := hex.DecodeString(b.PubKey) pubKeyHex, err := hex.DecodeString(b.PubKey)
if err != nil { if err != nil {
return nil, fmt.Errorf("error decoding base point pubkey: %v", return nil, fmt.Errorf("error decoding base point pubkey: %w",
err) err)
} }
pubKey, err := btcec.ParsePubKey(pubKeyHex) pubKey, err := btcec.ParsePubKey(pubKeyHex)
if err != nil { if err != nil {
return nil, fmt.Errorf("error parsing base point pubkey: %v", return nil, fmt.Errorf("error parsing base point pubkey: %w",
err) err)
} }

@ -210,7 +210,8 @@ func ClosedChannelDump(channels []*channeldb.ChannelCloseSummary,
} }
// BackupDump converts the given multi backup into a dumpable format. // BackupDump converts the given multi backup into a dumpable format.
func BackupDump(multi *chanbackup.Multi, params *chaincfg.Params) []BackupSingle { func BackupDump(multi *chanbackup.Multi,
params *chaincfg.Params) []BackupSingle {
dumpSingles := make([]BackupSingle, len(multi.StaticBackups)) dumpSingles := make([]BackupSingle, len(multi.StaticBackups))
for idx, single := range multi.StaticBackups { for idx, single := range multi.StaticBackups {

@ -109,7 +109,7 @@ func ReadAezeed(params *chaincfg.Params) (*hdkeychain.ExtendedKey, time.Time,
cipherSeed, err := mnemonic.ToCipherSeed(passphraseBytes) cipherSeed, err := mnemonic.ToCipherSeed(passphraseBytes)
if err != nil { if err != nil {
return nil, time.Unix(0, 0), fmt.Errorf("failed to decrypt "+ return nil, time.Unix(0, 0), fmt.Errorf("failed to decrypt "+
"seed with passphrase: %v", err) "seed with passphrase: %w", err)
} }
rootKey, err := hdkeychain.NewMaster(cipherSeed.Entropy[:], params) rootKey, err := hdkeychain.NewMaster(cipherSeed.Entropy[:], params)
if err != nil { if err != nil {

@ -18,7 +18,7 @@ func CreateChannelBackup(db *channeldb.DB, multiFile *chanbackup.MultiFile,
db.ChannelStateDB(), db, db.ChannelStateDB(), db,
) )
if err != nil { if err != nil {
return fmt.Errorf("error extracting channel backup: %v", err) return fmt.Errorf("error extracting channel backup: %w", err)
} }
multi := &chanbackup.Multi{ multi := &chanbackup.Multi{
Version: chanbackup.DefaultMultiVersion, Version: chanbackup.DefaultMultiVersion,
@ -27,11 +27,11 @@ func CreateChannelBackup(db *channeldb.DB, multiFile *chanbackup.MultiFile,
var b bytes.Buffer var b bytes.Buffer
err = multi.PackToWriter(&b, ring) err = multi.PackToWriter(&b, ring)
if err != nil { if err != nil {
return fmt.Errorf("unable to pack backup: %v", err) return fmt.Errorf("unable to pack backup: %w", err)
} }
err = multiFile.UpdateAndSwap(b.Bytes()) err = multiFile.UpdateAndSwap(b.Bytes())
if err != nil { if err != nil {
return fmt.Errorf("unable to write backup file: %v", err) return fmt.Errorf("unable to write backup file: %w", err)
} }
return nil return nil
} }

@ -94,13 +94,13 @@ func ParseOutpoint(s string) (*wire.OutPoint, error) {
index, err := strconv.ParseInt(split[1], 10, 32) index, err := strconv.ParseInt(split[1], 10, 32)
if err != nil { if err != nil {
return nil, fmt.Errorf("unable to decode output index: %v", return nil, fmt.Errorf("unable to decode output index: %w",
err) err)
} }
txid, err := chainhash.NewHashFromStr(split[0]) txid, err := chainhash.NewHashFromStr(split[0])
if err != nil { if err != nil {
return nil, fmt.Errorf("unable to parse hex string: %v", err) return nil, fmt.Errorf("unable to parse hex string: %w", err)
} }
return &wire.OutPoint{ return &wire.OutPoint{

@ -1,6 +1,7 @@
package lnd package lnd
import ( import (
"errors"
"fmt" "fmt"
"io" "io"
"os" "os"
@ -18,7 +19,7 @@ const (
func OpenDB(dbPath string, readonly bool) (*channeldb.DB, error) { func OpenDB(dbPath string, readonly bool) (*channeldb.DB, error) {
backend, err := openDB(dbPath, false, readonly, DefaultOpenTimeout) backend, err := openDB(dbPath, false, readonly, DefaultOpenTimeout)
if err == bbolt.ErrTimeout { if errors.Is(err, bbolt.ErrTimeout) {
return nil, fmt.Errorf("error opening %s: make sure lnd is "+ return nil, fmt.Errorf("error opening %s: make sure lnd is "+
"not running, database is locked by another process", "not running, database is locked by another process",
dbPath) dbPath)
@ -35,33 +36,33 @@ func OpenDB(dbPath string, readonly bool) (*channeldb.DB, error) {
// convertErr converts some bolt errors to the equivalent walletdb error. // convertErr converts some bolt errors to the equivalent walletdb error.
func convertErr(err error) error { func convertErr(err error) error {
switch err { switch {
// Database open/create errors. // Database open/create errors.
case bbolt.ErrDatabaseNotOpen: case errors.Is(err, bbolt.ErrDatabaseNotOpen):
return walletdb.ErrDbNotOpen return walletdb.ErrDbNotOpen
case bbolt.ErrInvalid: case errors.Is(err, bbolt.ErrInvalid):
return walletdb.ErrInvalid return walletdb.ErrInvalid
// Transaction errors. // Transaction errors.
case bbolt.ErrTxNotWritable: case errors.Is(err, bbolt.ErrTxNotWritable):
return walletdb.ErrTxNotWritable return walletdb.ErrTxNotWritable
case bbolt.ErrTxClosed: case errors.Is(err, bbolt.ErrTxClosed):
return walletdb.ErrTxClosed return walletdb.ErrTxClosed
// Value/bucket errors. // Value/bucket errors.
case bbolt.ErrBucketNotFound: case errors.Is(err, bbolt.ErrBucketNotFound):
return walletdb.ErrBucketNotFound return walletdb.ErrBucketNotFound
case bbolt.ErrBucketExists: case errors.Is(err, bbolt.ErrBucketExists):
return walletdb.ErrBucketExists return walletdb.ErrBucketExists
case bbolt.ErrBucketNameRequired: case errors.Is(err, bbolt.ErrBucketNameRequired):
return walletdb.ErrBucketNameRequired return walletdb.ErrBucketNameRequired
case bbolt.ErrKeyRequired: case errors.Is(err, bbolt.ErrKeyRequired):
return walletdb.ErrKeyRequired return walletdb.ErrKeyRequired
case bbolt.ErrKeyTooLarge: case errors.Is(err, bbolt.ErrKeyTooLarge):
return walletdb.ErrKeyTooLarge return walletdb.ErrKeyTooLarge
case bbolt.ErrValueTooLarge: case errors.Is(err, bbolt.ErrValueTooLarge):
return walletdb.ErrValueTooLarge return walletdb.ErrValueTooLarge
case bbolt.ErrIncompatibleValue: case errors.Is(err, bbolt.ErrIncompatibleValue):
return walletdb.ErrIncompatibleValue return walletdb.ErrIncompatibleValue
} }
@ -298,28 +299,28 @@ func (c *cursor) Delete() error {
// First positions the cursor at the first key/value pair and returns the pair. // First positions the cursor at the first key/value pair and returns the pair.
// //
// This function is part of the walletdb.ReadCursor interface implementation. // This function is part of the walletdb.ReadCursor interface implementation.
func (c *cursor) First() (key, value []byte) { func (c *cursor) First() ([]byte, []byte) {
return (*bbolt.Cursor)(c).First() return (*bbolt.Cursor)(c).First()
} }
// Last positions the cursor at the last key/value pair and returns the pair. // Last positions the cursor at the last key/value pair and returns the pair.
// //
// This function is part of the walletdb.ReadCursor interface implementation. // This function is part of the walletdb.ReadCursor interface implementation.
func (c *cursor) Last() (key, value []byte) { func (c *cursor) Last() ([]byte, []byte) {
return (*bbolt.Cursor)(c).Last() return (*bbolt.Cursor)(c).Last()
} }
// Next moves the cursor one key/value pair forward and returns the new pair. // Next moves the cursor one key/value pair forward and returns the new pair.
// //
// This function is part of the walletdb.ReadCursor interface implementation. // This function is part of the walletdb.ReadCursor interface implementation.
func (c *cursor) Next() (key, value []byte) { func (c *cursor) Next() ([]byte, []byte) {
return (*bbolt.Cursor)(c).Next() return (*bbolt.Cursor)(c).Next()
} }
// Prev moves the cursor one key/value pair backward and returns the new pair. // Prev moves the cursor one key/value pair backward and returns the new pair.
// //
// This function is part of the walletdb.ReadCursor interface implementation. // This function is part of the walletdb.ReadCursor interface implementation.
func (c *cursor) Prev() (key, value []byte) { func (c *cursor) Prev() ([]byte, []byte) {
return (*bbolt.Cursor)(c).Prev() return (*bbolt.Cursor)(c).Prev()
} }
@ -327,7 +328,7 @@ func (c *cursor) Prev() (key, value []byte) {
// the cursor is moved to the next key after seek. Returns the new pair. // the cursor is moved to the next key after seek. Returns the new pair.
// //
// This function is part of the walletdb.ReadCursor interface implementation. // This function is part of the walletdb.ReadCursor interface implementation.
func (c *cursor) Seek(seek []byte) (key, value []byte) { func (c *cursor) Seek(seek []byte) ([]byte, []byte) {
return (*bbolt.Cursor)(c).Seek(seek) return (*bbolt.Cursor)(c).Seek(seek)
} }

@ -103,27 +103,27 @@ func DeriveKey(extendedKey *hdkeychain.ExtendedKey, path string,
parsedPath, err := ParsePath(path) parsedPath, err := ParsePath(path)
if err != nil { if err != nil {
return nil, nil, nil, fmt.Errorf("could not parse derivation "+ return nil, nil, nil, fmt.Errorf("could not parse derivation "+
"path: %v", err) "path: %w", err)
} }
derivedKey, err := DeriveChildren(extendedKey, parsedPath) derivedKey, err := DeriveChildren(extendedKey, parsedPath)
if err != nil { if err != nil {
return nil, nil, nil, fmt.Errorf("could not derive children: "+ return nil, nil, nil, fmt.Errorf("could not derive children: "+
"%v", err) "%w", err)
} }
pubKey, err := derivedKey.ECPubKey() pubKey, err := derivedKey.ECPubKey()
if err != nil { if err != nil {
return nil, nil, nil, fmt.Errorf("could not derive public "+ return nil, nil, nil, fmt.Errorf("could not derive public "+
"key: %v", err) "key: %w", err)
} }
privKey, err := derivedKey.ECPrivKey() privKey, err := derivedKey.ECPrivKey()
if err != nil { if err != nil {
return nil, nil, nil, fmt.Errorf("could not derive private "+ return nil, nil, nil, fmt.Errorf("could not derive private "+
"key: %v", err) "key: %w", err)
} }
wif, err := btcutil.NewWIF(privKey, params, true) wif, err := btcutil.NewWIF(privKey, params, true)
if err != nil { if err != nil {
return nil, nil, nil, fmt.Errorf("could not encode WIF: %v", return nil, nil, nil, fmt.Errorf("could not encode WIF: %w",
err) err)
} }
@ -135,11 +135,11 @@ func PrivKeyFromPath(extendedKey *hdkeychain.ExtendedKey,
derivedKey, err := DeriveChildren(extendedKey, path) derivedKey, err := DeriveChildren(extendedKey, path)
if err != nil { if err != nil {
return nil, fmt.Errorf("could not derive children: %v", err) return nil, fmt.Errorf("could not derive children: %w", err)
} }
privKey, err := derivedKey.ECPrivKey() privKey, err := derivedKey.ECPrivKey()
if err != nil { if err != nil {
return nil, fmt.Errorf("could not derive private key: %v", err) return nil, fmt.Errorf("could not derive private key: %w", err)
} }
return privKey, nil return privKey, nil
} }
@ -158,7 +158,7 @@ func ShaChainFromPath(extendedKey *hdkeychain.ExtendedKey, path []uint32,
revRoot, err := chainhash.NewHash(privKey.Serialize()) revRoot, err := chainhash.NewHash(privKey.Serialize())
if err != nil { if err != nil {
return nil, fmt.Errorf("could not create revocation "+ return nil, fmt.Errorf("could not create revocation "+
"root hash: %v", err) "root hash: %w", err)
} }
return shachain.NewRevocationProducer(*revRoot), nil return shachain.NewRevocationProducer(*revRoot), nil
} }
@ -220,7 +220,7 @@ func DecodeAddressHash(addr string, chainParams *chaincfg.Params) ([]byte, bool,
// First parse address to get targetHash from it later. // First parse address to get targetHash from it later.
targetAddr, err := btcutil.DecodeAddress(addr, chainParams) targetAddr, err := btcutil.DecodeAddress(addr, chainParams)
if err != nil { if err != nil {
return nil, false, fmt.Errorf("unable to decode address %s: %v", return nil, false, fmt.Errorf("unable to decode address %s: %w",
addr, err) addr, err)
} }
@ -322,7 +322,7 @@ func P2PKHAddr(pubKey *btcec.PublicKey,
hash160 := btcutil.Hash160(pubKey.SerializeCompressed()) hash160 := btcutil.Hash160(pubKey.SerializeCompressed())
addrP2PKH, err := btcutil.NewAddressPubKeyHash(hash160, params) addrP2PKH, err := btcutil.NewAddressPubKeyHash(hash160, params)
if err != nil { if err != nil {
return nil, fmt.Errorf("could not create address: %v", err) return nil, fmt.Errorf("could not create address: %w", err)
} }
return addrP2PKH, nil return addrP2PKH, nil
@ -341,11 +341,11 @@ func NP2WKHAddr(pubKey *btcec.PublicKey,
hash160 := btcutil.Hash160(pubKey.SerializeCompressed()) hash160 := btcutil.Hash160(pubKey.SerializeCompressed())
addrP2WKH, err := btcutil.NewAddressWitnessPubKeyHash(hash160, params) addrP2WKH, err := btcutil.NewAddressWitnessPubKeyHash(hash160, params)
if err != nil { if err != nil {
return nil, fmt.Errorf("could not create address: %v", err) return nil, fmt.Errorf("could not create address: %w", err)
} }
script, err := txscript.PayToAddrScript(addrP2WKH) script, err := txscript.PayToAddrScript(addrP2WKH)
if err != nil { if err != nil {
return nil, fmt.Errorf("could not create script: %v", err) return nil, fmt.Errorf("could not create script: %w", err)
} }
return btcutil.NewAddressScriptHash(script, params) return btcutil.NewAddressScriptHash(script, params)
} }
@ -356,7 +356,7 @@ func P2AnchorStaticRemote(pubKey *btcec.PublicKey,
commitScript, err := input.CommitScriptToRemoteConfirmed(pubKey) commitScript, err := input.CommitScriptToRemoteConfirmed(pubKey)
if err != nil { if err != nil {
return nil, nil, fmt.Errorf("could not create script: %v", err) return nil, nil, fmt.Errorf("could not create script: %w", err)
} }
scriptHash := sha256.Sum256(commitScript) scriptHash := sha256.Sum256(commitScript)
p2wsh, err := btcutil.NewAddressWitnessScriptHash(scriptHash[:], params) p2wsh, err := btcutil.NewAddressWitnessScriptHash(scriptHash[:], params)

@ -24,6 +24,7 @@ type Signer struct {
func (s *Signer) SignOutputRaw(tx *wire.MsgTx, func (s *Signer) SignOutputRaw(tx *wire.MsgTx,
signDesc *input.SignDescriptor) (input.Signature, error) { signDesc *input.SignDescriptor) (input.Signature, error) {
witnessScript := signDesc.WitnessScript witnessScript := signDesc.WitnessScript
// First attempt to fetch the private key which corresponds to the // First attempt to fetch the private key which corresponds to the
@ -84,21 +85,21 @@ func (s *Signer) AddPartialSignature(packet *psbt.Packet,
} }
ourSigRaw, err := s.SignOutputRaw(packet.UnsignedTx, signDesc) ourSigRaw, err := s.SignOutputRaw(packet.UnsignedTx, signDesc)
if err != nil { if err != nil {
return fmt.Errorf("error signing with our key: %v", err) return fmt.Errorf("error signing with our key: %w", err)
} }
ourSig := append(ourSigRaw.Serialize(), byte(txscript.SigHashAll)) ourSig := append(ourSigRaw.Serialize(), byte(txscript.SigHashAll))
// Great, we were able to create our sig, let's add it to the PSBT. // Great, we were able to create our sig, let's add it to the PSBT.
updater, err := psbt.NewUpdater(packet) updater, err := psbt.NewUpdater(packet)
if err != nil { if err != nil {
return fmt.Errorf("error creating PSBT updater: %v", err) return fmt.Errorf("error creating PSBT updater: %w", err)
} }
status, err := updater.Sign( status, err := updater.Sign(
inputIndex, ourSig, keyDesc.PubKey.SerializeCompressed(), nil, inputIndex, ourSig, keyDesc.PubKey.SerializeCompressed(), nil,
witnessScript, witnessScript,
) )
if err != nil { if err != nil {
return fmt.Errorf("error adding signature to PSBT: %v", err) return fmt.Errorf("error adding signature to PSBT: %w", err)
} }
if status != 0 { if status != 0 {
return fmt.Errorf("unexpected status for signature update, "+ return fmt.Errorf("unexpected status for signature update, "+

Loading…
Cancel
Save