If want to customize what your contract does, Paper provides a set of interfces below that is required to ensure that Paper can support it out of the box. Please make sure the types and function names (case sensitive!) are identical to the interfaces below.

The following interface will work with both ERC1155 and ERC721. You should implement the interface that makes most sense for you depending on whether you need tokenId as a parameter.

NOTE: The types of the parameters have to be the same as those outlined below. Using types like uint8/uint16 instead of uint256 will result in an error

Paper Compatible Interface with no tokenId

contract IPaperCompatibleInterface {
    /// @custom:Required  
    ///
    /// @notice Gets any potential reason that the _userWallet is not able to claim _quantity of NFT.
    ///
    /// @dev You do not need to check if the user has enough balance in their wallet
    /// @dev You also do not need to check if there is enough quantity left to be claimed
    ///
    /// @param _userWallet The address of the user's wallet
    /// @param _quantity The number of NFTs to be purchased
    /// @return string containing the reason that they _userWallet cannot claim _quantity of the NFT if any. Empty string if the _userWallet can claim _quantity of the NFT.
    function getClaimIneligibilityReason(address _userWallet, uint256 _quantity) public view returns (string memory);

    /// @custom:Required
    ///
    /// @notice Checks the total amount of NFTs left to be claimed
    ///
    /// @return uint256 The number of NFTs left to be claimed
    function unclaimedSupply() public view returns (uint256);

    /// @custom:Required
    ///
    /// @notice Checks the price of the NFT
    ///
    /// @return uint256 The price of a single NFT in Wei
    function price() public view returns (uint256);

    /// @custom:Required
    /// 
    /// @notice Used by paper to purchase and deliver the NFT to the user.
    ///
    /// @dev This function should emit event Transfer(address indexed _from, address indexed _to, uint256 indexed _tokenId)
    ///
    /// @param _userWallet The address of the user's wallet
    /// @param _quantity The number of NFTs to be purchased
    function claimTo(address _userWallet, uint256 _quantity) public payable;

    /// @dev should be emitted by the claimTo method
    event Transfer(address indexed _from, address indexed _to, uint256 indexed _tokenId);
    
    /// @custom:Optional
    ///
    /// @notice Gets the address of the ERC20 contract that the NFT is priced in.
    ///
    /// @dev You do not need this if you are pricing in the chains native coin. E.g. Eth of Ethereum
    /// @dev You need this if you are pricing in some erc20 token. Some examples:
    /// - WETH on Polygon: 0x7ceB23fD6bC0adD59E62ac25578270cFf1b9f619
    /// - USDC on Polygon: 0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174
    /// - USDC on Ethereum: 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48
    ///
    /// @return string The address of the ERC20 contract that the NFT is priced in.
    function currency() public view returns (string memory);
}

Paper Compatible Interface wtih tokenId

contract IPaperCompatibleInterface {
    /// @custom:Required  
    ///
    /// @notice Gets any potential reason that the _userWallet is not able to claim _quantity of NFT.
    ///
    /// @dev You do not need to check if the user has enough balance in their wallet
    /// @dev You also do not need to check if there is enough quantity left to be claimed
    ///
    /// @param _userWallet The address of the user's wallet
    /// @param _quantity The number of NFTs to be purchased
    /// @param _tokenId The id of the NFT that the ineligibility reason corrsponds too.
    ///
    /// @return string containing the reason that they _userWallet cannot claim _quantity of the NFT if any. Empty string if the _userWallet can claim _quantity of the NFT.
    function getClaimIneligibilityReason(address _userWallet, uint256 _quantity, uint256 _tokenId) public view returns (string memory);

    /// @custom:Required
    ///
    /// @notice Checks the total amount of NFTs left to be claimed
    ///
    ///
    /// @param _tokenId The id of the NFT that the unclaimed supply corrsponds too.
    ///    
    /// @return uint256 The number of NFTs left to be claimed
    function unclaimedSupply(uint256 _tokenId) public view returns (uint256);
    
    /// @custom:Required
    ///
    /// @notice Checks the price of the NFT
    ///
    /// @param _tokenId The id of the NFT which the pricing corresponds too.
    ///
    /// @return uint256 The price of a single NFT in Wei
    function price(uint256 _tokenId) public view returns (uint256);

    /// @custom:Required
    /// 
    /// @notice Used by paper to purchase and deliver the NFT to the user.
    ///
    /// @dev This function should emit event Transfer(address indexed _from, address indexed _to, uint256 indexed _tokenId)
    ///
    /// @param _userWallet The address of the user's wallet
    /// @param _quantity The number of NFTs to be purchased
    /// @param _tokenId The id of the NFT to be purchased
    function claimTo(address _userWallet, uint256 _quantity, uint256 _tokenId) public payable;

    /// @custom:Optional
    ///
    /// @notice Gets the address of the ERC20 contract that the NFT is priced in.
    ///
    /// @dev You do not need this if you are pricing in the chains native coin. E.g. Eth of Ethereum
    /// @dev You need this if you are pricing in some erc20 token. Some examples:
    /// - WETH on Polygon: 0x7ceB23fD6bC0adD59E62ac25578270cFf1b9f619
    /// - USDC on Polygon: 0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174
    /// - USDC on Ethereum: 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48
    ///
    /// @param _tokenId The id of the NFT which the erc20 address corresponds too.
    ///
    /// @return string The address of the ERC20 contract that the NFT is priced in.
    function currency(uint256 _tokenId) public view returns (string memory);
}

Paper only mint function (Coming Soon)

In some scenarios, you want only us to be able to call the mint function. One common scenario is when you want users to be able to native mint base on various whitelist settings while still using Paper's credit card or cross chain crypto flow in conjunction with one-time purchase links after verifying their eligibility on your website.

In this case, you'd create an additional method paperMint that is used in conjuction with our PaperVerification contracts that allows you to whitelist and easily restrict the function to only be called by us.

Refer to the package documentation for the function stub and more.

You can grab the address to whitelist from the [`Developers` Section](https://paper.xyz/dashboard/developers) in your dashboardYou can grab the address to whitelist from the [`Developers` Section](https://paper.xyz/dashboard/developers) in your dashboard

You can grab the address to whitelist from the Developers Section in your dashboard

Once you deploy your Paper compatible smart contract, you are ready to sell it! You can do so by creating a checkout.