Интеграция фронтенда с Web3Modal

Проектируем и разрабатываем блокчейн-решения полного цикла: от архитектуры смарт-контрактов до запуска DeFi-протоколов, NFT-маркетплейсов и криптобирж. Аудит безопасности, токеномика, интеграция с существующей инфраструктурой.
Показано 1 из 1 услугВсе 1306 услуг
Интеграция фронтенда с Web3Modal
Простая
~2-3 рабочих дня
Часто задаваемые вопросы
Направления блокчейн-разработки
Этапы блокчейн-разработки
Последние работы
  • image_website-b2b-advance_0.png
    Разработка сайта компании B2B ADVANCE
    1221
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1163
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    855
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1056
  • image_logo-advance_0.png
    Разработка логотипа компании B2B Advance
    561
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    828

Интеграция фронтенда с Web3Modal

Если в dApp нужна поддержка больше одного кошелька — не пишите кастомный wallet selector с нуля. WalletConnect's Web3Modal v3 решает эту задачу: 300+ кошельков, WalletConnect QR, Mobile deeplinks, email/social login через Web3Auth — всё из коробки. Задача интеграции — правильно настроить конфиг и не наступить на типичные грабли с hydration и SSR.

Установка и базовая конфигурация

npm install @web3modal/wagmi wagmi viem @tanstack/react-query

Project ID получается на cloud.walletconnect.com. Без него Modal запустится, но WalletConnect соединения работать не будут.

// config/web3modal.ts
import { createWeb3Modal } from '@web3modal/wagmi/react'
import { defaultWagmiConfig } from '@web3modal/wagmi/react/config'
import { mainnet, arbitrum, base, polygon } from 'wagmi/chains'

const projectId = import.meta.env.VITE_WC_PROJECT_ID

const metadata = {
  name: 'My dApp',
  description: 'My dApp description',
  url: 'https://mydapp.xyz', // должен совпадать с доменом в WC Cloud
  icons: ['https://mydapp.xyz/icon.png'],
}

export const config = defaultWagmiConfig({
  chains: [mainnet, arbitrum, base, polygon],
  projectId,
  metadata,
})

createWeb3Modal({
  wagmiConfig: config,
  projectId,
  enableAnalytics: true,
  enableOnramp: true, // встроенный fiat on-ramp
  themeMode: 'dark',
  themeVariables: {
    '--w3m-accent': '#7c3aed',
    '--w3m-border-radius-master': '4px',
  },
})

Интеграция в React приложение

// main.tsx
import { WagmiProvider } from 'wagmi'
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import { config } from './config/web3modal'

const queryClient = new QueryClient()

export function App() {
  return (
    <WagmiProvider config={config}>
      <QueryClientProvider client={queryClient}>
        <Router />
      </QueryClientProvider>
    </WagmiProvider>
  )
}

Кнопка подключения — либо готовый компонент, либо кастомный через хук:

// Готовый компонент
<w3m-button />

// Кастомная кнопка
import { useWeb3Modal } from '@web3modal/wagmi/react'
import { useAccount } from 'wagmi'

function ConnectWallet() {
  const { open } = useWeb3Modal()
  const { address, isConnected } = useAccount()

  return (
    <button onClick={() => open()}>
      {isConnected ? `${address?.slice(0, 6)}...${address?.slice(-4)}` : 'Connect Wallet'}
    </button>
  )
}

Кастомные сети

Добавление сетей, которых нет в wagmi/chains:

import { defineChain } from 'viem'

const sonic = defineChain({
  id: 146,
  name: 'Sonic',
  nativeCurrency: { name: 'Sonic', symbol: 'S', decimals: 18 },
  rpcUrls: { default: { http: ['https://rpc.soniclabs.com'] } },
  blockExplorers: { default: { name: 'SonicScan', url: 'https://sonicscan.org' } },
})

export const config = defaultWagmiConfig({
  chains: [mainnet, sonic],
  // ...
})

Network switching

Web3Modal показывает network switcher автоматически. Для программного переключения:

import { useWeb3Modal } from '@web3modal/wagmi/react'

const { open } = useWeb3Modal()

// Открыть сразу на вкладке сетей
<button onClick={() => open({ view: 'Networks' })}>Switch Network</button>

SSR / Next.js

В Next.js App Router проблема с hydration: Web3Modal инициализируется client-side, но серверный рендер не знает о подключённом кошельке. Решение — 'use client' директива для провайдера и lazy initialization:

// providers/Web3Provider.tsx
'use client'
import { createWeb3Modal } from '@web3modal/wagmi/react'
import { useEffect, useState } from 'react'

// Инициализация вне компонента — выполняется один раз
createWeb3Modal({ wagmiConfig: config, projectId })

export function Web3Provider({ children }: { children: React.ReactNode }) {
  const [mounted, setMounted] = useState(false)
  useEffect(() => setMounted(true), [])

  return (
    <WagmiProvider config={config}>
      <QueryClientProvider client={queryClient}>
        {mounted ? children : null}
      </QueryClientProvider>
    </WagmiProvider>
  )
}

mounted guard предотвращает hydration mismatch — без него React выбрасывает предупреждение о различии серверного и клиентского рендера адреса кошелька.

Email и social login

Web3Modal поддерживает embedded wallets через Web3Auth. Включается в конфиге:

createWeb3Modal({
  // ...
  featuredWalletIds: [], // убираем featured wallets если нужен clean UI
  emailEnabled: true, // email OTP wallet
})

Пользователь входит через email или Google/GitHub — получает non-custodial кошелёк. Для широкой аудитории без крипто-опыта это значительно снижает барьер входа.