{"sources":{"DannyNFT.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.26;\n\n/// @title Dragon Agent - Pokechain-style: mint pertama gratis, sisanya bayar.\n/// Harga: #1 gratis, #2-15 = 0.00035 BNB. Maks 15/wallet.\n/// Pemilik bisa tarik hasil mint lewat withdraw(). Bisa digate ke pemegang .ai Agent ID.\ninterface IAgentRegistry {\n    function balanceOf(address a) external view returns (uint256);\n}\n\ncontract DannyNFT {\n    string public name;\n    string public symbol;\n    address public owner;\n    uint256 public totalSupply;\n    uint256 public maxSupply;\n    string public baseURI;\n\n    uint256 public constant FREE_COUNT = 1;\n    uint256 public constant MAX_PER_WALLET = 15;\n    uint256 public price = 0.000475 ether; // ~Rp6.000 per mint berbayar (BNB $697,08, $1 Rp18.118, 9 Nov 2026)\n    bool public agentGate = true;\n    IAgentRegistry public constant REGISTRY = IAgentRegistry(0x60B9262456dE011F7d15a54CdD8c48bAaa8B022F);\n\n    mapping(uint256 => address) private _owners;\n    mapping(address => uint256) private _balances;\n    mapping(address => uint256) public mintedBy;\n\n    event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\n\n    constructor(string memory _name, string memory _symbol, uint256 _maxSupply, string memory _baseURI, address _owner) {\n        name = _name;\n        symbol = _symbol;\n        maxSupply = _maxSupply;\n        baseURI = _baseURI;\n        owner = _owner; // explicit owner: bila deploy lewat factory, msg.sender = factory, bukan Danny\n    }\n\n    modifier onlyOwner() {\n        require(msg.sender == owner, \"not owner\");\n        _;\n    }\n\n    function balanceOf(address a) external view returns (uint256) {\n        return _balances[a];\n    }\n\n    function ownerOf(uint256 id) external view returns (address) {\n        address o = _owners[id];\n        require(o != address(0), \"no such token\");\n        return o;\n    }\n\n    function tokenURI(uint256 id) external view returns (string memory) {\n        require(_owners[id] != address(0), \"no such token\");\n        return string(abi.encodePacked(baseURI, _toString(id), \".json\"));\n    }\n\n    /// @notice Harga exact untuk mint `qty` kartu dari wallet `w`.\n    function priceOf(address w, uint256 qty) public view returns (uint256) {\n        uint256 have = mintedBy[w];\n        require(have + qty <= MAX_PER_WALLET, \"max 15/wallet\");\n        if (qty == 0) return 0;\n        uint256 freeLeft = have < FREE_COUNT ? FREE_COUNT - have : 0;\n        uint256 paid = qty > freeLeft ? qty - freeLeft : 0;\n        return paid * price;\n    }\n\n    function canMint(address w) public view returns (bool) {\n        if (!agentGate) return true;\n        return REGISTRY.balanceOf(w) > 0;\n    }\n\n    function mint(uint256 qty) external payable {\n        require(qty > 0, \"qty 0\");\n        require(canMint(msg.sender), \"need .ai Agent ID\");\n        require(msg.value == priceOf(msg.sender, qty), \"wrong value\");\n        require(totalSupply + qty <= maxSupply, \"sold out\");\n        for (uint256 i = 0; i < qty; i++) {\n            uint256 id = totalSupply + 1;\n            _owners[id] = msg.sender;\n            _balances[msg.sender] += 1;\n            totalSupply += 1;\n            emit Transfer(address(0), msg.sender, id);\n        }\n        mintedBy[msg.sender] += qty;\n    }\n\n    /// @notice Tarik semua BNB hasil mint ke wallet owner.\n    function withdraw() external onlyOwner {\n        payable(owner).transfer(address(this).balance);\n    }\n\n    function setPrice(uint256 _p) external onlyOwner {\n        price = _p;\n    }\n\n    function setAgentGate(bool _on) external onlyOwner {\n        agentGate = _on;\n    }\n\n    function setBaseURI(string calldata _u) external onlyOwner {\n        baseURI = _u;\n    }\n\n    function _toString(uint256 v) internal pure returns (string memory) {\n        if (v == 0) return \"0\";\n        uint256 len;\n        uint256 t = v;\n        while (t > 0) { len++; t /= 10; }\n        bytes memory b = new bytes(len);\n        while (v > 0) { len--; b[len] = bytes1(uint8(48 + (v % 10))); v /= 10; }\n        return string(b);\n    }\n}\n"}},"abi":[{"type":"constructor","inputs":[{"name":"_name","type":"string","internalType":"string"},{"name":"_symbol","type":"string","internalType":"string"},{"name":"_maxSupply","type":"uint256","internalType":"uint256"},{"name":"_baseURI","type":"string","internalType":"string"},{"name":"_owner","type":"address","internalType":"address"}],"stateMutability":"nonpayable"},{"name":"Transfer","type":"event","inputs":[{"name":"from","type":"address","indexed":true,"internalType":"address"},{"name":"to","type":"address","indexed":true,"internalType":"address"},{"name":"tokenId","type":"uint256","indexed":true,"internalType":"uint256"}],"anonymous":false},{"name":"FREE_COUNT","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"MAX_PER_WALLET","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"REGISTRY","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"contract IAgentRegistry"}],"stateMutability":"view"},{"name":"agentGate","type":"function","inputs":[],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"name":"balanceOf","type":"function","inputs":[{"name":"a","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"baseURI","type":"function","inputs":[],"outputs":[{"name":"","type":"string","internalType":"string"}],"stateMutability":"view"},{"name":"canMint","type":"function","inputs":[{"name":"w","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"name":"maxSupply","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"mint","type":"function","inputs":[{"name":"qty","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"payable"},{"name":"mintedBy","type":"function","inputs":[{"name":"","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"name","type":"function","inputs":[],"outputs":[{"name":"","type":"string","internalType":"string"}],"stateMutability":"view"},{"name":"owner","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"ownerOf","type":"function","inputs":[{"name":"id","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"price","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"priceOf","type":"function","inputs":[{"name":"w","type":"address","internalType":"address"},{"name":"qty","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"setAgentGate","type":"function","inputs":[{"name":"_on","type":"bool","internalType":"bool"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"setBaseURI","type":"function","inputs":[{"name":"_u","type":"string","internalType":"string"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"setPrice","type":"function","inputs":[{"name":"_p","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"symbol","type":"function","inputs":[],"outputs":[{"name":"","type":"string","internalType":"string"}],"stateMutability":"view"},{"name":"tokenURI","type":"function","inputs":[{"name":"id","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"string","internalType":"string"}],"stateMutability":"view"},{"name":"totalSupply","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"withdraw","type":"function","inputs":[],"outputs":[],"stateMutability":"nonpayable"}],"matchId":"58824215","creationMatch":"exact_match","runtimeMatch":"exact_match","verifiedAt":"2026-11-08T17:42:58Z","match":"exact_match","chainId":"56","address":"0xaa87b6B3eCDD3202A80d109A91e88783ffFb0BE6"}