From 38fb852795d784a07d22b07be877fc0059f5929a Mon Sep 17 00:00:00 2001 From: Jeremy Chou Date: Thu, 30 Jun 2022 00:00:06 +0800 Subject: [PATCH] [ioctl] Build hdwallet create command line into new ioctl (#3470) * [ioctl] build hdwallet create command line into new ioctl --- ioctl/newcmd/hdwallet/hdwalletcreate.go | 77 ++++++++++++++++++++ ioctl/newcmd/hdwallet/hdwalletcreate_test.go | 58 +++++++++++++++ 2 files changed, 135 insertions(+) create mode 100644 ioctl/newcmd/hdwallet/hdwalletcreate.go create mode 100644 ioctl/newcmd/hdwallet/hdwalletcreate_test.go diff --git a/ioctl/newcmd/hdwallet/hdwalletcreate.go b/ioctl/newcmd/hdwallet/hdwalletcreate.go new file mode 100644 index 0000000000..3c700bd753 --- /dev/null +++ b/ioctl/newcmd/hdwallet/hdwalletcreate.go @@ -0,0 +1,77 @@ +// Copyright (c) 2022 IoTeX Foundation +// This is an alpha (internal) release and is not suitable for production. This source code is provided 'as is' and no +// warranties are given as to title or non-infringement, merchantability or fitness for purpose and, to the extent +// permitted by law, all liability for your use of the code is disclaimed. This source code is governed by Apache +// License 2.0 that can be found in the LICENSE file. + +package hdwallet + +import ( + "github.com/pkg/errors" + "github.com/spf13/cobra" + "github.com/tyler-smith/go-bip39" + + "github.com/iotexproject/iotex-core/ioctl" + "github.com/iotexproject/iotex-core/ioctl/config" +) + +// Multi-language support +var ( + _createByMnemonicCmdShorts = map[config.Language]string{ + config.English: "create hdwallet using mnemonic", + config.Chinese: "通过助记词创建新钱包", + } + _createByMnemonicCmdUses = map[config.Language]string{ + config.English: "create", + config.Chinese: "create 创建", + } +) + +// NewHdwalletCreateCmd represents the hdwallet create command +func NewHdwalletCreateCmd(client ioctl.Client) *cobra.Command { + use, _ := client.SelectTranslation(_createByMnemonicCmdUses) + short, _ := client.SelectTranslation(_createByMnemonicCmdShorts) + + return &cobra.Command{ + Use: use, + Short: short, + Args: cobra.ExactArgs(0), + RunE: func(cmd *cobra.Command, args []string) error { + cmd.SilenceUsage = true + if client.IsHdWalletConfigFileExist() { + cmd.Println("Please run 'ioctl hdwallet delete' before import") + return nil + } + cmd.Println("Set password") + password, err := client.ReadSecret() + if err != nil { + return errors.Wrap(err, "failed to get password") + } + cmd.Println("Enter password again") + passwordAgain, err := client.ReadSecret() + if err != nil { + return errors.Wrap(err, "failed to get password") + } + if password != passwordAgain { + return ErrPasswdNotMatch + } + + entropy, err := bip39.NewEntropy(128) + if err != nil { + return err + } + mnemonic, err := bip39.NewMnemonic(entropy) + if err != nil { + return err + } + + if err = client.WriteHdWalletConfigFile(mnemonic, password); err != nil { + return err + } + + cmd.Printf("Mnemonic phrase: %s\n"+ + "It is used to recover your wallet in case you forgot the password. Write them down and store it in a safe place.\n", mnemonic) + return nil + }, + } +} diff --git a/ioctl/newcmd/hdwallet/hdwalletcreate_test.go b/ioctl/newcmd/hdwallet/hdwalletcreate_test.go new file mode 100644 index 0000000000..0647ed2719 --- /dev/null +++ b/ioctl/newcmd/hdwallet/hdwalletcreate_test.go @@ -0,0 +1,58 @@ +// Copyright (c) 2022 IoTeX Foundation +// This is an alpha (internal) release and is not suitable for production. This source code is provided 'as is' and no +// warranties are given as to title or non-infringement, merchantability or fitness for purpose and, to the extent +// permitted by law, all liability for your use of the code is disclaimed. This source code is governed by Apache +// License 2.0 that can be found in the LICENSE file. + +package hdwallet + +import ( + "testing" + + "github.com/golang/mock/gomock" + "github.com/pkg/errors" + "github.com/stretchr/testify/require" + + "github.com/iotexproject/iotex-core/ioctl/config" + "github.com/iotexproject/iotex-core/ioctl/util" + "github.com/iotexproject/iotex-core/test/mock/mock_ioctlclient" +) + +func TestNewHdwalletCreateCmd(t *testing.T) { + require := require.New(t) + ctrl := gomock.NewController(t) + client := mock_ioctlclient.NewMockClient(ctrl) + password := "123" + + client.EXPECT().SelectTranslation(gomock.Any()).Return("mockTranslationString", config.English).Times(9) + client.EXPECT().IsHdWalletConfigFileExist().Return(false).Times(3) + + t.Run("create hdwallet", func(t *testing.T) { + client.EXPECT().ReadSecret().Return(password, nil).Times(2) + client.EXPECT().WriteHdWalletConfigFile(gomock.Any(), gomock.Any()).Return(nil) + + cmd := NewHdwalletCreateCmd(client) + result, err := util.ExecuteCmd(cmd) + require.NoError(err) + require.Contains(result, "It is used to recover your wallet in case you forgot the password. Write them down and store it in a safe place.") + }) + + t.Run("failed to get password", func(t *testing.T) { + expectedErr := errors.New("failed to get password") + client.EXPECT().ReadSecret().Return("", expectedErr) + + cmd := NewHdwalletCreateCmd(client) + _, err := util.ExecuteCmd(cmd) + require.Contains(err.Error(), expectedErr.Error()) + }) + + t.Run("password not match", func(t *testing.T) { + expectedErr := errors.New("password doesn't match") + client.EXPECT().ReadSecret().Return(password, nil) + client.EXPECT().ReadSecret().Return("test", nil) + + cmd := NewHdwalletCreateCmd(client) + _, err := util.ExecuteCmd(cmd) + require.Equal(err.Error(), expectedErr.Error()) + }) +}