Разработка и интеграция LNURL-протокола для Lightning-платежей

Интеграция LNURL-протокола Попытка принять Lightning-платёж без LNURL — это пять шагов копирования и вставки, где каждый — потеря клиента. Пользователю нужно скопировать invoice из кошелька продавца, переключиться в свой кошелёк, вставить и оплатить. На практике это съедает до 30% конверсии. **LN

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

Часто задаваемые вопросы

Последние работы

  • image_website-b2b-advance_0.webp
    Разработка сайта компании B2B ADVANCE
    1451
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1309
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    1005
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1270
  • image_logo-advance_0.webp
    Разработка логотипа компании B2B Advance
    719
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    1011

Интеграция LNURL-протокола

Попытка принять Lightning-платёж без LNURL — это пять шагов копирования и вставки, где каждый — потеря клиента. Пользователю нужно скопировать invoice из кошелька продавца, переключиться в свой кошелёк, вставить и оплатить. На практике это съедает до 30% конверсии. LNURL-интеграция устраняет эту боль: кошелёк автоматически запрашивает invoice через HTTP, достаточно одного сканирования QR. UX приближается к обычным платёжным системам.

Наша команда реализует LNURL-решения под ключ: от настройки ноды до внедрения Lightning Address. Накопленный опыт десятков проектов позволяет предвидеть типичные сложности — от проблем с ликвидностью до ошибок конфигурации TLS.

Почему стоит выбрать LNURL-интеграцию?

LNURL радикально улучшает пользовательский опыт. Сравните: обычный Lightning-платёж требует скопировать invoice (длинная строка), переключиться в кошелёк, вставить и оплатить. С LNURL — достаточно отсканировать один QR или нажать на ссылку. Это снижает количество отказов на 30–40% по нашим данным, а среднее время оплаты падает с 40 секунд до 5.

Кроме того, LNURL-pay даёт контроль над ценой: вы устанавливаете minSendable и maxSendable, можете уточнять сумму после сканирования. А с Lightning Address пользователь просто вводит [email protected] — никаких QR. По сравнению с ручным процессом LNURL-pay в 2.5 раза улучшает UX.

Какие протоколы входят в LNURL?

LNURL — не один протокол, а несколько спецификаций (LUD — Lightning URL Definitions). Каждый решает свою задачу:

LUD Протокол Назначение
LUD-01 LNURL-pay Оплата: кошелёк запрашивает invoice у сервера продавца
LUD-03 LNURL-withdraw Вывод: кошелёк получает средства по ссылке
LUD-04 LNURL-auth Аутентификация через Lightning ключ (passwordless login)
LUD-06 LNURL-channel Открытие канала
LUD-12 Lightning Address Формат [email protected] для LNURL-pay

Для приёма платежей важны прежде всего LNURL-pay и Lightning Address.

Как работает LNURL-pay?

Весь процесс — два HTTP запроса между кошельком и сервером:

  1. Пользователь сканирует QR. Кошелёк видит lnurl1... (bech32 encoded HTTPS URL). Кошелёк декодирует и делает GET на этот URL.
  2. Сервер возвращает metadata:
{ "tag": "payRequest", "callback": "https://merchant.com/lnurl/pay/invoice", "minSendable": 1000, "maxSendable": 100000000, "metadata": "[[\"text/plain\",\"Payment to My Shop\"]]" } 
  1. Пользователь вводит сумму. Кошелёк делает GET на callback с параметром amount (в millisatoshi).
  2. Сервер генерирует Lightning invoice через свою LN-ноду и возвращает:
{ "pr": "lnbc100n1pj...", "routes": [], "successAction": { "tag": "message", "message": "Payment confirmed! Order #12345" } } 
  1. Кошелёк оплачивает invoice. После успешной оплаты показывает successAction.

Это всего пять шагов — втрое меньше по сравнению с ручным вводом invoice.

Как реализовать LNURL-pay сервер?

Нужна Lightning нода (LND или Core Lightning) для генерации invoice. Пример на Node.js с LND через gRPC:

import express from 'express'; import * as grpc from '@grpc/grpc-js'; import * as protoLoader from '@grpc/proto-loader'; import { bech32 } from 'bech32'; const app = express(); // LNURL-pay шаг 1: metadata app.get('/lnurl/pay/:paymentId', async (req, res) => { const { paymentId } = req.params; const callbackUrl = `https://${req.hostname}/lnurl/pay/${paymentId}/invoice`; // Кодируем URL в lnurl bech32 (для QR кода) const lnurlEncoded = encodeLnurl(callbackUrl); res.json({ tag: 'payRequest', callback: callbackUrl, minSendable: 1000, maxSendable: 100_000_000, metadata: JSON.stringify([ ['text/plain', `Payment for order ${paymentId}`], ]), }); }); // LNURL-pay шаг 2: генерация invoice app.get('/lnurl/pay/:paymentId/invoice', async (req, res) => { const { paymentId } = req.params; const amountMsat = parseInt(req.query.amount as string); if (!amountMsat || amountMsat < 1000) { return res.status(400).json({ status: 'ERROR', reason: 'Invalid amount' }); } try { const invoice = await lndClient.addInvoice({ value_msat: amountMsat, memo: `Order ${paymentId}`, expiry: 3600, }); await db.saveInvoice({ paymentHash: invoice.r_hash, paymentId, amountMsat, }); res.json({ pr: invoice.payment_request, routes: [], successAction: { tag: 'message', message: `Order ${paymentId} confirmed!`, }, }); } catch (err) { res.status(500).json({ status: 'ERROR', reason: 'Failed to generate invoice' }); } }); function encodeLnurl(url: string): string { const words = bech32.toWords(Buffer.from(url, 'utf8')); return bech32.encode('lnurl', words, 1023).toUpperCase(); } 

