3

How can I find out the Collection's public key of some NFT in Anchor? I know it was easy to do with the Solana SDK, but as far as I know it is not compatible with Anchor.

More specifically, how can I validate inside a Solana Rust program that the provided NFT token (public key) actually belongs to certain Collection?

2 Answers 2

3

Like John mentioned in the other answer, since Metadata Account is now supported as a part of Anchor 0.26.0, it has become fairly easy to validate Collection field in Anchor. Here's how you will do it:

Turn on metadata feature in Cargo.toml first:

anchor-spl = {version = "0.26.0",features = ["metadata"]}

Collection field is an optional struct with two fields: verified and key. Make sure to validate both i.e. verified is set to true and key matches your collection key:

use anchor_spl::metadata::MetadataAccount;
....
#[account(
    seeds = [
        b"metadata", 
        MPL_TOKEN_METADATA_ID.as_ref(), 
        mint.key().as_ref()
    ],
    seeds::program = MPL_TOKEN_METADATA_ID,
    bump,
    constraint = metadata_account.collection.as_ref().unwrap().verified @ Errors::CollectionNotVerified,
    constraint = metadata_account.collection.as_ref().unwrap().key ==
    collection_details.key() @ Errors::CollectionNotSame
)]
pub metadata_account: Account<'info,MetadataAccount>,
2

An NFT's "collection" field is stored on it's Metadata Account, so you would need to build and an instruction that requires the Metadata Account for the NFT to be provided to the instruction.

Here's metaplex docs for reference of how collections currently work: https://docs.metaplex.com/programs/token-metadata/certified-collections

You would then need the deserialized account data from the Metadata Account, which is now supported as part of Anchor 0.26:

#[account(
        seeds = [b"metadata", mpl_token_metadata::ID.as_ref(), mint.key().as_ref()],
        seeds::program = mpl_token_metadata::ID,
        bump,
)]
pub metadata_account: Account<'info, MetadataAccount>

https://github.com/coral-xyz/anchor/pull/2014 https://github.com/coral-xyz/anchor/blob/master/CHANGELOG.md

Then within your instruction, check that the "collection" field on the Metadata Account matches the "collection" you expect.

Note that you may also need to check if the "collection" field on the Metadata Account has been verified. This is because anyone can create an NFT and set the "collection" field to any address they want.

From the metaplex docs:

As mentioned above, the Collection field contains a Verified boolean which is used to determine if the NFT is truly part of the collection it points to. Without this field, anyone could pretend their NFT to be part of any collection.

In order to flip that Verified boolean to True, the Authority of the Collection NFT must sign the NFT to prove that it is allowed to be part of the collection.

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.