> ## 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.

# Melhores Práticas para o SDK TypeScript

> Padrões recomendados para agentes de IA usando o Helius TypeScript SDK. Cobre histórico de transações, envio de transações, agrupamento, dados em tempo real, paginação, busca incremental, erros comuns e tratamento de erros.

Melhores práticas e padrões recomendados para agentes usando o [Helius TypeScript SDK](https://github.com/helius-labs/helius-sdk). Para instalação e introdução, veja a [visão geral](/docs/pt-BR/agents/typescript-sdk).

## Recomendações para Agentes

### Use `getTransactionsForAddress` em vez de pesquisa em duas etapas

`getTransactionsForAddress` combina pesquisa de assinatura e busca de transação em uma única chamada com filtragem no servidor. Suporta intervalos de tempo/slot, filtragem de contas de token e paginação.

```typescript theme={"system"}
// GOOD: Single call, server-side filtering
const txs = await helius.getTransactionsForAddress([
  "address",
  {
    transactionDetails: "full",
    limit: 100,
    filters: {
      tokenAccounts: "balanceChanged",
      blockTime: { gte: Math.floor(Date.now() / 1000) - 86400 },
    },
  },
]);

// BAD: Two calls, client-side filtering, no token account support
const sigs = await helius.raw.getSignaturesForAddress(address).send();
const txs = await Promise.all(sigs.map(s => helius.raw.getTransaction(s.signature).send()));
```

### Use `sendSmartTransaction` para envios padrão

Simula automaticamente, estima unidades de computação, busca taxas de prioridade e confirma. Não construa manualmente instruções ComputeBudget — o SDK as adiciona automaticamente.

```typescript theme={"system"}
const sig = await helius.tx.sendSmartTransaction({
  instructions: [yourInstruction],
  signers: [walletSigner],
  commitment: "confirmed",
  priorityFeeCap: 100_000,   // Optional: cap fees in microlamports/CU
  bufferPct: 0.1,            // 10% compute unit headroom (default)
});
```

### Use Helius Sender para latência ultrabaixa

Para transações sensíveis ao tempo (arbitragem, sniping, liquidações), use `sendTransactionWithSender`. Ele faz o roteamento através da infraestrutura multirregional da Helius e Jito.

```typescript theme={"system"}
const sig = await helius.tx.sendTransactionWithSender({
  instructions: [yourInstruction],
  signers: [walletSigner],
  region: "US_EAST",          // Default, US_SLC, US_EAST, EU_WEST, EU_CENTRAL, EU_NORTH, AP_SINGAPORE, AP_TOKYO
  swqosOnly: true,            // Route through SWQOS only (lower tip requirement)
  pollTimeoutMs: 60_000,
  pollIntervalMs: 2_000,
});
```

### Use `getAssetBatch` para múltiplos ativos

Ao buscar mais de um ativo, agrupe-os. Não chame `getAsset` em um loop.

```typescript theme={"system"}
// GOOD: Single request
const assets = await helius.getAssetBatch({
  ids: ["mint1", "mint2", "mint3"],
  options: { showFungible: true, showCollectionMetadata: true },
});

// BAD: N requests
const assets = await Promise.all(mints.map(id => helius.getAsset({ id })));
```

### Use webhooks ou WebSockets em vez de polling

Não faça polling de `getTransactionsForAddress` em um loop. Use webhooks para notificações de servidor para servidor ou WebSockets para streaming em tempo real no lado do cliente.

```typescript theme={"system"}
// Webhook: server receives POST on matching transactions
const webhook = await helius.webhooks.create({
  webhookURL: "https://your-server.com/webhook",
  webhookType: "enhanced",
  transactionTypes: ["TRANSFER", "NFT_SALE", "SWAP"],
  accountAddresses: ["address_to_monitor"],
  authHeader: "Bearer your-secret",
});

// WebSocket: stream logs in real-time
const req = await helius.ws.logsNotifications({ mentions: ["address"] });
const stream = await req.subscribe({ abortSignal: controller.signal });
for await (const log of stream) {
  console.log(log);
}
```

## Paginação

O SDK usa diferentes estratégias de paginação dependendo do método.

### Baseada em Token/Cursor (Métodos RPC V2)

```typescript theme={"system"}
// getTransactionsForAddress uses paginationToken
let paginationToken = null;
const allTxs = [];
do {
  const result = await helius.getTransactionsForAddress([
    "address",
    { limit: 100, paginationToken },
  ]);
  allTxs.push(...result.data);
  paginationToken = result.paginationToken;
} while (paginationToken);

// getProgramAccountsV2 uses paginationKey
let paginationKey = null;
do {
  const result = await helius.getProgramAccountsV2([
    programId,
    { limit: 1000, paginationKey },
  ]);
  // process result.accounts
  paginationKey = result.paginationKey;
} while (paginationKey);
```

### Baseada em Página (API DAS)

```typescript theme={"system"}
let page = 1;
const allAssets = [];
while (true) {
  const result = await helius.getAssetsByOwner({ ownerAddress: "...", page, limit: 1000 });
  allAssets.push(...result.items);
  if (result.items.length < 1000) break;
  page++;
}
```

## Filtro `tokenAccounts`

Ao consultar `getTransactionsForAddress`, o filtro `tokenAccounts` controla se a atividade da conta de token está incluída:

| Valor              | Comportamento                                            | Use Quando                                                                                 |
| ------------------ | -------------------------------------------------------- | ------------------------------------------------------------------------------------------ |
| omitido / `"none"` | Apenas transações diretamente envolvendo o endereço      | Você só se importa com transferências de SOL e chamadas de programa                        |
| `"balanceChanged"` | Também inclui transações de token que alteraram um saldo | **Recomendado para a maioria dos agentes** — mostra envios/recebimentos de token sem ruído |
| `"all"`            | Inclui todas as transações de contas de token            | Você precisa de atividade completa de token (pode retornar muitos resultados)              |

## `changedSinceSlot` — Busca Incremental de Contas

`changedSinceSlot` retorna apenas contas modificadas após um determinado slot. Útil para sincronização ou fluxos de indexação. Suportado por `getProgramAccountsV2`, `getTokenAccountsByOwnerV2`, `getAccountInfo`, `getMultipleAccounts`, `getProgramAccounts`, e `getTokenAccountsByOwner`.

```typescript theme={"system"}
// First fetch: get all accounts
const baseline = await helius.getProgramAccountsV2([programId, { limit: 10_000 }]);
const lastSlot = currentSlot;

// Later: only get accounts that changed since your last fetch
const updates = await helius.getProgramAccountsV2([
  programId,
  { limit: 10_000, changedSinceSlot: lastSlot },
]);
```

## Erros Comuns

1. **`transactionDetails: "full"` não é o padrão** — Por padrão, `getTransactionsForAddress` retorna apenas assinaturas. Defina `transactionDetails: "full"` para obter dados completos da transação.

2. **Não adicione instruções ComputeBudget com `sendSmartTransaction`** — O SDK as adiciona automaticamente. Adicionar as suas próprias causa instruções duplicadas e falha na transação.

3. **As taxas de prioridade são em microlamports por unidade de computação** — Não em lamports. Os valores de `getPriorityFeeEstimate` já estão na unidade correta para `SetComputeUnitPrice`.

4. **A paginação DAS é indexada em 1** — `page: 1` é a primeira página, não `page: 0`.

5. **`blockTime` é em segundos Unix, não milissegundos** — Use `Math.floor(Date.now() / 1000)` ao filtrar por `blockTime`.

6. **`getAsset` oculta tokens fungíveis por padrão** — Passe `options: { showFungible: true }` para incluí-los.

7. **Streams de WebSocket precisam de limpeza** — Sempre use um sinal AbortController e chame `helius.ws.close()` quando terminar para evitar vazamentos de conexão.

## Tratamento de Erros e Repetições

O SDK lança objetos `Error` nativos com o código de status HTTP embutido na string de mensagem (por exemplo, `"API error (429): ..."`). Não há propriedade `.status` no objeto de erro, então a detecção de status requer análise da mensagem.

```typescript theme={"system"}
async function withRetry<T>(fn: () => Promise<T>, maxRetries = 3): Promise<T> {
  for (let attempt = 0; attempt <= maxRetries; attempt++) {
    try {
      return await fn();
    } catch (error) {
      const msg = error instanceof Error ? error.message : "";
      const status = msg.match(/\b(\d{3})\b/)?.[1];
      const retryable = status === "429" || (status && status.startsWith("5"));
      if (!retryable || attempt === maxRetries) throw error;
      await new Promise(r => setTimeout(r, 1000 * 2 ** attempt));
    }
  }
  throw new Error("Unreachable");
}
```

| Status | Significado                                   | Ação                                  |
| ------ | --------------------------------------------- | ------------------------------------- |
| 401    | Chave de API inválida ou ausente              | Verifique a chave de API              |
| 429    | Limite de taxa atingido ou créditos esgotados | Recuar e tentar novamente             |
| 5xx    | Erro do servidor                              | Tente novamente com recuo exponencial |
