Skip to content

Commit

Permalink
Merge pull request #25 from thepeanutgalleryandco/v1-6-0
Browse files Browse the repository at this point in the history
V1 6 0
  • Loading branch information
thepeanutgalleryandco committed Feb 27, 2022
2 parents 83c1925 + 6e3cdb6 commit bd8792b
Show file tree
Hide file tree
Showing 15 changed files with 578 additions and 58 deletions.
50 changes: 38 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,11 +70,12 @@ If you would like to support my NFT collection, please take a look at the below.
- [10. Uploading Files (Images and Metadata)](#10-uploading-files-images-and-metadata)
- [a. Pinata Or Similar Service](#a-pinata-or-similar-service)
- [b. NFTPort](#b-nftport)
- [11. ERC1155 Batch IPFS Metas Migration](#11-erc1155-batch-ipfs-metas-migration)
- [12. Minting NFTs](#12-minting-nfts)
- [13. Checking NFT Mint Files For Issues](#13-checking-nft-mint-files-for-issues)
- [14. Re-Mint Failed NFTs](#14-re-mint-failed-nfts)
- [15. Check Your Work On The Marketplace](#15-check-your-work-on-the-marketplace)
- [11. Create Wallet Edition Combo](#11-create-wallet-edition-combo)
- [12. ERC1155 Batch IPFS Metas Migration](#12-erc1155-batch-ipfs-metas-migration)
- [13. Minting NFTs](#13-minting-nfts)
- [14. Checking NFT Mint Files For Issues](#14-checking-nft-mint-files-for-issues)
- [15. Re-Mint Failed NFTs](#15-re-mint-failed-nfts)
- [16. Check Your Work On The Marketplace](#16-check-your-work-on-the-marketplace)


## Commands
Expand All @@ -91,6 +92,7 @@ If you would like to support my NFT collection, please take a look at the below.
- [Batch_Ipfs_Metas_Migration](#batch_ipfs_metas_migration)
- [Check_Mints](#check_mints)
- [Check_Mints_Batch](#check_mints_batch)
- [Create_Wallet_Edition_Combo Command](#create_wallet_edition_combo-command)
- [Update_Image_Info Command](#update_image_info-command)
- [Update_Json_To_Generic_Meta Command](#update_json_to_generic_meta-command)
- [Update_Metadata_Info Command](#update_metadata_info-command)
Expand All @@ -103,6 +105,7 @@ If you would like to support my NFT collection, please take a look at the below.
- [Mint Command](#mint-command)
- [Remint Command](#remint-command)
- [Remint_Batch Command](#remint_batch-command)
- [Reveal Command](#reveal-command)
- [UploadFiles Command](#uploadfiles-command)
- [UploadMetas Command](#uploadmetas-command)

Expand Down Expand Up @@ -191,11 +194,19 @@ If you would like to support my NFT collection, please take a look at the below.

### Added metadata exclusions functionality
Users have new metadata exclusion configuration options
- Maximum Repeatability - Set the maximum number of times that a layer be generated per layer configuration set. This is not on a layer item level, but instead of a layer level.
- Maximum Repeatability - Set the maximum number of times that a layer be generated per layer configuration set. This can now be set at a global level, layer level and layer item level.
- Incompatible Traits - Set the combination of traits that may not be generated together to remove / enforce certain combinations.

Please see the [Layer Configuration](./README.md#b-update-your-layer-configurations) section.

### Reveal Script
Users have a new Reveal script that can be used to reveal NFTs that do not belong to their wallet address anymore.
This script runs every X number of seconds, that can be set on the salesInterval field in the account_details.js file. The default is 900000 (15 minutes).
This script can be run manually and then stopped after running or it can be deployed to a server where it can run on the schedule of every X number of seconds.

### Minting Against Wallet Address List
Users have a new option of minting NFTs against a list of wallet addresses by making use of the create_wallet_edition_combo.js script. This script should be run before the minting process. Please see the `Create Wallet Edition Combo` section on when and how to use this functionality.

### Randomise generic metadata image URLs
Uses can now generate generic metadata where each NFT contains a different / randomised image URL instead of a static image URL. Users manually upload their generic images and retrieve the IPFS URLs and then simply add them into the list for genericURLs. Please see the [Generic Metadata](./README.md#9-update-nfts-for-reveal---generic-image-until-purchased-then-only-reveal-nft) section.

Expand Down Expand Up @@ -247,7 +258,7 @@ Modify the following parts at the very least, below are just sample values that

#### b. Update your layer configurations
- Update your folder names, order in which they need to be processed and the number of images to create
- Optionally add maximum repeatability rule in for the layers - Please see [Maximum Repeatability Feature](https://github.com/thepeanutgalleryandco/create-and-mint-nft-collection/issues/16)
- Optionally add maximum repeatability rule in for the layers - Please see [Maximum Repeatability Feature](https://github.com/thepeanutgalleryandco/create-and-mint-nft-collection/issues/16) and [Layer Item Maximum Repeatability Settings](https://github.com/thepeanutgalleryandco/create-and-mint-nft-collection/issues/20)
- Optionally add layer combination exclusion rules in for the layers - Please see [Layer Combination Exclusion Feature](https://github.com/thepeanutgalleryandco/create-and-mint-nft-collection/issues/15)

*Example of default configuration along with maximum repeatability and layer compatibility*
Expand Down Expand Up @@ -397,13 +408,17 @@ The new json files in the `ipfsMetas` directory will now contain a `metadata_uri
`Important` - Should you wish to do a reveal, please remember that your contract should allow for updates to your NFT files. You also need to update the `uploadGenericMeta` key's value to `true` in the `constants/account_details.js` file so that the genericJSON directory's metadata will be used instead of the json directory. Please see the section on NFT reveal steps to follow in the `EXAMPLE - REVEAL (ERC721)` and `EXAMPLE - REVEAL (ERC1155)` examples below.


### 11. ERC1155 Batch IPFS Metas Migration
### 11. Create Wallet Edition Combo
If you would like to mint your editions to different wallets, then you need to populate the account_details.js file's walletMintList with the wallet address and nft edition count. Once this is done, then run the `Custom - Create_Wallet_Edition_Combo Command`, which will generate a new `_walletAddressMintList.json` in the ipfsMetas directory. When you run the the `ERC1155 Batch IPFS Metas Migration` or `Minting NFTs` steps, then it will attempt to get the specific edition's wallet address that it needs to mint towards. If it can't find the `_walletAddressMintList.json` file or the edition is not in the file, then the mint process will default back to the mint_to_address field in the account_details.js file.


### 12. ERC1155 Batch IPFS Metas Migration
If you would like to make use of batch minting against an ERC1155 contract, you need to run the `Custom - Batch_Ipfs_Metas_Migration` script which will create a new `batchIPFSMetas` directory and it will create numbered json files, for example `1.json` which will contain a list of tokens for that specific batch to be minted, and a new `_batchIPFSMetas.json` file which will be a combined json file of all the numbered json files. The `NFTPort - Mint_Batch Command` will use this file these files to mint the token batches.

Before you use the `Custom - Batch_Ipfs_Metas_Migration` script, please be sure to update the `batch_mint_size` and `batch_mint_nft_amount` key's values to what your requirement is. By default, it is set to 50 for the `batch_mint_size` key and 1 for the `batch_mint_nft_amount` key.


### 12. Minting NFTs
### 13. Minting NFTs
- Use the `NFTPort - Mint_Batch Command` below to start minting against an ERC1155 contract where your mints will happen in batches.
- Use the `NFTPort - Mint Command` below to start minting against an ERC721 contract where your mint will happen individually.
- Use the `NFTPort - Mint_Range Command` below to start minting against an ERC721 contract for a range of NFTs between specific editions.
Expand All @@ -416,7 +431,7 @@ Before you use the `NFTPort - Mint_Item Command` script, please be sure to updat
Before you use the `NFTPort - Mint_Batch Command` script, please be sure to run the `Custom - Batch_Ipfs_Metas_Migration` script.


### 13. Checking NFT Mint Files For Issues
### 14. Checking NFT Mint Files For Issues
- Use the `Custom - Check_Mints Command` below to start checking each mint file to determine if there are any issues with the minted files for ERC721 contract files (individual files).
- Use the `Custom - Check_Mints_Batch Command` below to start checking each mint file to determine if there are any issues with the minted files for ERC1155 contract files (batch files).

Expand All @@ -431,14 +446,14 @@ The check mints scripts will go through the files once off, check all of their d
**Please note that this process can take time to complete as it runs through every minted json file.**


### 14. Re-Mint Failed NFTs
### 15. Re-Mint Failed NFTs
- Use the `NFTPort - ReMint Command` below to start re-minting each of the json files in the `failedMints` directory for ERC721 (Individual files) contract files.
- Use the `NFTPort - ReMint_Batch Command` below to start re-minting each of the json files in the `failedMints` directory for ERC1155 (batch files) contract files.

This process will write out a newly minted file in the `reMinted` directory as well as update the json file in the original `minted` directory. Due to this, a backup folder will be created every time this process runs with the date to keep a backup of the json file in the minted directory at the time of running this process just as a safe guard so that you have access to the original information or how the information changed in between your processing.


### 15. Check Your Work On The Marketplace
### 16. Check Your Work On The Marketplace
You are done with your minting process!
Well done!
Go and check out your mints on your marketplace and refresh the metadata where needde.
Expand Down Expand Up @@ -493,11 +508,17 @@ Use the following command from the code's root directory.
- node utils/custom/check_mints.js
- npm run check_mints


### Check_Mints_Batch
- node utils/custom/check_mints_batch.js
- npm run check_mints_batch


### Create_Wallet_Edition_Combo
- node utils/custom/create_wallet_edition_combo.js
- npm run create_wallet_edition_combo


### Update_Image_Info Command
- node utils/custom/update_image_info.js
- npm run update_image_info
Expand Down Expand Up @@ -551,6 +572,11 @@ Use the following command from the code's root directory.
- npm run remint_batch


### Reveal Command
- node utils/nftport/reveal.js
- npm run reveal


### UploadFiles Command
- node utils/nftport/uploadFiles.js
- npm run uploadFiles
Expand Down
13 changes: 12 additions & 1 deletion constants/account_details.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,18 @@ const ACCOUNT_DETAILS = {
mint_item: '1', // Set your NFT edition number in here and this specific NFT will be minted. Ex. '3'
uploadGenericMeta: false, // When this value is set to false, then the build/json directory's _metadata.json file will be used when uploadMetas.js is called. When this value is set to true, then the build/genericJSON directory's _metadata.json file will be used when uploadMetas.js is called.
batch_mint_size: '50', // Set the number of NFTs that are minted per batch_mint. Maximum is 50 NFTs per batch_mint.
batch_mint_nft_amount: '1' // Set the number of times that each NFT will be minted. For example, if set to 5, then each NFT edition can be sold 5 times.
batch_mint_nft_amount: '1', // Set the number of times that each NFT will be minted. For example, if set to 5, then each NFT edition can be sold 5 times.
salesInterval: '900000', // Set the interval that will be used to check for sales on your contract and then reveal the NFT. 900000 = 15 minutes.
walletMintList: [
{
"wallet_address": "WALLET_ADDRESS_ONE",
"nft_count": "20"
},
{
"wallet_address": "WALLET_ADDRESS_TWO_HERE",
"nft_count": "3"
}
] // Set your wallet list that consists of multiple wallets along with how many NFTs should be minted to each wallet address. E.x [ {"wallet_address": "WALLET_ADDRESS_ONE", "nft_count": "20"}, {"wallet_address": "WALLET_ADDRESS_TWO", "nft_count": "3"}, {"wallet_address": "WALLET_ADDRESS_THREE", "nft_count": "39"}]
};

module.exports = {
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "create-and-mint-nft-collection",
"version": "1.5.0",
"version": "1.6.0",
"description": "Source code to create and mint generative art via NFTPort API. Special thanks to codeSTACKr and Hashlips for their source codebase.",
"main": "index.js",
"bin": "index.js",
Expand All @@ -17,6 +17,7 @@
"check_mints": "node utils/custom/check_mints.js",
"check_mints_batch": "node utils/custom/check_mints_batch.js",
"create_provenance": "node utils/art_engine/create_provenance.js",
"create_wallet_edition_combo": "node utils/custom/create_wallet_edition_combo.js",
"generate": "node index.js",
"generate_metadata": "node utils/art_engine/generate_metadata.js",
"mint_batch": "node utils/nftport/mint_batch.js",
Expand All @@ -29,6 +30,7 @@
"rarity": "node utils/art_engine/rarity.js",
"remint": "node utils/nftport/remint.js",
"remint_batch": "node utils/nftport/remint_batch.js",
"reveal": "node utils/nftport/reveal.js",
"update_image_info": "node utils/custom/update_image_info.js",
"update_json_to_generic_meta": "node utils/custom/update_json_to_generic_meta.js",
"update_metadata_info": "node utils/custom/update_metadata_info.js",
Expand Down
31 changes: 31 additions & 0 deletions src/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,40 @@ const layerConfigurations = [
{ name: "Shine" },
{ name: "Bottom lid" },
{ name: "Top lid" },
]
},
];

/* Example of configuration settings
const layerConfigurations = [
{
growEditionSizeTo: 2,
maxRepeatedTraits: 1,
layersOrder: [
{ name: "Background" },
{ name: "Eyeball" },
{ name: "Eye color", maxRepeatedTrait: 2 },
{ name: "Iris" },
{ name: "Shine" },
{ name: "Bottom lid", maxRepeatedTrait: 3 },
{ name: "Top lid" },
],
layerItemsMaxRepeatedTraits: [
{ name: "Background/Black", layerItemMaxRepeatedTrait: 4 },
{ name: "Eyeball/Red", layerItemMaxRepeatedTrait: 5 }
],
incompatibleTraits: {
"Eye color/Cyan": [
"Eyeball/Red",
],
"Iris/Large": [
"Bottom lid/High",
"Top lid/High",
],
}
},
];
*/

const shuffleLayerConfigurations = false;

Expand Down
4 changes: 2 additions & 2 deletions src/exclusions.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ const { combinationOfTraitsAlreadyExists } = require('./exclusions/combination_t
const { incompatibleTraitsUsed } = require('./exclusions/incompatible_traits');

// Checks the different exclusions and return true if any of them are true
const needsExclusion = (selectedTraitsList, newTraits, maxRepeatedTraits, incompatibleTraits) => {
const needsExclusion = (selectedTraitsList, newTraits, maxRepeatedTraits, incompatibleTraits, layerItemsMaxRepeatedTraits) => {

return combinationOfTraitsAlreadyExists(selectedTraitsList, newTraits, maxRepeatedTraits) || incompatibleTraitsUsed(newTraits, incompatibleTraits);
return combinationOfTraitsAlreadyExists(selectedTraitsList, newTraits, maxRepeatedTraits, layerItemsMaxRepeatedTraits) || incompatibleTraitsUsed(newTraits, incompatibleTraits);
};

module.exports = {
Expand Down
77 changes: 46 additions & 31 deletions src/exclusions/combination_traits.js
Original file line number Diff line number Diff line change
@@ -1,40 +1,55 @@
// Check if the maximum repeatability have been reached
const combinationOfTraitsAlreadyExists = (selectedTraitsList, newTraits, maxRepeatedTraits) => {
//console.log(newTraits);
// Check if maximum repeatability check needs to be done and if not, return false and exit this check
if (!maxRepeatedTraits) {
return false;
const combinationOfTraitsAlreadyExists = (selectedTraitsList, newTraits, maxRepeatedTraits, layerItemsMaxRepeatedTraits) => {

let traitLayerCounts = {};
let traitLayerItemCounts = {};

// Loops through each trait list of previous selected traits list
for (let existingTraits of selectedTraitsList) {

// Loops through each trait and add to count
for (let i = 0; i < existingTraits.length; i++) {

// Check if trait exists in traitLayerCounts and traitLayerItemCounts objects and if it does, then add to the count, otherwise initialize with a count of 1.
traitLayerCounts[`${existingTraits[i].layer}`] = traitLayerCounts[`${existingTraits[i].layer}`] ? traitLayerCounts[`${existingTraits[i].layer}`] + 1 : 1 ;
traitLayerItemCounts[`${existingTraits[i].layer}/${existingTraits[i].name}`] = traitLayerItemCounts[`${existingTraits[i].layer}/${existingTraits[i].name}`] ? traitLayerItemCounts[`${existingTraits[i].layer}/${existingTraits[i].name}`] + 1 : 1 ;
}
}

// Loops through each new trait and add to count
for (let i = 0; i < newTraits.length; i++) {

// Loops through each trait within the selected traits list
for (let existingTraits of selectedTraitsList) {

// Set a starting value of 0 for the selected traits
let commonTraits = 0;
// Check if trait exists in traitLayerCounts and traitLayerItemCounts objects and if it does, then add to the count, otherwise initialize with a count of 1.
traitLayerCounts[`${newTraits[i].layer}`] = traitLayerCounts[`${newTraits[i].layer}`] ? traitLayerCounts[`${newTraits[i].layer}`] + 1 : 1 ;
traitLayerItemCounts[`${newTraits[i].layer}/${newTraits[i].name}`] = traitLayerItemCounts[`${newTraits[i].layer}/${newTraits[i].name}`] ? traitLayerItemCounts[`${newTraits[i].layer}/${newTraits[i].name}`] + 1 : 1 ;

// Loops through each new trait and only keep on looping if maximum repeatability have not been reached
for (let i = 0; (i < newTraits.length) && (commonTraits <= maxRepeatedTraits); i++) {
// Check if the selected trait has breached the layer maximum repeatability limit and return true if that is the case
if (traitLayerCounts[`${newTraits[i].layer}`] > newTraits[i].maxRepeatedTrait) {
console.log(`Combination of traits excluded because of layer (${newTraits[i].layer}) maximum repeatability exclusion rule!`);
return true;
}

// Checks if the new trait is already in the selected traits list
if (newTraits[i].id === existingTraits[i].id) {
// Check if the selected trait has breached the global maximum repeatability limit and return true if that is the case
if (traitLayerItemCounts[`${newTraits[i].layer}/${newTraits[i].name}`] > maxRepeatedTraits) {
console.log(`Combination of traits excluded because of global (${maxRepeatedTraits}) maximum repeatability exclusion rule!`);
return true;
}
}

// Increment the selected traits value as it has been found before
commonTraits++;
}
}
// Loops through layerItemsMaxRepeatedTraits list
for (layerItem in layerItemsMaxRepeatedTraits) {

// Check if the selected trait has breached the maximum repeatability limit and return true if that is the case
if (commonTraits > maxRepeatedTraits) {
console.log("Combination of traits excluded because of maximum repeatability exclusion rule!");
return true;
}

// Check if the selected trait has breached the layer item maximum repeatability limit and return true if that is the case
if (traitLayerItemCounts[`${layerItemsMaxRepeatedTraits[layerItem].name}`] > layerItemsMaxRepeatedTraits[layerItem].layerItemMaxRepeatedTrait) {
console.log(`Combination of traits excluded because of layer item (${layerItemsMaxRepeatedTraits[layerItem].name}) maximum repeatability exclusion rule!`);
return true;
}
}

// Return false if the traits have been looped through and the maximum repeatability have not been breached
return false;
};
module.exports = {
combinationOfTraitsAlreadyExists,
};
// Return false if the traits have been looped through and the maximum repeatability have not been breached
return false;
};

module.exports = {
combinationOfTraitsAlreadyExists,
};
Loading

0 comments on commit bd8792b

Please sign in to comment.