Wagmi в React: настройка хуков, миграция на v2 и оптимизация

SSR-гидрация в Next.js App Router с Wagmi — частая головная боль. Мы сталкивались с проектами, где useAccount() на сервере возвращает disconnected, а клиентский стор рассинхронизирован. Решение — строгое разделение клиентских и серверных компонентов и правильная настройка WagmiProvider. Наш опыт в W

Направления блокчейн-разработки

Часто задаваемые вопросы

Последние работы

  • image_website-b2b-advance_0.webp
    Разработка сайта компании B2B ADVANCE
    1441
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1301
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    998
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1267
  • image_logo-advance_0.webp
    Разработка логотипа компании B2B Advance
    713
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    1003

SSR-гидрация в Next.js App Router с Wagmi — частая головная боль. Мы сталкивались с проектами, где useAccount() на сервере возвращает disconnected, а клиентский стор рассинхронизирован. Решение — строгое разделение клиентских и серверных компонентов и правильная настройка WagmiProvider. Наш опыт в Web3-разработке — более 5 лет, мы выполнили 50+ интеграций для DeFi и NFT проектов. Wagmi — это де-факто стандарт для React-разработки на Ethereum. По сравнению с прямым использованием ethers.js, Wagmi сокращает время разработки в 3 раза и даёт на 60% меньше кода. Wagmi v2 дополнительно уменьшает количество RPC-запросов вдвое, что снижает затраты на инфраструктуру. Закажите оценку вашего проекта — мы предложим оптимальную архитектуру.

Почему стоит выбрать Wagmi для React-фронтенда?

Wagmi v2 — де-факто стандарт для React + EVM. В отличие от прямого использования ethers.js или Web3.js, Wagmi берёт на себя управление состоянием кошелька, автоматически обновляет данные при смене сети или аккаунта, и оптимизирует количество RPC-запросов через TanStack Query. Это сокращает время разработки в 3 раза: если ethers.js требует 100 строк кода для управления балансом и сетью, Wagmi делает это за 30. Экономия времени на каждом проекте — до 70% на рутинных операциях. Кроме того, библиотека автоматически обрабатывает смену сети и аккаунта, обновляя состояние без лишних ререндеров. В результате UX становится плавным, а код — поддерживаемым.

Как настроить Wagmi за 5 шагов

  1. Установите зависимости: npm i wagmi viem @tanstack/react-query. Обратите внимание, что wagmi v2 требует viem в качестве провайдера — ethers.js больше не используется.
  2. Создайте конфигурацию в config.ts с мультичейн транспортами и коннекторами. При этом каждый транспорт должен указывать на приватный RPC — публичные эндпоинты часто имеют лимиты запросов и вызывают задержки.
  3. Оберните приложение в WagmiProvider и QueryClientProvider. WagmiProvider должен быть размещён только в клиентском корне, чтобы избежать SSR-проблем.
  4. Реализуйте хуки чтения (useReadContract) с query.enabled для избежания лишних запросов. Используйте staleTime и gcTime для контроля кэширования.
  5. Добавьте хуки записи (useWriteContract) с обработкой подтверждения через useWaitForTransactionReceipt. Для оценки газа перед отправкой применяйте useSimulateContract — это предотвращает неожиданные ошибки out-of-gas.

Настройка и конфигурация

// config.ts import { createConfig, http } from 'wagmi'; import { mainnet, polygon, arbitrum, base } from 'wagmi/chains'; import { injected, coinbaseWallet, walletConnect } from 'wagmi/connectors'; export const config = createConfig({ chains: [mainnet, polygon, arbitrum, base], transports: { [mainnet.id]: http('https://eth-mainnet.g.alchemy.com/v2/YOUR_KEY'), [polygon.id]: http('https://polygon-mainnet.g.alchemy.com/v2/YOUR_KEY'), [arbitrum.id]: http('https://arb-mainnet.g.alchemy.com/v2/YOUR_KEY'), [base.id]: http('https://base-mainnet.g.alchemy.com/v2/YOUR_KEY'), }, connectors: [ injected(), coinbaseWallet({ appName: 'AppName' }), walletConnect({ projectId: process.env.VITE_WC_PROJECT_ID! }), ], }); 

