Disclaimer
We are not affiliated with Aptos or any NFT project. We develop tools for everyone to use, at their own risk.
What is this ?
The Aptos NFT Mint project is designed to let creators set up a candymachine for NFT minting and a minting website ultra fast on Aptos. Candy machine is originally from Solana. We use Candy machine here to refer to general nft minting system on blockchain.
Our twitter: https://twitter.com/FTMTeam1
Discord for questions: https://discord.gg/6ZPvDCR8Xd
Aptos is still in an early stage, We will update as soon as we can, but if you have questions, head into our discord for help.
Features developed
- Set start and finish time for everyone.
- Won't accept your funds if they're out of NFTs to sell.
- Wallet based whitelist.
- Royalties for your NFT.
- Asset upload on IPFS.
- Integrated with all the marketplace and wallets on Aptos.
- Fully customizable website with wallet integrated and your candy machine status displayed.
Preparations
In order to use this tool, here are the few things you need to have before continuing:
Code
git clone https://github.com/FTM-Labs/AptosNFTMint.git
Python3
You need python version 3.9 and above. https://www.python.org/downloads/
Install dependencies
You need python version 3.9 and above
cd script/third_party
pip3 install -r requirements.txt
nodeJs and npm
https://docs.npmjs.com/downloading-and-installing-node-js-and-npm
NFT assets
Thre are a bunch of solutions to generate NFT art and metadata. We recommend to use HashLips. Its simple and flexble.
Basically, you need layered art and use hashlips the generate images and metadata.
The metadata format we need is super simple. (the metadata format you generated from hashlips will work, we will just ignore the extra fields.) However, make sure each metadata file has a different, unique name.
{
"name": "NFT NAME",
"description": "NFT description",
"attributes": [
{ "trait_type": "Background", "value": "Black" },
{ "trait_type": "Eyeball", "value": "Red" },
{ "trait_type": "Eye color", "value": "Yellow" },
{ "trait_type": "Iris", "value": "Small" },
{ "trait_type": "Shine", "value": "Shapes" },
{ "trait_type": "Bottom lid", "value": "Low" },
{ "trait_type": "Top lid", "value": "Middle" }
]
}
After generated the metadata, put it in a separate folder than your images. The top level folder needs to be created like below:
Assets/
├─ Images/
| |- cover.png
│ ├─ 1.png
│ ├─ 2.png
│ ├─ 3.png
│ ├─ ...
├─ metadata/
│ ├─ 1.json
│ ├─ 2.json
│ ├─ ...
where the cover.png
is the cover image for the collection.
The metadata and corresponding image should have the same name, eg: 1.png and 1.json
Aptos wallet
For mainnet and testnet [Aptos disabled the faucte to fund account in testnet], you must prepare your own Aptos wallet and transfer some funds into it to cover the transaction fee.
Martian: https://chrome.google.com/webstore/detail/martian-aptos-wallet/efbglgofoippbgcjepnhiblaibcnclgk
Petra: https://chrome.google.com/webstore/detail/petra-aptos-wallet/ejjladinnckdgjemekebdpeokbikhfci
Our code will some check for the metadata format, you can disable it if you want in the code
Make sure the names for each nft (i.e the "name" field in individual NFT metadata) are unique. Two nft can not have the same name in the same collection. If you have duplicate names, there will be problem in your mint process.
Instructions
Collection metadata
"collection": {
"assetDir": "/Users/Shared/assets/images",
"metadataDir": "/Users/Shared/assets/metadata",
"collectionName": "TestCollection101",
"collectionDescription": "placeholder",
"collectionCover": "",
"collectionSize": 10,
"maxMintPerWallet": 10,
"mintFee": 100000000,
"royalty_points_denominator": 1000,
"royalty_points_numerator": 50,
"presaleMintTime": 100000000,
"publicMintTime": 100000000,
"whitelistDir": "/Users/Shared/assets"
}
assetDir
: Path to your image folder. Copy file path directly instead of manually putting it in to avoid errors.
metadataDir
: Path to your metadata folder. Copy file path directly instead of manually putting it in to avoid errors.
collectionName
: Your NFT collection name.
collectionDescription
: Your NFT description.
collectionCover
: if you have a image called cover
then this will automatically be filled. Otherwise, you need to provide a link to your cover image.
collectionSize
: Your NFT collection size.
maxMintPerWallet
: How many mints per wallet allowed.
mintFee
: 100000000 = 1 APT. e.g if you want 0.5 APT as mint fee, put 50000000.
royalty_points_denominator
: denominator of royaltie points.
royalty_points_numerator
: numerator of royaltie points.
presaleMintTime
: presale mint time, whitelisted user can mint after this. unix timstamp in seconds. https://www.unixtimestamp.com/
publicMintTime
: public mint time. unix timstamp in seconds. https://www.unixtimestamp.com/
whitelistDir
: Path to whitelist file.
Whitelist file is a text file of the following format:
0x6c4e890a882b013f82a65db9b917a6d285caa892e46f2d93808b56f2aab2dd92 2
0x9d40f83eee59912bed7488d49becd5274ec21c66c40931c9db95a501e03ecee2 3
0x6c4e890a882b013f82a65db9b917a6d285caa892e46f2d93808b56f2aab2dd92 2
each line must have a wallet address and how many can this wallet mint in white list phase
Candymachine metadata
"candymachine": {
"cmPublicKey": "",
"cmPrivateKey": ""
},
On devnet or testnet, leave cmPublicKey
and cmPrivateKey
blank as they will be generated and funded automatically.
On mainnet, you first have to create an account and send funds to it (used to create you candy machine, so make sure you have some funds to cover the gas.). You then have to export the account address and private key and input them in config.json.
Storage
We provide two options to upload your asstes. We will use Pinata as an example here. Please research yourself on how to set up arweave.
"storage": {
"solution": "pinata",
"pinata": {
"pinataApi": "https://api.pinata.cloud/pinning/pinFileToIPFS",
"pinataPublicKey": "",
"pinataSecretKey": ""
},
"arweave": {
"keyfilePath": "/Users/Shared/arweave-keyfile.json"
}
},
We will be using Pinata to batch upload your images and metadata to ipfs. Pinata is the most used service for upload NFT images and metadata to ipfs.
Register an account -> click the icon on top right -> click API key -> New Key -> enable pinFileToIPFS -> copy your public key and private key.
Open config.json
under src
folder (using VS code or other IDE).
Set Pinata keys.
"pinata" :{
"pinataApi": "https://api.pinata.cloud/pinning/pinFileToIPFS",
"pinataPublicKey" : "your pinata public key"
"pinataSecretKey" : "your pinata secret key"
}
Switch network
Go to constants.py
and change MODE
to be 'test' for testnet
, 'dev' for devnet
and 'mainnet' for using mainnet
.
Make sure the mode in candyMachineInfo.js
is set to the same.
Create candy machine
under src
folder, run
python3 cli.py
Choose Create candy machine
.
On devnet or testnet, we automatically deposited some aptos to the candy machine account.
If you need more aptos in devnet, check how to use faucet_client
to fund account in prepareCandyMachineAccount
in create_candy_machine.py
. As an example, you can write a for loop:
for i in range(15):
faucet_client.fund_account(alice.address(), 100000000)
If you want to change the maximum gas amount allowed, you can increase MAX_GAS
in constants.py
.
Additional functions
We provide options to update presale mint time, public mint time, mint fee and whitelist. Simply modify the values in config.json
and run the correspoinding command to update.
Update WL will override the past WL configuration. If you want to add some more wl spots, just add below the previous file and upload it.
Create website
You need to have npm installed, we are using nextJS to build this simple website
change the values in mint-site/helpers/candyMachineInfo.js
- can find those info in your config.json:
export const candyMachineAddress = "YOUR CM ADDRESS";
export const collectionName = "collection name(Case sensitive!)";
export const collectionCoverUrl = " THE COVER LINK eg: https://cloudflare-ipfs.com/ipfs/asjdhasjhd";
export const COLLECTION_SIZE = 10
open mint-site folder, run
npm install
then run
npm run dev
Sanity check
use test mint function from the cli to check if the minting is successful (preferably on devnet and testnet first). The test mint will attempt to ming ONE nft from your collection. On devnet, the program will automatically drop 3 Aptos, on testnet and mainnet, make sure your cm account has enough funds.)
Troubleshooting
ERESOURCE_ACCOUNT_EXISTS
: Currently one wallet can hold one resource account, this normally happen when creating candy machine on mainnet and for some reason (user interrupt or other errors) the process didint complete. If you collection has been successfully created, tryRetry failed uploads
from the cli menu. Otherwise, move your funds to a new wallet and paste in the account address and private key inconfig.json
and try create candy machine again.