> ## 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.

# LaunchLab PlatformConfig

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

<Info>
  **Эта страница переведена с помощью ИИ. За эталон принимается английская версия.**

  [Открыть английскую версию →](/products/launchlab/platform-config)
</Info>

<Info>
  `PlatformConfig` — это **уровень платформы**, который располагается над [`GlobalConfig`](/ru/products/launchlab/global-config). Если `GlobalConfig` определяет правила протокола в целом («комиссия торговли 1%, минимум предложения 10M, только этот кошелёк может сделать градацию»), то `PlatformConfig` — это то, что каждая платформа запуска — pump.fun, собственный интерфейс Raydium, сторонние лаунчпады — использует для добавления своей комиссии, получения доли LP после градации, ограничения формы кривых для своих запусков и размещения своего брендинга (имя, сайт, изображение) в блокчейне.
</Info>

## Что это такое

Аккаунт `PlatformConfig` управляет четырьмя сквозными функциями платформы:

1. **Брендинг** — имя, сайт, ссылка на изображение, хранящиеся в самом аккаунте, чтобы любой обозреватель или агрегатор мог показать платформу, запустившую токен.
2. **Комиссия платформы** — дополнительная торговая комиссия (`fee_rate`) сверх протокольной `trade_fee_rate`. Накапливается в `platform_fee_wallet` платформы. Ограничена 100 bps параметром `GlobalConfig.max_share_fee_rate`.
3. **Распределение миграции NFT** — три целых числа (`platform_scale`, `creator_scale`, `burn_scale`), которые в сумме дают `RATE_DENOMINATOR_VALUE = 1_000_000` и разбивают LP после градации на часть, отчеканиваемую на кошелёк NFT платформы, часть на кошелёк NFT создателя и часть, сжигаемую (Burn & Earn). Имеет значение только при градации на CPMM (`migrate_type = 1`).
4. **Белый список параметров кривой** — `Vec<PlatformCurveParam>`, перечисляющий ровно те комбинации `(supply, total_base_sell, total_quote_fund_raising, migrate_type, migrate_cpmm_fee_on, vesting_params...)`, которые разрешены на этой платформе. Если вектор пуст или все записи неверны, **любая** комбинация разрешена; в противном случае запуски должны точно совпадать с одной из записей.

Вывод PDA:

```ts theme={null}
const [platformConfigPda] = PublicKey.findProgramAddressSync(
  [
    Buffer.from("platform_config"),
    platformAdmin.toBuffer(),       // публичный ключ владельца платформы
  ],
  LAUNCHLAB_PROGRAM_ID,
);
```

(См. `create_platform_config` в исходном коде для полного списка семян.)

## Структура

```rust theme={null}
// states/platform_config.rs
pub const PLATFORM_CONFIG_SEED: &str = "platform_config";
pub const NAME_SIZE: usize = 64;
pub const WEB_SIZE:  usize = 256;
pub const IMG_SIZE:  usize = 256;
pub const MAX_CREATOR_FEE_RATE: u64 = 5000;       // 50 bps (знаменатель 1_000_000)
pub const MAX_TRANSFER_FEE_RATE: u16 = 500;       // 5%   (знаменатель 10_000)
pub const MAX_CURVE_PARAMS: usize = 10;

#[account]
pub struct PlatformConfig {
    pub epoch:                       u64,
    pub platform_fee_wallet:         Pubkey,            // подписывает ClaimPlatformFee
    pub platform_nft_wallet:         Pubkey,            // получает долю NFT платформы при градации на CPMM
    pub platform_scale:              u64,               // доля LP, отчеканиваемая для платформы NFT
    pub creator_scale:               u64,               // доля LP, отчеканиваемая для NFT создателя
    pub burn_scale:                  u64,               // доля LP, сжигаемая через Burn & Earn
    pub fee_rate:                    u64,               // торговая комиссия платформы (1/1_000_000)
    pub name:                        [u8; 64],          // utf-8 дополнена нулями
    pub web:                         [u8; 256],
    pub img:                         [u8; 256],
    pub cpswap_config:               Pubkey,            // AmmConfig CPMM, который получит пул после градации
    pub creator_fee_rate:            u64,               // комиссия создателя до градации
    pub transfer_fee_extension_auth: Pubkey,            // для запусков Token-2022: кто наследует права трансфер-комиссии после градации
    pub platform_vesting_wallet:     Pubkey,
    pub platform_vesting_scale:      u64,               // доля платформы в total_locked_amount
    pub platform_cp_creator:         Pubkey,            // опциональный создатель пула CPMM после градации
    pub padding:                     [u8; 108],
    pub curve_params:                Vec<PlatformCurveParam>, // белый список разрешённых форм кривых
}
```

