Token Extensions — це набір вбудованих розширень у програмі Token-2022 (також званій Token Extensions Program), які дозволяють створювати токени з поведінкою, що раніше вимагала написання окремих смарт-контрактів. Замість того щоб розробляти власну програму для токена з комісіями за переказ, метаданими чи делегуванням, ви вказуєте потрібні розширення під час ініціалізації mint-акаунта.

Що таке Token Extensions

Розширення SPL Token Program (Token-2022)

Оригінальна SPL Token Program (program ID: TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA) є базовим стандартом токенів на Solana. Вона підтримує створення mint-акаунтів, випуск, переказ та спалювання токенів, але її функціональність фіксована — ви не можете змінити логіку переказу чи додати метадані без зовнішніх програм.

Token-2022 (program ID: TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb) — це окрема програма, яка зберігає повну зворотну сумісність з оригінальною, але додає механізм розширень. Кожне розширення — це додаткові дані та інструкції, прив'язані до конкретного mint-акаунта. Mint без увімкнених розширень працює identically до оригінального Token.

Ключова архітектурна ідея: розширення зберігаються в самому mint-акаунті як додаткові байти (account extensions). Це означає, що розмір mint-акаунта з розширеннями більший за стандартні 82 байти, і його треба explicitly виділяти з урахуванням обраного набору розширень.

Навіщо вони потрібні

Без Token Extensions реалізація таких вимог, як комісія за кожен переказ, зберігання метаданих безпосередньо в mint-акаунті або постійне делегування, вимагала б:

  • написання окремої програми на Rust або Anchor;
  • додаткових транзакцій для взаємодії між вашою програмою та Token Program через CPI;
  • окремого аудиту безпеки для кожної нестандартної логіки.

Token Extensions зсовують цю складність на рівень перевіреної програми Solana Labs. Ви отримуєте готові інструкції, які вже пройшли аудит і тестування, зменшуючи поверхню атаки вашого проєкту.

Основні розширення

Transfer hook, transfer fee, metadata

Transfer hook — дозволяє вказати зовнішню програму, яка буде викликатися автоматично перед кожним переказом токена. Це дає змогу реалізувати кастомну логіку: перевірку дозволених адрес, блокування переказів за певних умов, логування тощо. Hook-програма не може змінювати суму переказу, але може відхилити транзакцію.

Transfer fee — вбудована комісія за переказ, яка стягується в самому токені (не в SOL). Комісія складається з двох параметрів: відсотка від суми (з точністю до базисних пунктів) та фіксованої суми. Зібрані комісії накопичуються на спеціальному акаунті та можуть бути виведені авторизованою стороною. Це корисно для протоколів, які потребують фінансування казначейства без окремого механізму.

Metadata — зберігає ім'я, символ та URI метаданих безпосередньо в mint-акаунті, усуваючи залежність від зовнішніх програм типу Metaplex Token Metadata. Це зменшує кількість акаунтів та транзакцій, необхідних для повноцінного токена.

Permanent delegate, interest-bearing

Permanent delegate — дозволяє призначити акаунт, який має необмежене делегування на всі токен-акаунти цього mint. Цей делегат може переказувати або спалювати токени з будь-якого акаунта без окремого схвалення власника. Типовий сценарій — регуляторні вимоги (наприклад, заморожування активів за рішенням суду) або токенізовані реальні активи (RWA), де емітент зберігає контроль.

Interest-bearing — додає до mint-акаунта коефіцієнт відсоткової ставки та базовий timestamp. Баланси акаунтів інтерпретуються з урахуванням нарахованих відсотків. Це дозволяє створювати токени, що зростають у часі, без необхідності перераховувати баланси кожному утримувачу.

Повний перелік розширень включає також: Confidential Transfers (конфіденційні перекази з доказами нульового розголошення), Default Account State (всі нові акаунти створюються замороженими), Mint Close Authority (можливість закрити mint-акаунт та повернути rent) та інші. Перевірте актуальний перелік у репозиторії spl-token, оскільки розширення додаються з новими релізами.

Як використовувати Token Extensions

Створення токена з розширеннями

Нижче наведено концептуальний приклад ініціалізації mint-акаунта з розширенням metadata за допомогою бібліотеки @solana/spl-token. Це не production-рішення, а мінімальний приклад для розуміння механіки.

Середовище: Node.js 18.x, @solana/spl-token версії 0.4.x+, @solana/web3.js версії 1.87.x+, кластер Devnet.

Передумови: встановлене з'єднання з Devnet, ключова пара з достатнім балансом SOL для rent-exempt акаунтів та комісій.

Очікуваний результат: створений mint-акаунт у програмі Token-2022 з увімкненим розширенням metadata та встановленими ім'ям, символом та URI.

Увага: цей приклад демонструє структуру викликів. Для production використовуйте Anchor або повну обробку помилок з перевіркою кожного кроку. Перевірте актуальність API у документації до вашої версії @solana/spl-token.

