github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/libs/cosmos-sdk/types/address.go (about)

     1  package types
     2  
     3  import (
     4  	"bytes"
     5  	"encoding/hex"
     6  	"encoding/json"
     7  	"errors"
     8  	"fmt"
     9  	"strings"
    10  
    11  	"github.com/fibonacci-chain/fbc/libs/tendermint/crypto"
    12  	tmamino "github.com/fibonacci-chain/fbc/libs/tendermint/crypto/encoding/amino"
    13  	yaml "gopkg.in/yaml.v2"
    14  
    15  	"github.com/fibonacci-chain/fbc/libs/tendermint/libs/bech32"
    16  )
    17  
    18  const (
    19  	// Constants defined here are the defaults value for address.
    20  	// You can use the specific values for your project.
    21  	// Add the follow lines to the `main()` of your server.
    22  	//
    23  	//	config := sdk.GetConfig()
    24  	//	config.SetBech32PrefixForAccount(yourBech32PrefixAccAddr, yourBech32PrefixAccPub)
    25  	//	config.SetBech32PrefixForValidator(yourBech32PrefixValAddr, yourBech32PrefixValPub)
    26  	//	config.SetBech32PrefixForConsensusNode(yourBech32PrefixConsAddr, yourBech32PrefixConsPub)
    27  	//	config.SetCoinType(yourCoinType)
    28  	//	config.SetFullFundraiserPath(yourFullFundraiserPath)
    29  	//	config.Seal()
    30  
    31  	// AddrLen defines a valid address length
    32  	AddrLen = 20
    33  	// WasmContractAddrLen defines a valid wasm contract address length
    34  	WasmContractAddrLen = 32
    35  	// Bech32MainPrefix defines the main SDK Bech32 prefix of an account's address
    36  	Bech32MainPrefix = "cosmos"
    37  
    38  	// CoinType is the ATOM coin type as defined in SLIP44 (https://github.com/satoshilabs/slips/blob/master/slip-0044.md)
    39  	CoinType = 118
    40  
    41  	// FullFundraiserPath is the parts of the BIP44 HD path that are fixed by
    42  	// what we used during the ATOM fundraiser.
    43  	FullFundraiserPath = "m/44'/118'/0'/0/0"
    44  
    45  	// PrefixAccount is the prefix for account keys
    46  	PrefixAccount = "acc"
    47  	// PrefixValidator is the prefix for validator keys
    48  	PrefixValidator = "val"
    49  	// PrefixConsensus is the prefix for consensus keys
    50  	PrefixConsensus = "cons"
    51  	// PrefixPublic is the prefix for public keys
    52  	PrefixPublic = "pub"
    53  	// PrefixOperator is the prefix for operator keys
    54  	PrefixOperator = "oper"
    55  
    56  	// PrefixAddress is the prefix for addresses
    57  	PrefixAddress = "addr"
    58  
    59  	// Bech32PrefixAccAddr defines the Bech32 prefix of an account's address
    60  	Bech32PrefixAccAddr = Bech32MainPrefix
    61  	// Bech32PrefixAccPub defines the Bech32 prefix of an account's public key
    62  	Bech32PrefixAccPub = Bech32MainPrefix + PrefixPublic
    63  	// Bech32PrefixValAddr defines the Bech32 prefix of a validator's operator address
    64  	Bech32PrefixValAddr = Bech32MainPrefix + PrefixValidator + PrefixOperator
    65  	// Bech32PrefixValPub defines the Bech32 prefix of a validator's operator public key
    66  	Bech32PrefixValPub = Bech32MainPrefix + PrefixValidator + PrefixOperator + PrefixPublic
    67  	// Bech32PrefixConsAddr defines the Bech32 prefix of a consensus node address
    68  	Bech32PrefixConsAddr = Bech32MainPrefix + PrefixValidator + PrefixConsensus
    69  	// Bech32PrefixConsPub defines the Bech32 prefix of a consensus node public key
    70  	Bech32PrefixConsPub = Bech32MainPrefix + PrefixValidator + PrefixConsensus + PrefixPublic
    71  )
    72  
    73  // Address is a common interface for different types of addresses used by the SDK
    74  type Address interface {
    75  	Equals(Address) bool
    76  	Empty() bool
    77  	Marshal() ([]byte, error)
    78  	MarshalJSON() ([]byte, error)
    79  	Bytes() []byte
    80  	String() string
    81  	Format(s fmt.State, verb rune)
    82  }
    83  
    84  // Ensure that different address types implement the interface
    85  var _ Address = AccAddress{}
    86  var _ Address = ValAddress{}
    87  var _ Address = ConsAddress{}
    88  
    89  var _ yaml.Marshaler = AccAddress{}
    90  var _ yaml.Marshaler = ValAddress{}
    91  var _ yaml.Marshaler = ConsAddress{}
    92  
    93  // ----------------------------------------------------------------------------
    94  // account
    95  // ----------------------------------------------------------------------------
    96  
    97  // AccAddress a wrapper around bytes meant to represent an account address.
    98  // When marshaled to a string or JSON, it uses Bech32.
    99  type AccAddress []byte
   100  
   101  func IsWasmAddress(acc AccAddress) bool {
   102  	return len(acc) == WasmContractAddrLen
   103  }
   104  
   105  func IsETHAddress(addr string) bool {
   106  	return strings.HasPrefix(addr, "0x")
   107  }
   108  
   109  func IsFBCAddress(addr string) bool {
   110  	return strings.HasPrefix(addr, GetConfig().GetBech32AccountAddrPrefix())
   111  }
   112  
   113  // AccAddressFromHex creates an AccAddress from a hex string.
   114  func AccAddressFromHex(address string) (addr AccAddress, err error) {
   115  	if len(address) == 0 {
   116  		return addr, errors.New("decoding Bech32 address failed: must provide an address")
   117  	}
   118  
   119  	bz, err := hex.DecodeString(address)
   120  	if err != nil {
   121  		return nil, err
   122  	}
   123  
   124  	return AccAddress(bz), nil
   125  }
   126  
   127  // VerifyAddressFormat verifies that the provided bytes form a valid address
   128  // according to the default address rules or a custom address verifier set by
   129  // GetConfig().SetAddressVerifier()
   130  func VerifyAddressFormat(bz []byte) error {
   131  	verifier := GetConfig().GetAddressVerifier()
   132  	if verifier != nil {
   133  		return verifier(bz)
   134  	}
   135  	if len(bz) != AddrLen && len(bz) != WasmContractAddrLen {
   136  		return errors.New("incorrect address length")
   137  	}
   138  	return nil
   139  }
   140  
   141  // MustAccAddressFromBech32 calls AccAddressFromBech32 and panics on error.
   142  func MustAccAddressFromBech32(address string) AccAddress {
   143  	addr, err := AccAddressFromBech32(address)
   144  	if err != nil {
   145  		panic(err)
   146  	}
   147  
   148  	return addr
   149  }
   150  
   151  // AccAddressFromBech32 creates an AccAddress from a Bech32 string.
   152  func AccAddressFromBech32(address string) (AccAddress, error) {
   153  	return AccAddressFromBech32ByPrefix(address, GetConfig().GetBech32AccountAddrPrefix())
   154  }
   155  
   156  // AccAddressFromBech32ByPrefix create an AccAddress from a Bech32 string by address prefix
   157  func AccAddressFromBech32ByPrefix(address string, bech32PrefixAccAddr string) (addr AccAddress, err error) {
   158  	if len(strings.TrimSpace(address)) == 0 {
   159  		return nil, errors.New("empty address string is not allowed")
   160  	}
   161  
   162  	if !strings.HasPrefix(address, bech32PrefixAccAddr) {
   163  		// strip 0x prefix if exists
   164  		addrStr := strings.TrimPrefix(address, "0x")
   165  		addr, err = AccAddressFromHex(addrStr)
   166  		if err != nil {
   167  			return addr, err
   168  		}
   169  		return addr, VerifyAddressFormat(addr)
   170  	}
   171  
   172  	//decodes a bytestring from a Bech32 encoded string
   173  	bz, err := GetFromBech32(address, bech32PrefixAccAddr)
   174  	if err != nil {
   175  		return nil, err
   176  	}
   177  
   178  	err = VerifyAddressFormat(bz)
   179  	if err != nil {
   180  		return nil, err
   181  	}
   182  
   183  	return AccAddress(bz), nil
   184  }
   185  
   186  // Returns boolean for whether two AccAddresses are Equal
   187  func (aa AccAddress) Equals(aa2 Address) bool {
   188  	if aa.Empty() && aa2.Empty() {
   189  		return true
   190  	}
   191  
   192  	return bytes.Equal(aa.Bytes(), aa2.Bytes())
   193  }
   194  
   195  // Returns boolean for whether an AccAddress is empty
   196  func (aa AccAddress) Empty() bool {
   197  	if aa == nil {
   198  		return true
   199  	}
   200  
   201  	aa2 := AccAddress{}
   202  	return bytes.Equal(aa.Bytes(), aa2.Bytes())
   203  }
   204  
   205  // Marshal returns the raw address bytes. It is needed for protobuf
   206  // compatibility.
   207  func (aa AccAddress) Marshal() ([]byte, error) {
   208  	return aa, nil
   209  }
   210  
   211  // Unmarshal sets the address to the given data. It is needed for protobuf
   212  // compatibility.
   213  func (aa *AccAddress) Unmarshal(data []byte) error {
   214  	*aa = data
   215  	return nil
   216  }
   217  
   218  // MarshalJSON marshals to JSON using Bech32.
   219  func (aa AccAddress) MarshalJSON() ([]byte, error) {
   220  	return json.Marshal(aa.String())
   221  }
   222  
   223  // MarshalYAML marshals to YAML using Bech32.
   224  func (aa AccAddress) MarshalYAML() (interface{}, error) {
   225  	return aa.String(), nil
   226  }
   227  
   228  // UnmarshalJSON unmarshals from JSON assuming Bech32 encoding.
   229  func (aa *AccAddress) UnmarshalJSON(data []byte) error {
   230  	var s string
   231  	err := json.Unmarshal(data, &s)
   232  	if err != nil {
   233  		return err
   234  	}
   235  
   236  	if s == "" {
   237  		*aa = AccAddress{}
   238  		return nil
   239  	}
   240  
   241  	aa2, err := AccAddressFromBech32(s)
   242  	if err != nil {
   243  		return err
   244  	}
   245  
   246  	*aa = aa2
   247  	return nil
   248  }
   249  
   250  // UnmarshalYAML unmarshals from JSON assuming Bech32 encoding.
   251  func (aa *AccAddress) UnmarshalYAML(data []byte) error {
   252  	var s string
   253  	err := yaml.Unmarshal(data, &s)
   254  	if err != nil {
   255  		return err
   256  	}
   257  
   258  	if s == "" {
   259  		*aa = AccAddress{}
   260  		return nil
   261  	}
   262  
   263  	aa2, err := AccAddressFromBech32(s)
   264  	if err != nil {
   265  		return err
   266  	}
   267  
   268  	*aa = aa2
   269  	return nil
   270  }
   271  
   272  // Bytes returns the raw address bytes.
   273  func (aa AccAddress) Bytes() []byte {
   274  	return aa
   275  }
   276  
   277  // String implements the Stringer interface.
   278  func (aa AccAddress) String() string {
   279  	if aa.Empty() {
   280  		return ""
   281  	}
   282  
   283  	return aa.Bech32StringOptimized(GetConfig().GetBech32AccountAddrPrefix())
   284  }
   285  
   286  // Bech32String convert account address to bech32 address.
   287  func (aa AccAddress) Bech32String(bech32PrefixAccAddr string) string {
   288  	bech32Addr, err := bech32.ConvertAndEncode(bech32PrefixAccAddr, aa.Bytes())
   289  	if err != nil {
   290  		panic(err)
   291  	}
   292  
   293  	return bech32Addr
   294  }
   295  
   296  // Format implements the fmt.Formatter interface.
   297  // nolint: errcheck
   298  func (aa AccAddress) Format(s fmt.State, verb rune) {
   299  	switch verb {
   300  	case 's':
   301  		s.Write([]byte(aa.String()))
   302  	case 'p':
   303  		s.Write([]byte(fmt.Sprintf("%p", aa)))
   304  	default:
   305  		s.Write([]byte(fmt.Sprintf("%X", []byte(aa))))
   306  	}
   307  }
   308  
   309  // ----------------------------------------------------------------------------
   310  // validator operator
   311  // ----------------------------------------------------------------------------
   312  
   313  // ValAddress defines a wrapper around bytes meant to present a validator's
   314  // operator. When marshaled to a string or JSON, it uses Bech32.
   315  type ValAddress []byte
   316  
   317  // ValAddressFromHex creates a ValAddress from a hex string.
   318  func ValAddressFromHex(address string) (addr ValAddress, err error) {
   319  	if len(address) == 0 {
   320  		return addr, errors.New("decoding Bech32 address failed: must provide an address")
   321  	}
   322  
   323  	bz, err := hex.DecodeString(address)
   324  	if err != nil {
   325  		return nil, err
   326  	}
   327  
   328  	return ValAddress(bz), nil
   329  }
   330  
   331  // ValAddressFromBech32 creates a ValAddress from a Bech32 string.
   332  func ValAddressFromBech32(address string) (addr ValAddress, err error) {
   333  	if len(strings.TrimSpace(address)) == 0 {
   334  		return nil, errors.New("empty address string is not allowed")
   335  	}
   336  
   337  	bech32PrefixValAddr := GetConfig().GetBech32ValidatorAddrPrefix()
   338  
   339  	bz, err := GetFromBech32(address, bech32PrefixValAddr)
   340  	if err != nil {
   341  		return nil, err
   342  	}
   343  
   344  	err = VerifyAddressFormat(bz)
   345  	if err != nil {
   346  		return nil, err
   347  	}
   348  
   349  	return ValAddress(bz), nil
   350  }
   351  
   352  // Returns boolean for whether two ValAddresses are Equal
   353  func (va ValAddress) Equals(va2 Address) bool {
   354  	if va.Empty() && va2.Empty() {
   355  		return true
   356  	}
   357  
   358  	return bytes.Equal(va.Bytes(), va2.Bytes())
   359  }
   360  
   361  // Returns boolean for whether an AccAddress is empty
   362  func (va ValAddress) Empty() bool {
   363  	if va == nil {
   364  		return true
   365  	}
   366  
   367  	va2 := ValAddress{}
   368  	return bytes.Equal(va.Bytes(), va2.Bytes())
   369  }
   370  
   371  // Marshal returns the raw address bytes. It is needed for protobuf
   372  // compatibility.
   373  func (va ValAddress) Marshal() ([]byte, error) {
   374  	return va, nil
   375  }
   376  
   377  // Unmarshal sets the address to the given data. It is needed for protobuf
   378  // compatibility.
   379  func (va *ValAddress) Unmarshal(data []byte) error {
   380  	*va = data
   381  	return nil
   382  }
   383  
   384  // MarshalJSON marshals to JSON using Bech32.
   385  func (va ValAddress) MarshalJSON() ([]byte, error) {
   386  	return json.Marshal(va.String())
   387  }
   388  
   389  // MarshalYAML marshals to YAML using Bech32.
   390  func (va ValAddress) MarshalYAML() (interface{}, error) {
   391  	return va.String(), nil
   392  }
   393  
   394  // UnmarshalJSON unmarshals from JSON assuming Bech32 encoding.
   395  func (va *ValAddress) UnmarshalJSON(data []byte) error {
   396  	var s string
   397  
   398  	err := json.Unmarshal(data, &s)
   399  	if err != nil {
   400  		return err
   401  	}
   402  
   403  	if s == "" {
   404  		*va = ValAddress{}
   405  		return nil
   406  	}
   407  
   408  	va2, err := ValAddressFromBech32(s)
   409  	if err != nil {
   410  		return err
   411  	}
   412  
   413  	*va = va2
   414  	return nil
   415  }
   416  
   417  // UnmarshalYAML unmarshals from YAML assuming Bech32 encoding.
   418  func (va *ValAddress) UnmarshalYAML(data []byte) error {
   419  	var s string
   420  
   421  	err := yaml.Unmarshal(data, &s)
   422  	if err != nil {
   423  		return err
   424  	}
   425  
   426  	if s == "" {
   427  		*va = ValAddress{}
   428  		return nil
   429  	}
   430  	va2, err := ValAddressFromBech32(s)
   431  	if err != nil {
   432  		return err
   433  	}
   434  
   435  	*va = va2
   436  	return nil
   437  }
   438  
   439  // Bytes returns the raw address bytes.
   440  func (va ValAddress) Bytes() []byte {
   441  	return va
   442  }
   443  
   444  // String implements the Stringer interface.
   445  func (va ValAddress) String() string {
   446  	if va.Empty() {
   447  		return ""
   448  	}
   449  
   450  	bech32PrefixValAddr := GetConfig().GetBech32ValidatorAddrPrefix()
   451  
   452  	bech32Addr, err := bech32.ConvertAndEncode(bech32PrefixValAddr, va.Bytes())
   453  	if err != nil {
   454  		panic(err)
   455  	}
   456  
   457  	return bech32Addr
   458  }
   459  
   460  // Format implements the fmt.Formatter interface.
   461  // nolint: errcheck
   462  func (va ValAddress) Format(s fmt.State, verb rune) {
   463  	switch verb {
   464  	case 's':
   465  		s.Write([]byte(va.String()))
   466  	case 'p':
   467  		s.Write([]byte(fmt.Sprintf("%p", va)))
   468  	default:
   469  		s.Write([]byte(fmt.Sprintf("%X", []byte(va))))
   470  	}
   471  }
   472  
   473  // ----------------------------------------------------------------------------
   474  // consensus node
   475  // ----------------------------------------------------------------------------
   476  
   477  // ConsAddress defines a wrapper around bytes meant to present a consensus node.
   478  // When marshaled to a string or JSON, it uses Bech32.
   479  type ConsAddress []byte
   480  
   481  // ConsAddressFromHex creates a ConsAddress from a hex string.
   482  func ConsAddressFromHex(address string) (addr ConsAddress, err error) {
   483  	if len(address) == 0 {
   484  		return addr, errors.New("decoding Bech32 address failed: must provide an address")
   485  	}
   486  
   487  	bz, err := hex.DecodeString(address)
   488  	if err != nil {
   489  		return nil, err
   490  	}
   491  
   492  	return ConsAddress(bz), nil
   493  }
   494  
   495  // ConsAddressFromBech32 creates a ConsAddress from a Bech32 string.
   496  func ConsAddressFromBech32(address string) (addr ConsAddress, err error) {
   497  	if len(strings.TrimSpace(address)) == 0 {
   498  		return ConsAddress{}, errors.New("empty address string is not allowed")
   499  	}
   500  
   501  	bech32PrefixConsAddr := GetConfig().GetBech32ConsensusAddrPrefix()
   502  
   503  	bz, err := GetFromBech32(address, bech32PrefixConsAddr)
   504  	if err != nil {
   505  		return nil, err
   506  	}
   507  
   508  	err = VerifyAddressFormat(bz)
   509  	if err != nil {
   510  		return nil, err
   511  	}
   512  
   513  	return ConsAddress(bz), nil
   514  }
   515  
   516  // get ConsAddress from pubkey
   517  func GetConsAddress(pubkey crypto.PubKey) ConsAddress {
   518  	return ConsAddress(pubkey.Address())
   519  }
   520  
   521  // Returns boolean for whether two ConsAddress are Equal
   522  func (ca ConsAddress) Equals(ca2 Address) bool {
   523  	if ca.Empty() && ca2.Empty() {
   524  		return true
   525  	}
   526  
   527  	return bytes.Equal(ca.Bytes(), ca2.Bytes())
   528  }
   529  
   530  // Returns boolean for whether an ConsAddress is empty
   531  func (ca ConsAddress) Empty() bool {
   532  	if ca == nil {
   533  		return true
   534  	}
   535  
   536  	ca2 := ConsAddress{}
   537  	return bytes.Equal(ca.Bytes(), ca2.Bytes())
   538  }
   539  
   540  // Marshal returns the raw address bytes. It is needed for protobuf
   541  // compatibility.
   542  func (ca ConsAddress) Marshal() ([]byte, error) {
   543  	return ca, nil
   544  }
   545  
   546  // Unmarshal sets the address to the given data. It is needed for protobuf
   547  // compatibility.
   548  func (ca *ConsAddress) Unmarshal(data []byte) error {
   549  	*ca = data
   550  	return nil
   551  }
   552  
   553  // MarshalJSON marshals to JSON using Bech32.
   554  func (ca ConsAddress) MarshalJSON() ([]byte, error) {
   555  	return json.Marshal(ca.String())
   556  }
   557  
   558  // MarshalYAML marshals to YAML using Bech32.
   559  func (ca ConsAddress) MarshalYAML() (interface{}, error) {
   560  	return ca.String(), nil
   561  }
   562  
   563  // UnmarshalJSON unmarshals from JSON assuming Bech32 encoding.
   564  func (ca *ConsAddress) UnmarshalJSON(data []byte) error {
   565  	var s string
   566  
   567  	err := json.Unmarshal(data, &s)
   568  	if err != nil {
   569  		return err
   570  	}
   571  
   572  	if s == "" {
   573  		*ca = ConsAddress{}
   574  		return nil
   575  	}
   576  
   577  	ca2, err := ConsAddressFromBech32(s)
   578  	if err != nil {
   579  		return err
   580  	}
   581  
   582  	*ca = ca2
   583  	return nil
   584  }
   585  
   586  // UnmarshalYAML unmarshals from YAML assuming Bech32 encoding.
   587  func (ca *ConsAddress) UnmarshalYAML(data []byte) error {
   588  	var s string
   589  
   590  	err := yaml.Unmarshal(data, &s)
   591  	if err != nil {
   592  		return err
   593  	}
   594  
   595  	if s == "" {
   596  		*ca = ConsAddress{}
   597  		return nil
   598  	}
   599  
   600  	ca2, err := ConsAddressFromBech32(s)
   601  	if err != nil {
   602  		return err
   603  	}
   604  
   605  	*ca = ca2
   606  	return nil
   607  }
   608  
   609  // Bytes returns the raw address bytes.
   610  func (ca ConsAddress) Bytes() []byte {
   611  	return ca
   612  }
   613  
   614  // String implements the Stringer interface.
   615  func (ca ConsAddress) String() string {
   616  	if ca.Empty() {
   617  		return ""
   618  	}
   619  
   620  	bech32PrefixConsAddr := GetConfig().GetBech32ConsensusAddrPrefix()
   621  
   622  	bech32Addr, err := bech32.ConvertAndEncode(bech32PrefixConsAddr, ca.Bytes())
   623  	if err != nil {
   624  		panic(err)
   625  	}
   626  
   627  	return bech32Addr
   628  }
   629  
   630  // Format implements the fmt.Formatter interface.
   631  // nolint: errcheck
   632  func (ca ConsAddress) Format(s fmt.State, verb rune) {
   633  	switch verb {
   634  	case 's':
   635  		s.Write([]byte(ca.String()))
   636  	case 'p':
   637  		s.Write([]byte(fmt.Sprintf("%p", ca)))
   638  	default:
   639  		s.Write([]byte(fmt.Sprintf("%X", []byte(ca))))
   640  	}
   641  }
   642  
   643  // ----------------------------------------------------------------------------
   644  // auxiliary
   645  // ----------------------------------------------------------------------------
   646  
   647  // Bech32PubKeyType defines a string type alias for a Bech32 public key type.
   648  type Bech32PubKeyType string
   649  
   650  // Bech32 conversion constants
   651  const (
   652  	Bech32PubKeyTypeAccPub  Bech32PubKeyType = "accpub"
   653  	Bech32PubKeyTypeValPub  Bech32PubKeyType = "valpub"
   654  	Bech32PubKeyTypeConsPub Bech32PubKeyType = "conspub"
   655  )
   656  
   657  // Bech32ifyPubKey returns a Bech32 encoded string containing the appropriate
   658  // prefix based on the key type provided for a given PublicKey.
   659  func Bech32ifyPubKey(pkt Bech32PubKeyType, pubkey crypto.PubKey) (string, error) {
   660  	var bech32Prefix string
   661  
   662  	switch pkt {
   663  	case Bech32PubKeyTypeAccPub:
   664  		bech32Prefix = GetConfig().GetBech32AccountPubPrefix()
   665  
   666  	case Bech32PubKeyTypeValPub:
   667  		bech32Prefix = GetConfig().GetBech32ValidatorPubPrefix()
   668  
   669  	case Bech32PubKeyTypeConsPub:
   670  		bech32Prefix = GetConfig().GetBech32ConsensusPubPrefix()
   671  
   672  	}
   673  
   674  	return bech32.ConvertAndEncode(bech32Prefix, pubkey.Bytes())
   675  }
   676  
   677  // MustBech32ifyPubKey calls Bech32ifyPubKey except it panics on error.
   678  func MustBech32ifyPubKey(pkt Bech32PubKeyType, pubkey crypto.PubKey) string {
   679  	res, err := Bech32ifyPubKey(pkt, pubkey)
   680  	if err != nil {
   681  		panic(err)
   682  	}
   683  
   684  	return res
   685  }
   686  
   687  // GetPubKeyFromBech32 returns a PublicKey from a bech32-encoded PublicKey with
   688  // a given key type.
   689  func GetPubKeyFromBech32(pkt Bech32PubKeyType, pubkeyStr string) (crypto.PubKey, error) {
   690  	var bech32Prefix string
   691  
   692  	switch pkt {
   693  	case Bech32PubKeyTypeAccPub:
   694  		bech32Prefix = GetConfig().GetBech32AccountPubPrefix()
   695  
   696  	case Bech32PubKeyTypeValPub:
   697  		bech32Prefix = GetConfig().GetBech32ValidatorPubPrefix()
   698  
   699  	case Bech32PubKeyTypeConsPub:
   700  		bech32Prefix = GetConfig().GetBech32ConsensusPubPrefix()
   701  
   702  	}
   703  
   704  	bz, err := GetFromBech32(pubkeyStr, bech32Prefix)
   705  	if err != nil {
   706  		return nil, err
   707  	}
   708  
   709  	pk, err := tmamino.PubKeyFromBytes(bz)
   710  	if err != nil {
   711  		return nil, err
   712  	}
   713  
   714  	return pk, nil
   715  }
   716  
   717  // MustGetPubKeyFromBech32 calls GetPubKeyFromBech32 except it panics on error.
   718  func MustGetPubKeyFromBech32(pkt Bech32PubKeyType, pubkeyStr string) crypto.PubKey {
   719  	res, err := GetPubKeyFromBech32(pkt, pubkeyStr)
   720  	if err != nil {
   721  		panic(err)
   722  	}
   723  
   724  	return res
   725  }
   726  
   727  // GetFromBech32 decodes a bytestring from a Bech32 encoded string.
   728  func GetFromBech32(bech32str, prefix string) ([]byte, error) {
   729  	if len(bech32str) == 0 {
   730  		return nil, errors.New("decoding Bech32 address failed: must provide an address")
   731  	}
   732  
   733  	hrp, bz, err := bech32.DecodeAndConvert(bech32str)
   734  	if err != nil {
   735  		return nil, err
   736  	}
   737  
   738  	if hrp != prefix {
   739  		return nil, fmt.Errorf("invalid Bech32 prefix; expected %s, got %s", prefix, hrp)
   740  	}
   741  
   742  	return bz, nil
   743  }