`platform_scale + creator_scale + burn_scale` должны равняться `1_000_000` (проверяется `MigrateNftInfo::check`). Стандартные распределения в продакшене:

* `(0, 100_000, 900_000)` — 90% LP сжигается, 10% создателю. Стандартный справедливый запуск в стиле pump.
* `(50_000, 100_000, 850_000)` — небольшая доля платформы (5%), 10% создателю, 85% сжигается.
* `(0, 0, 1_000_000)` — полное сжигание, без отчеканивания NFT. Строгие запуски «без инсайдеров».

## Поля брендинга

`name`, `web` и `img` — это встроенные массивы байтов, дополненные нулями до их констант размера. Чтобы прочитать их как строки, обрежьте до первого `\0`:

```ts theme={null}
function readString(bytes: Uint8Array): string {
  const end = bytes.indexOf(0);
  return Buffer.from(end === -1 ? bytes : bytes.subarray(0, end)).toString("utf-8");
}
```

Константы намеренно щедрые (`name: 64`, `web: 256`, `img: 256`), чтобы платформы могли включить достаточно метаданных для обозревателей и агрегаторов без обращения к off-chain хранилищу. Всё, что превышает эти размеры, отменяется при `CreatePlatformConfig` с ошибкой `InvalidInput`.

## Механика комиссий

Своп на кривой, привязанной к `PlatformConfig`, взимает три слоя комиссий:

```
trade_fee     = amount_in × global_config.trade_fee_rate    / 1_000_000
platform_fee  = amount_in × platform_config.fee_rate        / 1_000_000
creator_fee   = amount_in × platform_config.creator_fee_rate / 1_000_000

amount_after_fee = amount_in − trade_fee − platform_fee − creator_fee
```

* `trade_fee` накапливается на счету `protocol_fee_owner` протокола (снимается через `CollectFee`).
* `platform_fee` накапливается в хранилище для каждой платформы (снимается через `ClaimPlatformFee` или `ClaimPlatformFeeFromVault`; см. [`instructions`](/ru/products/launchlab/instructions)).
* `creator_fee` накапливается в хранилище для каждого создателя, ключ которого — это публичный ключ создателя + кошелёк кавычек (снимается через `ClaimCreatorFee`).

`creator_fee_rate` ограничена `MAX_CREATOR_FEE_RATE = 5000` (50 bps). `fee_rate` (комиссия платформы) ограничена `10000` (100 bps) по `GlobalConfig.max_share_fee_rate`.

## Распределение миграции NFT (только CPMM)

Когда запуск переходит на CPMM (`migrate_type = 1`, подписано `migrate_to_cpswap_wallet`), инструкция миграции разбивает отчеканенные LP токены тремя способами:

```
lp_to_platform = lp_total × platform_scale / 1_000_000   → platform_nft_wallet
lp_to_creator  = lp_total × creator_scale  / 1_000_000   → NFT создателя (Fee Key)
lp_to_burn     = lp_total × burn_scale     / 1_000_000   → программа Burn & Earn lock
```

Доли платформы и создателя обёртываются как **NFT** программой LP-Lock (`LockrWmn6K5twhz3y9w1dQERbmgSaRkfnTeTKbpofwE`) — владелец NFT может претендовать на накопленные комиссии CPMM бесконечно, но не может вывести базовую ликвидность. См. [`products/launchlab/creator-fees`](/ru/products/launchlab/creator-fees) для потока Fee Key после градации.

Доля для сжигания отправляется в программу Lock с `is_burn = true`, чтобы LP токены были постоянно недоступны — они обеспечивают ценовой минимум пула без никогда не выплачивая комиссии.

Когда `migrate_type = 0` (градация на AMM v4), поля распределения NFT игнорируются и весь LP блокируется / сжигается согласно отдельному потоку на стороне AMM v4.

## Белый список параметров кривой

`curve_params: Vec<PlatformCurveParam>` — это механизм платформы для ограничения того, какие формы кривых её запуски могут выбирать. Если вектор непуст и хотя бы одна запись верна, программа принудительно проверяет при `Initialize`, что параметры запуска совпадают с хотя бы одной записью ровно.

