-
Notifications
You must be signed in to change notification settings - Fork 269
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
RPC: parse BOLT12 invoices and offers #2843
Conversation
Codecov ReportAll modified and coverable lines are covered by tests ✅
❗ Your organization needs to install the Codecov GitHub app to enable full functionality. Additional details and impacted files@@ Coverage Diff @@
## master #2843 +/- ##
==========================================
+ Coverage 85.96% 86.00% +0.03%
==========================================
Files 219 219
Lines 18441 18442 +1
Branches 762 731 -31
==========================================
+ Hits 15853 15861 +8
+ Misses 2588 2581 -7
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You seem to be doing more than just adding a parseoffer
API in this PR, you're also adding support for Bolt 12 invoices which is arguably not a good idea...
@@ -138,6 +138,7 @@ private class OfferPayment(replyTo: ActorRef, | |||
Behaviors.stopped | |||
case None => | |||
context.spawnAnonymous(CompactBlindedPathsResolver(router)) ! Resolve(context.messageAdapter[Seq[ResolvedPath]](WrappedResolvedPaths), payload.invoice.blindedPaths) | |||
context.log.info(s"BOLT12 invoice: ${payload.invoice}") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: remove?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not really. It's really useful for debugging. How else could we know what kind of invoices our counterparties send to us?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't understand...? Why is it useful to log the Bolt 12 invoice we receive? If the payment completes it will be stored in our payments DB. If the payment fails, do you really need the invoice to investigate why it failed? It will generally be easy to figure out what fails without it?
val invoiceUnmarshaller: Unmarshaller[String, Invoice] = Unmarshaller.strict { str => | ||
Bolt11Invoice.fromString(str).orElse(Bolt12Invoice.fromString(str)).get | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why are you introducing this? It creates unnecessary complexity in API handlers since we don't support directly paying a Bolt 12 invoice (we should always start with an offer and go through the invoice_request
flow)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please advise how it is supposed to be done in the right way? All I need is to have an ability to parse Bolt 12 invoices and offers.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To parse an invoice when you don't know which kind of invoice to expect, you should use Invoice.fromString
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What I meant is that Bolt 12 invoices shouldn't be exposed, see #2843 (comment)
There was a decision to not even specify a string encoding for them, we have one in eclair for consistency (and because we added it before the spec removed it), but it shouldn't be relied on.
@@ -47,7 +47,7 @@ trait ExtraDirectives extends Directives { | |||
val outPointsFormParam: NameUnmarshallerReceptacle[List[OutPoint]] = "outpoints".as[List[OutPoint]](outPointListUnmarshaller) | |||
val paymentHashFormParam: NameUnmarshallerReceptacle[ByteVector32] = "paymentHash".as[ByteVector32](bytes32Unmarshaller) | |||
val amountMsatFormParam: NameReceptacle[MilliSatoshi] = "amountMsat".as[MilliSatoshi] | |||
val invoiceFormParam: NameReceptacle[Bolt11Invoice] = "invoice".as[Bolt11Invoice] | |||
val invoiceFormParam: NameUnmarshallerReceptacle[Invoice] = "invoice".as[Invoice](invoiceUnmarshaller) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should keep this for Bolt 11 only, Bolt 12 invoices should be obtained with the invoice_request
flow and never accepted as a parameter?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't really understand the question, sorry.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's actually not a question but a statement. I guess t-bast added a question mark to ask if you object to this statement.
Your reason to use it is parseinvoice
and I agree that it would be nice to have, but it would be cleaner to keep this only for Bolt11Invoice
(renaming it to bolt11invoiceFormParam
) and create a new invoiceFormParam
that you use only for parseinvoice
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From the spec point of view, Bolt 12 invoices should not be exposed to end users, only the offer should be exposed. You shouldn't be able to explicitly pay a Bolt 12 invoice, APIs should only allow you to pay a Bolt 12 offer.
So I'm not sure why you'd want to be able to parse them, since they're meant to be internal objects that aren't exposed to end users. On top of that, they're just a TLV stream, so it won't look nice in JSON at all...
Not at all. Only |
This is what threw me off, I don't think we should do this. But I may be wrong, @thomash-acinq do you think this would be useful? |
If there was an explicit decision to hide Bolt 12 invoices from the user (I didn't realize it was removed from the spec), then we shouldn't expose them. If it's only for debugging purposes, what I usually do is run this test: test("show invoice"){
val encodedInvoice = "lni1qqgds4gw..."
val invoice = Bolt12Invoice.fromString(encodedInvoice).get
invoice.records.records.foreach(println)
} |
Shelving this for now, as Bolt 12 invoices aren't supposed to be exposed yet. We can reopen this in the future when concrete use-cases need it. |
This PR adds the ability to parse BOLT12 invoices to
parseinvoice
RPC call, and introducesparseoffer
RPC call, that parses BOLT12 offers.