feat: Add community manager and fetch cached community metadata (#4450)
This commit is contained in:
parent
64a0d9e340
commit
7af313cd53
|
@ -128,7 +128,7 @@ func (b *StatusNode) initServices(config *params.NodeConfig, mediaServer *server
|
||||||
|
|
||||||
services = append(services, wakuext)
|
services = append(services, wakuext)
|
||||||
|
|
||||||
b.SetWalletCollectibleCommunityInfoProvider(wakuext)
|
b.SetWalletCommunityInfoProvider(wakuext)
|
||||||
}
|
}
|
||||||
|
|
||||||
if config.WakuV2Config.Enabled {
|
if config.WakuV2Config.Enabled {
|
||||||
|
@ -155,7 +155,7 @@ func (b *StatusNode) initServices(config *params.NodeConfig, mediaServer *server
|
||||||
|
|
||||||
services = append(services, wakuext)
|
services = append(services, wakuext)
|
||||||
|
|
||||||
b.SetWalletCollectibleCommunityInfoProvider(wakuext)
|
b.SetWalletCommunityInfoProvider(wakuext)
|
||||||
}
|
}
|
||||||
|
|
||||||
// We ignore for now local notifications flag as users who are upgrading have no mean to enable it
|
// We ignore for now local notifications flag as users who are upgrading have no mean to enable it
|
||||||
|
@ -518,9 +518,9 @@ func (b *StatusNode) WalletService() *wallet.Service {
|
||||||
return b.walletSrvc
|
return b.walletSrvc
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *StatusNode) SetWalletCollectibleCommunityInfoProvider(provider thirdparty.CollectibleCommunityInfoProvider) {
|
func (b *StatusNode) SetWalletCommunityInfoProvider(provider thirdparty.CommunityInfoProvider) {
|
||||||
if b.walletSrvc != nil {
|
if b.walletSrvc != nil {
|
||||||
b.walletSrvc.SetCollectibleCommunityInfoProvider(provider)
|
b.walletSrvc.SetWalletCommunityInfoProvider(provider)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -65,6 +65,7 @@ import (
|
||||||
localnotifications "github.com/status-im/status-go/services/local-notifications"
|
localnotifications "github.com/status-im/status-go/services/local-notifications"
|
||||||
mailserversDB "github.com/status-im/status-go/services/mailservers"
|
mailserversDB "github.com/status-im/status-go/services/mailservers"
|
||||||
"github.com/status-im/status-go/services/wallet"
|
"github.com/status-im/status-go/services/wallet"
|
||||||
|
"github.com/status-im/status-go/services/wallet/community"
|
||||||
"github.com/status-im/status-go/services/wallet/token"
|
"github.com/status-im/status-go/services/wallet/token"
|
||||||
"github.com/status-im/status-go/signal"
|
"github.com/status-im/status-go/signal"
|
||||||
"github.com/status-im/status-go/telemetry"
|
"github.com/status-im/status-go/telemetry"
|
||||||
|
@ -459,7 +460,7 @@ func NewMessenger(
|
||||||
if c.tokenManager != nil {
|
if c.tokenManager != nil {
|
||||||
managerOptions = append(managerOptions, communities.WithTokenManager(c.tokenManager))
|
managerOptions = append(managerOptions, communities.WithTokenManager(c.tokenManager))
|
||||||
} else if c.rpcClient != nil {
|
} else if c.rpcClient != nil {
|
||||||
tokenManager := token.NewTokenManager(c.walletDb, c.rpcClient, c.rpcClient.NetworkManager, database)
|
tokenManager := token.NewTokenManager(c.walletDb, c.rpcClient, community.NewManager(database), c.rpcClient.NetworkManager, database)
|
||||||
managerOptions = append(managerOptions, communities.WithTokenManager(communities.NewDefaultTokenManager(tokenManager)))
|
managerOptions = append(managerOptions, communities.WithTokenManager(communities.NewDefaultTokenManager(tokenManager)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,6 @@ import (
|
||||||
"github.com/status-im/status-go/services/accounts/settingsevent"
|
"github.com/status-im/status-go/services/accounts/settingsevent"
|
||||||
"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/community"
|
|
||||||
"github.com/status-im/status-go/services/wallet/transfer"
|
"github.com/status-im/status-go/services/wallet/transfer"
|
||||||
"github.com/status-im/status-go/services/wallet/walletevent"
|
"github.com/status-im/status-go/services/wallet/walletevent"
|
||||||
)
|
)
|
||||||
|
@ -35,7 +34,6 @@ type timerPerAddressAndChainID = map[common.Address]timerPerChainID
|
||||||
type Controller struct {
|
type Controller struct {
|
||||||
manager *Manager
|
manager *Manager
|
||||||
ownershipDB *OwnershipDB
|
ownershipDB *OwnershipDB
|
||||||
communityDB *community.DataDB
|
|
||||||
walletFeed *event.Feed
|
walletFeed *event.Feed
|
||||||
accountsDB *accounts.Database
|
accountsDB *accounts.Database
|
||||||
accountsFeed *event.Feed
|
accountsFeed *event.Feed
|
||||||
|
@ -67,7 +65,6 @@ func NewController(
|
||||||
return &Controller{
|
return &Controller{
|
||||||
manager: manager,
|
manager: manager,
|
||||||
ownershipDB: NewOwnershipDB(db),
|
ownershipDB: NewOwnershipDB(db),
|
||||||
communityDB: community.NewDataDB(db),
|
|
||||||
walletFeed: walletFeed,
|
walletFeed: walletFeed,
|
||||||
accountsDB: accountsDB,
|
accountsDB: accountsDB,
|
||||||
accountsFeed: accountsFeed,
|
accountsFeed: accountsFeed,
|
||||||
|
|
|
@ -4,7 +4,6 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"database/sql"
|
"database/sql"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
|
||||||
"math/big"
|
"math/big"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
|
@ -27,7 +26,6 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
const requestTimeout = 5 * time.Second
|
const requestTimeout = 5 * time.Second
|
||||||
const failedCommunityFetchRetryDelay = 1 * time.Hour
|
|
||||||
|
|
||||||
const hystrixContractOwnershipClientName = "contractOwnershipClient"
|
const hystrixContractOwnershipClientName = "contractOwnershipClient"
|
||||||
|
|
||||||
|
@ -56,13 +54,12 @@ type Manager struct {
|
||||||
collectibleDataProviders []thirdparty.CollectibleDataProvider
|
collectibleDataProviders []thirdparty.CollectibleDataProvider
|
||||||
collectionDataProviders []thirdparty.CollectionDataProvider
|
collectionDataProviders []thirdparty.CollectionDataProvider
|
||||||
collectibleProviders []thirdparty.CollectibleProvider
|
collectibleProviders []thirdparty.CollectibleProvider
|
||||||
communityInfoProvider thirdparty.CollectibleCommunityInfoProvider
|
|
||||||
|
|
||||||
httpClient *http.Client
|
httpClient *http.Client
|
||||||
|
|
||||||
collectiblesDataDB *CollectibleDataDB
|
collectiblesDataDB *CollectibleDataDB
|
||||||
collectionsDataDB *CollectionDataDB
|
collectionsDataDB *CollectionDataDB
|
||||||
communityDataDB *community.DataDB
|
communityManager *community.Manager
|
||||||
|
|
||||||
statuses map[string]*connection.Status
|
statuses map[string]*connection.Status
|
||||||
statusNotifier *connection.StatusNotifier
|
statusNotifier *connection.StatusNotifier
|
||||||
|
@ -71,6 +68,7 @@ type Manager struct {
|
||||||
func NewManager(
|
func NewManager(
|
||||||
db *sql.DB,
|
db *sql.DB,
|
||||||
rpcClient *rpc.Client,
|
rpcClient *rpc.Client,
|
||||||
|
communityManager *community.Manager,
|
||||||
contractOwnershipProviders []thirdparty.CollectibleContractOwnershipProvider,
|
contractOwnershipProviders []thirdparty.CollectibleContractOwnershipProvider,
|
||||||
accountOwnershipProviders []thirdparty.CollectibleAccountOwnershipProvider,
|
accountOwnershipProviders []thirdparty.CollectibleAccountOwnershipProvider,
|
||||||
collectibleDataProviders []thirdparty.CollectibleDataProvider,
|
collectibleDataProviders []thirdparty.CollectibleDataProvider,
|
||||||
|
@ -136,7 +134,7 @@ func NewManager(
|
||||||
},
|
},
|
||||||
collectiblesDataDB: NewCollectibleDataDB(db),
|
collectiblesDataDB: NewCollectibleDataDB(db),
|
||||||
collectionsDataDB: NewCollectionDataDB(db),
|
collectionsDataDB: NewCollectionDataDB(db),
|
||||||
communityDataDB: community.NewDataDB(db),
|
communityManager: communityManager,
|
||||||
statuses: statuses,
|
statuses: statuses,
|
||||||
statusNotifier: statusNotifier,
|
statusNotifier: statusNotifier,
|
||||||
}
|
}
|
||||||
|
@ -198,11 +196,6 @@ func (o *Manager) doContentTypeRequest(ctx context.Context, url string) (string,
|
||||||
return resp.Header.Get("Content-Type"), nil
|
return resp.Header.Get("Content-Type"), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Used to break circular dependency, call once as soon as possible after initialization
|
|
||||||
func (o *Manager) SetCommunityInfoProvider(communityInfoProvider thirdparty.CollectibleCommunityInfoProvider) {
|
|
||||||
o.communityInfoProvider = communityInfoProvider
|
|
||||||
}
|
|
||||||
|
|
||||||
// Need to combine different providers to support all needed ChainIDs
|
// Need to combine different providers to support all needed ChainIDs
|
||||||
func (o *Manager) FetchBalancesByOwnerAndContractAddress(ctx context.Context, chainID walletCommon.ChainID, ownerAddress common.Address, contractAddresses []common.Address) (thirdparty.TokenBalancesPerContractAddress, error) {
|
func (o *Manager) FetchBalancesByOwnerAndContractAddress(ctx context.Context, chainID walletCommon.ChainID, ownerAddress common.Address, contractAddresses []common.Address) (thirdparty.TokenBalancesPerContractAddress, error) {
|
||||||
ret := make(thirdparty.TokenBalancesPerContractAddress)
|
ret := make(thirdparty.TokenBalancesPerContractAddress)
|
||||||
|
@ -611,65 +604,22 @@ func (o *Manager) fillCommunityID(asset *thirdparty.FullCollectibleData) error {
|
||||||
|
|
||||||
communityID := ""
|
communityID := ""
|
||||||
if tokenURI != "" {
|
if tokenURI != "" {
|
||||||
communityID = o.communityInfoProvider.GetCommunityID(tokenURI)
|
communityID = o.communityManager.GetCommunityID(tokenURI)
|
||||||
}
|
}
|
||||||
|
|
||||||
asset.CollectibleData.CommunityID = communityID
|
asset.CollectibleData.CommunityID = communityID
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *Manager) mustFetchCommunityInfo(communityID string) bool {
|
|
||||||
// See if we have cached data
|
|
||||||
_, state, err := o.communityDataDB.GetCommunityInfo(communityID)
|
|
||||||
if err != nil {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// If we don't have a state, this community has never been fetched before
|
|
||||||
if state == nil {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the last fetch was successful, we can safely refresh our cache
|
|
||||||
if state.LastUpdateSuccesful {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the last fetch was not successful, we should only retry after a delay
|
|
||||||
if time.Unix(int64(state.LastUpdateTimestamp), 0).Add(failedCommunityFetchRetryDelay).Before(time.Now()) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func (o *Manager) fetchCommunityInfo(communityID string) (*thirdparty.CommunityInfo, error) {
|
|
||||||
if !o.mustFetchCommunityInfo(communityID) {
|
|
||||||
return nil, fmt.Errorf("backing off fetchCommunityInfo for id: %s", communityID)
|
|
||||||
}
|
|
||||||
|
|
||||||
communityInfo, err := o.communityInfoProvider.FetchCommunityInfo(communityID)
|
|
||||||
if err != nil {
|
|
||||||
dbErr := o.communityDataDB.SetCommunityInfo(communityID, nil)
|
|
||||||
if dbErr != nil {
|
|
||||||
log.Error("SetCommunityInfo failed", "communityID", communityID, "err", dbErr)
|
|
||||||
}
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = o.communityDataDB.SetCommunityInfo(communityID, communityInfo)
|
|
||||||
return communityInfo, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (o *Manager) fillCommunityInfo(communityID string, communityAssets []*thirdparty.FullCollectibleData) error {
|
func (o *Manager) fillCommunityInfo(communityID string, communityAssets []*thirdparty.FullCollectibleData) error {
|
||||||
communityInfo, err := o.fetchCommunityInfo(communityID)
|
communityInfo, err := o.communityManager.FetchCommunityInfo(communityID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if communityInfo != nil {
|
if communityInfo != nil {
|
||||||
for _, communityAsset := range communityAssets {
|
for _, communityAsset := range communityAssets {
|
||||||
err := o.communityInfoProvider.FillCollectibleMetadata(communityAsset)
|
err := o.communityManager.FillCollectibleMetadata(communityAsset)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,13 +69,13 @@ var (
|
||||||
)
|
)
|
||||||
|
|
||||||
type Service struct {
|
type Service struct {
|
||||||
manager *Manager
|
manager *Manager
|
||||||
controller *Controller
|
controller *Controller
|
||||||
db *sql.DB
|
db *sql.DB
|
||||||
ownershipDB *OwnershipDB
|
ownershipDB *OwnershipDB
|
||||||
communityDB *community.DataDB
|
communityManager *community.Manager
|
||||||
walletFeed *event.Feed
|
walletFeed *event.Feed
|
||||||
scheduler *async.MultiClientScheduler
|
scheduler *async.MultiClientScheduler
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewService(
|
func NewService(
|
||||||
|
@ -84,16 +84,17 @@ func NewService(
|
||||||
accountsDB *accounts.Database,
|
accountsDB *accounts.Database,
|
||||||
accountsFeed *event.Feed,
|
accountsFeed *event.Feed,
|
||||||
settingsFeed *event.Feed,
|
settingsFeed *event.Feed,
|
||||||
|
communityManager *community.Manager,
|
||||||
networkManager *network.Manager,
|
networkManager *network.Manager,
|
||||||
manager *Manager) *Service {
|
manager *Manager) *Service {
|
||||||
s := &Service{
|
s := &Service{
|
||||||
manager: manager,
|
manager: manager,
|
||||||
controller: NewController(db, walletFeed, accountsDB, accountsFeed, settingsFeed, networkManager, manager),
|
controller: NewController(db, walletFeed, accountsDB, accountsFeed, settingsFeed, networkManager, manager),
|
||||||
db: db,
|
db: db,
|
||||||
ownershipDB: NewOwnershipDB(db),
|
ownershipDB: NewOwnershipDB(db),
|
||||||
communityDB: community.NewDataDB(db),
|
communityManager: communityManager,
|
||||||
walletFeed: walletFeed,
|
walletFeed: walletFeed,
|
||||||
scheduler: async.NewMultiClientScheduler(),
|
scheduler: async.NewMultiClientScheduler(),
|
||||||
}
|
}
|
||||||
s.controller.SetReceivedCollectiblesCb(s.notifyCommunityCollectiblesReceived)
|
s.controller.SetReceivedCollectiblesCb(s.notifyCommunityCollectiblesReceived)
|
||||||
return s
|
return s
|
||||||
|
@ -413,7 +414,7 @@ func (s *Service) fullCollectiblesDataToHeaders(data []thirdparty.FullCollectibl
|
||||||
header := fullCollectibleDataToHeader(c)
|
header := fullCollectibleDataToHeader(c)
|
||||||
|
|
||||||
if c.CollectibleData.CommunityID != "" {
|
if c.CollectibleData.CommunityID != "" {
|
||||||
communityInfo, _, err := s.communityDB.GetCommunityInfo(c.CollectibleData.CommunityID)
|
communityInfo, _, err := s.communityManager.GetCommunityInfo(c.CollectibleData.CommunityID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -435,7 +436,7 @@ func (s *Service) fullCollectiblesDataToDetails(data []thirdparty.FullCollectibl
|
||||||
details := fullCollectibleDataToDetails(c)
|
details := fullCollectibleDataToDetails(c)
|
||||||
|
|
||||||
if c.CollectibleData.CommunityID != "" {
|
if c.CollectibleData.CommunityID != "" {
|
||||||
communityInfo, _, err := s.communityDB.GetCommunityInfo(c.CollectibleData.CommunityID)
|
communityInfo, _, err := s.communityManager.GetCommunityInfo(c.CollectibleData.CommunityID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -461,7 +462,7 @@ func (s *Service) fullCollectiblesDataToCommunityHeader(data []thirdparty.FullCo
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
communityInfo, _, err := s.communityDB.GetCommunityInfo(communityID)
|
communityInfo, _, err := s.communityManager.GetCommunityInfo(communityID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Error fetching community info", "error", err)
|
log.Error("Error fetching community info", "error", err)
|
||||||
continue
|
continue
|
||||||
|
|
|
@ -0,0 +1,87 @@
|
||||||
|
package community
|
||||||
|
|
||||||
|
import (
|
||||||
|
"database/sql"
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/log"
|
||||||
|
"github.com/status-im/status-go/services/wallet/thirdparty"
|
||||||
|
)
|
||||||
|
|
||||||
|
const failedCommunityFetchRetryDelay = 1 * time.Hour
|
||||||
|
|
||||||
|
type Manager struct {
|
||||||
|
db *DataDB
|
||||||
|
communityInfoProvider thirdparty.CommunityInfoProvider
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewManager(db *sql.DB) *Manager {
|
||||||
|
return &Manager{
|
||||||
|
db: NewDataDB(db),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Used to break circular dependency, call once as soon as possible after initialization
|
||||||
|
func (cm *Manager) SetCommunityInfoProvider(communityInfoProvider thirdparty.CommunityInfoProvider) {
|
||||||
|
cm.communityInfoProvider = communityInfoProvider
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cm *Manager) GetCommunityInfo(id string) (*thirdparty.CommunityInfo, *InfoState, error) {
|
||||||
|
return cm.db.GetCommunityInfo(id)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cm *Manager) GetCommunityID(tokenURI string) string {
|
||||||
|
return cm.communityInfoProvider.GetCommunityID(tokenURI)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cm *Manager) FillCollectibleMetadata(c *thirdparty.FullCollectibleData) error {
|
||||||
|
return cm.communityInfoProvider.FillCollectibleMetadata(c)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cm *Manager) setCommunityInfo(id string, c *thirdparty.CommunityInfo) (err error) {
|
||||||
|
return cm.db.SetCommunityInfo(id, c)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cm *Manager) mustFetchCommunityInfo(communityID string) bool {
|
||||||
|
// See if we have cached data
|
||||||
|
_, state, err := cm.GetCommunityInfo(communityID)
|
||||||
|
if err != nil {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we don't have a state, this community has never been fetched before
|
||||||
|
if state == nil {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the last fetch was successful, we can safely refresh our cache
|
||||||
|
if state.LastUpdateSuccesful {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the last fetch was not successful, we should only retry after a delay
|
||||||
|
if time.Unix(int64(state.LastUpdateTimestamp), 0).Add(failedCommunityFetchRetryDelay).Before(time.Now()) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cm *Manager) FetchCommunityInfo(communityID string) (*thirdparty.CommunityInfo, error) {
|
||||||
|
if !cm.mustFetchCommunityInfo(communityID) {
|
||||||
|
return nil, fmt.Errorf("backing off fetchCommunityInfo for id: %s", communityID)
|
||||||
|
}
|
||||||
|
|
||||||
|
communityInfo, err := cm.communityInfoProvider.FetchCommunityInfo(communityID)
|
||||||
|
if err != nil {
|
||||||
|
dbErr := cm.setCommunityInfo(communityID, nil)
|
||||||
|
if dbErr != nil {
|
||||||
|
log.Error("SetCommunityInfo failed", "communityID", communityID, "err", dbErr)
|
||||||
|
}
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = cm.setCommunityInfo(communityID, communityInfo)
|
||||||
|
return communityInfo, err
|
||||||
|
}
|
|
@ -21,6 +21,7 @@ import (
|
||||||
"github.com/status-im/status-go/services/wallet/activity"
|
"github.com/status-im/status-go/services/wallet/activity"
|
||||||
"github.com/status-im/status-go/services/wallet/balance"
|
"github.com/status-im/status-go/services/wallet/balance"
|
||||||
"github.com/status-im/status-go/services/wallet/collectibles"
|
"github.com/status-im/status-go/services/wallet/collectibles"
|
||||||
|
"github.com/status-im/status-go/services/wallet/community"
|
||||||
"github.com/status-im/status-go/services/wallet/currency"
|
"github.com/status-im/status-go/services/wallet/currency"
|
||||||
"github.com/status-im/status-go/services/wallet/history"
|
"github.com/status-im/status-go/services/wallet/history"
|
||||||
"github.com/status-im/status-go/services/wallet/market"
|
"github.com/status-im/status-go/services/wallet/market"
|
||||||
|
@ -96,8 +97,9 @@ func NewService(
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
communityManager := community.NewManager(db)
|
||||||
balanceCacher := balance.NewCacherWithTTL(5 * time.Minute)
|
balanceCacher := balance.NewCacherWithTTL(5 * time.Minute)
|
||||||
tokenManager := token.NewTokenManager(db, rpcClient, rpcClient.NetworkManager, appDB)
|
tokenManager := token.NewTokenManager(db, rpcClient, communityManager, rpcClient.NetworkManager, appDB)
|
||||||
savedAddressesManager := &SavedAddressesManager{db: db}
|
savedAddressesManager := &SavedAddressesManager{db: db}
|
||||||
transactionManager := transfer.NewTransactionManager(db, gethManager, transactor, config, accountsDB, pendingTxManager, feed)
|
transactionManager := transfer.NewTransactionManager(db, gethManager, transactor, config, accountsDB, pendingTxManager, feed)
|
||||||
transferController := transfer.NewTransferController(db, accountsDB, rpcClient, accountFeed, feed, transactionManager, pendingTxManager,
|
transferController := transfer.NewTransferController(db, accountsDB, rpcClient, accountFeed, feed, transactionManager, pendingTxManager,
|
||||||
|
@ -140,8 +142,8 @@ func NewService(
|
||||||
alchemyClient,
|
alchemyClient,
|
||||||
}
|
}
|
||||||
|
|
||||||
collectiblesManager := collectibles.NewManager(db, rpcClient, contractOwnershipProviders, accountOwnershipProviders, collectibleDataProviders, collectionDataProviders, feed)
|
collectiblesManager := collectibles.NewManager(db, rpcClient, communityManager, contractOwnershipProviders, accountOwnershipProviders, collectibleDataProviders, collectionDataProviders, feed)
|
||||||
collectibles := collectibles.NewService(db, feed, accountsDB, accountFeed, settingsFeed, rpcClient.NetworkManager, collectiblesManager)
|
collectibles := collectibles.NewService(db, feed, accountsDB, accountFeed, settingsFeed, communityManager, rpcClient.NetworkManager, collectiblesManager)
|
||||||
|
|
||||||
activity := activity.NewService(db, tokenManager, collectiblesManager, feed)
|
activity := activity.NewService(db, tokenManager, collectiblesManager, feed)
|
||||||
|
|
||||||
|
@ -152,6 +154,7 @@ func NewService(
|
||||||
accountsDB: accountsDB,
|
accountsDB: accountsDB,
|
||||||
rpcClient: rpcClient,
|
rpcClient: rpcClient,
|
||||||
tokenManager: tokenManager,
|
tokenManager: tokenManager,
|
||||||
|
communityManager: communityManager,
|
||||||
savedAddressesManager: savedAddressesManager,
|
savedAddressesManager: savedAddressesManager,
|
||||||
transactionManager: transactionManager,
|
transactionManager: transactionManager,
|
||||||
pendingTxManager: pendingTxManager,
|
pendingTxManager: pendingTxManager,
|
||||||
|
@ -185,6 +188,7 @@ type Service struct {
|
||||||
rpcClient *rpc.Client
|
rpcClient *rpc.Client
|
||||||
savedAddressesManager *SavedAddressesManager
|
savedAddressesManager *SavedAddressesManager
|
||||||
tokenManager *token.Manager
|
tokenManager *token.Manager
|
||||||
|
communityManager *community.Manager
|
||||||
transactionManager *transfer.TransactionManager
|
transactionManager *transfer.TransactionManager
|
||||||
pendingTxManager *transactions.PendingTxTracker
|
pendingTxManager *transactions.PendingTxTracker
|
||||||
cryptoOnRampManager *CryptoOnRampManager
|
cryptoOnRampManager *CryptoOnRampManager
|
||||||
|
@ -223,8 +227,8 @@ func (s *Service) Start() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set external Collectibles community info provider
|
// Set external Collectibles community info provider
|
||||||
func (s *Service) SetCollectibleCommunityInfoProvider(provider thirdparty.CollectibleCommunityInfoProvider) {
|
func (s *Service) SetWalletCommunityInfoProvider(provider thirdparty.CommunityInfoProvider) {
|
||||||
s.collectiblesManager.SetCommunityInfoProvider(provider)
|
s.communityManager.SetCommunityInfoProvider(provider)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stop reactor and close db.
|
// Stop reactor and close db.
|
||||||
|
|
|
@ -216,8 +216,3 @@ type CollectionDataProvider interface {
|
||||||
CollectibleProvider
|
CollectibleProvider
|
||||||
FetchCollectionsDataByContractID(ctx context.Context, ids []ContractID) ([]CollectionData, error)
|
FetchCollectionsDataByContractID(ctx context.Context, ids []ContractID) ([]CollectionData, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type CollectibleCommunityInfoProvider interface {
|
|
||||||
CommunityInfoProvider
|
|
||||||
FillCollectibleMetadata(collectible *FullCollectibleData) error
|
|
||||||
}
|
|
||||||
|
|
|
@ -10,4 +10,7 @@ type CommunityInfo struct {
|
||||||
type CommunityInfoProvider interface {
|
type CommunityInfoProvider interface {
|
||||||
GetCommunityID(tokenURI string) string
|
GetCommunityID(tokenURI string) string
|
||||||
FetchCommunityInfo(communityID string) (*CommunityInfo, error)
|
FetchCommunityInfo(communityID string) (*CommunityInfo, error)
|
||||||
|
|
||||||
|
// Collectible-related methods
|
||||||
|
FillCollectibleMetadata(collectible *FullCollectibleData) error
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,7 @@ import (
|
||||||
"github.com/status-im/status-go/services/communitytokens"
|
"github.com/status-im/status-go/services/communitytokens"
|
||||||
"github.com/status-im/status-go/services/utils"
|
"github.com/status-im/status-go/services/utils"
|
||||||
"github.com/status-im/status-go/services/wallet/async"
|
"github.com/status-im/status-go/services/wallet/async"
|
||||||
|
"github.com/status-im/status-go/services/wallet/community"
|
||||||
)
|
)
|
||||||
|
|
||||||
var requestTimeout = 20 * time.Second
|
var requestTimeout = 20 * time.Second
|
||||||
|
@ -52,10 +53,10 @@ type Token struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type CommunityData struct {
|
type CommunityData struct {
|
||||||
ID string `json:"id"`
|
ID string `json:"id"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Color string `json:"color"`
|
Color string `json:"color"`
|
||||||
ImageURL *string `json:"image_url,omitempty"`
|
Image string `json:"image,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *Token) IsNative() bool {
|
func (t *Token) IsNative() bool {
|
||||||
|
@ -86,6 +87,7 @@ type Manager struct {
|
||||||
networkManager *network.Manager
|
networkManager *network.Manager
|
||||||
stores []store // Set on init, not changed afterwards
|
stores []store // Set on init, not changed afterwards
|
||||||
communityTokensDB *communitytokens.Database
|
communityTokensDB *communitytokens.Database
|
||||||
|
communityManager *community.Manager
|
||||||
|
|
||||||
tokens []*Token
|
tokens []*Token
|
||||||
|
|
||||||
|
@ -110,6 +112,7 @@ func mergeTokens(sliceLists [][]*Token) []*Token {
|
||||||
func NewTokenManager(
|
func NewTokenManager(
|
||||||
db *sql.DB,
|
db *sql.DB,
|
||||||
RPCClient *rpc.Client,
|
RPCClient *rpc.Client,
|
||||||
|
communityManager *community.Manager,
|
||||||
networkManager *network.Manager,
|
networkManager *network.Manager,
|
||||||
appDB *sql.DB,
|
appDB *sql.DB,
|
||||||
) *Manager {
|
) *Manager {
|
||||||
|
@ -143,6 +146,7 @@ func NewTokenManager(
|
||||||
RPCClient: RPCClient,
|
RPCClient: RPCClient,
|
||||||
contractMaker: maker,
|
contractMaker: maker,
|
||||||
networkManager: networkManager,
|
networkManager: networkManager,
|
||||||
|
communityManager: communityManager,
|
||||||
stores: stores,
|
stores: stores,
|
||||||
communityTokensDB: communitytokens.NewCommunityTokensDatabase(appDB),
|
communityTokensDB: communitytokens.NewCommunityTokensDatabase(appDB),
|
||||||
tokens: tokens,
|
tokens: tokens,
|
||||||
|
@ -532,6 +536,16 @@ func (tm *Manager) getTokensFromDB(query string, args ...any) ([]*Token, error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if tm.communityManager != nil && token.CommunityData != nil {
|
||||||
|
communityInfo, _, err := tm.communityManager.GetCommunityInfo(token.CommunityData.ID)
|
||||||
|
if err == nil && communityInfo != nil {
|
||||||
|
// Fetched data from cache. Cache is refreshed during every wallet token list call.
|
||||||
|
token.CommunityData.Name = communityInfo.CommunityName
|
||||||
|
token.CommunityData.Color = communityInfo.CommunityColor
|
||||||
|
token.CommunityData.Image = communityInfo.CommunityImage
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
rst = append(rst, token)
|
rst = append(rst, token)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,7 @@ func setupTestTokenDB(t *testing.T) (*Manager, func()) {
|
||||||
networkManager: nil,
|
networkManager: nil,
|
||||||
stores: nil,
|
stores: nil,
|
||||||
communityTokensDB: nil,
|
communityTokensDB: nil,
|
||||||
|
communityManager: nil,
|
||||||
}, func() {
|
}, func() {
|
||||||
require.NoError(t, db.Close())
|
require.NoError(t, db.Close())
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,6 +29,7 @@ import (
|
||||||
"github.com/status-im/status-go/rpc/chain"
|
"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/async"
|
||||||
"github.com/status-im/status-go/services/wallet/balance"
|
"github.com/status-im/status-go/services/wallet/balance"
|
||||||
|
"github.com/status-im/status-go/services/wallet/community"
|
||||||
"github.com/status-im/status-go/t/helpers"
|
"github.com/status-im/status-go/t/helpers"
|
||||||
"github.com/status-im/status-go/t/utils"
|
"github.com/status-im/status-go/t/utils"
|
||||||
|
|
||||||
|
@ -932,7 +933,7 @@ func TestFindBlocksCommand(t *testing.T) {
|
||||||
}
|
}
|
||||||
client, _ := statusRpc.NewClient(nil, 1, params.UpstreamRPCConfig{Enabled: false, URL: ""}, []params.Network{}, db)
|
client, _ := statusRpc.NewClient(nil, 1, params.UpstreamRPCConfig{Enabled: false, URL: ""}, []params.Network{}, db)
|
||||||
client.SetClient(tc.NetworkID(), tc)
|
client.SetClient(tc.NetworkID(), tc)
|
||||||
tokenManager := token.NewTokenManager(db, client, network.NewManager(appdb), appdb)
|
tokenManager := token.NewTokenManager(db, client, community.NewManager(appdb), network.NewManager(appdb), appdb)
|
||||||
tokenManager.SetTokens([]*token.Token{
|
tokenManager.SetTokens([]*token.Token{
|
||||||
{
|
{
|
||||||
Address: tokenTXXAddress,
|
Address: tokenTXXAddress,
|
||||||
|
@ -1054,7 +1055,7 @@ func TestFetchTransfersForLoadedBlocks(t *testing.T) {
|
||||||
|
|
||||||
client, _ := statusRpc.NewClient(nil, 1, params.UpstreamRPCConfig{Enabled: false, URL: ""}, []params.Network{}, db)
|
client, _ := statusRpc.NewClient(nil, 1, params.UpstreamRPCConfig{Enabled: false, URL: ""}, []params.Network{}, db)
|
||||||
client.SetClient(tc.NetworkID(), tc)
|
client.SetClient(tc.NetworkID(), tc)
|
||||||
tokenManager := token.NewTokenManager(db, client, network.NewManager(appdb), appdb)
|
tokenManager := token.NewTokenManager(db, client, community.NewManager(appdb), network.NewManager(appdb), appdb)
|
||||||
|
|
||||||
tokenManager.SetTokens([]*token.Token{
|
tokenManager.SetTokens([]*token.Token{
|
||||||
{
|
{
|
||||||
|
@ -1171,7 +1172,7 @@ func TestFetchNewBlocksCommand_findBlocksWithEthTransfers(t *testing.T) {
|
||||||
|
|
||||||
client, _ := statusRpc.NewClient(nil, 1, params.UpstreamRPCConfig{Enabled: false, URL: ""}, []params.Network{}, db)
|
client, _ := statusRpc.NewClient(nil, 1, params.UpstreamRPCConfig{Enabled: false, URL: ""}, []params.Network{}, db)
|
||||||
client.SetClient(tc.NetworkID(), tc)
|
client.SetClient(tc.NetworkID(), tc)
|
||||||
tokenManager := token.NewTokenManager(db, client, network.NewManager(appdb), appdb)
|
tokenManager := token.NewTokenManager(db, client, community.NewManager(appdb), network.NewManager(appdb), appdb)
|
||||||
|
|
||||||
tokenManager.SetTokens([]*token.Token{
|
tokenManager.SetTokens([]*token.Token{
|
||||||
{
|
{
|
||||||
|
@ -1245,7 +1246,7 @@ func TestFetchNewBlocksCommand(t *testing.T) {
|
||||||
|
|
||||||
client, _ := statusRpc.NewClient(nil, 1, params.UpstreamRPCConfig{Enabled: false, URL: ""}, []params.Network{}, db)
|
client, _ := statusRpc.NewClient(nil, 1, params.UpstreamRPCConfig{Enabled: false, URL: ""}, []params.Network{}, db)
|
||||||
client.SetClient(tc.NetworkID(), tc)
|
client.SetClient(tc.NetworkID(), tc)
|
||||||
tokenManager := token.NewTokenManager(db, client, network.NewManager(appdb), appdb)
|
tokenManager := token.NewTokenManager(db, client, community.NewManager(appdb), network.NewManager(appdb), appdb)
|
||||||
|
|
||||||
tokenManager.SetTokens([]*token.Token{
|
tokenManager.SetTokens([]*token.Token{
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue