Інтеграція з Eclair (Lightning)

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

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

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

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

  • image_website-b2b-advance_0.webp
    Розробка сайту компанії B2B ADVANCE
    1286
  • 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

Інтеграція з Eclair (Lightning)

Eclair — реалізація Lightning Network на Scala від ACINQ. На відміну від LND з його монолітною архітектурою, Eclair строго слідує BOLT специфікаціям й відомий production надійністю: на ньому працює Phoenix wallet (мобільний Lightning гаманець ACINQ) й кілька великих сервісів. Якщо ваш стек JVM-based або ви вже працюєте з ACINQ екосистемою — це природний вибір.

Запуск та конфігурація

Вимоги

Eclair потребує Bitcoin Core ноди для доступу до blockchain даних. Нейтрино (спрощений режим) Eclair не підтримує — потрібна повна нода.

eclair.conf (Typesafe Config формат):

eclair {
  chain = "mainnet"
  server.port = 9735
  api.enabled = true
  api.port = 8080
  api.password = "your-api-password"
  
  bitcoind {
    host = "localhost"
    rpcport = 8332
    rpcuser = "bitcoinrpc"
    rpcpassword = "rpcpassword"
    zmqblock = "tcp://127.0.0.1:28334"
    zmqtx = "tcp://127.0.0.1:28335"
  }
  
  # Політика комісій для routing
  router.path-finding.default.max-fee-flat-sat = 21
  router.path-finding.default.max-fee-proportional = 0.01 // 1%
  
  # Лімити каналів
  max-htlc-value-in-flight-msat = 100000000000  // 1 BTC у msat
}

HTTP API: основні операції

Eclair надає REST API (form-encoded POST запити, не JSON body — це часто викликає плутанину):

# Інформація про ноду
curl -u :your-password http://localhost:8080/getinfo

# Відкрити канал
curl -u :your-password http://localhost:8080/open \
  -d nodeId=<peer_pubkey> \
  -d fundingSatoshis=1000000 \
  -d pushMsat=0

# Створити invoice
curl -u :your-password http://localhost:8080/createinvoice \
  -d description="Payment for order 123" \
  -d amountMsat=50000000 \
  -d expireIn=3600
  
# Відправити платіж
curl -u :your-password http://localhost:8080/payinvoice \
  -d invoice=lnbc500u1p... \
  -d blocking=true

TypeScript клієнт

import axios from "axios";
import FormData from "form-data";

class EclairClient {
  private readonly http = axios.create({
    baseURL: `http://${this.host}:${this.port}`,
    auth: { username: "", password: this.password },
  });

  async createInvoice(params: {
    amountMsat: number;
    description: string;
    expireIn?: number;
  }): Promise<{ serialized: string; paymentHash: string }> {
    const form = new FormData();
    form.append("amountMsat", params.amountMsat.toString());
    form.append("description", params.description);
    if (params.expireIn) form.append("expireIn", params.expireIn.toString());

    const { data } = await this.http.post("/createinvoice", form, {
      headers: form.getHeaders(),
    });
    return data;
  }

  async payInvoice(invoice: string, maxFeeMsat?: number): Promise<PaymentResult> {
    const form = new FormData();
    form.append("invoice", invoice);
    form.append("blocking", "true"); // чекаємо результату
    if (maxFeeMsat) form.append("maxFeeFlatMsat", maxFeeMsat.toString());

    const { data } = await this.http.post("/payinvoice", form, {
      headers: form.getHeaders(),
    });
    return data;
  }

  async getPayment(paymentHash: string): Promise<PaymentStatus> {
    const form = new FormData();
    form.append("paymentHash", paymentHash);
    const { data } = await this.http.post("/getsentinfo", form, {
      headers: form.getHeaders(),
    });
    return data[0];
  }
}

WebHooks: real-time события

Eclair підтримує WebHook нотифікації про события — основний спосіб реагувати на вхідні платежі без polling:

