Перейти к основному содержанию

Documentation Index

Fetch the complete documentation index at: https://docs.raydium.io/llms.txt

Use this file to discover all available pages before exploring further.

Эта страница переведена с помощью ИИ. За эталон принимается английская версия.Открыть английскую версию →
Информация о версии.
  • SDK: @raydium-io/raydium-sdk-v2@0.2.42-alpha
  • Кластер: Solana mainnet-beta
  • ID программы Stable AMM: 5quBtoiQqxF9Jv6KYKctB59NT3gtJD2Y65kdnB1Uev3h (см. reference/program-addresses)
  • Последняя проверка: 2026-04
Модуль liquidity SDK изначально поддерживает пулы Stable AMM. Стабильные пулы отображаются как version: 5 (или pooltype: "StablePool") на ApiV3PoolInfoStandardItem; те же вспомогательные функции addLiquidity / removeLiquidity / swap работают для них так же, как для пулов constant-product AMM v4 (version: 4) — SDK определяет вариант и автоматически генерирует правильные инструкции. Off-chain математика стабильной кривой находится в src/raydium/liquidity/stable.ts.

Установка

npm install @raydium-io/raydium-sdk-v2 @solana/web3.js @solana/spl-token
import { Raydium, TxVersion } from "@raydium-io/raydium-sdk-v2";
import { Connection, Keypair, clusterApiUrl } from "@solana/web3.js";
import BN from "bn.js";
import bs58 from "bs58";

const connection = new Connection(clusterApiUrl("mainnet-beta"));
const owner = Keypair.fromSecretKey(bs58.decode(process.env.PRIVATE_KEY!));

const raydium = await Raydium.load({
  connection,
  owner,
  cluster: "mainnet",
  // Опционально: загрузите раскладку модели стабильной кривой, если вы
  // намеревайтесь вызывать вспомогательные функции для подсчёта цены из
  // `liquidity/stable.ts` напрямую. Функции swap / add / remove на уровне
  // пула делают это ленивым образом для вас, поэтому большинство вызывающих
  // могут пропустить этот шаг.
});

// Однократно: предварительно загрузите раскладку данных модели на цепи,
// используемую вспомогательными функциями off-chain для стабильной кривой.
// Требуется только если вы вызываете getStablePrice / getDxByDyBaseIn /
// getDyByDxBaseIn напрямую. addLiquidity / removeLiquidity / swap не требуют этого.
await raydium.liquidity.initLayout();

Определение пула Stable

Два эквивалентных признака на ApiV3PoolInfoStandardItem:
const isStable =
  pool.version === 5 ||
  pool.pooltype.includes("StablePool"); // SDK использует эту проверку строк внутри

// Или по ID программы:
const STABLE_AMM_PROGRAM_ID = "5quBtoiQqxF9Jv6KYKctB59NT3gtJD2Y65kdnB1Uev3h";
const isStableByProgram = pool.programId === STABLE_AMM_PROGRAM_ID;
Как AMM v4 (version: 4, constant-product), так и Stable AMM (version: 5) проходят через один и тот же API LiquidityModule в SDK. Внутри модуль распределяет работу между:
  • InstructionType.AmmV4AddLiquidity / AmmV4RemoveLiquidity для пулов v4
  • InstructionType.AmmV5AddLiquidity / AmmV5RemoveLiquidity для пулов v5 (Stable)
programId пула (возвращаемый вместе с ключами пула) подсказывает SDK, в какую программу выполнить CPI; вам не нужно его жёстко кодировать.

Поиск пула по паре монет

import { PublicKey } from "@solana/web3.js";

// Две общепринятые монеты для использования в качестве примера
const mintA = new PublicKey("Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB"); // USDT
const mintB = new PublicKey("EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v"); // USDC

const pools = await raydium.api.fetchPoolByMintPair({
  mint1: mintA.toBase58(),
  mint2: mintB.toBase58(),
});

const stablePool = pools.find(
  (p) => p.version === 5 || p.pooltype.includes("StablePool"),
);

if (!stablePool) {
  throw new Error("Для этой пары монет не существует пула Stable");
}

console.log("ID пула Stable:", stablePool.id);
console.log("ID программы пула Stable:", stablePool.programId);
console.log("TVL:", stablePool.tvl);
Если пара монет имеет как пул v4 (constant-product), так и пул v5 (stable), ответ включает оба — выберите тот, который нужен вашему потоку, или передайте их программе AMM Routing и дайте ей выбрать лучший маршрут.

Обмен через пул Stable

Поток LiquidityModule.swap имеет ту же форму, что и для пулов v4 — просто передайте ему объект пула v5:
import { Percent, TokenAmount, toToken } from "@raydium-io/raydium-sdk-v2";

const inputAmount = new TokenAmount(toToken(stablePool.mintA), 1_000_000); // 1 USDT
const slippage = new Percent(50, 10_000); // 0.5%

// Вычислите ожидаемый вывод, используя вспомогательные функции стабильной
// кривой SDK внутри.
const { amountOut, minAmountOut } = raydium.liquidity.computeAmountOut({
  poolInfo: stablePool,
  amountIn: inputAmount,
  mintIn:  stablePool.mintA.address,
  mintOut: stablePool.mintB.address,
  slippage,
});

console.log("Ожидаемый выход:", amountOut.toSignificant());
console.log("Минимальный выход:", minAmountOut.toSignificant());

// Создайте и подпишите транзакцию обмена.
const { transaction, execute } = await raydium.liquidity.swap({
  poolInfo: stablePool,
  amountIn:    inputAmount.raw,
  amountOut:   minAmountOut.raw,
  fixedSide:   "in",
  txVersion:   TxVersion.V0,
});

