WEB3DEV

Cover image for Como criar uma coleção NFT em Solana usando o Candy Machine V3 e TypeScript
Adriano P. Araujo
Adriano P. Araujo

Posted on

Como criar uma coleção NFT em Solana usando o Candy Machine V3 e TypeScript

Visão geral

Você está pronto para lançar sua coleção NFT na Solana? Se sim, você veio ao lugar certo! Vamos explorar o novo JS SDK da Metaplex, que traz o poder da Candy Machine aos seus aplicativos JavaScript e TypeScript para permitir uma cunhagem rápida e fácil. O Metaplex adicionou vários novos recursos, principalmente os Candy Guards (, uma ferramenta para restringir ou limitar o acesso para cunhagem de NFTs ) que implementaremos neste guia.

O que você fará

Neste guia, você criará uma nova Candy Machine V3 através do seu próprio aplicativo TypeScript. Especificamente, você irá:

  1. Criar uma Candy Machine

  2. Adicionar itens à Candy Machine

  3. Implementar um Candy Guard para sua Candy Machine

  4. Cunhar um NFT!

O que você precisará

Configure seu projeto

Crie um novo diretório de projeto no seu terminal com o seguinte:


mkdir cm-v3-demo

cd cm-v3-demo



Enter fullscreen mode Exit fullscreen mode

Crie um arquivo para o seu aplicativo, app.ts:


echo > app.ts

Enter fullscreen mode Exit fullscreen mode

Inicialize seu projeto com o sinalizador "yes" para usar os valores padrão para o seu novo pacote:


yarn init --yes

#ou

npm init --yes



Enter fullscreen mode Exit fullscreen mode

Crie um tsconfig.json com a importação .json ativada:


tsc -init --resolveJsonModule true

Enter fullscreen mode Exit fullscreen mode

Instale a dependência  Solana Web3

Precisamos adicionar as bibliotecas Solana Web3 e SPL Token para este exercício. Além disso, usaremos JS SDK da Metaplex. No seu terminal, digite:


yarn add @solana/web3.js @metaplex-foundation/js

#ou

npm install @solana/web3.js @metaplex-foundation/js



Enter fullscreen mode Exit fullscreen mode

Adicione sua carteira e Airdrop SOL

Abra o diretório cm-v3-demo no seu editor de código de escolha ( estamos usando o VSCode ). Para seguir este guia, você precisará da mesma Carteira do sistema de arquivos Solana ( par de chaves escrito para um arquivo guideSecret.json ) que é a autoridade do seu NFT. Se você ainda não possuir uma carteira de autoridades  NFT ou  NFTs, crie uma seguindo nosso Guia: Como Cunhar um NFT em Solana usando TypeScript ou apenas pegue o código fonte diretamente (deste repositório Github).

Salve sua carteira no diretório do projeto como guideSecret.json ( você pode copiar isso diretamente do seu diretório mint-nft ).

Você também precisará garantir que sua carteira tenha um pouco de SOL devnet. Você pode conseguir alguns na Torneira Multichain QuickNode colando o endereço da carteira e selecionando Solana Devnet:

Após a configuração, seu ambiente deve ficar assim:

Configure seu aplicativo

Dependências necessárias para importação

Abra o app.ts, e cole as seguintes importações na linha 1:


import { Connection, Keypair, PublicKey } from "@solana/web3.js";

import { Metaplex, keypairIdentity, bundlrStorage, toMetaplexFile, toBigNumber, CreateCandyMachineInput, DefaultCandyGuardSettings, CandyMachineItem, toDateTime, sol, TransactionBuilder, CreateCandyMachineBuilderContext } from "@metaplex-foundation/js";

import secret from './guideSecret.json';

Enter fullscreen mode Exit fullscreen mode

Além da carteira que criamos na etapa anterior, também estamos importando alguns métodos e classes essenciais das bibliotecas Solana Web3 e Metaplex JS.

Configure seu Endpoint do QuickNode

