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

# Filtragem de Conta de Token (ATA)

> Capture transferências de tokens SPL recebidas de uma carteira nos fluxos gRPC e WebSocket do LaserStream com expansão de tokenAccounts (ATA) — correspondência baseada em proprietário que um filtro accountInclude simples perde.

O filtro `tokenAccounts` do LaserStream permite que uma assinatura de transação corresponda a atividades nas **contas de token associadas (ATAs) que uma carteira possui**, não apenas transações onde a pubkey da carteira aparece diretamente. Funciona da mesma forma tanto no [LaserStream gRPC](/docs/pt-BR/laserstream/grpc) quanto no [LaserStream WSS](/docs/pt-BR/rpc/websocket/transaction-subscribe).

## O problema: filtros de conta simples perdem transferências de token recebidas

Quando você observa uma carteira com `accountInclude: [wallet]`, apenas corresponde a transações onde essa pubkey de carteira aparece nas chaves de conta da transação. Um caso comum passa despercebido: quando alguém envia para a carteira um token SPL (USDC, por exemplo), a transferência toca na **conta de token associada (ATA)** da carteira — um endereço derivado separado — não na própria pubkey da carteira.

Portanto, uma assinatura `accountInclude: [wallet]` simples nunca vê transferências de token recebidas. Você teria que enumerar todas as ATAs que a carteira possui antecipadamente e adicionar cada uma ao filtro — mas as ATAs são criadas sob demanda (uma por mint), então você não pode saber o conjunto completo com antecedência.

## Como funciona a expansão `tokenAccounts`

Defina `tokenAccounts` em um filtro de transação para expandir a correspondência de modo que uma carteira `accountInclude` **também** corresponda a transações que toquem uma conta de token que ela possui. A correspondência é **baseada em proprietário**: o LaserStream resolve as contas de token possuídas pelos seus endereços `accountInclude` no momento da correspondência, assim capturando qualquer conta de token que a carteira possua — incluindo as não canônicas — não apenas o endereço ATA derivado. Você nunca precisa listar as ATAs.

Assinaturas que omitem `tokenAccounts` se comportam exatamente como antes, portanto é seguro adicionar a um filtro existente.

## Modos de Expansão

`tokenAccounts` aceita um dos três valores de string:

| Valor              | Corresponde                                                                                                  | Volume                       | Use para                                                                                                  |
| ------------------ | ------------------------------------------------------------------------------------------------------------ | ---------------------------- | --------------------------------------------------------------------------------------------------------- |
| `"balanceChanged"` | Transações onde um saldo de token possuído realmente mudou (ou sua conta de token foi fechada)               | Menor — o padrão recomendado | "Avise-me quando o dinheiro realmente se mover" — depósitos, retiradas, swaps que se liquidam na carteira |
| `"all"`            | Qualquer transação que faz referência a uma conta de token que a carteira possui, mesmo se o saldo não mudou | Maior                        | Visibilidade completa em qualquer coisa que toque as contas de token da carteira                          |
| `"none"`           | Sem expansão — idêntico a omitir o campo                                                                     | —                            | O padrão                                                                                                  |

Comece com `"balanceChanged"`. Captura movimento real de fundos com uma fração do volume de `"all"`.

## Use no LaserStream gRPC

Adicione `tokenAccounts` a um filtro de transação no seu `SubscribeRequest`. O [Helius LaserStream SDK](/docs/pt-BR/laserstream/clients) converte a string para o enum de nível de wire `TokenAccountExpansionControlFlag` para você (parte do `yellowstone-grpc-proto` 12.5.0+).

