Escrevendo na Rede

Na seção anterior, você aprendeu como ler dados da rede Solana buscando contas. Para gravar dados na rede Solana, é necessária uma transação. Uma transação contém uma ou mais instruções, e cada instrução invoca um programa.

Os programas definem a lógica de negócio para cada instrução. Quando você envia uma transação, o runtime da Solana executa as instruções da transação em ordem. As transações são atômicas. Ou todas as instruções da transação são executadas com sucesso, ou a transação inteira falha.

Os exemplos nesta seção mostram como:

  1. Transferir SOL entre contas
  2. Criar um novo token mint

Transferir SOL

O exemplo abaixo transfere SOL de uma conta para outra. Apenas o programa designado como proprietário de uma conta pode modificar os dados da conta ou deduzir lamports do seu saldo. As contas de carteira são de propriedade do System Program, portanto, transferir SOL entre contas de carteira requer uma instrução que invoca a instrução transfer do System Program. A conta de origem também deve assinar a transação.

Transfer SOL
import { createClient, generateKeyPairSigner, lamports } from "@solana/kit";
import { solanaRpc, rpcAirdrop } from "@solana/kit-plugin-rpc";
import { generatedPayer, airdropPayer } from "@solana/kit-plugin-signer";
import { getTransferSolInstruction } from "@solana-program/system";
const client = await createClient()
.use(generatedPayer())
.use(
solanaRpc({
rpcUrl: "http://localhost:8899",
rpcSubscriptionsUrl: "ws://localhost:8900"
})
)
.use(rpcAirdrop())
.use(airdropPayer(lamports(1_000_000_000n)));
const receiver = await generateKeyPairSigner();
const transferInstruction = getTransferSolInstruction({
source: client.payer,
destination: receiver.address,
amount: lamports(10_000_000n)
});
const result = await client.sendTransaction([transferInstruction]);
console.log("Transaction Signature:", result.context.signature);
const { value: senderBalance } = await client.rpc
.getBalance(client.payer.address)
.send();
const { value: receiverBalance } = await client.rpc
.getBalance(receiver.address)
.send();
console.log("Sender Balance:", senderBalance);
console.log("Receiver Balance:", receiverBalance);
Console
Click to execute the code.

Crie um cliente Kit para o validator de teste local. Este trecho adiciona um signatário pagador, conecta-se ao endpoint RPC local, habilita airdrops e financia o pagador com SOL de teste para a transferência.

Client setup
const client = await createClient()
.use(generatedPayer())
.use(
solanaRpc({
rpcUrl: "http://localhost:8899",
rpcSubscriptionsUrl: "ws://localhost:8900"
})
)
.use(rpcAirdrop())
.use(airdropPayer(lamports(1_000_000_000n)));

Gere um signatário para o destinatário. O remetente é client.payer, que foi criado por generatedPayer() e financiado por airdropPayer().

Receiver signer
const receiver = await generateKeyPairSigner();

O auxiliar getTransferSolInstruction() cria uma instrução do System Program. A instrução transfere SOL do signatário source para o endereço destination pelo valor especificado de amount lamports.

Transfer instruction
const transferInstruction = getTransferSolInstruction({
source: client.payer,
destination: receiver.address,
amount: lamports(10_000_000n)
});

Chame client.sendTransaction() com um array de instruções. O cliente Kit converte as instruções em uma transação, assina com os signatários vinculados às instruções, envia a transação e aguarda a confirmação.

Send transaction
const result = await client.sendTransaction([transferInstruction]);
console.log("Transaction Signature:", result.context.signature);

Após a transação ser confirmada, busque ambos os saldos usando client.rpc.

Fetch balances
const { value: senderBalance } = await client.rpc
.getBalance(client.payer.address)
.send();
const { value: receiverBalance } = await client.rpc
.getBalance(receiver.address)
.send();

Crie um cliente Kit para o validator de teste local. Este trecho adiciona um signatário pagador, conecta-se ao endpoint RPC local, habilita airdrops e financia o pagador com SOL de teste para a transferência.

Client setup
const client = await createClient()
.use(generatedPayer())
.use(
solanaRpc({
rpcUrl: "http://localhost:8899",
rpcSubscriptionsUrl: "ws://localhost:8900"
})
)
.use(rpcAirdrop())
.use(airdropPayer(lamports(1_000_000_000n)));

Gere um signatário para o destinatário. O remetente é client.payer, que foi criado por generatedPayer() e financiado por airdropPayer().

Receiver signer
const receiver = await generateKeyPairSigner();

O auxiliar getTransferSolInstruction() cria uma instrução do System Program. A instrução transfere SOL do signatário source para o endereço destination pelo valor especificado de amount lamports.

