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

# Filtrage par mint de jeton

> Abonnez-vous à chaque transaction qui concerne un mint de jeton dans LaserStream gRPC avec matchMints. Ce filtrage capture les transferts SPL que accountInclude manque lorsque le mint ne figure pas dans les clés de compte.

L'indicateur `matchMints` de LaserStream permet à un abonnement aux transactions gRPC d'effectuer une correspondance avec les **mints de jetons dans les soldes de jetons avant/après d'une transaction**, en plus de ses clés de compte.

Placez un mint dans `accountInclude`, définissez `matchMints: true` et vous recevrez chaque transaction qui concerne ce jeton : transferts, swaps, créations de jetons, destructions et fermetures de comptes.

<Note>
  `matchMints` est disponible uniquement sur LaserStream gRPC. Il n'est pas encore disponible sur LaserStream WebSocket.
</Note>

## Le problème : les filtres de compte simples manquent la plupart des transferts de jetons

Lorsque vous surveillez un jeton avec `accountInclude: [mint]`, seules les transactions dans lesquelles la clé publique du mint apparaît parmi les clés de compte correspondent au filtre.

Une instruction SPL `Transfer` classique ne référence jamais le mint. Elle indique uniquement le compte de jetons source, le compte de jetons de destination et le propriétaire. Un filtre de compte simple manque donc l'opération la plus courante pour n'importe quel jeton.

Seules les instructions qui transmettent directement le mint correspondent au filtre, telles que `MintTo`, `Burn`, `TransferChecked` et les swaps dont les comptes de programme incluent le mint. La seule solution de contournement consistait à diffuser toutes les transactions et à examiner vous-même les soldes de jetons de chacune.

## Fonctionnement de `matchMints`

Définissez `matchMints: true` sur un filtre de transaction. LaserStream crée alors un ensemble de mints à partir des champs `preTokenBalances` et `postTokenBalances` de la transaction.

Vos listes `accountInclude`, `accountExclude` et `accountRequired` sont ensuite comparées **à la fois** aux clés de compte et à cet ensemble de mints. Un mint correspond si l'un de ses comptes de jetons apparaît dans l'une ou l'autre des listes de soldes, que le solde ait changé ou non.

L'indicateur est facultatif. Les filtres qui ne l'incluent pas se comportent exactement comme auparavant. Vous pouvez donc l'ajouter à un abonnement existant sans modifier ce que cet abonnement reçoit déjà. Les mints SPL et Token-2022 fonctionnent, car les deux programmes renseignent les soldes de jetons avant/après.

## Sémantique

| Prédicat          | Sans `matchMints`                                                        | Avec `matchMints: true`                                                                                                                      |
| ----------------- | ------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------- |
| `accountInclude`  | Correspond si l'une des clés répertoriées figure dans les clés de compte | Correspond si l'une des clés répertoriées figure dans les clés de compte **ou** dans l'ensemble de mints                                     |
| `accountExclude`  | Rejette si l'une des clés répertoriées figure dans les clés de compte    | Rejette si l'une des clés répertoriées figure dans les clés de compte **ou** dans l'ensemble de mints                                        |
| `accountRequired` | Chaque clé répertoriée doit figurer dans les clés de compte              | Chaque clé répertoriée doit figurer dans les clés de compte **ou** dans l'ensemble de mints (chaque clé peut correspondre à l'un ou l'autre) |

Le reste de la logique du filtre ne change pas :

* Les prédicats d'un même filtre nommé sont toujours combinés avec l'opérateur AND (`vote`, `failed`, `signature` et les listes de comptes).
* Plusieurs filtres nommés sont toujours combinés avec l'opérateur OR.
* Les valeurs d'une liste sont combinées avec l'opérateur OR (sauf pour `accountRequired`, où toutes doivent correspondre).
* Pour une transaction sans solde de jetons, la correspondance repose uniquement sur les clés. `matchMints` n'ajoute jamais de transactions sans activité de jetons.
* Utilisé seul, `matchMints` ne restreint pas le flux. Vous devez toujours fournir au moins une clé ou un mint dans une liste de comptes (ou un autre prédicat restrictif) pour que le filtre soit accepté.

<Note>
  LaserStream recherche les correspondances exactes avec les clés publiques des mints. Il n'existe aucun mode « solde modifié uniquement » pour les mints, contrairement à `tokenAccounts: "balanceChanged"`.
</Note>

## Utilisation dans LaserStream gRPC

Ajoutez `matchMints: true` à un filtre de transaction dans votre `SubscribeRequest` et placez le mint dans `accountInclude`. Cet exemple diffuse chaque transaction USDC sur le réseau principal :

