mirror of https://github.com/certusone/santa.git
178 lines
3.4 KiB
Go
178 lines
3.4 KiB
Go
package utils
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
|
|
"github.com/cosmos/cosmos-sdk/client/keys"
|
|
ckeys "github.com/cosmos/cosmos-sdk/crypto/keys"
|
|
"github.com/cosmos/cosmos-sdk/crypto/keys/hd"
|
|
bip39 "github.com/cosmos/go-bip39"
|
|
)
|
|
|
|
// GetKeys returns key list
|
|
func (app SantaApp) GetKeys() (out []byte, err error) {
|
|
|
|
kb, err := keys.NewKeyBaseFromDir(app.KeyDir)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
infos, err := kb.List()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if len(infos) == 0 {
|
|
return []byte{}, nil
|
|
}
|
|
|
|
keysOutput, err := ckeys.Bech32KeysOutput(infos)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return json.Marshal(keysOutput)
|
|
}
|
|
|
|
// AddNewKey appends new key
|
|
func (app SantaApp) AddNewKey(name, password, mnemonic string, oldHdPath bool) (out []byte, err error) {
|
|
kb, err := keys.NewKeyBaseFromDir(app.KeyDir)
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
if name == "" || password == "" {
|
|
err = fmt.Errorf("must include both password and name with request")
|
|
return
|
|
}
|
|
|
|
// if mnemonic is empty, generate one
|
|
if mnemonic == "" {
|
|
_, mnemonic, _ = ckeys.NewInMemory().CreateMnemonic("inmemorykey", ckeys.English, "123456789", ckeys.Secp256k1)
|
|
}
|
|
|
|
if !bip39.IsMnemonicValid(mnemonic) {
|
|
err = fmt.Errorf("invalid mnemonic")
|
|
return
|
|
}
|
|
|
|
_, err = kb.Get(name)
|
|
if err == nil {
|
|
err = fmt.Errorf("key %s already exists", name)
|
|
return
|
|
}
|
|
|
|
account := uint32(0)
|
|
index := uint32(0)
|
|
coinType := uint32(330)
|
|
if oldHdPath {
|
|
coinType = uint32(118)
|
|
}
|
|
|
|
hdParams := hd.NewFundraiserParams(account, coinType, index)
|
|
info, err := kb.Derive(name, mnemonic, "", password, *hdParams)
|
|
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
keyOutput, err := ckeys.Bech32KeyOutput(info)
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
keyOutput.Mnemonic = mnemonic
|
|
|
|
out, err = json.Marshal(keyOutput)
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
// GetKey is the handler for the GET /keys/{name}
|
|
func (app SantaApp) GetKey(name, bechPrefix string) (out []byte, err error) {
|
|
kb, err := keys.NewKeyBaseFromDir(app.KeyDir)
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
if bechPrefix == "" {
|
|
bechPrefix = "acc"
|
|
}
|
|
|
|
bechKeyOut, err := getBechKeyOut(bechPrefix)
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
info, err := kb.Get(name)
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
keyOutput, err := bechKeyOut(info)
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
out, err = json.Marshal(keyOutput)
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
type bechKeyOutFn func(keyInfo ckeys.Info) (ckeys.KeyOutput, error)
|
|
|
|
func getBechKeyOut(bechPrefix string) (bechKeyOutFn, error) {
|
|
switch bechPrefix {
|
|
case "acc":
|
|
return ckeys.Bech32KeyOutput, nil
|
|
case "val":
|
|
return ckeys.Bech32ValKeyOutput, nil
|
|
case "cons":
|
|
return ckeys.Bech32ConsKeyOutput, nil
|
|
}
|
|
|
|
return nil, fmt.Errorf("invalid Bech32 prefix encoding provided: %s", bechPrefix)
|
|
}
|
|
|
|
// UpdateKey update key password
|
|
func (app SantaApp) UpdateKey(name, oldPassword, newPassword string) (err error) {
|
|
if name == "" || oldPassword == "" || newPassword == "" {
|
|
err = fmt.Errorf("must include name, oldPassword, and newPassword with request")
|
|
return
|
|
}
|
|
|
|
kb, err := keys.NewKeyBaseFromDir(app.KeyDir)
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
err = kb.Update(name, oldPassword, func() (string, error) { return newPassword, nil })
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
// DeleteKey is the handler for the DELETE /keys/{name}
|
|
func (app SantaApp) DeleteKey(name, password string) (err error) {
|
|
kb, err := keys.NewKeyBaseFromDir(app.KeyDir)
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
err = kb.Delete(name, password, false)
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
return
|
|
}
|