Preparação para produção

Construir localmente e testar na devnet são ótimas formas de começar com pagamentos na Solana. No entanto, quando estiver pronto para implantar na Mainnet, você precisa estar ciente das nuances da mainnet. A Devnet perdoa erros. A Mainnet não. Este guia aborda as diferenças que importam para garantir que seus usuários tenham uma experiência tranquila.

DevnetMainnet
SOL gratuito de faucetsAdquira SOL real para taxas
Baixa competição por espaço de blocoTaxas de prioridade importam
Transações são confirmadas facilmenteConfiguração de transação é crítica
RPC público é suficienteRPC de produção necessário
Keypairs e mints da devnetChaves e token mints diferentes—atualize sua configuração

Infraestrutura RPC

Endpoints públicos (api.mainnet-beta.solana.com) têm limite de taxa sem SLA. São adequados para desenvolvimento, mas falharão em fluxos de pagamento de produção—como tentar executar um processador de pagamentos através de uma API compartilhada sem garantia de tempo de atividade.

Nunca use RPC público para produção

Use um provedor de RPC privado para acesso confiável e de baixa latência.

Ao escolher um provedor de RPC, procure por:

  • Confiabilidade: SLAs com garantias de tempo de atividade (99,9%+)
  • Latência: Proximidade geográfica com seus usuários
  • Recursos: Recursos de confirmação de transações, indexação, APIs de taxa de prioridade

Para uma lista completa de provedores de RPC, consulte o guia Provedores de infraestrutura RPC.

Configuração de RPC redundante

Como qualquer provedor de serviços de rede, os provedores de RPC podem experimentar tempo de inatividade ou períodos de desempenho degradado. Para garantir que sua aplicação seja resiliente, você deve configurar sua aplicação para usar múltiplos provedores de RPC.

O Solana Kit fornece uma biblioteca para personalizar transportes RPC que permite construir o seu próprio cliente RPC redundante. Aqui está um exemplo de como você pode usá-lo para construir um cliente RPC redundante:

import { RpcTransport } from "@solana/rpc-spec";
import { RpcResponse } from "@solana/rpc-spec-types";
import { createHttpTransport } from "@solana/rpc-transport-http";
// Create a transport for each RPC server
const transports = [
createHttpTransport({ url: "https://mainnet-beta.my-server-1.com" }),
createHttpTransport({ url: "https://mainnet-beta.my-server-2.com" }),
createHttpTransport({ url: "https://mainnet-beta.my-server-3.com" })
];
// Create a wrapper transport that distributes requests to them
let nextTransport = 0;
async function roundRobinTransport<TResponse>(
...args: Parameters<RpcTransport>
): Promise<RpcResponse<TResponse>> {
const transport = transports[nextTransport];
nextTransport = (nextTransport + 1) % transports.length;
return await transport(...args);
}

Se preferir não construir as suas próprias ferramentas de roteamento, pode aproveitar um serviço de terceiros como o Iron Forge para lidar com o roteamento por si.

Confirmação de transação

Na Devnet, as transações são confirmadas facilmente. Na Mainnet, você está a competir por espaço no bloco. Para aumentar as hipóteses de ter a sua transação incluída num bloco, deve garantir que montou corretamente a sua transação. Isto significa:

  • incluir um blockhash recente antes de enviar a transação
  • incluir uma instrução de taxa de prioridade na transação com uma taxa de prioridade competitiva
  • incluir uma instrução de limite de unidades de computação na transação com um limite de unidades de computação baseado nas unidades de computação estimadas necessárias para a transação

Além disso, deve considerar outras ferramentas como Jito Bundles para aumentar as hipóteses da sua transação ser incluída num bloco. Vamos explorar estas ferramentas com mais detalhe.

Configuração de envio de transação

Ao enviar transações na Mainnet, configure estes parâmetros para taxas de confirmação ótimas:

Gestão de blockhash:

  • Obtenha com compromisso confirmed
  • Armazene o lastValidBlockHeight retornado por getLatestBlockhash—isto indica quando a sua transação expira
  • Os blockhashes expiram após ~150 blocos (~60-90 segundos)

Opções de envio:

  • maxRetries: 0 — Desative as tentativas automáticas de RPC. Gira as tentativas você mesmo para poder atualizar o blockhash quando necessário.
  • skipPreflight: true — Ignore a simulação antes de enviar. Use isto quando já validou a transação e quer a menor latência. Mantenha como false durante o desenvolvimento para detetar erros mais cedo.
