Use ERC721Enumerable Interface if available
- Create a new ERC721 type, ERC721_Enumerable (in
ContractType). - Check if the ERC721 contract has the Enumerable interface (
TokenRepository, find the correct value forINTERFACE_ERC721ENUMERABLE).bytes4 private constant _INTERFACE_ID_ERC721_ENUMERABLE = 0x780e9d63; - Label the ERC721 which we now know is an Enumerable as ERC721_Enumerable, when we do the
determineCommonType() - ~~Inherit the
ERC721Tokenclass and override theupdateBalancemethod to create the class.~~
Instead of needing to trawl event history we can fetch full TokenId balance with only two calls.
First calling the balanceOf(address) - which is already done by the default ERC721 balance update before updateBalance is called, then crawling the indices {0 -> balance count} up to the balance count by calling the contract function:
uint256 tokenOfOwnerByIndex({wallet address}, index)
This function returns the TokenId at the index eg.
Balance of NFT is 3 tokens, check tokenOfOwnerByIndex for 0,1,2 ->
0 -> 2556 1 -> 3456 2 -> 4431
Then we have all the TokenIds owned by the wallet without needing to trawl the event list, in only 1 extra call.
Note that, we still have to trawl the event list because we want the transfer events (provides better support for chains that don't have etherscan support, and we might in the future be looking for events that Etherscan etc don't report in their APIs).
This is going to be an addition.
Suggested approach:
- create new ERC721_ENUMERABLE contract type to
ContractType. - Detect that new contract type (interface) in
determineCommonType(). - Ensure you add the new contract type to all places where
case ERC721:is used. - In the
updateBalance()method inclass ERC721Tokencall the ethereum functionuint256 tokenOfOwnerByIndex({wallet address}, index)something like this:
for (int i = 0; i < balance.intValue(); i++)
{
tokenIds.add (tokenOfOwnerByIndex(getWallet(), i));
}
updateRealmBalance(realm, tokenIds)
Note that this ethereum function prototype looks like this: tokenOfOwnerByIndex(address,uint256)
see Sourcecode for contract extension
Let me know if you need any help to make the function call prototype, for reference see the ownerOf definition in the ERC721Token class, or the balanceOfBatch call in ERC1155Token