SoLibrary
  • Solana
  • The Meme Coin Problem and Solution
  • Developing on Solana
  • From Rust To Deployment
  • Solana Blockchain Explorer
  • Building a Solana dAPP
  • Deploying a Solana dApp
  • Deploying a Solana Memecoin using CLI
  • Solana Smart Contracts
  • Send Solana via javascript functions
  • Candy Machine
  • Pump fun APIs
  • Metaplex
  • Metaplex Program Library
  • Solana Program Library
  • UMI Framework
  • Umi and Web3js Differences
  • Fetching Accounts
  • UMI Helpers
  • HTTP Requests
  • Umi's Interfaces
  • Interface implementations
  • Kinobi
  • UMI Plugins
  • Registering Programs
  • Public keys and Signers
  • Connecting RPCS
  • Serializer
  • Storage
  • Transactions
  • Web 3.JS Adapters
  • Metaplex Umi Plugins
  • Core JS SDK v1.0
  • Local Validator
  • SolScriptions
  • FAQ
  • Initialize
  • Write Inscription Data
  • Fetch
  • Clear
  • Close
  • Authority
  • Sharding
  • Getting Started using JavaScript
  • Getting started using the Inscriptions CLI
  • Core Candy Machine
  • Getting Started using JavaScript
  • Candy Guard
  • Assets
  • Creating a Core Candy Machine
  • Inserting Items
  • Updating The Core Candy Machine
  • Guard Groups
  • Special Guard Instructions
  • Fetching a Core Candy Machine
  • Minting
  • Withdrawing a Core Candy Machine
  • Address Gate Guard
  • Allocation
  • Allowlist Guard
  • Asset Burn Guard
  • Asset Burn Multi
  • Asset Payment Guard
  • Asset Payment Multi
  • Asset Mint Limit
  • Bot Tax Guard
  • End Date Guard
  • Edition
  • Freeze Sol Payment guard
  • Freeze Token Payment Guard
  • Gatekeeper Guard
  • Mint Limit Guard
  • NFT Burn Guard
  • NFT Gate Guard
  • NFT Mint Limit Guard
  • NFT Payment Guard
  • Program Gate Guard
  • Redeemed Amount Guard
  • Sol Fixed Fee Guard
  • Sol Payment Guard
  • Start Date Guard
  • Third Party Signer Guard
  • Token Burn Guard
  • Token Gate Guard
  • Token Payment Guard
  • Token2022 Payment Guard
  • Generating Custom Guard Client for Core Candy Machine
Powered by GitBook
On this page
  • Guard Settings
  • Mint Settings
  • Route Instruction

Allowlist Guard

The Allow List guard validates the minting wallet against a predefined list of wallets. If the minting wallet is not part of this list, minting will fail.

PreviousAllocationNextAsset Burn Guard

Last updated 10 months ago

Providing a big list of wallets in the settings of this guard would require a lot of storage on the blockchain and would likely need more than one transaction to insert them all. Therefore, the Allow List guard uses to verify that the minting wallet is part of the preconfigured list of wallets.

This works by creating a binary tree of hashes where all leaves hash themselves two by two until we reach the final hash known as the Merkle Root. This means that if any leaf were to change, the final Merkle Root would be corrupted.

Hash 7Merkle RootHash 5Hash 6LeavesHash 1Hash 2Hash 3Hash 4DataUr1C...bWSGsXCd...edknRbJs...Ek7urwAv...u1ud

To verify that a leaf is part of the tree, we simply need a list of all the intermediary hashes that allow us to go up the tree and re-compute the Merkle Root. We call this list of intermediary hashes a Merkle Proof. If the computed Merkle Root matches the stored Merkle Root, we can be sure that the leaf is part of the tree and therefore part of the original list.

Hash 7Merkle RootHash 5Hash 6Merkle Proof =Hash 4+Hash 5LeavesHash 1Hash 2Hash 3Hash 4DataUr1C...bWSGsXCd...edknRbJs...Ek7urwAv...u1ud

Therefore, the Allow List guard’s settings require a Merkle Root which acts as a source of truth for the preconfigured list of allowed wallets. For a wallet to prove it is on the allowed list, it must provide a valid Merkle Proof that allows the program to re-compute the Merkle Root and ensure it matches the guard’s settings.

Note that our SDKs provide helpers to make it easy to create Merkle Root and Merkle Proofs for a given list of wallets.

if the payer's Merkle Proof does not match

the guard's Merkle Root validation will fail

Candy Machine

Owner: Candy Machine Core Program

Candy Guard

Owner: Candy Guard Program

GuardsAllowList- Merkle Root...

Merkle Root

Merkle Proof

List of wallets

allowed to mint

Payer

Owner: Any Program

Route from the

Candy Guard Program

Verify Merkle Proof

Allowlist PDA

Mint from

Candy Guard Program

Access Control

Mint from

Candy Machine Program

Mint Logic

Asset

Guard Settings

The Allow List guard contains the following settings:

  • Merkle Root: The Root of the Merkle Tree representing the allow list.

Set up a Candy Machine using the Allowlist guard

JavaScript

To help us manage Merkle Trees, the Umi library provides two helper methods called getMerkleRoot and getMerkleProof that you may use like so.

