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

# Panduan Memulai Cepat LaserStream gRPC

> Instal SDK, pilih endpoint, dan streaming transaksi Solana pertama Anda melalui LaserStream gRPC — mencakup endpoint, referensi permintaan berlangganan, dan contoh.

## Ikhtisar

LaserStream adalah layanan streaming gRPC Solana terkelola. Layanan ini kompatibel pada tingkat protokol dengan protokol terbuka Yellowstone gRPC — sehingga semua klien Yellowstone dapat langsung digunakan — serta menambahkan fitur produksi seperti pemutaran ulang historis, failover multi-node, dan lingkungan yang dikelola sepenuhnya.

LaserStream menggunakan protokol gRPC sumber terbuka, sehingga memastikan tidak ada ketergantungan pada vendor dan memberikan kompatibilitas maksimal dengan implementasi gRPC yang sudah ada.

Anda dapat terhubung menggunakan klien `@triton-one/yellowstone-grpc` standar atau menggunakan **[Helius LaserStream SDK](/docs/id/laserstream/clients)** yang dioptimalkan untuk performa guna memperoleh manfaat tambahan, termasuk throughput yang lebih tinggi, penyambungan ulang otomatis, pengelolaan langganan, penanganan kesalahan, dan lainnya.

<Card title="LaserStream SDK is 40x Faster vs. JavaScript Yellowstone Clients" icon="bolt" href="https://www.helius.dev/blog/laserstream-sdks">
  Pelajari cara kami menggunakan Rust Core dengan binding NAPI zero-copy untuk memaksimalkan performa JavaScript SDK
</Card>

