From 33e6aadfbbd48850ece5cbedebf362c519fbb91f Mon Sep 17 00:00:00 2001 From: j75689 Date: Thu, 2 Nov 2023 16:31:23 +0800 Subject: [PATCH 1/4] feat: support eip712 private keys import --- client/keys/import.go | 64 +++++++++++++++++++++++++++++++-------- crypto/keyring/keyring.go | 8 +++++ 2 files changed, 60 insertions(+), 12 deletions(-) diff --git a/client/keys/import.go b/client/keys/import.go index a9d5c185ac..eb04161bba 100644 --- a/client/keys/import.go +++ b/client/keys/import.go @@ -2,39 +2,79 @@ package keys import ( "bufio" + "encoding/hex" + "fmt" "os" "github.com/spf13/cobra" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/input" + "github.com/cosmos/cosmos-sdk/crypto/hd" + "github.com/cosmos/cosmos-sdk/crypto/keys/eth/ethsecp256k1" +) + +const ( + flagEIP712PrivateKey = "eip712-private-key" ) // ImportKeyCommand imports private keys from a keyfile. func ImportKeyCommand() *cobra.Command { - return &cobra.Command{ - Use: "import ", + cmd := &cobra.Command{ + Use: "import /", Short: "Import private keys into the local keybase", - Long: "Import a ASCII armored private key into the local keybase.", + Long: "Import a ASCII armored/EIP-712 private key into the local keybase.", Args: cobra.ExactArgs(2), RunE: func(cmd *cobra.Command, args []string) error { clientCtx, err := client.GetClientQueryContext(cmd) if err != nil { return err } - buf := bufio.NewReader(clientCtx.Input) - bz, err := os.ReadFile(args[1]) - if err != nil { - return err - } + isEIP712, _ := cmd.Flags().GetBool(flagEIP712PrivateKey) - passphrase, err := input.GetPassword("Enter passphrase to decrypt your key:", buf) - if err != nil { - return err + if !isEIP712 { + return importASCIIArmored(clientCtx, args) } - return clientCtx.Keyring.ImportPrivKey(args[0], string(bz), passphrase) + return importEIP712(clientCtx, args) }, } + + cmd.Flags().Bool(flagEIP712PrivateKey, false, "import EIP-712 format private key") + + return cmd +} + +func importASCIIArmored(clientCtx client.Context, args []string) error { + buf := bufio.NewReader(clientCtx.Input) + + bz, err := os.ReadFile(args[1]) + if err != nil { + return err + } + + passphrase, err := input.GetPassword("Enter passphrase to decrypt your key:", buf) + if err != nil { + return err + } + + return clientCtx.Keyring.ImportPrivKey(args[0], string(bz), passphrase) +} + +func importEIP712(clientCtx client.Context, args []string) error { + keyName := args[0] + keyBytes, err := hex.DecodeString(args[1]) + if err != nil { + return err + } + if len(keyBytes) != 32 { + return fmt.Errorf("len of keybytes is not equal to 32") + } + var keyBytesArray [32]byte + copy(keyBytesArray[:], keyBytes[:32]) + privKey := hd.EthSecp256k1.Generate()(keyBytesArray[:]).(*ethsecp256k1.PrivKey) + + clientCtx.Keyring.WriteLocalKey(keyName, privKey) + return nil } diff --git a/crypto/keyring/keyring.go b/crypto/keyring/keyring.go index 7e02b7f8d6..7b22b64d1b 100644 --- a/crypto/keyring/keyring.go +++ b/crypto/keyring/keyring.go @@ -116,6 +116,9 @@ type Importer interface { // ImportPubKey imports ASCII armored public keys. ImportPubKey(uid string, armor string) error + + // WriteLocalKey persists a private key object into storage. + WriteLocalKey(name string, privKey types.PrivKey) (*Record, error) } // Migrator is implemented by key stores and enables migration of keys from amino to proto @@ -757,6 +760,11 @@ func newRealPrompt(dir string, buf io.Reader) func(string) (string, error) { } } +// WriteLocalKey persists a local key to the keyring. +func (ks keystore) WriteLocalKey(name string, privKey types.PrivKey) (*Record, error) { + return ks.writeLocalKey(name, privKey) +} + func (ks keystore) writeLocalKey(name string, privKey types.PrivKey) (*Record, error) { k, err := NewLocalRecord(name, privKey, privKey.PubKey()) if err != nil { From c2097f96bdd115de2d1b38baf86cf70f54c3bcc0 Mon Sep 17 00:00:00 2001 From: j75689 Date: Thu, 2 Nov 2023 16:51:23 +0800 Subject: [PATCH 2/4] fix: rename --- client/keys/import.go | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/client/keys/import.go b/client/keys/import.go index eb04161bba..8416810952 100644 --- a/client/keys/import.go +++ b/client/keys/import.go @@ -15,7 +15,7 @@ import ( ) const ( - flagEIP712PrivateKey = "eip712-private-key" + flagSecp256k1PrivateKey = "secp256k1-private-key" ) // ImportKeyCommand imports private keys from a keyfile. @@ -23,7 +23,7 @@ func ImportKeyCommand() *cobra.Command { cmd := &cobra.Command{ Use: "import /", Short: "Import private keys into the local keybase", - Long: "Import a ASCII armored/EIP-712 private key into the local keybase.", + Long: "Import a ASCII armored/Secp256k1 private key into the local keybase.", Args: cobra.ExactArgs(2), RunE: func(cmd *cobra.Command, args []string) error { clientCtx, err := client.GetClientQueryContext(cmd) @@ -31,17 +31,17 @@ func ImportKeyCommand() *cobra.Command { return err } - isEIP712, _ := cmd.Flags().GetBool(flagEIP712PrivateKey) + isSecp256k1, _ := cmd.Flags().GetBool(flagSecp256k1PrivateKey) - if !isEIP712 { + if !isSecp256k1 { return importASCIIArmored(clientCtx, args) } - return importEIP712(clientCtx, args) + return importSecp256k1(clientCtx, args) }, } - cmd.Flags().Bool(flagEIP712PrivateKey, false, "import EIP-712 format private key") + cmd.Flags().Bool(flagSecp256k1PrivateKey, false, "import Secp256k1 format private key") return cmd } @@ -62,7 +62,7 @@ func importASCIIArmored(clientCtx client.Context, args []string) error { return clientCtx.Keyring.ImportPrivKey(args[0], string(bz), passphrase) } -func importEIP712(clientCtx client.Context, args []string) error { +func importSecp256k1(clientCtx client.Context, args []string) error { keyName := args[0] keyBytes, err := hex.DecodeString(args[1]) if err != nil { From a7960dcf851cada31dcf633482d35367832c88b4 Mon Sep 17 00:00:00 2001 From: j75689 Date: Thu, 2 Nov 2023 16:57:14 +0800 Subject: [PATCH 3/4] fix: typo --- client/keys/import.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/keys/import.go b/client/keys/import.go index 8416810952..b12fa2ef4e 100644 --- a/client/keys/import.go +++ b/client/keys/import.go @@ -21,7 +21,7 @@ const ( // ImportKeyCommand imports private keys from a keyfile. func ImportKeyCommand() *cobra.Command { cmd := &cobra.Command{ - Use: "import /", + Use: "import /", Short: "Import private keys into the local keybase", Long: "Import a ASCII armored/Secp256k1 private key into the local keybase.", Args: cobra.ExactArgs(2), From 025f41db2c082e8c9ffde38bda85057a867284d0 Mon Sep 17 00:00:00 2001 From: j75689 Date: Thu, 2 Nov 2023 17:29:05 +0800 Subject: [PATCH 4/4] fix: handle error --- client/keys/import.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/client/keys/import.go b/client/keys/import.go index b12fa2ef4e..ab4e3c4058 100644 --- a/client/keys/import.go +++ b/client/keys/import.go @@ -75,6 +75,9 @@ func importSecp256k1(clientCtx client.Context, args []string) error { copy(keyBytesArray[:], keyBytes[:32]) privKey := hd.EthSecp256k1.Generate()(keyBytesArray[:]).(*ethsecp256k1.PrivKey) - clientCtx.Keyring.WriteLocalKey(keyName, privKey) + _, err = clientCtx.Keyring.WriteLocalKey(keyName, privKey) + if err != nil { + return err + } return nil }