import { createSolanaRpc } from "@solana/kit";
const rpc = createSolanaRpc(process.env.RPC_URL!);
// 1. Get blockhash with confirmed commitment
const { value: latestBlockhash } = await rpc
.getLatestBlockhash({ commitment: "confirmed" })
.send();
// 2. Build and sign your transaction with the blockhash
// ... (transaction building code)
// 3. Send with production settings
const signature = await rpc
.sendTransaction(encodedTransaction, {
encoding: "base64",
maxRetries: 0n, // Handle retries yourself
skipPreflight: true, // Skip simulation for speed (use false during dev)
preflightCommitment: "confirmed"
})
.send();
// 4. Track expiration using lastValidBlockHeight
const { lastValidBlockHeight } = latestBlockhash;
// Stop retrying when current block height exceeds lastValidBlockHeight

Use taxas de prioridade

Toda transação Solana requer uma taxa de transação, paga em SOL. As taxas de transação são divididas em duas partes: a taxa base e a taxa de prioridade. A taxa base compensa os validadores pelo processamento da transação. A taxa de prioridade é uma taxa opcional, para aumentar a chance de o líder atual processar sua transação. Pense nisso como envio expresso: você paga mais por uma entrega mais rápida e confiável.

Como as taxas funcionam:

Total fee = Base fee (5,000 lamports per signature) + Priority fee
Priority fee = Compute units x Price per unit (micro-lamports per compute unit)

Custos reais:

  • Transferência simples de USDC: ~$0.001-0.005 durante condições normais
  • Durante congestionamento: ~$0.01-0.05
  • Pico de congestionamento: pode aumentar ainda mais

Exemplo de implementação:

O pacote @solana-program/compute-budget fornece uma função auxiliar para atualizar ou anexar facilmente a instrução de preço de unidade de computação (em micro-lamports) a uma transação.

import { updateOrAppendSetComputeUnitPriceInstruction } from "@solana-program/compute-budget";
const tx = pipe(
createTransactionMessage({ version: 0 }),
(m) => setTransactionMessageFeePayerSigner(payer, m),
(m) => setTransactionMessageLifetimeUsingBlockhash(latestBlockhash, m),
(m) => appendTransactionMessageInstructions([myInstructions], m),
(m) => updateOrAppendSetComputeUnitPriceInstruction(1000n as MicroLamports, m)
);

Obtendo estimativas de taxas: a maioria dos provedores RPC oferece APIs de taxa de prioridade:

Para a mecânica completa de taxas, consulte Taxas de transação e nosso guia: Como adicionar taxas de prioridade a uma transação.

Otimize unidades de computação

A computação na Solana é efetivamente uma medida da quantidade de trabalho que o programa está realizando. Há um limite na quantidade de computação que pode ser usada em uma transação (atualmente 1,4 milhão de unidades de computação) e um limite na quantidade de computação que pode ser usada por conta por bloco (atualmente 100 milhões de unidades de computação).

Quando você envia uma transação, precisa estimar a quantidade de computação que será usada e definir o limite de unidade de computação adequadamente - isso é efetivamente uma solicitação de quanto da capacidade total deve ser reservada para sua transação. Na prática, isso significa que estimar adequadamente as unidades de computação necessárias para sua transação é fundamental para que sua transação seja incluída em um bloco (e importante para gerenciar suas taxas de prioridade).

A API JSON RPC da Solana possui um método simulatetransaction que pode ser utilizado para estimar as unidades de computação necessárias para uma transação, incluindo uma estimativa das unidades de computação que serão usadas. @solana/kit fornece funções auxiliares que estimam os limites de recursos de uma transação e os definem na mensagem em uma única etapa (usando o método simulatetransaction internamente). Para transações da versão 1, essas funções auxiliares também estimam o limite de tamanho dos dados das contas carregadas.

import {
estimateResourceLimitsFactory,
estimateAndSetResourceLimitsFactory
} from "@solana/kit";
const estimateResourceLimits = estimateResourceLimitsFactory({ rpc });
const estimateAndSetResourceLimits = estimateAndSetResourceLimitsFactory(
estimateResourceLimits
);
const txWithResourceLimits = await estimateAndSetResourceLimits(tx);