<Warning>
  **Pemberitahuan Performa**: Jika Anda mengalami kelambatan atau masalah performa pada koneksi LaserStream, lihat [bagian Pemecahan Masalah](#pemecahan-masalah--faq) untuk mengetahui penyebab umum dan solusinya.
</Warning>

<Divider />

## Endpoint & Wilayah

LaserStream tersedia di berbagai wilayah di seluruh dunia.

Pilih endpoint yang paling dekat dengan aplikasi Anda untuk mendapatkan performa optimal:

### Endpoint Mainnet

| Wilayah  | Lokasi                            | Endpoint                                          |
| -------- | --------------------------------- | ------------------------------------------------- |
| **ewr**  | Newark, NJ (dekat New York)       | `https://laserstream-mainnet-ewr.helius-rpc.com`  |
| **pitt** | Pittsburgh, AS (Tengah)           | `https://laserstream-mainnet-pitt.helius-rpc.com` |
| **slc**  | Salt Lake City, AS (Pantai Barat) | `https://laserstream-mainnet-slc.helius-rpc.com`  |
| **lax**  | Los Angeles, AS (Pantai Barat)    | `https://laserstream-mainnet-lax.helius-rpc.com`  |
| **lon**  | London, Eropa                     | `https://laserstream-mainnet-lon.helius-rpc.com`  |
| **ams**  | Amsterdam, Eropa                  | `https://laserstream-mainnet-ams.helius-rpc.com`  |
| **fra**  | Frankfurt, Eropa                  | `https://laserstream-mainnet-fra.helius-rpc.com`  |
| **tyo**  | Tokyo, Asia                       | `https://laserstream-mainnet-tyo.helius-rpc.com`  |
| **sgp**  | Singapura, Asia                   | `https://laserstream-mainnet-sgp.helius-rpc.com`  |

### Endpoint Devnet

| Jaringan   | Lokasi                      | Endpoint                                        |
| ---------- | --------------------------- | ----------------------------------------------- |
| **Devnet** | Newark, NJ (dekat New York) | `https://laserstream-devnet-ewr.helius-rpc.com` |

<Note>
  **Pemilihan Jaringan & Wilayah**:

  * Untuk **aplikasi produksi**, pilih endpoint mainnet yang paling dekat dengan server Anda agar mendapatkan performa terbaik (misalnya, jika melakukan deployment di Eropa, gunakan Amsterdam (`ams`) atau Frankfurt (`fra`))
  * Untuk **pengujian**, gunakan: `https://laserstream-devnet-ewr.helius-rpc.com`.
</Note>

### Kompresi `zstd`

Semua endpoint LaserStream gRPC mendukung kompresi `zstd`. Kompresi bersifat opsional: respons tetap tidak dikompresi kecuali klien Anda menyatakan dukungan `zstd`.

Aktifkan `zstd` di Helius LaserStream TypeScript SDK:

```typescript theme={"system"}
import { CompressionAlgorithms } from 'helius-laserstream'
import type { LaserstreamConfig } from 'helius-laserstream'

const config: LaserstreamConfig = {
  apiKey: 'YOUR_API_KEY',
  endpoint: 'https://laserstream-mainnet-ewr.helius-rpc.com',
  channelOptions: {
    'grpc.default_compression_algorithm': CompressionAlgorithms.zstd,
  },
}
```

`zstd` mengurangi penggunaan bandwidth jaringan, tetapi menambah beban kerja kompresi. Lakukan benchmark dengan beban kerja langganan Anda sebelum mengaktifkannya untuk stream yang sensitif terhadap latensi.

### Pemotongan Log

Secara default, LaserStream memotong pesan log transaksi menjadi **10 KB** untuk meningkatkan kecepatan dan performa. Jika Anda memerlukan log lengkap, tersedia endpoint khusus tanpa pemotongan — lihat [Pemotongan Log](/docs/id/laserstream/log-truncation).

## Panduan Memulai Cepat

<Tip>
  Mulai gunakan LaserStream melalui [Dasbor Helius](https://dashboard.helius.dev/laserstream). Mainnet memerlukan paket Business atau Professional; Devnet tersedia pada paket Developer dan yang lebih tinggi. Lihat [Paket & Harga](/docs/id/billing/plans) untuk detailnya.
</Tip>

<Steps>
  <Step title="Create a New Project">
    ```bash theme={"system"}
    mkdir laserstream-grpc-demo
    cd laserstream-grpc-demo
    npm init -y
    ```
  </Step>

  <Step title="Install Dependencies">
    ```bash theme={"system"}
    npm install helius-laserstream
    npm install --save-dev typescript tsx @types/node
    ```

    Kami menggunakan `tsx` karena `npx tsc --init` default pada TypeScript 5.x menetapkan `verbatimModuleSyntax`, `module: "nodenext"`, dan `types: []`, yang semuanya menyebabkan eksekusi cepat `ts-node index.ts` gagal. `tsx` menjalankan file `.ts` tanpa tsconfig.
  </Step>

  <Step title="Obtain Your API Key">
    Buat kunci dari [Dasbor Helius](https://dashboard.helius.dev/).

    Kunci ini akan berfungsi sebagai token autentikasi Anda untuk LaserStream.

    <Note>
      **Persyaratan Paket**: LaserStream devnet tersedia pada semua [paket](/docs/id/billing/plans). LaserStream mainnet memerlukan paket Business atau Professional.
    </Note>
  </Step>

  <Step title="Create a Subscription Script">
    Buat **`index.ts`** dengan isi berikut:

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

    async function main() {
      const subscriptionRequest: SubscribeRequest = {
        transactions: {
          "token-filter": { // user-defined label for this filter
            accountInclude: ['TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA'],
            accountExclude: [],
            accountRequired: [],
            vote: false,
            failed: false
          }
        },
        commitment: CommitmentLevel.CONFIRMED,
        accounts: {},
        slots: {},
        transactionsStatus: {},
        blocks: {},
        blocksMeta: {},
        entry: {},
        accountsDataSlice: [],
        // Optionally, you can replay missed data by specifying a `fromSlot` (u64 number):
        // fromSlot: currentSlot - 1000,
        // Note: replay is currently limited to the last ~48 hours (~691,200 slots at current ~250ms slot time).
      };

    // Replace the values below with your actual LaserStream API key and endpoint
    const config: LaserstreamConfig = {
      apiKey: 'YOUR_API_KEY', // Replace with your key from https://dashboard.helius.dev/
      endpoint: 'https://laserstream-mainnet-ewr.helius-rpc.com', // Choose your closest region
    }

      await subscribe(config, subscriptionRequest, async (data) => {
        
        console.log(data);

      }, async (error) => {
        console.error(error);
      });
    }

    main().catch(console.error);
    ```
  </Step>

  <Step title="Replace Your API Key and Choose Your Region">
    Di `index.ts`, perbarui objek `config` dengan:

    1. Kunci API Anda yang sebenarnya dari [Dasbor Helius](https://dashboard.helius.dev/)
    2. Endpoint LaserStream yang paling dekat dengan lokasi server Anda

    ```typescript theme={"system"}
    const config: LaserstreamConfig = {
      apiKey: 'YOUR_ACTUAL_API_KEY', // Replace with your key from Helius Dashboard
      endpoint: 'https://laserstream-mainnet-fra.helius-rpc.com', // Example: Frankfurt mainnet
      // For devnet: endpoint: 'https://laserstream-devnet-ewr.helius-rpc.com'
    }
    ```

    **Contoh Pemilihan Jaringan & Wilayah:**

    * **Untuk Produksi (Mainnet)**:
      * Eropa: Gunakan `fra` (Frankfurt), `ams` (Amsterdam), atau `lon` (London)
      * AS Timur: Gunakan `ewr` (New York)
      * AS Barat: Gunakan `slc` (Salt Lake City) atau `lax` (Los Angeles)
      * Asia: Gunakan `tyo` (Tokyo) atau `sgp` (Singapura)
    * **Untuk Pengembangan (Devnet)**:
      * Gunakan `https://laserstream-devnet-ewr.helius-rpc.com`
  </Step>

  <Step title="Run and View Results">
    ```bash theme={"system"}
    npx tsx index.ts
    ```

    Setiap kali transaksi token `confirmed` melibatkan `TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA`, Anda akan melihat datanya di konsol.
  </Step>
</Steps>

<Divider />

## Alur Kerja Umum

Panduan langkah demi langkah untuk alur kerja yang paling sering kami temui. Setiap panduan menggunakan SDK [`helius-laserstream`](/docs/id/laserstream/clients) dengan penyambungan ulang otomatis dan pemutaran ulang historis bawaan.

<CardGroup cols={2}>
  <Card title="Account Subscriptions" icon="user" href="/docs/id/laserstream/guides/account-subscription">
    Pantau perubahan saldo, data, dan kepemilikan pada akun tertentu menggunakan filter.
  </Card>

  <Card title="Transaction Monitoring" icon="receipt" href="/docs/id/laserstream/guides/transaction-monitoring">
    Streaming transaksi yang melibatkan akun target, lalu filter berdasarkan program, suara, atau status kegagalan.
  </Card>

  <Card title="Slot & Block Monitoring" icon="cube" href="/docs/id/laserstream/guides/slot-and-block-monitoring">
    Lacak konsensus jaringan, produksi blok, dan transisi tingkat komitmen.
  </Card>

  <Card title="Decoding Transaction Data" icon="binary" href="/docs/id/laserstream/guides/decoding-transaction-data">
    Uraikan payload biner `transactionUpdate` menjadi transaksi Solana yang dapat dibaca.
  </Card>

  <Card title="Stream Pump AMM Data" icon="chart-line" href="/docs/id/laserstream/guides/stream-pump-amm-data">
    Contoh dunia nyata: pantau perdagangan Pump AMM dengan filter yang aman saat penyambungan ulang.
  </Card>
</CardGroup>

<Tip>
  Klien `@triton-one/yellowstone-grpc` berfungsi dengan endpoint yang sama jika Anda lebih memilih protokol mentah Yellowstone. Lihat [referensi Yellowstone gRPC](/docs/id/grpc) untuk detail tingkat protokol.
</Tip>

<Divider />

## Permintaan Berlangganan

Dalam permintaan berlangganan, Anda perlu menyertakan parameter umum berikut:

<Note>
  **Pemutaran Ulang Historis:** Anda dapat secara opsional menyertakan bidang `fromSlot` (nomor `u64`) dalam objek utama `SubscribeRequest` untuk memutar ulang data mulai dari slot tertentu. Pemutaran ulang saat ini dibatasi hingga sekitar 48 jam terakhir (\~691.200 slot pada kecepatan jaringan saat ini); perhatikan bahwa [pemutaran ulang yang lebih lama dari sekitar 20 menit hanya mengembalikan data yang sudah final](/docs/id/laserstream/historical-replay#seberapa-jauh-anda-dapat-memutar-ulang).
</Note>

<ParamField body="commitment" type="enum">
  Menentukan tingkat komitmen, yang dapat berupa **processed**, **confirmed**, atau **finalized**.
</ParamField>

<ParamField body="accountsDataSlice" type="array">
  Array objek `{ offset: uint64, length: uint64 }` yang memungkinkan Anda hanya menerima potongan data yang diperlukan dari akun.
</ParamField>

<ParamField body="ping" type="boolean">
  Beberapa penyedia cloud (seperti Cloudflare) dapat menutup stream yang tidak aktif setelah periode tertentu. Untuk mencegahnya dan menjaga koneksi tetap aktif tanpa perlu mengirim ulang filter, tetapkan nilai ini ke **true**. Server akan merespons dengan pesan Pong setiap 15 detik.
</ParamField>

```typescript theme={"system"}
const subscriptionRequest: SubscribeRequest = {
  commitment: CommitmentLevel.CONFIRMED,
  accountsDataSlice: [],
  transactions: {},
  accounts: {},
  slots: {},
  blocks: {},
  blocksMeta: {},
  entry: {},
}
```

Selanjutnya, Anda perlu menentukan filter untuk data yang ingin Anda langgani, seperti akun, blok, slot, atau transaksi.

<Accordion title="Slots">
  Tentukan filter untuk pembaruan slot. Kunci yang Anda gunakan (misalnya, `mySlotLabel`) adalah **label yang ditentukan pengguna** untuk konfigurasi filter khusus ini, sehingga Anda dapat menentukan beberapa konfigurasi bernama jika diperlukan (meskipun biasanya satu sudah cukup).

  <ParamField body="filterByCommitment" type="boolean">
    Secara default, slot dikirim untuk semua tingkat komitmen. Dengan filter ini, Anda dapat memilih untuk hanya menerima tingkat komitmen yang dipilih.
  </ParamField>

  <ParamField body="interslotUpdates" type="boolean">
    Memungkinkan langganan menerima pembaruan untuk perubahan di dalam slot, tidak hanya pada awal slot baru. Hal ini berguna untuk data slot yang lebih terperinci dan berlatensi rendah.
  </ParamField>

  ```typescript theme={"system"}
  slots: {
    // mySlotLabel is a user-defined name for this slot update filter configuration
    mySlotLabel: {
      // filterByCommitment: true => Only broadcast slot updates at the specified subscribeRequest commitment
      filterByCommitment: true
      // interslotUpdates: true allows receiving updates for changes occurring within a slot, not just new slots.
      interslotUpdates: true
    }
  },
  ```
</Accordion>

<Accordion title="Accounts">
  Tentukan filter untuk pembaruan data akun. Kunci yang Anda gunakan (misalnya, `tokenAccounts`) adalah **label yang ditentukan pengguna** untuk konfigurasi filter khusus ini.

  <ParamField body="account" type="array">
    Mencocokkan kunci publik mana pun dari array yang disediakan.
  </ParamField>

  <ParamField body="owner" type="array">
    Kunci publik pemilik akun. Mencocokkan kunci publik mana pun dari array yang disediakan.
  </ParamField>

  <ParamField body="filters" type="array">
    Mirip dengan filter dalam [getProgramAccounts](https://solana.com/docs/rpc/http/getprogramaccounts). Ini adalah array filter `datasize` dan/atau `memcmp`. Untuk `memcmp`, nilai pembanding ditempatkan langsung pada salah satu dari `bytes`, `base58`, atau `base64` di objek `memcmp`.
  </ParamField>

  <ParamField body="notifyOn" type="enum" deprecated>
    **Tidak digunakan lagi — tidak melakukan apa pun sejak Agave 4.2.** Menetapkan `notifyOn` tidak berpengaruh. Bidang ini akan dihapus di kemudian hari.
  </ParamField>

  Jika semua bidang kosong, semua akun akan disiarkan. Jika tidak:

  * Bidang beroperasi sebagai **AND** logis.
  * Nilai dalam array beroperasi sebagai **OR** logis (kecuali dalam `filters`, yang beroperasi sebagai **AND** logis).

  ```typescript theme={"system"}
  accounts: {
    // tokenAccounts is a user-defined label for this account filter configuration
    tokenAccounts: {
      // Matches any of these public keys (logical OR)
      account: ["9SHQTA66Ekh7ZgMnKWsjxXk6DwXku8przs45E8bcEe38"],
      // Matches owners that are any of these public keys
      owner: ["TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"],
      // Filters - all must match (AND logic)
      filters: [
        { datasize: 165 },
        {
          memcmp: {
            offset: 0,
            base58: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v"
          }
        }
      ]
    }
  },
  ```

  Melacak lebih dari \~10.000 akun? Alih-alih menggunakan daftar pubkey eksplisit (32 byte per akun), gunakan [filter cuckoo](/docs/id/laserstream/cuckoo-filters) terkompresi (\~3–4 byte per akun) untuk berlangganan ratusan ribu akun dalam satu stream. Tersedia dalam Rust dan JavaScript SDK.
</Accordion>

<Accordion title="Transaction">
  Tentukan filter untuk pembaruan transaksi. Kunci yang Anda gunakan (misalnya, `myTxSubscription`) adalah **label yang ditentukan pengguna** untuk konfigurasi filter khusus ini.

  <ParamField body="vote" type="boolean">
    Aktifkan atau nonaktifkan penyiaran transaksi suara.
  </ParamField>

  <ParamField body="failed" type="boolean">
    Aktifkan atau nonaktifkan penyiaran transaksi yang gagal.
  </ParamField>

  <ParamField body="signature" type="string">
    Siarkan hanya transaksi yang cocok dengan tanda tangan yang ditentukan.
  </ParamField>

  <ParamField body="accountInclude" type="array">
    Filter transaksi yang melibatkan akun mana pun dari daftar yang disediakan.
  </ParamField>

  <ParamField body="accountExclude" type="array">
    Kecualikan transaksi yang melibatkan akun mana pun dari daftar yang disediakan (kebalikan dari `accountInclude`).
  </ParamField>

  <ParamField body="accountRequired" type="array">
    Filter transaksi yang melibatkan semua akun dari daftar yang disediakan (semua akun harus digunakan).
  </ParamField>

  <ParamField body="tokenAccounts" type="string">
    Ekspansi `tokenAccounts` (akun token terkait) opsional. Jika ditetapkan, dompet `accountInclude` juga cocok dengan transaksi saat dompet tersebut **memiliki** saldo token SPL — misalnya transfer token masuk yang menyentuh akun token dompet, bukan pubkey-nya. Menerima `"balanceChanged"` (kecocokan delta saldo), `"all"` (referensi apa pun, volume lebih tinggi), atau `"none"` (tanpa ekspansi, default). SDK mengonversi string menjadi enum `TokenAccountExpansionControlFlag` tingkat protokol (bagian dari `yellowstone-grpc-proto` 12.5.0+). Lihat [Pemfilteran Akun Token (ATA)](/docs/id/laserstream/token-account-filtering) untuk mengetahui fungsi dan cara kerjanya.
  </ParamField>

  <ParamField body="matchMints" type="boolean">
    Flag `matchMints` opsional (default `false`). Saat `true`, daftar `accountInclude`, `accountExclude`, dan `accountRequired` juga dicocokkan dengan mint dalam saldo token sebelum/sesudah transaksi, bukan hanya dengan kunci akunnya. Masukkan mint ke `accountInclude` untuk menerima setiap transaksi yang menyentuh token tersebut, termasuk transfer SPL biasa yang tidak pernah mereferensikan mint dalam kunci akunnya. Fitur ini bersifat opsional dan tidak memengaruhi filter yang ada. Memerlukan `helius-laserstream` 0.8.5+ (JS), 0.6.4+ (Rust), atau `go/v0.3.0`+ (Go). Lihat [Pemfilteran Mint Token](/docs/id/laserstream/mint-filtering) untuk semantik dan contoh.
  </ParamField>

  Jika semua bidang dibiarkan kosong, semua transaksi akan disiarkan. Jika tidak:

  * Bidang beroperasi sebagai **AND** logis.
  * Nilai dalam array diperlakukan sebagai **OR** logis (kecuali untuk `accountRequired`, yang semuanya harus cocok).

  ```typescript theme={"system"}
  transactions: {
    // myTxSubscription is a user-defined label for this transaction filter configuration
    myTxSubscription: {
      vote: false,
      failed: false,
      signature: "",
      // Transaction must include at least one of these public keys (OR)
      accountInclude: ["86xCnPeV69n6t3DnyGvkKobf9FdN2H9oiVDdaMpo2MMY"],
      // Exclude if it matches any of these
      accountExclude: [],
      // Require all accounts in this array (AND)
      accountRequired: []
    }
  },
  ```
</Accordion>

<Accordion title="Block">
  Tentukan filter untuk pembaruan blok. Kunci yang Anda gunakan (misalnya, `myBlockLabel`) adalah **label yang ditentukan pengguna** untuk konfigurasi filter khusus ini.

  <ParamField body="accountInclude" type="array">
    Memfilter transaksi dan akun yang melibatkan akun mana pun dari daftar yang disediakan.
  </ParamField>

  <ParamField body="includeTransactions" type="boolean">
    Menyertakan semua transaksi dalam siaran.
  </ParamField>

  <ParamField body="includeAccounts" type="boolean">
    Menyertakan semua pembaruan akun dalam siaran.
  </ParamField>

  <ParamField body="includeEntries" type="boolean">
    Menyertakan semua entri dalam siaran.
  </ParamField>

  ```typescript theme={"system"}
  blocks: {
    // myBlockLabel is a user-defined label for this block filter configuration
    myBlockLabel: {
      // Only broadcast blocks referencing these accounts
      accountInclude: ["86xCnPeV69n6t3DnyGvkKobf9FdN2H9oiVDdaMpo2MMY"],
      includeTransactions: true,
      includeAccounts: false,
      includeEntries: false
    }
  },
  ```
</Accordion>

<Accordion title="Blocks Meta">
  Fitur ini berfungsi serupa dengan Blocks, tetapi tidak menyertakan transaksi, akun, dan entri. Kunci yang Anda gunakan (misalnya, `blockmetadata`) adalah **label yang ditentukan pengguna** untuk langganan ini. Saat ini, tidak tersedia filter untuk metadata blok—semua pesan disiarkan secara default.

  ```typescript theme={"system"}
  blocksMeta: {
    blockmetadata: {}
  },
  ```
</Accordion>

<Accordion title="Entries">
  Berlangganan entri ledger. Kunci yang Anda gunakan (misalnya, `entrySubscribe`) adalah **label yang ditentukan pengguna** untuk langganan ini. Saat ini, tidak tersedia filter untuk entri; semua entri disiarkan.

  ```typescript theme={"system"}
  entry: {
    entrySubscribe: {}
  },
  ```
</Accordion>

<Divider />

## Contoh Kode (LaserStream SDK)

<Tabs>
  <Tab title="Slot Updates">
    ```typescript theme={"system"}
    import { subscribe, CommitmentLevel, LaserstreamConfig, SubscribeRequest } from 'helius-laserstream'

    async function main() {
        const subscriptionRequest: SubscribeRequest = {
            transactions: {},
            commitment: CommitmentLevel.CONFIRMED,
            accounts: {},
            slots: {
                slot: { filterByCommitment: true },
            },
            transactionsStatus: {},
            blocks: {},
            blocksMeta: {},
            entry: {},
            accountsDataSlice: [],
        };

        const config: LaserstreamConfig = {
            apiKey: 'YOUR_API_KEY', // Replace with your key
            endpoint: 'https://laserstream-mainnet-ewr.helius-rpc.com', // Choose your closest region
        }

        await subscribe(config, subscriptionRequest, async (data) => {
            console.log(data);
        }, async (error) => {
            console.error(error);
        });
    }

    main().catch(console.error);
    ```
  </Tab>

  <Tab title="Account Updates">
    ```typescript theme={"system"}
    import { subscribe, CommitmentLevel, LaserstreamConfig, SubscribeRequest } from 'helius-laserstream'

    async function main() {
        const subscriptionRequest: SubscribeRequest = {
            accounts: {
                "usdc-account": { // user-defined label for this filter
                    account: ["EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v"], // USDC mint account
                    owner: [],
                    filters: []
                }
            },
            accountsDataSlice: [],
            commitment: CommitmentLevel.CONFIRMED,
            slots: {},
            transactions: {},
            transactionsStatus: {},
            blocks: {},
            blocksMeta: {},
            entry: {}
        };

        const config: LaserstreamConfig = {
            apiKey: 'YOUR_API_KEY', // Replace with your key
            endpoint: 'https://laserstream-mainnet-ewr.helius-rpc.com', // Choose your closest region
        }

        await subscribe(config, subscriptionRequest, async (data) => {
            console.log(data);
        }, async (error) => {
            console.error(error);
        });
    }

    main().catch(console.error);
    ```
  </Tab>

  <Tab title="Transaction Updates">
    ```typescript theme={"system"}
    import { subscribe, CommitmentLevel, LaserstreamConfig, SubscribeRequest } from 'helius-laserstream'

    async function main() {
        const subscriptionRequest: SubscribeRequest = {
            transactions: {
                "token-filter": { // user-defined label for this filter
                    accountInclude: ['TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA'],
                    accountExclude: [],
                    accountRequired: [],
                    vote: false,
                    failed: false
                }
            },
            commitment: CommitmentLevel.CONFIRMED,
            accounts: {},
            slots: {},
            transactionsStatus: {},
            blocks: {},
            blocksMeta: {},
            entry: {},
            accountsDataSlice: [],
        };

        const config: LaserstreamConfig = {
            apiKey: 'YOUR_API_KEY', // Replace with your key
            endpoint: 'https://laserstream-mainnet-ewr.helius-rpc.com', // Choose your closest region
        }

        await subscribe(config, subscriptionRequest, async (data) => {
            console.log(data);
        }, async (error) => {
            console.error(error);
        });
    }

    main().catch(console.error);
    ```
  </Tab>

  <Tab title="Blocks">
    ```typescript theme={"system"}
    import { subscribe, CommitmentLevel, LaserstreamConfig, SubscribeRequest } from 'helius-laserstream'

    async function main() {
        const subscriptionRequest: SubscribeRequest = {
            entry: {},
            accounts: {},
            accountsDataSlice: [],
            slots: {},
            blocks: {
                blocks: {
                    accountInclude: []
                }
            },
            blocksMeta: {},
            transactions: {},
            transactionsStatus: {},
            commitment: CommitmentLevel.CONFIRMED,
        };

        const config: LaserstreamConfig = {
            apiKey: 'YOUR_API_KEY', // Replace with your key
            endpoint: 'https://laserstream-mainnet-ewr.helius-rpc.com', // Choose your closest region
        }

        await subscribe(config, subscriptionRequest, async (data) => {
            console.log(data);
        }, async (error) => {
            console.error(error);
        });
    }

    main().catch(console.error);
    ```
  </Tab>

  <Tab title="Block Metadata">
    ```typescript theme={"system"}
    import { subscribe, CommitmentLevel, LaserstreamConfig, SubscribeRequest } from 'helius-laserstream'

    async function main() {
        const subscriptionRequest: SubscribeRequest = {
            entry: {},
            accounts: {},
            accountsDataSlice: [],
            slots: {},
            blocks: {},
            blocksMeta: {
                blockmetadata: {}
            },
            transactions: {},
            transactionsStatus: {},
            commitment: CommitmentLevel.CONFIRMED,
        };

        const config: LaserstreamConfig = {
            apiKey: 'YOUR_API_KEY', // Replace with your key
            endpoint: 'https://laserstream-mainnet-ewr.helius-rpc.com', // Choose your closest region
        }

        await subscribe(config, subscriptionRequest, async (data) => {
            console.log(data);
        }, async (error) => {
            console.error(error);
        });
    }

    main().catch(console.error);
    ```
  </Tab>

  <Tab title="Entries">
    ```typescript theme={"system"}
    import { subscribe, CommitmentLevel, LaserstreamConfig, SubscribeRequest } from 'helius-laserstream'

    async function main() {
        const subscriptionRequest: SubscribeRequest = {
            entry: {
                entrySubscribe: {}  // Subscribe to all entries
            },
            accounts: {},
            accountsDataSlice: [],
            slots: {},
            blocks: {},
            blocksMeta: {},
            transactions: {},
            transactionsStatus: {},
            commitment: CommitmentLevel.CONFIRMED,
        };

        const config: LaserstreamConfig = {
            apiKey: 'YOUR_API_KEY', // Replace with your key
            endpoint: 'https://laserstream-mainnet-ewr.helius-rpc.com', // Choose your closest region
        }

        await subscribe(config, subscriptionRequest, async (data) => {
            console.log(data);
        }, async (error) => {
            console.error(error);
        });
    }

    main().catch(console.error);
    ```
  </Tab>

  <Tab title="Unary Methods">
    ```typescript theme={"system"}
    import { LaserstreamClient, CommitmentLevel } from 'helius-laserstream'

    async function main() {
        // Create once and reuse: all calls share one connection
        const client = new LaserstreamClient({
            apiKey: 'YOUR_API_KEY', // Replace with your key
            endpoint: 'https://laserstream-mainnet-ewr.helius-rpc.com', // Choose your closest region
        });

        // Commitment is optional (server default when omitted)
        const { slot } = await client.getSlot(CommitmentLevel.CONFIRMED);
        const { blockHeight } = await client.getBlockHeight();
        const bh = await client.getLatestBlockhash(); // { blockhash, slot, lastValidBlockHeight }
        const { valid } = await client.isBlockhashValid(bh.blockhash);
        const { version } = await client.getVersion();
        const { count } = await client.ping(1);
        const { firstAvailable } = await client.subscribeReplayInfo(); // earliest replayable slot

        // uint64 values (slots, heights) are returned as strings
        console.log({ slot, blockHeight, blockhash: bh.blockhash, valid, version, count, firstAvailable });

        client.close();
    }

    main().catch(console.error);
    ```
  </Tab>
</Tabs>

<Divider />

## Opsi SDK

Kami menyediakan SDK resmi untuk beberapa bahasa pemrograman:

* **TypeScript**: [LaserStream TypeScript SDK](https://github.com/helius-labs/laserstream-sdk)
* **Rust**: [LaserStream Rust SDK](https://github.com/helius-labs/laserstream-sdk/tree/main/rust)
* **Go**: [LaserStream Go SDK](https://github.com/helius-labs/laserstream-sdk/tree/main/go)

Untuk bahasa lain atau implementasi khusus, Anda dapat langsung menggunakan [file proto Yellowstone gRPC](https://github.com/rpcpool/yellowstone-grpc/tree/v6.0.0%2Bsolana.2.2.12/yellowstone-grpc-proto/proto) untuk menghasilkan klien gRPC bagi bahasa pilihan Anda.

<Divider />

## Pemecahan Masalah / FAQ

<Accordion title="Q: I'm experiencing lag or slow performance with my LaserStream connection. What could be causing this?">
  **J:** Masalah performa pada koneksi LaserStream biasanya disebabkan oleh:

  * **Kelambatan Klien JavaScript**: Klien JavaScript dapat tertinggal saat memproses terlalu banyak pesan atau menggunakan terlalu banyak bandwidth. Pertimbangkan untuk mempersempit filter langganan guna mengurangi volume pesan, beralih ke [LaserStream JavaScript SDK](/docs/id/laserstream/clients), atau mencoba bahasa lain.

  * **Bandwidth lokal terbatas**: Langganan berat dapat membebani klien yang memiliki bandwidth jaringan terbatas. Pantau penggunaan jaringan Anda dan pertimbangkan untuk meningkatkan koneksi atau mengurangi cakupan langganan.

  * **Jarak geografis**: Rute jaringan yang panjang meningkatkan latensi dan kehilangan paket. Gunakan [endpoint yang paling dekat dengan server Anda](#endpoint-mainnet). Untuk koneksi berlatensi tinggi, tingkatkan ukuran buffer baca jaringan Anda (dapat meningkatkan bandwidth hingga 5x+):

    ```bash theme={"system"}
    sudo sysctl -w net.core.rmem_max=67108864 net.ipv4.tcp_rmem="4096 87380 67108864"
    ```

    Agar tetap berlaku setelah boot ulang, tambahkan ke `/etc/sysctl.conf`:

    ```bash theme={"system"}
    net.core.rmem_max=67108864
    net.ipv4.tcp_rmem=4096 87380 67108864
    ```

    Tingkatkan ukuran jendela stream **dan koneksi** HTTP/2 menjadi 64MB untuk mencegah hambatan kontrol aliran. Keduanya diperlukan — hanya meningkatkan jendela stream akan membuat jendela tingkat koneksi tetap menjadi batas yang mengikat:

    ```rust theme={"system"}
    // Rust (tonic)
    Channel::from_static("https://laserstream-mainnet-ewr.helius-rpc.com")
        .initial_stream_window_size(1024 * 1024 * 64)      // 64MB stream window
        .initial_connection_window_size(1024 * 1024 * 64)  // 64MB connection window
        .connect()
        .await?;
    ```

  * **Hambatan pemrosesan di sisi klien**: Pastikan logika pemrosesan pesan Anda dioptimalkan dan tidak memblokir thread utama dalam waktu lama.

  **Men-debug Kelambatan Klien**: Untuk membantu Anda men-debug klien, kami membuat alat untuk menguji bandwidth maksimum dari node Anda ke server Laserstream gRPC. Untuk menggunakannya, jalankan:

  ```
  cargo install helius-laserstream-bandwidth
  helius-laserstream-bandwidth --laserstream-url $LASERSTREAM_URL --api-key $API_KEY
  ```

  Output mengembalikan kapasitas jaringan maksimum antara server Anda dan server Laserstream. Minimal, Anda memerlukan 10MB/s untuk berlangganan semua data transaksi dan 80MB/s untuk berlangganan semua data akun. Kami menyarankan kapasitas setidaknya 2x dari yang diperlukan untuk performa optimal.
</Accordion>

<Accordion title="Q: I'm getting connection errors. What should I check?">
  **J:** Pastikan kunci API dan endpoint Anda benar serta jaringan Anda mengizinkan koneksi gRPC keluar ke endpoint yang ditentukan. Periksa [halaman status Helius](https://helius.statuspage.io/) untuk melihat insiden yang sedang berlangsung.
</Accordion>

<Accordion title="Q: Why aren't my filters working as expected?">
  **J:** Periksa kembali operator logis (AND/OR) yang dijelaskan dalam bagian filter. Pastikan kunci publik sudah benar. Tinjau tingkat komitmen yang ditentukan dalam permintaan Anda.
</Accordion>

<Accordion title="Q: Can I subscribe to multiple types of data (e.g., accounts and transactions) in one request?">
  **J:** Ya, Anda dapat menentukan konfigurasi filter di bawah beberapa kunci (misalnya, `accounts`, `transactions`) dalam objek `SubscribeRequest` yang sama.
</Accordion>

<Accordion title="Q: Does LaserStream support consumer groups?">
  **J:** Kami tidak mengimplementasikan grup konsumen. Sebagai gantinya, LaserStream memberikan hasil yang sama seperti yang dibutuhkan tim: melanjutkan, memutar ulang, dan keandalan multi-node tanpa lapisan koordinasi (beserta latensi/beban tambahan yang menyertainya). Kami berpendapat bahwa grup konsumen tidak diperlukan untuk sebagian besar beban kerja dan justru menambah latensi serta beban operasional. Sebagai contoh, satu koneksi LaserStream gRPC dapat menghasilkan hingga 10× data transaksi + akun Solana, sementara sebagian besar klien hanya berlangganan bagian kecil yang telah difilter. Penggunaan grup konsumen dalam kasus ini menghabiskan cadangan performa dan menambah titik kegagalan lainnya.
</Accordion>

<Accordion title="Q: Why are my transaction log messages cut off?">
  **J:** Secara default, LaserStream memotong pesan log transaksi menjadi 10 KB untuk meningkatkan kecepatan dan performa. Jika Anda memerlukan log lengkap, hubungkan ke endpoint khusus tanpa pemotongan — lihat [Pemotongan Log](/docs/id/laserstream/log-truncation) untuk daftarnya.
</Accordion>

<Accordion title="Q: Why am I only receiving Pong responses with no account or slot data?">
  **J:** Menyertakan bidang `ping` dalam `SubscribeRequest` awal menyebabkan LaserStream mengabaikan semua filter langganan secara diam-diam — hanya Pong yang dikembalikan tanpa data akun, transaksi, atau slot. Untuk memperbaikinya, hapus `ping` dari permintaan berlangganan awal, lalu kirim ping secara terpisah melalui sink stream setelah langganan dibuat. Cara ini menjaga koneksi tetap aktif tanpa mengganggu filter Anda.
</Accordion>
