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 nft_data_structs::*;2223use crate::Vec;242526#[derive(Debug, PartialEq, Encode, Decode)]27pub struct NFTExtCreateItem<E: Ext> {28 pub owner: <E::T as SysConfig>::AccountId,29 pub collection_id: u32,30 pub data: CreateItemData,31}323334#[derive(Debug, PartialEq, Encode, Decode)]35pub struct NFTExtTransfer<E: Ext> {36 pub recipient: <E::T as SysConfig>::AccountId,37 pub collection_id: u32,38 pub token_id: u32,39 pub amount: u128,40}4142#[derive(Debug, PartialEq, Encode, Decode)]43pub struct NFTExtCreateMultipleItems<E: Ext> {44 pub owner: <E::T as SysConfig>::AccountId,45 pub collection_id: u32,46 pub data: Vec<CreateItemData>,47}4849#[derive(Debug, PartialEq, Encode, Decode)]50pub struct NFTExtApprove<E: Ext> {51 pub spender: <E::T as SysConfig>::AccountId,52 pub collection_id: u32,53 pub item_id: u32,54 pub amount: u128,55}5657#[derive(Debug, PartialEq, Encode, Decode)]58pub struct NFTExtTransferFrom<E: Ext> {59 pub owner: <E::T as SysConfig>::AccountId,60 pub recipient: <E::T as SysConfig>::AccountId,61 pub collection_id: u32,62 pub item_id: u32,63 pub amount: u128,64}6566#[derive(Debug, PartialEq, Encode, Decode)]67pub struct NFTExtSetVariableMetaData {68 pub collection_id: u32,69 pub item_id: u32,70 pub data: Vec<u8>,71}7273#[derive(Debug, PartialEq, Encode, Decode)]74pub struct NFTExtToggleWhiteList<E: Ext> {75 pub collection_id: u32,76 pub address: <E::T as SysConfig>::AccountId,77 pub whitelisted: bool,78}798081pub struct NFTExtension;8283pub type NftWeightInfoOf<C> = <C as pallet_nft::Config>::WeightInfo;8485impl<C: Config + pallet_contracts::Config> ChainExtension<C> for NFTExtension {86 fn call<E: Ext>(func_id: u32, env: Environment<E, InitState>) -> Result<RetVal, DispatchError>87 where88 E: Ext<T = C>,89 C: pallet_nft::Config,90 <E::T as SysConfig>::AccountId: UncheckedFrom<<E::T as SysConfig>::Hash> + AsRef<[u8]>,91 {92 93 match func_id {94 0 => {95 let mut env = env.buf_in_buf_out();96 let input: NFTExtTransfer<E> = env.read_as()?;97 env.charge_weight(NftWeightInfoOf::<C>::transfer())?;9899 let collection = pallet_nft::Module::<C>::get_collection(input.collection_id)?;100101 pallet_nft::Module::<C>::transfer_internal(102 &C::CrossAccountId::from_sub(env.ext().address().clone()),103 &C::CrossAccountId::from_sub(input.recipient),104 &collection,105 input.token_id,106 input.amount,107 )?;108109 pallet_nft::Module::<C>::submit_logs(collection)?;110 Ok(RetVal::Converging(0))111 }112 1 => {113 114 let mut env = env.buf_in_buf_out();115 let input: NFTExtCreateItem<E> = env.read_as()?;116 env.charge_weight(NftWeightInfoOf::<C>::create_item(input.data.data_size()))?;117118 let collection = pallet_nft::Module::<C>::get_collection(input.collection_id)?;119120 pallet_nft::Module::<C>::create_item_internal(121 &C::CrossAccountId::from_sub(env.ext().address().clone()),122 &collection,123 &C::CrossAccountId::from_sub(input.owner),124 input.data,125 )?;126127 pallet_nft::Module::<C>::submit_logs(collection)?;128 Ok(RetVal::Converging(0))129 }130 2 => {131 132 let mut env = env.buf_in_buf_out();133 let input: NFTExtCreateMultipleItems<E> = env.read_as()?;134 env.charge_weight(NftWeightInfoOf::<C>::create_item(135 input.data.iter().map(|i| i.data_size()).sum(),136 ))?;137138 let collection = pallet_nft::Module::<C>::get_collection(input.collection_id)?;139140 pallet_nft::Module::<C>::create_multiple_items_internal(141 &C::CrossAccountId::from_sub(env.ext().address().clone()),142 &collection,143 &C::CrossAccountId::from_sub(input.owner),144 input.data,145 )?;146147 pallet_nft::Module::<C>::submit_logs(collection)?;148 Ok(RetVal::Converging(0))149 }150 3 => {151 152 let mut env = env.buf_in_buf_out();153 let input: NFTExtApprove<E> = env.read_as()?;154 env.charge_weight(NftWeightInfoOf::<C>::approve())?;155156 let collection = pallet_nft::Module::<C>::get_collection(input.collection_id)?;157158 pallet_nft::Module::<C>::approve_internal(159 &C::CrossAccountId::from_sub(env.ext().address().clone()),160 &C::CrossAccountId::from_sub(input.spender),161 &collection,162 input.item_id,163 input.amount,164 )?;165166 pallet_nft::Module::<C>::submit_logs(collection)?;167 Ok(RetVal::Converging(0))168 }169 4 => {170 171 let mut env = env.buf_in_buf_out();172 let input: NFTExtTransferFrom<E> = env.read_as()?;173 env.charge_weight(NftWeightInfoOf::<C>::transfer_from())?;174175 let collection = pallet_nft::Module::<C>::get_collection(input.collection_id)?;176177 pallet_nft::Module::<C>::transfer_from_internal(178 &C::CrossAccountId::from_sub(env.ext().address().clone()),179 &C::CrossAccountId::from_sub(input.owner),180 &C::CrossAccountId::from_sub(input.recipient),181 &collection,182 input.item_id,183 input.amount,184 )?;185186 pallet_nft::Module::<C>::submit_logs(collection)?;187 Ok(RetVal::Converging(0))188 }189 5 => {190 191 let mut env = env.buf_in_buf_out();192 let input: NFTExtSetVariableMetaData = env.read_as()?;193 env.charge_weight(NftWeightInfoOf::<C>::set_variable_meta_data())?;194195 let collection = pallet_nft::Module::<C>::get_collection(input.collection_id)?;196197 pallet_nft::Module::<C>::set_variable_meta_data_internal(198 &C::CrossAccountId::from_sub(env.ext().address().clone()),199 &collection,200 input.item_id,201 input.data,202 )?;203204 pallet_nft::Module::<C>::submit_logs(collection)?;205 Ok(RetVal::Converging(0))206 }207 6 => {208 209 let mut env = env.buf_in_buf_out();210 let input: NFTExtToggleWhiteList<E> = env.read_as()?;211 env.charge_weight(NftWeightInfoOf::<C>::add_to_white_list())?;212213 let collection = pallet_nft::Module::<C>::get_collection(input.collection_id)?;214215 pallet_nft::Module::<C>::toggle_white_list_internal(216 &C::CrossAccountId::from_sub(env.ext().address().clone()),217 &collection,218 &C::CrossAccountId::from_sub(input.address),219 input.whitelisted,220 )?;221222 pallet_nft::Module::<C>::submit_logs(collection)?;223 Ok(RetVal::Converging(0))224 }225 _ => Err(DispatchError::Other("unknown chain_extension func_id")),226 }227 }228}