Transfer instruction
const transferInstruction = getTransferSolInstruction({
source: client.payer,
destination: receiver.address,
amount: lamports(10_000_000n)
});

Chame client.sendTransaction() com um array de instruções. O cliente Kit converte as instruções em uma transação, assina com os signatários vinculados às instruções, envia a transação e aguarda a confirmação.

Send transaction
const result = await client.sendTransaction([transferInstruction]);
console.log("Transaction Signature:", result.context.signature);

Após a transação ser confirmada, busque ambos os saldos usando client.rpc.

Fetch balances
const { value: senderBalance } = await client.rpc
.getBalance(client.payer.address)
.send();
const { value: receiverBalance } = await client.rpc
.getBalance(receiver.address)
.send();
Transfer SOL
import { createClient, generateKeyPairSigner, lamports } from "@solana/kit";
import { solanaRpc, rpcAirdrop } from "@solana/kit-plugin-rpc";
import { generatedPayer, airdropPayer } from "@solana/kit-plugin-signer";
import { getTransferSolInstruction } from "@solana-program/system";
const client = await createClient()
.use(generatedPayer())
.use(
solanaRpc({
rpcUrl: "http://localhost:8899",
rpcSubscriptionsUrl: "ws://localhost:8900"
})
)
.use(rpcAirdrop())
.use(airdropPayer(lamports(1_000_000_000n)));

Criar um token

O exemplo abaixo cria um novo mint de token usando o Token Extensions Program. Um mint account é a conta que define as configurações globais de um token, como decimais, fornecimento, autoridade de mint e autoridade de congelamento.

Criar um mint account requer duas instruções:

  1. Invocar o System Program para criar uma nova conta de propriedade do Token Extensions Program.
  2. Invocar o Token Extensions Program para inicializar essa conta como um mint.
Create mint account
import { createClient, generateKeyPairSigner, lamports } from "@solana/kit";
import { solanaRpc, rpcAirdrop } from "@solana/kit-plugin-rpc";
import { generatedPayer, airdropPayer } from "@solana/kit-plugin-signer";
import { getCreateAccountInstruction } from "@solana-program/system";
import {
fetchMint,
getInitializeMintInstruction,
getMintSize,
TOKEN_2022_PROGRAM_ADDRESS
} from "@solana-program/token-2022";
const client = await createClient()
.use(generatedPayer())
.use(
solanaRpc({
rpcUrl: "http://localhost:8899",
rpcSubscriptionsUrl: "ws://localhost:8900"
})
)
.use(rpcAirdrop())
.use(airdropPayer(lamports(1_000_000_000n)));
const mint = await generateKeyPairSigner();
const space = BigInt(getMintSize());
const rent = await client.rpc.getMinimumBalanceForRentExemption(space).send();
const createAccountInstruction = getCreateAccountInstruction({
payer: client.payer,
newAccount: mint,
space,
lamports: rent,
programAddress: TOKEN_2022_PROGRAM_ADDRESS
});
const initializeMintInstruction = getInitializeMintInstruction({
mint: mint.address,
decimals: 2,
mintAuthority: client.payer.address,
freezeAuthority: client.payer.address,
tokenProgram: TOKEN_2022_PROGRAM_ADDRESS
});
const result = await client.sendTransaction([
createAccountInstruction,
initializeMintInstruction
]);
console.log("Mint Address:", mint.address);
console.log("Transaction Signature:", result.context.signature);
const mintAccount = await fetchMint(client.rpc, mint.address);
console.log("Mint Account:", mintAccount);
Console
Click to execute the code.

Crie e financie um cliente Kit, depois gere um signatário para usar como endereço da nova mint account. O pagador do cliente financia a criação da conta e paga a taxa de transação.

Client and mint setup
const client = await createClient()
.use(generatedPayer())
.use(
solanaRpc({
rpcUrl: "http://localhost:8899",
rpcSubscriptionsUrl: "ws://localhost:8900"
})
)
.use(rpcAirdrop())
.use(airdropPayer(lamports(1_000_000_000n)));
const mint = await generateKeyPairSigner();

Calcule o tamanho da mint account em bytes, depois faça uma requisição RPC para calcular os lamports necessários para armazenar esses dados na conta. Esse saldo necessário é chamado de rent.

Mint account size and rent
const space = BigInt(getMintSize());
const rent = await client.rpc.getMinimumBalanceForRentExemption(space).send();

A primeira instrução invoca o System Program. A instrução usa o payer para financiar uma newAccount, aloca o space da mint account, transfere os lamports isentos de rent e atribui a propriedade ao programAddress.

