Уявіть: у вас преміум-контент, доступ по NFT. Ви підключаєте готове рішення за 20 хвилин, але через тиждень користувачі скаржаться, що їхні Polygon-активи не враховуються, а TTL JWT занадто довгий. У 9 з 10 випадків готові інструменти не підходять: потрібна інтеграція з існуючою auth-системою, підтримка мультичейн, складні логічні умови (AND/OR/trait-based) або вимога мінімальної затримки. Ми розробили десятки кастомних token-gate систем і знайшли оптимальний стек.
Як ми реалізуємо token-gated доступ: від архітектури до деплою
Розглянемо ключові компоненти на прикладі production-проєкту для Web3-платформи з 50 000 DAU.
Чому server-side gating кращий за client-side?
Client-side перевірка — коли баланс перевіряється в браузері і контент ховається через CSS/JS. Контент уже в DOM, будь-хто може його побачити через DevTools. Підходить лише для soft gates. Server-side підхід — сервер перевіряє володіння токеном перед видачею контенту. Клієнт отримує лише те, до чого має доступ. Оптимальний варіант — JWT з blockchain claims: при логіні через SIWE (Sign-In with Ethereum) перевіряємо токени, вписуємо права в JWT. Подальші запити не вимагають звернення до ноди — лише JWT верифікація (у 95% випадків швидше, ніж on-chain check).
// Після успішної SIWE верифікації async function createSessionToken(address: string): Promise<string> { const [nftBalance, tokenBalance, ensName] = await Promise.all([ checkNFTOwnership(address), checkTokenBalance(address), resolveENS(address), ]); const roles: string[] = []; if (nftBalance > 0) roles.push("nft_holder"); if (tokenBalance >= parseEther("100")) roles.push("token_holder"); if (ensName) roles.push("ens_user"); return jwt.sign( { sub: address, roles, exp: Math.floor(Date.now() / 1000) + 3600, // 1 година }, process.env.JWT_SECRET! ); } Важливо: обирайте короткий expiry JWT (1-4 години). Для критичного контенту — ще коротше, з механізмом refresh через re-verification.
Як обробляти мультичейн сценарії?
Користувач може тримати NFT на Ethereum, токени на Polygon, а LP на Arbitrum. Перевіряємо паралельно:
const [ethBalance, polyBalance, arbBalance] = await Promise.all([ checkBalanceOnChain(address, "ethereum"), checkBalanceOnChain(address, "polygon"), checkBalanceOnChain(address, "arbitrum"), ]); const hasAccess = ethBalance > 0 || polyBalance > 0 || arbBalance > 0; Кешуємо результати в Redis з TTL 5-15 хвилин — постійні виклики до нод дорогі та повільні. Це знижує витрати на RPC в 10 разів при типовому навантаженні.
Складні умови доступу
Real-world token gates рідко бувають простими. Типові випадки:
- AND умова: потрібен І NFT, І достатній баланс токена.
- OR: достатньо будь-якої з умов.
- Trait-based: конкретні атрибути NFT (вимагає off-chain metadata або on-chain traits).
- Snapshot-based: баланс на конкретний блок (для airdrop eligibility).
Порівняння підходів
| Підхід | Безпека | Продуктивність | Складність реалізації |
|---|---|---|---|
| Client-side | Низька | Висока | Низька |
| Server-side | Висока | Середня (залежить від RPC) | Середня |
| JWT claims | Висока | Висока | Висока |
Наш досвід: JWT claims окупається при навантаженні від 1000 запитів/хв — час відповіді падає з 200-500 мс до 5-10 мс.
| TTL JWT | Ризик | Частота refresh | Рекомендація |
|---|---|---|---|
| < 1 год | Низький | Висока | Для цінного контенту |
| 1-4 год | Середній | Середня | Стандартний варіант |
| > 4 год | Високий | Низька | Уникати |
Middleware для API routes
// Express/Fastify middleware async function tokenGateMiddleware(req, res, next) { const token = req.headers.authorization?.replace("Bearer ", ""); if (!token) return res.status(401).json({ error: "Unauthorized" }); try { const payload = jwt.verify(token, process.env.JWT_SECRET) as JWTPayload; if (!payload.roles.includes("nft_holder")) { return res.status(403).json({ error: "NFT required" }); } req.user = payload; next(); } catch { return res.status(401).json({ error: "Invalid token" }); } } Делегування через delegate.cash
Користувач не хоче підключати cold wallet до сайту — це ризиковано. delegate.cash (EIP-5639) дозволяє власнику cold wallet делегувати права на hot wallet. Ми обов'язково реалізуємо підтримку цього стандарту. На практиці достатньо перевірити запис delegate для контракту колекції.
Процес роботи
- Аналіз вимог: визначаємо типи токенів, мережі, умови доступу, навантаження.
- Проектування архітектури: обираємо підхід (SIWE + JWT або server-side), проектуємо схему даних.
- Реалізація: пишемо смарт-контракти (якщо потрібні), бекенд middleware, frontend-компоненти.
- Інтеграція та тестування: підключаємо до існуючої системи (auth, API), проводимо навантажувальне тестування (гарантуємо обробку до 5000 запитів/сек).
- Деплой та моніторинг: розгортаємо в staging/production, налаштовуємо моніторинг та сповіщення.
Що входить в роботу
- Документація: архітектурна схема, опис API, інструкція з розгортання.
- Доступи до коду в приватному репозиторії, RPC-ключам та інфраструктурі.
- Навчання команди: 2 години онлайн-воркшопу з підтримки системи.
- Підтримка на 3 місяці після запуску (фікси, консультації).
Типові помилки та як їх уникнути
- Занадто довгий TTL для JWT — проданий NFT зберігає доступ на тиждень. Рішення: TTL не більше 4 годин, refresh через re-verification.
- Ігнорування мультичейн сценаріїв — користувачі скаржаться, що їхні активи на Polygon не враховуються. Рішення: з самого початку проектуємо мультичейн.
- Відсутність кешування — кожна перевірка викликає RPC, що дорого та повільно. Рішення: Redis з TTL 5-15 хвилин.
- Поганий UX при відмові — користувач не розуміє, що робити. Рішення: конкретне повідомлення з ціною та посиланням на маркетплейс.
Зв'яжіться з нами для оцінки вашого проєкту: ми проаналізуємо вимоги та запропонуємо оптимальне рішення. Замовте розробку token-gated системи — отримайте консультацію з архітектури.







