func MakeSignature(keybase crkeys.Keybase, name, passphrase string,
	msg StdSignMsg) (sig StdSignature, err error) {
	if keybase == nil {
		keybase, err = keys.NewKeyBaseFromHomeFlag()
		if err != nil {
			return
		}
	}
	sigBytes, pubkey, err := keybase.Sign(name, passphrase, msg.Bytes())
	if err != nil {
		return
	}
	return StdSignature{
		PubKey:    pubkey,
		Signature: sigBytes,
	}, nil
}
MakeSignature builds a StdSignature given keybase, key name, passphrase, and a StdSignMsg.
package types
import (
	"errors"
	"fmt"
	"strings"
	"github.com/spf13/viper"
	"github.com/Dipper-Labs/Dipper-Protocol/client/flags"
	"github.com/Dipper-Labs/Dipper-Protocol/client/keys"
	crkeys "github.com/Dipper-Labs/Dipper-Protocol/crypto/keys"
	sdk "github.com/Dipper-Labs/Dipper-Protocol/types"
)
type TxBuilder struct {
	txEncoder          sdk.TxEncoder
	keybase            crkeys.Keybase
	accountNumber      uint64
	sequence           uint64
	gas                uint64
	gasAdjustment      float64
	simulateAndExecute bool
	chainID            string
	memo               string
	fees               sdk.Coins
	gasPrices          sdk.DecCoins
}
func NewTxBuilder(
	txEncoder sdk.TxEncoder, accNumber, seq, gas uint64, gasAdj float64,
	simulateAndExecute bool, chainID, memo string, fees sdk.Coins, gasPrices sdk.DecCoins,
) TxBuilder {
	return TxBuilder{
		txEncoder:          txEncoder,
		keybase:            nil,
		accountNumber:      accNumber,
		sequence:           seq,
		gas:                gas,
		gasAdjustment:      gasAdj,
		simulateAndExecute: simulateAndExecute,
		chainID:            chainID,
		memo:               memo,
		fees:               fees,
		gasPrices:          gasPrices,
	}
}
func NewTxBuilderFromCLI() TxBuilder {
	kb, err := keys.NewKeyBaseFromHomeFlag()
	if err != nil {
		panic(err)
	}
	txbldr := TxBuilder{
		keybase:            kb,
		accountNumber:      uint64(viper.GetInt64(flags.FlagAccountNumber)),
		sequence:           uint64(viper.GetInt64(flags.FlagSequence)),
		gas:                flags.GasFlagVar.Gas,
		gasAdjustment:      viper.GetFloat64(flags.FlagGasAdjustment),
		simulateAndExecute: flags.GasFlagVar.Simulate,
		chainID:            viper.GetString(flags.FlagChainID),
		memo:               viper.GetString(flags.FlagMemo),
	}
	txbldr = txbldr.WithFees(viper.GetString(flags.FlagFees))
	txbldr = txbldr.WithGasPrices(viper.GetString(flags.FlagGasPrices))
	return txbldr
}
func (bldr TxBuilder) TxEncoder() sdk.TxEncoder { return bldr.txEncoder }
func (bldr TxBuilder) AccountNumber() uint64 { return bldr.accountNumber }
func (bldr TxBuilder) Sequence() uint64 { return bldr.sequence }
func (bldr TxBuilder) Gas() uint64 { return bldr.gas }
func (bldr TxBuilder) GasAdjustment() float64 { return bldr.gasAdjustment }
func (bldr TxBuilder) Keybase() crkeys.Keybase { return bldr.keybase }
func (bldr TxBuilder) SimulateAndExecute() bool { return bldr.simulateAndExecute }
func (bldr TxBuilder) ChainID() string { return bldr.chainID }
func (bldr TxBuilder) Memo() string { return bldr.memo }
func (bldr TxBuilder) Fees() sdk.Coins { return bldr.fees }
func (bldr TxBuilder) GasPrices() sdk.DecCoins { return bldr.gasPrices }
func (bldr TxBuilder) WithTxEncoder(txEncoder sdk.TxEncoder) TxBuilder {
	bldr.txEncoder = txEncoder
	return bldr
}
func (bldr TxBuilder) WithChainID(chainID string) TxBuilder {
	bldr.chainID = chainID
	return bldr
}
func (bldr TxBuilder) WithGas(gas uint64) TxBuilder {
	bldr.gas = gas
	return bldr
}
func (bldr TxBuilder) WithFees(fees string) TxBuilder {
	parsedFees, err := sdk.ParseCoins(fees)
	if err != nil {
		panic(err)
	}
	bldr.fees = parsedFees
	return bldr
}
func (bldr TxBuilder) WithGasPrices(gasPrices string) TxBuilder {
	parsedGasPrices, err := sdk.ParseDecCoins(gasPrices)
	if err != nil {
		panic(err)
	}
	bldr.gasPrices = parsedGasPrices
	return bldr
}
func (bldr TxBuilder) WithKeybase(keybase crkeys.Keybase) TxBuilder {
	bldr.keybase = keybase
	return bldr
}
func (bldr TxBuilder) WithSequence(sequence uint64) TxBuilder {
	bldr.sequence = sequence
	return bldr
}
func (bldr TxBuilder) WithMemo(memo string) TxBuilder {
	bldr.memo = strings.TrimSpace(memo)
	return bldr
}
func (bldr TxBuilder) WithAccountNumber(accnum uint64) TxBuilder {
	bldr.accountNumber = accnum
	return bldr
}
func (bldr TxBuilder) BuildSignMsg(msgs []sdk.Msg) (StdSignMsg, error) {
	if bldr.chainID == "" {
		return StdSignMsg{}, fmt.Errorf("chain ID required but not specified")
	}
	fees := bldr.fees
	if !bldr.gasPrices.IsZero() {
		if !fees.IsZero() {
			return StdSignMsg{}, errors.New("cannot provide both fees and gas prices")
		}
		glDec := sdk.NewDec(int64(bldr.gas))
		fees = make(sdk.Coins, len(bldr.gasPrices))
		for i, gp := range bldr.gasPrices {
			fee := gp.Amount.Mul(glDec)
			fees[i] = sdk.NewCoin(gp.Denom, fee.Ceil().RoundInt())
		}
	}
	return StdSignMsg{
		ChainID:       bldr.chainID,
		AccountNumber: bldr.accountNumber,
		Sequence:      bldr.sequence,
		Memo:          bldr.memo,
		Msgs:          msgs,
		Fee:           NewStdFee(bldr.gas, fees),
	}, nil
}
func (bldr TxBuilder) Sign(name, passphrase string, msg StdSignMsg) ([]byte, error) {
	sig, err := MakeSignature(bldr.keybase, name, passphrase, msg)
	if err != nil {
		return nil, err
	}
	return bldr.txEncoder(NewStdTx(msg.Msgs, msg.Fee, []StdSignature{sig}, msg.Memo))
}
func (bldr TxBuilder) BuildAndSign(name, passphrase string, msgs []sdk.Msg) ([]byte, error) {
	msg, err := bldr.BuildSignMsg(msgs)
	if err != nil {
		return nil, err
	}
	return bldr.Sign(name, passphrase, msg)
}
func (bldr TxBuilder) BuildTxForSim(msgs []sdk.Msg) ([]byte, error) {
	signMsg, err := bldr.BuildSignMsg(msgs)
	if err != nil {
		return nil, err
	}
	sigs := []StdSignature{{}}
	return bldr.txEncoder(NewStdTx(signMsg.Msgs, signMsg.Fee, sigs, signMsg.Memo))
}
func (bldr TxBuilder) SignStdTx(name, passphrase string, stdTx StdTx, appendSig bool) (signedStdTx StdTx, err error) {
	if bldr.chainID == "" {
		return StdTx{}, fmt.Errorf("chain ID required but not specified")
	}
	stdSignature, err := MakeSignature(bldr.keybase, name, passphrase, StdSignMsg{
		ChainID:       bldr.chainID,
		AccountNumber: bldr.accountNumber,
		Sequence:      bldr.sequence,
		Fee:           stdTx.Fee,
		Msgs:          stdTx.GetMsgs(),
		Memo:          stdTx.GetMemo(),
	})
	if err != nil {
		return
	}
	sigs := stdTx.Signatures
	if len(sigs) == 0 || !appendSig {
		sigs = []StdSignature{stdSignature}
	} else {
		sigs = append(sigs, stdSignature)
	}
	signedStdTx = NewStdTx(stdTx.GetMsgs(), stdTx.Fee, sigs, stdTx.GetMemo())
	return
}