consolidate: refactor prompt related code
This commit is contained in:
parent
dc7f1e88eb
commit
3aca0be46a
6 changed files with 23 additions and 61 deletions
|
@ -31,6 +31,7 @@ const (
|
||||||
defaultLogFilename = "lbcwallet.log"
|
defaultLogFilename = "lbcwallet.log"
|
||||||
defaultRPCMaxClients = 10
|
defaultRPCMaxClients = 10
|
||||||
defaultRPCMaxWebsockets = 25
|
defaultRPCMaxWebsockets = 25
|
||||||
|
defaultPassphrase = "password"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -56,8 +57,8 @@ type config struct {
|
||||||
Profile string `long:"profile" description:"Enable HTTP profiling on given port -- NOTE port must be between 1024 and 65536"`
|
Profile string `long:"profile" description:"Enable HTTP profiling on given port -- NOTE port must be between 1024 and 65536"`
|
||||||
DBTimeout time.Duration `long:"dbtimeout" description:"The timeout value to use when opening the wallet database."`
|
DBTimeout time.Duration `long:"dbtimeout" description:"The timeout value to use when opening the wallet database."`
|
||||||
|
|
||||||
// Wallet options
|
// Passphrase options
|
||||||
WalletPass string `long:"walletpass" default-mask:"-" description:"The public wallet password -- Only required if the wallet was created with one"`
|
Passphrase string `short:"p" long:"passphrase" default-mask:"-" description:"The wallet passphrase (default: \"insecurepassphrase\")"`
|
||||||
|
|
||||||
// RPC client options
|
// RPC client options
|
||||||
RPCConnect string `short:"c" long:"rpcconnect" description:"Hostname/IP and port of lbcd RPC server to connect to (default localhost:9245, testnet: localhost:19245, regtest: localhost:29245)"`
|
RPCConnect string `short:"c" long:"rpcconnect" description:"Hostname/IP and port of lbcd RPC server to connect to (default localhost:9245, testnet: localhost:19245, regtest: localhost:29245)"`
|
||||||
|
@ -242,6 +243,7 @@ func loadConfig() (*config, []string, error) {
|
||||||
LegacyRPCMaxWebsockets: defaultRPCMaxWebsockets,
|
LegacyRPCMaxWebsockets: defaultRPCMaxWebsockets,
|
||||||
DataDir: cfgutil.NewExplicitString(defaultAppDataDir),
|
DataDir: cfgutil.NewExplicitString(defaultAppDataDir),
|
||||||
DBTimeout: wallet.DefaultDBTimeout,
|
DBTimeout: wallet.DefaultDBTimeout,
|
||||||
|
Passphrase: defaultPassphrase,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pre-parse the command line options to see if an alternative config
|
// Pre-parse the command line options to see if an alternative config
|
||||||
|
|
|
@ -21,14 +21,7 @@ import (
|
||||||
"golang.org/x/crypto/ssh/terminal"
|
"golang.org/x/crypto/ssh/terminal"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ProvideSeed is used to prompt for the wallet seed which maybe required during
|
func promptSeed(reader *bufio.Reader) ([]byte, error) {
|
||||||
// upgrades.
|
|
||||||
func ProvideSeed() func() ([]byte, error) {
|
|
||||||
return func() ([]byte, error) {
|
|
||||||
return provideSeed(bufio.NewReader(os.Stdin))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
func provideSeed(reader *bufio.Reader) ([]byte, error) {
|
|
||||||
for {
|
for {
|
||||||
fmt.Print("Enter existing wallet seed: ")
|
fmt.Print("Enter existing wallet seed: ")
|
||||||
seedStr, err := reader.ReadString('\n')
|
seedStr, err := reader.ReadString('\n')
|
||||||
|
@ -52,26 +45,6 @@ func provideSeed(reader *bufio.Reader) ([]byte, error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ProvidePassphrase is used to prompt for the passphrase which maybe required
|
|
||||||
// during upgrades.
|
|
||||||
func ProvidePassphrase() ([]byte, error) {
|
|
||||||
prompt := "Enter the passphrase of your wallet: "
|
|
||||||
for {
|
|
||||||
fmt.Print(prompt)
|
|
||||||
pass, err := terminal.ReadPassword(int(os.Stdin.Fd()))
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
fmt.Print("\n")
|
|
||||||
pass = bytes.TrimSpace(pass)
|
|
||||||
if len(pass) == 0 {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
return pass, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// promptList prompts the user with the given prefix, list of valid responses,
|
// promptList prompts the user with the given prefix, list of valid responses,
|
||||||
// and default list entry to use. The function will repeat the prompt to the
|
// and default list entry to use. The function will repeat the prompt to the
|
||||||
// user until they enter a valid response.
|
// user until they enter a valid response.
|
||||||
|
@ -150,7 +123,12 @@ func promptUnixTimestamp(reader *bufio.Reader, prefix string,
|
||||||
// promptPassphrase prompts the user for a passphrase with the given prefix.
|
// promptPassphrase prompts the user for a passphrase with the given prefix.
|
||||||
// The function will ask the user to confirm the passphrase and will repeat
|
// The function will ask the user to confirm the passphrase and will repeat
|
||||||
// the prompts until they enter a matching response.
|
// the prompts until they enter a matching response.
|
||||||
func promptPassphrase(_ *bufio.Reader, prefix string, confirm bool) ([]byte, error) {
|
func promptPassphrase(prefix string, confirm bool) ([]byte, error) {
|
||||||
|
pass := os.Getenv("LBCWALLET_PASSPHRASE")
|
||||||
|
if len(pass) > 0 {
|
||||||
|
return []byte(pass), nil
|
||||||
|
}
|
||||||
|
|
||||||
// Prompt the user until they enter a passphrase.
|
// Prompt the user until they enter a passphrase.
|
||||||
prompt := fmt.Sprintf("%s: ", prefix)
|
prompt := fmt.Sprintf("%s: ", prefix)
|
||||||
for {
|
for {
|
||||||
|
@ -193,9 +171,9 @@ func birthday(reader *bufio.Reader) (time.Time, error) {
|
||||||
|
|
||||||
// Passphrase prompts the user for a passphrase.
|
// Passphrase prompts the user for a passphrase.
|
||||||
// All prompts are repeated until the user enters a valid response.
|
// All prompts are repeated until the user enters a valid response.
|
||||||
func Passphrase(reader *bufio.Reader) ([]byte, error) {
|
func Passphrase(confirm bool) ([]byte, error) {
|
||||||
return promptPassphrase(reader, "Enter the passphrase "+
|
return promptPassphrase("Enter the passphrase "+
|
||||||
"for your new wallet", true)
|
"for your new wallet", confirm)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Seed prompts the user whether they want to use an existing wallet generation
|
// Seed prompts the user whether they want to use an existing wallet generation
|
||||||
|
@ -239,7 +217,7 @@ func Seed(reader *bufio.Reader) ([]byte, time.Time, error) {
|
||||||
return seed, bday, nil
|
return seed, bday, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
seed, err := provideSeed(reader)
|
seed, err := promptSeed(reader)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, bday, err
|
return nil, bday, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -87,7 +87,7 @@ func walletMain() error {
|
||||||
startWalletRPCServices(w, legacyRPCServer)
|
startWalletRPCServices(w, legacyRPCServer)
|
||||||
})
|
})
|
||||||
|
|
||||||
_, err = loader.OpenExistingWallet(true)
|
_, err = loader.OpenExistingWallet()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error(err)
|
log.Error(err)
|
||||||
return err
|
return err
|
||||||
|
|
|
@ -14,8 +14,6 @@ import (
|
||||||
|
|
||||||
"github.com/lbryio/lbcd/chaincfg"
|
"github.com/lbryio/lbcd/chaincfg"
|
||||||
"github.com/lbryio/lbcutil/hdkeychain"
|
"github.com/lbryio/lbcutil/hdkeychain"
|
||||||
"github.com/lbryio/lbcwallet/internal/prompt"
|
|
||||||
"github.com/lbryio/lbcwallet/waddrmgr"
|
|
||||||
"github.com/lbryio/lbcwallet/walletdb"
|
"github.com/lbryio/lbcwallet/walletdb"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -224,7 +222,7 @@ func (l *Loader) createNewWallet(passphrase []byte,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Open the newly-created wallet.
|
// Open the newly-created wallet.
|
||||||
w, err := Open(l.db, nil, l.chainParams, l.recoveryWindow)
|
w, err := Open(l.db, l.chainParams, l.recoveryWindow)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -236,14 +234,10 @@ func (l *Loader) createNewWallet(passphrase []byte,
|
||||||
|
|
||||||
var errNoConsole = errors.New("db upgrade requires console access for additional input")
|
var errNoConsole = errors.New("db upgrade requires console access for additional input")
|
||||||
|
|
||||||
func noConsole() ([]byte, error) {
|
|
||||||
return nil, errNoConsole
|
|
||||||
}
|
|
||||||
|
|
||||||
// OpenExistingWallet opens the wallet from the loader's wallet database path.
|
// OpenExistingWallet opens the wallet from the loader's wallet database path.
|
||||||
// If the loader is being called by a context where standard input prompts may
|
// If the loader is being called by a context where standard input prompts may
|
||||||
// be used during wallet upgrades, setting canConsolePrompt will enables these prompts.
|
// be used during wallet upgrades, setting canConsolePrompt will enables these prompts.
|
||||||
func (l *Loader) OpenExistingWallet(canConsolePrompt bool) (*Wallet, error) {
|
func (l *Loader) OpenExistingWallet() (*Wallet, error) {
|
||||||
defer l.mu.Unlock()
|
defer l.mu.Unlock()
|
||||||
l.mu.Lock()
|
l.mu.Lock()
|
||||||
|
|
||||||
|
@ -269,19 +263,7 @@ func (l *Loader) OpenExistingWallet(canConsolePrompt bool) (*Wallet, error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var cbs *waddrmgr.OpenCallbacks
|
w, err := Open(l.db, l.chainParams, l.recoveryWindow)
|
||||||
if canConsolePrompt {
|
|
||||||
cbs = &waddrmgr.OpenCallbacks{
|
|
||||||
ObtainSeed: prompt.ProvideSeed(),
|
|
||||||
ObtainPassphrase: prompt.ProvidePassphrase,
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
cbs = &waddrmgr.OpenCallbacks{
|
|
||||||
ObtainSeed: noConsole,
|
|
||||||
ObtainPassphrase: noConsole,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
w, err := Open(l.db, cbs, l.chainParams, l.recoveryWindow)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// If opening the wallet fails (e.g. because of wrong
|
// If opening the wallet fails (e.g. because of wrong
|
||||||
// passphrase), we must close the backing database to
|
// passphrase), we must close the backing database to
|
||||||
|
|
|
@ -689,7 +689,7 @@ func (w *Wallet) recovery(chainClient chain.Interface,
|
||||||
// that a wallet rescan will be performed from the wallet's tip, which
|
// that a wallet rescan will be performed from the wallet's tip, which
|
||||||
// will be of bestHeight after completing the recovery process.
|
// will be of bestHeight after completing the recovery process.
|
||||||
|
|
||||||
pass, err := prompt.ProvidePassphrase()
|
pass, err := prompt.Passphrase(false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -3664,8 +3664,8 @@ func create(db walletdb.DB, privPass []byte, rootKey *hdkeychain.ExtendedKey,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Open loads an already-created wallet from the passed database and namespaces.
|
// Open loads an already-created wallet from the passed database and namespaces.
|
||||||
func Open(db walletdb.DB, cbs *waddrmgr.OpenCallbacks,
|
func Open(db walletdb.DB, params *chaincfg.Params, recoveryWindow uint32) (
|
||||||
params *chaincfg.Params, recoveryWindow uint32) (*Wallet, error) {
|
*Wallet, error) {
|
||||||
|
|
||||||
var (
|
var (
|
||||||
addrMgr *waddrmgr.Manager
|
addrMgr *waddrmgr.Manager
|
||||||
|
|
|
@ -47,7 +47,7 @@ func createWallet(cfg *config) error {
|
||||||
|
|
||||||
// Start by prompting for the passphrase.
|
// Start by prompting for the passphrase.
|
||||||
reader := bufio.NewReader(os.Stdin)
|
reader := bufio.NewReader(os.Stdin)
|
||||||
privPass, err := prompt.Passphrase(reader)
|
privPass, err := prompt.Passphrase(true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue