НОВОЕ: Helius приобретает Light Protocol
Выполнение транзакций в нулевом слоте с Sender и LaserStream
Блог/Разработка

Выполнение транзакций в нулевом слоте с Sender и LaserStream

Developer Experience Engineer0xIchigo в X0xIchigo в LinkedIn0xIchigo на GitHub
Чтение: 13 мин

Введение

Все хотят, чтобы их транзакции попадали в блок как можно быстрее. Но по мере усложнения торговой инфраструктуры Solana и развития ончейн-рынков уже недостаточно просто отправить транзакцию и надеяться на лучшее. Перегрузка, конкуренция и особенности сети превращают «быстро» в «невыносимо ненадёжно».

Цель проста: когда поступает сигнал — цена пересекает заданный порог, обновляется аккаунт или вызывается программа, — реагирующая на него транзакция должна попасть в тот же слот. 

В этом суть выполнения в нулевом слоте: обнаружение и отправка происходят настолько слаженно, что возможность удаётся использовать до того, как она исчезнет за считаные миллисекунды. 

На практике добиться этого становится всё сложнее. Нужны приём сигналов со сверхнизкой задержкой и надёжная детерминированная доставка.

Helius предоставляет и то и другое.

Сочетая LaserStream для молниеносного обнаружения событий с Sender для оптимизированной отправки транзакций, Helius создаёт комплексный конвейер, специально разработанный для выполнения в нулевом слоте.

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

Sender стабильно превосходит другие сервисы: мои транзакции попадают в блок почти мгновенно, большинство — в пределах одного слота. Раньше прибыльные сделки часто срывались из-за высокой задержки в слотах, но теперь включение практически гарантировано и гораздо надёжнее. Helius всегда предоставляла отличные сервисы, и Sender — ещё один выдающийся продукт, который напрямую повысил мою результативность.

Alan
Трейдер

LaserStream и Sender: единый рабочий процесс

Sender дополняет LaserStream и создаёт единый комплексный конвейер для торговых процессов в Solana, требующих быстрой реакции. На практике это выглядит так:

  1. Используйте LaserStream для получения сигналов: приём данных на уровне шредов и расширенная фильтрация доставляют ончейн-события в реальном времени быстрее любого другого конвейера.
  2. Используйте Helius Sender для реакции на сигналы: транзакции одновременно отправляются через SWQoS и Jito, а глобальная маршрутизация и доставка с учётом валидаторов максимизируют вероятность включения и минимизируют задержку.
  3. Получайте прибыль: вместе эти сервисы позволяют использовать прибыльные возможности не только в теории, но и на практике.

С Helius разработчики получают вертикально интегрированный стек, созданный специально для скорости и надёжности:

  • Не нужно объединять сторонние RPC, ретрансляторы или собственную инфраструктуру.
  • Глобальная маршрутизация, автоматические повторные попытки и доставка с учётом валидаторов уже встроены.
  • Прозрачно и честно: мы не проводим сэндвич-атаки на пользователей и не извлекаем другие виды негативного MEV за их счёт.

Helius уже обеспечивает лучшее в своём классе обнаружение сигналов с помощью LaserStream. Почему бы не дополнить его лучшим в своём классе сервисом отправки транзакций Sender? 

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

Как это выглядит на практике?

Поиск подходящего сигнала

В Solana возможности для арбитража и ликвидации могут исчезнуть за миллисекунды. Поэтому крайне важно вовремя обнаружить нужный ончейн-сигнал. Здесь «сигнал» — это любое событие в реальном времени, например перевод токена, обновление аккаунта или вызов программы, которое создаёт торговую возможность. Без приёма данных со сверхнизкой задержкой преимущество исчезает ещё до того, как им можно воспользоваться. Поэтому необходима надёжная высокоскоростная потоковая передача данных.

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

Расширенная фильтрация LaserStream позволяет разработчикам сосредоточиться на конкретных сигналах: типах транзакций, обновлениях аккаунтов и общем потоке блоков. Если нужен ещё более ранний сигнал, Preprocessed Transactions передаёт подписанные транзакции, декодированные из шредов, на 8 мс раньше уровня подтверждения processed и точно так же сочетается с Sender.

Интеграция выполняется без лишних сложностей: сервис спроектирован как прямая замена Yellowstone gRPC и поддерживает несколько клиентов, включая Rust, Go и TypeScript. 

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

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

LaserStream даёт преимущество при обнаружении событий и позволяет эффективнее отправлять ответные транзакции. Однако LaserStream не предназначен для отправки транзакций, а эффективное включение транзакций в Solana, к сожалению, не сводится к простому RPC-вызову sendTransaction.

Оптимизация процессов отправки транзакций

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

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

Например, даже если трейдер обнаружит сигнал на несколько миллисекунд раньше конкурентов, позднее прибытие или недостаточная комиссия могут привести к тому, что транзакция завершится ошибкой ончейн на слот позже, а прибыльная возможность обернётся потерей дохода.

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

Чтобы сегодня эффективно включить транзакцию в Solana, разработчику необходимо:

Использовать Staked Connections

Соединения со стейком используют механизм Solana Stake-Weighted Quality of Service (SWQoS), который приоритизирует трафик от валидаторов со стейком и связанных RPC, улучшая доступность лидеров и скорость распространения. Разработчикам следует направлять трафик через соединения со стейком, чтобы снизить риск сбоев при распространении, ускорить прибытие и повысить долю включённых транзакций. При этом не приходится полагаться только на публичные эндпоинты, которые могут страдать от перегрузки.

Добавить динамические приоритетные комиссии

Приоритетные комиссии помогают повысить позицию транзакции в планировщике лидера на этапе Banking Stage, где prio-graph, то есть очередь приоритетов с учётом зависимостей, определяет порядок ончейн-выполнения на основе комиссии за CU. Приоритетные комиссии следует рассчитывать динамически. Статические значения могут привести к переплате или недоплате и помешать включению при доступе к состоянию с высокой конкуренцией.

Оптимизировать использование CU

Compute Units (CU) определяют вычислительную нагрузку транзакции. Превышение запрошенного бюджета приводит к ошибкам выполнения, а избыточный запрос увеличивает затраты на приоритет. Если не указано иное, транзакция по умолчанию запрашивает 200 000 CU. Количество CU можно оптимизировать, заранее симулировав транзакцию для оценки потребления и запросив конкретный объём с помощью инструкции SetComputeUnitLimit программы Compute Budget Program.

Использовать подходящий уровень подтверждения при получении данных

Уровни подтверждения определяют глубину подтверждения получаемых данных, например хешей блоков. Они должны быть актуальными, чтобы не истечь и сохранить действительность транзакции. Уровень confirmed для вызовов getLatestBlockhash будет значительно быстрее, чем finalized.

Отключить предварительные проверки

Предварительные проверки симулируют транзакцию на RPC-ноде перед отправкой, проверяя подписи, инструкции и выполнение, чтобы заранее выявить ошибки. Однако это может добавить более 100 мс задержки. В процессах, где критично время и разработчики полностью уверены в корректности транзакций, следует задать параметру skipPreflight в RPC-методе sendTransaction значение true.

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

Задать параметру maxRetries нулевое значение

Параметр maxRetries метода sendTransaction включает автоматическую повторную отправку на стороне RPC при сбоях. Это может быть неэффективно, например из-за отправки дубликатов транзакций с устаревшими хешами блоков. Разработчикам следует задать maxRetries значение 0, вернуть себе контроль и реализовать повторные попытки на стороне клиента с экспоненциальной задержкой, обновлением хешей блоков и комиссий при повторной рассылке, а также отслеживанием высоты блока для корректного прекращения попыток.

Рассмотреть использование Jito

Чаевые Jito позволяют формировать офчейн-пакеты через MEV-аукционы, гарантируя включение и порядок транзакций в частичных блоках. Это оптимально для трейдеров и арбитражёров, которым нужно выполнение в начале блока или атомарность нескольких транзакций. Подход особенно полезен для дорогостоящих и срочных транзакций, а также любых транзакций, конкурирующих за востребованное состояние. Однако аукционы добавляют задержку, поэтому транзакция может попасть в блок позже, чем хорошо оптимизированная транзакция, отправленная через соединения со стейком. Разработчикам нужно сочетать эти внепротокольные аукционы с надёжностью соединений со стейком, чтобы любые транзакции всегда попадали в блок как можно быстрее.

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

Sender

Sender — сервис Helius для отправки транзакций со сверхнизкой задержкой. Он использует SWQoS и офчейн-аукционы Jito для включения с оптимизацией MEV, а также географическую маршрутизацию для минимизации задержек распространения. 

Sender одновременно отправляет транзакции через соединения со стейком и аукционную площадку Jito. Два маршрута включения повышают надёжность и сокращают время выполнения без расходования дополнительных кредитов.

Sender доступен на всех тарифах со стандартным ограничением 6 TPS, которое можно увеличить по запросу. Сервис создан для трейдеров, MEV-поисковиков и высокочастотных приложений, которым нужны детерминированные результаты. Sender дополняет LaserStream и обеспечивает непрерывные реактивные процессы с выполнением в нулевом слоте.

Как работает Sender

Sender обрабатывает транзакции стандартным способом — через простой POST-запрос JSON-RPC. Транзакция сериализуется в base64 и отправляется на один из его эндпоинтов. 

У Sender есть глобальный HTTPS-эндпоинт, который автоматически направляет запрос в ближайший географический регион. Его рекомендуется использовать во фронтенд-приложениях, чтобы избежать проблем с CORS. 

У Sender также есть несколько региональных HTTP-эндпоинтов для минимальной задержки между серверами, например в Солт-Лейк-Сити, Токио и Франкфурте.

Важно, что аутентификация по API-ключам отсутствует. Между получением и отправкой транзакции нет промежуточных сервисов, поэтому Sender отлично подходит для сценариев со сверхнизкой задержкой. 

Для эффективного использования Sender транзакцию нужно подготовить следующим образом:

  • Минимальные чаевые — 0,0002 SOL для Jito или 0,000005 SOL (5 000 лампортов) при отправке только через SWQoS. Для этого добавьте ?swqos_only=true к эндпоинту
  • Параметру skipPreflight нужно задать значение true — Sender оптимизирован для скорости, а не для проверки транзакций
  • Параметру maxRetries нужно задать значение 0 — повторные попытки увеличивают задержку
  • Добавьте приоритетную комиссию, чтобы повысить приоритет транзакции на этапе Banking Stage лидера

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

Чаевые необходимы для доступа к инфраструктуре Jito и включения транзакций через аукционы. Приоритетная комиссия сообщает лидеру, то есть валидатору, ответственному за обработку транзакции, о готовности заплатить за приоритетную обработку. Это даёт двойное преимущество: чаевые открывают доступ к аукционной инфраструктуре Jito, а приоритетная комиссия повышает приоритет транзакции. Вместе они максимизируют вероятность включения.

Рекомендуем получать размер чаевых динамически через API минимальных чаевых Jito, например брать 75-й процентиль и добавлять небольшой запас, а приоритетную комиссию — через Priority Fee API от Helius. 

После отправки Sender параллельно направит транзакции через SWQoS и Jito, максимизируя вероятность включения без дополнительных затрат. 

Также рекомендуем поддерживать соединения прогретыми в периоды простоя, то есть более 1 минуты, отправляя запросы на /ping, то есть https://sender.helius-rpc.com/ping. Это поможет избежать холодных запусков. Кроме того, следуйте рекомендациям по отправке транзакций, чтобы дополнительно повысить вероятность оптимального включения. 

Начало работы

Вот как начать торговать с LaserStream и Sender:

Работа с LaserStream

Работа с LaserStream ничем не отличается от работы с gRPC. Просто замените эндпоинт и API-ключ на данные LaserStream, чтобы сразу получить все преимущества сервиса.

Чтобы перенести существующий код, достаточно:

Migrating from Yellowstone to LaserStream
// Before: Using standard Yellowstone gRPC
const connection = new GeyserConnection(
  "your-current-endpoint.com",
  { token: "your-current-token" }
);

// After: Using LaserStream (just change the endpoint and token)
const connection = new GeyserConnection(
  "https://laserstream-mainnet-ewr.helius-rpc.com", // Choose the closest region to you
  { token: "your-helius-api-key" }
);

Рекомендуем использовать один из клиентов LaserStream, чтобы упростить разработку.

Например, открыть подписку можно так:

A Simple Subscription
// Using the dedicated LaserStream SDK
import { subscribe, CommitmentLevel, LaserstreamConfig } from 'helius-laserstream';

const config = {
  apiKey: "your-helius-api-key",
  endpoint: "https://laserstream-mainnet-ewr.helius-rpc.com" // Choose the closest region to you
};

// The SDK automatically handles:
// - Connection management
// - Reconnection with backoff
// - Historical replay after disconnects
// - Subscription management
await subscribe(config, subscriptionRequest, handleData, handleError);

Попробуйте LaserStream бесплатно

Хотите протестировать LaserStream перед переходом? Получите бесплатный пробный доступ, чтобы измерить задержку LaserStream, сравнить сервис с альтернативными решениями потоковой передачи и оценить его для вашего сценария.

Работа с Sender

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

Для начала создайте аккаунт в панели Helius. Затем перейдите в раздел API-ключи и скопируйте выданный ключ. Он нужен для получения хешей блоков и подтверждения транзакции, поскольку Sender отвечает только за её отправку.

Ниже показан простой перевод SOL через Sender. Пример включает все обязательные компоненты: чаевые, приоритетную комиссию и отключение предварительных проверок.

A Simple SOL Transfer Using Sender
import { pipe } from "@solana/kit";
import {
  createSolanaRpc,
  createTransactionMessage,
  setTransactionMessageFeePayerSigner,
  setTransactionMessageLifetimeUsingBlockhash,
  appendTransactionMessageInstruction,
  signTransactionMessageWithSigners,
  lamports,
  getBase64EncodedWireTransaction,
} from "@solana/kit";
import { getTransferSolInstruction } from "@solana-program/system";
import {
  getSetComputeUnitLimitInstruction,
  getSetComputeUnitPriceInstruction,
} from "@solana-program/compute-budget";

(async () => {
  const HELIUS_API_KEY = "your_api_key";
  const PRIV_KEY_B58 = "your_private_key";
  const RECIPIENT = "recipient_address";
  const TIP_ACCOUNTS = [
    "4ACfpUFoaSD9bfPdeu6DBt89gB6ENTeHBXCAi87NhDEE",
    "D2L6yPZ2FmmmTKPgzaMKdhu6EWZcTpLy1Vhx8uvZe7NZ",
    "9bnz4RShgq1hAnLnZbP8kbgBg1kEmcJBYQq3gQbmnSta",
    "5VY91ws6B2hMmBFRsXkoAAdsPHBJwRfBht4DXox3xkwn",
    "2nyhqdwKcJZR2vcqCyrYsaPVdAnFoJjiksCXJ7hfEYgD",
    "2q5pghRs6arqVjRvT5gfgWfWcHWmw1ZuCzphgd5KfWGJ",
    "wyvPkWjVZz1M8fHQnMMCDTQDbkManefNNhweYk5WkcF",
    "3KCKozbAaF75qEU33jtzozcJ29yJuaLJTy2jFdzUY8bT",
    "4vieeGHPYPG2MmyPRcYjdiDmmhN3ww7hsFNap8pVN3Ey",
    "4TQLFNWK8AovT1gFvda5jfw2oJeRMKEmw7aH6MGBJ3or"
  ];

  // Load signer from base58 private key
  const ownerSigner = await createKeyPairSignerFromBytes(bs58.decode(PRIV_KEY_B58));

  // Init RPC and fetch blockhash
  const rpc = createSolanaRpc(`https://mainnet.helius-rpc.com/?api-key=${HELIUS_API_KEY}`);
  const { value: blockhash } = await rpc.getLatestBlockhash().send();

  // Build and sign transaction
  const tx = pipe(
    createTransactionMessage({ version: 0 }),
    (m) => setTransactionMessageFeePayerSigner(ownerSigner, m),
    (m) => setTransactionMessageLifetimeUsingBlockhash(blockhash, m),
    (m) => appendTransactionMessageInstruction(getSetComputeUnitLimitInstruction({ units: 1000 }), m),
    (m) => appendTransactionMessageInstruction(getSetComputeUnitPriceInstruction({ microLamports: 200_000 }), m),
    (m) =>
      appendTransactionMessageInstruction(
        getTransferSolInstruction({
          source: ownerSigner,
          destination: RECIPIENT,
          amount: lamports(1_000_000n), // 0.001 SOL
        }),
        m
      ),
    (m) =>
      appendTransactionMessageInstruction(
        getTransferSolInstruction({
          source: ownerSigner,
          destination: TIP_ACCOUNTS[Math.floor(Math.random() * TIP_ACCOUNTS.length)],
          amount: lamports(200_000n), // 0.0002 SOL
        }),
        m
      )
  );

  const signedTx = await signTransactionMessageWithSigners(tx);
  const base64Tx = getBase64EncodedWireTransaction(signedTx);

  // Send via Sender
  const res = await fetch("https://sender.helius-rpc.com/fast", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({
      jsonrpc: "2.0",
      id: Date.now().toString(),
      method: "sendTransaction",
      params: [
        base64Tx,
        { encoding: "base64", skipPreflight: true, maxRetries: 0 },
      ],
    }),
  });

  const { result: sig, error } = await res.json();
  if (error) throw new Error(error.message);

  console.log("Transaction sent: ", sig);
  console.log(`Explorer: https://orb.helius.dev/tx/${sig}?cluster=mainnet`);
})();