Para criar o Solana, você precisará de um terminal de API para se conectar à rede. Você pode usar nós públicos ou implantar e gerenciar sua própria infraestrutura; no entanto, se você quiser tempos de resposta 8x mais rápidos, pode deixar o trabalho pesado para nós. Veja por que mais de 50% dos projetos no Solana escolhem o QuickNode e se inscrevem para uma conta gratuita aqui. Vamos usar um nó Solana Devnet.

Copie o link do provedor HTTP:

Dentro app.ts sob suas declarações de importação, declare seu RPC e estabeleça sua Conexão para Solana:




const QUICKNODE_RPC = 'https://example.solana-devnet.quiknode.pro/0123456/'; // 👈 Replace with your QuickNode Solana Devnet HTTP Endpoint

const SESSION_HASH = 'QNDEMO'+Math.ceil(Math.random() * 1e9); // Random unique identifier for your session

const SOLANA_CONNECTION = new Connection(QUICKNODE_RPC, { commitment: 'finalized' , httpHeaders: {"x-session-hash": SESSION_HASH}});

Enter fullscreen mode Exit fullscreen mode

Observe que também adicionamos um httpHeader. Esta é apenas uma string aleatória que criará aderência a um nó. Isso ajudará a melhorar a probabilidade de nossas chamadas Metaplex para a rede Solana atingirem o mesmo nó em cada solicitação e reduzir o risco de lacunas de latência entre nós.

Declarar variáveis

Você precisará declarar mais algumas variáveis para executar seu script:

  • Sua carteira de origem ( é um par de chaves derivado de sua chave secreta ).

  • Uma fonte de URL de metadados NFT ( nota: neste guia, focaremos na mecânica da Candy Machine, então reutilizaremos os metadados e a imagem NFT já carregados. Você pode incorporar o upload de imagens e metadados neste exercício - para obter mais informações sobre o upload para o Arweave usando o Metaplex JS SDK, consulte nosso guia sobre Como cunhar uma NFT em Solana usando o Typescript).

  • O endereço de cunhagem do NFT que você gostaria de usar como sua coleção NFT ( esta é a imagem de capa que você pode ver para a coleção em uma carteira ou troca. Mais informações em Metaplex.com).

  • Um espaço reservado para o seu ID de Candy Machine(, atualizaremos isso mais tarde ).

  • Uma instância Metaplex.

Adicione as seguintes declarações abaixo SOLANA_CONNECTION para estabelecer a carteira que usaremos e espaços reservados para os metadados do NFT e o ID da Machine Candy:


const WALLET = Keypair.fromSecretKey(new Uint8Array(secret));

const NFT_METADATA = 'https://mfp2m2qzszjbowdjl2vofmto5aq6rtlfilkcqdtx2nskls2gnnsa.arweave.net/YV-mahmWUhdYaV6q4rJu6CHozWVC1CgOd9NkpctGa2Q'; 

const COLLECTION_NFT_MINT = ''; 

const CANDY_MACHINE_ID = '';

Enter fullscreen mode Exit fullscreen mode

Estabeleça uma nova instância Metaplex chamando nossa SOLANA_CONNECTION em Metaplex.make ( ). Nossa instância usará o Keypair que acabamos de criar:


const METAPLEX = Metaplex.make(SOLANA_CONNECTION)

    .use(keypairIdentity(WALLET));

Enter fullscreen mode Exit fullscreen mode

Ao incluir nossa conexão de rede e carteira, a API facilitará o envio de transações à rede Solana.

Nota: você precisará incluir uma chamada adicional .use ( ) para uma rota de armazenamento se você pretende fazer upload de suas próprias imagens e metadados ( não necessários para seguir esta demonstração ):


    .use(bundlrStorage({

        address: 'https://devnet.bundlr.network',

        providerUrl: QUICKNODE_RPC,

        timeout: 60000,

    }))

Enter fullscreen mode Exit fullscreen mode

Criar coleção NFT

