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

# Hướng dẫn bắt đầu nhanh với LaserStream gRPC

> Cài đặt SDK, chọn một điểm cuối và truyền phát các giao dịch Solana đầu tiên qua LaserStream gRPC — bao gồm các điểm cuối, tài liệu tham khảo về yêu cầu đăng ký và ví dụ.

## Tổng quan

LaserStream là dịch vụ truyền phát Solana gRPC được quản lý. Dịch vụ này tương thích ở cấp giao thức truyền dẫn với giao thức Yellowstone gRPC mở — vì vậy mọi ứng dụng khách Yellowstone đều hoạt động ngay — đồng thời bổ sung các tính năng dành cho môi trường production như phát lại dữ liệu lịch sử, chuyển đổi dự phòng đa nút và môi trường được quản lý hoàn toàn.

LaserStream sử dụng giao thức gRPC mã nguồn mở, bảo đảm không bị phụ thuộc vào nhà cung cấp và có khả năng tương thích tối đa với các triển khai gRPC hiện có.

Bạn có thể kết nối bằng ứng dụng khách `@triton-one/yellowstone-grpc` tiêu chuẩn hoặc sử dụng **[Helius LaserStream SDK](/docs/vi/laserstream/clients)** đã được tối ưu hóa hiệu năng để nhận thêm các lợi ích như thông lượng cao hơn, tự động kết nối lại, quản lý đăng ký, xử lý lỗi và nhiều tính năng khác.

<Card title="LaserStream SDK is 40x Faster vs. JavaScript Yellowstone Clients" icon="bolt" href="https://www.helius.dev/blog/laserstream-sdks">
  Tìm hiểu cách chúng tôi sử dụng Rust Core với các liên kết NAPI không sao chép để tối đa hóa hiệu năng của JavaScript SDK
</Card>

