diff --git a/ARCs/arc-0053.md b/ARCs/arc-0053.md new file mode 100644 index 000000000..b7061daac --- /dev/null +++ b/ARCs/arc-0053.md @@ -0,0 +1,263 @@ +--- +arc: 53 +title: Metadata Declarations +description: A specification for a decentralized, Self-declared, & Verifiable Tokens, Collections, & Metadata +author: Kyle Breeding aka krby.algo (@kylebeee) +status: Living +type: Meta +created: 2023-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\ | An array of objects that represent the associates of the project. | false | +| collections | array\ | An array of objects that represent the collections of the project. | false | +| tokens | array\ | An array of objects that represent the tokens of the project. | false | +| faq | array\ | 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 +```json +{ + "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: +```json +"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\ | An array of strings that represent the prefixes to match against the `unit_name` of the NFTs in the collection. | false | +| addresses | array\ | An array of strings that represent the addresses that minted the NFTs in the collection. | false | +| assets | array\ | An array of strings that represent the asset_ids of the NFTs in the collection. | false | +| excluded_assets | array\ | An array of strings that represent the asset_ids of the NFTs in the collection that should be excluded. | false | +| artists | array\ | 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\ | 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: +```json +"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](./arc-0019.md) 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\ | 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: +```json +"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: +```json +"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: +```json +"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 + +Copyright and related rights waived via CCO.