> ## 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: восполнение пропущенных данных

> Восстанавливайтесь после разрывов соединения и восполняйте пропущенные данные блокчейна Solana с помощью функции исторического воспроизведения LaserStream. Больше не пропускайте ни одной транзакции.

<Info>
  **Не пропускайте ничего важного**: историческое воспроизведение LaserStream позволяет восстановиться после разрывов соединения и восполнить пропущенные данные за последние 48 часов активности блокчейна.
</Info>

## Что такое историческое воспроизведение?

Историческое воспроизведение — это функция LaserStream, которая позволяет повторно получать недавние данные блокчейна, задав начальную точку `fromSlot`. Это полезно для обработки разрывов соединения и обеспечения непрерывности данных в приложениях реального времени.

## За какой период можно воспроизводить данные

Вы можете воспроизводить данные за период до \~48 часов (\~691 200 слотов при текущей длительности слота Solana \~250 мс; точное количество слотов меняется вместе с длительностью слота в сети) независимо от уровня подтверждения подписки. Передайте `fromSlot` в пределах этого окна, и LaserStream будет передавать поток данных от указанной точки до настоящего времени.

**Для более старых периодов возвращаются финализированные данные.** LaserStream хранит в памяти слоты примерно за последние \~20 минут. Более старые данные поступают из исторического хранилища, содержащего только финализированные блоки. Поэтому при воспроизведении с `fromSlot` старше \~20 минут данные отражают финализированную цепочку: в этом диапазоне вы не увидите слоты из ответвлений, отброшенные слоты или обновления аккаунтов внутри слота даже при подписке `processed` или `confirmed`. Слоты за последние \~20 минут сохраняют фактическую семантику уровня подтверждения, включая ответвления и обновления аккаунтов внутри слота.

<Warning>
  **Ограниченное временное окно**: историческое воспроизведение охватывает только последние \~48 часов. Нельзя воспроизводить данные с произвольных моментов в прошлом.
</Warning>

<CardGroup cols={2}>
  <Card title="Handle Disconnections" icon="clock-rotate-left">
    Восстанавливайте данные, потерянные во время кратковременных разрывов соединения (до 48 часов)
  </Card>

  <Card title="Bootstrap Applications" icon="rocket">
    Запускайте приложения с недавним контекстом за последние 48 часов
  </Card>

  <Card title="Analyze Recent Events" icon="magnifying-glass">
    Просматривайте недавние транзакции и изменения аккаунтов
  </Card>

  <Card title="Test with Recent Data" icon="flask">
    Используйте реальные недавние данные для тестирования и разработки
  </Card>
</CardGroup>

## Проверка доступности воспроизведения

Вызовите [SubscribeReplayInfo](/docs/ru/api-reference/laserstream/grpc/subscribereplayinfo), чтобы проверить самый ранний слот, доступный для воспроизведения.

Если сохраненный слот находится за пределами окна воспроизведения, приложение может отдельно восстановить пропущенную историю или продолжить работу с более нового слота. Создайте новую подписку с выбранным `fromSlot`. Доступность может измениться между запросами.

## Как это работает

<Steps>
  <Step title="Specify Starting Point">
    Используйте параметр `fromSlot`, чтобы задать начальную точку воспроизведения (она должна находиться в пределах последних \~48 часов — \~691 200 слотов при текущей скорости сети)
  </Step>

  <Step title="Stream Historical Data">
    LaserStream передает все события, начиная с указанного вами слота
  </Step>

  <Step title="Catch Up to Real-Time">
    Поток исторических данных продолжается, пока не достигнет текущего слота
  </Step>

  <Step title="Continue Live Streaming">
    После этого поток незаметно переключается на передачу данных в реальном времени
  </Step>
</Steps>

