Sugar for Candy Machine V3
For Candy Machine V3 you have to use a Sugar version > v2.0
The Candy Machine V3 is the latest iteration of the Metaplex Protocol's Candy Machine minting and distribution program. While the deploy of a Candy Machine V3 works largely similar to the previous V2 version, Sugar offers a set of new command to configure and manage a Candy Guard.
The Candy Machine V3 has a modular architecture, where the mint logic is separated from the mint access control — check the overview to read more about Candy Machine V3 and Candy Guard.
This guide will walk through the changes in the configuration for a Candy Machine V3 and the commands used to set up and manage a Candy Guard. It assumes that you are already familiar with how Sugar works and have deployed a Candy Machine — if that is not the case, we recommend to first complete the My First Candy Machine tutorial.
Configuration
Since the configuration of the mint process has moved to guards, Sugar's config file has changed. A basic configuration without any guards is shown bellow:
{
"number": 10,
"symbol": "TEST",
"sellerFeeBasisPoints": 500,
"isMutable": true,
"isSequential": false,
"creators": [
{
"address": "PanbgtcTiZ2PveV96t2FHSffiLHXXjMuhvoabUUKKm8",
"share": 100
}
],
"uploadMethod": "bundlr",
"awsConfig": null,
"nftStorageAuthToken": null,
"shdwStorageAccount": null,
"pinataConfig": null,
"hiddenSettings": null,
"guards": null
}
There are two new elements in the configuration file:
isSequential
: indicates to whether a sequential index generation should be used during mint or not (recommended to set this value tofalse
);guards
: indicates the configuration for the Candy Guard. If this value is set tonull
, a Candy Guard will not be used and mint will only be possible using themint authority
of the Candy Machine.
You can use the Sugar's create-config
command to create a basic configuration file. The Candy Guard configuration needs to be added manually, further explained below.
Available Guards
The Candy Guard ships with a total of 16 default guards. These guards can be used to define a single guard set, which will applied to every mint transaction, or to define groups. The example below shows a configuration file with 2 groups:
{
"number": 10,
"symbol": "TEST",
"sellerFeeBasisPoints": 500,
"isMutable": true,
"isSequential": false,
"creators": [
{
"address": "PanbgtcTiZ2PveV96t2FHSffiLHXXjMuhvoabUUKKm8",
"share": 100
}
],
"uploadMethod": "bundlr",
"awsConfig": null,
"nftStorageAuthToken": null,
"shdwStorageAccount": null,
"pinataConfig": null,
"hiddenSettings": null,
"guards": {
"default": {
"botTax": {
"value": 0.01,
"lastInstruction": true
}
},
"groups": [
{
"label": "OGs",
"guards": {
"startDate": {
"date": "2022-10-20 12:00:00 +0000"
},
"tokenGate": {
"amount": 1,
"mint": "7nE1GmnMmDKiycFkpHF7mKtxt356FQzVonZqBWsTWZNf"
},
"solPayment": {
"value": 1,
"destination": "PanbgtcTiZ2PveV96t2FHSffiLHXXjMuhvoabUUKKm8"
}
}
},
{
"label": "Public",
"guards": {
"startDate": {
"date": "2022-10-20 18:00:00 +0000"
},
"solPayment": {
"value": 2,
"destination": "PanbgtcTiZ2PveV96t2FHSffiLHXXjMuhvoabUUKKm8"
}
}
}
]
}
}
In this example, there are 2 groups OGs
and Public
. The OGs
specifies that only transactions that are from an address which holds 1
token of the the SPL token 7nE1GmnMmDKiycFkpHF7mKtxt356FQzVonZqBWsTWZNf
are allowed to mint from the 2022-10-20 12:00:00 +0000
; the mint will be charged at 1 SOL
.
The Public
group is open to any address from the 2022-10-20 18:00:00 +0000
; the mint will be charged at 2 SOL
.
For both groups, the botTax
guard specified in the default
guard set applies, so any transaction that fails the guard validation will be subject to a 0.01 SOL
fee.
If we wanted to have a single "public" group, all the guard configuration can be added to the default
guard set:
{
"number": 10,
"symbol": "TEST",
"sellerFeeBasisPoints": 500,
"isMutable": true,
"isSequential": false,
"creators": [
{
"address": "PanbgtcTiZ2PveV96t2FHSffiLHXXjMuhvoabUUKKm8",
"share": 100
}
],
"uploadMethod": "bundlr",
"awsConfig": null,
"nftStorageAuthToken": null,
"shdwStorageAccount": null,
"pinataConfig": null,
"hiddenSettings": null,
"guards": {
"default": {
"botTax": {
"value": 0.01,
"lastInstruction": true
},
"startDate": {
"date": "2022-10-20 18:00:00 +0000"
},
"solPayment": {
"value": 2,
"destination": "PanbgtcTiZ2PveV96t2FHSffiLHXXjMuhvoabUUKKm8"
}
},
"groups": null
}
}
Below is a list of the available guards and their configuration options.
Address Gate
The AddressGate guard restricts the mint to a single address — the address must match the payer's address of the mint transaction.
"addressGate" : {
"address": "<PUBKEY>"
}
Allocation
The Allocation guard allows to specify a limit on the overall number of mints for a group, either the default or a specific one. The id
configuration represents the unique identification for the limit — changing the id has the effect of restarting the limit, since a different tracking account will be created. The limit
indicates the maximum number of mints allowed within the group.
"allocation" : {
"id": number,
"limit": number
}
Allow List
The AllowList guard validates the payer's address against a merkle tree-based allow list of addresses. The hash should be specified as a hexadecimal value.
"allowList" : {
"merkleRoot": "<HASH>"
}
Bot Tax
The BotTax guard is used to:
- charge a penalty for invalid transactions. The value of the penalty is specified by the lamports configuration.
- validate that the mint transaction is the last transaction (last_instruction = true).
The bot_tax is applied to any error that occurs during the validation of the guards.
"botTax" : {
"value": SOL value,
"lastInstruction": boolean
}
End Date
The End Date guard is used to specify a date to end the mint. Any transaction received after the end date will fail.
The date needs to be specified using RFC 3339 standard. In most cases, the format used will be "yyyy-mm-ddT
hh:mm:ssZ
", where T
is the separator between the full-date and full-time and Z
is the timezone offset from UTC (use Z
or +00:00 for UTC time).
"endDate" : {
"date": "string",
}
Freeze Sol Payment
The Freeze Sol Payment guard allows minting frozen NFTs by charging the payer an amount in SOL. Frozen NFTs cannot be transferred or listed on any marketplaces until thawed.
Frozen NFTs can be thawed by anyone as long as one of the following conditions is met:
- The Candy Machine has minted out.
- The Candy Machine was deleted.
- The configured Freeze Period — which can be a maximum of 30 days — has passed.
"freezeSolPayment" : {
"value": SOL value,
"destination": "<PUBKEY>"
}
Freeze Token Payment
The Freeze Token Payment guard allows minting frozen NFTs by charging the payer a specific amount of tokens from a certain mint account. Frozen NFTs cannot be transferred or listed on any marketplaces until thawed. The amount determines how many tokens are required.
Frozen NFTs can be thawed by anyone as long as one of the following conditions is met:
- The Candy Machine has minted out.
- The Candy Machine was deleted.
- The configured Freeze Period — which can be a maximum of 30 days — has passed.
"freezeTokenPayment" : {
"amount": number,
"mint": "<PUBKEY>",
"destinationAta": "<PUBKEY>"
}
Gatekeeper
The Gatekeeper guard validates if the payer of the transaction has a token from a specified gateway network — in most cases, a token after completing a captcha challenge. The expire_on_use
configuration is used to indicate whether or not the token should expire after minting.
"gatekeeper" : {
"gatekeeperNetwork": "<PUBKEY>",
"expireOnUse": boolean
}
Mint Limit
The Mint Limit guard allows to specify a limit on the number of mints for each individual address. The id
configuration represents the unique identification for the limit — changing the id has the effect of restarting the limit, since a different tracking account will be created. The limit
indicates the maximum number of mints allowed.
"mintLimit" : {
"id": number,
"limit": number
}
NFT Burn
The NFT Burn guard restricts the mint to holders of another NFT (token), requiring that the NFT is burned in exchange of being allowed to mint.
"nftBurn" : {
"requiredCollection": "<PUBKEY>",
}
NFT Gate
The NFT Gate guard restricts the mint to holders of a specified requiredCollection
NFT collection. The payer is required to hold at least one NFT of the collection.
"nftGate" : {
"requiredCollection": "<PUBKEY>",
}
NFT Payment
The NFT Payment guard is a payment guard that charges another NFT (token) from a specific collection for the mint. As a requirement of the mint, the specified NFT is transferred to the destination
address.
"nftPayment" : {
"requiredCollection": "<PUBKEY>",
"destination": "<PUBKEY>"
}
Program Gate
The Program Gate guard allows to specify a group of programs (up to 5) that can be present in the same transaction of the mint instruction. This can be used to limit the programs that are allowed to CPI to mint from the Candy Machine.
"programGate" : {
"additional": ["<PUBKEY 1>", "<PUBKEY 2>", ..., "<PUBKEY 5>"],
}
Redeemed Amount
The Redeemed Amount guard stops the mint when the number of items_redeemed
of the Candy Machine reaches the configured maximum
amount.
"redeemedAmount" : {
"maximum": number,
}
Sol Payment
The Sol Payment guard is used to charge an amount in SOL for the mint. The funds are transferred to the configured destination
address.
"solPayment" : {
"value": SOL value,
"destination": "<PUBKEY>"
}
Start Date
The Start Date guard determines the start date of the mint. If this guard is not specified, mint is allowed — similar to say any date is valid.
The date needs to be specified using RFC 3339 standard. In most cases, the format used will be "yyyy-mm-ddT
hh:mm:ssZ
", where T
is the separator between the full-date and full-time and Z
is the timezone offset from UTC (use Z
or +00:00 for UTC time).
"startDate" : {
"date": "string",
}
Third Party Signer
The Third Party Signer guard requires an extra signer on the transaction.
"thirdPartySigner" : {
"signerKey": "<PUBKEY>"
}
Token Burn
The Token Burn guard restricts the mint to holders of a specified SPL Token and requires the burn of the tokens. The amount
determines how many tokens are required.
"tokenBurn" : {
"amount": number,
"mint": "<PUBKEY>"
}
Token Gate
The Token Gate guard restricts the mint to holders of a specified SPL Token. The amount
determines how many tokens are required.
"tokenGate" : {
"amount": number,
"mint": "<PUBKEY>"
}
Token Payment
The Token Payment guard restricts the mint to holders of a specified SPL Token, transferring the required amount to the destinationAta
address. The amount determines how many tokens are required.
"tokenPayment" : {
"amount": number,
"mint": "<PUBKEY>",
"destinationAta": "<PUBKEY>"
}
Token2022 Payment
The Token2022 Payment guard allows minting by charging the payer some tokens from a configured Token-2022 mint account. Both the amount of tokens and the destination address can also be configured.
"token2022Payment" : {
"amount": number,
"mint": "<PUBKEY>",
"destinationAta": "<PUBKEY>"
}
Deployment Commands
The deployment of a Candy Machine V3 follows the same steps:
sugar validate
to verify that all metadata is in place;sugar upload
to upload the metadata to the selected storage;sugar deploy
to create and deploy a Candy Machine;sugar verify
to verify that all information is on-chain.
At this point, your Candy Machine is deployed and allows minting only from the mint authority
, which is the address that created the Candy Machine. The next step is to add a Candy Guard to the Candy Machine to specify the mint configuration (access control).
There are 5 new commands in Sugar to create and interact with a Candy Guard:
add
to create a new candy guard over a candy machine;update
to update the configuration of an existing candy guard;show
to print the current configuration;remove
to remove the candy guard from a candy machine;withdraw
to close a candy guard account and retrieve the rent funds.
add
Once you completed the guards configuration in your Sugar config file, you can add a Candy Guard using:
sugar guard add
Output
[1/3] 🔍 Looking up candy machine
Candy machine ID: 7W9sWpDW4EJBpw2n8oqgJek4LcYDEM1JDPkoTZ7gPn4A
[2/3] 🛡 Initializing a candy guard
Signature: 4fyVi6xj1a5qEzvVubhhNfEX875GFJZLbKfg2q42JLeTxi2pFQEn8GwWFkAWT31z6VxPTecHKRa5ZnKrt31ZCT8Q
Candy guard ID: Bw66NeQ6FF6bnXopiv8hhvXPLaCQR7RC6UEntqVuzhdL
[3/3] 📦 Wrapping
Signature: 4ACcw1g8G4fE7yZdqqAMXrZtBx96W5zERXnyib694FgvKV9y5TLsuKVViKf8D4GN1jhyP1uqkBpLrwpcgN7Mt9hc
The candy guard is now the mint authority of the candy machine.
✅ Command successful.
At this point, sugar mint
will stop working since the mint authority
is now the Candy Guard.
update
To update the Candy Guard configuration, you first need to make the required modification in the Sugar config file and the run the command:
sugar guard update
Output
[1/2] 🔍 Loading candy guard
▪▪▪▪▪ Done
Candy guard ID: Bw66NeQ6FF6bnXopiv8hhvXPLaCQR7RC6UEntqVuzhdL
[2/2] 🖥 Updating configuration
Signature: d8ge5n7rzpeYB68m6VEbJQTYrEmnHo4P3XKXAc5KNYMJnxvq63JegsUMAjMZgBiXAYEqxUrbg9D94D8hT92XH7k
✅ Command successful.
show
To print the on-chain configuration of a Candy Guard, use the command:
sugar guard show
Output
[1/1] 🔍 Loading candy guard
▪▪▪▪▪ Done
🛡 Candy Guard ID: Bw66NeQ6FF6bnXopiv8hhvXPLaCQR7RC6UEntqVuzhdL
:
:.. base: 7z6f7mq7qGjWu6dimqdAyYNhjG5iqGQ7DYnFV2ckpzoY
:.. bump: 255
:.. authority: PanbgtcTiZ2PveV96t2FHSffiLHXXjMuhvoabUUKKm8
:.. data:
:.. default:
: :.. bot tax:
: : :.. lamports: 10000000 (◎ 0.01)
: : :.. last instruction: true
: :.. sol payment: none
: :.. token payment: none
: :.. start date: none
: :.. third party signer: none
: :.. token gate: none
: :.. gatekeeper: none
: :.. end date: none
: :.. allow list: none
: :.. mint limit: none
: :.. nft payment: none
: :.. redeemed amount: none
: :.. address gate: none
: :.. nft gate: none
: :.. nft burn: none
: :.. token burn: none
:
:.. groups:
:.. label: OGslic
: :.. bot tax: none
: :.. sol payment:
: : :.. lamports: 1 (◎ 0.000000001)
: : :.. destination: PanbgtcTiZ2PveV96t2FHSffiLHXXjMuhvoabUUKKm8
: :.. token payment: none
: :.. start date:
: : :.. date: Thu October 20 2022 12:00:00 UTC
: :.. third party signer: none
: :.. token gate:
: : :.. amount: 1000000000
: : :.. mint: 7nE1GmnMmDKiycFkpHF7mKtxt356FQzVonZqBWsTWZNf
: :.. gatekeeper: none
: :.. end date: none
: :.. allow list: none
: :.. mint limit: none
: :.. nft payment: none
: :.. redeemed amount: none
: :.. address gate: none
: :.. nft gate: none
: :.. nft burn: none
: :.. token burn: none
:
:.. label: Public
:.. bot tax: none
:.. sol payment:
: :.. lamports: 2000000000 (◎ 2)
: :.. destination: PanbgtcTiZ2PveV96t2FHSffiLHXXjMuhvoabUUKKm8
:.. token payment: none
:.. start date:
: :.. date: Thu October 20 2022 18:00:00 UTC
:.. third party signer: none
:.. token gate: none
:.. gatekeeper: none
:.. end date: none
:.. allow list: none
:.. mint limit: none
:.. nft payment: none
:.. redeemed amount: none
:.. address gate: none
:.. nft gate: none
:.. nft burn: none
:.. token burn: none
✅ Command successful.
remove
To remove a Candy Guard from a Candy Machine, use the command:
sugar guard remove
Output
[1/1] 🔩 Unwrapping
Signature: 5hbySp2JPuFrdjauDFVu5P4Fa3EkV9pAyqtgqDRs38d6aVwgiSpsBEs33BKQjqPMvdyyteS2W7ApfmcGstRuajNz
The candy guard is no longer the mint authority of the candy machine.
-> New mint authority: PanbgtcTiZ2PveV96t2FHSffiLHXXjMuhvoabUUKKm8
✅ Command successful.
At this point, the mint authority
is transferred back to the Candy Machine authority
. The Candy Guard account remains on-chain and can be reused.
withdraw
To close the Candy Guard account and retrieve the rent fee, use the command:
sugar guard withdraw
Output
[1/2] 🔍 Loading candy guard
▪▪▪▪▪ Done
[2/2] 🏧 Retrieving funds
Signature: Yfm2kBbs5kygRzH6QDDTXyx2wxqGZ6P6RkTAHEMkHJ7PvpCZKUu2akkZBDHYfdy1TNyUPLywuNSJoPGWAmTSRuK
Received ◎ 0.00268656 from rent fee.
✅ Command successful.