diff --git a/packages/contracts/evm-contracts/contracts/token/IInverseAppProjectedNft.sol b/packages/contracts/evm-contracts/contracts/token/IInverseAppProjectedNft.sol index 1382ae741..9af89c24a 100644 --- a/packages/contracts/evm-contracts/contracts/token/IInverseAppProjectedNft.sol +++ b/packages/contracts/evm-contracts/contracts/token/IInverseAppProjectedNft.sol @@ -13,5 +13,17 @@ interface IInverseAppProjectedNft is IInverseProjectedNft { /// Increases the `totalSupply` and `currentTokenId`. /// Reverts if `_to` is a zero address or if it refers to smart contract but does not implement IERC721Receiver-onERC721Received. /// Emits the `Minted` event. + /// @param _to where to send the NFT to + /// @param _verificationData any additional data to verify the validity of the mint + function mint(address _to, bytes memory _verificationData) external returns (uint256); + + /// @dev This works identically to the other function with an extra data parameter, + /// except this function just sets data to "". function mint(address _to) external returns (uint256); + + /// @notice Returns the last nonce used (or 0 if the user has never minted) + /// @dev Useful if you need to either needs to + /// 1. Check if the nonce matches the expected value, or if more NFTs need to be minted + /// 2. Use a nonce algorithm where the next nonce depends on the current nonce + function currentNonce(address seller) external view returns (uint256); } diff --git a/packages/contracts/evm-contracts/contracts/token/InverseAppProjectedNft.sol b/packages/contracts/evm-contracts/contracts/token/InverseAppProjectedNft.sol index cb7f9085f..4e68cdd21 100644 --- a/packages/contracts/evm-contracts/contracts/token/InverseAppProjectedNft.sol +++ b/packages/contracts/evm-contracts/contracts/token/InverseAppProjectedNft.sol @@ -60,12 +60,26 @@ contract InverseAppProjectedNft is IInverseAppProjectedNft, ERC721, Ownable { super.supportsInterface(interfaceId); } + function currentNonce(address user) external view returns (uint256) { + return mintCount[user]; + } + + function validateMint(address, bytes memory) internal virtual returns (bool) { + // Base contract allows any mint + // Replace this with any custom verification logic + return true; + } + /// @dev Mints a new token to address `_to`. /// Increases the `totalSupply` and `currentTokenId`. /// Reverts if `_to` is a zero address or if it refers to smart contract but does not implement IERC721Receiver-onERC721Received. /// Emits the `Minted` event. - function mint(address _to) public virtual returns (uint256) { + function mint(address _to, bytes calldata _verificationData) public virtual returns (uint256) { require(_to != address(0), "InverseAppProjectedNft: zero receiver address"); + require( + validateMint(_to, _verificationData), + "InverseAppProjectedNft: invalid verification data" + ); uint256 tokenId = currentTokenId; _safeMint(_to, tokenId); @@ -80,6 +94,10 @@ contract InverseAppProjectedNft is IInverseAppProjectedNft, ERC721, Ownable { return tokenId; } + function mint(address _to) external returns (uint256) { + return this.mint(_to, ""); + } + /// @dev Burns token of ID `_tokenId`. Callable only by the owner of the specified token. /// Reverts if `_tokenId` does not exist. function burn(uint256 _tokenId) public virtual onlyTokenOwner(_tokenId) {