Розробка Lightning-бота для Telegram

Проєктуємо та розробляємо блокчейн-рішення повного циклу: від архітектури смарт-контрактів до запуску DeFi-протоколів, NFT-маркетплейсів та криптобірж. Аудит безпеки, токеноміка, інтеграція з наявною інфраструктурою.
Показано 1 з 1Усі 1306 послуг
Розробка Lightning-бота для Telegram
Середній
~3-5 днів
Часті запитання

Напрямки блокчейн-розробки

Етапи блокчейн-розробки

Останні роботи

  • image_website-b2b-advance_0.webp
    Розробка сайту компанії B2B ADVANCE
    1285
  • image_web-applications_feedme_466_0.webp
    Розробка веб-додатків для компанії FEEDME
    1198
  • image_websites_belfingroup_462_0.webp
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    902
  • image_ecommerce_furnoro_435_0.webp
    Розробка інтернет магазину для компанії FURNORO
    1122
  • image_logo-advance_0.webp
    Розробка логотипу компанії B2B Advance
    589
  • image_crm_enviok_479_0.webp
    Розробка веб-додатків для компанії Enviok
    859

Розробка Lightning-бота для Telegram

Lightning Network — це не просто «швидкий Bitcoin». Це окремий протокол зі своєю моделлю стану, платіжними каналами, routing-алгоритмами та специфічними видами атак. Telegram-бот поверх Lightning — це UI-шар над цією інфраструктурою, і помилка в інтеграції коштує користувачам реальних грошей.

Типичний запит: «зробіть бота, щоб користувачі могли отримувати та відправляти сатоші». За цим скриває вибір архітектури ноди, модель кастодіального зберігання, управління ліквідністю каналів та логіка обробки неудачних платежів.

Архітектура: кастодіальна vs non-custodial

Це перший та найважливіший вибір, який визначає все решту.

Кастодіальна модель

Бот тримає єдину Lightning-ноду, користувачі — це просто записи в базі даних з балансами. Платежі між користувачами всередині бота — off-chain операції всередину вашої БД, без реальних Lightning-транзакцій.

Переваги: немає проблем із routing, миттєві внутрішні переводи, проста реалізація. Недостатки: ви кастодіан, вимагається ліцензія у більшості юрисдикцій, користувачі вам довіряють — як біржа, тільки менше регулювання.

Архітектура:

Telegram Bot → Node.js сервіс → PostgreSQL (баланси) → LND/CLN нода (для зовнішніх платежів)

Внутрішній переведення — транзакція в PostgreSQL. Зовнішній вивід — реальний Lightning invoice через ноду. Поповнення — генерація invoice через ноду, мониторинг платежу.

Non-custodial через LSP

Lightning Service Provider (LSP) керує каналами користувача. Користувач тримає власні ключі, LSP забезпечує ліквідність. Протокол LSPS0-LSPS2 стандартизує це взаємодію.

Реалізація складніша: потрібно інтегруватися з LSP API (Breez SDK, LDK-node), керувати channel open/close, пояснювати користувачам концепцію каналів. Для Telegram-бота це зазвичай надмірно.

Практичний вибір для більшості проектів: кастодіальна модель з прозорою комунікацією користувачам, що бот кастодіальний.

Lightning-нода: LND vs Core Lightning

LND (Lightning Network Daemon)

Go, розробка Lightning Labs. gRPC API з хорошою документацією. Найпопулярніший для інтеграцій — більше SDK та прикладів.

import { AuthenticatedLnd } from "lightning";
import { createInvoice, payViaRoutes, getWalletInfo } from "lightning";

// Створення invoice для поповнення
const { request, id } = await createInvoice({
  lnd,
  tokens: 10000, // сатоші
  description: `Deposit for user ${userId}`,
  expires_at: new Date(Date.now() + 3600 * 1000).toISOString(),
});

Пакет lightning (npm) — типізована обгортка над LND gRPC. Значно зручніше raw gRPC.

Core Lightning (CLN)

C, розробка Blockstream. Більш модульна архітектура через plugin-систему. JSON-RPC API. Менше екосистема, але продуктивніше на великій кількості каналів.

Для більшості Telegram-ботів з обсягом до 10k користувачів — різниці немає. Вибирайте по знайомості стека та наявності документації.

Управління ліквідністю каналів

Головна операційна проблема Lightning-бота — ліквідність. У Lightning-каналу є inbound capacity (скільки можна отримати) та outbound capacity (скільки можна відправити). Після відкриття каналу вся ліквідність на вашій стороні — ви можете відправляти, але не отримувати.

Для бота, що приймає поповнення користувачів, потрібна inbound ліквідність:

Покупка inbound liquidity — сервіси типу Bitrefill Thor, Lightning Pool (LND), або ручні договорівки з routing-нодами. Ви платите провайдеру, він відкриває канал до вас з балансом на його стороні.

Circular rebalancing — якщо баланс змістився (багато outbound операцій), можна провести круговую платіжку через мережу: відправити через A → B → C → собі. Платите routing fee, але перебалансуєте канал.

