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

> Установите SDK, выберите конечную точку и начните передавать свои первые транзакции Solana через LaserStream gRPC — конечные точки, справочник по запросам подписки и примеры.

## Обзор

LaserStream — это управляемый сервис потоковой передачи Solana по gRPC. Он совместим на уровне протокола с открытым протоколом Yellowstone gRPC, поэтому любой клиент Yellowstone работает без дополнительной настройки. Кроме того, сервис предоставляет функции для промышленной эксплуатации, такие как воспроизведение исторических данных, аварийное переключение между несколькими узлами и полностью управляемая среда.

LaserStream использует протокол gRPC с открытым исходным кодом, что исключает зависимость от поставщика и обеспечивает максимальную совместимость с существующими реализациями gRPC.

Вы можете подключиться с помощью стандартного клиента `@triton-one/yellowstone-grpc` или использовать оптимизированный для высокой производительности **[Helius LaserStream SDK](/docs/ru/laserstream/clients)**. Он обеспечивает более высокую пропускную способность, автоматическое переподключение, управление подписками, обработку ошибок и другие преимущества.

<Card title="LaserStream SDK is 40x Faster vs. JavaScript Yellowstone Clients" icon="bolt" href="https://www.helius.dev/blog/laserstream-sdks">
  Узнайте, как мы использовали ядро на Rust с NAPI-привязками без копирования, чтобы максимально повысить производительность JavaScript SDK
</Card>

