XCM NFT types that use Granular NFT traits#4300
XCM NFT types that use Granular NFT traits#4300franciscoaguirre merged 99 commits intoparitytech:masterfrom
Conversation
polkadot/xcm/xcm-builder/src/unique_instances/backed_derivative.rs
Outdated
Show resolved
Hide resolved
|
@franciscoaguirre @xlc This PR adds new granular NFT traits to frame-support and provides new XCM types, giving us the instruments to implement XCM NFT in any chain regardless of differences in NFT solutions used in the ecosystem (different pallets, which represent NFTs differently or incompatible with each other, or smart contract-based solutions). This PR could undoubtedly be divided into at least two. However, I decided to provide all the pieces at once so we can discuss the complete picture. I can divide the PR if needed. |
| // Convert an XCM Location into a local account id: | ||
| LocationToAccountId, | ||
| // Our chain's account ID type (we can't get away without mentioning it explicitly): | ||
| pub type UniquesTransactor = UniqueInstancesAdapter< |
There was a problem hiding this comment.
Is this a breaking change? Is the behavior different than before?
There was a problem hiding this comment.
👍 you added tests to check the behavior is the same
| let collection_details = | ||
| maybe_collection_details.as_mut().ok_or(Error::<T, I>::UnknownCollection)?; | ||
|
|
||
| // TODO should it be UnknownItem instead of UnknownCollection? |
There was a problem hiding this comment.
Probably but changing it is a breaking change
c1dbcb7
## Overview This PR provides new XCM types and tools for building NFT Asset Transactors. The new types use general and granular NFT traits from #5620. The new XCM adapters and utility types to work with NFTs can be considered the main deliverable of the **[XCM NFT proposal](https://polkadot.polkassembly.io/referenda/379)**. The new types use a more general approach, making integration into any chain with various NFT implementations easier. For instance, different implementations could use: * different ID assignment approaches * predefined NFT IDs - pallet-uniques, pallet-nfts * derived NFT IDs (NFT IDs are automatically derived from collection IDs) - Unique Network, ORML/Acala, Aventus * classless (collection-less) tokens - CoreTime NFTs, Aventus NFT Manager NFTs * in-class (in-collection) tokens - Unique Network, pallet-uniques, pallet-nfts, ORML/Acala * different approaches to storing associated data on-chain: * data is stored entirely separately from tokens - pallet-uniques * data is stored partially or entirely within tokens (i.e., burning a token means destroying it with its data) - pallet-nfts ([partially](https://github.com/paritytech/polkadot-sdk/blob/8b4cfda7589325d1a34f70b3770ab494a9d4052c/substrate/frame/nfts/src/features/create_delete_item.rs#L240-L241)), Unique Network, ORML/Acala With new types, these differences can be abstracted away. Moreover, the new types provide greater flexibility for supporting derivative NFTs, allowing several possible approaches depending on the given chain's team's goals or restrictions (see the `pallet-derivatives` crate docs and mock docs). Also, this is the PR I mentioned in the #4073 issue, as it can be viewed as the solution. In particular, the new adapter (`UniqueInstancesAdapter`) requires the `Update` operation with the `ChangeOwnerFrom` strategy. This brings the attention of both a developer and a reviewer to the `ChangeOwnerFrom` strategy (meaning that the transfer checks if the asset can be transferred from a given account to another account), both at trait bound and at the call site, without sacrificing the flexibility of the NFT traits. ## New types for xcm-builder and xcm-executor This PR introduces several XCM types. The `UniqueInstancesAdapter` is a new `TransactAsset` adapter that supersedes both `NonFungibleAdapter` and `NonFungiblesAdapter` (for reserve-based transfers only, as teleports can't be implemented appropriately without transferring the NFT metadata alongside it; no standard solution exists for that yet. Hopefully, the Felloweship RFC 125 ([PR](polkadot-fellows/RFCs#125), [text](https://github.com/polkadot-fellows/RFCs/blob/3a24444278f22dac414fbd2b5c4b205f73d78af7/text/0125-xcm-asset-metadata.md)) will help with that). Thanks to the new Matcher types, the new adapter can be used instead of both `NonFungibleAdapter` and `NonFungiblesAdapter`: * `MatchesInstance` (a trait) * `MatchInClassInstances` * `MatchClasslessInstances` The `UniqueInstancesAdapter` works with existing tokens only. To create new tokens (derivative ones), there is the `UniqueInstancesDepositAdapter`. See the `pallet-derivatives` mock and tests for the usage example. ### Superseding the old adapters for pallet-uniques Here is how the new `UniqueInstancesAdapter` in Westend Asset Hub replaces the `NonFungiblesAdapter`: ```rust /// Means for transacting unique assets. pub type UniquesTransactor = UniqueInstancesAdapter< AccountId, LocationToAccountId, MatchInClassInstances<UniquesConvertedConcreteId>, pallet_uniques::asset_ops::Item<Uniques>, >; ``` `MatchInClassInstances` allows us to reuse the already existing `UniquesConvertedConcreteId` matcher. The `pallet_uniques::asset_ops::Item<Uniques>` already implements the needed traits. So, migrating from the old adapter to the new one regarding runtime config changes is easy. >NOTE: `pallet_uniques::asset_ops::Item` grants access to the asset operations of NFT items of a given pallet-uniques instance, whereas `pallet_uniques::asset_ops::Collection` grants access to the collection operations. ### Declarative modification of an NFT engine If an NFT-hosting pallet only implements a transfer operation but not the `Stash` and `Restore`, one could declaratively add them using the `UniqueInstancesWithStashAccount` adapter. So, you can use it with the `UniqueInstancesAdapter` as follows: ```rust parameter_types! { pub StashAccountId: AccountId = /* Some Stash Account ID */; } type Transactor = UniqueInstancesAdapter< AccountId, LocationToAccountId, Matcher, UniqueInstancesWithStashAccount<StashAccountId, NftEngine>, >; ``` ### Supporting derivative NFTs (reserve-based model) There are several possible scenarios of supporting derivative NFTs (and their collections, if applicable). A separate NFT-hosting pallet instance could be configured to use XCM `AssetId` as collection ID and `AssetInstance` token ID. In that case, the asset transaction doesn't need any special treatment. However, registering NFT collections might require a special API. Also, if the NFT-hosting pallet can't be configured to use XCM ID types, we would need to store a mapping between the XCM ID of the original token and the derivative ID. See the `pallet-derivatives` crate docs for details. The example of its usage can be found in its mock and tests. #### TODO No benchmarks were run for `pallet-derivatives`, so there is no `weights.rs` for it yet. --------- Co-authored-by: Branislav Kontur <[email protected]> Co-authored-by: Francisco Aguirre <[email protected]>
Overview
This PR provides new XCM types and tools for building NFT Asset Transactors.
The new types use general and granular NFT traits from #5620.
The new XCM adapters and utility types to work with NFTs can be considered the main deliverable of the XCM NFT proposal. The new types use a more general approach, making integration into any chain with various NFT implementations easier.
For instance, different implementations could use:
With new types, these differences can be abstracted away.
Moreover, the new types provide greater flexibility for supporting derivative NFTs, allowing several possible approaches depending on the given chain's team's goals or restrictions (see the
pallet-derivativescrate docs and mock docs).Also, this is the PR I mentioned in the #4073 issue, as it can be viewed as the solution. In particular, the new adapter (
UniqueInstancesAdapter) requires theUpdateoperation with theChangeOwnerFromstrategy. This brings the attention of both a developer and a reviewer to theChangeOwnerFromstrategy (meaning that the transfer checks if the asset can be transferred from a given account to another account), both at trait bound and at the call site, without sacrificing the flexibility of the NFT traits.New types for xcm-builder and xcm-executor
This PR introduces several XCM types.
The
UniqueInstancesAdapteris a newTransactAssetadapter that supersedes bothNonFungibleAdapterandNonFungiblesAdapter(for reserve-based transfers only, as teleports can't be implemented appropriately without transferring the NFT metadata alongside it; no standard solution exists for that yet. Hopefully, the Felloweship RFC 125 (PR, text) will help with that).Thanks to the new Matcher types, the new adapter can be used instead of both
NonFungibleAdapterandNonFungiblesAdapter:MatchesInstance(a trait)MatchInClassInstancesMatchClasslessInstancesThe
UniqueInstancesAdapterworks with existing tokens only. To create new tokens (derivative ones), there is theUniqueInstancesDepositAdapter.See the
pallet-derivativesmock and tests for the usage example.Superseding the old adapters for pallet-uniques
Here is how the new
UniqueInstancesAdapterin Westend Asset Hub replaces theNonFungiblesAdapter:MatchInClassInstancesallows us to reuse the already existingUniquesConvertedConcreteIdmatcher.The
pallet_uniques::asset_ops::Item<Uniques>already implements the needed traits.So, migrating from the old adapter to the new one regarding runtime config changes is easy.
Declarative modification of an NFT engine
If an NFT-hosting pallet only implements a transfer operation but not the
StashandRestore, one could declaratively add them using theUniqueInstancesWithStashAccountadapter.So, you can use it with the
UniqueInstancesAdapteras follows:Supporting derivative NFTs (reserve-based model)
There are several possible scenarios of supporting derivative NFTs (and their collections, if applicable).
A separate NFT-hosting pallet instance could be configured to use XCM
AssetIdas collection ID andAssetInstancetoken ID. In that case, the asset transaction doesn't need any special treatment.However, registering NFT collections might require a special API.
Also, if the NFT-hosting pallet can't be configured to use XCM ID types, we would need to store a mapping between the XCM ID of the original token and the derivative ID.
See the
pallet-derivativescrate docs for details.The example of its usage can be found in its mock and tests.
TODO
No benchmarks were run for
pallet-derivatives, so there is noweights.rsfor it yet.