github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/libs/cosmos-sdk/client/keys/parse.go (about) 1 package keys 2 3 import ( 4 "context" 5 "encoding/hex" 6 "errors" 7 "fmt" 8 "io" 9 "strings" 10 11 "github.com/spf13/cobra" 12 "github.com/spf13/viper" 13 yaml "gopkg.in/yaml.v2" 14 15 "github.com/fibonacci-chain/fbc/libs/tendermint/libs/bech32" 16 "github.com/fibonacci-chain/fbc/libs/tendermint/libs/cli" 17 18 "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/client/flags" 19 sdk "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types" 20 ) 21 22 func bech32Prefixes(config *sdk.Config) []string { 23 return []string{ 24 config.GetBech32AccountAddrPrefix(), 25 config.GetBech32AccountPubPrefix(), 26 config.GetBech32ValidatorAddrPrefix(), 27 config.GetBech32ValidatorPubPrefix(), 28 config.GetBech32ConsensusAddrPrefix(), 29 config.GetBech32ConsensusPubPrefix(), 30 } 31 } 32 33 type hexOutput struct { 34 Human string `json:"human"` 35 Bytes string `json:"bytes"` 36 } 37 38 func (ho hexOutput) String() string { 39 return fmt.Sprintf("Human readable part: %v\nBytes (hex): %s", ho.Human, ho.Bytes) 40 } 41 42 func newHexOutput(human string, bs []byte) hexOutput { 43 return hexOutput{Human: human, Bytes: fmt.Sprintf("%X", bs)} 44 } 45 46 type bech32Output struct { 47 Formats []string `json:"formats"` 48 } 49 50 func newBech32Output(config *sdk.Config, bs []byte) bech32Output { 51 bech32Prefixes := bech32Prefixes(config) 52 out := bech32Output{Formats: make([]string, len(bech32Prefixes))} 53 54 for i, prefix := range bech32Prefixes { 55 bech32Addr, err := bech32.ConvertAndEncode(prefix, bs) 56 if err != nil { 57 panic(err) 58 } 59 60 out.Formats[i] = bech32Addr 61 } 62 63 return out 64 } 65 66 func (bo bech32Output) String() string { 67 out := make([]string, len(bo.Formats)) 68 69 for i, format := range bo.Formats { 70 out[i] = fmt.Sprintf(" - %s", format) 71 } 72 73 return fmt.Sprintf("Bech32 Formats:\n%s", strings.Join(out, "\n")) 74 } 75 76 // ParseKeyStringCommand parses an address from hex to bech32 and vice versa. 77 func ParseKeyStringCommand() *cobra.Command { 78 cmd := &cobra.Command{ 79 Use: "parse <hex-or-bech32-address>", 80 Short: "Parse address from hex to bech32 and vice versa", 81 Long: `Convert and print to stdout key addresses and fingerprints from 82 hexadecimal into bech32 cosmos prefixed format and vice versa. 83 `, 84 Args: cobra.ExactArgs(1), 85 RunE: parseKey, 86 } 87 cmd.Flags().Bool(flags.FlagIndentResponse, false, "Indent JSON output") 88 89 return cmd 90 } 91 92 func parseKey(cmd *cobra.Command, args []string) error { 93 config, _ := sdk.GetSealedConfig(context.Background()) 94 95 return doParseKey(cmd, config, args) 96 } 97 98 func doParseKey(cmd *cobra.Command, config *sdk.Config, args []string) error { 99 addr := strings.TrimSpace(args[0]) 100 outstream := cmd.OutOrStdout() 101 102 if len(addr) == 0 { 103 return errors.New("couldn't parse empty input") 104 } 105 106 if !(runFromBech32(outstream, addr) || runFromHex(config, outstream, addr)) { 107 return errors.New("couldn't find valid bech32 nor hex data") 108 } 109 110 return nil 111 } 112 113 // print info from bech32 114 func runFromBech32(w io.Writer, bech32str string) bool { 115 hrp, bz, err := bech32.DecodeAndConvert(bech32str) 116 if err != nil { 117 return false 118 } 119 120 displayParseKeyInfo(w, newHexOutput(hrp, bz)) 121 122 return true 123 } 124 125 // print info from hex 126 func runFromHex(config *sdk.Config, w io.Writer, hexstr string) bool { 127 bz, err := hex.DecodeString(hexstr) 128 if err != nil { 129 return false 130 } 131 132 displayParseKeyInfo(w, newBech32Output(config, bz)) 133 134 return true 135 } 136 137 func displayParseKeyInfo(w io.Writer, stringer fmt.Stringer) { 138 var out []byte 139 var err error 140 141 switch viper.Get(cli.OutputFlag) { 142 case OutputFormatText: 143 out, err = yaml.Marshal(&stringer) 144 145 case OutputFormatJSON: 146 147 if viper.GetBool(flags.FlagIndentResponse) { 148 out, err = KeysCdc.MarshalJSONIndent(stringer, "", " ") 149 } else { 150 out = KeysCdc.MustMarshalJSON(stringer) 151 } 152 153 } 154 155 if err != nil { 156 panic(err) 157 } 158 159 _, _ = fmt.Fprintln(w, string(out)) 160 }