Разработка Discord-бота верификации NFT-холдеров

Проектируем и разрабатываем блокчейн-решения полного цикла: от архитектуры смарт-контрактов до запуска DeFi-протоколов, NFT-маркетплейсов и криптобирж. Аудит безопасности, токеномика, интеграция с существующей инфраструктурой.
Показано 1 из 1 услугВсе 1306 услуг
Разработка Discord-бота верификации NFT-холдеров
Средняя
~3-5 рабочих дней
Часто задаваемые вопросы
Направления блокчейн-разработки
Этапы блокчейн-разработки
Последние работы
  • 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

Разработка Discord-бота верификации NFT-холдеров

NFT-проект без системы верификации холдеров — это публичный Discord, где обладатели токенов ничем не отличаются от случайных посетителей. Holder-only каналы, early access к новым минтам, governance-голосования — всё это требует proof of ownership, который обновляется при каждом трансфере токена. Технически задача состоит из трёх слоёв: on-chain проверка через RPC, OAuth авторизация через Discord, и периодическая ревалидация ролей при изменении баланса.

Архитектура системы верификации

Wallet signature flow

Стандартный flow верификации без хранения приватных ключей:

  1. Пользователь нажимает /verify в Discord
  2. Бот отправляет ему DM с уникальным challenge message (UUID + timestamp)
  3. Пользователь подписывает message в MetaMask через WalletConnect или custody wallet
  4. Отправляет подпись боту
  5. Бот восстанавливает адрес через ecrecover (или viem.verifyMessage()), проверяет баланс NFT через RPC
import { verifyMessage } from 'viem';

const recoveredAddress = await verifyMessage({
  address: claimedAddress,
  message: challengeMessage,
  signature: userSignature,
});

if (!recoveredAddress) throw new Error('Invalid signature');

const balance = await publicClient.readContract({
  address: NFT_CONTRACT,
  abi: erc721Abi,
  functionName: 'balanceOf',
  args: [claimedAddress],
});

Challenge message должен содержать timestamp с коротким TTL (5-10 минут). Без TTL — атакующий может повторно использовать перехваченную подпись (signature replay). Храним использованные challenges в Redis с автоматическим истечением.

Мультиконтрактная верификация

Большинство реальных проектов верифицируют не один контракт, а несколько: основная коллекция + companion collection + staking контракт. Роли выдаются по комбинации условий:

Gold holder = balance(MainNFT) >= 1 AND balance(CompanionNFT) >= 1
Diamond holder = balance(MainNFT) >= 5
Staker = stakedBalance(StakingContract, address) >= 1

Для staking-контрактов нужен отдельный ABI вызов: стандартный balanceOf ERC-721 не учитывает застейканные токены (они принадлежат staking контракту, не пользователю). Вызываем stakedTokensOf(address) или аналог из кастомного staking контракта.

Периодическая ревалидация ролей

Это критичная часть, которую часто пропускают. Пользователь продал NFT — его Discord роль должна быть отозвана. Реализуем через scheduled job:

// Cron job каждые 6-12 часов
async function revalidateAllHolders() {
  const verifiedUsers = await db.getAllVerifiedUsers();
  
  for (const user of verifiedUsers) {
    const currentBalance = await checkNFTBalance(user.walletAddress);
    const requiredRoles = calculateRoles(currentBalance);
    
    await syncDiscordRoles(user.discordId, requiredRoles);
  }
}

Частота ревалидации — баланс между актуальностью и RPC rate limits. Для высоко-торгуемых коллекций (> 100 трансферов/день) — каждые 6 часов. Для медленных — раз в 24 часа. Альтернатива — event listening через WebSocket subscription на Transfer события контракта, но это требует стабильного WebSocket соединения 24/7.

Хранение данных и GDPR

Храним минимум: {discordId, walletAddress, verifiedAt}. Никаких дополнительных on-chain данных. В ЕС при наличии европейской аудитории — право на удаление через /unverify команду. Реализуем purge при удалении записи из Discord сервера.

Пароль к wallet — никогда не запрашиваем. Подпись message ≠ доступ к средствам, но объясняем это пользователям явно в интерфейсе бота.

Стек реализации

Discord.js v14 — основной фреймворк бота. Slash commands (не message commands — Discord deprecated). Кнопки для inline верификации без DM если нужно.

viem для on-chain взаимодействия — легче ethers.js по bundle size, строго типизирован.

PostgreSQL для хранения верифицированных пользователей. Redis для challenge message cache.

Alchemy/QuickNode как RPC провайдер — нативные WebSocket для event subscriptions, выше rate limits чем публичные ноды.

Для multi-chain коллекций (Ethereum + Polygon, например) — отдельный publicClient для каждого чейна, агрегация результатов перед выдачей ролей.

Процесс работы

Настройка (0.5 дня). Регистрация Discord Application, настройка bot permissions (MANAGE_ROLES обязательно), конфигурация ролей на сервере.

Разработка (2-3 дня). Core бот с verify flow, мультиконтрактная логика, scheduled ревалидация, база данных, деплой на VPS (Docker + PM2).

Тестирование (0.5-1 день). Тестирование на staging сервере: корректность выдачи ролей, ревалидация после трансфера, edge cases (нулевой баланс, множественные кошельки).

Базовый бот с верификацией одного контракта — 2-3 дня. С мультиконтрактной логикой, кастомными ролями и event-driven ревалидацией — 4-5 дней. Стоимость рассчитывается индивидуально.