```rust theme={null}
#[derive(AnchorSerialize, AnchorDeserialize, Clone)]
pub struct PlatformCurveParam {
    pub epoch:                u64,
    pub index:                u8,           // порядковый номер в белом списке платформы
    pub global_config:        Pubkey,       // какой GlobalConfig применяется для этой записи
    pub bonding_curve_param:  BondingCurveParam,
    pub padding:              [u64; 50],
}

#[derive(AnchorSerialize, AnchorDeserialize, Clone)]
pub struct BondingCurveParam {
    pub migrate_type:               u8,    // 0 = AMM v4, 1 = CPMM. u8::MAX = подстановочный символ
    pub migrate_cpmm_fee_on:        u8,    // 0 = только quote, 1 = оба. u8::MAX = подстановочный символ
    pub supply:                     u64,   // 0 = подстановочный символ
    pub total_base_sell:            u64,   // 0 = подстановочный символ
    pub total_quote_fund_raising:   u64,   // 0 = подстановочный символ
    pub total_locked_amount:        u64,   // u64::MAX = подстановочный символ
    pub cliff_period:               u64,   // u64::MAX = подстановочный символ
    pub unlock_period:              u64,   // u64::MAX = подстановочный символ
}
```

Каждое поле имеет значение-дозорный, означающий **подстановочный символ** (любое значение совпадает): `u64::MAX` для полей `u64`, `u8::MAX` для полей `u8`, `0` для полей предложения / продажи / сбора средств. `BondingCurveParam` со всеми дозорными символами — это «разрешить всё» — эквивалентно поведению пустого белого списка.

Алгоритм совпадения при `Initialize`:

1. Отфильтруйте `curve_params` к записям, чей `global_config` совпадает с выбранным запуском `GlobalConfig`.
2. Если отфильтрованный список пуст, разрешите любые параметры (платформа ничего не добавила в белый список для этого `GlobalConfig`).
3. Если каждая запись в отфильтрованном списке имеет `all_is_invalid()` (каждое поле — подстановочный символ), разрешите любые параметры.
4. Иначе переберите записи; для каждой записи проверьте параметры запуска по каждому не-подстановочному полю. Если все не-подстановочные поля совпадают, примите и вернитесь.
5. Если записи не совпали, откатитесь с `InvalidInput`.

Это позволяет платформе сказать «мы разрешаем только стандартную форму 1B-supply / 800M-sold / 30k-USDC-raise / no-vesting», написав одну запись с конкретными значениями для этих четырёх полей и подстановочными символами везде. Или более строгая платформа может перечислить три или четыре дискретные формы, по одной для каждого поддерживаемого уровня запуска.

`MAX_CURVE_PARAMS = 10` ограничивает размер белого списка.

## `PlatformGlobalAccess` — авторизация платформы

Когда `GlobalConfig` имеет `requires_platform_auth = 1`, каждый `Initialize` для него должен включить PDA `PlatformGlobalAccess`, доказывающий предварительную авторизацию платформы:

```rust theme={null}
// states/platform_global_access.rs
pub const PLATFORM_GLOBAL_ACCESS_SEED: &str = "platform_global_access";

#[account]
pub struct PlatformGlobalAccess {
    pub bump:            u8,
    pub global_config:   Pubkey,
    pub platform_config: Pubkey,
    pub padding:         [u64; 8],
}
```

PDA семена: `[b"platform_global_access", global_config, platform_config]`.

Администратор протокола создаёт по одному на каждую пару `(GlobalConfig, PlatformConfig)` через `CreatePlatformGlobalAccess` и отзывает через `ClosePlatformGlobalAccess`. Без этого аккаунта запуск не может привязаться к этому `GlobalConfig` из закрытой платформы.

## Путь чтения

```ts theme={null}
const platformConfig = await raydium.launchpad.getPlatformConfig(platformConfigPda);

console.log("Платформа:", readString(platformConfig.name));
console.log("Комиссия:", platformConfig.feeRate, "(/1M)");
console.log("Распределение NFT:",
  platformConfig.platformScale,
  platformConfig.creatorScale,
  platformConfig.burnScale,
);
console.log("Размер белого списка кривых:", platformConfig.curveParams.length);
```