// Мониторинг баланса каналу
const channels = await getChannels({ lnd });
for (const channel of channels.channels) {
  const localRatio = channel.local_balance / channel.capacity;
  if (localRatio < 0.2) {
    // Мало outbound — потрібна rebalance
    await alertOps(`Channel ${channel.id}: low outbound liquidity`);
  }
  if (localRatio > 0.8) {
    // Мало inbound — не можемо приймати платежі
    await alertOps(`Channel ${channel.id}: low inbound liquidity`);
  }
}

Для production бота потрібен автоматичний rebalancing або інтеграція з сервісом ліквідності.

Обробка платежів у боті

Webhook vs polling для Telegram

Webhook переважніший: менше latency, немає ліміту на частоту запитів. Вимагає публічний HTTPS endpoint. Для production — обов'язково webhook.

import { Telegraf } from "telegraf";
const bot = new Telegraf(BOT_TOKEN);

bot.command("deposit", async (ctx) => {
  const userId = ctx.from.id.toString();
  const invoice = await createDepositInvoice(userId, 0); // будь-яка сума
  await ctx.reply(
    `Ваш Lightning invoice для поповнення:\n\n\`${invoice.request}\`\n\nДійсний 1 годину.`,
    { parse_mode: "Markdown" }
  );
});

Мониторинг вхідних платежів

LND надає subscribeToInvoices — stream, що нотифікує при кожному settlement:

const sub = subscribeToInvoices({ lnd });
sub.on("invoice_updated", async (invoice) => {
  if (!invoice.is_confirmed) return;
  
  const userId = await getUserByInvoiceId(invoice.id);
  if (!userId) return;
  
  await db.transaction(async (trx) => {
    await trx("users")
      .where({ id: userId })
      .increment("balance_sats", invoice.received);
    await trx("transactions").insert({
      user_id: userId,
      type: "deposit",
      amount_sats: invoice.received,
      lightning_id: invoice.id,
      confirmed_at: new Date(),
    });
  });
  
  await bot.telegram.sendMessage(userId, 
    `Отримано ${invoice.received} sat. Баланс оновлено.`
  );
});

Важливо: операція повинна бути ідемпотентною — якщо воркер упав та перезапустився, повторна обробка одного invoice не повинна зачислити деньги двічі. lightning_id з UNIQUE constraint — проста захист.

Відправлення платежів (вивід)

Користувач вставляє invoice, бот його оплачує:

async function processWithdrawal(userId: string, invoiceStr: string) {
  const decoded = await decodePaymentRequest({ lnd, request: invoiceStr });
  
  // Перевірки
  if (decoded.tokens > user.balance_sats) throw new Error("Недостатньо коштів");
  if (decoded.expires_at < new Date()) throw new Error("Invoice мав");
  
  // Резервуємо баланс ДО відправки
  await db("users")
    .where({ id: userId })
    .decrement("balance_sats", decoded.tokens);
  
  try {
    const payment = await pay({ lnd, request: invoiceStr });
    // Успішно, записуємо транзакцію
    await recordWithdrawal(userId, decoded.tokens, payment.id);
  } catch (err) {
    // Платіж не пройшов — повертаємо баланс
    await db("users")
      .where({ id: userId })
      .increment("balance_sats", decoded.tokens);
    throw new Error(`Платіж не пройшов: ${err.message}`);
  }
}

Порядок операцій критичен: спочатку резервуємо, потім відправляємо. Іначе — double spend при паралельних запитах. Повернення при помилці — обов'язково.

Специфічні атаки на Lightning-ботів

Invoice replay: користувач присилає один і той же invoice двічі. Захист — зберігати всі оброблені payment hashes, перевіряти перед обробкою.

Amount mismatch на депозитах: користувач створив invoice на 1000 sat, хтось відправив 999 sat (partial amount). LND за замовчуванням приймає будь-яку суму якщо invoice без tokens. Завжди створюйте amount-less invoice або явно указуйте amount та перевіряйте received.

Timing attack на вивід: паралельні запити на вивід одночасно читають баланс та обидва бачать достатньо коштів. Захист — оптимістичний лок через UPDATE users SET balance = balance - X WHERE balance >= X AND id = Y, перевіряти affected rows.

Стек та деплой

  • Нода: LND 0.18.x на окремому сервері/VPS, Bitcoin full node або Neutrino (легкий клієнт)
  • Backend: Node.js + TypeScript + Fastify
  • База даних: PostgreSQL, таблиці: users, invoices, transactions, channels_log
  • Мониторинг: Grafana + LND Prometheus exporter, алерти на channel offline, низьку ліквідність
  • Резервні копії: SCB (Static Channel Backups) автоматично після кожної зміни каналу — це обов'язково, без цього при краху ноди потеряєте середства користувачів

Для запуску Lightning-ноди потрібно закласти на канальний депозит: мінімум 0.1 BTC для малого бота, 0.5–1 BTC для production з нормальною ліквідністю.

Сроки розробки

MVP з кастодіальною моделлю, deposit/withdraw, базовим p2p переводом — 3–4 тижні. Production з авто-rebalancing, мониторингом ліквідності, multi-channel управлінням, повним аудитом транзакцій — 8–12 тижнів.