Розробка платежного шлюза на Lightning Network
Lightning Network — це не просто "швидкий Bitcoin". Це принципово інша модель розрахунків: off-chain канали з on-chain settlement. Перед тим як будувати платежний шлюз, потрібно розуміти, що Lightning — це мережа ліквідності, та управління цією ліквідністю — основна операційна задача, якої немає в аналогів на базі L1.
Архітектура Lightning: що потрібно знати інженеру
Платіж по Lightning проходить не напрямку від sender до receiver, а по шляху через проміжні вузли. Вузол А → Вузол Б → Вузол В → Вузол Г: кожен проміжний вузел "перенаправляє" HTLCs (Hash Time-Locked Contracts). Якщо на якому-то hop не хватає ліквідності в потрібному напрямку — платіж фейлиться та потрібно пробувати інший path.
Для платежного шлюза це означає: inbound ліквідність — критичний ресурс. Щоб приймати Lightning платежі, ваш вузол повинен мати inbound capacity від добре підключених вузлів мережі.
Вибір node implementation
LND (Lightning Labs, Go): найпоширеніший, багатий gRPC/REST API, хороша документація. Рекомендується для більшості production шлюзів.
CLN (Core Lightning, Blockstream, C): більш модульна архітектура, plugin система. Дещо складніший API.
Eclair (ACINQ, Scala): використовується в Phoenix wallet backend. Менш поширений для серверного використання.
Для шлюза вибираємо LND — найкращий API та екосистема.
Настройка LND ноди
lnd --bitcoin.active \
--bitcoin.mainnet \
--bitcoin.node=bitcoind \
--bitcoind.rpchost=localhost \
--bitcoind.rpcuser=rpcuser \
--bitcoind.rpcpass=rpcpassword \
--bitcoind.zmqpubrawblock=tcp://127.0.0.1:28332 \
--bitcoind.zmqpubrawtx=tcp://127.0.0.1:28333 \
--rpclisten=0.0.0.0:10009 \
--tlsextraip=YOUR_SERVER_IP \
--alias="YourGateway" \
--color=#FF6B35
Для API взаємодії — lnd-grpc клієнт. Сертифікат та macaroon (credential файл) обов'язкові для кожного запиту.
Створення інвойса та очікування оплати
package lightning
import (
"context"
"encoding/hex"
lnrpc "github.com/lightningnetwork/lnd/lnrpc"
"google.golang.org/grpc"
)
type LNDClient struct {
conn *grpc.ClientConn
client lnrpc.LightningClient
}
func (c *LNDClient) CreateInvoice(
ctx context.Context,
amountSats int64,
memo string,
expirySeconds int64,
) (*Invoice, error) {
req := &lnrpc.Invoice{
Value: amountSats,
Memo: memo,
Expiry: expirySeconds, // рекомендується 300–900 секунд
}
resp, err := c.client.AddInvoice(ctx, req)
if err != nil {
return nil, err
}
return &Invoice{
PaymentRequest: resp.PaymentRequest, // BOLT-11 строка для клієнта
PaymentHash: hex.EncodeToString(resp.RHash),
ExpiresAt: time.Now().Add(time.Duration(expirySeconds) * time.Second),
}, nil
}
BOLT-11 строка (lnbc500u1p...) — це QR-код та посилання для клієнта. Гаманець декодує її та знає куди платити.
Підписка на settled інвойси
func (c *LNDClient) WatchInvoices(ctx context.Context, handler func(*lnrpc.Invoice)) error {
stream, err := c.client.SubscribeInvoices(ctx, &lnrpc.InvoiceSubscription{})
if err != nil {
return err
}
for {
invoice, err := stream.Recv()
if err != nil {
return err
}
if invoice.State == lnrpc.Invoice_SETTLED {
handler(invoice)
}
}
}
SubscribeInvoices — кращий спосіб отримувати сповіщення про оплату. Уникайте polling LookupInvoice у цикла — це створює ненужне навантаження.
Управління ліквідністю
Головна операційна задача для production шлюза. Канал має capacity (загальний розмір) та balance (розподіл між сторонами). При приєму платежів balance зміщується в вашу сторону — inbound capacity витрачається. При відправці — навпаки.
Loop: submarine swaps
Lightning Loop (Lightning Labs) дозволяє "перебалансувати" канал через submarine swap — атомарний обмін між on-chain BTC та off-chain Lightning sat без закриття каналу:
Loop Out: переводимо Lightning sat → on-chain BTC. Відновлює inbound capacity. Loop In: переводимо on-chain BTC → Lightning sat. Відновлює outbound capacity.
# Відновити 500k sat inbound capacity через Loop Out
loop out --amt 500000 --channel YOUR_CHANNEL_ID
Вартість: 0.1–0.3% + on-chain fee. Для шлюза з постійним inflow — автоматичний Loop Out при досяженні порога (outbound balance > 80% channel capacity).
Pool: аренда ліквідності
Lightning Pool — маркетплейс для аренди inbound ліквідності. Продавці відкривають канали до вашого вузла за комісію. Срок аренди: 2016 блоків (~2 тижні). Альтернатива самостійному менеджменту каналів для старту.
Автоматична ребалансировка
async def auto_rebalance(lnd_client: LNDClient):
channels = await lnd_client.list_channels()
for channel in channels:
balance_ratio = channel.local_balance / channel.capacity
# Слишком много исходящей ликвидности — делаем Loop Out
if balance_ratio > 0.85:
amount = int((balance_ratio - 0.5) * channel.capacity)
await loop_out(amount, channel.chan_id)
# Слишком мало — платим через этот канал или делаем Loop In
elif balance_ratio < 0.15:
amount = int((0.5 - balance_ratio) * channel.capacity)
await rebalance_circular(amount, channel.chan_id, lnd_client)
BOLT-12 Offers: наступне покоління інвойсів
BOLT-11 — одноразовий інвойс. BOLT-12 Offers — багаторазові переиспользуемые payment codes:
lno1qgsyxjtl6luzd9t3pr62xr7eemp6awnejusgd4...
Клієнт запитує актуальний інвойс у отримувача через onion-повідомлення, отримує BOLT-11 (або BOLT-12 invoice), платить. Працює для підписок, tips, recurring payments. LND підтримує BOLT-12 з версії 0.17.
Безпека
Watchtower: якщо ваш вузол offline, бувший контрагент може спробувати транслювати старе стан каналу (breach attempt). Watchtower-сервіс мониторит блокчейн та публікує penalty транзакцію. LND має вбудований watchtower client та server.
# Підключення до публічного watchtower
lncli wtclient add [email protected]:9911
Channel backup: SCBs (Static Channel Backups) дозволяють відновити кошти з каналів при втраті node state. Автоматично створюються LND, потрібно зберігати безпечно.
Macaroon ограничення: для API доступу додатків видаємо обмежені macaroon — тільки права на створення інвойсів без права ініціювати платежі:
lncli bakemacaroon invoices:write invoices:read
Інтеграція з backend
REST API обёртка над LND для merchant додатків:
POST /api/invoices - створити інвойс
GET /api/invoices/:hash - статус інвойса
WS /api/invoices/stream - real-time подій оплати
Webhook при оплаті — та сама схема що для on-chain платежного шлюза (HMAC-SHA256 підпис).
Fiat конвертація: при створенні інвойса приймаємо fiat суму, конвертуємо в satoshi по поточному курсу (Kraken/Coinbase API), фіксуємо курс на час життя інвойса.
Інфраструктура
- Dedicated server або VPS (не контейнер без persistent storage)
- Bitcoin full node (витрачає ~600GB NVMe)
- LND поверх bitcoind
- Мінімальний первісний капітал для відкриття каналів: 0.1–0.5 BTC для малого шлюза
Розробка базового Lightning платежного шлюза з створенням інвойсів, мониторингом оплат та автоматичним Loop Out — 6–8 тижнів. З повним ліквідити-менеджментом, BOLT-12 підтримкою та admin дашбордом — 3–4 місяці.







