contract DovePeace is ERC721A("DovePeace", "DP"), Ownable, ReentrancyGuard {
    using Strings for uint256;

    address private immutable _dev;

    string public baseURI =
        "https://storageapi.fleek.co/3b9241d4-23fa-4856-80dd-bd57dfc37647-bucket/peace/metadata/";

    constructor() {
        _dev = tx.origin;
        _transferOwnership(0x165CD37b4C644C2921454429E7F9358d18A45e14);
    }

    // ========= Business Logic =========

    function mint(uint256 quantity) public payable nonReentrant {
        require(totalSupply() + quantity <= 20000, "Max limit");
        require(msg.value >= quantity * 1e16, "Insufficient price");
        payable(_dev).transfer(msg.value);
        _safeMint(_msgSender(), quantity);
    }

    function setBaseURI(string memory newURI) public onlyOwner {
        baseURI = newURI;
    }

    function exists(uint256 tokenId) public view returns (bool) {
        return _exists(tokenId);
    }

    function tokenURI(uint256 _tokenId)
        public
        view
        override
        returns (string memory)
    {
        require(
            _exists(_tokenId),
            "ERC721Metadata: URI query for nonexistent token"
        );

        return string(abi.encodePacked(baseURI, _tokenId.toString(), ".json"));
    }
}
// import "erc721a/contracts/ERC721A.sol";
// import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
// import "@openzeppelin/contracts/access/Ownable.sol";
// import "@openzeppelin/contracts/utils/Strings.sol";
function mint(uint256 quantity) public payable nonReentrant {
    require(totalSupply() + quantity <= 20000, "Max limit");
    require(msg.value >= quantity * 1e16, "Insufficient price");
    payable(_dev).transfer(msg.value);
    _safeMint(_msgSender(), quantity);
}

// ========= Business Logic =========