func (link ChainLink) GetAddressData() AddressData {
	return link.Address.GetCachedValue().(AddressData)
}
GetAddressData returns the AddressData associated with this chain link
package types
import (
	"bytes"
	"encoding/hex"
	"fmt"
	"strings"
	"time"
	"github.com/cosmos/cosmos-sdk/types/bech32"
	"github.com/tendermint/tendermint/crypto/tmhash"
	"github.com/gogo/protobuf/proto"
	"github.com/mr-tron/base58"
	"github.com/cosmos/cosmos-sdk/codec"
	codectypes "github.com/cosmos/cosmos-sdk/codec/types"
	cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
	sdk "github.com/cosmos/cosmos-sdk/types"
)
func NewChainConfig(name string) ChainConfig {
	return ChainConfig{
		Name: name,
	}
}
func (c ChainConfig) Validate() error {
	if strings.TrimSpace(c.Name) == "" {
		return fmt.Errorf("chain name cannot be empty or blank")
	}
	if c.Name != strings.ToLower(c.Name) {
		return fmt.Errorf("chain name must be lowercase")
	}
	return nil
}
func NewProof(pubKey cryptotypes.PubKey, signature string, plainText string) Proof {
	pubKeyAny, err := codectypes.NewAnyWithValue(pubKey)
	if err != nil {
		panic("failed to pack public key to any type")
	}
	return Proof{
		PubKey:    pubKeyAny,
		Signature: signature,
		PlainText: plainText,
	}
}
func (p Proof) Validate() error {
	if p.PubKey == nil {
		return fmt.Errorf("public key field cannot be nil")
	}
	_, err := hex.DecodeString(p.Signature)
	if err != nil {
		return fmt.Errorf("invalid hex-encoded signature")
	}
	if strings.TrimSpace(p.PlainText) == "" {
		return fmt.Errorf("plain text cannot be empty or blank")
	}
	_, err = hex.DecodeString(p.PlainText)
	if err != nil {
		return fmt.Errorf("invalid hex-encoded plain text")
	}
	return nil
}
func (p Proof) Verify(unpacker codectypes.AnyUnpacker, address AddressData) error {
	var pubkey cryptotypes.PubKey
	err := unpacker.UnpackAny(p.PubKey, &pubkey)
	if err != nil {
		return fmt.Errorf("failed to unpack the public key")
	}
	value, _ := hex.DecodeString(p.PlainText)
	sig, _ := hex.DecodeString(p.Signature)
	if !pubkey.VerifySignature(value, sig) {
		return fmt.Errorf("failed to verify the signature")
	}
	valid, err := address.VerifyPubKey(pubkey)
	if err != nil {
		return err
	}
	if !valid {
		return fmt.Errorf("invalid address and public key combination provided")
	}
	return nil
}
func (p *Proof) UnpackInterfaces(unpacker codectypes.AnyUnpacker) error {
	var pubKey cryptotypes.PubKey
	return unpacker.UnpackAny(p.PubKey, &pubKey)
}
type AddressData interface {
	proto.Message
	Validate() error
	GetValue() string
	VerifyPubKey(key cryptotypes.PubKey) (bool, error)
}
var _ AddressData = &Bech32Address{}
func NewBech32Address(value, prefix string) *Bech32Address {
	return &Bech32Address{Value: value, Prefix: prefix}
}
func (b Bech32Address) Validate() error {
	if strings.TrimSpace(b.Value) == "" {
		return fmt.Errorf("value cannot be empty or blank")
	}
	if strings.TrimSpace(b.Prefix) == "" {
		return fmt.Errorf("prefix cannot be empty or blank")
	}
	_, err := sdk.GetFromBech32(b.Value, b.Prefix)
	if err != nil {
		return fmt.Errorf("invalid Bech32 value or wrong prefix")
	}
	return nil
}
func (b Bech32Address) GetValue() string {
	return b.Value
}
func (b Bech32Address) VerifyPubKey(key cryptotypes.PubKey) (bool, error) {
	_, bz, err := bech32.DecodeAndConvert(b.Value)
	if err != nil {
		return false, err
	}
	return bytes.Equal(bz, key.Address().Bytes()), nil
}
var _ AddressData = &Base58Address{}
func NewBase58Address(value string) *Base58Address {
	return &Base58Address{Value: value}
}
func (b Base58Address) Validate() error {
	if strings.TrimSpace(b.Value) == "" {
		return fmt.Errorf("address cannot be empty or blank")
	}
	if _, err := base58.Decode(b.Value); err != nil {
		return fmt.Errorf("invalid Base58 address")
	}
	return nil
}
func (b Base58Address) GetValue() string {
	return b.Value
}
func (b Base58Address) VerifyPubKey(key cryptotypes.PubKey) (bool, error) {
	bz, err := base58.Decode(b.Value)
	return bytes.Equal(tmhash.SumTruncated(bz), key.Address().Bytes()), err
}
func UnpackAddressData(unpacker codectypes.AnyUnpacker, addressAny *codectypes.Any) (AddressData, error) {
	var address AddressData
	if err := unpacker.UnpackAny(addressAny, &address); err != nil {
		return nil, err
	}
	return address, nil
}
func NewChainLink(user string, address AddressData, proof Proof, chainConfig ChainConfig, creationTime time.Time) ChainLink {
	addressAny, err := codectypes.NewAnyWithValue(address)
	if err != nil {
		panic("failed to pack address data to any type")
	}
	return ChainLink{
		User:         user,
		Address:      addressAny,
		Proof:        proof,
		ChainConfig:  chainConfig,
		CreationTime: creationTime,
	}
}