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 nft_data_structs::*;2122use crate::Vec;232425#[derive(Debug, PartialEq, Encode, Decode)]26pub struct NFTExtCreateItem<E: Ext> {27 pub owner: <E::T as SysConfig>::AccountId,28 pub collection_id: u32,29 pub data: CreateItemData,30}313233#[derive(Debug, PartialEq, Encode, Decode)]34pub struct NFTExtTransfer<E: Ext> {35 pub recipient: <E::T as SysConfig>::AccountId,36 pub collection_id: u32,37 pub token_id: u32,38 pub amount: u128,39}4041#[derive(Debug, PartialEq, Encode, Decode)]42pub struct NFTExtCreateMultipleItems<E: Ext> {43 pub owner: <E::T as SysConfig>::AccountId,44 pub collection_id: u32,45 pub data: Vec<CreateItemData>,46}4748#[derive(Debug, PartialEq, Encode, Decode)]49pub struct NFTExtApprove<E: Ext> {50 pub spender: <E::T as SysConfig>::AccountId,51 pub collection_id: u32,52 pub item_id: u32,53 pub amount: u128,54}5556#[derive(Debug, PartialEq, Encode, Decode)]57pub struct NFTExtTransferFrom<E: Ext> {58 pub owner: <E::T as SysConfig>::AccountId,59 pub recipient: <E::T as SysConfig>::AccountId,60 pub collection_id: u32,61 pub item_id: u32,62 pub amount: u128,63}6465#[derive(Debug, PartialEq, Encode, Decode)]66pub struct NFTExtSetVariableMetaData {67 pub collection_id: u32,68 pub item_id: u32,69 pub data: Vec<u8>, 70}7172#[derive(Debug, PartialEq, Encode, Decode)]73pub struct NFTExtToggleWhiteList<E: Ext> {74 pub collection_id: u32,75 pub address: <E::T as SysConfig>::AccountId,76 pub whitelisted: bool,77}787980pub struct NFTExtension;8182pub type NftWeightInfoOf<C> = <C as pallet_nft::Config>::WeightInfo;8384impl<C: Config + pallet_contracts::Config> ChainExtension<C> for NFTExtension {85 fn call<E: Ext>(func_id: u32, env: Environment<E, InitState>) -> Result<RetVal, DispatchError>86 where87 E: Ext<T = C>,88 C: pallet_nft::Config,89 <E::T as SysConfig>::AccountId: UncheckedFrom<<E::T as SysConfig>::Hash> + AsRef<[u8]>,90 {91 92 match func_id {93 0 => {94 let mut env = env.buf_in_buf_out();95 let input: NFTExtTransfer<E> = env.read_as()?;96 env.charge_weight(NftWeightInfoOf::<C>::transfer())?;9798 let collection = pallet_nft::Module::<C>::get_collection(input.collection_id)?;99100 pallet_nft::Module::<C>::transfer_internal(101 env.ext().address().clone(),102 input.recipient,103 &collection,104 input.token_id,105 input.amount,106 )?;107 108 Ok(RetVal::Converging(0))109 },110 1 => {111 112 let mut env = env.buf_in_buf_out();113 let input: NFTExtCreateItem<E> = env.read_as()?;114 env.charge_weight(NftWeightInfoOf::<C>::create_item(input.data.len()))?;115116 pallet_nft::Module::<C>::create_item_internal(117 env.ext().address().clone(),118 input.collection_id,119 input.owner,120 input.data,121 )?;122 123 Ok(RetVal::Converging(0))124 },125 2 => {126 127 let mut env = env.buf_in_buf_out();128 let input: NFTExtCreateMultipleItems<E> = env.read_as()?;129 env.charge_weight(NftWeightInfoOf::<C>::create_item(130 input.data.iter()131 .map(|i| i.len())132 .sum()133 ))?;134135 let collection = pallet_nft::Module::<C>::get_collection(input.collection_id)?;136137 pallet_nft::Module::<C>::create_multiple_items_internal(138 env.ext().address().clone(),139 &collection,140 input.owner,141 input.data,142 )?;143 144 Ok(RetVal::Converging(0))145 },146 3 => {147 148 let mut env = env.buf_in_buf_out();149 let input: NFTExtApprove<E> = env.read_as()?;150 env.charge_weight(NftWeightInfoOf::<C>::approve())?;151152 let collection = pallet_nft::Module::<C>::get_collection(input.collection_id)?;153154 pallet_nft::Module::<C>::approve_internal(155 env.ext().address().clone(),156 input.spender,157 &collection,158 input.item_id,159 input.amount,160 )?;161162 Ok(RetVal::Converging(0))163 },164 4 => {165 166 let mut env = env.buf_in_buf_out();167 let input: NFTExtTransferFrom<E> = env.read_as()?;168 env.charge_weight(NftWeightInfoOf::<C>::transfer_from())?;169170 let collection = pallet_nft::Module::<C>::get_collection(input.collection_id)?;171172 pallet_nft::Module::<C>::transfer_from_internal(173 env.ext().address().clone(),174 input.owner,175 input.recipient,176 &collection,177 input.item_id,178 input.amount179 )?;180181 Ok(RetVal::Converging(0))182 },183 5 => {184 185 let mut env = env.buf_in_buf_out();186 let input: NFTExtSetVariableMetaData = env.read_as()?;187 env.charge_weight(NftWeightInfoOf::<C>::set_variable_meta_data())?;188189 let collection = pallet_nft::Module::<C>::get_collection(input.collection_id)?;190191 pallet_nft::Module::<C>::set_variable_meta_data_internal(192 env.ext().address().clone(),193 &collection,194 input.item_id,195 input.data,196 )?;197198 Ok(RetVal::Converging(0))199 },200 6 => {201 202 let mut env = env.buf_in_buf_out();203 let input: NFTExtToggleWhiteList<E> = env.read_as()?;204 env.charge_weight(NftWeightInfoOf::<C>::add_to_white_list())?;205206 let collection = pallet_nft::Module::<C>::get_collection(input.collection_id)?;207208 pallet_nft::Module::<C>::toggle_white_list_internal(209 &env.ext().address().clone(),210 &collection,211 &input.address,212 input.whitelisted,213 )?;214215 Ok(RetVal::Converging(0))216 }217 _ => {218 Err(DispatchError::Other("unknown chain_extension func_id"))219 }220 }221 }222}