Candy Machine utiliza um recurso, Coleções certificadas Metaplex, para verificar as coleções em cadeia. A verificação facilitada para terceiros (, por exemplo, trocas ) agrupa e rastreia conjuntos de NFTs e evita falsificações. Para criar nossa Candy Machine, precisamos primeiro criar uma coleção NFT. Isso servirá como uma "imagem de capa" que você pode ver em uma troca ou carteira ( por exemplo., Éden ou Fantasma Mágico ).

Tudo o que precisamos fazer é criar um novo NFT usando, nfts ( ) .create ( ). 

Crie uma nova função, createCollectionNft:




async function createCollectionNft() {

    const { nft: collectionNft } = await METAPLEX.nfts().create({

        name: "QuickNode Demo NFT Collection",

        uri: NFT_METADATA,

        sellerFeeBasisPoints: 0,

        isCollection: true,

        updateAuthority: WALLET,

      });



      console.log(`✅ - Minted Collection NFT: ${collectionNft.address.toString()}`);

      console.log(`     https://explorer.solana.com/address/${collectionNft.address.toString()}?cluster=devnet`);

}



Enter fullscreen mode Exit fullscreen mode

Certifique-se de definir isCollection como true, com isso será observado que este NFT está sendo usado para definir uma coleção.

Cunhe seu NFT. No final do seu aplicativo, chame createCollectionNft ( ):


createCollectionNft();

Enter fullscreen mode Exit fullscreen mode

E então, no seu terminal, execute:


ts-node app

Enter fullscreen mode Exit fullscreen mode

Copie o MINT ID e atualize sua variável COLLECTION_NFT_MINT ( na linha 11 para nós ):


const COLLECTION_NFT_MINT = 'GWWhaWp7kJ3WKLkQTKyy5DEEGGF4TnCfHXXKxsBSbcwg'; 

Enter fullscreen mode Exit fullscreen mode

Antes de seguir em frente, exclua ou comente sua chamada para createCollectionNft ( ) uma vez que não precisamos mais disso.

Iniciar Candy Machine

O Metaplex SDK permite iniciar uma Candy Machine com uma única linha de código 🤯:


const { candyMachine } = await METAPLEX.candyMachines().create(candyMachineSettings);

Enter fullscreen mode Exit fullscreen mode

Como você pode ver, no entanto, precisamos primeiro definir algumas configurações para a nossa Candy Machine. Crie uma nova função, groverCandyMachine, onde definimos nossas configurações de Candy Machine e depois chamamos candyMachines ( ) .create ( ):


async function generateCandyMachine() {

    const candyMachineSettings: CreateCandyMachineInput<DefaultCandyGuardSettings> =

        {

            itemsAvailable: toBigNumber(3), // Tamanho da coleção: 3

            sellerFeeBasisPoints: 1000, // 10% Royalties da Coleção

            symbol: "DEMO",

            maxEditionSupply: toBigNumber(0), // 0 reproduções para cada NFT

            isMutable: true,

            creators: [

                { address: WALLET.publicKey, share: 100 },

            ],

            collection: {

                address: new PublicKey(COLLECTION_NFT_MINT), // Can replace with your own NFT or upload a new one

                updateAuthority: WALLET,

            },

        };

    const { candyMachine } = await METAPLEX.candyMachines().create(candyMachineSettings);

    console.log(`✅ - Created Candy Machine: ${candyMachine.address.toString()}`);

    console.log(`     https://explorer.solana.com/address/${candyMachine.address.toString()}?cluster=devnet`);

}

Enter fullscreen mode Exit fullscreen mode

As configurações da Candy Machine definem o tamanho da coleção e os principais pontos de dados que são iguais para cada NFT (, por exemplo, royalties, criadores, símbolos, mutabilidade ). Definimos alguns valores para este exemplo - fique à vontade para modificá-los levemente para atender às suas próprias necessidades. Uma visão geral detalhada das configurações do Candy Machine estão disponíveis  em Metaplex.com. Observe que você pode incluir os Candy Guards nesta etapa - nós os adicionaremos em seguida em uma etapa separada para permitir que você siga o processo de como atualizar uma Candy Machine.

