2020-03-25 08:20:36 -07:00
|
|
|
package keyring
|
2018-06-28 17:54:47 -07:00
|
|
|
|
|
|
|
import (
|
2019-02-25 03:34:39 -08:00
|
|
|
"fmt"
|
2018-06-28 17:54:47 -07:00
|
|
|
|
2020-12-02 05:50:50 -08:00
|
|
|
"github.com/cosmos/cosmos-sdk/codec/legacy"
|
2020-09-18 02:40:39 -07:00
|
|
|
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
|
2020-04-08 02:38:28 -07:00
|
|
|
"github.com/cosmos/cosmos-sdk/crypto/hd"
|
2020-09-18 02:40:39 -07:00
|
|
|
"github.com/cosmos/cosmos-sdk/crypto/keys/multisig"
|
2020-11-09 08:01:43 -08:00
|
|
|
cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
|
2018-09-25 13:48:38 -07:00
|
|
|
"github.com/cosmos/cosmos-sdk/types"
|
2018-06-28 17:54:47 -07:00
|
|
|
)
|
|
|
|
|
|
|
|
// Info is the publicly exposed information about a keypair
|
|
|
|
type Info interface {
|
|
|
|
// Human-readable type for key listing
|
2018-08-06 11:11:30 -07:00
|
|
|
GetType() KeyType
|
2018-06-28 17:54:47 -07:00
|
|
|
// Name of the key
|
|
|
|
GetName() string
|
|
|
|
// Public key
|
2020-11-09 08:01:43 -08:00
|
|
|
GetPubKey() cryptotypes.PubKey
|
2018-09-25 13:48:38 -07:00
|
|
|
// Address
|
|
|
|
GetAddress() types.AccAddress
|
2019-02-25 03:34:39 -08:00
|
|
|
// Bip44 Path
|
|
|
|
GetPath() (*hd.BIP44Params, error)
|
2020-01-15 05:38:09 -08:00
|
|
|
// Algo
|
2020-04-08 02:38:28 -07:00
|
|
|
GetAlgo() hd.PubKeyType
|
2018-06-28 17:54:47 -07:00
|
|
|
}
|
|
|
|
|
2019-03-01 13:29:33 -08:00
|
|
|
var (
|
|
|
|
_ Info = &localInfo{}
|
|
|
|
_ Info = &ledgerInfo{}
|
|
|
|
_ Info = &offlineInfo{}
|
|
|
|
_ Info = &multiInfo{}
|
|
|
|
)
|
2018-06-28 17:54:47 -07:00
|
|
|
|
|
|
|
// localInfo is the public information about a locally stored key
|
2020-01-15 05:38:09 -08:00
|
|
|
// Note: Algo must be last field in struct for backwards amino compatibility
|
2018-06-28 17:54:47 -07:00
|
|
|
type localInfo struct {
|
2020-11-09 08:01:43 -08:00
|
|
|
Name string `json:"name"`
|
|
|
|
PubKey cryptotypes.PubKey `json:"pubkey"`
|
|
|
|
PrivKeyArmor string `json:"privkey.armor"`
|
|
|
|
Algo hd.PubKeyType `json:"algo"`
|
2018-06-28 17:54:47 -07:00
|
|
|
}
|
|
|
|
|
2020-11-09 08:01:43 -08:00
|
|
|
func newLocalInfo(name string, pub cryptotypes.PubKey, privArmor string, algo hd.PubKeyType) Info {
|
2018-06-28 17:54:47 -07:00
|
|
|
return &localInfo{
|
|
|
|
Name: name,
|
|
|
|
PubKey: pub,
|
|
|
|
PrivKeyArmor: privArmor,
|
2020-01-14 07:40:10 -08:00
|
|
|
Algo: algo,
|
2018-06-28 17:54:47 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-07-31 08:47:18 -07:00
|
|
|
// GetType implements Info interface
|
2018-08-06 11:11:30 -07:00
|
|
|
func (i localInfo) GetType() KeyType {
|
|
|
|
return TypeLocal
|
2018-06-28 17:54:47 -07:00
|
|
|
}
|
|
|
|
|
2019-07-31 08:47:18 -07:00
|
|
|
// GetType implements Info interface
|
2018-06-28 17:54:47 -07:00
|
|
|
func (i localInfo) GetName() string {
|
|
|
|
return i.Name
|
|
|
|
}
|
|
|
|
|
2019-07-31 08:47:18 -07:00
|
|
|
// GetType implements Info interface
|
2020-11-09 08:01:43 -08:00
|
|
|
func (i localInfo) GetPubKey() cryptotypes.PubKey {
|
2018-06-28 17:54:47 -07:00
|
|
|
return i.PubKey
|
|
|
|
}
|
|
|
|
|
2019-07-31 08:47:18 -07:00
|
|
|
// GetType implements Info interface
|
2018-09-25 13:48:38 -07:00
|
|
|
func (i localInfo) GetAddress() types.AccAddress {
|
|
|
|
return i.PubKey.Address().Bytes()
|
|
|
|
}
|
|
|
|
|
2020-01-14 07:40:10 -08:00
|
|
|
// GetType implements Info interface
|
2020-04-08 02:38:28 -07:00
|
|
|
func (i localInfo) GetAlgo() hd.PubKeyType {
|
2020-01-14 07:40:10 -08:00
|
|
|
return i.Algo
|
|
|
|
}
|
|
|
|
|
2019-07-31 08:47:18 -07:00
|
|
|
// GetType implements Info interface
|
2019-02-25 03:34:39 -08:00
|
|
|
func (i localInfo) GetPath() (*hd.BIP44Params, error) {
|
|
|
|
return nil, fmt.Errorf("BIP44 Paths are not available for this type")
|
|
|
|
}
|
|
|
|
|
2018-06-28 17:54:47 -07:00
|
|
|
// ledgerInfo is the public information about a Ledger key
|
2020-01-15 05:38:09 -08:00
|
|
|
// Note: Algo must be last field in struct for backwards amino compatibility
|
2018-06-28 17:54:47 -07:00
|
|
|
type ledgerInfo struct {
|
2020-11-09 08:01:43 -08:00
|
|
|
Name string `json:"name"`
|
|
|
|
PubKey cryptotypes.PubKey `json:"pubkey"`
|
|
|
|
Path hd.BIP44Params `json:"path"`
|
|
|
|
Algo hd.PubKeyType `json:"algo"`
|
2018-06-28 17:54:47 -07:00
|
|
|
}
|
|
|
|
|
2020-11-09 08:01:43 -08:00
|
|
|
func newLedgerInfo(name string, pub cryptotypes.PubKey, path hd.BIP44Params, algo hd.PubKeyType) Info {
|
2018-06-28 17:54:47 -07:00
|
|
|
return &ledgerInfo{
|
|
|
|
Name: name,
|
|
|
|
PubKey: pub,
|
|
|
|
Path: path,
|
2020-01-14 07:40:10 -08:00
|
|
|
Algo: algo,
|
2018-06-28 17:54:47 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-07-31 08:47:18 -07:00
|
|
|
// GetType implements Info interface
|
2018-08-06 11:11:30 -07:00
|
|
|
func (i ledgerInfo) GetType() KeyType {
|
|
|
|
return TypeLedger
|
2018-06-28 17:54:47 -07:00
|
|
|
}
|
|
|
|
|
2019-07-31 08:47:18 -07:00
|
|
|
// GetName implements Info interface
|
2018-06-28 17:54:47 -07:00
|
|
|
func (i ledgerInfo) GetName() string {
|
|
|
|
return i.Name
|
|
|
|
}
|
|
|
|
|
2019-07-31 08:47:18 -07:00
|
|
|
// GetPubKey implements Info interface
|
2020-11-09 08:01:43 -08:00
|
|
|
func (i ledgerInfo) GetPubKey() cryptotypes.PubKey {
|
2018-06-28 17:54:47 -07:00
|
|
|
return i.PubKey
|
|
|
|
}
|
|
|
|
|
2019-07-31 08:47:18 -07:00
|
|
|
// GetAddress implements Info interface
|
2018-09-25 13:48:38 -07:00
|
|
|
func (i ledgerInfo) GetAddress() types.AccAddress {
|
|
|
|
return i.PubKey.Address().Bytes()
|
|
|
|
}
|
|
|
|
|
2020-01-14 07:40:10 -08:00
|
|
|
// GetPath implements Info interface
|
2020-04-08 02:38:28 -07:00
|
|
|
func (i ledgerInfo) GetAlgo() hd.PubKeyType {
|
2020-01-14 07:40:10 -08:00
|
|
|
return i.Algo
|
|
|
|
}
|
|
|
|
|
2019-07-31 08:47:18 -07:00
|
|
|
// GetPath implements Info interface
|
2019-02-25 03:34:39 -08:00
|
|
|
func (i ledgerInfo) GetPath() (*hd.BIP44Params, error) {
|
|
|
|
tmp := i.Path
|
|
|
|
return &tmp, nil
|
2019-02-11 09:02:47 -08:00
|
|
|
}
|
|
|
|
|
2018-06-28 17:54:47 -07:00
|
|
|
// offlineInfo is the public information about an offline key
|
2020-01-15 05:38:09 -08:00
|
|
|
// Note: Algo must be last field in struct for backwards amino compatibility
|
2018-06-28 17:54:47 -07:00
|
|
|
type offlineInfo struct {
|
2020-11-09 08:01:43 -08:00
|
|
|
Name string `json:"name"`
|
|
|
|
PubKey cryptotypes.PubKey `json:"pubkey"`
|
|
|
|
Algo hd.PubKeyType `json:"algo"`
|
2018-06-28 17:54:47 -07:00
|
|
|
}
|
|
|
|
|
2020-11-09 08:01:43 -08:00
|
|
|
func newOfflineInfo(name string, pub cryptotypes.PubKey, algo hd.PubKeyType) Info {
|
2018-06-28 17:54:47 -07:00
|
|
|
return &offlineInfo{
|
|
|
|
Name: name,
|
|
|
|
PubKey: pub,
|
2020-01-14 07:40:10 -08:00
|
|
|
Algo: algo,
|
2018-06-28 17:54:47 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-07-31 08:47:18 -07:00
|
|
|
// GetType implements Info interface
|
2018-08-06 11:11:30 -07:00
|
|
|
func (i offlineInfo) GetType() KeyType {
|
|
|
|
return TypeOffline
|
2018-06-28 17:54:47 -07:00
|
|
|
}
|
|
|
|
|
2019-07-31 08:47:18 -07:00
|
|
|
// GetName implements Info interface
|
2018-06-28 17:54:47 -07:00
|
|
|
func (i offlineInfo) GetName() string {
|
|
|
|
return i.Name
|
|
|
|
}
|
|
|
|
|
2019-07-31 08:47:18 -07:00
|
|
|
// GetPubKey implements Info interface
|
2020-11-09 08:01:43 -08:00
|
|
|
func (i offlineInfo) GetPubKey() cryptotypes.PubKey {
|
2018-06-28 17:54:47 -07:00
|
|
|
return i.PubKey
|
|
|
|
}
|
|
|
|
|
2020-01-14 07:40:10 -08:00
|
|
|
// GetAlgo returns the signing algorithm for the key
|
2020-04-08 02:38:28 -07:00
|
|
|
func (i offlineInfo) GetAlgo() hd.PubKeyType {
|
2020-01-14 07:40:10 -08:00
|
|
|
return i.Algo
|
|
|
|
}
|
|
|
|
|
2019-07-31 08:47:18 -07:00
|
|
|
// GetAddress implements Info interface
|
2018-09-25 13:48:38 -07:00
|
|
|
func (i offlineInfo) GetAddress() types.AccAddress {
|
|
|
|
return i.PubKey.Address().Bytes()
|
|
|
|
}
|
|
|
|
|
2019-07-31 08:47:18 -07:00
|
|
|
// GetPath implements Info interface
|
2019-02-25 03:34:39 -08:00
|
|
|
func (i offlineInfo) GetPath() (*hd.BIP44Params, error) {
|
|
|
|
return nil, fmt.Errorf("BIP44 Paths are not available for this type")
|
|
|
|
}
|
|
|
|
|
2021-03-25 07:53:22 -07:00
|
|
|
// Deprecated: this structure is not used anymore and it's here only to allow
|
|
|
|
// decoding old multiInfo records from keyring.
|
2021-04-29 03:46:22 -07:00
|
|
|
// The problem with legacy.Cdc.UnmarshalLengthPrefixed - the legacy codec doesn't
|
2021-03-25 07:53:22 -07:00
|
|
|
// tolerate extensibility.
|
2019-03-01 13:29:33 -08:00
|
|
|
type multisigPubKeyInfo struct {
|
2020-11-09 08:01:43 -08:00
|
|
|
PubKey cryptotypes.PubKey `json:"pubkey"`
|
|
|
|
Weight uint `json:"weight"`
|
2019-03-01 13:29:33 -08:00
|
|
|
}
|
2019-07-31 08:47:18 -07:00
|
|
|
|
|
|
|
// multiInfo is the public information about a multisig key
|
2019-03-01 13:29:33 -08:00
|
|
|
type multiInfo struct {
|
|
|
|
Name string `json:"name"`
|
2020-11-09 08:01:43 -08:00
|
|
|
PubKey cryptotypes.PubKey `json:"pubkey"`
|
2019-03-01 13:29:33 -08:00
|
|
|
Threshold uint `json:"threshold"`
|
|
|
|
PubKeys []multisigPubKeyInfo `json:"pubkeys"`
|
|
|
|
}
|
|
|
|
|
2019-07-31 08:47:18 -07:00
|
|
|
// NewMultiInfo creates a new multiInfo instance
|
2021-03-25 07:53:22 -07:00
|
|
|
func NewMultiInfo(name string, pub cryptotypes.PubKey) (Info, error) {
|
|
|
|
if _, ok := pub.(*multisig.LegacyAminoPubKey); !ok {
|
|
|
|
return nil, fmt.Errorf("MultiInfo supports only multisig.LegacyAminoPubKey, got %T", pub)
|
2019-03-01 13:29:33 -08:00
|
|
|
}
|
|
|
|
return &multiInfo{
|
2021-03-25 07:53:22 -07:00
|
|
|
Name: name,
|
|
|
|
PubKey: pub,
|
|
|
|
}, nil
|
2019-03-01 13:29:33 -08:00
|
|
|
}
|
|
|
|
|
2019-07-31 08:47:18 -07:00
|
|
|
// GetType implements Info interface
|
2019-03-01 13:29:33 -08:00
|
|
|
func (i multiInfo) GetType() KeyType {
|
|
|
|
return TypeMulti
|
|
|
|
}
|
|
|
|
|
2019-07-31 08:47:18 -07:00
|
|
|
// GetName implements Info interface
|
2019-03-01 13:29:33 -08:00
|
|
|
func (i multiInfo) GetName() string {
|
|
|
|
return i.Name
|
|
|
|
}
|
|
|
|
|
2019-07-31 08:47:18 -07:00
|
|
|
// GetPubKey implements Info interface
|
2020-11-09 08:01:43 -08:00
|
|
|
func (i multiInfo) GetPubKey() cryptotypes.PubKey {
|
2019-03-01 13:29:33 -08:00
|
|
|
return i.PubKey
|
|
|
|
}
|
|
|
|
|
2019-07-31 08:47:18 -07:00
|
|
|
// GetAddress implements Info interface
|
2019-03-01 13:29:33 -08:00
|
|
|
func (i multiInfo) GetAddress() types.AccAddress {
|
|
|
|
return i.PubKey.Address().Bytes()
|
|
|
|
}
|
|
|
|
|
2020-01-14 07:40:10 -08:00
|
|
|
// GetPath implements Info interface
|
2020-04-08 02:38:28 -07:00
|
|
|
func (i multiInfo) GetAlgo() hd.PubKeyType {
|
|
|
|
return hd.MultiType
|
2020-01-14 07:40:10 -08:00
|
|
|
}
|
|
|
|
|
2019-07-31 08:47:18 -07:00
|
|
|
// GetPath implements Info interface
|
2019-03-01 13:29:33 -08:00
|
|
|
func (i multiInfo) GetPath() (*hd.BIP44Params, error) {
|
|
|
|
return nil, fmt.Errorf("BIP44 Paths are not available for this type")
|
|
|
|
}
|
|
|
|
|
2020-09-18 02:40:39 -07:00
|
|
|
// UnpackInterfaces implements UnpackInterfacesMessage.UnpackInterfaces
|
|
|
|
func (i multiInfo) UnpackInterfaces(unpacker codectypes.AnyUnpacker) error {
|
|
|
|
multiPK := i.PubKey.(*multisig.LegacyAminoPubKey)
|
|
|
|
|
|
|
|
return codectypes.UnpackInterfaces(multiPK, unpacker)
|
|
|
|
}
|
|
|
|
|
2018-06-28 17:54:47 -07:00
|
|
|
// encoding info
|
2019-09-21 09:54:14 -07:00
|
|
|
func marshalInfo(i Info) []byte {
|
2021-04-29 03:46:22 -07:00
|
|
|
return legacy.Cdc.MustMarshalLengthPrefixed(i)
|
2018-06-28 17:54:47 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
// decoding info
|
2019-09-21 09:54:14 -07:00
|
|
|
func unmarshalInfo(bz []byte) (info Info, err error) {
|
2021-04-29 03:46:22 -07:00
|
|
|
err = legacy.Cdc.UnmarshalLengthPrefixed(bz, &info)
|
2020-09-18 02:40:39 -07:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
// After unmarshalling into &info, if we notice that the info is a
|
|
|
|
// multiInfo, then we unmarshal again, explicitly in a multiInfo this time.
|
|
|
|
// Since multiInfo implements UnpackInterfacesMessage, this will correctly
|
|
|
|
// unpack the underlying anys inside the multiInfo.
|
|
|
|
//
|
|
|
|
// This is a workaround, as go cannot check that an interface (Info)
|
|
|
|
// implements another interface (UnpackInterfacesMessage).
|
|
|
|
_, ok := info.(multiInfo)
|
|
|
|
if ok {
|
|
|
|
var multi multiInfo
|
2021-04-29 03:46:22 -07:00
|
|
|
err = legacy.Cdc.UnmarshalLengthPrefixed(bz, &multi)
|
2020-09-18 02:40:39 -07:00
|
|
|
|
|
|
|
return multi, err
|
|
|
|
}
|
|
|
|
|
2018-06-28 17:54:47 -07:00
|
|
|
return
|
|
|
|
}
|