Skip to main content
Эта страница переведена с помощью ИИ. За эталон принимается английская версия.Открыть английскую версию →
Баннер версии. Все примеры ориентированы на @raydium-io/raydium-sdk-v2@0.2.64-alpha для Solana mainnet-beta, проверено 2026-09-09 — каждое имя построителя, имя параметра и тип параметра ниже были проверены против src/raydium/farm/ этого релиза и против raydium-sdk-V2-demo/src/farm. SDK внутренне отправляет v3 / v5 / v6 в зависимости от владельца программы фермы; примеры ниже предполагают ферму v6. Три ID программ см. в reference/program-addresses.Имена методов модуля фермы не совпадают с ожиданиями: нет getFarmById и нет setRewards. Получение данных происходит через raydium.api.fetchFarmInfoById, а построители редактирования вознаграждений — это addNewRewardToken / addNewRewardsToken и restartReward / restartRewards.

Настройка

Примеры здесь отражают файлы в raydium-sdk-V2-demo/src/farm. Инициализация следует config.ts.template репозитория примеров:

Получить ферму по ID

Нет raydium.farm.getFarmById. Каждый пример фермы начинается с модуля API, который возвращает нормализованную форму FormatFarmInfoOut, которую принимают deposit / withdraw / harvestAllRewards:
fetchFarmInfoById принимает строку ID, разделённую запятыми, и возвращает массив, поэтому один вызов может загрузить весь портфель. Если вам нужны сырые ключи аккаунтов вместо информации отображения, raydium.api.fetchFarmKeysById({ ids }) возвращает хранилища и PDA полномочий; SDK вызывает это внутренне для вас в каждом построителе ниже.

Стейк LP токенов

Источник: src/farm/stake.ts
SDK обрабатывает предварительное урегулирование любых ожидающих вознаграждений, поэтому если этот кошелёк уже имеет стейк в этой ферме, инструкция выплатит накопленные вознаграждения на ATA пользователя в той же транзакции.

Только сбор (harvest)

Источник: src/farm/harvest.ts farmInfoList — это Record, индексированный по ID фермы, а не массив, и построитель возвращает несколько транзакций — поэтому execute должен получить sequentially: true:
Построитель упаковывает столько ферм на транзакцию, сколько позволяет лимит 1232 байта, и разбивает остаток на последующие транзакции, поэтому он возвращает txIds вместо одного txId. Для одной фермы используйте идиому amount: 0 — это то, что делает src/farm/harvest.ts на каждой версии, включая v6:

Вывод стейка

Источник: src/farm/unstake.ts

Создание фермы v6

Источник: src/farm/createAmmFarm.ts и editAmmFarm.ts create принимает объект информации пула для пула, чей LP mint стейкится (не голый mint), и каждая запись rewardInfos — это FarmRewardInfo: { mint: PublicKey, perSecond: string, openTime: number, endTime: number, rewardType: "Standard SPL" | "Option tokens" }. Времена — это простые секунды, а perSecond — это строка, не BN. programId по умолчанию — это программа v6, поэтому вы редко её передаёте.
Ключевые моменты:
  • perSecond — это скорость эмиссии в секунду в сырых единицах mint вознаграждения, передаётся как десятичная строка. SDK упаковывает её в представление с фиксированной точкой на цепи перед отправкой.
  • Полный бюджет (perSecond × (endTime − openTime)) должен присутствовать в вашем ATA вознаграждения — create перемещает его в хранилище вознаграждения атомарно.
  • Token-2022 mint вознаграждений не поддерживаются построителями фермы SDK в этой версии SDK; используйте обычный SPL mint для вознаграждений.
  • Вы можете инициализировать до 5 вознаграждений в одном вызове create. Список аккаунтов растёт на (reward_mint, reward_vault, sender_ata, token_program) за каждый дополнительный поток; помните о лимите размера транзакции 1232 байта. Для 4+ вознаграждений создавайте с 1–2 и используйте addNewRewardsToken в последующих транзакциях.

Добавить новый поток вознаграждения

