12345678use codec::{Decode, Encode};910pub use pallet_contracts::chain_extension::RetVal;11use pallet_contracts::chain_extension::{12 ChainExtension, Environment, Ext, InitState, SysConfig, UncheckedFrom,13};1415pub use frame_support::debug;16use frame_support::dispatch::DispatchError;1718extern crate pallet_nft;19pub use pallet_nft::*;20use pallet_nft::CrossAccountId;21use crate::Vec;222324#[derive(Debug, PartialEq, Encode, Decode)]25pub struct NFTExtCreateItem<E: Ext> {26 pub owner: <E::T as SysConfig>::AccountId,27 pub collection_id: u32,28 pub data: CreateItemData,29}303132#[derive(Debug, PartialEq, Encode, Decode)]33pub struct NFTExtTransfer<E: Ext> {34 pub recipient: <E::T as SysConfig>::AccountId,35 pub collection_id: u32,36 pub token_id: u32,37 pub amount: u128,38}3940#[derive(Debug, PartialEq, Encode, Decode)]41pub struct NFTExtCreateMultipleItems<E: Ext> {42 pub owner: <E::T as SysConfig>::AccountId,43 pub collection_id: u32,44 pub data: Vec<CreateItemData>,45}4647#[derive(Debug, PartialEq, Encode, Decode)]48pub struct NFTExtApprove<E: Ext> {49 pub spender: <E::T as SysConfig>::AccountId,50 pub collection_id: u32,51 pub item_id: u32,52 pub amount: u128,53}5455#[derive(Debug, PartialEq, Encode, Decode)]56pub struct NFTExtTransferFrom<E: Ext> {57 pub owner: <E::T as SysConfig>::AccountId,58 pub recipient: <E::T as SysConfig>::AccountId,59 pub collection_id: u32,60 pub item_id: u32,61 pub amount: u128,62}6364#[derive(Debug, PartialEq, Encode, Decode)]65pub struct NFTExtSetVariableMetaData {66 pub collection_id: u32,67 pub item_id: u32,68 pub data: Vec<u8>, 69}7071#[derive(Debug, PartialEq, Encode, Decode)]72pub struct NFTExtToggleWhiteList<E: Ext> {73 pub collection_id: u32,74 pub address: <E::T as SysConfig>::AccountId,75 pub whitelisted: bool,76}777879pub struct NFTExtension;8081impl<C: Config> ChainExtension<C> for NFTExtension {82 fn call<E: Ext>(func_id: u32, env: Environment<E, InitState>) -> Result<RetVal, DispatchError>83 where84 E: Ext<T = C>,85 <E::T as SysConfig>::AccountId: UncheckedFrom<<E::T as SysConfig>::Hash> + AsRef<[u8]>,86 {87 88 match func_id {89 0 => {90 let mut env = env.buf_in_buf_out();91 let input: NFTExtTransfer<E> = env.read_as()?;9293 let collection = pallet_nft::Module::<C>::get_collection(input.collection_id)?;9495 match pallet_nft::Module::<C>::transfer_internal(96 &C::CrossAccountId::from_sub(env.ext().caller().clone()),97 &C::CrossAccountId::from_sub(input.recipient),98 &collection,99 input.token_id,100 input.amount,101 ) {102 Ok(_) => Ok(RetVal::Converging(func_id)),103 _ => Err(DispatchError::Other("Transfer error"))104 }105 },106 1 => {107 108 let mut env = env.buf_in_buf_out();109 let input: NFTExtCreateItem<E> = env.read_as()?;110111 let collection = pallet_nft::Module::<C>::get_collection(input.collection_id)?;112113 match pallet_nft::Module::<C>::create_item_internal(114 &C::CrossAccountId::from_sub(env.ext().address().clone()),115 &collection,116 &C::CrossAccountId::from_sub(input.owner),117 input.data,118 ) {119 Ok(_) => Ok(RetVal::Converging(func_id)),120 _ => Err(DispatchError::Other("CreateItem error"))121 }122 },123 2 => {124 125 let mut env = env.buf_in_buf_out();126 let input: NFTExtCreateMultipleItems<E> = env.read_as()?;127128 let collection = pallet_nft::Module::<C>::get_collection(input.collection_id)?;129130 match pallet_nft::Module::<C>::create_multiple_items_internal(131 &C::CrossAccountId::from_sub(env.ext().address().clone()),132 &collection,133 &C::CrossAccountId::from_sub(input.owner),134 input.data,135 ) {136 Ok(_) => Ok(RetVal::Converging(func_id)),137 _ => Err(DispatchError::Other("CreateMultipleItems error"))138 }139 },140 3 => {141 142 let mut env = env.buf_in_buf_out();143 let input: NFTExtApprove<E> = env.read_as()?;144145 let collection = pallet_nft::Module::<C>::get_collection(input.collection_id)?;146147 pallet_nft::Module::<C>::approve_internal(148 &C::CrossAccountId::from_sub(env.ext().address().clone()),149 &C::CrossAccountId::from_sub(input.spender),150 &collection,151 input.item_id,152 input.amount,153 )?;154 Ok(RetVal::Converging(func_id))155 },156 4 => {157 158 let mut env = env.buf_in_buf_out();159 let input: NFTExtTransferFrom<E> = env.read_as()?;160161 let collection = pallet_nft::Module::<C>::get_collection(input.collection_id)?;162163 pallet_nft::Module::<C>::transfer_from_internal(164 &C::CrossAccountId::from_sub(env.ext().address().clone()),165 &C::CrossAccountId::from_sub(input.owner),166 &C::CrossAccountId::from_sub(input.recipient),167 &collection,168 input.item_id,169 input.amount170 )?;171 Ok(RetVal::Converging(func_id))172 },173 5 => {174 175 let mut env = env.buf_in_buf_out();176 let input: NFTExtSetVariableMetaData = env.read_as()?;177178 let collection = pallet_nft::Module::<C>::get_collection(input.collection_id)?;179180 pallet_nft::Module::<C>::set_variable_meta_data_internal(181 &C::CrossAccountId::from_sub(env.ext().address().clone()),182 &collection,183 input.item_id,184 input.data,185 )?;186 Ok(RetVal::Converging(func_id))187 },188 6 => {189 190 let mut env = env.buf_in_buf_out();191 let input: NFTExtToggleWhiteList<E> = env.read_as()?;192193 let collection = pallet_nft::Module::<C>::get_collection(input.collection_id)?;194195 pallet_nft::Module::<C>::toggle_white_list_internal(196 &C::CrossAccountId::from_sub(env.ext().address().clone()),197 &collection,198 &C::CrossAccountId::from_sub(input.address),199 input.whitelisted,200 )?;201 Ok(RetVal::Converging(func_id))202 }203 _ => {204 panic!("Passed unknown func_id to test chain extension: {}", func_id);205 }206 }207 }208}