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

# Lọc tài khoản token (ATA)

> Phát hiện các giao dịch chuyển token SPL đến ví trong luồng gRPC LaserStream bằng tính năng mở rộng tokenAccounts (ATA) — những giao dịch mà phép khớp accountInclude dựa trên chủ sở hữu bỏ sót.

Bộ lọc `tokenAccounts` của LaserStream cho phép gói đăng ký giao dịch gRPC khớp với hoạt động trên **các tài khoản token liên kết (ATA) thuộc sở hữu của ví**, thay vì chỉ các giao dịch có khóa công khai của ví xuất hiện trực tiếp. Bộ lọc tương tự cũng có trên WebSocket — xem [Lọc tài khoản token (ATA) qua WebSocket](/docs/vi/rpc/websocket/token-account-filtering).

## Vấn đề: bộ lọc tài khoản thông thường bỏ sót các giao dịch chuyển token đến

Khi theo dõi một ví bằng `accountInclude: [wallet]`, bạn chỉ khớp được các giao dịch có khóa công khai của ví đó xuất hiện trong danh sách khóa tài khoản của giao dịch. Một trường hợp phổ biến sẽ bị bỏ sót: khi ai đó gửi token SPL (chẳng hạn như USDC) đến ví, giao dịch chuyển sẽ tương tác với **tài khoản token liên kết (ATA)** của ví — một địa chỉ riêng biệt được dẫn xuất từ chương trình — chứ không phải chính khóa công khai của ví.

Do đó, gói đăng ký `accountInclude: [wallet]` thông thường sẽ không bao giờ thấy các giao dịch chuyển token đến. Bạn sẽ phải liệt kê trước mọi ATA thuộc sở hữu của ví rồi thêm từng tài khoản vào bộ lọc — nhưng ATA được tạo theo nhu cầu (mỗi mint một ATA), nên không thể biết trước toàn bộ danh sách.

## Cách hoạt động của tính năng mở rộng `tokenAccounts`

Đặt `tokenAccounts` trên bộ lọc giao dịch để mở rộng phạm vi khớp, nhờ đó ví `accountInclude` **cũng** khớp với các giao dịch tương tác với tài khoản token thuộc sở hữu của ví. Phép khớp **dựa trên chủ sở hữu**: LaserStream xác định các tài khoản token thuộc sở hữu của những địa chỉ `accountInclude` tại thời điểm khớp, nhờ đó phát hiện mọi tài khoản token thuộc sở hữu của ví — kể cả các tài khoản không chuẩn — chứ không chỉ địa chỉ ATA được dẫn xuất. Bạn không bao giờ phải tự liệt kê các ATA.

Các gói đăng ký không có `tokenAccounts` sẽ hoạt động chính xác như trước, vì vậy bạn có thể thêm trường này vào bộ lọc hiện có một cách an toàn.

Để khớp theo token thay vì theo ví, hãy xem [Lọc mint token](/docs/vi/laserstream/mint-filtering). Hai cờ này có thể kết hợp với nhau, vì vậy một bộ lọc có thể theo dõi hoạt động của một ví cụ thể đối với một token cụ thể.

## Các chế độ mở rộng

`tokenAccounts` nhận một trong ba giá trị chuỗi:

| Giá trị            | Khớp với                                                                                           | Lưu lượng                                    | Dùng cho                                                                                                      |
| ------------------ | -------------------------------------------------------------------------------------------------- | -------------------------------------------- | ------------------------------------------------------------------------------------------------------------- |
| `"balanceChanged"` | Các giao dịch mà số dư token thuộc sở hữu thực sự thay đổi (hoặc tài khoản token bị đóng)          | Thấp hơn — giá trị mặc định được khuyến nghị | "Cho tôi biết khi tiền thực sự được chuyển" — các khoản nạp, rút và giao dịch hoán đổi được quyết toán vào ví |
| `"all"`            | Mọi giao dịch tham chiếu đến tài khoản token thuộc sở hữu của ví, ngay cả khi số dư không thay đổi | Cao hơn                                      | Khả năng quan sát đầy đủ đối với mọi hoạt động có tương tác dù chỉ nhỏ nhất với các tài khoản token của ví    |
| `"none"`           | Không mở rộng — giống hệt như khi bỏ qua trường này                                                | —                                            | Giá trị mặc định                                                                                              |

