Інтеграція Coinbase Wallet для підключення до сайту
При розробці dApp на React/Next.js ми регулярно стикаємося із запитами на впровадження Coinbase Wallet. Клієнти скаржаться на hydration mismatch при SSR та надлишкові запити при підписанні. Розроблений нами підхід вирішує ці проблеми та забезпечує безшовний користувацький досвід.
Нещодавно до нас звернувся стартап з dApp для NFT-маркетплейсу на Next.js. Вони зіткнулися з тим, що при завантаженні сторінки гаманець не визначався, а після підключення виникали помилки підписання. Ми діагностували проблему — відсутність динамічного імпорту SDK та неправильна обробка саспенсу. Після інтеграції через Wagmi з coinbaseWallet connector та налаштування серверного рендерингу проблема була вирішена за один день.
Чому стандартна інтеграція Coinbase Wallet може підвести?
-
Hydration mismatch при рендерингу на сервері: Coinbase Wallet SDK не оптимізований для SSR. Якщо використовувати
window.ethereum без перевірки, Next.js видає помилки. Ми використовуємо динамічний імпорт та Suspense.
-
N+1 запити при авторизації: кожен виклик
eth_requestAccounts може призводити до надлишкових запитів. Ми кешуємо адресу через useAccount з Wagmi.
-
Mobile deep linking: на iOS/Android WalletConnect SDK не завжди коректно відкриває додаток. Потрібна правильна конфігурація
cbwallet:// та fallback.
Згідно з Coinbase Wallet SDK на GitHub, останні версії підтримують Smart Wallet без seed-фраз. Smart Wallet збільшує конверсію на 30% порівняно з традиційними гаманцями завдяки спрощеному входу.
Як уникнути помилок SSR при підключенні Coinbase Wallet?
Для запобігання hydration mismatch використовуйте динамічний імпорт SDK та компонента підключення. Оберніть код, який звертається до window.ethereum, у useEffect або використовуйте бібліотеку next/dynamic з відключенням SSR. Приклад:
const WalletButton = dynamic(() => import('./WalletButton'), { ssr: false });
Це гарантує, що код гаманця виконується тільки на клієнті.
Покрокове налаштування інтеграції Coinbase Wallet
- Встановіть пакети:
npm install @coinbase/wallet-sdk wagmi viem @tanstack/react-query.
- Створіть конфігурацію Wagmi з connector
coinbaseWallet та налаштуйте ланцюжки.
- Реалізуйте компонент підключення: використовуйте хук
useConnect з Wagmi для ініціації з'єднання.
- Додайте обробку підписання через
useSignMessage з nonce для верифікації.
- Протестуйте mobile deep link на реальних пристроях.
import { createConfig, http } from 'wagmi';
import { mainnet, polygon } from 'wagmi/chains';
import { coinbaseWallet } from 'wagmi/connectors';
export const config = createConfig({
chains: [mainnet, polygon],
connectors: [
coinbaseWallet({ appName: 'My App', preference: 'smartWalletOnly' }),
metaMask(),
walletConnect({ projectId: 'YOUR_PROJECT_ID' })
],
transports: {
[mainnet.id]: http(),
[polygon.id]: http()
}
});
Smart Wallet (Coinbase Wallet v4)
Coinbase Smart Wallet — новий тип гаманця без seed-фрази на основі Passkey. Дозволяє створити гаманець без MetaMask та без seed-фрази. Для активації використовуйте опцію preference: 'smartWalletOnly'.
import { CoinbaseWalletSDK } from '@coinbase/wallet-sdk';
const sdk = new CoinbaseWalletSDK({
appName: 'My App',
preference: {
options: 'smartWalletOnly',
keysUrl: 'https://keys.coinbase.com/connect'
}
});
Детальніше: Passkey — технологія аутентифікації без паролів. За статистикою, використання Passkey підвищує конверсію на 30%.
Авторизація через підписання
import { useConnect, useSignMessage, useAccount } from 'wagmi';
import { coinbaseWallet } from 'wagmi/connectors';
function CoinbaseLogin() {
const { connect } = useConnect();
const { address, isConnected } = useAccount();
const { signMessageAsync } = useSignMessage();
const handleLogin = async () => {
if (!isConnected) {
await connect({ connector: coinbaseWallet({ appName: 'My App' }) });
}
const nonce = await getNonce(address);
const signature = await signMessageAsync({
message: `Login to dApp\nNonce: ${nonce}`
});
const token = await verifySignature(address, signature);
setToken(token);
};
return <button onClick={handleLogin}>Увійти через Coinbase Wallet</button>;
}
Mobile Deep Link
Детальніше про налаштування Deep Link
На мобільних пристроях WalletConnect SDK автоматично відкриває Coinbase Wallet app через deep link: cbwallet://wsegue?uri=.... Для коректної роботи необхідно:
- Додати домен до whitelist WalletConnect Cloud.
- Налаштувати fallback на браузер, якщо додаток не встановлено.
- Перевірити роботу на iOS та Android емуляторах.
Який спосіб інтеграції обрати: прямий SDK чи Wagmi?
Прямий Coinbase Wallet SDK дає менший бандл (~20 KB), але вимагає ручного управління станом. Wagmi + coinbaseWallet connector збільшує бандл до ~50 KB, але забезпечує автоматичний стан, підтримку MetaMask та WalletConnect, а також вбудовану обробку SSR. Wagmi скорочує обсяг boilerplate коду на 60% порівняно з прямим SDK. Для масштабованих проєктів Wagmi краще в 2,5 рази за часом розробки.
| Параметр |
Прямий Coinbase Wallet SDK |
Wagmi + connector |
| Налаштування |
Середнє (ручне управління) |
Високе (автоматичний стан) |
| SSR |
Потребує доопрацювання |
Вбудована через динамічний імпорт |
| Сумісність |
Тільки Coinbase |
Будь-які Wagmi-гаманці |
| Бандл |
~20 KB |
~50 KB |
Вибір залежить від пріоритетів. Якщо важливий малий розмір бандла — прямий SDK. Якщо потрібна гнучкість та підтримка інших гаманців — Wagmi.
Як ми реалізуємо інтеграцію за 2–3 дні?
Ми використовуємо Wagmi + coinbaseWallet connector. Це дозволяє централізовано управляти станом гаманця та підтримувати MetaMask, WalletConnect. Процес роботи:
| Етап |
Деталі |
Термін |
| Аналіз та архітектура |
Визначаємо спосіб інтеграції |
0.5 дня |
| Налаштування SDK та конфігурація |
Встановлення пакетів, chains, transport |
0.5 дня |
| Реалізація підключення та підписання |
Компонент, nonce, верифікація |
1 день |
| Mobile deep link та тестування |
Перевірка на iOS/Android |
0.5 дня |
| Документація та навчання |
README, передача коду |
0.5 дня |
Разом: від 2 до 4 днів залежно від складності. Інтеграція через Wagmi знижує витрати на розробку та підтримку приблизно на 30%. Вартість робіт — від $500 під ключ.
Що входить в роботу під ключ
- Вихідний код компонента (TypeScript, React/Vue/Angular)
- Налаштування WalletConnect Cloud (якщо потрібно)
- Інтеграція з бекендом (nonce, верифікація підписання)
- Тестування на реальних мобільних пристроях
- Документація та README
- Підтримка протягом 1 місяця після здачі
Ми маємо понад 10 років досвіду у веб-розробці та 50+ проєктів з Web3. Даємо гарантію на код 3 місяці. Вартість фіксована — оцініть свій проєкт за ТЗ. Для отримання консультації з інтеграції зв'яжіться з нашими інженерами. Пишіть нам — замовте інтеграцію Coinbase Wallet у ваш проєкт.
Аутентифікація та авторизація: OAuth, JWT, сесії, RBAC, 2FA
На одному проєкті токен JWT із роллю admin: false» міг бути змінений клієнтом на admin: true» — і сервер прийняв його без верифікації підпису. Ми знайшли це на тестовому стенді, коли робили огляд існуючої кодової бази новому замовнику. Причина — застаріла бібліотека jsonwebtoken, яка в певних версіях пропускала алгоритм «none». Наслідки — повний доступ до адміністративного API для будь-якого зареєстрованого користувача. Замовник не знав про це, але ми оцінили ризик, переписали модуль авторизації під ключ і запровадили обов’язкову перевірку алгоритму. Тепер подібних інцидентів немає. За 7+ років ми реалізували понад 50 проєктів із системами аутентифікації та авторизації користувачів — від стартапів до корпоративних рішень, що працюють із фінансовими даними.
Чому JWT не варто зберігати в localStorage?
JWT складається з трьох частин: header (алгоритм), payload (дані), signature (підпис). Підпис верифікує, що payload не змінено. Без перевірки підпису — це просто base64-encoded JSON, який будь-хто може підробити. Помилки, які бачимо в коді регулярно:
- Зберігання в localStorage. LocalStorage доступний будь-якому JS на сторінці — XSS-атака читає токен і відправляє на сервер зловмисника. Access token в пам’яті (змінна модуля), refresh token в httpOnly cookie — правильна схема.
- Довгоживучі access-токени. Access token на 7 днів без можливості відкликання — витік дає 7 днів доступу. Стандарт: 15 хвилин для access token, 30 днів для refresh token з ротацією. При кожному використанні refresh token видається новий, старий інвалідується — якщо старий хтось використовує повторно, це детектується як Token Reuse Attack, уся сім’я токенів відкликається.
- Зберігання секретних даних у payload. JWT payload не зашифровано, лише підписано — його видно в base64. Паролі, платіжні дані, особиста інформація — не в JWT. Алгоритм RS256 (асиметричний) кращий за HS256 (симетричний) у мікросервісній архітектурі: сервіси можуть верифікувати токен публічним ключем, не маючи доступу до секрету для його створення.
Як обрати між сесіями та токенами?
Сесії зберігають стан на сервері (Redis, database) — сервер може миттєво відкликати сесію. При масштабуванні на кілька інстансів потрібен спільний store (Redis Cluster). Cookie з session ID — httpOnly, Secure, SameSite=Strict.
Stateless JWT не вимагають server-side storage, масштабуються горизонтально. Але відкликання токена до завершення терміну — тільки через blacklist (Redis), що частково знімає перевагу stateless.
| Параметр |
Сесії (серверний стан) |
JWT (stateless) |
| Відкликання |
миттєве (видалити запис у Redis) |
лише через blacklist, потребує storage |
| Масштабування |
потрібен спільний Redis |
горизонтальне без додаткових компонентів |
| Безпека XSS |
токен у httpOnly cookie захищений |
при зберіганні в localStorage — ризик |
| Складність реалізації |
проста (сесійний middleware) |
вища (управління refresh, ротація) |
Для більшості веб-додатків сесії простіші та безпечніші. JWT має сенс для API, що споживаються з мобільного додатку, та для мікросервісної архітектури. Оцініть ваш сценарій — ми допоможемо обрати правильний підхід.
OAuth 2.0 та OpenID Connect
OAuth 2.0 — протокол делегованої авторизації, не аутентифікації. «Увійти через Google» — це OpenID Connect поверх OAuth 2.0, який додає id_token з даними користувача. Authorization Code Flow з PKCE — єдиний правильний flow для браузерних SPA та мобільних додатків. Implicit Flow застарів і небезпечний. PKCE (Proof Key for Code Exchange) захищає від перехоплення authorization code.
Реалізація OAuth сервера: не пишемо з нуля. Keycloak (open source, self-hosted), Auth0, Okta — готові рішення. Laravel Passport або Laravel Sanctum для серверних додатків. NextAuth.js для Next.js — підтримує 50+ провайдерів з коробки. Для B2B продуктів з корпоративними клієнтами — SAML 2.0 SSO. Корпоративні IT-відділи часто вимагають його замість OAuth. @boxyhq/saml-jackson — node.js бібліотека для SAML → OAuth2 адаптера.
RBAC, ABAC, ReBAC — що і коли застосовувати
Role-Based Access Control — у користувача є ролі, у ролей — права. Проста реалізація: user → roles → permissions. Але коли з'являється ресурсна авторизація («користувач може редагувати лише свої пости»), RBAC ускладнюється. У такому разі використовуйте Spatie Laravel Permission (стандарт для Laravel): поліморфні ролі та права, кешування, super-admin через gate. Інтеграція з Eloquent — $user->can('edit posts'), $user->hasRole('editor').
ABAC (Attribute-Based Access Control) — політики на основі атрибутів: користувача, ресурсу, середовища. Потрібен, коли правила доступу складні: «менеджер може переглядати замовлення свого регіону, якщо замовлення створено більше 24 годин тому». Casbin — популярна cross-language бібліотека для ABAC.
ReBAC (Relationship-Based Access Control) — Google Zanzibar model. Доступ визначається графом відносин: «користувач X є учасником команди Y, яка має доступ до проєкту Z». OpenFGA — open source реалізація від Okta.
Як ми це робимо: кейс із впровадження 2FA
Проєкт — платіжний шлюз для маркетплейсу. Потрібно було захистити доступ до операцій виводу коштів. Ми спроєктували систему:
- Основний пароль замінили на комбінацію пароль + TOTP (Google Authenticator). Використали
otplib (Node.js) для генерації та верифікації кодів.
- Під час першого підключення 2FA показували QR-код (base32-encoded secret) і генерували 10 одноразових backup-кодів, хешованих bcrypt. Відображали коди лише один раз.
- Secret для TOTP зберігали у зашифрованому вигляді в базі даних (AES-256-GCM, ключ у AWS KMS).
- На стороні фронтенду інтегрували
@simplewebauthn/browser для passkeys — біометрична аутентифікація як альтернатива паролю. Публічний ключ зберігали на сервері, private key на пристрої користувача.
- Результат: час на логін зріс на 5 секунд, але кількість зламаних акаунтів упала до нуля за пів року роботи. Гарантія безпеки — на рівні OWASP ASVS Level 2.
Також варто зазначити, що TOTP значно надійніше за SMS-верифікацію через SIM-swapping, тому для фінансових даних ми рекомендуємо TOTP або апаратні ключі.
Типові вразливості, які ми знаходимо
- Broken Object Level Authorization (BOLA/IDOR): /api/orders/12345 повертає замовлення без перевірки, чи належить воно поточному користувачу. Найпоширеніша вразливість API за OWASP. Кожен запит до ресурсу — перевірка через $user->can('view', $order).
- Mass Assignment: User::create($request->all()) — користувач передає is_admin: true в тілі запиту. Laravel вирішує через $fillable / $guarded, але часто забувають.
- Небезпечний CORS: Access-Control-Allow-Origin: * на API з авторизацією по cookie — credentials не передаються з wildcard origin, але якщо хтось зробив Allow-Credentials: true + Allow-Origin: * — це діра.
Penetration testing обов’язковий для продуктів з фінансовими даними або персональними даними користувачів. Ми проводимо аудит коду й інфраструктури на етапі приймання.
Що входить у роботу
Ми передаємо замовнику:
- Документацію архітектури авторизації (flow діаграми, опис токенів, політик доступу).
- Репозиторій із вихідним кодом, покритий unit- та integration-тестами.
- Конфігурацію для CI/CD (GitHub Actions/ GitLab CI) із перевірками безпеки.
- Доступи до середовищ (staging, production) із правами адміністратора.
- Інструкцію з експлуатації та супроводу.
- Підтримку після впровадження — 2 тижні безкоштовних консультацій.
Терміни та вартість
Базова аутентифікація (email/password + OAuth + JWT/сесії): 1–3 тижні. RBAC з детальними політиками доступу: 2–4 тижні. 2FA (TOTP + SMS): 1–2 тижні. WebAuthn/Passkeys: 2–3 тижні. Повна система аутентифікації для SaaS з multi-tenancy: 4–8 тижнів.
Вартість розраховується індивідуально залежно від обсягу та складності. Замовте консультацію — оцінимо ваш проєкт безкоштовно. Отримайте гарантію безпеки вашої авторизації користувачів.