1#![cfg_attr(not(feature = "std"), no_std)]2extern crate alloc;3use alloc::vec::Vec;45use ink_lang as ink;6use ink_env::{Environment, DefaultEnvironment};78pub enum NftEnvironment {}910impl Environment for NftEnvironment {11 const MAX_EVENT_TOPICS: usize =12 <DefaultEnvironment as Environment>::MAX_EVENT_TOPICS;1314 type AccountId = <DefaultEnvironment as Environment>::AccountId;15 type Balance = <DefaultEnvironment as Environment>::Balance;16 type Hash = <DefaultEnvironment as Environment>::Hash;17 type BlockNumber = <DefaultEnvironment as Environment>::BlockNumber;18 type Timestamp = <DefaultEnvironment as Environment>::Timestamp;1920 type ChainExtension = NftChainExtension;21}222324#[derive(25 Debug, Copy, Clone, PartialEq, Eq, scale::Encode, scale::Decode,26)]27pub enum NftErrorCode {28 SomeError,29}3031impl ink_env::chain_extension::FromStatusCode for NftErrorCode {32 fn from_status_code(status_code: u32) -> Result<(), Self> {33 match status_code {34 0 => Ok(()),35 1 => Err(Self::SomeError),36 _ => panic!("encountered unknown status code"),37 }38 }39}4041#[derive(scale::Encode, scale::Decode, scale_info::TypeInfo)]42pub enum CreateItemData {43 Nft {44 const_data: Vec<u8>,45 variable_data: Vec<u8>,46 },47 Fungible {48 value: u128,49 },50 ReFungible {51 const_data: Vec<u8>,52 variable_data: Vec<u8>,53 pieces: u128,54 },55}5657type DefaultAccountId = <DefaultEnvironment as Environment>::AccountId;5859#[ink::chain_extension]60pub trait NftChainExtension {61 type ErrorCode = NftErrorCode;6263 64 65 #[ink(extension = 0, returns_result = false)]66 fn transfer(recipient: DefaultAccountId, collection_id: u32, token_id: u32, amount: u128);67 #[ink(extension = 1, returns_result = false)]68 fn create_item(owner: DefaultAccountId, collection_id: u32, data: CreateItemData);69 #[ink(extension = 2, returns_result = false)]70 fn create_multiple_items(owner: DefaultAccountId, collection_id: u32, data: Vec<CreateItemData>);71 #[ink(extension = 3, returns_result = false)]72 fn approve(spender: DefaultAccountId, collection_id: u32, item_id: u32, amount: u128);73 #[ink(extension = 4, returns_result = false)]74 fn transfer_from(owner: DefaultAccountId, recipient: DefaultAccountId, collection_id: u32, item_id: u32, amount: u128);75 #[ink(extension = 5, returns_result = false)]76 fn set_variable_meta_data(collection_id: u32, item_id: u32, data: Vec<u8>);77 #[ink(extension = 6, returns_result = false)]78 fn toggle_white_list(collection_id: u32, address: DefaultAccountId, whitelisted: bool);79}8081#[ink::contract(env = crate::NftEnvironment, dynamic_storage_allocator = true)]82mod nft_transfer {83 use alloc::vec::Vec;84 85 use crate::CreateItemData;8687 #[ink(storage)]88 pub struct NftTransfer {89 }9091 impl NftTransfer {92 93 94 95 #[ink(constructor)]96 pub fn default() -> Self {97 Self {}98 }99100 101 #[ink(message)]102 pub fn transfer(&mut self, recipient: AccountId, collection_id: u32, token_id: u32, amount: u128) {103 let _ = self.env()104 .extension()105 .transfer(recipient, collection_id, token_id, amount);106 }107 #[ink(message)]108 pub fn create_item(&mut self, recipient: AccountId, collection_id: u32, data: CreateItemData) {109 let _ = self.env()110 .extension()111 .create_item(recipient, collection_id, data);112 }113 #[ink(message)]114 pub fn create_multiple_items(&mut self, owner: AccountId, collection_id: u32, data: Vec<CreateItemData>) {115 let _ = self.env()116 .extension()117 .create_multiple_items(owner, collection_id, data);118 }119 #[ink(message)]120 pub fn approve(&mut self, spender: AccountId, collection_id: u32, item_id: u32, amount: u128) {121 let _ = self.env()122 .extension()123 .approve(spender, collection_id, item_id, amount);124 }125 #[ink(message)]126 pub fn transfer_from(&mut self, owner: AccountId, recipient: AccountId, collection_id: u32, item_id: u32, amount: u128) {127 let _ = self.env()128 .extension()129 .transfer_from(owner, recipient, collection_id, item_id, amount);130 }131 #[ink(message)]132 pub fn set_variable_meta_data(&mut self, collection_id: u32, item_id: u32, data: Vec<u8>) {133 let _ = self.env()134 .extension()135 .set_variable_meta_data(collection_id, item_id, data);136 }137 #[ink(message)]138 pub fn toggle_white_list(&mut self, collection_id: u32, address: AccountId, whitelisted: bool) {139 let _ = self.env()140 .extension()141 .toggle_white_list(collection_id, address, whitelisted);142 }143144 }145146}