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 }