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 }