--- a/pallets/nft/src/lib.rs +++ b/pallets/nft/src/lib.rs @@ -72,7 +72,7 @@ /// Balance owner per collection map pub Balance get(balance_count): map hasher(blake2_128_concat) (u64, T::AccountId) => u64; - /// Item double map (collection) + pub ApprovedList get(approved): map hasher(blake2_128_concat) (u64, u64) => Vec; pub ItemList get(item_id): map hasher(blake2_128_concat) (u64, u64) => NftItemType; pub ItemListIndex get(item_index): map hasher(blake2_128_concat) u64 => u64; } @@ -323,7 +323,92 @@ item.owner = new_owner; >::insert((collection_id, item_id), item); + // reset approved list + let itm: Vec = Vec::new(); + >::insert((collection_id, item_id), itm); + + Ok(()) + } + + #[weight = frame_support::weights::SimpleDispatchInfo::default()] + pub fn approve(origin, approved: T::AccountId, collection_id: u64, item_id: u64) -> DispatchResult { + + let sender = ensure_signed(origin)?; + ensure!(>::contains_key(collection_id), "This collection does not exist"); + + let target_collection = >::get(collection_id); + let is_owner = sender == target_collection.owner; + + ensure!(>::contains_key((collection_id, item_id)), "Item does not exists"); + let item = >::get((collection_id, item_id)); + + if !is_owner + { + // check if item owner + if item.owner != sender + { + let no_perm_mes = "You do not have permissions to modify this collection"; + + ensure!(>::contains_key(collection_id), no_perm_mes); + ensure!(>::get(collection_id).contains(&sender), no_perm_mes); + } + } + + let list_exists = >::contains_key((collection_id, item_id)); + if list_exists { + + let mut list = >::get((collection_id, item_id)); + let item_contains = list.contains(&approved.clone()); + if !item_contains { + list.push(approved.clone()); + } + } else { + + let mut itm = Vec::new(); + itm.push(approved.clone()); + >::insert((collection_id, item_id), itm); + } + + Ok(()) + } + + #[weight = frame_support::weights::SimpleDispatchInfo::default()] + pub fn transfer_from(origin, collection_id: u64, item_id: u64, new_owner: T::AccountId) -> DispatchResult { + + // let sender = ensure_signed(origin)?; + // ensure!(>::contains_key(collection_id), "This collection does not exist"); + + // let target_collection = >::get(collection_id); + // let is_owner = sender == target_collection.owner; + + // ensure!(>::contains_key((collection_id, item_id)), "Item does not exists"); + // let mut item = >::get((collection_id, item_id)); + + // if !is_owner + // { + // let no_perm_mes = "You do not have permissions to modify this collection"; + + // // check if item owner + // if item.owner != sender + // { + // ensure!(>::contains_key(collection_id), no_perm_mes); + // ensure!(>::get(collection_id).contains(&sender), no_perm_mes); + // } + + // ensure!(>::contains_key((collection_id, item_id)), no_perm_mes); + // let list_itm = >::get((collection_id, item_id)); + // ensure!(list_itm.contains(&new_owner.clone()), no_perm_mes); + + // } + + + let no_perm_mes = "You do not have permissions to modify this collection"; + ensure!(>::contains_key((collection_id, item_id)), no_perm_mes); + let list_itm = >::get((collection_id, item_id)); + ensure!(list_itm.contains(&new_owner.clone()), no_perm_mes); + + Self::transfer(origin, collection_id, item_id, new_owner); Ok(()) } --- a/pallets/nft/src/tests.rs +++ b/pallets/nft/src/tests.rs @@ -184,3 +184,81 @@ assert_eq!(TemplateModule::balance_count((1, 2)), 1); }); } + +#[test] +fn approve() { + new_test_ext().execute_with(|| { + let size = 1024; + let origin1 = Origin::signed(1); + let origin2 = Origin::signed(2); + let origin3 = Origin::signed(3); + + assert_ok!(TemplateModule::create_collection(origin1.clone(), size)); + assert_ok!(TemplateModule::create_collection(origin2.clone(), size)); + assert_ok!(TemplateModule::create_collection(origin3.clone(), size)); + + assert_eq!(TemplateModule::collection(1).owner, 1); + assert_eq!(TemplateModule::collection(2).owner, 2); + assert_eq!(TemplateModule::collection(3).owner, 3); + + // create item + assert_ok!(TemplateModule::create_item(origin1.clone(), 1, [1,1,1].to_vec())); + + // approve + assert_ok!(TemplateModule::approve(origin1.clone(), 2, 1, 1)); + assert_eq!(TemplateModule::approved((1,1)).contains(&2), true); + + }); +} + +#[test] +fn get_approved() { + new_test_ext().execute_with(|| { + let size = 1024; + let origin1 = Origin::signed(1); + let origin2 = Origin::signed(2); + let origin3 = Origin::signed(3); + + assert_ok!(TemplateModule::create_collection(origin1.clone(), size)); + assert_ok!(TemplateModule::create_collection(origin2.clone(), size)); + assert_ok!(TemplateModule::create_collection(origin3.clone(), size)); + + assert_eq!(TemplateModule::collection(1).owner, 1); + assert_eq!(TemplateModule::collection(2).owner, 2); + assert_eq!(TemplateModule::collection(3).owner, 3); + + // create item + assert_ok!(TemplateModule::create_item(origin1.clone(), 1, [1,1,1].to_vec())); + + // approve + assert_ok!(TemplateModule::approve(origin1.clone(), 2, 1, 1)); + assert_eq!(TemplateModule::approved((1,1)).contains(&2), true); + + }); +} + +#[test] +fn transfer_from() { + new_test_ext().execute_with(|| { + let size = 1024; + let origin1 = Origin::signed(1); + let origin2 = Origin::signed(2); + let origin3 = Origin::signed(3); + + assert_ok!(TemplateModule::create_collection(origin1.clone(), size)); + assert_ok!(TemplateModule::create_collection(origin2.clone(), size)); + assert_ok!(TemplateModule::create_collection(origin3.clone(), size)); + + assert_eq!(TemplateModule::collection(1).owner, 1); + assert_eq!(TemplateModule::collection(2).owner, 2); + assert_eq!(TemplateModule::collection(3).owner, 3); + + // create item + assert_ok!(TemplateModule::create_item(origin1.clone(), 1, [1,1,1].to_vec())); + + // approve + assert_ok!(TemplateModule::approve(origin1.clone(), 2, 1, 1)); + assert_ok!(TemplateModule::transfer_from(origin1.clone(), 1, 1, 2)); + + }); +} \ No newline at end of file