Skip to main content

Обзор

LaserStream — это управляемый сервис потоковой передачи Solana по gRPC. Он совместим на уровне протокола с открытым протоколом Yellowstone gRPC, поэтому любой клиент Yellowstone работает без дополнительной настройки. Кроме того, сервис предоставляет функции для промышленной эксплуатации, такие как воспроизведение исторических данных, аварийное переключение между несколькими узлами и полностью управляемая среда. LaserStream использует протокол gRPC с открытым исходным кодом, что исключает зависимость от поставщика и обеспечивает максимальную совместимость с существующими реализациями gRPC. Вы можете подключиться с помощью стандартного клиента @triton-one/yellowstone-grpc или использовать оптимизированный для высокой производительности Helius LaserStream SDK. Он обеспечивает более высокую пропускную способность, автоматическое переподключение, управление подписками, обработку ошибок и другие преимущества.

LaserStream SDK is 40x Faster vs. JavaScript Yellowstone Clients

Узнайте, как мы использовали ядро на Rust с NAPI-привязками без копирования, чтобы максимально повысить производительность JavaScript SDK
Примечание о производительности: если вы заметили задержки или проблемы с производительностью подключения LaserStream, ознакомьтесь с разделом об устранении неполадок, где описаны распространённые причины и решения.

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

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

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

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

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

Сжатие zstd

Все конечные точки LaserStream gRPC поддерживают сжатие zstd. Сжатие необходимо включать явно: ответы остаются несжатыми, если ваш клиент не заявляет о поддержке zstd. Включите zstd в Helius LaserStream TypeScript SDK:
zstd сокращает использование пропускной способности сети, но требует дополнительных ресурсов для сжатия. Прежде чем включать его для чувствительных к задержкам потоков, протестируйте производительность с вашей нагрузкой подписки.

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

По умолчанию LaserStream усекает сообщения журналов транзакций до 10 КБ, чтобы повысить скорость и производительность. Если вам нужны полные журналы, доступны выделенные конечные точки без усечения — см. раздел Усечение журналов.

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

Начните работу с LaserStream через панель управления Helius. Для Mainnet требуется тариф Business или Professional; Devnet доступна на тарифе Developer и выше. Подробности см. в разделе Тарифы и цены.
1

Create a New Project

2

Install Dependencies

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

Obtain Your API Key

Создайте ключ в панели управления Helius.Этот ключ будет служить токеном аутентификации для LaserStream.
Требования к тарифу: LaserStream Devnet доступна на всех тарифах. Для LaserStream Mainnet требуется тариф Business или Professional.
4

Create a Subscription Script

Создайте файл index.ts со следующим содержимым:
5

Replace Your API Key and Choose Your Region

В index.ts обновите объект config, указав:
  1. Фактический ключ API из панели управления Helius
  2. Ближайшую к расположению вашего сервера конечную точку LaserStream
Примеры выбора сети и региона:
  • Для промышленной эксплуатации (Mainnet):
    • Европа: используйте fra (Франкфурт), ams (Амстердам) или lon (Лондон)
    • Восток США: используйте ewr (Нью-Йорк)
    • Запад США: используйте slc (Солт-Лейк-Сити) или lax (Лос-Анджелес)
    • Азия: используйте tyo (Токио) или sgp (Сингапур)
  • Для разработки (Devnet):
    • Используйте https://laserstream-devnet-ewr.helius-rpc.com
6

Run and View Results

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

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

Пошаговые руководства для наиболее распространённых сценариев. В каждом руководстве используется SDK helius-laserstream со встроенным автоматическим переподключением и воспроизведением исторических данных.

Account Subscriptions

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

Transaction Monitoring

Получайте поток транзакций, затрагивающих целевые аккаунты, и фильтруйте их по программе, голосованию или статусу ошибки.

Slot & Block Monitoring

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

Decoding Transaction Data

Преобразуйте двоичные полезные данные transactionUpdate в читаемые транзакции Solana.

Stream Pump AMM Data

Практический пример: отслеживайте сделки Pump AMM с фильтрами, устойчивыми к переподключению.
Если вы предпочитаете использовать протокол Yellowstone напрямую, клиент @triton-one/yellowstone-grpc работает с теми же конечными точками. Подробности на уровне протокола см. в справочнике по Yellowstone gRPC.

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

