3

I want to build a governance program where only accounts which hold the NFT of a particular collection can vote. How can i check on chain if an accounts holds an NFT of a particular collection. Would this be computationally expensive?

1 Answer 1

6

You can fetch the metadata of a mint onchain using mpl_token_metadata crate. Steps to get the collection account on an account :

  1. Get the metadata PDA for a mint address

    pub fn get_metadata(mint: Pubkey) -> Pubkey {
    let (metadata, _) = Pubkey::find_program_address(
        &[
            mpl_token_metadata::state::PREFIX.as_bytes(),
            mpl_token_metadata::id().as_ref(),
            mint.as_ref(),
        ],
        &mpl_token_metadata::id(),
    );
     metadata 
    }
    
  2. Read the metadata data

    let mint_metadata= Metadata::from_account_info(&ctx.accounts.mint_metadata_address.to_account_info())?; 
  3. Check the collection NFT on the mint

     if mint_metadata.collection.is_some() {
                let collection = mint_metadata.collection.unwrap();
                if collection.verified  {
                   // Do your stuff here
                }
            } 

Suggestion - You can store your collection NFT mint address in some global variable (PDA data on a static seed) and then on 3rd step along with the exist check add another check if it belongs to that particular collection or not that you have stored.

3
  • In the step 2 are we fetching the metadata address using the function in step 1? Commented Jul 26, 2022 at 14:39
  • 1
    You can either use this function or pass the metadata calculated from JS file in the accounts array and verify if PDA address calculated from here and passed are same or not
    – maddy
    Commented Jul 26, 2022 at 17:56
  • mpl_token_metadata does not have id and state function. Do I have to use a specific version of mpl-token-metadata? Commented Jan 19 at 13:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.