I am trying to lazy mint NFTs with a voucher. I am mostly using the codes from this GitHub repo: https://github.com/ipfs-shipyard/nft-school-examples/tree/main/lazy-minting . I have decided to add two new parameters (a uint256 parameter royaltyAmount and an address royaltyReceiver) inside the NFTVoucher (in LazyMinter class). I also described new parameters inside the smart contract's _hash function. After adding this I started receiving the wrong address (a completely arbitrary address) from the smart contract's _verify function. Can someone help me?

Below is how I added new parameters to the createVoucher function:

   * Creates a new NFTVoucher object and signs it using this LazyMinter's signing key.
   * @param {ethers.BigNumber | number} tokenId the id of the un-minted NFT
   * @param {string} uri the metadata URI to associate with this NFT
   * @param {ethers.utils.getAddress | address} royaltyReceiver the address of which the royalty fee will be sent
   * @param {ethers.BigNumber | number} royaltyAmount the percentage of royalty fee
   * @param {ethers.BigNumber | number} minPrice the minimum price (in wei) that the creator will accept to redeem this NFT. defaults to zero
   * @returns {NFTVoucher}
  async createVoucher(tokenId, uri, royaltyReceiver, royaltyAmount, minPrice = 0) {
    const voucher = { tokenId, minPrice, uri, royaltyReceiver, royaltyAmount}
    const domain = await this._signingDomain()
    const types = {
      NFTVoucher: [
        {name: "tokenId", type: "uint256"},
        {name: "minPrice", type: "uint256"},
        {name: "uri", type: "string"},
        {name: "royaltyReceiver", type: "address"},
        {name: "royaltyAmount", type: "uint256"}

and in my smart contract, I changed the _hash like this:

// @notice Returns a hash of the given NFTVoucher, prepared using EIP712 typed data hashing rules.
  /// @param voucher An NFTVoucher to hash.
  function _hash(NFTVoucher calldata voucher) internal view returns (bytes32) {
    return _hashTypedDataV4(keccak256(abi.encode(
      keccak256("NFTVoucher(uint256 tokenId,uint256 minPrice,string uri, address royaltyReceiver, uint256 royaltyAmount)"),

I also changed the NFTVoucher struct like this:

/// @notice Represents an un-minted NFT, which has not yet been recorded into the blockchain. A signed voucher can be redeemed for a real NFT using the redeem function.
  struct NFTVoucher {
    /// @notice The id of the token to be redeemed. Must be unique - if another token with this ID already exists, the redeem function will revert.
    uint256 tokenId;

    /// @notice The minimum price (in wei) that the NFT creator is willing to accept for the initial sale of this NFT.
    uint256 minPrice;

    /// @notice The metadata URI to associate with this token.
    string uri;

    /// @notice The address of which the royalty fee will be sent.
    address royaltyReceiver;

    /// @notice The percentage of royalty fee
    uint256 royaltyAmount;

    /// @notice the EIP-712 signature of all other fields in the NFTVoucher struct. For a voucher to be valid, it must be signed by an account with the MINTER_ROLE.
    bytes signature;

1 Answer 1


So the problem was my createVoucher was returning the NFTVoucher in a different order than how I defined the NFTVoucher struct in my smart contract.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.