While coding to enter a hackathon, I had to use Tatum’s API since it was one of the sponsors there, although I had used Tatum before, this time I reached a new level, using the API to build an NFT gallery, with just a few other tools, and I’d like to share it with you.
In this case, I used React JS, react-query, wagmi.sh to connect the wallet, and Tatum’s API key. You can find the code in my GitHub repository.
In this case, we’ll show the NFTs of a specific collection that an address hold. We’ll need to do three consecutive API calls using Tatum to get it done.
Get the total token balance.
Filter by collection (contract).
Get the metadata.
Show the NFTs.
First of all, you need to connect your wallet, I’m using wagmi.sh which is a powerful open-source library for React, I’ll teach you how to use it in another post, meanwhile you can try using the official docs on their site.
Once you have your wallet connected, you need to get the balance of the tokens you hold and filter the result to get the data you need directly from the call.
To make this first call, you can use this Tatum’s endpoint, as you can see in the code below.
const fetchBalance = async () => {
const res = await fetch(`https://api-eu1.tatum.io/v3/multitoken/address/balance/${chain}/${address}`, {
"method": "GET",
"headers": {
"Content-Type": "application/json",
"x-api-key": process.env.REACT_APP_TATUM
}
}
)
try {
const result = await res.json();
const resultFiltered = result.find(element => element?.contractAddress?.toLowerCase() === nftContract.toLowerCase());
const resultBalances = resultFiltered.balances.map(ids => ids.tokenId)
return resultBalances;
} catch (error) {
console.log(error);
}
};
//First call
const { data: balance } = useQuery({ queryKey: ['nfts'], queryFn: fetchBalance});
After that, you’ll get a list of the tokens you hold, something like [0, 1, 20, 400, 123]. I recommend you use ReactQueryDevtools to see the data you’re fetching directly in your browser.
Once you have the balance and you’ve filtered it by collection (contract), you want to make a second and dependent query, to get the metadata of every token you find in the previous call. To do that, you can use this Tatum’s endpoint, as you can see below.
const fetchMetadata = async (ids) => {
const res = await fetch(`https://api-eu1.tatum.io/v3/multitoken/metadata/${chain}/${nftContract}/${ids}`, {
"method": "GET",
"headers": {
"Content-Type": "application/json",
"x-api-key": process.env.REACT_APP_TATUM
}
}
)
try {
const result = await res.json();
return result;
} catch (error) {
console.log(error);
}
};
//Second call
const { data: tokenId } = useQuery({ queryKey: ['tokenId'], queryFn: () => Promise.all(balance.map(ids => fetchMetadata(ids))), enabled: !!balance });
The last call is very similar to the second one, another dependent query, but, this time, you need to resolve the IPFS CID you got in the previous one to see the entire metadata information, and finally, show it to the user.
In this case, I decided to add a proxy to resolve the CID, but you can find a ton of ways to do the same thing, some of them could be better than the one I’m using, feel free to contribute to the code, I’d be very grateful.
const fetchIPFS = async (ids) => {
let url = "";
if (ids.data.includes("ipfs://")) {
url = ids.data.replace("ipfs://", "https://nftstorage.link/ipfs/");
}
const res = await fetch(`${url}`, {
"method": "GET",
"headers": {
"Content-Type": "application/json",
}
}
)
try {
const result = await res.json();
return result;
} catch (error) {
console.log(error);
}
};
//Third call
const { data: ipfs } = useQuery({ queryKey: ['ipfs'], queryFn: () => Promise.all(tokenId.map(ids => fetchIPFS(ids))), enabled: !!tokenId });
Now, just build a Card component (or reuse one from a library like TailwindCSS or MUI) is pending, I let it to your imagination. I hope it’ll be helpful in your journey. Happy code!
