Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

Commit

Permalink
[NFTs] Add the new owner param to mint() method (#12997)
Browse files Browse the repository at this point in the history
* Add the new `owner` param to mint() method

* Fmt

* Address comments
  • Loading branch information
jsidorenko authored Dec 22, 2022
1 parent 27e2f38 commit 56f228d
Show file tree
Hide file tree
Showing 6 changed files with 153 additions and 76 deletions.
19 changes: 10 additions & 9 deletions frame/nfts/src/benchmarking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ fn mint_item<T: Config<I>, I: 'static>(
SystemOrigin::Signed(caller.clone()).into(),
T::Helper::collection(0),
item,
caller_lookup.clone(),
None,
));
(item, caller, caller_lookup)
Expand Down Expand Up @@ -174,7 +175,7 @@ benchmarks_instance_pallet! {
let m in 0 .. 1_000;
let a in 0 .. 1_000;

let (collection, caller, caller_lookup) = create_collection::<T, I>();
let (collection, caller, _) = create_collection::<T, I>();
add_collection_metadata::<T, I>();
for i in 0..n {
mint_item::<T, I>(i as u16);
Expand All @@ -200,7 +201,7 @@ benchmarks_instance_pallet! {
mint {
let (collection, caller, caller_lookup) = create_collection::<T, I>();
let item = T::Helper::item(0);
}: _(SystemOrigin::Signed(caller.clone()), collection, item, None)
}: _(SystemOrigin::Signed(caller.clone()), collection, item, caller_lookup, None)
verify {
assert_last_event::<T, I>(Event::Issued { collection, item, owner: caller }.into());
}
Expand All @@ -222,7 +223,7 @@ benchmarks_instance_pallet! {
}

transfer {
let (collection, caller, caller_lookup) = create_collection::<T, I>();
let (collection, caller, _) = create_collection::<T, I>();
let (item, ..) = mint_item::<T, I>(0);

let target: T::AccountId = account("target", 0, SEED);
Expand All @@ -235,7 +236,7 @@ benchmarks_instance_pallet! {

redeposit {
let i in 0 .. 5_000;
let (collection, caller, caller_lookup) = create_collection::<T, I>();
let (collection, caller, _) = create_collection::<T, I>();
let items = (0..i).map(|x| mint_item::<T, I>(x as u16).0).collect::<Vec<_>>();
Nfts::<T, I>::force_collection_config(
SystemOrigin::Root.into(),
Expand All @@ -248,15 +249,15 @@ benchmarks_instance_pallet! {
}

lock_item_transfer {
let (collection, caller, caller_lookup) = create_collection::<T, I>();
let (collection, caller, _) = create_collection::<T, I>();
let (item, ..) = mint_item::<T, I>(0);
}: _(SystemOrigin::Signed(caller.clone()), T::Helper::collection(0), T::Helper::item(0))
verify {
assert_last_event::<T, I>(Event::ItemTransferLocked { collection: T::Helper::collection(0), item: T::Helper::item(0) }.into());
}

unlock_item_transfer {
let (collection, caller, caller_lookup) = create_collection::<T, I>();
let (collection, caller, _) = create_collection::<T, I>();
let (item, ..) = mint_item::<T, I>(0);
Nfts::<T, I>::lock_item_transfer(
SystemOrigin::Signed(caller.clone()).into(),
Expand All @@ -269,7 +270,7 @@ benchmarks_instance_pallet! {
}

lock_collection {
let (collection, caller, caller_lookup) = create_collection::<T, I>();
let (collection, caller, _) = create_collection::<T, I>();
let lock_settings = CollectionSettings::from_disabled(
CollectionSetting::TransferableItems |
CollectionSetting::UnlockedMetadata |
Expand Down Expand Up @@ -324,7 +325,7 @@ benchmarks_instance_pallet! {
}

force_collection_config {
let (collection, caller, caller_lookup) = create_collection::<T, I>();
let (collection, caller, _) = create_collection::<T, I>();
let origin = T::ForceOrigin::successful_origin();
let call = Call::<T, I>::force_collection_config {
collection,
Expand All @@ -336,7 +337,7 @@ benchmarks_instance_pallet! {
}

lock_item_properties {
let (collection, caller, caller_lookup) = create_collection::<T, I>();
let (collection, caller, _) = create_collection::<T, I>();
let (item, ..) = mint_item::<T, I>(0);
let lock_metadata = true;
let lock_attributes = true;
Expand Down
22 changes: 12 additions & 10 deletions frame/nfts/src/features/create_delete_item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ impl<T: Config<I>, I: 'static> Pallet<T, I> {
pub fn do_mint(
collection: T::CollectionId,
item: T::ItemId,
owner: T::AccountId,
depositor: T::AccountId,
mint_to: T::AccountId,
item_config: ItemConfig,
deposit_collection_owner: bool,
with_details_and_config: impl FnOnce(
Expand All @@ -45,9 +46,7 @@ impl<T: Config<I>, I: 'static> Pallet<T, I> {
ensure!(collection_details.items < max_supply, Error::<T, I>::MaxSupplyReached);
}

let items =
collection_details.items.checked_add(1).ok_or(ArithmeticError::Overflow)?;
collection_details.items = items;
collection_details.items.saturating_inc();

let collection_config = Self::get_collection_config(&collection)?;
let deposit_amount = match collection_config
Expand All @@ -58,11 +57,11 @@ impl<T: Config<I>, I: 'static> Pallet<T, I> {
};
let deposit_account = match deposit_collection_owner {
true => collection_details.owner.clone(),
false => owner.clone(),
false => depositor,
};

let owner = owner.clone();
Account::<T, I>::insert((&owner, &collection, &item), ());
let item_owner = mint_to.clone();
Account::<T, I>::insert((&item_owner, &collection, &item), ());

if let Ok(existing_config) = ItemConfigOf::<T, I>::try_get(&collection, &item) {
ensure!(existing_config == item_config, Error::<T, I>::InconsistentItemConfig);
Expand All @@ -73,14 +72,17 @@ impl<T: Config<I>, I: 'static> Pallet<T, I> {
T::Currency::reserve(&deposit_account, deposit_amount)?;

let deposit = ItemDeposit { account: deposit_account, amount: deposit_amount };
let details =
ItemDetails { owner, approvals: ApprovalsOf::<T, I>::default(), deposit };
let details = ItemDetails {
owner: item_owner,
approvals: ApprovalsOf::<T, I>::default(),
deposit,
};
Item::<T, I>::insert(&collection, &item, details);
Ok(())
},
)?;

Self::deposit_event(Event::Issued { collection, item, owner });
Self::deposit_event(Event::Issued { collection, item, owner: mint_to });
Ok(())
}

Expand Down
1 change: 1 addition & 0 deletions frame/nfts/src/impl_nonfungibles.rs
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,7 @@ impl<T: Config<I>, I: 'static> Mutate<<T as SystemConfig>::AccountId, ItemConfig
*collection,
*item,
who.clone(),
who.clone(),
*item_config,
deposit_collection_owner,
|_, _| Ok(()),
Expand Down
30 changes: 19 additions & 11 deletions frame/nfts/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ use frame_support::traits::{
use frame_system::Config as SystemConfig;
use sp_runtime::{
traits::{Saturating, StaticLookup, Zero},
ArithmeticError, RuntimeDebug,
RuntimeDebug,
};
use sp_std::prelude::*;

Expand Down Expand Up @@ -715,9 +715,12 @@ pub mod pallet {
///
/// - `collection`: The collection of the item to be minted.
/// - `item`: An identifier of the new item.
/// - `mint_to`: Account into which the item will be minted.
/// - `witness_data`: When the mint type is `HolderOf(collection_id)`, then the owned
/// item_id from that collection needs to be provided within the witness data object.
///
/// Note: the deposit will be taken from the `origin` and not the `owner` of the `item`.
///
/// Emits `Issued` event when successful.
///
/// Weight: `O(1)`
Expand All @@ -726,9 +729,11 @@ pub mod pallet {
origin: OriginFor<T>,
collection: T::CollectionId,
item: T::ItemId,
mint_to: AccountIdLookupOf<T>,
witness_data: Option<MintWitness<T::ItemId>>,
) -> DispatchResult {
let caller = ensure_signed(origin)?;
let mint_to = T::Lookup::lookup(mint_to)?;

let collection_config = Self::get_collection_config(&collection)?;
let item_settings = collection_config.mint_settings.default_item_settings;
Expand All @@ -738,9 +743,15 @@ pub mod pallet {
collection,
item,
caller.clone(),
mint_to.clone(),
item_config,
false,
|collection_details, collection_config| {
// Issuer can mint regardless of mint settings
if Self::has_role(&collection, &caller, CollectionRole::Issuer) {
return Ok(())
}

let mint_settings = collection_config.mint_settings;
let now = frame_system::Pallet::<T>::block_number();

Expand All @@ -752,12 +763,7 @@ pub mod pallet {
}

match mint_settings.mint_type {
MintType::Issuer => {
ensure!(
Self::has_role(&collection, &caller, CollectionRole::Issuer),
Error::<T, I>::NoPermission
)
},
MintType::Issuer => return Err(Error::<T, I>::NoPermission.into()),
MintType::HolderOf(collection_id) => {
let MintWitness { owner_of_item } =
witness_data.ok_or(Error::<T, I>::BadWitness)?;
Expand Down Expand Up @@ -813,7 +819,7 @@ pub mod pallet {
///
/// - `collection`: The collection of the item to be minted.
/// - `item`: An identifier of the new item.
/// - `owner`: An owner of the minted item.
/// - `mint_to`: Account into which the item will be minted.
/// - `item_config`: A config of the new item.
///
/// Emits `Issued` event when successful.
Expand All @@ -824,21 +830,23 @@ pub mod pallet {
origin: OriginFor<T>,
collection: T::CollectionId,
item: T::ItemId,
owner: AccountIdLookupOf<T>,
mint_to: AccountIdLookupOf<T>,
item_config: ItemConfig,
) -> DispatchResult {
let maybe_check_origin = T::ForceOrigin::try_origin(origin)
.map(|_| None)
.or_else(|origin| ensure_signed(origin).map(Some).map_err(DispatchError::from))?;
let owner = T::Lookup::lookup(owner)?;
let mint_to = T::Lookup::lookup(mint_to)?;

if let Some(check_origin) = maybe_check_origin {
ensure!(
Self::has_role(&collection, &check_origin, CollectionRole::Issuer),
Error::<T, I>::NoPermission
);
}
Self::do_mint(collection, item, owner, item_config, true, |_, _| Ok(()))
Self::do_mint(collection, item, mint_to.clone(), mint_to, item_config, true, |_, _| {
Ok(())
})
}

/// Destroy a single item.
Expand Down
Loading

0 comments on commit 56f228d

Please sign in to comment.