@solana/web3.js — це офіційний TypeScript/JavaScript SDK для взаємодії з нодами Solana. Через нього ваш код читає стан блокчейна, формує транзакції, підписує їх і відправляє в мережу. У цьому довіднику ви отримаєте робочий код, який можна запустити на Devnet одразу після встановлення.

Версії для прикладів у «Solana web3.js: перші кроки» перевірено 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.

Що таке @solana/web3.js

Основний SDK для взаємодії з Solana

Бібліотека надає класи та функції для трьох основних завдань: підключення до RPC-ноди (клас Connection), робота з криптографічними ключами (класи Keypair, PublicKey) і побудова транзакцій (класи Transaction, TransactionInstruction). Вона не містить високорівневих абстракцій на кшталт Anchor — ви працюєте з примітивами блокчейна безпосередньо.

SDK не залежить від CLI-інструментів і працює самостійно в будь-якому середовищі, де є доступ до HTTP- або WebSocket-endpoint ноди Solana.

Встановлення та версії

Передумови: Node.js 18 або новіший, ініціалізований проєкт із package.json.

Станом на момент написання актуальна стабільна гілка — @solana/[email protected]. Встановіть її:

npm install @solana/web3.js@1

Ця команда зафіксує мажорну версію 1 і дозволить отримувати патч-оновлення без ризику зламати код. Перевірте встановлену версію:

npx solana-web3-js --version

Усі приклади нижче перевірені для @solana/web3.js 1.95.x на кластері Devnet. Якщо ви використовуєте іншу мінорну версію, перевірте журнал змін у репозиторії бібліотеки.

Підключення до кластера

Створення Connection об'єкта

Клас Connection — це точка входу в будь-яку взаємодію з мережею. Він приймає RPC-endpoint рядком і опціонально — об'єкт із налаштуваннями.

import { Connection } from '@solana/web3.js';

const connection = new Connection(
  'https://api.devnet.solana.com',
  'confirmed'
);

console.log(await connection.getEpochInfo());

Другий аргумент — commitment. Значення confirmed означає, що нода поверне результат лише після того, як блок із транзакцією отримає підтвердження від супервузла. Це баланс між швидкістю та надійністю, який підходить для розробки на Devnet.

Очікуваний результат: об'єкт EpochInfo з полями epoch, slotIndex, slotsInEpoch тощо. Якщо ви бачите цей об'єкт — підключення працює.

Devnet endpoint: як обрати правильний

Для розробки використовуйте виключно Devnet — там тестові токени не мають реальної вартості. Доступні варіанти:

  • Публічний endpointhttps://api.devnet.solana.com. Безкоштовний, має rate-ліміти (зазвичай 100 запитів на 10 секунд). Підходить для перших експериментів.
  • Приватна нода — локальний solana-test-validator або виділений сервер. Дає повний контроль над станом і жодних лімітів. Рекомендується, коли публічний endpoint стає вузьким місцем.

Ніколи не використовуйте Mainnet-beta endpoint для навчальних транзакцій — це призводить до втрати реальних коштів.

Основні операції

Отримання балансу акаунта

У Solana кожен акаунт має власний баланс у lamports (1 SOL = 1 000 000 000 lamports). Щоб його прочитати, потрібен лише PublicKey акаунта:

import { Connection, PublicKey, LAMPORTS_PER_SOL } from '@solana/web3.js';

const connection = new Connection('https://api.devnet.solana.com', 'confirmed');
const address = new PublicKey('7xKXtg2CW87d97TXJSDpbD5jBkheTqA83TZRuJosgAsU');

const lamports = await connection.getBalance(address);
console.log(`Баланс: ${lamports / LAMPORTS_PER_SOL} SOL`);

Метод getBalance повертає Promise<number> — кількість lamports як ціле число. Ділення на LAMPORTS_PER_SOL конвертує їх у SOL для відображення.

Спосіб перевірки: підставте будь-який відомий Devnet-адрес (наприклад, свій, після отримання airdrop) і переконайтеся, що значення збігається з тим, що показує Solana Explorer на Devnet.

Створення та відправка транзакції

Найпростіша корисна транзакція — переказ SOL з одного акаунта на інший. Цей приклад використовує згенерований keypair і запитує airdrop для тестування:

import {
  Connection,
  Keypair,
  PublicKey,
  LAMPORTS_PER_SOL,
  SystemProgram,
  Transaction
} from '@solana/web3.js';

const connection = new Connection('https://api.devnet.solana.com', 'confirmed');
const sender = Keypair.generate();
const recipient = new PublicKey('7xKXtg2CW87d97TXJSDpbD5jBkheTqA83TZRuJosgAsU');

// Отримуємо тестові токени
const airdropSignature = await connection.requestAirdrop(
  sender.publicKey,
  2 * LAMPORTS_PER_SOL
);
await connection.confirmTransaction(airdropSignature, 'confirmed');

// Формуємо транзакцію
const transaction = new Transaction().add(
  SystemProgram.transfer({
    fromPubkey: sender.publicKey,
    toPubkey: recipient,
    lamports: 0.01 * LAMPORTS_PER_SOL,
  })
);

// Підписуємо та відправляємо
const signature = await connection.sendTransaction(transaction, [sender]);
await connection.confirmTransaction(signature, 'confirmed');