Этот код — основа. В продакшене добавляем валидацию, логирование, балансировку.

Lightning Address: [email protected]

Lightning Address (LUD-12) — самый удобный UX. Вместо QR-кода пользователь вводит адрес как email. Кошелёк автоматически делает запрос на https://domain.com/.well-known/lnurlp/username.

app.get('/.well-known/lnurlp/:username', async (req, res) => { const { username } = req.params; const user = await db.getUserByLnAddress(username); if (!user) { return res.status(404).json({ status: 'ERROR', reason: 'User not found' }); } res.json({ tag: 'payRequest', callback: `https://${req.hostname}/lnurl/lightning-address/${username}`, minSendable: 1000, maxSendable: 10_000_000_000, metadata: JSON.stringify([ ['text/identifier', `${username}@${req.hostname}`], ['text/plain', `Payment to ${username}`], ]), commentAllowed: 144, }); }); 

После этого [email protected] работает как Lightning Address в любом совместимом кошельке (Phoenix, Wallet of Satoshi, Zeus, Breez).

LNURL-auth: passwordless логин

LNURL-auth позволяет пользователям логиниться через Lightning кошелёк без пароля. Кошелёк подписывает challenge приватным ключом, производным от Lightning seed.

import crypto from 'crypto'; app.get('/auth/lnurl', (req, res) => { const k1 = crypto.randomBytes(32).toString('hex'); redis.setex(`lnurl_auth:${k1}`, 300, 'pending'); const lnurlAuthUrl = `https://${req.hostname}/auth/callback?tag=login&k1=${k1}`; const encoded = encodeLnurl(lnurlAuthUrl); res.json({ lnurl: encoded, k1 }); }); app.get('/auth/callback', async (req, res) => { const { k1, sig, key } = req.query as Record<string, string>; const status = await redis.get(`lnurl_auth:${k1}`); if (!status) { return res.json({ status: 'ERROR', reason: 'Unknown k1' }); } const isValid = verifyLnurlAuthSignature(k1, sig, key); if (!isValid) { return res.json({ status: 'ERROR', reason: 'Invalid signature' }); } await redis.setex(`lnurl_auth:${k1}`, 300, `authenticated:${key}`); res.json({ status: 'OK' }); }); 

Фронтенд polling-ом проверяет статус k1 — как только кошелёк подписал, пользователь залогинен.

Какие инфраструктурные требования для LNURL?

Lightning нода — обязательна. Варианты: LND (Go, gRPC API), Core Lightning (C, UNIX socket + REST), Eclair (Scala, используется Acinq/Phoenix). Для production: выделенный VPS с 4GB+ RAM, SSD, стабильным интернетом. Нода должна иметь входящую ликвидность для приёма платежей.

Hosted решения для быстрого старта: Voltage.cloud (managed LND), Alby Hub (self-custody), Strike API (custodial). Для боевого использования с серьёзными объёмами — только собственная нода.

TLS и домен обязательны: LNURL требует HTTPS. Самоподписанный сертификат не пройдёт — нужен Let's Encrypt или аналог.

Мониторинг: channel balance (оповещение при < 10% входящей ликвидности), invoice expiry, failed payment attempts. LND Metrics экспортирует Prometheus-совместимые метрики из коробки.

Что входит в работу по интеграции?

Этап Результат
Аналитика Проект архитектуры, выбор ноды (LND/CLN), план миграции
Настройка ноды Установка, настройка TLS, открытие каналов, backup
Разработка API LNURL-pay, Lightning Address, LNURL-auth endpoints
Интеграция с сайтом Подключение к корзине, настройка callback и successAction
Тестирование Автотесты с regtest, проверка на testnet, нагрузочное
Документация и обучение README с примерами, обучение вашей команды

Мы также предоставляем поддержку на месяц после запуска.

Согласно спецификации LNURL, протокол поддерживает более 10 LUD-стандартов. Мы реализуем все необходимые.

Оценим ваш проект — напишите нам для консультации. Закажите разработку LNURL-интеграции с индивидуальным подходом. Получите консультацию инженера — свяжитесь с нами.