{"id":20697590,"url":"https://github.com/epomatti/cmv2-whitelist","last_synced_at":"2026-01-22T16:36:39.170Z","repository":{"id":40123843,"uuid":"445145694","full_name":"epomatti/cmv2-whitelist","owner":"epomatti","description":"Demo SPL Token whitelist using Metaplex Candy Machine v2 \u0026 Gumdrop","archived":false,"fork":false,"pushed_at":"2022-06-25T15:50:23.000Z","size":27,"stargazers_count":3,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"main","last_synced_at":"2024-11-17T00:23:46.889Z","etag":null,"topics":["blockchain","candy-machine-v2","gumdrop","metaplex","solana","spl-token","web3","whitelist"],"latest_commit_sha":null,"homepage":"https://hackmd.io/@epomatti/B1kUsyEhF","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/epomatti.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2022-01-06T11:28:51.000Z","updated_at":"2024-06-04T08:38:54.000Z","dependencies_parsed_at":"2022-07-30T05:37:56.164Z","dependency_job_id":null,"html_url":"https://github.com/epomatti/cmv2-whitelist","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/epomatti%2Fcmv2-whitelist","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/epomatti%2Fcmv2-whitelist/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/epomatti%2Fcmv2-whitelist/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/epomatti%2Fcmv2-whitelist/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/epomatti","download_url":"https://codeload.github.com/epomatti/cmv2-whitelist/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":234410359,"owners_count":18828188,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["blockchain","candy-machine-v2","gumdrop","metaplex","solana","spl-token","web3","whitelist"],"created_at":"2024-11-17T00:19:06.507Z","updated_at":"2025-09-27T08:31:11.361Z","avatar_url":"https://github.com/epomatti.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"# How to: Candy Machine v2 Whitelist\n\n###### tags: `metaplex` `whitelist`\n\nA comprehensive, step-by-step tutorial, for you to launch your NFT project with whitelist using Candy Machine V2, SPL Tokens, and Gumdrop.\n\n```sequence\nDeveloper-\u003eSPL: 1. Create/mint token\nDeveloper-\u003eCandyMachine: 2. Create/upload assets + wl settings\nDeveloper-\u003eGumdrop: 3. Create \u0026 set the whitelist\nGumdrop-\u003eUser: Distribution\nUser-\u003eClaimSite: Claim tokens\nClaimSite--\u003eUser: tokens\nUser-\u003eMintSite: Initiate the Mint\nUser-\u003eCandyMachine: Mint NFT using token\nCandyMachine--\u003eUser: NFT\n```\n\n:::info\n:information_source: You should always read the [official docs](https://docs.metaplex.com/) and keep up with the community updates.\n:::\n\n### Environment Setup\n\nInstall the required tools as described in the [official guide](https://docs.metaplex.com/candy-machine-v2/getting-started).\n\n\n:::spoiler _Versions \u0026 Downloads_\n\nYou'll need all of these installed (don't need to be exact versions):\n\n```bash\n$ git version\ngit version 2.34.1\n\n$ node --version\nv16.13.1\n\n$ yarn --version\n1.22.17\n\n$ ts-node --version\nv10.4.0\n\n$ solana --version\nsolana-cli 1.8.11 (src:423a4d65; feat:2385070269)\n```\n\nDownload links:\n\n- Git - https://git-scm.com/downloads\n- Node.js - https://nodejs.org/en/download/\n- Yarn - https://classic.yarnpkg.com/lang/en/docs/install\n  _(Use `yarn v1.x` - later versions need extra config)_\n- ts-node - https://www.npmjs.com/package/ts-node#Installation\n- Solana Tool Suite - https://docs.solana.com/cli/install-solana-cli-tools\n\nOnly need Solana CLI? Run this bad boy:\n\n```bash\nsh -c \"$(curl -sSfL https://release.solana.com/stable/install)\"\n```\n\nI'm running on `WSL2` Ubuntu:\n\n```\n$ lsb_release -a\nNo LSB modules are available.\nDistributor ID: Ubuntu\nDescription:    Ubuntu 20.04.3 LTS\nRelease:        20.04\nCodename:       focal\n```\n:::\n\n### Environment Variables\n\nSetup the variables we'll need for this example:\n\n```bash\n# Environment\nexport ENV='devnet'\nexport URL='https://api.devnet.solana.com'\nexport KEYPAIR=\"$HOME/.config/solana/devnet.json\"\nexport RPC='https://api.devnet.solana.com'\n\n# Candy Machine\nexport EXTRAS='./extras'\nexport CONFIG=\"$EXTRAS/config.json\"\nexport WHITELIST=\"$EXTRAS/whitelist.json\"\n\n# Collection\nexport ASSETS=\"$EXTRAS/assets\"\n```\n\n:::spoiler _Setup your free custom RPC provider (Optional for this tutorial)_\n\nThis tutorial uses an RPC provider on all commands. Create a free one on Figment:\n\n1. Sign up to Figment here: https://datahub.figment.io/sign_up?service=solana\n3. Find and copy your `API Key` and the base URL.\n3. Set this URL as your RPC variable:\n   ```bash\n   export RPC='https://solana--devnet.datahub.figment.io/apikey/\u003cYOUR API KEY\u003e'\n   ```\n:::\n\n### Create your Treasury Wallet\n\nCreate and fund your wallet:\n\n```bash\nsolana config set --url $URL\nsolana config set --keypair $KEYPAIR\n\nsolana-keygen new --outfile $KEYPAIR\nsolana airdrop 2 --keypair $KEYPAIR\n```\n\n:bulb: Copy the public key - you'll need it later.\n\nYou can always get the public key later:\n\n```bash\nsolana-keygen pubkey\n```\n\n### Create the SPL Token\n\nWhitelisted users will be allowed to mint using SPL Tokens which will serve as an exchange currency. Create the token:\n\n```bash\nspl-token create-token --decimals 0\n```\n\n:bulb: Copy the token - you'll need it later.\n\nStore the output value and set the token address variable like this:\n\n```sh\nexport SPL_TOKEN=\"\u003cYOUR NEW TOKEN JUST CREATED\u003e\"\n```\n\nMint the tokens:\n\n```bash\nspl-token create-account $SPL_TOKEN\nspl-token mint $SPL_TOKEN 10\n\n# Consider disabling the mint when you're done\nspl-token authorize $SPL_TOKEN mint --disable\n```\n\nFor `mainnet` you should [register the token](https://github.com/solana-labs/token-list).\n\n### Candy Machine Configuration\n\nGet the Metaplex code, then install the dependencies:\n\n```bash\ngit clone 'git@github.com:metaplex-foundation/metaplex.git'\n\ncd metaplex\nyarn install --cwd ./js/\n```\n\nCreate the `extras` directory and the `config.json`:\n\n```bash\nmkdir extras\ntouch ./extras/config.json\n```\n\nCopy/paste the following JSON content into `config.json`:\n\n\n\n```json\n{\n  \"price\": 0.5,\n  \"number\": 10,\n  \"gatekeeper\": null,\n  \"solTreasuryAccount\": \"\u003cYOUR WALLET ADDRESS\u003e\",\n  \"splTokenAccount\": null,\n  \"splToken\": null,\n  \"goLiveDate\": \"30 Jan 2022 00:00:00 UTC\",\n  \"endSettings\": null,\n  \"whitelistMintSettings\": {\n    \"mode\": {\n      \"burnEveryTime\": true\n    },\n    \"mint\": \"\u003cSPL TOKEN\u003e\",\n    \"presale\": true,\n    \"discountPrice\": 0.33\n  },\n  \"hiddenSettings\": null,\n  \"storage\": \"arweave\",\n  \"ipfsInfuraProjectId\": null,\n  \"ipfsInfuraSecret\": null,\n  \"awsS3Bucket\": null,\n  \"noRetainAuthority\": false,\n  \"noMutable\": false\n}\n```\n\n:arrow_forward: Update `config.json` with your custom configuration:\n\n- **`solTreasuryAccount`** - The public key of the keypair of the Treasury Account.\n- **`goLiveDate`** - Set a date in the future to allow for the whitelist behavior.\n- **`whitelistMintSettings.mint`** - This is the SPL Token created earlier.\n\nNotice that the `discountPrice` is 0.33. It will override the `price` 0.5 only for the whitelist.\n\nCheck out the [official docs](https://docs.metaplex.com/candy-machine-v2/configuration) to learn more about these configurations.\n\n### Prepare the Assets\n\nDownload the sample assets:\n\n```bash\nwget -O 'assets.tar.gz' https://github.com/epomatti/cmv2-whitelist/blob/main/assets.tar.gz?raw=true\n     \ntar -xzf assets.tar.gz --directory $EXTRAS\n```\n\n:arrow_forward: Update all JSON files under `./extras/assets`\n\nFor this example, change **`properties.creators.address`** value to your Treasury Account public key.\n\n\n### Create the Candy Machine :candy:\n\nThis command will create the candy machine and upload all assets.\n\n```bash\nts-node ./js/packages/cli/src/candy-machine-v2-cli.ts upload \\\n  --env $ENV \\\n  --keypair $KEYPAIR \\\n  --config-path $CONFIG \\\n  --rpc-url $RPC \\\n  $ASSETS\n```\n\n:bulb: Wait for all assets to be uploaded, then copy the candy machine ID - you'll need it later\n\nFor more info on the metadata check the [official docs](https://docs.metaplex.com/nft-standard).\n\n:::info\n:information_source: The `number` of NFTs cannot be changed later, so make sure to get it right on `mainnet`\n:::\n\nVerify the uploads:\n\n```bash\nts-node ./js/packages/cli/src/candy-machine-v2-cli.ts verify_upload \\\n  --env $ENV \\\n  --keypair $KEYPAIR \\\n  --rpc-url $RPC\n```\nYou need an output like this before going forward:\n\n```\nKey size 10\nuploaded (10) out of (10)\nready to deploy!\n```\n\n:::spoiler _Click here if you need to Upload the candy machine_\n```bash\n# If you make changes in the \"config.json\"\nts-node ./js/packages/cli/src/candy-machine-v2-cli.ts update_candy_machine \\\n  --env $ENV \\\n  --keypair $KEYPAIR \\\n  --config-path $CONFIG \\\n  --rpc-url $RPC\n```\n::: \n\n### Create the Gumdrop\n\nOn this tutorial we're using `gumdrop` but you may use other means for token distribution.\n\nCreate the `whitelist.json` file which will hold the list of whitelisted users:\n\n```bash\ntouch ./extras/whitelist.json\n```\n\nCopy and paste the following content into the `whitelist.json`:\n\n```json\n[\n  {\n    \"handle\": \"\u003cUSER WALLET\u003e\",\n    \"amount\": 1\n  }\n]\n```\n\n:arrow_forward: Now change the `handle` property value to the user wallet.\n\nThe `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.\n\n:arrow_forward: Add funds to the new user wallets: https://solfaucet.com/\n\n:::spoiler _Demo: Create a Phantom user wallet on `devnet`_\n![](https://i.imgur.com/aauLh6q.gif)\n:::\n\n\u003cbr/\u003e\n\n:::info\n:information_source: Read the [official docs](https://docs.metaplex.com/airdrops/create-gumdrop) to learn more about other distribution methods (email, SMS, ...)\n:::\n\nHere we'll use the [Token Airdrop](https://docs.metaplex.com/airdrops/create-gumdrop#token-airdrop) drop type supported by `CMv2`.\n\nCreate the `gumdrop`:\n\n```bash\nts-node ./js/packages/cli/src/gumdrop-cli.ts create \\\n  --env $ENV \\\n  --keypair $KEYPAIR \\\n  --rpc-url $RPC \\\n  --claim-integration \"transfer\" \\\n  --transfer-mint $SPL_TOKEN \\\n  --distribution-method \"wallets\" \\\n  --otp-auth \"disable\" \\\n  --distribution-list $WHITELIST\n```\n\n:bulb: Copy the `gumdrop` ID - you'll need it later.\n\n:::info\n:information_source: Real launches should consider a custom `--host` deployment. Check the gumdrop docs.\n:::\n\n### URL Claim the SPL Token\n\nUnder the **`./logs`** folder the URLs have been generated in the `devnet-urls.json` file.\n\n![](https://i.imgur.com/yJnIetz.png)\n\n:arrow_forward: Open the URL and claim your token\n\nUsers will claim their own tokens using this URL and use their tokens as proof for whitelist privileges while minting their NFTs.\n\n:::spoiler _Demo: Claiming the token with a user wallet_\n![](https://i.imgur.com/xBOAYlr.gif)\n:::\n\n\n### Setup the Minting Frontend\n\n:::success\n\n:rocket:  Updated to use the newly released [Candy Machine UI](https://docs.metaplex.com/candy-machine-v2/mint-frontend) module.\n:::\n\nThe frontend is available at `./js/packages/candy-machine-ui`.\n\n```bash\nexport CANDYUI='./js/packages/candy-machine-ui'\n\ncp \"$CANDYUI/.env.example\" \"$CANDYUI/.env\"\n```\n\n\n:arrow_forward: Edit the `.env` file with your own configuration:\n\n```\nREACT_APP_CANDY_MACHINE_ID=\u003cYOUR CANDY MACHINE PROGRAM ID\u003e\nREACT_APP_SOLANA_NETWORK=devnet\nREACT_APP_SOLANA_RPC_HOST=https://api.devnet.solana.com\n```\n\nIf you're using a custom RPC server, change that too.\n\nNow install \u0026 start your minting frontend:\n\n```bash\nyarn --cwd $CANDYUI install\nyarn --cwd $CANDYUI start\n```\n\n:::spoiler _Click here if you forgot your Candy Machine ID_\n\nRun this to see your Candy Machine configuration:\n\n```bash\nts-node ./js/packages/cli/src/candy-machine-v2-cli.ts show \\\n  --env $ENV \\\n  --keypair $KEYPAIR \\\n  --rpc-url $RPC\n ```\n\nCopy the ID:\n\n![](https://i.imgur.com/s5KW4UC.png)\n::: \n\n\n### Mint an NFT providing your SPL Token\n\nWhitelisted users will then connect to the minting site and mint the NFT.\n\nThey will exchange the token as part of the whitelist + the SOL price configured in the `config.json` discount property.\n\n:arrow_forward: Site should be running here: **http://localhost:3000**\n\n![](https://i.imgur.com/ugMU789.gif)\n\nAs expected, the whitelist price is 0.33 SOL and the SPL Token is removed from the user wallet.\n\n:::info\n:information_source: Opened [this issue](https://github.com/metaplex-foundation/metaplex/issues/1465) to fix the displayed price, as it should be aware of the discount.\n:::\n\n\n### Close the Gumdrop\n\nFinally, once the whitelist launch is over, you should close the `gumdrop`:\n\n```sh\nts-node ./js/packages/cli/src/gumdrop-cli.ts close \\\n  --env $ENV \\\n  --keypair $KEYPAIR \\\n  --rpc-url $RPC \\\n  --claim-integration \"transfer\" \\\n  --transfer-mint $SPL_TOKEN \\\n  --base '.log/devnet-XXXXXXXXXXXXX.json'\n```\n\nCheck the [official docs](https://docs.metaplex.com/airdrops/create-gumdrop#closing-a-gumdrop) for this closing behavior.\n\n---\n\nI hope you find this article useful.\n\nLet me know of any fixes in the comments, or reach out on Twitter: [@EvandroPomatti](https://twitter.com/EvandroPomatti)","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fepomatti%2Fcmv2-whitelist","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fepomatti%2Fcmv2-whitelist","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fepomatti%2Fcmv2-whitelist/lists"}