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.len()))?;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()136 .map(|i| i.len())137 .sum()138 ))?;139140 let collection = pallet_nft::Module::<C>::get_collection(input.collection_id)?;141142 pallet_nft::Module::<C>::create_multiple_items_internal(143 &C::CrossAccountId::from_sub(env.ext().address().clone()),144 &collection,145 &C::CrossAccountId::from_sub(input.owner),146 input.data,147 )?;148149 pallet_nft::Module::<C>::submit_logs(collection)?;150 Ok(RetVal::Converging(0))151 },152 3 => {153 154 let mut env = env.buf_in_buf_out();155 let input: NFTExtApprove<E> = env.read_as()?;156 env.charge_weight(NftWeightInfoOf::<C>::approve())?;157158 let collection = pallet_nft::Module::<C>::get_collection(input.collection_id)?;159160 pallet_nft::Module::<C>::approve_internal(161 &C::CrossAccountId::from_sub(env.ext().address().clone()),162 &C::CrossAccountId::from_sub(input.spender),163 &collection,164 input.item_id,165 input.amount,166 )?;167168 pallet_nft::Module::<C>::submit_logs(collection)?;169 Ok(RetVal::Converging(0))170 },171 4 => {172 173 let mut env = env.buf_in_buf_out();174 let input: NFTExtTransferFrom<E> = env.read_as()?;175 env.charge_weight(NftWeightInfoOf::<C>::transfer_from())?;176177 let collection = pallet_nft::Module::<C>::get_collection(input.collection_id)?;178179 pallet_nft::Module::<C>::transfer_from_internal(180 &C::CrossAccountId::from_sub(env.ext().address().clone()),181 &C::CrossAccountId::from_sub(input.owner),182 &C::CrossAccountId::from_sub(input.recipient),183 &collection,184 input.item_id,185 input.amount186 )?;187188 pallet_nft::Module::<C>::submit_logs(collection)?;189 Ok(RetVal::Converging(0))190 },191 5 => {192 193 let mut env = env.buf_in_buf_out();194 let input: NFTExtSetVariableMetaData = env.read_as()?;195 env.charge_weight(NftWeightInfoOf::<C>::set_variable_meta_data())?;196197 let collection = pallet_nft::Module::<C>::get_collection(input.collection_id)?;198199 pallet_nft::Module::<C>::set_variable_meta_data_internal(200 &C::CrossAccountId::from_sub(env.ext().address().clone()),201 &collection,202 input.item_id,203 input.data,204 )?;205206 pallet_nft::Module::<C>::submit_logs(collection)?;207 Ok(RetVal::Converging(0))208 },209 6 => {210 211 let mut env = env.buf_in_buf_out();212 let input: NFTExtToggleWhiteList<E> = env.read_as()?;213 env.charge_weight(NftWeightInfoOf::<C>::add_to_white_list())?;214215 let collection = pallet_nft::Module::<C>::get_collection(input.collection_id)?;216217 pallet_nft::Module::<C>::toggle_white_list_internal(218 &C::CrossAccountId::from_sub(env.ext().address().clone()),219 &collection,220 &C::CrossAccountId::from_sub(input.address),221 input.whitelisted,222 )?;223224 pallet_nft::Module::<C>::submit_logs(collection)?;225 Ok(RetVal::Converging(0))226 }227 _ => {228 Err(DispatchError::Other("unknown chain_extension func_id"))229 }230 }231 }232}