В запрос подписки необходимо включить следующие общие параметры:
Воспроизведение исторических данных: при необходимости можно включить поле fromSlot (число u64) в основной объект SubscribeRequest, чтобы воспроизводить данные начиная с определённого слота. В настоящее время воспроизведение ограничено последними ~48 часами (~691 200 слотов при текущей скорости сети). Обратите внимание, что при воспроизведении данных старше ~20 минут возвращаются только финализированные данные.
enum
Задаёт уровень подтверждения: processed, confirmed или finalized.
array
Массив объектов { offset: uint64, length: uint64 }, позволяющий получать только необходимые фрагменты данных аккаунтов.
boolean
Некоторые облачные провайдеры, например Cloudflare, могут закрывать неактивные потоки после периода бездействия. Чтобы предотвратить это и сохранять подключение активным без повторной отправки фильтров, задайте значение true. Сервер будет отвечать сообщением Pong каждые 15 секунд.
Затем укажите фильтры для данных, на которые хотите подписаться, например аккаунтов, блоков, слотов или транзакций.
Определите фильтры для обновлений слотов. Используемый ключ (например, mySlotLabel) — это заданная пользователем метка для данной конфигурации фильтра. При необходимости она позволяет определить несколько именованных конфигураций, хотя обычно достаточно одной.
boolean
По умолчанию слоты отправляются для всех уровней подтверждения. Этот фильтр позволяет получать данные только для выбранного уровня подтверждения.
boolean
Позволяет подписке получать обновления об изменениях внутри слота, а не только в начале новых слотов. Это полезно для получения более детальных данных слотов с низкой задержкой.
Определите фильтры для обновлений данных аккаунтов. Используемый ключ (например, tokenAccounts) — это заданная пользователем метка для данной конфигурации фильтра.
array
Соответствует любому открытому ключу из предоставленного массива.
array
Открытый ключ владельца аккаунта. Соответствует любому открытому ключу из предоставленного массива.
array
Аналогично фильтрам в getProgramAccounts. Это массив фильтров datasize и/или memcmp. Для memcmp сравниваемое значение указывается в одном из полей bytes, base58 или base64 непосредственно в объекте memcmp.
enum
устарело
Устарело — не выполняет никаких действий начиная с Agave 4.2. Установка notifyOn ни на что не влияет. Поле будет удалено позднее.
Если все поля пусты, передаются все аккаунты. В противном случае:
  • Поля объединяются логическим оператором И.
  • Значения внутри массивов объединяются логическим оператором ИЛИ (кроме значений внутри filters, которые объединяются логическим оператором И).
Отслеживаете более ~10 000 аккаунтов? Вместо явного списка открытых ключей (32 байта на аккаунт) используйте сжатый фильтр кукушки (~3–4 байта на аккаунт), чтобы подписаться на сотни тысяч аккаунтов в одном потоке. Доступно в SDK для Rust и JavaScript.
Определите фильтры для обновлений транзакций. Используемый ключ (например, myTxSubscription) — это заданная пользователем метка для данной конфигурации фильтра.
boolean
Включает или отключает передачу транзакций голосования.
boolean
Включает или отключает передачу неуспешных транзакций.
string
Передаёт только транзакции, соответствующие указанной подписи.
array
Фильтрует транзакции, затрагивающие любой аккаунт из предоставленного списка.
array
Исключает транзакции, затрагивающие любой аккаунт из предоставленного списка (действует противоположно accountInclude).
array
Фильтрует транзакции, затрагивающие все аккаунты из предоставленного списка (должны использоваться все аккаунты).
string
Необязательное расширение tokenAccounts (связанный токен-аккаунт). Если оно задано, кошелёк accountInclude также соответствует транзакциям, в которых он владеет балансом токенов SPL. Например, это входящие переводы токенов, затрагивающие токен-аккаунт кошелька, а не его открытый ключ. Допустимые значения: "balanceChanged" (соответствие по изменению баланса), "all" (любая ссылка, больший объём) или "none" (без расширения, значение по умолчанию). SDK преобразует строку в перечисление TokenAccountExpansionControlFlag уровня протокола (входит в yellowstone-grpc-proto 12.5.0+). Описание принципа и механизма работы см. в разделе Фильтрация токен-аккаунтов (ATA).
boolean
Необязательный флаг matchMints (по умолчанию false). Если задано значение true, списки accountInclude, accountExclude и accountRequired также сопоставляются с адресами выпуска токенов в балансах токенов до и после транзакции, а не только с ключами её аккаунтов. Добавьте адрес выпуска в accountInclude, чтобы получать каждую транзакцию, затрагивающую этот токен, включая обычные переводы SPL, в ключах аккаунтов которых адрес выпуска не указывается. Функция включается явно и не влияет на существующие фильтры. Требуется helius-laserstream 0.8.5+ (JS), 0.6.4+ (Rust) или go/v0.3.0+ (Go). Семантику и примеры см. в разделе Фильтрация по адресу выпуска токена.
Если все поля оставлены пустыми, передаются все транзакции. В противном случае:
  • Поля объединяются логическим оператором И.
  • Значения внутри массивов объединяются логическим оператором ИЛИ (кроме accountRequired, где должны совпадать все значения).
