Інтеграція фронтенда з RainbowKit
Написати Connect Wallet кнопку з нуля — втратити кілька днів на edge cases: підтримка 15+ гаманців, deep linking для мобільних, QR-коди, автоматичне переподключення, обробка disconnect. RainbowKit вирішує все це в 30 рядках конфігурації поверх wagmi.
Установка та базова конфігурація
npm install @rainbow-me/rainbowkit wagmi viem @tanstack/react-query
// app/providers.tsx
import "@rainbow-me/rainbowkit/styles.css";
import { RainbowKitProvider, getDefaultConfig } from "@rainbow-me/rainbowkit";
import { WagmiProvider } from "wagmi";
import { mainnet, polygon, arbitrum } from "wagmi/chains";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
const config = getDefaultConfig({
appName: "My dApp",
projectId: process.env.NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID!, // обов'язково
chains: [mainnet, polygon, arbitrum],
});
const queryClient = new QueryClient();
export function Providers({ children }) {
return (
<WagmiProvider config={config}>
<QueryClientProvider client={queryClient}>
<RainbowKitProvider>{children}</RainbowKitProvider>
</QueryClientProvider>
</WagmiProvider>
);
}
WalletConnect Project ID отримуємо на cloud.walletconnect.com — безплатний tier достатньо для більшості проектів.
ConnectButton: кастомізація
Стандартна кнопка <ConnectButton /> підходить для прототипів. У production майже завжди потрібен кастомний вид:
import { ConnectButton } from "@rainbow-me/rainbowkit";
export function CustomConnectButton() {
return (
<ConnectButton.Custom>
{({ account, chain, openAccountModal, openChainModal, openConnectModal, mounted }) => {
const ready = mounted;
const connected = ready && account && chain;
return (
<div {...(!ready && { "aria-hidden": true, style: { opacity: 0 } })}>
{!connected ? (
<button onClick={openConnectModal}>Підключити гаманець</button>
) : chain.unsupported ? (
<button onClick={openChainModal}>Неверна мережа</button>
) : (
<div>
<button onClick={openChainModal}>{chain.name}</button>
<button onClick={openAccountModal}>
{account.displayBalance} · {account.displayName}
</button>
</div>
)}
</div>
);
}}
</ConnectButton.Custom>
);
}
Темізація
RainbowKit підтримує три встроєні теми (lightTheme, darkTheme, midnightTheme) з можливістю переопределення через theme prop:
import { lightTheme } from "@rainbow-me/rainbowkit";
<RainbowKitProvider
theme={lightTheme({
accentColor: "#6366f1", // indigo-500
accentColorForeground: "white",
borderRadius: "medium",
fontStack: "system",
})}
>
Для динамічного переключення тёмної/світлої теми передаємо вичисленне значення з контексту або next-themes.
Кастомні гаманці та порядок відображення
За замовчуванням RainbowKit показує гаманці у своєму порядку. Для кастомного списку:
import {
connectorsForWallets,
metaMaskWallet,
coinbaseWallet,
walletConnectWallet,
injectedWallet,
} from "@rainbow-me/rainbowkit/wallets";
const connectors = connectorsForWallets(
[
{
groupName: "Рекомендовані",
wallets: [metaMaskWallet, coinbaseWallet],
},
{
groupName: "Інші",
wallets: [walletConnectWallet, injectedWallet],
},
],
{ appName: "My dApp", projectId: "..." }
);
Можна додати кастомний гаманець (наприклад, Safe або Rabby) через інтерфейс Wallet з пакету.
Authentication: SIWE (Sign-In with Ethereum)
RainbowKit має встроєну підтримку EIP-4361 (Sign-In with Ethereum) — користувач підписує повідомлення замість пароля:
import { RainbowKitAuthenticationProvider, createAuthenticationAdapter } from "@rainbow-me/rainbowkit";
import { SiweMessage } from "siwe";
const authAdapter = createAuthenticationAdapter({
getNonce: async () => {
const res = await fetch("/api/auth/nonce");
return res.text();
},
createMessage: ({ nonce, address, chainId }) =>
new SiweMessage({
domain: window.location.host,
address,
statement: "Sign in to My dApp",
uri: window.location.origin,
version: "1",
chainId,
nonce,
}),
getMessageBody: ({ message }) => message.prepareMessage(),
verify: async ({ message, signature }) => {
const res = await fetch("/api/auth/verify", {
method: "POST",
body: JSON.stringify({ message, signature }),
});
return res.ok;
},
signOut: () => fetch("/api/auth/logout", { method: "POST" }),
});
Типічні проблеми
SSR / hydration — RainbowKit використовує window, що ломе SSR. У Next.js App Router оборачуємо Providers у client component ("use client"). Для Pages Router — dynamic(() => import('./Providers'), { ssr: false }) якщо проблема зберігається.
Mobile deep linking — працює з коробки для MetaMask Mobile та Coinbase Wallet через WalletConnect v2. Перевіряємо, що projectId правильно настроєний у WalletConnect Cloud з доменом додатка.
Множественні RainbowKit екземпляри — якщо RainbowKitProvider рендерится кілька разів (помилка архітектури), отримуємо конфлікти. Provider повинен бути ровно один, як можна вище в дереві компонентів.







