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

# Theo dõi giao dịch hoán đổi Jupiter bằng Luồng đã phân tích

> Tạo và đăng ký bộ lọc Luồng đã phân tích cho các chỉ thị định tuyến Jupiter bằng describeProgram.

Hướng dẫn này sẽ từng bước tạo một bộ lọc thực tế: theo dõi các giao dịch hoán đổi Jupiter của một ví, sử dụng tính năng [khám phá chương trình](/docs/vi/parsed-streams/quickstart#khám-phá) để đảm bảo bộ lọc chính xác trước khi bạn mở đăng ký.

<Steps>
  <Step title="Look Up the Program">
    Việc đoán tên chỉ thị là nguyên nhân phổ biến nhất khiến bộ lọc âm thầm không khớp với bất kỳ dữ liệu nào. Trước tiên, hãy gọi `describeProgram` để lấy chính xác các tên mà trình đối sánh sử dụng để so sánh. Hiện tại, phương thức này chỉ có trên `wss://fs-beta.helius-rpc.com/?api-key=<API_KEY>`, vì vậy hãy gửi yêu cầu đến đó thay vì qua kết nối đăng ký.

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

    Nên dùng **địa chỉ** chương trình thay vì tên trong danh mục — nhiều mục trong danh mục có thể có cùng tên và việc tra cứu theo tên có thể trả về phiên bản cũ hơn của chương trình. `route` và `shared_accounts_route` là hai chỉ thị bao quát hầu hết các giao dịch hoán đổi Jupiter v6, vì vậy bạn sẽ lọc theo hai chỉ thị này.
  </Step>

  <Step title="Build the Filter">
    Kết hợp ID chương trình, tên chỉ thị từ bước trước và ví đang theo dõi. Các trường được kết hợp bằng AND, vì vậy bộ lọc này sẽ khớp với những chỉ thị định tuyến có tương tác với tài khoản SOL của ví:

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

    `accounts.roles` cố định `user_transfer_authority` tại đúng vị trí của ví trong chỉ thị, chặt chẽ hơn so với việc chỉ dùng `accounts.include`: phép khớp địa chỉ đơn thuần cũng sẽ bắt trường hợp ví xuất hiện dưới dạng một tài khoản không liên quan ở vị trí khác trong chỉ thị. Tên vai trò phải khớp chính xác, vì vậy chúng được sao chép từ danh sách `roles` của `describeProgram` thay vì được phỏng đoán. Giữ nguyên `includeCpi: true` (giá trị mặc định) — các chuyển động token thực tế của giao dịch hoán đổi diễn ra trong các chỉ thị bên trong.
  </Step>

  <Step title="Subscribe and Handle Notifications">
    Mở đăng ký bằng bộ lọc, sau đó đọc các đối số đã giải mã của từng chỉ thị khớp:

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

    const ws = new WebSocket("wss://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` chỉ trỏ đến các chỉ thị mà bộ lọc của bạn đã khớp — hãy bỏ qua mọi nội dung khác trong giao dịch. Kiểm tra xem `decoded` có tồn tại hay không trước khi đọc: một chỉ thị định tuyến từ phiên bản chương trình chưa được lập chỉ mục sẽ được gửi đến với `decoded: null` và các trường thô.
  </Step>
</Steps>

## Các bước tiếp theo

<CardGroup cols={2}>
  <Card title="Filter Fields Reference" icon="filter" href="/docs/vi/parsed-streams/quickstart#các-trường-của-bộ-lọc">
    Tất cả các trường bộ lọc, tùy chọn và giới hạn.
  </Card>

  <Card title="Handling Reconnects" icon="rotate" href="/docs/vi/parsed-streams/guides/handling-reconnects">
    Duy trì đăng ký này khi bị ngắt kết nối và trong quá trình triển khai.
  </Card>
</CardGroup>
