github.com/gnolang/gno@v0.0.0-20240520182011-228e9d0192ce/tm2/pkg/crypto/keys/types.go (about) 1 package keys 2 3 import ( 4 "fmt" 5 6 "github.com/gnolang/gno/tm2/pkg/amino" 7 "github.com/gnolang/gno/tm2/pkg/crypto" 8 "github.com/gnolang/gno/tm2/pkg/crypto/hd" 9 "github.com/gnolang/gno/tm2/pkg/crypto/multisig" 10 ) 11 12 // Keybase exposes operations on a generic keystore 13 type Keybase interface { 14 // CRUD on the keystore 15 List() ([]Info, error) 16 HasByNameOrAddress(nameOrBech32 string) (bool, error) 17 HasByName(name string) (bool, error) 18 HasByAddress(address crypto.Address) (bool, error) 19 GetByNameOrAddress(nameOrBech32 string) (Info, error) 20 GetByName(name string) (Info, error) 21 GetByAddress(address crypto.Address) (Info, error) 22 Delete(name, passphrase string, skipPass bool) error 23 24 // Sign some bytes, looking up the private key to use 25 Sign(name, passphrase string, msg []byte) ([]byte, crypto.PubKey, error) 26 Verify(name string, msg, sig []byte) error 27 28 // CreateAccount creates an account based using the BIP44 path (44'/118'/{account}'/0/{index} 29 // Encrypt the key to disk using encryptPasswd. 30 // See https://github.com/tendermint/classic/sdk/issues/2095 31 CreateAccount(name, mnemonic, bip39Passwd, encryptPasswd string, account uint32, index uint32) (Info, error) 32 33 // Like CreateAccount but from general bip44 params. 34 CreateAccountBip44(name, mnemonic, bip39Passwd, encryptPasswd string, params hd.BIP44Params) (Info, error) 35 36 // CreateLedger creates, stores, and returns a new Ledger key reference 37 CreateLedger(name string, algo SigningAlgo, hrp string, account, index uint32) (info Info, err error) 38 39 // CreateOffline creates, stores, and returns a new offline key reference 40 CreateOffline(name string, pubkey crypto.PubKey) (info Info, err error) 41 42 // CreateMulti creates, stores, and returns a new multsig (offline) key reference 43 CreateMulti(name string, pubkey crypto.PubKey) (info Info, err error) 44 45 // The following operations will *only* work on locally-stored keys 46 Update(name, oldpass string, getNewpass func() (string, error)) error 47 Import(name string, armor string) (err error) 48 ImportPrivKey(name, armor, decryptPassphrase, encryptPassphrase string) error 49 ImportPrivKeyUnsafe(name, armor, encryptPassphrase string) error 50 ImportPubKey(name string, armor string) (err error) 51 Export(name string) (armor string, err error) 52 ExportPubKey(name string) (armor string, err error) 53 ExportPrivKey(name, decryptPassphrase, encryptPassphrase string) (armor string, err error) 54 ExportPrivKeyUnsafe(name, decryptPassphrase string) (armor string, err error) 55 56 // ExportPrivateKeyObject *only* works on locally-stored keys. Temporary method until we redo the exporting API 57 ExportPrivateKeyObject(name string, passphrase string) (crypto.PrivKey, error) 58 59 // CloseDB closes the database. 60 CloseDB() 61 } 62 63 // KeyType reflects a human-readable type for key listing. 64 type KeyType uint 65 66 // Info KeyTypes 67 const ( 68 TypeLocal KeyType = 0 69 TypeLedger KeyType = 1 70 TypeOffline KeyType = 2 71 TypeMulti KeyType = 3 72 ) 73 74 var keyTypes = map[KeyType]string{ 75 TypeLocal: "local", 76 TypeLedger: "ledger", 77 TypeOffline: "offline", 78 TypeMulti: "multi", 79 } 80 81 // String implements the stringer interface for KeyType. 82 func (kt KeyType) String() string { 83 return keyTypes[kt] 84 } 85 86 // Info is the publicly exposed information about a keypair 87 type Info interface { 88 // Human-readable type for key listing 89 GetType() KeyType 90 // Name of the key 91 GetName() string 92 // Public key 93 GetPubKey() crypto.PubKey 94 // Address 95 GetAddress() crypto.Address 96 // Bip44 Path 97 GetPath() (*hd.BIP44Params, error) 98 } 99 100 var ( 101 _ Info = &localInfo{} 102 _ Info = &ledgerInfo{} 103 _ Info = &offlineInfo{} 104 _ Info = &multiInfo{} 105 ) 106 107 // localInfo is the public information about a locally stored key 108 type localInfo struct { 109 Name string `json:"name"` 110 PubKey crypto.PubKey `json:"pubkey"` 111 PrivKeyArmor string `json:"privkey.armor"` 112 } 113 114 func newLocalInfo(name string, pub crypto.PubKey, privArmor string) Info { 115 return &localInfo{ 116 Name: name, 117 PubKey: pub, 118 PrivKeyArmor: privArmor, 119 } 120 } 121 122 // GetType implements Info interface 123 func (i localInfo) GetType() KeyType { 124 return TypeLocal 125 } 126 127 // GetType implements Info interface 128 func (i localInfo) GetName() string { 129 return i.Name 130 } 131 132 // GetType implements Info interface 133 func (i localInfo) GetPubKey() crypto.PubKey { 134 return i.PubKey 135 } 136 137 // GetType implements Info interface 138 func (i localInfo) GetAddress() crypto.Address { 139 return i.PubKey.Address() 140 } 141 142 // GetType implements Info interface 143 func (i localInfo) GetPath() (*hd.BIP44Params, error) { 144 return nil, fmt.Errorf("BIP44 Paths are not available for this type") 145 } 146 147 // ledgerInfo is the public information about a Ledger key 148 type ledgerInfo struct { 149 Name string `json:"name"` 150 PubKey crypto.PubKey `json:"pubkey"` 151 Path hd.BIP44Params `json:"path"` 152 } 153 154 func newLedgerInfo(name string, pub crypto.PubKey, path hd.BIP44Params) Info { 155 return &ledgerInfo{ 156 Name: name, 157 PubKey: pub, 158 Path: path, 159 } 160 } 161 162 // GetType implements Info interface 163 func (i ledgerInfo) GetType() KeyType { 164 return TypeLedger 165 } 166 167 // GetName implements Info interface 168 func (i ledgerInfo) GetName() string { 169 return i.Name 170 } 171 172 // GetPubKey implements Info interface 173 func (i ledgerInfo) GetPubKey() crypto.PubKey { 174 return i.PubKey 175 } 176 177 // GetAddress implements Info interface 178 func (i ledgerInfo) GetAddress() crypto.Address { 179 return i.PubKey.Address() 180 } 181 182 // GetPath implements Info interface 183 func (i ledgerInfo) GetPath() (*hd.BIP44Params, error) { 184 tmp := i.Path 185 return &tmp, nil 186 } 187 188 // offlineInfo is the public information about an offline key 189 type offlineInfo struct { 190 Name string `json:"name"` 191 PubKey crypto.PubKey `json:"pubkey"` 192 } 193 194 func newOfflineInfo(name string, pub crypto.PubKey) Info { 195 return &offlineInfo{ 196 Name: name, 197 PubKey: pub, 198 } 199 } 200 201 // GetType implements Info interface 202 func (i offlineInfo) GetType() KeyType { 203 return TypeOffline 204 } 205 206 // GetName implements Info interface 207 func (i offlineInfo) GetName() string { 208 return i.Name 209 } 210 211 // GetPubKey implements Info interface 212 func (i offlineInfo) GetPubKey() crypto.PubKey { 213 return i.PubKey 214 } 215 216 // GetAddress implements Info interface 217 func (i offlineInfo) GetAddress() crypto.Address { 218 return i.PubKey.Address() 219 } 220 221 // GetPath implements Info interface 222 func (i offlineInfo) GetPath() (*hd.BIP44Params, error) { 223 return nil, fmt.Errorf("BIP44 Paths are not available for this type") 224 } 225 226 type multisigPubKeyInfo struct { 227 PubKey crypto.PubKey `json:"pubkey"` 228 Weight uint `json:"weight"` 229 } 230 231 // multiInfo is the public information about a multisig key 232 type multiInfo struct { 233 Name string `json:"name"` 234 PubKey crypto.PubKey `json:"pubkey"` 235 Threshold uint `json:"threshold"` 236 PubKeys []multisigPubKeyInfo `json:"pubkeys"` 237 } 238 239 // NewMultiInfo creates a new multiInfo instance 240 func NewMultiInfo(name string, pub crypto.PubKey) Info { 241 multiPK := pub.(multisig.PubKeyMultisigThreshold) 242 243 pubKeys := make([]multisigPubKeyInfo, len(multiPK.PubKeys)) 244 for i, pk := range multiPK.PubKeys { 245 // TODO: Recursively check pk for total weight? 246 pubKeys[i] = multisigPubKeyInfo{pk, 1} 247 } 248 249 return &multiInfo{ 250 Name: name, 251 PubKey: pub, 252 Threshold: multiPK.K, 253 PubKeys: pubKeys, 254 } 255 } 256 257 // GetType implements Info interface 258 func (i multiInfo) GetType() KeyType { 259 return TypeMulti 260 } 261 262 // GetName implements Info interface 263 func (i multiInfo) GetName() string { 264 return i.Name 265 } 266 267 // GetPubKey implements Info interface 268 func (i multiInfo) GetPubKey() crypto.PubKey { 269 return i.PubKey 270 } 271 272 // GetAddress implements Info interface 273 func (i multiInfo) GetAddress() crypto.Address { 274 return i.PubKey.Address() 275 } 276 277 // GetPath implements Info interface 278 func (i multiInfo) GetPath() (*hd.BIP44Params, error) { 279 return nil, fmt.Errorf("BIP44 Paths are not available for this type") 280 } 281 282 // encoding info 283 func writeInfo(i Info) []byte { 284 return amino.MustMarshalAnySized(i) 285 } 286 287 // decoding info 288 func readInfo(bz []byte) (info Info, err error) { 289 err = amino.UnmarshalAnySized(bz, &info) 290 return 291 }