A comprehensive, step-by-step tutorial, for you to launch your NFT project with whitelist using Candy Machine V2, SPL Tokens, and Gumdrop.
Developer->SPL: 1. Create/mint token
Developer->CandyMachine: 2. Create/upload assets + wl settings
Developer->Gumdrop: 3. Create & set the whitelist
Gumdrop->User: Distribution
User->ClaimSite: Claim tokens
ClaimSite-->User: tokens
User->MintSite: Initiate the Mint
User->CandyMachine: Mint NFT using token
CandyMachine-->User: NFT
:::info :information_source: You should always read the official docs and keep up with the community updates. :::
Install the required tools as described in the official guide.
:::spoiler Versions & Downloads
You'll need all of these installed (don't need to be exact versions):
$ git version
git version 2.34.1
$ node --version
v16.13.1
$ yarn --version
1.22.17
$ ts-node --version
v10.4.0
$ solana --version
solana-cli 1.8.11 (src:423a4d65; feat:2385070269)
Download links:
- Git - https://git-scm.com/downloads
- Node.js - https://nodejs.org/en/download/
- Yarn - https://classic.yarnpkg.com/lang/en/docs/install
(Use
yarn v1.x
- later versions need extra config) - ts-node - https://www.npmjs.com/package/ts-node#Installation
- Solana Tool Suite - https://docs.solana.com/cli/install-solana-cli-tools
Only need Solana CLI? Run this bad boy:
sh -c "$(curl -sSfL https://release.solana.com/stable/install)"
I'm running on WSL2
Ubuntu:
$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 20.04.3 LTS
Release: 20.04
Codename: focal
:::
Setup the variables we'll need for this example:
# Environment
export ENV='devnet'
export URL='https://api.devnet.solana.com'
export KEYPAIR="$HOME/.config/solana/devnet.json"
export RPC='https://api.devnet.solana.com'
# Candy Machine
export EXTRAS='./extras'
export CONFIG="$EXTRAS/config.json"
export WHITELIST="$EXTRAS/whitelist.json"
# Collection
export ASSETS="$EXTRAS/assets"
:::spoiler Setup your free custom RPC provider (Optional for this tutorial)
This tutorial uses an RPC provider on all commands. Create a free one on Figment:
- Sign up to Figment here: https://datahub.figment.io/sign_up?service=solana
- Find and copy your
API Key
and the base URL. - Set this URL as your RPC variable:
export RPC='https://solana--devnet.datahub.figment.io/apikey/<YOUR API KEY>'
:::
Create and fund your wallet:
solana config set --url $URL
solana config set --keypair $KEYPAIR
solana-keygen new --outfile $KEYPAIR
solana airdrop 2 --keypair $KEYPAIR
💡 Copy the public key - you'll need it later.
You can always get the public key later:
solana-keygen pubkey
Whitelisted users will be allowed to mint using SPL Tokens which will serve as an exchange currency. Create the token:
spl-token create-token --decimals 0
💡 Copy the token - you'll need it later.
Store the output value and set the token address variable like this:
export SPL_TOKEN="<YOUR NEW TOKEN JUST CREATED>"
Mint the tokens:
spl-token create-account $SPL_TOKEN
spl-token mint $SPL_TOKEN 10
# Consider disabling the mint when you're done
spl-token authorize $SPL_TOKEN mint --disable
For mainnet
you should register the token.
Get the Metaplex code, then install the dependencies:
git clone 'git@github.com:metaplex-foundation/metaplex.git'
cd metaplex
yarn install --cwd ./js/
Create the extras
directory and the config.json
:
mkdir extras
touch ./extras/config.json
Copy/paste the following JSON content into config.json
:
{
"price": 0.5,
"number": 10,
"gatekeeper": null,
"solTreasuryAccount": "<YOUR WALLET ADDRESS>",
"splTokenAccount": null,
"splToken": null,
"goLiveDate": "30 Jan 2022 00:00:00 UTC",
"endSettings": null,
"whitelistMintSettings": {
"mode": {
"burnEveryTime": true
},
"mint": "<SPL TOKEN>",
"presale": true,
"discountPrice": 0.33
},
"hiddenSettings": null,
"storage": "arweave",
"ipfsInfuraProjectId": null,
"ipfsInfuraSecret": null,
"awsS3Bucket": null,
"noRetainAuthority": false,
"noMutable": false
}
config.json
with your custom configuration:
solTreasuryAccount
- The public key of the keypair of the Treasury Account.goLiveDate
- Set a date in the future to allow for the whitelist behavior.whitelistMintSettings.mint
- This is the SPL Token created earlier.
Notice that the discountPrice
is 0.33. It will override the price
0.5 only for the whitelist.
Check out the official docs to learn more about these configurations.
Download the sample assets:
wget -O 'assets.tar.gz' https://github.com/epomatti/cmv2-whitelist/blob/main/assets.tar.gz?raw=true
tar -xzf assets.tar.gz --directory $EXTRAS
./extras/assets
For this example, change properties.creators.address
value to your Treasury Account public key.
This command will create the candy machine and upload all assets.
ts-node ./js/packages/cli/src/candy-machine-v2-cli.ts upload \
--env $ENV \
--keypair $KEYPAIR \
--config-path $CONFIG \
--rpc-url $RPC \
$ASSETS
💡 Wait for all assets to be uploaded, then copy the candy machine ID - you'll need it later
For more info on the metadata check the official docs.
:::info
:information_source: The number
of NFTs cannot be changed later, so make sure to get it right on mainnet
:::
Verify the uploads:
ts-node ./js/packages/cli/src/candy-machine-v2-cli.ts verify_upload \
--env $ENV \
--keypair $KEYPAIR \
--rpc-url $RPC
You need an output like this before going forward:
Key size 10
uploaded (10) out of (10)
ready to deploy!
:::spoiler Click here if you need to Upload the candy machine
# If you make changes in the "config.json"
ts-node ./js/packages/cli/src/candy-machine-v2-cli.ts update_candy_machine \
--env $ENV \
--keypair $KEYPAIR \
--config-path $CONFIG \
--rpc-url $RPC
:::
On this tutorial we're using gumdrop
but you may use other means for token distribution.
Create the whitelist.json
file which will hold the list of whitelisted users:
touch ./extras/whitelist.json
Copy and paste the following content into the whitelist.json
:
[
{
"handle": "<USER WALLET>",
"amount": 1
}
]
handle
property value to the user wallet.
The handle
here is the public wallet address of the user that will be whitelisted. You can create a new one in your Phantom wallet connected to the devnet
network.
:::spoiler Demo: Create a Phantom user wallet on devnet
:::
:::info :information_source: Read the official docs to learn more about other distribution methods (email, SMS, ...) :::
Here we'll use the Token Airdrop drop type supported by CMv2
.
Create the gumdrop
:
ts-node ./js/packages/cli/src/gumdrop-cli.ts create \
--env $ENV \
--keypair $KEYPAIR \
--rpc-url $RPC \
--claim-integration "transfer" \
--transfer-mint $SPL_TOKEN \
--distribution-method "wallets" \
--otp-auth "disable" \
--distribution-list $WHITELIST
💡 Copy the gumdrop
ID - you'll need it later.
:::info
:information_source: Real launches should consider a custom --host
deployment. Check the gumdrop docs.
:::
Under the ./logs
folder the URLs have been generated in the devnet-urls.json
file.
Users will claim their own tokens using this URL and use their tokens as proof for whitelist privileges while minting their NFTs.
:::spoiler Demo: Claiming the token with a user wallet :::
:::success
🚀 Updated to use the newly released Candy Machine UI module. :::
The frontend is available at ./js/packages/candy-machine-ui
.
export CANDYUI='./js/packages/candy-machine-ui'
cp "$CANDYUI/.env.example" "$CANDYUI/.env"
.env
file with your own configuration:
REACT_APP_CANDY_MACHINE_ID=<YOUR CANDY MACHINE PROGRAM ID>
REACT_APP_SOLANA_NETWORK=devnet
REACT_APP_SOLANA_RPC_HOST=https://api.devnet.solana.com
If you're using a custom RPC server, change that too.
Now install & start your minting frontend:
yarn --cwd $CANDYUI install
yarn --cwd $CANDYUI start
:::spoiler Click here if you forgot your Candy Machine ID
Run this to see your Candy Machine configuration:
ts-node ./js/packages/cli/src/candy-machine-v2-cli.ts show \
--env $ENV \
--keypair $KEYPAIR \
--rpc-url $RPC
Copy the ID:
Whitelisted users will then connect to the minting site and mint the NFT.
They will exchange the token as part of the whitelist + the SOL price configured in the config.json
discount property.
As expected, the whitelist price is 0.33 SOL and the SPL Token is removed from the user wallet.
:::info :information_source: Opened this issue to fix the displayed price, as it should be aware of the discount. :::
Finally, once the whitelist launch is over, you should close the gumdrop
:
ts-node ./js/packages/cli/src/gumdrop-cli.ts close \
--env $ENV \
--keypair $KEYPAIR \
--rpc-url $RPC \
--claim-integration "transfer" \
--transfer-mint $SPL_TOKEN \
--base '.log/devnet-XXXXXXXXXXXXX.json'
Check the official docs for this closing behavior.
I hope you find this article useful.
Let me know of any fixes in the comments, or reach out on Twitter: @EvandroPomatti