Implementing 'attributes' in on-chain metadata for TON NFT collection

I’m developing an NFT project on TON and need help with the metadata. I want everything stored on-chain and generated in the contract because of the public minting feature. I’ve got most fields working, but I’m stuck on the ‘attributes’ part. Can anyone show me how to add this to the contract?

Here’s what I’ve tried so far:

cell trait_info = begin_cell()
    .store_uint(0, 8)
    .store_slice("{'type':'trait_category','info':'trait_details'}")
    .end_cell();

nft_data~dict_set_ref(256, "trait_info"H, trait_info);

It’s not quite right. How can I properly format and include the attributes in the on-chain metadata?

hey luna, have you tried using a dictionary for attributes? something like:

cell attributes = new_dict();
attributes~udict_set_ref(256, "trait_category"H, begin_cell().store_slice("trait_details").end_cell());
nft_data~dict_set_ref(256, "attributes"H, attributes);

this might work better for storing multiple traits. lmk if you need more help!

hey there luna_dreamy! i’ve been playing around with nft metadata on ton too, and i think i might have a solution for ya. have you considered using a cell-based approach for your attributes? something like this could work:

cell attributes = begin_cell()
    .store_uint(2, 8)  ;; number of attributes
    .store_ref(begin_cell()
        .store_slice("trait_category1")
        .store_slice("trait_details1")
        .end_cell())
    .store_ref(begin_cell()
        .store_slice("trait_category2")
        .store_slice("trait_details2")
        .end_cell())
    .end_cell();

nft_data~dict_set_ref(256, "attributes"H, attributes);

this way, you can store multiple attributes in a single cell and easily add more if needed. what do you think? have you tried something similar? curious to hear how it goes!

I’ve tackled a similar challenge in my TON NFT project. Instead of using a single cell for traits, consider creating a separate dictionary for each attribute category. This approach offers more flexibility and scalability:

cell trait_dict = new_dict();
trait_dict~udict_set_ref(256, "background"H, begin_cell().store_slice("blue").end_cell());
trait_dict~udict_set_ref(256, "headwear"H, begin_cell().store_slice("cap").end_cell());

nft_data~dict_set_ref(256, "attributes"H, trait_dict);

This structure allows you to easily add or modify traits without altering the entire metadata structure. It also provides better compatibility with standard NFT metadata formats, which typically expect attributes as an array of key-value pairs.