```typescript theme={"system"}
import { subscribe, CommitmentLevel, LaserstreamConfig, SubscribeRequest } from 'helius-laserstream';
import bs58 from 'bs58';

const wallet = '<WALLET_PUBKEY>';

const subscriptionRequest: SubscribeRequest = {
  transactions: {
    "wallet-activity": {
      accountInclude: [wallet],
      accountExclude: [],
      accountRequired: [],
      vote: false,
      failed: false,
      tokenAccounts: "balanceChanged" // also match the wallet's ATAs
    }
  },
  commitment: CommitmentLevel.CONFIRMED,
  accounts: {}, slots: {}, transactionsStatus: {},
  blocks: {}, blocksMeta: {}, entry: {}, accountsDataSlice: [],
};

const config: LaserstreamConfig = {
  apiKey: 'YOUR_API_KEY',
  endpoint: 'https://laserstream-mainnet-ewr.helius-rpc.com',
};

await subscribe(config, subscriptionRequest, async (data) => {
  if (!data.transaction?.transaction) return;
  const tx = data.transaction.transaction;
  // Token balances this wallet owns that changed in the tx
  const owned = (tx.meta?.postTokenBalances || []).filter((b: any) => b.owner === wallet);
  console.log(bs58.encode(tx.signature), owned);
}, async (error) => {
  console.error('Stream error:', error);
});
```

Veja o [Guia de Monitoramento de Transação](/docs/pt-BR/laserstream/guides/transaction-monitoring) para um exemplo mais completo que diferencia saldos antes e depois, e a [referência de Pedido de Inscrição](/docs/pt-BR/laserstream/grpc) para cada campo de filtro de transação.

## Use no LaserStream WebSocket

O mesmo campo está disponível no método [`transactionSubscribe`](/docs/pt-BR/rpc/websocket/transaction-subscribe) WebSocket — uma extensão Helius ao padrão API WebSocket do Solana. Um valor inválido retorna o erro JSON-RPC `-32602`: `Invalid tokenAccounts value '<x>', expected one of: none, balanceChanged, all`.

```javascript theme={"system"}
const ws = new WebSocket('wss://mainnet.helius-rpc.com/?api-key=<API_KEY>');

ws.on('open', () => {
  ws.send(JSON.stringify({
    jsonrpc: '2.0',
    id: 1,
    method: 'transactionSubscribe',
    params: [
      {
        accountInclude: ['<WALLET_PUBKEY>'],
        tokenAccounts: 'balanceChanged' // also match the wallet's ATAs
      },
      { commitment: 'confirmed', encoding: 'jsonParsed', maxSupportedTransactionVersion: 0 }
    ]
  }));
  setInterval(() => ws.ping(), 30_000);
});

ws.on('message', (data) => {
  const msg = JSON.parse(data.toString());
  const result = msg.params?.result;
  if (!result) return;
  // Token balances this wallet owns that changed in the tx
  const owned = (result.transaction.meta.postTokenBalances || [])
    .filter((b) => b.owner === '<WALLET_PUBKEY>');
  console.log(result.signature, owned);
});
```

## Lendo o que correspondeu

Uma vez que uma transação corresponda via expansão ATA, o movimento de token da carteira vive no `meta.postTokenBalances` e `meta.preTokenBalances` da transação. Filtre essas entradas por `owner` para isolar os saldos que sua carteira realmente possui, e depois diferencie `preTokenBalances` contra `postTokenBalances` no mesmo `accountIndex` para ver quanto cada mint se moveu. Os exemplos acima mostram a etapa de filtragem; o [Guia de Monitoramento de Transação](/docs/pt-BR/laserstream/guides/transaction-monitoring#example-4-watch-a-wallet-incl-token-transfers) mostra a diferença completa.

## Relacionado

<CardGroup cols={2}>
  <Card title="Monitoramento de Transação" icon="receipt" href="/docs/pt-BR/laserstream/guides/transaction-monitoring">
    Estratégias completas de filtragem e um exemplo executável de observação de carteira sobre gRPC.
  </Card>

  <Card title="transactionSubscribe (WebSocket)" icon="bolt" href="/docs/pt-BR/rpc/websocket/transaction-subscribe">
    O mesmo campo `tokenAccounts` no método WebSocket `transactionSubscribe`.
  </Card>

  <Card title="Referência de Pedido de Inscrição" icon="filter" href="/docs/pt-BR/laserstream/grpc">
    Cada campo de filtro de transação, incluindo `tokenAccounts`.
  </Card>

  <Card title="Filtros Compactados" icon="layer-group" href="/docs/pt-BR/laserstream/cuckoo-filters">
    Acompanhe centenas de milhares de contas em um fluxo.
  </Card>
</CardGroup>