<Note>
  **Автоматическое переподключение**: [SDK LaserStream](https://github.com/helius-labs/laserstream-sdk) автоматически обрабатывает переподключение и воспроизведение. Дополнительный код не требуется!
</Note>

При воспроизведении учитывается флаг фильтра транзакций `matchMints`, поэтому воспроизведение [с фильтрацией по mint](/docs/ru/laserstream/mint-filtering) возвращает тот же набор транзакций, который был бы передан потоком данных в реальном времени.

## Быстрый старт

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

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

    // Pick a slot within the last ~48 h (~691,200 slots at current ~250ms slot time). For a real start
    // value, call `getSlot` first and subtract however far back you want to replay.
    // Note: replays older than ~20 min return finalized data even at processed/confirmed;
    // slots within the last ~20 min carry true commitment semantics.
    const fromSlot = 419_800_000;

    const subscriptionRequest: SubscribeRequest = {
      transactions: {
        "token-filter": { // user-defined label for this filter
          accountInclude: ['TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA'],
          vote: false,
          failed: false
        }
      },
      commitment: CommitmentLevel.CONFIRMED,
      accounts: {},
      slots: {},
      blocks: {},
      blocksMeta: {},
      entry: {},
      accountsDataSlice: [],
      fromSlot, // u64 slot number; must fall inside the replay window
    };

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

    await subscribe(config, subscriptionRequest, 
      async (data) => {
        console.log('Received data:', data);
      }, 
      async (error) => {
        console.error('Error:', error);
      }
    );
    ```
  </Tab>
</Tabs>

## Параметры конфигурации

<ParamField path="fromSlot" type="number" required>
  Номер слота, с которого нужно начать воспроизведение, в виде `u64`. Он должен находиться в пределах окна воспроизведения (последние \~48 часов от текущего слота — \~691 200 слотов при текущей скорости сети) при любом уровне подтверждения.

  **Пример**: `currentSlot - 1000`

  **Важно**: если передать слот старше доступного окна, LaserStream отклонит запрос с ошибкой `Operation was attempted past the valid range`.
</ParamField>

## Сценарии использования

<AccordionGroup>
  <Accordion title="Reconnection After Brief Disconnection">
    Когда приложение повторно подключается после кратковременного разрыва соединения (менее 48 часов), используйте историческое воспроизведение, чтобы не пропустить данные. `getCurrentSlot` вызывает Helius RPC; `lastProcessedSlot` ниже хранится в памяти — сохраняйте его удобным для приложения способом (Redis, Postgres, в файле и т. д.).

    ```typescript theme={"system"}
    async function getCurrentSlot(): Promise<number> {
      const r = await fetch(`https://mainnet.helius-rpc.com/?api-key=${process.env.HELIUS_API_KEY}`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ jsonrpc: '2.0', id: 1, method: 'getSlot', params: [{ commitment: 'confirmed' }] }),
      });
      const { result } = await r.json();
      return result as number;
    }

    // Load the last slot you processed from wherever you store it.
    let lastProcessedSlot = Number(process.env.LAST_PROCESSED_SLOT ?? 0);

    // Check if it's still within the replay window
    // (~691,200 slots at current ~250ms slot time; recompute if network slot time changes)
    const currentSlot = await getCurrentSlot();
    const maxReplaySlot = currentSlot - 691_200;

    if (lastProcessedSlot < maxReplaySlot) {
      console.warn('Disconnection too long, some data may be lost');
      lastProcessedSlot = maxReplaySlot;
    }

    const subscriptionRequest: SubscribeRequest = {
      // ... your subscription config
      fromSlot: lastProcessedSlot, // pass as number, not string
    };

    await subscribe(config, subscriptionRequest,
      async (data) => {
        // your handler here
        if (data.transaction?.slot) {
          lastProcessedSlot = Number(data.transaction.slot);
          // persist `lastProcessedSlot` here so the next reconnect picks up
        }
      }
    );
    ```
  </Accordion>

  <Accordion title="Bootstrap with Recent Context">
    Запустите приложение с недавним контекстом за последние несколько минут:

    ```typescript theme={"system"}
    // Get a slot from 10 minutes ago (within the 48-hour window)
    const currentSlot = await getCurrentSlot();
    const startSlot = currentSlot - 2400; // ~10 minutes ago at current ~250ms slot time

    const subscriptionRequest: SubscribeRequest = {
      // ... your subscription config
      fromSlot: startSlot, // u64 number
    };
    ```
  </Accordion>

  <Accordion title="Testing with Recent Data">
    Используйте недавние исторические данные для тестирования (только за последние 48 часов):

    ```typescript theme={"system"}
    // Test with data from the last 5 minutes
    const currentSlot = await getCurrentSlot();
    const testStartSlot = currentSlot - 1200; // ~5 minutes ago at current ~250ms slot time
    const testEndSlot = currentSlot - 240;    // ~1 minute ago at current ~250ms slot time

    const subscriptionRequest: SubscribeRequest = {
      // ... your subscription config
      fromSlot: testStartSlot, // u64 number
    };

    // Stop processing when reaching the test end slot
    const stream = await subscribe(config, subscriptionRequest,
      async (data) => {
        const slot = Number(data.transaction?.slot ?? data.account?.slot ?? 0);
        if (slot >= testEndSlot) {
          stream.cancel();
          return;
        }
        // your test handler here
      }
    );
    ```
  </Accordion>
</AccordionGroup>

## Следующие шаги

<CardGroup cols={2}>
  <Card title="LaserStream gRPC" icon="bolt" href="/docs/ru/laserstream/grpc">
    Узнайте больше о возможностях и функциях потоковой передачи через gRPC
  </Card>

  <Card title="Get Started" icon="rocket" href="https://dashboard.helius.dev/laserstream">
    Включите LaserStream в панели управления Helius и начните потоковую передачу.
  </Card>

  <Card title="SDK Documentation" icon="github" href="https://github.com/helius-labs/laserstream-sdk">
    Ознакомьтесь с полной документацией SDK
  </Card>

  <Card title="Contact Support" icon="headset" href="/docs/ru/support">
    Получите помощь с реализацией
  </Card>
</CardGroup>


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