github.com/prysmaticlabs/prysm@v1.4.4/validator/accounts/accounts_list.go (about) 1 package accounts 2 3 import ( 4 "context" 5 "fmt" 6 "math" 7 "path/filepath" 8 "strings" 9 10 "github.com/logrusorgru/aurora" 11 "github.com/pkg/errors" 12 "github.com/prysmaticlabs/prysm/cmd/validator/flags" 13 ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1" 14 "github.com/prysmaticlabs/prysm/shared/petnames" 15 "github.com/prysmaticlabs/prysm/validator/accounts/iface" 16 "github.com/prysmaticlabs/prysm/validator/accounts/wallet" 17 "github.com/prysmaticlabs/prysm/validator/keymanager" 18 "github.com/prysmaticlabs/prysm/validator/keymanager/derived" 19 "github.com/prysmaticlabs/prysm/validator/keymanager/imported" 20 "github.com/prysmaticlabs/prysm/validator/keymanager/remote" 21 "github.com/urfave/cli/v2" 22 ) 23 24 // ListAccountsCli displays all available validator accounts in a Prysm wallet. 25 func ListAccountsCli(cliCtx *cli.Context) error { 26 w, err := wallet.OpenWalletOrElseCli(cliCtx, func(cliCtx *cli.Context) (*wallet.Wallet, error) { 27 return nil, wallet.ErrNoWalletFound 28 }) 29 if err != nil { 30 return errors.Wrap(err, "could not open wallet") 31 } 32 km, err := w.InitializeKeymanager(cliCtx.Context, iface.InitKeymanagerConfig{ListenForChanges: false}) 33 if err != nil && strings.Contains(err.Error(), "invalid checksum") { 34 return errors.New("wrong wallet password entered") 35 } 36 if err != nil { 37 return errors.Wrap(err, ErrCouldNotInitializeKeymanager) 38 } 39 showDepositData := cliCtx.Bool(flags.ShowDepositDataFlag.Name) 40 showPrivateKeys := cliCtx.Bool(flags.ShowPrivateKeysFlag.Name) 41 listIndices := cliCtx.Bool(flags.ListValidatorIndices.Name) 42 43 if listIndices { 44 client, _, err := prepareClients(cliCtx) 45 if err != nil { 46 return err 47 } 48 return listValidatorIndices(cliCtx.Context, km, *client) 49 } 50 51 switch w.KeymanagerKind() { 52 case keymanager.Imported: 53 km, ok := km.(*imported.Keymanager) 54 if !ok { 55 return errors.New("could not assert keymanager interface to concrete type") 56 } 57 if err := listImportedKeymanagerAccounts(cliCtx.Context, showDepositData, showPrivateKeys, km); err != nil { 58 return errors.Wrap(err, "could not list validator accounts with imported keymanager") 59 } 60 case keymanager.Derived: 61 km, ok := km.(*derived.Keymanager) 62 if !ok { 63 return errors.New("could not assert keymanager interface to concrete type") 64 } 65 if err := listDerivedKeymanagerAccounts(cliCtx.Context, showPrivateKeys, km); err != nil { 66 return errors.Wrap(err, "could not list validator accounts with derived keymanager") 67 } 68 case keymanager.Remote: 69 km, ok := km.(*remote.Keymanager) 70 if !ok { 71 return errors.New("could not assert keymanager interface to concrete type") 72 } 73 if err := listRemoteKeymanagerAccounts(cliCtx.Context, w, km, km.KeymanagerOpts()); err != nil { 74 return errors.Wrap(err, "could not list validator accounts with remote keymanager") 75 } 76 default: 77 return fmt.Errorf(errKeymanagerNotSupported, w.KeymanagerKind().String()) 78 } 79 return nil 80 } 81 82 func listImportedKeymanagerAccounts( 83 ctx context.Context, 84 showDepositData, 85 showPrivateKeys bool, 86 keymanager *imported.Keymanager, 87 ) error { 88 // We initialize the wallet's keymanager. 89 accountNames, err := keymanager.ValidatingAccountNames() 90 if err != nil { 91 return errors.Wrap(err, "could not fetch account names") 92 } 93 numAccounts := au.BrightYellow(len(accountNames)) 94 fmt.Printf("(keymanager kind) %s\n", au.BrightGreen("imported wallet").Bold()) 95 fmt.Println("") 96 if len(accountNames) == 1 { 97 fmt.Printf("Showing %d validator account\n", numAccounts) 98 } else { 99 fmt.Printf("Showing %d validator accounts\n", numAccounts) 100 } 101 fmt.Println( 102 au.BrightRed("View the eth1 deposit transaction data for your accounts " + 103 "by running `validator accounts list --show-deposit-data`"), 104 ) 105 106 pubKeys, err := keymanager.FetchValidatingPublicKeys(ctx) 107 if err != nil { 108 return errors.Wrap(err, "could not fetch validating public keys") 109 } 110 var privateKeys [][32]byte 111 if showPrivateKeys { 112 privateKeys, err = keymanager.FetchValidatingPrivateKeys(ctx) 113 if err != nil { 114 return errors.Wrap(err, "could not fetch private keys") 115 } 116 } 117 for i := 0; i < len(accountNames); i++ { 118 fmt.Println("") 119 fmt.Printf("%s | %s\n", au.BrightBlue(fmt.Sprintf("Account %d", i)).Bold(), au.BrightGreen(accountNames[i]).Bold()) 120 fmt.Printf("%s %#x\n", au.BrightMagenta("[validating public key]").Bold(), pubKeys[i]) 121 if showPrivateKeys { 122 if len(privateKeys) > i { 123 fmt.Printf("%s %#x\n", au.BrightRed("[validating private key]").Bold(), privateKeys[i]) 124 } 125 } 126 if !showDepositData { 127 continue 128 } 129 fmt.Printf( 130 "%s\n", 131 au.BrightRed("If you imported your account coming from the eth2 launchpad, you will find your "+ 132 "deposit_data.json in the eth2.0-deposit-cli's validator_keys folder"), 133 ) 134 fmt.Println("") 135 } 136 fmt.Println("") 137 return nil 138 } 139 140 func listDerivedKeymanagerAccounts( 141 ctx context.Context, 142 showPrivateKeys bool, 143 keymanager *derived.Keymanager, 144 ) error { 145 au := aurora.NewAurora(true) 146 fmt.Printf("(keymanager kind) %s\n", au.BrightGreen("derived, (HD) hierarchical-deterministic").Bold()) 147 fmt.Printf("(derivation format) %s\n", au.BrightGreen(derived.DerivationPathFormat).Bold()) 148 validatingPubKeys, err := keymanager.FetchValidatingPublicKeys(ctx) 149 if err != nil { 150 return errors.Wrap(err, "could not fetch validating public keys") 151 } 152 var validatingPrivateKeys [][32]byte 153 if showPrivateKeys { 154 validatingPrivateKeys, err = keymanager.FetchValidatingPrivateKeys(ctx) 155 if err != nil { 156 return errors.Wrap(err, "could not fetch validating private keys") 157 } 158 } 159 accountNames, err := keymanager.ValidatingAccountNames(ctx) 160 if err != nil { 161 return err 162 } 163 if len(accountNames) == 1 { 164 fmt.Print("Showing 1 validator account\n") 165 } else if len(accountNames) == 0 { 166 fmt.Print("No accounts found\n") 167 return nil 168 } else { 169 fmt.Printf("Showing %d validator accounts\n", len(accountNames)) 170 } 171 for i := 0; i < len(accountNames); i++ { 172 fmt.Println("") 173 validatingKeyPath := fmt.Sprintf(derived.ValidatingKeyDerivationPathTemplate, i) 174 175 // Retrieve the withdrawal key account metadata. 176 fmt.Printf("%s | %s\n", au.BrightBlue(fmt.Sprintf("Account %d", i)).Bold(), au.BrightGreen(accountNames[i]).Bold()) 177 // Retrieve the validating key account metadata. 178 fmt.Printf("%s %#x\n", au.BrightCyan("[validating public key]").Bold(), validatingPubKeys[i]) 179 if showPrivateKeys && validatingPrivateKeys != nil { 180 fmt.Printf("%s %#x\n", au.BrightRed("[validating private key]").Bold(), validatingPrivateKeys[i]) 181 } 182 fmt.Printf("%s %s\n", au.BrightCyan("[derivation path]").Bold(), validatingKeyPath) 183 fmt.Println(" ") 184 } 185 return nil 186 } 187 188 func listRemoteKeymanagerAccounts( 189 ctx context.Context, 190 w *wallet.Wallet, 191 keymanager keymanager.IKeymanager, 192 opts *remote.KeymanagerOpts, 193 ) error { 194 au := aurora.NewAurora(true) 195 fmt.Printf("(keymanager kind) %s\n", au.BrightGreen("remote signer").Bold()) 196 fmt.Printf( 197 "(configuration file path) %s\n", 198 au.BrightGreen(filepath.Join(w.AccountsDir(), wallet.KeymanagerConfigFileName)).Bold(), 199 ) 200 fmt.Println(" ") 201 fmt.Printf("%s\n", au.BrightGreen("Configuration options").Bold()) 202 fmt.Println(opts) 203 validatingPubKeys, err := keymanager.FetchValidatingPublicKeys(ctx) 204 if err != nil { 205 return errors.Wrap(err, "could not fetch validating public keys") 206 } 207 if len(validatingPubKeys) == 1 { 208 fmt.Print("Showing 1 validator account\n") 209 } else if len(validatingPubKeys) == 0 { 210 fmt.Print("No accounts found\n") 211 return nil 212 } else { 213 fmt.Printf("Showing %d validator accounts\n", len(validatingPubKeys)) 214 } 215 for i := 0; i < len(validatingPubKeys); i++ { 216 fmt.Println("") 217 fmt.Printf( 218 "%s\n", au.BrightGreen(petnames.DeterministicName(validatingPubKeys[i][:], "-")).Bold(), 219 ) 220 // Retrieve the validating key account metadata. 221 fmt.Printf("%s %#x\n", au.BrightCyan("[validating public key]").Bold(), validatingPubKeys[i]) 222 fmt.Println(" ") 223 } 224 return nil 225 } 226 227 func listValidatorIndices(ctx context.Context, km keymanager.IKeymanager, client ethpb.BeaconNodeValidatorClient) error { 228 pubKeys, err := km.FetchValidatingPublicKeys(ctx) 229 if err != nil { 230 return errors.Wrap(err, "could not get validating public keys") 231 } 232 var pks [][]byte 233 for i := range pubKeys { 234 pks = append(pks, pubKeys[i][:]) 235 } 236 req := ðpb.MultipleValidatorStatusRequest{PublicKeys: pks} 237 resp, err := client.MultipleValidatorStatus(ctx, req) 238 if err != nil { 239 return errors.Wrap(err, "could not request validator indices") 240 } 241 fmt.Println(au.BrightGreen("Validator indices:").Bold()) 242 for i, idx := range resp.Indices { 243 if idx != math.MaxUint64 { 244 fmt.Printf("%#x: %d\n", pubKeys[i][0:4], idx) 245 } 246 } 247 return nil 248 }