code.vegaprotocol.io/vega@v0.79.0/cmd/vegawallet/commands/key_generate.go (about) 1 // Copyright (C) 2023 Gobalsky Labs Limited 2 // 3 // This program is free software: you can redistribute it and/or modify 4 // it under the terms of the GNU Affero General Public License as 5 // published by the Free Software Foundation, either version 3 of the 6 // License, or (at your option) any later version. 7 // 8 // This program is distributed in the hope that it will be useful, 9 // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 // GNU Affero General Public License for more details. 12 // 13 // You should have received a copy of the GNU Affero General Public License 14 // along with this program. If not, see <http://www.gnu.org/licenses/>. 15 16 package cmd 17 18 import ( 19 "context" 20 "errors" 21 "fmt" 22 "io" 23 "os" 24 25 "code.vegaprotocol.io/vega/cmd/vegawallet/commands/cli" 26 "code.vegaprotocol.io/vega/cmd/vegawallet/commands/flags" 27 "code.vegaprotocol.io/vega/cmd/vegawallet/commands/printer" 28 "code.vegaprotocol.io/vega/wallet/api" 29 "code.vegaprotocol.io/vega/wallet/wallets" 30 31 "github.com/spf13/cobra" 32 ) 33 34 var ( 35 generateKeyLong = cli.LongDesc(` 36 Generate a new Ed25519 key pair in the specified wallet. 37 `) 38 39 generateKeyExample = cli.Examples(` 40 # Generate a key pair 41 {{.Software}} key generate --wallet WALLET 42 43 # Generate a key pair with additional metadata (name = my-wallet and type = validation) 44 {{.Software}} key generate --wallet WALLET --meta "name:my-wallet,type:validation" 45 46 # Generate a key pair with custom name 47 {{.Software}} key generate --wallet WALLET --meta "name:my-wallet" 48 `) 49 ) 50 51 type GenerateKeyHandler func(api.AdminGenerateKeyParams, string) (api.AdminGenerateKeyResult, error) 52 53 func NewCmdGenerateKey(w io.Writer, rf *RootFlags) *cobra.Command { 54 h := func(params api.AdminGenerateKeyParams, passphrase string) (api.AdminGenerateKeyResult, error) { 55 ctx := context.Background() 56 57 walletStore, err := wallets.InitialiseStore(rf.Home, false) 58 if err != nil { 59 return api.AdminGenerateKeyResult{}, fmt.Errorf("couldn't initialise wallets store: %w", err) 60 } 61 defer walletStore.Close() 62 63 if _, errDetails := api.NewAdminUnlockWallet(walletStore).Handle(ctx, api.AdminUnlockWalletParams{ 64 Wallet: params.Wallet, 65 Passphrase: passphrase, 66 }); errDetails != nil { 67 return api.AdminGenerateKeyResult{}, errors.New(errDetails.Data) 68 } 69 70 rawResult, errDetails := api.NewAdminGenerateKey(walletStore).Handle(ctx, params) 71 if errDetails != nil { 72 return api.AdminGenerateKeyResult{}, errors.New(errDetails.Data) 73 } 74 return rawResult.(api.AdminGenerateKeyResult), nil 75 } 76 77 return BuildCmdGenerateKey(w, h, rf) 78 } 79 80 func BuildCmdGenerateKey(w io.Writer, handler GenerateKeyHandler, rf *RootFlags) *cobra.Command { 81 f := &GenerateKeyFlags{} 82 83 cmd := &cobra.Command{ 84 Use: "generate", 85 Short: "Generate a new key pair in a given wallet", 86 Long: generateKeyLong, 87 Example: generateKeyExample, 88 RunE: func(_ *cobra.Command, _ []string) error { 89 req, pass, err := f.Validate() 90 if err != nil { 91 return err 92 } 93 94 resp, err := handler(req, pass) 95 if err != nil { 96 return err 97 } 98 99 switch rf.Output { 100 case flags.InteractiveOutput: 101 PrintGenerateKeyResponse(w, req, resp) 102 case flags.JSONOutput: 103 return printer.FprintJSON(w, resp) 104 } 105 106 return nil 107 }, 108 } 109 110 cmd.Flags().StringVarP(&f.Wallet, 111 "wallet", "w", 112 "", 113 "The wallet where the key is generated in", 114 ) 115 cmd.Flags().StringVarP(&f.PassphraseFile, 116 "passphrase-file", "p", 117 "", 118 "Path to the file containing the wallet's passphrase", 119 ) 120 cmd.Flags().StringSliceVarP(&f.RawMetadata, 121 "meta", "m", 122 []string{}, 123 `Metadata to add to the generated key-pair: "my-key1:my-value1,my-key2:my-value2"`, 124 ) 125 126 autoCompleteWallet(cmd, rf.Home, "wallet") 127 128 return cmd 129 } 130 131 type GenerateKeyFlags struct { 132 Wallet string 133 PassphraseFile string 134 RawMetadata []string 135 } 136 137 func (f *GenerateKeyFlags) Validate() (api.AdminGenerateKeyParams, string, error) { 138 req := api.AdminGenerateKeyParams{} 139 140 if len(f.Wallet) == 0 { 141 return api.AdminGenerateKeyParams{}, "", flags.MustBeSpecifiedError("wallet") 142 } 143 req.Wallet = f.Wallet 144 145 metadata, err := cli.ParseMetadata(f.RawMetadata) 146 if err != nil { 147 return api.AdminGenerateKeyParams{}, "", err 148 } 149 req.Metadata = metadata 150 151 passphrase, err := flags.GetPassphrase(f.PassphraseFile) 152 if err != nil { 153 return api.AdminGenerateKeyParams{}, "", err 154 } 155 156 return req, passphrase, nil 157 } 158 159 func PrintGenerateKeyResponse(w io.Writer, req api.AdminGenerateKeyParams, resp api.AdminGenerateKeyResult) { 160 p := printer.NewInteractivePrinter(w) 161 162 str := p.String() 163 defer p.Print(str) 164 165 str.CheckMark().Text("Key pair has been generated in wallet ").Bold(req.Wallet).NextLine() 166 str.CheckMark().SuccessText("Generating a key pair succeeded").NextSection() 167 str.Text("Public key:").NextLine() 168 str.WarningText(resp.PublicKey).NextLine() 169 str.Text("Metadata:").NextLine() 170 printMeta(str, resp.Metadata) 171 str.NextSection() 172 str.BlueArrow().InfoText("Run the service").NextLine() 173 str.Text("Now, you can run the service. See the following command:").NextSection() 174 str.Code(fmt.Sprintf("%s service run --help", os.Args[0])).NextLine() 175 }