const { txId } = await execute({ sendAndConfirm: true });
console.log("Транзакция обмена Stable:", txId);
SDK читает programId пула из ключей пула и распределяет работу в программу Stable AMM. Специальный аргумент programId не требуется.

Добавление и удаление ликвидности

addLiquidity и removeLiquidity работают идентично для пулов v4 и v5:
import { Percent, TokenAmount, toToken } from "@raydium-io/raydium-sdk-v2";

const amountInA = new TokenAmount(toToken(stablePool.mintA), 100_000_000); // 100 USDT
const slippage  = new Percent(50, 10_000); // 0.5%

// Вычислите соответствующий размер B, который требует кривая для этого
// размера A.
const { anotherAmount, minAnotherAmount } = raydium.liquidity.computePairAmount({
  poolInfo: stablePool,
  amount:   amountInA.toSignificant(),
  baseIn:   true,
  slippage,
});

const { execute } = await raydium.liquidity.addLiquidity({
  poolInfo: stablePool,
  amountInA,
  amountInB:      anotherAmount,
  otherAmountMin: minAnotherAmount,
  fixedSide:      "a",
  txVersion:      TxVersion.V0,
});

const { txId } = await execute({ sendAndConfirm: true });
console.log("Транзакция добавления ликвидности:", txId);
Внутри SDK генерирует InstructionType.AmmV5AddLiquidity, потому что pooltype.includes("StablePool") имеет значение true. Соответствующий поток removeLiquidity симметричен — передайте lpAmount и минимальные размеры, которые вы примете с каждой стороны.

Вспомогательные функции off-chain quote (stable.ts)

Для server-side расчётов цены или backtesting SDK предоставляет базовую математику стабильной кривой:
import {
  getStablePrice,
  getDxByDyBaseIn,
  getDyByDxBaseIn,
} from "@raydium-io/raydium-sdk-v2";

// Вы должны вызвать initLayout() один раз перед использованием этих функций
// (загружает раскладку `ModelDataInfo` на цепи в кэш StableLayout SDK).
await raydium.liquidity.initLayout();

const modelData = raydium.liquidity.stableLayout;

// Спотовая цена при текущих резервах пула.
const price = getStablePrice(modelData, /* x */, /* y */, /* withFee */);
console.log("Спотовая цена:", price);

// Расчёт: дано dx на входе, сколько dy на выходе (без применения комиссии)?
const dyOut = getDyByDxBaseIn(modelData, /* x */, /* y */, /* dx */);

// Расчёт: дано целевое dy на выходе, сколько dx на входе потребуется?
const dxIn  = getDxByDyBaseIn(modelData, /* x */, /* y */, /* dy */);
Это чистые функции — без RPC, без подписей. Данные ModelDataInfo на цепи загружаются один раз функцией initLayout() и кэшируются в raydium.liquidity.stableLayout. Передайте текущие резервы (x, y), и вспомогательные функции рассчитают, выполняя двоичный поиск в таблице поиска и линейно интерполируя между двумя окружающими строками DataElement. См. products/stable/math для базового алгоритма.

Маршрутизация через AMM Routing (multi-hop / лучшая цена)

Если вы не хотите самостоятельно выбирать площадку, программа AMM Routing рассмотрит все пулы Raydium AMM (v4 / CPMM / CLMM / Stable) и проведёт маршрут через ту комбинацию, которая лучше всего:
const route = await raydium.tradeV2.fetchRoutes({
  inputMint:  mintA,
  outputMint: mintB,
  amount:     new BN(1_000_000),
  slippage,
});

// route.routes[0].poolType подскажет вам, какие программы использует лучший
// маршрут; "Stable" появляется здесь всякий раз, когда пул Stable является
// частью оптимального пути.
console.log(route.routes[0]);

const { execute } = await raydium.tradeV2.swap({
  inputMint:    mintA,
  outputMint:   mintB,
  inputAmount:  new BN(1_000_000),
  swapResult:   route.routes[0],
  slippage,
  txVersion:    TxVersion.V0,
});

const { txId } = await execute({ sendAndConfirm: true });
Это рекомендуемый путь для производственных обменов и агрегаторов — вам никогда не нужно вручную решать, существует ли пул Stable или является ли он лучшей площадкой сегодня.

Рекомендации

  1. Для обменов конечных пользователей предпочитайте поток маршрутизации tradeV2. Он обрабатывает все типы пулов Raydium, включая Stable.
  2. Для операций, специфичных для пула (добавление / удаление LP в известном пуле Stable) используйте LiquidityModule напрямую — он автоматически определяет пулы v5.
  3. Для off-chain расчёта цены / аналитики вызывайте getStablePrice / getDyByDxBaseIn / getDxByDyBaseIn после initLayout(). Нет RPC-трафика за расчёт после кэширования данных модели.
  4. Не кодируйте вручную сырые инструкции SwapBaseIn. Программа Stable AMM (разветвлённая от AMM v4) ожидает 17–19 счётов OpenBook для V1 swap entrypoints, с model_data_account среди них. Встроенные вспомогательные функции SDK правильно обрабатывают каждый счёт и порядок; самостоятельная реализация подвержена ошибкам.

Что дальше

  • Math — как работает интерполяция таблицы поиска.
  • Instructions — полный справочник инструкций.
  • AMM Routing — маршрутизация между несколькими пулами через AMM v4, CPMM, CLMM, Stable.
Источники: