From 264170d55c68a07e8f503c49823df9f45b1b4c44 Mon Sep 17 00:00:00 2001 From: Thaddeus Diamond Date: Sun, 2 Nov 2025 14:52:00 -0600 Subject: [PATCH 1/3] CIP-0068 | Support multi-asset metadata a la CIP-0025 (#1112) Add version 4 metadata support with 721-ERC-style mappings to NFT (222), FT (333) and RFT (444) standards, ensuring consistency across all asset classes. Changes: - Add metadata_field union type supporting both direct and 721-map formats - Add __RESERVE_KEYWORD_721_V4__ marker for 721-style detection - Update retrieval steps to handle both metadata formats - Support version 4 in FT standard - Support version 3/4 in RFT standard - Add 721-style JSON example for NFT standard - Update pattern descriptions with asset_name terminology - Fix URI support to include [* bounded_bytes] for RFT --- CIP-0068/README.md | 164 +++++++++++++++++++++++++++++++++++++++------ 1 file changed, 142 insertions(+), 22 deletions(-) diff --git a/CIP-0068/README.md b/CIP-0068/README.md index 758fe94622..dcdb89ed03 100644 --- a/CIP-0068/README.md +++ b/CIP-0068/README.md @@ -155,7 +155,7 @@ The `user token` represents an NFT (non-fungible token). ##### Pattern -The `user token` and `reference NFT` MUST have an identical name, preceded by the `asset_name_label` prefix. +The `user token` and `reference NFT` MUST have an identical name (heretofore entitled `asset_name`), preceded by the `asset_name_label` prefix. Example:\ `user token`: `(222)Test123`\ @@ -163,8 +163,12 @@ Example:\ ##### Metadata -This is a low-level representation of the metadata, following closely the structure of CIP-0025. All UTF-8 encoded keys -and values need to be converted into their respective byte's representation when creating the datum on-chain. +This is either: + +1. A low-level direct representation of the metadata, following closely the structure of CIP-0025 +2. A 721-ERC-style token mapping exactly matching the structure of CIP-0025 + +All UTF-8 encoded keys and values need to be converted into their respective byte's representation when creating the datum on-chain. ``` files_details = @@ -188,6 +192,26 @@ metadata = ; ... Additional properties are allowed } +metadata_map = + { + __RESERVE_KEYWORD_721_V4__ : bool, ; Long name to avoid conflict + + "721": + { + ; As many of the below as needed based on which reference tokens are added + "": + { + "" : metadata, + ; ... + "" : metadata, + } + } + } + +metadata_field = + metadata ; For backwards-compatibility in v4 onward, a map itself is valid metadata + / metadata_map ; Multi-metadata is now supported as in CIP-0025 + ; A valid Uniform Resource Identifier (URI) as a UTF-8 encoded bytestring. ; The URI scheme must be one of `https` (HTTP), `ipfs` (IPFS), `ar` (Arweave) or `data` (on-chain). ; Data URLs (on-chain data) must comply to RFC2397. @@ -198,12 +222,12 @@ uri = bounded_bytes / [ * bounded_bytes ] ; UTF-8 ; and needs to be at least Unit/Void: #6.121([]) extra = plutus_data -datum = #6.121([metadata, version, extra]) +datum = #6.121([metadata_field, version, extra]) -version = 1 / 2 / 3 +version = 1 / 2 / 3 / 4 ``` -Example datum as JSON: +Example datum as JSON (direct metadata): ```json { @@ -236,6 +260,45 @@ Example datum as JSON: } ``` +Example datum as JSON (721-style): + +```json +{ + "constructor": 0, + "fields": [ + { + "map": [ + { + "k": { "bytes": "373231" }, + "v": { + "map": [ + { + "k": { "bytes": "5370616365427564204131" }, + "v": { + "map": [ + { + "k": { "bytes": "6E616D65" }, + "v": { "bytes": "5370616365427564" } + }, + { + "k": { "bytes": "696D616765" }, + "v": { "bytes": "697066733A2F2F74657374" } + } + ] + } + } + ] + } + } + ] + }, + { + "int": 4 + } + ] +} +``` + ##### Retrieve metadata as 3rd party A third party has the following NFT `d5e6bf0500378d4f0da4e8dde6becec7621cd8cbf5cbb9b87013d4cc.(222)TestToken` they want @@ -244,7 +307,9 @@ to lookup. The steps are 1. Construct `reference NFT` from `user token`: `d5e6bf0500378d4f0da4e8dde6becec7621cd8cbf5cbb9b87013d4cc.(100)TestToken` 2. Look up `reference NFT` and find the output it's locked in. 3. Get the datum from the output and lookup metadata by going into the first field of constructor 0. -4. Convert to JSON and encode all string entries to UTF-8 if possible, otherwise leave them in hex. +4. Determine whether this is a direct metadata or the CIP-0025 map style using the `__RESERVE_KEYWORD_721_V4__` map value (if present, default false) +5. Convert to JSON and encode all string entries to UTF-8 if possible, otherwise leave them in hex. +6. For multi-map style metadata, return only the JSON values inside the matching path: `721`->>`policy_id`->>`asset_name` ##### Retrieve metadata from a Plutus validator @@ -274,7 +339,7 @@ The `user token` is an FT (fungible token). ##### Pattern -The `user token` and `reference NFT` MUST have an identical name, preceded by the `asset_name_label` prefix. +The `user token` and `reference NFT` MUST have an identical name (heretofore called `asset_name`), preceded by the `asset_name_label` prefix. Example:\ `user token`: `(333)Test123`\ @@ -282,9 +347,12 @@ Example:\ ##### Metadata -This is a low-level representation of the metadata, following closely the structure of the Cardano foundation off-chain -metadata registry. All UTF-8 encoded keys and values need to be converted into their respective byte's representation -when creating the datum on-chain. +This is either: + +1. A low-level direct representation of the metadata, following closely the structure of the Cardano foundation off-chain metadata registry +2. A 721-ERC-style token mapping exactly matching the structure of CIP-0025 + +All UTF-8 encoded keys and values need to be converted into their respective byte's representation when creating the datum on-chain. ``` ; Explanation here: https://developers.cardano.org/docs/native-tokens/token-registry/cardano-token-registry/ @@ -304,6 +372,26 @@ metadata = ; ... Additional properties are allowed } +metadata_map = + { + __RESERVE_KEYWORD_721_V4__ : bool, ; Long name to avoid conflict + + "721": + { + ; As many of the below as needed based on which reference tokens are added + "": + { + "" : metadata, + ; ... + "" : metadata, + } + } + } + +metadata_field = + metadata ; For backwards-compatibility in v4 onward, a map itself is valid metadata + / metadata_map ; Multi-metadata is now supported as in CIP-0025 + ; A valid Uniform Resource Identifier (URI) as a UTF-8 encoded bytestring. ; The URI scheme must be one of `https` (HTTP), `ipfs` (IPFS), `ar` (Arweave) or `data` (on-chain). ; Data URLs (on-chain data) must comply to RFC2397. @@ -314,9 +402,9 @@ uri = bounded_bytes / [ * bounded_bytes ] ; UTF-8 ; and needs to be at least Unit/Void: #6.121([]) extra = plutus_data -datum = #6.121([metadata, version, extra]) +datum = #6.121([metadata_field, version, extra]) -version = 1 / 2 / 3 +version = 1 / 2 / 3 / 4 ``` Example datum as JSON: @@ -360,7 +448,9 @@ to lookup. The steps are 1. Construct `reference NFT` from `user token`: `d5e6bf0500378d4f0da4e8dde6becec7621cd8cbf5cbb9b87013d4cc.(100)TestToken` 2. Look up `reference NFT` and find the output it's locked in. 3. Get the datum from the output and lookup metadata by going into the first field of constructor 0. -4. Convert to JSON and encode all string entries to UTF-8 if possible, otherwise leave them in hex. +4. Determine whether this is a direct metadata or the CIP-0025 map style using the `__RESERVE_KEYWORD_721_V4__` map value (if present, default false) +5. Convert to JSON and encode all string entries to UTF-8 if possible, otherwise leave them in hex. +6. For multi-map style metadata, return only the JSON values inside the matching path: `721`->>`policy_id`->>`asset_name` ##### Retrieve metadata from a Plutus validator @@ -403,9 +493,12 @@ Example:\ ##### Metadata -This is a low-level representation of the metadata, following closely the structure of CIP-0025 with the optional -decimals field added. All UTF-8 encoded keys and values need to be converted into their respective byte's representation -when creating the datum on-chain. +This is either: + +1. A low-level direct representation of the metadata, following closely the structure of CIP-0025 with the optional decimals field added +2. A 721-ERC-style token mapping exactly matching the structure of CIP-0025 + +All UTF-8 encoded keys and values need to be converted into their respective byte's representation when creating the datum on-chain. ``` files_details = @@ -430,19 +523,39 @@ metadata = ; ... Additional properties are allowed } +metadata_map = + { + __RESERVE_KEYWORD_721_V4__ : bool, ; Long name to avoid conflict + + "721": + { + ; As many of the below as needed based on which reference tokens are added + "": + { + "" : metadata, + ; ... + "" : metadata, + } + } + } + +metadata_field = + metadata ; For backwards-compatibility in v4 onward, a map itself is valid metadata + / metadata_map ; Multi-metadata is now supported as in CIP-0025 + ; A valid Uniform Resource Identifier (URI) as a UTF-8 encoded bytestring. ; The URI scheme must be one of `https` (HTTP), `ipfs` (IPFS), `ar` (Arweave) or `data` (on-chain). ; Data URLs (on-chain data) must comply to RFC2397. -uri = bounded_bytes ; UTF-8 +uri = bounded_bytes / [ * bounded_bytes ] ; UTF-8 ; Custom user defined plutus data. ; Setting data is optional, but the field is required ; and needs to be at least Unit/Void: #6.121([]) extra = plutus_data -datum = #6.121([metadata, version, extra]) +datum = #6.121([metadata_field, version, extra]) -version = 3 +version = 3 / 4 ``` Example datum as JSON: @@ -502,7 +615,9 @@ to lookup. The steps are 1. Construct `reference NFT` from `user token`: `d5e6bf0500378d4f0da4e8dde6becec7621cd8cbf5cbb9b87013d4cc.(100)TestToken` 2. Look up `reference NFT` and find the output it's locked in. 3. Get the datum from the output and lookup metadata by going into the first field of constructor 0. -4. Convert to JSON and encode all string entries to UTF-8 if possible, otherwise leave them in hex. +4. Determine whether this is a direct metadata or the CIP-0025 map style using the `__RESERVE_KEYWORD_721_V4__` map value (if present, default false) +5. Convert to JSON and encode all string entries to UTF-8 if possible, otherwise leave them in hex. +6. For multi-map style metadata, return only the JSON values inside the matching path: `721`->>`policy_id`->>`asset_name` ##### Retrieve metadata from a Plutus validator @@ -551,7 +666,8 @@ version of these tokens from any point in time with the following format: 1. [6d897eb](https://github.com/cardano-foundation/CIPs/tree/6d897eb60805a58a3e54821fe61284d5c5903764/CIP-XXXX) 2. [45fa23b](https://github.com/cardano-foundation/CIPs/tree/45fa23b60806367a3e52231e552c4d7654237678/CIP-XXXX) 3. [bfc6fde](https://github.com/cardano-foundation/CIPs/tree/bfc6fde340280d8b51f5a7131b57f4cc6cc5f260/CIP-XXXX) -4. **Current** +4. [YYYYYYY](https://github.com/cardano-foundation/CIPs/tree/abcdefabcdefabcdefabcdefabcdefabcdefabcd/CIP-XXXX) +5. **Next Editor** ``` Each time a new version is introduced the previous version's link MUST be updated to match the last commit corresponding @@ -578,6 +694,10 @@ versions of the affected tokens. `asset_name_labels` **MUST** only be marked obs - Added [* bounded_bytes] support to the image and src tags on the metadata +#### version 4 + +- Add backwards-compatible support for multi-asset 721-ERC-style metadata mappings + ## Rationale: how does this CIP achieve its goals? Without separation of `reference NFT` and `user token` you lose all flexibility and moving the `user token` would be From 2cb68c7a10514be0e00af8d538fabcef5b82938c Mon Sep 17 00:00:00 2001 From: Thaddeus Diamond Date: Tue, 6 Jan 2026 15:48:22 -0600 Subject: [PATCH 2/3] CIP-0068 | Address review feedback on v4 metadata format Fix terminology and CDDL syntax issues identified in review: - Remove "721-ERC-style" terminology; clarify reference to CIP-0025's nested map structure vs individual metadata fields - Fix CDDL syntax: use proper bounded_bytes for "721", policy_id, and asset_name keys (matching CIP-0025 version 2 conventions) - Remove __RESERVE_KEYWORD_721_V4__ marker; presence of "721" key is sufficient for format detection - Update retrieval steps to detect format by checking for "721" key - Clarify "backwards-compatible" in changelog: version 4 adds nested map format as additional option, compatible with v1-3 direct format - Rename "721-style" example label to "nested map format" - Propagate all fixes consistently across 222, 333, and 444 standards --- CIP-0068/README.md | 77 +++++++++++++++++++--------------------------- 1 file changed, 31 insertions(+), 46 deletions(-) diff --git a/CIP-0068/README.md b/CIP-0068/README.md index dcdb89ed03..2f8867c760 100644 --- a/CIP-0068/README.md +++ b/CIP-0068/README.md @@ -165,10 +165,10 @@ Example:\ This is either: -1. A low-level direct representation of the metadata, following closely the structure of CIP-0025 -2. A 721-ERC-style token mapping exactly matching the structure of CIP-0025 +1. A low-level direct representation of the metadata, following closely the structure of CIP-0025 for individual asset metadata (name, image, files, etc.) +2. A nested map structure following CIP-0025's organization with policy_id and asset_name as keys, where the outer map contains a "721" key whose value maps policy_id to asset_name to metadata -All UTF-8 encoded keys and values need to be converted into their respective byte's representation when creating the datum on-chain. +All UTF-8 encoded keys and values need to be converted into their respective byte's representation when creating the datum on-chain. In the nested map format (option 2), the "721" key, policy_id keys, and asset_name keys must be encoded as bounded_bytes (following CIP-0025 version 2 conventions). ``` files_details = @@ -194,23 +194,18 @@ metadata = metadata_map = { - __RESERVE_KEYWORD_721_V4__ : bool, ; Long name to avoid conflict - - "721": + "721" : bounded_bytes => ; The "721" key encoded as UTF-8 bytes (0x373231) { - ; As many of the below as needed based on which reference tokens are added - "": + * policy_id : bounded_bytes => ; Policy ID encoded as bytes { - "" : metadata, - ; ... - "" : metadata, + * asset_name : bounded_bytes => metadata ; Asset name encoded as bytes (without label prefix) } } } metadata_field = - metadata ; For backwards-compatibility in v4 onward, a map itself is valid metadata - / metadata_map ; Multi-metadata is now supported as in CIP-0025 + metadata ; Direct metadata format (versions 1-3) + / metadata_map ; Nested map format with "721" key (version 4) ; A valid Uniform Resource Identifier (URI) as a UTF-8 encoded bytestring. ; The URI scheme must be one of `https` (HTTP), `ipfs` (IPFS), `ar` (Arweave) or `data` (on-chain). @@ -260,7 +255,7 @@ Example datum as JSON (direct metadata): } ``` -Example datum as JSON (721-style): +Example datum as JSON (nested map format): ```json { @@ -307,9 +302,9 @@ to lookup. The steps are 1. Construct `reference NFT` from `user token`: `d5e6bf0500378d4f0da4e8dde6becec7621cd8cbf5cbb9b87013d4cc.(100)TestToken` 2. Look up `reference NFT` and find the output it's locked in. 3. Get the datum from the output and lookup metadata by going into the first field of constructor 0. -4. Determine whether this is a direct metadata or the CIP-0025 map style using the `__RESERVE_KEYWORD_721_V4__` map value (if present, default false) +4. Determine whether this is direct metadata (map without "721" key) or nested map format (map with "721" key). 5. Convert to JSON and encode all string entries to UTF-8 if possible, otherwise leave them in hex. -6. For multi-map style metadata, return only the JSON values inside the matching path: `721`->>`policy_id`->>`asset_name` +6. For nested map format metadata, return only the metadata inside the matching path: map["721"][policy_id][asset_name], where policy_id and asset_name are matched without the asset_name_label prefix. ##### Retrieve metadata from a Plutus validator @@ -350,9 +345,9 @@ Example:\ This is either: 1. A low-level direct representation of the metadata, following closely the structure of the Cardano foundation off-chain metadata registry -2. A 721-ERC-style token mapping exactly matching the structure of CIP-0025 +2. A nested map structure following CIP-0025's organization with policy_id and asset_name as keys, where the outer map contains a "721" key whose value maps policy_id to asset_name to metadata -All UTF-8 encoded keys and values need to be converted into their respective byte's representation when creating the datum on-chain. +All UTF-8 encoded keys and values need to be converted into their respective byte's representation when creating the datum on-chain. In the nested map format (option 2), the "721" key, policy_id keys, and asset_name keys must be encoded as bounded_bytes (following CIP-0025 version 2 conventions). ``` ; Explanation here: https://developers.cardano.org/docs/native-tokens/token-registry/cardano-token-registry/ @@ -374,23 +369,18 @@ metadata = metadata_map = { - __RESERVE_KEYWORD_721_V4__ : bool, ; Long name to avoid conflict - - "721": + "721" : bounded_bytes => ; The "721" key encoded as UTF-8 bytes (0x373231) { - ; As many of the below as needed based on which reference tokens are added - "": + * policy_id : bounded_bytes => ; Policy ID encoded as bytes { - "" : metadata, - ; ... - "" : metadata, + * asset_name : bounded_bytes => metadata ; Asset name encoded as bytes (without label prefix) } } } metadata_field = - metadata ; For backwards-compatibility in v4 onward, a map itself is valid metadata - / metadata_map ; Multi-metadata is now supported as in CIP-0025 + metadata ; Direct metadata format (versions 1-3) + / metadata_map ; Nested map format with "721" key (version 4) ; A valid Uniform Resource Identifier (URI) as a UTF-8 encoded bytestring. ; The URI scheme must be one of `https` (HTTP), `ipfs` (IPFS), `ar` (Arweave) or `data` (on-chain). @@ -448,9 +438,9 @@ to lookup. The steps are 1. Construct `reference NFT` from `user token`: `d5e6bf0500378d4f0da4e8dde6becec7621cd8cbf5cbb9b87013d4cc.(100)TestToken` 2. Look up `reference NFT` and find the output it's locked in. 3. Get the datum from the output and lookup metadata by going into the first field of constructor 0. -4. Determine whether this is a direct metadata or the CIP-0025 map style using the `__RESERVE_KEYWORD_721_V4__` map value (if present, default false) +4. Determine whether this is direct metadata (map without "721" key) or nested map format (map with "721" key). 5. Convert to JSON and encode all string entries to UTF-8 if possible, otherwise leave them in hex. -6. For multi-map style metadata, return only the JSON values inside the matching path: `721`->>`policy_id`->>`asset_name` +6. For nested map format metadata, return only the metadata inside the matching path: map["721"][policy_id][asset_name], where policy_id and asset_name are matched without the asset_name_label prefix. ##### Retrieve metadata from a Plutus validator @@ -495,10 +485,10 @@ Example:\ This is either: -1. A low-level direct representation of the metadata, following closely the structure of CIP-0025 with the optional decimals field added -2. A 721-ERC-style token mapping exactly matching the structure of CIP-0025 +1. A low-level direct representation of the metadata, following closely the structure of CIP-0025 for individual asset metadata (name, image, files, etc.) with the optional decimals field added +2. A nested map structure following CIP-0025's organization with policy_id and asset_name as keys, where the outer map contains a "721" key whose value maps policy_id to asset_name to metadata -All UTF-8 encoded keys and values need to be converted into their respective byte's representation when creating the datum on-chain. +All UTF-8 encoded keys and values need to be converted into their respective byte's representation when creating the datum on-chain. In the nested map format (option 2), the "721" key, policy_id keys, and asset_name keys must be encoded as bounded_bytes (following CIP-0025 version 2 conventions). ``` files_details = @@ -525,23 +515,18 @@ metadata = metadata_map = { - __RESERVE_KEYWORD_721_V4__ : bool, ; Long name to avoid conflict - - "721": + "721" : bounded_bytes => ; The "721" key encoded as UTF-8 bytes (0x373231) { - ; As many of the below as needed based on which reference tokens are added - "": + * policy_id : bounded_bytes => ; Policy ID encoded as bytes { - "" : metadata, - ; ... - "" : metadata, + * asset_name : bounded_bytes => metadata ; Asset name encoded as bytes (without label prefix) } } } metadata_field = - metadata ; For backwards-compatibility in v4 onward, a map itself is valid metadata - / metadata_map ; Multi-metadata is now supported as in CIP-0025 + metadata ; Direct metadata format (versions 1-3) + / metadata_map ; Nested map format with "721" key (version 4) ; A valid Uniform Resource Identifier (URI) as a UTF-8 encoded bytestring. ; The URI scheme must be one of `https` (HTTP), `ipfs` (IPFS), `ar` (Arweave) or `data` (on-chain). @@ -615,9 +600,9 @@ to lookup. The steps are 1. Construct `reference NFT` from `user token`: `d5e6bf0500378d4f0da4e8dde6becec7621cd8cbf5cbb9b87013d4cc.(100)TestToken` 2. Look up `reference NFT` and find the output it's locked in. 3. Get the datum from the output and lookup metadata by going into the first field of constructor 0. -4. Determine whether this is a direct metadata or the CIP-0025 map style using the `__RESERVE_KEYWORD_721_V4__` map value (if present, default false) +4. Determine whether this is direct metadata (map without "721" key) or nested map format (map with "721" key). 5. Convert to JSON and encode all string entries to UTF-8 if possible, otherwise leave them in hex. -6. For multi-map style metadata, return only the JSON values inside the matching path: `721`->>`policy_id`->>`asset_name` +6. For nested map format metadata, return only the metadata inside the matching path: map["721"][policy_id][asset_name], where policy_id and asset_name are matched without the asset_name_label prefix. ##### Retrieve metadata from a Plutus validator @@ -696,7 +681,7 @@ versions of the affected tokens. `asset_name_labels` **MUST** only be marked obs #### version 4 -- Add backwards-compatible support for multi-asset 721-ERC-style metadata mappings +- Add support for nested map format following CIP-0025's policy_id -> asset_name structure, allowing multiple assets' metadata in a single datum. This format is backwards-compatible with versions 1-3, which only support direct metadata format. ## Rationale: how does this CIP achieve its goals? From 52fa8f219faef7250673be084d83271a56dcf629 Mon Sep 17 00:00:00 2001 From: Thaddeus Diamond Date: Tue, 6 Jan 2026 15:50:34 -0600 Subject: [PATCH 3/3] CIP-0068 | Add rationale for version 4 nested map format Add comprehensive rationale explaining the motivation for introducing the CIP-0025-compatible nested map format in version 4: - Addresses minUTxO cost barriers for large NFT collections - Enables metadata consolidation to reduce ADA locking (10-20% savings) - Improves migration path from CIP-0025 to CIP-0068 - Preserves backward compatibility through strict optionality This rationale explains the economic and practical benefits that led to the version 4 design decision. --- CIP-0068/README.md | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/CIP-0068/README.md b/CIP-0068/README.md index 2f8867c760..8f47a11f38 100644 --- a/CIP-0068/README.md +++ b/CIP-0068/README.md @@ -699,6 +699,45 @@ make use of this off-chain and on-chain. The security for the link is derived from the minting policy itself, so it's important to write the validator with the right constraints and rules since this CIP solely defines the interface to keep flexibility as high as possible. +### Rationale: Version 4 Nested Map Format + +The current design of CIP-0068 inadvertently creates a significant cost barrier for large NFT collections due to minimum-ADA requirements. As ADA approaches parity with USD, artists and platforms minting 5,000–10,000+ on-chain assets are increasingly impacted by the **minUTxO amplification effect**: the metadata-bearing reference scripts and datums mandated by CIP-0068 can cause **10–20% of project budgets** to be consumed purely by ADA locked in outputs, rather than by art production or ecosystem growth. + +This cost profile wasn't as visible when ADA was significantly cheaper, but it has now become an operational friction point across multiple creator workflows. + +The proposal aims to **reduce the minUTxO footprint** for CIP-0068 assets by allowing an **optional alternate metadata shape** that mirrors CIP-0025 (721-style metadata) while preserving CIP-0068's semantics. Concretely: + +#### 1. Dual-format Metadata Reduces Unnecessary ADA Locking + +Allowing a CIP-0025-shaped metadata payload means: + +* The on-chain metadata can consolidate across multiple reference tokens. +* The minUTxO requirement is correspondingly reduced. +* Large-scale mints return to economically sensible territory, especially for low-cost or promotional collections where the metadata weight provides no additional value to creators. + +This addresses a real-world pain point reported by multiple production-level minting pipelines, not just isolated cases. + +#### 2. Improved Migration Path from CIP-0025 to CIP-0068 + +A sizeable portion of the ecosystem still lives on CIP-0025, particularly older marketplaces and archived collections. When artists revisit or reissue older collections, the transition path to CIP-0068 is currently friction-heavy, requiring metadata restructuring and toolchain updates. + +Supporting a CIP-0025-compatible metadata envelope inside CIP-0068: + +* Enables forward migration without metadata rewrites. +* Preserves backward recognizability. +* Reduces engineering cost for wallets, indexers, and minting tools. + +#### 3. Strict Optionality Preserves Backward Compatibility + +This proposal does **not** modify or deprecate existing CIP-0068 patterns. +Instead, it introduces an explicitly flagged alternate metadata payload, using a reserved binary key or indicator to avoid collisions with existing fields. + +This allows: + +* Full backward compatibility. +* No disruptive changes for current indexers or marketplaces. +* Opt-in use where economic relief is necessary. + ### Backward Compatibility To keep metadata compatibility with changes coming in the future, we introduce a `version` field in the datum.