Skip to content

bolt12+lnwire: add codec foundation with Offer message#10789

Draft
bitromortac wants to merge 3 commits intolightningnetwork:masterfrom
bitromortac:2604-bolt12-1a
Draft

bolt12+lnwire: add codec foundation with Offer message#10789
bitromortac wants to merge 3 commits intolightningnetwork:masterfrom
bitromortac:2604-bolt12-1a

Conversation

@bitromortac
Copy link
Copy Markdown
Collaborator

Part of the first milestone in #10736 (total WIP of the first milestone can be found here).

This PR adds a new bolt12/ package skeleton, its first message struct (Offer), and the lnwire work needed to host it. Includes TLV subtypes as well as reader/write message validation.

May need another pass to split up the Offer commit before review, I'm looking for feedback on the message representation.

@github-actions github-actions Bot added the severity-critical Requires expert review - security/consensus critical label May 5, 2026
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 5, 2026

🔴 PR Severity: CRITICAL

Automated classification | 9 files (non-test) | 1,335 lines changed

🔴 Critical (2 files)
  • lnwire/custom_records.go - Lightning wire protocol messages (lnwire/*)
  • lnwire/pure_tlv.go - Lightning wire protocol messages (lnwire/*)
🟡 Medium (7 files)
  • bolt12/decode.go - New BOLT12 package (uncategorized Go files → medium)
  • bolt12/doc.go - New BOLT12 package documentation
  • bolt12/offer.go - New BOLT12 offer types
  • bolt12/pure_tlv.go - New BOLT12 TLV utilities
  • bolt12/subtypes.go - New BOLT12 subtypes
  • bolt12/tlv_types.go - New BOLT12 TLV type definitions
  • bolt12/validate.go - New BOLT12 validation logic

Analysis

This PR introduces a new bolt12 package implementing BOLT12 (Offers) functionality, alongside modifications to two files in the lnwire package. The changes to lnwire/custom_records.go and lnwire/pure_tlv.go drive this PR to CRITICAL severity, as lnwire/* covers Lightning wire protocol messages and requires expert review.

The new bolt12 package itself does not fall into any predefined critical or high category and classifies as medium. However, the highest severity file governs, making this PR overall CRITICAL.

Additionally, with ~1,335 non-test lines changed (exceeding the 500-line bump threshold), a severity bump is triggered — though the PR is already at the maximum level of CRITICAL.


To override, add a severity-override-{critical,high,medium,low} label.
<!-- pr-severity-bot -->

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 5, 2026

🔴 PR Severity: CRITICAL

Automated classification | 9 files (non-test) | 1,335 lines changed

🔴 Critical (2 files)
  • lnwire/custom_records.go - Lightning wire protocol messages (lnwire/*)
  • lnwire/pure_tlv.go - Lightning wire protocol messages (lnwire/*)
🟡 Medium (7 files)
  • bolt12/decode.go - New BOLT12 package (uncategorized Go files → medium)
  • bolt12/doc.go - New BOLT12 package documentation
  • bolt12/offer.go - New BOLT12 offer types
  • bolt12/pure_tlv.go - New BOLT12 TLV utilities
  • bolt12/subtypes.go - New BOLT12 subtypes
  • bolt12/tlv_types.go - New BOLT12 TLV type definitions
  • bolt12/validate.go - New BOLT12 validation logic

Analysis

This PR introduces a new bolt12 package implementing BOLT12 (Offers) functionality, alongside modifications to two files in the lnwire package. The changes to lnwire/custom_records.go and lnwire/pure_tlv.go drive this PR to CRITICAL severity, as lnwire/* covers Lightning wire protocol messages and requires expert review.

The new bolt12 package does not fall into any predefined critical or high category and classifies as medium. However, the highest severity file governs, making this PR overall CRITICAL.

Additionally, with ~1,335 non-test lines changed (exceeding the 500-line bump threshold), a severity bump is triggered — though the PR is already at the maximum level of CRITICAL.


To override, add a severity-override-{critical,high,medium,low} label.
<!-- pr-severity-bot -->

@gemini-code-assist
Copy link
Copy Markdown

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request establishes the foundational codec infrastructure for BOLT 12 support in LND. It introduces a dedicated bolt12 package to manage the serialization and validation of offer messages, while extending lnwire with necessary utilities to support the required TLV-based message structures.

Highlights

  • BOLT 12 Foundation: Introduced the bolt12 package skeleton to manage the encoding, decoding, and validation of BOLT 12 messages.
  • Offer Message Implementation: Implemented the Offer struct, supporting various optional TLV fields and providing a clean interface for message serialization.
  • lnwire Extensions: Added helper functions to lnwire to support PureTLVMessage handling and improved management of optional records.
  • Validation Logic: Included comprehensive validation rules to ensure BOLT 12 messages comply with spec-defined writer and reader requirements.
New Features

🧠 You can now enable Memory (public preview) to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize the Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counterproductive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request implements the core BOLT 12 offer codec, including encoding, decoding, and validation logic. It introduces the Offer message type, support for blinded paths, and chain-specific validation. Additionally, it extends the lnwire package with generic TLV helpers and predicate-driven serialization to accommodate BOLT 12's specific signed-range requirements. Feedback includes a critical fix for a dangling pointer in the AddOpt helper and a recommendation to use unsigned comparisons for expiry timestamps to avoid potential overflow issues.

Comment thread lnwire/custom_records.go
Comment thread bolt12/validate.go Outdated
Add UnsignedRangeFunc and the SerialiseFieldsToSignFn /
ExtraSignedFieldsFromTypeMapFn variants so callers with non-BOLT 7 v2
signed ranges (e.g. BOLT 12, which reserves only 240-1000) can plug in
their own predicate. The existing SerialiseFieldsToSign and
ExtraSignedFieldsFromTypeMap entry points keep their behaviour by
delegating to the Fn variants with InUnsignedRange.
This gives us easier optional tlv field handling.
The Offer struct models a long-lived, reusable BOLT 12 payment template.
It defines TLV fields as optional records, and exposes Encode/
DecodeOffer for round-trip serialization. The struct implements
lnwire.PureTLVMessage; AllRecords filters the decoded TypeMap through
bolt12InUnsignedRange to derive any signed-range extras the encoder must
re-emit, keeping offer_id and the Merkle root stable across encoders
that understand a wider set of even/odd extensions.
@saubyk saubyk added the bolt12 label May 6, 2026
@saubyk saubyk added this to lnd v0.22 May 6, 2026
@saubyk saubyk moved this to In progress in lnd v0.22 May 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bolt12 severity-critical Requires expert review - security/consensus critical

Projects

Status: In progress

Development

Successfully merging this pull request may close these issues.

2 participants