Vá em frente e inicie sua Candy Machine. No final do seu aplicativo, chame  giveCandyMachine ( ):


generateCandyMachine();

Enter fullscreen mode Exit fullscreen mode

E então, no seu terminal, execute:


ts-node app

Enter fullscreen mode Exit fullscreen mode

Você deve ver um ID da Candy Machine e vincular-o ao Solana Explorer:

Copie o ID da Candy Machine e atualize sua variável CANDY_MACHINE_ID ( na linha 11 para nós ):


const CANDY_MACHINE_ID = 'D2ARG7rXosZfnZwVBx3v7piG3H2tcYvWyw5YJCPuEpBU';

Enter fullscreen mode Exit fullscreen mode

Se você estiver recebendo um erro ou tiver dúvidas, envie uma mensagem para nós no Discord, e teremos o maior prazer em ajudar.

Antes de seguir em frente, exclua ou comente sua chamada para giveCandyMachine ( ) uma vez que não precisaremos mais disso.

Adicionar os Candy Guards

A Candy Machine V3 inclui um novo recurso chamado "Candy Guards" ( ou apenas Guards para abreviar ). Os guards são pedaços de código modulares que podem restringir o acesso à cunhagem de uma Candy Machine e até adicionar novos recursos a ela! ( Fonte: Metaplex.com). Em novembro de 2022, o Metaplex tinha 16 guards diferentes disponíveis:

  • Address Gate: Restringe a cunhagem a um único endereço.

  • Allow List: Usa uma lista de endereços da carteira para determinar quem tem permissão para cunhar.

  • Bot Tax: Taxa configurável para cobrar transações inválidas.

  • End Date: Determina uma data para encerrar a cunhagem.

  • Gatekeeper : Restringe a cunhagem através de uma rede Gatekeeper, por exemplo, integração Captcha.

  • Mint Limit: Especifica um número limite de cunhagem por carteira.

  • Nft Burn: Restringe a cunhagem aos detentores de uma coleção especificada, exigindo uma queima do NFT.

  • Nft Gate: Restringe a cunhagem aos titulares de uma coleção especificada.

  • Nft Payment: Define o preço da cunhagem como um NFT de uma coleção especificada.

  • Redeemed Amount: Determina o final da cunhagem  com base no valor total cunhado.

  • Sol Payment: Define o preço da cunhagem em SOL.

  • Start Date: Determina a data de início da cunhagem.

  • Third-Party Signer: Requer um assinante adicional na transação.

  • Token Burn: Restringe a cunhagem aos detentores de um token especificado, exigindo uma queima dos tokens.

  • Token Gate: Restringe a cunhagem aos titulares de um token especificado.

  • Token Payment : Define o preço da cunhagem no valor do token. ( Fonte: Metaplex.com)

O Metaplex permite misturar, combinar e empilhar vários Guards para personalizar a cunhagem do seu NFT. Você pode até criar vários "Grupos de Guards" para criar experiências personalizadas de cunhagem para diferentes usuários.

Para a nossa cunhagem, definiremos um Start Date, um Sol Payment, e um Limitede 2 cunhagens por usuário. Crie uma nova função, updateCandyMachine ( ):


async function updateCandyMachine() {

    const candyMachine = await METAPLEX

        .candyMachines()

        .findByAddress({ address: new PublicKey(CANDY_MACHINE_ID) });



    const { response } = await METAPLEX.candyMachines().update({

        candyMachine,

        guards: {

            startDate: { date: toDateTime("2022-10-17T16:00:00Z") },

            mintLimit: {

                id: 1,

                limit: 2,

            },

            solPayment: {

                amount: sol(0.1),

                destination: METAPLEX.identity().publicKey,

            },

        }

    })

    console.log(`✅ - Updated Candy Machine: ${CANDY_MACHINE_ID}`);

    console.log(`     https://explorer.solana.com/tx/${response.signature}?cluster=devnet`);

}