console.log('Транзакція відправлена:', signature);

Що відбувається по кроках:

  1. requestAirdrop надсилає запит на безкоштовні тестові SOL на Devnet. confirmTransaction чекає, поки airdrop буде підтверджений.
  2. SystemProgram.transfer створює інструкцію для переказу. SystemProgram — це вбудована програма Solana, яка обробляє базові операції з нативним токеном.
  3. sendTransaction підписує транзакцію приватним ключем sender і відправляє її в мережу. Другий аргумент — масив keypair-ів, які підписують транзакцію.

Очікуваний результат: рядок signature (base58, ~88 символів). Перевірте його у Solana Explorer, переключившись на Devnet.

Застереження: цей приклад підходить лише для навчання на Devnet. У production-середовищі приватний ключ ніколи не повинен генеруватися в коді клієнта — використовуйте захищене сховище або серверну архітектуру.

Робота з ключами

Keypair: генерація та завантаження

Keypair — це пара з публічного та приватного ключів. Публічний ключ — це адреса акаунта в мережі. Приватний ключ потрібен для підпису транзакцій.

Генерація нового keypair:

import { Keypair } from '@solana/web3.js';

const keypair = Keypair.generate();
console.log('Публічний ключ:', keypair.publicKey.toBase58());
console.log('Секретний ключ (байти):', keypair.secretKey);

Завантаження з існуючого масиву байтів (типовий формат експорту з CLI або файлів JSON):

import { Keypair } from '@solana/web3.js';

const secretKey = new Uint8Array([
  174, 47, 154, 16, 202, 193, 206, 113,
  199, 190, 53, 133, 169, 175, 31, 56,
  222, 53, 138, 189, 221, 129, 85, 2,
  234, 255, 222, 155, 27, 131, 230, 249,
  148, 48, 162, 242, 218, 24, 51, 37,
  216, 89, 168, 202, 128, 27, 86, 106,
  231, 116, 147, 73, 206, 107, 113, 64,
  223, 210, 157, 226, 241, 76, 149, 252
]);

const keypair = Keypair.fromSecretKey(secretKey);
console.log('Відновлено:', keypair.publicKey.toBase58());

Важливо: масив secretKey у @solana/web3.js завжди містить 64 байти — 32 байти приватного ключа Ed25519 і 32 байти публічного ключа. Якщо у вас є лише 32-байтовий приватний ключ, його потрібно спочатку перетворити на 64-байтовий формат.

Безпека: ніколи не комітьте файли з секретними ключами. Додайте *.json з ключами до .gitignore одразу.

PublicKey: створення з рядка та з base58

PublicKey — це обгортка над 32-байтовим публічним ключем. У мережі Solana адреси зазвичай кодуються у форматі base58.

import { PublicKey } from '@solana/web3.js';

// З base58-рядка (найчастіший випадок)
const pubkeyFromString = new PublicKey('7xKXtg2CW87d97TXJSDpbD5jBkheTqA83TZRuJosgAsU');

// З масиву байтів
const pubkeyFromBytes = new PublicKey(new Uint8Array([7, 55, 148, ...]));

// Перевірка рівності
console.log(pubkeyFromString.equals(pubkeyFromBytes)); // true, якщо ключі однакові

Конструктор PublicKey автоматично визначає формат вхідних даних: якщо передати рядок — він розпізнає base58, якщо масив байтів — використає його безпосередньо. Якщо рядок містить некоректний base58 або довжина не дорівнює 32 байтам після декодування, конструктор викине помилку.

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

Невірний RPC endpoint

Симптом: помилка FetchError, network error або 404 при виклику будь-якого методу Connection.

Причина: рядок endpoint містить помилку, використовується HTTPS замість HTTP для локальної ноди, або endpoint недоступний.

Перевірка:

  • Відкрийте endpoint-рядок у браузері. Публічні ноди повертають JSON-відповідь на запит до кореня.
  • Для локального solana-test-validator використовуйте http://127.0.0.1:8899 (без HTTPS).
  • Переконайтеся, що ви не переплутали Mainnet-beta і Devnet endpoint — їхні URL відрізняються лише одним словом у шляху.

Таймаут підключення

Симптом: помилка Connection timeout або метод зависає без відповіді.

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

  • Rate-ліміти публічної ноди. Якщо ви надсилаєте багато запитів послідовно в циклі, додайте затримку або перейдіть на власну ноду.
  • Занадто короткий таймаут. За замовчуванням Connection використовує розумні значення, але ви можете явно вказати більше:

const connection = new Connection(
  'https://api.devnet.solana.com',
  {
    commitment: 'confirmed',
    confirmTransactionInitialTimeout: 60_000, // 60 секунд замість стандартних
  }
);

  • Блокування з боку мережі. Якщо ви за корпоративним проксі або VPN, перевірте, чи дозволено вихідні HTTPS-з'єднання до *.solana.com.

Загальне правило діагностики: якщо метод Connection не спрацьовує, спочатку викличте connection.getHealth(). Якщо він повертає ok — проблема в вашій логіці. Якщо теж зависає — проблема на рівні мережі або endpoint.

Після освоєння цих основ ви готові переходити до високорівневих інструментів. Наступний крок у вашому навчанні — Solana Kit для початківця, де абстракції значно спрощують типові сценарії розробки.

Джерела