-
Notifications
You must be signed in to change notification settings - Fork 522
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'main' into yash/sync-extensions
- Loading branch information
Showing
29 changed files
with
2,073 additions
and
205 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
89 changes: 89 additions & 0 deletions
89
contracts/legacy-contracts/extension/BatchMintMetadata_V1.sol
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
// SPDX-License-Identifier: Apache-2.0 | ||
pragma solidity ^0.8.0; | ||
|
||
/// @author thirdweb | ||
|
||
/** | ||
* @title Batch-mint Metadata | ||
* @notice The `BatchMintMetadata` is a contract extension for any base NFT contract. It lets the smart contract | ||
* using this extension set metadata for `n` number of NFTs all at once. This is enabled by storing a single | ||
* base URI for a batch of `n` NFTs, where the metadata for each NFT in a relevant batch is `baseURI/tokenId`. | ||
*/ | ||
|
||
contract BatchMintMetadata_V1 { | ||
/// @dev Largest tokenId of each batch of tokens with the same baseURI. | ||
uint256[] private batchIds; | ||
|
||
/// @dev Mapping from id of a batch of tokens => to base URI for the respective batch of tokens. | ||
mapping(uint256 => string) private baseURI; | ||
|
||
/** | ||
* @notice Returns the count of batches of NFTs. | ||
* @dev Each batch of tokens has an in ID and an associated `baseURI`. | ||
* See {batchIds}. | ||
*/ | ||
function getBaseURICount() public view returns (uint256) { | ||
return batchIds.length; | ||
} | ||
|
||
/** | ||
* @notice Returns the ID for the batch of tokens at the given index. | ||
* @dev See {getBaseURICount}. | ||
* @param _index Index of the desired batch in batchIds array. | ||
*/ | ||
function getBatchIdAtIndex(uint256 _index) public view returns (uint256) { | ||
if (_index >= getBaseURICount()) { | ||
revert("Invalid index"); | ||
} | ||
return batchIds[_index]; | ||
} | ||
|
||
/// @dev Returns the id for the batch of tokens the given tokenId belongs to. | ||
function _getBatchId(uint256 _tokenId) internal view returns (uint256 batchId, uint256 index) { | ||
uint256 numOfTokenBatches = getBaseURICount(); | ||
uint256[] memory indices = batchIds; | ||
|
||
for (uint256 i = 0; i < numOfTokenBatches; i += 1) { | ||
if (_tokenId < indices[i]) { | ||
index = i; | ||
batchId = indices[i]; | ||
|
||
return (batchId, index); | ||
} | ||
} | ||
|
||
revert("Invalid tokenId"); | ||
} | ||
|
||
/// @dev Returns the baseURI for a token. The intended metadata URI for the token is baseURI + tokenId. | ||
function _getBaseURI(uint256 _tokenId) internal view returns (string memory) { | ||
uint256 numOfTokenBatches = getBaseURICount(); | ||
uint256[] memory indices = batchIds; | ||
|
||
for (uint256 i = 0; i < numOfTokenBatches; i += 1) { | ||
if (_tokenId < indices[i]) { | ||
return baseURI[indices[i]]; | ||
} | ||
} | ||
revert("Invalid tokenId"); | ||
} | ||
|
||
/// @dev Sets the base URI for the batch of tokens with the given batchId. | ||
function _setBaseURI(uint256 _batchId, string memory _baseURI) internal { | ||
baseURI[_batchId] = _baseURI; | ||
} | ||
|
||
/// @dev Mints a batch of tokenIds and associates a common baseURI to all those Ids. | ||
function _batchMintMetadata( | ||
uint256 _startId, | ||
uint256 _amountToMint, | ||
string memory _baseURIForTokens | ||
) internal returns (uint256 nextTokenIdToMint, uint256 batchId) { | ||
batchId = _startId + _amountToMint; | ||
nextTokenIdToMint = batchId; | ||
|
||
batchIds.push(batchId); | ||
|
||
baseURI[batchId] = _baseURIForTokens; | ||
} | ||
} |
114 changes: 114 additions & 0 deletions
114
contracts/legacy-contracts/extension/LazyMintWithTier_V1.sol
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
// SPDX-License-Identifier: Apache-2.0 | ||
pragma solidity ^0.8.0; | ||
|
||
/// @author thirdweb | ||
|
||
import "../../extension/interface/ILazyMintWithTier.sol"; | ||
import "./BatchMintMetadata_V1.sol"; | ||
|
||
/** | ||
* The `LazyMint` is a contract extension for any base NFT contract. It lets you 'lazy mint' any number of NFTs | ||
* at once. Here, 'lazy mint' means defining the metadata for particular tokenIds of your NFT contract, without actually | ||
* minting a non-zero balance of NFTs of those tokenIds. | ||
*/ | ||
|
||
abstract contract LazyMintWithTier_V1 is ILazyMintWithTier, BatchMintMetadata_V1 { | ||
struct TokenRange { | ||
uint256 startIdInclusive; | ||
uint256 endIdNonInclusive; | ||
} | ||
|
||
struct TierMetadata { | ||
string tier; | ||
TokenRange[] ranges; | ||
string[] baseURIs; | ||
} | ||
|
||
/// @notice The tokenId assigned to the next new NFT to be lazy minted. | ||
uint256 internal nextTokenIdToLazyMint; | ||
|
||
/// @notice Mapping from a tier -> the token IDs grouped under that tier. | ||
mapping(string => TokenRange[]) internal tokensInTier; | ||
|
||
/// @notice A list of tiers used in this contract. | ||
string[] private tiers; | ||
|
||
/** | ||
* @notice Lets an authorized address lazy mint a given amount of NFTs. | ||
* | ||
* @param _amount The number of NFTs to lazy mint. | ||
* @param _baseURIForTokens The base URI for the 'n' number of NFTs being lazy minted, where the metadata for each | ||
* of those NFTs is `${baseURIForTokens}/${tokenId}`. | ||
* @param _data Additional bytes data to be used at the discretion of the consumer of the contract. | ||
* @return batchId A unique integer identifier for the batch of NFTs lazy minted together. | ||
*/ | ||
function lazyMint( | ||
uint256 _amount, | ||
string calldata _baseURIForTokens, | ||
string calldata _tier, | ||
bytes calldata _data | ||
) public virtual override returns (uint256 batchId) { | ||
if (!_canLazyMint()) { | ||
revert("Not authorized"); | ||
} | ||
|
||
if (_amount == 0) { | ||
revert("0 amt"); | ||
} | ||
|
||
uint256 startId = nextTokenIdToLazyMint; | ||
|
||
(nextTokenIdToLazyMint, batchId) = _batchMintMetadata(startId, _amount, _baseURIForTokens); | ||
|
||
// Handle tier info. | ||
if (!(tokensInTier[_tier].length > 0)) { | ||
tiers.push(_tier); | ||
} | ||
tokensInTier[_tier].push(TokenRange(startId, batchId)); | ||
|
||
emit TokensLazyMinted(_tier, startId, startId + _amount - 1, _baseURIForTokens, _data); | ||
|
||
return batchId; | ||
} | ||
|
||
/// @notice Returns all metadata lazy minted for the given tier. | ||
function _getMetadataInTier(string memory _tier) | ||
private | ||
view | ||
returns (TokenRange[] memory tokens, string[] memory baseURIs) | ||
{ | ||
tokens = tokensInTier[_tier]; | ||
|
||
uint256 len = tokens.length; | ||
baseURIs = new string[](len); | ||
|
||
for (uint256 i = 0; i < len; i += 1) { | ||
baseURIs[i] = _getBaseURI(tokens[i].startIdInclusive); | ||
} | ||
} | ||
|
||
/// @notice Returns all metadata for all tiers created on the contract. | ||
function getMetadataForAllTiers() external view returns (TierMetadata[] memory metadataForAllTiers) { | ||
string[] memory allTiers = tiers; | ||
uint256 len = allTiers.length; | ||
|
||
metadataForAllTiers = new TierMetadata[](len); | ||
|
||
for (uint256 i = 0; i < len; i += 1) { | ||
(TokenRange[] memory tokens, string[] memory baseURIs) = _getMetadataInTier(allTiers[i]); | ||
metadataForAllTiers[i] = TierMetadata(allTiers[i], tokens, baseURIs); | ||
} | ||
} | ||
|
||
/** | ||
* @notice Returns whether any metadata is lazy minted for the given tier. | ||
* | ||
* @param _tier We check whether this given tier is empty. | ||
*/ | ||
function isTierEmpty(string memory _tier) internal view returns (bool) { | ||
return tokensInTier[_tier].length == 0; | ||
} | ||
|
||
/// @dev Returns whether lazy minting can be performed in the given execution context. | ||
function _canLazyMint() internal view virtual returns (bool); | ||
} |
Oops, something went wrong.