diff --git a/ioctl/cmd/account/accountcreateadd.go b/ioctl/cmd/account/accountcreateadd.go index 0f634aab18..cca0d08343 100644 --- a/ioctl/cmd/account/accountcreateadd.go +++ b/ioctl/cmd/account/accountcreateadd.go @@ -13,6 +13,7 @@ import ( "github.com/spf13/cobra" "gopkg.in/yaml.v2" + "github.com/iotexproject/iotex-address/address" "github.com/iotexproject/iotex-core/v2/ioctl/config" "github.com/iotexproject/iotex-core/v2/ioctl/output" "github.com/iotexproject/iotex-core/v2/ioctl/validator" @@ -43,50 +44,81 @@ var _accountCreateAddCmd = &cobra.Command{ } func accountCreateAdd(args []string) error { - // Validate inputs + // Validate alias if err := validator.ValidateAlias(args[0]); err != nil { return output.NewError(output.ValidationError, "invalid alias", err) } alias := args[0] - if addr, ok := config.ReadConfig.Aliases[alias]; ok { - var confirm string - info := fmt.Sprintf("** Alias \"%s\" has already used for %s\n"+ - "Overwriting the account will keep the previous keystore file stay, "+ - "but bind the alias to the new one.\nWould you like to continue?\n", alias, addr) - message := output.ConfirmationMessage{Info: info, Options: []string{"yes"}} - fmt.Println(message.String()) - if _, err := fmt.Scanf("%s", &confirm); err != nil { - return output.NewError(output.InputError, "failed to input yes", err) + + // Check for existing alias and confirm overwrite if necessary + if io1Addr, ok := config.ReadConfig.Aliases[alias]; ok { + // Convert io1 to 0x format for display + iotexAddr, err := address.FromString(io1Addr) + if err != nil { + return output.NewError(output.AddressError, "failed to parse existing alias address", err) + } + ethAddr := iotexAddr.Hex() + + // Show confirmation prompt in "0x (io1)" format + proceed, err := confirmOverwrite(alias, fmt.Sprintf("%s (%s)", ethAddr, io1Addr)) + if err != nil { + return err } - if !strings.EqualFold(confirm, "yes") { + if !proceed { output.PrintResult("quit") return nil } } - var addr string + // Create new account based on crypto type + var io1Addr string var err error if CryptoSm2 { - addr, err = newAccountSm2(alias) + io1Addr, err = newAccountSm2(alias) if err != nil { - return output.NewError(0, "", err) + return output.NewError(output.CryptoError, "failed to create SM2 account", err) } } else { - addr, err = newAccount(alias) + io1Addr, err = newAccount(alias) if err != nil { - return output.NewError(0, "", err) + return output.NewError(output.CryptoError, "failed to create account", err) } } - config.ReadConfig.Aliases[alias] = addr + + // Convert io1 address to 0x format for display + iotexAddr, err := address.FromString(io1Addr) + if err != nil { + return output.NewError(output.AddressError, "failed to convert to address struct", err) + } + ethAddr := iotexAddr.Hex() + + // Update alias configuration and write changes to the config file + config.ReadConfig.Aliases[alias] = io1Addr out, err := yaml.Marshal(&config.ReadConfig) if err != nil { return output.NewError(output.SerializationError, "failed to marshal config", err) } if err := os.WriteFile(config.DefaultConfigFile, out, 0600); err != nil { - return output.NewError(output.WriteFileError, - fmt.Sprintf("failed to write to config file %s", config.DefaultConfigFile), err) + return output.NewError(output.WriteFileError, fmt.Sprintf("failed to write to config file %s", config.DefaultConfigFile), err) } + + // Display both formats in "0x (io1)" format on a single line output.PrintResult(fmt.Sprintf("New account \"%s\" is created.\n"+ - "Please Keep your password, or you will lose your private key.", alias)) + "Please keep your password safe, or you will lose access to your private key.\n\n"+ + "Account address:\n%s (%s)", alias, ethAddr, io1Addr)) + return nil } + +func confirmOverwrite(alias, formattedAddress string) (bool, error) { + info := fmt.Sprintf("** Alias \"%s\" is already used for:\n\n%s\n\n"+ + "Overwriting the account will keep the previous keystore file, "+ + "but bind the alias to the new one.\nWould you like to continue? [yes/no]", alias, formattedAddress) + fmt.Println(info) + + var confirm string + if _, err := fmt.Scanf("%s", &confirm); err != nil { + return false, output.NewError(output.InputError, "failed to read confirmation input", err) + } + return strings.EqualFold(confirm, "yes"), nil +}