mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-04-29 14:57:56 +00:00
[NFTs] Track item's metadata depositor (#13124)
* Refactor do_mint() * Track the depositor of item's metadata * Revert back the access control * On collection destroy return the metadata deposit * Clear the metadata on item burn returning the deposit * Address comments * Fix clippy * Don't return Ok on non-existing attribute removal
This commit is contained in:
@@ -152,65 +152,68 @@ impl<T: Config<I>, I: 'static> Pallet<T, I> {
|
||||
namespace: AttributeNamespace<T::AccountId>,
|
||||
key: BoundedVec<u8, T::KeyLimit>,
|
||||
) -> DispatchResult {
|
||||
if let Some((_, deposit)) =
|
||||
Attribute::<T, I>::take((collection, maybe_item, &namespace, &key))
|
||||
{
|
||||
let mut collection_details =
|
||||
Collection::<T, I>::get(&collection).ok_or(Error::<T, I>::UnknownCollection)?;
|
||||
let (_, deposit) = Attribute::<T, I>::take((collection, maybe_item, &namespace, &key))
|
||||
.ok_or(Error::<T, I>::AttributeNotFound)?;
|
||||
let mut collection_details =
|
||||
Collection::<T, I>::get(&collection).ok_or(Error::<T, I>::UnknownCollection)?;
|
||||
|
||||
if let Some(check_owner) = &maybe_check_owner {
|
||||
if deposit.account != maybe_check_owner {
|
||||
ensure!(
|
||||
Self::is_valid_namespace(
|
||||
&check_owner,
|
||||
&namespace,
|
||||
&collection,
|
||||
&collection_details.owner,
|
||||
&maybe_item,
|
||||
)?,
|
||||
Error::<T, I>::NoPermission
|
||||
);
|
||||
}
|
||||
|
||||
// can't clear `CollectionOwner` type attributes if the collection/item is locked
|
||||
match namespace {
|
||||
AttributeNamespace::CollectionOwner => match maybe_item {
|
||||
None => {
|
||||
let collection_config = Self::get_collection_config(&collection)?;
|
||||
ensure!(
|
||||
collection_config
|
||||
.is_setting_enabled(CollectionSetting::UnlockedAttributes),
|
||||
Error::<T, I>::LockedCollectionAttributes
|
||||
)
|
||||
},
|
||||
Some(item) => {
|
||||
// NOTE: if the item was previously burned, the ItemConfigOf record
|
||||
// might not exist. In that case, we allow to clear the attribute.
|
||||
let maybe_is_locked = Self::get_item_config(&collection, &item)
|
||||
.map_or(false, |c| {
|
||||
c.has_disabled_setting(ItemSetting::UnlockedAttributes)
|
||||
});
|
||||
ensure!(!maybe_is_locked, Error::<T, I>::LockedItemAttributes);
|
||||
},
|
||||
},
|
||||
_ => (),
|
||||
};
|
||||
if let Some(check_owner) = &maybe_check_owner {
|
||||
// validate the provided namespace when it's not a root call and the caller is not
|
||||
// the same as the `deposit.account` (e.g. the deposit was paid by different account)
|
||||
if deposit.account != maybe_check_owner {
|
||||
ensure!(
|
||||
Self::is_valid_namespace(
|
||||
&check_owner,
|
||||
&namespace,
|
||||
&collection,
|
||||
&collection_details.owner,
|
||||
&maybe_item,
|
||||
)?,
|
||||
Error::<T, I>::NoPermission
|
||||
);
|
||||
}
|
||||
|
||||
collection_details.attributes.saturating_dec();
|
||||
// can't clear `CollectionOwner` type attributes if the collection/item is locked
|
||||
match namespace {
|
||||
AttributeNamespace::CollectionOwner => {
|
||||
collection_details.owner_deposit.saturating_reduce(deposit.amount);
|
||||
T::Currency::unreserve(&collection_details.owner, deposit.amount);
|
||||
AttributeNamespace::CollectionOwner => match maybe_item {
|
||||
None => {
|
||||
let collection_config = Self::get_collection_config(&collection)?;
|
||||
ensure!(
|
||||
collection_config
|
||||
.is_setting_enabled(CollectionSetting::UnlockedAttributes),
|
||||
Error::<T, I>::LockedCollectionAttributes
|
||||
)
|
||||
},
|
||||
Some(item) => {
|
||||
// NOTE: if the item was previously burned, the ItemConfigOf record
|
||||
// might not exist. In that case, we allow to clear the attribute.
|
||||
let maybe_is_locked = Self::get_item_config(&collection, &item)
|
||||
.map_or(false, |c| {
|
||||
c.has_disabled_setting(ItemSetting::UnlockedAttributes)
|
||||
});
|
||||
ensure!(!maybe_is_locked, Error::<T, I>::LockedItemAttributes);
|
||||
},
|
||||
},
|
||||
_ => (),
|
||||
};
|
||||
if let Some(deposit_account) = deposit.account {
|
||||
T::Currency::unreserve(&deposit_account, deposit.amount);
|
||||
}
|
||||
Collection::<T, I>::insert(collection, &collection_details);
|
||||
Self::deposit_event(Event::AttributeCleared { collection, maybe_item, key, namespace });
|
||||
}
|
||||
|
||||
collection_details.attributes.saturating_dec();
|
||||
match namespace {
|
||||
AttributeNamespace::CollectionOwner => {
|
||||
collection_details.owner_deposit.saturating_reduce(deposit.amount);
|
||||
T::Currency::unreserve(&collection_details.owner, deposit.amount);
|
||||
},
|
||||
_ => (),
|
||||
};
|
||||
|
||||
if let Some(deposit_account) = deposit.account {
|
||||
T::Currency::unreserve(&deposit_account, deposit.amount);
|
||||
}
|
||||
|
||||
Collection::<T, I>::insert(collection, &collection_details);
|
||||
Self::deposit_event(Event::AttributeCleared { collection, maybe_item, key, namespace });
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user