I'm writing a custom pallet that interacts with the NFTs pallet. In particular my custom pallet mints an NFT with metadata.

Here is how the token is minted and metadata is set in the custom pallet:

T::Nfts::mint_into(&T::ExperienceNFTCollectionId::get(), &token_id, &to, &item_config, true)?;
T::Nfts::set_item_metadata(None, &T::ExperienceNFTCollectionId::get(), &token_id, &credential.encode())?;

In my test case I want to test the metadata. This isn't possible, because the data field of ItemMetaData is private.

Here is how I try to get the metadata for testing in my custom pallet:

let metadata = ItemMetadataOf::<Test>::get(0, 0).unwrap();
assert_eq!(metadata.data, bounded_vec![]);

The error I'm getting on the assert_eq line is:

field `data` of struct `ItemMetadata` is private

If I'm not supposed to directly read the data field, then how am I supposed to test or work with the metadata I set?

3 Answers 3


what if you compose an ItemMetadata struct and compare that instead?

let actual_metadata = ItemMetadataOf::<Test>::get(0, 0).unwrap();

let expected_metadata = ItemMetadataOf::<Test> {
  deposit: Zero::zero(),
  data: [1, 2, 3].try_into().unwrap()

assert_eq!(expected_metadata, actual_metadata);
  • The getter returns a value of type ItemMetadata, not ItemMetadataOf. Constructing it in the test doesn't work for the same reason as reading: The fields are private. Dec 19, 2023 at 6:22
  • you are right. In this case, @Szegoo is correct. You can access the metadata via <Nfts as Inspect>::attribute(&collection_id, &item_id, []). When you pass the key as empty it will access ItemMetadataOf, if you pass a non-empty key it will access the Attribute github.com/paritytech/polkadot-sdk/blob/master/substrate/frame/…
    – dastansam
    Dec 19, 2023 at 8:58

You can access a specific it through the Inspect trait: https://github.com/paritytech/polkadot-sdk/blob/ebe2aad6f0ae576a0e176f38a084fe7579f936dd/substrate/frame/nfts/src/impl_nonfungibles.rs#L30

// E.g. accessing a specific attribute:
let attribute = pallet_nfts::Pallet::<T>::attribute(&collection_id, &item, &key);
  • For as far as I know attributes and metadata isn't the same thing. Also every tutorial or instruction that I have read indicates that I should use metadata and not attributes. Dec 19, 2023 at 6:25

The trick was to use Nfts::attribute(0, 0, []), thus with an empty key argument to receive the data I needed.

Big thanks to @dastansam and @Szegoo for helping me to get on the right track.

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.