> ## Documentation Index
> Fetch the complete documentation index at: https://www.helius.dev/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Guia de Otimização de Transações Solana

> Otimize transações Solana para minimizar a latência de confirmação e maximizar as taxas de entrega. Saiba mais sobre taxas de prioridade, unidades de computação e melhores práticas.

Existem dois métodos principais para enviar transações em Solana:

1. Usando [conexões staked](https://www.helius.dev/staked-connections) (padrão)
2. Usando serviços de landing especializados como [Sender](https://www.helius.dev/sender) (recomendado)

Este artigo aborda as melhores práticas de otimização de transações ao usar conexões staked, que é o método padrão para todos os planos pagos da Helius.

As conexões staked são mais adequadas para casos de uso em que a latência não é crítica para o seu negócio (por exemplo, pagamentos, carteiras, aplicativos sociais, etc.)

Se você é um trader avançado (por exemplo, propAMM, sniper, copy trader, bot de liquidação, arbitragem) procurando um serviço de landing de transação especializado com baixa latência, leia nosso [tutorial Sender](/docs/pt-BR/sending-transactions/sender).

## Resumo

As conexões staked da Helius garantem 100% de entrega de transação com tempos de confirmação mínimos. Para otimizar suas taxas de landing de transação com conexões staked, recomendamos as seguintes melhores práticas:

* Use o compromisso "confirmed" para buscar o [blockhash mais recente](/docs/pt-BR/rpc/guides/getlatestblockhash)
* Adicione [taxas de prioridade](/docs/pt-BR/sending-transactions/optimizing-transactions#setting-the-right-priority-fee) e calcule-as dinamicamente
* Otimize o uso de unidade de computação (CU)
* Defina `maxRetries` para 0 e implemente lógica de retentativa robusta
* Envie com `skipPreflight` definido para `true` (opcional)

<Tip>
  Quer ir mais a fundo? Cobrimos todos os fundamentos neste [post do blog](https://www.helius.dev/blog/how-to-land-transactions-on-solana).
</Tip>

## Otimizações Recomendadas para Traders

Para casos de uso de negociação sensíveis à latência, recomendamos [usar o Sender](/docs/pt-BR/sending-transactions/sender).

No entanto, se você estiver usando conexões staked e quiser otimizar sua configuração para as latências mais baixas possíveis, recomendamos as seguintes otimizações (além de aplicar as melhores práticas mencionadas acima):

* Seu servidor cliente (a máquina que você usa para enviar transações) deve estar localizado no Leste dos EUA ou na Europa Ocidental.
* Escolha FRA ou PIT se quiser co-locar com os servidores de envio de transações da Helius.
* Evite enviar de regiões distantes da rede do validador (por exemplo, LATAM, África do Sul).
* Aqueça os caches regionais da Helius para minimizar a latência de cauda.
* Apenas um thread de aquecimento é necessário por região - qualquer mais não terá benefício.
* Envie uma chamada RPC [`getHealth`](/docs/pt-BR/rpc/guides/gethealth) a cada segundo usando o mesmo endpoint e chave de API que você usa para enviar transações.

Esses benefícios serão notáveis apenas para traders experientes. Para desenvolvedores de aplicativos em geral, recomendamos seguir as diretrizes na seção Enviando Transações Inteligentes abaixo.

<Tip>
  Obtenha dados de transações onchain o mais rápido possível com [Raw Shreds (UDP)](/docs/pt-BR/shred-delivery/raw-shreds). [Inscreva-se no seu Dashboard da Helius](https://dashboard.helius.dev/shred-delivery-seats).
</Tip>

## Enviando Transações Inteligentes

Tanto os SDKs Helius [Node.js](/docs/pt-BR/sending-transactions/optimizing-transactions#node-js-sdk) quanto [Rust](/docs/pt-BR/sending-transactions/optimizing-transactions#rust-sdk) podem enviar transações inteligentes. Este novo método constrói e envia uma transação otimizada enquanto gerencia seu status de confirmação.

Os usuários podem configurar as opções de envio da transação, como, por exemplo, se a transação deve pular verificações preflight.

No nível mais básico, os usuários devem fornecer seu par de chaves e as instruções que desejam executar, e nós cuidamos do resto.

Nós:

* Buscamos o blockhash mais recente
* Construímos a transação inicial
* Simulamos a transação inicial para buscar as unidades de computação (CUs) consumidas
* Definimos o limite de CU para as CUs consumidas na etapa anterior, com alguma margem
* Obtemos a taxa de prioridade recomendada pela Helius via nossa [API de Taxa de Prioridade](/docs/pt-BR/priority-fee-api)
* Definimos a taxa de prioridade (microlamports por CU) como a taxa recomendada pela Helius
* Adicionamos uma pequena taxa de buffer caso a taxa recomendada mude nos próximos segundos
* Construímos e enviamos a transação otimizada
* Retornamos a assinatura da transação se for bem-sucedida

<Note>
  Requerer o valor recomendado (ou superior) para nossas conexões staked garante que a Helius envie transações de alta qualidade e que não seremos limitados pelos validadores.
</Note>

Este método é a maneira mais fácil de construir, enviar e aterrar uma transação em Solana.

Ao usar a taxa recomendada pela Helius, as transações enviadas por usuários da Helius em um de nossos [planos pagos padrão](/docs/pt-BR/billing/plans) serão enviadas por nossas conexões staked, garantindo quase 100% de entrega de transação e latência mínima.

### Node.js SDK

O método `sendSmartTransaction` está disponível no nosso [Helius Node.js SDK](/docs/pt-BR/sdks) para [versões >= 1.3.2](https://www.npmjs.com/package/helius-sdk). Para atualizar para uma versão mais recente do SDK, execute `npm update helius-sdk`.

Este exemplo transfere SOL para uma conta de sua escolha. Ele usa `sendSmartTransaction` para enviar uma transação otimizada que não pula verificações preflight:

```typescript theme={"system"}
import { Helius } from "helius-sdk";
import {
  Keypair,
  SystemProgram,
  LAMPORTS_PER_SOL,
  TransactionInstruction,
} from "@solana/web3.js";

const helius = new Helius("YOUR_API_KEY");
const fromKeypair = /* Your keypair goes here */;
const fromPubkey = fromKeypair.publicKey;
const toPubkey = /* The person we're sending 0.5 SOL to */;

const instructions: TransactionInstruction[] = [
  SystemProgram.transfer({
    fromPubkey: fromPubkey,
    toPubkey: toPubkey,
    lamports: 0.5 * LAMPORTS_PER_SOL, 
  }),
];

const transactionSignature = await helius.rpc.sendSmartTransaction(instructions, [fromKeypair]);
console.log(`Successful transfer: ${transactionSignature}`);
```

### Rust SDK

O método `send_smart_transaction` está disponível no nosso [Rust SDK](/docs/pt-BR/sdks) para [versões >= 0.1.5](https://docs.rs/helius/latest/helius/). Para atualizar para uma versão mais recente do SDK, execute `cargo update helius`.

O exemplo a seguir transfere 0,01 SOL para uma conta de sua escolha.

Ele utiliza `send_smart_transaction` para enviar uma transação otimizada que pula verificações preflight e faz retentativas duas vezes, se necessário:

```rust theme={"system"}
use helius::types::*;
use helius::Helius;
use solana_sdk::{
    pubkey::Pubkey,
    signature::Keypair,
    system_instruction
};

#[tokio::main]
async fn main() {
    let api_key: &str = "YOUR_API_KEY";
    let cluster: Cluster = Cluster::MainnetBeta;
    let helius: Helius = Helius::new(api_key, cluster).unwrap();
    
    let from_keypair: Keypair = /* Your keypair goes here */;
    let from_pubkey: Pubkey = from_keypair.pubkey();
    let to_pubkey: Pubkey = /* The person we're sending 0.01 SOL to */;

    // Create a simple instruction (transfer 0.01 SOL from from_pubkey to to_pubkey)
    let transfer_amount = 100_000; // 0.01 SOL in lamports
    let instruction = system_instruction::transfer(&from_pubkey, &to_pubkey, transfer_amount);

    // Create the SmartTransactionConfig
    let config = SmartTransactionConfig {
        instructions,
        signers: vec![&from_keypair],
        send_options: RpcSendTransactionConfig {
            skip_preflight: true,
            preflight_commitment: None,
            encoding: None,
            max_retries: Some(2),
            min_context_slot: None,
        },
        lookup_tables: None,
    };

    // Send the optimized transaction
    match helius.send_smart_transaction(config).await {
        Ok(signature) => {
            println!("Transaction sent successfully: {}", signature);
        }
        Err(e) => {
            eprintln!("Failed to send transaction: {:?}", e);
        }
    }
}
```

## Enviando Transações Sem o SDK

Recomendamos enviar transações inteligentes com um de nossos SDKs, mas a mesma funcionalidade pode ser alcançada sem usar um.

Tanto o Node.js SDK quanto o Rust SDK são de código aberto, então o código subjacente para a funcionalidade de enviar transação inteligente pode ser visualizado a qualquer momento.

### Preparar e Construir a Transação Inicial

Primeiro, prepare e construa a transação inicial. Isso inclui criar uma nova transação com um conjunto de instruções, adicionar o blockhash recente e designar um pagador de taxas.

Para transações versionadas, crie um `TransactionMessage` e compile-o com tabelas de consulta, se houver.

Em seguida, crie uma nova transação versionada e assine-a — isso é necessário para o próximo passo, quando simulamos a transação, pois a transação deve ser assinada.

Por exemplo, se quiséssemos preparar uma transação versionada:

```typescript theme={"system"}
// Prepare your instructions and set them to an instructions variable
// The payerKey is the public key that will be paying for this transaction
// Prepare your lookup tables and set them to a lookupTables variable
let recentBlockhash = (await this.connection.getLatestBlockhash()).blockhash;
const v0Message = new TransactionMessage({
    instructions: instructions,
    payerKey: pubKey,
    recentBlockhash: recentBlockhash,
}).compileToV0Message(lookupTables);
versionedTransaction = new VersionedTransaction(v0Message);
versionedTransaction.sign([fromKeypair]);
```

### Otimizar o Uso da Unidade de Computação (CU) da Transação

Para [otimizar o uso da unidade de computação (CU) da transação](https://www.helius.dev/blog/optimizing-solana-programs), podemos usar o método RPC `simulateTransaction` para simular a transação.

[Simular a transação](/docs/pt-BR/api-reference/rpc/http/simulatetransaction) retornará a quantidade de CUs utilizadas, para que possamos usar esse valor para definir nosso limite de computação adequadamente.

É recomendado usar uma transação de teste com as instruções desejadas primeiro, além de uma instrução que define o limite de computação para 1,4m CUs.

Isso é feito para garantir que a simulação da transação tenha sucesso.

Por exemplo:

```typescript theme={"system"}
const testInstructions = [
    ComputeBudgetProgram.setComputeUnitLimit({ units: 1_400_000 }),
    ...instructions,
];

const testTransaction = new VersionedTransaction(
    new TransactionMessage({
        instructions: testInstructions,
        payerKey: payer,
        recentBlockhash: (await this.connection.getLatestBlockhash()).blockhash,
    }).compileToV0Message(lookupTables)
);

const rpcResponse = await this.connection.simulateTransaction(testTransaction, {
    replaceRecentBlockhash: true,
    sigVerify: false,
});

const unitsConsumed = rpcResponse.value.unitsConsumed;
```

Também é recomendado adicionar um pouco de margem para garantir que a transação seja executada sem problemas. Podemos fazer isso definindo o seguinte:

```typescript theme={"system"}
let customersCU = Math.ceil(unitsConsumed * 1.1);
```

Em seguida, crie uma instrução que define o limite da unidade de computação para esse valor e adicione-o ao seu array de instruções:

```typescript theme={"system"}
const computeUnitIx = ComputeBudgetProgram.setComputeUnitLimit({
    units: customersCU
});
instructions.push(computeUnitIx);
```

### Serializar e Codificar a Transação

Isso é relativamente simples.

Primeiro, para serializar a transação, ambos os tipos Transaction e VersionedTransaction têm um método `.serialize()`. Em seguida, use o [pacote bs58](https://www.npmjs.com/package/bs58) para codificar a transação.

Seu código deve ser semelhante a `bs58.encode(txt.serialize());`

### Definindo a Taxa de Prioridade Correta

Primeiro, use a [API de Taxa de Prioridade](/docs/pt-BR/priority-fee-api) para obter a estimativa da taxa de prioridade. Queremos passar nossa transação e obter a taxa recomendada pela Helius via o parâmetro recomendado:

```typescript theme={"system"}
const response = await fetch(HeliusURL, {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({
        jsonrpc: "2.0",
        id: "1",
        method: "getPriorityFeeEstimate",
        params: [
            {
                transaction: bs58.encode(versionedTransaction), // Pass the serialized transaction in
                options: { recommended: true },
            },
        ],   
    }),
});

const data = await response.json();
const priorityFeeRecommendation = data.result.priorityFeeEstimate;
```

Em seguida, crie uma instrução que define o preço da unidade de computação para esse valor e adicione essa instrução às suas instruções anteriores:

```typescript theme={"system"}
const computeBudgetIx = ComputeBudgetProgram.setComputeUnitPrice({
    microLamports: priorityFeeRecommendation,
});

instructions.push(computeBudgetIx);
```

### Construir e Enviar a Transação Otimizada

Esta etapa é quase uma repetição da primeira etapa. No entanto, o array de instruções iniciais foi alterado para adicionar duas instruções para definir o limite e o preço da unidade de computação de forma otimizada.

Agora, envie a transação.

Não importa se você enviar com ou sem verificações preflight ou alterar qualquer outra opção de envio — a transação será encaminhada por nossas conexões staked para todos os planos pagos.

### Consultar o Status da Transação e Reenviá-la

<Warning>
  Embora as conexões staked encaminhem uma transação diretamente para o líder, ainda é possível que a transação seja descartada no [Estágio Bancário](https://www.helius.dev/blog/solana-virtual-machine#the-banking-stage). Recomenda-se que os usuários empreguem sua própria lógica de reenviamento em vez de confiar no RPC para reenviar a transação por eles.
</Warning>

O método RPC [`sendTransaction`](/docs/pt-BR/api-reference/rpc/http/sendtransaction) tem um parâmetro `maxRetries` que pode ser definido para substituir a lógica de retentativa padrão do RPC, dando aos desenvolvedores mais controle sobre o processo de retentativa.

É um padrão comum buscar o blockhash atual via [`getLatestBlockhash`](/docs/pt-BR/rpc/guides/getlatestblockhash), armazenar o `lastValidBlockHeight`, e reenviar a transação até que o blockhash expire.

É crucial re-assinar uma transação apenas quando o blockhash não for mais válido, caso contrário, é possível que ambas as transações sejam aceitas pela rede.

Uma vez que uma transação é enviada, é importante consultar seu status de confirmação para ver se a rede a processou e confirmou antes de reenviar. Use o método RPC [`getSignatureStatuses`](/docs/pt-BR/rpc/guides/getsignaturestatuses) para verificar a lista de status de confirmação das transações.

O SDK @solana/web3.js também tem um método `getSignatureStatuses` em sua classe `Connection` para buscar o status atual de várias assinaturas.

### Como o sendSmartTransaction Lida com Consultas e Reenviamentos

O método `sendSmartTransaction` tem um período de tempo limite de 60 segundos. Como um blockhash é válido por 150 slots, e assumindo slots perfeitos de 400ms, podemos assumir razoavelmente que um blockhash de transação será inválido após um minuto.

O método envia a transação e consulta sua assinatura usando este período de tempo limite:

```typescript theme={"system"}
try {
   // Create a smart transaction
   const transaction = await this.createSmartTransaction(instructions, signers, lookupTables, sendOptions);
  
   const timeout = 60000;
   const startTime = Date.now();
   let txtSig;
  
   while (Date.now() - startTime < timeout) {
     try {
       txtSig = await this.connection.sendRawTransaction(transaction.serialize(), {
         skipPreflight: sendOptions.skipPreflight,
         ...sendOptions,
       });
  
       return await this.pollTransactionConfirmation(txtSig);
     } catch (error) {
       continue;
     }
   }
} catch (error) {
   throw new Error(`Error sending smart transaction: ${error}`);
}
```

`txtSig` é definido para a assinatura da transação que acabou de ser enviada.

O método então usa o método `pollTransactionConfirmation()` para consultar o status de confirmação da transação. Este método verifica o status de uma transação a cada cinco segundos por um máximo de três vezes.

Se a transação não for confirmada durante este tempo, um erro é retornado:

```typescript theme={"system"}
async pollTransactionConfirmation(txtSig: TransactionSignature): Promise<TransactionSignature> {
    // 15 second timeout
    const timeout = 15000;
    // 5 second retry interval
    const interval = 5000;
    let elapsed = 0;

    return new Promise<TransactionSignature>((resolve, reject) => {
      const intervalId = setInterval(async () => {
        elapsed += interval;

        if (elapsed >= timeout) {
          clearInterval(intervalId);
          reject(new Error(`Transaction ${txtSig}'s confirmation timed out`));
        }

        const status = await this.connection.getSignatureStatuses([txtSig]);

        if (status?.value[0]?.confirmationStatus === "confirmed") {
          clearInterval(intervalId);
          resolve(txtSig);
        }
      }, interval);
   });
}
```
