feat: implement collectible ownership status
This commit is contained in:
parent
e502ba82ce
commit
e337ab4f13
|
@ -3,6 +3,7 @@ package collectibles
|
|||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
|
@ -27,16 +28,19 @@ type periodicRefreshOwnedCollectiblesCommand struct {
|
|||
walletFeed *event.Feed
|
||||
|
||||
group *async.Group
|
||||
state atomic.Value
|
||||
}
|
||||
|
||||
func newPeriodicRefreshOwnedCollectiblesCommand(manager *Manager, ownershipDB *OwnershipDB, walletFeed *event.Feed, chainID walletCommon.ChainID, account common.Address) *periodicRefreshOwnedCollectiblesCommand {
|
||||
return &periodicRefreshOwnedCollectiblesCommand{
|
||||
ret := &periodicRefreshOwnedCollectiblesCommand{
|
||||
manager: manager,
|
||||
ownershipDB: ownershipDB,
|
||||
walletFeed: walletFeed,
|
||||
chainID: chainID,
|
||||
account: account,
|
||||
}
|
||||
ret.state.Store(OwnershipStateIdle)
|
||||
return ret
|
||||
}
|
||||
|
||||
func (c *periodicRefreshOwnedCollectiblesCommand) Command() async.Command {
|
||||
|
@ -50,6 +54,10 @@ func (c *periodicRefreshOwnedCollectiblesCommand) Run(ctx context.Context) (err
|
|||
return c.loadOwnedCollectibles(ctx)
|
||||
}
|
||||
|
||||
func (c *periodicRefreshOwnedCollectiblesCommand) GetState() OwnershipState {
|
||||
return c.state.Load().(OwnershipState)
|
||||
}
|
||||
|
||||
func (c *periodicRefreshOwnedCollectiblesCommand) Stop() {
|
||||
if c.group != nil {
|
||||
c.group.Stop()
|
||||
|
@ -60,8 +68,17 @@ func (c *periodicRefreshOwnedCollectiblesCommand) Stop() {
|
|||
|
||||
func (c *periodicRefreshOwnedCollectiblesCommand) loadOwnedCollectibles(ctx context.Context) error {
|
||||
c.group = async.NewGroup(ctx)
|
||||
|
||||
command := newLoadOwnedCollectiblesCommand(c.manager, c.ownershipDB, c.walletFeed, c.chainID, c.account)
|
||||
|
||||
c.state.Store(OwnershipStateUpdating)
|
||||
defer func() {
|
||||
if command.err != nil {
|
||||
c.state.Store(OwnershipStateError)
|
||||
} else {
|
||||
c.state.Store(OwnershipStateIdle)
|
||||
}
|
||||
}()
|
||||
|
||||
c.group.Add(command.Command())
|
||||
|
||||
select {
|
||||
|
|
|
@ -84,12 +84,29 @@ const (
|
|||
ErrorCodeFailed
|
||||
)
|
||||
|
||||
type OwnershipState = int
|
||||
|
||||
const (
|
||||
OwnershipStateIdle OwnershipState = iota + 1
|
||||
OwnershipStateUpdating
|
||||
OwnershipStateError
|
||||
)
|
||||
|
||||
type OwnershipStatus struct {
|
||||
State OwnershipState `json:"state"`
|
||||
Timestamp int64 `json:"timestamp"`
|
||||
}
|
||||
|
||||
type OwnershipStatusPerChainID = map[walletCommon.ChainID]OwnershipStatus
|
||||
type OwnershipStatusPerAddressAndChainID = map[common.Address]OwnershipStatusPerChainID
|
||||
|
||||
type FilterOwnedCollectiblesResponse struct {
|
||||
Collectibles []CollectibleHeader `json:"collectibles"`
|
||||
Offset int `json:"offset"`
|
||||
// Used to indicate that there might be more collectibles that were not returned
|
||||
// based on a simple heuristic
|
||||
HasMore bool `json:"hasMore"`
|
||||
OwnershipStatus OwnershipStatusPerAddressAndChainID `json:"ownershipStatus"`
|
||||
ErrorCode ErrorCode `json:"errorCode"`
|
||||
}
|
||||
|
||||
|
@ -101,6 +118,7 @@ type GetCollectiblesDetailsResponse struct {
|
|||
type filterOwnedCollectiblesTaskReturnType struct {
|
||||
collectibles []CollectibleHeader
|
||||
hasMore bool
|
||||
ownershipStatus OwnershipStatusPerAddressAndChainID
|
||||
}
|
||||
|
||||
// FilterOwnedCollectiblesResponse allows only one filter task to run at a time
|
||||
|
@ -116,10 +134,15 @@ func (s *Service) FilterOwnedCollectiblesAsync(requestID int32, chainIDs []walle
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ownershipStatus, err := s.GetOwnershipStatus(chainIDs, addresses)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return filterOwnedCollectiblesTaskReturnType{
|
||||
collectibles: fullCollectiblesDataToHeaders(data),
|
||||
hasMore: hasMore,
|
||||
ownershipStatus: ownershipStatus,
|
||||
}, err
|
||||
}, func(result interface{}, taskType async.TaskType, err error) {
|
||||
res := FilterOwnedCollectiblesResponse{
|
||||
|
@ -133,6 +156,7 @@ func (s *Service) FilterOwnedCollectiblesAsync(requestID int32, chainIDs []walle
|
|||
res.Collectibles = fnRet.collectibles
|
||||
res.Offset = offset
|
||||
res.HasMore = fnRet.hasMore
|
||||
res.OwnershipStatus = fnRet.ownershipStatus
|
||||
res.ErrorCode = ErrorCodeSuccess
|
||||
}
|
||||
|
||||
|
@ -355,3 +379,26 @@ func (s *Service) GetOwnedCollectibles(chainIDs []walletCommon.ChainID, owners [
|
|||
func (s *Service) GetOwnedCollectible(chainID walletCommon.ChainID, owner common.Address, contractAddress common.Address, tokenID *big.Int) (*thirdparty.CollectibleUniqueID, error) {
|
||||
return s.ownershipDB.GetOwnedCollectible(chainID, owner, contractAddress, tokenID)
|
||||
}
|
||||
|
||||
func (s *Service) GetOwnershipStatus(chainIDs []walletCommon.ChainID, owners []common.Address) (OwnershipStatusPerAddressAndChainID, error) {
|
||||
ret := make(OwnershipStatusPerAddressAndChainID)
|
||||
for _, address := range owners {
|
||||
ret[address] = make(OwnershipStatusPerChainID)
|
||||
for _, chainID := range chainIDs {
|
||||
timestamp, err := s.ownershipDB.GetOwnershipUpdateTimestamp(address, chainID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
state := OwnershipStateIdle
|
||||
if s.commands[address] != nil && s.commands[address][chainID] != nil {
|
||||
state = s.commands[address][chainID].GetState()
|
||||
}
|
||||
ret[address][chainID] = OwnershipStatus{
|
||||
State: state,
|
||||
Timestamp: timestamp,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret, nil
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue