chore: use single opensea client instance

This commit is contained in:
Dario Gabriel Lipicar 2023-07-10 06:02:17 -03:00 committed by dlipicar
parent f138964a9c
commit 849be69299
4 changed files with 100 additions and 112 deletions

View file

@ -2189,6 +2189,8 @@ func (m *Manager) GetOwnedERC721Tokens(walletAddresses []gethcommon.Address, tok
ownedERC721Tokens := make(CollectiblesByChain)
client := m.openseaClientBuilder.NewOpenseaClient(m.walletConfig.OpenseaAPIKey, nil)
for chainID, erc721Tokens := range tokenRequirements {
skipChain := true

View file

@ -38,10 +38,9 @@ type Manager struct {
mainContractOwnershipProvider thirdparty.CollectibleContractOwnershipProvider
fallbackContractOwnershipProvider thirdparty.CollectibleContractOwnershipProvider
metadataProvider thirdparty.CollectibleMetadataProvider
openseaAPIKey string
opensea *opensea.Client
nftCache map[uint64]map[string]opensea.Asset
nftCacheLock sync.RWMutex
walletFeed *event.Feed
}
func NewManager(rpcClient *rpc.Client, mainContractOwnershipProvider thirdparty.CollectibleContractOwnershipProvider, fallbackContractOwnershipProvider thirdparty.CollectibleContractOwnershipProvider, openseaAPIKey string, walletFeed *event.Feed) *Manager {
@ -56,9 +55,8 @@ func NewManager(rpcClient *rpc.Client, mainContractOwnershipProvider thirdparty.
rpcClient: rpcClient,
mainContractOwnershipProvider: mainContractOwnershipProvider,
fallbackContractOwnershipProvider: fallbackContractOwnershipProvider,
openseaAPIKey: openseaAPIKey,
opensea: opensea.NewClient(openseaAPIKey, walletFeed),
nftCache: make(map[uint64]map[string]opensea.Asset),
walletFeed: walletFeed,
}
}
@ -97,20 +95,11 @@ func (o *Manager) SetMetadataProvider(metadataProvider thirdparty.CollectibleMet
}
func (o *Manager) FetchAllCollectionsByOwner(chainID uint64, owner common.Address) ([]opensea.OwnedCollection, error) {
client, err := opensea.NewOpenseaClient(chainID, o.openseaAPIKey, o.walletFeed)
if err != nil {
return nil, err
}
return client.FetchAllCollectionsByOwner(owner)
return o.opensea.FetchAllCollectionsByOwner(chainID, owner)
}
func (o *Manager) FetchAllAssetsByOwnerAndCollection(chainID uint64, owner common.Address, collectionSlug string, cursor string, limit int) (*opensea.AssetContainer, error) {
client, err := opensea.NewOpenseaClient(chainID, o.openseaAPIKey, o.walletFeed)
if err != nil {
return nil, err
}
assetContainer, err := client.FetchAllAssetsByOwnerAndCollection(owner, collectionSlug, cursor, limit)
assetContainer, err := o.opensea.FetchAllAssetsByOwnerAndCollection(chainID, owner, collectionSlug, cursor, limit)
if err != nil {
return nil, err
}
@ -166,12 +155,7 @@ func (o *Manager) FetchBalancesByOwnerAndContractAddress(chainID uint64, ownerAd
}
func (o *Manager) FetchAllAssetsByOwnerAndContractAddress(chainID uint64, owner common.Address, contractAddresses []common.Address, cursor string, limit int) (*opensea.AssetContainer, error) {
client, err := opensea.NewOpenseaClient(chainID, o.openseaAPIKey, o.walletFeed)
if err != nil {
return nil, err
}
assetContainer, err := client.FetchAllAssetsByOwnerAndContractAddress(owner, contractAddresses, cursor, limit)
assetContainer, err := o.opensea.FetchAllAssetsByOwnerAndContractAddress(chainID, owner, contractAddresses, cursor, limit)
if err != nil {
return nil, err
}
@ -185,12 +169,7 @@ func (o *Manager) FetchAllAssetsByOwnerAndContractAddress(chainID uint64, owner
}
func (o *Manager) FetchAllAssetsByOwner(chainID uint64, owner common.Address, cursor string, limit int) (*opensea.AssetContainer, error) {
client, err := opensea.NewOpenseaClient(chainID, o.openseaAPIKey, o.walletFeed)
if err != nil {
return nil, err
}
assetContainer, err := client.FetchAllAssetsByOwner(owner, cursor, limit)
assetContainer, err := o.opensea.FetchAllAssetsByOwner(chainID, owner, cursor, limit)
if err != nil {
return nil, err
}
@ -208,12 +187,7 @@ func (o *Manager) FetchAssetsByNFTUniqueID(chainID uint64, uniqueIDs []thirdpart
idsToFetch := o.getIDsNotInCache(chainID, uniqueIDs)
if len(idsToFetch) > 0 {
client, err := opensea.NewOpenseaClient(chainID, o.openseaAPIKey, o.walletFeed)
if err != nil {
return nil, err
}
fetchedAssetContainer, err := client.FetchAssetsByNFTUniqueID(idsToFetch, limit)
fetchedAssetContainer, err := o.opensea.FetchAssetsByNFTUniqueID(chainID, idsToFetch, limit)
if err != nil {
return nil, err
}

View file

@ -0,0 +1,56 @@
package connection
import (
"sync"
"time"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/event"
"github.com/status-im/status-go/services/wallet/walletevent"
)
type Status struct {
eventType walletevent.EventType
feed *event.Feed
isConnected bool
lastCheckedAt int64
isConnectedLock sync.RWMutex
}
func NewStatus(eventType walletevent.EventType, feed *event.Feed) *Status {
return &Status{
eventType: eventType,
feed: feed,
isConnected: true,
lastCheckedAt: time.Now().Unix(),
}
}
func (c *Status) SetIsConnected(value bool) {
c.isConnectedLock.Lock()
defer c.isConnectedLock.Unlock()
c.lastCheckedAt = time.Now().Unix()
if value != c.isConnected {
message := "down"
if value {
message = "up"
}
if c.feed != nil {
c.feed.Send(walletevent.Event{
Type: c.eventType,
Accounts: []common.Address{},
Message: message,
At: time.Now().Unix(),
})
}
}
c.isConnected = value
}
func (c *Status) IsConnected() bool {
c.isConnectedLock.RLock()
defer c.isConnectedLock.RUnlock()
return c.isConnected
}

View file

@ -18,6 +18,7 @@ import (
"github.com/status-im/status-go/services/wallet/bigint"
walletCommon "github.com/status-im/status-go/services/wallet/common"
"github.com/status-im/status-go/services/wallet/connection"
"github.com/status-im/status-go/services/wallet/thirdparty"
"github.com/status-im/status-go/services/wallet/walletevent"
)
@ -50,10 +51,6 @@ func getbaseURL(chainID uint64) (string, error) {
return "", ErrChainIDNotSupported
}
var OpenseaClientInstances = make(map[uint64]*Client)
var OpenseaClientInstancesLock = sync.RWMutex{}
var OpenseaHTTPClient *HTTPClient = nil
type TraitValue string
func (st *TraitValue) UnmarshalJSON(b []byte) error {
@ -242,81 +239,37 @@ func (o *HTTPClient) doContentTypeRequest(url string) (string, error) {
}
type Client struct {
client *HTTPClient
url string
apiKey string
IsConnected bool
LastCheckedAt int64
IsConnectedLock sync.RWMutex
feed *event.Feed
client *HTTPClient
apiKey string
connectionStatus *connection.Status
}
// new opensea client.
func NewOpenseaClient(chainID uint64, apiKey string, feed *event.Feed) (*Client, error) {
OpenseaClientInstancesLock.Lock()
defer OpenseaClientInstancesLock.Unlock()
func NewClient(apiKey string, feed *event.Feed) *Client {
return &Client{
client: newHTTPClient(),
apiKey: apiKey,
connectionStatus: connection.NewStatus(EventCollectibleStatusChanged, feed),
}
}
if OpenseaHTTPClient == nil {
OpenseaHTTPClient = newHTTPClient()
}
var tmpAPIKey string = ""
if chainID == ChainIDRequiringAPIKey {
tmpAPIKey = apiKey
}
if client, ok := OpenseaClientInstances[chainID]; ok {
if client.apiKey == tmpAPIKey {
return client, nil
}
}
func (o *Client) FetchAllCollectionsByOwner(chainID uint64, owner common.Address) ([]OwnedCollection, error) {
offset := 0
var collections []OwnedCollection
baseURL, err := getbaseURL(chainID)
if err != nil {
return nil, err
}
openseaClient := &Client{
client: OpenseaHTTPClient,
url: baseURL,
apiKey: tmpAPIKey,
IsConnected: true,
LastCheckedAt: time.Now().Unix(),
feed: feed,
}
OpenseaClientInstances[chainID] = openseaClient
return openseaClient, nil
}
func (o *Client) setIsConnected(value bool) {
o.IsConnectedLock.Lock()
defer o.IsConnectedLock.Unlock()
o.LastCheckedAt = time.Now().Unix()
if value != o.IsConnected {
message := "down"
if value {
message = "up"
}
if o.feed != nil {
o.feed.Send(walletevent.Event{
Type: EventCollectibleStatusChanged,
Accounts: []common.Address{},
Message: message,
At: time.Now().Unix(),
})
}
}
o.IsConnected = value
}
func (o *Client) FetchAllCollectionsByOwner(owner common.Address) ([]OwnedCollection, error) {
offset := 0
var collections []OwnedCollection
for {
url := fmt.Sprintf("%s/collections?asset_owner=%s&offset=%d&limit=%d", o.url, owner, offset, CollectionLimit)
url := fmt.Sprintf("%s/collections?asset_owner=%s&offset=%d&limit=%d", baseURL, owner, offset, CollectionLimit)
body, err := o.client.doGetRequest(url, o.apiKey)
if err != nil {
o.setIsConnected(false)
o.connectionStatus.SetIsConnected(false)
return nil, err
}
o.connectionStatus.SetIsConnected(true)
// if Json is not returned there must be an error
if !json.Valid(body) {
@ -326,7 +279,6 @@ func (o *Client) FetchAllCollectionsByOwner(owner common.Address) ([]OwnedCollec
var tmp []OwnedCollection
err = json.Unmarshal(body, &tmp)
if err != nil {
o.setIsConnected(false)
return nil, err
}
@ -336,11 +288,10 @@ func (o *Client) FetchAllCollectionsByOwner(owner common.Address) ([]OwnedCollec
break
}
}
o.setIsConnected(true)
return collections, nil
}
func (o *Client) FetchAllAssetsByOwnerAndCollection(owner common.Address, collectionSlug string, cursor string, limit int) (*AssetContainer, error) {
func (o *Client) FetchAllAssetsByOwnerAndCollection(chainID uint64, owner common.Address, collectionSlug string, cursor string, limit int) (*AssetContainer, error) {
queryParams := url.Values{
"owner": {owner.String()},
"collection": {collectionSlug},
@ -350,10 +301,10 @@ func (o *Client) FetchAllAssetsByOwnerAndCollection(owner common.Address, collec
queryParams["cursor"] = []string{cursor}
}
return o.fetchAssets(queryParams, limit)
return o.fetchAssets(chainID, queryParams, limit)
}
func (o *Client) FetchAllAssetsByOwnerAndContractAddress(owner common.Address, contractAddresses []common.Address, cursor string, limit int) (*AssetContainer, error) {
func (o *Client) FetchAllAssetsByOwnerAndContractAddress(chainID uint64, owner common.Address, contractAddresses []common.Address, cursor string, limit int) (*AssetContainer, error) {
queryParams := url.Values{
"owner": {owner.String()},
}
@ -366,10 +317,10 @@ func (o *Client) FetchAllAssetsByOwnerAndContractAddress(owner common.Address, c
queryParams["cursor"] = []string{cursor}
}
return o.fetchAssets(queryParams, limit)
return o.fetchAssets(chainID, queryParams, limit)
}
func (o *Client) FetchAllAssetsByOwner(owner common.Address, cursor string, limit int) (*AssetContainer, error) {
func (o *Client) FetchAllAssetsByOwner(chainID uint64, owner common.Address, cursor string, limit int) (*AssetContainer, error) {
queryParams := url.Values{
"owner": {owner.String()},
}
@ -378,10 +329,10 @@ func (o *Client) FetchAllAssetsByOwner(owner common.Address, cursor string, limi
queryParams["cursor"] = []string{cursor}
}
return o.fetchAssets(queryParams, limit)
return o.fetchAssets(chainID, queryParams, limit)
}
func (o *Client) FetchAssetsByNFTUniqueID(uniqueIDs []thirdparty.CollectibleUniqueID, limit int) (*AssetContainer, error) {
func (o *Client) FetchAssetsByNFTUniqueID(chainID uint64, uniqueIDs []thirdparty.CollectibleUniqueID, limit int) (*AssetContainer, error) {
queryParams := url.Values{}
for _, uniqueID := range uniqueIDs {
@ -389,10 +340,10 @@ func (o *Client) FetchAssetsByNFTUniqueID(uniqueIDs []thirdparty.CollectibleUniq
queryParams.Add("asset_contract_addresses", uniqueID.ContractAddress.String())
}
return o.fetchAssets(queryParams, limit)
return o.fetchAssets(chainID, queryParams, limit)
}
func (o *Client) fetchAssets(queryParams url.Values, limit int) (*AssetContainer, error) {
func (o *Client) fetchAssets(chainID uint64, queryParams url.Values, limit int) (*AssetContainer, error) {
assets := new(AssetContainer)
if len(queryParams["cursor"]) > 0 {
@ -404,15 +355,22 @@ func (o *Client) fetchAssets(queryParams url.Values, limit int) (*AssetContainer
tmpLimit = limit
}
baseURL, err := getbaseURL(chainID)
if err != nil {
return nil, err
}
queryParams["limit"] = []string{strconv.Itoa(tmpLimit)}
for {
url := o.url + "/assets?" + queryParams.Encode()
url := baseURL + "/assets?" + queryParams.Encode()
body, err := o.client.doGetRequest(url, o.apiKey)
if err != nil {
o.setIsConnected(false)
o.connectionStatus.SetIsConnected(false)
return nil, err
}
o.connectionStatus.SetIsConnected(true)
// if Json is not returned there must be an error
if !json.Valid(body) {
@ -422,7 +380,6 @@ func (o *Client) fetchAssets(queryParams url.Values, limit int) (*AssetContainer
container := AssetContainer{}
err = json.Unmarshal(body, &container)
if err != nil {
o.setIsConnected(false)
return nil, err
}
@ -452,6 +409,5 @@ func (o *Client) fetchAssets(queryParams url.Values, limit int) (*AssetContainer
}
}
o.setIsConnected(true)
return assets, nil
}