What is the best way to fetch all ERC721 tokens owned by an address?

:1234: Code to reproduce

//none

:computer: Environment

Hardhat.

If the ERC721 contract has the enumerable property, its very easy to get them from the tokenOfOwnerByIndex function.

However, if there is no enumerable property and its just a straight ERC721, you need to look for transfer events associated with the wallet you are targeting using something like The Graph or other Ethereum events tracking method.

2 Likes

Here is some code to complement @TtheBC01's answer, showing how to use events to get a list of contracts owned by someone:

Using The Graph would scale much better than this, though. You can check out our OpenZeppeiln Subgraphs, as well as a predeployed ERC721 subgraph for Ethereum Mainnet.

1 Like

Thank you for the responses, they have been very helpful.

So, I can either use the enumerable contract or use a subgraph for this purpose.

Is using the enumerable approach that much costly/ cumbersome as to make the graph approach a better choice? Also, the main Graph API's main offering is fast querying of the blockchain, right?

@hasanza Note that my script above doesn't rely on including Enumerable. It uses the built-in Transfer events.

I don't know the exact overhead of including Enumerable, but you could run some benchmarks to see. Personally I would choose a The Graph based approach rather than the Enumerable extension.

The Graph's offering is a combination of indexing (gathering data from the blockchain) and subsequent querying.

@frangio Could you expand on this potential decision a bit more? Size, complexity, gas?

For composability reasons alone I find Enumerable to be worth it. For example, I build a lot on top of other ERC721, and being able to on-chain capture all tokens of an owner is a really common use-case. Using The Graph just to pass around potentially large arrays only to then have to ensure that ownerOf is still valid seems like the juice isn't worth the squeeze.

@0xLostArchitect, I'm also a fan of having enumerable tokens because (as you've said) it makes it way easier for the ERC721 tokens to be queried by other contracts for various purposes. Since event logs aren't accessible by contracts, sometimes enumeration is the only reasonable way to find a token's owning address.

However, it increases the gas of minting significantly (like nearly doubling the gas required to mint). The ERC721Enumerable.sol extension adds 3 additional mappings and an array that are maintained for each token.

1 Like

Easy way. Just scan the address.

You can conveniently use xscan.io
This scanner is powered by Unmarshal, a Blockchain data network.

Just wanted to note that there are some dedicated services taking care of that, my current favorite being https://www.nftport.xyz (which is a funded project). From a decentralized perspective that might not be exactly what you might be looking for but for real world apps (quickly find all NFTs of an user / from one collection) that might make total sense. Another one that has a similar offering but actually comes with high latencies sometimes is https://www.covalenthq.com/.

1 Like