chore(wallet)_: tests for wallet.Reader fetching balances
chore(wallet)_: split getWalletTokenBalances into multiple functions Removed some unused balances methods from wallet API chore(wallet)_: refactored FetchOrGetWalletTokenBalances - getWalletTokenBalances only returns cached ones - update of balances is done in a separate method chore(wallet)_: fix isVisible in getWalletTokenBalances is overwritten It is overwritten and in some cases its value is desrespected chore(wallet)_: simplify getWalletTokenBalance even further chore(wallet)_: remove accountsDB from wallet.Reader Call GetTestNetworkEnabled from NetworkManager instead chore(wallet)_: remove rpc.Client from wallet.Reader. Added GetActiveNetworks() method for NetworkManager Removed adding native tokens from networks, as this is done already in NetworkManager chore(wallet)_: moved Persistence to token package As it works with token_balances table, moved Persistence to token package. Fixed TokenManager's Mark/Get previously owned tokens to use persistence storage instead of direct SQL calls. Introduced StorageToken that aggregates Token type, because when Persistence moved to token package, names clash test(wallet)_: tests for wallet.Reader.FetchorGetCachedBalances
This commit is contained in:
parent
d2f4cae18f
commit
bd816f1e29
4
Makefile
4
Makefile
|
@ -339,6 +339,10 @@ mock: ##@other Regenerate mocks
|
|||
mockgen -package=peer -destination=services/peer/discoverer_mock.go -source=services/peer/service.go
|
||||
mockgen -package=mock_transactor -destination=transactions/mock_transactor/transactor.go -source=transactions/transactor.go
|
||||
mockgen -package=mock_pathprocessor -destination=services/wallet/router/pathprocessor/mock_pathprocessor/processor.go -source=services/wallet/router/pathprocessor/processor.go
|
||||
mockgen -package=mock_bridge -destination=services/wallet/bridge/mock_bridge/bridge.go -source=services/wallet/bridge/bridge.go
|
||||
mockgen -package=mock_client -destination=rpc/chain/mock/client/client.go -source=rpc/chain/client.go
|
||||
mockgen -package=mock_token -destination=services/wallet/token/mock/token/tokenmanager.go -source=services/wallet/token/token.go
|
||||
mockgen -package=mock_balance_persistence -destination=services/wallet/token/mock/balance_persistence/balance_persistence.go -source=services/wallet/token/balance_persistence.go
|
||||
|
||||
docker-test: ##@tests Run tests in a docker container with golang.
|
||||
docker run --privileged --rm -it -v "$(PWD):$(DOCKER_TEST_WORKDIR)" -w "$(DOCKER_TEST_WORKDIR)" $(DOCKER_TEST_IMAGE) go test ${ARGS}
|
||||
|
|
|
@ -467,7 +467,7 @@ func NewMessenger(
|
|||
if c.tokenManager != nil {
|
||||
managerOptions = append(managerOptions, communities.WithTokenManager(c.tokenManager))
|
||||
} else if c.rpcClient != nil {
|
||||
tokenManager := token.NewTokenManager(c.walletDb, c.rpcClient, community.NewManager(database, c.httpServer, nil), c.rpcClient.NetworkManager, database, c.httpServer, nil, nil, nil)
|
||||
tokenManager := token.NewTokenManager(c.walletDb, c.rpcClient, community.NewManager(database, c.httpServer, nil), c.rpcClient.NetworkManager, database, c.httpServer, nil, nil, nil, token.NewPersistence(c.walletDb))
|
||||
managerOptions = append(managerOptions, communities.WithTokenManager(communities.NewDefaultTokenManager(tokenManager)))
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,917 @@
|
|||
// Code generated by MockGen. DO NOT EDIT.
|
||||
// Source: rpc/chain/client.go
|
||||
|
||||
// Package mock_client is a generated GoMock package.
|
||||
package mock_client
|
||||
|
||||
import (
|
||||
context "context"
|
||||
big "math/big"
|
||||
reflect "reflect"
|
||||
|
||||
gomock "github.com/golang/mock/gomock"
|
||||
|
||||
ethereum "github.com/ethereum/go-ethereum"
|
||||
common "github.com/ethereum/go-ethereum/common"
|
||||
types "github.com/ethereum/go-ethereum/core/types"
|
||||
rpc "github.com/ethereum/go-ethereum/rpc"
|
||||
chain "github.com/status-im/status-go/rpc/chain"
|
||||
)
|
||||
|
||||
// MockBatchCallClient is a mock of BatchCallClient interface.
|
||||
type MockBatchCallClient struct {
|
||||
ctrl *gomock.Controller
|
||||
recorder *MockBatchCallClientMockRecorder
|
||||
}
|
||||
|
||||
// MockBatchCallClientMockRecorder is the mock recorder for MockBatchCallClient.
|
||||
type MockBatchCallClientMockRecorder struct {
|
||||
mock *MockBatchCallClient
|
||||
}
|
||||
|
||||
// NewMockBatchCallClient creates a new mock instance.
|
||||
func NewMockBatchCallClient(ctrl *gomock.Controller) *MockBatchCallClient {
|
||||
mock := &MockBatchCallClient{ctrl: ctrl}
|
||||
mock.recorder = &MockBatchCallClientMockRecorder{mock}
|
||||
return mock
|
||||
}
|
||||
|
||||
// EXPECT returns an object that allows the caller to indicate expected use.
|
||||
func (m *MockBatchCallClient) EXPECT() *MockBatchCallClientMockRecorder {
|
||||
return m.recorder
|
||||
}
|
||||
|
||||
// BatchCallContext mocks base method.
|
||||
func (m *MockBatchCallClient) BatchCallContext(ctx context.Context, b []rpc.BatchElem) error {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "BatchCallContext", ctx, b)
|
||||
ret0, _ := ret[0].(error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// BatchCallContext indicates an expected call of BatchCallContext.
|
||||
func (mr *MockBatchCallClientMockRecorder) BatchCallContext(ctx, b interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BatchCallContext", reflect.TypeOf((*MockBatchCallClient)(nil).BatchCallContext), ctx, b)
|
||||
}
|
||||
|
||||
// MockChainInterface is a mock of ChainInterface interface.
|
||||
type MockChainInterface struct {
|
||||
ctrl *gomock.Controller
|
||||
recorder *MockChainInterfaceMockRecorder
|
||||
}
|
||||
|
||||
// MockChainInterfaceMockRecorder is the mock recorder for MockChainInterface.
|
||||
type MockChainInterfaceMockRecorder struct {
|
||||
mock *MockChainInterface
|
||||
}
|
||||
|
||||
// NewMockChainInterface creates a new mock instance.
|
||||
func NewMockChainInterface(ctrl *gomock.Controller) *MockChainInterface {
|
||||
mock := &MockChainInterface{ctrl: ctrl}
|
||||
mock.recorder = &MockChainInterfaceMockRecorder{mock}
|
||||
return mock
|
||||
}
|
||||
|
||||
// EXPECT returns an object that allows the caller to indicate expected use.
|
||||
func (m *MockChainInterface) EXPECT() *MockChainInterfaceMockRecorder {
|
||||
return m.recorder
|
||||
}
|
||||
|
||||
// BalanceAt mocks base method.
|
||||
func (m *MockChainInterface) BalanceAt(ctx context.Context, account common.Address, blockNumber *big.Int) (*big.Int, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "BalanceAt", ctx, account, blockNumber)
|
||||
ret0, _ := ret[0].(*big.Int)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// BalanceAt indicates an expected call of BalanceAt.
|
||||
func (mr *MockChainInterfaceMockRecorder) BalanceAt(ctx, account, blockNumber interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BalanceAt", reflect.TypeOf((*MockChainInterface)(nil).BalanceAt), ctx, account, blockNumber)
|
||||
}
|
||||
|
||||
// BatchCallContext mocks base method.
|
||||
func (m *MockChainInterface) BatchCallContext(ctx context.Context, b []rpc.BatchElem) error {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "BatchCallContext", ctx, b)
|
||||
ret0, _ := ret[0].(error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// BatchCallContext indicates an expected call of BatchCallContext.
|
||||
func (mr *MockChainInterfaceMockRecorder) BatchCallContext(ctx, b interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BatchCallContext", reflect.TypeOf((*MockChainInterface)(nil).BatchCallContext), ctx, b)
|
||||
}
|
||||
|
||||
// BlockByHash mocks base method.
|
||||
func (m *MockChainInterface) BlockByHash(ctx context.Context, hash common.Hash) (*types.Block, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "BlockByHash", ctx, hash)
|
||||
ret0, _ := ret[0].(*types.Block)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// BlockByHash indicates an expected call of BlockByHash.
|
||||
func (mr *MockChainInterfaceMockRecorder) BlockByHash(ctx, hash interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BlockByHash", reflect.TypeOf((*MockChainInterface)(nil).BlockByHash), ctx, hash)
|
||||
}
|
||||
|
||||
// BlockByNumber mocks base method.
|
||||
func (m *MockChainInterface) BlockByNumber(ctx context.Context, number *big.Int) (*types.Block, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "BlockByNumber", ctx, number)
|
||||
ret0, _ := ret[0].(*types.Block)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// BlockByNumber indicates an expected call of BlockByNumber.
|
||||
func (mr *MockChainInterfaceMockRecorder) BlockByNumber(ctx, number interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BlockByNumber", reflect.TypeOf((*MockChainInterface)(nil).BlockByNumber), ctx, number)
|
||||
}
|
||||
|
||||
// BlockNumber mocks base method.
|
||||
func (m *MockChainInterface) BlockNumber(ctx context.Context) (uint64, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "BlockNumber", ctx)
|
||||
ret0, _ := ret[0].(uint64)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// BlockNumber indicates an expected call of BlockNumber.
|
||||
func (mr *MockChainInterfaceMockRecorder) BlockNumber(ctx interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BlockNumber", reflect.TypeOf((*MockChainInterface)(nil).BlockNumber), ctx)
|
||||
}
|
||||
|
||||
// CallBlockHashByTransaction mocks base method.
|
||||
func (m *MockChainInterface) CallBlockHashByTransaction(ctx context.Context, blockNumber *big.Int, index uint) (common.Hash, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "CallBlockHashByTransaction", ctx, blockNumber, index)
|
||||
ret0, _ := ret[0].(common.Hash)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// CallBlockHashByTransaction indicates an expected call of CallBlockHashByTransaction.
|
||||
func (mr *MockChainInterfaceMockRecorder) CallBlockHashByTransaction(ctx, blockNumber, index interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CallBlockHashByTransaction", reflect.TypeOf((*MockChainInterface)(nil).CallBlockHashByTransaction), ctx, blockNumber, index)
|
||||
}
|
||||
|
||||
// CallContext mocks base method.
|
||||
func (m *MockChainInterface) CallContext(ctx context.Context, result interface{}, method string, args ...interface{}) error {
|
||||
m.ctrl.T.Helper()
|
||||
varargs := []interface{}{ctx, result, method}
|
||||
for _, a := range args {
|
||||
varargs = append(varargs, a)
|
||||
}
|
||||
ret := m.ctrl.Call(m, "CallContext", varargs...)
|
||||
ret0, _ := ret[0].(error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// CallContext indicates an expected call of CallContext.
|
||||
func (mr *MockChainInterfaceMockRecorder) CallContext(ctx, result, method interface{}, args ...interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
varargs := append([]interface{}{ctx, result, method}, args...)
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CallContext", reflect.TypeOf((*MockChainInterface)(nil).CallContext), varargs...)
|
||||
}
|
||||
|
||||
// CallContract mocks base method.
|
||||
func (m *MockChainInterface) CallContract(ctx context.Context, call ethereum.CallMsg, blockNumber *big.Int) ([]byte, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "CallContract", ctx, call, blockNumber)
|
||||
ret0, _ := ret[0].([]byte)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// CallContract indicates an expected call of CallContract.
|
||||
func (mr *MockChainInterfaceMockRecorder) CallContract(ctx, call, blockNumber interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CallContract", reflect.TypeOf((*MockChainInterface)(nil).CallContract), ctx, call, blockNumber)
|
||||
}
|
||||
|
||||
// CodeAt mocks base method.
|
||||
func (m *MockChainInterface) CodeAt(ctx context.Context, contract common.Address, blockNumber *big.Int) ([]byte, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "CodeAt", ctx, contract, blockNumber)
|
||||
ret0, _ := ret[0].([]byte)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// CodeAt indicates an expected call of CodeAt.
|
||||
func (mr *MockChainInterfaceMockRecorder) CodeAt(ctx, contract, blockNumber interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CodeAt", reflect.TypeOf((*MockChainInterface)(nil).CodeAt), ctx, contract, blockNumber)
|
||||
}
|
||||
|
||||
// FilterLogs mocks base method.
|
||||
func (m *MockChainInterface) FilterLogs(ctx context.Context, q ethereum.FilterQuery) ([]types.Log, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "FilterLogs", ctx, q)
|
||||
ret0, _ := ret[0].([]types.Log)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// FilterLogs indicates an expected call of FilterLogs.
|
||||
func (mr *MockChainInterfaceMockRecorder) FilterLogs(ctx, q interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FilterLogs", reflect.TypeOf((*MockChainInterface)(nil).FilterLogs), ctx, q)
|
||||
}
|
||||
|
||||
// GetBaseFeeFromBlock mocks base method.
|
||||
func (m *MockChainInterface) GetBaseFeeFromBlock(ctx context.Context, blockNumber *big.Int) (string, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "GetBaseFeeFromBlock", ctx, blockNumber)
|
||||
ret0, _ := ret[0].(string)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// GetBaseFeeFromBlock indicates an expected call of GetBaseFeeFromBlock.
|
||||
func (mr *MockChainInterfaceMockRecorder) GetBaseFeeFromBlock(ctx, blockNumber interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBaseFeeFromBlock", reflect.TypeOf((*MockChainInterface)(nil).GetBaseFeeFromBlock), ctx, blockNumber)
|
||||
}
|
||||
|
||||
// HeaderByHash mocks base method.
|
||||
func (m *MockChainInterface) HeaderByHash(ctx context.Context, hash common.Hash) (*types.Header, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "HeaderByHash", ctx, hash)
|
||||
ret0, _ := ret[0].(*types.Header)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// HeaderByHash indicates an expected call of HeaderByHash.
|
||||
func (mr *MockChainInterfaceMockRecorder) HeaderByHash(ctx, hash interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HeaderByHash", reflect.TypeOf((*MockChainInterface)(nil).HeaderByHash), ctx, hash)
|
||||
}
|
||||
|
||||
// HeaderByNumber mocks base method.
|
||||
func (m *MockChainInterface) HeaderByNumber(ctx context.Context, number *big.Int) (*types.Header, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "HeaderByNumber", ctx, number)
|
||||
ret0, _ := ret[0].(*types.Header)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// HeaderByNumber indicates an expected call of HeaderByNumber.
|
||||
func (mr *MockChainInterfaceMockRecorder) HeaderByNumber(ctx, number interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HeaderByNumber", reflect.TypeOf((*MockChainInterface)(nil).HeaderByNumber), ctx, number)
|
||||
}
|
||||
|
||||
// NetworkID mocks base method.
|
||||
func (m *MockChainInterface) NetworkID() uint64 {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "NetworkID")
|
||||
ret0, _ := ret[0].(uint64)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// NetworkID indicates an expected call of NetworkID.
|
||||
func (mr *MockChainInterfaceMockRecorder) NetworkID() *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetworkID", reflect.TypeOf((*MockChainInterface)(nil).NetworkID))
|
||||
}
|
||||
|
||||
// NonceAt mocks base method.
|
||||
func (m *MockChainInterface) NonceAt(ctx context.Context, account common.Address, blockNumber *big.Int) (uint64, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "NonceAt", ctx, account, blockNumber)
|
||||
ret0, _ := ret[0].(uint64)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// NonceAt indicates an expected call of NonceAt.
|
||||
func (mr *MockChainInterfaceMockRecorder) NonceAt(ctx, account, blockNumber interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NonceAt", reflect.TypeOf((*MockChainInterface)(nil).NonceAt), ctx, account, blockNumber)
|
||||
}
|
||||
|
||||
// ToBigInt mocks base method.
|
||||
func (m *MockChainInterface) ToBigInt() *big.Int {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "ToBigInt")
|
||||
ret0, _ := ret[0].(*big.Int)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// ToBigInt indicates an expected call of ToBigInt.
|
||||
func (mr *MockChainInterfaceMockRecorder) ToBigInt() *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ToBigInt", reflect.TypeOf((*MockChainInterface)(nil).ToBigInt))
|
||||
}
|
||||
|
||||
// TransactionByHash mocks base method.
|
||||
func (m *MockChainInterface) TransactionByHash(ctx context.Context, hash common.Hash) (*types.Transaction, bool, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "TransactionByHash", ctx, hash)
|
||||
ret0, _ := ret[0].(*types.Transaction)
|
||||
ret1, _ := ret[1].(bool)
|
||||
ret2, _ := ret[2].(error)
|
||||
return ret0, ret1, ret2
|
||||
}
|
||||
|
||||
// TransactionByHash indicates an expected call of TransactionByHash.
|
||||
func (mr *MockChainInterfaceMockRecorder) TransactionByHash(ctx, hash interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "TransactionByHash", reflect.TypeOf((*MockChainInterface)(nil).TransactionByHash), ctx, hash)
|
||||
}
|
||||
|
||||
// TransactionReceipt mocks base method.
|
||||
func (m *MockChainInterface) TransactionReceipt(ctx context.Context, txHash common.Hash) (*types.Receipt, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "TransactionReceipt", ctx, txHash)
|
||||
ret0, _ := ret[0].(*types.Receipt)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// TransactionReceipt indicates an expected call of TransactionReceipt.
|
||||
func (mr *MockChainInterfaceMockRecorder) TransactionReceipt(ctx, txHash interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "TransactionReceipt", reflect.TypeOf((*MockChainInterface)(nil).TransactionReceipt), ctx, txHash)
|
||||
}
|
||||
|
||||
// MockClientInterface is a mock of ClientInterface interface.
|
||||
type MockClientInterface struct {
|
||||
ctrl *gomock.Controller
|
||||
recorder *MockClientInterfaceMockRecorder
|
||||
}
|
||||
|
||||
// MockClientInterfaceMockRecorder is the mock recorder for MockClientInterface.
|
||||
type MockClientInterfaceMockRecorder struct {
|
||||
mock *MockClientInterface
|
||||
}
|
||||
|
||||
// NewMockClientInterface creates a new mock instance.
|
||||
func NewMockClientInterface(ctrl *gomock.Controller) *MockClientInterface {
|
||||
mock := &MockClientInterface{ctrl: ctrl}
|
||||
mock.recorder = &MockClientInterfaceMockRecorder{mock}
|
||||
return mock
|
||||
}
|
||||
|
||||
// EXPECT returns an object that allows the caller to indicate expected use.
|
||||
func (m *MockClientInterface) EXPECT() *MockClientInterfaceMockRecorder {
|
||||
return m.recorder
|
||||
}
|
||||
|
||||
// BalanceAt mocks base method.
|
||||
func (m *MockClientInterface) BalanceAt(ctx context.Context, account common.Address, blockNumber *big.Int) (*big.Int, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "BalanceAt", ctx, account, blockNumber)
|
||||
ret0, _ := ret[0].(*big.Int)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// BalanceAt indicates an expected call of BalanceAt.
|
||||
func (mr *MockClientInterfaceMockRecorder) BalanceAt(ctx, account, blockNumber interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BalanceAt", reflect.TypeOf((*MockClientInterface)(nil).BalanceAt), ctx, account, blockNumber)
|
||||
}
|
||||
|
||||
// BatchCallContext mocks base method.
|
||||
func (m *MockClientInterface) BatchCallContext(ctx context.Context, b []rpc.BatchElem) error {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "BatchCallContext", ctx, b)
|
||||
ret0, _ := ret[0].(error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// BatchCallContext indicates an expected call of BatchCallContext.
|
||||
func (mr *MockClientInterfaceMockRecorder) BatchCallContext(ctx, b interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BatchCallContext", reflect.TypeOf((*MockClientInterface)(nil).BatchCallContext), ctx, b)
|
||||
}
|
||||
|
||||
// BlockByHash mocks base method.
|
||||
func (m *MockClientInterface) BlockByHash(ctx context.Context, hash common.Hash) (*types.Block, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "BlockByHash", ctx, hash)
|
||||
ret0, _ := ret[0].(*types.Block)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// BlockByHash indicates an expected call of BlockByHash.
|
||||
func (mr *MockClientInterfaceMockRecorder) BlockByHash(ctx, hash interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BlockByHash", reflect.TypeOf((*MockClientInterface)(nil).BlockByHash), ctx, hash)
|
||||
}
|
||||
|
||||
// BlockByNumber mocks base method.
|
||||
func (m *MockClientInterface) BlockByNumber(ctx context.Context, number *big.Int) (*types.Block, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "BlockByNumber", ctx, number)
|
||||
ret0, _ := ret[0].(*types.Block)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// BlockByNumber indicates an expected call of BlockByNumber.
|
||||
func (mr *MockClientInterfaceMockRecorder) BlockByNumber(ctx, number interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BlockByNumber", reflect.TypeOf((*MockClientInterface)(nil).BlockByNumber), ctx, number)
|
||||
}
|
||||
|
||||
// BlockNumber mocks base method.
|
||||
func (m *MockClientInterface) BlockNumber(ctx context.Context) (uint64, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "BlockNumber", ctx)
|
||||
ret0, _ := ret[0].(uint64)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// BlockNumber indicates an expected call of BlockNumber.
|
||||
func (mr *MockClientInterfaceMockRecorder) BlockNumber(ctx interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BlockNumber", reflect.TypeOf((*MockClientInterface)(nil).BlockNumber), ctx)
|
||||
}
|
||||
|
||||
// CallBlockHashByTransaction mocks base method.
|
||||
func (m *MockClientInterface) CallBlockHashByTransaction(ctx context.Context, blockNumber *big.Int, index uint) (common.Hash, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "CallBlockHashByTransaction", ctx, blockNumber, index)
|
||||
ret0, _ := ret[0].(common.Hash)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// CallBlockHashByTransaction indicates an expected call of CallBlockHashByTransaction.
|
||||
func (mr *MockClientInterfaceMockRecorder) CallBlockHashByTransaction(ctx, blockNumber, index interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CallBlockHashByTransaction", reflect.TypeOf((*MockClientInterface)(nil).CallBlockHashByTransaction), ctx, blockNumber, index)
|
||||
}
|
||||
|
||||
// CallContext mocks base method.
|
||||
func (m *MockClientInterface) CallContext(ctx context.Context, result interface{}, method string, args ...interface{}) error {
|
||||
m.ctrl.T.Helper()
|
||||
varargs := []interface{}{ctx, result, method}
|
||||
for _, a := range args {
|
||||
varargs = append(varargs, a)
|
||||
}
|
||||
ret := m.ctrl.Call(m, "CallContext", varargs...)
|
||||
ret0, _ := ret[0].(error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// CallContext indicates an expected call of CallContext.
|
||||
func (mr *MockClientInterfaceMockRecorder) CallContext(ctx, result, method interface{}, args ...interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
varargs := append([]interface{}{ctx, result, method}, args...)
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CallContext", reflect.TypeOf((*MockClientInterface)(nil).CallContext), varargs...)
|
||||
}
|
||||
|
||||
// CallContract mocks base method.
|
||||
func (m *MockClientInterface) CallContract(ctx context.Context, call ethereum.CallMsg, blockNumber *big.Int) ([]byte, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "CallContract", ctx, call, blockNumber)
|
||||
ret0, _ := ret[0].([]byte)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// CallContract indicates an expected call of CallContract.
|
||||
func (mr *MockClientInterfaceMockRecorder) CallContract(ctx, call, blockNumber interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CallContract", reflect.TypeOf((*MockClientInterface)(nil).CallContract), ctx, call, blockNumber)
|
||||
}
|
||||
|
||||
// CodeAt mocks base method.
|
||||
func (m *MockClientInterface) CodeAt(ctx context.Context, contract common.Address, blockNumber *big.Int) ([]byte, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "CodeAt", ctx, contract, blockNumber)
|
||||
ret0, _ := ret[0].([]byte)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// CodeAt indicates an expected call of CodeAt.
|
||||
func (mr *MockClientInterfaceMockRecorder) CodeAt(ctx, contract, blockNumber interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CodeAt", reflect.TypeOf((*MockClientInterface)(nil).CodeAt), ctx, contract, blockNumber)
|
||||
}
|
||||
|
||||
// EstimateGas mocks base method.
|
||||
func (m *MockClientInterface) EstimateGas(ctx context.Context, call ethereum.CallMsg) (uint64, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "EstimateGas", ctx, call)
|
||||
ret0, _ := ret[0].(uint64)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// EstimateGas indicates an expected call of EstimateGas.
|
||||
func (mr *MockClientInterfaceMockRecorder) EstimateGas(ctx, call interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EstimateGas", reflect.TypeOf((*MockClientInterface)(nil).EstimateGas), ctx, call)
|
||||
}
|
||||
|
||||
// FilterLogs mocks base method.
|
||||
func (m *MockClientInterface) FilterLogs(ctx context.Context, q ethereum.FilterQuery) ([]types.Log, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "FilterLogs", ctx, q)
|
||||
ret0, _ := ret[0].([]types.Log)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// FilterLogs indicates an expected call of FilterLogs.
|
||||
func (mr *MockClientInterfaceMockRecorder) FilterLogs(ctx, q interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FilterLogs", reflect.TypeOf((*MockClientInterface)(nil).FilterLogs), ctx, q)
|
||||
}
|
||||
|
||||
// GetBaseFeeFromBlock mocks base method.
|
||||
func (m *MockClientInterface) GetBaseFeeFromBlock(ctx context.Context, blockNumber *big.Int) (string, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "GetBaseFeeFromBlock", ctx, blockNumber)
|
||||
ret0, _ := ret[0].(string)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// GetBaseFeeFromBlock indicates an expected call of GetBaseFeeFromBlock.
|
||||
func (mr *MockClientInterfaceMockRecorder) GetBaseFeeFromBlock(ctx, blockNumber interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBaseFeeFromBlock", reflect.TypeOf((*MockClientInterface)(nil).GetBaseFeeFromBlock), ctx, blockNumber)
|
||||
}
|
||||
|
||||
// GetLimiter mocks base method.
|
||||
func (m *MockClientInterface) GetLimiter() chain.RequestLimiter {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "GetLimiter")
|
||||
ret0, _ := ret[0].(chain.RequestLimiter)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// GetLimiter indicates an expected call of GetLimiter.
|
||||
func (mr *MockClientInterfaceMockRecorder) GetLimiter() *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetLimiter", reflect.TypeOf((*MockClientInterface)(nil).GetLimiter))
|
||||
}
|
||||
|
||||
// GetWalletNotifier mocks base method.
|
||||
func (m *MockClientInterface) GetWalletNotifier() func(uint64, string) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "GetWalletNotifier")
|
||||
ret0, _ := ret[0].(func(uint64, string))
|
||||
return ret0
|
||||
}
|
||||
|
||||
// GetWalletNotifier indicates an expected call of GetWalletNotifier.
|
||||
func (mr *MockClientInterfaceMockRecorder) GetWalletNotifier() *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetWalletNotifier", reflect.TypeOf((*MockClientInterface)(nil).GetWalletNotifier))
|
||||
}
|
||||
|
||||
// HeaderByHash mocks base method.
|
||||
func (m *MockClientInterface) HeaderByHash(ctx context.Context, hash common.Hash) (*types.Header, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "HeaderByHash", ctx, hash)
|
||||
ret0, _ := ret[0].(*types.Header)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// HeaderByHash indicates an expected call of HeaderByHash.
|
||||
func (mr *MockClientInterfaceMockRecorder) HeaderByHash(ctx, hash interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HeaderByHash", reflect.TypeOf((*MockClientInterface)(nil).HeaderByHash), ctx, hash)
|
||||
}
|
||||
|
||||
// HeaderByNumber mocks base method.
|
||||
func (m *MockClientInterface) HeaderByNumber(ctx context.Context, number *big.Int) (*types.Header, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "HeaderByNumber", ctx, number)
|
||||
ret0, _ := ret[0].(*types.Header)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// HeaderByNumber indicates an expected call of HeaderByNumber.
|
||||
func (mr *MockClientInterfaceMockRecorder) HeaderByNumber(ctx, number interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HeaderByNumber", reflect.TypeOf((*MockClientInterface)(nil).HeaderByNumber), ctx, number)
|
||||
}
|
||||
|
||||
// IsConnected mocks base method.
|
||||
func (m *MockClientInterface) IsConnected() bool {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "IsConnected")
|
||||
ret0, _ := ret[0].(bool)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// IsConnected indicates an expected call of IsConnected.
|
||||
func (mr *MockClientInterfaceMockRecorder) IsConnected() *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IsConnected", reflect.TypeOf((*MockClientInterface)(nil).IsConnected))
|
||||
}
|
||||
|
||||
// NetworkID mocks base method.
|
||||
func (m *MockClientInterface) NetworkID() uint64 {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "NetworkID")
|
||||
ret0, _ := ret[0].(uint64)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// NetworkID indicates an expected call of NetworkID.
|
||||
func (mr *MockClientInterfaceMockRecorder) NetworkID() *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetworkID", reflect.TypeOf((*MockClientInterface)(nil).NetworkID))
|
||||
}
|
||||
|
||||
// NonceAt mocks base method.
|
||||
func (m *MockClientInterface) NonceAt(ctx context.Context, account common.Address, blockNumber *big.Int) (uint64, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "NonceAt", ctx, account, blockNumber)
|
||||
ret0, _ := ret[0].(uint64)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// NonceAt indicates an expected call of NonceAt.
|
||||
func (mr *MockClientInterfaceMockRecorder) NonceAt(ctx, account, blockNumber interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NonceAt", reflect.TypeOf((*MockClientInterface)(nil).NonceAt), ctx, account, blockNumber)
|
||||
}
|
||||
|
||||
// PendingCodeAt mocks base method.
|
||||
func (m *MockClientInterface) PendingCodeAt(ctx context.Context, account common.Address) ([]byte, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "PendingCodeAt", ctx, account)
|
||||
ret0, _ := ret[0].([]byte)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// PendingCodeAt indicates an expected call of PendingCodeAt.
|
||||
func (mr *MockClientInterfaceMockRecorder) PendingCodeAt(ctx, account interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PendingCodeAt", reflect.TypeOf((*MockClientInterface)(nil).PendingCodeAt), ctx, account)
|
||||
}
|
||||
|
||||
// PendingNonceAt mocks base method.
|
||||
func (m *MockClientInterface) PendingNonceAt(ctx context.Context, account common.Address) (uint64, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "PendingNonceAt", ctx, account)
|
||||
ret0, _ := ret[0].(uint64)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// PendingNonceAt indicates an expected call of PendingNonceAt.
|
||||
func (mr *MockClientInterfaceMockRecorder) PendingNonceAt(ctx, account interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PendingNonceAt", reflect.TypeOf((*MockClientInterface)(nil).PendingNonceAt), ctx, account)
|
||||
}
|
||||
|
||||
// SendTransaction mocks base method.
|
||||
func (m *MockClientInterface) SendTransaction(ctx context.Context, tx *types.Transaction) error {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "SendTransaction", ctx, tx)
|
||||
ret0, _ := ret[0].(error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// SendTransaction indicates an expected call of SendTransaction.
|
||||
func (mr *MockClientInterfaceMockRecorder) SendTransaction(ctx, tx interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendTransaction", reflect.TypeOf((*MockClientInterface)(nil).SendTransaction), ctx, tx)
|
||||
}
|
||||
|
||||
// SetIsConnected mocks base method.
|
||||
func (m *MockClientInterface) SetIsConnected(arg0 bool) {
|
||||
m.ctrl.T.Helper()
|
||||
m.ctrl.Call(m, "SetIsConnected", arg0)
|
||||
}
|
||||
|
||||
// SetIsConnected indicates an expected call of SetIsConnected.
|
||||
func (mr *MockClientInterfaceMockRecorder) SetIsConnected(arg0 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetIsConnected", reflect.TypeOf((*MockClientInterface)(nil).SetIsConnected), arg0)
|
||||
}
|
||||
|
||||
// SetLimiter mocks base method.
|
||||
func (m *MockClientInterface) SetLimiter(arg0 chain.RequestLimiter) {
|
||||
m.ctrl.T.Helper()
|
||||
m.ctrl.Call(m, "SetLimiter", arg0)
|
||||
}
|
||||
|
||||
// SetLimiter indicates an expected call of SetLimiter.
|
||||
func (mr *MockClientInterfaceMockRecorder) SetLimiter(arg0 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetLimiter", reflect.TypeOf((*MockClientInterface)(nil).SetLimiter), arg0)
|
||||
}
|
||||
|
||||
// SetWalletNotifier mocks base method.
|
||||
func (m *MockClientInterface) SetWalletNotifier(notifier func(uint64, string)) {
|
||||
m.ctrl.T.Helper()
|
||||
m.ctrl.Call(m, "SetWalletNotifier", notifier)
|
||||
}
|
||||
|
||||
// SetWalletNotifier indicates an expected call of SetWalletNotifier.
|
||||
func (mr *MockClientInterfaceMockRecorder) SetWalletNotifier(notifier interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetWalletNotifier", reflect.TypeOf((*MockClientInterface)(nil).SetWalletNotifier), notifier)
|
||||
}
|
||||
|
||||
// SubscribeFilterLogs mocks base method.
|
||||
func (m *MockClientInterface) SubscribeFilterLogs(ctx context.Context, query ethereum.FilterQuery, ch chan<- types.Log) (ethereum.Subscription, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "SubscribeFilterLogs", ctx, query, ch)
|
||||
ret0, _ := ret[0].(ethereum.Subscription)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// SubscribeFilterLogs indicates an expected call of SubscribeFilterLogs.
|
||||
func (mr *MockClientInterfaceMockRecorder) SubscribeFilterLogs(ctx, query, ch interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SubscribeFilterLogs", reflect.TypeOf((*MockClientInterface)(nil).SubscribeFilterLogs), ctx, query, ch)
|
||||
}
|
||||
|
||||
// SuggestGasPrice mocks base method.
|
||||
func (m *MockClientInterface) SuggestGasPrice(ctx context.Context) (*big.Int, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "SuggestGasPrice", ctx)
|
||||
ret0, _ := ret[0].(*big.Int)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// SuggestGasPrice indicates an expected call of SuggestGasPrice.
|
||||
func (mr *MockClientInterfaceMockRecorder) SuggestGasPrice(ctx interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SuggestGasPrice", reflect.TypeOf((*MockClientInterface)(nil).SuggestGasPrice), ctx)
|
||||
}
|
||||
|
||||
// SuggestGasTipCap mocks base method.
|
||||
func (m *MockClientInterface) SuggestGasTipCap(ctx context.Context) (*big.Int, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "SuggestGasTipCap", ctx)
|
||||
ret0, _ := ret[0].(*big.Int)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// SuggestGasTipCap indicates an expected call of SuggestGasTipCap.
|
||||
func (mr *MockClientInterfaceMockRecorder) SuggestGasTipCap(ctx interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SuggestGasTipCap", reflect.TypeOf((*MockClientInterface)(nil).SuggestGasTipCap), ctx)
|
||||
}
|
||||
|
||||
// ToBigInt mocks base method.
|
||||
func (m *MockClientInterface) ToBigInt() *big.Int {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "ToBigInt")
|
||||
ret0, _ := ret[0].(*big.Int)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// ToBigInt indicates an expected call of ToBigInt.
|
||||
func (mr *MockClientInterfaceMockRecorder) ToBigInt() *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ToBigInt", reflect.TypeOf((*MockClientInterface)(nil).ToBigInt))
|
||||
}
|
||||
|
||||
// TransactionByHash mocks base method.
|
||||
func (m *MockClientInterface) TransactionByHash(ctx context.Context, hash common.Hash) (*types.Transaction, bool, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "TransactionByHash", ctx, hash)
|
||||
ret0, _ := ret[0].(*types.Transaction)
|
||||
ret1, _ := ret[1].(bool)
|
||||
ret2, _ := ret[2].(error)
|
||||
return ret0, ret1, ret2
|
||||
}
|
||||
|
||||
// TransactionByHash indicates an expected call of TransactionByHash.
|
||||
func (mr *MockClientInterfaceMockRecorder) TransactionByHash(ctx, hash interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "TransactionByHash", reflect.TypeOf((*MockClientInterface)(nil).TransactionByHash), ctx, hash)
|
||||
}
|
||||
|
||||
// TransactionReceipt mocks base method.
|
||||
func (m *MockClientInterface) TransactionReceipt(ctx context.Context, txHash common.Hash) (*types.Receipt, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "TransactionReceipt", ctx, txHash)
|
||||
ret0, _ := ret[0].(*types.Receipt)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// TransactionReceipt indicates an expected call of TransactionReceipt.
|
||||
func (mr *MockClientInterfaceMockRecorder) TransactionReceipt(ctx, txHash interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "TransactionReceipt", reflect.TypeOf((*MockClientInterface)(nil).TransactionReceipt), ctx, txHash)
|
||||
}
|
||||
|
||||
// MockTagger is a mock of Tagger interface.
|
||||
type MockTagger struct {
|
||||
ctrl *gomock.Controller
|
||||
recorder *MockTaggerMockRecorder
|
||||
}
|
||||
|
||||
// MockTaggerMockRecorder is the mock recorder for MockTagger.
|
||||
type MockTaggerMockRecorder struct {
|
||||
mock *MockTagger
|
||||
}
|
||||
|
||||
// NewMockTagger creates a new mock instance.
|
||||
func NewMockTagger(ctrl *gomock.Controller) *MockTagger {
|
||||
mock := &MockTagger{ctrl: ctrl}
|
||||
mock.recorder = &MockTaggerMockRecorder{mock}
|
||||
return mock
|
||||
}
|
||||
|
||||
// EXPECT returns an object that allows the caller to indicate expected use.
|
||||
func (m *MockTagger) EXPECT() *MockTaggerMockRecorder {
|
||||
return m.recorder
|
||||
}
|
||||
|
||||
// DeepCopyTag mocks base method.
|
||||
func (m *MockTagger) DeepCopyTag() chain.Tagger {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "DeepCopyTag")
|
||||
ret0, _ := ret[0].(chain.Tagger)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// DeepCopyTag indicates an expected call of DeepCopyTag.
|
||||
func (mr *MockTaggerMockRecorder) DeepCopyTag() *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeepCopyTag", reflect.TypeOf((*MockTagger)(nil).DeepCopyTag))
|
||||
}
|
||||
|
||||
// GroupTag mocks base method.
|
||||
func (m *MockTagger) GroupTag() string {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "GroupTag")
|
||||
ret0, _ := ret[0].(string)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// GroupTag indicates an expected call of GroupTag.
|
||||
func (mr *MockTaggerMockRecorder) GroupTag() *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GroupTag", reflect.TypeOf((*MockTagger)(nil).GroupTag))
|
||||
}
|
||||
|
||||
// SetGroupTag mocks base method.
|
||||
func (m *MockTagger) SetGroupTag(tag string) {
|
||||
m.ctrl.T.Helper()
|
||||
m.ctrl.Call(m, "SetGroupTag", tag)
|
||||
}
|
||||
|
||||
// SetGroupTag indicates an expected call of SetGroupTag.
|
||||
func (mr *MockTaggerMockRecorder) SetGroupTag(tag interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetGroupTag", reflect.TypeOf((*MockTagger)(nil).SetGroupTag), tag)
|
||||
}
|
||||
|
||||
// SetTag mocks base method.
|
||||
func (m *MockTagger) SetTag(tag string) {
|
||||
m.ctrl.T.Helper()
|
||||
m.ctrl.Call(m, "SetTag", tag)
|
||||
}
|
||||
|
||||
// SetTag indicates an expected call of SetTag.
|
||||
func (mr *MockTaggerMockRecorder) SetTag(tag interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetTag", reflect.TypeOf((*MockTagger)(nil).SetTag), tag)
|
||||
}
|
||||
|
||||
// Tag mocks base method.
|
||||
func (m *MockTagger) Tag() string {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "Tag")
|
||||
ret0, _ := ret[0].(string)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// Tag indicates an expected call of Tag.
|
||||
func (mr *MockTaggerMockRecorder) Tag() *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Tag", reflect.TypeOf((*MockTagger)(nil).Tag))
|
||||
}
|
|
@ -324,3 +324,26 @@ func (nm *Manager) GetConfiguredNetworks() []params.Network {
|
|||
func (nm *Manager) GetTestNetworksEnabled() (result bool, err error) {
|
||||
return nm.accountsDB.GetTestNetworksEnabled()
|
||||
}
|
||||
|
||||
// Returns all networks for active mode (test/prod) and in case of test mode,
|
||||
// returns either Goerli or Sepolia networks based on the value of isGoerliEnabled
|
||||
func (nm *Manager) GetActiveNetworks() ([]*params.Network, error) {
|
||||
areTestNetworksEnabled, err := nm.GetTestNetworksEnabled()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
networks, err := nm.Get(false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
availableNetworks := make([]*params.Network, 0)
|
||||
for _, network := range networks {
|
||||
if network.IsTest != areTestNetworksEnabled {
|
||||
continue
|
||||
}
|
||||
availableNetworks = append(availableNetworks, network)
|
||||
}
|
||||
|
||||
return availableNetworks, nil
|
||||
}
|
||||
|
|
|
@ -8,10 +8,12 @@ import (
|
|||
"time"
|
||||
|
||||
eth "github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
"github.com/ethereum/go-ethereum/event"
|
||||
|
||||
"github.com/status-im/status-go/appdatabase"
|
||||
"github.com/status-im/status-go/multiaccounts/accounts"
|
||||
"github.com/status-im/status-go/rpc/chain"
|
||||
"github.com/status-im/status-go/services/wallet/bigint"
|
||||
"github.com/status-im/status-go/services/wallet/common"
|
||||
"github.com/status-im/status-go/services/wallet/thirdparty"
|
||||
|
@ -70,6 +72,18 @@ func (m *mockTokenManager) LookupToken(chainID *uint64, tokenSymbol string) (tkn
|
|||
return args.Get(0).(*token.Token), args.Bool(1)
|
||||
}
|
||||
|
||||
func (m *mockTokenManager) GetBalancesByChain(parent context.Context, clients map[uint64]chain.ClientInterface, accounts, tokens []eth.Address) (map[uint64]map[eth.Address]map[eth.Address]*hexutil.Big, error) {
|
||||
return nil, nil // Not used here
|
||||
}
|
||||
|
||||
func (m *mockTokenManager) GetTokensByChainIDs(chainIDs []uint64) ([]*token.Token, error) {
|
||||
return nil, nil // Not used here
|
||||
}
|
||||
|
||||
func (m *mockTokenManager) GetTokenHistoricalBalance(account eth.Address, chainID uint64, symbol string, timestamp int64) (*big.Int, error) {
|
||||
return nil, nil // Not used here
|
||||
}
|
||||
|
||||
type testState struct {
|
||||
service *Service
|
||||
eventFeed *event.Feed
|
||||
|
|
|
@ -64,8 +64,25 @@ func (api *API) SetPairingsJSONFileContent(content []byte) error {
|
|||
return api.s.keycardPairings.SetPairingsJSONFileContent(content)
|
||||
}
|
||||
|
||||
func (api *API) GetWalletToken(ctx context.Context, addresses []common.Address) (map[common.Address][]Token, error) {
|
||||
return api.reader.GetWalletToken(ctx, addresses)
|
||||
// Used by mobile
|
||||
func (api *API) GetWalletToken(ctx context.Context, addresses []common.Address) (map[common.Address][]token.StorageToken, error) {
|
||||
currency, err := api.s.accountsDB.GetCurrency()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
activeNetworks, err := api.s.rpcClient.NetworkManager.GetActiveNetworks()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
chainIDs := wcommon.NetworksToChainIDs(activeNetworks)
|
||||
clients, err := api.s.rpcClient.EthClients(chainIDs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return api.reader.GetWalletToken(ctx, clients, addresses, currency)
|
||||
}
|
||||
|
||||
// GetBalancesByChain return a map with key as chain id and value as map of account address and map of token address and balance
|
||||
|
@ -79,16 +96,19 @@ func (api *API) GetBalancesByChain(ctx context.Context, chainIDs []uint64, addre
|
|||
return api.s.tokenManager.GetBalancesByChain(ctx, clients, addresses, tokens)
|
||||
}
|
||||
|
||||
func (api *API) GetWalletTokenBalances(ctx context.Context, addresses []common.Address) (map[common.Address][]Token, error) {
|
||||
return api.reader.GetWalletTokenBalances(ctx, addresses)
|
||||
}
|
||||
func (api *API) FetchOrGetCachedWalletBalances(ctx context.Context, addresses []common.Address) (map[common.Address][]token.StorageToken, error) {
|
||||
activeNetworks, err := api.s.rpcClient.NetworkManager.GetActiveNetworks()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
func (api *API) FetchOrGetCachedWalletBalances(ctx context.Context, addresses []common.Address) (map[common.Address][]Token, error) {
|
||||
return api.reader.FetchOrGetCachedWalletBalances(ctx, addresses)
|
||||
}
|
||||
chainIDs := wcommon.NetworksToChainIDs(activeNetworks)
|
||||
clients, err := api.s.rpcClient.EthClients(chainIDs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
func (api *API) GetCachedWalletTokensWithoutMarketData(ctx context.Context) (map[common.Address][]Token, error) {
|
||||
return api.reader.GetCachedWalletTokensWithoutMarketData()
|
||||
return api.reader.FetchOrGetCachedWalletBalances(ctx, clients, addresses)
|
||||
}
|
||||
|
||||
type DerivedAddress struct {
|
||||
|
@ -428,7 +448,7 @@ func (api *API) GetSuggestedRoutes(
|
|||
) (*router.SuggestedRoutes, error) {
|
||||
log.Debug("call to GetSuggestedRoutes")
|
||||
|
||||
testnetMode, err := api.s.accountsDB.GetTestNetworksEnabled()
|
||||
testnetMode, err := api.s.rpcClient.NetworkManager.GetTestNetworksEnabled()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -439,7 +459,7 @@ func (api *API) GetSuggestedRoutes(
|
|||
|
||||
func (api *API) GetSuggestedRoutesV2(ctx context.Context, input *router.RouteInputParams) (*router.SuggestedRoutesV2, error) {
|
||||
log.Debug("call to GetSuggestedRoutesV2")
|
||||
testnetMode, err := api.s.accountsDB.GetTestNetworksEnabled()
|
||||
testnetMode, err := api.s.rpcClient.NetworkManager.GetTestNetworksEnabled()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
package common
|
||||
|
||||
import "context"
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/status-im/status-go/params"
|
||||
)
|
||||
|
||||
// ShouldCancel returns true if the context has been cancelled and task should be aborted
|
||||
func ShouldCancel(ctx context.Context) bool {
|
||||
|
@ -11,3 +15,12 @@ func ShouldCancel(ctx context.Context) bool {
|
|||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func NetworksToChainIDs(networks []*params.Network) []uint64 {
|
||||
chainIDs := make([]uint64, 0)
|
||||
for _, network := range networks {
|
||||
chainIDs = append(chainIDs, network.ChainID)
|
||||
}
|
||||
|
||||
return chainIDs
|
||||
}
|
||||
|
|
|
@ -7,15 +7,14 @@ import (
|
|||
"sync"
|
||||
"time"
|
||||
|
||||
"golang.org/x/exp/maps"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
"github.com/ethereum/go-ethereum/event"
|
||||
"github.com/ethereum/go-ethereum/log"
|
||||
"github.com/status-im/status-go/multiaccounts/accounts"
|
||||
"github.com/status-im/status-go/params"
|
||||
"github.com/status-im/status-go/rpc"
|
||||
"github.com/status-im/status-go/rpc/chain"
|
||||
"github.com/status-im/status-go/services/wallet/async"
|
||||
"github.com/status-im/status-go/services/wallet/community"
|
||||
"github.com/status-im/status-go/services/wallet/market"
|
||||
"github.com/status-im/status-go/services/wallet/thirdparty"
|
||||
"github.com/status-im/status-go/services/wallet/token"
|
||||
|
@ -47,13 +46,10 @@ func belongsToMandatoryTokens(symbol string) bool {
|
|||
return false
|
||||
}
|
||||
|
||||
func NewReader(rpcClient *rpc.Client, tokenManager *token.Manager, marketManager *market.Manager, communityManager *community.Manager, accountsDB *accounts.Database, persistence *Persistence, walletFeed *event.Feed) *Reader {
|
||||
func NewReader(tokenManager token.ManagerInterface, marketManager *market.Manager, persistence token.TokenBalancesStorage, walletFeed *event.Feed) *Reader {
|
||||
return &Reader{
|
||||
rpcClient: rpcClient,
|
||||
tokenManager: tokenManager,
|
||||
marketManager: marketManager,
|
||||
communityManager: communityManager,
|
||||
accountsDB: accountsDB,
|
||||
persistence: persistence,
|
||||
walletFeed: walletFeed,
|
||||
refreshBalanceCache: true,
|
||||
|
@ -61,12 +57,9 @@ func NewReader(rpcClient *rpc.Client, tokenManager *token.Manager, marketManager
|
|||
}
|
||||
|
||||
type Reader struct {
|
||||
rpcClient *rpc.Client
|
||||
tokenManager *token.Manager
|
||||
tokenManager token.ManagerInterface
|
||||
marketManager *market.Manager
|
||||
communityManager *community.Manager
|
||||
accountsDB *accounts.Database
|
||||
persistence *Persistence
|
||||
persistence token.TokenBalancesStorage
|
||||
walletFeed *event.Feed
|
||||
cancel context.CancelFunc
|
||||
walletEventsWatcher *walletevent.Watcher
|
||||
|
@ -76,42 +69,6 @@ type Reader struct {
|
|||
rw sync.RWMutex
|
||||
}
|
||||
|
||||
type TokenMarketValues struct {
|
||||
MarketCap float64 `json:"marketCap"`
|
||||
HighDay float64 `json:"highDay"`
|
||||
LowDay float64 `json:"lowDay"`
|
||||
ChangePctHour float64 `json:"changePctHour"`
|
||||
ChangePctDay float64 `json:"changePctDay"`
|
||||
ChangePct24hour float64 `json:"changePct24hour"`
|
||||
Change24hour float64 `json:"change24hour"`
|
||||
Price float64 `json:"price"`
|
||||
HasError bool `json:"hasError"`
|
||||
}
|
||||
|
||||
type ChainBalance struct {
|
||||
RawBalance string `json:"rawBalance"`
|
||||
Balance *big.Float `json:"balance"`
|
||||
Balance1DayAgo string `json:"balance1DayAgo"`
|
||||
Address common.Address `json:"address"`
|
||||
ChainID uint64 `json:"chainId"`
|
||||
HasError bool `json:"hasError"`
|
||||
}
|
||||
|
||||
type Token struct {
|
||||
Name string `json:"name"`
|
||||
Symbol string `json:"symbol"`
|
||||
Decimals uint `json:"decimals"`
|
||||
BalancesPerChain map[uint64]ChainBalance `json:"balancesPerChain"`
|
||||
Description string `json:"description"`
|
||||
AssetWebsiteURL string `json:"assetWebsiteUrl"`
|
||||
BuiltOn string `json:"builtOn"`
|
||||
MarketValuesPerCurrency map[string]TokenMarketValues `json:"marketValuesPerCurrency"`
|
||||
PegSymbol string `json:"pegSymbol"`
|
||||
Verified bool `json:"verified"`
|
||||
Image string `json:"image,omitempty"`
|
||||
CommunityData *community.Data `json:"community_data,omitempty"`
|
||||
}
|
||||
|
||||
func splitVerifiedTokens(tokens []*token.Token) ([]*token.Token, []*token.Token) {
|
||||
verified := make([]*token.Token, 0)
|
||||
unverified := make([]*token.Token, 0)
|
||||
|
@ -248,12 +205,12 @@ func (r *Reader) stopWalletEventsWatcher() {
|
|||
}
|
||||
|
||||
func (r *Reader) tokensCachedForAddresses(addresses []common.Address) bool {
|
||||
for _, address := range addresses {
|
||||
cachedTokens, err := r.GetCachedWalletTokensWithoutMarketData()
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
cachedTokens, err := r.getCachedWalletTokensWithoutMarketData()
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
for _, address := range addresses {
|
||||
_, ok := cachedTokens[address]
|
||||
if !ok {
|
||||
return false
|
||||
|
@ -299,189 +256,152 @@ func (r *Reader) invalidateBalanceCache() {
|
|||
r.refreshBalanceCache = true
|
||||
}
|
||||
|
||||
func (r *Reader) FetchOrGetCachedWalletBalances(ctx context.Context, addresses []common.Address) (map[common.Address][]Token, error) {
|
||||
if !r.isBalanceCacheValid(addresses) {
|
||||
balances, err := r.GetWalletTokenBalances(ctx, addresses)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
r.balanceRefreshed()
|
||||
|
||||
return balances, nil
|
||||
func (r *Reader) FetchOrGetCachedWalletBalances(ctx context.Context, clients map[uint64]chain.ClientInterface, addresses []common.Address) (map[common.Address][]token.StorageToken, error) {
|
||||
needFetch := !r.isBalanceCacheValid(addresses) || r.isBalanceUpdateNeededAnyway(clients, addresses)
|
||||
if needFetch {
|
||||
return r.FetchBalances(ctx, clients, addresses)
|
||||
}
|
||||
|
||||
tokens, err := r.getWalletTokenBalances(ctx, addresses, false)
|
||||
return tokens, err
|
||||
return r.GetCachedBalances(clients, addresses)
|
||||
}
|
||||
|
||||
func (r *Reader) getWalletTokenBalances(ctx context.Context, addresses []common.Address, updateBalances bool) (map[common.Address][]Token, error) {
|
||||
areTestNetworksEnabled, err := r.accountsDB.GetTestNetworksEnabled()
|
||||
func (r *Reader) isBalanceUpdateNeededAnyway(clients map[uint64]chain.ClientInterface, addresses []common.Address) bool {
|
||||
cachedTokens, err := r.getCachedWalletTokensWithoutMarketData()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return true
|
||||
}
|
||||
|
||||
networks, err := r.rpcClient.NetworkManager.Get(false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
availableNetworks := make([]*params.Network, 0)
|
||||
for _, network := range networks {
|
||||
if network.IsTest != areTestNetworksEnabled {
|
||||
continue
|
||||
chainIDs := maps.Keys(clients)
|
||||
updateAnyway := false
|
||||
for _, address := range addresses {
|
||||
if res, ok := cachedTokens[address]; !ok || len(res) == 0 {
|
||||
updateAnyway = true
|
||||
break
|
||||
}
|
||||
|
||||
networkFound := map[uint64]bool{}
|
||||
for _, token := range cachedTokens[address] {
|
||||
for _, chain := range chainIDs {
|
||||
if _, ok := token.BalancesPerChain[chain]; ok {
|
||||
networkFound[chain] = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for _, chain := range chainIDs {
|
||||
if !networkFound[chain] {
|
||||
updateAnyway = true
|
||||
return updateAnyway
|
||||
}
|
||||
}
|
||||
availableNetworks = append(availableNetworks, network)
|
||||
}
|
||||
|
||||
cachedTokens, err := r.GetCachedWalletTokensWithoutMarketData()
|
||||
return updateAnyway
|
||||
}
|
||||
|
||||
func tokensToBalancesPerChain(cachedTokens map[common.Address][]token.StorageToken) map[uint64]map[common.Address]map[common.Address]*hexutil.Big {
|
||||
cachedBalancesPerChain := map[uint64]map[common.Address]map[common.Address]*hexutil.Big{}
|
||||
for address, tokens := range cachedTokens {
|
||||
for _, token := range tokens {
|
||||
for _, balance := range token.BalancesPerChain {
|
||||
if _, ok := cachedBalancesPerChain[balance.ChainID]; !ok {
|
||||
cachedBalancesPerChain[balance.ChainID] = map[common.Address]map[common.Address]*hexutil.Big{}
|
||||
}
|
||||
if _, ok := cachedBalancesPerChain[balance.ChainID][address]; !ok {
|
||||
cachedBalancesPerChain[balance.ChainID][address] = map[common.Address]*hexutil.Big{}
|
||||
}
|
||||
|
||||
bigBalance, _ := new(big.Int).SetString(balance.RawBalance, 10)
|
||||
cachedBalancesPerChain[balance.ChainID][address][balance.Address] = (*hexutil.Big)(bigBalance)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return cachedBalancesPerChain
|
||||
}
|
||||
|
||||
func (r *Reader) fetchBalances(ctx context.Context, clients map[uint64]chain.ClientInterface, addresses []common.Address, tokenAddresses []common.Address) (map[uint64]map[common.Address]map[common.Address]*hexutil.Big, error) {
|
||||
latestBalances, err := r.tokenManager.GetBalancesByChain(ctx, clients, addresses, tokenAddresses)
|
||||
if err != nil {
|
||||
log.Error("tokenManager.GetBalancesByChain error", "err", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
chainIDs := make([]uint64, 0)
|
||||
for _, network := range availableNetworks {
|
||||
chainIDs = append(chainIDs, network.ChainID)
|
||||
return latestBalances, nil
|
||||
}
|
||||
|
||||
func toChainBalance(
|
||||
balances map[uint64]map[common.Address]map[common.Address]*hexutil.Big,
|
||||
tok *token.Token,
|
||||
address common.Address,
|
||||
decimals uint,
|
||||
cachedTokens map[common.Address][]token.StorageToken,
|
||||
hasError bool,
|
||||
isMandatoryToken bool,
|
||||
) *token.ChainBalance {
|
||||
hexBalance := &big.Int{}
|
||||
if balances != nil {
|
||||
hexBalance = balances[tok.ChainID][address][tok.Address].ToInt()
|
||||
}
|
||||
|
||||
allTokens, err := r.tokenManager.GetTokensByChainIDs(chainIDs)
|
||||
balance := big.NewFloat(0.0)
|
||||
if hexBalance != nil {
|
||||
balance = new(big.Float).Quo(
|
||||
new(big.Float).SetInt(hexBalance),
|
||||
big.NewFloat(math.Pow(10, float64(decimals))),
|
||||
)
|
||||
}
|
||||
|
||||
isVisible := balance.Cmp(big.NewFloat(0.0)) > 0 || isCachedToken(cachedTokens, address, tok.Symbol, tok.ChainID)
|
||||
if !isVisible && !isMandatoryToken {
|
||||
return nil
|
||||
}
|
||||
|
||||
return &token.ChainBalance{
|
||||
RawBalance: hexBalance.String(),
|
||||
Balance: balance,
|
||||
Balance1DayAgo: "0",
|
||||
Address: tok.Address,
|
||||
ChainID: tok.ChainID,
|
||||
HasError: hasError,
|
||||
}
|
||||
}
|
||||
|
||||
func (r *Reader) getBalance1DayAgo(balance *token.ChainBalance, dayAgoTimestamp int64, symbol string, address common.Address) (*big.Int, error) {
|
||||
balance1DayAgo, err := r.tokenManager.GetTokenHistoricalBalance(address, balance.ChainID, symbol, dayAgoTimestamp)
|
||||
if err != nil {
|
||||
log.Error("tokenManager.GetTokenHistoricalBalance error", "err", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, network := range availableNetworks {
|
||||
allTokens = append(allTokens, r.tokenManager.ToToken(network))
|
||||
}
|
||||
|
||||
tokenAddresses := getTokenAddresses(allTokens)
|
||||
|
||||
clients, err := r.rpcClient.EthClients(chainIDs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return balance1DayAgo, nil
|
||||
}
|
||||
|
||||
func (r *Reader) balancesToTokensByAddress(connectedPerChain map[uint64]bool, addresses []common.Address, allTokens []*token.Token, balances map[uint64]map[common.Address]map[common.Address]*hexutil.Big, cachedTokens map[common.Address][]token.StorageToken) map[common.Address][]token.StorageToken {
|
||||
verifiedTokens, unverifiedTokens := splitVerifiedTokens(allTokens)
|
||||
|
||||
cachedBalancesPerChain := map[common.Address]map[common.Address]map[uint64]string{}
|
||||
updateAnyway := false
|
||||
if !updateBalances {
|
||||
cacheCheck:
|
||||
for _, address := range addresses {
|
||||
if res, ok := cachedTokens[address]; !ok || len(res) == 0 {
|
||||
updateAnyway = true
|
||||
break
|
||||
}
|
||||
|
||||
networkFound := map[uint64]bool{}
|
||||
for _, token := range cachedTokens[address] {
|
||||
for _, chain := range chainIDs {
|
||||
if _, ok := token.BalancesPerChain[chain]; ok {
|
||||
networkFound[chain] = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for _, chain := range chainIDs {
|
||||
if !networkFound[chain] {
|
||||
updateAnyway = true
|
||||
break cacheCheck
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if !updateBalances && !updateAnyway {
|
||||
for address, tokens := range cachedTokens {
|
||||
for _, token := range tokens {
|
||||
for _, balance := range token.BalancesPerChain {
|
||||
if _, ok := cachedBalancesPerChain[address]; !ok {
|
||||
cachedBalancesPerChain[address] = map[common.Address]map[uint64]string{}
|
||||
}
|
||||
if _, ok := cachedBalancesPerChain[address][balance.Address]; !ok {
|
||||
cachedBalancesPerChain[address][balance.Address] = map[uint64]string{}
|
||||
}
|
||||
cachedBalancesPerChain[address][balance.Address][balance.ChainID] = balance.RawBalance
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
var latestBalances map[uint64]map[common.Address]map[common.Address]*hexutil.Big
|
||||
if updateBalances || updateAnyway {
|
||||
latestBalances, err = r.tokenManager.GetBalancesByChain(ctx, clients, addresses, tokenAddresses)
|
||||
if err != nil {
|
||||
log.Info("tokenManager.GetBalancesByChain error", "err", err)
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
result := make(map[common.Address][]Token)
|
||||
result := make(map[common.Address][]token.StorageToken)
|
||||
dayAgoTimestamp := time.Now().Add(-24 * time.Hour).Unix()
|
||||
|
||||
for _, address := range addresses {
|
||||
for _, tokenList := range [][]*token.Token{verifiedTokens, unverifiedTokens} {
|
||||
for symbol, tokens := range getTokenBySymbols(tokenList) {
|
||||
balancesPerChain := make(map[uint64]ChainBalance)
|
||||
decimals := tokens[0].Decimals
|
||||
isVisible := false
|
||||
for _, token := range tokens {
|
||||
var balance *big.Float
|
||||
hexBalance := &big.Int{}
|
||||
if latestBalances != nil {
|
||||
hexBalance = latestBalances[token.ChainID][address][token.Address].ToInt()
|
||||
} else {
|
||||
if cachedRawBalance, ok := cachedBalancesPerChain[address][token.Address][token.ChainID]; ok {
|
||||
hexBalance, _ = new(big.Int).SetString(cachedRawBalance, 10)
|
||||
}
|
||||
}
|
||||
balance = big.NewFloat(0.0)
|
||||
if hexBalance != nil {
|
||||
balance = new(big.Float).Quo(
|
||||
new(big.Float).SetInt(hexBalance),
|
||||
big.NewFloat(math.Pow(10, float64(decimals))),
|
||||
)
|
||||
}
|
||||
|
||||
hasError := false
|
||||
if client, ok := clients[token.ChainID]; ok {
|
||||
hasError = err != nil || !client.IsConnected()
|
||||
}
|
||||
if !isVisible {
|
||||
isVisible = balance.Cmp(big.NewFloat(0.0)) > 0 || r.isCachedToken(cachedTokens, address, token.Symbol, token.ChainID)
|
||||
}
|
||||
balancesPerChain[token.ChainID] = ChainBalance{
|
||||
RawBalance: hexBalance.String(),
|
||||
Balance: balance,
|
||||
Balance1DayAgo: "0",
|
||||
Address: token.Address,
|
||||
ChainID: token.ChainID,
|
||||
HasError: hasError,
|
||||
}
|
||||
}
|
||||
|
||||
if !isVisible && !belongsToMandatoryTokens(symbol) {
|
||||
balancesPerChain := r.createBalancePerChainPerSymbol(address, balances, tokens, cachedTokens, connectedPerChain, dayAgoTimestamp)
|
||||
if balancesPerChain == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
for _, balance := range balancesPerChain {
|
||||
balance1DayAgo, err := r.tokenManager.GetTokenHistoricalBalance(address, balance.ChainID, symbol, dayAgoTimestamp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if balance1DayAgo != nil {
|
||||
balance.Balance1DayAgo = balance1DayAgo.String()
|
||||
balancesPerChain[balance.ChainID] = balance
|
||||
}
|
||||
}
|
||||
|
||||
walletToken := Token{
|
||||
Name: tokens[0].Name,
|
||||
Symbol: symbol,
|
||||
walletToken := token.StorageToken{
|
||||
Token: token.Token{
|
||||
Name: tokens[0].Name,
|
||||
Symbol: symbol,
|
||||
Decimals: tokens[0].Decimals,
|
||||
PegSymbol: token.GetTokenPegSymbol(symbol),
|
||||
Verified: tokens[0].Verified,
|
||||
CommunityData: tokens[0].CommunityData,
|
||||
Image: tokens[0].Image,
|
||||
},
|
||||
BalancesPerChain: balancesPerChain,
|
||||
Decimals: decimals,
|
||||
PegSymbol: token.GetTokenPegSymbol(symbol),
|
||||
Verified: tokens[0].Verified,
|
||||
CommunityData: tokens[0].CommunityData,
|
||||
Image: tokens[0].Image,
|
||||
}
|
||||
|
||||
result[address] = append(result[address], walletToken)
|
||||
|
@ -489,66 +409,63 @@ func (r *Reader) getWalletTokenBalances(ctx context.Context, addresses []common.
|
|||
}
|
||||
}
|
||||
|
||||
r.updateTokenUpdateTimestamp(addresses)
|
||||
|
||||
return result, r.persistence.SaveTokens(result)
|
||||
return result
|
||||
}
|
||||
|
||||
func (r *Reader) GetWalletTokenBalances(ctx context.Context, addresses []common.Address) (map[common.Address][]Token, error) {
|
||||
return r.getWalletTokenBalances(ctx, addresses, true)
|
||||
}
|
||||
|
||||
func (r *Reader) GetWalletToken(ctx context.Context, addresses []common.Address) (map[common.Address][]Token, error) {
|
||||
areTestNetworksEnabled, err := r.accountsDB.GetTestNetworksEnabled()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
networks, err := r.rpcClient.NetworkManager.Get(false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
availableNetworks := make([]*params.Network, 0)
|
||||
for _, network := range networks {
|
||||
if network.IsTest != areTestNetworksEnabled {
|
||||
continue
|
||||
// For tokens with single symbol, create a chain balance for each chain
|
||||
func (r *Reader) createBalancePerChainPerSymbol(
|
||||
address common.Address,
|
||||
balances map[uint64]map[common.Address]map[common.Address]*hexutil.Big,
|
||||
tokens []*token.Token,
|
||||
cachedTokens map[common.Address][]token.StorageToken,
|
||||
clientConnectionPerChain map[uint64]bool,
|
||||
dayAgoTimestamp int64,
|
||||
) map[uint64]token.ChainBalance {
|
||||
var balancesPerChain map[uint64]token.ChainBalance
|
||||
decimals := tokens[0].Decimals
|
||||
isMandatoryToken := belongsToMandatoryTokens(tokens[0].Symbol) // we expect all tokens in the list to have the same symbol
|
||||
for _, tok := range tokens {
|
||||
hasError := false
|
||||
if connected, ok := clientConnectionPerChain[tok.ChainID]; ok {
|
||||
hasError = !connected
|
||||
}
|
||||
|
||||
// TODO: Avoid passing the entire balances map to toChainBalance. Iterate over the balances map once and pass the balance per address per token to toChainBalance
|
||||
balance := toChainBalance(balances, tok, address, decimals, cachedTokens, hasError, isMandatoryToken)
|
||||
if balance != nil {
|
||||
balance1DayAgo, _ := r.getBalance1DayAgo(balance, dayAgoTimestamp, tok.Symbol, address) // Ignore error
|
||||
if balance1DayAgo != nil {
|
||||
balance.Balance1DayAgo = balance1DayAgo.String()
|
||||
}
|
||||
|
||||
if balancesPerChain == nil {
|
||||
balancesPerChain = make(map[uint64]token.ChainBalance)
|
||||
}
|
||||
balancesPerChain[tok.ChainID] = *balance
|
||||
}
|
||||
availableNetworks = append(availableNetworks, network)
|
||||
}
|
||||
|
||||
cachedTokens, err := r.GetCachedWalletTokensWithoutMarketData()
|
||||
return balancesPerChain
|
||||
}
|
||||
|
||||
func (r *Reader) GetWalletToken(ctx context.Context, clients map[uint64]chain.ClientInterface, addresses []common.Address, currency string) (map[common.Address][]token.StorageToken, error) {
|
||||
cachedTokens, err := r.getCachedWalletTokensWithoutMarketData()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
chainIDs := make([]uint64, 0)
|
||||
for _, network := range availableNetworks {
|
||||
chainIDs = append(chainIDs, network.ChainID)
|
||||
}
|
||||
chainIDs := maps.Keys(clients)
|
||||
|
||||
currencies := make([]string, 0)
|
||||
currency, err := r.accountsDB.GetCurrency()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
currencies = append(currencies, currency)
|
||||
currencies = append(currencies, getFixedCurrencies()...)
|
||||
allTokens, err := r.tokenManager.GetTokensByChainIDs(chainIDs)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, network := range availableNetworks {
|
||||
allTokens = append(allTokens, r.tokenManager.ToToken(network))
|
||||
}
|
||||
|
||||
tokenAddresses := getTokenAddresses(allTokens)
|
||||
|
||||
clients, err := r.rpcClient.EthClients(chainIDs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
balances, err := r.tokenManager.GetBalancesByChain(ctx, clients, addresses, tokenAddresses)
|
||||
if err != nil {
|
||||
log.Info("tokenManager.GetBalancesByChain error", "err", err)
|
||||
|
@ -557,16 +474,16 @@ func (r *Reader) GetWalletToken(ctx context.Context, addresses []common.Address)
|
|||
|
||||
verifiedTokens, unverifiedTokens := splitVerifiedTokens(allTokens)
|
||||
tokenSymbols := make([]string, 0)
|
||||
result := make(map[common.Address][]Token)
|
||||
result := make(map[common.Address][]token.StorageToken)
|
||||
|
||||
for _, address := range addresses {
|
||||
for _, tokenList := range [][]*token.Token{verifiedTokens, unverifiedTokens} {
|
||||
for symbol, tokens := range getTokenBySymbols(tokenList) {
|
||||
balancesPerChain := make(map[uint64]ChainBalance)
|
||||
balancesPerChain := make(map[uint64]token.ChainBalance)
|
||||
decimals := tokens[0].Decimals
|
||||
isVisible := false
|
||||
for _, token := range tokens {
|
||||
hexBalance := balances[token.ChainID][address][token.Address]
|
||||
for _, tok := range tokens {
|
||||
hexBalance := balances[tok.ChainID][address][tok.Address]
|
||||
balance := big.NewFloat(0.0)
|
||||
if hexBalance != nil {
|
||||
balance = new(big.Float).Quo(
|
||||
|
@ -575,17 +492,17 @@ func (r *Reader) GetWalletToken(ctx context.Context, addresses []common.Address)
|
|||
)
|
||||
}
|
||||
hasError := false
|
||||
if client, ok := clients[token.ChainID]; ok {
|
||||
if client, ok := clients[tok.ChainID]; ok {
|
||||
hasError = err != nil || !client.IsConnected()
|
||||
}
|
||||
if !isVisible {
|
||||
isVisible = balance.Cmp(big.NewFloat(0.0)) > 0 || r.isCachedToken(cachedTokens, address, token.Symbol, token.ChainID)
|
||||
isVisible = balance.Cmp(big.NewFloat(0.0)) > 0 || isCachedToken(cachedTokens, address, tok.Symbol, tok.ChainID)
|
||||
}
|
||||
balancesPerChain[token.ChainID] = ChainBalance{
|
||||
balancesPerChain[tok.ChainID] = token.ChainBalance{
|
||||
RawBalance: hexBalance.ToInt().String(),
|
||||
Balance: balance,
|
||||
Address: token.Address,
|
||||
ChainID: token.ChainID,
|
||||
Address: tok.Address,
|
||||
ChainID: tok.ChainID,
|
||||
HasError: hasError,
|
||||
}
|
||||
}
|
||||
|
@ -594,15 +511,17 @@ func (r *Reader) GetWalletToken(ctx context.Context, addresses []common.Address)
|
|||
continue
|
||||
}
|
||||
|
||||
walletToken := Token{
|
||||
Name: tokens[0].Name,
|
||||
Symbol: symbol,
|
||||
walletToken := token.StorageToken{
|
||||
Token: token.Token{
|
||||
Name: tokens[0].Name,
|
||||
Symbol: symbol,
|
||||
Decimals: decimals,
|
||||
PegSymbol: token.GetTokenPegSymbol(symbol),
|
||||
Verified: tokens[0].Verified,
|
||||
CommunityData: tokens[0].CommunityData,
|
||||
Image: tokens[0].Image,
|
||||
},
|
||||
BalancesPerChain: balancesPerChain,
|
||||
Decimals: decimals,
|
||||
PegSymbol: token.GetTokenPegSymbol(symbol),
|
||||
Verified: tokens[0].Verified,
|
||||
CommunityData: tokens[0].CommunityData,
|
||||
Image: tokens[0].Image,
|
||||
}
|
||||
|
||||
tokenSymbols = append(tokenSymbols, symbol)
|
||||
|
@ -653,32 +572,32 @@ func (r *Reader) GetWalletToken(ctx context.Context, addresses []common.Address)
|
|||
}
|
||||
|
||||
for address, tokens := range result {
|
||||
for index, token := range tokens {
|
||||
marketValuesPerCurrency := make(map[string]TokenMarketValues)
|
||||
for index, tok := range tokens {
|
||||
marketValuesPerCurrency := make(map[string]token.TokenMarketValues)
|
||||
for _, currency := range currencies {
|
||||
if _, ok := tokenMarketValues[token.Symbol]; !ok {
|
||||
if _, ok := tokenMarketValues[tok.Symbol]; !ok {
|
||||
continue
|
||||
}
|
||||
marketValuesPerCurrency[currency] = TokenMarketValues{
|
||||
MarketCap: tokenMarketValues[token.Symbol].MKTCAP,
|
||||
HighDay: tokenMarketValues[token.Symbol].HIGHDAY,
|
||||
LowDay: tokenMarketValues[token.Symbol].LOWDAY,
|
||||
ChangePctHour: tokenMarketValues[token.Symbol].CHANGEPCTHOUR,
|
||||
ChangePctDay: tokenMarketValues[token.Symbol].CHANGEPCTDAY,
|
||||
ChangePct24hour: tokenMarketValues[token.Symbol].CHANGEPCT24HOUR,
|
||||
Change24hour: tokenMarketValues[token.Symbol].CHANGE24HOUR,
|
||||
Price: prices[token.Symbol][currency],
|
||||
marketValuesPerCurrency[currency] = token.TokenMarketValues{
|
||||
MarketCap: tokenMarketValues[tok.Symbol].MKTCAP,
|
||||
HighDay: tokenMarketValues[tok.Symbol].HIGHDAY,
|
||||
LowDay: tokenMarketValues[tok.Symbol].LOWDAY,
|
||||
ChangePctHour: tokenMarketValues[tok.Symbol].CHANGEPCTHOUR,
|
||||
ChangePctDay: tokenMarketValues[tok.Symbol].CHANGEPCTDAY,
|
||||
ChangePct24hour: tokenMarketValues[tok.Symbol].CHANGEPCT24HOUR,
|
||||
Change24hour: tokenMarketValues[tok.Symbol].CHANGE24HOUR,
|
||||
Price: prices[tok.Symbol][currency],
|
||||
HasError: !r.marketManager.IsConnected,
|
||||
}
|
||||
}
|
||||
|
||||
if _, ok := tokenDetails[token.Symbol]; !ok {
|
||||
if _, ok := tokenDetails[tok.Symbol]; !ok {
|
||||
continue
|
||||
}
|
||||
|
||||
result[address][index].Description = tokenDetails[token.Symbol].Description
|
||||
result[address][index].AssetWebsiteURL = tokenDetails[token.Symbol].AssetWebsiteURL
|
||||
result[address][index].BuiltOn = tokenDetails[token.Symbol].BuiltOn
|
||||
result[address][index].Description = tokenDetails[tok.Symbol].Description
|
||||
result[address][index].AssetWebsiteURL = tokenDetails[tok.Symbol].AssetWebsiteURL
|
||||
result[address][index].BuiltOn = tokenDetails[tok.Symbol].BuiltOn
|
||||
result[address][index].MarketValuesPerCurrency = marketValuesPerCurrency
|
||||
}
|
||||
}
|
||||
|
@ -688,7 +607,7 @@ func (r *Reader) GetWalletToken(ctx context.Context, addresses []common.Address)
|
|||
return result, r.persistence.SaveTokens(result)
|
||||
}
|
||||
|
||||
func (r *Reader) isCachedToken(cachedTokens map[common.Address][]Token, address common.Address, symbol string, chainID uint64) bool {
|
||||
func isCachedToken(cachedTokens map[common.Address][]token.StorageToken, address common.Address, symbol string, chainID uint64) bool {
|
||||
if tokens, ok := cachedTokens[address]; ok {
|
||||
for _, t := range tokens {
|
||||
if t.Symbol != symbol {
|
||||
|
@ -703,9 +622,9 @@ func (r *Reader) isCachedToken(cachedTokens map[common.Address][]Token, address
|
|||
return false
|
||||
}
|
||||
|
||||
// GetCachedWalletTokensWithoutMarketData returns the latest fetched balances, minus
|
||||
// getCachedWalletTokensWithoutMarketData returns the latest fetched balances, minus
|
||||
// price information
|
||||
func (r *Reader) GetCachedWalletTokensWithoutMarketData() (map[common.Address][]Token, error) {
|
||||
func (r *Reader) getCachedWalletTokensWithoutMarketData() (map[common.Address][]token.StorageToken, error) {
|
||||
return r.persistence.GetTokens()
|
||||
}
|
||||
|
||||
|
@ -714,3 +633,61 @@ func (r *Reader) updateTokenUpdateTimestamp(addresses []common.Address) {
|
|||
r.lastWalletTokenUpdateTimestamp.Store(address, time.Now().Unix())
|
||||
}
|
||||
}
|
||||
|
||||
func (r *Reader) FetchBalances(ctx context.Context, clients map[uint64]chain.ClientInterface, addresses []common.Address) (map[common.Address][]token.StorageToken, error) {
|
||||
cachedTokens, err := r.getCachedWalletTokensWithoutMarketData()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
chainIDs := maps.Keys(clients)
|
||||
allTokens, err := r.tokenManager.GetTokensByChainIDs(chainIDs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
connectedPerChain := map[uint64]bool{}
|
||||
for chainID, client := range clients {
|
||||
connectedPerChain[chainID] = client.IsConnected()
|
||||
}
|
||||
|
||||
tokenAddresses := getTokenAddresses(allTokens)
|
||||
balances, err := r.fetchBalances(ctx, clients, addresses, tokenAddresses)
|
||||
if err != nil {
|
||||
log.Error("failed to update balances", "err", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
tokens := r.balancesToTokensByAddress(connectedPerChain, addresses, allTokens, balances, cachedTokens)
|
||||
|
||||
err = r.persistence.SaveTokens(tokens)
|
||||
if err != nil {
|
||||
log.Error("failed to save tokens", "err", err) // Do not return error, as it is not critical
|
||||
}
|
||||
|
||||
r.updateTokenUpdateTimestamp(addresses)
|
||||
r.balanceRefreshed()
|
||||
|
||||
return tokens, err
|
||||
}
|
||||
|
||||
func (r *Reader) GetCachedBalances(clients map[uint64]chain.ClientInterface, addresses []common.Address) (map[common.Address][]token.StorageToken, error) {
|
||||
cachedTokens, err := r.getCachedWalletTokensWithoutMarketData()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
chainIDs := maps.Keys(clients)
|
||||
allTokens, err := r.tokenManager.GetTokensByChainIDs(chainIDs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
connectedPerChain := map[uint64]bool{}
|
||||
for chainID, client := range clients {
|
||||
connectedPerChain[chainID] = client.IsConnected()
|
||||
}
|
||||
|
||||
balances := tokensToBalancesPerChain(cachedTokens)
|
||||
return r.balancesToTokensByAddress(connectedPerChain, addresses, allTokens, balances, cachedTokens), nil
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -103,7 +103,7 @@ func NewService(
|
|||
|
||||
communityManager := community.NewManager(db, mediaServer, feed)
|
||||
balanceCacher := balance.NewCacherWithTTL(5 * time.Minute)
|
||||
tokenManager := token.NewTokenManager(db, rpcClient, communityManager, rpcClient.NetworkManager, appDB, mediaServer, feed, accountFeed, accountsDB)
|
||||
tokenManager := token.NewTokenManager(db, rpcClient, communityManager, rpcClient.NetworkManager, appDB, mediaServer, feed, accountFeed, accountsDB, token.NewPersistence(db))
|
||||
tokenManager.Start()
|
||||
savedAddressesManager := &SavedAddressesManager{db: db}
|
||||
transactionManager := transfer.NewTransactionManager(transfer.NewMultiTransactionDB(db), gethManager, transactor, config, accountsDB, pendingTxManager, feed)
|
||||
|
@ -114,7 +114,7 @@ func NewService(
|
|||
cryptoCompare := cryptocompare.NewClient()
|
||||
coingecko := coingecko.NewClient()
|
||||
marketManager := market.NewManager(cryptoCompare, coingecko, feed)
|
||||
reader := NewReader(rpcClient, tokenManager, marketManager, communityManager, accountsDB, NewPersistence(db), feed)
|
||||
reader := NewReader(tokenManager, marketManager, token.NewPersistence(db), feed)
|
||||
history := history.NewService(db, accountsDB, accountFeed, feed, rpcClient, tokenManager, marketManager, balanceCacher.Cache())
|
||||
currency := currency.NewService(db, feed, tokenManager, marketManager)
|
||||
|
||||
|
|
|
@ -1,6 +1,13 @@
|
|||
package testutils
|
||||
|
||||
import "reflect"
|
||||
import (
|
||||
"reflect"
|
||||
"sort"
|
||||
|
||||
"github.com/golang/mock/gomock"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
)
|
||||
|
||||
const EthSymbol = "ETH"
|
||||
const SntSymbol = "SNT"
|
||||
|
@ -31,3 +38,85 @@ func Filter[T any](ss []T, test func(T) bool) (ret []T) {
|
|||
}
|
||||
return
|
||||
}
|
||||
|
||||
// AddressSliceMatcher is a custom matcher for comparing common.Address slices regardless of order.
|
||||
type AddressSliceMatcher struct {
|
||||
expected []common.Address
|
||||
}
|
||||
|
||||
func NewAddressSliceMatcher(expected []common.Address) gomock.Matcher {
|
||||
return &AddressSliceMatcher{expected: expected}
|
||||
}
|
||||
|
||||
func (m *AddressSliceMatcher) Matches(x interface{}) bool {
|
||||
actual, ok := x.([]common.Address)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
if len(m.expected) != len(actual) {
|
||||
return false
|
||||
}
|
||||
|
||||
// Create copies of the slices to sort them
|
||||
expectedCopy := make([]common.Address, len(m.expected))
|
||||
actualCopy := make([]common.Address, len(actual))
|
||||
copy(expectedCopy, m.expected)
|
||||
copy(actualCopy, actual)
|
||||
|
||||
sort.Slice(expectedCopy, func(i, j int) bool { return expectedCopy[i].Hex() < expectedCopy[j].Hex() })
|
||||
sort.Slice(actualCopy, func(i, j int) bool { return actualCopy[i].Hex() < actualCopy[j].Hex() })
|
||||
|
||||
for i := range expectedCopy {
|
||||
if expectedCopy[i] != actualCopy[i] {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func (m *AddressSliceMatcher) String() string {
|
||||
return "matches Address slice regardless of order"
|
||||
}
|
||||
|
||||
// Uint64SliceMatcher is a custom matcher for comparing uint64 slices regardless of order.
|
||||
type Uint64SliceMatcher struct {
|
||||
expected []uint64
|
||||
}
|
||||
|
||||
func NewUint64SliceMatcher(expected []uint64) gomock.Matcher {
|
||||
return &Uint64SliceMatcher{expected: expected}
|
||||
}
|
||||
|
||||
func (m *Uint64SliceMatcher) Matches(x interface{}) bool {
|
||||
actual, ok := x.([]uint64)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
if len(m.expected) != len(actual) {
|
||||
return false
|
||||
}
|
||||
|
||||
// Create copies of the slices to sort them
|
||||
expectedCopy := make([]uint64, len(m.expected))
|
||||
actualCopy := make([]uint64, len(actual))
|
||||
copy(expectedCopy, m.expected)
|
||||
copy(actualCopy, actual)
|
||||
|
||||
sort.Slice(expectedCopy, func(i, j int) bool { return expectedCopy[i] < expectedCopy[j] })
|
||||
sort.Slice(actualCopy, func(i, j int) bool { return actualCopy[i] < actualCopy[j] })
|
||||
|
||||
for i := range expectedCopy {
|
||||
if expectedCopy[i] != actualCopy[i] {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func (m *Uint64SliceMatcher) String() string {
|
||||
return "matches uint64 slice regardless of order"
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
package wallet
|
||||
package token
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
@ -8,6 +8,41 @@ import (
|
|||
"github.com/ethereum/go-ethereum/common"
|
||||
)
|
||||
|
||||
type TokenMarketValues struct {
|
||||
MarketCap float64 `json:"marketCap"`
|
||||
HighDay float64 `json:"highDay"`
|
||||
LowDay float64 `json:"lowDay"`
|
||||
ChangePctHour float64 `json:"changePctHour"`
|
||||
ChangePctDay float64 `json:"changePctDay"`
|
||||
ChangePct24hour float64 `json:"changePct24hour"`
|
||||
Change24hour float64 `json:"change24hour"`
|
||||
Price float64 `json:"price"`
|
||||
HasError bool `json:"hasError"`
|
||||
}
|
||||
|
||||
type StorageToken struct {
|
||||
Token
|
||||
BalancesPerChain map[uint64]ChainBalance `json:"balancesPerChain"`
|
||||
Description string `json:"description"`
|
||||
AssetWebsiteURL string `json:"assetWebsiteUrl"`
|
||||
BuiltOn string `json:"builtOn"`
|
||||
MarketValuesPerCurrency map[string]TokenMarketValues `json:"marketValuesPerCurrency"`
|
||||
}
|
||||
|
||||
type ChainBalance struct {
|
||||
RawBalance string `json:"rawBalance"`
|
||||
Balance *big.Float `json:"balance"`
|
||||
Balance1DayAgo string `json:"balance1DayAgo"`
|
||||
Address common.Address `json:"address"`
|
||||
ChainID uint64 `json:"chainId"`
|
||||
HasError bool `json:"hasError"`
|
||||
}
|
||||
|
||||
type TokenBalancesStorage interface {
|
||||
SaveTokens(tokens map[common.Address][]StorageToken) error
|
||||
GetTokens() (map[common.Address][]StorageToken, error)
|
||||
}
|
||||
|
||||
type Persistence struct {
|
||||
db *sql.DB
|
||||
}
|
||||
|
@ -16,7 +51,7 @@ func NewPersistence(db *sql.DB) *Persistence {
|
|||
return &Persistence{db: db}
|
||||
}
|
||||
|
||||
func (p *Persistence) SaveTokens(tokens map[common.Address][]Token) (err error) {
|
||||
func (p *Persistence) SaveTokens(tokens map[common.Address][]StorageToken) (err error) {
|
||||
tx, err := p.db.BeginTx(context.Background(), &sql.TxOptions{})
|
||||
if err != nil {
|
||||
return
|
||||
|
@ -48,7 +83,7 @@ func (p *Persistence) SaveTokens(tokens map[common.Address][]Token) (err error)
|
|||
return nil
|
||||
}
|
||||
|
||||
func (p *Persistence) GetTokens() (map[common.Address][]Token, error) {
|
||||
func (p *Persistence) GetTokens() (map[common.Address][]StorageToken, error) {
|
||||
rows, err := p.db.Query(`SELECT user_address, token_name, token_symbol, token_address, token_decimals, token_description, token_url, balance, raw_balance, chain_id FROM token_balances `)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -56,11 +91,11 @@ func (p *Persistence) GetTokens() (map[common.Address][]Token, error) {
|
|||
|
||||
defer rows.Close()
|
||||
|
||||
acc := make(map[common.Address]map[string]Token)
|
||||
acc := make(map[common.Address]map[string]StorageToken)
|
||||
|
||||
for rows.Next() {
|
||||
var addressStr, balance, rawBalance, tokenAddress string
|
||||
token := Token{}
|
||||
token := StorageToken{}
|
||||
var chainID uint64
|
||||
|
||||
err := rows.Scan(&addressStr, &token.Name, &token.Symbol, &tokenAddress, &token.Decimals, &token.Description, &token.AssetWebsiteURL, &balance, &rawBalance, &chainID)
|
||||
|
@ -68,10 +103,12 @@ func (p *Persistence) GetTokens() (map[common.Address][]Token, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
token.Address = common.HexToAddress(tokenAddress)
|
||||
token.ChainID = chainID
|
||||
address := common.HexToAddress(addressStr)
|
||||
|
||||
if acc[address] == nil {
|
||||
acc[address] = make(map[string]Token)
|
||||
acc[address] = make(map[string]StorageToken)
|
||||
}
|
||||
|
||||
if acc[address][token.Name].Name == "" {
|
||||
|
@ -95,7 +132,7 @@ func (p *Persistence) GetTokens() (map[common.Address][]Token, error) {
|
|||
}
|
||||
}
|
||||
|
||||
result := make(map[common.Address][]Token)
|
||||
result := make(map[common.Address][]StorageToken)
|
||||
|
||||
for address, tks := range acc {
|
||||
for _, t := range tks {
|
|
@ -1,4 +1,4 @@
|
|||
package wallet
|
||||
package token
|
||||
|
||||
import (
|
||||
"math/big"
|
||||
|
@ -21,7 +21,7 @@ func TestSaveTokens(t *testing.T) {
|
|||
persistence := NewPersistence(db)
|
||||
require.NotNil(t, persistence)
|
||||
|
||||
tokens := make(map[common.Address][]Token)
|
||||
tokens := make(map[common.Address][]StorageToken)
|
||||
address1 := common.HexToAddress("0xdAC17F958D2ee523a2206206994597C13D831ec7")
|
||||
address2 := common.HexToAddress("0x5e4e65926ba27467555eb562121fac00d24e9dd2")
|
||||
|
||||
|
@ -31,10 +31,12 @@ func TestSaveTokens(t *testing.T) {
|
|||
var chain1 uint64 = 1
|
||||
var chain2 uint64 = 2
|
||||
|
||||
token1 := Token{
|
||||
Name: "token-1",
|
||||
Symbol: "TT1",
|
||||
Decimals: 10,
|
||||
token1 := StorageToken{
|
||||
Token: Token{
|
||||
Name: "token-1",
|
||||
Symbol: "TT1",
|
||||
Decimals: 10,
|
||||
},
|
||||
BalancesPerChain: make(map[uint64]ChainBalance),
|
||||
Description: "description-1",
|
||||
AssetWebsiteURL: "url-1",
|
||||
|
@ -54,10 +56,12 @@ func TestSaveTokens(t *testing.T) {
|
|||
ChainID: chain2,
|
||||
}
|
||||
|
||||
token2 := Token{
|
||||
Name: "token-2",
|
||||
Symbol: "TT2",
|
||||
Decimals: 11,
|
||||
token2 := StorageToken{
|
||||
Token: Token{
|
||||
Name: "token-2",
|
||||
Symbol: "TT2",
|
||||
Decimals: 11,
|
||||
},
|
||||
BalancesPerChain: make(map[uint64]ChainBalance),
|
||||
Description: "description-2",
|
||||
AssetWebsiteURL: "url-2",
|
||||
|
@ -70,10 +74,12 @@ func TestSaveTokens(t *testing.T) {
|
|||
ChainID: chain1,
|
||||
}
|
||||
|
||||
token3 := Token{
|
||||
Name: "token-3",
|
||||
Symbol: "TT3",
|
||||
Decimals: 11,
|
||||
token3 := StorageToken{
|
||||
Token: Token{
|
||||
Name: "token-3",
|
||||
Symbol: "TT3",
|
||||
Decimals: 11,
|
||||
},
|
||||
BalancesPerChain: make(map[uint64]ChainBalance),
|
||||
Description: "description-3",
|
||||
AssetWebsiteURL: "url-3",
|
||||
|
@ -86,9 +92,9 @@ func TestSaveTokens(t *testing.T) {
|
|||
ChainID: chain1,
|
||||
}
|
||||
|
||||
tokens[address1] = []Token{token1, token2}
|
||||
tokens[address1] = []StorageToken{token1, token2}
|
||||
|
||||
tokens[address2] = []Token{token3}
|
||||
tokens[address2] = []StorageToken{token3}
|
||||
|
||||
require.NoError(t, persistence.SaveTokens(tokens))
|
||||
|
||||
|
@ -98,7 +104,7 @@ func TestSaveTokens(t *testing.T) {
|
|||
require.NotNil(t, actualTokens[address1])
|
||||
require.Len(t, actualTokens[address1], 2)
|
||||
|
||||
var actualToken1, actualToken2, actualToken3 Token
|
||||
var actualToken1, actualToken2, actualToken3 StorageToken
|
||||
if actualTokens[address1][0].Name == "token-1" {
|
||||
actualToken1 = actualTokens[address1][0]
|
||||
actualToken2 = actualTokens[address1][1]
|
|
@ -0,0 +1,66 @@
|
|||
// Code generated by MockGen. DO NOT EDIT.
|
||||
// Source: services/wallet/token/balance_persistence.go
|
||||
|
||||
// Package mock_balance_persistence is a generated GoMock package.
|
||||
package mock_balance_persistence
|
||||
|
||||
import (
|
||||
reflect "reflect"
|
||||
|
||||
gomock "github.com/golang/mock/gomock"
|
||||
|
||||
common "github.com/ethereum/go-ethereum/common"
|
||||
token "github.com/status-im/status-go/services/wallet/token"
|
||||
)
|
||||
|
||||
// MockTokenBalancesStorage is a mock of TokenBalancesStorage interface
|
||||
type MockTokenBalancesStorage struct {
|
||||
ctrl *gomock.Controller
|
||||
recorder *MockTokenBalancesStorageMockRecorder
|
||||
}
|
||||
|
||||
// MockTokenBalancesStorageMockRecorder is the mock recorder for MockTokenBalancesStorage
|
||||
type MockTokenBalancesStorageMockRecorder struct {
|
||||
mock *MockTokenBalancesStorage
|
||||
}
|
||||
|
||||
// NewMockTokenBalancesStorage creates a new mock instance
|
||||
func NewMockTokenBalancesStorage(ctrl *gomock.Controller) *MockTokenBalancesStorage {
|
||||
mock := &MockTokenBalancesStorage{ctrl: ctrl}
|
||||
mock.recorder = &MockTokenBalancesStorageMockRecorder{mock}
|
||||
return mock
|
||||
}
|
||||
|
||||
// EXPECT returns an object that allows the caller to indicate expected use
|
||||
func (m *MockTokenBalancesStorage) EXPECT() *MockTokenBalancesStorageMockRecorder {
|
||||
return m.recorder
|
||||
}
|
||||
|
||||
// SaveTokens mocks base method
|
||||
func (m *MockTokenBalancesStorage) SaveTokens(tokens map[common.Address][]token.StorageToken) error {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "SaveTokens", tokens)
|
||||
ret0, _ := ret[0].(error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// SaveTokens indicates an expected call of SaveTokens
|
||||
func (mr *MockTokenBalancesStorageMockRecorder) SaveTokens(tokens interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SaveTokens", reflect.TypeOf((*MockTokenBalancesStorage)(nil).SaveTokens), tokens)
|
||||
}
|
||||
|
||||
// GetTokens mocks base method
|
||||
func (m *MockTokenBalancesStorage) GetTokens() (map[common.Address][]token.StorageToken, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "GetTokens")
|
||||
ret0, _ := ret[0].(map[common.Address][]token.StorageToken)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// GetTokens indicates an expected call of GetTokens
|
||||
func (mr *MockTokenBalancesStorageMockRecorder) GetTokens() *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetTokens", reflect.TypeOf((*MockTokenBalancesStorage)(nil).GetTokens))
|
||||
}
|
|
@ -0,0 +1,115 @@
|
|||
// Code generated by MockGen. DO NOT EDIT.
|
||||
// Source: services/wallet/token/token.go
|
||||
|
||||
// Package mock_token is a generated GoMock package.
|
||||
package mock_token
|
||||
|
||||
import (
|
||||
context "context"
|
||||
big "math/big"
|
||||
reflect "reflect"
|
||||
|
||||
gomock "github.com/golang/mock/gomock"
|
||||
|
||||
common "github.com/ethereum/go-ethereum/common"
|
||||
hexutil "github.com/ethereum/go-ethereum/common/hexutil"
|
||||
chain "github.com/status-im/status-go/rpc/chain"
|
||||
token "github.com/status-im/status-go/services/wallet/token"
|
||||
)
|
||||
|
||||
// MockManagerInterface is a mock of ManagerInterface interface
|
||||
type MockManagerInterface struct {
|
||||
ctrl *gomock.Controller
|
||||
recorder *MockManagerInterfaceMockRecorder
|
||||
}
|
||||
|
||||
// MockManagerInterfaceMockRecorder is the mock recorder for MockManagerInterface
|
||||
type MockManagerInterfaceMockRecorder struct {
|
||||
mock *MockManagerInterface
|
||||
}
|
||||
|
||||
// NewMockManagerInterface creates a new mock instance
|
||||
func NewMockManagerInterface(ctrl *gomock.Controller) *MockManagerInterface {
|
||||
mock := &MockManagerInterface{ctrl: ctrl}
|
||||
mock.recorder = &MockManagerInterfaceMockRecorder{mock}
|
||||
return mock
|
||||
}
|
||||
|
||||
// EXPECT returns an object that allows the caller to indicate expected use
|
||||
func (m *MockManagerInterface) EXPECT() *MockManagerInterfaceMockRecorder {
|
||||
return m.recorder
|
||||
}
|
||||
|
||||
// LookupTokenIdentity mocks base method
|
||||
func (m *MockManagerInterface) LookupTokenIdentity(chainID uint64, address common.Address, native bool) *token.Token {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "LookupTokenIdentity", chainID, address, native)
|
||||
ret0, _ := ret[0].(*token.Token)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// LookupTokenIdentity indicates an expected call of LookupTokenIdentity
|
||||
func (mr *MockManagerInterfaceMockRecorder) LookupTokenIdentity(chainID, address, native interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LookupTokenIdentity", reflect.TypeOf((*MockManagerInterface)(nil).LookupTokenIdentity), chainID, address, native)
|
||||
}
|
||||
|
||||
// LookupToken mocks base method
|
||||
func (m *MockManagerInterface) LookupToken(chainID *uint64, tokenSymbol string) (*token.Token, bool) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "LookupToken", chainID, tokenSymbol)
|
||||
ret0, _ := ret[0].(*token.Token)
|
||||
ret1, _ := ret[1].(bool)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// LookupToken indicates an expected call of LookupToken
|
||||
func (mr *MockManagerInterfaceMockRecorder) LookupToken(chainID, tokenSymbol interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LookupToken", reflect.TypeOf((*MockManagerInterface)(nil).LookupToken), chainID, tokenSymbol)
|
||||
}
|
||||
|
||||
// GetTokensByChainIDs mocks base method
|
||||
func (m *MockManagerInterface) GetTokensByChainIDs(chainIDs []uint64) ([]*token.Token, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "GetTokensByChainIDs", chainIDs)
|
||||
ret0, _ := ret[0].([]*token.Token)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// GetTokensByChainIDs indicates an expected call of GetTokensByChainIDs
|
||||
func (mr *MockManagerInterfaceMockRecorder) GetTokensByChainIDs(chainIDs interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetTokensByChainIDs", reflect.TypeOf((*MockManagerInterface)(nil).GetTokensByChainIDs), chainIDs)
|
||||
}
|
||||
|
||||
// GetBalancesByChain mocks base method
|
||||
func (m *MockManagerInterface) GetBalancesByChain(parent context.Context, clients map[uint64]chain.ClientInterface, accounts, tokens []common.Address) (map[uint64]map[common.Address]map[common.Address]*hexutil.Big, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "GetBalancesByChain", parent, clients, accounts, tokens)
|
||||
ret0, _ := ret[0].(map[uint64]map[common.Address]map[common.Address]*hexutil.Big)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// GetBalancesByChain indicates an expected call of GetBalancesByChain
|
||||
func (mr *MockManagerInterfaceMockRecorder) GetBalancesByChain(parent, clients, accounts, tokens interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBalancesByChain", reflect.TypeOf((*MockManagerInterface)(nil).GetBalancesByChain), parent, clients, accounts, tokens)
|
||||
}
|
||||
|
||||
// GetTokenHistoricalBalance mocks base method
|
||||
func (m *MockManagerInterface) GetTokenHistoricalBalance(account common.Address, chainID uint64, symbol string, timestamp int64) (*big.Int, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "GetTokenHistoricalBalance", account, chainID, symbol, timestamp)
|
||||
ret0, _ := ret[0].(*big.Int)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// GetTokenHistoricalBalance indicates an expected call of GetTokenHistoricalBalance
|
||||
func (mr *MockManagerInterfaceMockRecorder) GetTokenHistoricalBalance(account, chainID, symbol, timestamp interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetTokenHistoricalBalance", reflect.TypeOf((*MockManagerInterface)(nil).GetTokenHistoricalBalance), account, chainID, symbol, timestamp)
|
||||
}
|
|
@ -94,22 +94,26 @@ type storeMap = map[uint64]addressTokenMap
|
|||
type ManagerInterface interface {
|
||||
LookupTokenIdentity(chainID uint64, address common.Address, native bool) *Token
|
||||
LookupToken(chainID *uint64, tokenSymbol string) (token *Token, isNative bool)
|
||||
GetTokensByChainIDs(chainIDs []uint64) ([]*Token, error)
|
||||
GetBalancesByChain(parent context.Context, clients map[uint64]chain.ClientInterface, accounts, tokens []common.Address) (map[uint64]map[common.Address]map[common.Address]*hexutil.Big, error)
|
||||
GetTokenHistoricalBalance(account common.Address, chainID uint64, symbol string, timestamp int64) (*big.Int, error)
|
||||
}
|
||||
|
||||
// Manager is used for accessing token store. It changes the token store based on overridden tokens
|
||||
type Manager struct {
|
||||
db *sql.DB
|
||||
RPCClient *rpc.Client
|
||||
ContractMaker *contracts.ContractMaker
|
||||
networkManager *network.Manager
|
||||
stores []store // Set on init, not changed afterwards
|
||||
communityTokensDB *communitytokensdatabase.Database
|
||||
communityManager *community.Manager
|
||||
mediaServer *server.MediaServer
|
||||
walletFeed *event.Feed
|
||||
accountFeed *event.Feed
|
||||
accountWatcher *accountsevent.Watcher
|
||||
accountsDB *accounts.Database
|
||||
db *sql.DB
|
||||
RPCClient *rpc.Client
|
||||
ContractMaker *contracts.ContractMaker
|
||||
networkManager *network.Manager
|
||||
stores []store // Set on init, not changed afterwards
|
||||
communityTokensDB *communitytokensdatabase.Database
|
||||
communityManager *community.Manager
|
||||
mediaServer *server.MediaServer
|
||||
walletFeed *event.Feed
|
||||
accountFeed *event.Feed
|
||||
accountWatcher *accountsevent.Watcher
|
||||
accountsDB *accounts.Database
|
||||
tokenBalancesStorage TokenBalancesStorage
|
||||
|
||||
tokens []*Token
|
||||
|
||||
|
@ -167,24 +171,26 @@ func NewTokenManager(
|
|||
walletFeed *event.Feed,
|
||||
accountFeed *event.Feed,
|
||||
accountsDB *accounts.Database,
|
||||
tokenBalancesStorage TokenBalancesStorage,
|
||||
) *Manager {
|
||||
maker, _ := contracts.NewContractMaker(RPCClient)
|
||||
stores := []store{newUniswapStore(), newDefaultStore()}
|
||||
tokens := prepareTokens(networkManager, stores)
|
||||
|
||||
return &Manager{
|
||||
db: db,
|
||||
RPCClient: RPCClient,
|
||||
ContractMaker: maker,
|
||||
networkManager: networkManager,
|
||||
communityManager: communityManager,
|
||||
stores: stores,
|
||||
communityTokensDB: communitytokensdatabase.NewCommunityTokensDatabase(appDB),
|
||||
tokens: tokens,
|
||||
mediaServer: mediaServer,
|
||||
walletFeed: walletFeed,
|
||||
accountFeed: accountFeed,
|
||||
accountsDB: accountsDB,
|
||||
db: db,
|
||||
RPCClient: RPCClient,
|
||||
ContractMaker: maker,
|
||||
networkManager: networkManager,
|
||||
communityManager: communityManager,
|
||||
stores: stores,
|
||||
communityTokensDB: communitytokensdatabase.NewCommunityTokensDatabase(appDB),
|
||||
tokens: tokens,
|
||||
mediaServer: mediaServer,
|
||||
walletFeed: walletFeed,
|
||||
accountFeed: accountFeed,
|
||||
accountsDB: accountsDB,
|
||||
tokenBalancesStorage: tokenBalancesStorage,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -360,13 +366,43 @@ func (tm *Manager) MarkAsPreviouslyOwnedToken(token *Token, owner common.Address
|
|||
if (owner == common.Address{}) {
|
||||
return false, errors.New("owner is nil")
|
||||
}
|
||||
count := 0
|
||||
err := tm.db.QueryRow(`SELECT EXISTS(SELECT 1 FROM token_balances WHERE user_address = ? AND token_address = ? AND chain_id = ?)`, owner.Hex(), token.Address.Hex(), token.ChainID).Scan(&count)
|
||||
if err != nil || count > 0 {
|
||||
|
||||
tokens, err := tm.tokenBalancesStorage.GetTokens()
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
_, err = tm.db.Exec(`INSERT INTO token_balances(user_address,token_name,token_symbol,token_address,token_decimals,chain_id,token_decimals,raw_balance,balance) VALUES (?,?,?,?,?,?,?,?,?)`, owner.Hex(), token.Name, token.Symbol, token.Address.Hex(), token.Decimals, token.ChainID, 0, "0", "0")
|
||||
return true, err
|
||||
|
||||
if tokens[owner] == nil {
|
||||
tokens[owner] = make([]StorageToken, 0)
|
||||
} else {
|
||||
for _, t := range tokens[owner] {
|
||||
if t.Address == token.Address && t.ChainID == token.ChainID && t.Symbol == token.Symbol {
|
||||
log.Info("Token already marked as previously owned", "token", token, "owner", owner)
|
||||
return false, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// append token to the list of tokens
|
||||
tokens[owner] = append(tokens[owner], StorageToken{
|
||||
Token: *token,
|
||||
BalancesPerChain: map[uint64]ChainBalance{
|
||||
token.ChainID: {
|
||||
RawBalance: "0",
|
||||
Balance: &big.Float{},
|
||||
Address: token.Address,
|
||||
ChainID: token.ChainID,
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
// save the updated list of tokens
|
||||
err = tm.tokenBalancesStorage.SaveTokens(tokens)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func (tm *Manager) discoverTokenCommunityID(ctx context.Context, token *Token, address common.Address) {
|
||||
|
@ -917,37 +953,20 @@ func (tm *Manager) GetTokenHistoricalBalance(account common.Address, chainID uin
|
|||
return &balance, nil
|
||||
}
|
||||
|
||||
func (tm *Manager) GetPreviouslyOwnedTokens() (map[common.Address][]*Token, error) {
|
||||
tokenMap := make(map[common.Address][]*Token)
|
||||
rows, err := tm.db.Query("SELECT user_address, token_name, token_symbol, token_address, token_decimals, chain_id FROM token_balances")
|
||||
func (tm *Manager) GetPreviouslyOwnedTokens() (map[common.Address][]Token, error) {
|
||||
storageTokens, err := tm.tokenBalancesStorage.GetTokens()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
for rows.Next() {
|
||||
token := &Token{}
|
||||
var addressStr, tokenAddressStr string
|
||||
err := rows.Scan(&addressStr, &token.Name, &token.Symbol, &tokenAddressStr, &token.Decimals, &token.ChainID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
tokens := make(map[common.Address][]Token)
|
||||
for account, storageToken := range storageTokens {
|
||||
for _, token := range storageToken {
|
||||
tokens[account] = append(tokens[account], token.Token)
|
||||
}
|
||||
address := common.HexToAddress(addressStr)
|
||||
if (address == common.Address{}) {
|
||||
continue
|
||||
}
|
||||
token.Address = common.HexToAddress(tokenAddressStr)
|
||||
if (token.Address == common.Address{}) {
|
||||
continue
|
||||
}
|
||||
|
||||
if _, ok := tokenMap[address]; !ok {
|
||||
tokenMap[address] = make([]*Token, 0)
|
||||
}
|
||||
tokenMap[address] = append(tokenMap[address], token)
|
||||
}
|
||||
|
||||
return tokenMap, nil
|
||||
return tokens, nil
|
||||
}
|
||||
|
||||
func (tm *Manager) removeTokenBalances(account common.Address) error {
|
||||
|
|
|
@ -35,13 +35,14 @@ func setupTestTokenDB(t *testing.T) (*Manager, func()) {
|
|||
require.NoError(t, err)
|
||||
|
||||
return &Manager{
|
||||
db: db,
|
||||
RPCClient: nil,
|
||||
ContractMaker: nil,
|
||||
networkManager: nil,
|
||||
stores: nil,
|
||||
communityTokensDB: nil,
|
||||
communityManager: nil,
|
||||
db: db,
|
||||
RPCClient: nil,
|
||||
ContractMaker: nil,
|
||||
networkManager: nil,
|
||||
stores: nil,
|
||||
communityTokensDB: nil,
|
||||
communityManager: nil,
|
||||
tokenBalancesStorage: NewPersistence(db),
|
||||
}, func() {
|
||||
require.NoError(t, db.Close())
|
||||
}
|
||||
|
@ -335,7 +336,7 @@ func Test_removeTokenBalanceOnEventAccountRemoved(t *testing.T) {
|
|||
mediaServer, err := mediaserver.NewMediaServer(appDB, nil, nil, walletDB)
|
||||
require.NoError(t, err)
|
||||
|
||||
manager := NewTokenManager(walletDB, rpcClient, nil, nm, appDB, mediaServer, nil, &accountFeed, accountsDB)
|
||||
manager := NewTokenManager(walletDB, rpcClient, nil, nm, appDB, mediaServer, nil, &accountFeed, accountsDB, NewPersistence(walletDB))
|
||||
|
||||
// Insert balances for address
|
||||
marked, err := manager.MarkAsPreviouslyOwnedToken(&Token{
|
||||
|
@ -397,7 +398,7 @@ func Test_tokensListsValidity(t *testing.T) {
|
|||
|
||||
nm := network.NewManager(appDB)
|
||||
|
||||
manager := NewTokenManager(walletDB, nil, nil, nm, appDB, nil, nil, nil, accountsDB)
|
||||
manager := NewTokenManager(walletDB, nil, nil, nm, appDB, nil, nil, nil, accountsDB, NewPersistence(walletDB))
|
||||
require.NotNil(t, manager)
|
||||
|
||||
tokensListWrapper := manager.GetList()
|
||||
|
|
|
@ -1075,7 +1075,7 @@ func setupFindBlocksCommand(t *testing.T, accountAddress common.Address, fromBlo
|
|||
}
|
||||
client, _ := statusRpc.NewClient(nil, 1, params.UpstreamRPCConfig{Enabled: false, URL: ""}, []params.Network{}, db)
|
||||
client.SetClient(tc.NetworkID(), tc)
|
||||
tokenManager := token.NewTokenManager(db, client, community.NewManager(appdb, nil, nil), network.NewManager(appdb), appdb, mediaServer, nil, nil, nil)
|
||||
tokenManager := token.NewTokenManager(db, client, community.NewManager(appdb, nil, nil), network.NewManager(appdb), appdb, mediaServer, nil, nil, nil, token.NewPersistence(db))
|
||||
tokenManager.SetTokens([]*token.Token{
|
||||
{
|
||||
Address: tokenTXXAddress,
|
||||
|
@ -1337,7 +1337,7 @@ func TestFetchTransfersForLoadedBlocks(t *testing.T) {
|
|||
|
||||
client, _ := statusRpc.NewClient(nil, 1, params.UpstreamRPCConfig{Enabled: false, URL: ""}, []params.Network{}, db)
|
||||
client.SetClient(tc.NetworkID(), tc)
|
||||
tokenManager := token.NewTokenManager(db, client, community.NewManager(appdb, nil, nil), network.NewManager(appdb), appdb, mediaServer, nil, nil, nil)
|
||||
tokenManager := token.NewTokenManager(db, client, community.NewManager(appdb, nil, nil), network.NewManager(appdb), appdb, mediaServer, nil, nil, nil, token.NewPersistence(db))
|
||||
|
||||
tokenManager.SetTokens([]*token.Token{
|
||||
{
|
||||
|
@ -1457,7 +1457,7 @@ func TestFetchNewBlocksCommand_findBlocksWithEthTransfers(t *testing.T) {
|
|||
|
||||
client, _ := statusRpc.NewClient(nil, 1, params.UpstreamRPCConfig{Enabled: false, URL: ""}, []params.Network{}, db)
|
||||
client.SetClient(tc.NetworkID(), tc)
|
||||
tokenManager := token.NewTokenManager(db, client, community.NewManager(appdb, nil, nil), network.NewManager(appdb), appdb, mediaServer, nil, nil, nil)
|
||||
tokenManager := token.NewTokenManager(db, client, community.NewManager(appdb, nil, nil), network.NewManager(appdb), appdb, mediaServer, nil, nil, nil, token.NewPersistence(db))
|
||||
|
||||
tokenManager.SetTokens([]*token.Token{
|
||||
{
|
||||
|
@ -1537,7 +1537,7 @@ func TestFetchNewBlocksCommand_nonceDetection(t *testing.T) {
|
|||
|
||||
client, _ := statusRpc.NewClient(nil, 1, params.UpstreamRPCConfig{Enabled: false, URL: ""}, []params.Network{}, db)
|
||||
client.SetClient(tc.NetworkID(), tc)
|
||||
tokenManager := token.NewTokenManager(db, client, community.NewManager(appdb, nil, nil), network.NewManager(appdb), appdb, mediaServer, nil, nil, nil)
|
||||
tokenManager := token.NewTokenManager(db, client, community.NewManager(appdb, nil, nil), network.NewManager(appdb), appdb, mediaServer, nil, nil, nil, token.NewPersistence(db))
|
||||
|
||||
wdb := NewDB(db)
|
||||
blockChannel := make(chan []*DBHeader, 10)
|
||||
|
@ -1652,7 +1652,7 @@ func TestFetchNewBlocksCommand(t *testing.T) {
|
|||
client, _ := statusRpc.NewClient(nil, 1, params.UpstreamRPCConfig{Enabled: false, URL: ""}, []params.Network{}, db)
|
||||
client.SetClient(tc.NetworkID(), tc)
|
||||
|
||||
tokenManager := token.NewTokenManager(db, client, community.NewManager(appdb, nil, nil), network.NewManager(appdb), appdb, mediaServer, nil, nil, nil)
|
||||
tokenManager := token.NewTokenManager(db, client, community.NewManager(appdb, nil, nil), network.NewManager(appdb), appdb, mediaServer, nil, nil, nil, token.NewPersistence(db))
|
||||
|
||||
tokenManager.SetTokens([]*token.Token{
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue