📢 This ARC is in the last call for review stage. The authors wish to finalize the ARC and appreciate feedback.

ARC-53: Metadata Declarations Source

A specification for a decentralized, Self-declared, & Verifiable Tokens, Collections, & Metadata

AuthorKyle Breeding aka krby.algo
StatusLast Call
Last Call Deadline2025-02-15
TypeMeta
Created2023-09-12

Abstract

This ARC describes a standard for a self-sovereign on-chain project & info declaration. The declaration is an ipfs link to a JSON document attached to a smart contract with multi-wallet verification capabilities that contains information about a project, including project tokens, FAQ, NFT collections, team members, and more.

Motivation

In our current ecosystem we have a number of centralized implementations for parts of these vital pieces of information to be communicated to other relevant parties. All NFT marketplaces implement their own collection listing systems & requirements. Block explorers all take different approaches to sourcing images for ASA’s; The most common being a github repository that the Tinyman team controls & maintains. This ARC aims to standardize the way that projects communicate this information to other parts of our ecosystem.

We can use a smart contract with multi-wallet verification to store this information in a decentralized, self-sovereign & verifiable way by using custom field metadata & IPFS. A chain parser can be used to read the information stored & verify the details against the verified wallets attached to the contract.

Specification

The keywords “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in RFC 2119.

This proposal specifies an associated off-chain JSON metadata file, displayed below. This metadata file contains many separate sections and escape hatches to include unique metadata about various businesses & projects. For the purposes of requiring as few files & ipfs uploads as possible the sections are all included within the same file. The file is then added to IPFS and the link saved in a custom field on the smart contract under the key project.

Field Schema Description Required
version string The version of the standard that the metadata is following. true
associates array<Associate> An array of objects that represent the associates of the project. false
collections array<Collection> An array of objects that represent the collections of the project. false
tokens array<Token> An array of objects that represent the tokens of the project. false
faq array<FAQ> An array of objects that represent the FAQ of the project. false
extras object An object that represents any extra information that the project wants to include. false
Top Level JSON Example
{
    "version": "0.0.2",
    "associates": [...],
    "collections": [...],
    "tokens": [...],
    "faq": [...],
    "extras": {...}
}

Version

We envision this is an evolving / living standard that allows the community to add new sections & metadata as needed. The version field will be used to determine which version of the standard the metadata is following. This will allow for backwards compatibility & future proofing as the standard changes & grows. At the top level, version is the only required field.

Associates

Associates are a list of wallets & roles that are associated with the project. This can be used to display the team members of a project, or the owners of a collection.

The associates field is an array of objects that contain the following fields:

Field Schema Description Required
address string The algorand wallet address of the associated person true
role string A short title for the role the associate plays within the project. true

eg:

"associates": [
    {
        "address": "W5MD3VTDUN3H2FFYJR2NDXGAAV2SJ44XEEDGBWHIZKH6ZZXF44SE7KEPVP",
        "role": "Project Founder"
    },
    ...
]

Collections

NFT Collections have no formal standard for how they should be declared. This section aims to standardize the way that collections are declared & categorized. The collections field is an array of objects that contain the following fields:

Field Schema Description Required
name string The name of the collection true
network string The blockchain network that the collection is minted on.
Default: algorand
Special: multichain
false
prefixes array<string> An array of strings that represent the prefixes to match against the unit_name of the NFTs in the collection. false
addresses array<string> An array of strings that represent the addresses that minted the NFTs in the collection. false
assets array<uint64> An array of strings that represent the asset_ids of the NFTs in the collection. false
excluded_assets array<uint64> An array of strings that represent the asset_ids of the NFTs in the collection that should be excluded. false
artists array<string> An array of strings that represent the addresses of the artists that created the NFTs in the collection. false
banner_image string An IPFS link to an image that represents the collection.
if set banner_id should be unset & vice-versa
false
banner_id uint64 An asset_id that represents the collection. false
avatar_image string An IPFS link to an image that represents the collection.
if set avatar_id should be unset & vice-versa
false
avatar_id uint64 An asset_id that represents the collection. false
explicit boolean A boolean that represents whether or not the collection contains explicit content. false
royalty_percentage uint64 A uint64 with a value ranging from 0-10000 that represents the royalty percentage that the collection would prefer to take on secondary sales. false
properties array<CollectionProperties> An array of objects that represent traits from an entire collection. false
extras object An object of key value pairs for any extra information that the project wants to include for the collection. false

eg:

"collections": [
    {
        "name": "My Collection",
        "networks": "algorand",
        "prefixes": [
            "AKC",
            ...
        ],
        "addresses": [
            "W5MD3VTDUN3H2FFYJR2NDXGAAV2SJ44XEEDGBWHIZKH6ZZXF44SE7KEPVP",
            ...
        ],
        "assets": [
            123456789,
            ...
        ],
        "excluded_assets": [
            123456789,
            ...
        ],
        "artists": [
            "W5MD3VTDUN3H2FFYJR2NDXGAAV2SJ44XEEDGBWHIZKH6ZZXF44SE7KEPVP",
            ...
        ],
        "banner_image": "ipfs://...",
        "avatar": 123456789,
        "explicit": false,
        "royalty_percentage": "750", // ie: 7.5%
        "properties": [
            {
                "name": "Fur",
                "values": [
                    {
                        "name": "Red",
                        "image": "ipfs://...",
                        "image_integrity": "sha256-...",
                        "image_mimetype": "image/png",
                        "animation_url": "ipfs://...",
                        "animation_url_integrity": "sha256-...",
                        "animation_url_mimetype": "image/gif",
                        "extras": {
                            "key": "value",
                            ...
                        }
                    },
                    ...     
                ]
            }
            ...
        ],
        "extras": {
            "key": "value",
            ...
        }
    },
    ...
]

Collection Scoping

Not all collections have been consistent with their naming conventions. Some collections are minted across multiple wallets due to prior asa minting limitations. The following fields used together offer great flexibility in creating a group of NFTs to include in a collection. prefixes, addresses, assets, excluded_assets. Combined, these fields allow for maximum flexibility for mints that may have mistakes or exist across wallets & dont all conform to a consistent standard.

prefixes allows for simple grouping of a set of NFTs based on the beginning part of the ASAs unit_name. This is useful for collections that have a consistent naming convention for their NFTs. Every other scoping field modifies this rule.

addresses scope down the collection to only include ASAs minted by the addresses listed in this field. This is useful for projects that mint different collections across multiple wallets that utilize the same prefix.

assets is a direct entry in the collection for NFTs that dont conform to any of the prefix rules.

excluded_assets is a direct exclusion on an NFT that may conform to a prefix but should be excluded from the collection.

banner_image, banner_id, avatar_image, avatar_id are all very self explanatory. They allow for a glancable preview of the collection to display on NFT marketplaces, analytics sites & others. Both banner & avatar field groups should be one or the other, not both. banner_image or banner_id (likely an ASA id from the creator). avatar_image or avatar_id (likely an ASA id from the collection).

explicit is a boolean that indicates whether or not the collection contains explicit content. This is useful for sites that want to filter out explicit content.

properties is an array of objects that represent traits from an entire collection. Many new NFT collections are choosing to use ARC-19 and mint their NFTs as blank slates. This can prevent sniping but also has the adverse affect of obscuring the trait information of a collection. This field allows for a collection to declare its traits, values, image previews of the trait it references and extra metadata.

Collection Properties

| Field | Schema | Description | Required | — | — | — | — | | name | string | The name of the property | true | | values | array<CollectionPropertyValue> | An array of objects that represent the values of the property. | true |

Collection Property Values

| Field | Schema | Description | Required | — | — | — | — | | name | string | The name of the value | true | | image | string | An IPFS link to an image that represents the value. | false | | image_integrity | string | A sha256 hash of the image that represents the value. | false | | image_mimetype | string | The mimetype of the image that represents the value. | false | | animation_url | string | An IPFS link to an animation that represents the value. | false | | animation_url_integrity | string | A sha256 hash of the animation that represents the value. | false | | animation_url_mimetype | string | The mimetype of the animation that represents the value. | false | | extras | object | An object of key value pairs for any extra information that the project wants to include for the property value. | false |

Tokens

Tokens are a list of assets that are associated with the project. This can be used to verify the tokens of a project and for others to easily source images to represent the token on their own platforms.

Field Schema Description Required
asset_id uint64 The asset_id of the token true
image string An IPFS link to an image that represents the token. false
image_integrity string A sha256 hash of the image that represents the token. false
image_mimetype string The mimetype of the image that represents the token. false

eg:

"tokens": [
    {
        "asset_id": 123456789,
        "image": "ipfs://...",
        "image_integrity": "sha256-...",
        "image_mimetype": "image/png",
    }
    ...
]

FAQ

Frequently Asked Questions for the project to address the common questions people have about their project and help inform the community.

Field Schema Description Required
q string The question true
a string The answer true

eg:

"faq": [
    {
        "q": "What is XYZ Collection?",
        "a": "XYZ Collection is a premiere NFT project that..."
    },
    ...
]

Extras

Custom Metadata for extending & customizing the declaration for your own use cases. This object can be found at several levels throughout the specification, The top level, within collections & within collection property value objects.

Field Schema Description Required
key string The key of the extra information true
value string The value of the extra information true

eg:

"extras": {
    "key": "value",
    ...
}

Contract Providers

Custom metadata needs to be verifiable and many projects use many wallets as a means of separating concerns. Providers are smart contracts that have the capability of verifying multiple wallets & thus provide evidence to parsers of the authenticity of such data. Providers that support this standard will be listed on the ARC compatibility matrices site.

Rationale

See the motivation section above for the general rationale.

Security Considerations

None

Copyright and related rights waived via CCO.

Citation

Please cite this document as:

Kyle Breeding aka krby.algo, "ARC-53: Metadata Declarations [DRAFT]," Algorand Requests for Comments, no. 53, September 2023. [Online serial]. Available: https://github.com/algorandfoundation/ARCs/blob/main/ARCs/arc-0053.md.