code.vegaprotocol.io/vega@v0.79.0/cmd/vegawallet/commands/key_describe.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  
    24  	"code.vegaprotocol.io/vega/cmd/vegawallet/commands/cli"
    25  	"code.vegaprotocol.io/vega/cmd/vegawallet/commands/flags"
    26  	"code.vegaprotocol.io/vega/cmd/vegawallet/commands/printer"
    27  	"code.vegaprotocol.io/vega/wallet/api"
    28  	"code.vegaprotocol.io/vega/wallet/wallets"
    29  
    30  	"github.com/spf13/cobra"
    31  )
    32  
    33  var (
    34  	describeKeyLong = cli.LongDesc(`
    35  		Describe all known information about the specified key pair
    36  	`)
    37  
    38  	describeKeyExample = cli.Examples(`
    39  		# Describe a key
    40  		{{.Software}} key describe --wallet WALLET --pubkey PUBLIC_KEY
    41  	`)
    42  )
    43  
    44  type DescribeKeyHandler func(api.AdminDescribeKeyParams, string) (api.AdminDescribeKeyResult, error)
    45  
    46  func NewCmdDescribeKey(w io.Writer, rf *RootFlags) *cobra.Command {
    47  	h := func(params api.AdminDescribeKeyParams, passphrase string) (api.AdminDescribeKeyResult, error) {
    48  		ctx := context.Background()
    49  
    50  		walletStore, err := wallets.InitialiseStore(rf.Home, false)
    51  		if err != nil {
    52  			return api.AdminDescribeKeyResult{}, fmt.Errorf("couldn't initialise wallets store: %w", err)
    53  		}
    54  		defer walletStore.Close()
    55  
    56  		if _, errDetails := api.NewAdminUnlockWallet(walletStore).Handle(ctx, api.AdminUnlockWalletParams{
    57  			Wallet:     params.Wallet,
    58  			Passphrase: passphrase,
    59  		}); errDetails != nil {
    60  			return api.AdminDescribeKeyResult{}, errors.New(errDetails.Data)
    61  		}
    62  
    63  		rawResult, errDetails := api.NewAdminDescribeKey(walletStore).Handle(ctx, params)
    64  		if errDetails != nil {
    65  			return api.AdminDescribeKeyResult{}, errors.New(errDetails.Data)
    66  		}
    67  		return rawResult.(api.AdminDescribeKeyResult), nil
    68  	}
    69  
    70  	return BuildCmdDescribeKey(w, h, rf)
    71  }
    72  
    73  func BuildCmdDescribeKey(w io.Writer, handler DescribeKeyHandler, rf *RootFlags) *cobra.Command {
    74  	f := &DescribeKeyFlags{}
    75  
    76  	cmd := &cobra.Command{
    77  		Use:     "describe",
    78  		Short:   "Describe the specified key pair",
    79  		Long:    describeKeyLong,
    80  		Example: describeKeyExample,
    81  		RunE: func(_ *cobra.Command, _ []string) error {
    82  			req, pass, err := f.Validate()
    83  			if err != nil {
    84  				return err
    85  			}
    86  
    87  			resp, err := handler(req, pass)
    88  			if err != nil {
    89  				return err
    90  			}
    91  
    92  			switch rf.Output {
    93  			case flags.InteractiveOutput:
    94  				PrintDescribeKeyResponse(w, resp)
    95  			case flags.JSONOutput:
    96  				return printer.FprintJSON(w, resp)
    97  			}
    98  
    99  			return nil
   100  		},
   101  	}
   102  
   103  	cmd.Flags().StringVarP(&f.Wallet,
   104  		"wallet", "w",
   105  		"",
   106  		"Name of the wallet to use",
   107  	)
   108  	cmd.Flags().StringVarP(&f.PublicKey,
   109  		"pubkey", "k",
   110  		"",
   111  		"Public key to describe (hex-encoded)",
   112  	)
   113  	cmd.Flags().StringVarP(&f.PassphraseFile,
   114  		"passphrase-file", "p",
   115  		"",
   116  		"Path to the file containing the wallet's passphrase",
   117  	)
   118  
   119  	autoCompleteWallet(cmd, rf.Home, "wallet")
   120  
   121  	return cmd
   122  }
   123  
   124  type DescribeKeyFlags struct {
   125  	Wallet         string
   126  	PassphraseFile string
   127  	PublicKey      string
   128  }
   129  
   130  func (f *DescribeKeyFlags) Validate() (api.AdminDescribeKeyParams, string, error) {
   131  	if len(f.Wallet) == 0 {
   132  		return api.AdminDescribeKeyParams{}, "", flags.MustBeSpecifiedError("wallet")
   133  	}
   134  
   135  	if len(f.PublicKey) == 0 {
   136  		return api.AdminDescribeKeyParams{}, "", flags.MustBeSpecifiedError("pubkey")
   137  	}
   138  
   139  	passphrase, err := flags.GetPassphrase(f.PassphraseFile)
   140  	if err != nil {
   141  		return api.AdminDescribeKeyParams{}, "", err
   142  	}
   143  
   144  	return api.AdminDescribeKeyParams{
   145  		Wallet:    f.Wallet,
   146  		PublicKey: f.PublicKey,
   147  	}, passphrase, nil
   148  }
   149  
   150  func PrintDescribeKeyResponse(w io.Writer, resp api.AdminDescribeKeyResult) {
   151  	p := printer.NewInteractivePrinter(w)
   152  
   153  	str := p.String()
   154  	defer p.Print(str)
   155  
   156  	str.Text("Name:              ").WarningText(resp.Name).NextLine()
   157  	str.Text("Public key:        ").WarningText(resp.PublicKey).NextLine()
   158  	str.Text("Algorithm Name:    ").WarningText(resp.Algorithm.Name).NextLine()
   159  	str.Text("Algorithm Version: ").WarningText(fmt.Sprint(resp.Algorithm.Version)).NextSection()
   160  
   161  	str.Text("Key pair is: ")
   162  	switch resp.IsTainted {
   163  	case true:
   164  		str.DangerText("tainted").NextLine()
   165  	case false:
   166  		str.SuccessText("not tainted").NextLine()
   167  	}
   168  	str.Text("Tainting a key marks it as unsafe to use and ensures it will not be used to sign transactions.").NextLine()
   169  	str.Text("This mechanism is useful when the key pair has been compromised.").NextSection()
   170  
   171  	str.Text("Metadata:").NextLine()
   172  	printMeta(str, resp.Metadata)
   173  }