-
Notifications
You must be signed in to change notification settings - Fork 109
/
account.go
192 lines (163 loc) · 5.4 KB
/
account.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
// Copyright 2023 ChainSafe Systems (ON)
// SPDX-License-Identifier: LGPL-3.0-only
package commands
import (
"fmt"
"github.com/ChainSafe/gossamer/lib/crypto"
"github.com/ChainSafe/gossamer/lib/keystore"
"github.com/ChainSafe/gossamer/lib/utils"
"github.com/spf13/cobra"
)
func init() {
AccountCmd.Flags().String("keystore-path", "", "path to keystore")
AccountCmd.Flags().String("keystore-file", "", "name of keystore file to import")
AccountCmd.Flags().String("password", "", "password used to encrypt the keystore. Used with --generate or --unlock")
AccountCmd.Flags().String("scheme", crypto.Sr25519Type, "keyring scheme (sr25519, ed25519, secp256k1)")
}
// AccountCmd is the command to manage the gossamer keystore
var AccountCmd = &cobra.Command{
Use: "account",
Short: "Create and manage node keystore accounts",
Long: `The account command is used to manage the gossamer keystore.
Examples:
To generate a new ed25519 account:
gossamer account generate --keystore-path=path/to/location --scheme=ed25519
To generate a new secp256k1 account:
gossamer account generate --keystore-path=path/to/location --scheme secp256k1
To import a keystore file:
gossamer account import --keystore-path=path/to/location --keystore-file=keystore.json
To import a raw key:
gossamer account import-raw --keystore-path=path/to/location --keystore-file=keystore.json
To list keys: gossamer account list --keystore-path=path/to/location`,
RunE: func(cmd *cobra.Command, args []string) error {
if len(args) == 0 {
logger.Errorf("account command cannot be empty")
return cmd.Help()
}
switch args[0] {
case "generate":
if err := generateKeyPair(cmd); err != nil {
return err
}
case "import":
if err := importKey(cmd); err != nil {
return err
}
case "import-raw":
if err := importRawKey(cmd); err != nil {
return err
}
case "list":
if err := listKeys(cmd); err != nil {
return err
}
default:
logger.Errorf("invalid account command: %s", args[0])
return fmt.Errorf("invalid account command: %s", args[0])
}
return nil
},
}
// generateKeyPair generates a new keypair and saves it to the keystore
func generateKeyPair(cmd *cobra.Command) error {
keystorePath, err := cmd.Flags().GetString("keystore-path")
if err != nil {
return fmt.Errorf("failed to get keystore-path: %s", err)
}
if keystorePath == "" {
return fmt.Errorf("keystore-path cannot be empty")
}
scheme, err := cmd.Flags().GetString("scheme")
if err != nil {
return fmt.Errorf("failed to get scheme: %s", err)
}
if !(scheme == crypto.Ed25519Type || scheme == crypto.Sr25519Type || scheme == crypto.Secp256k1Type) {
return fmt.Errorf("invalid scheme: %s", scheme)
}
password, err := cmd.Flags().GetString("password")
if err != nil {
return fmt.Errorf("failed to get password: %s", err)
}
logger.Info("Generating keypair")
file, err := keystore.GenerateKeypair(scheme, nil, keystorePath, []byte(password))
if err != nil {
logger.Errorf("failed to generate keypair: %s", err)
return err
}
logger.Infof("keypair generated and saved to %s", file)
return nil
}
// importKey imports a keypair from a keystore file into the keystore
func importKey(cmd *cobra.Command) error {
keystorePath, err := cmd.Flags().GetString("keystore-path")
if err != nil {
return fmt.Errorf("failed to get keystore-path: %s", err)
}
if keystorePath == "" {
return fmt.Errorf("keystore-path cannot be empty")
}
keystoreFile, err := cmd.Flags().GetString("keystore-file")
if err != nil {
return fmt.Errorf("failed to get keystore-file: %s", err)
}
if keystoreFile == "" {
return fmt.Errorf("keystore-file cannot be empty")
}
_, err = keystore.ImportKeypair(keystoreFile, keystorePath)
if err != nil {
logger.Errorf("failed to import keypair: %s", err)
return err
}
return nil
}
// importRawKey imports a raw keypair into the keystore
func importRawKey(cmd *cobra.Command) error {
keystorePath, err := cmd.Flags().GetString("keystore-path")
if err != nil {
return fmt.Errorf("failed to get keystore-path: %s", err)
}
if keystorePath == "" {
return fmt.Errorf("keystore-path cannot be empty")
}
keystoreFile, err := cmd.Flags().GetString("keystore-file")
if err != nil {
return fmt.Errorf("failed to get keystore-file: %s", err)
}
if keystoreFile == "" {
return fmt.Errorf("keystore-file cannot be empty")
}
scheme, err := cmd.Flags().GetString("scheme")
if err != nil {
return fmt.Errorf("failed to get scheme: %s", err)
}
if !(scheme == crypto.Ed25519Type || scheme == crypto.Sr25519Type || scheme == crypto.Secp256k1Type) {
return fmt.Errorf("invalid scheme: %s", scheme)
}
password, err := cmd.Flags().GetString("password")
if err != nil {
return fmt.Errorf("failed to get password: %s", err)
}
file, err := keystore.ImportRawPrivateKey(keystoreFile, scheme, keystorePath, []byte(password))
if err != nil {
logger.Errorf("failed to import private key: %s", err)
return err
}
logger.Info("imported private key and saved it to " + file)
return nil
}
// listKeys lists the keys in the keystore
func listKeys(cmd *cobra.Command) error {
keystorePath, err := cmd.Flags().GetString("keystore-path")
if err != nil {
return fmt.Errorf("failed to get keystore-path: %s", err)
}
if keystorePath == "" {
return fmt.Errorf("keystore-path cannot be empty")
}
_, err = utils.KeystoreFilepaths(keystorePath)
if err != nil {
logger.Errorf("failed to list keys: %s", err)
return err
}
return nil
}