// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "@thirdweb-dev/contracts/base/ERC1155Base.sol";
import "@thirdweb-dev/contracts/extension/SignatureMintERC1155.sol";
import "@thirdweb-dev/contracts/lib/CurrencyTransferLib.sol";
contract ERC1155SignatureMint is ERC1155Base, SignatureMintERC1155 {
constructor(
string memory _name,
string memory _symbol,
address _royaltyRecipient,
uint128 _royaltyBps
) ERC1155Base(_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 > 0, "Minting zero tokens.");
uint256 tokenIdToMint;
uint256 nextIdToMint = nextTokenIdToMint();
if (_req.tokenId == type(uint256).max) {
tokenIdToMint = nextIdToMint;
nextTokenIdToMint_ += 1;
} else {
require(_req.tokenId < nextIdToMint, "invalid id");
tokenIdToMint = _req.tokenId;
}
// Verify and process payload.
signer = _processRequest(_req, _signature);
address receiver = _req.to;
// Collect price
_collectPriceOnClaim(
_req.primarySaleRecipient,
_req.quantity,
_req.currency,
_req.pricePerToken
);
// Set royalties, if applicable.
if (_req.royaltyRecipient != address(0)) {
_setupRoyaltyInfoForToken(
tokenIdToMint,
_req.royaltyRecipient,
_req.royaltyBps
);
}
// Set URI
if (_req.tokenId == type(uint256).max) {
_setTokenURI(tokenIdToMint, _req.uri);
}
// Mint tokens.
_mint(receiver, tokenIdToMint, _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
);
}
}