github.com/cosmos/cosmos-sdk@v0.50.1/crypto/keyring/record.go (about) 1 package keyring 2 3 import ( 4 "github.com/cockroachdb/errors" 5 6 errorsmod "cosmossdk.io/errors" 7 8 codectypes "github.com/cosmos/cosmos-sdk/codec/types" 9 "github.com/cosmos/cosmos-sdk/crypto/hd" 10 cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" 11 "github.com/cosmos/cosmos-sdk/types" 12 ) 13 14 var ( 15 // ErrPrivKeyExtr is used to output an error if extraction of a private key from Local item fails. 16 ErrPrivKeyExtr = errors.New("private key extraction works only for Local") 17 // ErrPrivKeyNotAvailable is used when a Record_Local.PrivKey is nil. 18 ErrPrivKeyNotAvailable = errors.New("private key is not available") 19 // ErrCastAny is used to output an error if cast from types.Any fails. 20 ErrCastAny = errors.New("unable to cast to cryptotypes") 21 ) 22 23 func newRecord(name string, pk cryptotypes.PubKey, item isRecord_Item) (*Record, error) { 24 any, err := codectypes.NewAnyWithValue(pk) 25 if err != nil { 26 return nil, err 27 } 28 29 return &Record{name, any, item}, nil 30 } 31 32 // NewLocalRecord creates a new Record with local key item 33 func NewLocalRecord(name string, priv cryptotypes.PrivKey, pk cryptotypes.PubKey) (*Record, error) { 34 any, err := codectypes.NewAnyWithValue(priv) 35 if err != nil { 36 return nil, err 37 } 38 39 recordLocal := &Record_Local{any} 40 recordLocalItem := &Record_Local_{recordLocal} 41 42 return newRecord(name, pk, recordLocalItem) 43 } 44 45 // NewLedgerRecord creates a new Record with ledger item 46 func NewLedgerRecord(name string, pk cryptotypes.PubKey, path *hd.BIP44Params) (*Record, error) { 47 recordLedger := &Record_Ledger{path} 48 recordLedgerItem := &Record_Ledger_{recordLedger} 49 return newRecord(name, pk, recordLedgerItem) 50 } 51 52 func (rl *Record_Ledger) GetPath() *hd.BIP44Params { 53 return rl.Path 54 } 55 56 // NewOfflineRecord creates a new Record with offline item 57 func NewOfflineRecord(name string, pk cryptotypes.PubKey) (*Record, error) { 58 recordOffline := &Record_Offline{} 59 recordOfflineItem := &Record_Offline_{recordOffline} 60 return newRecord(name, pk, recordOfflineItem) 61 } 62 63 // NewMultiRecord creates a new Record with multi item 64 func NewMultiRecord(name string, pk cryptotypes.PubKey) (*Record, error) { 65 recordMulti := &Record_Multi{} 66 recordMultiItem := &Record_Multi_{recordMulti} 67 return newRecord(name, pk, recordMultiItem) 68 } 69 70 // GetPubKey fetches a public key of the record 71 func (k *Record) GetPubKey() (cryptotypes.PubKey, error) { 72 pk, ok := k.PubKey.GetCachedValue().(cryptotypes.PubKey) 73 if !ok { 74 return nil, errorsmod.Wrap(ErrCastAny, "PubKey") 75 } 76 77 return pk, nil 78 } 79 80 // GetAddress fetches an address of the record 81 func (k Record) GetAddress() (types.AccAddress, error) { 82 pk, err := k.GetPubKey() 83 if err != nil { 84 return nil, err 85 } 86 return pk.Address().Bytes(), nil 87 } 88 89 // GetType fetches type of the record 90 func (k Record) GetType() KeyType { 91 switch { 92 case k.GetLocal() != nil: 93 return TypeLocal 94 case k.GetLedger() != nil: 95 return TypeLedger 96 case k.GetMulti() != nil: 97 return TypeMulti 98 case k.GetOffline() != nil: 99 return TypeOffline 100 default: 101 panic("unrecognized record type") 102 } 103 } 104 105 // UnpackInterfaces implements UnpackInterfacesMessage.UnpackInterfaces 106 func (k *Record) UnpackInterfaces(unpacker codectypes.AnyUnpacker) error { 107 var pk cryptotypes.PubKey 108 if err := unpacker.UnpackAny(k.PubKey, &pk); err != nil { 109 return err 110 } 111 112 if l := k.GetLocal(); l != nil { 113 var priv cryptotypes.PrivKey 114 return unpacker.UnpackAny(l.PrivKey, &priv) 115 } 116 117 return nil 118 } 119 120 func extractPrivKeyFromRecord(k *Record) (cryptotypes.PrivKey, error) { 121 rl := k.GetLocal() 122 if rl == nil { 123 return nil, ErrPrivKeyExtr 124 } 125 126 return extractPrivKeyFromLocal(rl) 127 } 128 129 func extractPrivKeyFromLocal(rl *Record_Local) (cryptotypes.PrivKey, error) { 130 if rl.PrivKey == nil { 131 return nil, ErrPrivKeyNotAvailable 132 } 133 134 priv, ok := rl.PrivKey.GetCachedValue().(cryptotypes.PrivKey) 135 if !ok { 136 return nil, errorsmod.Wrap(ErrCastAny, "PrivKey") 137 } 138 139 return priv, nil 140 }