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)"),
voucher.tokenId,
voucher.minPrice,
keccak256(bytes(voucher.uri)),
voucher.royaltyReceiver,
voucher.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;
}