1234567891011121314151617#![cfg_attr(not(feature = "std"), no_std)]18extern crate alloc;19use alloc::vec::Vec;2021use ink_lang as ink;22use ink_env::{Environment, DefaultEnvironment};2324pub enum NftEnvironment {}2526impl Environment for NftEnvironment {27 const MAX_EVENT_TOPICS: usize =28 <DefaultEnvironment as Environment>::MAX_EVENT_TOPICS;2930 type AccountId = <DefaultEnvironment as Environment>::AccountId;31 type Balance = <DefaultEnvironment as Environment>::Balance;32 type Hash = <DefaultEnvironment as Environment>::Hash;33 type BlockNumber = <DefaultEnvironment as Environment>::BlockNumber;34 type Timestamp = <DefaultEnvironment as Environment>::Timestamp;3536 type ChainExtension = NftChainExtension;37}383940#[derive(41 Debug, Copy, Clone, PartialEq, Eq, scale::Encode, scale::Decode,42)]43pub enum NftErrorCode {44 SomeError,45}4647impl ink_env::chain_extension::FromStatusCode for NftErrorCode {48 fn from_status_code(status_code: u32) -> Result<(), Self> {49 match status_code {50 0 => Ok(()),51 1 => Err(Self::SomeError),52 _ => panic!("encountered unknown status code"),53 }54 }55}5657#[derive(scale::Encode, scale::Decode, scale_info::TypeInfo)]58pub enum CreateItemData {59 Nft {60 const_data: Vec<u8>,61 variable_data: Vec<u8>,62 },63 Fungible {64 value: u128,65 },66 ReFungible {67 const_data: Vec<u8>,68 variable_data: Vec<u8>,69 pieces: u128,70 },71}7273type DefaultAccountId = <DefaultEnvironment as Environment>::AccountId;7475#[ink::chain_extension]76pub trait NftChainExtension {77 type ErrorCode = NftErrorCode;7879 80 81 #[ink(extension = 0, returns_result = false)]82 fn transfer(recipient: DefaultAccountId, collection_id: u32, token_id: u32, amount: u128);83 #[ink(extension = 1, returns_result = false)]84 fn create_item(owner: DefaultAccountId, collection_id: u32, data: CreateItemData);85 #[ink(extension = 2, returns_result = false)]86 fn create_multiple_items(owner: DefaultAccountId, collection_id: u32, data: Vec<CreateItemData>);87 #[ink(extension = 3, returns_result = false)]88 fn approve(spender: DefaultAccountId, collection_id: u32, item_id: u32, amount: u128);89 #[ink(extension = 4, returns_result = false)]90 fn transfer_from(owner: DefaultAccountId, recipient: DefaultAccountId, collection_id: u32, item_id: u32, amount: u128);91 #[ink(extension = 5, returns_result = false)]92 fn set_variable_meta_data(collection_id: u32, item_id: u32, data: Vec<u8>);93 #[ink(extension = 6, returns_result = false)]94 fn toggle_allow_list(collection_id: u32, address: DefaultAccountId, allowlisted: bool);95}9697#[ink::contract(env = crate::NftEnvironment, dynamic_storage_allocator = true)]98mod nft_transfer {99 use alloc::vec::Vec;100 101 use crate::CreateItemData;102103 #[ink(storage)]104 pub struct NftTransfer {105 }106107 impl NftTransfer {108 109 110 111 #[ink(constructor)]112 pub fn default() -> Self {113 Self {}114 }115116 117 #[ink(message)]118 pub fn transfer(&mut self, recipient: AccountId, collection_id: u32, token_id: u32, amount: u128) {119 let _ = self.env()120 .extension()121 .transfer(recipient, collection_id, token_id, amount);122 }123 #[ink(message)]124 pub fn create_item(&mut self, recipient: AccountId, collection_id: u32, data: CreateItemData) {125 let _ = self.env()126 .extension()127 .create_item(recipient, collection_id, data);128 }129 #[ink(message)]130 pub fn create_multiple_items(&mut self, owner: AccountId, collection_id: u32, data: Vec<CreateItemData>) {131 let _ = self.env()132 .extension()133 .create_multiple_items(owner, collection_id, data);134 }135 #[ink(message)]136 pub fn approve(&mut self, spender: AccountId, collection_id: u32, item_id: u32, amount: u128) {137 let _ = self.env()138 .extension()139 .approve(spender, collection_id, item_id, amount);140 }141 #[ink(message)]142 pub fn transfer_from(&mut self, owner: AccountId, recipient: AccountId, collection_id: u32, item_id: u32, amount: u128) {143 let _ = self.env()144 .extension()145 .transfer_from(owner, recipient, collection_id, item_id, amount);146 }147 #[ink(message)]148 pub fn set_variable_meta_data(&mut self, collection_id: u32, item_id: u32, data: Vec<u8>) {149 let _ = self.env()150 .extension()151 .set_variable_meta_data(collection_id, item_id, data);152 }153 #[ink(message)]154 pub fn toggle_allow_list(&mut self, collection_id: u32, address: AccountId, allowlisted: bool) {155 let _ = self.env()156 .extension()157 .toggle_allow_list(collection_id, address, allowlisted);158 }159160 }161162}