// SPDX-License-Identifier: MIT
// Copyright (c) 2023 Kenchiro.
// Source code forked from Keisuke OHNO.

/*

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

*/

pragma solidity >=0.7.0 <0.9.0;

import '@openzeppelin/contracts/utils/cryptography/MerkleProof.sol';
import "@openzeppelin/contracts/token/common/ERC2981.sol";
import "contract-allow-list/contracts/ERC721AntiScam/ERC721AntiScam.sol";
import "@openzeppelin/contracts/access/AccessControl.sol";
import "operator-filter-registry/src/DefaultOperatorFilterer.sol";

contract X2E_SIDEKICKS_Ropi is DefaultOperatorFilterer, ERC2981, ERC721AntiScam, AccessControl{

	address public withdrawAddress;
	string baseURI;
	string public baseExtension = ".json";
	uint256 public cost = 0;
	uint256 public maxSupply = 10000;
	mapping(uint256 => uint256) public tokenToImageId;

	enum em_saleStage{
		Pause,		//0 : consruct paused
		WLSale		//1 : WL Sale
	}
	em_saleStage public saleStage = em_saleStage.Pause; //現在のセール内容
					
	uint8 public wlSaleCount = 0;               //1回目のセールが0
	struct WLSaleInfo{
		bytes32 WLMearkleRoot;										//wlSaleCountに応じたMearkleRoot
		mapping(address => uint8) WLMintedAmount;	//アドレスに対してwlSaleCountに応じたmint枚数を格納
	}
	WLSaleInfo[] public wlSaleData;

	uint8 public maxImageLv = 0;								// 最大レベル
	mapping(uint256 => uint8) tokenLv;					// Token毎のレベル
	uint256[] public ImageLvNumber = [1];			// 各レベルの画像枚数

	constructor() ERC721A('X2E_SIDEKICKS_Ropi', 'ROPI') {
		//Role initialization
		_setupRole(DEFAULT_ADMIN_ROLE, msg.sender);
		setBaseURI("https://x2e-dao-mint.com/data/ropi/main/meta/");
		setWithdrawAddress(0x67CaA1b4C959C79a92b81258E5a2C6dBAB865DFe);
		//setWithdrawAddress(0xe8dF89785B9a726dE1f45b1DBe03E550f0043B92);		//Goerli Develop
		
		//Royality initialization
		_setDefaultRoyalty(withdrawAddress, 1000);

		//CAL initialization
		_setCAL(0xdbaa28cBe70aF04EbFB166b1A3E8F8034e5B9FC7);//Ethereum mainnet proxy
		// _setCAL(0xb506d7BbE23576b8AAf22477cd9A7FDF08002211);//Goerli testnet proxy

	}

	// internal
	function _baseURI() internal view virtual override returns (string memory) {
		return baseURI;
	}

	// external
	function wl_mint(uint8 _mintAmount, uint8 _wlMaxMintAmount, bytes32[] calldata _merkleProof) external payable {
		uint256 supply = totalSupply();
		require(_mintAmount > 0, "need to mint at least 1 NFT");
		require(supply + _mintAmount <= maxSupply, "max NFT limit exceeded");
		
		if (!hasRole(DEFAULT_ADMIN_ROLE, msg.sender)) {
			require(saleStage == em_saleStage.WLSale, "the contract is not WL Sale");
			require(_mintAmount <= _wlMaxMintAmount, "max mint amount per session exceeded");
			require(isWhitelisted(msg.sender, _wlMaxMintAmount, _merkleProof), "You don't have WL.");
			require(wlSaleData[wlSaleCount].WLMintedAmount[msg.sender] + _mintAmount <= _wlMaxMintAmount, "max NFT per address exceeded");
			require(msg.value >= cost * _mintAmount, "insufficient funds. : Wl mint");
			wlSaleData[wlSaleCount].WLMintedAmount[msg.sender] += _mintAmount;
		}
		_safeMint(msg.sender, _mintAmount);
	}

	function airdropMint(address[] calldata _airdropAddresses , uint256[] memory _UserMintAmount) public onlyRole(DEFAULT_ADMIN_ROLE){
		uint256 supply = totalSupply();
		uint256 totalmintAmount = 0;
		for (uint256 i = 0; i < _UserMintAmount.length; i++) {
			totalmintAmount += _UserMintAmount[i];
		}
		require(totalmintAmount > 0, "need to mint at least 1 NFT");
		require(supply + totalmintAmount <= maxSupply, "max NFT limit exceeded");

		for (uint256 i = 0; i < _UserMintAmount.length; i++) {
			_safeMint(_airdropAddresses[i], _UserMintAmount[i] );
		}
	}

	function tokenURI(uint256 tokenId) public view virtual override returns (string memory){
		if (!_exists(tokenId)) revert URIQueryForNonexistentToken();
		uint8 imageLv = tokenLv[tokenId];
		if(imageLv > maxImageLv){
			imageLv = maxImageLv;
		}
		uint256 imageId = tokenId % ImageLvNumber[imageLv] + 1;
		return string(abi.encodePacked(_baseURI(), _toString(imageLv), "/" , _toString(imageId), baseExtension));
	}

	function checkTokenExists(uint256 _tokenId) external view returns(bool){
		return _exists(_tokenId);
	}

	function isWhitelisted(address _user, uint8 _wlMaxMintAmount, bytes32[] calldata _merkleProof) public view returns (bool) {
		bytes32 leaf = keccak256(abi.encodePacked(_user, _wlMaxMintAmount));
		return MerkleProof.verify(_merkleProof, wlSaleData[wlSaleCount].WLMearkleRoot, leaf);
	}

	function getWLMintedAmount(address _user, uint8 _wlSaleCount)public view returns(uint8){
		require(_wlSaleCount < wlSaleData.length, "WL Sale count over!");
		return wlSaleData[_wlSaleCount].WLMintedAmount[_user];
	}

	function getWLMearkleRoot(uint8 _wlSaleCount)public view returns(bytes32){
		require(_wlSaleCount < wlSaleData.length, "WL Sale count over!");
		return wlSaleData[_wlSaleCount].WLMearkleRoot;
	}

	//only owner  
	function setCost(uint256 _newCost) public onlyRole(DEFAULT_ADMIN_ROLE) {
		cost = _newCost;
	}

	function setMaxSupply(uint256 _maxSupply) public onlyRole(DEFAULT_ADMIN_ROLE) {
		maxSupply = _maxSupply;
	}

	function setMaxImageLv(uint8 _maxImageLv) public onlyRole(DEFAULT_ADMIN_ROLE){
		maxImageLv = _maxImageLv;
	}

	function setImageLvNumber(uint8 _level, uint256 _number) public onlyRole(DEFAULT_ADMIN_ROLE){
		ImageLvNumber[_level] = _number;
	}

	function setBaseURI(string memory _newBaseURI) public onlyRole(DEFAULT_ADMIN_ROLE) {
		baseURI = _newBaseURI;
	}

	function setBaseExtension(string memory _newBaseExtension) public onlyRole(DEFAULT_ADMIN_ROLE) {
		baseExtension = _newBaseExtension;
	}

	function setSaleStage(em_saleStage _saleStage) public onlyRole(DEFAULT_ADMIN_ROLE) {
		saleStage = _saleStage;
	}

	function setWithdrawAddress(address _withdrawAddress) public onlyRole(DEFAULT_ADMIN_ROLE) {
		withdrawAddress = _withdrawAddress;
	}

	//WL
	function setWLMearkleRoot(uint256 _wlSaleCount, bytes32 _wlMearkleRoot) public onlyRole(DEFAULT_ADMIN_ROLE){
		require(_wlSaleCount < wlSaleData.length, "WL Sale count over!");
		wlSaleData[_wlSaleCount].WLMearkleRoot = _wlMearkleRoot;
	}

	function setWlSaleCount(uint8 _wlSaleCount) public onlyRole(DEFAULT_ADMIN_ROLE){
		require(_wlSaleCount < wlSaleData.length, "WL Sale count over!");
		wlSaleCount = _wlSaleCount;
	}

	function addNewWLSale() public onlyRole(DEFAULT_ADMIN_ROLE) returns (uint){
		wlSaleData.push();
		return wlSaleData.length;
	}

	function wlSaleDataLength() view public onlyRole(DEFAULT_ADMIN_ROLE) returns (uint){
		return wlSaleData.length;
	}

	//Other
	function withdraw() public payable onlyRole(DEFAULT_ADMIN_ROLE) {
		require(withdrawAddress != address(0), "The payment address is 0.");
		(bool os, ) = payable(withdrawAddress).call{value: address(this).balance}("");
		require(os);
	}

	//ERC2981 Royalty Data.
	function setRoyaltyFee(uint96 _feeNumerator) public onlyRole(DEFAULT_ADMIN_ROLE) {
		_setDefaultRoyalty(withdrawAddress, _feeNumerator);
	}

	/*―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――
		OVERRIDES operator-filter-registry
	―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――*/
	function setApprovalForAll(address operator, bool approved) public override onlyAllowedOperatorApproval(operator){
		super.setApprovalForAll(operator, approved);
	}

	function approve(address operator, uint256 tokenId) public payable override onlyAllowedOperatorApproval(operator){
		super.approve(operator, tokenId);
	}

	function transferFrom(address from, address to, uint256 tokenId) public payable override onlyAllowedOperator(from){
		super.transferFrom(from, to, tokenId);
	}

	function safeTransferFrom(address from, address to, uint256 tokenId) public payable override onlyAllowedOperator(from){
		super.safeTransferFrom(from, to, tokenId);
	}

	function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data) public payable override onlyAllowedOperator(from){
		super.safeTransferFrom(from, to, tokenId, data);
	}

	/*―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――
		OVERRIDES ERC721Lockable
	―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――*/
	function setTokenLock(uint256[] calldata tokenIds, LockStatus lockStatus)external override{
		for (uint256 i = 0; i < tokenIds.length; i++) {
				require(msg.sender == ownerOf(tokenIds[i]), "not owner.");
		}
		_setTokenLock(tokenIds, lockStatus);
	}

	function setWalletLock(address to, LockStatus lockStatus)external override{
		require(to == msg.sender, "not yourself.");
		_setWalletLock(to, lockStatus);
	}

	function setContractLock(LockStatus lockStatus)external override onlyRole(DEFAULT_ADMIN_ROLE){
		_setContractLock(lockStatus);
	}

	function setEnableLock(bool _enableLock)external onlyRole(DEFAULT_ADMIN_ROLE){
		enableLock = _enableLock;
	}

	/*―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――
		OVERRIDES ERC721RestrictApprove
	―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――*/
	function addLocalContractAllowList(address transferer) external override onlyRole(DEFAULT_ADMIN_ROLE){
		_addLocalContractAllowList(transferer);
	}

	function removeLocalContractAllowList(address transferer) external override onlyRole(DEFAULT_ADMIN_ROLE){
		_removeLocalContractAllowList(transferer);
	}

	function setCALLevel(uint256 level) external override onlyRole(DEFAULT_ADMIN_ROLE){
		CALLevel = level;
	}

	function setCAL(address calAddress) external onlyRole(DEFAULT_ADMIN_ROLE){
		_setCAL(calAddress);
	}

	/*―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――
		OVERRIDES ERC721AntiScam
	―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――*/
	//for ERC2981,ERC721AntiScam.AccessControl
	function supportsInterface(bytes4 interfaceId) public view override(ERC721AntiScam , AccessControl, ERC2981) returns (bool) {
		return(
				ERC721AntiScam.supportsInterface(interfaceId) || 
				AccessControl.supportsInterface(interfaceId) ||
				ERC2981.supportsInterface(interfaceId) ||
				super.supportsInterface(interfaceId)
		);
	}
	function _startTokenId() internal view virtual override returns (uint256) {
		return 1;
	}    
}
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ApprovalCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"ApprovalQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"BalanceQueryForZeroAddress","type":"error"},{"inputs":[],"name":"MintERC2309QuantityExceedsLimit","type":"error"},{"inputs":[],"name":"MintToZeroAddress","type":"error"},{"inputs":[],"name":"MintZeroQuantity","type":"error"},{"inputs":[{"internalType":"address","name":"operator","type":"address"}],"name":"OperatorNotAllowed","type":"error"},{"inputs":[],"name":"OwnerQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"OwnershipNotInitializedForExtraData","type":"error"},{"inputs":[],"name":"TransferCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"TransferFromIncorrectOwner","type":"error"},{"inputs":[],"name":"TransferToNonERC721ReceiverImplementer","type":"error"},{"inputs":[],"name":"TransferToZeroAddress","type":"error"},{"inputs":[],"name":"URIQueryForNonexistentToken","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":true,"internalType":"uint256","name":"level","type":"uint256"}],"name":"CalLevelChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"fromTokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"toTokenId","type":"uint256"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"ConsecutiveTransfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":true,"internalType":"address","name":"transferer","type":"address"}],"name":"LocalCalAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":true,"internalType":"address","name":"transferer","type":"address"}],"name":"LocalCalRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"holder","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"enum IERC721Lockable.LockStatus","name":"lockStatus","type":"uint8"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"TokenLock","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"holder","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"enum IERC721Lockable.LockStatus","name":"lockStatus","type":"uint8"}],"name":"WalletLock","type":"event"},{"inputs":[],"name":"CAL","outputs":[{"internalType":"contract IContractAllowListProxy","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"CALLevel","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"ImageLvNumber","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"OPERATOR_FILTER_REGISTRY","outputs":[{"internalType":"contract IOperatorFilterRegistry","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"transferer","type":"address"}],"name":"addLocalContractAllowList","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"addNewWLSale","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_airdropAddresses","type":"address[]"},{"internalType":"uint256[]","name":"_UserMintAmount","type":"uint256[]"}],"name":"airdropMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseExtension","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"checkTokenExists","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"contractLockStatus","outputs":[{"internalType":"enum IERC721Lockable.LockStatus","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"cost","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"enableLock","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"enableRestrict","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"start","type":"uint256"},{"internalType":"uint256","name":"end","type":"uint256"}],"name":"getTokensUnderLock","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTokensUnderLock","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint8","name":"_wlSaleCount","type":"uint8"}],"name":"getWLMearkleRoot","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"},{"internalType":"uint8","name":"_wlSaleCount","type":"uint8"}],"name":"getWLMintedAmount","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"holder","type":"address"}],"name":"isLocked","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"isLocked","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"},{"internalType":"uint8","name":"_wlMaxMintAmount","type":"uint8"},{"internalType":"bytes32[]","name":"_merkleProof","type":"bytes32[]"}],"name":"isWhitelisted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxImageLv","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"transferer","type":"address"}],"name":"removeLocalContractAllowList","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"uint256","name":"_salePrice","type":"uint256"}],"name":"royaltyInfo","outputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"saleStage","outputs":[{"internalType":"enum X2E_SIDEKICKS_Ropi.em_saleStage","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_newBaseExtension","type":"string"}],"name":"setBaseExtension","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_newBaseURI","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"calAddress","type":"address"}],"name":"setCAL","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"level","type":"uint256"}],"name":"setCALLevel","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"enum IERC721Lockable.LockStatus","name":"lockStatus","type":"uint8"}],"name":"setContractLock","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newCost","type":"uint256"}],"name":"setCost","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_enableLock","type":"bool"}],"name":"setEnableLock","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint8","name":"_level","type":"uint8"},{"internalType":"uint256","name":"_number","type":"uint256"}],"name":"setImageLvNumber","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint8","name":"_maxImageLv","type":"uint8"}],"name":"setMaxImageLv","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_maxSupply","type":"uint256"}],"name":"setMaxSupply","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint96","name":"_feeNumerator","type":"uint96"}],"name":"setRoyaltyFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"enum X2E_SIDEKICKS_Ropi.em_saleStage","name":"_saleStage","type":"uint8"}],"name":"setSaleStage","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"level","type":"uint256"}],"name":"setTokenCALLevel","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"},{"internalType":"enum IERC721Lockable.LockStatus","name":"lockStatus","type":"uint8"}],"name":"setTokenLock","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_wlSaleCount","type":"uint256"},{"internalType":"bytes32","name":"_wlMearkleRoot","type":"bytes32"}],"name":"setWLMearkleRoot","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"level","type":"uint256"}],"name":"setWalletCALLevel","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"enum IERC721Lockable.LockStatus","name":"lockStatus","type":"uint8"}],"name":"setWalletLock","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_withdrawAddress","type":"address"}],"name":"setWithdrawAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint8","name":"_wlSaleCount","type":"uint8"}],"name":"setWlSaleCount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"tokenCALLevel","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"tokenLock","outputs":[{"internalType":"enum IERC721Lockable.LockStatus","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"tokenToImageId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"walletCALLevel","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"walletLock","outputs":[{"internalType":"enum IERC721Lockable.LockStatus","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"withdrawAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"wlSaleCount","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"wlSaleData","outputs":[{"internalType":"bytes32","name":"WLMearkleRoot","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"wlSaleDataLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint8","name":"_mintAmount","type":"uint8"},{"internalType":"uint8","name":"_wlMaxMintAmount","type":"uint8"},{"internalType":"bytes32[]","name":"_merkleProof","type":"bytes32[]"}],"name":"wl_mint","outputs":[],"stateMutability":"payable","type":"function"}]