Se você constrói e envia transações com um cliente plugin kit, normalmente não precisa desta etapa — o cliente adiciona instruções de orçamento de computação para você ao enviar (.sendTransaction()). O fluxo manual acima é para quando você monta transações diretamente com @solana/kit.

Em produção, se você estiver repetindo o mesmo tipo de transação várias vezes, deve considerar armazenar em cache a estimativa de computação para o tipo de transação, a fim de evitar o custo adicional de estimar as unidades de computação a cada vez.

Jito Bundles

Os Jito bundles são uma ferramenta para gerenciar a execução atômica de múltiplas transações. Isso é alcançado enviando múltiplas transações para a rede Jito com uma gorjeta. As gorjetas podem ser usadas para incentivar a rede Jito a incluir suas transações em um bloco.

Recursos:

Estratégias de Repetição

As transações podem falhar por diversas razões. Ao contrário das APIs de pagamento tradicionais que retornam sucesso/falha imediatamente, as transações em blockchain exigem rastreamento de confirmação.

Conceitos principais:

  • Expiração do blockhash: As transações são válidas por ~150 blocos (~60-90 segundos)
  • Idempotência: A mesma transação assinada sempre produz a mesma assinatura — reenviar é seguro
  • Recuo exponencial: Evite sobrecarregar a rede com repetições rápidas
import {
createSolanaRpc,
createSolanaRpcSubscriptions,
sendAndConfirmTransactionFactory,
isSolanaError,
SOLANA_ERROR__BLOCK_HEIGHT_EXCEEDED
} from "@solana/kit";
const rpc = createSolanaRpc(process.env.RPC_URL!);
const rpcSubscriptions = createSolanaRpcSubscriptions(process.env.RPC_WSS_URL!);
const sendAndConfirmTransaction = sendAndConfirmTransactionFactory({
rpc,
rpcSubscriptions
});
// Send with automatic confirmation tracking and block height monitoring
try {
await sendAndConfirmTransaction(signedTransaction, {
commitment: "confirmed",
// Optional: abort after 75 seconds
abortSignal: AbortSignal.timeout(75_000)
});
} catch (e) {
if (isSolanaError(e, SOLANA_ERROR__BLOCK_HEIGHT_EXCEEDED)) {
// Blockhash expired—rebuild transaction with fresh blockhash and retry
rebuildAndRetryTransaction(); // implement your own logic for rebuilding and retrying the transaction
}
throw e;
}

O sendAndConfirmTransactionFactory de @solana/kit gerencia automaticamente o polling de confirmação e o rastreamento da altura do bloco. Ele lança SOLANA_ERROR__BLOCK_HEIGHT_EXCEEDED quando o blockhash da transação expira, indicando que você precisa reconstruir a transação com um blockhash atualizado.

Recursos Adicionais

Entendendo os Níveis de Confirmação

A Solana oferece três níveis de confirmação. Em termos de finanças tradicionais:

NívelDefinição na SolanaEquivalente TradicionalCaso de Uso
processedEm um bloco, ainda não votadoAutorização pendenteAtualizações de UI em tempo real
confirmedSupermaioria votouFundos compensadosMaioria dos pagamentos
finalizedEnraizado, irreversívelFundos liquidadosAlto valor, conformidade

Quando usar cada um:

  • Atualizações de UI: Exibir processed para feedback imediato ("Pagamento enviado")
  • Creditar conta do usuário: Aguardar confirmed (seguro para a maioria das transações)
  • Enviar produtos físicos: Aguardar finalized
  • Saques de grande valor: Aguardar finalized
  • Conformidade/auditoria: Sempre registrar o status finalized

Para mais informações sobre como verificar o status de transações, consulte Interagindo com a Solana.

Tratamento de Erros

O Solana Kit fornece erros tipados via isSolanaError(). Use códigos de erro específicos em vez de correspondência por string:

