IDL (Interface Definition Language) у фреймворку Anchor — це JSON-файл, який описує публічний інтерфейс вашої програми на Solana: які instruction-и вона приймає, які акаунти очікує, які типи даних використовує. Без IDL клієнтський код (зазвичай на TypeScript) не знає, як сформувати транзакцію для вашої програми. Це не оптимізація чи додаткова зручність — це необхідна складова розробки на Anchor.

Версії для прикладів у «Що таке IDL у Anchor» перевірено 2 серпня 2026 року. Стабільна гілка Anchor v1 має релізи 1.0.x і орієнтується на Solana 3.x; Anchor v2 у документації позначений як alpha. Приклади для Anchor 0.29–0.32 залишаються лише відтворюваними прикладами для зафіксованого legacy-середовища: їх не слід переносити в новий проєкт без міграції залежностей і повторного тестування. Клієнт @anchor-lang/core сумісний із legacy @solana/web3.js v1, а не з v2.

Означення IDL

Interface Definition Language — опис програми

Коли ви пишете програму на Rust за допомогою Anchor, компілятор перетворює ваш код на байт-код для Solana Virtual Machine (SVM). Цей байт-код непридатний для прямого читання — клієнт не може з нього дізнатися, які аргументи потребує певна instruction. IDL вирішує цю проблему: це структурований опис усього, що програма «показує назовні».

