github.com/prysmaticlabs/prysm@v1.4.4/validator/accounts/prompt/prompt.go (about)

     1  package prompt
     2  
     3  import (
     4  	"fmt"
     5  	"os"
     6  	"strings"
     7  
     8  	"github.com/logrusorgru/aurora"
     9  	"github.com/manifoldco/promptui"
    10  	"github.com/pkg/errors"
    11  	"github.com/prysmaticlabs/prysm/cmd/validator/flags"
    12  	"github.com/prysmaticlabs/prysm/shared/fileutil"
    13  	"github.com/prysmaticlabs/prysm/shared/promptutil"
    14  	"github.com/prysmaticlabs/prysm/validator/keymanager/remote"
    15  	"github.com/urfave/cli/v2"
    16  )
    17  
    18  const (
    19  	// ImportKeysDirPromptText for the import keys cli function.
    20  	ImportKeysDirPromptText = "Enter the directory or filepath where your keystores to import are located"
    21  	// DataDirDirPromptText for the validator database directory.
    22  	DataDirDirPromptText = "Enter the directory of the validator database you would like to use"
    23  	// SlashingProtectionJSONPromptText for the EIP-3076 slashing protection JSON prompt.
    24  	SlashingProtectionJSONPromptText = "Enter the the filepath of your EIP-3076 Slashing Protection JSON from your previously used validator client"
    25  	// WalletDirPromptText for the wallet.
    26  	WalletDirPromptText = "Enter a wallet directory"
    27  	// SelectAccountsDeletePromptText --
    28  	SelectAccountsDeletePromptText = "Select the account(s) you would like to delete"
    29  	// SelectAccountsBackupPromptText --
    30  	SelectAccountsBackupPromptText = "Select the account(s) you wish to backup"
    31  	// SelectAccountsVoluntaryExitPromptText --
    32  	SelectAccountsVoluntaryExitPromptText = "Select the account(s) on which you wish to perform a voluntary exit"
    33  )
    34  
    35  var au = aurora.NewAurora(true)
    36  
    37  // InputDirectory from the cli.
    38  func InputDirectory(cliCtx *cli.Context, promptText string, flag *cli.StringFlag) (string, error) {
    39  	directory := cliCtx.String(flag.Name)
    40  	if cliCtx.IsSet(flag.Name) {
    41  		return fileutil.ExpandPath(directory)
    42  	}
    43  	// Append and log the appropriate directory name depending on the flag used.
    44  	if flag.Name == flags.WalletDirFlag.Name {
    45  		ok, err := fileutil.HasDir(directory)
    46  		if err != nil {
    47  			return "", errors.Wrapf(err, "could not check if wallet dir %s exists", directory)
    48  		}
    49  		if ok {
    50  			log.Infof("%s %s", au.BrightMagenta("(wallet path)"), directory)
    51  			return directory, nil
    52  		}
    53  	}
    54  
    55  	inputtedDir, err := promptutil.DefaultPrompt(au.Bold(promptText).String(), directory)
    56  	if err != nil {
    57  		return "", err
    58  	}
    59  	if inputtedDir == directory {
    60  		return directory, nil
    61  	}
    62  	return fileutil.ExpandPath(inputtedDir)
    63  }
    64  
    65  // InputRemoteKeymanagerConfig via the cli.
    66  func InputRemoteKeymanagerConfig(cliCtx *cli.Context) (*remote.KeymanagerOpts, error) {
    67  	addr := cliCtx.String(flags.GrpcRemoteAddressFlag.Name)
    68  	requireTls := !cliCtx.Bool(flags.DisableRemoteSignerTlsFlag.Name)
    69  	crt := cliCtx.String(flags.RemoteSignerCertPathFlag.Name)
    70  	key := cliCtx.String(flags.RemoteSignerKeyPathFlag.Name)
    71  	ca := cliCtx.String(flags.RemoteSignerCACertPathFlag.Name)
    72  	log.Info("Input desired configuration")
    73  	var err error
    74  	if addr == "" {
    75  		addr, err = promptutil.ValidatePrompt(
    76  			os.Stdin,
    77  			"Remote gRPC address (such as host.example.com:4000)",
    78  			promptutil.NotEmpty)
    79  		if err != nil {
    80  			return nil, err
    81  		}
    82  	}
    83  	if requireTls && crt == "" {
    84  		crt, err = promptutil.ValidatePrompt(
    85  			os.Stdin,
    86  			"Path to TLS crt (such as /path/to/client.crt)",
    87  			validateCertPath)
    88  		if err != nil {
    89  			return nil, err
    90  		}
    91  	}
    92  	if requireTls && key == "" {
    93  		key, err = promptutil.ValidatePrompt(
    94  			os.Stdin,
    95  			"Path to TLS key (such as /path/to/client.key)",
    96  			validateCertPath)
    97  		if err != nil {
    98  			return nil, err
    99  		}
   100  	}
   101  	if requireTls && ca == "" {
   102  		ca, err = promptutil.ValidatePrompt(
   103  			os.Stdin,
   104  			"Path to certificate authority (CA) crt (such as /path/to/ca.crt)",
   105  			validateCertPath)
   106  		if err != nil {
   107  			return nil, err
   108  		}
   109  	}
   110  
   111  	crtPath, keyPath, caPath := "", "", ""
   112  	if crt != "" {
   113  		crtPath, err = fileutil.ExpandPath(strings.TrimRight(crt, "\r\n"))
   114  		if err != nil {
   115  			return nil, errors.Wrapf(err, "could not determine absolute path for %s", crt)
   116  		}
   117  	}
   118  	if key != "" {
   119  		keyPath, err = fileutil.ExpandPath(strings.TrimRight(key, "\r\n"))
   120  		if err != nil {
   121  			return nil, errors.Wrapf(err, "could not determine absolute path for %s", crt)
   122  		}
   123  	}
   124  	if ca != "" {
   125  		caPath, err = fileutil.ExpandPath(strings.TrimRight(ca, "\r\n"))
   126  		if err != nil {
   127  			return nil, errors.Wrapf(err, "could not determine absolute path for %s", crt)
   128  		}
   129  	}
   130  
   131  	newCfg := &remote.KeymanagerOpts{
   132  		RemoteCertificate: &remote.CertificateConfig{
   133  			RequireTls:     requireTls,
   134  			ClientCertPath: crtPath,
   135  			ClientKeyPath:  keyPath,
   136  			CACertPath:     caPath,
   137  		},
   138  		RemoteAddr: addr,
   139  	}
   140  	fmt.Printf("%s\n", newCfg)
   141  	return newCfg, nil
   142  }
   143  
   144  func validateCertPath(input string) error {
   145  	if input == "" {
   146  		return errors.New("crt path cannot be empty")
   147  	}
   148  	if !promptutil.IsValidUnicode(input) {
   149  		return errors.New("not valid unicode")
   150  	}
   151  	if !fileutil.FileExists(input) {
   152  		return fmt.Errorf("no crt found at path: %s", input)
   153  	}
   154  	return nil
   155  }
   156  
   157  // FormatPromptError for the user.
   158  func FormatPromptError(err error) error {
   159  	switch err {
   160  	case promptui.ErrAbort:
   161  		return errors.New("wallet creation aborted, closing")
   162  	case promptui.ErrInterrupt:
   163  		return errors.New("keyboard interrupt, closing")
   164  	case promptui.ErrEOF:
   165  		return errors.New("no input received, closing")
   166  	default:
   167  		return err
   168  	}
   169  }