import {
isSolanaError,
SOLANA_ERROR__BLOCK_HEIGHT_EXCEEDED,
SOLANA_ERROR__TRANSACTION_ERROR__INSUFFICIENT_FUNDS_FOR_FEE,
SOLANA_ERROR__TRANSACTION_ERROR__BLOCKHASH_NOT_FOUND,
SOLANA_ERROR__INSTRUCTION_ERROR__INSUFFICIENT_FUNDS
} from "@solana/kit";
function handlePaymentError(error: unknown): {
message: string;
retryable: boolean;
} {
// Blockhash expired—rebuild and retry
if (
isSolanaError(error, SOLANA_ERROR__BLOCK_HEIGHT_EXCEEDED) ||
isSolanaError(error, SOLANA_ERROR__TRANSACTION_ERROR__BLOCKHASH_NOT_FOUND)
) {
return { message: "Transaction expired—rebuilding", retryable: true };
}
// Insufficient SOL for fees
if (
isSolanaError(
error,
SOLANA_ERROR__TRANSACTION_ERROR__INSUFFICIENT_FUNDS_FOR_FEE
)
) {
return { message: "Not enough SOL for fees", retryable: false };
}
// Insufficient token balance
if (
isSolanaError(error, SOLANA_ERROR__INSTRUCTION_ERROR__INSUFFICIENT_FUNDS)
) {
return { message: "Insufficient balance", retryable: false };
}
// Unknown error
console.error("Payment error:", error);
return { message: "Payment failed—please retry", retryable: true };
}

Códigos de Erro Comuns:

Código de ErroCausaRecuperação
BLOCK_HEIGHT_EXCEEDEDBlockhash expiradoReconstruir com um blockhash atualizado
BLOCKHASH_NOT_FOUNDBlockhash não encontradoReconstruir com um blockhash atualizado
INSUFFICIENT_FUNDS_FOR_FEESOL insuficienteFinancie o pagador de taxas ou use abstração de taxas
INSUFFICIENT_FUNDSTokens insuficientesO usuário precisa de mais saldo
ACCOUNT_NOT_FOUNDtoken account ausenteCriar ATA na transação

Transações Sem Gas

Os usuários esperam pagar em stablecoins, não precisar adquirir SOL para taxas de rede. As transações sem gas resolvem isso — semelhante a como os usuários do Venmo não pensam nas taxas ACH. Consulte Abstração de Taxas para a implementação completa.

Segurança

Gerenciamento de Chaves

  • Nunca exponha chaves privadas no código do frontend. Use assinatura no backend, carteiras de hardware, carteiras multissinatura ou serviços de gerenciamento de chaves.
  • Separe carteiras quentes e frias. Carteira quente para operações, fria para o tesouro.
  • Faça backup de todas as chaves de produção. Armazene backups criptografados em múltiplos locais seguros. Perder uma chave significa perder o acesso permanentemente.
  • Use chaves diferentes para devnet e mainnet. Suas chaves de devnet não devem ser as suas chaves de mainnet. Use configuração baseada em ambiente para garantir que as chaves corretas sejam carregadas para cada rede.

Infraestrutura de Assinatura

Para assinatura no backend em produção, use o Keychain — uma biblioteca de assinatura unificada que abstrai múltiplos backends de gerenciamento de chaves por meio de uma única interface: Memory, Vault, Privy, Turnkey, AWS KMS, Fireblocks, GCP KMS, CDP, Para, Dfns, Crossmint, Openfort e Utila. Isso permite que você desenvolva localmente com chaves em memória e, em seguida, troque para backends de nível de produção sem alterar o código da aplicação.

Não sabe qual backend é o ideal? Consulte Escolhendo um backend. O Keychain está disponível tanto para Rust quanto para TypeScript.

Segurança de RPC

Trate os endpoints RPC como chaves de API—não os exponha no código frontend onde podem ser extraídos e utilizados de forma abusiva. Use um proxy de backend ou variáveis de ambiente que não sejam incluídas no código do cliente.

Monitoramento

Acompanhe estas métricas em produção:

MétricaPor quê
Taxa de sucesso de transaçõesDetectar problemas precocemente
Latência de confirmaçãoMonitorar saúde da rede
Gasto com taxa de prioridadeGestão de custos
Taxa de erros RPCSaúde do provedor

Configure alertas para:

  • Transferências acima do limite da tesouraria
  • Picos na taxa de transações falhas
  • Padrões incomuns de destinatários
  • Aumentos na taxa de erros RPC

Para monitoramento de transações em tempo real em escala, consulte nosso Guia de Indexação.

Verificar Endereços

Cada token e programa tem exatamente um endereço correto na mainnet. Tokens falsificados imitando USDC ou outras stablecoins são comuns—eles terão o mesmo nome e símbolo, mas um mint diferente. Sua aplicação deve ter os endereços de mint codificados ou em lista de permissões (com base em seus requisitos), nunca os aceite dinamicamente de fontes não confiáveis.

