func (kb *Keybase) CreateOffline(name string, pubkey crypto.PubKey, algo keys.SigningAlgo) (keys.Info, error) {
	kb.mx.Lock()
	defer kb.mx.Unlock()
	return kb.kb.CreateOffline(name, pubkey, algo)
}
CreateOffline is a lock protected version of keys.CreateOffline
package cosmos
import (
	"crypto/sha256"
	"sync"
	clientkey "github.com/cosmos/cosmos-sdk/client/keys"
	"github.com/cosmos/cosmos-sdk/crypto/keys"
	"github.com/cosmos/cosmos-sdk/crypto/keys/keyerror"
	"github.com/cosmos/cosmos-sdk/types"
	bip39 "github.com/cosmos/go-bip39"
	"github.com/tendermint/tendermint/crypto"
)
const (
	mnemonicEntropySize = 256
)
type Keybase struct {
	kb            keys.Keybase
	mx            sync.Mutex
	privKeysCache map[[sha256.Size]byte]crypto.PrivKey
}
func NewKeybase(dir string) (*Keybase, error) {
	kb, err := clientkey.NewKeyBaseFromDir(dir)
	if err != nil {
		return nil, err
	}
	return &Keybase{
		kb:            kb,
		privKeysCache: make(map[[sha256.Size]byte]crypto.PrivKey),
	}, nil
}
func NewInMemoryKeybase() *Keybase {
	return &Keybase{
		kb:            clientkey.NewInMemoryKeyBase(),
		privKeysCache: make(map[[sha256.Size]byte]crypto.PrivKey),
	}
}
func (kb *Keybase) NewMnemonic() (string, error) {
	entropySeed, err := bip39.NewEntropy(mnemonicEntropySize)
	if err != nil {
		return "", err
	}
	return bip39.NewMnemonic(entropySeed)
}
func (kb *Keybase) Exist(name string) (bool, error) {
	_, err := kb.Get(name)
	if keyerror.IsErrKeyNotFound(err) {
		return false, nil
	}
	if err != nil {
		return false, err
	}
	return true, nil
}
func (kb *Keybase) List() ([]keys.Info, error) {
	kb.mx.Lock()
	defer kb.mx.Unlock()
	return kb.kb.List()
}
func (kb *Keybase) Get(name string) (keys.Info, error) {
	kb.mx.Lock()
	defer kb.mx.Unlock()
	return kb.kb.Get(name)
}
func (kb *Keybase) GetByAddress(address types.AccAddress) (keys.Info, error) {
	kb.mx.Lock()
	defer kb.mx.Unlock()
	return kb.kb.GetByAddress(address)
}
func (kb *Keybase) Delete(name, passphrase string, skipPass bool) error {
	kb.mx.Lock()
	defer kb.mx.Unlock()
	return kb.kb.Delete(name, passphrase, skipPass)
}
func (kb *Keybase) Sign(name, passphrase string, msg []byte) ([]byte, crypto.PubKey, error) {
	hash := sha256.Sum256([]byte(name + ":" + passphrase))
	kb.mx.Lock()
	priv, ok := kb.privKeysCache[hash]
	if !ok {
		var err error
		if priv, err = kb.kb.ExportPrivateKeyObject(name, passphrase); err != nil {
			kb.mx.Unlock()
			return nil, nil, err
		}
		kb.privKeysCache[hash] = priv
	}
	kb.mx.Unlock()
	sig, err := priv.Sign(msg)
	return sig, priv.PubKey(), err
}
func (kb *Keybase) CreateMnemonic(name string, language keys.Language, passwd string, algo keys.SigningAlgo) (keys.Info, string, error) {
	kb.mx.Lock()
	defer kb.mx.Unlock()
	return kb.kb.CreateMnemonic(name, language, passwd, algo)
}
func (kb *Keybase) CreateAccount(name, mnemonic, bip39Passwd, encryptPasswd, hdPath string, algo keys.SigningAlgo) (keys.Info, error) {
	kb.mx.Lock()
	defer kb.mx.Unlock()
	return kb.kb.CreateAccount(name, mnemonic, bip39Passwd, encryptPasswd, hdPath, algo)
}
func (kb *Keybase) CreateLedger(name string, algo keys.SigningAlgo, hrp string, account, index uint32) (keys.Info, error) {
	kb.mx.Lock()
	defer kb.mx.Unlock()
	return kb.kb.CreateLedger(name, algo, hrp, account, index)
}