Skip to content
This repository has been archived by the owner on Dec 12, 2023. It is now read-only.

add keys relative to home folder #118

Merged
merged 4 commits into from
Oct 17, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Fixed

- Pull plugin image if does not exist locally ([#101](https://github.com/NethermindEth/eigenlayer/pull/101))

- Updated keystore folder relative to user's HOME directory ([#118](https://github.com/NethermindEth/eigenlayer/pull/118))
## [v0.2.0] - 2023-10-10

### Added
Expand Down
43 changes: 24 additions & 19 deletions cli/operator/keys/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import (
)

const (
OperatorKeyFolder = "operator_keys"
OperatorKeystoreSubFolder = ".eigenlayer/operator_keys"

KeyTypeECDSA = "ecdsa"
KeyTypeBLS = "bls"
Expand Down Expand Up @@ -88,7 +88,6 @@ This command will create keys in ./operator_keys/ location
},
RunE: func(cmd *cobra.Command, args []string) error {
keyName := args[0]

switch keyType {
case KeyTypeECDSA:
privateKey, err := crypto.GenerateKey()
Expand All @@ -115,10 +114,13 @@ This command will create keys in ./operator_keys/ location
}

func saveBlsKey(keyName string, p prompter.Prompter, keyPair *bls.KeyPair, insecure bool) error {
// TODO: Path should be relative to user home dir https://github.com/NethermindEth/eigenlayer/issues/109
basePath, _ := os.Getwd()
homePath, err := os.UserHomeDir()
if err != nil {
return err
}
keyFileName := keyName + ".bls.key.json"
if checkIfKeyExists(keyFileName) {
fileLoc := filepath.Clean(filepath.Join(homePath, OperatorKeystoreSubFolder, keyFileName))
if checkIfKeyExists(fileLoc) {
return errors.New("key name already exists. Please choose a different name")
}
password, err := p.InputHiddenString("Enter password to encrypt the bls private key:", "",
Expand All @@ -133,7 +135,7 @@ func saveBlsKey(keyName string, p prompter.Prompter, keyPair *bls.KeyPair, insec
return err
}

err = keyPair.SaveToFile(OperatorKeyFolder+"/"+keyFileName, password)
err = keyPair.SaveToFile(fileLoc, password)
if err != nil {
return err
}
Expand All @@ -142,15 +144,18 @@ func saveBlsKey(keyName string, p prompter.Prompter, keyPair *bls.KeyPair, insec
fmt.Println("Please backup the above private key in safe place.")
fmt.Println()
fmt.Println("BLS Pub key: " + keyPair.PubKey.String())
fmt.Println("Key location: " + basePath + "/" + OperatorKeyFolder + "/" + keyFileName)
fmt.Println("Key location: " + fileLoc)
return nil
}

func saveEcdsaKey(keyName string, p prompter.Prompter, privateKey *ecdsa.PrivateKey, insecure bool) error {
// TODO: Path should be relative to user home dir https://github.com/NethermindEth/eigenlayer/issues/109
basePath, _ := os.Getwd()
homePath, err := os.UserHomeDir()
if err != nil {
return err
}
keyFileName := keyName + ".ecdsa.key.json"
if checkIfKeyExists(keyFileName) {
fileLoc := filepath.Clean(filepath.Join(homePath, OperatorKeystoreSubFolder, keyFileName))
if checkIfKeyExists(fileLoc) {
return errors.New("key name already exists. Please choose a different name")
}

Expand All @@ -166,7 +171,7 @@ func saveEcdsaKey(keyName string, p prompter.Prompter, privateKey *ecdsa.Private
return err
}

err = WriteEncryptedECDSAPrivateKeyToPath(keyFileName, privateKey, password)
err = WriteEncryptedECDSAPrivateKeyToPath(fileLoc, privateKey, password)
if err != nil {
return err
}
Expand All @@ -176,7 +181,7 @@ func saveEcdsaKey(keyName string, p prompter.Prompter, privateKey *ecdsa.Private
fmt.Println("ECDSA Private Key (Hex): ", privateKeyHex)
fmt.Println("Please backup the above private key hex in safe place.")
fmt.Println()
fmt.Println("Key location: " + basePath + "/" + OperatorKeyFolder + "/" + keyFileName)
fmt.Println("Key location: " + fileLoc)
publicKey := privateKey.Public()
publicKeyECDSA, ok := publicKey.(*ecdsa.PublicKey)
if !ok {
Expand All @@ -189,7 +194,7 @@ func saveEcdsaKey(keyName string, p prompter.Prompter, privateKey *ecdsa.Private
return nil
}

func WriteEncryptedECDSAPrivateKeyToPath(keyName string, privateKey *ecdsa.PrivateKey, password string) error {
func WriteEncryptedECDSAPrivateKeyToPath(fileLoc string, privateKey *ecdsa.PrivateKey, password string) error {
UUID, err := uuid.NewRandom()
if err != nil {
return err
Expand All @@ -205,15 +210,15 @@ func WriteEncryptedECDSAPrivateKeyToPath(keyName string, privateKey *ecdsa.Priva
return err
}

return writeBytesToFile(keyName, encryptedBytes)
return writeBytesToFile(fileLoc, encryptedBytes)
}

func writeBytesToFile(keyName string, data []byte) error {
err := os.Mkdir(OperatorKeyFolder, 0o755)
func writeBytesToFile(fileLoc string, data []byte) error {
err := os.MkdirAll(filepath.Dir(fileLoc), 0o755)
if err != nil && !os.IsExist(err) {
return err
}
file, err := os.Create(filepath.Clean(OperatorKeyFolder + "/" + keyName))
file, err := os.Create(fileLoc)
if err != nil {
fmt.Println("file create error")
return err
Expand All @@ -233,8 +238,8 @@ func writeBytesToFile(keyName string, data []byte) error {
return err
}

func checkIfKeyExists(keyName string) bool {
_, err := os.Stat(OperatorKeyFolder + "/" + keyName)
func checkIfKeyExists(fileLoc string) bool {
_, err := os.Stat(fileLoc)
return !os.IsNotExist(err)
}

Expand Down
12 changes: 9 additions & 3 deletions cli/operator/keys/create_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package keys
import (
"fmt"
"os"
"path/filepath"
"testing"

prompterMock "github.com/NethermindEth/eigenlayer/cli/prompter/mocks"
Expand All @@ -11,6 +12,11 @@ import (
)

func TestCreateCmd(t *testing.T) {
homePath, err := os.UserHomeDir()
if err != nil {
t.Fatal(err)
}

tests := []struct {
name string
args []string
Expand Down Expand Up @@ -66,7 +72,7 @@ func TestCreateCmd(t *testing.T) {
promptMock: func(p *prompterMock.MockPrompter) {
p.EXPECT().InputHiddenString(gomock.Any(), gomock.Any(), gomock.Any()).Return("", nil)
},
keyPath: OperatorKeyFolder + "/test.ecdsa.key.json",
keyPath: filepath.Join(homePath, OperatorKeystoreSubFolder, "/test.ecdsa.key.json"),
},
{
name: "valid bls key creation",
Expand All @@ -75,13 +81,13 @@ func TestCreateCmd(t *testing.T) {
promptMock: func(p *prompterMock.MockPrompter) {
p.EXPECT().InputHiddenString(gomock.Any(), gomock.Any(), gomock.Any()).Return("", nil)
},
keyPath: OperatorKeyFolder + "/test.bls.key.json",
keyPath: filepath.Join(homePath, OperatorKeystoreSubFolder, "/test.bls.key.json"),
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
t.Cleanup(func() {
_ = os.RemoveAll(OperatorKeyFolder)
_ = os.Remove(tt.keyPath)
})
controller := gomock.NewController(t)
p := prompterMock.NewMockPrompter(controller)
Expand Down
14 changes: 10 additions & 4 deletions cli/operator/keys/import_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"encoding/hex"
"fmt"
"os"
"path/filepath"
"strings"
"testing"

Expand All @@ -15,6 +16,11 @@ import (
)

func TestImportCmd(t *testing.T) {
homePath, err := os.UserHomeDir()
if err != nil {
t.Fatal(err)
}

tests := []struct {
name string
args []string
Expand Down Expand Up @@ -86,7 +92,7 @@ func TestImportCmd(t *testing.T) {
promptMock: func(p *prompterMock.MockPrompter) {
p.EXPECT().InputHiddenString(gomock.Any(), gomock.Any(), gomock.Any()).Return("", nil)
},
keyPath: OperatorKeyFolder + "/test.ecdsa.key.json",
keyPath: filepath.Join(homePath, OperatorKeystoreSubFolder, "/test.ecdsa.key.json"),
},
{
name: "valid ecdsa key import with 0x prefix",
Expand All @@ -95,7 +101,7 @@ func TestImportCmd(t *testing.T) {
promptMock: func(p *prompterMock.MockPrompter) {
p.EXPECT().InputHiddenString(gomock.Any(), gomock.Any(), gomock.Any()).Return("", nil)
},
keyPath: OperatorKeyFolder + "/test.ecdsa.key.json",
keyPath: filepath.Join(homePath, OperatorKeystoreSubFolder, "/test.ecdsa.key.json"),
},
{
name: "valid bls key import",
Expand All @@ -104,13 +110,13 @@ func TestImportCmd(t *testing.T) {
promptMock: func(p *prompterMock.MockPrompter) {
p.EXPECT().InputHiddenString(gomock.Any(), gomock.Any(), gomock.Any()).Return("", nil)
},
keyPath: OperatorKeyFolder + "/test.bls.key.json",
keyPath: filepath.Join(homePath, OperatorKeystoreSubFolder, "/test.bls.key.json"),
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
t.Cleanup(func() {
_ = os.RemoveAll(OperatorKeyFolder)
_ = os.Remove(tt.keyPath)
})
controller := gomock.NewController(t)
p := prompterMock.NewMockPrompter(controller)
Expand Down
20 changes: 13 additions & 7 deletions cli/operator/keys/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"encoding/json"
"fmt"
"os"
"path/filepath"
"strings"

"github.com/NethermindEth/eigenlayer/cli/prompter"
Expand All @@ -22,13 +23,16 @@ func ListCmd(p prompter.Prompter) *cobra.Command {
It will only list keys created in the default folder (./operator_keys/)
`,
RunE: func(cmd *cobra.Command, args []string) error {
files, err := os.ReadDir(OperatorKeyFolder + "/")
homePath, err := os.UserHomeDir()
if err != nil {
return err
}
keyStorePath := filepath.Clean(filepath.Join(homePath, OperatorKeystoreSubFolder))
files, err := os.ReadDir(keyStorePath)
if err != nil {
return err
}

// TODO: Path should be relative to user home dir https://github.com/NethermindEth/eigenlayer/issues/109
basePath, _ := os.Getwd()
for _, file := range files {
keySplits := strings.Split(file.Name(), ".")
fileName := keySplits[0]
Expand All @@ -37,22 +41,24 @@ func ListCmd(p prompter.Prompter) *cobra.Command {
switch keyType {
case KeyTypeECDSA:
fmt.Println("Key Type: ECDSA")
address, err := GetAddress(OperatorKeyFolder + "/" + file.Name())
keyFilePath := filepath.Join(keyStorePath, file.Name())
address, err := GetAddress(filepath.Clean(keyFilePath))
if err != nil {
return err
}
fmt.Println("Address: 0x" + address)
fmt.Println("Key location: " + basePath + "/" + OperatorKeyFolder + "/" + file.Name())
fmt.Println("Key location: " + keyFilePath)
fmt.Println("====================================================================================")
fmt.Println()
case KeyTypeBLS:
fmt.Println("Key Type: BLS")
pubKey, err := GetPubKey(OperatorKeyFolder + "/" + file.Name())
keyFilePath := filepath.Join(keyStorePath, file.Name())
pubKey, err := GetPubKey(filepath.Clean(keyFilePath))
if err != nil {
return err
}
fmt.Println("Public Key: " + pubKey)
fmt.Println("Key location: " + basePath + "/" + OperatorKeyFolder + "/" + file.Name())
fmt.Println("Key location: " + keyFilePath)
fmt.Println("====================================================================================")
fmt.Println()
}
Expand Down