diff --git a/btc/summary.go b/btc/summary.go index 17638c6..622b357 100644 --- a/btc/summary.go +++ b/btc/summary.go @@ -7,13 +7,12 @@ import ( "github.com/lightninglabs/chantools/dataformat" ) -func SummarizeChannels(apiURL string, channels []*dataformat.SummaryEntry, +func SummarizeChannels(api *ExplorerAPI, channels []*dataformat.SummaryEntry, log btclog.Logger) (*dataformat.SummaryEntryFile, error) { summaryFile := &dataformat.SummaryEntryFile{ Channels: channels, } - api := &ExplorerAPI{BaseURL: apiURL} for idx, channel := range channels { tx, err := api.Transaction(channel.FundingTXID) diff --git a/cmd/chantools/closepoolaccount.go b/cmd/chantools/closepoolaccount.go index dc85a28..fa8cf0a 100644 --- a/cmd/chantools/closepoolaccount.go +++ b/cmd/chantools/closepoolaccount.go @@ -10,7 +10,6 @@ import ( "github.com/btcsuite/btcd/btcutil/hdkeychain" "github.com/btcsuite/btcd/txscript" "github.com/btcsuite/btcd/wire" - "github.com/lightninglabs/chantools/btc" "github.com/lightninglabs/chantools/lnd" "github.com/lightninglabs/pool/account" "github.com/lightninglabs/pool/poolscript" @@ -165,7 +164,7 @@ func closePoolAccount(extendedKey *hdkeychain.ExtendedKey, apiURL string, ExtendedKey: extendedKey, ChainParams: chainParams, } - api := &btc.ExplorerAPI{BaseURL: apiURL} + api := newExplorerAPI(apiURL) tx, err := api.Transaction(outpoint.Hash.String()) if err != nil { diff --git a/cmd/chantools/doublespendinputs.go b/cmd/chantools/doublespendinputs.go index a7ea4e1..ece5d1c 100644 --- a/cmd/chantools/doublespendinputs.go +++ b/cmd/chantools/doublespendinputs.go @@ -13,7 +13,6 @@ import ( "github.com/btcsuite/btcd/txscript" "github.com/btcsuite/btcd/wire" "github.com/decred/dcrd/dcrec/secp256k1/v4" - "github.com/lightninglabs/chantools/btc" "github.com/lightninglabs/chantools/lnd" "github.com/lightningnetwork/lnd/input" "github.com/lightningnetwork/lnd/lnwallet/chainfee" @@ -93,7 +92,7 @@ func (c *doubleSpendInputs) Execute(_ *cobra.Command, _ []string) error { return fmt.Errorf("inputoutpoints are required") } - api := &btc.ExplorerAPI{BaseURL: c.APIURL} + api := newExplorerAPI(c.APIURL) addresses := make([]btcutil.Address, 0, len(c.InputOutpoints)) outpoints := make([]*wire.OutPoint, 0, len(c.InputOutpoints)) diff --git a/cmd/chantools/forceclose.go b/cmd/chantools/forceclose.go index 90ea393..f6362aa 100644 --- a/cmd/chantools/forceclose.go +++ b/cmd/chantools/forceclose.go @@ -11,7 +11,6 @@ import ( "github.com/btcsuite/btcd/btcutil/hdkeychain" "github.com/btcsuite/btcd/txscript" - "github.com/lightninglabs/chantools/btc" "github.com/lightninglabs/chantools/dataformat" "github.com/lightninglabs/chantools/lnd" "github.com/lightningnetwork/lnd/channeldb" @@ -105,7 +104,7 @@ func forceCloseChannels(apiURL string, extendedKey *hdkeychain.ExtendedKey, if err != nil { return err } - api := &btc.ExplorerAPI{BaseURL: apiURL} + api := newExplorerAPI(apiURL) signer := &lnd.Signer{ ExtendedKey: extendedKey, ChainParams: chainParams, diff --git a/cmd/chantools/pullanchor.go b/cmd/chantools/pullanchor.go index 7a4f890..ed438ba 100644 --- a/cmd/chantools/pullanchor.go +++ b/cmd/chantools/pullanchor.go @@ -132,7 +132,7 @@ func createPullTransactionTemplate(rootKey *hdkeychain.ExtendedKey, ExtendedKey: rootKey, ChainParams: chainParams, } - api := &btc.ExplorerAPI{BaseURL: apiURL} + api := newExplorerAPI(apiURL) estimator := input.TxWeightEstimator{} // Make sure the sponsor input is a P2WPKH or P2TR input and is known diff --git a/cmd/chantools/recoverloopin.go b/cmd/chantools/recoverloopin.go index 52330c3..21654ce 100644 --- a/cmd/chantools/recoverloopin.go +++ b/cmd/chantools/recoverloopin.go @@ -9,7 +9,6 @@ import ( "github.com/btcsuite/btcd/chaincfg/chainhash" "github.com/btcsuite/btcd/txscript" "github.com/btcsuite/btcd/wire" - "github.com/lightninglabs/chantools/btc" "github.com/lightninglabs/chantools/lnd" "github.com/lightninglabs/loop" "github.com/lightninglabs/loop/loopdb" @@ -121,7 +120,7 @@ func (c *recoverLoopInCommand) Execute(_ *cobra.Command, _ []string) error { return fmt.Errorf("sweep_addr is required") } - api := &btc.ExplorerAPI{BaseURL: c.APIURL} + api := newExplorerAPI(c.APIURL) signer := &lnd.Signer{ ExtendedKey: extendedKey, diff --git a/cmd/chantools/rescuefunding.go b/cmd/chantools/rescuefunding.go index 9e4e4cd..cc59219 100644 --- a/cmd/chantools/rescuefunding.go +++ b/cmd/chantools/rescuefunding.go @@ -9,7 +9,6 @@ import ( "github.com/btcsuite/btcd/btcutil" "github.com/btcsuite/btcd/btcutil/psbt" "github.com/btcsuite/btcd/wire" - "github.com/lightninglabs/chantools/btc" "github.com/lightninglabs/chantools/lnd" "github.com/lightningnetwork/lnd/input" "github.com/lightningnetwork/lnd/keychain" @@ -255,7 +254,7 @@ func rescueFunding(localKeyDesc *keychain.KeyDescriptor, } // Locate the output in the funding TX. - api := &btc.ExplorerAPI{BaseURL: apiURL} + api := newExplorerAPI(apiURL) tx, err := api.Transaction(chainPoint.Hash.String()) if err != nil { return fmt.Errorf("error fetching UTXO info for outpoint %s: "+ diff --git a/cmd/chantools/root.go b/cmd/chantools/root.go index 13a04f7..c8aaf6f 100644 --- a/cmd/chantools/root.go +++ b/cmd/chantools/root.go @@ -26,7 +26,9 @@ import ( ) const ( - defaultAPIURL = "https://blockstream.info/api" + defaultAPIURL = "https://blockstream.info/api" + defaultTestnetAPIURL = "https://blockstream.info/testnet/api" + defaultRegtestAPIURL = "http://localhost:3004" // version is the current version of the tool. It is set during build. // NOTE: When changing this, please also update the version in the @@ -56,7 +58,8 @@ var rootCmd = &cobra.Command{ Short: "Chantools helps recover funds from lightning channels", Long: `This tool provides helper functions that can be used rescue funds locked in lnd channels in case lnd itself cannot run properly anymore. -Complete documentation is available at https://github.com/lightninglabs/chantools/.`, +Complete documentation is available at +https://github.com/lightninglabs/chantools/.`, Version: fmt.Sprintf("v%s, commit %s", version, Commit), PersistentPreRun: func(cmd *cobra.Command, args []string) { switch { @@ -326,3 +329,22 @@ func setSubLogger(subsystem string, logger btclog.Logger, func noConsole() ([]byte, error) { return nil, fmt.Errorf("wallet db requires console access") } + +func newExplorerAPI(apiURL string) *btc.ExplorerAPI { + // Override for testnet if default is used. + if apiURL == defaultAPIURL && + chainParams.Name == chaincfg.TestNet3Params.Name { + + return &btc.ExplorerAPI{BaseURL: defaultTestnetAPIURL} + } + + // Also override for regtest if default is used. + if apiURL == defaultAPIURL && + chainParams.Name == chaincfg.RegressionNetParams.Name { + + return &btc.ExplorerAPI{BaseURL: defaultRegtestAPIURL} + } + + // Otherwise use the provided URL. + return &btc.ExplorerAPI{BaseURL: apiURL} +} diff --git a/cmd/chantools/summary.go b/cmd/chantools/summary.go index c1b9e3d..2544975 100644 --- a/cmd/chantools/summary.go +++ b/cmd/chantools/summary.go @@ -53,7 +53,8 @@ func (c *summaryCommand) Execute(_ *cobra.Command, _ []string) error { func summarizeChannels(apiURL string, channels []*dataformat.SummaryEntry) error { - summaryFile, err := btc.SummarizeChannels(apiURL, channels, log) + api := newExplorerAPI(apiURL) + summaryFile, err := btc.SummarizeChannels(api, channels, log) if err != nil { return fmt.Errorf("error running summary: %w", err) } diff --git a/cmd/chantools/sweepremoteclosed.go b/cmd/chantools/sweepremoteclosed.go index 5ec63f4..6ed9227 100644 --- a/cmd/chantools/sweepremoteclosed.go +++ b/cmd/chantools/sweepremoteclosed.go @@ -129,7 +129,7 @@ func sweepRemoteClosed(extendedKey *hdkeychain.ExtendedKey, apiURL, var ( targets []*targetAddr - api = &btc.ExplorerAPI{BaseURL: apiURL} + api = newExplorerAPI(apiURL) ) for index := uint32(0); index < recoveryWindow; index++ { path := fmt.Sprintf("m/1017'/%d'/%d'/0/%d", diff --git a/cmd/chantools/sweeptimelock.go b/cmd/chantools/sweeptimelock.go index 8a1c98d..a1ce477 100644 --- a/cmd/chantools/sweeptimelock.go +++ b/cmd/chantools/sweeptimelock.go @@ -10,7 +10,6 @@ import ( "github.com/btcsuite/btcd/chaincfg/chainhash" "github.com/btcsuite/btcd/txscript" "github.com/btcsuite/btcd/wire" - "github.com/lightninglabs/chantools/btc" "github.com/lightninglabs/chantools/dataformat" "github.com/lightninglabs/chantools/lnd" "github.com/lightningnetwork/lnd/input" @@ -220,7 +219,7 @@ func sweepTimeLock(extendedKey *hdkeychain.ExtendedKey, apiURL string, ExtendedKey: extendedKey, ChainParams: chainParams, } - api := &btc.ExplorerAPI{BaseURL: apiURL} + api := newExplorerAPI(apiURL) var ( sweepTx = wire.NewMsgTx(2) diff --git a/cmd/chantools/sweeptimelockmanual.go b/cmd/chantools/sweeptimelockmanual.go index ab64e1d..04cde72 100644 --- a/cmd/chantools/sweeptimelockmanual.go +++ b/cmd/chantools/sweeptimelockmanual.go @@ -10,7 +10,6 @@ import ( "github.com/btcsuite/btcd/chaincfg/chainhash" "github.com/btcsuite/btcd/txscript" "github.com/btcsuite/btcd/wire" - "github.com/lightninglabs/chantools/btc" "github.com/lightninglabs/chantools/lnd" "github.com/lightningnetwork/lnd/input" "github.com/lightningnetwork/lnd/keychain" @@ -298,7 +297,7 @@ func sweepTimeLockManual(extendedKey *hdkeychain.ExtendedKey, apiURL string, ExtendedKey: extendedKey, ChainParams: chainParams, } - api := &btc.ExplorerAPI{BaseURL: apiURL} + api := newExplorerAPI(apiURL) // We now know everything we need to construct the sweep transaction, // except for what outpoint to sweep. We'll ask the chain API to give diff --git a/cmd/chantools/triggerforceclose.go b/cmd/chantools/triggerforceclose.go index 2a33316..382a61e 100644 --- a/cmd/chantools/triggerforceclose.go +++ b/cmd/chantools/triggerforceclose.go @@ -10,7 +10,6 @@ import ( "github.com/btcsuite/btcd/chaincfg/chainhash" "github.com/btcsuite/btcd/connmgr" "github.com/btcsuite/btcd/wire" - "github.com/lightninglabs/chantools/btc" "github.com/lightninglabs/chantools/lnd" "github.com/lightningnetwork/lnd/brontide" "github.com/lightningnetwork/lnd/keychain" @@ -152,7 +151,7 @@ func (c *triggerForceCloseCommand) Execute(_ *cobra.Command, _ []string) error { log.Infof("Message sent, waiting for force close transaction to " + "appear in mempool") - api := &btc.ExplorerAPI{BaseURL: c.APIURL} + api := newExplorerAPI(c.APIURL) channelAddress, err := api.Address(c.ChannelPoint) if err != nil { return fmt.Errorf("error getting channel address: %w", err) diff --git a/cmd/chantools/zombierecovery_findmatches.go b/cmd/chantools/zombierecovery_findmatches.go index 50cb849..0b33ffd 100644 --- a/cmd/chantools/zombierecovery_findmatches.go +++ b/cmd/chantools/zombierecovery_findmatches.go @@ -14,7 +14,6 @@ import ( "github.com/btcsuite/btcd/btcec/v2" "github.com/hasura/go-graphql-client" - "github.com/lightninglabs/chantools/btc" "github.com/spf13/cobra" "golang.org/x/oauth2" ) @@ -188,7 +187,7 @@ func (c *zombieRecoveryFindMatchesCommand) Execute(_ *cobra.Command, log.Infof("%s: %s", groups[1], groups[2]) } - api := &btc.ExplorerAPI{BaseURL: c.APIURL} + api := newExplorerAPI(c.APIURL) src := oauth2.StaticTokenSource(&oauth2.Token{AccessToken: c.AmbossKey}) httpClient := oauth2.NewClient(context.Background(), src) client := graphql.NewClient(