code.vegaprotocol.io/vega@v0.79.0/cmd/vegawallet/commands/wallet_delete.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  	vgterm "code.vegaprotocol.io/vega/libs/term"
    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  	ErrForceFlagIsRequiredWithoutTTY = errors.New("--force is required without TTY")
    36  
    37  	deleteWalletLong = cli.LongDesc(`
    38  		Delete the specified wallet and its keys.
    39  
    40  		Be sure to have its recovery phrase, otherwise you won't be able to restore it. If you
    41  		lost it, you should transfer your funds, assets, orders, and anything else attached to
    42  		this wallet to another wallet.
    43  
    44  		The deletion removes the file in which the wallet and its keys are stored, meaning you
    45  		can reuse the wallet name, without causing any conflict.
    46  	`)
    47  
    48  	deleteWalletExample = cli.Examples(`
    49  		# Delete the specified wallet
    50  		{{.Software}} delete --wallet WALLET
    51  
    52  		# Delete the specified wallet without asking for confirmation
    53  		{{.Software}} delete --wallet WALLET --force
    54  	`)
    55  )
    56  
    57  type RemoveWalletHandler func(api.AdminRemoveWalletParams) error
    58  
    59  func NewCmdDeleteWallet(w io.Writer, rf *RootFlags) *cobra.Command {
    60  	h := func(params api.AdminRemoveWalletParams) error {
    61  		walletStore, err := wallets.InitialiseStore(rf.Home, false)
    62  		if err != nil {
    63  			return fmt.Errorf("couldn't initialise wallets store: %w", err)
    64  		}
    65  		defer walletStore.Close()
    66  
    67  		deleteWallet := api.NewAdminRemoveWallet(walletStore)
    68  
    69  		_, errDetails := deleteWallet.Handle(context.Background(), params)
    70  		if errDetails != nil {
    71  			return errors.New(errDetails.Data)
    72  		}
    73  		return nil
    74  	}
    75  
    76  	return BuildCmdDeleteWallet(w, h, rf)
    77  }
    78  
    79  func BuildCmdDeleteWallet(w io.Writer, handler RemoveWalletHandler, rf *RootFlags) *cobra.Command {
    80  	f := &DeleteWalletFlags{}
    81  
    82  	cmd := &cobra.Command{
    83  		Use:     "delete",
    84  		Short:   "Delete the specified wallet and its keys",
    85  		Long:    deleteWalletLong,
    86  		Example: deleteWalletExample,
    87  		RunE: func(_ *cobra.Command, _ []string) error {
    88  			params, err := f.Validate()
    89  			if err != nil {
    90  				return err
    91  			}
    92  
    93  			if !f.Force && vgterm.HasTTY() {
    94  				if !flags.AreYouSure() {
    95  					return nil
    96  				}
    97  			}
    98  
    99  			if err := handler(params); err != nil {
   100  				return err
   101  			}
   102  
   103  			switch rf.Output {
   104  			case flags.InteractiveOutput:
   105  				PrintDeleteWalletResponse(w, f.Wallet)
   106  			case flags.JSONOutput:
   107  				return nil
   108  			}
   109  
   110  			return nil
   111  		},
   112  	}
   113  
   114  	cmd.Flags().StringVarP(&f.Wallet,
   115  		"wallet", "w",
   116  		"",
   117  		"Wallet to delete",
   118  	)
   119  	cmd.Flags().BoolVarP(&f.Force,
   120  		"force", "f",
   121  		false,
   122  		"Do not ask for confirmation",
   123  	)
   124  
   125  	autoCompleteWallet(cmd, rf.Home, "wallet")
   126  
   127  	return cmd
   128  }
   129  
   130  type DeleteWalletFlags struct {
   131  	Wallet string
   132  	Force  bool
   133  }
   134  
   135  func (f *DeleteWalletFlags) Validate() (api.AdminRemoveWalletParams, error) {
   136  	if len(f.Wallet) == 0 {
   137  		return api.AdminRemoveWalletParams{}, flags.MustBeSpecifiedError("wallet")
   138  	}
   139  
   140  	if !f.Force && vgterm.HasNoTTY() {
   141  		return api.AdminRemoveWalletParams{}, ErrForceFlagIsRequiredWithoutTTY
   142  	}
   143  
   144  	return api.AdminRemoveWalletParams{
   145  		Wallet: f.Wallet,
   146  	}, nil
   147  }
   148  
   149  func PrintDeleteWalletResponse(w io.Writer, walletName string) {
   150  	p := printer.NewInteractivePrinter(w)
   151  
   152  	str := p.String()
   153  	defer p.Print(str)
   154  
   155  	str.CheckMark().SuccessText("Wallet ").SuccessBold(walletName).SuccessText(" deleted").NextLine()
   156  }