mirror of https://github.com/guggero/chantools
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
82 lines
2.4 KiB
Go
82 lines
2.4 KiB
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"github.com/btcsuite/btcutil"
|
|
"github.com/btcsuite/btcutil/hdkeychain"
|
|
"github.com/guggero/chantools/btc"
|
|
"github.com/guggero/chantools/lnd"
|
|
)
|
|
|
|
type deriveKeyCommand struct {
|
|
BIP39 bool `long:"bip39" description:"Read a classic BIP39 seed and passphrase from the terminal instead of asking for the lnd seed format or providing the --rootkey flag."`
|
|
RootKey string `long:"rootkey" description:"BIP32 HD root key to derive the key from."`
|
|
Path string `long:"path" description:"The BIP32 derivation path to derive. Must start with \"m/\"."`
|
|
Neuter bool `long:"neuter" description:"Do not output the private key, just the public key."`
|
|
}
|
|
|
|
func (c *deriveKeyCommand) Execute(_ []string) error {
|
|
setupChainParams(cfg)
|
|
|
|
var (
|
|
extendedKey *hdkeychain.ExtendedKey
|
|
err error
|
|
)
|
|
|
|
// Check that root key is valid or fall back to terminal input.
|
|
switch {
|
|
case c.BIP39:
|
|
extendedKey, err = btc.ReadMnemonicFromTerminal(chainParams)
|
|
|
|
case c.RootKey != "":
|
|
extendedKey, err = hdkeychain.NewKeyFromString(c.RootKey)
|
|
|
|
default:
|
|
extendedKey, _, err = lnd.ReadAezeed(chainParams)
|
|
}
|
|
if err != nil {
|
|
return fmt.Errorf("error reading root key: %v", err)
|
|
}
|
|
|
|
return deriveKey(extendedKey, c.Path, c.Neuter)
|
|
}
|
|
|
|
func deriveKey(extendedKey *hdkeychain.ExtendedKey, path string,
|
|
neuter bool) error {
|
|
|
|
fmt.Printf("Deriving path %s for network %s.\n", path, chainParams.Name)
|
|
child, pubKey, wif, err := lnd.DeriveKey(extendedKey, path, chainParams)
|
|
if err != nil {
|
|
return fmt.Errorf("could not derive keys: %v", err)
|
|
}
|
|
neutered, err := child.Neuter()
|
|
if err != nil {
|
|
return fmt.Errorf("could not neuter child key: %v", err)
|
|
}
|
|
fmt.Printf("\nPublic key: %x\n", pubKey.SerializeCompressed())
|
|
fmt.Printf("Extended public key (xpub): %s\n", neutered.String())
|
|
|
|
// Print the address too.
|
|
hash160 := btcutil.Hash160(pubKey.SerializeCompressed())
|
|
addrP2PKH, err := btcutil.NewAddressPubKeyHash(hash160, chainParams)
|
|
if err != nil {
|
|
return fmt.Errorf("could not create address: %v", err)
|
|
}
|
|
addrP2WKH, err := btcutil.NewAddressWitnessPubKeyHash(
|
|
hash160, chainParams,
|
|
)
|
|
if err != nil {
|
|
return fmt.Errorf("could not create address: %v", err)
|
|
}
|
|
fmt.Printf("Address: %s\n", addrP2WKH)
|
|
fmt.Printf("Legacy address: %s\n", addrP2PKH)
|
|
|
|
if !neuter {
|
|
fmt.Printf("\nPrivate key (WIF): %s\n", wif.String())
|
|
fmt.Printf("Extended private key (xprv): %s\n", child.String())
|
|
}
|
|
|
|
return nil
|
|
}
|