Compare commits

...

14 Commits

Author SHA1 Message Date
Oliver Gugger 85f207c58f
Merge pull request #137 from hieblmi/gitignore-idea
gitignore: .idea folder
1 week ago
Slyghtning da904ae1d7
gitignore: .idea folder 1 week ago
Oliver Gugger 14aa06fa41
Merge pull request #134 from lightninglabs/dependabot/go_modules/tools/github.com/btcsuite/btcd-0.24.0
build(deps): bump github.com/btcsuite/btcd from 0.23.4 to 0.24.0 in /tools
4 weeks ago
dependabot[bot] 601789f445
build(deps): bump github.com/btcsuite/btcd in /tools
Bumps [github.com/btcsuite/btcd](https://github.com/btcsuite/btcd) from 0.23.4 to 0.24.0.
- [Release notes](https://github.com/btcsuite/btcd/releases)
- [Changelog](https://github.com/btcsuite/btcd/blob/master/CHANGES)
- [Commits](https://github.com/btcsuite/btcd/compare/v0.23.4...v0.24.0)

---
updated-dependencies:
- dependency-name: github.com/btcsuite/btcd
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
4 weeks ago
Oliver Gugger cc284baa67
Merge pull request #132 from lightninglabs/triggerforceclose
triggerforceclose: make compatible with all nodes, add Tor support
1 month ago
Oliver Gugger 6acc81815e
root: bump version to v0.13.1 1 month ago
Oliver Gugger e3285daf5b
triggerforceclose: support Tor connections 1 month ago
Oliver Gugger 179773fdb9
triggerforceclose: make cmd compatible with all nodes 1 month ago
Oliver Gugger 0fd58ee7eb
Merge pull request #130 from lightninglabs/dependabot/go_modules/golang.org/x/net-0.23.0
build(deps): bump golang.org/x/net from 0.21.0 to 0.23.0
1 month ago
dependabot[bot] 7c405057bd
build(deps): bump golang.org/x/net from 0.21.0 to 0.23.0
Bumps [golang.org/x/net](https://github.com/golang/net) from 0.21.0 to 0.23.0.
- [Commits](https://github.com/golang/net/compare/v0.21.0...v0.23.0)

---
updated-dependencies:
- dependency-name: golang.org/x/net
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
1 month ago
Oliver Gugger d07251df9c
Merge pull request #129 from lightninglabs/fix-signpsbt
signpsbt+lnd: fix signing for P2WKH
2 months ago
Oliver Gugger 7f840cf03b
signpsbt+lnd: fix signing for P2WKH 2 months ago
Oliver Gugger f062b53a21
Merge pull request #127 from lightninglabs/dependabot/go_modules/github.com/docker/docker-24.0.9incompatible
build(deps): bump github.com/docker/docker from 24.0.7+incompatible to 24.0.9+incompatible
2 months ago
dependabot[bot] c54184b8d0
build(deps): bump github.com/docker/docker
Bumps [github.com/docker/docker](https://github.com/docker/docker) from 24.0.7+incompatible to 24.0.9+incompatible.
- [Release notes](https://github.com/docker/docker/releases)
- [Commits](https://github.com/docker/docker/compare/v24.0.7...v24.0.9)

---
updated-dependencies:
- dependency-name: github.com/docker/docker
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2 months ago

1
.gitignore vendored

@ -1,3 +1,4 @@
.idea
/chantools
results
/chantools-v*

@ -107,7 +107,8 @@ Scenarios:
Another reason might be that the peer is a CLN node with a specific version
that doesn't react to force close requests normally. You can use the
[`chantools triggerforceclose` command](doc/chantools_triggerforceclose.md) in
that case (ONLY works with CLN peers of a certain version).
that case (should work with CLN peers of a certain version that don't respond
to normal force close requests).
## What should I NEVER do?
@ -437,7 +438,7 @@ Available Commands:
sweeptimelock Sweep the force-closed state after the time lock has expired
sweeptimelockmanual Sweep the force-closed state of a single channel manually if only a channel backup file is available
sweepremoteclosed Go through all the addresses that could have funds of channels that were force-closed by the remote party. A public block explorer is queried for each address and if any balance is found, all funds are swept to a given address
triggerforceclose Connect to a peer and send a custom message to trigger a force close of the specified channel
triggerforceclose Connect to a peer and send request to trigger a force close of the specified channel
vanitygen Generate a seed with a custom lnd node identity public key that starts with the given prefix
walletinfo Shows info about an lnd wallet.db file and optionally extracts the BIP32 HD root key
zombierecovery Try rescuing funds stuck in channels with zombie nodes
@ -499,7 +500,7 @@ Legend:
| [sweepremoteclosed](doc/chantools_sweepremoteclosed.md) | :pencil: Find channel funds from remotely force closed channels and sweep them |
| [sweeptimelock](doc/chantools_sweeptimelock.md) | :pencil: Sweep funds in locally force closed channels once time lock has expired (requires `channel.db`) |
| [sweeptimelockmanual](doc/chantools_sweeptimelockmanual.md) | :pencil: Manually sweep funds in a locally force closed channel where no `channel.db` file is available |
| [triggerforceclose](doc/chantools_triggerforceclose.md) | :pencil: (:pushpin:) Request certain CLN peers to force close a channel that don't react to normal SCB recovery requests |
| [triggerforceclose](doc/chantools_triggerforceclose.md) | :pencil: (:pushpin:) Request a peer to force close a channel |
| [vanitygen](doc/chantools_vanitygen.md) | Generate an `lnd` seed for a node public key that starts with a certain sequence of hex digits |
| [walletinfo](doc/chantools_walletinfo.md) | Show information from a `wallet.db` file, requires access to the wallet password |
| [zombierecovery](doc/chantools_zombierecovery.md) | :pencil: Cooperatively rescue funds from channels where normal recovery is not possible (see [full guide here][zombie-recovery]) |

@ -30,7 +30,7 @@ const (
// version is the current version of the tool. It is set during build.
// NOTE: When changing this, please also update the version in the
// download link shown in the README.
version = "0.13.0"
version = "0.13.1"
na = "n/a"
// lndVersion is the current version of lnd that we support. This is

@ -10,6 +10,7 @@ import (
"github.com/btcsuite/btcd/btcutil"
"github.com/btcsuite/btcd/btcutil/hdkeychain"
"github.com/btcsuite/btcd/btcutil/psbt"
"github.com/btcsuite/btcd/txscript"
"github.com/lightninglabs/chantools/lnd"
"github.com/spf13/cobra"
)
@ -153,17 +154,25 @@ func signPsbt(rootKey *hdkeychain.ExtendedKey,
return fmt.Errorf("could not derive local key: %w", err)
}
if len(packet.Inputs[inputIndex].WitnessScript) == 0 {
return fmt.Errorf("invalid PSBT, input %d is missing witness "+
"script", inputIndex)
}
witnessScript := packet.Inputs[inputIndex].WitnessScript
if packet.Inputs[inputIndex].WitnessUtxo == nil {
return fmt.Errorf("invalid PSBT, input %d is missing witness "+
"UTXO", inputIndex)
}
utxo := packet.Inputs[inputIndex].WitnessUtxo
// The signing is a bit different for P2WPKH, we need to specify the
// pk script as the witness script.
var witnessScript []byte
if txscript.IsPayToWitnessPubKeyHash(utxo.PkScript) {
witnessScript = utxo.PkScript
} else {
if len(packet.Inputs[inputIndex].WitnessScript) == 0 {
return fmt.Errorf("invalid PSBT, input %d is missing "+
"witness script", inputIndex)
}
witnessScript = packet.Inputs[inputIndex].WitnessScript
}
localPrivateKey, err := localKey.ECPrivKey()
if err != nil {
return fmt.Errorf("error getting private key: %w", err)

@ -2,11 +2,11 @@ package main
import (
"fmt"
"net"
"strconv"
"strings"
"time"
"github.com/btcsuite/btcd/btcec/v2"
"github.com/btcsuite/btcd/chaincfg/chainhash"
"github.com/btcsuite/btcd/connmgr"
"github.com/btcsuite/btcd/wire"
@ -15,12 +15,15 @@ import (
"github.com/lightningnetwork/lnd/keychain"
"github.com/lightningnetwork/lnd/lncfg"
"github.com/lightningnetwork/lnd/lnwire"
"github.com/lightningnetwork/lnd/peer"
"github.com/lightningnetwork/lnd/tor"
"github.com/spf13/cobra"
)
var (
dialTimeout = time.Minute
defaultTorDNSHostPort = "soa.nodes.lightning.directory:53"
)
type triggerForceCloseCommand struct {
@ -29,6 +32,8 @@ type triggerForceCloseCommand struct {
APIURL string
TorProxy string
rootKey *rootKey
cmd *cobra.Command
}
@ -37,13 +42,13 @@ func newTriggerForceCloseCommand() *cobra.Command {
cc := &triggerForceCloseCommand{}
cc.cmd = &cobra.Command{
Use: "triggerforceclose",
Short: "Connect to a CLN peer and send a custom message to " +
"trigger a force close of the specified channel",
Long: `Certain versions of CLN didn't properly react to error
messages sent by peers and therefore didn't follow the DLP protocol to recover
channel funds using SCB. This command can be used to trigger a force close with
those earlier versions of CLN (this command will not work for lnd peers or CLN
peers of a different version).`,
Short: "Connect to a Lightning Network peer and send " +
"specific messages to trigger a force close of the " +
"specified channel",
Long: `Asks the specified remote peer to force close a specific
channel by first sending a channel re-establish message, and if that doesn't
work, a custom error message (in case the peer is a specific version of CLN that
does not properly respond to a Data Loss Protection re-establish message).'`,
Example: `chantools triggerforceclose \
--peer 03abce...@xx.yy.zz.aa:9735 \
--channel_point abcdef01234...:x`,
@ -62,6 +67,10 @@ peers of a different version).`,
&cc.APIURL, "apiurl", defaultAPIURL, "API URL to use (must "+
"be esplora compatible)",
)
cc.cmd.Flags().StringVar(
&cc.TorProxy, "torproxy", "", "SOCKS5 proxy to use for Tor "+
"connections (to .onion addresses)",
)
cc.rootKey = newRootKey(cc.cmd, "deriving the identity key")
return cc.cmd
@ -88,101 +97,152 @@ func (c *triggerForceCloseCommand) Execute(_ *cobra.Command, _ []string) error {
PrivKey: identityPriv,
}
peerAddr, err := lncfg.ParseLNAddressString(
c.Peer, "9735", net.ResolveTCPAddr,
outPoint, err := parseOutPoint(c.ChannelPoint)
if err != nil {
return fmt.Errorf("error parsing channel point: %w", err)
}
err = requestForceClose(
c.Peer, c.TorProxy, pubKey, outPoint, identityECDH,
)
if err != nil {
return fmt.Errorf("error parsing peer address: %w", err)
return fmt.Errorf("error requesting force close: %w", err)
}
outPoint, err := parseOutPoint(c.ChannelPoint)
log.Infof("Message sent, waiting for force close transaction to " +
"appear in mempool")
api := newExplorerAPI(c.APIURL)
channelAddress, err := api.Address(c.ChannelPoint)
if err != nil {
return fmt.Errorf("error parsing channel point: %w", err)
return fmt.Errorf("error getting channel address: %w", err)
}
spends, err := api.Spends(channelAddress)
if err != nil {
return fmt.Errorf("error getting spends: %w", err)
}
for len(spends) == 0 {
log.Infof("No spends found yet, waiting 5 seconds...")
time.Sleep(5 * time.Second)
spends, err = api.Spends(channelAddress)
if err != nil {
return fmt.Errorf("error getting spends: %w", err)
}
}
channelID := lnwire.NewChanIDFromOutPoint(outPoint)
conn, err := noiseDial(
identityECDH, peerAddr, &tor.ClearNet{}, dialTimeout,
log.Infof("Found force close transaction %v", spends[0].TXID)
log.Infof("You can now use the sweepremoteclosed command to sweep " +
"the funds from the channel")
return nil
}
func noiseDial(idKey keychain.SingleKeyECDH, lnAddr *lnwire.NetAddress,
netCfg tor.Net, timeout time.Duration) (*brontide.Conn, error) {
return brontide.Dial(idKey, lnAddr, timeout, netCfg.Dial)
}
func connectPeer(peerHost, torProxy string, peerPubKey *btcec.PublicKey,
identity keychain.SingleKeyECDH,
dialTimeout time.Duration) (*peer.Brontide, error) {
var dialNet tor.Net = &tor.ClearNet{}
if torProxy != "" {
dialNet = &tor.ProxyNet{
SOCKS: torProxy,
DNS: defaultTorDNSHostPort,
StreamIsolation: false,
SkipProxyForClearNetTargets: true,
}
}
log.Debugf("Attempting to resolve peer address %v", peerHost)
peerAddr, err := lncfg.ParseLNAddressString(
peerHost, "9735", dialNet.ResolveTCPAddr,
)
if err != nil {
return fmt.Errorf("error dialing peer: %w", err)
return nil, fmt.Errorf("error parsing peer address: %w", err)
}
log.Infof("Attempting to connect to peer %x, dial timeout is %v",
pubKey.SerializeCompressed(), dialTimeout)
log.Debugf("Attempting to dial resolved peer address %v",
peerAddr.String())
conn, err := noiseDial(identity, peerAddr, dialNet, dialTimeout)
if err != nil {
return nil, fmt.Errorf("error dialing peer: %w", err)
}
log.Infof("Attempting to establish p2p connection to peer %x, dial"+
"timeout is %v", peerPubKey.SerializeCompressed(), dialTimeout)
req := &connmgr.ConnReq{
Addr: peerAddr,
Permanent: false,
}
p, err := lnd.ConnectPeer(conn, req, chainParams, identityECDH)
p, err := lnd.ConnectPeer(conn, req, chainParams, identity)
if err != nil {
return fmt.Errorf("error connecting to peer: %w", err)
return nil, fmt.Errorf("error connecting to peer: %w", err)
}
log.Infof("Connection established to peer %x",
pubKey.SerializeCompressed())
peerPubKey.SerializeCompressed())
// We'll wait until the peer is active.
select {
case <-p.ActiveSignal():
case <-p.QuitSignal():
return fmt.Errorf("peer %x disconnected",
pubKey.SerializeCompressed())
return nil, fmt.Errorf("peer %x disconnected",
peerPubKey.SerializeCompressed())
}
return p, nil
}
func requestForceClose(peerHost, torProxy string, peerPubKey *btcec.PublicKey,
channelPoint *wire.OutPoint, identity keychain.SingleKeyECDH) error {
p, err := connectPeer(
peerHost, torProxy, peerPubKey, identity, dialTimeout,
)
if err != nil {
return fmt.Errorf("error connecting to peer: %w", err)
}
channelID := lnwire.NewChanIDFromOutPoint(channelPoint)
// Channel ID (32 byte) + u16 for the data length (which will be 0).
data := make([]byte, 34)
copy(data[:32], channelID[:])
log.Infof("Sending channel error message to peer to trigger force "+
"close of channel %v", c.ChannelPoint)
log.Infof("Sending channel re-establish to peer to trigger force "+
"close of channel %v", channelPoint)
_ = lnwire.SetCustomOverrides([]uint16{lnwire.MsgError})
msg, err := lnwire.NewCustom(lnwire.MsgError, data)
err = p.SendMessageLazy(true, &lnwire.ChannelReestablish{
ChanID: channelID,
})
if err != nil {
return err
}
err = p.SendMessageLazy(true, msg)
if err != nil {
return fmt.Errorf("error sending message: %w", err)
}
log.Infof("Message sent, waiting for force close transaction to " +
"appear in mempool")
log.Infof("Sending channel error message to peer to trigger force "+
"close of channel %v", channelPoint)
api := newExplorerAPI(c.APIURL)
channelAddress, err := api.Address(c.ChannelPoint)
_ = lnwire.SetCustomOverrides([]uint16{
lnwire.MsgError, lnwire.MsgChannelReestablish,
})
msg, err := lnwire.NewCustom(lnwire.MsgError, data)
if err != nil {
return fmt.Errorf("error getting channel address: %w", err)
return err
}
spends, err := api.Spends(channelAddress)
err = p.SendMessageLazy(true, msg)
if err != nil {
return fmt.Errorf("error getting spends: %w", err)
}
for len(spends) == 0 {
log.Infof("No spends found yet, waiting 5 seconds...")
time.Sleep(5 * time.Second)
spends, err = api.Spends(channelAddress)
if err != nil {
return fmt.Errorf("error getting spends: %w", err)
}
return fmt.Errorf("error sending message: %w", err)
}
log.Infof("Found force close transaction %v", spends[0].TXID)
log.Infof("You can now use the sweepremoteclosed command to sweep " +
"the funds from the channel")
return nil
}
func noiseDial(idKey keychain.SingleKeyECDH, lnAddr *lnwire.NetAddress,
netCfg tor.Net, timeout time.Duration) (*brontide.Conn, error) {
return brontide.Dial(idKey, lnAddr, timeout, netCfg.Dial)
}
func parseOutPoint(s string) (*wire.OutPoint, error) {
split := strings.Split(s, ":")
if len(split) != 2 || len(split[0]) == 0 || len(split[1]) == 0 {

@ -51,7 +51,7 @@ https://github.com/lightninglabs/chantools/.
* [chantools sweepremoteclosed](chantools_sweepremoteclosed.md) - Go through all the addresses that could have funds of channels that were force-closed by the remote party. A public block explorer is queried for each address and if any balance is found, all funds are swept to a given address
* [chantools sweeptimelock](chantools_sweeptimelock.md) - Sweep the force-closed state after the time lock has expired
* [chantools sweeptimelockmanual](chantools_sweeptimelockmanual.md) - Sweep the force-closed state of a single channel manually if only a channel backup file is available
* [chantools triggerforceclose](chantools_triggerforceclose.md) - Connect to a CLN peer and send a custom message to trigger a force close of the specified channel
* [chantools triggerforceclose](chantools_triggerforceclose.md) - Connect to a Lightning Network peer and send specific messages to trigger a force close of the specified channel
* [chantools vanitygen](chantools_vanitygen.md) - Generate a seed with a custom lnd node identity public key that starts with the given prefix
* [chantools walletinfo](chantools_walletinfo.md) - Shows info about an lnd wallet.db file and optionally extracts the BIP32 HD root key
* [chantools zombierecovery](chantools_zombierecovery.md) - Try rescuing funds stuck in channels with zombie nodes

@ -10,7 +10,7 @@ If only the failed payments should be deleted (and not the successful ones), the
CAUTION: Running this command will make it impossible to use the channel DB
with an older version of lnd. Downgrading is not possible and you'll need to
run lnd v0.17.0-beta or later after using this command!'
run lnd v0.17.4-beta or later after using this command!'
```
chantools deletepayments [flags]

@ -12,7 +12,7 @@ without removing any other data.
CAUTION: Running this command will make it impossible to use the channel DB
with an older version of lnd. Downgrading is not possible and you'll need to
run lnd v0.17.0-beta or later after using this command!'
run lnd v0.17.4-beta or later after using this command!'
```
chantools dropchannelgraph [flags]

@ -12,7 +12,7 @@ be helpful to fix a graph that is out of sync with the network.
CAUTION: Running this command will make it impossible to use the channel DB
with an older version of lnd. Downgrading is not possible and you'll need to
run lnd v0.17.0-beta or later after using this command!'
run lnd v0.17.4-beta or later after using this command!'
```
chantools dropgraphzombies [flags]

@ -11,7 +11,7 @@ needs to read the database content.
CAUTION: Running this command will make it impossible to use the channel DB
with an older version of lnd. Downgrading is not possible and you'll need to
run lnd v0.17.0-beta or later after using this command!'
run lnd v0.17.4-beta or later after using this command!'
```
chantools migratedb [flags]

@ -30,6 +30,7 @@ chantools recoverloopin \
--output_amt uint amount of the output to sweep
--publish publish sweep TX to the chain API instead of just printing the TX
--rootkey string BIP32 HD root key of the wallet to use for deriving starting key; leave empty to prompt for lnd 24 word aezeed
--sqlite_file string optional path to the loop sqlite database file, if not specified, the default location will be loaded from --loop_db_dir
--start_key_index int start key index to try to find the correct key index
--swap_hash string swap hash of the loop in swap
--sweepaddr string address to recover the funds to; specify 'fromseed' to derive a new address from the seed automatically

@ -11,7 +11,7 @@ channel was never confirmed on chain!
CAUTION: Running this command will make it impossible to use the channel DB
with an older version of lnd. Downgrading is not possible and you'll need to
run lnd v0.17.0-beta or later after using this command!
run lnd v0.17.4-beta or later after using this command!
```
chantools removechannel [flags]

@ -1,14 +1,13 @@
## chantools triggerforceclose
Connect to a CLN peer and send a custom message to trigger a force close of the specified channel
Connect to a Lightning Network peer and send specific messages to trigger a force close of the specified channel
### Synopsis
Certain versions of CLN didn't properly react to error
messages sent by peers and therefore didn't follow the DLP protocol to recover
channel funds using SCB. This command can be used to trigger a force close with
those earlier versions of CLN (this command will not work for lnd peers or CLN
peers of a different version).
Asks the specified remote peer to force close a specific
channel by first sending a channel re-establish message, and if that doesn't
work, a custom error message (in case the peer is a specific version of CLN that
does not properly respond to a Data Loss Protection re-establish message).'
```
chantools triggerforceclose [flags]
@ -31,6 +30,7 @@ chantools triggerforceclose \
-h, --help help for triggerforceclose
--peer string remote peer address (<pubkey>@<host>[:<port>])
--rootkey string BIP32 HD root key of the wallet to use for deriving the identity key; leave empty to prompt for lnd 24 word aezeed
--torproxy string SOCKS5 proxy to use for Tor connections (to .onion addresses)
--walletdb string read the seed/master root key to use fro deriving the identity key from an lnd wallet.db file instead of asking for a seed or providing the --rootkey flag
```

@ -31,7 +31,7 @@ require (
github.com/spf13/cobra v1.1.3
github.com/stretchr/testify v1.8.4
go.etcd.io/bbolt v1.3.7
golang.org/x/crypto v0.20.0
golang.org/x/crypto v0.21.0
golang.org/x/oauth2 v0.11.0
)
@ -61,7 +61,7 @@ require (
github.com/decred/dcrd/crypto/blake256 v1.0.0 // indirect
github.com/decred/dcrd/lru v1.0.0 // indirect
github.com/docker/cli v20.10.17+incompatible // indirect
github.com/docker/docker v24.0.7+incompatible // indirect
github.com/docker/docker v24.0.9+incompatible // indirect
github.com/docker/go-connections v0.4.0 // indirect
github.com/docker/go-units v0.5.0 // indirect
github.com/dsnet/compress v0.0.1 // indirect
@ -176,10 +176,10 @@ require (
go.uber.org/zap v1.17.0 // indirect
golang.org/x/exp v0.0.0-20230315142452-642cacee5cc0 // indirect
golang.org/x/mod v0.10.0 // indirect
golang.org/x/net v0.21.0 // indirect
golang.org/x/net v0.23.0 // indirect
golang.org/x/sync v0.3.0 // indirect
golang.org/x/sys v0.17.0 // indirect
golang.org/x/term v0.17.0 // indirect
golang.org/x/sys v0.18.0 // indirect
golang.org/x/term v0.18.0 // indirect
golang.org/x/text v0.14.0 // indirect
golang.org/x/time v0.3.0 // indirect
golang.org/x/tools v0.9.1 // indirect

@ -551,8 +551,8 @@ github.com/docker/cli v20.10.17+incompatible h1:eO2KS7ZFeov5UJeaDmIs1NFEDRf32Paq
github.com/docker/cli v20.10.17+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8=
github.com/docker/distribution v2.8.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
github.com/docker/docker v24.0.7+incompatible h1:Wo6l37AuwP3JaMnZa226lzVXGA3F9Ig1seQen0cKYlM=
github.com/docker/docker v24.0.7+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/docker v24.0.9+incompatible h1:HPGzNmwfLZWdxHqK9/II92pyi1EpYKsAqcl4G0Of9v0=
github.com/docker/docker v24.0.9+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ=
github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec=
github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4=
@ -1279,8 +1279,8 @@ golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5y
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20220314234659-1baeb1ce4c0b/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.20.0 h1:jmAMJJZXr5KiCw05dfYK9QnqaqKLYXijU23lsEdcQqg=
golang.org/x/crypto v0.20.0/go.mod h1:Xwo95rrVNIoSMx9wa1JroENMToLWn3RNVrTBpLHgZPQ=
golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA=
golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
@ -1387,8 +1387,8 @@ golang.org/x/net v0.0.0-20221012135044-0b7e1fb9d458/go.mod h1:YDH+HFinaLZZlnHAfS
golang.org/x/net v0.0.0-20221014081412-f15817d10f9b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws=
golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4=
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs=
golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@ -1527,15 +1527,15 @@ golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y=
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4=
golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ=
golang.org/x/term v0.17.0 h1:mkTF7LCd6WGJNL3K1Ad7kwxNfYAW6a8a8QqtMblp/4U=
golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
golang.org/x/term v0.18.0 h1:FcHjZXDMxI8mM3nwhX9HlKop4C0YQvCVCdwYl2wOtE8=
golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=

@ -210,6 +210,14 @@ func (s *Signer) AddPartialSignatureForPrivateKey(packet *psbt.Packet,
if err != nil {
return fmt.Errorf("error creating PSBT updater: %w", err)
}
// If the witness script is the pk script for a P2WPKH output, then we
// need to blank it out for the PSBT code, otherwise it interprets it as
// a P2WSH.
if txscript.IsPayToWitnessPubKeyHash(utxo.PkScript) {
witnessScript = nil
}
status, err := updater.Sign(
inputIndex, ourSig, privateKey.PubKey().SerializeCompressed(),
nil, witnessScript,

@ -3,7 +3,7 @@ module github.com/lightninglabs/chantools/tools
go 1.18
require (
github.com/btcsuite/btcd v0.23.4
github.com/btcsuite/btcd v0.24.0
github.com/golangci/golangci-lint v1.51.2
github.com/ory/go-acc v0.2.8
github.com/rinchsan/gosimports v0.1.5
@ -32,8 +32,8 @@ require (
github.com/breml/bidichk v0.2.3 // indirect
github.com/breml/errchkjson v0.3.0 // indirect
github.com/btcsuite/btcd/btcec/v2 v2.1.3 // indirect
github.com/btcsuite/btcd/btcutil v1.1.0 // indirect
github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1 // indirect
github.com/btcsuite/btcd/btcutil v1.1.5 // indirect
github.com/btcsuite/btcd/chaincfg/chainhash v1.1.0 // indirect
github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f // indirect
github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd // indirect
github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792 // indirect

@ -92,16 +92,20 @@ github.com/breml/errchkjson v0.3.0 h1:YdDqhfqMT+I1vIxPSas44P+9Z9HzJwCeAzjB8PxP1x
github.com/breml/errchkjson v0.3.0/go.mod h1:9Cogkyv9gcT8HREpzi3TiqBxCqDzo8awa92zSDFcofU=
github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ=
github.com/btcsuite/btcd v0.22.0-beta.0.20220111032746-97732e52810c/go.mod h1:tjmYdS6MLJ5/s0Fj4DbLgSbDHbEqLJrtnHecBFkdz5M=
github.com/btcsuite/btcd v0.23.4 h1:IzV6qqkfwbItOS/sg/aDfPDsjPP8twrCOE2R93hxMlQ=
github.com/btcsuite/btcd v0.23.4/go.mod h1:0QJIIN1wwIXF/3G/m87gIwGniDMDQqjVn4SZgnFpsYY=
github.com/btcsuite/btcd v0.23.5-0.20231215221805-96c9fd8078fd/go.mod h1:nm3Bko6zh6bWP60UxwoT5LzdGJsQJaPo6HjduXq9p6A=
github.com/btcsuite/btcd v0.24.0 h1:gL3uHE/IaFj6fcZSu03SvqPMSx7s/dPzfpG/atRwWdo=
github.com/btcsuite/btcd v0.24.0/go.mod h1:K4IDc1593s8jKXIF7yS7yCTSxrknB9z0STzc2j6XgE4=
github.com/btcsuite/btcd/btcec/v2 v2.1.0/go.mod h1:2VzYrv4Gm4apmbVVsSq5bqf1Ec8v56E48Vt0Y/umPgA=
github.com/btcsuite/btcd/btcec/v2 v2.1.3 h1:xM/n3yIhHAhHy04z4i43C8p4ehixJZMsnrVJkgl+MTE=
github.com/btcsuite/btcd/btcec/v2 v2.1.3/go.mod h1:ctjw4H1kknNJmRN4iP1R7bTQ+v3GJkZBd6mui8ZsAZE=
github.com/btcsuite/btcd/btcutil v1.0.0/go.mod h1:Uoxwv0pqYWhD//tfTiipkxNfdhG9UrLwaeswfjfdF0A=
github.com/btcsuite/btcd/btcutil v1.1.0 h1:MO4klnGY+EWJdoWF12Wkuf4AWDBPMpZNeN/jRLrklUU=
github.com/btcsuite/btcd/btcutil v1.1.0/go.mod h1:5OapHB7A2hBBWLm48mmw4MOHNJCcUBTwmWH/0Jn8VHE=
github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1 h1:q0rUy8C/TYNBQS1+CGKw68tLOFYSNEs0TFnxxnS9+4U=
github.com/btcsuite/btcd/btcutil v1.1.5 h1:+wER79R5670vs/ZusMTF1yTcRYE5GUsFbdjdisflzM8=
github.com/btcsuite/btcd/btcutil v1.1.5/go.mod h1:PSZZ4UitpLBWzxGd5VGOrLnmOjtPP/a6HaFo12zMs00=
github.com/btcsuite/btcd/chaincfg/chainhash v1.0.0/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc=
github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc=
github.com/btcsuite/btcd/chaincfg/chainhash v1.1.0 h1:59Kx4K6lzOW5w6nFlA0v5+lk/6sjybR934QNHSJZPTQ=
github.com/btcsuite/btcd/chaincfg/chainhash v1.1.0/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc=
github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f h1:bAs4lUbRJpnnkd9VhRV3jjAVU7DJVjMaK+IsvSeZvFo=
github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA=
github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg=
@ -320,6 +324,7 @@ github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORR
github.com/gordonklaus/ineffassign v0.0.0-20230107090616-13ace0543b28 h1:9alfqbrhuD+9fLZ4iaAVwhlp5PEhmnBt7yvK2Oy5C1U=
github.com/gordonklaus/ineffassign v0.0.0-20230107090616-13ace0543b28/go.mod h1:Qcp2HIAYhR7mNUVSIxZww3Guk4it82ghYcEXIAk+QT0=
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/gostaticanalysis/analysisutil v0.0.3/go.mod h1:eEOZF4jCKGi+aprrirO9e7WKB3beBRtWgqGunKl6pKE=
github.com/gostaticanalysis/analysisutil v0.1.0/go.mod h1:dMhHRU9KTiDcuLGdy87/2gTR8WruwYZrKdRq9m1O6uw=
github.com/gostaticanalysis/analysisutil v0.7.1 h1:ZMCjoue3DtDWQ5WyU16YbjbQEQ3VuzwxALrpYd+HeKk=

Loading…
Cancel
Save