Представьте: у вас премиум-контент, доступ по 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 системы — получите консультацию по архитектуре.







