BOLT 12 بروتوكول للاتفاق على دفعة عبر Lightning Network. يميز بين العرض offer والطلب invoice_request والفاتورة الناتجة invoice. يمكن أن يظل العرض منشورًا لدفعات متعددة، بينما تحدد كل فاتورة شروط الدفعة المعنية.
تخيل مقهى يريد وضع رمز واحد على المنضدة للمساهمات الطوعية. دفع فاتورة BOLT 11 العادية نفسها مرارًا يسبب مشكلات. بدلًا من ذلك ينشر BOLT 12 عرض offer. ترسل محفظة العميل بناء عليه invoice_request لطلب فاتورتها الخاصة، ويرد المستلم بفاتورة invoice جديدة. بعدها فقط يمكن الدفع. هكذا يخدم QR مطبوع واحد أشخاصًا مختلفين من دون استخدام الفاتورة نفسها. الحصول عليها، مثلًا بواسطة fetchinvoice، لا يرسل المال بعد. ولا يعطي العرض بحد ذاته المقهى إذنًا لاقتطاع دفعات أخرى من محفظة شخص آخر. [1] [3] [4]
قد يذكر العرض السعر بالبيتكوين أو بعملة أخرى. يستخدم الحقل offer_currency رموز ISO 4217؛ فمبلغ USD مثلًا يُعبّر عنه بالسنتات. وقد تدخل الكمية وتحويل العملة في الحساب عند إصدار الفاتورة. لكن invoice_amount النهائي للبيتكوين يكون بوحدة millisatoshi، أي أجزاء من ألف من satoshi: 1000 msat = 1 sat. على الدافع معرفة هذا المبلغ والرسوم قبل الدفع، لا الاكتفاء بالسعر الأصلي على اللافتة. إذا حدد الطلب invreq_amount دقيقة، وجب أن تطابقها الفاتورة. وإلا تتحقق المحفظة من النطاق المسموح وينبغي أن تطلب موافقة جديدة عند تجاوزه. تحويل العملة ليس موافقة خفية على أي سعر. [1] [3]
قد يبقى الرمز على المنضدة، لكن العرض نفسه قد ينتهي في offer_absolute_expiry. ولكل فاتورة أيضًا وقت إنشاء invoice_created_at ومدة صلاحية invoice_relative_expiry. عند غياب المدة، تكون القيمة الافتراضية 7200 ثانية، أي ساعتين. لذا ليست الفاتورة القديمة وسيلة اتصال صالحة دائمًا. وعلى المحافظ أيضًا فهم الميزات الإلزامية المعلنة في الرسائل. البت الزوجي غير المعروف يعني ميزة مطلوبة ويؤدي إلى الرفض؛ أما الفردي غير المعروف فاختياري ويمكن تجاهله. هذا لضمان توافق آمن، وليس عقبة ينبغي للمستخدم تجاوزها بتعديل الرمز يدويًا. [1]
بعد الدفع احتفظ بالفاتورة وبالنتيجة التي تعرضها المحفظة. ومن أدلة التسوية preimage، وهو قيمة سرية تُستلم عند اكتمال الدفع. تحسب المحفظة منها هاشًا، أي قيمة للتحقق، وتقارنه بهاش الدفع الموجود في الفاتورة. وبالاستعانة بالفاتورة يمكن بذلك إثبات دفعها، لكن هذا وحده لا يحدد الشخص الذي دفع. إذا انقطع اتصال التطبيق أو ضاعت الاستجابة، فتحقق من حالة الدفعة السابقة قبل المحاولة مجددًا؛ فقد تؤدي فاتورة جديدة إلى دفع آخر. وتعامل بالحذر نفسه مع وعود الدفعات المتكررة. دعم BOLT 12 لا يعني تلقائيًا دعم كل امتداد ولا السماح بالخصم الآلي. افحص على حدة استقبال المدفوعات عبر العروض، والدفع لعروض الآخرين، والصلاحيات الممنوحة للتطبيق المتصل. [1] [3]
يستخدم طلب الفاتورة ونقل الأموال الشبكة لغرضين مختلفين. يحدد offer_paths مسار رسالة الطلب، بينما يوفر invoice_paths مسارات الدفع. يستخدم BOLT 12 ما يسمى blinded paths، وهي مسارات تخفي جزءًا من معلومات الاتصال بالمستلم. تقليل كشف بنية الشبكة يساعد الخصوصية، لكنه لا يعد بإخفاء الهوية كليًا. ولا يضمن المسار المخفي توفر المستلم أو السيولة، أي المال الكافي على الجوانب المطلوبة من قنوات الدفع. تقنيًا يجب أن تتضمن invoice الحالية هذه المسارات ومعايير invoice_blindedpay المقابلة، حتى لو قاد المسار مباشرة إلى المستلم. ولا يتطلب طلب الفاتورة خادم دفع HTTPS تقليديًا. [1] [2]
إذا أراد التاجر إعادة المال للعميل، انعكس اتجاه التفاوض. يمكن لمن يريد الدفع نشر invoice_request من دون offer سابقة. يرد العميل، بصفته المستلم المنتظر، بفاتورة invoice خاصة به ليدفعها التاجر. هذا لا يمحو الدفعة الأصلية ولا يلغيها؛ بل ينشئ دفعة جديدة في الاتجاه المعاكس. على التاجر التحقق من أن الفاتورة تخص المستلم المقصود، وقد يتطلب ذلك تواصلًا خارج البروتوكول. مسح الطلب وحده لا يثبت حقًا في الاسترداد ولا يوافق على التحويل. يسهل الإجراء التقني التواصل، لكنه لا يقرر لمن يُرد المال. [1]
يحفظ BOLT 12 البيانات بصيغة TLV: يحدد كل حقل نوعه وطوله وقيمته. يبدأ العرض النصي بـ lno والطلب بـ lnr. تشبه مجموعة المحارف Bech32، لكن من دون المجموع الاختباري في نهايته. هذا وحده لا يبين من يحق له تلقي الدفع. العرض offer غير موقّع. تُستخدم توقيعات BIP340 Schnorr الرقمية للتحقق من الفاتورة ومن الطلب المعتاد الذي يرد على عرض. أما الطلب المستقل المنشور من دون عرض سابق، مثل طلب إعادة المال، فلا يتضمن توقيعًا. يرتبط التوقيع بجذر بنية Merkle، أي قيمة تحقق مشتركة تُحسب من الحقول المعنية. لذا يمكن إثبات حقول مختارة من دون كشف كل التفاصيل دائمًا. لا يسمح ذلك بتغيير الشروط الموقّعة ولا يثبت الهوية القانونية للتاجر. [1]
على المحفظة التأكد من أنها تلقت جوابًا عن طلبها، لا مجرد فاتورة ما بتوقيع صحيح. تقارن حقول invoice_request المنقولة إلى invoice، إلى جانب الشبكة والمبلغ والتوقيع. يجب أن يطابق المفتاح العام invoice_node_id قيمة offer_issuer_id؛ وإذا استخدم العرض المسار المخفي المعني بدل هذا المعرّف، تُراجع قيمة blinded_node_id النهائية فيه. يشبه ذلك التأكد من أن الحساب يخص طاولتك، لا مجرد أن الختم أصلي. تتيح بنية Merkle أدلة انتقائية، لكنها لا تعفي المحفظة من فحص جميع الشروط اللازمة للدفع. فاتورة شخص آخر الصحيحة لا تصبح فاتورتك لمجرد اجتياز توقيعها الفحص. [1]
للحصول على صورة أوضح، اقرأ هذا المدخل مع BOLT 11, Lightning Network, Lightning Routing, خصوصية Bitcoin, Satoshi, LNURL. تشير إلى هذا المدخل أيضًا BOLT 11, LNURL, Just-in-Time Channels.