Для интерфейса, показывающего «откуда был запущен этот токен», `PoolState.platform_config` указывает напрямую на исходящий `PlatformConfig` — получите его один раз и кэшируйте брендинг.

## Путь обновления

| Инструкция                  | Кто подписывает                    | Что изменяется                                                                                                                                                                            |
| --------------------------- | ---------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `CreatePlatformConfig`      | администратор платформы (один раз) | Инициализирует аккаунт с `PlatformParams`.                                                                                                                                                |
| `UpdatePlatformConfig`      | администратор платформы            | Универсальная диспетчеризация, ключ по `param: u8`; изменяет одно поле за вызов. Поля брендинга, ставки комиссий, кошелёк вестинга и различные кошельки — всё можно установить через это. |
| `UpdatePlatformCurveParam`  | администратор платформы            | Добавить или заменить одну запись `PlatformCurveParam` по `(global_config, index)`.                                                                                                       |
| `RemovePlatformCurveParam`  | администратор платформы            | Очистить одну запись (установить на все-дозорные = подстановочный символ).                                                                                                                |
| `ClaimPlatformFee`          | `platform_fee_wallet`              | Собрать комиссию платформы для каждого пула из `PoolState.quote_vault`.                                                                                                                   |
| `ClaimPlatformFeeFromVault` | `platform_fee_wallet`              | Собрать хранилище платформы (PDA по `[platform_config, quote_mint]`).                                                                                                                     |

Ротация кошельков (`platform_fee_wallet`, `platform_nft_wallet`, `platform_vesting_wallet`, `platform_cp_creator`, `transfer_fee_extension_auth`, `cpswap_config`) — всё через `UpdatePlatformConfig`. Прочитайте таблицу диспетчеризации `update_platform_config` в исходном коде для точных кодов `param`.

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

* **Неправильно установленные дозорные символы белого списка.** `BondingCurveParam` с `total_locked_amount = 0` **не является** подстановочным символом — он совпадает с запусками, явно отказывающимися от вестинга. Подстановочный символ для этого поля — `u64::MAX`. Та же ловушка существует для `cliff_period` и `unlock_period`. Используйте `clear()` (который программа предоставляет) для правильной установки дозорных символов.
* **Округление распределения NFT.** Три масштаба должны в сумме дать ровно `1_000_000`. Ошибки на один при `CreatePlatformConfig` откатываются; ошибки во время выполнения отчеканили бы или сожгли один дополнительный LP unit, что именно предотвращает проверка строгого равенства.
* **Двойное распределение вестинга платформы.** Если `platform_vesting_scale > 0`, платформа должна вызвать `CreatePlatformVestingAccount` один раз после окончания сбора средств запуска; если забудет, эта доля остаётся нераспределённой и неактивной навечно (бюджет `total_locked_amount` запуска расходуется, но платформа никогда не требует).
* **Неоднозначность `platform_cp_creator`.** Когда установлен на `Pubkey::default()`, создатель запуска записывается как `pool_creator` пула CPMM после градации; когда установлен на реальный ключ, вместо него записывается этот ключ. Это влияет на то, кто может позже вызвать `CPMM::CollectCreatorFee`. Решите при создании конфигурации платформы, какую модель вы хотите.

## Ссылки

* [`products/launchlab/global-config`](/ru/products/launchlab/global-config) — протокольные правила, которые должен удовлетворять запуск.
* [`products/launchlab/vesting`](/ru/products/launchlab/vesting) — механика `platform_vesting_scale`.
* [`products/launchlab/creator-fees`](/ru/products/launchlab/creator-fees) — NFT Fee Key, Burn & Earn.
* [`products/launchlab/platforms`](/ru/products/launchlab/platforms) — руководство интегратора платформы.

Исходные файлы:

* `raydium-launch/programs/launchpad/src/states/platform_config.rs` — `PlatformConfig`, `PlatformParams`, `MigrateNftInfo`, `PlatformCurveParam`, `BondingCurveParam`, `is_valid_curve_param`.
* `raydium-launch/programs/launchpad/src/states/platform_global_access.rs` — `PlatformGlobalAccess`.
* `raydium-launch/programs/launchpad/src/lib.rs` — `create_platform_config`, `update_platform_config`, `update_platform_curve_param`, `remove_platform_curve_param`, `create_platform_global_access`, `close_platform_global_access`, `claim_platform_fee`, `claim_platform_fee_from_vault`.