<Warning>
  **Lưu ý về hiệu năng**: Nếu kết nối LaserStream bị trễ hoặc gặp vấn đề về hiệu năng, hãy tham khảo [phần Khắc phục sự cố](#khắc-phục-sự-cố--câu-hỏi-thường-gặp) để biết các nguyên nhân và giải pháp thường gặp.
</Warning>

<Divider />

## Điểm cuối và khu vực

LaserStream có mặt tại nhiều khu vực trên toàn thế giới.

Chọn điểm cuối gần ứng dụng nhất để có hiệu năng tối ưu:

### Điểm cuối Mainnet

| Khu vực  | Vị trí                          | Điểm cuối                                         |
| -------- | ------------------------------- | ------------------------------------------------- |
| **ewr**  | Newark, NJ (gần New York)       | `https://laserstream-mainnet-ewr.helius-rpc.com`  |
| **pitt** | Pittsburgh, Hoa Kỳ (miền Trung) | `https://laserstream-mainnet-pitt.helius-rpc.com` |
| **slc**  | Salt Lake City, Hoa Kỳ (Bờ Tây) | `https://laserstream-mainnet-slc.helius-rpc.com`  |
| **lax**  | Los Angeles, Hoa Kỳ (Bờ Tây)    | `https://laserstream-mainnet-lax.helius-rpc.com`  |
| **lon**  | London, châu Âu                 | `https://laserstream-mainnet-lon.helius-rpc.com`  |
| **ams**  | Amsterdam, châu Âu              | `https://laserstream-mainnet-ams.helius-rpc.com`  |
| **fra**  | Frankfurt, châu Âu              | `https://laserstream-mainnet-fra.helius-rpc.com`  |
| **tyo**  | Tokyo, châu Á                   | `https://laserstream-mainnet-tyo.helius-rpc.com`  |
| **sgp**  | Singapore, châu Á               | `https://laserstream-mainnet-sgp.helius-rpc.com`  |

### Điểm cuối Devnet

| Mạng       | Vị trí                    | Điểm cuối                                       |
| ---------- | ------------------------- | ----------------------------------------------- |
| **Devnet** | Newark, NJ (gần New York) | `https://laserstream-devnet-ewr.helius-rpc.com` |

<Note>
  **Chọn mạng và khu vực**:

  * Với **ứng dụng production**, hãy chọn điểm cuối mainnet gần máy chủ nhất để có hiệu năng tốt nhất (ví dụ: nếu triển khai tại châu Âu, hãy dùng Amsterdam (`ams`) hoặc Frankfurt (`fra`))
  * Để **kiểm thử**, hãy dùng: `https://laserstream-devnet-ewr.helius-rpc.com`.
</Note>

### Nén `zstd`

Tất cả điểm cuối LaserStream gRPC đều hỗ trợ nén `zstd`. Tính năng nén là tùy chọn: phản hồi vẫn không được nén trừ khi ứng dụng khách thông báo hỗ trợ `zstd`.

Bật `zstd` trong 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` giảm băng thông mạng nhưng làm tăng khối lượng xử lý nén. Hãy đo điểm chuẩn với khối lượng công việc đăng ký trước khi bật tính năng này cho các luồng nhạy cảm với độ trễ.

### Cắt ngắn nhật ký

Theo mặc định, LaserStream cắt ngắn thông báo nhật ký giao dịch ở mức **10 KB** để cải thiện tốc độ và hiệu năng. Nếu cần nhật ký đầy đủ, bạn có thể dùng các điểm cuối chuyên dụng không cắt ngắn — xem [Cắt ngắn nhật ký](/docs/vi/laserstream/log-truncation).

## Bắt đầu nhanh

<Tip>
  Bắt đầu sử dụng LaserStream từ [Bảng điều khiển Helius](https://dashboard.helius.dev/laserstream). Mainnet yêu cầu gói Business hoặc Professional; Devnet dành cho gói Developer trở lên. Xem [Gói dịch vụ và giá](/docs/vi/billing/plans) để biết chi tiết.
</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
    ```

    Chúng tôi dùng `tsx` vì `npx tsc --init` mặc định trên TypeScript 5.x đặt `verbatimModuleSyntax`, `module: "nodenext"` và `types: []`, khiến thao tác chạy nhanh bằng `ts-node index.ts` bị lỗi. `tsx` chạy các tệp `.ts` mà không cần tsconfig.
  </Step>

  <Step title="Obtain Your API Key">
    Tạo khóa từ [Bảng điều khiển Helius](https://dashboard.helius.dev/).

    Khóa này sẽ được dùng làm token xác thực cho LaserStream.

    <Note>
      **Yêu cầu về gói dịch vụ**: LaserStream devnet có trong tất cả [gói dịch vụ](/docs/vi/billing/plans). LaserStream mainnet yêu cầu gói Business hoặc Professional.
    </Note>
  </Step>

  <Step title="Create a Subscription Script">
    Tạo **`index.ts`** với nội dung sau:

    ```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">
    Trong `index.ts`, hãy cập nhật đối tượng `config` bằng:

    1. Khóa API thực tế từ [Bảng điều khiển Helius](https://dashboard.helius.dev/)
    2. Điểm cuối LaserStream gần vị trí máy chủ nhất

    ```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'
    }
    ```

    **Ví dụ chọn mạng và khu vực:**

    * **Cho production (Mainnet)**:
      * Châu Âu: Dùng `fra` (Frankfurt), `ams` (Amsterdam) hoặc `lon` (London)
      * Miền Đông Hoa Kỳ: Dùng `ewr` (New York)
      * Miền Tây Hoa Kỳ: Dùng `slc` (Salt Lake City) hoặc `lax` (Los Angeles)
      * Châu Á: Dùng `tyo` (Tokyo) hoặc `sgp` (Singapore)
    * **Cho phát triển (Devnet)**:
      * Dùng `https://laserstream-devnet-ewr.helius-rpc.com`
  </Step>

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

    Bất cứ khi nào giao dịch token `confirmed` có liên quan đến `TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA`, dữ liệu sẽ xuất hiện trong bảng điều khiển.
  </Step>
</Steps>

<Divider />

## Quy trình làm việc phổ biến

Hướng dẫn từng bước cho các quy trình làm việc thường gặp nhất. Mỗi hướng dẫn đều sử dụng SDK [`helius-laserstream`](/docs/vi/laserstream/clients), tích hợp sẵn tính năng tự động kết nối lại và phát lại dữ liệu lịch sử.

<CardGroup cols={2}>
  <Card title="Account Subscriptions" icon="user" href="/docs/vi/laserstream/guides/account-subscription">
    Theo dõi thay đổi về số dư, dữ liệu và quyền sở hữu trên các tài khoản cụ thể bằng bộ lọc.
  </Card>

  <Card title="Transaction Monitoring" icon="receipt" href="/docs/vi/laserstream/guides/transaction-monitoring">
    Truyền phát các giao dịch liên quan đến tài khoản mục tiêu; lọc theo chương trình, phiếu bầu hoặc trạng thái thất bại.
  </Card>

  <Card title="Slot & Block Monitoring" icon="cube" href="/docs/vi/laserstream/guides/slot-and-block-monitoring">
    Theo dõi sự đồng thuận của mạng, quá trình tạo khối và các lần chuyển đổi cấp độ cam kết.
  </Card>

  <Card title="Decoding Transaction Data" icon="binary" href="/docs/vi/laserstream/guides/decoding-transaction-data">
    Phân tích các tải trọng nhị phân `transactionUpdate` thành giao dịch Solana có thể đọc được.
  </Card>

  <Card title="Stream Pump AMM Data" icon="chart-line" href="/docs/vi/laserstream/guides/stream-pump-amm-data">
    Ví dụ thực tế: theo dõi giao dịch Pump AMM bằng các bộ lọc an toàn khi kết nối lại.
  </Card>
</CardGroup>

<Tip>
  Ứng dụng khách `@triton-one/yellowstone-grpc` hoạt động với cùng các điểm cuối nếu bạn muốn dùng giao thức Yellowstone thô. Xem [tài liệu tham khảo Yellowstone gRPC](/docs/vi/grpc) để biết chi tiết ở cấp giao thức.
</Tip>

<Divider />

## Yêu cầu đăng ký

Trong yêu cầu đăng ký, bạn cần đưa vào các tham số chung sau:

<Note>
  **Phát lại dữ liệu lịch sử:** Bạn có thể tùy chọn thêm trường `fromSlot` (một số `u64`) vào đối tượng `SubscribeRequest` chính để phát lại dữ liệu từ một slot cụ thể trở đi. Hiện tại, phạm vi phát lại được giới hạn trong khoảng 48 giờ gần nhất (\~691.200 slot theo tốc độ mạng hiện tại); lưu ý rằng [các bản phát lại cũ hơn khoảng 20 phút chỉ trả về dữ liệu đã hoàn tất](/docs/vi/laserstream/historical-replay#bạn-có-thể-phát-lại-dữ-liệu-từ-bao-lâu-trước-đây).
</Note>

<ParamField body="commitment" type="enum">
  Chỉ định cấp độ cam kết, có thể là **processed**, **confirmed** hoặc **finalized**.
</ParamField>

<ParamField body="accountsDataSlice" type="array">
  Một mảng đối tượng `{ offset: uint64, length: uint64 }` cho phép chỉ nhận các lát dữ liệu cần thiết từ tài khoản.
</ParamField>

<ParamField body="ping" type="boolean">
  Một số nhà cung cấp đám mây (như Cloudflare) có thể đóng các luồng không hoạt động sau một khoảng thời gian. Để ngăn điều này và duy trì kết nối mà không cần gửi lại bộ lọc, hãy đặt giá trị này thành **true**. Máy chủ sẽ phản hồi bằng thông báo Pong sau mỗi 15 giây.
</ParamField>

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

Tiếp theo, bạn cần chỉ định các bộ lọc cho dữ liệu muốn đăng ký, chẳng hạn như tài khoản, khối, slot hoặc giao dịch.

<Accordion title="Slots">
  Xác định bộ lọc cho các bản cập nhật slot. Khóa bạn sử dụng (ví dụ: `mySlotLabel`) là **nhãn do người dùng xác định** cho cấu hình bộ lọc cụ thể này, cho phép bạn xác định nhiều cấu hình có tên nếu cần (mặc dù thông thường chỉ cần một cấu hình).

  <ParamField body="filterByCommitment" type="boolean">
    Theo mặc định, slot được gửi cho mọi cấp độ cam kết. Với bộ lọc này, bạn có thể chọn chỉ nhận cấp độ cam kết đã chọn.
  </ParamField>

  <ParamField body="interslotUpdates" type="boolean">
    Cho phép đăng ký nhận thông tin cập nhật về các thay đổi bên trong một slot, không chỉ ở đầu các slot mới. Tính năng này hữu ích để nhận dữ liệu slot chi tiết hơn với độ trễ thấp.
  </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">
  Xác định bộ lọc cho các bản cập nhật dữ liệu tài khoản. Khóa bạn sử dụng (ví dụ: `tokenAccounts`) là **nhãn do người dùng xác định** cho cấu hình bộ lọc cụ thể này.

  <ParamField body="account" type="array">
    Khớp với bất kỳ khóa công khai nào trong mảng được cung cấp.
  </ParamField>

  <ParamField body="owner" type="array">
    Khóa công khai của chủ sở hữu tài khoản. Khớp với bất kỳ khóa công khai nào trong mảng được cung cấp.
  </ParamField>

  <ParamField body="filters" type="array">
    Tương tự các bộ lọc trong [getProgramAccounts](https://solana.com/docs/rpc/http/getprogramaccounts). Đây là một mảng các bộ lọc `datasize` và/hoặc `memcmp`. Với `memcmp`, giá trị so sánh được đặt trong một trong các trường `bytes`, `base58` hoặc `base64` trực tiếp trên đối tượng `memcmp`.
  </ParamField>

  <ParamField body="notifyOn" type="enum" deprecated>
    **Không dùng nữa — không có tác dụng kể từ Agave 4.2.** Việc đặt `notifyOn` không có tác dụng. Trường này sẽ bị xóa trong tương lai.
  </ParamField>

  Nếu tất cả trường đều trống, mọi tài khoản sẽ được phát. Nếu không:

  * Các trường hoạt động theo phép logic **AND**.
  * Các giá trị trong mảng hoạt động theo phép logic **OR** (ngoại trừ trong `filters`, nơi chúng hoạt động theo phép logic **AND**).

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

  Theo dõi hơn \~10.000 tài khoản? Thay vì dùng danh sách pubkey tường minh (32 byte cho mỗi tài khoản), hãy dùng [bộ lọc cuckoo](/docs/vi/laserstream/cuckoo-filters) nén (\~3–4 byte cho mỗi tài khoản) để đăng ký hàng trăm nghìn tài khoản trong một luồng duy nhất. Có trong SDK Rust và JavaScript.
</Accordion>

<Accordion title="Transaction">
  Xác định bộ lọc cho các bản cập nhật giao dịch. Khóa bạn sử dụng (ví dụ: `myTxSubscription`) là **nhãn do người dùng xác định** cho cấu hình bộ lọc cụ thể này.

  <ParamField body="vote" type="boolean">
    Bật hoặc tắt việc phát các giao dịch bỏ phiếu.
  </ParamField>

  <ParamField body="failed" type="boolean">
    Bật hoặc tắt việc phát các giao dịch thất bại.
  </ParamField>

  <ParamField body="signature" type="string">
    Chỉ phát các giao dịch khớp với chữ ký đã chỉ định.
  </ParamField>

  <ParamField body="accountInclude" type="array">
    Lọc các giao dịch liên quan đến bất kỳ tài khoản nào trong danh sách được cung cấp.
  </ParamField>

  <ParamField body="accountExclude" type="array">
    Loại trừ các giao dịch liên quan đến bất kỳ tài khoản nào trong danh sách được cung cấp (ngược với `accountInclude`).
  </ParamField>

  <ParamField body="accountRequired" type="array">
    Lọc các giao dịch liên quan đến tất cả tài khoản trong danh sách được cung cấp (phải sử dụng mọi tài khoản).
  </ParamField>

  <ParamField body="tokenAccounts" type="string">
    Phần mở rộng `tokenAccounts` (tài khoản token liên kết) tùy chọn. Khi được đặt, ví `accountInclude` cũng khớp với các giao dịch mà ví đó **sở hữu** số dư token SPL — ví dụ: giao dịch chuyển token đến tác động vào tài khoản token của ví thay vì pubkey của ví. Chấp nhận `"balanceChanged"` (khớp theo chênh lệch số dư), `"all"` (mọi tham chiếu, khối lượng cao hơn) hoặc `"none"` (không mở rộng, mặc định). SDK chuyển đổi chuỗi thành enum `TokenAccountExpansionControlFlag` ở cấp giao thức truyền dẫn (thuộc `yellowstone-grpc-proto` 12.5.0+). Xem [Lọc tài khoản token (ATA)](/docs/vi/laserstream/token-account-filtering) để biết chức năng và cách hoạt động.
  </ParamField>

  <ParamField body="matchMints" type="boolean">
    Cờ `matchMints` tùy chọn (mặc định là `false`). Khi là `true`, các danh sách `accountInclude`, `accountExclude` và `accountRequired` cũng được đối chiếu với các mint trong số dư token trước/sau giao dịch, thay vì chỉ với khóa tài khoản. Đặt một mint vào `accountInclude` để nhận mọi giao dịch tác động đến token đó, bao gồm cả các giao dịch chuyển SPL thông thường không bao giờ tham chiếu đến mint trong khóa tài khoản. Đây là tính năng tùy chọn và không ảnh hưởng đến các bộ lọc hiện có. Yêu cầu `helius-laserstream` 0.8.5+ (JS), 0.6.4+ (Rust) hoặc `go/v0.3.0`+ (Go). Xem [Lọc mint token](/docs/vi/laserstream/mint-filtering) để biết ngữ nghĩa và ví dụ.
  </ParamField>

  Nếu tất cả trường đều để trống, mọi giao dịch sẽ được phát. Nếu không:

  * Các trường hoạt động theo phép logic **AND**.
  * Các giá trị trong mảng được xử lý theo phép logic **OR** (ngoại trừ `accountRequired`, nơi tất cả giá trị đều phải khớp).

  ```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">
  Xác định bộ lọc cho các bản cập nhật khối. Khóa bạn sử dụng (ví dụ: `myBlockLabel`) là **nhãn do người dùng xác định** cho cấu hình bộ lọc cụ thể này.

  <ParamField body="accountInclude" type="array">
    Lọc các giao dịch và tài khoản liên quan đến bất kỳ tài khoản nào trong danh sách được cung cấp.
  </ParamField>

  <ParamField body="includeTransactions" type="boolean">
    Bao gồm tất cả giao dịch trong nội dung phát.
  </ParamField>

  <ParamField body="includeAccounts" type="boolean">
    Bao gồm tất cả bản cập nhật tài khoản trong nội dung phát.
  </ParamField>

  <ParamField body="includeEntries" type="boolean">
    Bao gồm tất cả mục nhập trong nội dung phát.
  </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">
  Hoạt động tương tự Blocks nhưng không bao gồm giao dịch, tài khoản và mục nhập. Khóa bạn sử dụng (ví dụ: `blockmetadata`) là **nhãn do người dùng xác định** cho đăng ký này. Hiện tại không có bộ lọc cho siêu dữ liệu khối — theo mặc định, mọi thông báo đều được phát.

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

<Accordion title="Entries">
  Đăng ký các mục nhập sổ cái. Khóa bạn sử dụng (ví dụ: `entrySubscribe`) là **nhãn do người dùng xác định** cho đăng ký này. Hiện tại không có bộ lọc cho mục nhập; tất cả mục nhập đều được phát.

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

<Divider />

## Ví dụ mã (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 />

## Tùy chọn SDK

Chúng tôi cung cấp SDK chính thức cho nhiều ngôn ngữ lập trình:

* **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)

Với các ngôn ngữ khác hoặc triển khai tùy chỉnh, bạn có thể dùng trực tiếp [các tệp proto Yellowstone gRPC](https://github.com/rpcpool/yellowstone-grpc/tree/v6.0.0%2Bsolana.2.2.12/yellowstone-grpc-proto/proto) để tạo ứng dụng khách gRPC cho ngôn ngữ mong muốn.

<Divider />

## Khắc phục sự cố / Câu hỏi thường gặp

<Accordion title="Q: I'm experiencing lag or slow performance with my LaserStream connection. What could be causing this?">
  **Trả lời:** Các vấn đề về hiệu năng của kết nối LaserStream thường do:

  * **Ứng dụng khách Javascript chậm**: Ứng dụng khách JavaScript có thể bị chậm khi xử lý quá nhiều thông báo hoặc sử dụng quá nhiều băng thông. Hãy cân nhắc thu hẹp bộ lọc đăng ký để giảm số lượng thông báo, chuyển sang [LaserStream JavaScript SDK](/docs/vi/laserstream/clients) hoặc thử dùng ngôn ngữ khác.

  * **Băng thông cục bộ hạn chế**: Các đăng ký có lưu lượng lớn có thể làm quá tải ứng dụng khách có băng thông mạng hạn chế. Theo dõi mức sử dụng mạng và cân nhắc nâng cấp kết nối hoặc thu hẹp phạm vi đăng ký.

  * **Khoảng cách địa lý**: Tuyến mạng dài làm tăng độ trễ và tỷ lệ mất gói. Hãy dùng [điểm cuối gần máy chủ nhất](#điểm-cuối-mainnet). Với kết nối có độ trễ cao, hãy tăng kích thước bộ đệm đọc mạng (có thể cải thiện băng thông hơn 5 lần):

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

    Để duy trì thiết lập sau khi khởi động lại, hãy thêm vào `/etc/sysctl.conf`:

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

    Tăng kích thước cửa sổ **luồng và kết nối** HTTP/2 lên 64MB để tránh nút thắt cổ chai do điều khiển luồng. Cần tăng cả hai — nếu chỉ tăng cửa sổ luồng, cửa sổ cấp kết nối vẫn là giới hạn ràng buộc:

    ```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?;
    ```

  * **Nút thắt xử lý phía ứng dụng khách**: Bảo đảm logic xử lý thông báo được tối ưu hóa và không chặn luồng chính trong thời gian dài.

  **Gỡ lỗi độ trễ ứng dụng khách**: Để hỗ trợ gỡ lỗi ứng dụng khách, chúng tôi đã xây dựng một công cụ kiểm tra băng thông tối đa từ nút của bạn đến máy chủ Laserstream gRPC. Để sử dụng, hãy chạy:

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

  Kết quả trả về dung lượng mạng tối đa giữa máy chủ của bạn và máy chủ Laserstream. Tối thiểu, bạn cần 10MB/giây để đăng ký toàn bộ dữ liệu giao dịch và 80MB/giây để đăng ký toàn bộ dữ liệu tài khoản. Để có hiệu năng tối ưu, chúng tôi khuyên dùng dung lượng ít nhất gấp 2 lần mức yêu cầu.
</Accordion>

<Accordion title="Q: I'm getting connection errors. What should I check?">
  **Trả lời:** Xác minh rằng khóa API và điểm cuối là chính xác, đồng thời mạng cho phép kết nối gRPC đi đến điểm cuối được chỉ định. Kiểm tra [trang trạng thái Helius](https://helius.statuspage.io/) để xem có sự cố nào đang diễn ra hay không.
</Accordion>

<Accordion title="Q: Why aren't my filters working as expected?">
  **Trả lời:** Kiểm tra lại các toán tử logic (AND/OR) được mô tả trong phần bộ lọc. Bảo đảm các khóa công khai là chính xác. Kiểm tra cấp độ cam kết được chỉ định trong yêu cầu.
</Accordion>

<Accordion title="Q: Can I subscribe to multiple types of data (e.g., accounts and transactions) in one request?">
  **Trả lời:** Có, bạn có thể xác định cấu hình bộ lọc dưới nhiều khóa (ví dụ: `accounts`, `transactions`) trong cùng một đối tượng `SubscribeRequest`.
</Accordion>

<Accordion title="Q: Does LaserStream support consumer groups?">
  **Trả lời:** Chúng tôi không triển khai nhóm người tiêu dùng. Thay vào đó, LaserStream cung cấp những kết quả mà các nhóm cần: tiếp tục, phát lại và độ tin cậy đa nút mà không cần lớp điều phối (cũng như độ trễ và chi phí phát sinh đi kèm). Chúng tôi cho rằng hầu hết khối lượng công việc không cần nhóm người tiêu dùng, vì chúng làm tăng độ trễ và chi phí vận hành. Ví dụ: một kết nối LaserStream gRPC duy nhất có thể phát ra lượng dữ liệu giao dịch + tài khoản gấp tối đa 10 lần Solana, trong khi hầu hết ứng dụng khách chỉ đăng ký một phần nhỏ đã lọc. Việc dùng nhóm người tiêu dùng trong trường hợp này làm lãng phí dư địa hiệu năng và tạo thêm một điểm lỗi.
</Accordion>

<Accordion title="Q: Why are my transaction log messages cut off?">
  **Trả lời:** Theo mặc định, LaserStream cắt ngắn thông báo nhật ký giao dịch ở mức 10 KB để cải thiện tốc độ và hiệu năng. Nếu cần nhật ký đầy đủ, hãy kết nối với một điểm cuối chuyên dụng không cắt ngắn — xem [Cắt ngắn nhật ký](/docs/vi/laserstream/log-truncation) để biết danh sách.
</Accordion>

<Accordion title="Q: Why am I only receiving Pong responses with no account or slot data?">
  **Trả lời:** Việc đưa trường `ping` vào `SubscribeRequest` ban đầu khiến LaserStream âm thầm bỏ qua mọi bộ lọc đăng ký — hệ thống chỉ trả về Pong mà không có dữ liệu tài khoản, giao dịch hoặc slot. Để khắc phục, hãy xóa `ping` khỏi yêu cầu đăng ký ban đầu, sau đó gửi ping riêng qua sink của luồng sau khi đăng ký được thiết lập. Cách này duy trì kết nối mà không ảnh hưởng đến bộ lọc.
</Accordion>
