📘

The mintMethod is only required when using a custom smart contract (contracts registered with the CUSTOM_CONTRACT type)

If your smart contract is from Thirdweb, Auction House, or Candy Machine, then you do not need to provide the mintMethod as Paper already knows what the method is and works out of the box.

Upon a successful payment by the customer, Paper will call the mintMethod you provide along with any arguments you specify, and the necessary cryptocurrency value based on the price and currency that you set. There's a few things to keep in mind:

Your mint method should not rely on msg.sender.
Your contract will be called by Paper's internal wallets instead of the buyer's wallet. This means contracts with an on-chain allowlist may require a different mint method that is restricted only to Paper.

Your mint method should accept the buyer wallet address (required) and quantity (optional). An example mint method looks like:

Template variables

We have a couple of template variables that allow you to pass special values to your smart contract functions.

VariableDescription
$WALLETThe user-selected destination wallet address for the purchase.
$QUANTITYThe number of tokens the user selected to purchase.

Example JSON for specifying mintMethod

Here's an example smart contract method to mint an NFT:

function mint(address toAddress, uint256 quantity) public payable

Here's how the mintMethod should look:

{
  "name": "mint",
  "args": {
    "toAddress": "$WALLET",
    "quantity": "$QUANTITY"
  },
  "payment": {
    "value": "0.1 * $QUANTITY",
    "currency": "ETH"
  }
}

Use this format when passing in a mintMethod to create either a Checkout Link Intent or Checkout SDK Intent

Make sure the value field inside payment is set to the unit value multiplied by $QUANTITY, as in the example above. The value amount is specified in real readable units, as opposed to wei. For example, 1 * $QUANTITY means 1 ETH and not 1 wei ETH.

For a free NFT on Polygon, set the payment to "payment": { value: "0 * $QUANTITY", currency: "MATIC" }, or whatever the native coin for the chain is.

Example Smart Contract Implementation


    function mintTo(address recipient, uint256 quantity) public payable returns (uint256) {
        uint256 tokenId = currentTokenId.current();
        require(tokenId + quantity <= TOTAL_SUPPLY, "Max supply reached");
        require(msg.value == MINT_PRICE, "Transaction value did not equal the mint price");

        currentTokenId.increment();
        uint256 newItemId = currentTokenId.current();
        _safeMint(recipient, newItemId);
        return newItemId;
    }

Typescript Type

mintMethod is typed as a WriteMethodCallType.

export type WriteMethodCallType =
  | ReadMethodCallType & {
      payment: {
        currency: 'MATIC' | 'ETH' | 'USDC' | 'SOL' | 'AVAX' | 'USDC.e';
        value: string;
      };
      callOptions?: { gasOptions?: 'low' | 'medium' | 'high' };
    };

export type ReadMethodCallType = {
  name: string;
  args?: ArgumentMapType;
};

type ArgumentMapType = {
  [key: string]:
    | string
    | null
    | number
    | boolean
    | Array<ArgumentMapType>
    | ArgumentMapType;
};

Where do I provide the mintMethod?

Checkout SDK intents and Checkout Links intents

Pass it along in the API when creating the intent for either the Checkout Link Intent or Checkout SDK Intent

Shareable Checkout Links

📘

See our Checkout Link builder for an example of how the mintMethod query parameter is sent.

The mintMethod object (as defined above) should be provided as a query parameter that is JSON-stringified and base64-encoded.

Here's a simple Typescript implementation:

const mintMethod = {
  name: "mint",
  args: {
    toAddress: "$WALLET",
    quantity: "$QUANTITY"
  },
  payment: {
    value: "0.1 * $QUANTITY",
    currency: "ETH"
  }
}
const mintMethodQuery = btoa(JSON.stringify(mintMethod))
const checkoutUrl = `https://paper.xyz/checkout/${checkoutId}?mintMethod=${mintMethodQuery}`