// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "@thirdweb-dev/contracts/base/ERC721Base.sol";
import "@thirdweb-dev/contracts/extension/SignatureMintERC721.sol";
import "@thirdweb-dev/contracts/lib/CurrencyTransferLib.sol";
contract ERC721SignatureMint is ERC721Base, SignatureMintERC721 {
constructor(
address _defaultAdmin,
string memory _name,
string memory _symbol,
address _royaltyRecipient,
uint128 _royaltyBps
) ERC721Base(_defaultAdmin, _name, _symbol, _royaltyRecipient, _royaltyBps) {}
/// @dev Mints tokens according to the provided mint request.
function mintWithSignature(
MintRequest calldata _req,
bytes calldata _signature
) external payable virtual override returns (address signer) {
require(_req.quantity == 1, "quantity must be 1");
uint256 tokenIdToMint = nextTokenIdToMint();
// Verify and process payload.
signer = _processRequest(_req, _signature);
address receiver = _req.to;
// Collect price
_collectPriceOnClaim(
_req.primarySaleRecipient,
_req.quantity,
_req.currency,
_req.pricePerToken
);
// Mint tokens.
_setTokenURI(tokenIdToMint, _req.uri);
_safeMint(receiver, _req.quantity);
emit TokensMintedWithSignature(signer, receiver, tokenIdToMint, _req);
}
/// @dev Returns whether a given address is authorized to sign mint requests.
function _canSignMintRequest(address _signer)
internal
view
virtual
override
returns (bool)
{
return _signer == owner();
}
/// @dev Collects and distributes the primary sale value of tokens being claimed.
function _collectPriceOnClaim(
address _primarySaleRecipient,
uint256 _quantityToClaim,
address _currency,
uint256 _pricePerToken
) internal virtual {
if (_pricePerToken == 0) {
return;
}
uint256 totalPrice = (_quantityToClaim * _pricePerToken) / 1 ether;
require(totalPrice > 0, "quantity too low");
if (_currency == CurrencyTransferLib.NATIVE_TOKEN) {
require(msg.value == totalPrice, "Must send total price.");
}
address saleRecipient = _primarySaleRecipient;
CurrencyTransferLib.transferCurrency(
_currency,
msg.sender,
saleRecipient,
totalPrice
);
}
}