Partial metadata queries
In the context of the discussions regarding dynamic NFTs, I would like to bring up the question of reading parts of very large metadata to overcome the message size limit of 2MB for very large metadata. This limitation may currently prevent certain use cases with large metadata or require that certain metadata elements be moved out into an on-chain file system. This has also been discussed earlier and I would like to bring it up again because it may be important for adoption. This is probably a controversial proposal to make now.
In the spirit of a simple, yet powerful ICRC-7, partial metadata queries would allow to overcome the 2MB limits by allowing to query arbitrary parts of a Value
. The idea is essentially a very lightweight and readily available variant of functionality that is expected to become available in the context of the upcoming standards for metadata and is not thought of a replacement thereof, but rather to give the basic standard enough functionality to be applicable to a wide range of use cases.
Proposal
The proposal is to either extend ICRC-7 with a simple mechanism to achieve partial metadata queries of define a new ICRC standard that extends ICRC-7 with this functionality. The core part of such extension or proposal is a language for referring to parts of a Value
and definition of a method for partial metadata queries.
A canonical way to refer to a part of a metadata Value
is to refer to the sequence of Variants or fields one needs to traverse from the top-level Value
to the target element.
Canonical solution: Use /path/to/target/element
to traverse through the tree implied by the Value
until the target element is reached.
Example:
Consider an NFT for an in-game item that has an item_info
array of properties that can change during gameplay, assuming the metadata is structured as proposed here for dynamic metadata.
-
/Map/dynamic/Value/Map/item_info/Value/Array[1]
could refer to the second array element contained in the dynamic elementitem_info
contained in theMap
of theValue
in thedynamic
part of the NFT metadata. The root/
corresponds to theValue
instance being addressed, the followingMap
being the variant thereof. -
Value/Map/dynamic
would give us the fulldynamic
metadata element in the form of aValue
. -
/
is the wholeValue
-
/Map
would not be valid as it would not return aValue
, but avec record
Method specification
The batch interface of the method for querying partial metadata is defined as follow, where a list of token_id
s is given and for each token_id
a list of vpath
s (value paths) to query in its metadata. The interface is positional as usual for ICRC-7 in that the i
-th response element is the response to the i
-th request element.
icrc7_partial_metadata(vec token_id, vec vec vpath) -> vec vec Value
Allowing a vector of queries per request is likely good enough for capturing a large number of use cases and it is still simple. Further extensions to make it more powerful, more towards what XPath offers, is likely not really important for most use cases, but a discussion is required here.
Rationale
Without this method for accessing parts of the metadata of an NFT, the overall NFT metadata size is constrained to the maximum response size of the ICP, 2 MB. This partial read allows for large metadata Value
s to be defined and then only parts to be read in one go. Hashing large metadata for ICRC-3 is possible without issues, even if various metadata items are stored in different canisters, as the overall hash is computed by combining hashes of its constituents in a well-defined manner. Thus, adding this method would make the current standard applicable to a wider range of use cases without a big effort.
Having this extension available would allow ledgers to spread their metadata over multiple canisters as they want and allow for arbitrarily large metadata structures. They need to make sure that each “node” of the Value
of the metadata be smaller than 2MB. This does not impose undue constraints and can be accomplished by a design that puts all large assets in their own nodes that can be retrieved individually.
Conclusions
This is a strictly additive change and does not invalidate parts that have been implemented already in the various ongoing implementations, thus it should be fine to add in the current late stage to ICRC-7. It would add value in terms of overcoming the 2MB message size limit without adding much complexity. With such extension and solving the dynamic metadata issue, the NFT standard could be considered complete, yet still very simple.
What do others think about this? Any (strong) reason to not add this extension to ICRC-7 or define an extension standard?