Enter fullscreen mode Exit fullscreen mode

Nossa função faz três coisas:

  1. Pega nossa Candy Machine: procura nossa Candy Machine por ID e devolve um objeto CandyMachine chamando .candyMachines ( ) .findByAddress ( ).

  2. Atualiza nossa Candy Machine chamando candyMachines ( ) .update ( ). Nós passamos primeiro a candyMachine do passo 1 e depois definimos nossos guards. Cada guard possui uma Chave de Bbjeto específica com um único GuardSettings. As configurações para cada Candy Guard podem ser encontradas em Metaplex.com.

  • Start Date: passa uma  data  inicial usando o método Metaplex's toDateTime.

  • Mint Limit: passa um único id para esse guard ( necessário para permitir que diferentes limites sejam rastreados usando grupos de guards ) e um limite quantidade.

  • Sol Payment : passa um montante de SOL para coletar usando o método Metaplex  sol e destinando-o  à Chave pública ( o tesouro da sua cunhagem).

  1. Registra um link para a transação no Solana Explorer.

Adicione seus Candy Guards chamando updateCandyMachine ( ). No final do seu aplicativo, adicione o seguinte:


updateCandyMachine();

Enter fullscreen mode Exit fullscreen mode

E então, no seu terminal, execute:


ts-node app

Enter fullscreen mode Exit fullscreen mode

Você deve ver algo assim em seu terminal:

Bom trabalho. Antes de seguir em frente, exclua ou comente sua chamada para updateCandyMachine ( ) uma vez que não precisamos mais disso.

Vamos adicionar alguns itens à nossa Candy Machine!

Adicione itens à sua Candy Machine

Adicionar itens à sua Candy Machine é bem semelhante à atualização. Em vez de .update ( ), no entanto, precisamos invocar .insertItems ( ). Crie uma nova função, addItems ( ) e adicione o seguinte código:




async function addItems() {

    const candyMachine = await METAPLEX

        .candyMachines()

        .findByAddress({ address: new PublicKey(CANDY_MACHINE_ID) }); 

    const items = [];

    for (let i = 0; i < 3; i++ ) { // Add 3 NFTs (the size of our collection)

        items.push({

            name: `QuickNode Demo NFT # ${i+1}`,

            uri: NFT_METADATA

        })

    }

    const { response } = await METAPLEX.candyMachines().insertItems({

        candyMachine,

        items: items,

      },{commitment:'finalized'});



    console.log(`✅ - Items added to Candy Machine: ${CANDY_MACHINE_ID}`);

    console.log(`     https://explorer.solana.com/tx/${response.signature}?cluster=devnet`);

}

Enter fullscreen mode Exit fullscreen mode

Nossa função faz três coisas:

  1. Busca nossa Candy Machine: procura nossa Candy Machine pelo ID e devolve um objeto CandyMachine chamando .candyMachines ( ) .findByAddress ( ).

  2. Cria uma matriz de itens a serem adicionados: o insertItems ( ) método exige que passemos uma matriz itens que inclui nome e uri de cada item a ser adicionado à Candy Machine. Como definimos o tamanho da nossa Candy Machine como 3 na etapa "Iniciar Candy Machine", adicionaremos 3 itens usando um loop simples. Se você estiver adicionando NFTs exclusivas, adicione sua lógica personalizada aqui. Como os tamanhos das transações da Solana são limitados, podemos passar apenas um número limitado de itens por chamada. "O número de itens que podemos inserir por transação dependerá dos atributos Comprimento do nome e Comprimento do URI definidos nas Configurações da linha de configuração. Quanto mais curtos forem nossos nomes e URIs, mais poderemos encaixar em uma transação." (Metaplex.com).

  3. Insere itens na Candy Machine chamando candyMachines ( ) .insertItems ( ): Nós passamos primeiro candyMachine do passo 1 e depois passe nosso itens definido na etapa 2.

  4. Registra um link para a transação no Solana Explorer.

Vá em frente e adicione seus itens chamando addItems ( ). No final do seu aplicativo, adicione o seguinte:


addItems();

Enter fullscreen mode Exit fullscreen mode

E então, no seu terminal, execute:


ts-node app

Enter fullscreen mode Exit fullscreen mode

Você deve ver algo assim em seu terminal:

Antes de seguir em frente, exclua ou comente sua chamada para addItems ( ) uma vez que não precisamos mais disso.

Agora você deve ter uma Candy Machine carregada com guards no lugar. Vamos testar!

Cunhe um NFT

Assim como nossas etapas anteriores, precisaremos buscar nossa Candy Machine e chamar um novo método, candyMachines ( ) .mint ( ). Crie uma nova função, mintNft ( ):


async function mintNft() {

    const candyMachine = await METAPLEX

        .candyMachines()

        .findByAddress({ address: new PublicKey(CANDY_MACHINE_ID) }); 

    let { nft, response } = await METAPLEX.candyMachines().mint({

        candyMachine,

        collectionUpdateAuthority: WALLET.publicKey,

        },{commitment:'finalized'})



    console.log(`✅ - Minted NFT: ${nft.address.toString()}`);

    console.log(`     https://explorer.solana.com/address/${nft.address.toString()}?cluster=devnet`);

    console.log(`     https://explorer.solana.com/tx/${response.signature}?cluster=devnet`);

}

Enter fullscreen mode Exit fullscreen mode

Este código deve começar a parecer bastante familiar - eis o que ele faz:

  1. Busca nossa Candy Machine: procura nossa Candy Machine por ID e devolve um objeto CandyMachine chamando .candyMachines ( ) .findByAddress ( ).

  2. Cunha um NFT chamando candyMachines ( ) .mint ( ): Nós passamos primeiro candyMachine do passo 1 e depois passa a chave pública da nossa carteira como o collectionUpdateAuthority ( necessário porque "esta informação não está no modelo candyMachine e é exigida pelas instruções subjacentes da cunhagem" Fonte: Metaplex.com).

  3. Registra um link para a cunhagem  e transação no Solana Explorer.

Finalmente, cunhe um NFT chamando mintNft ( ). No final do seu aplicativo, adicione o seguinte:


mintNft();

Enter fullscreen mode Exit fullscreen mode

E então, no seu terminal, execute:


ts-node app

Enter fullscreen mode Exit fullscreen mode

Você deve ver algo assim em seu terminal:

Bom trabalho! Vamos testar um dos nossos Candy Guards. Execute seu script. Você deve ver um resultado semelhante a cunhagem de um segundo NFT na sua carteira. Então tente pela terceira vez.

A terceira tentativa deve lhe dar alguns problemas. Por quê? Bem, se você digitar seu código de erro, verá algo assim:


  title: CandyGuardProgram > The maximum number of allowed mints was reached,

  problem: The program [CandyGuardProgram] at address [Guard1JwRhJkVH6XZhzoYxeBVQe872VH6QggF4BWmS9g] raised an error of code [6029] that translates to The maximum number of allowed mints was reached.



Enter fullscreen mode Exit fullscreen mode

Se você se lembra, criamos um mintLimit Candy Guard que limita qualquer carteira a ser capaz de cunhar apenas 2 NFTs, de modo que o guard está nos impedindo de cunhar um terceiro! Muito legal, hein?

Próximos passos e sucessos

Agora você tem alguns scripts úteis para interagir com o Candy Machine usando o TypeScript! Estamos empolgados em ver o que você construiu com isso. Entre no Discord ou Twitter e compartilhe seus projetos!

Procurando um desafio extra? Tente criar um site de cunhagem usando os scripts que acabamos de aprender e os Solana dApp Scaffold!

Nós < 3 Feedback!

Se você tiver algum feedback ou pergunta sobre este guia, deixe-nos saber. Gostaríamos muito de ouvir de você!


Este artigo foi escrito por Aaron Milano e traduzido por Adriano P. de Araujo. O original em inglês pode ser encontrado aqui.

Latest comments (0)