fix: ensure full collectible list is fetched from a single provider

This commit is contained in:
Dario Gabriel Lipicar 2023-10-04 13:21:45 -03:00 committed by dlipicar
parent 1fedf5503a
commit 94ae683bc2
8 changed files with 25 additions and 8 deletions

View File

@ -392,13 +392,13 @@ func (api *API) GetCollectiblesByOwnerAndCollectionWithCursor(ctx context.Contex
// @deprecated
func (api *API) GetCollectiblesByOwnerWithCursor(ctx context.Context, chainID wcommon.ChainID, owner common.Address, cursor string, limit int) (*thirdparty.FullCollectibleDataContainer, error) {
log.Debug("call to GetCollectiblesByOwnerWithCursor")
return api.s.collectiblesManager.FetchAllAssetsByOwner(chainID, owner, cursor, limit)
return api.s.collectiblesManager.FetchAllAssetsByOwner(chainID, owner, cursor, limit, thirdparty.FetchFromAnyProvider)
}
// @deprecated
func (api *API) GetCollectiblesByOwnerAndContractAddressWithCursor(ctx context.Context, chainID wcommon.ChainID, owner common.Address, contractAddresses []common.Address, cursor string, limit int) (*thirdparty.FullCollectibleDataContainer, error) {
log.Debug("call to GetCollectiblesByOwnerAndContractAddressWithCursor")
return api.s.collectiblesManager.FetchAllAssetsByOwnerAndContractAddress(chainID, owner, contractAddresses, cursor, limit)
return api.s.collectiblesManager.FetchAllAssetsByOwnerAndContractAddress(chainID, owner, contractAddresses, cursor, limit, thirdparty.FetchFromAnyProvider)
}
// @deprecated

View File

@ -134,6 +134,7 @@ func (c *loadOwnedCollectiblesCommand) Run(parent context.Context) (err error) {
pageNr := 0
cursor := thirdparty.FetchFromStartCursor
providerID := thirdparty.FetchFromAnyProvider
start := time.Now()
c.triggerEvent(EventCollectiblesOwnershipUpdateStarted, c.chainID, c.account, "")
@ -153,7 +154,7 @@ func (c *loadOwnedCollectiblesCommand) Run(parent context.Context) (err error) {
pageStart := time.Now()
log.Debug("start loadOwnedCollectiblesCommand", "chain", c.chainID, "account", c.account, "page", pageNr)
partialOwnership, err := c.manager.FetchCollectibleOwnershipByOwner(c.chainID, c.account, cursor, fetchLimit)
partialOwnership, err := c.manager.FetchCollectibleOwnershipByOwner(c.chainID, c.account, cursor, fetchLimit, providerID)
if err != nil {
log.Error("failed loadOwnedCollectiblesCommand", "chain", c.chainID, "account", c.account, "page", pageNr, "error", err)
@ -167,6 +168,7 @@ func (c *loadOwnedCollectiblesCommand) Run(parent context.Context) (err error) {
pageNr++
cursor = partialOwnership.NextCursor
providerID = partialOwnership.Provider
finished := cursor == thirdparty.FetchFromStartCursor

View File

@ -239,7 +239,7 @@ func (o *Manager) FetchBalancesByOwnerAndContractAddress(chainID walletCommon.Ch
}
// Try with account ownership providers first
assetsContainer, err := o.FetchAllAssetsByOwnerAndContractAddress(chainID, ownerAddress, contractAddresses, thirdparty.FetchFromStartCursor, thirdparty.FetchNoLimit)
assetsContainer, err := o.FetchAllAssetsByOwnerAndContractAddress(chainID, ownerAddress, contractAddresses, thirdparty.FetchFromStartCursor, thirdparty.FetchNoLimit, thirdparty.FetchFromAnyProvider)
if err == ErrNoProvidersAvailableForChainID {
// Use contract ownership providers
for _, contractAddress := range contractAddresses {
@ -272,7 +272,7 @@ func (o *Manager) FetchBalancesByOwnerAndContractAddress(chainID walletCommon.Ch
return ret, nil
}
func (o *Manager) FetchAllAssetsByOwnerAndContractAddress(chainID walletCommon.ChainID, owner common.Address, contractAddresses []common.Address, cursor string, limit int) (*thirdparty.FullCollectibleDataContainer, error) {
func (o *Manager) FetchAllAssetsByOwnerAndContractAddress(chainID walletCommon.ChainID, owner common.Address, contractAddresses []common.Address, cursor string, limit int, providerID string) (*thirdparty.FullCollectibleDataContainer, error) {
defer o.checkConnectionStatus(chainID)
anyProviderAvailable := false
@ -281,6 +281,9 @@ func (o *Manager) FetchAllAssetsByOwnerAndContractAddress(chainID walletCommon.C
continue
}
anyProviderAvailable = true
if providerID != thirdparty.FetchFromAnyProvider && providerID != provider.ID() {
continue
}
assetContainer, err := provider.FetchAllAssetsByOwnerAndContractAddress(chainID, owner, contractAddresses, cursor, limit)
if err != nil {
@ -302,7 +305,7 @@ func (o *Manager) FetchAllAssetsByOwnerAndContractAddress(chainID walletCommon.C
return nil, ErrNoProvidersAvailableForChainID
}
func (o *Manager) FetchAllAssetsByOwner(chainID walletCommon.ChainID, owner common.Address, cursor string, limit int) (*thirdparty.FullCollectibleDataContainer, error) {
func (o *Manager) FetchAllAssetsByOwner(chainID walletCommon.ChainID, owner common.Address, cursor string, limit int, providerID string) (*thirdparty.FullCollectibleDataContainer, error) {
defer o.checkConnectionStatus(chainID)
anyProviderAvailable := false
@ -310,6 +313,10 @@ func (o *Manager) FetchAllAssetsByOwner(chainID walletCommon.ChainID, owner comm
if !provider.IsChainSupported(chainID) {
continue
}
anyProviderAvailable = true
if providerID != thirdparty.FetchFromAnyProvider && providerID != provider.ID() {
continue
}
assetContainer, err := provider.FetchAllAssetsByOwner(chainID, owner, cursor, limit)
if err != nil {
@ -331,10 +338,10 @@ func (o *Manager) FetchAllAssetsByOwner(chainID walletCommon.ChainID, owner comm
return nil, ErrNoProvidersAvailableForChainID
}
func (o *Manager) FetchCollectibleOwnershipByOwner(chainID walletCommon.ChainID, owner common.Address, cursor string, limit int) (*thirdparty.CollectibleOwnershipContainer, error) {
func (o *Manager) FetchCollectibleOwnershipByOwner(chainID walletCommon.ChainID, owner common.Address, cursor string, limit int, providerID string) (*thirdparty.CollectibleOwnershipContainer, error) {
// We don't yet have an API that will return only Ownership data
// Use the full Ownership + Metadata endpoint and use the data we need
assetContainer, err := o.FetchAllAssetsByOwner(chainID, owner, cursor, limit)
assetContainer, err := o.FetchAllAssetsByOwner(chainID, owner, cursor, limit, providerID)
if err != nil {
return nil, err
}

View File

@ -204,6 +204,7 @@ func (o *Client) fetchOwnedAssets(chainID walletCommon.ChainID, owner common.Add
queryParams["pageKey"] = []string{cursor}
assets.PreviousCursor = cursor
}
assets.Provider = o.ID()
baseURL, err := getNFTBaseURL(chainID, o.apiKeys[uint64(chainID)])

View File

@ -18,6 +18,7 @@ var (
const FetchNoLimit = 0
const FetchFromStartCursor = ""
const FetchFromAnyProvider = ""
type CollectibleProvider interface {
ID() string
@ -144,6 +145,7 @@ type CollectiblesContainer[T any] struct {
Items []T
NextCursor string
PreviousCursor string
Provider string
}
type CollectibleOwnershipContainer CollectiblesContainer[CollectibleUniqueID]
@ -165,6 +167,7 @@ func (c *FullCollectibleDataContainer) ToOwnershipContainer() CollectibleOwnersh
Items: collectibleItemsToIDs(c.Items),
NextCursor: c.NextCursor,
PreviousCursor: c.PreviousCursor,
Provider: c.Provider,
}
}

View File

@ -149,6 +149,7 @@ func (o *Client) fetchOwnedAssets(chainID walletCommon.ChainID, owner common.Add
if len(queryParams["cursor"]) > 0 {
assets.PreviousCursor = queryParams["cursor"][0]
}
assets.Provider = o.ID()
for {
url := fmt.Sprintf("%s/networks/%d/accounts/%s/assets/nfts?%s", baseURL, chainID, owner.String(), queryParams.Encode())

View File

@ -217,6 +217,7 @@ func (o *Client) fetchAssets(chainID walletCommon.ChainID, queryParams url.Value
if len(queryParams["cursor"]) > 0 {
assets.PreviousCursor = queryParams["cursor"][0]
}
assets.Provider = o.ID()
tmpLimit := AssetLimit
if limit > thirdparty.FetchNoLimit && limit < tmpLimit {

View File

@ -88,6 +88,7 @@ func (o *ClientV2) FetchAllAssetsByOwnerAndContractAddress(chainID walletCommon.
assets.PreviousCursor = cursor
assets.NextCursor = cursor
assets.Provider = o.ID()
for {
assetsPage, err := o.FetchAllAssetsByOwner(chainID, owner, assets.NextCursor, assetLimitV2)
@ -144,6 +145,7 @@ func (o *ClientV2) fetchAssets(chainID walletCommon.ChainID, pathParams []string
if cursor != "" {
queryParams["next"] = []string{cursor}
}
assets.Provider = o.ID()
for {
path := fmt.Sprintf("%s?%s", strings.Join(pathParams, "/"), queryParams.Encode())