
O Token Program
Na Solana, tudo relacionado a tokens é gerenciado pelo SPL Token Program e pelo Token2022 Program: o framework de tokens nativo da Solana que define como todos os tokens são criados, gerenciados e transferidos.
É um programa único e unificado que gerencia todas as operações de tokens na rede, garantindo consistência e interoperabilidade.
Vamos começar instalando o pacote necessário para trabalhar com o programa SPL Token usando Web3.js:
npm i @solana/spl-tokenContas Mint e Token
Por baixo dos panos, criar uma conta Mint e Token é bastante "complicado". Há diferentes instruções que requerem diferentes inputs e contas; a conta precisa ser tornada isenta de aluguel antes que possamos realmente inicializá-la, ...
Conta Mint
Sem nenhuma abstração, criar uma conta Mint ficaria assim:
import {
Keypair,
sendAndConfirmTransaction,
SystemProgram,
Transaction,
} from "@solana/web3.js";
import {
createInitializeMint2Instruction,
MINT_SIZE,
getMinimumBalanceForRentExemptMint,
TOKEN_PROGRAM_ID,
} from "@solana/spl-token";
const mint = Keypair.generate();
const mintRent = await getMinimumBalanceForRentExemptMint(connection);
const createAccountInstruction = SystemProgram.createAccount({
fromPubkey: feePayer.publicKey,
newAccountPubkey: mint.publicKey,
space: MINT_SIZE,
lamports: mintRent,
programId: TOKEN_PROGRAM_ID
});
const initializeMintInstruction = createInitializeMint2Instruction(
mint.publicKey, // pubkey da mint
6, // decimais
feePayer.publicKey, // autoridade de mint
null, // autoridade de freeze
TOKEN_PROGRAM_ID
);
const transaction = new Transaction().add(
createAccountInstruction,
initializeMintInstruction,
);
const signature = await sendAndConfirmTransaction(connection, transaction, [keypair, mint]);
console.log(`Mint criada! Veja sua TX aqui: https://explorer.solana.com/tx/${signature}?cluster=devnet`);Felizmente, o pacote @solana/spl-token tem algumas abstrações. Então podemos criar uma conta Mint com uma única função createMint() assim:
const mint = await createMint(
connection, // conexão
keypair, // pagador
keypair.publicKey, // autoridade de mint
null, // autoridade de freeze
6 // decimais
);Conta Token
O mesmo vale para a conta Token. Se fôssemos criá-la sem abstrações, ficaria assim:
import {
Keypair,
sendAndConfirmTransaction,
SystemProgram,
Transaction,
} from "@solana/web3.js";
import {
createInitializeAccount3Instruction,
ACCOUNT_SIZE,
getMinimumBalanceForRentExemptAccount,
TOKEN_PROGRAM_ID,
} from "@solana/spl-token";
const token = Keypair.generate();
const tokenRent = await getMinimumBalanceForRentExemptAccount(connection);
const createAccountInstruction = SystemProgram.createAccount({
fromPubkey: feePayer.publicKey,
newAccountPubkey: token.publicKey,
space: ACCOUNT_SIZE,
lamports: tokenRent,
programId: TOKEN_PROGRAM_ID
});
const initializeTokenInstruction = createInitializeAccount3Instruction(
token.publicKey, // pubkey do token
mint.publicKey, // pubkey da mint
feePayer.publicKey, // pubkey do dono
TOKEN_PROGRAM_ID
);
const transaction = new Transaction().add(
createAccountInstruction,
initializeTokenInstruction,
);
const signature = await sendAndConfirmTransaction(connection, transaction, [keypair, token]);
console.log(`Token criado! Veja sua TX aqui: https://explorer.solana.com/tx/${signature}?cluster=devnet`);Mas assim como a conta Mint, o pacote @solana/spl-token tem abstrações para criar a conta Token. Podemos usar a função createAccount() assim:
const token = await createAccount(
connection, // conexão
keypair, // pagador
mint.publicKey, // pubkey da mint
keypair.publicKey, // pubkey do dono
);Conta Associated Token
O mesmo se aplica à conta Associated Token, mas a abstração não está relacionada à criação das contas como para as contas Mint e Token, está principalmente relacionada à derivação de endereços.
Então aqui está como criamos uma conta Associated Token sem abstrações:
import {
sendAndConfirmTransaction,
Transaction,
} from "@solana/web3.js";
import {
TOKEN_PROGRAM_ID,
createAssociatedTokenAccountIdempotentInstruction,
getAssociatedTokenAddress,
} from "@solana/spl-token";
const associatedTokenAccount = await getAssociatedTokenAddress(
mint.publicKey, // pubkey da mint
keypair.publicKey, // pubkey do dono
false, // permitir owner off-curve
TOKEN_PROGRAM_ID
);
// Criar instruções de criação de ATA para todas as contas
const createAtaInstruction = createAssociatedTokenAccountIdempotentInstruction(
keypair.publicKey, // pagador
associatedTokenAccount, // endereço da conta associated token
keypair.publicKey, // dono
mint.publicKey, // mint
TOKEN_PROGRAM_ID
);
const transaction = new Transaction().add(
createAtaInstruction,
);
const signature = await sendAndConfirmTransaction(connection, transaction, [keypair]);
console.log(`Associated Token criado! Veja sua TX aqui: https://explorer.solana.com/tx/${signature}?cluster=devnet`);E aqui está como fica com abstrações:
const ata = await getOrCreateAssociatedTokenAccount(
connection, // conexão
keypair, // pagador
mint, // pubkey da mint
keypair.publicKey // pubkey do dono
);