Uh oh!
There was an error while loading. Please reload this page.
Introduce Stronger Typing for VerifiedInvoiceRequest and Refactor Invoice Building Flow - #3964
Conversation
👋 Thanks for assigning @jkczyz as a reviewer! |
shaavan
commented
Jul 26, 2025
cc @jkczyz |
ldk-reviews-bot
commented
Jul 28, 2025
🔔 1st Reminder Hey @valentinewallace! This PR has been waiting for your review. |
ldk-reviews-bot
commented
Jul 30, 2025
🔔 2nd Reminder Hey @jkczyz@valentinewallace! This PR has been waiting for your review. |
ldk-reviews-bot
commented
Jul 31, 2025
🔔 1st Reminder Hey @jkczyz@valentinewallace! This PR has been waiting for your review. |
ldk-reviews-bot
commented
Aug 2, 2025
🔔 3rd Reminder Hey @jkczyz@valentinewallace! This PR has been waiting for your review. |
ldk-reviews-bot
commented
Aug 2, 2025
🔔 2nd Reminder Hey @jkczyz@valentinewallace! This PR has been waiting for your review. |
ldk-reviews-bot
commented
Aug 4, 2025
🔔 4th Reminder Hey @jkczyz@valentinewallace! This PR has been waiting for your review. |
ldk-reviews-bot
commented
Aug 4, 2025
🔔 3rd Reminder Hey @jkczyz@valentinewallace! This PR has been waiting for your review. |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
ldk-reviews-bot
commented
Aug 6, 2025
🔔 5th Reminder Hey @valentinewallace! This PR has been waiting for your review. |
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@## main #3964 +/- ##
==========================================
+ Coverage 88.60% 88.62% +0.01%
==========================================
Files 180 180 Lines 134878 134947 +69 Branches 134878 134947 +69 ==========================================
+ Hits 119511 119591 +80 + Misses 12608 12587 -21 - Partials 2759 2769 +10
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
ldk-reviews-bot
commented
Aug 9, 2025
🔔 6th Reminder Hey @valentinewallace! This PR has been waiting for your review. |
ldk-reviews-bot
commented
Aug 11, 2025
🔔 7th Reminder Hey @valentinewallace! This PR has been waiting for your review. |
ldk-reviews-bot
commented
Aug 13, 2025
🔔 8th Reminder Hey @valentinewallace! This PR has been waiting for your review. |
Uh oh!
There was an error while loading. Please reload this page.
shaavan
commented
Aug 15, 2025
ldk-reviews-bot
commented
Aug 16, 2025
🔔 9th Reminder Hey @valentinewallace! This PR has been waiting for your review. |
ldk-reviews-bot
commented
Aug 18, 2025
🔔 10th Reminder Hey @valentinewallace! This PR has been waiting for your review. |
ldk-reviews-bot
commented
Aug 20, 2025
🔔 11th Reminder Hey @valentinewallace! This PR has been waiting for your review. |
valentinewallace
commented
Aug 20, 2025
I'm unfortunately not going to have time to review this in a timely manner, so unassigning myself and letting the bot take the wheel |
Uh oh!
There was an error while loading. Please reload this page.
shaavan
commented
Aug 22, 2025
Thanks for the thoughtful review, Joost! I’m working through your points and will follow up with concrete changes soon. In the meantime, I’ve updated the PR description to explain the motivation a bit more, especially around the manual invoice request handling mentioned by Jeff. Would love your thoughts when you get a chance. |
Just to be sure that I am looking at the benefits in the right location, I posted #3833 (comment) |
shaavan
commented
Aug 25, 2025
Updated frompr3964.04 to pr3964.05 (diff): Changes:
|
joostjager
left a comment
There was a problem hiding this comment.
HIgh-level ack, although I remain doubtful of the cost/benefit of this PR. A runtime check isn't the end of the world, especially if it isn't hard to hit the case during testing.
The end result isn't completely ideal either, taking some away from the benefit side of the scale:
- Enum + generic feels a bit redundant, even though I understand the reason for doing it
- Code duplication
- Need for macros which we generally want to get rid of
Will leave full final review to @jkczyz
ldk-reviews-bot
commented
Sep 15, 2025
🔔 1st Reminder Hey @jkczyz! This PR has been waiting for your review. |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
ldk-reviews-bot
commented
Sep 20, 2025
🔔 1st Reminder Hey @jkczyz! This PR has been waiting for your review. |
ldk-reviews-bot
commented
Sep 22, 2025
🔔 2nd Reminder Hey @jkczyz! This PR has been waiting for your review. |
ldk-reviews-bot
commented
Sep 24, 2025
🔔 3rd Reminder Hey @jkczyz! This PR has been waiting for your review. |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
In the following commits we will introduce `fields` function for other types as well, so to keep code DRY we convert the function to a macro.
This commit reintroduces `VerifiedInvoiceRequest`, now parameterized by `SigningPubkeyStrategy`. The key motivation is to restrict which functions can be called on a `VerifiedInvoiceRequest` based on its strategy type. This enables compile-time guarantees — ensuring that an incorrect `InvoiceBuilder` cannot be constructed for a given request, and misuses are caught early.
This change improves type safety and architectural clarity by introducing dedicated `InvoiceBuilder` methods tied to each variant of `VerifiedInvoiceRequestEnum`. With this change, users are now required to match on the enum variant before calling the corresponding builder method. This pushes the responsibility of selecting the correct builder to the user and ensures that invalid builder usage is caught at compile time, rather than relying on runtime checks. The signing logic has also been moved from the builder to the `ChannelManager`. This shift simplifies the builder's role and aligns it with the rest of the API, where builder methods return a configurable object that can be extended before signing. The result is a more consistent and predictable interface that separates concerns cleanly and makes future maintenance easier.
To ensure correct Bolt12 payment flow behavior, the `amount_msats` used for generating the `payment_hash`, `payment_secret`, and payment path must remain consistent. Previously, these steps could inadvertently diverge due to separate sources of `amount_msats`. This commit refactors the interface to use a `get_payment_info` closure, which captures the required variables and provides a single source of truth for both payment info (payment_hash, payment_secret) and path generation. This ensures consistency and eliminates subtle bugs that could arise from mismatched amounts across the flow.
shaavan
commented
Sep 26, 2025
Uh oh!
There was an error while loading. Please reload this page.
This PR refactors how invoice building works from a
VerifiedInvoiceRequest, replacing runtime checks with compile-time guarantees. Previously, invoice builder selection (betweenusing_derived_keyandusing_explicit_key) was based on an optionalkeyfield, which left room for misuse and bugs that could only be caught at runtime.To address this,
VerifiedInvoiceRequestis now parameterized by aSigningPubkeyStrategy, exposing only the appropriate builder method for each variant. This enforces correctness at the type level and prevents invalid combinations from compiling.Additional changes:
OffersMessageFlowinterface now uses distinct builder paths based on theVerifiedInvoiceRequestvariant, shifting variant matching to compile time.ChannelManager: Aligns with existing patterns and gives users flexibility to customize theInvoiceBuilderbefore signing.(payment_hash, payment_secret)creation and consolidatesamount_msatsinto a single authoritative source.Reasoning:
This change lays the groundwork for #3833, which introduces Flow events to support manual handling of
OffersMessages.Invoice building from an
InvoiceRequestdepends on aSigningPubkeyStrategy, which can be either:DerivedSigningPubkey: the key is derived from the offer inside the request, orExplicitSigningPubkey: the key is supplied by the user when signing the final invoice.Previously, we relied on runtime checks to validate builder–strategy alignment. While this worked, it lacked compile-time safety—invalid combinations could still compile and only fail at runtime.
This was acceptable under the previous model, where users couldn’t build invoices manually (e.g., when using the default
OffersMessageFlowwithChannelManager). But with the Flow event API introduced in #3833, users will now handle invoice requests asynchronously and construct invoices directly.With this PR, only the valid builder–strategy pairs are allowed at compile time. This improves type safety, prevents incorrect usage, and makes the manual invoice-generation flow more robust as LDK evolves.