From 0e26a39f6f72307d198d7727025d20f227e5e3eb Mon Sep 17 00:00:00 2001 From: Jack Zampolin Date: Tue, 8 Jan 2019 08:49:03 -0800 Subject: [PATCH] Support adding offline pubkeys to gaiacli keys (#3224) --- PENDING.md | 1 + client/keys/add.go | 23 ++++++++++++++++++----- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/PENDING.md b/PENDING.md index a49d8771fc..8be9469675 100644 --- a/PENDING.md +++ b/PENDING.md @@ -60,6 +60,7 @@ IMPROVEMENTS * [\#2948](https://github.com/cosmos/cosmos-sdk/issues/2948) Swagger UI now makes requests to light client node * Gaia CLI (`gaiacli`) + * [\#3224](https://github.com/cosmos/cosmos-sdk/pull/3224) Support adding offline public keys to the keystore * Gaia * [\#2186](https://github.com/cosmos/cosmos-sdk/issues/2186) Add Address Interface diff --git a/client/keys/add.go b/client/keys/add.go index 8c2f666d83..2a0890fbe6 100644 --- a/client/keys/add.go +++ b/client/keys/add.go @@ -18,9 +18,11 @@ import ( ccrypto "github.com/cosmos/cosmos-sdk/crypto" "github.com/cosmos/cosmos-sdk/crypto/keys" "github.com/cosmos/cosmos-sdk/crypto/keys/hd" + sdk "github.com/cosmos/cosmos-sdk/types" ) const ( + flagPublicKey = "pubkey" flagInteractive = "interactive" flagBIP44Path = "bip44-path" flagRecover = "recover" @@ -36,16 +38,18 @@ func addKeyCommand() *cobra.Command { Short: "Add an encrypted private key (either newly generated or recovered), encrypt it, and save to disk", Long: `Derive a new private key and encrypt to disk. Optionally specify a BIP39 mnemonic, a BIP39 passphrase to further secure the mnemonic, -and a bip32 HD path to derive a specific account. The key will be stored under the given name +and a bip32 HD path to derive a specific account. The key will be stored under the given name and encrypted with the given password. The only input that is required is the encryption password. If run with -i, it will prompt the user for BIP44 path, BIP39 mnemonic, and passphrase. The flag --recover allows one to recover a key from a seed passphrase. If run with --dry-run, a key would be generated (or recovered) but not stored to the local keystore. +Use the --pubkey flag to add arbitrary public keys to the keystore for constructing multisig transactions. `, Args: cobra.ExactArgs(1), RunE: runAddCmd, } + cmd.Flags().String(FlagPublicKey, "", "Store only a public key (useful for constructing multisigs e.g. cosmospub1...)") cmd.Flags().BoolP(flagInteractive, "i", false, "Interactively prompt user for BIP39 passphrase and mnemonic") cmd.Flags().Bool(client.FlagUseLedger, false, "Store a local reference to a private key on a Ledger device") cmd.Flags().String(flagBIP44Path, "44'/118'/0'/0/0", "BIP44 path from which to derive a private key") @@ -73,6 +77,9 @@ func runAddCmd(cmd *cobra.Command, args []string) error { buf := client.BufferStdin() name := args[0] + + interactive := viper.GetBool(flagInteractive) + if viper.GetBool(flagDryRun) { // we throw this away, so don't enforce args, // we want to get a new random seed phrase quickly @@ -94,7 +101,7 @@ func runAddCmd(cmd *cobra.Command, args []string) error { } // ask for a password when generating a local key - if !viper.GetBool(client.FlagUseLedger) { + if viper.GetString(flagPublicKey) == "" && !viper.GetBool(client.FlagUseLedger) { encryptPassword, err = client.GetCheckPassword( "Enter a passphrase to encrypt your key to disk:", "Repeat the passphrase:", buf) @@ -104,10 +111,16 @@ func runAddCmd(cmd *cobra.Command, args []string) error { } } - interactive := viper.GetBool(flagInteractive) - flags := cmd.Flags() - bipFlag := flags.Lookup(flagBIP44Path) + if viper.GetString(flagPublicKey) != "" { + pk, err := sdk.GetAccPubKeyBech32(viper.GetString(flagPublicKey)) + if err != nil { + return err + } + kb.CreateOffline(name, pk) + return nil + } + bipFlag := cmd.Flags().Lookup(flagBIP44Path) bip44Params, err := getBIP44ParamsAndPath(bipFlag.Value.String(), bipFlag.Changed || !interactive) if err != nil { return err