Наш SDK для Node.js упрощает отправку транзакций через Sender. Метод `sendTransactionWithSender` динамически выполняет все расчёты вычислительных единиц и комиссий, включая чаевые Jito: 

A Streamlined Sender Example Using the Node.js SDK
import { createHelius } from "helius-sdk";
import { address, createKeyPairSignerFromBytes, lamports } from "@solana/kit";
import { getTransferSolInstruction } from "@solana-program/system";
import bs58 from "bs58";

(async () => {
  const apiKey = ""; // From Helius dashboard
  const helius = createHelius({ apiKey });

  try {
    const feePayerSigner = await createKeyPairSignerFromBytes(
      bs58.decode(process.env.FEEPAYER_SECRET ?? "")
    );

    const toPubkey = address("your_to_address");

    const transferIx = getTransferSolInstruction({
      amount: lamports(1_000_000n), // 0.001 SOL
      destination: toPubkey,
      source: feePayerSigner,
    });

    const sig = await helius.tx.sendTransactionWithSender({
      signers: [feePayerSigner],
      instructions: [transferIx],
      version: 0,
      commitment: "confirmed",
      minUnits: 1_000,
      bufferPct: 0.1,
      region: "US_EAST",
      swqosOnly: true,
      pollTimeoutMs: 60_000,
      pollIntervalMs: 2_000,
    });

    console.log("Confirmed signature:", sig);
    console.log(
      `Explorer link: https://orb.helius.dev/tx/${sig}?cluster=mainnet`
    );
  } catch (error) {
    console.error("Error:", error);
  }
})();

Этот процесс также можно упростить с помощью нашего SDK для Rust, используя метод send_smart_transaction_with_sender().

Работа с LaserStream и Sender

Настоящие возможности Helius раскрываются при объединении LaserStream и Sender в единый рабочий процесс. LaserStream предоставляет полезные сигналы сразу после их появления, а Sender помогает реагирующим на них транзакциям попасть в блок как можно быстрее.

Схема проста:

  • Подпишитесь через LaserStream, чтобы отслеживать изменения аккаунтов, вызовы программ или переводы.
  • Создайте транзакцию в ответ на полученный сигнал.
  • Отправьте транзакцию через Sender, обеспечив самый быстрый и надёжный маршрут для включения.

Ниже приведён минимальный пример полного рабочего процесса: 