IDL містить:

  • Назву програми (ім'я crate)
  • Версію (з поля Cargo.toml)
  • Опис кожної instruction: ім'я, список акаунтів з їхніми ролями (signer, mutable, payer тощо), список аргументів із типами
  • Опис користувацьких типів: struct-ів та enum-ів, які використовуються в аргументах або акаунтах
  • Помилки: користувацькі error-коди з текстовими повідомленнями

Аналогія з ABI в Ethereum

Якщо ви приходите з Ethereum, IDL в Anchor — це прямий аналог ABI (Application Binary Interface) у Solidity-контрактах. Обидва формати виконують одне завдання: дають клієнту машинозчитуваний опис того, як взаємодіяти з програмою. Різниця в деталях: ABI використовує специфічну для EVM кодування функцій, тоді як IDL в Anchor описує структуру даних, а серіалізацію виконує формат Borsh.

Як генерується IDL

Автоматична генерація при anchor build

Ви не створюєте IDL вручну. Фреймворк генерує його автоматично під час збірки. Щоб переконатися, виконайте:

Середовище: Ubuntu 24.04 LTS, Anchor 0.30.1, Solana CLI 1.18.26, Rust 1.77.0, кластер — Devnet.

Кроки:

  1. Створіть проєкт: anchor init idl_example
  2. Перейдіть у каталог: cd idl_example
  3. Зберіть: anchor build

Очікуваний результат: у каталозі target/idl/ з'явиться файл idl_example.json.

Перевірка:

  1. ls target/idl/idl_example.json — файл має існувати
  2. cat target/idl/idl_example.json | jq .version — має повернути версію з Cargo.toml

Anchor аналізує макроси у вашому Rust-коді (#[account], #[derive(AnchorSerialize, AnchorDeserialize)], атрибути instruction) і на їхній основі будує JSON-структуру. Якщо код компілюється успішно — IDL генерується коректно.

Формат та структура IDL-файлу

Ось спрощений приклад IDL для програми з однією instruction create_item, яка створює акаунт Item:

{
  "version": "0.1.0",
  "name": "idl_example",
  "instructions": [
    {
      "name": "create_item",
      "accounts": [
        { "name": "authority", "isMut": false, "isSigner": true },
        { "name": "item", "isMut": true, "isSigner": false },
        { "name": "systemProgram", "isMut": false, "isSigner": false }
      ],
      "args": [
        { "name": "title", "type": "string" },
        { "name": "value", "type": "u64" }
      ]
    }
  ],
  "accounts": [
    {
      "name": "Item",
      "type": {
        "kind": "struct",
        "fields": [
          { "name": "authority", "type": "publicKey" },
          { "name": "title", "type": "string" },
          { "name": "value", "type": "u64" },
          { "name": "bump", "type": "u8" }
        ]
      }
    }
  ],
  "errors": [
    { "code": 6000, "name": "InvalidTitle", "msg": "Title is too short" }
  ]
}

Зверніть увагу: IDL не містить логіки програми, лише структуру. Внутрішні деталі (як саме обчислюється PDA, які перевірки виконуються всередині instruction) у IDL не потрапляють.

Як використовується IDL

Генерація TypeScript-клієнта

Головне призначення IDL — автоматична генерація типізованого клієнта для взаємодії з програмою. Anchor постачається з пакетом @coral-xyz/anchor, який має функцію Program. Ви передаєте їй IDL, і отримуєте об'єкт із методами для кожної instruction.

Середовище: Node.js 20.x, @coral-xyz/anchor 0.30.1, кластер — Devnet.

Приклад концептуального коду (не для production, але перевірюваний на Devnet):

import { AnchorProvider, Program, Idl } from "@coral-xyz/anchor";
import { Connection, Keypair, PublicKey } from "@solana/web3.js";
import idlJson from "../target/idl/idl_example.json";

const idl = idlJson as Idl;
const programId = new PublicKey("YOUR_PROGRAM_ID_HERE");

const connection = new Connection("https://api.devnet.solana.com", "confirmed");
const wallet = Keypair.generate();
const provider = new AnchorProvider(connection, wallet, {
  commitment: "confirmed",
});

const program = new Program(idl, programId, provider);

// Тепер program.methods.create_item("My Item", 42)
// дає вам типізований метод з автодоповненням у редакторі

Саме завдяки IDL редактор коду (наприклад, VS Code) знає, що create_item приймає string та u64, і що потрібно передати три акаунти. Без IDL вам довелося б вручну серіалізувати дані через Borsh і формувати транзакцію — це значно більше коду і більше місць для помилок.

Використання у frontend-застосунку

У реальному застосунку IDL-файл зазвичай копіюється у проєкт frontend (наприклад, у каталог src/idl/) або розміщується як статичний актив. Типовий підхід для навчального проєкту на Devnet:

  1. Після anchor build скопіюйте target/idl/idl_example.json у app/src/idl/
  2. Імпортуйте його у модулі, що працює з блокчейном
  3. Створіть єдиний екземпляр Program і використовуйте його в компонентах

Для production-рішень IDL часто завантажується динамічно з сервера або CDN, щоб оновлювати клієнт без перерозгортання frontend. Але це тема окремого проєкту — на поточному етапі достатньо статичного імпорту.

IDL та версіонування

Що робити при оновленні програми

Коли ви змінюєте програму (додаєте instruction, змінюєте поля акаунта, додаєте аргументи), IDL також змінюється після наступного anchor build. Важливо розуміти: Solana не зберігає IDL на ланцюгу автоматично. IDL — це офланч-артефакт.

Практичні кроки при оновленні:

  1. Змініть версію в Cargo.toml (наприклад, з 0.1.0 на 0.2.0)
  2. Виконайте anchor build — IDL оновиться автоматично
  3. Оновіть IDL-файл у клієнтському проєкті
  4. Перевірте, що TypeScript-код компілюється без помилок типів
  5. Протестуйте на Devnet перед розгортанням

Сумісність IDL між версіями

Anchor не застосовує формальне версіонування IDL-схеми, але дотримується зворотної сумісності в межах мажорних версій фреймворку. Це означає:

  • Додавання нової instruction — безпечне, старий клієнт просто не використовує її
  • Додавання нового поля в кінець акаунта — потенційно небезпечне: старі дані на ланцюгу не матимуть цього поля, десеріалізація може зламатися. У Anchor для цього існують специфічні патерни (наприклад, окремий акаунт для нової версії)
  • Видалення instruction або зміна сигнатури — ламає старих клієнтів, потребує оновлення IDL скрізь
  • Перейменування поля акаунта — ламає десеріалізацію, оскільки Borsh використовує порядок полів, а не імена

Правило: якщо ви змінили структуру існуючого акаунта на ланцюгу — це не просто оновлення IDL, це міграція даних, яка потребує окремої instruction.

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

IDL не генерується або порожній

Симптом: після anchor build файл target/idl/ відсутній або містить порожній об'єкт {}.

Причини та рішення:

  • Помилка компіляції Rust. Якщо anchor build завершується з помилкою, IDL не генерується. Спочатку виправте помилки компіляції. Перевірте: anchor build 2>&1 | tail -20
  • Відсутній макрос #[program]. Якщо ви випадково видалили цей макрос над модулем з instruction-ами, Anchor не знайде що описувати. Перевірте, що модуль з логікою обгорнутий у #[program]
  • Неправильна структура проєкту. Anchor очікує стандартну структуру каталогів. Якщо ви перейменували programs/ або змінили розташування Cargo.toml — генерація може не спрацювати
  • Кеш Anchor. Іноді допомагає anchor clean і повторний anchor build

Невідповідність IDL та реальної програми

Симптом: клієнт формує транзакцію, вона відправляється, але на ланцюгу повертається помилка (наприклад, InstructionFallbackNotFound або InvalidInstructionData).

Причини та рішення:

  • Застарілий IDL у клієнті. Ви оновили програму, зібрали новий IDL, але забули скопіювати його у frontend-проєкт. Рішення: завжди перевіряйте, що IDL у клієнті відповідає останньому anchor build. Для Devnet-розробки можна додати перевірку хешу файлу у скрипт збірки
  • Розгортання старого байт-коду з новим IDL. Ви змінили код, зібрали новий IDL, але розгорнули на Devnet стару версію байт-коду (наприклад, забули anchor deploy після змін). Рішення: після кожної зміни коду виконуйте і anchor build, і anchor deploy, і оновлюйте IDL у клієнті
  • Ручне редагування IDL. Іноді розробники намагаються «виправити» IDL вручну. Це призводить до розбіжностей, які важко діагностувати. Рішення: ніколи не редагуйте IDL вручну — завжди генеруйте з коду

Безпечний відкат: якщо після оновлення щось зламалося на Devnet, поверніть IDL з git-історії (git checkout HEAD~1 -- target/idl/), поверніть код програми до попередньої версії і виконайте anchor build && anchor deploy повторно. На Devnet це безпечно, оскільки програму можна перезаписати тим самим ключем.

Тепер, коли ви розумієте, що таке IDL, як він генерується і використовується, наступний логічний крок — написати першу instruction на Anchor і побачити, як IDL описує її в дії.

Джерела