Определите фильтры для обновлений блоков. Используемый ключ (например, myBlockLabel) — это заданная пользователем метка для данной конфигурации фильтра.
array
Фильтрует транзакции и аккаунты, затрагивающие любой аккаунт из предоставленного списка.
boolean
Включает в передачу все транзакции.
boolean
Включает в передачу все обновления аккаунтов.
boolean
Включает в передачу все записи.
Работает аналогично блокам, но исключает транзакции, аккаунты и записи. Используемый ключ (например, blockmetadata) — это заданная пользователем метка для данной подписки. В настоящее время фильтры метаданных блоков недоступны: по умолчанию передаются все сообщения.
Подпишитесь на записи реестра. Используемый ключ (например, entrySubscribe) — это заданная пользователем метка для данной подписки. В настоящее время фильтры для записей недоступны; передаются все записи.

Примеры кода (LaserStream SDK)

Варианты SDK

Мы предоставляем официальные SDK для нескольких языков программирования: Для других языков или собственных реализаций можно напрямую использовать proto-файлы Yellowstone gRPC, чтобы создать клиенты gRPC для предпочитаемого языка.

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

О: Проблемы с производительностью подключений LaserStream обычно вызваны следующими причинами:
  • Низкая скорость клиента JavaScript: клиент JavaScript может отставать при обработке слишком большого количества сообщений или использовании чрезмерной пропускной способности. Попробуйте сузить фильтры подписок, чтобы сократить объём сообщений, перейти на LaserStream JavaScript SDK или использовать другой язык.
  • Ограниченная локальная пропускная способность: интенсивные подписки могут перегружать клиентов с ограниченной пропускной способностью сети. Отслеживайте использование сети и рассмотрите возможность улучшить подключение или сузить область подписки.
  • Географическая удалённость: длинные сетевые маршруты увеличивают задержку и потерю пакетов. Используйте ближайшую к вашему серверу конечную точку. Для подключений с высокой задержкой увеличьте размеры буферов чтения сети — это может повысить пропускную способность в 5 и более раз:
    Чтобы сохранить настройки после перезагрузки, добавьте в /etc/sysctl.conf:
    Увеличьте размеры окон потока и подключения HTTP/2 до 64 МБ, чтобы избежать узких мест при управлении потоком. Необходимо изменить оба значения: если увеличить только окно потока, ограничивающим фактором останется окно на уровне подключения:
  • Узкие места при обработке на стороне клиента: убедитесь, что логика обработки сообщений оптимизирована и не блокирует основной поток на длительное время.
Диагностика отставания клиента: чтобы помочь вам диагностировать клиент, мы создали инструмент для проверки максимальной пропускной способности между вашим узлом и сервером LaserStream gRPC. Для его использования выполните:
Результат показывает максимальную пропускную способность сети между вашим сервером и сервером LaserStream. Для подписки на все данные транзакций требуется не менее 10 МБ/с, а для подписки на все данные аккаунтов — 80 МБ/с. Для оптимальной производительности рекомендуется иметь как минимум двукратный запас относительно требуемой пропускной способности.
О: Убедитесь, что ключ API и конечная точка указаны правильно, а ваша сеть разрешает исходящие подключения gRPC к указанной конечной точке. Проверьте страницу состояния Helius на наличие текущих инцидентов.
О: Ещё раз проверьте логические операторы (И/ИЛИ), описанные в разделах о фильтрах. Убедитесь, что открытые ключи указаны правильно. Проверьте уровень подтверждения, указанный в запросе.
О: Да, в одном объекте SubscribeRequest можно определить конфигурации фильтров под несколькими ключами (например, accounts и transactions).
О: Мы не реализуем группы потребителей. Вместо этого LaserStream предоставляет необходимые командам возможности: возобновление, воспроизведение и надёжность нескольких узлов без координационного слоя и связанных с ним задержек и накладных расходов. Мы считаем, что для большинства нагрузок группы потребителей не нужны, а их использование увеличивает задержку и эксплуатационные расходы. Например, одно подключение LaserStream gRPC может передавать объём данных о транзакциях и аккаунтах, который до 10 раз превышает соответствующий объём Solana, при этом большинство клиентов подписываются лишь на небольшой отфильтрованный фрагмент. Использование групп потребителей в таком случае расходует запас производительности и создаёт ещё одну точку отказа.
О: По умолчанию LaserStream усекает сообщения журналов транзакций до 10 КБ, чтобы повысить скорость и производительность. Если вам нужны полные журналы, подключитесь к выделенной конечной точке без усечения. Их список приведён в разделе Усечение журналов.
О: Если включить поле ping в исходный объект SubscribeRequest, LaserStream без уведомления проигнорирует все фильтры подписки. В результате будет возвращаться только Pong без данных аккаунтов, транзакций или слотов. Чтобы исправить это, удалите ping из исходного запроса подписки, а после установления подписки отправляйте запросы ping отдельно через приёмник потока. Это сохранит подключение активным, не мешая работе фильтров.