12345678910111213141516171819use pallet_common::CollectionHandle;20use pallet_evm::account::CrossAccountId;21use pallet_fungible::Config as FungibleConfig;22use pallet_nonfungible::Config as NonfungibleConfig;23use pallet_refungible::{24 erc::{25 ERC721BurnableCall, ERC721Call, ERC721EnumerableCall, ERC721MetadataCall,26 ERC721UniqueExtensionsCall, ERC721UniqueMintableCall, TokenPropertiesCall,27 UniqueRefungibleCall,28 },29 erc_token::{30 ERC1633Call, ERC20Call, ERC20UniqueExtensionsCall, RefungibleTokenHandle,31 UniqueRefungibleTokenCall,32 },33 Config as RefungibleConfig,34};35use pallet_unique::Config as UniqueConfig;36use up_data_structs::{CreateItemData, CreateNftData, TokenId};3738use super::common;39use crate::runtime_common::sponsoring::*;4041pub fn call_sponsor<T>(42 call: UniqueRefungibleCall<T>,43 collection: CollectionHandle<T>,44 who: &T::CrossAccountId,45) -> Option<()>46where47 T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,48{49 use UniqueRefungibleCall::*;5051 match call {52 53 ERC165Call(_, _) => None,5455 ERC721Enumerable(call) => erc721::enumerable_call_sponsor(call, collection, who),56 ERC721Burnable(call) => erc721::burnable_call_sponsor(call, collection, who),57 ERC721Metadata(call) => erc721::metadata_call_sponsor(call, collection, who),58 Collection(call) => common::collection_call_sponsor(call, collection, who),59 ERC721(call) => erc721::call_sponsor(call, collection, who),60 ERC721UniqueExtensions(call) => {61 erc721::unique_extensions_call_sponsor(call, collection, who)62 }63 ERC721UniqueMintable(call) => erc721::unique_mintable_call_sponsor(call, collection, who),64 TokenProperties(call) => token_properties_call_sponsor(call, collection, who),65 }66}6768pub fn token_properties_call_sponsor<T>(69 call: TokenPropertiesCall<T>,70 collection: CollectionHandle<T>,71 who: &T::CrossAccountId,72) -> Option<()>73where74 T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,75{76 use TokenPropertiesCall::*;7778 match call {79 80 ERC165Call(_, _) | Property { .. } | TokenPropertyPermissions => None,8182 83 SetTokenPropertyPermission { .. }84 | SetTokenPropertyPermissions { .. }85 | SetProperties { .. }86 | DeleteProperty { .. }87 | DeleteProperties { .. } => None,8889 SetProperty {90 token_id,91 key,92 value,93 ..94 } => {95 let token_id = TokenId::try_from(token_id).ok()?;96 withdraw_set_existing_token_property::<T>(97 &collection,98 who,99 &token_id,100 key.len() + value.len(),101 )102 }103 }104}105106pub fn token_call_sponsor<T>(107 call: UniqueRefungibleTokenCall<T>,108 token: RefungibleTokenHandle<T>,109 who: &T::CrossAccountId,110) -> Option<()>111where112 T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,113{114 use UniqueRefungibleTokenCall::*;115116 match call {117 118 ERC165Call(_, _) => None,119120 ERC20(call) => erc20::call_sponsor(call, token, who),121 ERC20UniqueExtensions(call) => erc20::unique_extensions_call_sponsor(call, token, who),122 ERC1633(call) => erc1633::call_sponsor(call, token, who),123 }124}125126mod erc721 {127 use super::*;128129 pub fn call_sponsor<T>(130 call: ERC721Call<T>,131 collection: CollectionHandle<T>,132 _who: &T::CrossAccountId,133 ) -> Option<()>134 where135 T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,136 {137 use ERC721Call::*;138139 match call {140 141 ERC165Call(_, _)142 | BalanceOf { .. }143 | OwnerOf { .. }144 | GetApproved { .. }145 | IsApprovedForAll { .. } => None,146147 148 SafeTransferFromWithData { .. }149 | SafeTransferFrom { .. }150 | SetApprovalForAll { .. } => None,151152 TransferFrom { token_id, from, .. } => {153 let token_id = TokenId::try_from(token_id).ok()?;154 let from = T::CrossAccountId::from_eth(from);155 withdraw_transfer::<T>(&collection, &from, &token_id)156 }157158 159 Approve { .. } => None,160 }161 }162163 pub fn enumerable_call_sponsor<T>(164 call: ERC721EnumerableCall<T>,165 _collection: CollectionHandle<T>,166 _who: &T::CrossAccountId,167 ) -> Option<()>168 where169 T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,170 {171 use ERC721EnumerableCall::*;172173 match call {174 175 ERC165Call(_, _) | TokenByIndex { .. } | TokenOfOwnerByIndex { .. } | TotalSupply => {176 None177 }178 }179 }180181 pub fn burnable_call_sponsor<T>(182 call: ERC721BurnableCall<T>,183 _collection: CollectionHandle<T>,184 _who: &T::CrossAccountId,185 ) -> Option<()>186 where187 T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,188 {189 use ERC721BurnableCall::*;190191 match call {192 193 ERC165Call(_, _) => None,194195 196 Burn { .. } => None,197 }198 }199200 pub fn metadata_call_sponsor<T>(201 call: ERC721MetadataCall<T>,202 _collection: CollectionHandle<T>,203 _who: &T::CrossAccountId,204 ) -> Option<()>205 where206 T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,207 {208 use ERC721MetadataCall::*;209210 match call {211 212 ERC165Call(_, _) | NameProxy | SymbolProxy | TokenUri { .. } => None,213 }214 }215216 pub fn unique_extensions_call_sponsor<T>(217 call: ERC721UniqueExtensionsCall<T>,218 collection: CollectionHandle<T>,219 who: &T::CrossAccountId,220 ) -> Option<()>221 where222 T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,223 {224 use ERC721UniqueExtensionsCall::*;225226 match call {227 228 ERC165Call(_, _)229 | Name230 | Symbol231 | Description232 | CrossOwnerOf { .. }233 | OwnerOfCross { .. }234 | BalanceOfCross { .. }235 | Properties { .. }236 | NextTokenId237 | TokenContractAddress { .. }238 | CollectionHelperAddress => None,239240 241 BurnFrom { .. }242 | BurnFromCross { .. }243 | MintBulk { .. }244 | MintBulkCross { .. }245 | MintBulkWithTokenUri { .. } => None,246247 MintCross { .. } => withdraw_create_item::<T>(248 &collection,249 who,250 &CreateItemData::NFT(CreateNftData::default()),251 ),252253 TransferCross { token_id, .. }254 | TransferFromCross { token_id, .. }255 | Transfer { token_id, .. } => {256 let token_id = TokenId::try_from(token_id).ok()?;257 withdraw_transfer::<T>(&collection, who, &token_id)258 }259 }260 }261262 pub fn unique_mintable_call_sponsor<T>(263 call: ERC721UniqueMintableCall<T>,264 collection: CollectionHandle<T>,265 who: &T::CrossAccountId,266 ) -> Option<()>267 where268 T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,269 {270 use ERC721UniqueMintableCall::*;271272 match call {273 274 ERC165Call(_, _) => None,275276 277 Mint { .. }278 | MintCheckId { .. }279 | MintWithTokenUri { .. }280 | MintWithTokenUriCheckId { .. } => withdraw_create_item::<T>(281 &collection,282 who,283 &CreateItemData::NFT(CreateNftData::default()),284 ),285 }286 }287}288289290291292293mod erc20 {294 use super::*;295296 pub fn call_sponsor<T>(297 call: ERC20Call<T>,298 token: RefungibleTokenHandle<T>,299 who: &T::CrossAccountId,300 ) -> Option<()>301 where302 T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,303 {304 use ERC20Call::*;305306 match call {307 308 ERC165Call(_, _)309 | Name310 | Symbol311 | TotalSupply312 | Decimals313 | BalanceOf { .. }314 | Allowance { .. } => None,315316 Transfer { .. } => {317 let RefungibleTokenHandle(handle, token_id) = token;318 withdraw_transfer::<T>(&handle, who, &token_id)319 }320 TransferFrom { from, .. } => {321 let RefungibleTokenHandle(handle, token_id) = token;322 let from = T::CrossAccountId::from_eth(from);323 withdraw_transfer::<T>(&handle, &from, &token_id)324 }325 Approve { .. } => {326 let RefungibleTokenHandle(handle, token_id) = token;327 withdraw_approve::<T>(&handle, who.as_sub(), &token_id)328 }329 }330 }331332 pub fn unique_extensions_call_sponsor<T>(333 call: ERC20UniqueExtensionsCall<T>,334 token: RefungibleTokenHandle<T>,335 who: &T::CrossAccountId,336 ) -> Option<()>337 where338 T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,339 {340 use ERC20UniqueExtensionsCall::*;341342 match call {343 344 ERC165Call(_, _) => None,345346 347 AllowanceCross { .. }348 | BalanceOfCross { .. }349 | BurnFrom { .. }350 | BurnFromCross { .. }351 | Repartition { .. } => None,352353 TransferCross { .. } | TransferFromCross { .. } => {354 let RefungibleTokenHandle(handle, token_id) = token;355 withdraw_transfer::<T>(&handle, who, &token_id)356 }357358 ApproveCross { .. } => {359 let RefungibleTokenHandle(handle, token_id) = token;360 withdraw_approve::<T>(&handle, who.as_sub(), &token_id)361 }362 }363 }364}365366mod erc1633 {367 use super::*;368369 pub fn call_sponsor<T>(370 call: ERC1633Call<T>,371 _token: RefungibleTokenHandle<T>,372 _who: &T::CrossAccountId,373 ) -> Option<()>374 where375 T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,376 {377 use ERC1633Call::*;378379 match call {380 381 ERC165Call(_, _) | ParentToken | ParentTokenId => None,382 }383 }384}