This section provides you with the tools to efficiently manage and retrieve collectibles data. Here’s a brief overview of what you’ll find:
- Basic Filtering: Filter collectibles based on ownership and collection criteria, allowing you to retrieve items owned by specific users or belonging to particular collections.
- Comparative Filtering: Advanced filtering techniques, including direct equal comparisons, property existence filter queries, and text searches, to narrow down your results more precisely.
- Pagination: Handle large datasets effectively by implementing pagination, ensuring a smooth and responsive user experience even when dealing with extensive amounts of collectibles data.
Basic Filtering
Filter Collectibles owned by a user and collection
Retrieve collectibles owned by a user
Properties
addresses (optional)
A list of addresses used to query assets.
e.g.
[
"0x1213486Ea42bB6EA45bC7434389dA3239738B0E2",
"0xFffFffff00000000000000000000000000000226"
]
collectionIds (optional)
A list of collection IDs to filter assets on the addresses provided.
e.g.
[
"7672:root:1234",
"7672:root:2341",
]
Since both the above properties are optional you can use the independently or together based on the use case. For example filtering using addresses
and collectionIds
will return all the collectibles in the specified collections owned by the addresses.
import React from 'react'
import { useAccount } from 'wagmi'
import { ChainAddress } from '@futureverse/asset-register/types'
import { useAssets } from '@futureverse/asset-register-react/v2'
import { useFuturePassAccountAddress } from '@futureverse/react'
// React component to render all collectibles owned by a FuturePass user logged in.
export const AssetList = () => {
// Get EOA address
const { address } = useAccount()
// Get FV address
const { data: fpAccount } = useFuturePassAccountAddress()
const {
assets
} = useAssets(
{
first: 1000,
addresses: [address as ChainAddress, fpAccount as ChainAddress],
},
{ enabled: !!fpAccount && !!address },
)
if (!assets) {
return null
}
return (
<div>
{assets.map((asset) => <Asset key={asset.id} asset={asset} />)}
</div>
)
}
import React from 'react'
import { useAccount } from 'wagmi'
import { ChainAddress } from '@futureverse/asset-register/types'
import { useAssets } from '@futureverse/asset-register-react/v2'
import { useFuturePassAccountAddress } from '@futureverse/react'
// React component to render all collectibles owned by a FuturePass user logged in.
export const AssetList = () => {
// Get EOA address
const { address } = useAccount()
// Get FV address
const { data: fpAccount } = useFuturePassAccountAddress()
const {
assets
} = useAssets(
{
first: 1000,
addresses: [address as ChainAddress, fpAccount as ChainAddress],
},
{ enabled: !!fpAccount && !!address },
)
if (!assets) {
return null
}
return (
<div>
{assets.map((asset) => <Asset key={asset.id} asset={asset} />)}
</div>
)
}
import { AssetRegister } from '@futureverse/asset-register'
import { AssetsModel } from '@futureverse/asset-register/models';
const ar = new AssetRegister({
...
})
const assets = await ar.assets({
addresses: [
"0x2D2438C6281B5115733287fC279f854c868D3ee2",
"0xFFFFFfFF00000000000000000000000000000417"
],
collectionIds: [
"7672:root:1234",
"7672:root:2341",
]
}).execute()[0] as AssetsModel
query GetAssets($addresses: [ChainAddress!]!, $collectionIds: [CollectionId!], $after: String, $first: Float) {
assets(
addresses: $addresses
collectionIds: $collectionIds
after: $after
first: $first
) {
pageInfo {
endCursor
hasNextPage
}
edges {
node {
id
collectionId
tokenId
assetType
assetTree {
data
nodeId
}
schema {
name
namespace
schema
version
}
ownership {
__typename
... on SFTAssetOwnership {
id
balancesOf(addresses: $addresses) {
balance
owner {
address
}
}
}
... on NFTAssetOwnership {
owner {
address
}
}
}
metadata {
attributes
properties
uri
}
links {
__typename
... on SFTAssetLink {
parentLinks(addresses: $addresses) {
collectionId
tokenId
}
}
... on NFTAssetLink {
parentLink {
collectionId
tokenId
}
}
}
collection {
id
chainId
chainType
location
name
}
}
}
}
}
{
"first": 1000,
"addresses": [
"0x2D2438C6281B5115733287fC279f854c868D3ee2",
"0xFFFFFfFF00000000000000000000000000000417"
]
}
Comparative Filtering
In addition to address and collection-based filtering, further filtering can be done using a direct equal comparison of values, values that fit in a specified range or even a direct text search.
Filter Types
Equal
The name
property is used to target the correct item to filter. The equal filter must take a string property as the value, even if the targeted property is a number.
"eqFilters":[{
"name":"Fur Colour",
"value":"Freedom"
}]
Has
The has
filter simply filters assets based on the existence of a specific property or attribute in their metadata during querying.
"hasFilters": ["description"],
Search
The search filter simply takes a string value to search across all the properties and attributes in the metadata.
Filter Targeting
We don’t need to specify whether the target is an attribute or a property; the filter function handles this automatically.
By traits (aliased as attributes)
Filter through the attributes
e.g. Fur Colour
, Age
By properties
Filter through properties on the metadata
e.g. properties.name
An example of a filter expression will look like the following for the above trait and property filters when put together:
{
"eqFilters":[
{
"name":"Fur Colour",
"value":"Freedom"
},
{
"name":"name",
"value":"Bob"
}
],
"hasFilters":[
"age"
]
}
import React from 'react'
import { useAccount } from 'wagmi'
import { ChainAddress } from '@fv-asset-registry/common'
import { useAssets } from '@futureverse/asset-register-react'
import { useFuturePassAccountAddress } from '@futureverse/react'
// React component to render all collectibles owned by a FuturePass user logged in.
export const AssetList = () => {
// Get EOA address
const { address } = useAccount()
// Get FV address
const { data: fpAccount } = useFuturePassAccountAddress()
const {
assets
} = useAssets(
{
first: 1000,
addresses: [address as ChainAddress, fpAccount as ChainAddress],
filter: {
eqFilters: [
{
name: "Fur Colour",
value: "Freedom"
}
],
hasFilters: [
"age"
],
search: "Blue"
}
},
{ enabled: !!fpAccount && !!address },
)
if (!assets) {
return null
}
return (
<div>
{assets.map((asset) => <Asset key={asset.id} asset={asset} />)}
</div>
)
import React from 'react'
import { useAccount } from 'wagmi'
import { ChainAddress } from '@fv-asset-registry/common'
import { useAssets } from '@futureverse/asset-register-react'
import { useFuturePassAccountAddress } from '@futureverse/react'
// React component to render all collectibles owned by a FuturePass user logged in.
export const AssetList = () => {
// Get EOA address
const { address } = useAccount()
// Get FV address
const { data: fpAccount } = useFuturePassAccountAddress()
const {
assets
} = useAssets(
{
first: 1000,
addresses: [address as ChainAddress, fpAccount as ChainAddress],
filter: {
eqFilters: [
{
name: "Fur Colour",
value: "Freedom"
}
],
hasFilters: [
"age"
],
search: "Blue"
}
},
{ enabled: !!fpAccount && !!address },
)
if (!assets) {
return null
}
return (
<div>
{assets.map((asset) => <Asset key={asset.id} asset={asset} />)}
</div>
)
import { AssetRegister } from '@futureverse/asset-register'
const ar = new AssetRegister({
...
})
const assets = await ar.assets({
addresses: [
"0x2D2438C6281B5115733287fC279f854c868D3ee2",
"0xFFFFFfFF00000000000000000000000000000417"
],
collectionIds: [
"7672:root:1234",
"7672:root:2341",
],
filter: {
eqFilters: [
{
name: "Fur Colour",
value: "Freedom"
}
],
hasFilters: [
"age"
],
search: "Blue"
}
})
query GetAssets($addresses: [ChainAddress!]!, $collectionIds: [CollectionId!], $after: String, $first: Float) {
assets(
addresses: $addresses
collectionIds: $collectionIds
after: $after
first: $first
) {
pageInfo {
endCursor
hasNextPage
}
edges {
node {
id
collectionId
tokenId
assetType
assetTree {
data
nodeId
}
schema {
name
namespace
schema
version
}
ownership {
__typename
... on SFTAssetOwnership {
id
balancesOf(addresses: $addresses) {
balance
owner {
address
}
}
}
... on NFTAssetOwnership {
owner {
address
}
}
}
metadata {
attributes
properties
uri
}
links {
__typename
... on SFTAssetLink {
parentLinks(addresses: $addresses) {
collectionId
tokenId
}
}
... on NFTAssetLink {
parentLink {
collectionId
tokenId
}
}
}
collection {
id
chainId
chainType
location
name
}
}
}
}
}
Large amounts of collectibles can be returned during querying, this section will help you manage the results to provide better UX to your users.
By default, the Assets Query will return 10 results.
Throughout the API we use Relay compliant pagination.
Page Information
This means we allow the following properties in pageInfo
:
endCursor
- The cursor of the last item returned
nextPage
- The cursor for the start of the next page (This is the same as endCursor
)
startCursor
- The cursor of the first element retrieved
hasNextPage
- If there are more pages of data
hasPreviousPage
- If there is a previous page of data (Not supported)
In Query Arguments
When running a paginated query the following properties in the query arguments are available:
after
- The cursor to start from. Typically this would be the endCursor
from a previous query
first
- The amount of items that you are requesting to be returned
Usage
import React from 'react'
import { useAccount } from 'wagmi'
import { ChainAddress } from '@fv-asset-registry/common'
import { useAssets } from '@futureverse/asset-register-react'
import { useFuturePassAccountAddress } from '@futureverse/react'
// React component to render all collectibles owned by a FuturePass user logged in.
export const AssetList = () => {
const {
assets
} = useAssets(
{
first: 1000,
after: "NA=="
}
)
if (!assets) {
return null
}
return (
<div>
{assets.map((asset) => <Asset key={asset.id} asset={asset} />)}
</div>
)
import React from 'react'
import { useAccount } from 'wagmi'
import { ChainAddress } from '@fv-asset-registry/common'
import { useAssets } from '@futureverse/asset-register-react'
import { useFuturePassAccountAddress } from '@futureverse/react'
// React component to render all collectibles owned by a FuturePass user logged in.
export const AssetList = () => {
const {
assets
} = useAssets(
{
first: 1000,
after: "NA=="
}
)
if (!assets) {
return null
}
return (
<div>
{assets.map((asset) => <Asset key={asset.id} asset={asset} />)}
</div>
)
import { AssetRegister } from '@futureverse/asset-register'
const ar = new AssetRegister({
...
})
const assets = await ar.assets({
first: 1000,
after: "NA=="
})
query GetAssets($after: String, $first: Float) {
assets(
addresses: $addresses
collectionIds: $collectionIds
after: $after
first: $first
) {
pageInfo {
endCursor
hasNextPage
}
edges {
node {
id
collectionId
tokenId
assetType
assetTree {
data
nodeId
}
schema {
name
namespace
schema
version
}
ownership {
__typename
... on SFTAssetOwnership {
id
balancesOf(addresses: $addresses) {
balance
owner {
address
}
}
}
... on NFTAssetOwnership {
owner {
address
}
}
}
metadata {
attributes
properties
uri
}
links {
__typename
... on SFTAssetLink {
parentLinks(addresses: $addresses) {
collectionId
tokenId
}
}
... on NFTAssetLink {
parentLink {
collectionId
tokenId
}
}
}
collection {
id
chainId
chainType
location
name
}
}
}
}
}
{
"first": 1000,
"after": "NA=="
}