github.com/iotexproject/iotex-core@v1.14.1-rc1/ioctl/newcmd/account/accountdelete.go (about)

     1  // Copyright (c) 2019 IoTeX Foundation
     2  // This source code is provided 'as is' and no warranties are given as to title or non-infringement, merchantability
     3  // or fitness for purpose and, to the extent permitted by law, all liability for your use of the code is disclaimed.
     4  // This source code is governed by Apache License 2.0 that can be found in the LICENSE file.
     5  
     6  package account
     7  
     8  import (
     9  	"bytes"
    10  	"fmt"
    11  	"os"
    12  	"path/filepath"
    13  
    14  	"github.com/iotexproject/iotex-address/address"
    15  	"github.com/pkg/errors"
    16  	"github.com/spf13/cobra"
    17  
    18  	"github.com/iotexproject/iotex-core/ioctl"
    19  	"github.com/iotexproject/iotex-core/ioctl/config"
    20  )
    21  
    22  // Multi-language support
    23  var (
    24  	_deleteShorts = map[config.Language]string{
    25  		config.English: "Delete an IoTeX account/address from wallet/config",
    26  		config.Chinese: "从 钱包/配置 中删除一个IoTeX的账户或地址",
    27  	}
    28  	_deleteUses = map[config.Language]string{
    29  		config.English: "delete [ALIAS|ADDRESS]",
    30  		config.Chinese: "delete [别名|地址]",
    31  	}
    32  	_failToGetAddress = map[config.Language]string{
    33  		config.English: "failed to get address",
    34  		config.Chinese: "获取账户地址失败",
    35  	}
    36  	_failToConvertStringIntoAddress = map[config.Language]string{
    37  		config.English: "failed to convert string into address",
    38  		config.Chinese: "转换字符串到账户地址失败",
    39  	}
    40  	_infoWarn = map[config.Language]string{
    41  		config.English: "** This is an irreversible action!\n" +
    42  			"Once an account is deleted, all the assets under this account may be lost!\n" +
    43  			"Type 'YES' to continue, quit for anything else.",
    44  		config.Chinese: "** 这是一个不可逆转的操作!\n" +
    45  			"一旦一个账户被删除, 该账户下的所有资源都可能会丢失!\n" +
    46  			"输入 'YES' 以继续, 否则退出",
    47  	}
    48  	_infoQuit = map[config.Language]string{
    49  		config.English: "quit",
    50  		config.Chinese: "退出",
    51  	}
    52  	_failToRemoveKeystoreFile = map[config.Language]string{
    53  		config.English: "failed to remove keystore file",
    54  		config.Chinese: "移除keystore文件失败",
    55  	}
    56  	_failToWriteToConfigFile = map[config.Language]string{
    57  		config.English: "Failed to write to config file.",
    58  		config.Chinese: "写入配置文件失败",
    59  	}
    60  	_resultSuccess = map[config.Language]string{
    61  		config.English: "Account #%s has been deleted.",
    62  		config.Chinese: "账户 #%s 已被删除",
    63  	}
    64  	_failToFindAccount = map[config.Language]string{
    65  		config.English: "account #%s not found",
    66  		config.Chinese: "账户 #%s 未找到",
    67  	}
    68  )
    69  
    70  // NewAccountDelete represents the account delete command
    71  func NewAccountDelete(client ioctl.Client) *cobra.Command {
    72  	use, _ := client.SelectTranslation(_deleteUses)
    73  	short, _ := client.SelectTranslation(_deleteShorts)
    74  	_failToGetAddress, _ := client.SelectTranslation(_failToGetAddress)
    75  	_failToConvertStringIntoAddress, _ := client.SelectTranslation(_failToConvertStringIntoAddress)
    76  	_infoWarn, _ := client.SelectTranslation(_infoWarn)
    77  	_failToRemoveKeystoreFile, _ := client.SelectTranslation(_failToRemoveKeystoreFile)
    78  	_failToWriteToConfigFile, _ := client.SelectTranslation(_failToWriteToConfigFile)
    79  	_resultSuccess, _ := client.SelectTranslation(_resultSuccess)
    80  	_failToFindAccount, _ := client.SelectTranslation(_failToFindAccount)
    81  	_infoQuit, _ := client.SelectTranslation(_infoQuit)
    82  
    83  	return &cobra.Command{
    84  		Use:   use,
    85  		Short: short,
    86  		Args:  cobra.RangeArgs(0, 1),
    87  		RunE: func(cmd *cobra.Command, args []string) error {
    88  			cmd.SilenceUsage = true
    89  			arg := ""
    90  			if len(args) == 1 {
    91  				arg = args[0]
    92  			}
    93  
    94  			addr, err := client.AddressWithDefaultIfNotExist(arg)
    95  			if err != nil {
    96  				return errors.Wrap(err, _failToGetAddress)
    97  			}
    98  			account, err := address.FromString(addr)
    99  			if err != nil {
   100  				return errors.Wrap(err, _failToConvertStringIntoAddress)
   101  			}
   102  
   103  			var filePath string
   104  			if client.IsCryptoSm2() {
   105  				if filePath == "" {
   106  					filePath = filepath.Join(client.Config().Wallet, "sm2sk-"+account.String()+".pem")
   107  				}
   108  			} else {
   109  				ks := client.NewKeyStore()
   110  				for _, v := range ks.Accounts() {
   111  					if bytes.Equal(account.Bytes(), v.Address.Bytes()) {
   112  						filePath = v.URL.Path
   113  						break
   114  					}
   115  				}
   116  			}
   117  
   118  			// check whether crypto file exists
   119  			if _, err = os.Stat(filePath); err != nil {
   120  				return errors.Wrapf(err, _failToFindAccount, addr)
   121  			}
   122  			confirmed, err := client.AskToConfirm(_infoWarn)
   123  			if err != nil {
   124  				return errors.Wrap(err, "failed to ask confirm")
   125  			}
   126  			if !confirmed {
   127  				cmd.Println(_infoQuit)
   128  				return nil
   129  			}
   130  			if err = os.Remove(filePath); err != nil {
   131  				return errors.Wrap(err, _failToRemoveKeystoreFile)
   132  			}
   133  			if err = client.DeleteAlias(client.AliasMap()[addr]); err != nil {
   134  				return errors.Wrap(err, _failToWriteToConfigFile)
   135  			}
   136  			cmd.Println(fmt.Sprintf(_resultSuccess, addr))
   137  			return nil
   138  		},
   139  	}
   140  }