diff --git a/frame/nfts/src/impl_nonfungibles.rs b/frame/nfts/src/impl_nonfungibles.rs index edfc29710b7da..ab4d7a16ec215 100644 --- a/frame/nfts/src/impl_nonfungibles.rs +++ b/frame/nfts/src/impl_nonfungibles.rs @@ -237,6 +237,49 @@ impl, I: 'static> Mutate<::AccountId, ItemConfig }) }) } + + fn clear_attribute( + collection: &Self::CollectionId, + item: &Self::ItemId, + key: &[u8], + ) -> DispatchResult { + Self::do_clear_attribute( + None, + *collection, + Some(*item), + AttributeNamespace::Pallet, + Self::construct_attribute_key(key.to_vec())?, + ) + } + + fn clear_typed_attribute( + collection: &Self::CollectionId, + item: &Self::ItemId, + key: &K, + ) -> DispatchResult { + key.using_encoded(|k| { + >::clear_attribute(collection, item, k) + }) + } + + fn clear_collection_attribute(collection: &Self::CollectionId, key: &[u8]) -> DispatchResult { + Self::do_clear_attribute( + None, + *collection, + None, + AttributeNamespace::Pallet, + Self::construct_attribute_key(key.to_vec())?, + ) + } + + fn clear_typed_collection_attribute( + collection: &Self::CollectionId, + key: &K, + ) -> DispatchResult { + key.using_encoded(|k| { + >::clear_collection_attribute(collection, k) + }) + } } impl, I: 'static> Transfer for Pallet { diff --git a/frame/nfts/src/tests.rs b/frame/nfts/src/tests.rs index 18a3fd83b4de3..f8187b3777ebd 100644 --- a/frame/nfts/src/tests.rs +++ b/frame/nfts/src/tests.rs @@ -1012,6 +1012,22 @@ fn validate_deposit_required_setting() { assert_eq!(Balances::reserved_balance(1), 0); assert_eq!(Balances::reserved_balance(2), 3); assert_eq!(Balances::reserved_balance(3), 3); + + assert_ok!( + ::AccountId, ItemConfig>>::clear_attribute( + &0, + &0, + &[3], + ) + ); + assert_eq!( + attributes(0), + vec![ + (Some(0), AttributeNamespace::CollectionOwner, bvec![0], bvec![0]), + (Some(0), AttributeNamespace::ItemOwner, bvec![1], bvec![0]), + (Some(0), AttributeNamespace::Account(3), bvec![2], bvec![0]), + ] + ); }); } diff --git a/frame/support/src/traits/tokens/nonfungible_v2.rs b/frame/support/src/traits/tokens/nonfungible_v2.rs index a1b75e62e4db5..e1899020bb336 100644 --- a/frame/support/src/traits/tokens/nonfungible_v2.rs +++ b/frame/support/src/traits/tokens/nonfungible_v2.rs @@ -127,6 +127,20 @@ pub trait Mutate: Inspect { ) -> DispatchResult { key.using_encoded(|k| value.using_encoded(|v| Self::set_attribute(item, k, v))) } + + /// Clear attribute of `item`'s `key`. + /// + /// By default, this is not a supported operation. + fn clear_attribute(_item: &Self::ItemId, _key: &[u8]) -> DispatchResult { + Err(TokenError::Unsupported.into()) + } + + /// Attempt to clear the strongly-typed attribute of `item`'s `key`. + /// + /// By default this just attempts to use `clear_attribute`. + fn clear_typed_attribute(item: &Self::ItemId, key: &K) -> DispatchResult { + key.using_encoded(|k| Self::clear_attribute(item, k)) + } } /// Trait for transferring a non-fungible item. @@ -234,6 +248,16 @@ impl< value, ) } + fn clear_attribute(item: &Self::ItemId, key: &[u8]) -> DispatchResult { + >::clear_attribute(&A::get(), item, key) + } + fn clear_typed_attribute(item: &Self::ItemId, key: &K) -> DispatchResult { + >::clear_typed_attribute( + &A::get(), + item, + key, + ) + } } impl< diff --git a/frame/support/src/traits/tokens/nonfungibles_v2.rs b/frame/support/src/traits/tokens/nonfungibles_v2.rs index d2f5f5529fa96..17c5d887defc0 100644 --- a/frame/support/src/traits/tokens/nonfungibles_v2.rs +++ b/frame/support/src/traits/tokens/nonfungibles_v2.rs @@ -244,6 +244,45 @@ pub trait Mutate: Inspect { value.using_encoded(|v| Self::set_collection_attribute(collection, k, v)) }) } + + /// Clear attribute of `item` of `collection`'s `key`. + /// + /// By default, this is not a supported operation. + fn clear_attribute( + _collection: &Self::CollectionId, + _item: &Self::ItemId, + _key: &[u8], + ) -> DispatchResult { + Err(TokenError::Unsupported.into()) + } + + /// Attempt to clear the strongly-typed attribute of `item` of `collection`'s `key`. + /// + /// By default this just attempts to use `clear_attribute`. + fn clear_typed_attribute( + collection: &Self::CollectionId, + item: &Self::ItemId, + key: &K, + ) -> DispatchResult { + key.using_encoded(|k| Self::clear_attribute(collection, item, k)) + } + + /// Clear attribute of `collection`'s `key`. + /// + /// By default, this is not a supported operation. + fn clear_collection_attribute(_collection: &Self::CollectionId, _key: &[u8]) -> DispatchResult { + Err(TokenError::Unsupported.into()) + } + + /// Attempt to clear the strongly-typed attribute of `collection`'s `key`. + /// + /// By default this just attempts to use `clear_attribute`. + fn clear_typed_collection_attribute( + collection: &Self::CollectionId, + key: &K, + ) -> DispatchResult { + key.using_encoded(|k| Self::clear_collection_attribute(collection, k)) + } } /// Trait for transferring non-fungible sets of items.