Skip to main content

Signature Minting ERC1155

import "@thirdweb-dev/contracts/extension/SignatureMintERC1155.sol";

The SignatureMintERC1155 smart contract is an extension meant for distributing ERC721 tokens.

The 'signature minting' mechanism in the SignatureMintERC1155 extension uses EIP-712, and is a way for a contract admin to authorize an external party's request to mint tokens on the admin's contract. At a high level, this means you can authorize some external party to mint tokens on your contract, and specify what exactly will be minted by that external party.

Availability in base contracts

The SignatureMintERC1155 extension is already available in the following base contracts:

Unlocked Features

Once deployed, you can use the features made available by these contracts on the SDK and dashboard:

Implementing the Contract

This section is meant for advanced users who want to write functionality from scratch. If that's not you, use one of these base contracts that already implement signature minting functionlity for you!

The SignatureMintERC1155 extension is an abstract contract, and expects you to implement the following functions by yourself:

NameTypeParametersReturnsDescription
_canSignMintRequestinternal view virtualn/aboolRuns on every attempt to mint tokens with signature on the contract. Returns whether the signer is authorized to issue a signature for minting.
mintWithSignatureexternal payablen/aaddressMints tokens according to the provided mint request.
// 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
);
}
}

Full API reference

verify

struct MintRequest {
address to;
address royaltyRecipient;
uint256 royaltyBps;
address primarySaleRecipient;
uint256 tokenId;
string uri;
uint256 quantity;
uint256 pricePerToken;
address currency;
uint128 validityStartTimestamp;
uint128 validityEndTimestamp;
bytes32 uid;
}

function verify(MintRequest calldata req, bytes calldata signature)
public
view
returns (bool success, address signer)
  • Verifies that a mint request is valid and signed by an authorized wallet.
  • Parameter req: The mint request.
    • to: The recipient of the tokens to mint.
    • royaltyRecipient: The recipient of the minted token's secondary sales royalties.
    • royaltyBps: The percentage of the minted token's secondary sales to take as royalties.
    • primarySaleRecipient: The recipient of the minted token's primary sales proceeds.
    • tokenId: The tokenId of the NFT to mint.
    • uri: The metadata URI of the token to mint.
    • quantity: The quantity of tokens to mint.
    • pricePerToken: The price to pay per quantity of tokens minted.
    • currency: The currency in which to pay the price per token minted.
    • validityStartTimestamp: The unix timestamp after which the payload is valid.
    • validityEndTimestamp: The unix timestamp at which the payload expires.
    • uid: A unique identifier for the payload.
  • Parameter signature: The signature produced by an authorized wallet signing the mint request.

mintWithSignature

struct MintRequest {
address to;
address royaltyRecipient;
uint256 royaltyBps;
address primarySaleRecipient;
uint256 tokenId;
string uri;
uint256 quantity;
uint256 pricePerToken;
address currency;
uint128 validityStartTimestamp;
uint128 validityEndTimestamp;
bytes32 uid;
}

function mintWithSignature(MintRequest calldata req, bytes calldata signature)
external
payable
returns (address signer)
  • Mints tokens according to the provided mint request.
  • Parameter req: The mint request.
    • to: The recipient of the tokens to mint.
    • royaltyRecipient: The recipient of the minted token's secondary sales royalties.
    • royaltyBps: The percentage of the minted token's secondary sales to take as royalties.
    • primarySaleRecipient: The recipient of the minted token's primary sales proceeds.
    • tokenId: The tokenId of the NFT to mint.
    • uri: The metadata URI of the token to mint.
    • quantity: The quantity of tokens to mint.
    • pricePerToken: The price to pay per quantity of tokens minted.
    • currency: The currency in which to pay the price per token minted.
    • validityStartTimestamp: The unix timestamp after which the payload is valid.
    • validityEndTimestamp: The unix timestamp at which the payload expires.
    • uid: A unique identifier for the payload.
  • Parameter signature: The signature produced by an authorized wallet signing the mint request.

_processRequest

struct MintRequest {
address to;
address royaltyRecipient;
uint256 royaltyBps;
address primarySaleRecipient;
uint256 tokenId;
string uri;
uint256 quantity;
uint256 pricePerToken;
address currency;
uint128 validityStartTimestamp;
uint128 validityEndTimestamp;
bytes32 uid;
}

function _processRequest(MintRequest calldata req, bytes calldata signature)
internal
returns (address signer)
  • Verifies a mint request and marks the request and signature as used.
  • Parameter req: The mint request.
    • to: The recipient of the tokens to mint.
    • royaltyRecipient: The recipient of the minted token's secondary sales royalties.
    • royaltyBps: The percentage of the minted token's secondary sales to take as royalties.
    • primarySaleRecipient: The recipient of the minted token's primary sales proceeds.
    • tokenId: The tokenId of the NFT to mint.
    • uri: The metadata URI of the token to mint.
    • quantity: The quantity of tokens to mint.
    • pricePerToken: The price to pay per quantity of tokens minted.
    • currency: The currency in which to pay the price per token minted.
    • validityStartTimestamp: The unix timestamp after which the payload is valid.
    • validityEndTimestamp: The unix timestamp at which the payload expires.
    • uid: A unique identifier for the payload.
  • Parameter signature: The signature produced by an authorized wallet signing the mint request.

_recoverAddress

struct MintRequest {
address to;
address royaltyRecipient;
uint256 royaltyBps;
address primarySaleRecipient;
uint256 tokenId;
string uri;
uint256 quantity;
uint256 pricePerToken;
address currency;
uint128 validityStartTimestamp;
uint128 validityEndTimestamp;
bytes32 uid;
}

function _recoverAddress(MintRequest calldata req, bytes calldata signature)
internal
view
returns (address signer)
  • Returns the address of the signer of the mint request.
  • Parameter req: The mint request.
    • to: The recipient of the tokens to mint.
    • royaltyRecipient: The recipient of the minted token's secondary sales royalties.
    • royaltyBps: The percentage of the minted token's secondary sales to take as royalties.
    • primarySaleRecipient: The recipient of the minted token's primary sales proceeds.
    • tokenId: The tokenId of the NFT to mint.
    • uri: The metadata URI of the token to mint.
    • quantity: The quantity of tokens to mint.
    • pricePerToken: The price to pay per quantity of tokens minted.
    • currency: The currency in which to pay the price per token minted.
    • validityStartTimestamp: The unix timestamp after which the payload is valid.
    • validityEndTimestamp: The unix timestamp at which the payload expires.
    • uid: A unique identifier for the payload.
  • Parameter signature: The signature produced by an authorized wallet signing the mint request.

_canSignMintRequest

function _canSignMintRequest(address signer) internal view virtual returns (bool);
  • Returns whether a given address is authorized to sign mint requests.
  • Parameter signer: the address that the contract checks is eligible to sign mint requests, or not.