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  }