1// SPDX-License-Identifier: Apache License2pragma solidity >=0.8.0;3import {CollectionHelpers} from "../api/CollectionHelpers.sol";4import {ContractHelpers} from "../api/ContractHelpers.sol";5import {UniqueRefungibleToken} from "../api/UniqueRefungibleToken.sol";6import {UniqueRefungible, Collection, EthCrossAccount as RftCrossAccountId, Tuple20 as RftProperties} from "../api/UniqueRefungible.sol";7import {UniqueNFT, EthCrossAccount as NftCrossAccountId, Tuple21 as NftProperty, TokenProperties} from "../api/UniqueNFT.sol";89struct Property {10 string key;11 bytes value;12}1314// interface Foo {15// struct Tuple19 {16// string field_0;17// bytes field_1;18// }1920// }2122contract EvmToSubstrate {23 bytes32 constant REFUNGIBLE_COLLECTION_TYPE = keccak256(bytes("ReFungible"));24 bytes32 constant NONFUNGIBLE_COLLECTION_TYPE = keccak256(bytes("NFT"));25 // bytes32 collectionType;2627 // Collection commonContract;28 // UniqueNFT nftCollection;29 // UniqueRefungible rftCollection;3031 // function(address, uint256) external returns (bool) mintInvoke;32 // function(address, address, uint256) external transferInvoke;3334 modifier checkRestrictions(address _collection) {35 Collection commonContract = Collection(_collection);36 require(commonContract.isOwnerOrAdmin(msg.sender), "Only collection admin/owner can call this method");3738 // bytes32 collectionType = keccak256(bytes(commonContract.uniqueCollectionType()));39 // uint256 tokenId;4041 // if (collectionType == REFUNGIBLE_COLLECTION_TYPE) {42 // UniqueRefungible rftCollection = UniqueRefungible(_collection);43 // mintInvoke = rftCollection.mint;44 // transferInvoke = rftCollection.transferFrom;45 // tokenId = rftCollection.nextTokenId();46 // } else if (collectionType == NONFUNGIBLE_COLLECTION_TYPE) {47 // UniqueNFT nftCollection = UniqueNFT(_collection);48 // mintInvoke = nftCollection.mint;49 // transferInvoke = nftCollection.transferFrom;5051 // tokenId = nftCollection.nextTokenId();52 // } else {53 // revert("Wrong collection type. Works only with NFT or RFT");54 // }5556 _;57 }5859 /// @dev This emits when a mint to a substrate address has been made.60 event MintToSub(address _toEth, uint256 _toSub, address _collection, uint256 _tokenId);6162 function mintToSubstrate(address _collection, uint256 _substrateReceiver) external checkRestrictions(_collection) {63 // function(address, uint256) external returns (bool) mintInvoke;64 // function(Tuple8 memory, Tuple8 memory, uint256) external transferInvoke;65 Collection commonContract = Collection(_collection);66 bytes32 collectionType = keccak256(bytes(commonContract.uniqueCollectionType()));67 uint256 tokenId;6869 if (collectionType == REFUNGIBLE_COLLECTION_TYPE) {70 UniqueRefungible rftCollection = UniqueRefungible(_collection);71 72 tokenId = rftCollection.mint(address(this));7374 rftCollection.transferFromCross(75 RftCrossAccountId(address(this), 0),76 RftCrossAccountId(address(0), _substrateReceiver),77 tokenId78 );79 } else if (collectionType == NONFUNGIBLE_COLLECTION_TYPE) {80 UniqueNFT nftCollection = UniqueNFT(_collection);81 // tokenId = nftCollection.nextTokenId();82 tokenId = nftCollection.mint(address(this));8384 nftCollection.transferFromCross(85 NftCrossAccountId(address(this), 0),86 NftCrossAccountId(address(0), _substrateReceiver),87 tokenId88 );89 } else {90 revert("Wrong collection type. Works only with NFT or RFT");91 }9293 // mintInvoke(address(this), tokenId);94 // Tuple8 memory sender = Tuple8(address(this), 0);95 // Tuple8 memory receiver = Tuple8(address(0), _substrateReceiver);9697 // transferInvoke(sender, receiver, tokenId);9899 emit MintToSub(address(0), _substrateReceiver, _collection, tokenId);100 }101102 function mintToSubstrateWithProperty(103 address _collection,104 uint256 _substrateReceiver,105 Property[] calldata properties106 ) external checkRestrictions(_collection) {107 // function(address, uint256, string memory) external returns (bool) mintInvoke;108 // function(address, address, uint256) external transferInvoke;109 uint256 propertiesLength = properties.length;110 require(propertiesLength > 0, "Properies is empty");111112 Collection commonContract = Collection(_collection);113 bytes32 collectionType = keccak256(bytes(commonContract.uniqueCollectionType()));114 uint256 tokenId;115116 if (collectionType == REFUNGIBLE_COLLECTION_TYPE) {117 UniqueRefungible rftCollection = UniqueRefungible(_collection);118 tokenId = rftCollection.nextTokenId();119 rftCollection.mint(address(this));120 for (uint256 i = 0; i < propertiesLength; ++i) {121 rftCollection.setProperty(tokenId, properties[i].key, properties[i].value);122 }123 rftCollection.transferFromCross(124 RftCrossAccountId(address(this), 0),125 RftCrossAccountId(address(0), _substrateReceiver),126 tokenId127 );128 } else if (collectionType == NONFUNGIBLE_COLLECTION_TYPE) {129 UniqueNFT nftCollection = UniqueNFT(_collection);130 // tokenId = nftCollection.nextTokenId();131 tokenId = nftCollection.mint(address(this));132 for (uint256 i = 0; i < propertiesLength; ++i) {133 nftCollection.setProperty(tokenId, properties[i].key, properties[i].value);134 }135 nftCollection.transferFromCross(136 NftCrossAccountId(address(this), 0),137 NftCrossAccountId(address(0), _substrateReceiver),138 tokenId139 );140 } else {141 revert("Wrong collection type. Works only with NFT or RFT");142 }143144 // transferInvoke(address(this), _gap, tokenId);145146 emit MintToSub(address(0), _substrateReceiver, _collection, tokenId);147 }148149 function mintToSubstrateBulkProperty(150 address _collection,151 uint256 _substrateReceiver,152 NftProperty[] calldata _properties153 ) external checkRestrictions(_collection) {154 uint256 propertiesLength = _properties.length;155 require(propertiesLength > 0, "Properies is empty");156157 Collection commonContract = Collection(_collection);158 bytes32 collectionType = keccak256(bytes(commonContract.uniqueCollectionType()));159 uint256 tokenId;160161 if (collectionType == REFUNGIBLE_COLLECTION_TYPE) {} else if (collectionType == NONFUNGIBLE_COLLECTION_TYPE) {162 UniqueNFT nftCollection = UniqueNFT(_collection);163 // tokenId = nftCollection.nextTokenId();164 tokenId = nftCollection.mint(address(this));165166 nftCollection.setProperties(tokenId, _properties);167168 nftCollection.transferFromCross(169 NftCrossAccountId(address(this), 0),170 NftCrossAccountId(address(0), _substrateReceiver),171 tokenId172 );173 } else {174 revert("Wrong collection type. Works only with NFT or RFT");175 }176177 emit MintToSub(address(0), _substrateReceiver, _collection, tokenId);178 }179}