> ## 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 por mint de token

> Assine todas as transações que envolvem um mint de token no LaserStream gRPC com matchMints. Isso captura transferências SPL que accountInclude não detecta porque o mint não está nas chaves de conta.

A flag `matchMints` do LaserStream permite que uma assinatura de transações gRPC faça correspondência com os **mints de token nos saldos de token anteriores/posteriores de uma transação**, além das chaves de conta.

Coloque um mint em `accountInclude`, defina `matchMints: true` e você receberá todas as transações que envolvem esse token: transferências, swaps, emissões, queimas e encerramentos de contas.

<Note>
  `matchMints` está disponível apenas no LaserStream gRPC. Ainda não está disponível no LaserStream WebSocket.
</Note>

## O problema: filtros de conta simples não detectam a maioria das transferências de tokens

Ao monitorar um token com `accountInclude: [mint]`, você só encontra transações em que a chave pública do mint aparece nas chaves de conta da transação.

Uma instrução SPL `Transfer` clássica nunca referencia o mint. Ela informa apenas a conta de token de origem, a conta de token de destino e o proprietário. Por isso, um filtro de conta simples não detecta a operação mais comum de qualquer token.

Somente instruções que passam o mint diretamente geram uma correspondência, como `MintTo`, `Burn`, `TransferChecked` e swaps cujas contas de programa incluem o mint. A única solução alternativa era transmitir todas as transações e inspecionar por conta própria os saldos de token de cada uma.

## Como `matchMints` funciona

Defina `matchMints: true` em um filtro de transações e o LaserStream criará um conjunto de mints com base em `preTokenBalances` e `postTokenBalances` da transação.

As listas `accountInclude`, `accountExclude` e `accountRequired` são então comparadas com **ambos**: as chaves de conta e esse conjunto de mints. Um mint atende ao critério se qualquer conta de token dele aparecer em uma das listas de saldos, independentemente de o saldo ter sido alterado.

A flag é opcional, e os filtros que a omitem continuam funcionando exatamente como antes. Assim, você pode adicioná-la a uma assinatura existente sem alterar o que essa assinatura já recebe. Mints SPL e Token-2022 funcionam porque ambos os programas preenchem os saldos de token anteriores/posteriores.

## Semântica

| Predicado         | Sem `matchMints`                                                  | Com `matchMints: true`                                                                                                                         |
| ----------------- | ----------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- |
| `accountInclude`  | Corresponde se qualquer chave listada estiver nas chaves de conta | Corresponde se qualquer chave listada estiver nas chaves de conta **ou** no conjunto de mints                                                  |
| `accountExclude`  | Rejeita se qualquer chave listada estiver nas chaves de conta     | Rejeita se qualquer chave listada estiver nas chaves de conta **ou** no conjunto de mints                                                      |
| `accountRequired` | Todas as chaves listadas devem estar nas chaves de conta          | Todas as chaves listadas devem estar nas chaves de conta **ou** no conjunto de mints (cada chave pode ser satisfeita por qualquer um dos dois) |

O restante da lógica do filtro permanece inalterado:

* Os predicados dentro de um mesmo filtro nomeado continuam combinados com AND (`vote`, `failed`, `signature` e as listas de contas).
* Vários filtros nomeados continuam combinados com OR.
* Os valores dentro de uma lista são combinados com OR (exceto em `accountRequired`, em que todos devem corresponder).
* Uma transação sem saldos de token volta a usar a correspondência somente por chaves. `matchMints` nunca adiciona transações sem atividade de token.
* `matchMints` isoladamente não restringe o stream. Você ainda precisa de pelo menos uma chave ou um mint em uma lista de contas (ou outro predicado restritivo) para que o filtro seja aceito.

<Note>
  O LaserStream faz a correspondência de mints pela chave pública exata. Não há um modo de "apenas saldo alterado" para mints, diferentemente de `tokenAccounts: "balanceChanged"`.
</Note>

## Use no LaserStream gRPC

Adicione `matchMints: true` a um filtro de transações em seu `SubscribeRequest` e coloque o mint em `accountInclude`. Este exemplo transmite todas as transações de USDC na mainnet:

<Tabs>
  <Tab title="TypeScript">
    Requer `helius-laserstream` 0.8.5 ou posterior. O campo também é aceito como `match_mints`.

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

    const USDC = 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v';

    const subscriptionRequest: SubscribeRequest = {
      transactions: {
        'usdc-txs': {
          accountInclude: [USDC],
          accountExclude: [],
          accountRequired: [],
          vote: false,
          failed: false,
          matchMints: true, // match USDC via pre/post token-balance mints
        },
      },
      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) => {
      const tx = data.transaction?.transaction;
      if (!tx) return;
      // USDC balances touched by this transaction
      const usdcBalances = (tx.meta?.postTokenBalances || []).filter((b: any) => b.mint === USDC);
      console.log(bs58.encode(tx.signature), usdcBalances);
    }, async (error) => {
      console.error('Stream error:', error);
    });
    ```
  </Tab>

  <Tab title="Rust">
    Requer `helius-laserstream` 0.6.4 ou posterior (que inclui `laserstream-core-proto` 11.3.0). O campo vem diretamente do crate proto.

    ```rust theme={"system"}
    use std::collections::HashMap;
    use helius_laserstream::grpc::{SubscribeRequest, SubscribeRequestFilterTransactions};

    let request = SubscribeRequest {
        transactions: HashMap::from([(
            "usdc-txs".to_string(),
            SubscribeRequestFilterTransactions {
                account_include: vec!["EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v".to_string()],
                vote: Some(false),
                failed: Some(false),
                match_mints: true,
                ..Default::default()
            },
        )]),
        ..Default::default()
    };
    ```
  </Tab>

  <Tab title="Go">
    Requer o módulo Go na tag `go/v0.3.0` ou posterior.

    ```go theme={"system"}
    vote := false
    failed := false
    req := &laserstream.SubscribeRequest{
        Transactions: map[string]*laserstream.SubscribeRequestFilterTransactions{
            "usdc-txs": {
                AccountInclude: []string{"EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v"},
                Vote:           &vote,
                Failed:         &failed,
                MatchMints:     true,
            },
        },
        Commitment: &commitmentLevel,
    }
    ```
  </Tab>
</Tabs>

Se você usa um cliente gRPC bruto ou Yellowstone em vez do SDK, gere-o novamente com base no proto da Helius (`laserstream-core-proto` 11.3.0 ou posterior, ou o `.proto` incluído no repositório do SDK).

`match_mints` é o campo 32 de `SubscribeRequestFilterTransactions`. Clientes gerados com base no proto Triton upstream descartam silenciosamente o campo desconhecido. Portanto, a flag não terá efeito até você gerar o cliente novamente.

Consulte a [referência de Subscribe Request](/docs/pt-BR/laserstream/grpc#pedido-de-inscrição) para ver todos os campos de filtro de transações.

## Combine com `tokenAccounts` para monitorar um token de uma carteira

`matchMints` pode ser combinado com a [expansão de `tokenAccounts`](/docs/pt-BR/laserstream/token-account-filtering). Assim, um único filtro pode fazer a correspondência por proprietários de carteiras e mints ao mesmo tempo.

Este exemplo transmite todas as alterações no saldo de USDC de uma carteira:

```typescript theme={"system"}
transactions: {
  'wallet-usdc': {
    accountInclude: [WALLET],
    accountRequired: [USDC],
    accountExclude: [],
    tokenAccounts: 'balanceChanged', // wallet matched via its token accounts
    matchMints: true,                // USDC matched via balance mints
    vote: false,
    failed: false,
  },
},
```

`accountInclude` junto com `tokenAccounts` encontra transações em que os saldos de token da carteira foram alterados. `accountRequired` junto com `matchMints` restringe os resultados àquelas que envolvem USDC.

## Como identificar o que correspondeu

Quando uma transação corresponder por meio de um mint, procure o mint em `meta.preTokenBalances[].mint` e `meta.postTokenBalances[].mint`. Em transferências simples, o mint geralmente não aparece nas chaves de conta. Portanto, não o procure nelas.

Compare `preTokenBalances` com `postTokenBalances` no mesmo `accountIndex` para ver quanto do token foi movimentado e entre quais proprietários.

O [guia de monitoramento de transações](/docs/pt-BR/laserstream/guides/transaction-monitoring#estrutura-de-dados-da-transação) aborda em detalhes a estrutura das transações.

## Limites e observações

* Os mints ficam nas mesmas listas `accountInclude`, `accountExclude` e `accountRequired` que as chaves de conta. Portanto, eles contam para os mesmos limites por lista do plano. Não há um limite separado para mints.
* O custo da correspondência não aumenta com o número de mints listados. O desempenho é o mesmo com 100 ou 100.000 mints, e os assinantes que não definem a flag não têm nenhum custo adicional.
* A [reprodução histórica](/docs/pt-BR/laserstream/historical-replay) respeita `matchMints`. Portanto, uma assinatura de reprodução retorna as mesmas transações que o stream em tempo real retornaria.
* Se você anexar um [filtro compactado (cuckoo)](/docs/pt-BR/laserstream/cuckoo-filters) a uma assinatura de transações, `matchMints` também verifica o conjunto de mints no filtro, além das chaves de conta.
* `matchMints` está disponível em todas as regiões do LaserStream gRPC, na mainnet e na devnet. No momento, não está disponível no LaserStream WebSocket.
* Versões mínimas do SDK: JavaScript/TypeScript `helius-laserstream` 0.8.5, Rust `helius-laserstream` 0.6.4, Go `go/v0.3.0`.

## Relacionados

<CardGroup cols={2}>
  <Card title="Token Account (ATA) Filtering" icon="coins" href="/docs/pt-BR/laserstream/token-account-filtering">
    Encontre transações que envolvem as contas de token pertencentes a uma carteira
  </Card>

  <Card title="Transaction Monitoring" icon="receipt" href="/docs/pt-BR/laserstream/guides/transaction-monitoring">
    Estratégias completas de filtragem e exemplos executáveis por gRPC
  </Card>

  <Card title="Subscribe Request Reference" icon="filter" href="/docs/pt-BR/laserstream/grpc">
    Todos os campos de filtro de transações, incluindo `matchMints`
  </Card>

  <Card title="Historical Replay" icon="clock-rotate-left" href="/docs/pt-BR/laserstream/historical-replay">
    Preencha retroativamente até 24 horas de atividade de tokens com o mesmo filtro
  </Card>
</CardGroup>
