mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-12 08:51:09 +00:00
NFTs 2.0 (#12765)
* Copy Uniques into Nfts * Connect new pallet * Update weights * Nfts: Multiple approvals (#12178) * multiple approvals * clear * tests & clean up * fix in logic & fmt * fix benchmarks * deadline * test deadline * current_block + deadline * update ApprovedTransfer event * benchmark * docs * Update frame/nfts/src/lib.rs Co-authored-by: Jegor Sidorenko <5252494+jsidorenko@users.noreply.github.com> * fmt fix * Update frame/nfts/src/lib.rs Co-authored-by: Jegor Sidorenko <5252494+jsidorenko@users.noreply.github.com> * update tests * anyone can cancel * Update frame/nfts/src/tests.rs Co-authored-by: Jegor Sidorenko <5252494+jsidorenko@users.noreply.github.com> * fmt * fix logic * unnecessary line * ".git/.scripts/bench-bot.sh" pallet dev pallet_nfts * Update frame/nfts/src/lib.rs * Update lib.rs * fmt * Update frame/nfts/src/lib.rs Co-authored-by: Squirrel <gilescope@gmail.com> * Update frame/nfts/src/lib.rs Co-authored-by: Squirrel <gilescope@gmail.com> * fmt * Update frame/nfts/src/lib.rs Co-authored-by: Squirrel <gilescope@gmail.com> * suggestion * new line * ".git/.scripts/bench-bot.sh" pallet dev pallet_nfts Co-authored-by: Jegor Sidorenko <5252494+jsidorenko@users.noreply.github.com> Co-authored-by: command-bot <> Co-authored-by: Squirrel <gilescope@gmail.com> * Fixes * cargo fmt * Fixes * Fixes * Fix CI * Nfts: Fix Auto-Increment (#12223) * commit * passing benchmarks * clean up * sync * runtime implementation * fix * fmt * fix benchmark * cfg * remove try-increment-id * remove unused error * impl Incrementable for unsigned types * clean up * fix in tests * not needed anymore * Use OptionQuery Co-authored-by: Keith Yeung <kungfukeith11@gmail.com> * Rename Origin to RuntimeOrigin * [Uniques V2] Tips (#12168) * Allow to add tips when buying an NFT * Chore * Rework tips feature * Add weights + benchmarks * Convert tuple to struct * Fix benchmark * ".git/.scripts/bench-bot.sh" pallet dev pallet_nfts * Update frame/nfts/src/benchmarking.rs Co-authored-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Fix benchmarks * Revert the bounded_vec![] approach * ".git/.scripts/bench-bot.sh" pallet dev pallet_nfts Co-authored-by: command-bot <> Co-authored-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * [Uniques V2] Atomic NFTs swap (#12285) * Atomic NFTs swap * Fmt * Fix benchmark * Rename swap -> atomic_swap * Update target balance * Rollback * Fix * ".git/.scripts/bench-bot.sh" pallet dev pallet_nfts * Make desired item optional * Apply suggestions * Update frame/nfts/src/features/atomic_swap.rs Co-authored-by: Squirrel <gilescope@gmail.com> * Rename fields * Optimisation * Add a comment * deadline -> maybe_deadline * Add docs * Change comments * Add price direction field * ".git/.scripts/bench-bot.sh" pallet dev pallet_nfts * Wrap price and direction * Fix benchmarks * Use ensure! instead of if {} * Make duration param mandatory and limit it to MaxDeadlineDuration * Make the code safer * Fix clippy * Chore * Remove unused vars * try * try 2 * try 3 Co-authored-by: command-bot <> Co-authored-by: Squirrel <gilescope@gmail.com> * [Uniques V2] Feature flags (#12367) * Basics * WIP: change the data format * Refactor * Remove redundant new() method * Rename settings * Enable tests * Chore * Change params order * Delete the config on collection removal * Chore * Remove redundant system features * Rename force_item_status to force_collection_status * Update node runtime * Chore * Remove thaw_collection * Chore * Connect collection.is_frozen to config * Allow to lock the collection in a new way * Move free_holding into settings * Connect collection's metadata locker to feature flags * DRY * Chore * Connect pallet level feature flags * Prepare tests for the new changes * Implement Item settings * Allow to lock the metadata or attributes of an item * Common -> Settings * Extract settings related code to a separate file * Move feature flag checks inside the do_* methods * Split settings.rs into parts * Extract repeated code into macro * Extract macros into their own file * Chore * Fix traits * Fix traits * Test SystemFeatures * Fix benchmarks * Add missing benchmark * Fix node/runtime/lib.rs * ".git/.scripts/bench-bot.sh" pallet dev pallet_nfts * Keep item's config on burn if it's not empty * Fix the merge artifacts * Fmt * Add SystemFeature::NoSwaps check * Rename SystemFeatures to PalletFeatures * Rename errors * Add docs * Change error message * Rework pallet features * Move macros * Change comments * Fmt * Refactor Incrementable * Use pub(crate) for do_* functions * Update comments * Refactor freeze and lock functions * Rework Collection config and Item confg api * Chore * Make clippy happy * Chore * Update comment * RequiredDeposit => DepositRequired * Address comments Co-authored-by: command-bot <> * [Uniques V2] Refactor roles (#12437) * Basics * WIP: change the data format * Refactor * Remove redundant new() method * Rename settings * Enable tests * Chore * Change params order * Delete the config on collection removal * Chore * Remove redundant system features * Rename force_item_status to force_collection_status * Update node runtime * Chore * Remove thaw_collection * Chore * Connect collection.is_frozen to config * Allow to lock the collection in a new way * Move free_holding into settings * Connect collection's metadata locker to feature flags * DRY * Chore * Connect pallet level feature flags * Prepare tests for the new changes * Implement Item settings * Allow to lock the metadata or attributes of an item * Common -> Settings * Extract settings related code to a separate file * Move feature flag checks inside the do_* methods * Split settings.rs into parts * Extract repeated code into macro * Extract macros into their own file * Chore * Fix traits * Fix traits * Test SystemFeatures * Fix benchmarks * Add missing benchmark * Fix node/runtime/lib.rs * ".git/.scripts/bench-bot.sh" pallet dev pallet_nfts * Keep item's config on burn if it's not empty * Fix the merge artifacts * Fmt * Add SystemFeature::NoSwaps check * Refactor roles structure * Rename SystemFeatures to PalletFeatures * Rename errors * Add docs * Change error message * Rework pallet features * Move macros * Change comments * Fmt * Refactor Incrementable * Use pub(crate) for do_* functions * Update comments * Refactor freeze and lock functions * Rework Collection config and Item confg api * Chore * Make clippy happy * Chore * Fix artifacts * Address comments * Further refactoring * Add comments * Add tests for group_roles_by_account() * Update frame/nfts/src/impl_nonfungibles.rs * Add test * Replace Itertools group_by with a custom implementation * ItemsNotTransferable => ItemsNonTransferable * Update frame/nfts/src/features/roles.rs Co-authored-by: Muharem Ismailov <ismailov.m.h@gmail.com> * Address PR comments * Add missed comment Co-authored-by: command-bot <> Co-authored-by: Muharem Ismailov <ismailov.m.h@gmail.com> * Fix copy * Remove storage_prefix * Remove transactional * Update comment * [Uniques V2] Minting options (#12483) * Basics * WIP: change the data format * Refactor * Remove redundant new() method * Rename settings * Enable tests * Chore * Change params order * Delete the config on collection removal * Chore * Remove redundant system features * Rename force_item_status to force_collection_status * Update node runtime * Chore * Remove thaw_collection * Chore * Connect collection.is_frozen to config * Allow to lock the collection in a new way * Move free_holding into settings * Connect collection's metadata locker to feature flags * DRY * Chore * Connect pallet level feature flags * Prepare tests for the new changes * Implement Item settings * Allow to lock the metadata or attributes of an item * Common -> Settings * Extract settings related code to a separate file * Move feature flag checks inside the do_* methods * Split settings.rs into parts * Extract repeated code into macro * Extract macros into their own file * Chore * Fix traits * Fix traits * Test SystemFeatures * Fix benchmarks * Add missing benchmark * Fix node/runtime/lib.rs * ".git/.scripts/bench-bot.sh" pallet dev pallet_nfts * Keep item's config on burn if it's not empty * Fix the merge artifacts * Fmt * Add SystemFeature::NoSwaps check * Rename SystemFeatures to PalletFeatures * Rename errors * Add docs * Change error message * Change the format of CollectionConfig to store more data * Move max supply to the CollectionConfig and allow to change it * Remove ItemConfig from the mint() function and use the one set in mint settings * Add different mint options * Allow to change the mint settings * Add a force_mint() method * Check mint params * Some optimisations * Cover with tests * Remove merge artifacts * Chore * Use the new has_role() method * Rework item deposits * More tests * Refactoring * Address comments * Refactor lock_collection() * Update frame/nfts/src/types.rs Co-authored-by: Squirrel <gilescope@gmail.com> * Update frame/nfts/src/types.rs Co-authored-by: Squirrel <gilescope@gmail.com> * Update frame/nfts/src/lib.rs Co-authored-by: Squirrel <gilescope@gmail.com> * Update frame/nfts/src/lib.rs Co-authored-by: Squirrel <gilescope@gmail.com> * Private => Issuer * Add more tests * Fix benchmarks * Add benchmarks for new methods * [Uniques v2] Refactoring (#12570) * Move do_set_price() and do_buy_item() to buy_sell.rs * Move approvals to feature file * Move metadata to feature files * Move the rest of methods to feature files * Remove artifacts * Split force_collection_status into 2 methods * Fix benchmarks * Fix benchmarks * Update deps Co-authored-by: command-bot <> Co-authored-by: Squirrel <gilescope@gmail.com> * [Uniques V2] Smart attributes (#12702) * Basics * WIP: change the data format * Refactor * Remove redundant new() method * Rename settings * Enable tests * Chore * Change params order * Delete the config on collection removal * Chore * Remove redundant system features * Rename force_item_status to force_collection_status * Update node runtime * Chore * Remove thaw_collection * Chore * Connect collection.is_frozen to config * Allow to lock the collection in a new way * Move free_holding into settings * Connect collection's metadata locker to feature flags * DRY * Chore * Connect pallet level feature flags * Prepare tests for the new changes * Implement Item settings * Allow to lock the metadata or attributes of an item * Common -> Settings * Extract settings related code to a separate file * Move feature flag checks inside the do_* methods * Split settings.rs into parts * Extract repeated code into macro * Extract macros into their own file * Chore * Fix traits * Fix traits * Test SystemFeatures * Fix benchmarks * Add missing benchmark * Fix node/runtime/lib.rs * ".git/.scripts/bench-bot.sh" pallet dev pallet_nfts * Keep item's config on burn if it's not empty * Fix the merge artifacts * Fmt * Add SystemFeature::NoSwaps check * Rename SystemFeatures to PalletFeatures * Rename errors * Add docs * Change error message * Change the format of CollectionConfig to store more data * Move max supply to the CollectionConfig and allow to change it * Remove ItemConfig from the mint() function and use the one set in mint settings * Add different mint options * Allow to change the mint settings * Add a force_mint() method * Check mint params * Some optimisations * Cover with tests * Remove merge artifacts * Chore * Use the new has_role() method * Rework item deposits * More tests * Refactoring * Address comments * Refactor lock_collection() * Update frame/nfts/src/types.rs Co-authored-by: Squirrel <gilescope@gmail.com> * Update frame/nfts/src/types.rs Co-authored-by: Squirrel <gilescope@gmail.com> * Update frame/nfts/src/lib.rs Co-authored-by: Squirrel <gilescope@gmail.com> * Update frame/nfts/src/lib.rs Co-authored-by: Squirrel <gilescope@gmail.com> * Private => Issuer * Add more tests * Fix benchmarks * Add benchmarks for new methods * [Uniques v2] Refactoring (#12570) * Move do_set_price() and do_buy_item() to buy_sell.rs * Move approvals to feature file * Move metadata to feature files * Move the rest of methods to feature files * Remove artifacts * Smart attributes * Split force_collection_status into 2 methods * Fix benchmarks * Fix benchmarks * Update deps * Fix merge artifact * Weights + benchmarks + docs * Change params order * Chore * Update frame/nfts/src/lib.rs Co-authored-by: Squirrel <gilescope@gmail.com> * Update frame/nfts/src/lib.rs Co-authored-by: Squirrel <gilescope@gmail.com> * Update docs * Update frame/nfts/src/lib.rs Co-authored-by: Squirrel <gilescope@gmail.com> * Add PalletId * Chore * Add tests * More tests * Add doc * Update errors snapshots * Ensure we track the owner_deposit field correctly Co-authored-by: command-bot <> Co-authored-by: Squirrel <gilescope@gmail.com> * [Uniques V2] Final improvements (#12736) * Use KeyPrefixIterator instead of Box * Change create_collection() * Restrict from claiming NFTs twice * Update Readme * Remove dead code * Refactoring * Update readme * Fix clippy * Update frame/nfts/src/lib.rs Co-authored-by: Squirrel <gilescope@gmail.com> * ".git/.scripts/bench-bot.sh" pallet dev pallet_nfts * Update docs * Typo * Fix benchmarks * Add more docs * DepositRequired setting should affect only the attributes within the CollectionOwner namespace * [NFTs] Implement missed methods to set the attributes from other pallets (#12919) * Implement missed methods to set the attributes from other pallets * Revert snapshots * Update snapshot * Update snapshot * Revert snapshot changes * Update snapshots * Yet another snapshot update.. * Update frame/support/src/traits/tokens/nonfungible_v2.rs Co-authored-by: joe petrowski <25483142+joepetrowski@users.noreply.github.com> * Update frame/support/src/traits/tokens/nonfungible_v2.rs Co-authored-by: joe petrowski <25483142+joepetrowski@users.noreply.github.com> * Update frame/support/src/traits/tokens/nonfungible_v2.rs Co-authored-by: joe petrowski <25483142+joepetrowski@users.noreply.github.com> * Update frame/support/src/traits/tokens/nonfungibles_v2.rs Co-authored-by: joe petrowski <25483142+joepetrowski@users.noreply.github.com> * Update frame/nfts/src/lib.rs Co-authored-by: joe petrowski <25483142+joepetrowski@users.noreply.github.com> * Update frame/nfts/src/lib.rs Co-authored-by: joe petrowski <25483142+joepetrowski@users.noreply.github.com> * Update frame/nfts/src/lib.rs Co-authored-by: joe petrowski <25483142+joepetrowski@users.noreply.github.com> * Update frame/nfts/src/lib.rs Co-authored-by: joe petrowski <25483142+joepetrowski@users.noreply.github.com> * Update frame/nfts/src/lib.rs Co-authored-by: joe petrowski <25483142+joepetrowski@users.noreply.github.com> * Update frame/support/src/traits/tokens/nonfungible_v2.rs * Update frame/nfts/src/lib.rs Co-authored-by: joe petrowski <25483142+joepetrowski@users.noreply.github.com> * Update frame/support/src/traits/tokens/nonfungibles_v2.rs Co-authored-by: joe petrowski <25483142+joepetrowski@users.noreply.github.com> * Update frame/nfts/src/lib.rs Co-authored-by: joe petrowski <25483142+joepetrowski@users.noreply.github.com> * Update frame/nfts/src/lib.rs Co-authored-by: joe petrowski <25483142+joepetrowski@users.noreply.github.com> * Update frame/nfts/src/lib.rs Co-authored-by: joe petrowski <25483142+joepetrowski@users.noreply.github.com> * Update frame/nfts/src/lib.rs Co-authored-by: joe petrowski <25483142+joepetrowski@users.noreply.github.com> * Address comments * [NFTs] Add the new `owner` param to mint() method (#12997) * Add the new `owner` param to mint() method * Fmt * Address comments * ".git/.scripts/bench-bot.sh" pallet dev pallet_nfts * Update frame/nfts/src/common_functions.rs Co-authored-by: joe petrowski <25483142+joepetrowski@users.noreply.github.com> * Update frame/nfts/src/types.rs Co-authored-by: joe petrowski <25483142+joepetrowski@users.noreply.github.com> * Update frame/nfts/src/types.rs Co-authored-by: joe petrowski <25483142+joepetrowski@users.noreply.github.com> * Update frame/nfts/src/types.rs Co-authored-by: joe petrowski <25483142+joepetrowski@users.noreply.github.com> * Update frame/nfts/src/types.rs Co-authored-by: joe petrowski <25483142+joepetrowski@users.noreply.github.com> * Update frame/nfts/src/types.rs Co-authored-by: joe petrowski <25483142+joepetrowski@users.noreply.github.com> * Add call indexes * Update snapshots Co-authored-by: Sergej Sakac <73715684+Szegoo@users.noreply.github.com> Co-authored-by: Squirrel <gilescope@gmail.com> Co-authored-by: Keith Yeung <kungfukeith11@gmail.com> Co-authored-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> Co-authored-by: Muharem Ismailov <ismailov.m.h@gmail.com> Co-authored-by: command-bot <> Co-authored-by: joe petrowski <25483142+joepetrowski@users.noreply.github.com>
This commit is contained in:
@@ -23,9 +23,11 @@ pub mod fungibles;
|
||||
pub mod imbalance;
|
||||
mod misc;
|
||||
pub mod nonfungible;
|
||||
pub mod nonfungible_v2;
|
||||
pub mod nonfungibles;
|
||||
pub mod nonfungibles_v2;
|
||||
pub use imbalance::Imbalance;
|
||||
pub use misc::{
|
||||
AssetId, Balance, BalanceConversion, BalanceStatus, DepositConsequence, ExistenceRequirement,
|
||||
Locker, WithdrawConsequence, WithdrawReasons,
|
||||
AssetId, AttributeNamespace, Balance, BalanceConversion, BalanceStatus, DepositConsequence,
|
||||
ExistenceRequirement, Locker, WithdrawConsequence, WithdrawReasons,
|
||||
};
|
||||
|
||||
@@ -126,6 +126,21 @@ pub enum BalanceStatus {
|
||||
Reserved,
|
||||
}
|
||||
|
||||
/// Attribute namespaces for non-fungible tokens.
|
||||
#[derive(
|
||||
Clone, Encode, Decode, Eq, PartialEq, RuntimeDebug, scale_info::TypeInfo, MaxEncodedLen,
|
||||
)]
|
||||
pub enum AttributeNamespace<AccountId> {
|
||||
/// An attribute was set by the pallet.
|
||||
Pallet,
|
||||
/// An attribute was set by collection's owner.
|
||||
CollectionOwner,
|
||||
/// An attribute was set by item's owner.
|
||||
ItemOwner,
|
||||
/// An attribute was set by pre-approved account.
|
||||
Account(AccountId),
|
||||
}
|
||||
|
||||
bitflags::bitflags! {
|
||||
/// Reasons for moving funds out of an account.
|
||||
#[derive(Encode, Decode, MaxEncodedLen)]
|
||||
|
||||
@@ -0,0 +1,248 @@
|
||||
// This file is part of Substrate.
|
||||
|
||||
// Copyright (C) 2019-2022 Parity Technologies (UK) Ltd.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
//! Traits for dealing with a single non-fungible item.
|
||||
//!
|
||||
//! This assumes a single-level namespace identified by `Inspect::ItemId`, and could
|
||||
//! reasonably be implemented by pallets that want to expose a single collection of NFT-like
|
||||
//! objects.
|
||||
//!
|
||||
//! For an NFT API that has dual-level namespacing, the traits in `nonfungibles` are better to
|
||||
//! use.
|
||||
|
||||
use super::nonfungibles_v2 as nonfungibles;
|
||||
use crate::{
|
||||
dispatch::DispatchResult,
|
||||
traits::{tokens::misc::AttributeNamespace, Get},
|
||||
};
|
||||
use codec::{Decode, Encode};
|
||||
use sp_runtime::TokenError;
|
||||
use sp_std::prelude::*;
|
||||
|
||||
/// Trait for providing an interface to a read-only NFT-like item.
|
||||
pub trait Inspect<AccountId> {
|
||||
/// Type for identifying an item.
|
||||
type ItemId;
|
||||
|
||||
/// Returns the owner of `item`, or `None` if the item doesn't exist or has no
|
||||
/// owner.
|
||||
fn owner(item: &Self::ItemId) -> Option<AccountId>;
|
||||
|
||||
/// Returns the attribute value of `item` corresponding to `key`.
|
||||
///
|
||||
/// By default this is `None`; no attributes are defined.
|
||||
fn attribute(
|
||||
_item: &Self::ItemId,
|
||||
_namespace: &AttributeNamespace<AccountId>,
|
||||
_key: &[u8],
|
||||
) -> Option<Vec<u8>> {
|
||||
None
|
||||
}
|
||||
|
||||
/// Returns the strongly-typed attribute value of `item` corresponding to `key`.
|
||||
///
|
||||
/// By default this just attempts to use `attribute`.
|
||||
fn typed_attribute<K: Encode, V: Decode>(
|
||||
item: &Self::ItemId,
|
||||
namespace: &AttributeNamespace<AccountId>,
|
||||
key: &K,
|
||||
) -> Option<V> {
|
||||
key.using_encoded(|d| Self::attribute(item, namespace, d))
|
||||
.and_then(|v| V::decode(&mut &v[..]).ok())
|
||||
}
|
||||
|
||||
/// Returns `true` if the `item` may be transferred.
|
||||
///
|
||||
/// Default implementation is that all items are transferable.
|
||||
fn can_transfer(_item: &Self::ItemId) -> bool {
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
/// Interface for enumerating items in existence or owned by a given account over a collection
|
||||
/// of NFTs.
|
||||
pub trait InspectEnumerable<AccountId>: Inspect<AccountId> {
|
||||
/// The iterator type for [`Self::items`].
|
||||
type ItemsIterator: Iterator<Item = Self::ItemId>;
|
||||
/// The iterator type for [`Self::owned`].
|
||||
type OwnedIterator: Iterator<Item = Self::ItemId>;
|
||||
|
||||
/// Returns an iterator of the items within a `collection` in existence.
|
||||
fn items() -> Self::ItemsIterator;
|
||||
|
||||
/// Returns an iterator of the items of all collections owned by `who`.
|
||||
fn owned(who: &AccountId) -> Self::OwnedIterator;
|
||||
}
|
||||
|
||||
/// Trait for providing an interface for NFT-like items which may be minted, burned and/or have
|
||||
/// attributes set on them.
|
||||
pub trait Mutate<AccountId, ItemConfig>: Inspect<AccountId> {
|
||||
/// Mint some `item` to be owned by `who`.
|
||||
///
|
||||
/// By default, this is not a supported operation.
|
||||
fn mint_into(
|
||||
_item: &Self::ItemId,
|
||||
_who: &AccountId,
|
||||
_config: &ItemConfig,
|
||||
_deposit_collection_owner: bool,
|
||||
) -> DispatchResult {
|
||||
Err(TokenError::Unsupported.into())
|
||||
}
|
||||
|
||||
/// Burn some `item`.
|
||||
///
|
||||
/// By default, this is not a supported operation.
|
||||
fn burn(_item: &Self::ItemId, _maybe_check_owner: Option<&AccountId>) -> DispatchResult {
|
||||
Err(TokenError::Unsupported.into())
|
||||
}
|
||||
|
||||
/// Set attribute `value` of `item`'s `key`.
|
||||
///
|
||||
/// By default, this is not a supported operation.
|
||||
fn set_attribute(_item: &Self::ItemId, _key: &[u8], _value: &[u8]) -> DispatchResult {
|
||||
Err(TokenError::Unsupported.into())
|
||||
}
|
||||
|
||||
/// Attempt to set the strongly-typed attribute `value` of `item`'s `key`.
|
||||
///
|
||||
/// By default this just attempts to use `set_attribute`.
|
||||
fn set_typed_attribute<K: Encode, V: Encode>(
|
||||
item: &Self::ItemId,
|
||||
key: &K,
|
||||
value: &V,
|
||||
) -> DispatchResult {
|
||||
key.using_encoded(|k| value.using_encoded(|v| Self::set_attribute(item, k, v)))
|
||||
}
|
||||
}
|
||||
|
||||
/// Trait for transferring a non-fungible item.
|
||||
pub trait Transfer<AccountId>: Inspect<AccountId> {
|
||||
/// Transfer `item` into `destination` account.
|
||||
fn transfer(item: &Self::ItemId, destination: &AccountId) -> DispatchResult;
|
||||
}
|
||||
|
||||
/// Convert a `nonfungibles` trait implementation into a `nonfungible` trait implementation by
|
||||
/// identifying a single item.
|
||||
pub struct ItemOf<
|
||||
F: nonfungibles::Inspect<AccountId>,
|
||||
A: Get<<F as nonfungibles::Inspect<AccountId>>::CollectionId>,
|
||||
AccountId,
|
||||
>(sp_std::marker::PhantomData<(F, A, AccountId)>);
|
||||
|
||||
impl<
|
||||
F: nonfungibles::Inspect<AccountId>,
|
||||
A: Get<<F as nonfungibles::Inspect<AccountId>>::CollectionId>,
|
||||
AccountId,
|
||||
> Inspect<AccountId> for ItemOf<F, A, AccountId>
|
||||
{
|
||||
type ItemId = <F as nonfungibles::Inspect<AccountId>>::ItemId;
|
||||
fn owner(item: &Self::ItemId) -> Option<AccountId> {
|
||||
<F as nonfungibles::Inspect<AccountId>>::owner(&A::get(), item)
|
||||
}
|
||||
fn attribute(
|
||||
item: &Self::ItemId,
|
||||
namespace: &AttributeNamespace<AccountId>,
|
||||
key: &[u8],
|
||||
) -> Option<Vec<u8>> {
|
||||
<F as nonfungibles::Inspect<AccountId>>::attribute(&A::get(), item, namespace, key)
|
||||
}
|
||||
fn typed_attribute<K: Encode, V: Decode>(
|
||||
item: &Self::ItemId,
|
||||
namespace: &AttributeNamespace<AccountId>,
|
||||
key: &K,
|
||||
) -> Option<V> {
|
||||
<F as nonfungibles::Inspect<AccountId>>::typed_attribute(&A::get(), item, namespace, key)
|
||||
}
|
||||
fn can_transfer(item: &Self::ItemId) -> bool {
|
||||
<F as nonfungibles::Inspect<AccountId>>::can_transfer(&A::get(), item)
|
||||
}
|
||||
}
|
||||
|
||||
impl<
|
||||
F: nonfungibles::InspectEnumerable<AccountId>,
|
||||
A: Get<<F as nonfungibles::Inspect<AccountId>>::CollectionId>,
|
||||
AccountId,
|
||||
> InspectEnumerable<AccountId> for ItemOf<F, A, AccountId>
|
||||
{
|
||||
type ItemsIterator = <F as nonfungibles::InspectEnumerable<AccountId>>::ItemsIterator;
|
||||
type OwnedIterator =
|
||||
<F as nonfungibles::InspectEnumerable<AccountId>>::OwnedInCollectionIterator;
|
||||
|
||||
fn items() -> Self::ItemsIterator {
|
||||
<F as nonfungibles::InspectEnumerable<AccountId>>::items(&A::get())
|
||||
}
|
||||
fn owned(who: &AccountId) -> Self::OwnedIterator {
|
||||
<F as nonfungibles::InspectEnumerable<AccountId>>::owned_in_collection(&A::get(), who)
|
||||
}
|
||||
}
|
||||
|
||||
impl<
|
||||
F: nonfungibles::Mutate<AccountId, ItemConfig>,
|
||||
A: Get<<F as nonfungibles::Inspect<AccountId>>::CollectionId>,
|
||||
AccountId,
|
||||
ItemConfig,
|
||||
> Mutate<AccountId, ItemConfig> for ItemOf<F, A, AccountId>
|
||||
{
|
||||
fn mint_into(
|
||||
item: &Self::ItemId,
|
||||
who: &AccountId,
|
||||
config: &ItemConfig,
|
||||
deposit_collection_owner: bool,
|
||||
) -> DispatchResult {
|
||||
<F as nonfungibles::Mutate<AccountId, ItemConfig>>::mint_into(
|
||||
&A::get(),
|
||||
item,
|
||||
who,
|
||||
config,
|
||||
deposit_collection_owner,
|
||||
)
|
||||
}
|
||||
fn burn(item: &Self::ItemId, maybe_check_owner: Option<&AccountId>) -> DispatchResult {
|
||||
<F as nonfungibles::Mutate<AccountId, ItemConfig>>::burn(&A::get(), item, maybe_check_owner)
|
||||
}
|
||||
fn set_attribute(item: &Self::ItemId, key: &[u8], value: &[u8]) -> DispatchResult {
|
||||
<F as nonfungibles::Mutate<AccountId, ItemConfig>>::set_attribute(
|
||||
&A::get(),
|
||||
item,
|
||||
key,
|
||||
value,
|
||||
)
|
||||
}
|
||||
fn set_typed_attribute<K: Encode, V: Encode>(
|
||||
item: &Self::ItemId,
|
||||
key: &K,
|
||||
value: &V,
|
||||
) -> DispatchResult {
|
||||
<F as nonfungibles::Mutate<AccountId, ItemConfig>>::set_typed_attribute(
|
||||
&A::get(),
|
||||
item,
|
||||
key,
|
||||
value,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl<
|
||||
F: nonfungibles::Transfer<AccountId>,
|
||||
A: Get<<F as nonfungibles::Inspect<AccountId>>::CollectionId>,
|
||||
AccountId,
|
||||
> Transfer<AccountId> for ItemOf<F, A, AccountId>
|
||||
{
|
||||
fn transfer(item: &Self::ItemId, destination: &AccountId) -> DispatchResult {
|
||||
<F as nonfungibles::Transfer<AccountId>>::transfer(&A::get(), item, destination)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,257 @@
|
||||
// This file is part of Substrate.
|
||||
|
||||
// Copyright (C) 2019-2022 Parity Technologies (UK) Ltd.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
//! Traits for dealing with multiple collections of non-fungible items.
|
||||
//!
|
||||
//! This assumes a dual-level namespace identified by `Inspect::ItemId`, and could
|
||||
//! reasonably be implemented by pallets which want to expose multiple independent collections of
|
||||
//! NFT-like objects.
|
||||
//!
|
||||
//! For an NFT API which has single-level namespacing, the traits in `nonfungible` are better to
|
||||
//! use.
|
||||
//!
|
||||
//! Implementations of these traits may be converted to implementations of corresponding
|
||||
//! `nonfungible` traits by using the `nonfungible::ItemOf` type adapter.
|
||||
|
||||
use crate::{
|
||||
dispatch::{DispatchError, DispatchResult},
|
||||
traits::tokens::misc::AttributeNamespace,
|
||||
};
|
||||
use codec::{Decode, Encode};
|
||||
use sp_runtime::TokenError;
|
||||
use sp_std::prelude::*;
|
||||
|
||||
/// Trait for providing an interface to many read-only NFT-like sets of items.
|
||||
pub trait Inspect<AccountId> {
|
||||
/// Type for identifying an item.
|
||||
type ItemId;
|
||||
|
||||
/// Type for identifying a collection (an identifier for an independent collection of
|
||||
/// items).
|
||||
type CollectionId;
|
||||
|
||||
/// Returns the owner of `item` of `collection`, or `None` if the item doesn't exist
|
||||
/// (or somehow has no owner).
|
||||
fn owner(collection: &Self::CollectionId, item: &Self::ItemId) -> Option<AccountId>;
|
||||
|
||||
/// Returns the owner of the `collection`, if there is one. For many NFTs this may not
|
||||
/// make any sense, so users of this API should not be surprised to find a collection
|
||||
/// results in `None` here.
|
||||
fn collection_owner(_collection: &Self::CollectionId) -> Option<AccountId> {
|
||||
None
|
||||
}
|
||||
|
||||
/// Returns the attribute value of `item` of `collection` corresponding to `key`.
|
||||
///
|
||||
/// By default this is `None`; no attributes are defined.
|
||||
fn attribute(
|
||||
_collection: &Self::CollectionId,
|
||||
_item: &Self::ItemId,
|
||||
_namespace: &AttributeNamespace<AccountId>,
|
||||
_key: &[u8],
|
||||
) -> Option<Vec<u8>> {
|
||||
None
|
||||
}
|
||||
|
||||
/// Returns the strongly-typed attribute value of `item` of `collection` corresponding to
|
||||
/// `key`.
|
||||
///
|
||||
/// By default this just attempts to use `attribute`.
|
||||
fn typed_attribute<K: Encode, V: Decode>(
|
||||
collection: &Self::CollectionId,
|
||||
item: &Self::ItemId,
|
||||
namespace: &AttributeNamespace<AccountId>,
|
||||
key: &K,
|
||||
) -> Option<V> {
|
||||
key.using_encoded(|d| Self::attribute(collection, item, namespace, d))
|
||||
.and_then(|v| V::decode(&mut &v[..]).ok())
|
||||
}
|
||||
|
||||
/// Returns the attribute value of `collection` corresponding to `key`.
|
||||
///
|
||||
/// By default this is `None`; no attributes are defined.
|
||||
fn collection_attribute(_collection: &Self::CollectionId, _key: &[u8]) -> Option<Vec<u8>> {
|
||||
None
|
||||
}
|
||||
|
||||
/// Returns the strongly-typed attribute value of `collection` corresponding to `key`.
|
||||
///
|
||||
/// By default this just attempts to use `collection_attribute`.
|
||||
fn typed_collection_attribute<K: Encode, V: Decode>(
|
||||
collection: &Self::CollectionId,
|
||||
key: &K,
|
||||
) -> Option<V> {
|
||||
key.using_encoded(|d| Self::collection_attribute(collection, d))
|
||||
.and_then(|v| V::decode(&mut &v[..]).ok())
|
||||
}
|
||||
|
||||
/// Returns `true` if the `item` of `collection` may be transferred.
|
||||
///
|
||||
/// Default implementation is that all items are transferable.
|
||||
fn can_transfer(_collection: &Self::CollectionId, _item: &Self::ItemId) -> bool {
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
/// Interface for enumerating items in existence or owned by a given account over many collections
|
||||
/// of NFTs.
|
||||
pub trait InspectEnumerable<AccountId>: Inspect<AccountId> {
|
||||
/// The iterator type for [`Self::collections`].
|
||||
type CollectionsIterator: Iterator<Item = Self::CollectionId>;
|
||||
/// The iterator type for [`Self::items`].
|
||||
type ItemsIterator: Iterator<Item = Self::ItemId>;
|
||||
/// The iterator type for [`Self::owned`].
|
||||
type OwnedIterator: Iterator<Item = (Self::CollectionId, Self::ItemId)>;
|
||||
/// The iterator type for [`Self::owned_in_collection`].
|
||||
type OwnedInCollectionIterator: Iterator<Item = Self::ItemId>;
|
||||
|
||||
/// Returns an iterator of the collections in existence.
|
||||
fn collections() -> Self::CollectionsIterator;
|
||||
|
||||
/// Returns an iterator of the items of a `collection` in existence.
|
||||
fn items(collection: &Self::CollectionId) -> Self::ItemsIterator;
|
||||
|
||||
/// Returns an iterator of the items of all collections owned by `who`.
|
||||
fn owned(who: &AccountId) -> Self::OwnedIterator;
|
||||
|
||||
/// Returns an iterator of the items of `collection` owned by `who`.
|
||||
fn owned_in_collection(
|
||||
collection: &Self::CollectionId,
|
||||
who: &AccountId,
|
||||
) -> Self::OwnedInCollectionIterator;
|
||||
}
|
||||
|
||||
/// Trait for providing the ability to create collections of nonfungible items.
|
||||
pub trait Create<AccountId, CollectionConfig>: Inspect<AccountId> {
|
||||
/// Create a `collection` of nonfungible items to be owned by `who` and managed by `admin`.
|
||||
fn create_collection(
|
||||
who: &AccountId,
|
||||
admin: &AccountId,
|
||||
config: &CollectionConfig,
|
||||
) -> Result<Self::CollectionId, DispatchError>;
|
||||
}
|
||||
|
||||
/// Trait for providing the ability to destroy collections of nonfungible items.
|
||||
pub trait Destroy<AccountId>: Inspect<AccountId> {
|
||||
/// The witness data needed to destroy an item.
|
||||
type DestroyWitness;
|
||||
|
||||
/// Provide the appropriate witness data needed to destroy an item.
|
||||
fn get_destroy_witness(collection: &Self::CollectionId) -> Option<Self::DestroyWitness>;
|
||||
|
||||
/// Destroy an existing fungible item.
|
||||
/// * `collection`: The `CollectionId` to be destroyed.
|
||||
/// * `witness`: Any witness data that needs to be provided to complete the operation
|
||||
/// successfully.
|
||||
/// * `maybe_check_owner`: An optional `AccountId` that can be used to authorize the destroy
|
||||
/// command. If not provided, we will not do any authorization checks before destroying the
|
||||
/// item.
|
||||
///
|
||||
/// If successful, this function will return the actual witness data from the destroyed item.
|
||||
/// This may be different than the witness data provided, and can be used to refund weight.
|
||||
fn destroy(
|
||||
collection: Self::CollectionId,
|
||||
witness: Self::DestroyWitness,
|
||||
maybe_check_owner: Option<AccountId>,
|
||||
) -> Result<Self::DestroyWitness, DispatchError>;
|
||||
}
|
||||
|
||||
/// Trait for providing an interface for multiple collections of NFT-like items which may be
|
||||
/// minted, burned and/or have attributes set on them.
|
||||
pub trait Mutate<AccountId, ItemConfig>: Inspect<AccountId> {
|
||||
/// Mint some `item` of `collection` to be owned by `who`.
|
||||
///
|
||||
/// By default, this is not a supported operation.
|
||||
fn mint_into(
|
||||
_collection: &Self::CollectionId,
|
||||
_item: &Self::ItemId,
|
||||
_who: &AccountId,
|
||||
_config: &ItemConfig,
|
||||
_deposit_collection_owner: bool,
|
||||
) -> DispatchResult {
|
||||
Err(TokenError::Unsupported.into())
|
||||
}
|
||||
|
||||
/// Burn some `item` of `collection`.
|
||||
///
|
||||
/// By default, this is not a supported operation.
|
||||
fn burn(
|
||||
_collection: &Self::CollectionId,
|
||||
_item: &Self::ItemId,
|
||||
_maybe_check_owner: Option<&AccountId>,
|
||||
) -> DispatchResult {
|
||||
Err(TokenError::Unsupported.into())
|
||||
}
|
||||
|
||||
/// Set attribute `value` of `item` of `collection`'s `key`.
|
||||
///
|
||||
/// By default, this is not a supported operation.
|
||||
fn set_attribute(
|
||||
_collection: &Self::CollectionId,
|
||||
_item: &Self::ItemId,
|
||||
_key: &[u8],
|
||||
_value: &[u8],
|
||||
) -> DispatchResult {
|
||||
Err(TokenError::Unsupported.into())
|
||||
}
|
||||
|
||||
/// Attempt to set the strongly-typed attribute `value` of `item` of `collection`'s `key`.
|
||||
///
|
||||
/// By default this just attempts to use `set_attribute`.
|
||||
fn set_typed_attribute<K: Encode, V: Encode>(
|
||||
collection: &Self::CollectionId,
|
||||
item: &Self::ItemId,
|
||||
key: &K,
|
||||
value: &V,
|
||||
) -> DispatchResult {
|
||||
key.using_encoded(|k| value.using_encoded(|v| Self::set_attribute(collection, item, k, v)))
|
||||
}
|
||||
|
||||
/// Set attribute `value` of `collection`'s `key`.
|
||||
///
|
||||
/// By default, this is not a supported operation.
|
||||
fn set_collection_attribute(
|
||||
_collection: &Self::CollectionId,
|
||||
_key: &[u8],
|
||||
_value: &[u8],
|
||||
) -> DispatchResult {
|
||||
Err(TokenError::Unsupported.into())
|
||||
}
|
||||
|
||||
/// Attempt to set the strongly-typed attribute `value` of `collection`'s `key`.
|
||||
///
|
||||
/// By default this just attempts to use `set_attribute`.
|
||||
fn set_typed_collection_attribute<K: Encode, V: Encode>(
|
||||
collection: &Self::CollectionId,
|
||||
key: &K,
|
||||
value: &V,
|
||||
) -> DispatchResult {
|
||||
key.using_encoded(|k| {
|
||||
value.using_encoded(|v| Self::set_collection_attribute(collection, k, v))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// Trait for transferring non-fungible sets of items.
|
||||
pub trait Transfer<AccountId>: Inspect<AccountId> {
|
||||
/// Transfer `item` of `collection` into `destination` account.
|
||||
fn transfer(
|
||||
collection: &Self::CollectionId,
|
||||
item: &Self::ItemId,
|
||||
destination: &AccountId,
|
||||
) -> DispatchResult;
|
||||
}
|
||||
Reference in New Issue
Block a user