Nostr Wallet Connect (NWC)
Nostr Wallet Connect คืออะไร และมีประโยชน์อะไร
Nostr Wallet Connect (NWC) หรือที่รู้จักในเอกสารมาตรฐานว่า NIP-47 เป็นโพรโทคอลเปิด (open standard) ที่ออกแบบให้แอปพลิเคชัน Nostr สามารถติดต่อกับกระเป๋าเงิน Lightning Network จากระยะไกลได้ผ่านเครือข่าย Nostr โดยมีเป้าหมายหลักคือให้ผู้ใช้สามารถผูกกระเป๋า Lightning (เช่น LND, Breez, Greenlight ฯลฯ) เข้ากับไคลเอนต์ Nostr ได้อย่างง่ายดาย โดยไคลเอนต์จะส่งคำสั่งการชำระเงินไปยังกระเป๋าผ่าน event ของ Nostr และรอรับผลลัพธ์กลับมา (เช่น preimage ของการชำระเงิน) แนวคิดนี้ได้ช่วยรวม Lightning Wallet เข้ากับระบบนิเวศ Nostr โดยให้สิทธิ์เข้าถึงกระเป๋าได้อย่างปลอดภัย โดยไม่ต้องเปิดเผยคีย์ส่วนตัวหลักของผู้ใช้ไปยังไคลเอนต์ภายนอกนอกจากนี้ NWC ยังใช้ประโยชน์จากโครงสร้างพื้นฐานของเครือข่าย Nostr (Relays และ Event) เพื่อส่งข้อมูล ทำให้ง่ายต่อการนำไปใช้กับแอปต่างๆ ในระบบ Nostr
องค์ประกอบสำคัญของระบบ
ไคลเอนต์ (Client): แอป Nostr บนแพลตฟอร์มใดก็ได้ที่ต้องการส่งการชำระเงิน Lightning ให้แก่ผู้ใช้ (เช่น Damus, Amethyst) โดยไคลเอนต์จะเก็บข้อมูลการเชื่อมต่อ (connection URI) จากผู้ใช้ และใช้เพื่อส่งคำสั่งไปยังกระเป๋าเงินผ่าน Nostr relay
รีเลย์ (Relay): เซิร์ฟเวอร์กลางของเครือข่าย Nostr ทำหน้าที่รับและส่งต่อ events ระหว่างไคลเอนต์และบริการกระเป๋าเงิน โดยที่รีเลย์เก็บ event ในระบบเพื่อให้ฝ่ายตรงข้ามสามารถดึงข้อมูลมาประมวลผลได้
บริการกระเป๋าเงิน (Wallet Service): เป็นโปรแกรมที่รันตลอดเวลา (เช่น บนเครื่องเซิร์ฟเวอร์หรือ Raspberry Pi) ทำหน้าที่เชื่อมต่อกับ API ของกระเป๋าเงิน Lightning และติดตาม event จาก Nostr relay โดยบริการนี้จะส่งข้อมูลบอกว่ารองรับคำสั่งใดบ้างและประมวลผลคำสั่งชำระเงินจากไคลเอนต์
โพรโตคอล/API: Nostr Wallet Connect กำหนดรูปแบบและฟอร์แมตของ event บน Nostr สำหรับการสื่อสารระหว่างไคลเอนต์กับ Wallet Service ซึ่งมี event หลัก 3 ชนิดคือ info event (kind 13194), request (kind 23194) และ response (kind 23195) ไคลเอนต์และ Wallet Service ใช้ NIP-04 เพื่อเข้ารหัส/ถอดรหัสเนื้อหาใน event เหล่านี้ และข้อมูลภายในจะเป็น JSON ที่ระบุ
method
เช่น"pay_invoice"
พร้อมparams
ต่าง ๆ (ตัวอย่างเช่น ใบแจ้งหนี้ Bolt11)Nostr Wallet Connect URI: เป็นสตริงรูปแบบ
nostr+walletconnect:<pubkey>?relay=<relayURL>&secret=<secret>&lud16=<address>
ซึ่งแอปกระเป๋าเงินสร้างให้ผู้ใช้งาน โดยมีพารามิเตอร์สำคัญได้แก่relay
(URL ของ Nostr Relay ที่รันบริการกระเป๋า),secret
(รหัสลับสุ่ม 32 ไบต์ ที่ใช้เป็นกุญแจลงชื่อและเข้ารหัสการสื่อสาร) และlud16
(Lightning Address) การใช้secret
แยกต่างหากจากคีย์ส่วนตัวหลักของผู้ใช้ช่วยเพิ่มความปลอดภัยและความเป็นส่วนตัว เพราะผู้ใช้สามารถรีเซ็ตหรือเพิกถอนสิทธิ์ได้โดยไม่กระทบคีย์หลัก
การทำงานของระบบ - ตามทฤษฎี NIP-47
การตั้งค่าการเชื่อมต่อ: ผู้ใช้เปิดบริการกระเป๋าเงิน NIP-47 และสร้าง connection URI (เช่น สแกน QR code หรือก๊อปปี้สตริง) เพื่อเชื่อมโยงกับไคลเอนต์ Nostr ซึ่งผู้ใช้ป้อน URI นี้ในไคลเอนต์ (หรือสแกน QR) ไคลเอนต์เพื่อจะบันทึก URI ดังกล่าวไว้
ดึง
info
event: ก่อนส่งคำสั่งใดๆ ไคลเอนต์จะร้องขอเหตุการณ์ info (kind 13194) จาก relay ที่ระบุใน URI เหตุการณ์นี้ถูก Wallet Service ส่งไว้ก่อนแล้ว และในเนื้อหาที่เป็น plain-text จะระบุคำสั่งที่รองรับ (เช่นpay_invoice get_balance
) วิธีนี้ทำให้ไคลเอนต์รู้ว่ากระเป๋าเงินสามารถทำอะไรได้บ้างส่งคำขอชำระเงิน: เมื่อผู้ใช้ป้อนใบแจ้งหนี้ Lightning (BOLT11) ในไคลเอนต์ ไคลเอนต์จะสร้างเหตุการณ์ request (kind 23194) โดยใส่เนื้อหา JSON เช่น
{"method":"pay_invoice","params":{"invoice":"lnbc50n1..."}}
ไคลเอนต์ใช้คีย์ลับจาก URI ลงชื่อและเข้ารหัสเนื้อหา (ตาม NIP-04) และส่ง event นี้ไปยัง relay ซี่งใน request event จะมี tagp
กำกับ public key ของ Wallet Service เพื่อระบุผู้รับบริการกระเป๋าเงินประมวลผล: บริการกระเป๋าเงินที่เฝ้าฟัง event บน relay โดยหลังจากรับ event kind 23194 มาแล้วถอดรหัส จากนั้นตรวจสอบสิทธิ์ (ว่า public key ของผู้ส่งได้รับอนุญาต) และสั่งให้กระเป๋า Lightning ชำระเงินตามใบแจ้งหนี้นั้น หากการชำระเงินสำเร็จ Wallet Service จะสร้าง response event (kind 23195) ใส่เนื้อหาเช่น
{"result_type":"pay_invoice","result":{"preimage":"012345..."}}
ใน response นี้จะมี tagp
เป็นคีย์ของผู้ใช้ และ tage
ชี้ไปยัง ID ของ request event เดิมรับผลลัพธ์ที่ไคลเอนต์: ไคลเอนต์ที่ติดตาม event kind 23195 บน relay จะรับเนื้อหาตอบกลับนี้มา และถอดรหัสด้วยคีย์ลับ (หรือคีย์หลักของผู้ใช้) และอ่านผลลัพธ์ (เช่น รหัส preimage หรือโค้ดข้อผิดพลาด) จากนั้นไคลเอนต์จะแสดงผลให้ผู้ใช้ทราบว่าสำเร็จหรือไม่
ภาพรวมการไหลของข้อมูลคือ ไคลเอนต์ส่ง request ผ่าน Nostr relay ไปยังบริการกระเป๋าเงิน แล้วบริการตอบกลับ (ผ่าน relay เดียวกัน) โดยทุกข้อความเป็นแบบเข้ารหัส (NIP-04) และเชื่อมโยงกันด้วย tag บน Nostr
ตัวอย่างการ implement หรือโค้ดที่เกี่ยวข้อง
มีไลบรารีและตัวอย่างโปรเจกต์เปิดเผยหลายตัวสำหรับใช้งาน Nostr Wallet Connect:
JavaScript (Alby SDK): Alby SDK มีคลาส
NWCClient
และNostrWebLNProvider
สำหรับใช้ในเว็บหรือ Node.js
import { nwc } from "@getalby/sdk";
const nwcClient = new nwc.NWCClient({ nostrWalletConnectUrl: "<NWC_URI>" });
const response = await nwcClient.payInvoice({ invoice: "<BOLT11_invoice>" });
ซึ่งจะส่งคำขอ pay_invoice
และคืนผลลัพธ์ (preimage) สำหรับแอปเว็บ สามารถใช้ NostrWebLNProvider
ที่เป็น WebLN adapter เช่น await webln.sendPayment(invoice)
Rust/Python (nostr-sdk): ตัวอย่างที่ rust-nostr SDK แสดงให้เห็นการใช้งาน NWC ใน Rust และ Python
uri = NostrWalletConnectUri.parse("nostr+walletconnect://...")
nwc = Nwc(uri)
info = await nwc.get_info()
await nwc.pay_invoice(PayInvoiceRequest(invoice="lnbc..."))
ไลบรารี nostr-sdk
จะช่วย parse URI, ส่ง request และรอรับ response อัตโนมัติ
โดยรวมแล้วนักพัฒนาสามารถเลือกใช้ไลบรารีเหล่านี้หรือสร้างจากศูนย์ได้ตามความเหมาะสม ซึ่งตัวอย่างโค้ดข้างต้นแสดงวิธีการเรียกใช้เมธอดหลัก (เช่น get_info()
, get_balance()
, pay_invoice()
) ผ่าน Nostr Wallet Connect
ข้อดีและข้อจำกัดเทียบกับวิธีอื่น (LNURL, WebLN)
ข้อดีของ Nostr Wallet Connect:
ใช้โครงสร้างของเครือข่าย Nostr อยู่แล้ว (relay/event) จึงไม่ต้องพึ่งพาเซิร์ฟเวอร์ HTTP แยกเฉพาะ (ต่างจาก LNURL ที่เป็น HTTP-based) ผู้ใช้สามารถเลือก Relay หรือโฮสต์ของตนเองเพื่อเพิ่มความเป็นส่วนตัวและความปลอดภัย
มีระบบการอนุญาตด้วยคีย์ลับแยก (
secret
) แทนการส่งผ่านคีย์หลักของผู้ใช้โดยตรงผู้ใช้จึงสามารถสร้าง ลบ หรือจำกัดคีย์การเชื่อมต่อกับแอปต่างๆ ได้ เช่น กำหนดงบประมาณ (quota) หรือเพิกถอนสิทธิ์เมื่อไม่ต้องการใช้แล้วข้อมูลการชำระเงินถูกเข้ารหัสด้วย NIP-04 ทั้งสองทาง (client และ wallet) จึงปลอดภัยต่อการดักฟังและโจมตีแบบคนกลาง นอกจากนี้การใช้แท็ก
p
/e
ช่วยให้ตรวจสอบผู้รับ-ผู้ส่งและเชื่อมโยงคำขอ–คำตอบได้อย่างชัดเจนระบบนี้ออกแบบมาเพื่อ Nostr โดยเฉพาะ จึงสามารถผนวกคุณสมบัติของ Nostr อื่น ๆ ได้ (เช่น การเซ็นด้วยคีย์ Nostr ดั้งเดิม) และเหมาะกับแอป Nostr ที่ต้องการฟีเจอร์จ่าย Lightning โดยไม่ต้องเสียเวลา integrate ระบบภายนอกเพิ่มเติม
เนื่องจากใช้มาตรฐาน NIP ผู้ใช้และนักพัฒนาจึงสามารถอ้างอิงเอกสารสเปคหรือโค้ดโอเพนซอร์สที่มีอยู่ได้โดยตรง (เช่น NIP-47 เอง หรือโครงการต่างๆ ข้างต้น) ทำให้ง่ายต่อการพัฒนาและใช้งานร่วมกัน
ข้อจำกัดของ Nostr Wallet Connect:
ต้องพึ่งพาเครือข่าย Nostr และ Relay ที่เสถียร การสื่อสารอาจเกิดความหน่วง (latency) สูงกว่า HTTP เนื่องจากต้องผ่านหลายโหนด (relay) ในระบบ หาก Relay ปิดการเชื่อมต่อขณะ Idle (ตามที่ NIP แนะนำให้ใช้ relay ที่ไม่ปิด connection บ่อย) ก็อาจพลาดเหตุการณ์สำคัญได้
ต้องมีบริการกระเป๋าเงินที่รองรับ NIP-47 โดยตรง ซึ่งปัจจุบันยังมีบริการไม่มาก (ส่วนใหญ่เป็นโครงการใหม่หรือบั๊กน์จำกัด) ต่างจาก LNURL ที่มีผู้ให้บริการหลายรายรองรับ (เช่น Lightning Address, LNBits เป็นต้น) หากแอปยังไม่รองรับ NWC จะไม่สามารถใช้ฟีเจอร์นี้ได้
ขั้นตอนเริ่มต้น (onboarding) อาจดูยุ่งยากสำหรับผู้ใช้ทั่วไป เพราะต้องสร้าง URI, สแกน QR หรือก๊อปปี้แล้ววางเอง ต่างจาก LNURL ที่แค่สแกน QR หรือใช้ URL ธรรมดา หรือ WebLN ที่เพียงคลิกปุ่ม connect ในเบราว์เซอร์
เปรียบเทียบกับ LNURL: LNURL เป็นโพรโทคอลบน HTTP ที่เน้นการใช้งาน QR สแตติกหรือ Lightning Address (LUD-12) เพื่อดึง invoice/withdraw จากเซิร์ฟเวอร์ผ่าน REST API LNURL เหมาะกับการตั้งค่าสถานะแบบคงที่ (เช่น การชำระเงินที่อยู่ตายตัว) และมีการรองรับจากวอลเล็ตหลายตัวแล้ว แต่จำเป็นต้องมีโฮสต์หรือบริการที่รันโพรโทคอล LNURL นี้ ในทางกลับกัน NWC ใช้ Nostr แทน HTTP ทำให้ไม่ต้องตั้งเซิร์ฟเวอร์เว็บเพิ่ม แต่แลกกับการต้องใช้ Nostr infrastructure.
เปรียบเทียบกับ WebLN: WebLN เป็นสเปคที่กำหนดวิธีให้เว็บแอปและเบราว์เซอร์คอมโพเนนต์สื่อสารกับผู้ใช้ผ่าน Lightning provider (มักเป็น browser extension) เว็บแอปที่ใช้ WebLN จะเรียกฟังก์ชันเช่น
webln.sendPayment()
เพื่อทำการจ่ายเงิน ผู้ใช้จึงต้องติดตั้ง WebLN wallet (เช่น Alby Extension, Joule ฯลฯ) NWC ต่างจาก WebLN ตรงที่ไม่ต้องพึ่งเบราว์เซอร์หรือส่วนขยาย แต่ใช้ไคลเอนต์ Nostr แทน ซึ่งเหมาะกับแอปนอกเว็บ อย่างไรก็ดี ผู้ใช้ต้องมี Nostr wallet/app ที่รองรับ NWC (เช่น Amethyst) แทนการมีแค่ extension บนเว็บ
สรุปคือ Nostr Wallet Connect เป็นทางเลือกที่รวม Lightning Wallet เข้ากับโลก Nostr ได้อย่างลงตัว ให้ความยืดหยุ่นในการเลือกรันบริการและการจัดการคีย์ แต่ต้องแลกกับข้อจำกัดเรื่องโครงสร้างพื้นฐาน (Nostr Relay) และความพร้อมในการรองรับของแอปและบริการต่างๆ เมื่อเทียบกับวิธีเชื่อมต่อ Lightning อื่นๆ อย่าง LNURL หรือ WebLN
อ้างอิง: แนวคิดและรายละเอียดทางเทคนิคอ้างอิงจากเอกสาร NIP-47 และโค้ดตัวอย่างของโครงการโอเพ่นซอร์สที่เกี่ยวข้อง
Last updated