Ключові відмінності порівняно з оригінальним Token:

  • замість TOKEN_PROGRAM_ID використовується TOKEN_2022_PROGRAM_ID;
  • перед createInitializeMintInstruction додаються інструкції ініціалізації обраних розширень;
  • розмір акаунта обчислюється з урахуванням додаткового простору для розширень через getMintLen з параметром extensions.

Структура транзакції для mint з metadata виглядає так:

  1. Обчислити розмір mint: getMintLen([ExtensionType.Metadata]).
  2. Створити акаунт з цим розміром та встановити його rent-exempt.
  3. Викликати createInitializeMetadataPointerInstruction — вказує, що метадані зберігаються в самому mint.
  4. Викликати createInitializeMintInstruction з TOKEN_2022_PROGRAM_ID.
  5. Викликати createInitializeMetadataAccountInstruction з ім'ям, символом та URI.

Кожна інструкція ініціалізації розширення повинна бути викликана до ініціалізації самого mint. Порядок має значення: спочатку вказуються поінтери на розширення, потім ініціалізується mint, потім заповнюються дані розширень.

Відмінності у CLI-командах

Для роботи з Token-2022 через spl-token CLI (версія 4.0.0+) до кожної команди додається прапорець --program-id TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb.

Створення базового mint без розширень:

  • Оригінальний Token: spl-token create-token
  • Token-2022: spl-token create-token --program-id TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb

Створення mint з увімкненим розширенням metadata:

  • spl-token create-token --program-id TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb --enable-metadata

Після створення mint з metadata-розширенням встановіть дані:

  • spl-token update-metadata <MINT_ADDRESS> --program-id TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb --name "MyToken" --symbol "MTK" --uri "https://example.com/meta.json"

Створення акаунта для Token-2022 токена також вимагає вказання program ID:

  • spl-token create-account <MINT_ADDRESS> --program-id TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb

Перевірте точні назви прапорців для вашої версії CLI командою spl-token create-token --help, оскільки синтаксис може змінюватися між мінорними релізами.

Коли обрати Token-2022 замість Token

Сумісність з існуючими інструментами

Головне обмеження Token-2022: не всі гаманці, DEX-и, агрегатори та бриджі повністю підтримують цю програму. Станом на момент написання більшість великих гаманців (Phantom, Solflare) відображають Token-2022 токени, але деякі інструменти можуть:

  • не показувати баланс Token-2022 токенів взагалі;
  • не підтримувати конкретні розширення (наприклад, transfer fee може не відображатися коректно в інтерфейсі);
  • не дозволяти обмін Token-2022 токенів через свої пули ліквідності.

Перед вибором Token-2022 для production-проєкту перевірте підтримку в конкретних інструментах, які ви плануєте використовувати. Для тестування на Devnet це обмеження не є критичним.

Міграція з Token на Token-2022

Прямої міграції не існує. Mint-акаунт оригінального Token не можна «перетворити» на Token-2022 акаунт. Можливі підходи:

  • Створення нового токена — випустити новий Token-2022 токен та забезпечити механізм обміну старих токенів на нові (через окрему програму або вручну).
  • Залишити як є — якщо оригінальний токен вже має ліквідність та користувачів, міграція може бути дорожчою за користь від розширень.

Token-2022 має сенс обирати для нових проєктів, де ви заздалегідь знаєте, що вам потрібні розширення, або де підтримка інструментів вже підтверджена.

Типові помилки

Невірний program ID (Token vs Token-2022)

Найчастіша помилка — створити mint через Token-2022, але при переказі чи створенні токен-акаунта використовувати оригінальний TOKEN_PROGRAM_ID. Це призведе до помилки, оскільки акаунти різних програм не сумісні між собою.

Правило: якщо mint створено в Token-2022, всі операції з цим токеном (створення акаунтів, перекази, затвердження, спалювання) повинні вказувати TOKEN_2022_PROGRAM_ID. У коді це означає, що program ID має бути єдиним параметром, який передається в усі інструкції.

У CLI це означає, що прапорець --program-id треба додавати до кожної команди, а не лише до create-token.

Розширення не підтримується інструментом

Інша поширена ситуація: токен створено з transfer fee, але гаманець або DEX не враховує цю комісію. Користувач намагається переказати 100 токенів, але отримувач отримує менше через комісію, яку інтерфейс не відобразив. Це не є технічною помилкою у вашому коді — програма працює коректно, але інструмент на стороні користувача не підтримує розширення.

Мінімізація ризику:

  • Перед випуском перевірте, як обраний набір розширень відображається в основних гаманцях на Devnet.
  • Якщо розширення критичне для вашої моделі (наприклад, transfer fee є частиною економіки), переконайтеся, що ключові інтерфейси користувачів його підтримують.
  • У документації до токена чітко вкажіть, які розширення увімкнені та як вони впливають на перекази.

Також варто уникати ситуації, коли ви ініціалізуєте розширення, але не завершуєте його налаштування. Наприклад, увімкнути metadata pointer, але не викликати інструкцію встановлення самих метаданих. У такому разі mint буде створено, але метадані будуть порожніми, що може спричинити некоректне відображення в гаманцях.

Наступний крок у вивченні — практичне створення токена з розширеннями на Devnet, що розглядається в наступному матеріалі розділу.

Джерела