<Tabs>
  <Tab title="TypeScript">
    Nécessite `helius-laserstream` 0.8.5 ou une version ultérieure. Le champ est également accepté sous le nom `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">
    Nécessite `helius-laserstream` 0.6.4 ou une version ultérieure (qui récupère `laserstream-core-proto` 11.3.0). Le champ provient directement du 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">
    Nécessite le module Go avec le tag `go/v0.3.0` ou une version ultérieure.

    ```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 vous utilisez un client gRPC brut ou Yellowstone au lieu du SDK, régénérez-le à partir du proto Helius (`laserstream-core-proto` 11.3.0 ou une version ultérieure, ou le fichier `.proto` inclus dans le dépôt du SDK).

`match_mints` est le champ 32 de `SubscribeRequestFilterTransactions`. Les clients générés à partir du proto Triton en amont ignorent silencieusement le champ inconnu. L'indicateur reste donc sans effet tant que vous ne les régénérez pas.

Consultez la [référence de la requête Subscribe](/docs/fr/laserstream/grpc#demande-de-souscription) pour découvrir tous les champs de filtre de transaction.

## Combinaison avec `tokenAccounts` pour surveiller un jeton d'un portefeuille

`matchMints` se combine avec l'[extension `tokenAccounts`](/docs/fr/laserstream/token-account-filtering). Un même filtre peut donc rechercher simultanément les propriétaires de portefeuilles et les mints.

Cet exemple diffuse chaque modification du solde USDC d'un portefeuille :

```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` associé à `tokenAccounts` trouve les transactions dans lesquelles les soldes de jetons du portefeuille ont changé. `accountRequired` associé à `matchMints` limite ces résultats aux transactions impliquant USDC.

## Lecture des correspondances

Lorsqu'une transaction correspond grâce à un mint, recherchez ce dernier dans `meta.preTokenBalances[].mint` et `meta.postTokenBalances[].mint`. Pour les transferts simples, le mint est généralement absent des clés de compte. Ne le cherchez donc pas à cet endroit.

Comparez `preTokenBalances` à `postTokenBalances` pour le même `accountIndex` afin de déterminer la quantité de jetons déplacée et les propriétaires concernés.

Le [guide de surveillance des transactions](/docs/fr/laserstream/guides/transaction-monitoring#structure-des-données-de-transaction) décrit en détail la structure des transactions.

## Limites et remarques

* Les mints utilisent les mêmes listes `accountInclude`, `accountExclude` et `accountRequired` que les clés de compte. Ils sont donc soumis aux mêmes limites par liste selon l'offre. Il n'existe aucune limite distincte pour les mints.
* Le coût de la recherche de correspondances n'augmente pas avec le nombre de mints répertoriés. Les performances sont identiques pour 100 et 100 000 mints, et les abonnés qui n'activent pas l'indicateur ne supportent aucun coût supplémentaire.
* La [relecture historique](/docs/fr/laserstream/historical-replay) prend en charge `matchMints`. Un abonnement de relecture renvoie donc les mêmes transactions que le flux en direct aurait renvoyées.
* Si vous associez un [filtre compressé (cuckoo)](/docs/fr/laserstream/cuckoo-filters) à un abonnement aux transactions, `matchMints` teste également l'ensemble de mints avec ce filtre, en plus des clés de compte.
* `matchMints` est actif dans toutes les régions LaserStream gRPC, sur le réseau principal et le réseau de développement. Il n'est pas disponible sur LaserStream WebSocket pour le moment.
* Versions minimales du SDK : JavaScript/TypeScript `helius-laserstream` 0.8.5, Rust `helius-laserstream` 0.6.4, Go `go/v0.3.0`.

## Contenu associé

<CardGroup cols={2}>
  <Card title="Token Account (ATA) Filtering" icon="coins" href="/docs/fr/laserstream/token-account-filtering">
    Filtrez les transactions qui concernent les comptes de jetons détenus par un portefeuille
  </Card>

  <Card title="Transaction Monitoring" icon="receipt" href="/docs/fr/laserstream/guides/transaction-monitoring">
    Stratégies de filtrage complètes et exemples exécutables avec gRPC
  </Card>

  <Card title="Subscribe Request Reference" icon="filter" href="/docs/fr/laserstream/grpc">
    Tous les champs de filtre de transaction, y compris `matchMints`
  </Card>

  <Card title="Historical Replay" icon="clock-rotate-left" href="/docs/fr/laserstream/historical-replay">
    Récupérez jusqu'à 24 heures d'activité de jetons avec le même filtre
  </Card>
</CardGroup>
