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

# Filtrado por mint de token

> Suscríbete a todas las transacciones que involucren un mint de token en LaserStream gRPC con matchMints. Detecta transferencias SPL que accountInclude omite porque el mint no está en las claves de cuenta.

La marca `matchMints` de LaserStream permite que una suscripción a transacciones de gRPC filtre por los **mints de tokens en los saldos de tokens previos y posteriores de una transacción**, además de sus claves de cuenta.

Coloca un mint en `accountInclude`, establece `matchMints: true` y recibirás cada transacción que involucre ese token: transferencias, swaps, acuñaciones, quemas y cierres de cuentas.

<Note>
  `matchMints` solo está disponible en LaserStream gRPC. Aún no está disponible en LaserStream WebSocket.
</Note>

## El problema: los filtros de cuenta simples omiten la mayoría de las transferencias de tokens

Cuando monitoreas un token con `accountInclude: [mint]`, solo se detectan las transacciones en las que la pubkey del mint aparece en las claves de cuenta de la transacción.

Una instrucción SPL `Transfer` clásica nunca hace referencia al mint. Solo especifica la cuenta de token de origen, la cuenta de token de destino y el propietario, por lo que un filtro de cuenta simple omite la operación más común de cualquier token.

Solo coinciden las instrucciones que pasan el mint directamente, como `MintTo`, `Burn`, `TransferChecked` y los swaps cuyas cuentas de programa incluyen el mint. La única solución alternativa era transmitir todas las transacciones e inspeccionar por tu cuenta los saldos de tokens de cada una.

## Cómo funciona `matchMints`

Establece `matchMints: true` en un filtro de transacciones y LaserStream creará un conjunto de mints a partir de `preTokenBalances` e `postTokenBalances` de la transacción.

Tus listas `accountInclude`, `accountExclude` e `accountRequired` se comparan con **tanto** las claves de cuenta como ese conjunto de mints. Un mint cumple la condición si cualquier cuenta de token asociada aparece en cualquiera de las listas de saldos, independientemente de si el saldo cambió.

La marca es opcional y los filtros que la omiten se comportan exactamente como antes. Por eso, puedes agregarla a una suscripción existente sin cambiar lo que ya recibe. Los mints SPL y Token-2022 funcionan porque ambos programas rellenan los saldos de tokens previos y posteriores.

## Semántica

| Predicado         | Sin `matchMints`                                                  | Con `matchMints: true`                                                                                                                                     |
| ----------------- | ----------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `accountInclude`  | Coincide si alguna clave de la lista está en las claves de cuenta | Coincide si alguna clave de la lista está en las claves de cuenta **o** en el conjunto de mints                                                            |
| `accountExclude`  | Rechaza si alguna clave de la lista está en las claves de cuenta  | Rechaza si alguna clave de la lista está en las claves de cuenta **o** en el conjunto de mints                                                             |
| `accountRequired` | Todas las claves de la lista deben estar en las claves de cuenta  | Todas las claves de la lista deben estar en las claves de cuenta **o** en el conjunto de mints (cada clave puede cumplirse mediante cualquiera de los dos) |

El resto de la lógica del filtro no cambia:

* Los predicados dentro de un mismo filtro con nombre siguen combinándose con AND (`vote`, `failed`, `signature` y las listas de cuentas).
* Varios filtros con nombre siguen combinándose con OR.
* Los valores dentro de una lista se combinan con OR (excepto `accountRequired`, donde todos deben coincidir).
* Una transacción sin saldos de tokens vuelve a usar la comparación solo por claves. `matchMints` nunca agrega transacciones que no tengan actividad de tokens.
* `matchMints` por sí solo no restringe el flujo. Aún necesitas al menos una clave o un mint en una lista de cuentas (u otro predicado restrictivo) para que se acepte el filtro.

<Note>
  LaserStream compara los mints por pubkey exacta. No existe un modo de "solo cambió el saldo" para los mints, a diferencia de `tokenAccounts: "balanceChanged"`.
</Note>

## Úsalo en LaserStream gRPC

Agrega `matchMints: true` a un filtro de transacciones en tu `SubscribeRequest` y coloca el mint en `accountInclude`. Este ejemplo transmite todas las transacciones de USDC en mainnet:

