Розробка торгового бота для DEX на Solana (Jupiter, Raydium)
Solana теоретично обробляє 65 000 TPS при confirmation time 400ms. На практиці для торгового бота це означає: конкурентне преимущество існує, але тільки якщо ви правильно працюєте з приоритетними комісіями та розумієте механіку Solana transaction scheduling. Більшість ботів програють не через поганий алгоритм, а тому що транзакції потрапляють у кінець черги через неправильно розрахований priority fee.
Solana transaction model: чим відрізняється від EVM
На Ethereum gas price визначає приоритет. На Solana — комбінація compute units та priority fee:
- Compute units (CU) — аналог gas, лімітація обчислювальних ресурсів для транзакції. Максимум 1.4M CU на транзакцію.
- Priority fee — додаткова оплата в lamports за кожен compute unit крім базової комісії.
Обов'язкові інструкції для конкурентного бота:
import { ComputeBudgetProgram } from "@solana/web3.js";
// Встановлюємо лімітацію CU (важливо: не більше ніж потрібно)
const setComputeLimit = ComputeBudgetProgram.setComputeUnitLimit({
units: 200_000, // зазвичай для swap достатньо 100k-200k
});
// Встановлюємо priority fee
const setPriorityFee = ComputeBudgetProgram.setComputeUnitPrice({
microLamports: 100_000, // 0.1 lamport per CU = 0.02 SOL на 200k CU
});
transaction.add(setComputeLimit, setPriorityFee, ...swapInstructions);
Неправильно розраховану лімітацію CU у меншу сторону → транзакція fails з exceeded compute budget. У більшу сторону → переплата та зниження приоритету (validators оптимізують throughput по fee/CU ratio).
Динамічний розрахунок priority fee: використовуємо getRecentPrioritizationFees RPC метод, повертає останні fee рівні для аккаунтів, задіяних у транзакції. Беремо 75-90 percentile для високого приоритету.
Jupiter: агрегація маршрутів
Jupiter — de-facto стандартний агрегатор ліквідності на Solana. Агрегує Raydium, Orca, Meteora, Lifinity та 20+ ще DEX/AMM. API v6 — найактуальніша версія.
Quote API
const quote = await fetch(`https://quote-api.jup.ag/v6/quote?` + new URLSearchParams({
inputMint: "So11111111111111111111111111111111111111112", // SOL
outputMint: USDC_MINT,
amount: "1000000000", // 1 SOL у lamports
slippageBps: "50", // 0.5%
onlyDirectRoutes: "false",
maxAccounts: "64", // обмеження аккаунтів у транзакції
}));
const quoteData = await quote.json();
// quoteData.outAmount — очікуваний вивід у USDC
// quoteData.priceImpactPct — price impact у процентах
maxAccounts: 64 — критичний параметр. Solana транзакція обмежена 64 унікальними аккаунтами. Складний маршрут через 4-5 протоколів може перевищити лімітацію → TooManyAccounts ошибка. Обмеження зменшує оптимальність маршруту, але гарантує исполнимость.
Swap execution
Після отримання quote — виконання через Swap API:
const swapResponse = await fetch("https://quote-api.jup.ag/v6/swap", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
quoteResponse: quoteData,
userPublicKey: wallet.publicKey.toString(),
wrapAndUnwrapSol: true,
dynamicComputeUnitLimit: true, // автоматичний розрахунок CU
prioritizationFeeLamports: "auto", // автоматичний priority fee
}),
});
const { swapTransaction } = await swapResponse.json();
// Десеріалізуємо, підписуємо, відправляємо
const tx = VersionedTransaction.deserialize(Buffer.from(swapTransaction, "base64"));
tx.sign([wallet]);
const txid = await connection.sendRawTransaction(tx.serialize(), {
skipPreflight: false,
maxRetries: 3,
});
dynamicComputeUnitLimit: true — Jupiter автоматично симулює транзакцію та встановлює правильний CU лімітацію. Рекомендується для production.
Raydium: пряма інтеграція
Jupiter працює поверх Raydium, але для latency-sensitive операцій пряма інтеграція з Raydium CLMM (Concentrated Liquidity Market Maker) швидша.
Raydium SDK v2:
import { Raydium, TxVersion } from "@raydium-io/raydium-sdk-v2";
import { PublicKey } from "@solana/web3.js";
const raydium = await Raydium.load({
owner: wallet,
connection,
disableFeatureCheck: true,
});
// Отримуємо інформацію про пул
const poolInfo = await raydium.clmm.getPoolInfoFromRpc(POOL_ID);
// Будуємо swap транзакцію
const { transaction } = await raydium.clmm.swap({
poolInfo,
ownerInfo: { useSOLBalance: true },
inputMint: new PublicKey(INPUT_MINT),
amountIn: new BN(amount),
amountOutMin: new BN(minAmountOut),
observationId: poolInfo.observationId,
txVersion: TxVersion.V0, // Versioned transactions
});
Versioned Transactions (V0) з Address Lookup Tables — обов'язкові для complex multi-hop swaps. Дозволяють включати більше аккаунтів через ALT стиснення.
Latency оптимізація
Для конкурентного бота latency вимірюється не у секундах — у мілісекундах:
Jito bundling. Jito — MEV-інфраструктура на Solana. Bundle з кількох транзакцій відправляється прямо до Jito block engine, мінуючи стандартний gossip. Переваги: atomic виконання кількох транзакцій у одному блоці, перший слот у блоці.
import { searcherClient } from "jito-ts/dist/sdk/block-engine/searcher";
const client = searcherClient(JITO_BLOCK_ENGINE_URL, keypair);
const bundle = new Bundle([tx1, tx2], 5); // max 5 transactions
await client.sendBundle(bundle);
Jito взимає tip — мінімум 1000 lamports per bundle, реально при конкурентних умовах 10 000 - 100 000+ lamports.
Geyser plugin / Yellowstone. Для real-time мониторингу on-chain даних (зміни пулів, нові транзакції) — Solana Geyser plugin через Yellowstone gRPC. Latency 5-20ms vs 200-500ms через стандартний RPC polling.
Географічне розташування. Серверы нод кластеру Solana сконцентровані у певних датацентрах. Розташування бота близько до validator nodes — Amsterdam, Frankfurt для Європи, Ashburn для США — знижує network latency на 10-50ms.
Мониторинг та управління ризиками
Transaction confirmation tracking: confirmTransaction через WebSocket subscription набагато швидше ніж polling. Статусы: processed → confirmed → finalized.
Failed transaction handling: При ошибці BlockhashNotFound (застарілий blockhash) — автоматично fetch новий blockhash та retry. При SlippageToleranceExceeded — пересчитати quote та retry з актуальними даними.
Capital management: Окремий keypair для кожної торгової стратегії. Ніколи не тримаємо весь баланс у hot wallet. Hardware wallet або KMS для long-term storage.
Порівняння підходів: Jupiter API vs пряма інтеграція
| Параметр | Jupiter API | Пряма інтеграція (Raydium SDK) |
|---|---|---|
| Оптимальність маршруту | Висока (20+ DEX) | Нижча (один протокол) |
| Latency quote | ~100-200ms | ~20-50ms (on-chain) |
| Maintenance | Мінімальна | SDK оновлення |
| Складність | Низька | Висока |
| Кастомізація | Обмежена | Повна |
Для більшості ботів Jupiter API — правильний вибір: найкращі ціни, менше коду. Пряма інтеграція з Raydium — тільки якщо потрібна sub-50ms latency або спеціфічна взаємодія з пулами (LP management, concentrated liquidity range orders).
Процес розробки
Аналітика (2-3 дні). Визначення стратегії, вибір Jupiter API vs пряма інтеграція, визначення вимог до latency та обсягу.
Розробка core бота (1-2 тижні). WebSocket мониторинг, quote engine, execution з priority fees, Jito bundling (якщо потрібно).
Risk management та мониторинг (3-5 днів). Slippage захист, failed tx handling, Telegram алерти, метрики.
Оптимізація (3-5 днів). Профілювання latency, оптимізація CU usage, тюнинг priority fees під реальний трафік.
Орієнтири за часом
Базовий бот з Jupiter API та автоматичним priority fee — 1 тиждень. Конкурентний бот з Jito bundling, Geyser мониторингом та кастомними стратегіями — 2-3 тижні. Вартість розраховується індивідуально.







