github.com/Finschia/finschia-sdk@v0.48.1/crypto/keyring/info.go (about)

     1  package keyring
     2  
     3  import (
     4  	"fmt"
     5  
     6  	"github.com/Finschia/finschia-sdk/codec/legacy"
     7  	codectypes "github.com/Finschia/finschia-sdk/codec/types"
     8  	"github.com/Finschia/finschia-sdk/crypto/hd"
     9  	"github.com/Finschia/finschia-sdk/crypto/keys/multisig"
    10  	cryptotypes "github.com/Finschia/finschia-sdk/crypto/types"
    11  	"github.com/Finschia/finschia-sdk/types"
    12  )
    13  
    14  // Info is the publicly exposed information about a keypair
    15  type Info interface {
    16  	// Human-readable type for key listing
    17  	GetType() KeyType
    18  	// Name of the key
    19  	GetName() string
    20  	// Public key
    21  	GetPubKey() cryptotypes.PubKey
    22  	// Address
    23  	GetAddress() types.AccAddress
    24  	// Bip44 Path
    25  	GetPath() (*hd.BIP44Params, error)
    26  	// Algo
    27  	GetAlgo() hd.PubKeyType
    28  }
    29  
    30  var (
    31  	_ Info = &localInfo{}
    32  	_ Info = &ledgerInfo{}
    33  	_ Info = &offlineInfo{}
    34  	_ Info = &multiInfo{}
    35  )
    36  
    37  // localInfo is the public information about a locally stored key
    38  // Note: Algo must be last field in struct for backwards amino compatibility
    39  type localInfo struct {
    40  	Name         string             `json:"name"`
    41  	PubKey       cryptotypes.PubKey `json:"pubkey"`
    42  	PrivKeyArmor string             `json:"privkey.armor"`
    43  	Algo         hd.PubKeyType      `json:"algo"`
    44  }
    45  
    46  func newLocalInfo(name string, pub cryptotypes.PubKey, privArmor string, algo hd.PubKeyType) Info {
    47  	return &localInfo{
    48  		Name:         name,
    49  		PubKey:       pub,
    50  		PrivKeyArmor: privArmor,
    51  		Algo:         algo,
    52  	}
    53  }
    54  
    55  // GetType implements Info interface
    56  func (i localInfo) GetType() KeyType {
    57  	return TypeLocal
    58  }
    59  
    60  // GetType implements Info interface
    61  func (i localInfo) GetName() string {
    62  	return i.Name
    63  }
    64  
    65  // GetType implements Info interface
    66  func (i localInfo) GetPubKey() cryptotypes.PubKey {
    67  	return i.PubKey
    68  }
    69  
    70  // GetType implements Info interface
    71  func (i localInfo) GetAddress() types.AccAddress {
    72  	return i.PubKey.Address().Bytes()
    73  }
    74  
    75  // GetType implements Info interface
    76  func (i localInfo) GetAlgo() hd.PubKeyType {
    77  	return i.Algo
    78  }
    79  
    80  // GetType implements Info interface
    81  func (i localInfo) GetPath() (*hd.BIP44Params, error) {
    82  	return nil, fmt.Errorf("BIP44 Paths are not available for this type")
    83  }
    84  
    85  // ledgerInfo is the public information about a Ledger key
    86  // Note: Algo must be last field in struct for backwards amino compatibility
    87  type ledgerInfo struct {
    88  	Name   string             `json:"name"`
    89  	PubKey cryptotypes.PubKey `json:"pubkey"`
    90  	Path   hd.BIP44Params     `json:"path"`
    91  	Algo   hd.PubKeyType      `json:"algo"`
    92  }
    93  
    94  func newLedgerInfo(name string, pub cryptotypes.PubKey, path hd.BIP44Params, algo hd.PubKeyType) Info {
    95  	return &ledgerInfo{
    96  		Name:   name,
    97  		PubKey: pub,
    98  		Path:   path,
    99  		Algo:   algo,
   100  	}
   101  }
   102  
   103  // GetType implements Info interface
   104  func (i ledgerInfo) GetType() KeyType {
   105  	return TypeLedger
   106  }
   107  
   108  // GetName implements Info interface
   109  func (i ledgerInfo) GetName() string {
   110  	return i.Name
   111  }
   112  
   113  // GetPubKey implements Info interface
   114  func (i ledgerInfo) GetPubKey() cryptotypes.PubKey {
   115  	return i.PubKey
   116  }
   117  
   118  // GetAddress implements Info interface
   119  func (i ledgerInfo) GetAddress() types.AccAddress {
   120  	return i.PubKey.Address().Bytes()
   121  }
   122  
   123  // GetPath implements Info interface
   124  func (i ledgerInfo) GetAlgo() hd.PubKeyType {
   125  	return i.Algo
   126  }
   127  
   128  // GetPath implements Info interface
   129  func (i ledgerInfo) GetPath() (*hd.BIP44Params, error) {
   130  	tmp := i.Path
   131  	return &tmp, nil
   132  }
   133  
   134  // offlineInfo is the public information about an offline key
   135  // Note: Algo must be last field in struct for backwards amino compatibility
   136  type offlineInfo struct {
   137  	Name   string             `json:"name"`
   138  	PubKey cryptotypes.PubKey `json:"pubkey"`
   139  	Algo   hd.PubKeyType      `json:"algo"`
   140  }
   141  
   142  func newOfflineInfo(name string, pub cryptotypes.PubKey, algo hd.PubKeyType) Info {
   143  	return &offlineInfo{
   144  		Name:   name,
   145  		PubKey: pub,
   146  		Algo:   algo,
   147  	}
   148  }
   149  
   150  // GetType implements Info interface
   151  func (i offlineInfo) GetType() KeyType {
   152  	return TypeOffline
   153  }
   154  
   155  // GetName implements Info interface
   156  func (i offlineInfo) GetName() string {
   157  	return i.Name
   158  }
   159  
   160  // GetPubKey implements Info interface
   161  func (i offlineInfo) GetPubKey() cryptotypes.PubKey {
   162  	return i.PubKey
   163  }
   164  
   165  // GetAlgo returns the signing algorithm for the key
   166  func (i offlineInfo) GetAlgo() hd.PubKeyType {
   167  	return i.Algo
   168  }
   169  
   170  // GetAddress implements Info interface
   171  func (i offlineInfo) GetAddress() types.AccAddress {
   172  	return i.PubKey.Address().Bytes()
   173  }
   174  
   175  // GetPath implements Info interface
   176  func (i offlineInfo) GetPath() (*hd.BIP44Params, error) {
   177  	return nil, fmt.Errorf("BIP44 Paths are not available for this type")
   178  }
   179  
   180  // Deprecated: this structure is not used anymore and it's here only to allow
   181  // decoding old multiInfo records from keyring.
   182  // The problem with legacy.Cdc.UnmarshalLengthPrefixed - the legacy codec doesn't
   183  // tolerate extensibility.
   184  type multisigPubKeyInfo struct {
   185  	PubKey cryptotypes.PubKey `json:"pubkey"`
   186  	Weight uint               `json:"weight"`
   187  }
   188  
   189  // multiInfo is the public information about a multisig key
   190  type multiInfo struct {
   191  	Name      string               `json:"name"`
   192  	PubKey    cryptotypes.PubKey   `json:"pubkey"`
   193  	Threshold uint                 `json:"threshold"`
   194  	PubKeys   []multisigPubKeyInfo `json:"pubkeys"`
   195  }
   196  
   197  // NewMultiInfo creates a new multiInfo instance
   198  func NewMultiInfo(name string, pub cryptotypes.PubKey) (Info, error) {
   199  	if _, ok := pub.(*multisig.LegacyAminoPubKey); !ok {
   200  		return nil, fmt.Errorf("MultiInfo supports only multisig.LegacyAminoPubKey, got  %T", pub)
   201  	}
   202  	return &multiInfo{
   203  		Name:   name,
   204  		PubKey: pub,
   205  	}, nil
   206  }
   207  
   208  // GetType implements Info interface
   209  func (i multiInfo) GetType() KeyType {
   210  	return TypeMulti
   211  }
   212  
   213  // GetName implements Info interface
   214  func (i multiInfo) GetName() string {
   215  	return i.Name
   216  }
   217  
   218  // GetPubKey implements Info interface
   219  func (i multiInfo) GetPubKey() cryptotypes.PubKey {
   220  	return i.PubKey
   221  }
   222  
   223  // GetAddress implements Info interface
   224  func (i multiInfo) GetAddress() types.AccAddress {
   225  	return i.PubKey.Address().Bytes()
   226  }
   227  
   228  // GetPath implements Info interface
   229  func (i multiInfo) GetAlgo() hd.PubKeyType {
   230  	return hd.MultiType
   231  }
   232  
   233  // GetPath implements Info interface
   234  func (i multiInfo) GetPath() (*hd.BIP44Params, error) {
   235  	return nil, fmt.Errorf("BIP44 Paths are not available for this type")
   236  }
   237  
   238  // UnpackInterfaces implements UnpackInterfacesMessage.UnpackInterfaces
   239  func (i multiInfo) UnpackInterfaces(unpacker codectypes.AnyUnpacker) error {
   240  	multiPK := i.PubKey.(*multisig.LegacyAminoPubKey)
   241  
   242  	return codectypes.UnpackInterfaces(multiPK, unpacker)
   243  }
   244  
   245  // encoding info
   246  func marshalInfo(i Info) []byte {
   247  	return legacy.Cdc.MustMarshalLengthPrefixed(i)
   248  }
   249  
   250  // decoding info
   251  func unmarshalInfo(bz []byte) (info Info, err error) {
   252  	err = legacy.Cdc.UnmarshalLengthPrefixed(bz, &info)
   253  	if err != nil {
   254  		return nil, err
   255  	}
   256  
   257  	// After unmarshalling into &info, if we notice that the info is a
   258  	// multiInfo, then we unmarshal again, explicitly in a multiInfo this time.
   259  	// Since multiInfo implements UnpackInterfacesMessage, this will correctly
   260  	// unpack the underlying anys inside the multiInfo.
   261  	//
   262  	// This is a workaround, as go cannot check that an interface (Info)
   263  	// implements another interface (UnpackInterfacesMessage).
   264  	_, ok := info.(multiInfo)
   265  	if ok {
   266  		var multi multiInfo
   267  		err = legacy.Cdc.UnmarshalLengthPrefixed(bz, &multi)
   268  
   269  		return multi, err
   270  	}
   271  
   272  	return
   273  }