Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

test: create an NFT collection #85

Merged
merged 1 commit into from
May 1, 2024
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
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
Loading