Интеграция фронтенда с @solana/web3.js
Solana фронтенд — это не EVM. Нет ethers.js, нет useContractRead. Модель аккаунтов, кошельки через Wallet Adapter, десериализация через Borsh — всё другое. Основная ловушка для разработчиков с EVM-бэкграундом: попытка применить те же паттерны. Не работает.
Подключение кошелька: Wallet Adapter
@solana/wallet-adapter — стандартный способ подключения Phantom, Solflare, Backpack и других кошельков:
// providers.tsx
import { ConnectionProvider, WalletProvider } from '@solana/wallet-adapter-react'
import { WalletModalProvider } from '@solana/wallet-adapter-react-ui'
import { PhantomWalletAdapter, SolflareWalletAdapter } from '@solana/wallet-adapter-wallets'
import { clusterApiUrl } from '@solana/web3.js'
const wallets = [new PhantomWalletAdapter(), new SolflareWalletAdapter()]
const endpoint = clusterApiUrl('mainnet-beta') // или ваш RPC
export function SolanaProviders({ children }: { children: React.ReactNode }) {
return (
<ConnectionProvider endpoint={endpoint}>
<WalletProvider wallets={wallets} autoConnect>
<WalletModalProvider>
{children}
</WalletModalProvider>
</WalletProvider>
</ConnectionProvider>
)
}
Импорт стилей обязателен: import '@solana/wallet-adapter-react-ui/styles.css'. Без него модалка подключения не отобразится корректно.
Чтение данных с блокчейна
Connection из @solana/web3.js — аналог PublicClient в viem. Ключевые методы:
import { Connection, PublicKey, LAMPORTS_PER_SOL } from '@solana/web3.js'
const connection = new Connection(
process.env.NEXT_PUBLIC_RPC_URL!,
'confirmed' // commitment level: processed | confirmed | finalized
)
// SOL баланс
const balance = await connection.getBalance(new PublicKey(address))
const solBalance = balance / LAMPORTS_PER_SOL
// Информация об аккаунте (data аккаунта программы)
const accountInfo = await connection.getAccountInfo(new PublicKey(address))
Commitment levels — важная деталь, которую упускают. processed — максимально быстро, но транзакция может откатиться. confirmed — подтверждено ~66% stake. finalized — необратимо. Для UI обычно confirmed, для финансовых операций — finalized.
Работа с SPL токенами
Большинство dApp работают с SPL токенами, а не нативным SOL. Нужен @solana/spl-token:
import { getAssociatedTokenAddress, getAccount } from '@solana/spl-token'
import { PublicKey } from '@solana/web3.js'
// Адрес token account пользователя
const tokenAccount = await getAssociatedTokenAddress(
new PublicKey(mintAddress), // mint адрес токена
new PublicKey(walletAddress) // кошелёк владельца
)
// Баланс
try {
const account = await getAccount(connection, tokenAccount)
const balance = Number(account.amount) / 10 ** decimals
} catch (e) {
// TokenAccountNotFoundError — аккаунт не создан, баланс 0
}
Нюанс: token account может не существовать если пользователь никогда не держал этот токен. Это не ошибка — просто баланс 0. Нужно обрабатывать TokenAccountNotFoundError.
Отправка транзакций
import { useWallet } from '@solana/wallet-adapter-react'
import { Transaction, SystemProgram, LAMPORTS_PER_SOL, PublicKey } from '@solana/web3.js'
const { publicKey, sendTransaction } = useWallet()
const handleSend = async () => {
if (!publicKey) return
const { blockhash, lastValidBlockHeight } =
await connection.getLatestBlockhash()
const transaction = new Transaction().add(
SystemProgram.transfer({
fromPubkey: publicKey,
toPubkey: new PublicKey(recipient),
lamports: amount * LAMPORTS_PER_SOL,
})
)
transaction.recentBlockhash = blockhash
transaction.feePayer = publicKey
const signature = await sendTransaction(transaction, connection)
// Ожидание подтверждения
await connection.confirmTransaction({ signature, blockhash, lastValidBlockHeight })
}
sendTransaction из wallet adapter автоматически запрашивает подпись в кошельке пользователя.
RPC и rate limits
Публичный clusterApiUrl('mainnet-beta') — только для разработки, он жёстко лимитирован. Для production: Helius, QuickNode, Alchemy (Solana), или собственная нода. Helius особенно удобен — предоставляет enhanced API с парсингом транзакций и webhook'ами для on-chain событий.
Интеграция занимает 2–3 дня: настройка wallet adapter, подключение к RPC, базовые операции чтения/записи и обработка типичных ошибок (insufficient funds, blockhash expired, simulation failed).







