1// SPDX-License-Identifier: Apache License2pragma solidity >=0.8.0;3import {CollectionHelpers} from "../../eth/api/CollectionHelpers.sol";4import {ContractHelpers} from "../../eth/api/ContractHelpers.sol";5import {UniqueRefungibleToken} from "../../eth/api/UniqueRefungibleToken.sol";6import {UniqueRefungible, Collection, CrossAddress as RftCrossAccountId, Property as RftProperty} from "../../eth/api/UniqueRefungible.sol";7import {UniqueNFT, CrossAddress as NftCrossAccountId, Property as NftProperty} from "../../eth/api/UniqueNFT.sol";89struct Property {10 string key;11 bytes value;12}1314interface SoftDeprecatedMethods {15 /// @notice Set token property value.16 /// @dev Throws error if `msg.sender` has no permission to edit the property.17 /// @param tokenId ID of the token.18 /// @param key Property key.19 /// @param value Property value.20 /// @dev EVM selector for this function is: 0x1752d67b,21 /// or in textual repr: setProperty(uint256,string,bytes)22 function setProperty(23 uint256 tokenId,24 string memory key,25 bytes memory value26 ) external;27}2829interface BenchUniqueRefungible is UniqueRefungible, SoftDeprecatedMethods {}30interface BenchUniqueNFT is UniqueNFT, SoftDeprecatedMethods {}31323334contract ProxyMint {35 bytes32 constant REFUNGIBLE_COLLECTION_TYPE = keccak256(bytes("ReFungible"));36 bytes32 constant NONFUNGIBLE_COLLECTION_TYPE = keccak256(bytes("NFT"));3738 modifier checkRestrictions(address _collection) {39 Collection commonContract = Collection(_collection);40 require(41 commonContract.isOwnerOrAdminCross(RftCrossAccountId(msg.sender, 0)),42 "Only collection admin/owner can call this method"43 );44 _;45 }4647 /// @dev This emits when a mint to a substrate address has been made.48 event MintToSub(address _toEth, uint256 _toSub, address _collection, uint256 _tokenId);4950 function mintToSubstrate(address _collection, uint256 _substrateReceiver) external checkRestrictions(_collection) {51 Collection commonContract = Collection(_collection);52 bytes32 collectionType = keccak256(bytes(commonContract.uniqueCollectionType()));53 uint256 tokenId;5455 if (collectionType == REFUNGIBLE_COLLECTION_TYPE) {56 UniqueRefungible rftCollection = UniqueRefungible(_collection);5758 tokenId = rftCollection.mint(address(this));5960 rftCollection.transferFromCross(61 RftCrossAccountId(address(this), 0),62 RftCrossAccountId(address(0), _substrateReceiver),63 tokenId64 );65 } else if (collectionType == NONFUNGIBLE_COLLECTION_TYPE) {66 UniqueNFT nftCollection = UniqueNFT(_collection);67 tokenId = nftCollection.mint(address(this));6869 nftCollection.transferFromCross(70 NftCrossAccountId(address(this), 0),71 NftCrossAccountId(address(0), _substrateReceiver),72 tokenId73 );74 } else {75 revert("Wrong collection type. Works only with NFT or RFT");76 }7778 emit MintToSub(address(0), _substrateReceiver, _collection, tokenId);79 }8081 function mintToSubstrateWithProperty(82 address _collection,83 uint256 _substrateReceiver,84 Property[] calldata _properties85 ) external checkRestrictions(_collection) {86 uint256 propertiesLength = _properties.length;87 require(propertiesLength > 0, "Properies is empty");8889 Collection commonContract = Collection(_collection);90 bytes32 collectionType = keccak256(bytes(commonContract.uniqueCollectionType()));91 uint256 tokenId;9293 if (collectionType == REFUNGIBLE_COLLECTION_TYPE) {94 BenchUniqueRefungible rftCollection = BenchUniqueRefungible(_collection);95 tokenId = rftCollection.nextTokenId();96 rftCollection.mint(address(this));9798 for (uint256 i = 0; i < propertiesLength; ++i) {99 rftCollection.setProperty(tokenId, _properties[i].key, _properties[i].value);100 }101 rftCollection.transferFromCross(102 RftCrossAccountId(address(this), 0),103 RftCrossAccountId(address(0), _substrateReceiver),104 tokenId105 );106 } else if (collectionType == NONFUNGIBLE_COLLECTION_TYPE) {107 BenchUniqueNFT nftCollection = BenchUniqueNFT(_collection);108 tokenId = nftCollection.mint(address(this));109 for (uint256 i = 0; i < propertiesLength; ++i) {110 nftCollection.setProperty(tokenId, _properties[i].key, _properties[i].value);111 }112 nftCollection.transferFromCross(113 NftCrossAccountId(address(this), 0),114 NftCrossAccountId(address(0), _substrateReceiver),115 tokenId116 );117 } else {118 revert("Wrong collection type. Works only with NFT or RFT");119 }120121 emit MintToSub(address(0), _substrateReceiver, _collection, tokenId);122 }123124 function mintToSubstrateBulkProperty(125 address _collection,126 uint256 _substrateReceiver,127 NftProperty[] calldata _properties128 ) external checkRestrictions(_collection) {129 uint256 propertiesLength = _properties.length;130 require(propertiesLength > 0, "Properies is empty");131132 Collection commonContract = Collection(_collection);133 bytes32 collectionType = keccak256(bytes(commonContract.uniqueCollectionType()));134 uint256 tokenId;135136 if (collectionType == REFUNGIBLE_COLLECTION_TYPE) {} else if (collectionType == NONFUNGIBLE_COLLECTION_TYPE) {137 UniqueNFT nftCollection = UniqueNFT(_collection);138 tokenId = nftCollection.mint(address(this));139140 nftCollection.setProperties(tokenId, _properties);141142 nftCollection.transferFromCross(143 NftCrossAccountId(address(this), 0),144 NftCrossAccountId(address(0), _substrateReceiver),145 tokenId146 );147 } else {148 revert("Wrong collection type. Works only with NFT or RFT");149 }150151 emit MintToSub(address(0), _substrateReceiver, _collection, tokenId);152 }153}