Create account instruction
const createAccountInstruction = getCreateAccountInstruction({
payer: client.payer,
newAccount: mint,
space,
lamports: rent,
programAddress: TOKEN_2022_PROGRAM_ADDRESS
});

A segunda instrução invoca o Token Extensions Program. A instrução inicializa o endereço da mint com um valor de decimals, uma mintAuthority, uma freezeAuthority, e especifica o tokenProgram que é proprietário da mint account.

Initialize mint instruction
const initializeMintInstruction = getInitializeMintInstruction({
mint: mint.address,
decimals: 2,
mintAuthority: client.payer.address,
freezeAuthority: client.payer.address,
tokenProgram: TOKEN_2022_PROGRAM_ADDRESS
});

Envie ambas as instruções em uma única transação. A instrução de criação de conta deve vir antes da instrução de inicialização do mint porque o mint account deve existir antes que o Token Extensions Program possa gravar os dados do mint na conta.

Send transaction
const result = await client.sendTransaction([
createAccountInstruction,
initializeMintInstruction
]);

Após a confirmação da transação, busque o mint account.

Fetch mint account
const mintAccount = await fetchMint(client.rpc, mint.address);
console.log("Mint Account:", mintAccount);

Crie e financie um cliente Kit, depois gere um signatário para usar como endereço da nova mint account. O pagador do cliente financia a criação da conta e paga a taxa de transação.

Client and mint setup
const client = await createClient()
.use(generatedPayer())
.use(
solanaRpc({
rpcUrl: "http://localhost:8899",
rpcSubscriptionsUrl: "ws://localhost:8900"
})
)
.use(rpcAirdrop())
.use(airdropPayer(lamports(1_000_000_000n)));
const mint = await generateKeyPairSigner();

Calcule o tamanho da mint account em bytes, depois faça uma requisição RPC para calcular os lamports necessários para armazenar esses dados na conta. Esse saldo necessário é chamado de rent.

Mint account size and rent
const space = BigInt(getMintSize());
const rent = await client.rpc.getMinimumBalanceForRentExemption(space).send();

A primeira instrução invoca o System Program. A instrução usa o payer para financiar uma newAccount, aloca o space da mint account, transfere os lamports isentos de rent e atribui a propriedade ao programAddress.

Create account instruction
const createAccountInstruction = getCreateAccountInstruction({
payer: client.payer,
newAccount: mint,
space,
lamports: rent,
programAddress: TOKEN_2022_PROGRAM_ADDRESS
});

A segunda instrução invoca o Token Extensions Program. A instrução inicializa o endereço da mint com um valor de decimals, uma mintAuthority, uma freezeAuthority, e especifica o tokenProgram que é proprietário da mint account.

Initialize mint instruction
const initializeMintInstruction = getInitializeMintInstruction({
mint: mint.address,
decimals: 2,
mintAuthority: client.payer.address,
freezeAuthority: client.payer.address,
tokenProgram: TOKEN_2022_PROGRAM_ADDRESS
});

Envie ambas as instruções em uma única transação. A instrução de criação de conta deve vir antes da instrução de inicialização do mint porque o mint account deve existir antes que o Token Extensions Program possa gravar os dados do mint na conta.

Send transaction
const result = await client.sendTransaction([
createAccountInstruction,
initializeMintInstruction
]);

Após a confirmação da transação, busque o mint account.

Fetch mint account
const mintAccount = await fetchMint(client.rpc, mint.address);
console.log("Mint Account:", mintAccount);
Create mint account
import { createClient, generateKeyPairSigner, lamports } from "@solana/kit";
import { solanaRpc, rpcAirdrop } from "@solana/kit-plugin-rpc";
import { generatedPayer, airdropPayer } from "@solana/kit-plugin-signer";
import { getCreateAccountInstruction } from "@solana-program/system";
import {
fetchMint,
getInitializeMintInstruction,
getMintSize,
TOKEN_2022_PROGRAM_ADDRESS
} from "@solana-program/token-2022";
const client = await createClient()
.use(generatedPayer())
.use(
solanaRpc({
rpcUrl: "http://localhost:8899",
rpcSubscriptionsUrl: "ws://localhost:8900"
})
)
.use(rpcAirdrop())
.use(airdropPayer(lamports(1_000_000_000n)));
const mint = await generateKeyPairSigner();

Estes exemplos usam generatedPayer() para criar um keypair descartável para testes locais. Aplicações em produção nunca devem armazenar chaves privadas brutas no código — delegue a assinatura a um backend de gerenciamento de chaves. Consulte Assinatura em Produção.

Is this page helpful?

Índice

Editar Página
© 2026 Fundação Solana. Todos os direitos reservados.