Skip to content

Commit

Permalink
test: create an NFT collection (#85)
Browse files Browse the repository at this point in the history
  • Loading branch information
brunopgalvao authored May 1, 2024
1 parent 6cc1885 commit bc41540
Show file tree
Hide file tree
Showing 3 changed files with 138 additions and 17 deletions.
62 changes: 47 additions & 15 deletions pop-api/examples/nfts/lib.rs
Original file line number Diff line number Diff line change
@@ -1,46 +1,70 @@
#![cfg_attr(not(feature = "std"), no_std, no_main)]

use pop_api::nfts;
use pop_api::nfts::*;

#[derive(Debug, Copy, Clone, PartialEq, Eq, scale::Encode, scale::Decode)]
#[cfg_attr(feature = "std", derive(scale_info::TypeInfo))]
pub enum ContractError {
InvalidCollection,
ItemAlreadyExists,
NftsError(nfts::Error),
NftsError(Error),
NotOwner,
}

impl From<nfts::Error> for ContractError {
fn from(value: nfts::Error) -> Self {
impl From<Error> for ContractError {
fn from(value: Error) -> Self {
ContractError::NftsError(value)
}
}

#[ink::contract(env = pop_api::Environment)]
mod pop_api_extension_demo {
use super::ContractError;
mod pop_api_nfts {
use super::*;

#[ink(storage)]
#[derive(Default)]
pub struct PopApiExtensionDemo;
pub struct Nfts;

impl PopApiExtensionDemo {
impl Nfts {
#[ink(constructor, payable)]
pub fn new() -> Self {
ink::env::debug_println!("Contract::new");
ink::env::debug_println!("Nfts::new");
Default::default()
}

#[ink(message)]
pub fn mint_through_runtime(
pub fn create_nft_collection( &self ) -> Result<(), ContractError>{
ink::env::debug_println!("Nfts::create_nft_collection: collection creation started.");
let admin = Self::env().caller();
let item_settings = ItemSettings(BitFlags::from(ItemSetting::Transferable));

let mint_settings = MintSettings {
mint_type: MintType::Issuer,
price: Some(0),
start_block: Some(0),
end_block: Some(0),
default_item_settings: item_settings,
};

let config = CollectionConfig {
settings: CollectionSettings(BitFlags::from(CollectionSetting::TransferableItems)),
max_supply: None,
mint_settings,
};
pop_api::nfts::create(admin, config)?;
ink::env::debug_println!("Nfts::create_nft_collection: collection created successfully.");
Ok(())
}

#[ink(message)]
pub fn mint_nft(
&mut self,
collection_id: u32,
item_id: u32,
receiver: AccountId,
) -> Result<(), ContractError> {
ink::env::debug_println!(
"Contract::mint_through_runtime: collection_id: {:?} item_id {:?} receiver: {:?}",
"Nfts::mint_through_runtime: collection_id: {:?} item_id {:?} receiver: {:?}",
collection_id,
item_id,
receiver
Expand All @@ -53,21 +77,29 @@ mod pop_api_extension_demo {

// mint api
pop_api::nfts::mint(collection_id, item_id, receiver)?;
ink::env::debug_println!("Contract::mint_through_runtime: item minted successfully");
ink::env::debug_println!("Nfts::mint_through_runtime: item minted successfully");

// check owner
match pop_api::nfts::owner(collection_id, item_id)? {
Some(owner) if owner == receiver => {
ink::env::debug_println!(
"Contract::mint_through_runtime success: minted item belongs to receiver"
"Nfts::mint_through_runtime success: minted item belongs to receiver"
);
},
_ => {
return Err(ContractError::NotOwner);
},
}

ink::env::debug_println!("Contract::mint_through_runtime end");
ink::env::debug_println!("Nfts::mint_through_runtime end");
Ok(())
}

#[ink(message)]
pub fn read_collection(&self, collection_id: u32) -> Result<(), ContractError> {
ink::env::debug_println!("Nfts::read_collection: collection_id: {:?}", collection_id);
let collection = pop_api::nfts::collection(collection_id)?;
ink::env::debug_println!("Nfts::read_collection: collection: {:?}", collection);
Ok(())
}
}
Expand All @@ -78,7 +110,7 @@ mod pop_api_extension_demo {

#[ink::test]
fn default_works() {
PopApiExtensionDemo::new();
Nfts::new();
}
}
}
4 changes: 2 additions & 2 deletions pop-api/src/v0/nfts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -681,7 +681,7 @@ mod types {
primitives::{CollectionId, ItemId},
Balance, BlockNumber,
};
use enumflags2::{bitflags, BitFlags};
pub use enumflags2::{bitflags, BitFlags};
use scale::{Decode, EncodeLike, MaxEncodedLen};
use scale_info::{build::Fields, meta_type, prelude::vec, Path, Type, TypeInfo, TypeParameter};

Expand Down Expand Up @@ -807,7 +807,7 @@ mod types {
pub default_item_settings: ItemSettings,
}

/// Mint type. Can the NFT be create by anyone, or only the creator of the collection,
/// Mint type. Can the NFT be created by anyone, or only the creator of the collection,
/// or only by wallets that already hold an NFT from a certain collection?
/// The ownership of a privately minted NFT is still publicly visible.
#[derive(Encode)]
Expand Down
89 changes: 89 additions & 0 deletions runtime/devnet/src/extensions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -474,6 +474,95 @@ mod tests {
});
}

// Create a test for tesing create_nft_collection
#[test]
#[ignore]
fn dispatch_nfts_create_nft_collection() {
new_test_ext().execute_with(|| {
let _ = env_logger::try_init();

let (wasm_binary, _) = load_wasm_module::<Runtime>(
"../../pop-api/examples/nfts/target/ink/pop_api_nft_example.wasm",
)
.unwrap();

let init_value = 100 * UNIT;

let result = Contracts::bare_instantiate(
ALICE,
init_value,
GAS_LIMIT,
None,
Code::Upload(wasm_binary),
function_selector("new"),
vec![],
DEBUG_OUTPUT,
pallet_contracts::CollectEvents::Skip,
)
.result
.unwrap();

assert!(!result.result.did_revert(), "deploying contract reverted {:?}", result);

let addr = result.account_id;

let function = function_selector("create_nft_collection");

let params = [function].concat();

let result = Contracts::bare_call(
ALICE,
addr.clone(),
0,
Weight::from_parts(100_000_000_000, 3 * 1024 * 1024),
None,
params,
DEBUG_OUTPUT,
pallet_contracts::CollectEvents::Skip,
pallet_contracts::Determinism::Enforced,
);

if DEBUG_OUTPUT == pallet_contracts::DebugInfo::UnsafeDebug {
log::debug!(
"Contract debug buffer - {:?}",
String::from_utf8(result.debug_message.clone())
);
log::debug!("result: {:?}", result);
}

// check that the nft collection was created
assert_eq!(Nfts::collection_owner(0), Some(addr.clone().into()));

// test reading the collection
let function = function_selector("read_collection");

let params = [function, 0.encode()].concat();

let result = Contracts::bare_call(
ALICE,
addr.clone(),
0,
Weight::from_parts(100_000_000_000, 3 * 1024 * 1024),
None,
params,
DEBUG_OUTPUT,
pallet_contracts::CollectEvents::Skip,
pallet_contracts::Determinism::Enforced,
);

if DEBUG_OUTPUT == pallet_contracts::DebugInfo::UnsafeDebug {
log::debug!(
"Contract debug buffer - {:?}",
String::from_utf8(result.debug_message.clone())
);
log::debug!("result: {:?}", result);
}

// assert that the collection was read successfully
assert_eq!(result.result.clone().unwrap().data, vec![1, 1]);
});
}

#[test]
#[ignore]
fn dispatch_nfts_mint_from_contract_works() {
Expand Down

0 comments on commit bc41540

Please sign in to comment.