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

# Rastrea swaps de Jupiter con flujos analizados

> Crea un filtro de flujos analizados para las instrucciones de ruta de Jupiter mediante describeProgram y suscríbete a él.

Esta guía crea un filtro real paso a paso: monitorea los swaps de Jupiter de una billetera mediante el [descubrimiento de programas](/docs/es/parsed-streams/quickstart#descubrimiento), para que el filtro sea correcto antes de que abras una suscripción.

<Steps>
  <Step title="Look Up the Program">
    Adivinar los nombres de las instrucciones es la causa más común de que un filtro no encuentre coincidencias sin mostrar ningún aviso. Primero, llama a `describeProgram` para obtener los nombres exactos con los que compara el motor de coincidencias.

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

    Prefiere la **dirección** del programa en lugar de un nombre del catálogo. Varias entradas del catálogo pueden compartir un nombre, y una búsqueda por nombre puede devolver una versión anterior del programa. `route` y `shared_accounts_route` son las dos instrucciones que abarcan la mayoría de los swaps de Jupiter v6, así que debes filtrar por ellas.
  </Step>

  <Step title="Build the Filter">
    Combina el ID del programa, los nombres de las instrucciones del paso anterior y la billetera que estás monitoreando. Los campos se combinan con AND, por lo que esto encuentra instrucciones de ruta que interactúan con la cuenta de SOL de la billetera:

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

    `accounts.roles` fija `user_transfer_authority` en la posición exacta de la billetera dentro de la instrucción, lo cual es más estricto que usar solo `accounts.include`: una coincidencia simple de dirección también detectaría la billetera si apareciera como una cuenta no relacionada en otra parte de la instrucción. Los nombres de los roles deben coincidir exactamente, por lo que se copian de la lista `roles` de `describeProgram`, en lugar de adivinarlos. Mantén `includeCpi: true` (el valor predeterminado): los movimientos reales de tokens de un swap ocurren en instrucciones internas.
  </Step>

  <Step title="Subscribe and Handle Notifications">
    Abre la suscripción con el filtro y, luego, lee los argumentos decodificados de cada instrucción que coincida:

    ```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` apunta únicamente a las instrucciones que coincidieron con tu filtro; omite todo lo demás en la transacción. Comprueba que `decoded` esté presente antes de leerlo: una instrucción de ruta de una versión no indexada del programa llega con `decoded: null` y campos sin procesar.
  </Step>
</Steps>

## Próximos pasos

<CardGroup cols={2}>
  <Card title="Filter Fields Reference" icon="filter" href="/docs/es/parsed-streams/quickstart#campos-del-filtro">
    Todos los campos, las opciones y los límites de los filtros.
  </Card>

  <Card title="Handling Reconnects" icon="rotate" href="/docs/es/parsed-streams/guides/handling-reconnects">
    Mantén activa esta suscripción durante desconexiones e implementaciones.
  </Card>
</CardGroup>
