mirror of
https://github.com/galacticship/terra.git
synced 2024-11-13 19:57:51 +00:00
112 lines
2.7 KiB
Go
112 lines
2.7 KiB
Go
|
package terra
|
||
|
|
||
|
import (
|
||
|
"context"
|
||
|
"fmt"
|
||
|
"sync"
|
||
|
|
||
|
"github.com/galacticship/terra/cosmos"
|
||
|
"github.com/galacticship/terra/crypto"
|
||
|
"github.com/pkg/errors"
|
||
|
)
|
||
|
|
||
|
type Wallet struct {
|
||
|
q *Querier
|
||
|
privKey crypto.PrivKey
|
||
|
transactionLock *sync.Mutex
|
||
|
|
||
|
gasAdjustment cosmos.Dec
|
||
|
gasPrice cosmos.DecCoin
|
||
|
}
|
||
|
|
||
|
type WalletOption func(w *Wallet) *Wallet
|
||
|
|
||
|
func WithGasAdjustment(gasAdjustment cosmos.Dec) WalletOption {
|
||
|
return func(w *Wallet) *Wallet {
|
||
|
w.gasAdjustment = gasAdjustment
|
||
|
return w
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func WithGasPrice(gasPrice cosmos.DecCoin) WalletOption {
|
||
|
return func(w *Wallet) *Wallet {
|
||
|
w.gasPrice = gasPrice
|
||
|
return w
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func NewWalletFromMnemonic(querier *Querier, mnemonic string, account uint32, index uint32, options ...WalletOption) (*Wallet, error) {
|
||
|
privKeyBz, err := crypto.DerivePrivKeyBz(mnemonic, crypto.CreateHDPath(account, index))
|
||
|
if err != nil {
|
||
|
return nil, errors.Wrap(err, "deriving private key bytes")
|
||
|
}
|
||
|
privKey, err := crypto.PrivKeyGen(privKeyBz)
|
||
|
if err != nil {
|
||
|
return nil, errors.Wrap(err, "generating private key")
|
||
|
}
|
||
|
|
||
|
return NewWalletFromPrivateKey(querier, privKey, options...), nil
|
||
|
}
|
||
|
|
||
|
func NewWalletFromPrivateKey(querier *Querier, privateKey crypto.PrivKey, options ...WalletOption) *Wallet {
|
||
|
w := &Wallet{
|
||
|
q: querier,
|
||
|
privKey: privateKey,
|
||
|
transactionLock: &sync.Mutex{},
|
||
|
|
||
|
gasAdjustment: cosmos.NewDecFromIntWithPrec(cosmos.NewInt(14), 1),
|
||
|
gasPrice: cosmos.NewDecCoinFromDec("uusd", cosmos.NewDecFromIntWithPrec(cosmos.NewInt(15), 2)),
|
||
|
}
|
||
|
for _, option := range options {
|
||
|
w = option(w)
|
||
|
}
|
||
|
return w
|
||
|
}
|
||
|
|
||
|
func (a Wallet) GasAdjustment() cosmos.Dec {
|
||
|
return a.gasAdjustment
|
||
|
}
|
||
|
func (a Wallet) GasPrice() cosmos.DecCoin {
|
||
|
return a.gasPrice
|
||
|
}
|
||
|
|
||
|
func (a Wallet) Address() cosmos.AccAddress {
|
||
|
return cosmos.AccAddress(a.privKey.PubKey().Address())
|
||
|
}
|
||
|
|
||
|
type WalletState struct {
|
||
|
AccountNumber uint64 `json:"account_number,string"`
|
||
|
Sequence uint64 `json:"sequence,string"`
|
||
|
}
|
||
|
|
||
|
func (a Wallet) State(ctx context.Context) (WalletState, error) {
|
||
|
var response struct {
|
||
|
AccountInfo WalletState `json:"account"`
|
||
|
}
|
||
|
err := a.q.GET(ctx, fmt.Sprintf("cosmos/auth/v1beta1/accounts/%s", a.Address().String()), nil, &response)
|
||
|
if err != nil {
|
||
|
return WalletState{}, errors.Wrap(err, "querying lcd")
|
||
|
}
|
||
|
return response.AccountInfo, nil
|
||
|
}
|
||
|
|
||
|
func (a Wallet) SignTransaction(transaction *Transaction) error {
|
||
|
err := transaction.sign(transaction.signMode, cosmos.SignerData{
|
||
|
AccountNumber: transaction.accountNumber,
|
||
|
ChainID: a.q.ChainId(),
|
||
|
Sequence: transaction.sequence,
|
||
|
}, a.privKey, true)
|
||
|
if err != nil {
|
||
|
return errors.Wrap(err, "signing transaction")
|
||
|
}
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
func (a Wallet) lock() {
|
||
|
a.transactionLock.Lock()
|
||
|
}
|
||
|
|
||
|
func (a Wallet) unlock() {
|
||
|
a.transactionLock.Unlock()
|
||
|
}
|