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

# Suivre les échanges Jupiter avec des flux analysés

> Construisez et abonnez-vous à un filtre de flux analysé pour les instructions de route Jupiter en utilisant describeProgram.

Ce guide construit un vrai filtre étape par étape : surveillez les échanges Jupiter d'un portefeuille, en utilisant [découverte de programme](/docs/fr/parsed-streams/quickstart#découverte) afin que le filtre soit correct avant même d'ouvrir un abonnement.

<Steps>
  <Step title="Rechercher le programme">
    Les noms d'instructions devinés sont la façon la plus courante pour qu'un filtre ne corresponde silencieusement à rien. Appelez `describeProgram` d'abord pour obtenir les noms exacts que le compareur utilise.

    ```json Request theme={"system"}
    { "jsonrpc": "2.0", "id": 1, "method": "describeProgram", "params": [{ "program": "JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4" }] }
    ```

    ```json Response theme={"system"}
    {
      "jsonrpc": "2.0", "id": 1,
      "result": {
        "id": "JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4",
        "name": "jupiter",
        "instructions": ["route", "shared_accounts_route", "exact_out_route"],
        "events": ["SwapEvent"],
        "roles": ["user_transfer_authority", "destination_token_account"]
      }
    }
    ```

    Préférez l’**adresse** du programme à un nom de catalogue — plus d'une entrée de catalogue peut partager un nom, et une recherche de nom peut se résoudre à une version plus ancienne du programme. `route` et `shared_accounts_route` sont les deux instructions qui couvrent la plupart des échanges Jupiter v6, ce sont donc celles sur lesquelles vous allez filtrer.
  </Step>

  <Step title="Construire le filtre">
    Combinez l'id du programme, les noms d'instructions de l'étape précédente, et le portefeuille que vous surveillez. Les champs se combinent avec AND, ce qui correspond donc aux instructions de route qui touchent le compte SOL du portefeuille :

    ```json theme={"system"}
    {
      "programs": ["JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4"],
      "instructionNames": ["route", "shared_accounts_route"],
      "accounts": {
        "include": ["So11111111111111111111111111111111111111112"],
        "roles": { "user_transfer_authority": "9xQeWvG816bUx9EPjHmaT23yvVM2ZWbrrpZb9PusVFin" }
      },
      "includeFailed": false,
      "includeCpi": true
    }
    ```

    `accounts.roles` épingle `user_transfer_authority` à la position exacte du portefeuille dans l'instruction, ce qui est plus strict que `accounts.include` seul : une correspondance d'adresse simple capturerait également le portefeuille apparaissant comme un compte non lié ailleurs dans l'instruction. Les noms de rôles correspondent exactement, ils sont donc copiés de la liste `describeProgram` d’`roles`, non devinés. Laissez `includeCpi: true` (la valeur par défaut) — les mouvements de jetons réels d’un échange se produisent dans des instructions internes.
  </Step>

  <Step title="S'abonner et gérer les notifications">
    Ouvrez l'abonnement avec le filtre, puis lisez les arguments décodés de chaque instruction correspondante :

    ```typescript theme={"system"}
    import WebSocket from "ws";

    const ws = new WebSocket("wss://fs-beta.helius-rpc.com/?api-key=<API_KEY>");

    const filter = {
      programs: ["JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4"],
      instructionNames: ["route", "shared_accounts_route"],
      accounts: {
        include: ["So11111111111111111111111111111111111111112"],
        roles: { user_transfer_authority: "9xQeWvG816bUx9EPjHmaT23yvVM2ZWbrrpZb9PusVFin" },
      },
      includeFailed: false,
      includeCpi: true,
    };

    ws.on("open", () => {
      ws.send(JSON.stringify({
        jsonrpc: "2.0",
        id: 1,
        method: "parsedTransactionSubscribe",
        params: [filter, { commitment: "confirmed", details: "full" }],
      }));
    });

    ws.on("message", (data) => {
      const msg = JSON.parse(data.toString());
      if (msg.method === "parsedTransactionNotification") {
        const { transaction, instructions, matchedIndexes } = msg.params.result.value;
        for (const i of matchedIndexes) {
          const ix = instructions[i];
          if (!ix.decoded) continue;
          console.log(transaction.signature, ix.decoded.args.in_amount, ix.decoded.args.slippage_bps);
        }
      }
    });
    ```

    `matchedIndexes` pointe uniquement sur les instructions que votre filtre a touchées — ignorez tout le reste dans la transaction. Vérifiez que `decoded` est présent avant de le lire : une instruction de route d’une version non indexée du programme arrive avec `decoded: null` et des champs bruts à la place.
  </Step>
</Steps>

## Prochaines étapes

<CardGroup cols={2}>
  <Card title="Référence des champs de filtre" icon="filter" href="/docs/fr/parsed-streams/quickstart#champs-du-filtre">
    Tous les champs de filtre, options et limites.
  </Card>

  <Card title="Gestion des reconnexions" icon="rotate" href="/docs/fr/parsed-streams/guides/handling-reconnects">
    Gardez cet abonnement actif lors des déconnexions et des déploiements.
  </Card>
</CardGroup>