// eclair.conf
eclair.api.webhooks = [
  {
    id = "my-backend"
    url = "https://your-backend.com/eclair/webhook"
    secret = "webhook-secret-for-hmac"
  }
]

Типи подій:

type EclairEvent =
  | { type: "payment-received"; paymentHash: string; amount: number; timestamp: number }
  | { type: "payment-sent"; paymentHash: string; amount: number; feesPaid: number }
  | { type: "payment-failed"; paymentHash: string; failures: string[] }
  | { type: "channel-opened"; channelId: string; remotePubkey: string; capacity: number }
  | { type: "channel-closed"; channelId: string; reason: string };

Обробник webhook з верифікацією підпису:

app.post("/eclair/webhook", (req, res) => {
  const signature = req.headers["x-eclair-hmac"];
  const expectedSig = createHmac("sha256", WEBHOOK_SECRET)
    .update(JSON.stringify(req.body))
    .digest("hex");

  if (signature !== expectedSig) {
    return res.status(401).send("Invalid signature");
  }

  const event: EclairEvent = req.body;

  if (event.type === "payment-received") {
    handleIncomingPayment(event.paymentHash, event.amount);
  }

  res.sendStatus(200);
});

Особливості Eclair порівняно з LND

BOLT-12 підтримка — Eclair реалізує BOLT-12 Offers раніше й повніше, ніж LND. Якщо вам потрібні reusable payment codes або offline платіжні схеми — Eclair преимущество.

Trampoline routing — механізм делегування pathfinding на проміжну ноду. Критично для мобільних клієнтів (Phoenix використовує це): легкий клієнт не хоче зберігати повний граф мережі. Eclair — одна з небагатьох реалізацій з production підтримкою Trampoline.

# Відправити через trampoline
curl -u :password http://localhost:8080/payinvoice \
  -d invoice=lnbc... \
  -d trampolineNodeId=<trampoline_pubkey> \
  -d blocking=true

API стиль: form-encoded замість JSON. Це не баг, це design decision. Генерувати form data з існуючих JSON структур — одна додаткова строка.

Metrologia: Eclair експортує метрики через вбудований Kamon instrumentation. Prometheus ендпоінт включається конфігурацією:

kamon.prometheus.embedded-server.port = 9095

Типові сценарії інтеграції

Merchant платежі

  1. Користувач вибирає "оплата Lightning" → POST /createinvoice → QR код / BOLT-11 строка
  2. Webhook payment-received → оновити статус замовлення в БД
  3. Дублюючий polling через /getreceivedinfo для надійності (на випадок пропущеного webhook)

Масові виплати

async function bulkPayout(payments: { invoice: string; maxFeeMsat: number }[]) {
  const results = await Promise.allSettled(
    payments.map((p) => eclairClient.payInvoice(p.invoice, p.maxFeeMsat))
  );

  const failed = results
    .map((r, i) => ({ result: r, payment: payments[i] }))
    .filter((r) => r.result.status === "rejected");

  // Логування помилок, retry з exponential backoff
  for (const { payment, result } of failed) {
    logger.error("Payment failed", { invoice: payment.invoice, reason: result });
  }
}

Канальна політика для routing ноди

Eclair дозволяє встановлювати індивідуальні fee політики на канал:

# Оновити політику для конкретного каналу
curl -u :password http://localhost:8080/updaterelayfee \
  -d channelId=<channel_id> \
  -d feeBaseMsat=1000 \
  -d feeProportionalMillionths=100  # 0.01%

Моніторинг production ноди

Ключові метрики для Eclair:

  • channels.count за станом (NORMAL, CLOSING, OFFLINE)
  • payment.sent.success_rate — % успішних вихідних платежів
  • payment.received.count / amount — вхідний потік
  • router.graph.nodes й channels — розмір мережі видимий ноді

Grafana дашборд з цими метриками — стандартна операційна необхідність для будь-якої Lightning ноди з більш ніж кількома каналами.

Срок інтеграції Eclair у існуючий backend (прийом й відправка платежів, webhook обробка, моніторинг): 3–5 тижнів.