diff --git a/CHANGELOG.md b/CHANGELOG.md index 6dfdb6caf3..76ad92d2d0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -49,6 +49,8 @@ Ref: https://keepachangelog.com/en/1.0.0/ Distribution, Encode, Evidence, FeeGrant Global Fee, Legacy Gov, New Gov, Groups, IBC, ICA, packet forwarding middleware, Slashing, Staking, and Vesting module. * (tests) use gaiad to swap out [Ignite](https://github.com/ignite/cli) in [liveness tests](https://github.com/cosmos/gaia/blob/main/.github/workflows/test.yml). +* (gaia) [#1845](https://github.com/cosmos/gaia/pull/1447) Add bech32-convert command to gaiad + ## [v7.0.2] -2022-05-09 diff --git a/cmd/gaiad/cmd/bech32_convert.go b/cmd/gaiad/cmd/bech32_convert.go new file mode 100644 index 0000000000..ff5a14ca28 --- /dev/null +++ b/cmd/gaiad/cmd/bech32_convert.go @@ -0,0 +1,53 @@ +package cmd + +import ( + "fmt" + + addressutil "github.com/cosmos/gaia/v8/pkg/address" + + "github.com/spf13/cobra" +) + +var flagBech32Prefix = "prefix" + +// AddBech32ConvertCommand returns bech32-convert cobra Command. +func AddBech32ConvertCommand() *cobra.Command { + cmd := &cobra.Command{ + Use: "bech32-convert [address]", + Short: "Convert any bech32 string to the cosmos prefix", + Long: `Convert any bech32 string to the cosmos prefix + +Example: + gaiad debug bech32-convert akash1a6zlyvpnksx8wr6wz8wemur2xe8zyh0ytz6d88 + + gaiad debug bech32-convert stride1673f0t8p893rqyqe420mgwwz92ac4qv6synvx2 --prefix osmo + `, + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + bech32prefix, err := cmd.Flags().GetString(flagBech32Prefix) + if err != nil { + return err + } + + address := args[0] + convertedAddress, err := addressutil.ConvertBech32Prefix(address, bech32prefix) + if err != nil { + return fmt.Errorf("convertation failed: %s", err) + } + + cmd.Println(convertedAddress) + + return nil + }, + } + + cmd.Flags().StringP(flagBech32Prefix, "p", "cosmos", "Bech32 Prefix to encode to") + + return cmd +} + +// addDebugCommands injects custom debug commands into another command as children. +func addDebugCommands(cmd *cobra.Command) *cobra.Command { + cmd.AddCommand(AddBech32ConvertCommand()) + return cmd +} diff --git a/cmd/gaiad/cmd/root.go b/cmd/gaiad/cmd/root.go index 151bb2a5bb..b37df02937 100644 --- a/cmd/gaiad/cmd/root.go +++ b/cmd/gaiad/cmd/root.go @@ -115,7 +115,7 @@ func initRootCmd(rootCmd *cobra.Command, encodingConfig params.EncodingConfig) { AddGenesisAccountCmd(gaia.DefaultNodeHome), tmcli.NewCompletionCmd(rootCmd, true), testnetCmd(gaia.ModuleBasics, banktypes.GenesisBalancesIterator{}), - debug.Cmd(), + addDebugCommands(debug.Cmd()), config.Cmd(), ) diff --git a/pkg/address/address.go b/pkg/address/address.go new file mode 100644 index 0000000000..90d7bce788 --- /dev/null +++ b/pkg/address/address.go @@ -0,0 +1,22 @@ +package address + +import ( + "fmt" + + "github.com/cosmos/cosmos-sdk/types/bech32" +) + +// ConvertBech32Prefix convert bech32 address to specified prefix. +func ConvertBech32Prefix(address, prefix string) (string, error) { + _, bz, err := bech32.DecodeAndConvert(address) + if err != nil { + return "", fmt.Errorf("cannot decode %s address: %s", address, err) + } + + convertedAddress, err := bech32.ConvertAndEncode(prefix, bz) + if err != nil { + return "", fmt.Errorf("cannot convert %s address: %s", address, err) + } + + return convertedAddress, nil +} diff --git a/pkg/address/address_test.go b/pkg/address/address_test.go new file mode 100644 index 0000000000..2a2972ec45 --- /dev/null +++ b/pkg/address/address_test.go @@ -0,0 +1,43 @@ +package address + +import ( + "errors" + "testing" + + "github.com/stretchr/testify/require" +) + +func TestConvertBech32Prefix(t *testing.T) { + cases := []struct { + name string + address string + prefix string + converted string + err error + }{ + { + name: "Convert valid bech 32 address", + address: "akash1a6zlyvpnksx8wr6wz8wemur2xe8zyh0ytz6d88", + converted: "cosmos1a6zlyvpnksx8wr6wz8wemur2xe8zyh0yxeh27a", + prefix: "cosmos", + }, + { + name: "Convert invalid address", + address: "invalidaddress", + prefix: "cosmos", + err: errors.New("cannot decode invalidaddress address: decoding bech32 failed: invalid separator index -1"), + }, + } + + for _, tt := range cases { + t.Run(tt.name, func(t *testing.T) { + convertedAddress, err := ConvertBech32Prefix(tt.address, tt.prefix) + if tt.err != nil { + require.ErrorContains(t, err, tt.err.Error()) + } else { + require.NoError(t, err) + } + require.Equal(t, tt.converted, convertedAddress) + }) + } +}