cosmossdk.io/client/v2@v2.0.0-beta.1/autocli/flag/address.go (about)

     1  package flag
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  
     7  	"google.golang.org/protobuf/reflect/protoreflect"
     8  
     9  	"cosmossdk.io/client/v2/autocli/keyring"
    10  	"cosmossdk.io/core/address"
    11  
    12  	"github.com/cosmos/cosmos-sdk/codec"
    13  	"github.com/cosmos/cosmos-sdk/codec/types"
    14  	cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec"
    15  	cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
    16  	sdk "github.com/cosmos/cosmos-sdk/types"
    17  )
    18  
    19  type addressStringType struct{}
    20  
    21  func (a addressStringType) NewValue(_ context.Context, b *Builder) Value {
    22  	return &addressValue{addressCodec: b.AddressCodec, keyring: b.Keyring}
    23  }
    24  
    25  func (a addressStringType) DefaultValue() string {
    26  	return ""
    27  }
    28  
    29  type validatorAddressStringType struct{}
    30  
    31  func (a validatorAddressStringType) NewValue(_ context.Context, b *Builder) Value {
    32  	return &addressValue{addressCodec: b.ValidatorAddressCodec, keyring: b.Keyring}
    33  }
    34  
    35  func (a validatorAddressStringType) DefaultValue() string {
    36  	return ""
    37  }
    38  
    39  type addressValue struct {
    40  	value        string
    41  	addressCodec address.Codec
    42  	keyring      keyring.Keyring
    43  }
    44  
    45  func (a addressValue) Get(protoreflect.Value) (protoreflect.Value, error) {
    46  	return protoreflect.ValueOfString(a.value), nil
    47  }
    48  
    49  func (a addressValue) String() string {
    50  	return a.value
    51  }
    52  
    53  // Set implements the flag.Value interface for addressValue.
    54  func (a *addressValue) Set(s string) error {
    55  	addr, err := a.keyring.LookupAddressByKeyName(s)
    56  	if err == nil {
    57  		addrStr, err := a.addressCodec.BytesToString(addr)
    58  		if err != nil {
    59  			return fmt.Errorf("invalid account address got from keyring: %w", err)
    60  		}
    61  
    62  		a.value = addrStr
    63  		return nil
    64  	}
    65  
    66  	_, err = a.addressCodec.StringToBytes(s)
    67  	if err != nil {
    68  		return fmt.Errorf("invalid account address or key name: %w", err)
    69  	}
    70  
    71  	a.value = s
    72  
    73  	return nil
    74  }
    75  
    76  func (a addressValue) Type() string {
    77  	return "account address or key name"
    78  }
    79  
    80  type consensusAddressStringType struct{}
    81  
    82  func (a consensusAddressStringType) NewValue(ctx context.Context, b *Builder) Value {
    83  	return &consensusAddressValue{
    84  		addressValue: addressValue{
    85  			addressCodec: b.ConsensusAddressCodec,
    86  			keyring:      b.Keyring,
    87  		},
    88  	}
    89  }
    90  
    91  func (a consensusAddressStringType) DefaultValue() string {
    92  	return ""
    93  }
    94  
    95  type consensusAddressValue struct {
    96  	addressValue
    97  }
    98  
    99  func (a consensusAddressValue) Get(protoreflect.Value) (protoreflect.Value, error) {
   100  	return protoreflect.ValueOfString(a.value), nil
   101  }
   102  
   103  func (a consensusAddressValue) String() string {
   104  	return a.value
   105  }
   106  
   107  func (a *consensusAddressValue) Set(s string) error {
   108  	addr, err := a.keyring.LookupAddressByKeyName(s)
   109  	if err == nil {
   110  		addrStr, err := a.addressCodec.BytesToString(addr)
   111  		if err != nil {
   112  			return fmt.Errorf("invalid consensus address got from keyring: %w", err)
   113  		}
   114  
   115  		a.value = addrStr
   116  		return nil
   117  	}
   118  
   119  	_, err = a.addressCodec.StringToBytes(s)
   120  	if err == nil {
   121  		a.value = s
   122  		return nil
   123  	}
   124  
   125  	// fallback to pubkey parsing
   126  	registry := types.NewInterfaceRegistry()
   127  	cryptocodec.RegisterInterfaces(registry)
   128  	cdc := codec.NewProtoCodec(registry)
   129  
   130  	var pk cryptotypes.PubKey
   131  	err2 := cdc.UnmarshalInterfaceJSON([]byte(s), &pk)
   132  	if err2 != nil {
   133  		return fmt.Errorf("input isn't a pubkey %w or is an invalid account address: %w", err, err2)
   134  	}
   135  
   136  	a.value = sdk.ConsAddress(pk.Address()).String()
   137  	return nil
   138  }