feat: add balance to collectibles api

This commit is contained in:
Dario Gabriel Lipicar 2023-12-18 10:16:31 -03:00 committed by dlipicar
parent 88fd1ce942
commit b1e000ed59
9 changed files with 267 additions and 50 deletions

View File

@ -3,6 +3,7 @@ package collectibles
import (
"context"
"errors"
"math/big"
"sync/atomic"
"time"
@ -10,6 +11,7 @@ import (
"github.com/ethereum/go-ethereum/event"
"github.com/ethereum/go-ethereum/log"
"github.com/status-im/status-go/services/wallet/async"
"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/thirdparty"
"github.com/status-im/status-go/services/wallet/walletevent"
@ -181,6 +183,18 @@ func (c *loadOwnedCollectiblesCommand) triggerEvent(eventType walletevent.EventT
})
}
func ownedTokensToTokenBalancesPerContractAddress(ownership []thirdparty.CollectibleUniqueID) thirdparty.TokenBalancesPerContractAddress {
ret := make(thirdparty.TokenBalancesPerContractAddress)
for _, id := range ownership {
balance := thirdparty.TokenBalance{
TokenID: id.TokenID,
Balance: &bigint.BigInt{Int: big.NewInt(1)},
}
ret[id.ContractID.Address] = append(ret[id.ContractID.Address], balance)
}
return ret
}
func (c *loadOwnedCollectiblesCommand) Run(parent context.Context) (err error) {
log.Debug("start loadOwnedCollectiblesCommand", "chain", c.chainID, "account", c.account)
@ -233,7 +247,12 @@ func (c *loadOwnedCollectiblesCommand) Run(parent context.Context) (err error) {
return err
}
err = c.ownershipDB.Update(c.chainID, c.account, c.partialOwnership, start.Unix())
// Token balances should come from the providers. For now we assume all balances are 1, which
// is only valid for ERC721.
// TODO (#13025): Fetch balances from the providers.
balances := ownedTokensToTokenBalancesPerContractAddress(c.partialOwnership)
err = c.ownershipDB.Update(c.chainID, c.account, balances, start.Unix())
if err != nil {
log.Error("failed updating ownershipDB in loadOwnedCollectiblesCommand", "chain", c.chainID, "account", c.account, "error", err)
c.err = err

View File

@ -3,11 +3,13 @@ package collectibles
import (
"context"
"database/sql"
"math/big"
"testing"
"github.com/ethereum/go-ethereum/common"
"github.com/status-im/status-go/protocol/communities/token"
"github.com/status-im/status-go/services/wallet/bigint"
w_common "github.com/status-im/status-go/services/wallet/common"
"github.com/status-im/status-go/services/wallet/thirdparty"
"github.com/status-im/status-go/t/helpers"
@ -45,7 +47,7 @@ func TestFilterOwnedCollectibles(t *testing.T) {
dataPerID := make(map[string]thirdparty.CollectibleData)
communityDataPerID := make(map[string]thirdparty.CollectibleCommunityInfo)
idsPerChainIDAndOwner := make(map[w_common.ChainID]map[common.Address][]thirdparty.CollectibleUniqueID)
balancesPerChainIDAndOwner := make(map[w_common.ChainID]map[common.Address]thirdparty.TokenBalancesPerContractAddress)
var err error
@ -56,21 +58,30 @@ func TestFilterOwnedCollectibles(t *testing.T) {
chainID := data[i].ID.ContractID.ChainID
ownerAddress := ownerAddresses[i%len(ownerAddresses)]
if _, ok := idsPerChainIDAndOwner[chainID]; !ok {
idsPerChainIDAndOwner[chainID] = make(map[common.Address][]thirdparty.CollectibleUniqueID)
if _, ok := balancesPerChainIDAndOwner[chainID]; !ok {
balancesPerChainIDAndOwner[chainID] = make(map[common.Address]thirdparty.TokenBalancesPerContractAddress)
}
if _, ok := idsPerChainIDAndOwner[chainID][ownerAddress]; !ok {
idsPerChainIDAndOwner[chainID][ownerAddress] = make([]thirdparty.CollectibleUniqueID, 0, len(data))
if _, ok := balancesPerChainIDAndOwner[chainID][ownerAddress]; !ok {
balancesPerChainIDAndOwner[chainID][ownerAddress] = make(thirdparty.TokenBalancesPerContractAddress)
}
idsPerChainIDAndOwner[chainID][ownerAddress] = append(idsPerChainIDAndOwner[chainID][ownerAddress], data[i].ID)
contractAddress := data[i].ID.ContractID.Address
if _, ok := balancesPerChainIDAndOwner[chainID][ownerAddress][contractAddress]; !ok {
balancesPerChainIDAndOwner[chainID][ownerAddress][contractAddress] = make([]thirdparty.TokenBalance, 0, len(data))
}
tokenBalance := thirdparty.TokenBalance{
TokenID: data[i].ID.TokenID,
Balance: &bigint.BigInt{Int: big.NewInt(int64(i % 10))},
}
balancesPerChainIDAndOwner[chainID][ownerAddress][contractAddress] = append(balancesPerChainIDAndOwner[chainID][ownerAddress][contractAddress], tokenBalance)
}
timestamp := int64(1234567890)
for chainID, idsPerOwner := range idsPerChainIDAndOwner {
for ownerAddress, ids := range idsPerOwner {
err = oDB.Update(chainID, ownerAddress, ids, timestamp)
for chainID, balancesPerOwner := range balancesPerChainIDAndOwner {
for ownerAddress, balances := range balancesPerOwner {
err = oDB.Update(chainID, ownerAddress, balances, timestamp)
require.NoError(t, err)
}
}

View File

@ -28,8 +28,9 @@ func NewOwnershipDB(sqlDb *sql.DB) *OwnershipDB {
}
}
const ownershipColumns = "chain_id, contract_address, token_id, owner_address"
const ownershipColumns = "chain_id, contract_address, token_id, owner_address, balance"
const selectOwnershipColumns = "chain_id, contract_address, token_id"
const selectAccountBalancesColumns = "owner_address, balance"
const ownershipTimestampColumns = "owner_address, chain_id, timestamp"
const selectOwnershipTimestampColumns = "timestamp"
@ -48,17 +49,19 @@ func removeAddressOwnership(creator sqlite.StatementCreator, chainID w_common.Ch
return nil
}
func insertAddressOwnership(creator sqlite.StatementCreator, ownerAddress common.Address, collectibles []thirdparty.CollectibleUniqueID) error {
func insertAddressOwnership(creator sqlite.StatementCreator, chainID w_common.ChainID, ownerAddress common.Address, balancesPerContractAdddress thirdparty.TokenBalancesPerContractAddress) error {
insertOwnership, err := creator.Prepare(fmt.Sprintf(`INSERT INTO collectibles_ownership_cache (%s)
VALUES (?, ?, ?, ?)`, ownershipColumns))
VALUES (?, ?, ?, ?, ?)`, ownershipColumns))
if err != nil {
return err
}
for _, c := range collectibles {
_, err = insertOwnership.Exec(c.ContractID.ChainID, c.ContractID.Address, (*bigint.SQLBigIntBytes)(c.TokenID.Int), ownerAddress)
if err != nil {
return err
for contractAddress, balances := range balancesPerContractAdddress {
for _, balance := range balances {
_, err = insertOwnership.Exec(chainID, contractAddress, (*bigint.SQLBigIntBytes)(balance.TokenID.Int), ownerAddress, (*bigint.SQLBigIntBytes)(balance.Balance.Int))
if err != nil {
return err
}
}
}
@ -113,7 +116,7 @@ func (o *OwnershipDB) GetIDsNotInDB(
return ret, nil
}
func (o *OwnershipDB) Update(chainID w_common.ChainID, ownerAddress common.Address, collectibles []thirdparty.CollectibleUniqueID, timestamp int64) (err error) {
func (o *OwnershipDB) Update(chainID w_common.ChainID, ownerAddress common.Address, balances thirdparty.TokenBalancesPerContractAddress, timestamp int64) (err error) {
var (
tx *sql.Tx
)
@ -136,7 +139,7 @@ func (o *OwnershipDB) Update(chainID w_common.ChainID, ownerAddress common.Addre
}
// Insert new ownership data
err = insertAddressOwnership(tx, ownerAddress, collectibles)
err = insertAddressOwnership(tx, chainID, ownerAddress, balances)
if err != nil {
return err
}
@ -252,3 +255,39 @@ func (o *OwnershipDB) GetLatestOwnershipUpdateTimestamp(chainID walletCommon.Cha
return InvalidTimestamp, nil
}
func (o *OwnershipDB) GetOwnership(id thirdparty.CollectibleUniqueID) ([]thirdparty.AccountBalance, error) {
query := fmt.Sprintf(`SELECT %s
FROM collectibles_ownership_cache
WHERE chain_id = ? AND contract_address = ? AND token_id = ?`, selectAccountBalancesColumns)
stmt, err := o.db.Prepare(query)
if err != nil {
return nil, err
}
defer stmt.Close()
rows, err := stmt.Query(id.ContractID.ChainID, id.ContractID.Address, (*bigint.SQLBigIntBytes)(id.TokenID.Int))
if err != nil {
return nil, err
}
defer rows.Close()
var ret []thirdparty.AccountBalance
for rows.Next() {
accountBalance := thirdparty.AccountBalance{
Balance: &bigint.BigInt{Int: big.NewInt(0)},
}
err = rows.Scan(
&accountBalance.Address,
(*bigint.SQLBigIntBytes)(accountBalance.Balance.Int),
)
if err != nil {
return nil, err
}
ret = append(ret, accountBalance)
}
return ret, nil
}

View File

@ -23,18 +23,33 @@ func setupOwnershipDBTest(t *testing.T) (*OwnershipDB, func()) {
}
}
func generateTestCollectibles(chainID w_common.ChainID, offset int, count int) (result []thirdparty.CollectibleUniqueID) {
result = make([]thirdparty.CollectibleUniqueID, 0, count)
func generateTestCollectibles(offset int, count int) (result thirdparty.TokenBalancesPerContractAddress) {
result = make(thirdparty.TokenBalancesPerContractAddress)
for i := offset; i < offset+count; i++ {
bigI := big.NewInt(int64(i))
newCollectible := thirdparty.CollectibleUniqueID{
ContractID: thirdparty.ContractID{
ChainID: chainID,
Address: common.BigToAddress(bigI),
},
TokenID: &bigint.BigInt{Int: bigI},
contractAddress := common.BigToAddress(big.NewInt(int64(i % 10)))
tokenID := &bigint.BigInt{Int: big.NewInt(int64(i))}
result[contractAddress] = append(result[contractAddress], thirdparty.TokenBalance{
TokenID: tokenID,
Balance: &bigint.BigInt{Int: big.NewInt(int64(i%5 + 1))},
})
}
return result
}
func testCollectiblesToList(chainID w_common.ChainID, balances thirdparty.TokenBalancesPerContractAddress) (result []thirdparty.CollectibleUniqueID) {
result = make([]thirdparty.CollectibleUniqueID, 0, len(balances))
for contractAddress, balances := range balances {
for _, balance := range balances {
newCollectible := thirdparty.CollectibleUniqueID{
ContractID: thirdparty.ContractID{
ChainID: chainID,
Address: contractAddress,
},
TokenID: balance.TokenID,
}
result = append(result, newCollectible)
}
result = append(result, newCollectible)
}
return result
}
@ -48,23 +63,51 @@ func TestUpdateOwnership(t *testing.T) {
chainID2 := w_common.ChainID(2)
ownerAddress1 := common.HexToAddress("0x1234")
ownedListChain0 := generateTestCollectibles(chainID0, 0, 10)
ownedBalancesChain0 := generateTestCollectibles(0, 10)
ownedListChain0 := testCollectiblesToList(chainID0, ownedBalancesChain0)
timestampChain0 := int64(1234567890)
ownedListChain1 := generateTestCollectibles(chainID1, 0, 15)
ownedBalancesChain1 := generateTestCollectibles(0, 15)
ownedListChain1 := testCollectiblesToList(chainID1, ownedBalancesChain1)
timestampChain1 := int64(1234567891)
ownedList1 := append(ownedListChain0, ownedListChain1...)
ownerAddress2 := common.HexToAddress("0x5678")
ownedListChain2 := generateTestCollectibles(chainID2, 0, 20)
ownedBalancesChain2 := generateTestCollectibles(0, 20)
ownedListChain2 := testCollectiblesToList(chainID2, ownedBalancesChain2)
timestampChain2 := int64(1234567892)
ownedList2 := ownedListChain2
ownerAddress3 := common.HexToAddress("0xABCD")
ownedListChain1b := generateTestCollectibles(chainID1, len(ownedListChain1), 5)
ownedBalancesChain1b := generateTestCollectibles(len(ownedListChain1), 5)
ownedListChain1b := testCollectiblesToList(chainID1, ownedBalancesChain1b)
timestampChain1b := timestampChain1 - 100
ownedListChain2b := generateTestCollectibles(chainID2, len(ownedListChain2), 20)
ownedBalancesChain2b := generateTestCollectibles(len(ownedListChain2), 20)
// Add one collectible that is already owned by ownerAddress2
commonChainID := chainID2
var commonContractAddress common.Address
var commonTokenID *bigint.BigInt
var commonBalanceAddress2 *bigint.BigInt
commonBalanceAddress3 := &bigint.BigInt{Int: big.NewInt(5)}
for contractAddress, balances := range ownedBalancesChain2 {
for _, balance := range balances {
commonContractAddress = contractAddress
commonTokenID = balance.TokenID
commonBalanceAddress2 = balance.Balance
newBalance := thirdparty.TokenBalance{
TokenID: commonTokenID,
Balance: commonBalanceAddress3,
}
ownedBalancesChain2b[commonContractAddress] = append(ownedBalancesChain2b[commonContractAddress], newBalance)
break
}
break
}
ownedListChain2b := testCollectiblesToList(chainID2, ownedBalancesChain2b)
timestampChain2b := timestampChain2 + 100
ownedList3 := append(ownedListChain1b, ownedListChain2b...)
@ -105,7 +148,7 @@ func TestUpdateOwnership(t *testing.T) {
require.NoError(t, err)
require.Equal(t, InvalidTimestamp, loadedTimestamp)
err = oDB.Update(chainID0, ownerAddress1, ownedListChain0, timestampChain0)
err = oDB.Update(chainID0, ownerAddress1, ownedBalancesChain0, timestampChain0)
require.NoError(t, err)
loadedTimestamp, err = oDB.GetOwnershipUpdateTimestamp(ownerAddress1, chainID0)
@ -132,16 +175,16 @@ func TestUpdateOwnership(t *testing.T) {
require.NoError(t, err)
require.Equal(t, InvalidTimestamp, loadedTimestamp)
err = oDB.Update(chainID1, ownerAddress1, ownedListChain1, timestampChain1)
err = oDB.Update(chainID1, ownerAddress1, ownedBalancesChain1, timestampChain1)
require.NoError(t, err)
err = oDB.Update(chainID2, ownerAddress2, ownedListChain2, timestampChain2)
err = oDB.Update(chainID2, ownerAddress2, ownedBalancesChain2, timestampChain2)
require.NoError(t, err)
err = oDB.Update(chainID1, ownerAddress3, ownedListChain1b, timestampChain1b)
err = oDB.Update(chainID1, ownerAddress3, ownedBalancesChain1b, timestampChain1b)
require.NoError(t, err)
err = oDB.Update(chainID2, ownerAddress3, ownedListChain2b, timestampChain2b)
err = oDB.Update(chainID2, ownerAddress3, ownedBalancesChain2b, timestampChain2b)
require.NoError(t, err)
loadedTimestamp, err = oDB.GetOwnershipUpdateTimestamp(ownerAddress1, chainID0)
@ -178,15 +221,15 @@ func TestUpdateOwnership(t *testing.T) {
loadedList, err = oDB.GetOwnedCollectibles([]w_common.ChainID{chainID0}, []common.Address{ownerAddress1}, 0, len(allCollectibles))
require.NoError(t, err)
require.Equal(t, ownedListChain0, loadedList)
require.ElementsMatch(t, ownedListChain0, loadedList)
loadedList, err = oDB.GetOwnedCollectibles([]w_common.ChainID{chainID0, chainID1}, []common.Address{ownerAddress1, randomAddress}, 0, len(allCollectibles))
require.NoError(t, err)
require.Equal(t, ownedList1, loadedList)
require.ElementsMatch(t, ownedList1, loadedList)
loadedList, err = oDB.GetOwnedCollectibles([]w_common.ChainID{chainID2}, []common.Address{ownerAddress2}, 0, len(allCollectibles))
require.NoError(t, err)
require.Equal(t, ownedList2, loadedList)
require.ElementsMatch(t, ownedList2, loadedList)
loadedList, err = oDB.GetOwnedCollectibles(allChains, allOwnerAddresses, 0, len(allCollectibles))
require.NoError(t, err)
@ -195,6 +238,43 @@ func TestUpdateOwnership(t *testing.T) {
loadedList, err = oDB.GetOwnedCollectibles([]w_common.ChainID{chainID0}, []common.Address{randomAddress}, 0, len(allCollectibles))
require.NoError(t, err)
require.Empty(t, loadedList)
// Test GetOwnership for common token
commonID := thirdparty.CollectibleUniqueID{
ContractID: thirdparty.ContractID{
ChainID: commonChainID,
Address: commonContractAddress,
},
TokenID: commonTokenID,
}
loadedOwnership, err := oDB.GetOwnership(commonID)
require.NoError(t, err)
expectedOwnership := []thirdparty.AccountBalance{
{
Address: ownerAddress2,
Balance: commonBalanceAddress2,
},
{
Address: ownerAddress3,
Balance: commonBalanceAddress3,
},
}
require.ElementsMatch(t, expectedOwnership, loadedOwnership)
// Test GetOwnership for random token
randomID := thirdparty.CollectibleUniqueID{
ContractID: thirdparty.ContractID{
ChainID: 0xABCDEF,
Address: common.BigToAddress(big.NewInt(int64(123456789))),
},
TokenID: &bigint.BigInt{Int: big.NewInt(int64(987654321))},
}
loadedOwnership, err = oDB.GetOwnership(randomID)
require.NoError(t, err)
require.Empty(t, loadedOwnership)
}
func TestLargeTokenID(t *testing.T) {
@ -203,14 +283,24 @@ func TestLargeTokenID(t *testing.T) {
ownerAddress := common.HexToAddress("0xABCD")
chainID := w_common.ChainID(0)
contractAddress := common.HexToAddress("0x1234")
tokenID := &bigint.BigInt{Int: big.NewInt(0).SetBytes([]byte("0x1234567890123456789012345678901234567890"))}
balance := &bigint.BigInt{Int: big.NewInt(100)}
ownedListChain := []thirdparty.CollectibleUniqueID{
{
ContractID: thirdparty.ContractID{
ChainID: chainID,
Address: common.HexToAddress("0x1234"),
ownedBalancesChain := thirdparty.TokenBalancesPerContractAddress{
contractAddress: []thirdparty.TokenBalance{
{
TokenID: tokenID,
Balance: balance,
},
TokenID: &bigint.BigInt{Int: big.NewInt(0).SetBytes([]byte("0x1234567890123456789012345678901234567890"))},
},
}
ownedListChain := testCollectiblesToList(chainID, ownedBalancesChain)
ownership := []thirdparty.AccountBalance{
{
Address: ownerAddress,
Balance: balance,
},
}
@ -218,10 +308,22 @@ func TestLargeTokenID(t *testing.T) {
var err error
err = oDB.Update(chainID, ownerAddress, ownedListChain, timestamp)
err = oDB.Update(chainID, ownerAddress, ownedBalancesChain, timestamp)
require.NoError(t, err)
loadedList, err := oDB.GetOwnedCollectibles([]w_common.ChainID{chainID}, []common.Address{ownerAddress}, 0, len(ownedListChain))
require.NoError(t, err)
require.Equal(t, ownedListChain, loadedList)
// Test GetOwnership
id := thirdparty.CollectibleUniqueID{
ContractID: thirdparty.ContractID{
ChainID: chainID,
Address: contractAddress,
},
TokenID: tokenID,
}
loadedOwnership, err := oDB.GetOwnership(id)
require.NoError(t, err)
require.Equal(t, ownership, loadedOwnership)
}

View File

@ -413,6 +413,12 @@ func (s *Service) fullCollectiblesDataToHeaders(data []thirdparty.FullCollectibl
for _, c := range data {
header := fullCollectibleDataToHeader(c)
ownership, err := s.ownershipDB.GetOwnership(c.CollectibleData.ID)
if err != nil {
return nil, err
}
header.Ownership = ownership
if c.CollectibleData.CommunityID != "" {
communityInfo, _, err := s.communityManager.GetCommunityInfo(c.CollectibleData.CommunityID)
if err != nil {
@ -435,6 +441,12 @@ func (s *Service) fullCollectiblesDataToDetails(data []thirdparty.FullCollectibl
for _, c := range data {
details := fullCollectibleDataToDetails(c)
ownership, err := s.ownershipDB.GetOwnership(c.CollectibleData.ID)
if err != nil {
return nil, err
}
details.Ownership = ownership
if c.CollectibleData.CommunityID != "" {
communityInfo, _, err := s.communityManager.GetCommunityInfo(c.CollectibleData.CommunityID)
if err != nil {

View File

@ -12,6 +12,7 @@ type Collectible struct {
CollectibleData *CollectibleData `json:"collectible_data,omitempty"`
CollectionData *CollectionData `json:"collection_data,omitempty"`
CommunityData *CommunityData `json:"community_data,omitempty"`
Ownership []thirdparty.AccountBalance `json:"ownership,omitempty"`
}
type CollectibleData struct {

View File

@ -198,6 +198,11 @@ type CollectibleContractOwnership struct {
Owners []CollectibleOwner `json:"owners"`
}
type AccountBalance struct {
Address common.Address `json:"address"`
Balance *bigint.BigInt `json:"balance"`
}
type CollectibleContractOwnershipProvider interface {
CollectibleProvider
FetchCollectibleOwnersByContractAddress(ctx context.Context, chainID w_common.ChainID, contractAddress common.Address) (*CollectibleContractOwnership, error)

View File

@ -15,6 +15,7 @@
// 1701101493_add_token_blocks_range.up.sql (469B)
// 1702467441_wallet_connect_sessions_instead_of_pairings.up.sql (356B)
// 1702577524_add_community_collections_and_collectibles_images_cache.up.sql (210B)
// 1702867707_add_balance_to_collectibles_ownership_cache.up.sql (289B)
// doc.go (74B)
package migrations
@ -378,11 +379,31 @@ func _1702577524_add_community_collections_and_collectibles_images_cacheUpSql()
return nil, err
}
info := bindataFileInfo{name: "1702577524_add_community_collections_and_collectibles_images_cache.up.sql", size: 210, mode: os.FileMode(0644), modTime: time.Unix(1702580163, 0)}
info := bindataFileInfo{name: "1702577524_add_community_collections_and_collectibles_images_cache.up.sql", size: 210, mode: os.FileMode(0644), modTime: time.Unix(1702866853, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x8e, 0x1b, 0x32, 0x2c, 0xfa, 0x11, 0x5e, 0x5e, 0x5d, 0xef, 0x92, 0xa0, 0x29, 0x52, 0xbf, 0x6e, 0xe3, 0x30, 0xe4, 0xdf, 0xdc, 0x5, 0xbe, 0xd1, 0xf8, 0x3e, 0xd9, 0x9b, 0xd6, 0x9b, 0x95, 0x96}}
return a, nil
}
var __1702867707_add_balance_to_collectibles_ownership_cacheUpSql = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x84\x8d\x31\x4b\xc4\x30\x18\x40\xf7\xfe\x8a\x6f\x3b\x85\x1b\x74\x3e\x1c\xd2\x4b\x0e\x0a\x31\x91\x36\x81\x6e\x21\xfd\xfa\x49\x83\x21\x91\x24\xa0\x3f\x5f\xea\x50\x5c\xd4\xf9\xf1\xde\x63\xd2\x88\x11\x0c\xeb\xa5\x00\xcc\x31\x12\xb6\xb0\x44\xaa\x2e\x7f\x24\x2a\x75\x0b\xef\x0e\x3d\x6e\x04\x8c\x73\xb8\x6a\x69\x9f\x15\x2c\x3e\xfa\x84\x04\xbd\xd4\x3d\x28\x6d\x40\x59\x29\x81\x8b\x1b\xb3\xd2\xc0\xe7\xe9\xe1\xf1\x74\xe9\x3a\xfb\xc2\x99\xf9\x27\x3a\x09\x73\xd4\x9e\x0e\xf3\x3a\x8a\xdd\x1c\x14\x17\x33\x0c\xb7\xef\x85\x98\x87\xc9\x4c\xbf\xd5\x5e\x43\x6c\x54\xdc\x0f\x0a\x5a\xfd\xbd\xbe\xc3\xcd\x87\xe4\xc2\x7a\x06\xcc\xa9\x15\x8f\xcd\xf9\x75\x2d\x54\xeb\x19\x5a\x7e\xa3\x9d\xdd\x5f\xba\xaf\x00\x00\x00\xff\xff\x19\x3b\x1b\x24\x21\x01\x00\x00")
func _1702867707_add_balance_to_collectibles_ownership_cacheUpSqlBytes() ([]byte, error) {
return bindataRead(
__1702867707_add_balance_to_collectibles_ownership_cacheUpSql,
"1702867707_add_balance_to_collectibles_ownership_cache.up.sql",
)
}
func _1702867707_add_balance_to_collectibles_ownership_cacheUpSql() (*asset, error) {
bytes, err := _1702867707_add_balance_to_collectibles_ownership_cacheUpSqlBytes()
if err != nil {
return nil, err
}
info := bindataFileInfo{name: "1702867707_add_balance_to_collectibles_ownership_cache.up.sql", size: 289, mode: os.FileMode(0644), modTime: time.Unix(1702904956, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x6f, 0x63, 0x30, 0x11, 0x22, 0xb9, 0xee, 0xae, 0xb8, 0xc4, 0xe6, 0xd3, 0x7, 0xc, 0xe6, 0xa3, 0x72, 0x8c, 0x6, 0x9d, 0x6c, 0x97, 0x8f, 0xb2, 0xd0, 0x37, 0x69, 0x69, 0x6, 0x7f, 0x67, 0x94}}
return a, nil
}
var _docGo = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x2c\xc9\xb1\x0d\xc4\x20\x0c\x05\xd0\x9e\x29\xfe\x02\xd8\xfd\x6d\xe3\x4b\xac\x2f\x44\x82\x09\x78\x7f\xa5\x49\xfd\xa6\x1d\xdd\xe8\xd8\xcf\x55\x8a\x2a\xe3\x47\x1f\xbe\x2c\x1d\x8c\xfa\x6f\xe3\xb4\x34\xd4\xd9\x89\xbb\x71\x59\xb6\x18\x1b\x35\x20\xa2\x9f\x0a\x03\xa2\xe5\x0d\x00\x00\xff\xff\x60\xcd\x06\xbe\x4a\x00\x00\x00")
func docGoBytes() ([]byte, error) {
@ -509,6 +530,7 @@ var _bindata = map[string]func() (*asset, error){
"1701101493_add_token_blocks_range.up.sql": _1701101493_add_token_blocks_rangeUpSql,
"1702467441_wallet_connect_sessions_instead_of_pairings.up.sql": _1702467441_wallet_connect_sessions_instead_of_pairingsUpSql,
"1702577524_add_community_collections_and_collectibles_images_cache.up.sql": _1702577524_add_community_collections_and_collectibles_images_cacheUpSql,
"1702867707_add_balance_to_collectibles_ownership_cache.up.sql": _1702867707_add_balance_to_collectibles_ownership_cacheUpSql,
"doc.go": docGo,
}
@ -573,6 +595,7 @@ var _bintree = &bintree{nil, map[string]*bintree{
"1701101493_add_token_blocks_range.up.sql": {_1701101493_add_token_blocks_rangeUpSql, map[string]*bintree{}},
"1702467441_wallet_connect_sessions_instead_of_pairings.up.sql": {_1702467441_wallet_connect_sessions_instead_of_pairingsUpSql, map[string]*bintree{}},
"1702577524_add_community_collections_and_collectibles_images_cache.up.sql": {_1702577524_add_community_collections_and_collectibles_images_cacheUpSql, map[string]*bintree{}},
"1702867707_add_balance_to_collectibles_ownership_cache.up.sql": {_1702867707_add_balance_to_collectibles_ownership_cacheUpSql, map[string]*bintree{}},
"doc.go": {docGo, map[string]*bintree{}},
}}

View File

@ -0,0 +1,5 @@
ALTER TABLE collectibles_ownership_cache ADD COLUMN balance BLOB NOT NULL DEFAULT x'01';
UPDATE collectibles_ownership_cache SET balance = x'01';
CREATE INDEX IF NOT EXISTS collectibles_ownership_filter_collectible ON collectibles_ownership_cache (chain_id, contract_address, token_id);