WagmiProvider оборачивает приложение; QueryClientProvider — обязателен, Wagmi использует его для кэширования. Важно передавать транспорты для каждой сети, иначе запросы пойдут на публичные RPC, что вызовет лимиты и задержки.

Основные паттерны

Чтение данных

useReadContract для одного вызова, useReadContracts для батча через Multicall3:

const { data: balance } = useReadContract({ address: TOKEN_ADDRESS, abi: erc20Abi, functionName: 'balanceOf', args: [address], query: { enabled: !!address }, }); 

query.enabled — критичная опция: без неё хук пытается читать до того, как address определён. staleTime и gcTime контролируют как часто данные перечитываются — для балансов разумно 30 секунд, для медленно меняющихся параметров контракта — 5 минут.

Запись (транзакции)

const { writeContractAsync } = useWriteContract(); const { isLoading: isConfirming } = useWaitForTransactionReceipt({ hash }); const handleStake = async () => { const hash = await writeContractAsync({ address: STAKING_ADDRESS, abi: stakingAbi, functionName: 'stake', args: [parseEther(amount)], }); // hash получен — транзакция отправлена, ждём подтверждения }; 

Подписи

Для SIWE и permit-подписей — useSignMessage и useSignTypedData:

const { signTypedDataAsync } = useSignTypedData(); // EIP-712 типизированные данные для permit const signature = await signTypedDataAsync({ domain, types, primaryType: 'Permit', message: permitMessage, }); 

Как избежать повторной отправки транзакции?

После отправки транзакции нужно дождаться её подтверждения и инвалидировать кэш. Используем useWaitForTransactionReceipt с onSuccess:

const queryClient = useQueryClient(); useWaitForTransactionReceipt({ hash, onSuccess: () => { queryClient.invalidateQueries({ queryKey: ['readContract'] }); }}); 

Это предотвращает отправку дублирующих транзакций и гарантирует актуальность данных на UI.

Сравнение Wagmi v1 vs Wagmi v2

Аспект Wagmi v1 Wagmi v2 (текущая)
Базовый провайдер ethers.js Viem
Хуки для контрактов useContractRead, useContractWrite useReadContract, useWriteContract
Типизация Частичная, через ethers Полная, через as const
Производительность Высокое потребление памяти В 2 раза меньше RPC-запросов
Поддержка EIP-1193 Через Web3Provider Нативно

Миграция с v1 на v2 — типичная задача: мы заменяем зависимости, переписываем конфиг и хуки, тестируем в Tenderly. Весь процесс занимает 1–2 дня.

Типичные ошибки при интеграции
  • SSR-гидрация — useAccount() возвращает disconnected в Next.js
  • Потеря типов ABI
  • ENS-резолвинг не работает в других сетях
  • Устаревшие данные после транзакции

Что входит в работу

Мы предоставляем интеграцию под ключ:

  • Конфигурация мультичейн транспортов и коннекторов.
  • Реализация всех необходимых хуков для чтения и записи.
  • Настройка автоподписания и типизированных данных (EIP-712).
  • Тестирование транзакций через Tenderly и симуляцию в Foundry.
  • Документация с примерами использования.
  • Миграция с Wagmi v1 на v2.

Все работы сопровождаются гарантией совместимости с последними версиями Wagmi и Viem.

Ориентиры по срокам

Настройка с нуля (мультичейн, wallet UI, базовые read/write хуки): от 1 дня. Интеграция существующего React-приложения с несколькими смарт-контрактами и миграция с v1: 2–3 дня. Свяжитесь с нами для персонализированной оценки — мы подготовим архитектуру и рассчитаем точные сроки.