Нет raydium.farm.setRewards. Два построителя, которые изменяют вознаграждения фермы, — это addNewRewardToken / addNewRewardsToken (занимают свободный слот с новым mint) и restartReward / restartRewards (переактивируют слот, чей поток закончился). Оба принимают объекты FarmRewardInfo в точно такой же форме, как create.
Дельта бюджета (perSecond × duration) извлекается из ATA плательщика как часть транзакции. Базовая инструкция не может сократить поток, не может снизить per_second на активном потоке и не может изменить mint слота — чтобы поменять mint, дождитесь end_time и используйте addNewRewardsToken на освобождённом слоте, или создайте новую ферму.
restartRewards и addNewRewardsToken каждый возвращают построитель, поэтому одна транзакция может сделать оба. src/farm/editAmmFarm.ts показывает паттерн: editFarmBuilder.builder.addInstruction(addNewRewardBuildData.builder.AllTxData), затем один versionBuild({ txVersion }).

Перезапустить завершённый поток

Источник: src/farm/editAmmFarm.ts restartRewards принимает newRewardInfos (множественное число, массив); restartReward — это форма для одного элемента и принимает newRewardInfo. Поле mint — это mint, а не rewardMint, и оно должно совпадать со слотом, который уже существует на ферме — построитель ищет слот по mint и выдаёт ошибку, если его нет.
restartRewards — это только v6 — построитель читает ID программы фермы и выдаёт ошибку для ферм v3 / v5. Действительно только когда reward_state == 2 целевого слота (завершено); вызывающий должен быть reward_sender слота. Обратите внимание, что openTime >= endTime отклоняется на стороне клиента перед любым RPC.

Rust CPI

Нет крейта raydium_farm_v6 Anchor. Крейта с таким именем не существует на crates.io, программа Farm v6 не публикует IDL на цепи (ни устаревший аккаунт anchor:idl, ни запись в Program Metadata программе), и нет публичного репозитория исходного кода для неё. Более ранняя версия этой страницы показывала пример raydium_farm_v6::cpi::deposit; он не компилировался ни против чего и был удалён.
Farm v6 был последний раз развёрнут 2024-05-13 и не является программой Anchor с точки зрения интегратора. Если вам нужно составить с ней из вашей собственной программы на цепи, постройте Instruction вручную — выведите список аккаунтов и дискриминаторы инструкций независимо (из макетов TypeScript SDK под raydium-sdk-V2/src/raydium/farm/, или декодируя реальные транзакции), и invoke_signed её. Смотрите sdk-api/rust-cpi для этой процедуры. Какой бы маршрут вы ни выбрали, хвост remaining_accounts должен совпадать с активными слотами вознаграждения фермы 1-к-1 (пары reward_vault_i, user_reward_ata_i в порядке индекса). Пропуск или неправильный порядок этих элементов приводит к молчаливому неправильному учёту — программа передаст неправильную сумму.

Подводные камни

  • Забыть сбор перед выводом. Безвредно — Withdraw сначала урегулирует ожидающие вознаграждения. Но если ваш UI показывает “сбор” отдельно от “вывода”, пользователь может подумать, что после Withdraw ещё что-то нужно собрать. Нет; всё накопленное до этого момента было выплачено.
  • total_staked = 0 во время эмиссии. Эмиссии, накопленные, пока ничего не было в стейке, теряются (формула обновления reward_per_share делит на 0 и программа пропускает обновление). Для программ с запланированным open_time запустите “seed stake” в open_time, чтобы избежать этого.
  • Комиссии передачи Token-2022. На фермах v6 с mint вознаграждений Token-2022 комиссия передачи применяется при эмиссии (хранилище → пользователь). Учитывайте это в котировках APR.
  • Малый per_second на v5. u64 скорость v5 означает, что любой per_second < 1 единица токена в секунду (на mint с ≥9 десятичными знаками это часто желаемая скорость) не может быть выражен — скорость потока округляется до 0 и ферма ничего не эмитирует. Используйте v6.

Куда дальше

Источники: