163 / 736NWC

Nostr Wallet Connect

Как дать приложению ограниченный доступ к Lightning-кошельку

Хотите поддержать автора прямо из приложения, не открывая каждый раз кошелёк? Nostr Wallet Connect связывает их между собой. Важно не только установить связь, но и понять, что приложение вправе делать, сколько может потратить и как отозвать доступ.

Nostr Wallet Connect (NWC) — общие правила, описанные в документе NIP-47. Они позволяют приложению передавать запросы Lightning-кошельку через Nostr. Транспортный сервер, называемый relay, переносит зашифрованные команды и ответы, а не сами биткоины. Разрешения и выполнение платежей контролирует сервис кошелька.

Анна слушает подкаст и хочет отправить его автору небольшую сумму через Lightning Network. С NWC проигрыватель может напрямую попросить её кошелёк выполнить платёж. Сервис кошелька сначала проверяет права подключения и лишь затем выполняет разрешённый запрос. NWC не определяет, у кого находятся ключи от биткоинов: на другой стороне может быть собственный узел Анны или сервис, хранящий средства за неё. За одинаковой кнопкой «Подключить кошелёк» поэтому может стоять разный контроль над деньгами. В зависимости от выданных прав приложение также способно действовать без нового подтверждения каждого отдельного платежа. [1] [2]

Кошелёк обычно предоставляет QR-код или текстовую строку подключения, технически URI. Она содержит публичный ключ сервиса, адрес relay и secret — приватный ключ этого клиентского подключения. Это не seed, исходное секретное значение кошелька, и не его Seed Phrase, слова восстановления. Но и не безобидная публичная ссылка: обладатель пригодной копии может пользоваться теми же разрешениями. Возможный ущерб зависит от доступных функций и лимитов. Отдельные подключения для разных приложений позволяют различать их и отзывать по одному, а также уменьшают возможность связать их между собой. [1]

Приложению может требоваться лишь чтение баланса или также отправка денег. Это разные полномочия. Публичное событие info сообщает о возможностях сервиса; get_info возвращает методы, доступные конкретному подключению. Метод — именованная команда: pay_invoice запрашивает оплату, make_invoice создаёт платёжный запрос, lookup_invoice проверяет его состояние, get_balance читает баланс. Сам get_info тоже входит в базовый набор. История, keysend — платёж без заранее созданного счёта — и уведомления относятся к необязательным расширениям. Поддержка команды сервером не разрешает любому подключённому приложению выполнять её. [1] [3] [5]

Анна может выделить проигрывателю ограниченный бюджет. Если сервис предлагает лимиты расходов, методов или срока действия, он сам должен их соблюдать и проверять. Число только на экране проигрывателя не защищает от приложения, которое отправит другой запрос. Выясните также, разовый ли это бюджет или возобновляемый и как учитываются комиссии. Когда Анна перестаёт пользоваться приложением, следует отозвать его права в сервисе кошелька. Удаление приложения или локального подключения не доказывает отзыв доступа. Отзыв блокирует будущие запросы, но не отменяет завершённый платёж. [1]

Lightning-счёт является запросом на оплату, например в формате BOLT11, а не доказательством платежа. NIP-47 выражает суммы и комиссии в msat, тысячных долях satoshi: 1000 msat = 1 sat. Путаница в единицах изменяет сумму в тысячу раз. make_invoice только создаёт запрос. Успешный pay_invoice возвращает preimage. Из этого значения вычисляют хеш — короткое контрольное значение. Оно должно совпадать с платёжным хешем счёта; возвращённая preimage служит свидетельством завершения платежа. Ответ об ошибке использует error. Состояние можно запросить через lookup_invoice. Приложение должно обработать настоящий результат, а не показывать успех сразу после отправки сообщения. [1]

Анна нажимает «Оплатить», но ответ не приходит. Timeout, истечение времени ожидания, ещё не объясняет, что случилось с деньгами. Запросы и ответы NWC используют эфемерные события; отключённый relay или недоступный сервис могут привести к потере сообщения. Однако исчезнуть мог лишь ответ на уже завершённый платёж. Сначала проверьте состояние через lookup_invoice или непосредственно в кошельке. Молчание не подтверждает неудачу. Новый запрос нельзя автоматически считать безопасным повторением предыдущего действия; прежде нужно выяснить его результат. [1]

Приложение и кошелёк обмениваются зашифрованными сообщениями. Текущее согласование предпочитает nip44_v2, а устаревший nip04 остаётся для совместимости. Отсутствующий тег encryption означает старый режим. При этом NIP-44 не обеспечивает forward secrecy — защиту прошлой переписки при последующей утечке долговременного ключа. Relay также может видеть типы событий, теги, публичные ключи подключений и время обмена. Поэтому для NWC не следует использовать основной ключ идентичности, которым человек публикует записи в Nostr. Отдельные ключи уменьшают связь платежей с публичным профилем, но не гарантируют полной анонимности. [1] [4]

Для обычного использования не нужно помнить номера сообщений, но при разработке интеграции они важны. Info использует kind 13194, запросы — 23194, ответы — 23195. kind обозначает тип события. Тег p указывает другую сторону, а тег e в ответе ссылается на исходный запрос. Клиент проверяет подпись, ожидаемый ключ сервиса, эту связь и result_type — команду, к которой относится результат. Нельзя принимать любое сообщение от relay за подтверждение. Иначе чужой ответ или ответ на другое действие можно ошибочно принять за результат данного платежа. [1]

Для полной картины прочитайте эту статью вместе с Nostr, Lightning Network, BOLT 11, Кошелёк, Private Key, Satoshi. На эту статью также ссылаются Nostr, BOLT 11.

DOC · 001NWC — NIP-47: Core protocolСпецификация DOC · 002NWC — Project overviewПервичный источник DOC · 003NWC — Optional specificationsСпецификация DOC · 004Nostr — NIP-44: Encrypted payloadsСпецификация DOC · 005NWC-02 — NotificationsСпецификация
Обновлено: Сначала источники · Не является инвестиционной рекомендацией