import {
  getMerkleProof,
  getMerkleRoot,
} from "@metaplex-foundation/mpl-core-candy-machine";

const allowList = [
  "Ur1CbWSGsXCdedknRbJsEk7urwAvu1uddmQv51nAnXB",
  "GjwcWFQYzemBtpUoN5fMAP2FZviTtMRWCmrppGuTthJS",
  "AT8nPwujHAD14cLojTcB1qdBzA1VXnT6LVGuUd6Y73Cy",
];

const merkleRoot = getMerkleRoot(allowList);
const validMerkleProof = getMerkleProof(
  allowList,
  "Ur1CbWSGsXCdedknRbJsEk7urwAvu1uddmQv51nAnXB"
);
const invalidMerkleProof = getMerkleProof(allowList, "invalid-address");

Once we have computed the Merkle Root of our allow list, we can use it to set up the Allow List guard on our Candy Machine.

import { getMerkleRoot } from "@metaplex-foundation/mpl-core-candy-machine";

const allowList = [
  "Ur1CbWSGsXCdedknRbJsEk7urwAvu1uddmQv51nAnXB",
  "GjwcWFQYzemBtpUoN5fMAP2FZviTtMRWCmrppGuTthJS",
  "AT8nPwujHAD14cLojTcB1qdBzA1VXnT6LVGuUd6Y73Cy",
];

create(umi, {
  // ...
  guards: {
    allowList: some({ merkleRoot: getMerkleRoot(allowList) }),
  },
});

Mint Settings

The Allow List guard contains the following Mint Settings:

  • Merkle Root: The Root of the Merkle Tree representing the allow list.

Mint with the Allow List guard

JavaScript

You may pass the Mint Settings of the Allow List guard using the mintArgs argument like so.

import { getMerkleRoot } from "@metaplex-foundation/mpl-core-candy-machine";

const allowList = [
  "Ur1CbWSGsXCdedknRbJsEk7urwAvu1uddmQv51nAnXB",
  "GjwcWFQYzemBtpUoN5fMAP2FZviTtMRWCmrppGuTthJS",
  "AT8nPwujHAD14cLojTcB1qdBzA1VXnT6LVGuUd6Y73Cy",
];

mintV1(umi, {
  // ...
  mintArgs: {
    allowList: some({ merkleRoot: getMerkleRoot(allowList) }),
  },
});

Route Instruction

The Allow List route instruction supports the following features.

Validate a Merkle Proof

Path: proof

This route instruction will compute the Merkle Root from the provided Merkle Proof and, if valid, will create a new PDA account acting as proof that the minting wallet is part of the allowed list. Therefore, when minting, the Allow List guard only needs to check for the existence of this PDA account to authorize or deny minting to the wallet.

So why can’t we just verify the Merkle Proof directly within the mint instruction? That’s simply because, for big allow lists, Merkle Proofs can end up being pretty lengthy. After a certain size, it becomes impossible to include it within the mint transaction that already contains a decent amount of instructions. By separating the validation process from the minting process, we make it possible for allow lists to be as big as we need them to be.

This path of the route instruction accepts the following arguments:

  • Path = proof: Selects the path to execute in the route instruction.

  • Merkle Root: The Root of the Merkle Tree representing the allow list.

  • Merkle Proof: The list of intermediary hashes that should be used to compute the Merkle Root and verify that it matches the Merkle Root stored on the guard’s settings.

  • Minter (optional): The minter account as a signer if it is not the same as the payer. When provided, this account must be part of the allow list for the proof to be valid.

Pre-Validate a Wallet

JavaScript

You may pass the "Proof" Route Settings of the Allow List guard using the routeArgs argument like so.

import {
  getMerkleProof,
  getMerkleRoot,
} from "@metaplex-foundation/mpl-core-candy-machine";
import { publicKey } from "@metaplex-foundation/umi";

const allowList = [
  "Ur1CbWSGsXCdedknRbJsEk7urwAvu1uddmQv51nAnXB",
  "GjwcWFQYzemBtpUoN5fMAP2FZviTtMRWCmrppGuTthJS",
  "AT8nPwujHAD14cLojTcB1qdBzA1VXnT6LVGuUd6Y73Cy",
];

await route(umi, {
  // ...
  guard: "allowList",
  routeArgs: {
    path: "proof",
    merkleRoot: getMerkleRoot(allowList),
    merkleProof: getMerkleProof(allowList, publicKey(umi.identity)),
  },
}).sendAndConfirm(umi);

The umi.identity wallet is now allowed to mint from the Candy Machine.

API References: ,

Note that, before being able to mint, we must validate the minting wallet by providing a Merkle Proof. See below for more details.

Also note that, if you’re planning on constructing instructions without the help of our SDKs, you will need to add the Allow List Proof PDA to the remaining accounts of the mint instruction. See the for more details.

API References: ,

Instead of passing the Merkle Proof directly to the mint instruction, the minting wallet must perform a by using the route instruction of the Allow List guard.

API References: ,

Merkle Trees
React Flow
React Flow
React Flow
create
AllowList
Validate a Merkle Proof
Candy Guard’s program documentation
mintV1
AllowListMintArgs
Pre-Validation
route
AllowListRouteArgs