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 шагов
- Установите зависимости:
npm i wagmi viem @tanstack/react-query. Обратите внимание, что wagmi v2 требует viem в качестве провайдера — ethers.js больше не используется. - Создайте конфигурацию в
config.tsс мультичейн транспортами и коннекторами. При этом каждый транспорт должен указывать на приватный RPC — публичные эндпоинты часто имеют лимиты запросов и вызывают задержки. - Оберните приложение в WagmiProvider и QueryClientProvider. WagmiProvider должен быть размещён только в клиентском корне, чтобы избежать SSR-проблем.
- Реализуйте хуки чтения (useReadContract) с
query.enabledдля избежания лишних запросов. ИспользуйтеstaleTimeиgcTimeдля контроля кэширования. - Добавьте хуки записи (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 дня. Свяжитесь с нами для персонализированной оценки — мы подготовим архитектуру и рассчитаем точные сроки.







