--- a/runtime/src/chain_extension.rs +++ /dev/null @@ -1,234 +0,0 @@ -//! NFT Chain Extension - -// -// This file is subject to the terms and conditions defined in -// file 'LICENSE', which is part of this source code package. -// - -use codec::{Decode, Encode}; -use max_encoded_len::MaxEncodedLen; -use derivative::Derivative; - -pub use pallet_contracts::chain_extension::RetVal; -use pallet_contracts::chain_extension::{ - ChainExtension, Environment, Ext, InitState, SysConfig, UncheckedFrom, -}; - -pub use frame_support::debug; -use frame_support::dispatch::DispatchError; - -extern crate pallet_nft; -pub use pallet_nft::*; -use pallet_nft::CrossAccountId; -use nft_data_structs::*; - -/// Create item parameters -#[derive(Debug, PartialEq, Encode, Decode, MaxEncodedLen)] -pub struct NFTExtCreateItem { - pub owner: AccountId, - pub collection_id: u32, - pub data: CreateItemData, -} - -/// Transfer parameters -#[derive(Debug, PartialEq, Encode, Decode, MaxEncodedLen)] -pub struct NFTExtTransfer { - pub recipient: AccountId, - pub collection_id: u32, - pub token_id: u32, - pub amount: u128, -} - -#[derive(Derivative, PartialEq, Encode, Decode, MaxEncodedLen)] -#[derivative(Debug)] -pub struct NFTExtCreateMultipleItems { - pub owner: AccountId, - pub collection_id: u32, - #[derivative(Debug = "ignore")] - pub data: BoundedVec, -} - -#[derive(Debug, PartialEq, Encode, Decode, MaxEncodedLen)] -pub struct NFTExtApprove { - pub spender: AccountId, - pub collection_id: u32, - pub item_id: u32, - pub amount: u128, -} - -#[derive(Debug, PartialEq, Encode, Decode, MaxEncodedLen)] -pub struct NFTExtTransferFrom { - pub owner: AccountId, - pub recipient: AccountId, - pub collection_id: u32, - pub item_id: u32, - pub amount: u128, -} - -#[derive(Derivative, PartialEq, Encode, Decode, MaxEncodedLen)] -#[derivative(Debug)] -pub struct NFTExtSetVariableMetaData { - pub collection_id: u32, - pub item_id: u32, - #[derivative(Debug = "ignore")] - pub data: BoundedVec, -} - -#[derive(Debug, PartialEq, Encode, Decode, MaxEncodedLen)] -pub struct NFTExtToggleWhiteList { - pub collection_id: u32, - pub address: AccountId, - pub whitelisted: bool, -} - -/// The chain Extension of NFT pallet -pub struct NFTExtension; - -pub type NftWeightInfoOf = ::WeightInfo; - -pub type AccountIdOf = ::AccountId; - -impl ChainExtension for NFTExtension { - fn call(func_id: u32, env: Environment) -> Result - where - E: Ext, - C: pallet_nft::Config, - ::AccountId: UncheckedFrom<::Hash> + AsRef<[u8]>, - { - // The memory of the vm stores buf in scale-codec - match func_id { - 0 => { - let mut env = env.buf_in_buf_out(); - let input: NFTExtTransfer> = env.read_as()?; - env.charge_weight(NftWeightInfoOf::::transfer())?; - - let collection = pallet_nft::Module::::get_collection(input.collection_id)?; - - pallet_nft::Module::::transfer_internal( - &C::CrossAccountId::from_sub(env.ext().address().clone()), - &C::CrossAccountId::from_sub(input.recipient), - &collection, - input.token_id, - input.amount, - )?; - - collection.submit_logs()?; - Ok(RetVal::Converging(0)) - } - 1 => { - // Create Item - let mut env = env.buf_in_buf_out(); - let input: NFTExtCreateItem> = env.read_as()?; - env.charge_weight(NftWeightInfoOf::::create_item(input.data.data_size()))?; - - let collection = pallet_nft::Module::::get_collection(input.collection_id)?; - - pallet_nft::Module::::create_item_internal( - &C::CrossAccountId::from_sub(env.ext().address().clone()), - &collection, - &C::CrossAccountId::from_sub(input.owner), - input.data, - )?; - - collection.submit_logs()?; - Ok(RetVal::Converging(0)) - } - 2 => { - // Create multiple items - let mut env = env.buf_in_buf_out(); - let input: NFTExtCreateMultipleItems> = env.read_as()?; - env.charge_weight(NftWeightInfoOf::::create_item( - input.data.iter().map(|i| i.data_size()).sum(), - ))?; - - let collection = pallet_nft::Module::::get_collection(input.collection_id)?; - - pallet_nft::Module::::create_multiple_items_internal( - &C::CrossAccountId::from_sub(env.ext().address().clone()), - &collection, - &C::CrossAccountId::from_sub(input.owner), - input.data.into_inner(), - )?; - - collection.submit_logs()?; - Ok(RetVal::Converging(0)) - } - 3 => { - // Approve - let mut env = env.buf_in_buf_out(); - let input: NFTExtApprove> = env.read_as()?; - env.charge_weight(NftWeightInfoOf::::approve())?; - - let collection = pallet_nft::Module::::get_collection(input.collection_id)?; - - pallet_nft::Module::::approve_internal( - &C::CrossAccountId::from_sub(env.ext().address().clone()), - &C::CrossAccountId::from_sub(input.spender), - &collection, - input.item_id, - input.amount, - )?; - - collection.submit_logs()?; - Ok(RetVal::Converging(0)) - } - 4 => { - // Transfer from - let mut env = env.buf_in_buf_out(); - let input: NFTExtTransferFrom> = env.read_as()?; - env.charge_weight(NftWeightInfoOf::::transfer_from())?; - - let collection = pallet_nft::Module::::get_collection(input.collection_id)?; - - pallet_nft::Module::::transfer_from_internal( - &C::CrossAccountId::from_sub(env.ext().address().clone()), - &C::CrossAccountId::from_sub(input.owner), - &C::CrossAccountId::from_sub(input.recipient), - &collection, - input.item_id, - input.amount, - )?; - - collection.submit_logs()?; - Ok(RetVal::Converging(0)) - } - 5 => { - // Set variable metadata - let mut env = env.buf_in_buf_out(); - let input: NFTExtSetVariableMetaData = env.read_as()?; - env.charge_weight(NftWeightInfoOf::::set_variable_meta_data())?; - - let collection = pallet_nft::Module::::get_collection(input.collection_id)?; - - pallet_nft::Module::::set_variable_meta_data_internal( - &C::CrossAccountId::from_sub(env.ext().address().clone()), - &collection, - input.item_id, - input.data.into_inner(), - )?; - - collection.submit_logs()?; - Ok(RetVal::Converging(0)) - } - 6 => { - // Toggle whitelist - let mut env = env.buf_in_buf_out(); - let input: NFTExtToggleWhiteList> = env.read_as()?; - env.charge_weight(NftWeightInfoOf::::add_to_white_list())?; - - let collection = pallet_nft::Module::::get_collection(input.collection_id)?; - - pallet_nft::Module::::toggle_white_list_internal( - &C::CrossAccountId::from_sub(env.ext().address().clone()), - &collection, - &C::CrossAccountId::from_sub(input.address), - input.whitelisted, - )?; - - collection.submit_logs()?; - Ok(RetVal::Converging(0)) - } - _ => Err(DispatchError::Other("unknown chain_extension func_id")), - } - } -}