Configuração baseada em ambiente: Devnet e Mainnet frequentemente usam mints de token completamente diferentes. Configure sua aplicação para carregar os endereços corretos por ambiente—não codifique endereços da mainnet permanentemente e esqueça de trocá-los durante os testes, ou pior, envie endereços da devnet para produção.

Alguns mints de stablecoin comuns são:

TokenEmissorEndereço do Mint
USDCCircleEPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v
USDTTetherEs9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB
PYUSDPayPal2b1kV6DkPAnxd5ixfnxCpjxmKwqjjaYmCZfHsFu24GXo
USDGPaxos2u1tszSeqZ3qBWF3uNGPFc8TzMk2tdiwknnRMWGWjGWH

Endereços de programa também são importantes. Enviar instruções para o programa errado falhará—ou pior, resultará em perda irreversível de fundos. Os endereços do Token Program são:

ProgramaEndereço
Token ProgramTokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA
Token-2022 ProgramTokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb

Adicionar os endereços corretos à lista de permissões protege contra tokens falsificados, mas não protege contra o envio para o tipo errado de conta. Um endereço de destinatário pode ser uma carteira, um token account, uma mint ou um programa, e cada um exige um tratamento diferente. SOL nativo enviado para qualquer coisa que não seja uma carteira sai do controle do remetente — perdido definitivamente no caso de uma mint ou programa, recuperável apenas pelo proprietário da conta no caso de um token account — sem nenhuma transação falhada para alertar o utilizador.

Valide os destinatários antes de enviar

Classifique cada endereço de destinatário antes de assinar uma transferência. Consulte Verificar Endereço para a árvore de decisão completa e o código de referência que distingue carteiras, token accounts, mints e programas.

Lista de Verificação Pré-Lançamento

  • SOL da Mainnet adquirido para taxas e rent
  • RPC de produção configurado (não endpoint público)
  • Endpoint RPC de fallback configurado
  • Taxas de prioridade implementadas com precificação dinâmica
  • Lógica de retry trata a expiração de blockhash
  • Nível de confirmação adequado para o caso de uso
  • Todos os erros comuns tratados adequadamente
  • Gasless configurado (se aplicável)
  • Endereços de tokens da Mainnet verificados (não mints da devnet)
  • Validação de endereço do destinatário antes do envio (carteira vs token account vs mint vs programa)
  • Todas as chaves guardadas em segurança
  • Gestão de chaves revista (sem chaves no frontend)
  • Monitorização e alertas de transações ativos
  • Teste de carga realizado no volume esperado

Implantação de Programas

Se estiver a implementar um programa Solana personalizado como parte da sua infraestrutura de pagamentos, existem considerações adicionais.

Pré-implantação

  • Versão do Solana CLI: Certifique-se de que está usando a versão mais recente do Solana CLI.
  • keypair do programa: Seu programa terá um endereço diferente na mainnet em relação à devnet (a menos que você esteja reutilizando o mesmo keypair). Atualize todas as referências na configuração da sua aplicação. Armazene o keypair do seu programa em um local seguro (observe que executar cargo clean provavelmente excluirá o keypair do seu programa).
  • Inicializar contas: Se o seu programa requer contas de administrador, PDAs ou outras contas de estado, certifique-se de que estas sejam criadas na mainnet antes que os usuários interajam com sua aplicação. O mesmo vale para quaisquer Associated Token Accounts (ATAs) que seu programa necessite.

Processo de Implantação

  • Contas de buffer: Programas grandes são implantados por meio de contas de buffer. O comando solana program deploy lida com isso automaticamente, mas saiba que a implantação não é atômica — se for interrompida, pode ser necessário recuperar ou fechar contas de buffer. Consulte Implantando Programas.
  • Autoridade de atualização: Decida se o seu programa deve ser atualizável após o lançamento. Para imutabilidade, revogue a autoridade de atualização após a implantação. Para flexibilidade, proteja adequadamente a chave de autoridade de atualização.
  • Rent: Certifique-se de que sua carteira de implantação tenha SOL suficiente para cobrir os mínimos de isenção de rent para todos os program accounts.
  • Verificação: Verifique seu programa para garantir que o programa executável que você implanta na rede da Solana corresponde ao código-fonte em seu repositório

Para orientações completas sobre implantação de programas, consulte Implantando Programas.

Is this page helpful?

© 2026 Fundação Solana. Todos os direitos reservados.