A unified LaserStream and Sender Workflow
import bs58 from "bs58";
import { subscribe, CommitmentLevel } from "helius-laserstream";
import {
  pipe,
  createSolanaRpc,
  createTransactionMessage,
  setTransactionMessageFeePayerSigner,
  setTransactionMessageLifetimeUsingBlockhash,
  appendTransactionMessageInstruction,
  signTransactionMessageWithSigners,
  getBase64EncodedWireTransaction,
  createKeyPairSignerFromBytes,
  lamports,
  address,
} from "@solana/kit";
import { getTransferSolInstruction } from "@solana-program/system";
import {
  getSetComputeUnitLimitInstruction,
  getSetComputeUnitPriceInstruction,
} from "@solana-program/compute-budget";

const HELIUS_API_KEY = "your_api_key";
const LASERSTREAM_ENDPOINT = "https://laserstream-mainnet-ewr.helius-rpc.com"; // Pick the nearest region
const PRIV_KEY_B58 = "your_private_key";
const RECIPIENT = "recipient_address";
const TIP_ACCOUNTS = [
    "4ACfpUFoaSD9bfPdeu6DBt89gB6ENTeHBXCAi87NhDEE",
    "D2L6yPZ2FmmmTKPgzaMKdhu6EWZcTpLy1Vhx8uvZe7NZ",
    "9bnz4RShgq1hAnLnZbP8kbgBg1kEmcJBYQq3gQbmnSta",
    "5VY91ws6B2hMmBFRsXkoAAdsPHBJwRfBht4DXox3xkwn",
    "2nyhqdwKcJZR2vcqCyrYsaPVdAnFoJjiksCXJ7hfEYgD",
    "2q5pghRs6arqVjRvT5gfgWfWcHWmw1ZuCzphgd5KfWGJ",
    "wyvPkWjVZz1M8fHQnMMCDTQDbkManefNNhweYk5WkcF",
    "3KCKozbAaF75qEU33jtzozcJ29yJuaLJTy2jFdzUY8bT",
    "4vieeGHPYPG2MmyPRcYjdiDmmhN3ww7hsFNap8pVN3Ey",
    "4TQLFNWK8AovT1gFvda5jfw2oJeRMKEmw7aH6MGBJ3or"
  ];

// Example: scope the stream to a program you care about
const PROGRAM_OWNER_TO_WATCH = "11111111111111111111111111111111";

(async () => {
  // Setup signer and fetch blockhash
  const ownerSigner = await createKeyPairSignerFromBytes(bs58.decode(PRIV_KEY_B58));
  const rpc = createSolanaRpc(`https://mainnet.helius-rpc.com/?api-key=${HELIUS_API_KEY}`);

  // Setup LaserStream config and request
  const config = {
    apiKey: HELIUS_API_KEY,
    endpoint: LASERSTREAM_ENDPOINT,
  };

  // We keep it scoped to a given program for less noise
  const request = {
    accounts: {
      watch: {
        account: [],
        owner: [PROGRAM_OWNER_TO_WATCH],
        filters: [],
      },
    },
    commitment: CommitmentLevel.PROCESSED, // Can also change to CONFIRMED for more reliability
    slots: {},
    transactions: {},
    transactionsStatus: {},
    blocks: {},
    blocksMeta: {},
    entry: {},
    accountsDataSlice: [],
  };

  // On signal, build and send a reactive transaction via Sender
  const handleData = async () => {
    // Fresh blockhash for lifetime
    const { value: blockhash } = await rpc.getLatestBlockhash().send();

    // Build the transaction with compute-budget ixs first, then user ixs
    const tx = pipe(
      createTransactionMessage({ version: 0 }),
      (m) => setTransactionMessageFeePayerSigner(ownerSigner, m),
      (m) => setTransactionMessageLifetimeUsingBlockhash(blockhash, m),
      (m) => appendTransactionMessageInstruction(getSetComputeUnitLimitInstruction({ units: 100_000 }), m),
      (m) => appendTransactionMessageInstruction(getSetComputeUnitPriceInstruction({ microLamports: 200_000 }), m),
      (m) =>
        // In prod, this could be a buy / sell instruction
        appendTransactionMessageInstruction(
          getTransferSolInstruction({
            source: ownerSigner,
            destination: address(RECIPIENT),
            amount: lamports(1_000_000n), // 0.001 SOL
          }),
          m
        ),
      (m) =>
        appendTransactionMessageInstruction(
          getTransferSolInstruction({
            source: ownerSigner,
            destination: address(TIP_ACCOUNTS[Math.floor(Math.random() * TIP_ACCOUNTS.length)]),
            amount: lamports(200_000n), // 0.0002 SOL tip
          }),
          m
        )
    );

    const signedTx = await signTransactionMessageWithSigners(tx);
    const base64Tx = getBase64EncodedWireTransaction(signedTx);

    // Send via Sender (i.e., skip preflight and no RPC-side retries)
    const res = await fetch("https://sender.helius-rpc.com/fast", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({
        jsonrpc: "2.0",
        id: Date.now().toString(),
        method: "sendTransaction",
        params: [base64Tx, { encoding: "base64", skipPreflight: true, maxRetries: 0 }],
      }),
    });

    const { result: sig, error } = await res.json();
    if (error) throw new Error(error.message);

    console.log("Reactive transaction sent: ", sig);
    console.log(`Explorer:  https://orb.helius.dev/tx/${sig}?cluster=mainnet`);
  };

  const handleError = console.error;

  // Start the stream (signals → reactive sends)
  const stream = await subscribe(config, request, handleData, handleError);
  console.log(`LaserStream subscription started (id: ${stream.id})`);
})();

