From 4ed4af9219735f13b81f0deb1923a7c663768455 Mon Sep 17 00:00:00 2001 From: ASCorreia <36857753+ASCorreia@users.noreply.github.com> Date: Thu, 26 Dec 2024 14:01:30 +0000 Subject: [PATCH 01/10] Added Candy Machine with hidden settings guide --- ...core-candy-machine-with-hidden-settings.md | 314 ++++++++++++++++++ 1 file changed, 314 insertions(+) create mode 100644 src/pages/core-candy-machine/guides/create-a-core-candy-machine-with-hidden-settings.md diff --git a/src/pages/core-candy-machine/guides/create-a-core-candy-machine-with-hidden-settings.md b/src/pages/core-candy-machine/guides/create-a-core-candy-machine-with-hidden-settings.md new file mode 100644 index 00000000..1dc8a271 --- /dev/null +++ b/src/pages/core-candy-machine/guides/create-a-core-candy-machine-with-hidden-settings.md @@ -0,0 +1,314 @@ +--- +title: Create a Core Candy Machine with Hidden Settings +metaTitle: Create a Core Candy Machine with Hidden Settings | Core Candy Machine +description: How to create a Core Candy Machine with hidden settings to create a hide-and-reveal NFT drop. +--- + +If you are looking to create a hide-and-reveal NFT drop, you can use Core Candy Machine to achieve that goal. +A hide-and-reveal NFT drop can be useful when you want to reveal all the NFTs after they have been minted. + +How this works, is that you Core Candy Machine will have a hidden settings field, that will contain a hash of the metadata of the revealed NFTs +Every NFT that will be minted pre-reveal will have the same name and URI. After the collection has been minted, the assets will be updated with the correct name and URI + +This guide focuses on the core Candy Machine functionality and interactions, rather than providing a complete website implementation. It will not cover aspects like adding buttons to a website or integrating with a wallet adapter. Instead, it provides essential information on working with the Core Candy Machine. + +For a full website implementation, including UI elements and wallet integration, you may want to start with a template like the [`metaplex-nextjs-tailwind-template`](https://github.com/metaplex-foundation/metaplex-nextjs-tailwind-template). This template includes many setup steps for components like the Wallet Adapter. + +If you're looking for guidance on general web development practices or how to use specific frameworks, tools like Visual Studio Code offer extensive documentation and community resources. + +## Prerequisites + +- Basic familiarity with web development and your chosen framework. We recommend Next JS for easiest compatibility to umi. + +## Required Packages + +Regardless of your chosen template or implementation, you'll need to install the following packages for interacting with the Core Candy Machine: + +{% packagesUsed packages=["umi", "umiDefaults", "core", "candyMachineCore", "mpl-toolbox"] type="npm" /%} + +```ts +npm i @metaplex-foundation/umi @metaplex-foundation/umi-bundle-defaults @metaplex-foundation/mpl-core-candy-machine +``` + +## Setting up umi + +After setting up your environment, let's start by setting up umi: + +```ts +import { createUmi } from "@metaplex-foundation/umi-bundle-defaults"; +import { generateSigner, some, none, createSignerFromKeypair, signerIdentity, transactionBuilder, dateTime } from "@metaplex-foundation/umi"; +import { mplCandyMachine as mplCoreCandyMachine } from '@metaplex-foundation/mpl-core-candy-machine'; +import wallet from "../wallet.json"; + +const umi = createUmi("https://api.devnet.solana.com") + .use(mplCoreCandyMachine()); + +let keypair = umi.eddsa.createKeypairFromSecretKey(new Uint8Array(wallet)); +const signer = createSignerFromKeypair(umi, keypair); +console.log("Signer: ", signer.publicKey); + +umi.use(signerIdentity(signer)); +``` + +It can also make sense to fetch additional data that is not shown to the user but used in background calculations. For example, when using the [Redeemed Amount](/core-candy-machine/guards/redeemed-amount) Guard, you would want to fetch the already redeemed amount to see if the user is allowed to mint more. + +### Prepare Reveal Data +Let's now prepare the reveal data, that will contain the metadata that will be updated to the NFT upon reveal. + +```ts +import crypto from 'crypto'; + +const revealData = [ + { name: 'Nft #1', uri: 'http://example.com/1.json' }, + { name: 'Nft #2', uri: 'http://example.com/2.json' }, + { name: 'Nft #3', uri: 'http://example.com/3.json' }, + { name: 'Nft #4', uri: 'http://example.com/4.json' }, + { name: 'Nft #5', uri: 'http://example.com/5.json' }, + ] + +let string = JSON.stringify(revealData) +let hash = crypto.createHash('sha256').update(string).digest() +``` + +Here, we just created an array with 5 different attributes that will be updated into our revealed NFTs + +### Create a collection + +```ts +import { createCollection, ruleSet } from '@metaplex-foundation/mpl-core'; + +const collectionMint = generateSigner(umi); +const collectionUpdateAuthority = generateSigner(umi); + +const creator1 = generateSigner(umi).publicKey; +const creator2 = generateSigner(umi).publicKey; + +console.log("collection update authority: ", collectionUpdateAuthority.publicKey); +await createCollection(umi, { + collection: collectionMint, + updateAuthority: collectionUpdateAuthority.publicKey, + name: 'My NFT', + uri: 'https://example.com/my-nft.json', + plugins: [ + { + type: 'Royalties', + basisPoints: 500, + creators: [ + { + address: creator1, + percentage: 20, + }, + { + address: creator2, + percentage: 80, + }, + ], + ruleSet: ruleSet('None'), + }, + ], +}).sendAndConfirm(umi) +``` + +Let's now fetch our created collection and print the details of it + +```ts +import { fetchCollection } from '@metaplex-foundation/mpl-core'; + +const collection = await fetchCollection(umi, collectionMint.publicKey); + +console.log("Collection Details: \n", collection); +``` + +### Create a Core Candy Machine with Hidden Settings + +```ts +import { create } from '@metaplex-foundation/mpl-core-candy-machine'; + +const candyMachine = generateSigner(umi); + +const res = await create(umi, { + candyMachine, + collection: collectionMint.publicKey, + collectionUpdateAuthority: collectionUpdateAuthority, + authority: umi.identity.publicKey, + itemsAvailable: 5, + configLineSettings: none(), + hiddenSettings: some({ + name: 'My Hidden NFT Project', + uri: 'https://example.com/path/to/teaser.json', + hash: hash, + }), + guards: { + startDate: some({ date: dateTime('2023-04-04T16:00:00Z') }), + } +}); +let tx = await res.sendAndConfirm(umi); +``` + +Let's now fetch our created candy machine and print the details of it + +```ts +import { fetchCandyMachine } from '@metaplex-foundation/mpl-core-candy-machine'; + +let candyMachineDetails = await fetchCandyMachine(umi, candyMachine.publicKey); + +console.log("Candy Machine Details: \n", candyMachineDetails); +``` + +This would return the Candy Machine Data like this: + +```json +{ + "publicKey": "FVQYpQxtT4ZqCmq3MNiWY1mZcEJsVA6DaaW6bMhERoVY", + "header": { + "executable": false, + "owner": "CMACYFENjoBMHzapRXyo1JZkVS6EtaDDzkjMrmQLvr4J", + "lamports": { "basisPoints": 5428800, "identifier": "SOL", "decimals": 9 }, + "rentEpoch": 18446744073709551616, + "exists": true + }, + "discriminator": [ + 51, 173, 177, 113, + 25, 241, 109, 189 + ], + "authority": "Cce2qGViiD1SqAiJMDJVJQrGfxcb3DMyLgyhaqYB8uZr", + "mintAuthority": "4P6VhHmNi9Qt5eRuQsE9SaE5bYWoLxpdPwmfNZeiU2mv", + "collectionMint": "3RLCk7G2ckGHt7XPNfzUYKLriME2BmMoumF8N4H5LvsS", + "itemsRedeemed": 0, + "data": { + "itemsAvailable": 5, + "maxEditionSupply": 0, + "isMutable": true, + "configLineSettings": { "__option": "None" }, + "hiddenSettings": { "__option": "Some", "value": "[Object]" } + }, + "items": [], + "itemsLoaded": 0 +} +Candy Guard Account: + { + "publicKey": "4P6VhHmNi9Qt5eRuQsE9SaE5bYWoLxpdPwmfNZeiU2mv", + "header": { + "executable": false, + "owner": "CMAGAKJ67e9hRZgfC5SFTbZH8MgEmtqazKXjmkaJjWTJ", + "lamports": { "basisPoints": 1538160, "identifier": "SOL", "decimals": 9 }, + "rentEpoch": 18446744073709551616, + "exists": true + }, + "discriminator": [ + 44, 207, 199, 184, + 112, 103, 34, 181 + ], + "base": "FVQYpQxtT4ZqCmq3MNiWY1mZcEJsVA6DaaW6bMhERoVY", + "bump": 251, + "authority": "Cce2qGViiD1SqAiJMDJVJQrGfxcb3DMyLgyhaqYB8uZr", + "guards": { + "botTax": { "__option": "None" }, + "solPayment": { "__option": "None" }, + "tokenPayment": { "__option": "None" }, + "startDate": { "__option": "Some", "value": "[Object]" }, + "thirdPartySigner": { "__option": "None" }, + "tokenGate": { "__option": "None" }, + "gatekeeper": { "__option": "None" }, + "endDate": { "__option": "None" }, + "allowList": { "__option": "None" }, + "mintLimit": { "__option": "None" }, + "nftPayment": { "__option": "None" }, + "redeemedAmount": { "__option": "None" }, + "addressGate": { "__option": "None" }, + "nftGate": { "__option": "None" }, + "nftBurn": { "__option": "None" }, + "tokenBurn": { "__option": "None" }, + "freezeSolPayment": { "__option": "None" }, + "freezeTokenPayment": { "__option": "None" }, + "programGate": { "__option": "None" }, + "allocation": { "__option": "None" }, + "token2022Payment": { "__option": "None" }, + "solFixedFee": { "__option": "None" }, + "nftMintLimit": { "__option": "None" }, + "edition": { "__option": "None" }, + "assetPayment": { "__option": "None" }, + "assetBurn": { "__option": "None" }, + "assetMintLimit": { "__option": "None" }, + "assetBurnMulti": { "__option": "None" }, + "assetPaymentMulti": { "__option": "None" }, + "assetGate": { "__option": "None" }, + "vanityMint": { "__option": "None" }, + }, + "groups": [] +} +``` + +### Mint the collection + +Let's now mint the 5 NFTs from our Core Candy Machine + +```ts +import { mintV1 } from '@metaplex-foundation/mpl-core-candy-machine'; + +const nftMint = [ + generateSigner(umi), + generateSigner(umi), + generateSigner(umi), + generateSigner(umi), + generateSigner(umi), +]; + +for(let i = 0; i < nftMint.length; i++) { + let mintNFT = await transactionBuilder() + .add(setComputeUnitLimit(umi, { units: 800_000 })) + .add( + mintV1(umi, { + candyMachine: candyMachine.publicKey, + asset: nftMint[i], + collection: collectionMint.publicKey, + }) + ).sendAndConfirm(umi); + + console.log("NFT minted!"); +}; +``` + +### Reveal the Collection + +Let's now reveal the collection + +```ts +import { fetchAssetsByCollection } from '@metaplex-foundation/mpl-core'; + +candyMachineDetails = await fetchCandyMachine(umi, candyMachine.publicKey); +assert(candyMachineDetails.data.itemsAvailable == candyMachineDetails.itemsRedeemed); + +let collectionDetails = await fetchCollection(umi, collectionMint.publicKey); +let collectionAssets = await fetchAssetsByCollection(umi,collectionMint.publicKey); + +for(let i = 0; i < candyMachineDetails.itemsRedeemed; i++) { + await update(umi, { + asset: collectionAssets[i], + collection: collectionDetails, + authority: collectionUpdateAuthority, + name: revealData[i].name, + uri: revealData[i].uri, + }).sendAndConfirm(umi); + + console.log("NFT revealed"); +} +``` + +### Confirm the hidden settings + +```ts +let fetchedAssets = []; + +collectionAssets = await fetchAssetsByCollection(umi,collectionMint.publicKey); +for(let i = 0; i < collectionAssets.length; i++) { + fetchedAssets[i] = {name: collectionAssets[i].name, uri: collectionAssets[i].uri}; +} + +console.log(revealData); +console.log(fetchedAssets); + +let string2 = JSON.stringify(fetchedAssets); +let hash2 = crypto.createHash('sha256').update(string2).digest(); +assert(hash == hash2); +``` From 09566f9c55923c49a6114c44d4f65d3ee2840b57 Mon Sep 17 00:00:00 2001 From: ASCorreia <36857753+ASCorreia@users.noreply.github.com> Date: Thu, 26 Dec 2024 14:05:51 +0000 Subject: [PATCH 02/10] minor changes --- ...core-candy-machine-with-hidden-settings.md | 37 +++++++++++++------ 1 file changed, 25 insertions(+), 12 deletions(-) diff --git a/src/pages/core-candy-machine/guides/create-a-core-candy-machine-with-hidden-settings.md b/src/pages/core-candy-machine/guides/create-a-core-candy-machine-with-hidden-settings.md index 1dc8a271..89c9c628 100644 --- a/src/pages/core-candy-machine/guides/create-a-core-candy-machine-with-hidden-settings.md +++ b/src/pages/core-candy-machine/guides/create-a-core-candy-machine-with-hidden-settings.md @@ -12,9 +12,6 @@ Every NFT that will be minted pre-reveal will have the same name and URI. After This guide focuses on the core Candy Machine functionality and interactions, rather than providing a complete website implementation. It will not cover aspects like adding buttons to a website or integrating with a wallet adapter. Instead, it provides essential information on working with the Core Candy Machine. -For a full website implementation, including UI elements and wallet integration, you may want to start with a template like the [`metaplex-nextjs-tailwind-template`](https://github.com/metaplex-foundation/metaplex-nextjs-tailwind-template). This template includes many setup steps for components like the Wallet Adapter. - -If you're looking for guidance on general web development practices or how to use specific frameworks, tools like Visual Studio Code offer extensive documentation and community resources. ## Prerequisites @@ -50,10 +47,8 @@ console.log("Signer: ", signer.publicKey); umi.use(signerIdentity(signer)); ``` -It can also make sense to fetch additional data that is not shown to the user but used in background calculations. For example, when using the [Redeemed Amount](/core-candy-machine/guards/redeemed-amount) Guard, you would want to fetch the already redeemed amount to see if the user is allowed to mint more. - ### Prepare Reveal Data -Let's now prepare the reveal data, that will contain the metadata that will be updated to the NFT upon reveal. +Let's now prepare the reveal data. This will basically contain the name and the URI, that will be used to update our collection assets once they are minted. ```ts import crypto from 'crypto'; @@ -70,9 +65,13 @@ let string = JSON.stringify(revealData) let hash = crypto.createHash('sha256').update(string).digest() ``` -Here, we just created an array with 5 different attributes that will be updated into our revealed NFTs +Here, we just created an array with 5 different elements since our Core Candy Machine will have 5 assets available. + +We also created an hash of all the elements, that will be used to configure our Core Candy Machine. -### Create a collection +### Create a Collection + +Let's now create a Collection asset. For that, the mpl-core library provides a `createCollection` method will help us performing that action ```ts import { createCollection, ruleSet } from '@metaplex-foundation/mpl-core'; @@ -109,6 +108,8 @@ await createCollection(umi, { }).sendAndConfirm(umi) ``` +We added a plugin of type `Royalties` and added 2 different creators that will share those royalties + Let's now fetch our created collection and print the details of it ```ts @@ -145,7 +146,7 @@ const res = await create(umi, { let tx = await res.sendAndConfirm(umi); ``` -Let's now fetch our created candy machine and print the details of it +Let's now fetch our created candy machine and print the details of it. To achieve that, we will use the `fetchCandyMachine` method from the mpl-core-candy-machine library ```ts import { fetchCandyMachine } from '@metaplex-foundation/mpl-core-candy-machine'; @@ -185,7 +186,7 @@ This would return the Candy Machine Data like this: "items": [], "itemsLoaded": 0 } -Candy Guard Account: +"Candy Guard Account": { "publicKey": "4P6VhHmNi9Qt5eRuQsE9SaE5bYWoLxpdPwmfNZeiU2mv", "header": { @@ -239,6 +240,8 @@ Candy Guard Account: } ``` +As you can see, it also prints the Candy Guard Account where we can check that actually only the `startDate` is set, as intended. + ### Mint the collection Let's now mint the 5 NFTs from our Core Candy Machine @@ -271,10 +274,14 @@ for(let i = 0; i < nftMint.length; i++) { ### Reveal the Collection -Let's now reveal the collection +Let's now reveal the collection. + +To reveal the collection, we will fetch the collection assets using the `fetchAssetsByCollection` method and will update those assets by invoking the method `update` with the `revealData` that we prepared in the beggining of this guide. + +As we only want to reveal our assets after all items have been minted, we will fetch the Core Candy Machine details and make sure that the items available are the same as the items redeemed. This unsures us that all assets have been minted ```ts -import { fetchAssetsByCollection } from '@metaplex-foundation/mpl-core'; +import { update, fetchAssetsByCollection } from '@metaplex-foundation/mpl-core'; candyMachineDetails = await fetchCandyMachine(umi, candyMachine.publicKey); assert(candyMachineDetails.data.itemsAvailable == candyMachineDetails.itemsRedeemed); @@ -297,6 +304,12 @@ for(let i = 0; i < candyMachineDetails.itemsRedeemed; i++) { ### Confirm the hidden settings +Now that the we revealed our assets, it is time to confirm that the assets are indeed the intended ones. + +For that, we will again fetch the assets of our collections, but this time we will save the name and the URI of every single one of them. + +After that, we will log both arrays (`revealData` and `fetchedAssets`) and will also hash the `fetchedAssets` data and compare to the initial hash + ```ts let fetchedAssets = []; From d5266f9e43a24a63126d99b08879b10f73c9d831 Mon Sep 17 00:00:00 2001 From: ASCorreia <36857753+ASCorreia@users.noreply.github.com> Date: Thu, 26 Dec 2024 14:12:27 +0000 Subject: [PATCH 03/10] minor changes --- .../create-a-core-candy-machine-with-hidden-settings.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/pages/core-candy-machine/guides/create-a-core-candy-machine-with-hidden-settings.md b/src/pages/core-candy-machine/guides/create-a-core-candy-machine-with-hidden-settings.md index 89c9c628..695648fd 100644 --- a/src/pages/core-candy-machine/guides/create-a-core-candy-machine-with-hidden-settings.md +++ b/src/pages/core-candy-machine/guides/create-a-core-candy-machine-with-hidden-settings.md @@ -122,6 +122,12 @@ console.log("Collection Details: \n", collection); ### Create a Core Candy Machine with Hidden Settings +Next step is to create our Core Candy Machine with the Hidden Settings. + +To achieve that, we will use the `create` method from the mpl-core-candy-machine library, and we will set the `hiddenSettings` with the name and URI that all the assets will be minted with. We also pass the hash that was previously calculated from the `revealData` + +We will also add a `startDate` guard. You can find the list of all available guards here. + ```ts import { create } from '@metaplex-foundation/mpl-core-candy-machine'; @@ -140,7 +146,7 @@ const res = await create(umi, { hash: hash, }), guards: { - startDate: some({ date: dateTime('2023-04-04T16:00:00Z') }), + startDate: some({ date: dateTime('2024-01-01T16:00:00Z') }), } }); let tx = await res.sendAndConfirm(umi); From a9e84a4414e6f617e750d42d2dec31235d70c091 Mon Sep 17 00:00:00 2001 From: ASCorreia <36857753+ASCorreia@users.noreply.github.com> Date: Thu, 26 Dec 2024 14:18:50 +0000 Subject: [PATCH 04/10] minor changes --- ...eate-a-core-candy-machine-with-hidden-settings.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/pages/core-candy-machine/guides/create-a-core-candy-machine-with-hidden-settings.md b/src/pages/core-candy-machine/guides/create-a-core-candy-machine-with-hidden-settings.md index 695648fd..08acefc9 100644 --- a/src/pages/core-candy-machine/guides/create-a-core-candy-machine-with-hidden-settings.md +++ b/src/pages/core-candy-machine/guides/create-a-core-candy-machine-with-hidden-settings.md @@ -331,3 +331,15 @@ let string2 = JSON.stringify(fetchedAssets); let hash2 = crypto.createHash('sha256').update(string2).digest(); assert(hash == hash2); ``` + +### And that is it +Congrats! You just created your Core Candy Machine with hiddens settings. + +Let's revise all that we did: +- We started by setting up UMI +- After setting up UMI, we create an array with the data that will be used to update our assets after the initial mint +- We created a Collection asset to where our minted assets will beling to +- We create a Core Candy Machine with hidden setting, 5 items available, and a start time guard +- We minted all the assets from out Core Candy Machine +- We fetched all the assets of our collection and updated those assets with our reveal data +- We confirmed that the reveal of our collection was correct \ No newline at end of file From 31588f7ac2db1d3860c07976eb56d31922ffa7bc Mon Sep 17 00:00:00 2001 From: ASCorreia <36857753+ASCorreia@users.noreply.github.com> Date: Sun, 29 Dec 2024 01:25:57 +0000 Subject: [PATCH 05/10] minor changes --- ...core-candy-machine-with-hidden-settings.md | 20 +++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/src/pages/core-candy-machine/guides/create-a-core-candy-machine-with-hidden-settings.md b/src/pages/core-candy-machine/guides/create-a-core-candy-machine-with-hidden-settings.md index 08acefc9..147fac8e 100644 --- a/src/pages/core-candy-machine/guides/create-a-core-candy-machine-with-hidden-settings.md +++ b/src/pages/core-candy-machine/guides/create-a-core-candy-machine-with-hidden-settings.md @@ -7,10 +7,12 @@ description: How to create a Core Candy Machine with hidden settings to create a If you are looking to create a hide-and-reveal NFT drop, you can use Core Candy Machine to achieve that goal. A hide-and-reveal NFT drop can be useful when you want to reveal all the NFTs after they have been minted. -How this works, is that you Core Candy Machine will have a hidden settings field, that will contain a hash of the metadata of the revealed NFTs +How this works, is that you Core Candy Machine will have a hidden settings field, that will contain some basic metadata (name and URI) that will be the same to all the minted assets and a hash of the metadata of the revealed NFTs Every NFT that will be minted pre-reveal will have the same name and URI. After the collection has been minted, the assets will be updated with the correct name and URI -This guide focuses on the core Candy Machine functionality and interactions, rather than providing a complete website implementation. It will not cover aspects like adding buttons to a website or integrating with a wallet adapter. Instead, it provides essential information on working with the Core Candy Machine. +After minting our collection, we will perform a reveal process where we will update the assets with the proper metadata. + +To ensure that the assets were correctly updated, we will perform a validation process where we will check the name and URI of the updated assets, hash it, and compare it with the previously calculated hash ## Prerequisites @@ -29,7 +31,7 @@ npm i @metaplex-foundation/umi @metaplex-foundation/umi-bundle-defaults @metaple ## Setting up umi -After setting up your environment, let's start by setting up umi: +After setting up your environment, let's start by setting up umi ```ts import { createUmi } from "@metaplex-foundation/umi-bundle-defaults"; @@ -37,9 +39,11 @@ import { generateSigner, some, none, createSignerFromKeypair, signerIdentity, tr import { mplCandyMachine as mplCoreCandyMachine } from '@metaplex-foundation/mpl-core-candy-machine'; import wallet from "../wallet.json"; +// We will be using Solana Devnet as endpoint, and loading the mplCoreCandyMachine plugin const umi = createUmi("https://api.devnet.solana.com") .use(mplCoreCandyMachine()); +// Let's create a Keypair from our wallet json file that contains a secret key, and create a signer based on the created keypair let keypair = umi.eddsa.createKeypairFromSecretKey(new Uint8Array(wallet)); const signer = createSignerFromKeypair(umi, keypair); console.log("Signer: ", signer.publicKey); @@ -48,7 +52,11 @@ umi.use(signerIdentity(signer)); ``` ### Prepare Reveal Data -Let's now prepare the reveal data. This will basically contain the name and the URI, that will be used to update our collection assets once they are minted. +Let's now prepare the reveal data. This will basically contain the name and the URI, that will be used to update our collection assets once they are minted. + +We will create an array with 5 different elements since our Core Candy Machine will have 5 assets available. + +We will also create an hash of all the elements, that will be used to configure our Core Candy Machine. ```ts import crypto from 'crypto'; @@ -65,10 +73,6 @@ let string = JSON.stringify(revealData) let hash = crypto.createHash('sha256').update(string).digest() ``` -Here, we just created an array with 5 different elements since our Core Candy Machine will have 5 assets available. - -We also created an hash of all the elements, that will be used to configure our Core Candy Machine. - ### Create a Collection Let's now create a Collection asset. For that, the mpl-core library provides a `createCollection` method will help us performing that action From 3b377f4ede2d245fb6193ae9ced89cdc76e60a52 Mon Sep 17 00:00:00 2001 From: ASCorreia <36857753+ASCorreia@users.noreply.github.com> Date: Sun, 29 Dec 2024 02:24:55 +0000 Subject: [PATCH 06/10] minor changes --- ...core-candy-machine-with-hidden-settings.md | 45 ++++++++++--------- 1 file changed, 25 insertions(+), 20 deletions(-) diff --git a/src/pages/core-candy-machine/guides/create-a-core-candy-machine-with-hidden-settings.md b/src/pages/core-candy-machine/guides/create-a-core-candy-machine-with-hidden-settings.md index 147fac8e..ebe170e2 100644 --- a/src/pages/core-candy-machine/guides/create-a-core-candy-machine-with-hidden-settings.md +++ b/src/pages/core-candy-machine/guides/create-a-core-candy-machine-with-hidden-settings.md @@ -7,12 +7,14 @@ description: How to create a Core Candy Machine with hidden settings to create a If you are looking to create a hide-and-reveal NFT drop, you can use Core Candy Machine to achieve that goal. A hide-and-reveal NFT drop can be useful when you want to reveal all the NFTs after they have been minted. -How this works, is that you Core Candy Machine will have a hidden settings field, that will contain some basic metadata (name and URI) that will be the same to all the minted assets and a hash of the metadata of the revealed NFTs +In this guide, we’ll walk you through the step-by-step process of setting up, minting, revealing, and validating your hide-and-reveal NFT drop using Core Candy Machine. Whether you’re an experienced developer or new to NFT drops, this guide will provide you with everything you need + +How this works, is that when setting up your Core Candy Machine, you’ll configure the hidden settings field. This field will contain placeholder metadata (generic name and URI) that will be applied to all minted NFTs prior to the reveal. Additionally, it includes a pre-calculated hash of the metadata. Every NFT that will be minted pre-reveal will have the same name and URI. After the collection has been minted, the assets will be updated with the correct name and URI After minting our collection, we will perform a reveal process where we will update the assets with the proper metadata. -To ensure that the assets were correctly updated, we will perform a validation process where we will check the name and URI of the updated assets, hash it, and compare it with the previously calculated hash +To ensure that the assets were correctly updated, a validation step is performed. This involves hashing the updated metadata (name and URI) of the revealed assets and comparing it with the original hash stored in the hidden settings. This ensures that every NFT has been updated accurately. ## Prerequisites @@ -52,11 +54,11 @@ umi.use(signerIdentity(signer)); ``` ### Prepare Reveal Data -Let's now prepare the reveal data. This will basically contain the name and the URI, that will be used to update our collection assets once they are minted. +Now, let’s prepare the reveal data, which will include the metadata for the final revealed NFTs. This data contains the name and URI for each NFT in the collection and will be used to update the placeholder metadata after minting. -We will create an array with 5 different elements since our Core Candy Machine will have 5 assets available. +In this example, we will work with a collection of five assets, so our reveal data will include an array of five objects, each representing an individual NFT’s name and URI. -We will also create an hash of all the elements, that will be used to configure our Core Candy Machine. +We’ll also generate a hash of the reveal data. This hash will be stored in the hidden settings of the Core Candy Machine and used during the validation step to confirm that the metadata was updated correctly. ```ts import crypto from 'crypto'; @@ -75,7 +77,8 @@ let hash = crypto.createHash('sha256').update(string).digest() ### Create a Collection -Let's now create a Collection asset. For that, the mpl-core library provides a `createCollection` method will help us performing that action +Let's now create a Collection asset. +For that, the mpl-core library provides a `createCollection` method will help us performing that action ```ts import { createCollection, ruleSet } from '@metaplex-foundation/mpl-core'; @@ -128,9 +131,9 @@ console.log("Collection Details: \n", collection); Next step is to create our Core Candy Machine with the Hidden Settings. -To achieve that, we will use the `create` method from the mpl-core-candy-machine library, and we will set the `hiddenSettings` with the name and URI that all the assets will be minted with. We also pass the hash that was previously calculated from the `revealData` +To achieve that, we will use the `create` method from the mpl-core-candy-machine library, and we will set the `hiddenSettings` with the placeholder name, URI, and pre-calculated hash from the `revealData` -We will also add a `startDate` guard. You can find the list of all available guards here. +Additionally, we’ll configure a startDate guard, which determines when minting begins. This is only one of the many guards available and you can find the list of all available guards here. ```ts import { create } from '@metaplex-foundation/mpl-core-candy-machine'; @@ -141,7 +144,6 @@ const res = await create(umi, { candyMachine, collection: collectionMint.publicKey, collectionUpdateAuthority: collectionUpdateAuthority, - authority: umi.identity.publicKey, itemsAvailable: 5, configLineSettings: none(), hiddenSettings: some({ @@ -156,7 +158,8 @@ const res = await create(umi, { let tx = await res.sendAndConfirm(umi); ``` -Let's now fetch our created candy machine and print the details of it. To achieve that, we will use the `fetchCandyMachine` method from the mpl-core-candy-machine library +Let's now fetch our created candy machine and print the details of it. +To achieve that, we will use the `fetchCandyMachine` method from the mpl-core-candy-machine library ```ts import { fetchCandyMachine } from '@metaplex-foundation/mpl-core-candy-machine'; @@ -256,6 +259,8 @@ As you can see, it also prints the Candy Guard Account where we can check that a Let's now mint the 5 NFTs from our Core Candy Machine +All these minted assets will have the placeholder name and URI that we set in the `hiddenSettings` field of the Core Candy machine that we created + ```ts import { mintV1 } from '@metaplex-foundation/mpl-core-candy-machine'; @@ -286,9 +291,9 @@ for(let i = 0; i < nftMint.length; i++) { Let's now reveal the collection. -To reveal the collection, we will fetch the collection assets using the `fetchAssetsByCollection` method and will update those assets by invoking the method `update` with the `revealData` that we prepared in the beggining of this guide. +To reveal the collection, we will fetch the collection assets using the `fetchAssetsByCollection` method and will update those same minted assets by invoking the method `update` with the `revealData` that we prepared in the beggining of this guide. -As we only want to reveal our assets after all items have been minted, we will fetch the Core Candy Machine details and make sure that the items available are the same as the items redeemed. This unsures us that all assets have been minted +As we only want to reveal our assets after all items have been minted, we will validate the mint completion by fetching the Core Candy Machine details and making sure that the items available are the same as the items redeemed. This unsures us that all assets have been minted ```ts import { update, fetchAssetsByCollection } from '@metaplex-foundation/mpl-core'; @@ -312,13 +317,13 @@ for(let i = 0; i < candyMachineDetails.itemsRedeemed; i++) { } ``` -### Confirm the hidden settings +### Validation of the revealed assets Now that the we revealed our assets, it is time to confirm that the assets are indeed the intended ones. -For that, we will again fetch the assets of our collections, but this time we will save the name and the URI of every single one of them. +For that, we will again fetch the assets of our collection and, for each asset, we will extract the name and URI and store them in a new array. -After that, we will log both arrays (`revealData` and `fetchedAssets`) and will also hash the `fetchedAssets` data and compare to the initial hash +After that, we will log both arrays (`revealData` and `fetchedAssets`) to help visualize and verify that the metadata has been updated as expected and will also hash the `fetchedAssets` data and compare to the initial hash ```ts let fetchedAssets = []; @@ -341,9 +346,9 @@ Congrats! You just created your Core Candy Machine with hiddens settings. Let's revise all that we did: - We started by setting up UMI -- After setting up UMI, we create an array with the data that will be used to update our assets after the initial mint -- We created a Collection asset to where our minted assets will beling to +- After setting up UMI, we created an array containing the metadata (name and URI) that would be used to update the assets after the initial mint. This included calculating a hash for validation purposes. +- We created a Collection asset to where our minted assets will belong to - We create a Core Candy Machine with hidden setting, 5 items available, and a start time guard -- We minted all the assets from out Core Candy Machine -- We fetched all the assets of our collection and updated those assets with our reveal data -- We confirmed that the reveal of our collection was correct \ No newline at end of file +- We minted all the assets from our Core Candy Machine +- After verifying that all assets were minted, we fetched the collection assets and updated their metadata with the prepared reveal data. +- We confirmed that the reveal of our collection was correct by hashing the metadata (name and URI) of the revealed assets and comparing it to the expected hash \ No newline at end of file From a6b184126f02c0e2a7341c0cf3c31cb950d52479 Mon Sep 17 00:00:00 2001 From: ASCorreia <36857753+ASCorreia@users.noreply.github.com> Date: Mon, 30 Dec 2024 01:27:48 +0000 Subject: [PATCH 07/10] minor changes --- .../create-a-core-candy-machine-with-hidden-settings.md | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/pages/core-candy-machine/guides/create-a-core-candy-machine-with-hidden-settings.md b/src/pages/core-candy-machine/guides/create-a-core-candy-machine-with-hidden-settings.md index ebe170e2..f60bbe9a 100644 --- a/src/pages/core-candy-machine/guides/create-a-core-candy-machine-with-hidden-settings.md +++ b/src/pages/core-candy-machine/guides/create-a-core-candy-machine-with-hidden-settings.md @@ -16,14 +16,9 @@ After minting our collection, we will perform a reveal process where we will upd To ensure that the assets were correctly updated, a validation step is performed. This involves hashing the updated metadata (name and URI) of the revealed assets and comparing it with the original hash stored in the hidden settings. This ensures that every NFT has been updated accurately. - -## Prerequisites - -- Basic familiarity with web development and your chosen framework. We recommend Next JS for easiest compatibility to umi. - ## Required Packages -Regardless of your chosen template or implementation, you'll need to install the following packages for interacting with the Core Candy Machine: +You'll need to install the following packages for interacting with the Core Candy Machine: {% packagesUsed packages=["umi", "umiDefaults", "core", "candyMachineCore", "mpl-toolbox"] type="npm" /%} From 4a444125a4693e3285354b2e3cb98e057a6b17c1 Mon Sep 17 00:00:00 2001 From: ASCorreia <36857753+ASCorreia@users.noreply.github.com> Date: Mon, 30 Dec 2024 01:55:03 +0000 Subject: [PATCH 08/10] added reference links --- ...-core-candy-machine-with-hidden-settings.md | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/pages/core-candy-machine/guides/create-a-core-candy-machine-with-hidden-settings.md b/src/pages/core-candy-machine/guides/create-a-core-candy-machine-with-hidden-settings.md index f60bbe9a..53948fbe 100644 --- a/src/pages/core-candy-machine/guides/create-a-core-candy-machine-with-hidden-settings.md +++ b/src/pages/core-candy-machine/guides/create-a-core-candy-machine-with-hidden-settings.md @@ -75,6 +75,8 @@ let hash = crypto.createHash('sha256').update(string).digest() Let's now create a Collection asset. For that, the mpl-core library provides a `createCollection` method will help us performing that action +You can learn more about collections [here](https://developers.metaplex.com/core/collections) + ```ts import { createCollection, ruleSet } from '@metaplex-foundation/mpl-core'; @@ -128,7 +130,7 @@ Next step is to create our Core Candy Machine with the Hidden Settings. To achieve that, we will use the `create` method from the mpl-core-candy-machine library, and we will set the `hiddenSettings` with the placeholder name, URI, and pre-calculated hash from the `revealData` -Additionally, we’ll configure a startDate guard, which determines when minting begins. This is only one of the many guards available and you can find the list of all available guards here. +Additionally, we’ll configure a startDate guard, which determines when minting begins. This is only one of the many guards available and you can find the list of all available guards [here](https://developers.metaplex.com/candy-machine/guards). ```ts import { create } from '@metaplex-foundation/mpl-core-candy-machine'; @@ -252,9 +254,11 @@ As you can see, it also prints the Candy Guard Account where we can check that a ### Mint the collection -Let's now mint the 5 NFTs from our Core Candy Machine +Let's now mint the 5 NFTs from our Core Candy Machine. + +All these minted assets will have the placeholder name and URI that we set in the `hiddenSettings` field of the Core Candy machine that we created. -All these minted assets will have the placeholder name and URI that we set in the `hiddenSettings` field of the Core Candy machine that we created +These placeholder elements will be updated during the reveal process ```ts import { mintV1 } from '@metaplex-foundation/mpl-core-candy-machine'; @@ -288,7 +292,7 @@ Let's now reveal the collection. To reveal the collection, we will fetch the collection assets using the `fetchAssetsByCollection` method and will update those same minted assets by invoking the method `update` with the `revealData` that we prepared in the beggining of this guide. -As we only want to reveal our assets after all items have been minted, we will validate the mint completion by fetching the Core Candy Machine details and making sure that the items available are the same as the items redeemed. This unsures us that all assets have been minted +As we only want to reveal our assets after all items have been minted, we will validate the mint completion by fetching the Core Candy Machine details using the `fetchCandyMachine` method and making sure that the items available are the same as the items redeemed. This unsures us that all assets have been minted ```ts import { update, fetchAssetsByCollection } from '@metaplex-foundation/mpl-core'; @@ -314,9 +318,9 @@ for(let i = 0; i < candyMachineDetails.itemsRedeemed; i++) { ### Validation of the revealed assets -Now that the we revealed our assets, it is time to confirm that the assets are indeed the intended ones. +Now that the we revealed our assets, it is time to confirm that the assets integrity. -For that, we will again fetch the assets of our collection and, for each asset, we will extract the name and URI and store them in a new array. +For that, we will again fetch the assets of our collection using the `fetchAssetsByCollection` method and, for each asset, we will extract the name and URI and store them in a new array. After that, we will log both arrays (`revealData` and `fetchedAssets`) to help visualize and verify that the metadata has been updated as expected and will also hash the `fetchedAssets` data and compare to the initial hash @@ -344,6 +348,6 @@ Let's revise all that we did: - After setting up UMI, we created an array containing the metadata (name and URI) that would be used to update the assets after the initial mint. This included calculating a hash for validation purposes. - We created a Collection asset to where our minted assets will belong to - We create a Core Candy Machine with hidden setting, 5 items available, and a start time guard -- We minted all the assets from our Core Candy Machine +- We minted all the assets from our Core Candy Machine with a the placeholder valuee stored in the hidden setting of our Core Candy Machine - After verifying that all assets were minted, we fetched the collection assets and updated their metadata with the prepared reveal data. - We confirmed that the reveal of our collection was correct by hashing the metadata (name and URI) of the revealed assets and comparing it to the expected hash \ No newline at end of file From d396e25024a4b0c7e7b646b8c3396da284beaedd Mon Sep 17 00:00:00 2001 From: ASCorreia <36857753+ASCorreia@users.noreply.github.com> Date: Mon, 30 Dec 2024 02:34:06 +0000 Subject: [PATCH 09/10] minor changes --- ...e-a-core-candy-machine-with-hidden-settings.md | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/pages/core-candy-machine/guides/create-a-core-candy-machine-with-hidden-settings.md b/src/pages/core-candy-machine/guides/create-a-core-candy-machine-with-hidden-settings.md index 53948fbe..a15eff0a 100644 --- a/src/pages/core-candy-machine/guides/create-a-core-candy-machine-with-hidden-settings.md +++ b/src/pages/core-candy-machine/guides/create-a-core-candy-machine-with-hidden-settings.md @@ -28,23 +28,29 @@ npm i @metaplex-foundation/umi @metaplex-foundation/umi-bundle-defaults @metaple ## Setting up umi -After setting up your environment, let's start by setting up umi +After setting up your environment, let's start by setting up umi. + +While setting up Umi, you can create new wallets for testing, import wallets from you filesystem or even use `walletAdapter`. +For this example, we will be creating a Keypair from a json file (wallet.json) containing a secret key. ```ts import { createUmi } from "@metaplex-foundation/umi-bundle-defaults"; import { generateSigner, some, none, createSignerFromKeypair, signerIdentity, transactionBuilder, dateTime } from "@metaplex-foundation/umi"; import { mplCandyMachine as mplCoreCandyMachine } from '@metaplex-foundation/mpl-core-candy-machine'; -import wallet from "../wallet.json"; +import * as fs from 'fs'; // We will be using Solana Devnet as endpoint, and loading the mplCoreCandyMachine plugin const umi = createUmi("https://api.devnet.solana.com") .use(mplCoreCandyMachine()); // Let's create a Keypair from our wallet json file that contains a secret key, and create a signer based on the created keypair -let keypair = umi.eddsa.createKeypairFromSecretKey(new Uint8Array(wallet)); +const walletFile = fs.readFileSync('./wallet.json'); + +let keypair = umi.eddsa.createKeypairFromSecretKey(new Uint8Array(walletFile)); const signer = createSignerFromKeypair(umi, keypair); console.log("Signer: ", signer.publicKey); +// Set the identity and the payer to the given signer umi.use(signerIdentity(signer)); ``` @@ -58,6 +64,7 @@ We’ll also generate a hash of the reveal data. This hash will be stored in the ```ts import crypto from 'crypto'; +// Reveal data of our assets, to be used during the reveal process const revealData = [ { name: 'Nft #1', uri: 'http://example.com/1.json' }, { name: 'Nft #2', uri: 'http://example.com/2.json' }, @@ -130,6 +137,8 @@ Next step is to create our Core Candy Machine with the Hidden Settings. To achieve that, we will use the `create` method from the mpl-core-candy-machine library, and we will set the `hiddenSettings` with the placeholder name, URI, and pre-calculated hash from the `revealData` +More details on the Core Candy Machine creation and guards can be found [here](https://developers.metaplex.com/core-candy-machine/create). + Additionally, we’ll configure a startDate guard, which determines when minting begins. This is only one of the many guards available and you can find the list of all available guards [here](https://developers.metaplex.com/candy-machine/guards). ```ts From 53ef044a8b8ae46bdff0815140dfd09e77b519c8 Mon Sep 17 00:00:00 2001 From: ASCorreia <36857753+ASCorreia@users.noreply.github.com> Date: Sat, 11 Jan 2025 17:41:22 +0000 Subject: [PATCH 10/10] Added UMI and Turbo ref --- ...create-a-core-candy-machine-with-hidden-settings.md | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/pages/core-candy-machine/guides/create-a-core-candy-machine-with-hidden-settings.md b/src/pages/core-candy-machine/guides/create-a-core-candy-machine-with-hidden-settings.md index a15eff0a..d6a3f5b7 100644 --- a/src/pages/core-candy-machine/guides/create-a-core-candy-machine-with-hidden-settings.md +++ b/src/pages/core-candy-machine/guides/create-a-core-candy-machine-with-hidden-settings.md @@ -54,6 +54,8 @@ console.log("Signer: ", signer.publicKey); umi.use(signerIdentity(signer)); ``` +You can find more details about setting up UMI [here](https://developers.metaplex.com/core/guides/javascript/how-to-create-a-core-nft-asset-with-javascript#setting-up-umi) + ### Prepare Reveal Data Now, let’s prepare the reveal data, which will include the metadata for the final revealed NFTs. This data contains the name and URI for each NFT in the collection and will be used to update the placeholder metadata after minting. @@ -77,6 +79,8 @@ let string = JSON.stringify(revealData) let hash = crypto.createHash('sha256').update(string).digest() ``` +Please note that you will need to upload the reveal data yoursel. In order to do it in a determenistic way, you can use [turbo](https://developers.metaplex.com/guides/general/create-deterministic-metadata-with-turbo) + ### Create a Collection Let's now create a Collection asset. @@ -349,8 +353,8 @@ let hash2 = crypto.createHash('sha256').update(string2).digest(); assert(hash == hash2); ``` -### And that is it -Congrats! You just created your Core Candy Machine with hiddens settings. +### Conclusion +Congratulations! You just created your Core Candy Machine with hiddens settings. Let's revise all that we did: - We started by setting up UMI @@ -359,4 +363,4 @@ Let's revise all that we did: - We create a Core Candy Machine with hidden setting, 5 items available, and a start time guard - We minted all the assets from our Core Candy Machine with a the placeholder valuee stored in the hidden setting of our Core Candy Machine - After verifying that all assets were minted, we fetched the collection assets and updated their metadata with the prepared reveal data. -- We confirmed that the reveal of our collection was correct by hashing the metadata (name and URI) of the revealed assets and comparing it to the expected hash \ No newline at end of file +- We confirmed that the reveal of our collection was correct by hashing the metadata (name and URI) of the revealed assets and comparing it to the expected hash