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

# Как использовать preprocessedSubscribe

> Передавайте транзакции Solana до выполнения через WebSocket с помощью метода preprocessedSubscribe — оформляйте подписку, фильтруйте по аккаунту и декодируйте бинарные полезные данные.

<Note>
  **Публичная бета-версия.** `preprocessedSubscribe` доступен на **всех платных тарифах**
  и тарифицируется по ставке **0,1 кредита за сообщение** (одно сообщение на каждую
  доставленную транзакцию).
</Note>

## Что такое `preprocessedSubscribe`?

`preprocessedSubscribe` — это метод WebSocket от Helius, который передает поток предварительно обработанных транзакций — транзакций Solana до выполнения, доставляемых **до достижения ими уровня подтверждения `processed`**. Helius объединяет несколько источников данных до выполнения — главным образом шреды, декодируемые непосредственно по мере их поступления валидатору и дополненные сигналами [предварительного подтверждения](/docs/ru/pre-confirmations/overview), — и доставляет их в виде единого дедуплицированного потока компактных бинарных сообщений. Вам не требуется собственная инфраструктура сборки шредов.

Транзакции, полученные из сигналов предварительного подтверждения, поступают в этот поток позже, чем в специализированный продукт [Preconfirmations](/docs/ru/pre-confirmations/overview), который по-прежнему обеспечивает самый ранний доступ к ним.

Этот метод пришел на смену предыдущему продукту предварительно обработанных данных LaserStream (gRPC). Если сейчас вы получаете предварительно обработанные транзакции через gRPC, перейдите на этот метод: он доставляет тот же класс данных через обычное соединение WebSocket с меньшей задержкой, а доставка через gRPC будет объявлена устаревшей.

| Поток | Относительное время | Охват | Данные |
| - | - | - | - |
| [Preconfirmations](/docs/ru/pre-confirmations/overview) | Самый ранний | Транзакции, запланированные участвующими валидаторами | Транзакция и статус выполнения (только для предварительных подтверждений Helius; предварительные подтверждения BAM сообщают неизвестный статус) |
| `preprocessedSubscribe` | Обычно после Preconfirmations, до `processed` | Широкий охват транзакций Solana | Подписанная транзакция до выполнения |
| [`transactionSubscribe`](/docs/ru/rpc/websocket/transaction-subscribe) с уровнем `processed` | После выполнения | Обработанные транзакции | Транзакция с метаданными выполнения |

<Warning>
  `preprocessedSubscribe` — это **сигнал до выполнения, предоставляемый без гарантий**, а не
  уровень подтверждения. Переданная в потоке транзакция может завершиться ошибкой, быть отброшена или попасть в
  другую ветвь. Сопоставьте ее с обработанным или подтвержденным потоком, прежде чем
  считать окончательной.
</Warning>

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

`preprocessedSubscribe` обслуживается через `wss://beta.helius-rpc.com` — конечную точку Helius Gatekeeper, — а не через `mainnet.helius-rpc.com`. Для аутентификации передайте ключ API в качестве параметра запроса:

```
wss://beta.helius-rpc.com/?api-key=<API_KEY>
```

Для каждого ключа API разрешено не более **10 одновременных соединений/подписок**.

## Подписка

