This commit is contained in:
Laurent Le Houerou 2021-11-09 08:11:05 +04:00
parent c3908948ec
commit b927854098
7 changed files with 48 additions and 38 deletions

View File

@ -34,8 +34,8 @@ func NewWBNB(address string, client evm.Client) (*WBNB, error) {
}, nil
}
func (w *WBNB) UnwrapWBNB(ctx context.Context, amount decimal.Decimal) (evm.Transaction, error) {
func (w *WBNB) UnwrapWBNB(ctx context.Context, amount decimal.Decimal, opts ...evm.ExecutionOption) (evm.Transaction, error) {
return w.client.Execute(ctx, func(ctx context.Context, opts *evm.TransactOpts) (*types.Transaction, error) {
return w.contract.Withdraw(opts.TransactOpts, w.ValueToBigInt(amount))
})
}, opts...)
}

View File

@ -24,22 +24,21 @@ type Client interface {
PublicAddressAsHexString() string
PendingNonce(context.Context) (uint64, error)
NewTransactor() (*bind.TransactOpts, error)
Execute(context.Context, func(context.Context, *TransactOpts) (*types.Transaction, error)) (Transaction, error)
Execute(context.Context, func(context.Context, *TransactOpts) (*types.Transaction, error), ...ExecutionOption) (Transaction, error)
ExecuteAndWait(context.Context, func(context.Context) (Transaction, error)) error
NativeTokenBalance(context.Context) (decimal.Decimal, error)
CurrentBlockNumber(context.Context) (uint64, error)
CurrentBlock(context.Context) (*types.Block, error)
SetPendingTransactionCheckPeriod(duration time.Duration)
TransactionByHash(context.Context, common.Hash) (*types.Transaction, bool, error)
TokenService() TokenService
}
type ClientOption func(c Client) (Client, error)
type ClientOption func(c *client) (*client, error)
func WithPendingTransactionWaitResolution(duration time.Duration) ClientOption {
return func(c Client) (Client, error) {
c.SetPendingTransactionCheckPeriod(duration)
return func(c *client) (*client, error) {
c.pendingTransactionCheckPeriod = duration
return c, nil
}
}
@ -87,24 +86,19 @@ func NewClient(ctx context.Context, rpcurl string, privatekey string, tm TokenMa
return nil, errors.Wrap(err, "retrieving chain id")
}
ires := Client(res)
for _, option := range options {
ires, err = option(ires)
res, err = option(res)
if err != nil {
return nil, errors.Wrap(err, "applying option")
}
}
return ires, nil
return res, nil
}
func (c *client) PublicAddress() common.Address {
return c.fromAddress
}
func (c *client) SetPendingTransactionCheckPeriod(period time.Duration) {
c.pendingTransactionCheckPeriod = period
}
func (c *client) PendingNonce(ctx context.Context) (uint64, error) {
return c.PendingNonceAt(ctx, c.PublicAddress())
}
@ -117,7 +111,7 @@ func (c *client) NewTransactor() (*bind.TransactOpts, error) {
return bind.NewKeyedTransactorWithChainID(c.privateKey, c.chainId)
}
func (c *client) Execute(ctx context.Context, action func(context.Context, *TransactOpts) (*types.Transaction, error)) (Transaction, error) {
func (c *client) Execute(ctx context.Context, action func(context.Context, *TransactOpts) (*types.Transaction, error), opts ...ExecutionOption) (Transaction, error) {
c.transactionlock.Lock()
defer c.transactionlock.Unlock()
localctx, cancel := context.WithTimeout(ctx, c.defaultTimeout)

View File

@ -50,13 +50,13 @@ func (m *MasterChef) PendingCakeOfAddress(pid int64, address common.Address) (de
return m.cake.ValueFromBigInt(raw), nil
}
func (m *MasterChef) EnterStaking(ctx context.Context, amount decimal.Decimal) (evm.Transaction, error) {
func (m *MasterChef) EnterStaking(ctx context.Context, amount decimal.Decimal, opts ...evm.ExecutionOption) (evm.Transaction, error) {
return m.client.Execute(ctx, func(ctx context.Context, opts *evm.TransactOpts) (*types.Transaction, error) {
return m.contract.EnterStaking(opts.TransactOpts, m.cake.ValueToBigInt(amount))
})
}, opts...)
}
func (m *MasterChef) CompoundAndAddCakeBalance(ctx context.Context) (evm.Transaction, error) {
func (m *MasterChef) CompoundAndAddCakeBalance(ctx context.Context, opts ...evm.ExecutionOption) (evm.Transaction, error) {
pending, err := m.PendingCake(0)
if err != nil {
return nil, errors.Wrap(err, "getting pending cake reward")
@ -65,5 +65,5 @@ func (m *MasterChef) CompoundAndAddCakeBalance(ctx context.Context) (evm.Transac
if err != nil {
return nil, errors.Wrap(err, "getting cake balance")
}
return m.EnterStaking(ctx, pending.Add(balance))
return m.EnterStaking(ctx, pending.Add(balance), opts...)
}

View File

@ -51,25 +51,22 @@ func (m *NftMarket) GetAskPriceForToken(collection common.Address, tokenid int)
return m.wbnb.ValueFromBigInt(res.AskInfo[0].Price), nil
}
func (m *NftMarket) BuyTokenWithBNB(ctx context.Context, collection common.Address, tokenid int, price decimal.Decimal, gas decimal.Decimal) (evm.Transaction, error) {
func (m *NftMarket) BuyTokenWithBNB(ctx context.Context, collection common.Address, tokenid int, opts ...evm.ExecutionOption) (evm.Transaction, error) {
return m.client.Execute(ctx, func(ctx context.Context, opts *evm.TransactOpts) (*types.Transaction, error) {
opts.SetValue(price)
opts.SetGasPrice(gas)
opts.SetGasLimit(1000000)
return m.contract.BuyTokenUsingBNB(opts.TransactOpts, collection, big.NewInt(int64(tokenid)))
})
}, opts...)
}
func (m *NftMarket) BuyTokenWithWBNB(ctx context.Context, collection common.Address, tokenid int, price decimal.Decimal, gas decimal.Decimal) (evm.Transaction, error) {
func (m *NftMarket) BuyTokenWithWBNB(ctx context.Context, collection common.Address, tokenid int, price decimal.Decimal, opts ...evm.ExecutionOption) (evm.Transaction, error) {
return m.client.Execute(ctx, func(ctx context.Context, opts *evm.TransactOpts) (*types.Transaction, error) {
opts.SetGasPrice(gas)
opts.SetGasLimit(1000000)
return m.contract.BuyTokenUsingWBNB(opts.TransactOpts, collection, big.NewInt(int64(tokenid)), m.wbnb.ValueToBigInt(price))
})
}, opts...)
}
func (m *NftMarket) CreateAskOrder(ctx context.Context, collection common.Address, tokenid int, price decimal.Decimal) (evm.Transaction, error) {
func (m *NftMarket) CreateAskOrder(ctx context.Context, collection common.Address, tokenid int, price decimal.Decimal, opts ...evm.ExecutionOption) (evm.Transaction, error) {
return m.client.Execute(ctx, func(ctx context.Context, opts *evm.TransactOpts) (*types.Transaction, error) {
return m.contract.CreateAskOrder(opts.TransactOpts, collection, big.NewInt(int64(tokenid)), m.wbnb.ValueToBigInt(price))
})
}, opts...)
}