<Tabs>
  <Tab title="TypeScript">
    Requiere `helius-laserstream` 0.8.5 o una versión posterior. El campo también se acepta 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">
    Requiere `helius-laserstream` 0.6.4 o una versión posterior (que incorpora `laserstream-core-proto` 11.3.0). El campo proviene directamente del crate de 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">
    Requiere el módulo de Go con la etiqueta `go/v0.3.0` o una versión 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>

Si usas un cliente gRPC sin procesar o un cliente de Yellowstone en lugar del SDK, vuelve a generarlo a partir del proto de Helius (`laserstream-core-proto` 11.3.0 o una versión posterior, o el `.proto` incluido en el repositorio del SDK).

`match_mints` es el campo 32 de `SubscribeRequestFilterTransactions`. Los clientes generados a partir del proto de Triton original descartan silenciosamente el campo desconocido, por lo que la marca no tendrá efecto hasta que vuelvas a generarlos.

Consulta la [referencia de solicitudes de suscripción](/docs/es/laserstream/grpc#solicitud-de-suscripción) para conocer todos los campos de filtro de transacciones.

## Combínalo con `tokenAccounts` para monitorear un token de una billetera

`matchMints` se combina con la [expansión `tokenAccounts`](/docs/es/laserstream/token-account-filtering), por lo que un filtro puede buscar propietarios de billeteras y mints al mismo tiempo.

Este ejemplo transmite cada cambio en el saldo de USDC de una billetera:

```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 con `tokenAccounts` encuentra transacciones en las que cambiaron los saldos de tokens de la billetera. `accountRequired` junto con `matchMints` limita esas transacciones a las que involucran USDC.

## Cómo interpretar lo que coincidió

Cuando una transacción coincida mediante un mint, busca el mint en `meta.preTokenBalances[].mint` e `meta.postTokenBalances[].mint`. En las transferencias simples, el mint normalmente no aparece en las claves de cuenta, así que no lo busques allí.

Compara `preTokenBalances` con `postTokenBalances` en el mismo `accountIndex` para ver qué cantidad del token se transfirió y entre qué propietarios.

La [guía de monitoreo de transacciones](/docs/es/laserstream/guides/transaction-monitoring#estructura-de-datos-de-las-transacciones) explica en detalle la estructura de las transacciones.

## Límites y notas

* Los mints se colocan en las mismas listas `accountInclude`, `accountExclude` e `accountRequired` que las claves de cuenta, por lo que cuentan para los mismos límites del plan por lista. No hay un límite separado para mints.
* El costo de la comparación no aumenta con la cantidad de mints que incluyas. El rendimiento es el mismo con 100 mints que con 100,000, y los suscriptores que no establecen la marca no incurren en ningún costo adicional.
* La [reproducción histórica](/docs/es/laserstream/historical-replay) respeta `matchMints`, por lo que una suscripción de reproducción devuelve las mismas transacciones que habría devuelto el flujo en vivo.
* Si adjuntas un [filtro comprimido (cuckoo)](/docs/es/laserstream/cuckoo-filters) a una suscripción de transacciones, `matchMints` compara el conjunto de mints con él, además de las claves de cuenta.
* `matchMints` está activo en todas las regiones de LaserStream gRPC, tanto en mainnet como en devnet. Actualmente no está disponible en LaserStream WebSocket.
* Versiones mínimas del SDK: JavaScript/TypeScript `helius-laserstream` 0.8.5, Rust `helius-laserstream` 0.6.4, Go `go/v0.3.0`.

## Contenido relacionado

<CardGroup cols={2}>
  <Card title="Token Account (ATA) Filtering" icon="coins" href="/docs/es/laserstream/token-account-filtering">
    Detecta transacciones que involucran las cuentas de tokens propiedad de una billetera
  </Card>

  <Card title="Transaction Monitoring" icon="receipt" href="/docs/es/laserstream/guides/transaction-monitoring">
    Estrategias completas de filtrado y ejemplos ejecutables mediante gRPC
  </Card>

  <Card title="Subscribe Request Reference" icon="filter" href="/docs/es/laserstream/grpc">
    Todos los campos de filtro de transacciones, incluido `matchMints`
  </Card>

  <Card title="Historical Replay" icon="clock-rotate-left" href="/docs/es/laserstream/historical-replay">
    Recupera hasta 24 horas de actividad de tokens con el mismo filtro
  </Card>
</CardGroup>
