Разработка Telegram-бота для управления портфелем

Проектируем и разрабатываем блокчейн-решения полного цикла: от архитектуры смарт-контрактов до запуска DeFi-протоколов, NFT-маркетплейсов и криптобирж. Аудит безопасности, токеномика, интеграция с существующей инфраструктурой.
Показано 1 из 1 услугВсе 1306 услуг
Разработка Telegram-бота для управления портфелем
Средняя
~1-2 недели
Часто задаваемые вопросы
Направления блокчейн-разработки
Этапы блокчейн-разработки
Последние работы
  • image_website-b2b-advance_0.png
    Разработка сайта компании B2B ADVANCE
    1258
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1170
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    873
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1092
  • image_logo-advance_0.png
    Разработка логотипа компании B2B Advance
    563
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    830

Разработка Telegram-бота для управления портфелем

Telegram — основная платформа крипто-сообщества. Управление портфелем прямо в мессенджере без переключения между приложениями — логичный следующий шаг. Бот может показывать балансы, отправлять уведомления об изменениях цен, выполнять свапы через DEX-агрегаторы и отслеживать позиции в DeFi протоколах.

Архитектура

Варианты хранения кошелька

Watch-only режим. Пользователь добавляет публичный адрес, бот только читает данные. Никакого риска для средств. Подходит для мониторинга.

Встроенный кошелёк. Бот генерирует key pair, encrypted private key хранится в базе данных. Пользователь устанавливает пароль/PIN, который используется для расшифровки при подписи. Наиболее удобный вариант для торговли, но требует безопасного хранения.

Connect существующего кошелька. Через WalletConnect v2 пользователь подключает MetaMask — транзакции подписываются в кошельке. Безопасно, но менее удобно (нужен мобильный кошелёк рядом).

Стек

Telegram Bot API (telegraf.js)
    ↓
Bot Server (Node.js + TypeScript)
    ├── Portfolio Service (балансы через Alchemy/DeBank API)
    ├── DeFi Service (позиции: AAVE, Compound, Uniswap)
    ├── Wallet Service (генерация, шифрование ключей)
    ├── Trading Service (свапы через 1inch/Paraswap API)
    └── Alert Service (price alerts, liquidation warnings)
         ↓
    PostgreSQL + Redis (sessions, cache)

Реализация основных функций

Балансы и портфолио

import { Telegraf, Context } from "telegraf";
import { message } from "telegraf/filters";

const bot = new Telegraf(process.env.BOT_TOKEN!);

bot.command("portfolio", async (ctx) => {
  const userId = ctx.from.id;
  const user = await userService.getUser(userId);
  
  if (!user?.watchAddress) {
    return ctx.reply("Добавьте адрес кошелька: /add_wallet 0x...");
  }
  
  await ctx.reply("Загружаю портфолио...");
  
  const portfolio = await portfolioService.getPortfolio(user.watchAddress);
  
  const message = formatPortfolioMessage(portfolio);
  await ctx.reply(message, { parse_mode: "HTML" });
});

function formatPortfolioMessage(portfolio: Portfolio): string {
  const totalUSD = portfolio.tokens.reduce((sum, t) => sum + t.valueUSD, 0);
  
  let msg = `<b>Портфолио</b> — $${totalUSD.toFixed(2)}\n\n`;
  
  for (const token of portfolio.tokens.sort((a, b) => b.valueUSD - a.valueUSD)) {
    const pct = ((token.valueUSD / totalUSD) * 100).toFixed(1);
    msg += `${token.symbol}: ${token.balance.toFixed(4)} ($${token.valueUSD.toFixed(2)}, ${pct}%)\n`;
  }
  
  if (portfolio.defiPositions.length > 0) {
    msg += `\n<b>DeFi позиции:</b>\n`;
    for (const pos of portfolio.defiPositions) {
      msg += `${pos.protocol}: $${pos.valueUSD.toFixed(2)} (${pos.type})\n`;
    }
  }
  
  return msg;
}

Price alerts

interface PriceAlert {
  userId: number;
  token: string;
  targetPrice: number;
  direction: 'above' | 'below';
  isTriggered: boolean;
}

// Worker который проверяет алерты каждую минуту
async function checkAlerts() {
  const activeAlerts = await db.alerts.findActive();
  const tokens = [...new Set(activeAlerts.map(a => a.token))];
  const prices = await priceService.getPrices(tokens);
  
  for (const alert of activeAlerts) {
    const currentPrice = prices[alert.token];
    const triggered = 
      (alert.direction === 'above' && currentPrice >= alert.targetPrice) ||
      (alert.direction === 'below' && currentPrice <= alert.targetPrice);
    
    if (triggered) {
      await bot.telegram.sendMessage(
        alert.userId,
        `🔔 ${alert.token} достиг $${currentPrice.toFixed(2)} (цель: $${alert.targetPrice})`
      );
      await db.alerts.markTriggered(alert.id);
    }
  }
}

Inline-клавиатуры для навигации

Удобный UX для бота — inline кнопки вместо команд:

bot.command("start", async (ctx) => {
  await ctx.reply("Главное меню", {
    reply_markup: {
      inline_keyboard: [
        [
          { text: "📊 Портфолио", callback_data: "portfolio" },
          { text: "💰 Балансы", callback_data: "balances" },
        ],
        [
          { text: "🔄 Своп", callback_data: "swap" },
          { text: "🔔 Алерты", callback_data: "alerts" },
        ],
        [
          { text: "⚙️ Настройки", callback_data: "settings" },
        ],
      ],
    },
  });
});

Безопасность хранения ключей

Если бот хранит private keys пользователей — это критичная ответственность:

  • Шифрование AES-256-GCM с ключом = KDF(user_pin + server_secret)
  • Server secret хранится в AWS Secrets Manager (не в коде)
  • PIN никогда не хранится, только проверяется через попытку расшифровки
  • Автоматический logout после N минут неактивности
  • Лимиты на транзакции (максимальная сумма в сутки)
  • Whitelist адресов-получателей

Данные для портфолио

Источник Что даёт
Alchemy Token API ERC-20 балансы по адресу
DeBank API DeFi позиции (AAVE, Compound, Uniswap LP)
CoinGecko API Цены токенов
1inch API Котировки свапов
Etherscan API История транзакций

Базовый мониторинг-бот (watch-only, балансы, DeFi позиции, price alerts) — 2-3 недели. Версия со встроенным кошельком и свапами — 4-6 недель с учётом security review.