Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 32 additions & 8 deletions pallets/rmrk-core/src/functions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ where
T: pallet_uniques::Config<ClassId = CollectionId, InstanceId = NftId>,
{
fn priority_set(
sender: T::AccountId,
_sender: T::AccountId,
collection_id: CollectionId,
nft_id: NftId,
priorities: Vec<Vec<u8>>,
Expand Down Expand Up @@ -262,10 +262,14 @@ where
collection_id: CollectionId,
nft_id: NftId,
new_owner: AccountIdOrCollectionNftTuple<T::AccountId>,
max_recursions: u32,
) -> sp_std::result::Result<T::AccountId, DispatchError> {
// Get current owner for child removal later
let parent =
pallet_uniques::Pallet::<T>::owner(collection_id, nft_id);
// Check if parent returns None which indicates the NFT is not available
ensure!(parent.is_some(),Error::<T>::NoAvailableNftId);

let (root_owner, root_nft) = Pallet::<T>::lookup_root_owner(collection_id, nft_id)?;
let (root_owner, _root_nft) = Pallet::<T>::lookup_root_owner(collection_id, nft_id)?;
// Check ownership
ensure!(sender == root_owner, Error::<T>::NoPermission);
// Get NFT info
Expand Down Expand Up @@ -293,6 +297,21 @@ where
sending_nft.owner = new_owner.clone();
NFTs::<T>::insert(collection_id, nft_id, sending_nft);

if let Some(current_owner) = parent {
// Handle Children StorageMap for NFTs
let current_owner_cid_nid = Pallet::<T>::decode_nft_account_id::<T::AccountId>(current_owner);
if let Some(current_owner_cid_nid) = current_owner_cid_nid {
// Remove child from parent
Pallet::<T>::remove_child(current_owner_cid_nid, (collection_id, nft_id));
}
}

// add child to new parent if NFT virtual address
let new_owner_cid_nid = Pallet::<T>::decode_nft_account_id::<T::AccountId>(new_owner_account.clone());
if let Some(new_owner_cid_nid) = new_owner_cid_nid {
Pallet::<T>::add_child(new_owner_cid_nid, (collection_id, nft_id));
}

Ok(new_owner_account)
}
}
Expand Down Expand Up @@ -359,12 +378,10 @@ where
let parent =
pallet_uniques::Pallet::<T>::owner(collection_id, nft_id);
// Check if parent returns None which indicates the NFT is not available
if parent.is_none() {
return Err(Error::<T>::NoAvailableNftId)
}
let owner = parent.as_ref().unwrap();
parent.as_ref().ok_or(Error::<T>::NoAvailableNftId)?;
let owner = parent.unwrap();
match Self::decode_nft_account_id::<T::AccountId>(owner.clone()) {
None => Ok((owner.clone(), (collection_id, nft_id))),
None => Ok((owner, (collection_id, nft_id))),
Some((cid, nid)) => Pallet::<T>::lookup_root_owner(cid, nid),
}
}
Expand Down Expand Up @@ -452,6 +469,13 @@ where
}
}