Почему Helius

Helius — лучший выбор для оптимизации процессов работы с транзакциями в Solana благодаря тому, что мы являемся крупнейшим валидатором сети по объёму стейка. Поэтому пропускная способность со стейком для нас не проблема. Это фактически устраняет узкие места и сбои, связанные со снижением приоритета транзакций или потерей пакетов при перегрузке, и предоставляет вашим транзакциям прямой высокоприоритетный маршрут к лидерам без ограничений. 

Глубоко интегрируя различные аппаратные и программные оптимизации с нашей пропускной способностью со стейком, Helius сохраняет лидерство среди провайдеров и обеспечивает самую низкую среднюю задержку в слотах. Это подтверждает нашу вертикальную экспертизу в Solana. 

Наша приверженность Solana позволяет нам оставаться в авангарде новых исследований и разработок. Например, результаты исследования Chorus One о задержке транзакций показывают, что SWQoS нередко превосходит Jito по скорости включения, особенно для пользователей с задержкой p95 более 40 секунд. Sender интеллектуально направляет транзакции одновременно через SWQoS и Jito, обеспечивая максимальную надёжность для всех типов транзакций. 

В конечном счёте значительный объём стейка и маршрутизация транзакций через соединения со стейком — важнейшие факторы сокращения времени до включения.

Быстрее

LaserStream снижает задержку и неопределённость. Чем раньше приходит сигнал, тем предсказуемее результат. В сочетании с Sender транзакции, отправленные в ответ на сигнал, повышают операционную уверенность, помогают принимать более взвешенные решения и улучшают надёжность. Этот единый конвейер оптимизирует не только скорость, но и уверенность в результате.

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

Вместе они дают накопительный эффект:

  • Меньше сквозная задержка: от обнаружения события до включения транзакции каждый этап занимает считаные миллисекунды
  • Выше доля успешных операций: транзакции попадают в нужное место и время, поэтому возможности используются, а не упускаются
  • Меньше инженерных затрат: можно сосредоточиться на продукте, стратегии и точной настройке торговых алгоритмов, а не на управлении выделенными нодами и их оптимизации для отправки транзакций
  • Выполнение в нулевом слоте: LaserStream отправляет уведомления во время выполнения транзакций для конкретного слота, а не после завершения слота. Поэтому транзакция, отправленная в ответ на уведомление, может попасть в тот же слот 

На практике трейдеры получают больше арбитражных возможностей, ликвидаторы выигрывают больше аукционов, а высокочастотные приложения обеспечивают более комфортное взаимодействие с пользователем. Выполнение в нулевом слоте — не далёкий теоретический идеал, а воспроизводимый рабочий процесс, доступный только с Helius.

Перейдите в панель Helius и начните работу прямо сейчас.

Подпишитесь на Helius

Следите за новостями разработки на Solana и получайте уведомления о наших публикациях

Увеличенное изображение