difftreelog
Merge branch 'develop' into feature/NFTPAR-90
in: master
7 files changed
README.mddiffbeforeafterboth142 "enable_println": "bool",142 "enable_println": "bool",143 "max_subject_len": "u32"143 "max_subject_len": "u32"144 },144 },145 "AccessMode": {146 "_enum": [147 "Normal",148 "WhiteList"149 ]150 },145 "CollectionMode": {151 "CollectionMode": {146 "_enum": {152 "_enum": {147 "Invalid": null,153 "Invalid": null,181 "CollectionType": {187 "CollectionType": {182 "Owner": "AccountId",188 "Owner": "AccountId",183 "Mode": "CollectionMode",189 "Mode": "CollectionMode",184 "Access": "u8",190 "Access": "AccessMode",185 "DecimalPoints": "u32",191 "DecimalPoints": "u32",186 "Name": "Vec<u16>",192 "Name": "Vec<u16>",187 "Description": "Vec<u16>",193 "Description": "Vec<u16>",188 "TokenPrefix": "Vec<u8>",194 "TokenPrefix": "Vec<u8>",189 "CustomDataSize": "u32",195 "CustomDataSize": "u32",196 "MintMode": "bool",190 "OffchainSchema": "Vec<u8>",197 "OffchainSchema": "Vec<u8>",191 "Sponsor": "AccountId",198 "Sponsor": "AccountId",192 "UnconfirmedSponsor": "AccountId"199 "UnconfirmedSponsor": "AccountId"196 "LookupSource": "AccountId",203 "LookupSource": "AccountId",197 "Weight": "u64"204 "Weight": "u64"198}205}206199```207```node/src/chain_spec.rsdiffbeforeafterboth1// use nft_runtime::{2// AccountId, AuraConfig, BalancesConfig, GenesisConfig, GrandpaConfig, Signature, SudoConfig,3// SystemConfig, WASM_BINARY,4// };5// use nft_runtime::{ContractsConfig, ContractsSchedule, NftConfig, CollectionType};1use nft_runtime::{6use nft_runtime::*;2 AccountId, AuraConfig, BalancesConfig, GenesisConfig, GrandpaConfig, Signature, SudoConfig,3 SystemConfig, WASM_BINARY,4};5use nft_runtime::{ContractsConfig, ContractsSchedule};6use sc_service::ChainType;7use sc_service::ChainType;7use sp_consensus_aura::sr25519::AuthorityId as AuraId;8use sp_consensus_aura::sr25519::AuthorityId as AuraId;8use sp_core::{sr25519, Pair, Public};9use sp_core::{sr25519, Pair, Public};128 .collect(),129 .collect(),129 }),130 }),130 sudo: Some(SudoConfig { key: root_key }),131 sudo: Some(SudoConfig { key: root_key }),132 nft: Some(NftConfig {133 collection: vec![(1, CollectionType { 134 owner: get_account_id_from_seed::<sr25519::Public>("Alice"),135 mode: CollectionMode::NFT(50),136 access: AccessMode::Normal,137 decimal_points: 0,138 name: vec!(),139 description: vec!(),140 token_prefix: vec!(),141 custom_data_size: 50,142 mint_mode: false,143 offchain_schema: vec!(),144 sponsor: get_account_id_from_seed::<sr25519::Public>("Alice"),145 unconfirmed_sponsor: get_account_id_from_seed::<sr25519::Public>("Alice"),146 })],147 nft_item_id: vec!(),148 fungible_item_id: vec!(),149 refungible_item_id: vec!(),150 }),131 contracts: Some(ContractsConfig {151 contracts: Some(ContractsConfig {132 current_schedule: ContractsSchedule {152 current_schedule: ContractsSchedule {133 enable_println,153 enable_println,pallets/nft/src/lib.rsdiffbeforeafterboth1#![cfg_attr(not(feature = "std"), no_std)]1#![cfg_attr(not(feature = "std"), no_std)]223/// For more guidance on Substrate FRAME, see the example pallet3#[cfg(feature = "std")]4/// https://github.com/paritytech/substrate/blob/master/frame/example/src/lib.rs4pub use serde::*;55use codec::{Decode, Encode};6use codec::{Decode, Encode};6pub use frame_support::{7pub use frame_support::{32 },33 },33 FixedPointOperand, FixedU128,34 FixedPointOperand, FixedU128,34};35};35use sp_std::prelude::*;363637#[cfg(test)]37#[cfg(test)]38mod mock;38mod mock;393940#[cfg(test)]40#[cfg(test)]41mod tests;41mod tests;424243// Structs43#[derive(Encode, Decode, Debug, Eq, Clone, PartialEq)]44// #region4546#[derive(Encode, Decode, Eq, Debug, Clone, PartialEq)]47#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]44pub enum CollectionMode {48pub enum CollectionMode {45 Invalid,49 Invalid,46 // custom data size50 // custom data size62 }66 }63}67}646865#[derive(Encode, Decode, Debug, Clone, PartialEq)]69#[derive(Encode, Decode, Eq, Debug, Clone, PartialEq)]70#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]66pub enum AccessMode {71pub enum AccessMode {67 Normal,72 Normal,68 WhiteList,73 WhiteList,79 }84 }80}85}818682#[derive(Encode, Decode, Default, Clone, PartialEq)]87#[derive(Encode, Decode, Default, Debug, Clone, PartialEq)]83#[cfg_attr(feature = "std", derive(Debug))]88#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]84pub struct Ownership<AccountId> {89pub struct Ownership<AccountId> {85 pub owner: AccountId,90 pub owner: AccountId,86 pub fraction: u128,91 pub fraction: u128,87}92}889389#[derive(Encode, Decode, Default, Clone, PartialEq)]94#[derive(Encode, Decode, Default, Debug, Clone, PartialEq)]90#[cfg_attr(feature = "std", derive(Debug))]95#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]91pub struct CollectionType<AccountId> {96pub struct CollectionType<AccountId> {92 pub owner: AccountId,97 pub owner: AccountId,93 pub mode: CollectionMode,98 pub mode: CollectionMode,97 pub description: Vec<u16>, // 256 include null escape char102 pub description: Vec<u16>, // 256 include null escape char98 pub token_prefix: Vec<u8>, // 16 include null escape char103 pub token_prefix: Vec<u8>, // 16 include null escape char99 pub custom_data_size: u32,104 pub custom_data_size: u32,105 pub mint_mode: bool,100 pub offchain_schema: Vec<u8>,106 pub offchain_schema: Vec<u8>,101 pub sponsor: AccountId, // Who pays fees. If set to default address, the fees are applied to the transaction sender107 pub sponsor: AccountId, // Who pays fees. If set to default address, the fees are applied to the transaction sender102 pub unconfirmed_sponsor: AccountId, // Sponsor address that has not yet confirmed sponsorship108 pub unconfirmed_sponsor: AccountId, // Sponsor address that has not yet confirmed sponsorship103}109}104110105#[derive(Encode, Decode, Default, Clone, PartialEq)]111#[derive(Encode, Decode, Default, Debug, Clone, PartialEq)]106#[cfg_attr(feature = "std", derive(Debug))]112#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]107pub struct CollectionAdminsType<AccountId> {113pub struct CollectionAdminsType<AccountId> {108 pub admin: AccountId,114 pub admin: AccountId,109 pub collection_id: u64,115 pub collection_id: u64,110}116}111117112#[derive(Encode, Decode, Default, Clone, PartialEq)]118#[derive(Encode, Decode, Default, Debug, Clone, PartialEq)]113#[cfg_attr(feature = "std", derive(Debug))]119#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]114pub struct NftItemType<AccountId> {120pub struct NftItemType<AccountId> {115 pub collection: u64,121 pub collection: u64,116 pub owner: AccountId,122 pub owner: AccountId,117 pub data: Vec<u8>,123 pub data: Vec<u8>,118}124}119125120#[derive(Encode, Decode, Default, Clone, PartialEq)]126#[derive(Encode, Decode, Default, Debug, Clone, PartialEq)]121#[cfg_attr(feature = "std", derive(Debug))]127#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]122pub struct FungibleItemType<AccountId> {128pub struct FungibleItemType<AccountId> {123 pub collection: u64,129 pub collection: u64,124 pub owner: AccountId,130 pub owner: AccountId,125 pub value: u128,131 pub value: u128,126}132}127133128#[derive(Encode, Decode, Default, Clone, PartialEq)]134#[derive(Encode, Decode, Default, Debug, Clone, PartialEq)]129#[cfg_attr(feature = "std", derive(Debug))]135#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]130pub struct ReFungibleItemType<AccountId> {136pub struct ReFungibleItemType<AccountId> {131 pub collection: u64,137 pub collection: u64,132 pub owner: Vec<Ownership<AccountId>>,138 pub owner: Vec<Ownership<AccountId>>,133 pub data: Vec<u8>,139 pub data: Vec<u8>,134}140}135141136#[derive(Encode, Decode, Default, Clone, PartialEq)]142#[derive(Encode, Decode, Default, Debug, Clone, PartialEq)]137#[cfg_attr(feature = "std", derive(Debug))]143#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]138pub struct ApprovePermissions<AccountId> {144pub struct ApprovePermissions<AccountId> {139 pub approved: AccountId,145 pub approved: AccountId,140 pub amount: u64,146 pub amount: u64,141}147}142148143#[derive(Encode, Decode, Default, Clone, PartialEq)]149#[derive(Encode, Decode, Default, Debug, Clone, PartialEq)]144#[cfg_attr(feature = "std", derive(Debug))]150#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]145pub struct VestingItem<AccountId, Moment> {151pub struct VestingItem<AccountId, Moment> {146 pub sender: AccountId,152 pub sender: AccountId,147 pub recipient: AccountId,153 pub recipient: AccountId,155 type Event: From<Event<Self>> + Into<<Self as system::Trait>::Event>;161 type Event: From<Event<Self>> + Into<<Self as system::Trait>::Event>;156}162}157163164// #endregion165158decl_storage! {166decl_storage! {159 trait Store for Module<T: Trait> as Nft {167 trait Store for Module<T: Trait> as Nft {160168164 ChainVersion: u64;172 ChainVersion: u64;165 ItemListIndex: map hasher(blake2_128_concat) u64 => u64;173 ItemListIndex: map hasher(blake2_128_concat) u64 => u64;166174167 pub Collection get(fn collection): map hasher(identity) u64 => CollectionType<T::AccountId>;175 pub Collection get(fn collection) config(): map hasher(identity) u64 => CollectionType<T::AccountId>;168 pub AdminList get(fn admin_list_collection): map hasher(identity) u64 => Vec<T::AccountId>;176 pub AdminList get(fn admin_list_collection): map hasher(identity) u64 => Vec<T::AccountId>;169 pub WhiteList get(fn white_list): map hasher(identity) u64 => Vec<T::AccountId>;177 pub WhiteList get(fn white_list): map hasher(identity) u64 => Vec<T::AccountId>;170178175 pub ApprovedList get(fn approved): double_map hasher(blake2_128_concat) u64, hasher(blake2_128_concat) (u64, T::AccountId) => Vec<ApprovePermissions<T::AccountId>>;183 pub ApprovedList get(fn approved): double_map hasher(blake2_128_concat) u64, hasher(blake2_128_concat) (u64, T::AccountId) => Vec<ApprovePermissions<T::AccountId>>;176184177 /// Item collections185 /// Item collections178 pub NftItemList get(fn nft_item_id): double_map hasher(blake2_128_concat) u64, hasher(blake2_128_concat) u64 => NftItemType<T::AccountId>;186 pub NftItemList get(fn nft_item_id) config(): double_map hasher(blake2_128_concat) u64, hasher(blake2_128_concat) u64 => NftItemType<T::AccountId>;179 pub FungibleItemList get(fn fungible_item_id): double_map hasher(blake2_128_concat) u64, hasher(blake2_128_concat) u64 => FungibleItemType<T::AccountId>;187 pub FungibleItemList get(fn fungible_item_id) config(): double_map hasher(blake2_128_concat) u64, hasher(blake2_128_concat) u64 => FungibleItemType<T::AccountId>;180 pub ReFungibleItemList get(fn refungible_item_id): double_map hasher(blake2_128_concat) u64, hasher(blake2_128_concat) u64 => ReFungibleItemType<T::AccountId>;188 pub ReFungibleItemList get(fn refungible_item_id) config(): double_map hasher(blake2_128_concat) u64, hasher(blake2_128_concat) u64 => ReFungibleItemType<T::AccountId>;181189182 // Active vesting list183 // pub VestingList get(fn vesting): double_map hasher(blake2_128_concat) u64, hasher(blake2_128_concat) u64 => VestingItem<T::AccountId, T::Moment>;184185 /// Index list190 /// Index list186 pub AddressTokens get(fn address_tokens): double_map hasher(blake2_128_concat) u64, hasher(blake2_128_concat) T::AccountId => Vec<u64>;191 pub AddressTokens get(fn address_tokens): double_map hasher(blake2_128_concat) u64, hasher(blake2_128_concat) T::AccountId => Vec<u64>;187192188 // Sponsorship193 // Sponsorship189 pub ContractSponsor get(fn contract_sponsor): map hasher(identity) T::AccountId => T::AccountId;194 pub ContractSponsor get(fn contract_sponsor): map hasher(identity) T::AccountId => T::AccountId;190 pub UnconfirmedContractSponsor get(fn unconfirmed_contract_sponsor): map hasher(identity) T::AccountId => T::AccountId;195 pub UnconfirmedContractSponsor get(fn unconfirmed_contract_sponsor): map hasher(identity) T::AccountId => T::AccountId;191 }196 }197 add_extra_genesis {198 build(|config: &GenesisConfig<T>| {199 // Modification of storage200 for (_num, _c) in &config.collection {201 <Module<T>>::init_collection(_c);202 }203204 for (_num, _q, _i) in &config.nft_item_id {205 <Module<T>>::init_nft_token(_i);206 }207208 for (_num, _q, _i) in &config.fungible_item_id {209 <Module<T>>::init_fungible_token(_i);210 }211212 for (_num, _q, _i) in &config.refungible_item_id {213 <Module<T>>::init_refungible_token(_i);214 }215 })216 }192}217}193218194decl_event!(219decl_event!(209234210 fn on_initialize(now: T::BlockNumber) -> Weight {235 fn on_initialize(now: T::BlockNumber) -> Weight {211236212 if ChainVersion::get() == 0237 if ChainVersion::get() < 2213 {238 {214 let value = NextCollectionID::get();239 let value = NextCollectionID::get();215 CreatedCollectionCount::put(value);240 CreatedCollectionCount::put(value);224 // @param customDataSz size of custom data in each collection item249 // @param customDataSz size of custom data in each collection item225 // returns collection ID250 // returns collection ID226 #[weight = 0]251 #[weight = 0]227 pub fn create_collection( origin,252 pub fn create_collection(origin,228 collection_name: Vec<u16>,253 collection_name: Vec<u16>,229 collection_description: Vec<u16>,254 collection_description: Vec<u16>,230 token_prefix: Vec<u8>,255 token_prefix: Vec<u8>,231 mode: CollectionMode) -> DispatchResult {256 mode: CollectionMode) -> DispatchResult {232257233 // Anyone can create a collection258 // Anyone can create a collection234 let who = ensure_signed(origin)?;259 let who = ensure_signed(origin)?;271 owner: who.clone(),296 owner: who.clone(),272 name: name,297 name: name,273 mode: mode.clone(),298 mode: mode.clone(),299 mint_mode: false,274 access: AccessMode::Normal,300 access: AccessMode::Normal,275 description: description,301 description: description,276 decimal_points: decimal_points,302 decimal_points: decimal_points,309 }335 }310336311 #[weight = 0]337 #[weight = 0]338 pub fn add_to_white_list(origin, collection_id: u64, address: T::AccountId) -> DispatchResult{339340 let sender = ensure_signed(origin)?;341 Self::check_owner_or_admin_permissions(collection_id, sender)?;342343 let mut white_list_collection: Vec<T::AccountId>;344 if <WhiteList<T>>::contains_key(collection_id) {345 white_list_collection = <WhiteList<T>>::get(collection_id);346 if !white_list_collection.contains(&address.clone())347 {348 white_list_collection.push(address.clone());349 }350 }351 else {352 white_list_collection = Vec::new();353 white_list_collection.push(address.clone());354 }355356 <WhiteList<T>>::insert(collection_id, white_list_collection);357 Ok(())358 }359360 #[weight = 0]361 pub fn remove_from_white_list(origin, collection_id: u64, address: T::AccountId) -> DispatchResult{362363 let sender = ensure_signed(origin)?;364 Self::check_owner_or_admin_permissions(collection_id, sender)?;365366 if <WhiteList<T>>::contains_key(collection_id) {367 let mut white_list_collection = <WhiteList<T>>::get(collection_id);368 if white_list_collection.contains(&address.clone())369 {370 white_list_collection.retain(|i| *i != address.clone());371 <WhiteList<T>>::insert(collection_id, white_list_collection);372 }373 }374375 Ok(())376 }377378 #[weight = 0]379 pub fn set_public_access_mode(origin, collection_id: u64, mode: AccessMode) -> DispatchResult380 {381 let sender = ensure_signed(origin)?;382383 Self::check_owner_permissions(collection_id, sender)?;384 let mut target_collection = <Collection<T>>::get(collection_id);385 target_collection.access = mode;386 <Collection<T>>::insert(collection_id, target_collection);387388 Ok(())389 }390391 #[weight = 0]392 pub fn set_mint_permission(origin, collection_id: u64, mint_permission: bool) -> DispatchResult393 {394 let sender = ensure_signed(origin)?;395396 Self::check_owner_permissions(collection_id, sender)?;397 let mut target_collection = <Collection<T>>::get(collection_id);398 target_collection.mint_mode = mint_permission;399 <Collection<T>>::insert(collection_id, target_collection);400401 Ok(())402 }403404 #[weight = 0]312 pub fn change_collection_owner(origin, collection_id: u64, new_owner: T::AccountId) -> DispatchResult {405 pub fn change_collection_owner(origin, collection_id: u64, new_owner: T::AccountId) -> DispatchResult {313406314 let sender = ensure_signed(origin)?;407 let sender = ensure_signed(origin)?;405 pub fn create_item(origin, collection_id: u64, properties: Vec<u8>, owner: T::AccountId) -> DispatchResult {498 pub fn create_item(origin, collection_id: u64, properties: Vec<u8>, owner: T::AccountId) -> DispatchResult {406499407 let sender = ensure_signed(origin)?;500 let sender = ensure_signed(origin)?;501 Self::collection_exists(collection_id)?;408 let target_collection = <Collection<T>>::get(collection_id);502 let target_collection = <Collection<T>>::get(collection_id);409 Self::check_owner_or_admin_permissions(collection_id, sender.clone())?;410503504 if !Self::is_owner_or_admin_permissions(collection_id, sender.clone()) {505 ensure!(target_collection.mint_mode == true, "Collection is not in mint mode");506 Self::check_white_list(collection_id, owner.clone())?;507 }508411 match target_collection.mode509 match target_collection.mode412 {510 {413 CollectionMode::NFT(_) => {511 CollectionMode::NFT(_) => {469 pub fn burn_item(origin, collection_id: u64, item_id: u64) -> DispatchResult {567 pub fn burn_item(origin, collection_id: u64, item_id: u64) -> DispatchResult {470568471 let sender = ensure_signed(origin)?;569 let sender = ensure_signed(origin)?;472 let item_owner = Self::is_item_owner(sender.clone(), collection_id, item_id);570 Self::collection_exists(collection_id)?;473 if !item_owner571474 {572 // Transfer permissions check475 Self::check_owner_or_admin_permissions(collection_id, sender.clone())?;476 }477 let target_collection = <Collection<T>>::get(collection_id);573 let target_collection = <Collection<T>>::get(collection_id);574 ensure!(Self::is_item_owner(sender.clone(), collection_id, item_id) || 575 Self::is_owner_or_admin_permissions(collection_id, sender.clone()), 576 "Only item owner, collection owner and admins can modify item");478577578 if target_collection.access == AccessMode::WhiteList {579 Self::check_white_list(collection_id, sender.clone())?;580 }581479 match target_collection.mode582 match target_collection.mode480 {583 {481 CollectionMode::NFT(_) => Self::burn_nft_item(collection_id, item_id)?,584 CollectionMode::NFT(_) => Self::burn_nft_item(collection_id, item_id)?,494 pub fn transfer(origin, recipient: T::AccountId, collection_id: u64, item_id: u64, value: u64) -> DispatchResult {597 pub fn transfer(origin, recipient: T::AccountId, collection_id: u64, item_id: u64, value: u64) -> DispatchResult {495598496 let sender = ensure_signed(origin)?;599 let sender = ensure_signed(origin)?;497 ensure!(Self::is_item_owner(sender.clone(), collection_id, item_id), "Only item owner can call transfer method");498600601 // Transfer permissions check499 let target_collection = <Collection<T>>::get(collection_id);602 let target_collection = <Collection<T>>::get(collection_id);603 ensure!(Self::is_item_owner(sender.clone(), collection_id, item_id) || 604 Self::is_owner_or_admin_permissions(collection_id, sender.clone()), 605 "Only item owner, collection owner and admins can modify item");500606501 // TODO: implement other modes607 if target_collection.access == AccessMode::WhiteList {608 Self::check_white_list(collection_id, sender.clone())?;609 Self::check_white_list(collection_id, recipient.clone())?;610 }611502 match target_collection.mode612 match target_collection.mode503 {613 {515625516 let sender = ensure_signed(origin)?;626 let sender = ensure_signed(origin)?;517627628 // Transfer permissions check629 let target_collection = <Collection<T>>::get(collection_id);630 ensure!(Self::is_item_owner(sender.clone(), collection_id, item_id) || 631 Self::is_owner_or_admin_permissions(collection_id, sender.clone()), 632 "Only item owner, collection owner and admins can approve");633634 if target_collection.access == AccessMode::WhiteList {635 Self::check_white_list(collection_id, sender.clone())?;636 Self::check_white_list(collection_id, approved.clone())?;637 }638518 // amount param stub639 // amount param stub519 let amount = 100000000;640 let amount = 100000000;520641521 ensure!(Self::is_item_owner(sender.clone(), collection_id, item_id), "Only item owner can call transfer method");522523 let list_exists = <ApprovedList<T>>::contains_key(collection_id, (item_id, sender.clone()));642 let list_exists = <ApprovedList<T>>::contains_key(collection_id, (item_id, sender.clone()));524 if list_exists {643 if list_exists {525644544 pub fn transfer_from(origin, from: T::AccountId, recipient: T::AccountId, collection_id: u64, item_id: u64, value: u64 ) -> DispatchResult {663 pub fn transfer_from(origin, from: T::AccountId, recipient: T::AccountId, collection_id: u64, item_id: u64, value: u64 ) -> DispatchResult {545664546 let sender = ensure_signed(origin)?;665 let sender = ensure_signed(origin)?;547 let approved_list_exists = <ApprovedList<T>>::contains_key(collection_id, (item_id, from.clone()));666 let mut appoved_transfer = false;667548 if approved_list_exists668 // Check approve549 {669 if <ApprovedList<T>>::contains_key(collection_id, (item_id, from.clone())) {550 let list_itm = <ApprovedList<T>>::get(collection_id, (item_id, from.clone()));670 let list_itm = <ApprovedList<T>>::get(collection_id, (item_id, from.clone()));551 let opt_item = list_itm.iter().find(|i| i.approved == sender.clone());671 let opt_item = list_itm.iter().find(|i| i.approved == sender.clone());552 ensure!(opt_item.is_some(), "No approve found");672 appoved_transfer = opt_item.is_some();553 ensure!(opt_item.unwrap().amount >= value, "Requested value more than approved");673 ensure!(opt_item.unwrap().amount >= value, "Requested value more than approved");554555 // remove approve556 let approve_list: Vec<ApprovePermissions<T::AccountId>> = <ApprovedList<T>>::get(collection_id, (item_id, from.clone()))557 .into_iter().filter(|i| i.approved != sender.clone()).collect();558 <ApprovedList<T>>::insert(collection_id, (item_id, from.clone()), approve_list);559 }674 }560 else561 {562 Self::check_owner_or_admin_permissions(collection_id, sender)?;563 }564675676 // Transfer permissions check565 let target_collection = <Collection<T>>::get(collection_id);677 let target_collection = <Collection<T>>::get(collection_id);678 ensure!(appoved_transfer || Self::is_owner_or_admin_permissions(collection_id, sender.clone()), 679 "Only item owner, collection owner and admins can modify items");566680681 if target_collection.access == AccessMode::WhiteList {682 Self::check_white_list(collection_id, sender.clone())?;683 Self::check_white_list(collection_id, recipient.clone())?;684 }685686 // remove approve687 let approve_list: Vec<ApprovePermissions<T::AccountId>> = <ApprovedList<T>>::get(collection_id, (item_id, from.clone()))688 .into_iter().filter(|i| i.approved != sender.clone()).collect();689 <ApprovedList<T>>::insert(collection_id, (item_id, from.clone()), approve_list);690691567 match target_collection.mode692 match target_collection.mode568 {693 {569 CollectionMode::NFT(_) => Self::transfer_nft(collection_id, item_id, from, recipient)?,694 CollectionMode::NFT(_) => Self::transfer_nft(collection_id, item_id, from, recipient)?,675 Ok(())800 Ok(())676 }801 }677802678 fn burn_refungible_item(803 fn burn_refungible_item(collection_id: u64, item_id: u64, owner: T::AccountId) -> DispatchResult {679 collection_id: u64,680 item_id: u64,681 owner: T::AccountId,682 ) -> DispatchResult {683 ensure!(804 ensure!(684 <ReFungibleItemList<T>>::contains_key(collection_id, item_id),805 <ReFungibleItemList<T>>::contains_key(collection_id, item_id),685 "Item does not exists"806 "Item does not exists"770 Ok(())891 Ok(())771 }892 }772893773 fn check_owner_or_admin_permissions(894 fn is_owner_or_admin_permissions(collection_id: u64, subject: T::AccountId) -> bool {774 collection_id: u64,775 subject: T::AccountId,776 ) -> DispatchResult {777 Self::collection_exists(collection_id)?;778895779 let target_collection = <Collection<T>>::get(collection_id);896 let target_collection = <Collection<T>>::get(collection_id);780 let is_owner = subject == target_collection.owner;897 let mut result: bool = subject == target_collection.owner;781782 let no_perm_mes = "You do not have permissions to modify this collection";783 let exists = <AdminList<T>>::contains_key(collection_id);898 let exists = <AdminList<T>>::contains_key(collection_id);784899785 if !is_owner {900 if !result & exists {786 ensure!(exists, no_perm_mes);787 ensure!(901 if <AdminList<T>>::get(collection_id).contains(&subject) {788 <AdminList<T>>::get(collection_id).contains(&subject),789 no_perm_mes902 result = true790 );903 }791 }904 }905906 result907 }908909 fn check_owner_or_admin_permissions(collection_id: u64, subject: T::AccountId) -> DispatchResult {910 911 Self::collection_exists(collection_id)?;912 let result = Self::is_owner_or_admin_permissions(collection_id, subject.clone());913914 ensure!(result, "You do not have permissions to modify this collection");792 Ok(())915 Ok(())793 }916 }794917812 }935 }813 }936 }814937938 fn check_white_list(collection_id: u64, address: T::AccountId) -> DispatchResult {939940 let mes = "Address is not in white list";941 ensure!(<WhiteList<T>>::contains_key(collection_id), mes);942 let wl = <WhiteList<T>>::get(collection_id);943 ensure!(wl.contains(&address.clone()), mes);944945 Ok(())946 }947815 fn transfer_fungible(948 fn transfer_fungible(816 collection_id: u64,949 collection_id: u64,817 item_id: u64,950 item_id: u64,818 value: u64,951 value: u64,819 owner: T::AccountId,952 owner: T::AccountId,820 new_owner: T::AccountId,953 new_owner: T::AccountId,821 ) -> DispatchResult {954 ) -> DispatchResult {955956 ensure!(957 <FungibleItemList<T>>::contains_key(collection_id, item_id),958 "Item not exists"959 );960822 let full_item = <FungibleItemList<T>>::get(collection_id, item_id);961 let full_item = <FungibleItemList<T>>::get(collection_id, item_id);823 let amount = full_item.value;962 let amount = full_item.value;824963903 owner: T::AccountId,1042 owner: T::AccountId,904 new_owner: T::AccountId,1043 new_owner: T::AccountId,905 ) -> DispatchResult {1044 ) -> DispatchResult {10451046 ensure!(1047 <ReFungibleItemList<T>>::contains_key(collection_id, item_id),1048 "Item not exists"1049 );1050906 let full_item = <ReFungibleItemList<T>>::get(collection_id, item_id);1051 let full_item = <ReFungibleItemList<T>>::get(collection_id, item_id);907 let item = full_item1052 let item = full_item908 .owner1053 .owner983 sender: T::AccountId,1128 sender: T::AccountId,984 new_owner: T::AccountId,1129 new_owner: T::AccountId,985 ) -> DispatchResult {1130 ) -> DispatchResult {1131 1132 ensure!(1133 <NftItemList<T>>::contains_key(collection_id, item_id),1134 "Item not exists"1135 );1136986 let mut item = <NftItemList<T>>::get(collection_id, item_id);1137 let mut item = <NftItemList<T>>::get(collection_id, item_id);9871138988 ensure!(1139 ensure!(1012 // reset approved list1163 // reset approved list1013 <ApprovedList<T>>::remove(collection_id, (item_id, old_owner));1164 <ApprovedList<T>>::remove(collection_id, (item_id, old_owner));1014 Ok(())1165 Ok(())1166 }11671168 fn init_collection(item: &CollectionType<T::AccountId>){11691170 // check params1171 assert!(item.decimal_points <= 4, "decimal_points parameter must be lower than 4");1172 assert!(item.name.len() <= 64, "Collection name can not be longer than 63 char");1173 assert!(item.name.len() <= 256, "Collection description can not be longer than 255 char");1174 assert!(item.token_prefix.len() <= 16, "Token prefix can not be longer than 15 char");1175 1176 // Generate next collection ID1177 let next_id = CreatedCollectionCount::get()1178 .checked_add(1)1179 .expect("collection id error");1180 1181 CreatedCollectionCount::put(next_id); 1182 }11831184 fn init_nft_token(item: &NftItemType<T::AccountId>){11851186 let current_index = <ItemListIndex>::get(item.collection)1187 .checked_add(1)1188 .expect("Item list index id error");11891190 let item_owner = item.owner.clone();1191 let collection_id = item.collection.clone();1192 Self::add_token_index(collection_id, current_index, item.owner.clone()).unwrap();11931194 <ItemListIndex>::insert(collection_id, current_index);11951196 // Update balance1197 let new_balance = <Balance<T>>::get(collection_id, item_owner.clone())1198 .checked_add(1)1199 .unwrap();1200 <Balance<T>>::insert(collection_id, item_owner.clone(), new_balance);1201 }12021203 fn init_fungible_token(item: &FungibleItemType<T::AccountId>){12041205 let current_index = <ItemListIndex>::get(item.collection)1206 .checked_add(1)1207 .expect("Item list index id error");1208 let owner = item.owner.clone();1209 let value = item.value as u64;12101211 Self::add_token_index(item.collection, current_index, owner.clone()).unwrap();12121213 <ItemListIndex>::insert(item.collection, current_index);12141215 // Update balance1216 let new_balance = <Balance<T>>::get(item.collection, owner.clone())1217 .checked_add(value)1218 .unwrap();1219 <Balance<T>>::insert(item.collection, owner.clone(), new_balance);1220 }12211222 fn init_refungible_token(item: &ReFungibleItemType<T::AccountId>){12231224 let current_index = <ItemListIndex>::get(item.collection)1225 .checked_add(1)1226 .expect("Item list index id error");12271228 let value = item.owner.first().unwrap().fraction as u64;1229 let owner = item.owner.first().unwrap().owner.clone();12301231 Self::add_token_index(item.collection, current_index, owner.clone()).unwrap();12321233 <ItemListIndex>::insert(item.collection, current_index);12341235 // Update balance1236 let new_balance = <Balance<T>>::get(item.collection, owner.clone())1237 .checked_add(value)1238 .unwrap();1239 <Balance<T>>::insert(item.collection, owner.clone(), new_balance);1015 }1240 }101612411017 fn add_token_index(collection_id: u64, item_index: u64, owner: T::AccountId) -> DispatchResult {1242 fn add_token_index(collection_id: u64, item_index: u64, owner: T::AccountId) -> DispatchResult {106812931069////////////////////////////////////////////////////////////////////////////////////////////////////1294////////////////////////////////////////////////////////////////////////////////////////////////////1070// Economic models1295// Economic models1296// #region107112971072/// Fee multiplier.1298/// Fee multiplier.1073pub type Multiplier = FixedU128;1299pub type Multiplier = FixedU128;1262 Ok(())1488 Ok(())1263 }1489 }1264}1490}12651491// #endregionpallets/nft/src/tests.rsdiffbeforeafterboth1// Tests to be written here1// Tests to be written here2use crate::mock::*;2use crate::mock::*;3use crate::{ApprovePermissions, CollectionMode, Ownership};3use crate::{ApprovePermissions, CollectionMode, AccessMode, Ownership};4use frame_support::{assert_noop, assert_ok};4use frame_support::{assert_noop, assert_ok};556// Use cases tests region7// #region6#[test]8#[test]7fn create_nft_item() {9fn create_nft_item() {8 new_test_ext().execute_with(|| {10 new_test_ext().execute_with(|| {321 assert_eq!(TemplateModule::balance_count(1, 1), 1);323 assert_eq!(TemplateModule::balance_count(1, 1), 1);322 assert_eq!(TemplateModule::address_tokens(1, 1), [1]);324 assert_eq!(TemplateModule::address_tokens(1, 1), [1]);323325324 assert_noop!(326 assert_ok!(TemplateModule::set_mint_permission(origin1.clone(), 1, true));325 TemplateModule::transfer_from(origin2.clone(), 1, 3, 1, 1, 1),327 assert_ok!(TemplateModule::set_public_access_mode(origin1.clone(), 1, AccessMode::WhiteList));326 "You do not have permissions to modify this collection"328 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 1));329 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 2));327 );330 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 3));328331329 // do approve332 // do approve330 assert_ok!(TemplateModule::approve(origin1.clone(), 2, 1, 1));333 assert_ok!(TemplateModule::approve(origin1.clone(), 2, 1, 1));331 assert_eq!(TemplateModule::approved(1, (1, 1)).len(), 1);334 assert_eq!(TemplateModule::approved(1, (1, 1)).len(), 1);332 assert_ok!(TemplateModule::approve(origin1.clone(), 10, 1, 1));335 assert_ok!(TemplateModule::approve(origin1.clone(), 3, 1, 1));333 assert_eq!(TemplateModule::approved(1, (1, 1)).len(), 2);336 assert_eq!(TemplateModule::approved(1, (1, 1)).len(), 2);334 assert_eq!(337 assert_eq!(335 TemplateModule::approved(1, (1, 1))[0],338 TemplateModule::approved(1, (1, 1))[0],390 assert_eq!(TemplateModule::balance_count(1, 1), 1000);393 assert_eq!(TemplateModule::balance_count(1, 1), 1000);391 assert_eq!(TemplateModule::address_tokens(1, 1), [1]);394 assert_eq!(TemplateModule::address_tokens(1, 1), [1]);392395393 assert_noop!(396 assert_ok!(TemplateModule::set_mint_permission(origin1.clone(), 1, true));394 TemplateModule::transfer_from(origin2.clone(), 1, 3, 1, 1, 1),397 assert_ok!(TemplateModule::set_public_access_mode(origin1.clone(), 1, AccessMode::WhiteList));395 "You do not have permissions to modify this collection"398 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 1));399 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 2));396 );400 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 3));397401398 // do approve402 // do approve399 assert_ok!(TemplateModule::approve(origin1.clone(), 2, 1, 1));403 assert_ok!(TemplateModule::approve(origin1.clone(), 2, 1, 1));400 assert_eq!(TemplateModule::approved(1, (1, 1)).len(), 1);404 assert_eq!(TemplateModule::approved(1, (1, 1)).len(), 1);401 assert_ok!(TemplateModule::approve(origin1.clone(), 10, 1, 1));405 assert_ok!(TemplateModule::approve(origin1.clone(), 3, 1, 1));402 assert_eq!(TemplateModule::approved(1, (1, 1)).len(), 2);406 assert_eq!(TemplateModule::approved(1, (1, 1)).len(), 2);403 assert_eq!(407 assert_eq!(404 TemplateModule::approved(1, (1, 1))[0],408 TemplateModule::approved(1, (1, 1))[0],425 assert_eq!(429 assert_eq!(426 TemplateModule::approved(1, (1, 1))[0],430 TemplateModule::approved(1, (1, 1))[0],427 ApprovePermissions {431 ApprovePermissions {428 approved: 10,432 approved: 3,429 amount: 100000000433 amount: 100000000430 }434 }431 );435 );461 assert_eq!(TemplateModule::balance_count(1, 1), 1000);465 assert_eq!(TemplateModule::balance_count(1, 1), 1000);462 assert_eq!(TemplateModule::address_tokens(1, 1), [1]);466 assert_eq!(TemplateModule::address_tokens(1, 1), [1]);463467464 assert_noop!(468 assert_ok!(TemplateModule::set_mint_permission(origin1.clone(), 1, true));465 TemplateModule::transfer_from(origin2.clone(), 1, 3, 1, 1, 1),469 assert_ok!(TemplateModule::set_public_access_mode(origin1.clone(), 1, AccessMode::WhiteList));466 "You do not have permissions to modify this collection"470 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 1));471 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 2));467 );472 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 3));468473469 // do approve474 // do approve470 assert_ok!(TemplateModule::approve(origin1.clone(), 2, 1, 1));475 assert_ok!(TemplateModule::approve(origin1.clone(), 2, 1, 1));471 assert_eq!(TemplateModule::approved(1, (1, 1)).len(), 1);476 assert_eq!(TemplateModule::approved(1, (1, 1)).len(), 1);472 assert_ok!(TemplateModule::approve(origin1.clone(), 10, 1, 1));477 assert_ok!(TemplateModule::approve(origin1.clone(), 3, 1, 1));473 assert_eq!(TemplateModule::approved(1, (1, 1)).len(), 2);478 assert_eq!(TemplateModule::approved(1, (1, 1)).len(), 2);474 assert_eq!(479 assert_eq!(475 TemplateModule::approved(1, (1, 1))[0],480 TemplateModule::approved(1, (1, 1))[0],496 assert_eq!(501 assert_eq!(497 TemplateModule::approved(1, (1, 1))[0],502 TemplateModule::approved(1, (1, 1))[0],498 ApprovePermissions {503 ApprovePermissions {499 approved: 10,504 approved: 3,500 amount: 100000000505 amount: 100000000501 }506 }502 );507 );573 let mode: CollectionMode = CollectionMode::NFT(2000);578 let mode: CollectionMode = CollectionMode::NFT(2000);574579575 let origin1 = Origin::signed(1);580 let origin1 = Origin::signed(1);576 let origin2 = Origin::signed(2);577 assert_ok!(TemplateModule::create_collection(581 assert_ok!(TemplateModule::create_collection(578 origin1.clone(),582 origin1.clone(),579 col_name1.clone(),583 col_name1.clone(),583 ));587 ));584 assert_ok!(TemplateModule::add_collection_admin(origin1.clone(), 1, 2));588 assert_ok!(TemplateModule::add_collection_admin(origin1.clone(), 1, 2));585 assert_ok!(TemplateModule::create_item(589 assert_ok!(TemplateModule::create_item(586 origin2.clone(),590 origin1.clone(),587 1,591 1,588 [1, 2, 3].to_vec(),592 [1, 2, 3].to_vec(),589 1593 1614 let mode: CollectionMode = CollectionMode::Fungible(3);618 let mode: CollectionMode = CollectionMode::Fungible(3);615619616 let origin1 = Origin::signed(1);620 let origin1 = Origin::signed(1);617 let origin2 = Origin::signed(2);618 assert_ok!(TemplateModule::create_collection(621 assert_ok!(TemplateModule::create_collection(619 origin1.clone(),622 origin1.clone(),620 col_name1.clone(),623 col_name1.clone(),624 ));627 ));625 assert_ok!(TemplateModule::add_collection_admin(origin1.clone(), 1, 2));628 assert_ok!(TemplateModule::add_collection_admin(origin1.clone(), 1, 2));626 assert_ok!(TemplateModule::create_item(629 assert_ok!(TemplateModule::create_item(627 origin2.clone(),630 origin1.clone(),628 1,631 1,629 [].to_vec(),632 [].to_vec(),630 1633 1661 token_prefix1.clone(),664 token_prefix1.clone(),662 mode665 mode663 ));666 ));667 668 assert_ok!(TemplateModule::set_mint_permission(origin1.clone(), 1, true));669 assert_ok!(TemplateModule::set_public_access_mode(origin1.clone(), 1, AccessMode::WhiteList));670 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 1));671664 assert_ok!(TemplateModule::add_collection_admin(origin1.clone(), 1, 2));672 assert_ok!(TemplateModule::add_collection_admin(origin1.clone(), 1, 2));665 assert_ok!(TemplateModule::create_item(673 assert_ok!(TemplateModule::create_item(666 origin2.clone(),674 origin2.clone(),928 // approve936 // approve929 assert_ok!(TemplateModule::approve(origin1.clone(), 2, 1, 1));937 assert_ok!(TemplateModule::approve(origin1.clone(), 2, 1, 1));930 assert_eq!(TemplateModule::approved(1, (1, 1))[0].approved, 2);938 assert_eq!(TemplateModule::approved(1, (1, 1))[0].approved, 2);939940 assert_ok!(TemplateModule::set_mint_permission(origin1.clone(), 1, true));941 assert_ok!(TemplateModule::set_public_access_mode(origin1.clone(), 1, AccessMode::WhiteList));942 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 1));943 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 2));944 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 3));945931 assert_ok!(TemplateModule::transfer_from(946 assert_ok!(TemplateModule::transfer_from(932 origin2.clone(),947 origin2.clone(),933 1,948 1,943 });958 });944}959}945960961// #endregion962963// Coverage tests region964// #region965966#[test]967fn owner_can_add_address_to_white_list() {968 new_test_ext().execute_with(|| {969 let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();970 let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();971 let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();972 let mode: CollectionMode = CollectionMode::NFT(2000);973 let origin1 = Origin::signed(1);974975 assert_ok!(TemplateModule::create_collection(976 origin1.clone(),977 col_name1.clone(),978 col_desc1.clone(),979 token_prefix1.clone(),980 mode981 ));982983 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 2));984 assert_eq!(TemplateModule::white_list(1)[0], 2);985 });986}987988#[test]989fn admin_can_add_address_to_white_list() {990 new_test_ext().execute_with(|| {991 let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();992 let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();993 let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();994 let mode: CollectionMode = CollectionMode::NFT(2000);995 let origin1 = Origin::signed(1);996 let origin2 = Origin::signed(2);997998 assert_ok!(TemplateModule::create_collection(999 origin1.clone(),1000 col_name1.clone(),1001 col_desc1.clone(),1002 token_prefix1.clone(),1003 mode1004 ));10051006 assert_ok!(TemplateModule::add_collection_admin(origin1.clone(), 1, 2));1007 assert_ok!(TemplateModule::add_to_white_list(origin2.clone(), 1, 3));1008 assert_eq!(TemplateModule::white_list(1)[0], 3);1009 });1010}10111012#[test]1013fn nonprivileged_user_cannot_add_address_to_white_list() {1014 new_test_ext().execute_with(|| {1015 let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();1016 let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();1017 let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();1018 let mode: CollectionMode = CollectionMode::NFT(2000);1019 let origin1 = Origin::signed(1);1020 let origin2 = Origin::signed(2);10211022 assert_ok!(TemplateModule::create_collection(1023 origin1.clone(),1024 col_name1.clone(),1025 col_desc1.clone(),1026 token_prefix1.clone(),1027 mode1028 ));10291030 assert_noop!(TemplateModule::add_to_white_list(origin2.clone(), 1, 3), "You do not have permissions to modify this collection");1031 });1032}10331034#[test]1035fn nobody_can_add_address_to_white_list_of_nonexisting_collection() {1036 new_test_ext().execute_with(|| {10371038 let origin1 = Origin::signed(1);1039 assert_noop!(TemplateModule::add_to_white_list(origin1.clone(), 1, 2), "This collection does not exist");1040 });1041}10421043#[test]1044fn nobody_can_add_address_to_white_list_of_deleted_collection() {1045 new_test_ext().execute_with(|| {1046 let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();1047 let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();1048 let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();1049 let mode: CollectionMode = CollectionMode::NFT(2000);1050 let origin1 = Origin::signed(1);10511052 assert_ok!(TemplateModule::create_collection(1053 origin1.clone(),1054 col_name1.clone(),1055 col_desc1.clone(),1056 token_prefix1.clone(),1057 mode1058 ));10591060 assert_ok!(TemplateModule::destroy_collection(origin1.clone(), 1));1061 assert_noop!(TemplateModule::add_to_white_list(origin1.clone(), 1, 2), "This collection does not exist");1062 });1063}10641065// If address is already added to white list, nothing happens1066#[test]1067fn address_is_already_added_to_white_list() {1068 new_test_ext().execute_with(|| {10691070 let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();1071 let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();1072 let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();1073 let mode: CollectionMode = CollectionMode::NFT(2000);1074 let origin1 = Origin::signed(1);10751076 assert_ok!(TemplateModule::create_collection(1077 origin1.clone(),1078 col_name1.clone(),1079 col_desc1.clone(),1080 token_prefix1.clone(),1081 mode1082 ));10831084 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 2));1085 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 2));1086 assert_eq!(TemplateModule::white_list(1)[0], 2);1087 assert_eq!(TemplateModule::white_list(1).len(), 1);1088 });1089}10901091#[test]1092fn owner_can_remove_address_from_white_list() {1093 new_test_ext().execute_with(|| {1094 1095 let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();1096 let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();1097 let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();1098 let mode: CollectionMode = CollectionMode::NFT(2000);1099 let origin1 = Origin::signed(1);11001101 assert_ok!(TemplateModule::create_collection(1102 origin1.clone(),1103 col_name1.clone(),1104 col_desc1.clone(),1105 token_prefix1.clone(),1106 mode1107 ));11081109 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 2));1110 assert_ok!(TemplateModule::remove_from_white_list(origin1.clone(), 1, 2));1111 assert_eq!(TemplateModule::white_list(1).len(), 0);1112 });1113}11141115#[test]1116fn admin_can_remove_address_from_white_list() {1117 new_test_ext().execute_with(|| {11181119 let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();1120 let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();1121 let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();1122 let mode: CollectionMode = CollectionMode::NFT(2000);1123 let origin1 = Origin::signed(1);1124 let origin2 = Origin::signed(2);11251126 assert_ok!(TemplateModule::create_collection(1127 origin1.clone(),1128 col_name1.clone(),1129 col_desc1.clone(),1130 token_prefix1.clone(),1131 mode1132 ));11331134 assert_ok!(TemplateModule::add_collection_admin(origin1.clone(), 1, 2));11351136 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 3));1137 assert_ok!(TemplateModule::remove_from_white_list(origin2.clone(), 1, 3));1138 assert_eq!(TemplateModule::white_list(1).len(), 0);1139 });1140}11411142#[test]1143fn nonprivileged_user_cannot_remove_address_from_white_list() {1144 new_test_ext().execute_with(|| {11451146 let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();1147 let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();1148 let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();1149 let mode: CollectionMode = CollectionMode::NFT(2000);1150 let origin1 = Origin::signed(1);1151 let origin2 = Origin::signed(2);11521153 assert_ok!(TemplateModule::create_collection(1154 origin1.clone(),1155 col_name1.clone(),1156 col_desc1.clone(),1157 token_prefix1.clone(),1158 mode1159 ));11601161 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 2));1162 assert_noop!(TemplateModule::remove_from_white_list(origin2.clone(), 1, 2), "You do not have permissions to modify this collection");1163 assert_eq!(TemplateModule::white_list(1)[0], 2);1164 });1165}11661167#[test]1168fn nobody_can_remove_address_from_white_list_of_nonexisting_collection() {1169 new_test_ext().execute_with(|| {11701171 let origin1 = Origin::signed(1);1172 assert_noop!(TemplateModule::remove_from_white_list(origin1.clone(), 1, 2), "This collection does not exist");1173 });1174}11751176#[test]1177fn nobody_can_remove_address_from_white_list_of_deleted_collection() {1178 new_test_ext().execute_with(|| {11791180 let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();1181 let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();1182 let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();1183 let mode: CollectionMode = CollectionMode::NFT(2000);1184 let origin1 = Origin::signed(1);1185 let origin2 = Origin::signed(2);11861187 assert_ok!(TemplateModule::create_collection(1188 origin1.clone(),1189 col_name1.clone(),1190 col_desc1.clone(),1191 token_prefix1.clone(),1192 mode1193 ));11941195 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 2));1196 assert_ok!(TemplateModule::destroy_collection(origin1.clone(), 1));1197 assert_noop!(TemplateModule::remove_from_white_list(origin2.clone(), 1, 2), "This collection does not exist");1198 assert_eq!(TemplateModule::white_list(1).len(), 0);1199 });1200}12011202// If address is already removed from white list, nothing happens1203#[test]1204fn address_is_already_removed_from_white_list() {1205 new_test_ext().execute_with(|| {1206 let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();1207 let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();1208 let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();1209 let mode: CollectionMode = CollectionMode::NFT(2000);1210 let origin1 = Origin::signed(1);12111212 assert_ok!(TemplateModule::create_collection(1213 origin1.clone(),1214 col_name1.clone(),1215 col_desc1.clone(),1216 token_prefix1.clone(),1217 mode1218 ));12191220 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 2));1221 assert_ok!(TemplateModule::remove_from_white_list(origin1.clone(), 1, 2));1222 assert_ok!(TemplateModule::remove_from_white_list(origin1.clone(), 1, 2));1223 assert_eq!(TemplateModule::white_list(1).len(), 0);1224 });1225}12261227// If Public Access mode is set to WhiteList, tokens can’t be transferred from a non-whitelisted address with transfer or transferFrom (2 tests)1228#[test]1229fn white_list_test_1() {1230 new_test_ext().execute_with(|| {1231 let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();1232 let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();1233 let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();1234 let mode: CollectionMode = CollectionMode::NFT(2000);12351236 let origin1 = Origin::signed(1);1237 assert_ok!(TemplateModule::create_collection(1238 origin1.clone(),1239 col_name1.clone(),1240 col_desc1.clone(),1241 token_prefix1.clone(),1242 mode1243 ));1244 assert_eq!(TemplateModule::collection(1).owner, 1);12451246 assert_ok!(TemplateModule::create_item(1247 origin1.clone(),1248 1,1249 [1, 2, 3].to_vec(),1250 11251 ));12521253 assert_ok!(TemplateModule::set_public_access_mode(origin1.clone(), 1, AccessMode::WhiteList));1254 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 2));12551256 assert_noop!(TemplateModule::transfer(1257 origin1.clone(),1258 3,1259 1,1260 1,1261 11262 ), "Address is not in white list");1263 });1264}12651266#[test]1267fn white_list_test_2() {1268 new_test_ext().execute_with(|| {1269 let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();1270 let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();1271 let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();1272 let mode: CollectionMode = CollectionMode::NFT(2000);12731274 let origin1 = Origin::signed(1);1275 assert_ok!(TemplateModule::create_collection(1276 origin1.clone(),1277 col_name1.clone(),1278 col_desc1.clone(),1279 token_prefix1.clone(),1280 mode1281 ));1282 assert_eq!(TemplateModule::collection(1).owner, 1);12831284 assert_ok!(TemplateModule::create_item(1285 origin1.clone(),1286 1,1287 [1, 2, 3].to_vec(),1288 11289 ));12901291 assert_ok!(TemplateModule::set_public_access_mode(origin1.clone(), 1, AccessMode::WhiteList));1292 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 1));1293 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 2));12941295 // do approve1296 assert_ok!(TemplateModule::approve(origin1.clone(), 1, 1, 1));1297 assert_eq!(TemplateModule::approved(1, (1, 1)).len(), 1);12981299 assert_ok!(TemplateModule::remove_from_white_list(origin1.clone(), 1, 1));13001301 assert_noop!(TemplateModule::transfer_from(1302 origin1.clone(),1303 1,1304 3,1305 1,1306 1,1307 11308 ), "Address is not in white list");1309 });1310}13111312// If Public Access mode is set to WhiteList, tokens can’t be transferred to a non-whitelisted address with transfer or transferFrom (2 tests)1313#[test]1314fn white_list_test_3() {1315 new_test_ext().execute_with(|| {1316 let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();1317 let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();1318 let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();1319 let mode: CollectionMode = CollectionMode::NFT(2000);13201321 let origin1 = Origin::signed(1);1322 assert_ok!(TemplateModule::create_collection(1323 origin1.clone(),1324 col_name1.clone(),1325 col_desc1.clone(),1326 token_prefix1.clone(),1327 mode1328 ));1329 assert_eq!(TemplateModule::collection(1).owner, 1);13301331 assert_ok!(TemplateModule::create_item(1332 origin1.clone(),1333 1,1334 [1, 2, 3].to_vec(),1335 11336 ));13371338 assert_ok!(TemplateModule::set_public_access_mode(origin1.clone(), 1, AccessMode::WhiteList));1339 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 1));13401341 assert_noop!(TemplateModule::transfer(1342 origin1.clone(),1343 3,1344 1,1345 1,1346 11347 ), "Address is not in white list");1348 });1349}13501351#[test]1352fn white_list_test_4() {1353 new_test_ext().execute_with(|| {1354 let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();1355 let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();1356 let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();1357 let mode: CollectionMode = CollectionMode::NFT(2000);13581359 let origin1 = Origin::signed(1);1360 assert_ok!(TemplateModule::create_collection(1361 origin1.clone(),1362 col_name1.clone(),1363 col_desc1.clone(),1364 token_prefix1.clone(),1365 mode1366 ));1367 assert_eq!(TemplateModule::collection(1).owner, 1);13681369 assert_ok!(TemplateModule::create_item(1370 origin1.clone(),1371 1,1372 [1, 2, 3].to_vec(),1373 11374 ));13751376 assert_ok!(TemplateModule::set_public_access_mode(origin1.clone(), 1, AccessMode::WhiteList));1377 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 1));1378 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 2));13791380 // do approve1381 assert_ok!(TemplateModule::approve(origin1.clone(), 1, 1, 1));1382 assert_eq!(TemplateModule::approved(1, (1, 1)).len(), 1);13831384 assert_ok!(TemplateModule::remove_from_white_list(origin1.clone(), 1, 2));13851386 assert_noop!(TemplateModule::transfer_from(1387 origin1.clone(),1388 1,1389 3,1390 1,1391 1,1392 11393 ), "Address is not in white list");1394 });1395}13961397// If Public Access mode is set to WhiteList, tokens can’t be destroyed by a non-whitelisted address (even if it owned them before enabling WhiteList mode)1398#[test]1399fn white_list_test_5() {1400 new_test_ext().execute_with(|| {1401 let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();1402 let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();1403 let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();1404 let mode: CollectionMode = CollectionMode::NFT(2000);14051406 let origin1 = Origin::signed(1);1407 assert_ok!(TemplateModule::create_collection(1408 origin1.clone(),1409 col_name1.clone(),1410 col_desc1.clone(),1411 token_prefix1.clone(),1412 mode1413 ));1414 assert_eq!(TemplateModule::collection(1).owner, 1);14151416 assert_ok!(TemplateModule::create_item(1417 origin1.clone(),1418 1,1419 [1, 2, 3].to_vec(),1420 11421 ));14221423 assert_ok!(TemplateModule::set_public_access_mode(origin1.clone(), 1, AccessMode::WhiteList));1424 assert_noop!(TemplateModule::burn_item(origin1.clone(), 1, 1), "Address is not in white list");1425 });1426}14271428// If Public Access mode is set to WhiteList, oken transfers can’t be Approved by a non-whitelisted address (see Approve method).1429#[test]1430fn white_list_test_6() {1431 new_test_ext().execute_with(|| {1432 let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();1433 let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();1434 let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();1435 let mode: CollectionMode = CollectionMode::NFT(2000);14361437 let origin1 = Origin::signed(1);1438 assert_ok!(TemplateModule::create_collection(1439 origin1.clone(),1440 col_name1.clone(),1441 col_desc1.clone(),1442 token_prefix1.clone(),1443 mode1444 ));1445 assert_ok!(TemplateModule::set_public_access_mode(origin1.clone(), 1, AccessMode::WhiteList));14461447 // do approve1448 assert_noop!(TemplateModule::approve(origin1.clone(), 1, 1, 1), "Address is not in white list");1449 });1450}14511452// If Public Access mode is set to WhiteList, tokens can be transferred from a whitelisted address with transfer or transferFrom (2 tests) and1453// tokens can be transferred from a whitelisted address with transfer or transferFrom (2 tests)1454#[test]1455fn white_list_test_7() {1456 new_test_ext().execute_with(|| {1457 let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();1458 let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();1459 let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();1460 let mode: CollectionMode = CollectionMode::NFT(2000);14611462 let origin1 = Origin::signed(1);1463 assert_ok!(TemplateModule::create_collection(1464 origin1.clone(),1465 col_name1.clone(),1466 col_desc1.clone(),1467 token_prefix1.clone(),1468 mode1469 ));1470 assert_eq!(TemplateModule::collection(1).owner, 1);14711472 assert_ok!(TemplateModule::create_item(1473 origin1.clone(),1474 1,1475 [1, 2, 3].to_vec(),1476 11477 ));14781479 assert_ok!(TemplateModule::set_public_access_mode(origin1.clone(), 1, AccessMode::WhiteList));1480 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 1));1481 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 2));14821483 assert_ok!(TemplateModule::transfer(1484 origin1.clone(),1485 2,1486 1,1487 1,1488 11489 ));1490 });1491}14921493#[test]1494fn white_list_test_8() {1495 new_test_ext().execute_with(|| {1496 let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();1497 let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();1498 let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();1499 let mode: CollectionMode = CollectionMode::NFT(2000);15001501 let origin1 = Origin::signed(1);1502 assert_ok!(TemplateModule::create_collection(1503 origin1.clone(),1504 col_name1.clone(),1505 col_desc1.clone(),1506 token_prefix1.clone(),1507 mode1508 ));1509 assert_eq!(TemplateModule::collection(1).owner, 1);15101511 assert_ok!(TemplateModule::create_item(1512 origin1.clone(),1513 1,1514 [1, 2, 3].to_vec(),1515 11516 ));15171518 assert_ok!(TemplateModule::set_public_access_mode(origin1.clone(), 1, AccessMode::WhiteList));1519 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 1));1520 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 2));15211522 // do approve1523 assert_ok!(TemplateModule::approve(origin1.clone(), 1, 1, 1));1524 assert_eq!(TemplateModule::approved(1, (1, 1)).len(), 1);15251526 assert_ok!(TemplateModule::transfer_from(1527 origin1.clone(),1528 1,1529 2,1530 1,1531 1,1532 11533 ));1534 });1535}15361537// If Public Access mode is set to WhiteList, and Mint Permission is set to false, tokens can be created by owner.1538#[test]1539fn white_list_test_9() {1540 new_test_ext().execute_with(|| {1541 let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();1542 let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();1543 let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();1544 let mode: CollectionMode = CollectionMode::NFT(2000);15451546 let origin1 = Origin::signed(1);1547 assert_ok!(TemplateModule::create_collection(1548 origin1.clone(),1549 col_name1.clone(),1550 col_desc1.clone(),1551 token_prefix1.clone(),1552 mode1553 ));15541555 assert_ok!(TemplateModule::set_public_access_mode(origin1.clone(), 1, AccessMode::WhiteList));1556 assert_ok!(TemplateModule::set_mint_permission(origin1.clone(), 1, false));15571558 assert_ok!(TemplateModule::create_item(1559 origin1.clone(),1560 1,1561 [1, 2, 3].to_vec(),1562 11563 ));1564 });1565}15661567// If Public Access mode is set to WhiteList, and Mint Permission is set to false, tokens can be created by admin.1568#[test]1569fn white_list_test_10() {1570 new_test_ext().execute_with(|| {1571 let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();1572 let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();1573 let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();1574 let mode: CollectionMode = CollectionMode::NFT(2000);15751576 let origin1 = Origin::signed(1);1577 let origin2 = Origin::signed(2);1578 assert_ok!(TemplateModule::create_collection(1579 origin1.clone(),1580 col_name1.clone(),1581 col_desc1.clone(),1582 token_prefix1.clone(),1583 mode1584 ));15851586 assert_ok!(TemplateModule::set_public_access_mode(origin1.clone(), 1, AccessMode::WhiteList));1587 assert_ok!(TemplateModule::set_mint_permission(origin1.clone(), 1, false));15881589 assert_ok!(TemplateModule::add_collection_admin(origin1.clone(), 1, 2));15901591 assert_ok!(TemplateModule::create_item(1592 origin2.clone(),1593 1,1594 [1, 2, 3].to_vec(),1595 21596 ));1597 });1598}15991600// If Public Access mode is set to WhiteList, and Mint Permission is set to false, tokens cannot be created by non-privileged and white listed address.1601#[test]1602fn white_list_test_11() {1603 new_test_ext().execute_with(|| {1604 let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();1605 let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();1606 let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();1607 let mode: CollectionMode = CollectionMode::NFT(2000);16081609 let origin1 = Origin::signed(1);1610 let origin2 = Origin::signed(2);1611 assert_ok!(TemplateModule::create_collection(1612 origin1.clone(),1613 col_name1.clone(),1614 col_desc1.clone(),1615 token_prefix1.clone(),1616 mode1617 ));16181619 assert_ok!(TemplateModule::set_public_access_mode(origin1.clone(), 1, AccessMode::WhiteList));1620 assert_ok!(TemplateModule::set_mint_permission(origin1.clone(), 1, false));1621 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 2));16221623 assert_noop!(TemplateModule::create_item(1624 origin2.clone(),1625 1,1626 [1, 2, 3].to_vec(),1627 21628 ), "Collection is not in mint mode");1629 });1630}16311632// If Public Access mode is set to WhiteList, and Mint Permission is set to false, tokens cannot be created by non-privileged and non-white listed address.1633#[test]1634fn white_list_test_12() {1635 new_test_ext().execute_with(|| {1636 let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();1637 let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();1638 let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();1639 let mode: CollectionMode = CollectionMode::NFT(2000);16401641 let origin1 = Origin::signed(1);1642 let origin2 = Origin::signed(2);1643 assert_ok!(TemplateModule::create_collection(1644 origin1.clone(),1645 col_name1.clone(),1646 col_desc1.clone(),1647 token_prefix1.clone(),1648 mode1649 ));16501651 assert_ok!(TemplateModule::set_public_access_mode(origin1.clone(), 1, AccessMode::WhiteList));1652 assert_ok!(TemplateModule::set_mint_permission(origin1.clone(), 1, false));16531654 assert_noop!(TemplateModule::create_item(1655 origin2.clone(),1656 1,1657 [1, 2, 3].to_vec(),1658 21659 ), "Collection is not in mint mode");1660 });1661}16621663// If Public Access mode is set to WhiteList, and Mint Permission is set to true, tokens can be created by owner.1664#[test]1665fn white_list_test_13() {1666 new_test_ext().execute_with(|| {1667 let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();1668 let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();1669 let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();1670 let mode: CollectionMode = CollectionMode::NFT(2000);16711672 let origin1 = Origin::signed(1);1673 assert_ok!(TemplateModule::create_collection(1674 origin1.clone(),1675 col_name1.clone(),1676 col_desc1.clone(),1677 token_prefix1.clone(),1678 mode1679 ));16801681 assert_ok!(TemplateModule::set_public_access_mode(origin1.clone(), 1, AccessMode::WhiteList));1682 assert_ok!(TemplateModule::set_mint_permission(origin1.clone(), 1, true));16831684 assert_ok!(TemplateModule::create_item(1685 origin1.clone(),1686 1,1687 [1, 2, 3].to_vec(),1688 11689 ));1690 });1691}16921693// If Public Access mode is set to WhiteList, and Mint Permission is set to true, tokens can be created by admin.1694#[test]1695fn white_list_test_14() {1696 new_test_ext().execute_with(|| {1697 let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();1698 let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();1699 let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();1700 let mode: CollectionMode = CollectionMode::NFT(2000);17011702 let origin1 = Origin::signed(1);1703 let origin2 = Origin::signed(2);1704 assert_ok!(TemplateModule::create_collection(1705 origin1.clone(),1706 col_name1.clone(),1707 col_desc1.clone(),1708 token_prefix1.clone(),1709 mode1710 ));17111712 assert_ok!(TemplateModule::set_public_access_mode(origin1.clone(), 1, AccessMode::WhiteList));1713 assert_ok!(TemplateModule::set_mint_permission(origin1.clone(), 1, true));17141715 assert_ok!(TemplateModule::add_collection_admin(origin1.clone(), 1, 2));17161717 assert_ok!(TemplateModule::create_item(1718 origin2.clone(),1719 1,1720 [1, 2, 3].to_vec(),1721 21722 ));1723 });1724}17251726// If Public Access mode is set to WhiteList, and Mint Permission is set to true, tokens cannot be created by non-privileged and non-white listed address.1727#[test]1728fn white_list_test_15() {1729 new_test_ext().execute_with(|| {1730 let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();1731 let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();1732 let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();1733 let mode: CollectionMode = CollectionMode::NFT(2000);17341735 let origin1 = Origin::signed(1);1736 let origin2 = Origin::signed(2);1737 assert_ok!(TemplateModule::create_collection(1738 origin1.clone(),1739 col_name1.clone(),1740 col_desc1.clone(),1741 token_prefix1.clone(),1742 mode1743 ));17441745 assert_ok!(TemplateModule::set_public_access_mode(origin1.clone(), 1, AccessMode::WhiteList));1746 assert_ok!(TemplateModule::set_mint_permission(origin1.clone(), 1, true));17471748 assert_noop!(TemplateModule::create_item(1749 origin2.clone(),1750 1,1751 [1, 2, 3].to_vec(),1752 21753 ), "Address is not in white list");1754 });1755}17561757// If Public Access mode is set to WhiteList, and Mint Permission is set to true, tokens can be created by non-privileged and white listed address.1758#[test]1759fn white_list_test_16() {1760 new_test_ext().execute_with(|| {1761 let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();1762 let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();1763 let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();1764 let mode: CollectionMode = CollectionMode::NFT(2000);17651766 let origin1 = Origin::signed(1);1767 let origin2 = Origin::signed(2);1768 assert_ok!(TemplateModule::create_collection(1769 origin1.clone(),1770 col_name1.clone(),1771 col_desc1.clone(),1772 token_prefix1.clone(),1773 mode1774 ));17751776 assert_ok!(TemplateModule::set_public_access_mode(origin1.clone(), 1, AccessMode::WhiteList));1777 assert_ok!(TemplateModule::set_mint_permission(origin1.clone(), 1, true));1778 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 2));17791780 assert_ok!(TemplateModule::create_item(1781 origin2.clone(),1782 1,1783 [1, 2, 3].to_vec(),1784 21785 ));1786 });1787}17881789// #endregionrun-testnet.shdiffbeforeafterboth49 --rpc-port $RPCPORT \49 --rpc-port $RPCPORT \50 --name $NODE \50 --name $NODE \51 --ws-external \51 --ws-external \52 --ws-max-connections 10000 \52 --rpc-cors all \53 --rpc-cors all \53 -lruntime \54 -lruntime \54 $BOOTNODES;55 $BOOTNODES;runtime/src/lib.rsdiffbeforeafterboth535354pub use timestamp::Call as TimestampCall;54pub use timestamp::Call as TimestampCall;555556/// Importing a nft pallet56/// Re-export a nft pallet57/// TODO: Check this re-export. Is this safe and good style?58extern crate nft;57pub use nft;59pub use nft::*;586059/// An index to a block.61/// An index to a block.60pub type BlockNumber = u32;62pub type BlockNumber = u32;111 spec_name: create_runtime_str!("nft"),113 spec_name: create_runtime_str!("nft"),112 impl_name: create_runtime_str!("nft"),114 impl_name: create_runtime_str!("nft"),113 authoring_version: 1,115 authoring_version: 1,114 spec_version: 1,116 spec_version: 2,115 impl_version: 1,117 impl_version: 1,116 apis: RUNTIME_API_VERSIONS,118 apis: RUNTIME_API_VERSIONS,117 transaction_version: 1,119 transaction_version: 1,318 Balances: balances::{Module, Call, Storage, Config<T>, Event<T>},320 Balances: balances::{Module, Call, Storage, Config<T>, Event<T>},319 TransactionPayment: transaction_payment::{Module, Storage},321 TransactionPayment: transaction_payment::{Module, Storage},320 Sudo: sudo::{Module, Call, Config<T>, Storage, Event<T>},322 Sudo: sudo::{Module, Call, Config<T>, Storage, Event<T>},321 Nft: nft::{Module, Call, Storage, Event<T>},323 Nft: nft::{Module, Call, Config<T>, Storage, Event<T>},322 }324 }323);325);324326tests/src/blocks-production.test.tsdiffbeforeafterbothno changes