Skip to main content
Эта страница переведена с помощью ИИ. За эталон принимается английская версия.Открыть английскую версию →
Информация о версии. Все примеры используют @raydium-io/raydium-sdk-v2@0.2.42-alpha на Solana mainnet-beta, проверено в апреле 2026 г. Идентификаторы программ берутся из reference/program-addresses через SDK.

Настройка

Каждый пример на этой странице соответствует файлу в raydium-sdk-V2-demo/src/clmm; ссылка на GitHub находится рядом с каждым разделом. Инициализация следует файлу config.ts.template из репозитория демонстрации (источник) — disableFeatureCheck: true — рекомендуемая настройка для любой нетривиальной интеграции:

Создание пула CLMM

Источник: src/clmm/createPool.ts
SDK:
  • Сортирует mint1/mint2 по порядку байтов перед выведением.
  • Вычисляет sqrt_price_x64 = floor(sqrt(initialPrice × 10^(dB−dA)) × 2^64).
  • Создаёт учётные записи observation и tick_array_bitmap_extension.
  • Оплачивает комиссию за создание пула, определённую в ammConfig.

Открытие позиции в выбранном диапазоне

Источник: src/clmm/createPosition.ts
SDK автоматически вычисляет, какие массивы тиков затрагивает диапазон, и объединяет инструкции InitTickArray, если какие-либо из них не инициализированы.

Увеличение ликвидности на существующей позиции

Источник: src/clmm/increaseLiquidity.ts

Уменьшение ликвидности (и сбор комиссий одновременно)

Источник: src/clmm/decreaseLiquidity.ts и src/clmm/closePosition.ts
Чтобы собрать только комиссии, вызовите decreaseLiquidity с liquidity = new BN(0). Побочный эффект инструкции — это урегулирование tokens_fees_owed_{0,1} и их передача. Чтобы полностью закрыть позицию после обнуления ликвидности и комиссий, передайте closePosition: true при последнем вызове decreaseLiquidity. SDK добавляет ClosePosition и сжигает NFT.
Позиции с ограниченным эмитентом требуют совместимого построителя закрытия. Эти позиции имеют замороженный счёт токена NFT. ClosePosition должен добавить идентификатор пула позиции в качестве первого оставшегося счёта, чтобы CLMM мог разморозить счёт перед сжиганием. Ветка исходного кода программы не включает изменение SDK. Убедитесь, что ваш выпуск SDK явно поддерживает путь замороженного закрытия перед включением создания позиций с ограниченным эмитентом.
Для прямого клиента Anchor оставьте объявленные счета без изменений и добавьте пул:
Вы можете передать poolId при каждом закрытии. CLMM читает его только когда positionNftAccount заморожен, что сохраняет один путь клиента совместимым со старыми и новыми позициями.

Сбор вознаграждений

Источник: src/clmm/harvestAllRewards.ts
harvestAllRewards проходит по каждой позиции в каждом переданном пуле, объединяет инструкции CollectReward (и любые UpdateRewardInfos), и разбивает их на несколько транзакций при необходимости.

Своп

Источник: src/clmm/swap.ts
computeAmountOutFormat проходит по карте тиков в автономном режиме, используя ту же логику, что и программа на цепи, и возвращает:
  • ожидаемое количество на выходе,
  • минимальное количество на выходе после проскальзывания,
  • список счетов массива тиков, которые коснётся фактический своп (remainingAccounts).
Всегда передавайте remainingAccounts, возвращённые симуляцией: если вы передадите слишком мало, своп откатится в середине обхода с ошибкой TickArrayNotFound; если вы передадите устаревшие, будет потрачено вычисление.

Создание настраиваемого пула CLMM

createCustomizablePool — это новая точка входа, которая раскрывает переключатели динамической комиссии и односторонней комиссии во время создания пула. Она имеет ту же форму, что и createPool, плюс три дополнения:
createPool продолжает работать для пути с комиссией по умолчанию, без лимитных ордеров и без динамической комиссии. Используйте createCustomizablePool всякий раз, когда вам нужен любой из трёх новых переключателей. См. products/clmm/instructions для списка учётных записей на цепи.

Лимитные ордеры

Лимитный ордер паркует пользовательский ввод на одном тике и заполняется FIFO, когда своп пересекает этот тик. Выходы отправляются на ATA владельца во время расчёта; владельцу не нужно быть в сети, чтобы быть заполненным.

Открытие лимитного ордера

SDK выводит PDA LimitOrderState из (pool, owner, tick, nonce), увеличивает LimitOrderNonce для каждого (pool, owner) и вставляет ордер в когорту FIFO на этом тике.

Увеличение / уменьшение открытого ордера

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

Расчёт заполненного ордера

settleLimitOrder читает unfilled_ratio_x64 ордера в отношении трекера когорты, вычисляет заполненный выход и передаёт его на ATA владельца. Владелец может вызвать это сам; limit_order_admin (автономный оперативный хранитель) также может вызвать это от имени владельца — выход всё равно идёт владельцу. Для закрытия полностью расчётных ордеров для восстановления ренты используйте closeLimitOrder (одиночный) или closeAllLimitOrder (пакетный). Для расчёта многих одновременно settleAllLimitOrder упаковывает столько вызовов SettleLimitOrder, сколько поместится в транзакцию v0.

Список припаркованных ордеров кошелька (автономно)

Конечная точка активных ордеров возвращает как незаполненные, так и частично заполненные ордеры в одном полезном грузе (totalAmount / filledAmount / pendingSettle различают фазы). Для истории закрытых ордеров используйте /limit-order/history/order/list-by-user?wallet=… (по кошельку, разбито на страницы по nextPageId); для полного журнала событий конкретного ордера используйте /limit-order/history/event/list-by-pda?pda=….

Скелет Rust CPI

Порядок оставшихся счетов для SwapV2:
Если своп никогда не нуждается в расширении, опустите его; в противном случае это первый оставшийся счёт.

Распространённые ошибки

  • Конечные точки тика не по интервалуInvalidTickIndex. Всегда привязывайте через TickUtils.getPriceAndTick.
  • Недостаточно массивов тиков в SwapV2TickArrayNotFound. Используйте computeAmountOutFormat для получения полного списка.
  • Позиция полного диапазона без расширения растрового изображения → PDA расширения должен быть записываемым; SDK обрабатывает это автоматически.
  • Путаница sqrt_price_x64 с price → ошибка в коэффициенте 2 здесь особенно болезненна. Если сомневаетесь, позвольте SDK вычислить это из читаемой человеком цены.
  • Слишком частый сбор вознаграждений → каждый сбор стоит одну транзакцию. Объединяйте через harvestAllRewards по многим позициям.
  • Самостоятельное закрытие счетов NFTClosePosition сжигает NFT и закрывает его ATA. Он также закрывает монету NFT Token-2022; классическая монета SPL Token остаётся с нулевым предложением, потому что эта программа не может закрывать монеты. Не закрывайте поддерживаемые счета отдельно, иначе инструкция откатится.
  • Открытие лимитного ордера на тике не по интервалуInvalidTickIndex. Всегда квантуйте через TickUtils.getPriceAndTick.
  • Вызов decreaseLimitOrder на полностью заполненном ордереInvalidOrderPhase. Вместо этого используйте settleLimitOrder, затем closeLimitOrder.
  • Забыли dynamicFeeConfigId при передаче enableDynamicFee: true → откат CreateCustomizablePool — это InvalidDynamicFeeConfigParams. Либо отключите динамическую комиссию, либо выберите конфиг из /main/clmm-dynamic-config.

Что дальше

Источники: