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

# LaserStream gRPC Quickstart

> Install the SDK, pick an endpoint, and stream your first Solana transactions over LaserStream gRPC — endpoints, subscribe-request reference, and examples.

## Overview

LaserStream is a managed Solana gRPC streaming service. It is wire-compatible with the open Yellowstone gRPC protocol — so any Yellowstone client works out of the box — and adds production features like historical replay, multi-node failover, and a fully managed environment.

LaserStream uses the open source gRPC protocol, ensuring no vendor lock-in and maximum compatibility with existing gRPC implementations.

You can connect either with the standard `@triton-one/yellowstone-grpc` client or use the performance-optimized **[Helius LaserStream SDK](https://www.helius.dev/docs/laserstream/clients.md)** for added benefits including higher throughput, automatic reconnects, subscription management, error handling, and more.

> [card] [LaserStream SDK is 40x Faster vs. JavaScript Yellowstone Clients](https://www.helius.dev/blog/laserstream-sdks)
>
> Learn how we used Rust Core with zero-copy NAPI bindings to maximize JavaScript SDK performance

> [!WARNING]
>
> **Performance Notice**: If you experience any lag or performance issues with your LaserStream connection, please refer to the [Troubleshooting section](#troubleshooting--faq) for common causes and solutions.

## Endpoints & Regions

LaserStream is available in multiple regions worldwide.

Choose the endpoint closest to your application for optimal performance:

### Mainnet Endpoints

| Region | Location | Endpoint |
| - | - | - |
| **ewr** | Newark, NJ (near New York) | `https://laserstream-mainnet-ewr.helius-rpc.com` |
| **pitt** | Pittsburgh, US (Central) | `https://laserstream-mainnet-pitt.helius-rpc.com` |
| **slc** | Salt Lake City, US (West Coast) | `https://laserstream-mainnet-slc.helius-rpc.com` |
| **lax** | Los Angeles, US (West Coast) | `https://laserstream-mainnet-lax.helius-rpc.com` |
| **lon** | London, Europe | `https://laserstream-mainnet-lon.helius-rpc.com` |
| **ams** | Amsterdam, Europe | `https://laserstream-mainnet-ams.helius-rpc.com` |
| **fra** | Frankfurt, Europe | `https://laserstream-mainnet-fra.helius-rpc.com` |
| **tyo** | Tokyo, Asia | `https://laserstream-mainnet-tyo.helius-rpc.com` |
| **sgp** | Singapore, Asia | `https://laserstream-mainnet-sgp.helius-rpc.com` |

### Devnet Endpoint

| Network | Location | Endpoint |
| - | - | - |
| **Devnet** | Newark, NJ (near New York) | `https://laserstream-devnet-ewr.helius-rpc.com` |

> [!NOTE]
>
> **Network & Region Selection**:
>
> * For **production apps**, pick the mainnet endpoint nearest your server for best performance (e.g., if deploying in Europe, use Amsterdam (`ams`) or Frankfurt (`fra`))
> * For **testing**, use: `https://laserstream-devnet-ewr.helius-rpc.com`.

### `zstd` Compression

All LaserStream gRPC endpoints support `zstd` compression. Compression is opt-in: responses remain uncompressed unless your client advertises `zstd` support.

Enable `zstd` in the 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` reduces network bandwidth but adds compression work. Benchmark it with your subscription workload before enabling it for latency-sensitive streams.

### Log Truncation

By default, LaserStream truncates transaction log messages to **10 KB** for better speed and performance. If you need full logs, dedicated untruncated endpoints are available — see [Log Truncation](https://www.helius.dev/docs/laserstream/log-truncation.md).

## Quickstart

> [!TIP]
>
> Get started with LaserStream from your [Helius Dashboard](https://dashboard.helius.dev/laserstream). Mainnet requires a Business or Professional plan; Devnet is available on Developer and above. See [Plans & Pricing](https://www.helius.dev/docs/billing/plans.md) for details.

**1. Create a New Project**

```bash theme={"system"}
mkdir laserstream-grpc-demo
cd laserstream-grpc-demo
npm init -y
```

**2. Install Dependencies**

```bash theme={"system"}
npm install helius-laserstream
npm install --save-dev typescript tsx @types/node
```

We use `tsx` because the default `npx tsc --init` on TypeScript 5.x sets `verbatimModuleSyntax`, `module: "nodenext"`, and `types: []`, which all break a quick `ts-node index.ts` run. `tsx` runs `.ts` files without a tsconfig.

**3. Obtain Your API Key**

Generate a key from the [Helius Dashboard](https://dashboard.helius.dev/).

This key will serve as your authentication token for LaserStream.

> [!NOTE]
>
> **Plan Requirements**: LaserStream devnet is available on all [plans](https://www.helius.dev/docs/billing/plans.md). LaserStream mainnet requires a Business or Professional plan.

**4. Create a Subscription Script**

Create **`index.ts`** with the following:

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

**5. Replace Your API Key and Choose Your Region**

In `index.ts`, update the `config` object with:

1. Your actual API key from the [Helius Dashboard](https://dashboard.helius.dev/)
2. The LaserStream endpoint closest to your server location

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

**Network & Region Selection Examples:**

* **For Production (Mainnet)**:
  * Europe: Use `fra` (Frankfurt), `ams` (Amsterdam), or `lon` (London)
  * US East: Use `ewr` (New York)
  * US West: Use `slc` (Salt Lake City) or `lax` (Los Angeles)
  * Asia: Use `tyo` (Tokyo) or `sgp` (Singapore)
* **For Development (Devnet)**:
  * Use `https://laserstream-devnet-ewr.helius-rpc.com`

**6. Run and View Results**

```bash theme={"system"}
npx tsx index.ts
```

Whenever a `confirmed` token transaction involves `TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA`, you'll see the data in your console.

## Common Workflows

Step-by-step guides for the workflows we see most often. Each guide uses the [`helius-laserstream`](https://www.helius.dev/docs/laserstream/clients) SDK with auto-reconnect and historical replay built in.

> [card] [Account Subscriptions](https://www.helius.dev/docs/laserstream/guides/account-subscription.md)
>
> Monitor balance, data, and ownership changes on specific accounts with filters.

> [card] [Transaction Monitoring](https://www.helius.dev/docs/laserstream/guides/transaction-monitoring.md)
>
> Stream transactions involving target accounts, filter by program, vote, or failure status.

> [card] [Slot & Block Monitoring](https://www.helius.dev/docs/laserstream/guides/slot-and-block-monitoring.md)
>
> Track network consensus, block production, and commitment-level transitions.

> [card] [Decoding Transaction Data](https://www.helius.dev/docs/laserstream/guides/decoding-transaction-data.md)
>
> Parse the binary `transactionUpdate` payloads into readable Solana transactions.

> [card] [Stream Pump AMM Data](https://www.helius.dev/docs/laserstream/guides/stream-pump-amm-data.md)
>
> Real-world example: monitor Pump AMM trades with reconnect-safe filters.

> [!TIP]
>
> The `@triton-one/yellowstone-grpc` client works against the same endpoints if you prefer the raw Yellowstone protocol. See the [Yellowstone gRPC reference](https://www.helius.dev/docs/grpc) for protocol-level details.

## Subscribe Request

In the subscribe request, you need to include the following general parameters:

> [!NOTE]
>
> **Historical Replay:** You can optionally include a `fromSlot` field (a `u64` number) in the main `SubscribeRequest` object to replay data from a specific slot onwards. Replay is currently limited to the last \~48 hours (\~691,200 slots at current network speed); note that [replays older than \~20 minutes return finalized-only data](https://www.helius.dev/docs/laserstream/historical-replay.md#how-far-back-you-can-replay).

**commitment** `enum`

Specifies the commitment level, which can be **processed**, **confirmed**, or **finalized**.

**accountsDataSlice** `array`

An array of objects `{ offset: uint64, length: uint64 }` that allows you to receive only the required data slices from accounts.

**ping** `boolean`

Some cloud providers (like Cloudflare) may close idle streams after a period of inactivity. To prevent this and keep the connection alive without needing to resend filters, set this to **true**. The server will respond with a Pong message every 15 seconds.

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

Next, you'll need to specify the filters for the data you want to subscribe to, such as accounts, blocks, slots, or transactions.

> [accordion] Slots
>
> Define filters for slot updates. The key you use (e.g., `mySlotLabel`) is a **user-defined label** for this specific filter configuration, allowing you to potentially define multiple named configurations if needed (though typically one is sufficient).
>
> **filterByCommitment** `boolean`
>
> By default, slots are sent for all commitment levels. With this filter, you can choose to receive only the selected commitment level.
>
> **interslotUpdates** `boolean`
>
> Enables the subscription to receive updates for changes within a slot, not just at the beginning of new slots. This is useful for more granular, low-latency slot data.
>
> ```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] Accounts
>
> Define filters for account data updates. The key you use (e.g., `tokenAccounts`) is a **user-defined label** for this specific filter configuration.
>
> **account** `array`
>
> Matches any public key from the provided array.
>
> **owner** `array`
>
> The account owner's public key. Matches any public key from the provided array.
>
> **filters** `array`
>
> Similar to the filters in [getProgramAccounts](https://solana.com/docs/rpc/http/getprogramaccounts). This is an array of `datasize` and/or `memcmp` filters. For `memcmp`, the comparand goes on one of `bytes`, `base58`, or `base64` directly on the `memcmp` object.
>
> **notifyOn** `enum` *deprecated*
>
> **Deprecated — no-op as of Agave 4.2.** Setting `notifyOn` has no effect. The field will be removed at a later date.
>
> If all fields are empty, all accounts are broadcasted. Otherwise:
>
> * Fields operate as a logical **AND**.
> * Values within arrays act as a logical **OR** (except within `filters`, which operate as a logical **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"
>         }
>       }
>     ]
>   }
> },
> ```
>
> Tracking more than \~10,000 accounts? Instead of an explicit pubkey list (32 bytes per account), use a compressed [cuckoo filter](https://www.helius.dev/docs/laserstream/cuckoo-filters.md) (\~3–4 bytes per account) to subscribe to hundreds of thousands of accounts in a single stream. Available in the Rust and JavaScript SDKs.

> [accordion] Transaction
>
> Define filters for transaction updates. The key you use (e.g., `myTxSubscription`) is a **user-defined label** for this specific filter configuration.
>
> **vote** `boolean`
>
> Enable or disable the broadcast of vote transactions.
>
> **failed** `boolean`
>
> Enable or disable the broadcast of failed transactions.
>
> **signature** `string`
>
> Broadcast only transactions matching the specified signature.
>
> **accountInclude** `array`
>
> Filter transactions that involve any account from the provided list.
>
> **accountExclude** `array`
>
> Exclude transactions that involve any account from the provided list (opposite of `accountInclude`).
>
> **accountRequired** `array`
>
> Filter transactions that involve all accounts from the provided list (all accounts must be used).
>
> **tokenAccounts** `string`
>
> Optional `tokenAccounts` (associated token account) expansion. When set, an `accountInclude` wallet also matches transactions where it **owns** an SPL token balance — e.g. incoming token transfers that touch the wallet's token account rather than its pubkey. Accepts `"balanceChanged"` (balance-delta matches), `"all"` (any reference, higher volume), or `"none"` (no expansion, the default). The SDK converts the string to the wire-level `TokenAccountExpansionControlFlag` enum (part of `yellowstone-grpc-proto` 12.5.0+). See [Token Account (ATA) Filtering](https://www.helius.dev/docs/laserstream/token-account-filtering.md) for what it does and how it works.
>
> **matchMints** `boolean`
>
> Optional `matchMints` flag (default `false`). When `true`, the `accountInclude`, `accountExclude`, and `accountRequired` lists are also matched against the mints in the transaction's pre/post token balances, not just its account keys. Put a mint in `accountInclude` to receive every transaction that touches that token, including plain SPL transfers that never reference the mint in their account keys. Opt-in with no effect on existing filters. Requires `helius-laserstream` 0.8.5+ (JS), 0.6.4+ (Rust), or `go/v0.3.0`+ (Go). See [Token Mint Filtering](https://www.helius.dev/docs/laserstream/mint-filtering.md) for semantics and examples.
>
> If all fields are left empty, all transactions are broadcasted. Otherwise:
>
> * Fields operate as a logical **AND**.
> * Values within arrays are treated as a logical **OR** (except for `accountRequired`, where all must match).
>
> ```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] Block
>
> Define filters for block updates. The key you use (e.g., `myBlockLabel`) is a **user-defined label** for this specific filter configuration.
>
> **accountInclude** `array`
>
> Filters transactions and accounts that involve any account from the provided list.
>
> **includeTransactions** `boolean`
>
> Includes all transactions in the broadcast.
>
> **includeAccounts** `boolean`
>
> Includes all account updates in the broadcast.
>
> **includeEntries** `boolean`
>
> Includes all entries in the broadcast.
>
> ```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] Blocks Meta
>
> This functions similarly to Blocks but excludes transactions, accounts, and entries. The key you use (e.g., `blockmetadata`) is a **user-defined label** for this subscription. Currently, no filters are available for block metadata—all messages are broadcasted by default.
>
> ```typescript theme={"system"}
> blocksMeta: {
>   blockmetadata: {}
> },
> ```

> [accordion] Entries
>
> Subscribe to ledger entries. The key you use (e.g., `entrySubscribe`) is a **user-defined label** for this subscription. Currently, there are no filters available for entries; all entries are broadcasted.
>
> ```typescript theme={"system"}
> entry: {
>   entrySubscribe: {}
> },
> ```

## Code Examples (LaserStream SDK)

> [tab] 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] 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] 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] 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] 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] 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] 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);
> ```

## SDK Options

We provide official SDKs for multiple programming languages:

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

For other languages or custom implementations, you can use the [Yellowstone gRPC proto files](https://github.com/rpcpool/yellowstone-grpc/tree/v6.0.0%2Bsolana.2.2.12/yellowstone-grpc-proto/proto) directly to generate gRPC clients for your preferred language.

## Troubleshooting / FAQ

> [accordion] Q: I'm experiencing lag or slow performance with my LaserStream connection. What could be causing this?
>
> **A:** Performance issues with LaserStream connections are typically caused by:
>
> * **Javascript Client Slowness**: The JavaScript client may lag behind when processing too many messages or consuming too much bandwidth. Consider filtering your subscriptions more narrowly to reduce message volume, switch to the [LaserStream JavaScript SDK](https://www.helius.dev/docs/laserstream/clients.md), or try using another language.
>
> * **Limited local bandwidth**: Heavy subscriptions can overwhelm clients with limited network bandwidth. Monitor your network usage and consider upgrading your connection or reducing subscription scope.
>
> * **Geographic distance**: Long network routes increase latency and packet loss. Use the [endpoint closest to your server](#mainnet-endpoints). For high-latency connections, increase your network read buffer sizes (can improve bandwidth by 5x+):
>   ```bash theme={"system"}
>   sudo sysctl -w net.core.rmem_max=67108864 net.ipv4.tcp_rmem="4096 87380 67108864"
>   ```
>   To persist across reboots, add to `/etc/sysctl.conf`:
>   ```bash theme={"system"}
>   net.core.rmem_max=67108864
>   net.ipv4.tcp_rmem=4096 87380 67108864
>   ```
>   Increase the HTTP/2 stream **and connection** window sizes to 64MB to prevent flow control bottlenecks. Both are required — raising only the stream window leaves the connection-level window as the binding constraint:
>   ```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?;
>   ```
>
> * **Client-side processing bottlenecks**: Ensure your message processing logic is optimized and doesn't block the main thread for extended periods.
>
> **Debugging Client Lag**: To help you debug client, we built a tool to test for the max bandwidth from your node to a Laserstream gRPC server. To use it run:
>
> ```
> cargo install helius-laserstream-bandwidth
> helius-laserstream-bandwidth --laserstream-url $LASERSTREAM_URL --api-key $API_KEY
> ```
>
> The output returns the max network capacity between your server and the Laserstream server. At a minimum, you need 10MB/s to subscribe to all transaction data and 80MB/s to subscribe to all account data. We recommend having at least 2x the required capacity for optimal performance.

> [accordion] Q: I'm getting connection errors. What should I check?
>
> **A:** Verify your API key and endpoint are correct and that your network allows outbound gRPC connections to the specified endpoint. Check the [Helius status page](https://helius.statuspage.io/) for any ongoing incidents.

> [accordion] Q: Why aren't my filters working as expected?
>
> **A:** Double-check the logical operators (AND/OR) described in the filter sections. Ensure public keys are correct. Review the commitment level specified in your request.

> [accordion] Q: Can I subscribe to multiple types of data (e.g., accounts and transactions) in one request?
>
> **A:** Yes, you can define filter configurations under multiple keys (e.g., `accounts`, `transactions`) within the same `SubscribeRequest` object.

> [accordion] Q: Does LaserStream support consumer groups?
>
> **A:** We don't implement consumer groups. Instead, LaserStream delivers the same outcomes teams want: resume, replay, and multi-node reliability without a coordination layer (and the latency/overhead that comes with it). We believe consumer groups are not needed for most workloads and they add latency and operational overhead. As an example a single LaserStream gRPC connection can emit up to 10× Solana's transaction + account data, and most clients subscribe to a small, filtered slice. Using consumer groups in this case burns performance headroom and introduces another point of failure.

> [accordion] Q: Why are my transaction log messages cut off?
>
> **A:** LaserStream truncates transaction log messages to 10 KB by default for better speed and performance. If you need full logs, connect to a dedicated untruncated endpoint — see [Log Truncation](https://www.helius.dev/docs/laserstream/log-truncation.md) for the list.

> [accordion] Q: Why am I only receiving Pong responses with no account or slot data?
>
> **A:** Including a `ping` field in your initial `SubscribeRequest` causes LaserStream to silently ignore all subscription filters — only a Pong is returned with zero account, transaction, or slot data. To fix this, remove `ping` from the initial subscribe request and instead send pings separately via the stream's sink after the subscription is established. This keeps the connection alive without interfering with your filters.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.