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

# Acompanhar Swaps Jupiter com Streams Analisados

> Construa e assine um filtro de Streams Analisados para instruções de rota Jupiter usando describeProgram.

Este guia constrói um filtro real passo a passo: observe os swaps do Jupiter de uma carteira, usando [descoberta de programa](/docs/pt-BR/parsed-streams/quickstart#discovery) para que o filtro esteja correto antes mesmo de você abrir uma assinatura.

<Steps>
  <Step title="Pesquisar o Programa">
    Nomes de instrução adivinhados são a maneira mais comum de um filtro não corresponder a nada silenciosamente. Chame `describeProgram` primeiro para obter os nomes exatos que o comparador utiliza.

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

    Prefira o **endereço** do programa em vez de um nome de catálogo — mais de uma entrada de catálogo pode compartilhar um nome, e uma consulta pelo nome pode resolver para uma versão mais antiga do programa. `route` e `shared_accounts_route` são as duas instruções que cobrem a maioria dos swaps Jupiter v6, então é neles que você deve filtrar.
  </Step>

  <Step title="Construir o Filtro">
    Combine o id do programa, os nomes das instruções do passo anterior e a carteira que você está observando. Os campos se combinam com E, então isso corresponde a instruções de rota que tocam na conta SOL da carteira:

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

    `accounts.roles` fixa `user_transfer_authority` à posição exata da carteira na instrução, que é mais restritiva do que `accounts.include` sozinha: uma correspondência de endereço simples também capturaria a carteira aparecendo como uma conta não relacionada em outro lugar na instrução. Os nomes dos papéis correspondem exatamente, então eles são copiados da lista `describeProgram`'s `roles`, não adivinhados. Deixe `includeCpi: true` (o padrão) — os movimentos reais de token de um swap acontecem em instruções internas.
  </Step>

  <Step title="Assine e Gerencie Notificações">
    Abra a assinatura com o filtro e, em seguida, leia cada argumento decodificado da instrução correspondente:

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

    const ws = new WebSocket("wss://<ENDPOINT>/?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` aponta apenas para as instruções que seu filtro encontrou — ignore todo o resto na transação. Verifique se `decoded` está presente antes de lê-lo: uma instrução de rota de uma versão de programa não indexada chega com `decoded: null` e campos brutos em vez disso.
  </Step>
</Steps>

## Próximas Etapas

<CardGroup cols={2}>
  <Card title="Referência de Campos de Filtro" icon="filter" href="/docs/pt-BR/parsed-streams/quickstart#filter-fields">
    Todos os campos de filtro, opções e limites.
  </Card>

  <Card title="Gerenciando Reconexões" icon="rotate" href="/docs/pt-BR/parsed-streams/guides/handling-reconnects">
    Mantenha esta assinatura ativa durante desconexões e implantações.
  </Card>
</CardGroup>
