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

# Verfolge Jupiter Swaps mit Parsed Streams

> Erstelle und abonniere einen Parsed Streams Filter für Jupiter-Routenanweisungen mit describeProgram.

Diese Anleitung erstellt einen realen Filter Schritt für Schritt: Beobachte Jupiter Swaps einer Wallet, indem du [Programmentdeckung](/docs/de/parsed-streams/quickstart#entdeckung) verwendest, sodass der Filter korrekt ist, bevor du ein Abonnement öffnest.

<Steps>
  <Step title="Schau dir das Programm an">
    Vermutete Anweisungsnamen sind die häufigste Ursache dafür, dass ein Filter stillschweigend nichts trifft. Rufe `describeProgram` zuerst auf, um die genauen Namen zu erhalten, gegen die der Matcher vergleicht.

    ```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"]
      }
    }
    ```

    Bevorzuge die Programm-**Adresse** gegenüber einem Katalognamen — mehr als ein Katalogeintrag kann einen Namen teilen, und eine Namenssuche kann zu einer älteren Version des Programms auflösen. `route` und `shared_accounts_route` sind die beiden Anweisungen, die die meisten Jupiter v6 Swaps abdecken, daher wirst du darauf filtern.
  </Step>

  <Step title="Erstelle den Filter">
    Kombiniere die Programm-ID, die Anweisungsnamen aus dem vorherigen Schritt und die Wallet, die du beobachtest. Felder werden mit UND kombiniert, sodass dies Routenanweisungen entspricht, die das SOL-Konto der Wallet berühren:

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

    `accounts.roles` fixiert `user_transfer_authority` auf die genaue Position der Wallet in der Anweisung, was strenger ist als `accounts.include` allein: eine einfache Adressübereinstimmung würde auch die Wallet als ein nicht zugehöriges Konto an anderer Stelle in der Anweisung erfassen. Rollennamen stimmen genau überein, daher werden sie aus `describeProgram`'s `roles`-Liste kopiert, nicht geraten. Lass `includeCpi: true` (die Standardeinstellung) — die tatsächlichen Token-Bewegungen eines Swaps erfolgen in inneren Anweisungen.
  </Step>

  <Step title="Abonniere und bearbeite Benachrichtigungen">
    Öffne das Abonnement mit dem Filter und lese dann die dekodierten Argumente jeder übereinstimmenden Anweisung:

    ```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` zeigt nur auf die Anweisungen, die dein Filter getroffen hat — überspringe alles andere in der Transaktion. Überprüfe, dass `decoded` vorhanden ist, bevor du es liest: Eine Routenanweisung von einer nicht indexierten Programmversion kommt stattdessen mit `decoded: null` und rohen Feldern an.
  </Step>
</Steps>

## Nächste Schritte

<CardGroup cols={2}>
  <Card title="Filterfeld-Referenz" icon="filter" href="/docs/de/parsed-streams/quickstart#filterfelder">
    Alle Filterfelder, Optionen und Grenzen.
  </Card>

  <Card title="Umgang mit Wiederverbindungen" icon="rotate" href="/docs/de/parsed-streams/guides/handling-reconnects">
    Halte dieses Abonnement über Trennungen und Bereitstellungen hinweg am Leben.
  </Card>
</CardGroup>
