feat: trigger collectibles fetch on new account
This commit is contained in:
parent
5ba5611a8d
commit
85d8e83394
|
@ -0,0 +1,86 @@
|
||||||
|
package walletaccounts
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
"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/services/accounts/accountsevent"
|
||||||
|
"github.com/status-im/status-go/services/wallet/async"
|
||||||
|
)
|
||||||
|
|
||||||
|
type AccountsChangeCb func(changedAddresses []common.Address, eventType accountsevent.EventType, currentAddresses []common.Address)
|
||||||
|
|
||||||
|
// Watcher executes a given callback whenever an account gets added/removed
|
||||||
|
type Watcher struct {
|
||||||
|
accountsDB *accounts.Database
|
||||||
|
accountFeed *event.Feed
|
||||||
|
group *async.Group
|
||||||
|
callback AccountsChangeCb
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewWatcher(accountsDB *accounts.Database, accountFeed *event.Feed, callback AccountsChangeCb) *Watcher {
|
||||||
|
return &Watcher{
|
||||||
|
accountsDB: accountsDB,
|
||||||
|
accountFeed: accountFeed,
|
||||||
|
callback: callback,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *Watcher) Start() {
|
||||||
|
if w.group != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
w.group = async.NewGroup(context.Background())
|
||||||
|
w.group.Add(func(ctx context.Context) error {
|
||||||
|
return watch(ctx, w.accountsDB, w.accountFeed, w.callback)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *Watcher) Stop() {
|
||||||
|
if w.group != nil {
|
||||||
|
w.group.Stop()
|
||||||
|
w.group.Wait()
|
||||||
|
w.group = nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func onAccountsChange(accountsDB *accounts.Database, callback AccountsChangeCb, changedAddresses []common.Address, eventType accountsevent.EventType) {
|
||||||
|
currentEthAddresses, err := accountsDB.GetWalletAddresses()
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
log.Error("failed getting wallet addresses", "error", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
currentAddresses := make([]common.Address, 0, len(currentEthAddresses))
|
||||||
|
for _, ethAddress := range currentEthAddresses {
|
||||||
|
currentAddresses = append(currentAddresses, common.Address(ethAddress))
|
||||||
|
}
|
||||||
|
|
||||||
|
if callback != nil {
|
||||||
|
callback(changedAddresses, eventType, currentAddresses)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func watch(ctx context.Context, accountsDB *accounts.Database, accountFeed *event.Feed, callback AccountsChangeCb) error {
|
||||||
|
ch := make(chan accountsevent.Event, 1)
|
||||||
|
sub := accountFeed.Subscribe(ch)
|
||||||
|
defer sub.Unsubscribe()
|
||||||
|
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case <-ctx.Done():
|
||||||
|
return nil
|
||||||
|
case err := <-sub.Err():
|
||||||
|
if err != nil {
|
||||||
|
log.Error("accounts watcher subscription failed", "error", err)
|
||||||
|
}
|
||||||
|
case ev := <-ch:
|
||||||
|
onAccountsChange(accountsDB, callback, ev.Accounts, ev.Type)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -10,8 +10,11 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/event"
|
"github.com/ethereum/go-ethereum/event"
|
||||||
"github.com/ethereum/go-ethereum/log"
|
"github.com/ethereum/go-ethereum/log"
|
||||||
|
|
||||||
|
"github.com/status-im/status-go/multiaccounts/accounts"
|
||||||
"github.com/status-im/status-go/rpc/network"
|
"github.com/status-im/status-go/rpc/network"
|
||||||
|
|
||||||
|
"github.com/status-im/status-go/services/accounts/accountsevent"
|
||||||
|
walletaccounts "github.com/status-im/status-go/services/wallet/accounts"
|
||||||
"github.com/status-im/status-go/services/wallet/async"
|
"github.com/status-im/status-go/services/wallet/async"
|
||||||
walletCommon "github.com/status-im/status-go/services/wallet/common"
|
walletCommon "github.com/status-im/status-go/services/wallet/common"
|
||||||
"github.com/status-im/status-go/services/wallet/thirdparty"
|
"github.com/status-im/status-go/services/wallet/thirdparty"
|
||||||
|
@ -40,21 +43,27 @@ var (
|
||||||
)
|
)
|
||||||
|
|
||||||
type Service struct {
|
type Service struct {
|
||||||
manager *Manager
|
manager *Manager
|
||||||
db *sql.DB
|
db *sql.DB
|
||||||
eventFeed *event.Feed
|
walletFeed *event.Feed
|
||||||
|
accountsDB *accounts.Database
|
||||||
|
accountsFeed *event.Feed
|
||||||
|
|
||||||
networkManager *network.Manager
|
networkManager *network.Manager
|
||||||
cancelFn context.CancelFunc
|
cancelFn context.CancelFunc
|
||||||
|
|
||||||
group *async.Group
|
group *async.Group
|
||||||
scheduler *async.Scheduler
|
scheduler *async.Scheduler
|
||||||
|
accountsWatcher *walletaccounts.Watcher
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewService(db *sql.DB, eventFeed *event.Feed, networkManager *network.Manager, manager *Manager) *Service {
|
func NewService(db *sql.DB, walletFeed *event.Feed, accountsDB *accounts.Database, accountsFeed *event.Feed, networkManager *network.Manager, manager *Manager) *Service {
|
||||||
return &Service{
|
return &Service{
|
||||||
manager: manager,
|
manager: manager,
|
||||||
db: db,
|
db: db,
|
||||||
eventFeed: eventFeed,
|
walletFeed: walletFeed,
|
||||||
|
accountsDB: accountsDB,
|
||||||
|
accountsFeed: accountsFeed,
|
||||||
networkManager: networkManager,
|
networkManager: networkManager,
|
||||||
scheduler: async.NewScheduler(),
|
scheduler: async.NewScheduler(),
|
||||||
}
|
}
|
||||||
|
@ -144,7 +153,8 @@ func (s *Service) GetCollectiblesDataAsync(ctx context.Context, uniqueIDs []thir
|
||||||
s.sendResponseEvent(EventGetCollectiblesDataDone, res, err)
|
s.sendResponseEvent(EventGetCollectiblesDataDone, res, err)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
func (s *Service) Start() {
|
|
||||||
|
func (s *Service) startPeriodicalOwnershipFetch() {
|
||||||
if s.group != nil {
|
if s.group != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -156,14 +166,14 @@ func (s *Service) Start() {
|
||||||
command := newRefreshOwnedCollectiblesCommand(
|
command := newRefreshOwnedCollectiblesCommand(
|
||||||
s.manager,
|
s.manager,
|
||||||
s.db,
|
s.db,
|
||||||
s.eventFeed,
|
s.walletFeed,
|
||||||
s.networkManager,
|
s.networkManager,
|
||||||
)
|
)
|
||||||
|
|
||||||
s.group.Add(command.Command())
|
s.group.Add(command.Command())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Service) Stop() {
|
func (s *Service) stopPeriodicalOwnershipFetch() {
|
||||||
if s.cancelFn != nil {
|
if s.cancelFn != nil {
|
||||||
s.cancelFn()
|
s.cancelFn()
|
||||||
s.cancelFn = nil
|
s.cancelFn = nil
|
||||||
|
@ -173,6 +183,47 @@ func (s *Service) Stop() {
|
||||||
s.group.Wait()
|
s.group.Wait()
|
||||||
s.group = nil
|
s.group = nil
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Service) startAccountsWatcher() {
|
||||||
|
if s.accountsWatcher != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
accountChangeCb := func(changedAddresses []common.Address, eventType accountsevent.EventType, currentAddresses []common.Address) {
|
||||||
|
// Whenever an account gets added, restart fetch
|
||||||
|
// TODO: Fetch only added accounts
|
||||||
|
if eventType == accountsevent.EventTypeAdded {
|
||||||
|
s.stopPeriodicalOwnershipFetch()
|
||||||
|
s.startPeriodicalOwnershipFetch()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
s.accountsWatcher = walletaccounts.NewWatcher(s.accountsDB, s.accountsFeed, accountChangeCb)
|
||||||
|
|
||||||
|
s.accountsWatcher.Start()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Service) stopAccountsWatcher() {
|
||||||
|
if s.accountsWatcher != nil {
|
||||||
|
s.accountsWatcher.Stop()
|
||||||
|
s.accountsWatcher = nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Service) Start() {
|
||||||
|
// Setup periodical collectibles refresh
|
||||||
|
s.startPeriodicalOwnershipFetch()
|
||||||
|
|
||||||
|
// Setup collectibles fetch when a new account gets added
|
||||||
|
s.startAccountsWatcher()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Service) Stop() {
|
||||||
|
s.stopAccountsWatcher()
|
||||||
|
|
||||||
|
s.stopPeriodicalOwnershipFetch()
|
||||||
|
|
||||||
s.scheduler.Stop()
|
s.scheduler.Stop()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -186,7 +237,7 @@ func (s *Service) sendResponseEvent(eventType walletevent.EventType, payloadObj
|
||||||
|
|
||||||
log.Debug("wallet.api.collectibles.Service RESPONSE", "eventType", eventType, "error", err, "payload.len", len(payload))
|
log.Debug("wallet.api.collectibles.Service RESPONSE", "eventType", eventType, "error", err, "payload.len", len(payload))
|
||||||
|
|
||||||
s.eventFeed.Send(walletevent.Event{
|
s.walletFeed.Send(walletevent.Event{
|
||||||
Type: eventType,
|
Type: eventType,
|
||||||
Message: string(payload),
|
Message: string(payload),
|
||||||
})
|
})
|
||||||
|
|
|
@ -109,7 +109,7 @@ func NewService(
|
||||||
infuraClient := infura.NewClient(config.WalletConfig.InfuraAPIKey, config.WalletConfig.InfuraAPIKeySecret)
|
infuraClient := infura.NewClient(config.WalletConfig.InfuraAPIKey, config.WalletConfig.InfuraAPIKeySecret)
|
||||||
openseaClient := opensea.NewClient(config.WalletConfig.OpenseaAPIKey, walletFeed)
|
openseaClient := opensea.NewClient(config.WalletConfig.OpenseaAPIKey, walletFeed)
|
||||||
collectiblesManager := collectibles.NewManager(rpcClient, alchemyClient, infuraClient, openseaClient)
|
collectiblesManager := collectibles.NewManager(rpcClient, alchemyClient, infuraClient, openseaClient)
|
||||||
collectibles := collectibles.NewService(db, walletFeed, rpcClient.NetworkManager, collectiblesManager)
|
collectibles := collectibles.NewService(db, walletFeed, accountsDB, accountFeed, rpcClient.NetworkManager, collectiblesManager)
|
||||||
return &Service{
|
return &Service{
|
||||||
db: db,
|
db: db,
|
||||||
accountsDB: accountsDB,
|
accountsDB: accountsDB,
|
||||||
|
|
Loading…
Reference in New Issue