<Warning>
  **Примечание о производительности**: если вы заметили задержки или проблемы с производительностью подключения LaserStream, ознакомьтесь с [разделом об устранении неполадок](#устранение-неполадок-и-часто-задаваемые-вопросы), где описаны распространённые причины и решения.
</Warning>

<Divider />

## Конечные точки и регионы

LaserStream доступен в нескольких регионах по всему миру.

Для оптимальной производительности выберите ближайшую к вашему приложению конечную точку:

### Конечные точки Mainnet

| Регион | Расположение | Конечная точка |
| - | - | - |
| **ewr** | Ньюарк, Нью-Джерси (рядом с Нью-Йорком) | `https://laserstream-mainnet-ewr.helius-rpc.com` |
| **pitt** | Питтсбург, США (центральная часть) | `https://laserstream-mainnet-pitt.helius-rpc.com` |
| **slc** | Солт-Лейк-Сити, США (западное побережье) | `https://laserstream-mainnet-slc.helius-rpc.com` |
| **lax** | Лос-Анджелес, США (западное побережье) | `https://laserstream-mainnet-lax.helius-rpc.com` |
| **lon** | Лондон, Европа | `https://laserstream-mainnet-lon.helius-rpc.com` |
| **ams** | Амстердам, Европа | `https://laserstream-mainnet-ams.helius-rpc.com` |
| **fra** | Франкфурт, Европа | `https://laserstream-mainnet-fra.helius-rpc.com` |
| **tyo** | Токио, Азия | `https://laserstream-mainnet-tyo.helius-rpc.com` |
| **sgp** | Сингапур, Азия | `https://laserstream-mainnet-sgp.helius-rpc.com` |

### Конечная точка Devnet

| Сеть | Расположение | Конечная точка |
| - | - | - |
| **Devnet** | Ньюарк, Нью-Джерси (рядом с Нью-Йорком) | `https://laserstream-devnet-ewr.helius-rpc.com` |

<Note>
  **Выбор сети и региона**:

  * Для **приложений в промышленной эксплуатации** выберите ближайшую к вашему серверу конечную точку Mainnet, чтобы получить максимальную производительность (например, при развёртывании в Европе используйте Амстердам (`ams`) или Франкфурт (`fra`))
  * Для **тестирования** используйте: `https://laserstream-devnet-ewr.helius-rpc.com`.
</Note>

### Сжатие `zstd`

Все конечные точки LaserStream gRPC поддерживают сжатие `zstd`. Сжатие необходимо включать явно: ответы остаются несжатыми, если ваш клиент не заявляет о поддержке `zstd`.

Включите `zstd` в 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` сокращает использование пропускной способности сети, но требует дополнительных ресурсов для сжатия. Прежде чем включать его для чувствительных к задержкам потоков, протестируйте производительность с вашей нагрузкой подписки.

### Усечение журналов

По умолчанию LaserStream усекает сообщения журналов транзакций до **10 КБ**, чтобы повысить скорость и производительность. Если вам нужны полные журналы, доступны выделенные конечные точки без усечения — см. раздел [Усечение журналов](/docs/ru/laserstream/log-truncation).

## Краткое руководство

<Tip>
  Начните работу с LaserStream через [панель управления Helius](https://dashboard.helius.dev/laserstream). Для Mainnet требуется тариф Business или Professional; Devnet доступна на тарифе Developer и выше. Подробности см. в разделе [Тарифы и цены](/docs/ru/billing/plans).
</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
    ```

    Мы используем `tsx`, поскольку стандартный `npx tsc --init` в TypeScript 5.x задаёт `verbatimModuleSyntax`, `module: "nodenext"` и `types: []`, из-за чего быстрый запуск `ts-node index.ts` завершается с ошибкой. `tsx` запускает файлы `.ts` без tsconfig.
  </Step>

  <Step title="Obtain Your API Key">
    Создайте ключ в [панели управления Helius](https://dashboard.helius.dev/).

    Этот ключ будет служить токеном аутентификации для LaserStream.

    <Note>
      **Требования к тарифу**: LaserStream Devnet доступна на всех [тарифах](/docs/ru/billing/plans). Для LaserStream Mainnet требуется тариф Business или Professional.
    </Note>
  </Step>

  <Step title="Create a Subscription Script">
    Создайте файл **`index.ts`** со следующим содержимым:

    ```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">
    В `index.ts` обновите объект `config`, указав:

    1. Фактический ключ API из [панели управления Helius](https://dashboard.helius.dev/)
    2. Ближайшую к расположению вашего сервера конечную точку LaserStream

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

    **Примеры выбора сети и региона:**

    * **Для промышленной эксплуатации (Mainnet)**:
      * Европа: используйте `fra` (Франкфурт), `ams` (Амстердам) или `lon` (Лондон)
      * Восток США: используйте `ewr` (Нью-Йорк)
      * Запад США: используйте `slc` (Солт-Лейк-Сити) или `lax` (Лос-Анджелес)
      * Азия: используйте `tyo` (Токио) или `sgp` (Сингапур)
    * **Для разработки (Devnet)**:
      * Используйте `https://laserstream-devnet-ewr.helius-rpc.com`
  </Step>

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

    Каждый раз, когда транзакция токена `confirmed` затрагивает `TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA`, данные появляются в консоли.
  </Step>
</Steps>

<Divider />

## Распространённые сценарии

Пошаговые руководства для наиболее распространённых сценариев. В каждом руководстве используется SDK [`helius-laserstream`](/docs/ru/laserstream/clients) со встроенным автоматическим переподключением и воспроизведением исторических данных.

<CardGroup cols={2}>
  <Card title="Account Subscriptions" icon="user" href="/docs/ru/laserstream/guides/account-subscription">
    Отслеживайте изменения баланса, данных и владельца определённых аккаунтов с помощью фильтров.
  </Card>

  <Card title="Transaction Monitoring" icon="receipt" href="/docs/ru/laserstream/guides/transaction-monitoring">
    Получайте поток транзакций, затрагивающих целевые аккаунты, и фильтруйте их по программе, голосованию или статусу ошибки.
  </Card>

  <Card title="Slot & Block Monitoring" icon="cube" href="/docs/ru/laserstream/guides/slot-and-block-monitoring">
    Отслеживайте консенсус сети, создание блоков и переходы между уровнями подтверждения.
  </Card>

  <Card title="Decoding Transaction Data" icon="binary" href="/docs/ru/laserstream/guides/decoding-transaction-data">
    Преобразуйте двоичные полезные данные `transactionUpdate` в читаемые транзакции Solana.
  </Card>

  <Card title="Stream Pump AMM Data" icon="chart-line" href="/docs/ru/laserstream/guides/stream-pump-amm-data">
    Практический пример: отслеживайте сделки Pump AMM с фильтрами, устойчивыми к переподключению.
  </Card>
</CardGroup>

<Tip>
  Если вы предпочитаете использовать протокол Yellowstone напрямую, клиент `@triton-one/yellowstone-grpc` работает с теми же конечными точками. Подробности на уровне протокола см. в [справочнике по Yellowstone gRPC](/docs/ru/grpc).
</Tip>

<Divider />

## Запрос подписки

В запрос подписки необходимо включить следующие общие параметры:

<Note>
  **Воспроизведение исторических данных:** при необходимости можно включить поле `fromSlot` (число `u64`) в основной объект `SubscribeRequest`, чтобы воспроизводить данные начиная с определённого слота. В настоящее время воспроизведение ограничено последними \~48 часами (\~691 200 слотов при текущей скорости сети). Обратите внимание, что [при воспроизведении данных старше \~20 минут возвращаются только финализированные данные](/docs/ru/laserstream/historical-replay#за-какой-период-можно-воспроизводить-данные).
</Note>

<ParamField body="commitment" type="enum">
  Задаёт уровень подтверждения: **processed**, **confirmed** или **finalized**.
</ParamField>

<ParamField body="accountsDataSlice" type="array">
  Массив объектов `{ offset: uint64, length: uint64 }`, позволяющий получать только необходимые фрагменты данных аккаунтов.
</ParamField>

<ParamField body="ping" type="boolean">
  Некоторые облачные провайдеры, например Cloudflare, могут закрывать неактивные потоки после периода бездействия. Чтобы предотвратить это и сохранять подключение активным без повторной отправки фильтров, задайте значение **true**. Сервер будет отвечать сообщением Pong каждые 15 секунд.
</ParamField>

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

Затем укажите фильтры для данных, на которые хотите подписаться, например аккаунтов, блоков, слотов или транзакций.

<Accordion title="Slots">
  Определите фильтры для обновлений слотов. Используемый ключ (например, `mySlotLabel`) — это **заданная пользователем метка** для данной конфигурации фильтра. При необходимости она позволяет определить несколько именованных конфигураций, хотя обычно достаточно одной.

  <ParamField body="filterByCommitment" type="boolean">
    По умолчанию слоты отправляются для всех уровней подтверждения. Этот фильтр позволяет получать данные только для выбранного уровня подтверждения.
  </ParamField>

  <ParamField body="interslotUpdates" type="boolean">
    Позволяет подписке получать обновления об изменениях внутри слота, а не только в начале новых слотов. Это полезно для получения более детальных данных слотов с низкой задержкой.
  </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">
  Определите фильтры для обновлений данных аккаунтов. Используемый ключ (например, `tokenAccounts`) — это **заданная пользователем метка** для данной конфигурации фильтра.

  <ParamField body="account" type="array">
    Соответствует любому открытому ключу из предоставленного массива.
  </ParamField>

  <ParamField body="owner" type="array">
    Открытый ключ владельца аккаунта. Соответствует любому открытому ключу из предоставленного массива.
  </ParamField>

  <ParamField body="filters" type="array">
    Аналогично фильтрам в [getProgramAccounts](https://solana.com/docs/rpc/http/getprogramaccounts). Это массив фильтров `datasize` и/или `memcmp`. Для `memcmp` сравниваемое значение указывается в одном из полей `bytes`, `base58` или `base64` непосредственно в объекте `memcmp`.
  </ParamField>

  <ParamField body="notifyOn" type="enum" deprecated>
    **Устарело — не выполняет никаких действий начиная с Agave 4.2.** Установка `notifyOn` ни на что не влияет. Поле будет удалено позднее.
  </ParamField>

  Если все поля пусты, передаются все аккаунты. В противном случае:

  * Поля объединяются логическим оператором **И**.
  * Значения внутри массивов объединяются логическим оператором **ИЛИ** (кроме значений внутри `filters`, которые объединяются логическим оператором **И**).

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

  Отслеживаете более \~10 000 аккаунтов? Вместо явного списка открытых ключей (32 байта на аккаунт) используйте сжатый [фильтр кукушки](/docs/ru/laserstream/cuckoo-filters) (\~3–4 байта на аккаунт), чтобы подписаться на сотни тысяч аккаунтов в одном потоке. Доступно в SDK для Rust и JavaScript.
</Accordion>

<Accordion title="Transaction">
  Определите фильтры для обновлений транзакций. Используемый ключ (например, `myTxSubscription`) — это **заданная пользователем метка** для данной конфигурации фильтра.

  <ParamField body="vote" type="boolean">
    Включает или отключает передачу транзакций голосования.
  </ParamField>

  <ParamField body="failed" type="boolean">
    Включает или отключает передачу неуспешных транзакций.
  </ParamField>

  <ParamField body="signature" type="string">
    Передаёт только транзакции, соответствующие указанной подписи.
  </ParamField>

  <ParamField body="accountInclude" type="array">
    Фильтрует транзакции, затрагивающие любой аккаунт из предоставленного списка.
  </ParamField>

  <ParamField body="accountExclude" type="array">
    Исключает транзакции, затрагивающие любой аккаунт из предоставленного списка (действует противоположно `accountInclude`).
  </ParamField>

  <ParamField body="accountRequired" type="array">
    Фильтрует транзакции, затрагивающие все аккаунты из предоставленного списка (должны использоваться все аккаунты).
  </ParamField>

  <ParamField body="tokenAccounts" type="string">
    Необязательное расширение `tokenAccounts` (связанный токен-аккаунт). Если оно задано, кошелёк `accountInclude` также соответствует транзакциям, в которых он **владеет** балансом токенов SPL. Например, это входящие переводы токенов, затрагивающие токен-аккаунт кошелька, а не его открытый ключ. Допустимые значения: `"balanceChanged"` (соответствие по изменению баланса), `"all"` (любая ссылка, больший объём) или `"none"` (без расширения, значение по умолчанию). SDK преобразует строку в перечисление `TokenAccountExpansionControlFlag` уровня протокола (входит в `yellowstone-grpc-proto` 12.5.0+). Описание принципа и механизма работы см. в разделе [Фильтрация токен-аккаунтов (ATA)](/docs/ru/laserstream/token-account-filtering).
  </ParamField>

  <ParamField body="matchMints" type="boolean">
    Необязательный флаг `matchMints` (по умолчанию `false`). Если задано значение `true`, списки `accountInclude`, `accountExclude` и `accountRequired` также сопоставляются с адресами выпуска токенов в балансах токенов до и после транзакции, а не только с ключами её аккаунтов. Добавьте адрес выпуска в `accountInclude`, чтобы получать каждую транзакцию, затрагивающую этот токен, включая обычные переводы SPL, в ключах аккаунтов которых адрес выпуска не указывается. Функция включается явно и не влияет на существующие фильтры. Требуется `helius-laserstream` 0.8.5+ (JS), 0.6.4+ (Rust) или `go/v0.3.0`+ (Go). Семантику и примеры см. в разделе [Фильтрация по адресу выпуска токена](/docs/ru/laserstream/mint-filtering).
  </ParamField>

  Если все поля оставлены пустыми, передаются все транзакции. В противном случае:

  * Поля объединяются логическим оператором **И**.
  * Значения внутри массивов объединяются логическим оператором **ИЛИ** (кроме `accountRequired`, где должны совпадать все значения).

  ```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">
  Определите фильтры для обновлений блоков. Используемый ключ (например, `myBlockLabel`) — это **заданная пользователем метка** для данной конфигурации фильтра.

  <ParamField body="accountInclude" type="array">
    Фильтрует транзакции и аккаунты, затрагивающие любой аккаунт из предоставленного списка.
  </ParamField>

  <ParamField body="includeTransactions" type="boolean">
    Включает в передачу все транзакции.
  </ParamField>

  <ParamField body="includeAccounts" type="boolean">
    Включает в передачу все обновления аккаунтов.
  </ParamField>

  <ParamField body="includeEntries" type="boolean">
    Включает в передачу все записи.
  </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">
  Работает аналогично блокам, но исключает транзакции, аккаунты и записи. Используемый ключ (например, `blockmetadata`) — это **заданная пользователем метка** для данной подписки. В настоящее время фильтры метаданных блоков недоступны: по умолчанию передаются все сообщения.

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

<Accordion title="Entries">
  Подпишитесь на записи реестра. Используемый ключ (например, `entrySubscribe`) — это **заданная пользователем метка** для данной подписки. В настоящее время фильтры для записей недоступны; передаются все записи.

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

<Divider />

## Примеры кода (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 />

## Варианты SDK

Мы предоставляем официальные SDK для нескольких языков программирования:

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

Для других языков или собственных реализаций можно напрямую использовать [proto-файлы Yellowstone gRPC](https://github.com/rpcpool/yellowstone-grpc/tree/v6.0.0%2Bsolana.2.2.12/yellowstone-grpc-proto/proto), чтобы создать клиенты gRPC для предпочитаемого языка.

<Divider />

## Устранение неполадок и часто задаваемые вопросы

<Accordion title="Q: I'm experiencing lag or slow performance with my LaserStream connection. What could be causing this?">
  **О:** Проблемы с производительностью подключений LaserStream обычно вызваны следующими причинами:

  * **Низкая скорость клиента JavaScript**: клиент JavaScript может отставать при обработке слишком большого количества сообщений или использовании чрезмерной пропускной способности. Попробуйте сузить фильтры подписок, чтобы сократить объём сообщений, перейти на [LaserStream JavaScript SDK](/docs/ru/laserstream/clients) или использовать другой язык.

  * **Ограниченная локальная пропускная способность**: интенсивные подписки могут перегружать клиентов с ограниченной пропускной способностью сети. Отслеживайте использование сети и рассмотрите возможность улучшить подключение или сузить область подписки.

  * **Географическая удалённость**: длинные сетевые маршруты увеличивают задержку и потерю пакетов. Используйте [ближайшую к вашему серверу конечную точку](#конечные-точки-mainnet). Для подключений с высокой задержкой увеличьте размеры буферов чтения сети — это может повысить пропускную способность в 5 и более раз:

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

    Чтобы сохранить настройки после перезагрузки, добавьте в `/etc/sysctl.conf`:

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

    Увеличьте размеры окон **потока и подключения** HTTP/2 до 64 МБ, чтобы избежать узких мест при управлении потоком. Необходимо изменить оба значения: если увеличить только окно потока, ограничивающим фактором останется окно на уровне подключения:

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

  * **Узкие места при обработке на стороне клиента**: убедитесь, что логика обработки сообщений оптимизирована и не блокирует основной поток на длительное время.

  **Диагностика отставания клиента**: чтобы помочь вам диагностировать клиент, мы создали инструмент для проверки максимальной пропускной способности между вашим узлом и сервером LaserStream gRPC. Для его использования выполните:

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

  Результат показывает максимальную пропускную способность сети между вашим сервером и сервером LaserStream. Для подписки на все данные транзакций требуется не менее 10 МБ/с, а для подписки на все данные аккаунтов — 80 МБ/с. Для оптимальной производительности рекомендуется иметь как минимум двукратный запас относительно требуемой пропускной способности.
</Accordion>

<Accordion title="Q: I'm getting connection errors. What should I check?">
  **О:** Убедитесь, что ключ API и конечная точка указаны правильно, а ваша сеть разрешает исходящие подключения gRPC к указанной конечной точке. Проверьте [страницу состояния Helius](https://helius.statuspage.io/) на наличие текущих инцидентов.
</Accordion>

<Accordion title="Q: Why aren't my filters working as expected?">
  **О:** Ещё раз проверьте логические операторы (И/ИЛИ), описанные в разделах о фильтрах. Убедитесь, что открытые ключи указаны правильно. Проверьте уровень подтверждения, указанный в запросе.
</Accordion>

<Accordion title="Q: Can I subscribe to multiple types of data (e.g., accounts and transactions) in one request?">
  **О:** Да, в одном объекте `SubscribeRequest` можно определить конфигурации фильтров под несколькими ключами (например, `accounts` и `transactions`).
</Accordion>

<Accordion title="Q: Does LaserStream support consumer groups?">
  **О:** Мы не реализуем группы потребителей. Вместо этого LaserStream предоставляет необходимые командам возможности: возобновление, воспроизведение и надёжность нескольких узлов без координационного слоя и связанных с ним задержек и накладных расходов. Мы считаем, что для большинства нагрузок группы потребителей не нужны, а их использование увеличивает задержку и эксплуатационные расходы. Например, одно подключение LaserStream gRPC может передавать объём данных о транзакциях и аккаунтах, который до 10 раз превышает соответствующий объём Solana, при этом большинство клиентов подписываются лишь на небольшой отфильтрованный фрагмент. Использование групп потребителей в таком случае расходует запас производительности и создаёт ещё одну точку отказа.
</Accordion>

<Accordion title="Q: Why are my transaction log messages cut off?">
  **О:** По умолчанию LaserStream усекает сообщения журналов транзакций до 10 КБ, чтобы повысить скорость и производительность. Если вам нужны полные журналы, подключитесь к выделенной конечной точке без усечения. Их список приведён в разделе [Усечение журналов](/docs/ru/laserstream/log-truncation).
</Accordion>

<Accordion title="Q: Why am I only receiving Pong responses with no account or slot data?">
  **О:** Если включить поле `ping` в исходный объект `SubscribeRequest`, LaserStream без уведомления проигнорирует все фильтры подписки. В результате будет возвращаться только Pong без данных аккаунтов, транзакций или слотов. Чтобы исправить это, удалите `ping` из исходного запроса подписки, а после установления подписки отправляйте запросы ping отдельно через приёмник потока. Это сохранит подключение активным, не мешая работе фильтров.
</Accordion>


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