Отправьте запрос JSON-RPC с методом `preprocessedSubscribe`. Обязательный параметр `params` содержит фильтры аккаунтов: в `accountInclude` и `accountRequired` должен быть указан хотя бы один аккаунт (см. раздел [Фильтрация](#фильтрация)):

```json theme={"system"}
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "preprocessedSubscribe",
  "params": {
    "accountInclude": ["JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4"],
    "accountExclude": [],
    "accountRequired": []
  }
}
```

Сервер подтверждает подписку текстовым кадром JSON, содержащим идентификатор подписки:

```json theme={"system"}
{
  "jsonrpc": "2.0",
  "result": 1,
  "id": 1
}
```

После этого подтверждения обновления транзакций поступают в виде **бинарных** кадров WebSocket — см. раздел [Полезные данные уведомления](#полезные-данные-уведомления).

## Фильтрация

Область каждой подписки определяется фильтрами аккаунтов в `params`. Фильтрация выполняется на стороне сервера, поэтому вы получаете только нужные вам транзакции:

```json theme={"system"}
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "preprocessedSubscribe",
  "params": {
    "accountInclude": ["JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4"],
    "accountExclude": ["Vote111111111111111111111111111111111111111"],
    "accountRequired": []
  }
}
```

| Фильтр | Условие совпадения |
| - | - |
| `accountInclude` | Совпадение, если транзакция ссылается на **любой** из перечисленных аккаунтов. |
| `accountExclude` | Транзакция отбрасывается, если ссылается на **любой** из перечисленных аккаунтов. |
| `accountRequired` | Совпадение, только если транзакция ссылается на **все** перечисленные аккаунты. |

Правила фильтрации:

* Три фильтра объединяются логическим оператором AND.
* В `accountInclude` и `accountRequired` должен быть указан **хотя бы один аккаунт** — полный поток без фильтрации недоступен.
* Аккаунты указываются как публичные ключи в кодировке base58. Каждый список может содержать до **5 000** адресов.

### Разрешение таблиц поиска адресов (ALT)

Фильтры аккаунтов сопоставляются не только со статическими ключами аккаунтов транзакции: Helius разрешает [таблицы поиска адресов](/docs/ru/glossary#таблица-поиска-адресов-alt) на стороне сервера, поэтому `accountInclude`, `accountExclude` и `accountRequired` также сопоставляются с аккаунтами, которые транзакция загружает через ALT. Просто передайте публичный ключ аккаунта. Вам не нужно вести сопоставления ALT или самостоятельно разрешать таблицы.

## Полезные данные уведомления

Уведомления доставляются в виде **бинарных** кадров WebSocket, а не JSON. Каждый кадр содержит одну транзакцию в упакованной структуре байтов:

| Байты | Поле | Тип | Описание |
| - | - | - | - |
| 0 | `version` | `u8` | Версия схемы полезных данных. Сейчас — `1`. |
| 1–8 | `slot` | `u64` (с обратным порядком байтов) | Слот, в котором наблюдалась транзакция. |
| 9–72 | `signature` | 64 байта | Первая подпись транзакции в бинарном виде. |
| 73+ | `transaction` | `bytes` | Подписанная транзакция в сетевом формате Solana. См. раздел [Декодирование транзакции](#декодирование-транзакции). |

Последовательно прочитайте фиксированный 73-байтовый префикс, а затем декодируйте оставшиеся байты, чтобы получить инструкции, аккаунты и обращения к таблицам адресов. Подпись включена в префикс, поэтому вы можете идентифицировать и дедуплицировать транзакцию, не декодируя ее полное тело.

Всегда сначала считывайте и проверяйте байт `version`. Если Helius потребуется обновить формат полезных данных, номер версии увеличится. Добавьте ветвление по нему, чтобы декодер продолжал работать после изменений схемы.

### Декодирование транзакции

Байты транзакции передаются в точности в том виде, в котором они наблюдались в сети, в стандартной сетевой кодировке соответствующей версии транзакции. Транзакции устаревшего формата и v0 используют структуру с подписями в начале, которую создает `bincode`. Транзакции v1 ([SIMD-0385](https://github.com/solana-foundation/solana-improvement-documents/blob/main/proposals/0385-transaction-v1.md)) используют структуру с сообщением в начале и подписями в конце, поэтому `bincode` не может обработать полезные данные v1. Используйте декодер, поддерживающий все версии:

* **Rust:** [`agave-transaction-view`](https://docs.rs/agave-transaction-view) выполняет разбор транзакций устаревшего формата, v0 и v1 на месте, без промежуточного копирования. Это рекомендуемый вариант. [`wincode`](https://docs.rs/wincode), совместимый с bincode сериализатор, который используется текущими SDK Solana, также декодирует v1 в `VersionedTransaction`.
* **JavaScript / TypeScript:** убедитесь, что версия вашей библиотеки поддерживает транзакции v1. Более старые реализации `VersionedTransaction.deserialize` поддерживают только устаревший формат и v0. Используйте `@solana/kit` 8.0+ или `@solana/web3.js` v3. См. раздел [Поддержка транзакций v1](/docs/ru/rpc/transaction-v1).

```rust theme={"system"}
use agave_transaction_view::transaction_view::TransactionView;

// `frame` is the full binary WebSocket message
let tx_bytes = &frame[73..];
let tx = TransactionView::try_new_unsanitized(tx_bytes)?;

println!("version: {:?}", tx.version()); // Legacy, V0, or V1
for ix in tx.instructions_iter() {
    println!("program index {}: {} bytes", ix.program_id_index, ix.data.len());
}
```

## Пример

```javascript theme={"system"}
const WebSocket = require('ws');
const bs58module = require('bs58');
const bs58 = bs58module.default ?? bs58module;

const ws = new WebSocket('wss://beta.helius-rpc.com/?api-key=<API_KEY>');

ws.on('open', () => {
  ws.send(JSON.stringify({
    jsonrpc: '2.0',
    id: 1,
    method: 'preprocessedSubscribe',
    // Only Jupiter v6 transactions — accountInclude/accountRequired must
    // specify at least one account between them.
    params: {
      accountInclude: ['JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4'],
      accountExclude: [],
      accountRequired: []
    }
  }));

  // Keep the connection alive
  setInterval(() => ws.ping(), 30_000);
});

ws.on('message', (data, isBinary) => {
  // The subscribe acknowledgement arrives as a JSON text frame
  if (!isBinary) {
    const msg = JSON.parse(data.toString());
    if (msg.id === 1) console.log('Subscribed, ID:', msg.result);
    return;
  }

  // Notifications arrive as binary frames:
  // version (u8) | slot (u64 LE) | signature ([u8; 64]) | transaction bytes
  const buf = Buffer.from(data);
  const version = buf.readUInt8(0); // currently 1 — branch on this if it changes
  if (version !== 1) return; // unknown schema version; update your decoder
  const slot = buf.readBigUInt64LE(1);
  const signature = bs58.encode(buf.subarray(9, 73));
  const txBytes = buf.subarray(73); // transaction in Solana wire format (legacy, v0, or v1)

  console.log('Preprocessed transaction:', { slot, signature, bytes: txBytes.length });
  // Decode txBytes with a decoder that supports transaction v1 (see "Decoding the transaction")
});

ws.on('error', console.error);
ws.on('close', () => process.exit(1));
```

## Какие данные доступны?

Каждое уведомление содержит подписанную транзакцию, ее первую подпись и слот. Поскольку доставка происходит до выполнения, поток **не** содержит:

* Статус выполнения или ошибки
* Балансы до и после выполнения или изменения балансов токенов
* Сообщения журналов или внутренние инструкции
* Количество использованных вычислительных единиц

Рассматривайте это как получение «предложения» без «результата»: вы видите, что отправитель пытался сделать, но не видите, что произошло на самом деле. Обновлений состояния аккаунтов и программ на этом этапе также еще не существует. Если вам нужно состояние аккаунтов в реальном времени, используйте [LaserStream gRPC](/docs/ru/laserstream) с уровнем подтверждения `processed`.

## Обратное давление

Поток не буферизует данные для медленных потребителей бесконечно. Если ваш клиент читает слишком медленно и на стороне сервера накапливается более **4 000 сообщений**, Helius закрывает соединение — вы получаете корректный кадр закрытия WebSocket. Обрабатывайте кадры быстрее, чем они поступают: вынесите ресурсоемкие операции, такие как декодирование транзакций и логика стратегии, за пределы цикла приема. После отключения повторно подключитесь и оформите подписку заново.

## Гарантии доставки

Доставка выполняется без гарантий, а воспроизведение исторических данных недоступно. Клиентам следует:

1. Повторно подключаться и оформлять подписку заново после закрытия соединения.
2. Выполнять дедупликацию по подписи транзакции.
3. Считать слот наблюдением, а не окончательным результатом.
4. Сопоставлять данные с обработанным или подтвержденным потоком, когда важны результаты выполнения.

## Тарификация

`preprocessedSubscribe` доступен на **всех платных тарифах** и тарифицируется по ставке **0,1 кредита за сообщение** — одно сообщение на каждую доставленную транзакцию, со списанием в рамках вашего тарифа. Подробности см. в разделе [Кредиты](/docs/ru/billing/credits).

## Связанные материалы

<CardGroup cols={2}>
  <Card title="Preconfirmations" icon="bolt" href="/docs/ru/pre-confirmations/overview">
    Транзакции, передаваемые в потоке до их преобразования в шреды, — самый ранний сигнал о транзакции.
  </Card>

  <Card title="Raw Shreds (UDP)" icon="network-wired" href="/docs/ru/shred-delivery/raw-shreds">
    Необработанные пакеты шредов через UDP. Сборку шредов реализуете вы.
  </Card>

  <Card title="transactionSubscribe" icon="tower-broadcast" href="/docs/ru/rpc/websocket/transaction-subscribe">
    Транзакции после выполнения с расширенной фильтрацией и метаданными выполнения.
  </Card>
</CardGroup>


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