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::*;2021use 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;8081pub type NftWeightInfoOf<C> = <C as pallet_nft::Config>::WeightInfo;8283impl<C: Config> ChainExtension<C> for NFTExtension {84 fn call<E: Ext>(func_id: u32, env: Environment<E, InitState>) -> Result<RetVal, DispatchError>85 where86 E: Ext<T = C>,87 C: pallet_nft::Config,88 <E::T as SysConfig>::AccountId: UncheckedFrom<<E::T as SysConfig>::Hash> + AsRef<[u8]>,89 {90 91 match func_id {92 0 => {93 let mut env = env.buf_in_buf_out();94 let input: NFTExtTransfer<E> = env.read_as()?;95 env.charge_weight(NftWeightInfoOf::<C>::transfer())?;9697 let collection = pallet_nft::Module::<C>::get_collection(input.collection_id)?;9899 pallet_nft::Module::<C>::transfer_internal(100 env.ext().address().clone(),101 input.recipient,102 &collection,103 input.token_id,104 input.amount,105 )?;106 107 Ok(RetVal::Converging(0))108 },109 1 => {110 111 let mut env = env.buf_in_buf_out();112 let input: NFTExtCreateItem<E> = env.read_as()?;113 env.charge_weight(NftWeightInfoOf::<C>::create_item(input.data.len()))?;114115 pallet_nft::Module::<C>::create_item_internal(116 env.ext().address().clone(),117 input.collection_id,118 input.owner,119 input.data,120 )?;121 122 Ok(RetVal::Converging(0))123 },124 2 => {125 126 let mut env = env.buf_in_buf_out();127 let input: NFTExtCreateMultipleItems<E> = env.read_as()?;128 env.charge_weight(NftWeightInfoOf::<C>::create_item(129 input.data.iter()130 .map(|i| i.len())131 .sum()132 ))?;133134 let collection = pallet_nft::Module::<C>::get_collection(input.collection_id)?;135136 pallet_nft::Module::<C>::create_multiple_items_internal(137 env.ext().address().clone(),138 &collection,139 input.owner,140 input.data,141 )?;142 143 Ok(RetVal::Converging(0))144 },145 3 => {146 147 let mut env = env.buf_in_buf_out();148 let input: NFTExtApprove<E> = env.read_as()?;149 env.charge_weight(NftWeightInfoOf::<C>::approve())?;150151 let collection = pallet_nft::Module::<C>::get_collection(input.collection_id)?;152153 pallet_nft::Module::<C>::approve_internal(154 env.ext().address().clone(),155 input.spender,156 &collection,157 input.item_id,158 input.amount,159 )?;160161 Ok(RetVal::Converging(0))162 },163 4 => {164 165 let mut env = env.buf_in_buf_out();166 let input: NFTExtTransferFrom<E> = env.read_as()?;167 env.charge_weight(NftWeightInfoOf::<C>::transfer_from())?;168169 let collection = pallet_nft::Module::<C>::get_collection(input.collection_id)?;170171 pallet_nft::Module::<C>::transfer_from_internal(172 env.ext().address().clone(),173 input.owner,174 input.recipient,175 &collection,176 input.item_id,177 input.amount178 )?;179180 Ok(RetVal::Converging(0))181 },182 5 => {183 184 let mut env = env.buf_in_buf_out();185 let input: NFTExtSetVariableMetaData = env.read_as()?;186 env.charge_weight(NftWeightInfoOf::<C>::set_variable_meta_data())?;187188 let collection = pallet_nft::Module::<C>::get_collection(input.collection_id)?;189190 pallet_nft::Module::<C>::set_variable_meta_data_internal(191 env.ext().address().clone(),192 &collection,193 input.item_id,194 input.data,195 )?;196197 Ok(RetVal::Converging(0))198 },199 6 => {200 201 let mut env = env.buf_in_buf_out();202 let input: NFTExtToggleWhiteList<E> = env.read_as()?;203 env.charge_weight(NftWeightInfoOf::<C>::add_to_white_list())?;204205 let collection = pallet_nft::Module::<C>::get_collection(input.collection_id)?;206207 pallet_nft::Module::<C>::toggle_white_list_internal(208 &env.ext().address().clone(),209 &collection,210 &input.address,211 input.whitelisted,212 )?;213214 Ok(RetVal::Converging(0))215 }216 _ => {217 Err(DispatchError::Other("unknown chain_extension func_id"))218 }219 }220 }221}