Hãy bắt đầu với `"balanceChanged"`. Chế độ này ghi nhận chuyển động thực tế của tiền với lưu lượng chỉ bằng một phần nhỏ so với `"all"`.

## Sử dụng trong LaserStream gRPC

Thêm `tokenAccounts` vào bộ lọc giao dịch trong `SubscribeRequest`. [Helius LaserStream SDK](/docs/vi/laserstream/clients) sẽ chuyển đổi chuỗi thành enum `TokenAccountExpansionControlFlag` ở cấp giao thức cho bạn (thuộc `yellowstone-grpc-proto` 12.5.0+).

```typescript theme={"system"}
import { subscribe, CommitmentLevel, LaserstreamConfig, SubscribeRequest } from 'helius-laserstream';
import bs58 from 'bs58';

const wallet = '<WALLET_PUBKEY>';

const subscriptionRequest: SubscribeRequest = {
  transactions: {
    "wallet-activity": {
      accountInclude: [wallet],
      accountExclude: [],
      accountRequired: [],
      vote: false,
      failed: false,
      tokenAccounts: "balanceChanged" // also match the wallet's ATAs
    }
  },
  commitment: CommitmentLevel.CONFIRMED,
  accounts: {}, slots: {}, transactionsStatus: {},
  blocks: {}, blocksMeta: {}, entry: {}, accountsDataSlice: [],
};

const config: LaserstreamConfig = {
  apiKey: 'YOUR_API_KEY',
  endpoint: 'https://laserstream-mainnet-ewr.helius-rpc.com',
};

await subscribe(config, subscriptionRequest, async (data) => {
  if (!data.transaction?.transaction) return;
  const tx = data.transaction.transaction;
  // Token balances this wallet owns that changed in the tx
  const owned = (tx.meta?.postTokenBalances || []).filter((b: any) => b.owner === wallet);
  console.log(bs58.encode(tx.signature), owned);
}, async (error) => {
  console.error('Stream error:', error);
});
```

Xem [hướng dẫn Giám sát giao dịch](/docs/vi/laserstream/guides/transaction-monitoring) để tham khảo ví dụ đầy đủ hơn về cách so sánh số dư trước và sau, cũng như [tài liệu tham khảo về Yêu cầu đăng ký](/docs/vi/laserstream/grpc) để xem mọi trường của bộ lọc giao dịch.

## Đọc nội dung đã khớp

Sau khi một giao dịch khớp thông qua tính năng mở rộng ATA, chuyển động token của ví nằm trong `meta.postTokenBalances` và `meta.preTokenBalances` của giao dịch. Lọc các mục này theo `owner` để tách riêng số dư thực sự thuộc sở hữu của ví, sau đó so sánh `preTokenBalances` với `postTokenBalances` trên cùng một `accountIndex` để xem lượng token của từng mint đã thay đổi bao nhiêu. Ví dụ trên minh họa bước lọc; [hướng dẫn Giám sát giao dịch](/docs/vi/laserstream/guides/transaction-monitoring#ví-dụ-4-theo-dõi-ví-bao-gồm-giao-dịch-chuyển-token) trình bày toàn bộ phép so sánh.

## Nội dung liên quan

<CardGroup cols={2}>
  <Card title="Transaction Monitoring" icon="receipt" href="/docs/vi/laserstream/guides/transaction-monitoring">
    Các chiến lược lọc đầy đủ và một ví dụ có thể chạy để theo dõi ví qua gRPC.
  </Card>

  <Card title="Token Account Filtering (WebSocket)" icon="bolt" href="/docs/vi/rpc/websocket/token-account-filtering">
    Trường `tokenAccounts` tương tự trên phương thức WebSocket `transactionSubscribe`.
  </Card>

  <Card title="Subscribe Request Reference" icon="filter" href="/docs/vi/laserstream/grpc">
    Mọi trường của bộ lọc giao dịch, bao gồm `tokenAccounts`.
  </Card>

  <Card title="Compressed Filters" icon="layer-group" href="/docs/vi/laserstream/cuckoo-filters">
    Theo dõi hàng trăm nghìn tài khoản trong một luồng duy nhất.
  </Card>

  <Card title="Token Mint Filtering" icon="coins" href="/docs/vi/laserstream/mint-filtering">
    Đăng ký nhận mọi giao dịch cho một mint token bằng `matchMints`.
  </Card>
</CardGroup>