View File

@ -21,8 +21,8 @@ type Token interface {
BalanceOf(common.Address) (decimal.Decimal, error)
Balance() (decimal.Decimal, error)
Allowance(owner common.Address, spender common.Address) (decimal.Decimal, error)
Approve(ctx context.Context, spender common.Address, value decimal.Decimal) (Transaction, error)
Transfer(ctx context.Context, to common.Address, value decimal.Decimal) (Transaction, error)
Approve(ctx context.Context, spender common.Address, value decimal.Decimal, opts ...ExecutionOption) (Transaction, error)
Transfer(ctx context.Context, to common.Address, value decimal.Decimal, opts ...ExecutionOption) (Transaction, error)
ValueToBigInt(value decimal.Decimal) *big.Int
ValueFromBigInt(value *big.Int) decimal.Decimal
@ -89,16 +89,16 @@ func (t *baseToken) Allowance(owner common.Address, spender common.Address) (dec
return t.ValueFromBigInt(a), nil
}
func (t *baseToken) Approve(ctx context.Context, spender common.Address, value decimal.Decimal) (Transaction, error) {
func (t *baseToken) Approve(ctx context.Context, spender common.Address, value decimal.Decimal, opts ...ExecutionOption) (Transaction, error) {
return t.client.Execute(ctx, func(ctx context.Context, options *TransactOpts) (*types.Transaction, error) {
return t.contract.Approve(options.TransactOpts, spender, t.ValueToBigInt(value))
})
}, opts...)
}
func (t *baseToken) Transfer(ctx context.Context, to common.Address, value decimal.Decimal) (Transaction, error) {
func (t *baseToken) Transfer(ctx context.Context, to common.Address, value decimal.Decimal, opts ...ExecutionOption) (Transaction, error) {
return t.client.Execute(ctx, func(ctx context.Context, options *TransactOpts) (*types.Transaction, error) {
return t.contract.Transfer(options.TransactOpts, to, t.ValueToBigInt(value))
})
}, opts...)
}
func (t *baseToken) Address() common.Address {

View File

@ -2,6 +2,7 @@ package evm
import (
"context"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/shopspring/decimal"
)
@ -37,3 +38,21 @@ func (o *TransactOpts) SetGasPrice(gasprice decimal.Decimal) *TransactOpts {
o.GasPrice = gasprice.Shift(9).BigInt()
return o
}
type ExecutionOption func(*TransactOpts) *TransactOpts
func WithGasPrice(gasprice decimal.Decimal) ExecutionOption {
return func(opts *TransactOpts) *TransactOpts {
return opts.SetGasPrice(gasprice)
}
}
func WithGasLimit(gaslimit uint64) ExecutionOption {
return func(opts *TransactOpts) *TransactOpts {
return opts.SetGasLimit(gaslimit)
}
}
func WithValue(value decimal.Decimal) ExecutionOption {
return func(opts *TransactOpts) *TransactOpts {
return opts.SetValue(value)
}
}

View File

@ -49,7 +49,7 @@ func (s *UniswapRouter) Name() string {
return s.name
}
func (s *UniswapRouter) SwapTokenToToken(ctx context.Context, path []common.Address, amount decimal.Decimal, slippage decimal.Decimal) (Transaction, error) {
func (s *UniswapRouter) SwapTokenToToken(ctx context.Context, path []common.Address, amount decimal.Decimal, slippage decimal.Decimal, opts ...ExecutionOption) (Transaction, error) {
if len(path) < 2 {
return nil, errors.Errorf("swap path must contain at least 2 addresses, currently %d", len(path))
}
@ -94,7 +94,7 @@ func (s *UniswapRouter) SwapTokenToToken(ctx context.Context, path []common.Addr
path,
s.client.PublicAddress(),
s.getDeadline())
})
}, opts...)
if err != nil {
return nil, errors.Wrap(err, "swaping")
}
@ -134,7 +134,7 @@ func (s *UniswapRouter) GetAmountRate(token0 Token, token1 Token, amount decimal
return token1.ValueFromBigInt(expectedout[len(expectedout)-1]), nil
}
func (s *UniswapRouter) AddLiquidity(ctx context.Context, token1 Token, token2 Token, amounttoken1 decimal.Decimal, amounttoken2 decimal.Decimal) (Transaction, error) {
func (s *UniswapRouter) AddLiquidity(ctx context.Context, token1 Token, token2 Token, amounttoken1 decimal.Decimal, amounttoken2 decimal.Decimal, opts ...ExecutionOption) (Transaction, error) {
return s.client.Execute(ctx, func(ctx context.Context, options *TransactOpts) (*types.Transaction, error) {
return s.contract.AddLiquidity(
options.TransactOpts,
@ -146,5 +146,5 @@ func (s *UniswapRouter) AddLiquidity(ctx context.Context, token1 Token, token2 T
token2.ValueToBigInt(amounttoken2.Sub(amounttoken2.Mul(decimal.NewFromFloat(0.01)))),
s.client.PublicAddress(),
s.getDeadline())
})
}, opts...)
}