Search code examples
rustblockchainsolanametaplex

Filter NFT's in wallet by metaplex candy machine id


Is there any way to filter a users wallet by metaplex candy machine id?

I know how to get all of a users nfts via getParsedTokenAccountsByOwner.

 const tokens = await connection.getParsedTokenAccountsByOwner(publicKey, {
   mint: mintAccount,
   programId,
 });

 const nftList = tokens.value.filter((row) => {
   return row.account.data.parsed.info.tokenAmount.amount === "1";
 });

The problem, I'd have to get the metadata for each token and then filter it from there, which is a lot of unneeded hits to the the chain. I know I can get all the addresses for a candy machine via getProgramAccounts but this is slow, and can take about 30 seconds to run.

This def makes a front end display of a specific candy machine tokens frustrating with out any sort of caching layer + regular polling which I'm trying to avoid if possible.


Solution

  • Ok I figured it out!

    1. Get the solana metadata for each nft in a users wallet. (Very easy thanks to metaplex helper)
    2. Filter on matching update authority (typically the wallet used to create the candy machines)
    
    const connection = new Connection('mainnet-beta');
    const ownerPublickey = 'OWNER_PUBLICK_KEY';
    const nftsmetadata = await Metadata.findDataByOwner(connection, ownerPublickey)
    .filter((r) => r.updateAuthority === 'SOLANAWALLETADDRESS');
    
    // Profit
    console.log(nftsmetadata)
    

    I this question didn't get a lot of love, but for someone building ui's on top of solana this was not obvious and very overwhelming to figure out. As solana's api can be a lot for someone to get their head around. Thankfully the Metaplex community has done an amazing job of building some awesome helper methods to make this super easy.

    Also shout out to the solana cookbook folks, you helped connect the dots here. You can see more awesome nft related helpers here:

    https://solanacookbook.com/references/nfts.html#candy-machine-v2