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

# Pemfilteran Akun Token (ATA) melalui WebSocket

> Tangkap transfer token SPL yang masuk ke dompet dalam aliran WebSocket LaserStream dengan filter tokenAccounts pada transactionSubscribe — pencocokan berbasis pemilik.

Filter `tokenAccounts` pada metode WebSocket [`transactionSubscribe`](/docs/id/rpc/websocket/transaction-subscribe) memungkinkan langganan mencocokkan aktivitas pada **akun token terkait (ATA) yang dimiliki dompet**, bukan hanya transaksi yang memuat pubkey dompet secara langsung. Filter yang sama tersedia melalui gRPC — lihat [Pemfilteran Akun Token (ATA)](/docs/id/laserstream/token-account-filtering) untuk versi gRPC.

## Masalahnya: filter akun biasa melewatkan transfer token masuk

Saat Anda memantau dompet dengan `accountInclude: [wallet]`, pencocokan hanya dilakukan terhadap transaksi yang memuat pubkey dompet tersebut dalam kunci akun transaksi. Ada kasus umum yang terlewat: ketika seseorang mengirim token SPL (misalnya USDC) ke dompet, transfer tersebut menyentuh **akun token terkait (ATA)** milik dompet — alamat terpisah yang diturunkan oleh program — bukan pubkey dompet itu sendiri.

Karena itu, langganan `accountInclude: [wallet]` biasa tidak pernah mendeteksi transfer token masuk. Anda harus mencantumkan terlebih dahulu setiap ATA yang dimiliki dompet dan menambahkan masing-masing ke filter — tetapi ATA dibuat sesuai kebutuhan (satu per mint), sehingga Anda tidak dapat mengetahui seluruh daftarnya sebelumnya.

## Cara kerja perluasan `tokenAccounts`

Tetapkan `tokenAccounts` pada langganan untuk memperluas pencocokan agar dompet `accountInclude` **juga** cocok dengan transaksi yang menyentuh akun token miliknya. Pencocokan ini **berbasis pemilik**: LaserStream mencari akun token yang dimiliki oleh alamat `accountInclude` Anda pada saat pencocokan, sehingga dapat mendeteksi setiap akun token yang dimiliki dompet — termasuk akun nonkanonis — bukan hanya alamat ATA turunan. Anda tidak perlu mencantumkan sendiri ATA tersebut.

Langganan yang tidak menyertakan `tokenAccounts` tetap berperilaku persis seperti sebelumnya, sehingga opsi ini aman ditambahkan ke filter yang ada.

## Mode perluasan

`tokenAccounts` menerima salah satu dari tiga nilai string:

| Nilai              | Yang dicocokkan                                                                             | Volume                                             | Gunakan untuk                                                                                               |
| ------------------ | ------------------------------------------------------------------------------------------- | -------------------------------------------------- | ----------------------------------------------------------------------------------------------------------- |
| `"balanceChanged"` | Transaksi ketika saldo token milik dompet benar-benar berubah (atau akun tokennya ditutup)  | Lebih rendah — nilai default yang direkomendasikan | "Beri tahu saya saat dana benar-benar berpindah" — setoran, penarikan, dan swap yang diselesaikan ke dompet |
| `"all"`            | Setiap transaksi yang merujuk pada akun token milik dompet, meskipun saldonya tidak berubah | Lebih tinggi                                       | Visibilitas penuh atas apa pun yang menyentuh akun token dompet                                             |
| `"none"`           | Tanpa perluasan — sama seperti tidak menyertakan kolom ini                                  | —                                                  | Nilai default                                                                                               |

Mulailah dengan `"balanceChanged"`. Nilai ini menangkap pergerakan dana nyata dengan volume yang jauh lebih kecil dibandingkan `"all"`.

## Menggunakannya dalam `transactionSubscribe`

`tokenAccounts` adalah ekstensi Helius untuk API WebSocket Solana standar. Nilai yang tidak valid akan menghasilkan kesalahan JSON-RPC `-32602`: `Invalid tokenAccounts value '<x>', expected one of: none, balanceChanged, all`.

```javascript theme={"system"}
const ws = new WebSocket('wss://mainnet.helius-rpc.com/?api-key=<API_KEY>');

ws.on('open', () => {
  ws.send(JSON.stringify({
    jsonrpc: '2.0',
    id: 1,
    method: 'transactionSubscribe',
    params: [
      {
        accountInclude: ['<WALLET_PUBKEY>'],
        tokenAccounts: 'balanceChanged' // also match the wallet's ATAs
      },
      { commitment: 'confirmed', encoding: 'jsonParsed', maxSupportedTransactionVersion: 1 }
    ]
  }));
  setInterval(() => ws.ping(), 30_000);
});

ws.on('message', (data) => {
  const msg = JSON.parse(data.toString());
  const result = msg.params?.result;
  if (!result) return;
  // Token balances this wallet owns that changed in the tx
  const owned = (result.transaction.meta.postTokenBalances || [])
    .filter((b) => b.owner === '<WALLET_PUBKEY>');
  console.log(result.signature, owned);
});
```

## Membaca hasil yang cocok

Setelah transaksi cocok melalui perluasan ATA, pergerakan token dompet berada dalam `meta.postTokenBalances` dan `meta.preTokenBalances` transaksi. Filter entri tersebut berdasarkan `owner` untuk mengisolasi saldo yang benar-benar dimiliki dompet Anda, lalu bandingkan selisih `preTokenBalances` dengan `postTokenBalances` pada `accountIndex` yang sama untuk melihat jumlah perpindahan setiap mint. Contoh di atas menunjukkan langkah pemfilteran tersebut.

## Terkait

<CardGroup cols={2}>
  <Card title="transactionSubscribe" icon="bolt" href="/docs/id/rpc/websocket/transaction-subscribe">
    Setiap filter dan opsi `transactionSubscribe`, termasuk `tokenAccounts`.
  </Card>

  <Card title="Token Account Filtering (gRPC)" icon="coins" href="/docs/id/laserstream/token-account-filtering">
    Perluasan `tokenAccounts` yang sama pada filter transaksi gRPC LaserStream.
  </Card>

  <Card title="WebSocket Quickstart" icon="rocket" href="/docs/id/rpc/websocket/quickstart">
    Hubungkan ke WebSocket LaserStream dan alirkan peristiwa pertama Anda.
  </Card>
</CardGroup>