/// `recursive_burn` function will recursively call itself to burn the NFT and all the children
/// of the NFT. Any caller functions must be #[transactional]
///
/// Parameters:
/// - `collection_id`: Collection ID of the NFT to be burned
/// - `nft_id`: NFT ID that is to be burned
/// - `max_recursion`: Maximum number of recursion allowed
pub fn recursive_burn(
collection_id: CollectionId,
nft_id: NftId,
Expand Down
37 changes: 9 additions & 28 deletions pallets/rmrk-core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,7 @@ use frame_support::{
use frame_system::ensure_signed;

use sp_runtime::{traits::StaticLookup, DispatchError, Permill};
use sp_std::{convert::TryInto, vec, vec::Vec};

use types::ClassInfo;
use sp_std::{convert::TryInto, vec::Vec};

use rmrk_traits::{
primitives::*, AccountIdOrCollectionNftTuple, Collection, CollectionInfo, Nft, NftInfo,
Expand Down Expand Up @@ -46,11 +44,9 @@ pub use pallet::*;

#[frame_support::pallet]
pub mod pallet {

use super::*;
use frame_support::{dispatch::DispatchResult, pallet_prelude::*};
use frame_system::pallet_prelude::*;
use rmrk_traits::AccountIdOrCollectionNftTuple::AccountId;

/// Configure the pallet by specifying the parameters and types on which it depends.
#[pallet::config]
Expand Down Expand Up @@ -345,7 +341,13 @@ pub mod pallet {
Ok(())
}

/// transfer NFT from account A to (account B or NFT)
/// Transfers a NFT from an Account or NFT A to another Account or NFT B
///
/// Parameters:
/// - `origin`: sender of the transaction
/// - `collection_id`: collection id of the nft to be transferred
/// - `nft_id`: nft id of the nft to be transferred
/// - `new_owner`: new owner of the nft which can be either an account or a NFT
#[pallet::weight(10_000 + T::DbWeight::get().reads_writes(1,1))]
#[transactional]
pub fn send(
Expand All @@ -356,42 +358,21 @@ pub mod pallet {
) -> DispatchResult {
let sender = ensure_signed(origin.clone())?;

// Get current owner for child removal later
let parent =
pallet_uniques::Pallet::<T>::owner(collection_id, nft_id);
// Check if parent returns None which indicates the NFT is not available
ensure!(parent.is_some(),Error::<T>::NoAvailableNftId);
let current_owner = parent.as_ref().unwrap();

let max_recursions = T::MaxRecursions::get();
let new_owner_account = Self::nft_send(
sender.clone(),
collection_id,
nft_id,
new_owner.clone(),
max_recursions,
)?;

pallet_uniques::Pallet::<T>::do_transfer(
collection_id,
nft_id,
new_owner_account.clone(),
|class_details, details|
|_class_details, _details|
Ok(())
)?;

// Handle Children StorageMap for NFTs
let current_cid_nid = Pallet::<T>::decode_nft_account_id::<T::AccountId>(current_owner.clone());
if current_cid_nid.is_some() {
// remove child from parent
Pallet::<T>::remove_child((current_cid_nid.unwrap().0, current_cid_nid.unwrap().1), (collection_id, nft_id));
}
// add child to new parent if NFT virtual address
let new_cid_nid = Pallet::<T>::decode_nft_account_id::<T::AccountId>(new_owner_account.clone());
if new_cid_nid.is_some() {
Pallet::<T>::add_child((new_cid_nid.unwrap().0, new_cid_nid.unwrap().1), (collection_id, nft_id));
}

Self::deposit_event(Event::NFTSent {
sender,
recipient: new_owner.clone(),
Expand Down
2 changes: 0 additions & 2 deletions pallets/rmrk-core/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@ use scale_info::TypeInfo;
#[cfg(feature = "std")]
use serde::{Deserialize, Serialize};

use rmrk_traits::{primitives::*, AccountIdOrCollectionNftTuple};

#[derive(Encode, Decode, Eq, Copy, PartialEq, Clone, RuntimeDebug, TypeInfo)]
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
pub struct ClassInfo<BoundedString, AccountId> {
Expand Down
1 change: 0 additions & 1 deletion traits/src/collection.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
use codec::{Decode, Encode};
use scale_info::TypeInfo;
use sp_runtime::{DispatchError, DispatchResult, RuntimeDebug};
use sp_std::cmp::Eq;

use crate::primitives::*;
use sp_std::result::Result;
Expand Down
1 change: 0 additions & 1 deletion traits/src/nft.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,5 @@ pub trait Nft<AccountId, BoundedString> {
collection_id: CollectionId,
nft_id: NftId,
new_owner: AccountIdOrCollectionNftTuple<AccountId>,
max_recursions: u32,
) -> Result<AccountId, DispatchError>;
}