2019-06-14 13:16:30 +03:00
|
|
|
package wallet
|
|
|
|
|
|
|
|
import (
|
2021-09-09 16:28:54 +02:00
|
|
|
"database/sql"
|
2023-03-23 13:13:16 +01:00
|
|
|
"encoding/json"
|
2023-06-28 15:39:13 +02:00
|
|
|
"sync"
|
2023-02-20 10:32:45 +01:00
|
|
|
"time"
|
2019-06-14 13:16:30 +03:00
|
|
|
|
2023-03-20 14:02:09 +01:00
|
|
|
"github.com/ethereum/go-ethereum/common"
|
2019-06-14 13:16:30 +03:00
|
|
|
"github.com/ethereum/go-ethereum/event"
|
|
|
|
"github.com/ethereum/go-ethereum/log"
|
|
|
|
"github.com/ethereum/go-ethereum/p2p"
|
2021-09-22 19:49:20 +02:00
|
|
|
gethrpc "github.com/ethereum/go-ethereum/rpc"
|
|
|
|
|
2022-05-18 13:31:45 +02:00
|
|
|
"github.com/status-im/status-go/account"
|
2022-05-10 09:48:05 +02:00
|
|
|
"github.com/status-im/status-go/multiaccounts/accounts"
|
2022-07-15 10:53:56 +02:00
|
|
|
"github.com/status-im/status-go/params"
|
2021-09-22 19:49:20 +02:00
|
|
|
"github.com/status-im/status-go/rpc"
|
2023-12-15 17:29:39 -03:00
|
|
|
"github.com/status-im/status-go/server"
|
2022-09-13 09:10:59 +02:00
|
|
|
"github.com/status-im/status-go/services/ens"
|
|
|
|
"github.com/status-im/status-go/services/stickers"
|
2023-06-09 01:52:45 +02:00
|
|
|
"github.com/status-im/status-go/services/wallet/activity"
|
2023-09-04 07:34:09 +02:00
|
|
|
"github.com/status-im/status-go/services/wallet/balance"
|
2024-01-25 13:05:59 +01:00
|
|
|
"github.com/status-im/status-go/services/wallet/blockchainstate"
|
2023-03-21 10:52:14 -03:00
|
|
|
"github.com/status-im/status-go/services/wallet/collectibles"
|
2023-12-14 17:50:46 +01:00
|
|
|
"github.com/status-im/status-go/services/wallet/community"
|
2023-02-17 11:11:07 -03:00
|
|
|
"github.com/status-im/status-go/services/wallet/currency"
|
2022-11-15 14:14:41 +02:00
|
|
|
"github.com/status-im/status-go/services/wallet/history"
|
2023-02-21 10:05:16 +01:00
|
|
|
"github.com/status-im/status-go/services/wallet/market"
|
2023-03-21 10:52:14 -03:00
|
|
|
"github.com/status-im/status-go/services/wallet/thirdparty"
|
2023-04-17 08:42:01 -03:00
|
|
|
"github.com/status-im/status-go/services/wallet/thirdparty/alchemy"
|
2023-02-28 09:14:37 +01:00
|
|
|
"github.com/status-im/status-go/services/wallet/thirdparty/coingecko"
|
2023-02-21 10:05:16 +01:00
|
|
|
"github.com/status-im/status-go/services/wallet/thirdparty/cryptocompare"
|
2023-07-18 12:01:53 -03:00
|
|
|
"github.com/status-im/status-go/services/wallet/thirdparty/opensea"
|
2023-11-23 18:11:18 -03:00
|
|
|
"github.com/status-im/status-go/services/wallet/thirdparty/rarible"
|
2022-09-13 09:10:59 +02:00
|
|
|
"github.com/status-im/status-go/services/wallet/token"
|
2021-09-09 16:28:54 +02:00
|
|
|
"github.com/status-im/status-go/services/wallet/transfer"
|
2023-10-30 18:58:57 +02:00
|
|
|
"github.com/status-im/status-go/services/wallet/walletconnect"
|
2022-12-01 10:19:32 +01:00
|
|
|
"github.com/status-im/status-go/services/wallet/walletevent"
|
2022-07-15 10:53:56 +02:00
|
|
|
"github.com/status-im/status-go/transactions"
|
2019-06-14 13:16:30 +03:00
|
|
|
)
|
|
|
|
|
2023-03-20 14:02:09 +01:00
|
|
|
const (
|
|
|
|
EventBlockchainStatusChanged walletevent.EventType = "wallet-blockchain-status-changed"
|
|
|
|
)
|
2023-01-17 10:56:16 +01:00
|
|
|
|
2019-06-14 13:16:30 +03:00
|
|
|
// NewService initializes service instance.
|
2022-07-15 10:53:56 +02:00
|
|
|
func NewService(
|
|
|
|
db *sql.DB,
|
|
|
|
accountsDB *accounts.Database,
|
2023-12-12 08:37:57 +01:00
|
|
|
appDB *sql.DB,
|
2022-07-15 10:53:56 +02:00
|
|
|
rpcClient *rpc.Client,
|
|
|
|
accountFeed *event.Feed,
|
2023-10-10 09:18:47 -03:00
|
|
|
settingsFeed *event.Feed,
|
2022-07-15 10:53:56 +02:00
|
|
|
gethManager *account.GethManager,
|
|
|
|
transactor *transactions.Transactor,
|
|
|
|
config *params.NodeConfig,
|
2022-09-13 09:10:59 +02:00
|
|
|
ens *ens.Service,
|
|
|
|
stickers *stickers.Service,
|
2023-08-01 19:50:30 +01:00
|
|
|
pendingTxManager *transactions.PendingTxTracker,
|
|
|
|
feed *event.Feed,
|
2023-12-15 17:29:39 -03:00
|
|
|
mediaServer *server.MediaServer,
|
2022-07-15 10:53:56 +02:00
|
|
|
) *Service {
|
2021-09-09 16:28:54 +02:00
|
|
|
cryptoOnRampManager := NewCryptoOnRampManager(&CryptoOnRampOptions{
|
|
|
|
dataSourceType: DataSourceStatic,
|
|
|
|
})
|
2023-08-01 19:50:30 +01:00
|
|
|
|
2022-12-01 10:19:32 +01:00
|
|
|
signals := &walletevent.SignalsTransmitter{
|
2023-08-01 19:50:30 +01:00
|
|
|
Publisher: feed,
|
2022-12-01 10:19:32 +01:00
|
|
|
}
|
2023-03-23 13:13:16 +01:00
|
|
|
blockchainStatus := make(map[uint64]string)
|
2023-06-28 15:39:13 +02:00
|
|
|
mutex := sync.Mutex{}
|
2023-03-20 14:02:09 +01:00
|
|
|
rpcClient.SetWalletNotifier(func(chainID uint64, message string) {
|
2023-06-28 15:39:13 +02:00
|
|
|
mutex.Lock()
|
|
|
|
defer mutex.Unlock()
|
|
|
|
|
2023-03-23 13:13:16 +01:00
|
|
|
if len(blockchainStatus) == 0 {
|
|
|
|
networks, err := rpcClient.NetworkManager.Get(false)
|
|
|
|
if err != nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, network := range networks {
|
|
|
|
blockchainStatus[network.ChainID] = "up"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
blockchainStatus[chainID] = message
|
|
|
|
encodedmessage, err := json.Marshal(blockchainStatus)
|
|
|
|
if err != nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2023-08-01 19:50:30 +01:00
|
|
|
feed.Send(walletevent.Event{
|
2023-03-20 14:02:09 +01:00
|
|
|
Type: EventBlockchainStatusChanged,
|
|
|
|
Accounts: []common.Address{},
|
2023-03-23 13:13:16 +01:00
|
|
|
Message: string(encodedmessage),
|
2023-03-20 14:02:09 +01:00
|
|
|
At: time.Now().Unix(),
|
|
|
|
ChainID: chainID,
|
|
|
|
})
|
|
|
|
})
|
2023-09-04 07:34:09 +02:00
|
|
|
|
2023-12-22 10:43:19 +01:00
|
|
|
communityManager := community.NewManager(db, mediaServer, feed)
|
2023-10-04 14:00:12 +02:00
|
|
|
balanceCacher := balance.NewCacherWithTTL(5 * time.Minute)
|
2024-01-04 13:22:06 +01:00
|
|
|
tokenManager := token.NewTokenManager(db, rpcClient, communityManager, rpcClient.NetworkManager, appDB, mediaServer, feed)
|
2021-09-11 04:08:22 +10:00
|
|
|
savedAddressesManager := &SavedAddressesManager{db: db}
|
2023-08-01 19:50:30 +01:00
|
|
|
transactionManager := transfer.NewTransactionManager(db, gethManager, transactor, config, accountsDB, pendingTxManager, feed)
|
2024-01-25 13:05:59 +01:00
|
|
|
blockChainState := blockchainstate.NewBlockChainState()
|
2023-10-18 12:02:35 +02:00
|
|
|
transferController := transfer.NewTransferController(db, accountsDB, rpcClient, accountFeed, feed, transactionManager, pendingTxManager,
|
2024-01-25 13:05:59 +01:00
|
|
|
tokenManager, balanceCacher, blockChainState)
|
2023-11-30 06:59:55 +01:00
|
|
|
transferController.Start()
|
2023-02-21 10:05:16 +01:00
|
|
|
cryptoCompare := cryptocompare.NewClient()
|
2023-02-28 09:14:37 +01:00
|
|
|
coingecko := coingecko.NewClient()
|
2023-08-01 19:50:30 +01:00
|
|
|
marketManager := market.NewManager(cryptoCompare, coingecko, feed)
|
2023-12-22 10:43:19 +01:00
|
|
|
reader := NewReader(rpcClient, tokenManager, marketManager, communityManager, accountsDB, NewPersistence(db), feed)
|
2023-10-04 14:00:12 +02:00
|
|
|
history := history.NewService(db, accountsDB, feed, rpcClient, tokenManager, marketManager, balanceCacher.Cache())
|
2023-08-01 19:50:30 +01:00
|
|
|
currency := currency.NewService(db, feed, tokenManager, marketManager)
|
2023-04-17 08:42:01 -03:00
|
|
|
|
2023-08-17 15:10:13 -03:00
|
|
|
openseaHTTPClient := opensea.NewHTTPClient()
|
2023-09-22 10:18:42 -03:00
|
|
|
openseaV2Client := opensea.NewClientV2(config.WalletConfig.OpenseaAPIKey, openseaHTTPClient)
|
2023-11-23 18:11:18 -03:00
|
|
|
raribleClient := rarible.NewClient(config.WalletConfig.RaribleMainnetAPIKey, config.WalletConfig.RaribleTestnetAPIKey)
|
2023-08-01 20:17:59 -03:00
|
|
|
alchemyClient := alchemy.NewClient(config.WalletConfig.AlchemyAPIKeys)
|
|
|
|
|
|
|
|
// Try OpenSea, Infura, Alchemy in that order
|
|
|
|
contractOwnershipProviders := []thirdparty.CollectibleContractOwnershipProvider{
|
2023-11-23 18:11:18 -03:00
|
|
|
raribleClient,
|
2023-08-01 20:17:59 -03:00
|
|
|
alchemyClient,
|
|
|
|
}
|
|
|
|
|
|
|
|
accountOwnershipProviders := []thirdparty.CollectibleAccountOwnershipProvider{
|
2023-11-23 18:11:18 -03:00
|
|
|
raribleClient,
|
2023-08-01 20:17:59 -03:00
|
|
|
alchemyClient,
|
2024-02-07 09:54:37 -03:00
|
|
|
openseaV2Client,
|
2023-08-01 20:17:59 -03:00
|
|
|
}
|
|
|
|
|
2023-08-03 09:24:23 -03:00
|
|
|
collectibleDataProviders := []thirdparty.CollectibleDataProvider{
|
2023-11-23 18:11:18 -03:00
|
|
|
raribleClient,
|
2023-08-03 09:24:23 -03:00
|
|
|
alchemyClient,
|
2024-02-07 09:54:37 -03:00
|
|
|
openseaV2Client,
|
2023-08-03 09:24:23 -03:00
|
|
|
}
|
|
|
|
|
2023-08-16 10:01:57 -03:00
|
|
|
collectionDataProviders := []thirdparty.CollectionDataProvider{
|
2023-11-23 18:11:18 -03:00
|
|
|
raribleClient,
|
2023-08-16 10:01:57 -03:00
|
|
|
alchemyClient,
|
2024-02-07 09:54:37 -03:00
|
|
|
openseaV2Client,
|
2023-08-16 10:01:57 -03:00
|
|
|
}
|
|
|
|
|
2023-12-15 17:29:39 -03:00
|
|
|
collectiblesManager := collectibles.NewManager(db, rpcClient, communityManager, contractOwnershipProviders, accountOwnershipProviders, collectibleDataProviders, collectionDataProviders, mediaServer, feed)
|
2023-12-14 17:50:46 +01:00
|
|
|
collectibles := collectibles.NewService(db, feed, accountsDB, accountFeed, settingsFeed, communityManager, rpcClient.NetworkManager, collectiblesManager)
|
2023-08-11 18:28:46 +01:00
|
|
|
|
2024-01-08 16:24:30 -05:00
|
|
|
activity := activity.NewService(db, tokenManager, collectiblesManager, feed, pendingTxManager)
|
2023-08-11 18:28:46 +01:00
|
|
|
|
2023-12-01 17:42:08 +01:00
|
|
|
walletconnect := walletconnect.NewService(db, rpcClient.NetworkManager, accountsDB, transactionManager, gethManager, feed, config)
|
2023-10-30 18:58:57 +02:00
|
|
|
|
2019-06-14 13:16:30 +03:00
|
|
|
return &Service{
|
2022-05-10 09:48:05 +02:00
|
|
|
db: db,
|
|
|
|
accountsDB: accountsDB,
|
2021-09-22 19:49:20 +02:00
|
|
|
rpcClient: rpcClient,
|
2021-09-11 04:08:22 +10:00
|
|
|
tokenManager: tokenManager,
|
2023-12-14 17:50:46 +01:00
|
|
|
communityManager: communityManager,
|
2021-09-11 04:08:22 +10:00
|
|
|
savedAddressesManager: savedAddressesManager,
|
|
|
|
transactionManager: transactionManager,
|
2023-06-21 16:09:55 +02:00
|
|
|
pendingTxManager: pendingTxManager,
|
2021-09-11 04:08:22 +10:00
|
|
|
transferController: transferController,
|
|
|
|
cryptoOnRampManager: cryptoOnRampManager,
|
2023-03-21 10:52:14 -03:00
|
|
|
collectiblesManager: collectiblesManager,
|
2023-07-18 12:02:56 -03:00
|
|
|
collectibles: collectibles,
|
2022-03-29 22:12:05 +01:00
|
|
|
feesManager: &FeeManager{rpcClient},
|
2022-05-18 13:31:45 +02:00
|
|
|
gethManager: gethManager,
|
2023-02-21 10:05:16 +01:00
|
|
|
marketManager: marketManager,
|
2022-09-13 09:10:59 +02:00
|
|
|
transactor: transactor,
|
|
|
|
ens: ens,
|
|
|
|
stickers: stickers,
|
2023-08-01 19:50:30 +01:00
|
|
|
feed: feed,
|
2022-12-01 10:19:32 +01:00
|
|
|
signals: signals,
|
|
|
|
reader: reader,
|
2022-11-15 14:14:41 +02:00
|
|
|
history: history,
|
2023-02-17 11:11:07 -03:00
|
|
|
currency: currency,
|
2023-06-09 01:52:45 +02:00
|
|
|
activity: activity,
|
2023-07-06 09:37:04 +02:00
|
|
|
decoder: NewDecoder(),
|
2023-09-04 12:18:46 +02:00
|
|
|
blockChainState: blockChainState,
|
2023-09-12 14:45:32 +02:00
|
|
|
keycardPairings: NewKeycardPairings(),
|
2023-10-30 18:58:57 +02:00
|
|
|
walletConnect: walletconnect,
|
2019-06-14 13:16:30 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Service is a wallet service.
|
|
|
|
type Service struct {
|
2022-05-10 09:48:05 +02:00
|
|
|
db *sql.DB
|
|
|
|
accountsDB *accounts.Database
|
2021-09-22 19:49:20 +02:00
|
|
|
rpcClient *rpc.Client
|
2021-09-11 04:08:22 +10:00
|
|
|
savedAddressesManager *SavedAddressesManager
|
2022-10-25 16:50:32 +02:00
|
|
|
tokenManager *token.Manager
|
2023-12-14 17:50:46 +01:00
|
|
|
communityManager *community.Manager
|
2023-02-15 14:28:19 +02:00
|
|
|
transactionManager *transfer.TransactionManager
|
2023-08-01 19:50:30 +01:00
|
|
|
pendingTxManager *transactions.PendingTxTracker
|
2021-09-11 04:08:22 +10:00
|
|
|
cryptoOnRampManager *CryptoOnRampManager
|
|
|
|
transferController *transfer.Controller
|
2022-03-29 22:12:05 +01:00
|
|
|
feesManager *FeeManager
|
2023-02-21 10:05:16 +01:00
|
|
|
marketManager *market.Manager
|
2021-09-11 04:08:22 +10:00
|
|
|
started bool
|
2023-03-21 10:52:14 -03:00
|
|
|
collectiblesManager *collectibles.Manager
|
2023-07-18 12:02:56 -03:00
|
|
|
collectibles *collectibles.Service
|
2022-05-18 13:31:45 +02:00
|
|
|
gethManager *account.GethManager
|
2022-09-13 09:10:59 +02:00
|
|
|
transactor *transactions.Transactor
|
|
|
|
ens *ens.Service
|
|
|
|
stickers *stickers.Service
|
2022-11-29 14:43:18 +01:00
|
|
|
feed *event.Feed
|
2022-12-01 10:19:32 +01:00
|
|
|
signals *walletevent.SignalsTransmitter
|
|
|
|
reader *Reader
|
2022-11-15 14:14:41 +02:00
|
|
|
history *history.Service
|
2023-02-17 11:11:07 -03:00
|
|
|
currency *currency.Service
|
2023-06-09 01:52:45 +02:00
|
|
|
activity *activity.Service
|
2023-07-06 09:37:04 +02:00
|
|
|
decoder *Decoder
|
2024-01-25 13:05:59 +01:00
|
|
|
blockChainState *blockchainstate.BlockChainState
|
2023-09-12 14:45:32 +02:00
|
|
|
keycardPairings *KeycardPairings
|
2023-10-30 18:58:57 +02:00
|
|
|
walletConnect *walletconnect.Service
|
2019-06-14 13:16:30 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
// Start signals transmitter.
|
2021-06-30 13:40:54 +02:00
|
|
|
func (s *Service) Start() error {
|
2022-12-01 10:19:32 +01:00
|
|
|
s.transferController.Start()
|
2023-02-17 11:11:07 -03:00
|
|
|
s.currency.Start()
|
2022-12-01 10:19:32 +01:00
|
|
|
err := s.signals.Start()
|
2023-01-25 22:28:51 +04:00
|
|
|
s.history.Start()
|
2023-07-18 12:02:56 -03:00
|
|
|
s.collectibles.Start()
|
2021-09-09 16:28:54 +02:00
|
|
|
s.started = true
|
|
|
|
return err
|
2019-06-14 13:16:30 +03:00
|
|
|
}
|
|
|
|
|
2023-09-21 09:40:58 -03:00
|
|
|
// Set external Collectibles community info provider
|
2023-12-14 17:50:46 +01:00
|
|
|
func (s *Service) SetWalletCommunityInfoProvider(provider thirdparty.CommunityInfoProvider) {
|
|
|
|
s.communityManager.SetCommunityInfoProvider(provider)
|
2023-09-21 09:40:58 -03:00
|
|
|
}
|
|
|
|
|
2022-12-01 10:19:32 +01:00
|
|
|
// Stop reactor and close db.
|
2019-06-14 13:16:30 +03:00
|
|
|
func (s *Service) Stop() error {
|
|
|
|
log.Info("wallet will be stopped")
|
2022-12-01 10:19:32 +01:00
|
|
|
s.signals.Stop()
|
2021-09-09 16:28:54 +02:00
|
|
|
s.transferController.Stop()
|
2023-02-17 11:11:07 -03:00
|
|
|
s.currency.Stop()
|
2022-12-01 10:19:32 +01:00
|
|
|
s.reader.Stop()
|
2022-11-15 14:14:41 +02:00
|
|
|
s.history.Stop()
|
2023-06-09 01:52:45 +02:00
|
|
|
s.activity.Stop()
|
2023-07-18 12:02:56 -03:00
|
|
|
s.collectibles.Stop()
|
2021-09-09 16:28:54 +02:00
|
|
|
s.started = false
|
2019-06-14 13:16:30 +03:00
|
|
|
log.Info("wallet stopped")
|
2021-09-09 16:28:54 +02:00
|
|
|
return nil
|
2019-06-14 13:16:30 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
// APIs returns list of available RPC APIs.
|
2021-09-22 19:49:20 +02:00
|
|
|
func (s *Service) APIs() []gethrpc.API {
|
|
|
|
return []gethrpc.API{
|
2019-06-14 13:16:30 +03:00
|
|
|
{
|
|
|
|
Namespace: "wallet",
|
|
|
|
Version: "0.1.0",
|
|
|
|
Service: NewAPI(s),
|
|
|
|
Public: true,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Protocols returns list of p2p protocols.
|
|
|
|
func (s *Service) Protocols() []p2p.Protocol {
|
|
|
|
return nil
|
|
|
|
}
|
2019-08-28 10:49:03 +03:00
|
|
|
|
2020-02-28 18:05:37 +02:00
|
|
|
func (s *Service) IsStarted() bool {
|
2020-08-18 10:44:56 +02:00
|
|
|
return s.started
|
2020-02-28 18:05:37 +02:00
|
|
|
}
|
2023-09-12 14:45:32 +02:00
|
|
|
|
|
|
|
func (s *Service) KeycardPairings() *KeycardPairings {
|
|
|
|
return s.keycardPairings
|
|
|
|
}
|