-
Notifications
You must be signed in to change notification settings - Fork 45
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
adding support for bolt12 offers #598
base: main
Are you sure you want to change the base?
Conversation
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.
Looking good @hydra-yse, thanks. I did a pass over the PR, let me know if you need help running the code generators.
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.
Left some small remarks.
I think it could be useful to put the actual sending to bolt12 invoices in the same pull request eventually. So you know exactly which fields you need where. Like blinded paths for example are probably useful for sending, but maybe not so useful to expose to the caller.
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 made another pass and left comments, looking good.
Are you going to add the bindings interface to the uniffi UDL in sdk-bindings also? If you make changes there, please rerun the flutter/RN codegen.
libs/sdk-core/src/invoice.rs
Outdated
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] | ||
pub enum Amount { | ||
Bitcoin { amount_msats: u64 }, | ||
Currency { iso4217_code: [u8; 3], amount: u64 }, |
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 would suggest changing the Currency iso4217_code to id, to match FiatCurrency id and converting it to String.
Currency { iso4217_code: [u8; 3], amount: u64 }, | |
Currency { id: String, amount: u64 }, |
libs/sdk-core/src/invoice.rs
Outdated
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] | ||
pub enum Amount { | ||
Bitcoin { amount_msats: u64 }, | ||
Currency { iso4217_code: [u8; 3], amount: u64 }, |
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 have to be careful with the currency amount, as in the Offer spec it is denominated in the fractional unit of the currency. Maybe renaming it to fractional_amount
is clearer.
- MUST specify
offer_amount
in the currency unit adjusted by the ISO 4712 exponent (e.g. USD cents).
libs/sdk-core/src/invoice.rs
Outdated
|
||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] | ||
pub enum Amount { | ||
Bitcoin { amount_msats: u64 }, |
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.
Bitcoin { amount_msats: u64 }, | |
Bitcoin { amount_msat: u64 }, |
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 originally named it amount_msats
to keep naming persistence with the lightning::offers::offer::Amount
enum, but there is no problem in changing it 👍
libs/sdk-core/src/models.rs
Outdated
|
||
#[derive(Clone, Debug, Serialize, Deserialize, Eq, PartialEq)] | ||
pub struct FetchInvoiceResponse { | ||
pub invoice: String, |
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.
If we're following the current SDK naming convention, this should be bolt12
. But we should consider unifying these string invoice names across the SDK to something like payment_request
or invoice
. send_payment
should also be able to handle both bolt11 and bolt12.
What are your thoughts on changes to the invoice naming @roeierez?
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 think in the response it is OK to differentiate and use bolt12, bolt11 as it is more clear to the caller.
About send_payment
I agree it should take either bolt11 or bolt12 so clearly the current bolt11 should be changed in SendPaymentRequest.
libs/sdk-core/src/test_utils.rs
Outdated
@@ -719,6 +729,25 @@ fn sign_invoice(invoice: RawInvoice) -> String { | |||
.to_string() | |||
} | |||
|
|||
fn fetch_invoice(offer: LNOffer) -> FetchInvoiceResponse { | |||
// Mock node receiving FetchInvoiceRequest and building an invoice out of it | |||
let minimum_sats = 10000u64; |
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.
Maybe rename to currency_amount_msat
I know the CLN method is called fetchinvoice, but what do you think to the interface being called |
Fair point. I can see the reasoning behind naming it |
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.
Looking good! Some small comments.
libs/sdk-core/src/models.rs
Outdated
|
||
#[derive(Clone, Debug, Serialize, Deserialize, Eq, PartialEq)] | ||
pub struct FetchInvoiceResponse { | ||
pub invoice: String, |
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 think in the response it is OK to differentiate and use bolt12, bolt11 as it is more clear to the caller.
About send_payment
I agree it should take either bolt11 or bolt12 so clearly the current bolt11 should be changed in SendPaymentRequest.
libs/sdk-core/Cargo.toml
Outdated
@@ -64,6 +61,7 @@ miniz_oxide = "0.7.1" | |||
tokio-stream = "0.1.14" | |||
serde_with = "3.3.0" | |||
regex = "1.8.1" | |||
gl-client = { git = "https://github.com/hydra-yse/greenlight", branch = "20231109-fetchinvoice" } |
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 can now use the gl main branch as this was merged yesterday.
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.
Looking good!
Some small nits about naming.
There's some changes in Cargo.toml/Cargo.lock files that seem unnecessary for this change, let's clean that up before merging.
libs/sdk-core/src/node_api.rs
Outdated
OfferReplyError(anyhow::Error), | ||
|
||
#[error("Offer timeout: {0}")] | ||
OfferTimeout(anyhow::Error), |
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.
Suggestion to make more clear what this does.
It's a long name I'm suggesting though, maybe we can do better.
OfferTimeout(anyhow::Error), | |
OfferInvoiceRequestTimeout(anyhow::Error), |
libs/sdk-core/src/node_api.rs
Outdated
OfferExpired(anyhow::Error), | ||
|
||
#[error("Offer reply error: {0}")] | ||
OfferReplyError(anyhow::Error), |
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.
Suggestion to make more clear what this does.
It's a long name I'm suggesting though, maybe we can do better.
OfferReplyError(anyhow::Error), | |
OfferInvoiceRequestError(anyhow::Error), |
}, | ||
JsonRpcErrCode::OfferExpired => Self::OfferExpired(status.into()), | ||
JsonRpcErrCode::OfferBadInvreqReply => Self::OfferReplyError(status.into()), | ||
JsonRpcErrCode::OfferRouteNotFound => Self::RouteNotFound(status.into()), |
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.
Thinking out loud. I think it may be useful to distinguish between 'payment' route not found and 'messaging' route not found. RouteNotFound is such a general error that pops up too many times. @dangeross what do you think?
libs/sdk-bindings/src/breez_sdk.udl
Outdated
@@ -133,7 +133,7 @@ dictionary RouteHint { | |||
}; | |||
|
|||
dictionary LNInvoice { | |||
string bolt11; | |||
string raw_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.
Why is this field changed? do we use it for bolt12 also? I couldn't find any reference for such usage in the code.
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 consider whether the LNInvoice
wrapper should be able to support both Bolt11 and Bolt12 fields at once, given the overlap between the two. Currently CLN makes the invoice field naming distinct between the two types in most methods (e.g. createinvoice, listinvoices etc.) with the exception of outward methods like sendpay and pay.
The initial reasoning was that, in terms of UX, I believe that the final user is probably not really interested in the type of invoice they are paying (whether bolt11 or 12), so perhaps unifying the optional bolt11
and bolt12
parameters into a single field raw_invoice
could make sense and reduce the need to constantly check which one it is. Additionally, the client would know the type a priori to the fetchinvoice call simply by the scanned QR (offer or bolt11 invoice), therefore there is most probably a way to make this work with a single field.
On the other hand, I can also see instances where the developers would like to know which type of invoice it is at any given time. That is of course more flexible on the developer's side as they are now able to handle the two distinct cases better (such as adding more fields depending on which kind it is [e.g. quantity]) and throw an error, for example, if neither is specified, without having to refer to the original offer to discern so.
I'll probably roll back this change and specify the two fields as optional, just wanted to let you in on what the thought process was behind that decision
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.
Thanks for the details on what you had in mind @hydra-yse
For me it is even more simple than that. As long as the code doesn't user LNINvoice for bolt12 (and we don't even expose this parsing to the user) then there is no reason to unified.
If/When we implement and expose such parsing we will have more information to take the right decision.
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.
Agree with Roei. For parsing we can differentiate between bolt11 and bolt12 invoices. For send_payment we can call the bolt11
argument payment_request
. The developer would call send_payment
with either the bolt11 fields from LNInvoice or the bolt12_offer
field from LNOffer.
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.
The main questions for me are:
- what to do with the
parse_invoice
interface? - can we call the
fetch_invoice
inside thesend_payment
method, rather than exposing it to the client?
libs/sdk-bindings/src/breez_sdk.udl
Outdated
@@ -133,7 +133,8 @@ dictionary RouteHint { | |||
}; | |||
|
|||
dictionary LNInvoice { | |||
string bolt11; | |||
string? bolt11; | |||
string? bolt12; |
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 like the side-by-side fields here. You see this change cascading throughout the codebase, into swaps and lnurl. While I don't think it's relevant there.
Maybe we need another type: Bolt12Invoice? I think the main place where this change is needed is in the parse_invoice
function. Perhaps the parse_invoice
function can return an enum instead?
I see that parse_invoice
is exposed in the udl as well. @roeierez why do we expose that function? Doesn't the input parser cover that?
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 was also conflicted about the decision. The merging into LNInvoice
made sense to me given that the invoices are functionally equivalent at the moment, since we do not handle recurrence and blinded paths yet, plus the fact that CLN's create_invoice command (which is not directly called, as it is more low-level) does exactly the same.
Despite that, some higher level commands like lightning-invoice
do not allow us to create bolt12 invoices directly, therefore it would make sense to distinguish between those which can and can't with two different interfaces, then using enums to specify either one of them.
Lastly, regarding the codebase, I agree that having to propagate the changes everywhere is not ideal, yet I've checked that altering parse_invoice
would require us to make many changes (if not more) as well. Despite the hassle though, I still think it may be worth going forward as you suggested.
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 agree and strongly feel that parsing bolt11 should return a different type than LNInvoice simply because it has different data (even though currently we don't expose/use it).
As for exposing parse_invoice in the udl I agree it is not really necessary (perhaps there are times when the user "knows" that she have a bolt11 in hand and can use this function directly rather than going through the input parser). Doesn't mean we have to do the same mistake twice if we are not sure.
How about:
- Leave the parse_invoice as is for now (bolt11 only).
- Not expose parsing bolt12 directly but only via the input parser
- Use different structure for bolt12 invoices.
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 think
LNInvoice
could be renamed toBolt11Invoice
to take away any ambiguity.parse_invoice
could be renamed toparse_bolt11_invoice
to make it clear what it's for. Maybe add aparse_bolt12_invoice
function (internally) if necessary.- Add a
Bolt12Invoice
type - The input parser could probably use another branch to parse bolt12 invoices as well.
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 agree. I am ok with renaming and break computability a bit.
libs/sdk-core/src/breez_services.rs
Outdated
@@ -1368,6 +1368,16 @@ impl BreezServices { | |||
}, | |||
}) | |||
} | |||
|
|||
pub async fn fetch_invoice(&self, req: FetchInvoiceRequest) -> Result<FetchInvoiceResponse> { |
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.
Is the goal to actually expose this to the client? (in that case needs changes to the udl)
I thought we could do the fetching of the invoice inside the send_payment method and we wouldn't need to expose this to the client? Maybe I misunderstood that.
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.
Based on my thoughts on how the flow would be, and the discussions previously had, I have ended up with the following conclusion:
- User scans the QR code, reading the offer and decoding its contents
- User gets prompted with mandatory fields to fill (e.g.
quantity
,amount_msat
[if offer'samount
= any] etc.) - Client calls
fetch_invoice
with specified parameters, gets a bolt12 invoice in return and displays relevant changes (e.g.amount_msat
, which should correspond to the specifiedamount_msat
field times thequantity
field, but may have been changed by the recipient for any reason) - Client displays the invoice details, if user agrees they execute
send_payment
, and the invoice gets paid
Thus, since it is relevant for the user to see which changes may or may not have been made, I suggest keeping fetch_invoice as a separate function exposed to the client.
Let me know if you agree or if perhaps we could generalize the mismatches directly within send_payment
(e.g. when amount_msat
mismatches, simply return Err and have the user retry until the amount is valid, although I do think that would be somewhat limiting for both users and developers).
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.
OK, I think that makes sense. It would need some extensive documentation on how to use this bolt12 flow.
Question is whether we even want to put the bolt12 send_payment
in the same function as the bolt11 send_payment
then. Since the caller already has to use a different flow to grab the invoice and show things to the user, maybe we're better off having separate functions, rather than trying to fit everything in the same?
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 a shame we have to expose all this all the way to the user. It makes the sdk harder to use. It's not just a send_payment flow anymore, but you really have to implement many branches as a developer. I guess there's not much we can do about that though.
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 think we can start with error when mismatch. It is too duplicate flow to show changes. Also we don't know currently if in practice this really happens or what is the probability for this to happen.
How about start simple? :
- User pay offer (and pass amount for amount-less offers)
- We fetch the invoice internally if amount doesn't match return error otherwise we just pay.
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.
@JssDWt @hydra-yse my suggestion above consolidates the flow I agree we shouldn't make the flow complicated and we should do our best do send_payment would fit both cases (bolt12 and bolt11).
If the internally fetch 8nvoice returns mismatch in amount let's just return error
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.
Just to make sure, we came to a conclusion that we don't need this method at the BreezServices
level right?
libs/sdk-bindings/src/breez_sdk.udl
Outdated
string description; | ||
u64? absolute_expiry; | ||
string? issuer; | ||
u64? supported_quantity; |
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.
How about remove this field and not supporting quantity at all at this stage?
libs/sdk-bindings/src/breez_sdk.udl
Outdated
dictionary PayOfferRequest { | ||
string offer; | ||
u64? amount_msat; | ||
u64? quantity; |
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.
Also here perhaps not pass quantity at all? I am OK with starting without supporting quantity at all and even return error when user scans an offer that requires quantity.
I think it is better to wait for a feedback from the users here to understand if supporting it is required.
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.
After thinking about it, I agree. Implementing quantity doesn't take much (just a few lines of code in fact, since the changes are handled on CLN) though I do agree in more general terms that perhaps it could be handled elsewhere. Leaving it out for now 👍
let mut field_errors: Vec<FetchInvoiceRequiredField> = vec![]; | ||
|
||
if parsed_offer.expects_quantity() && req.quantity.is_none() { | ||
field_errors.push(FetchInvoiceRequiredField::Quantity); |
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.
Perhaps a simple way would be to just return error here? These are validation errors for the developer, not for the end user if I understand correctly.
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.
Indeed, I kept them for the developer side if a change is ever detected. This way, they can check the array of fields and get a convenient enum which they can then use to throw specific errors, or perhaps show a "red field" for the values that need to be changed in order for the offer to succeed.
Edit: After thinking more about it, I have changed my mind. The offer is of course still parsed both client-side and through the SDK, yet no validation is done on the fields. The client (developer) has full responsibility of rendering the appropriate fields and checking they are valid before calling the method. If they do not, the grpc call will of course fail. Understanding whether or not it did due to missing fields is ultimately the developer's task, as we want to keep the sdk as simple as possible.
|
||
Ok(FetchInvoiceResponse { | ||
bolt12: response.invoice, | ||
changes: response.changes.map(|changes| FetchInvoiceChanges { |
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.
The changes seems like complicating the flow and I don't understand when exactly the API call should return changes in practice? Is this a positive or negative scenario?
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.
For the end user, this is a negative scenario. If the amount changes from what the user expects without them knowing, they would be paying a higher amount than expected without confirmation.
I'll remove throwing an error when the description
or vendor
change, as they are not that relevant (added them for completeness), but definitely will keep the change in the expected amount.
libs/sdk-core/src/models.rs
Outdated
pub struct FetchInvoiceRequest { | ||
pub offer: String, | ||
pub amount_msat: Option<u64>, | ||
pub quantity: Option<u64>, | ||
pub timeout: Option<f64>, | ||
pub payer_note: Option<String>, | ||
} | ||
|
||
#[derive(Clone, Debug, Serialize, Deserialize, Eq, PartialEq)] | ||
pub struct FetchInvoiceChanges { | ||
pub description_appended: Option<String>, | ||
pub description: Option<String>, | ||
pub vendor_removed: Option<String>, | ||
pub vendor: Option<String>, | ||
pub amount_msat: Option<u64>, | ||
} | ||
|
||
#[derive(Clone, Debug, Serialize, Deserialize, Eq, PartialEq)] | ||
pub struct FetchInvoiceResponse { |
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.
Seems like these are used internally in the sdk and should not be public.
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.
The structs must be prefixed with pub
in order to be accessible from other sub-modules, like the node_api
libs/sdk-core/src/test_utils.rs
Outdated
.amount | ||
.map(|amount| match amount { | ||
crate::invoice::Amount::Bitcoin { amount_msat } => amount_msat, | ||
crate::invoice::Amount::Currency { .. } => currency_amount_msat, |
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.
Do we need to do convert the currency to sats here? Let's not support it at first stage?
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're right, this was part of the old tests, planning to change it and find a better way to replicate the invoice creation step from the offer using the lightning library.
libs/sdk-core/src/breez_services.rs
Outdated
@@ -1368,6 +1368,16 @@ impl BreezServices { | |||
}, | |||
}) | |||
} | |||
|
|||
pub async fn fetch_invoice(&self, req: FetchInvoiceRequest) -> Result<FetchInvoiceResponse> { |
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.
Just to make sure, we came to a conclusion that we don't need this method at the BreezServices
level right?
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.
@hydra-yse this shapes up very nicely and looks really good. I added some comments, most of them are Nits.
I think we are missing two things:
- Supporting open channels as part of bolt12 received payment.
- Adding cli commands to create offer and pay offer.
Ok(FetchInvoiceResponse { | ||
bolt12: response.invoice, | ||
new_amount_msat: match response.changes { | ||
Some(changes) => changes.amount_msat.map(|amount| amount.msat), |
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.
Do we need to check if other changes exists and return error? My concern is that it seems we swallow these changes without any indication for the user.
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.
For basic support, currently not. Changes in description/vendor can be ignored while a change in the amount could mean the user paying more than they expect, thus an error has to be thrown
@@ -1368,6 +1368,38 @@ impl BreezServices { | |||
}, | |||
}) | |||
} | |||
|
|||
pub async fn create_offer(&self, req: CreateOfferRequest) -> Result<String> { |
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.
This API is actually similar to receive_payment
(that returns bolt11) but for bolt12.
The way it is right now is a bit inconsistent since the receive_payment
returns a response with the invoice parsed (LNInvoice) and here we return just the raw offer. For consistency perhaps we should return the LNOffer structure here.
libs/sdk-core/src/models.rs
Outdated
pub struct FetchInvoiceRequest { | ||
pub offer: String, | ||
pub amount_msat: Option<u64>, | ||
pub timeout: Option<f64>, | ||
pub payer_note: Option<String>, | ||
} | ||
|
||
#[derive(Clone, Debug, Serialize, Deserialize, Eq, PartialEq)] | ||
pub struct FetchInvoiceResponse { | ||
pub bolt12: String, | ||
pub new_amount_msat: Option<u64>, | ||
} |
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.
These are not publicly exposed right but only needed internally in the sdk right? If so let's change their access modifier accordingly.
libs/sdk-bindings/src/breez_sdk.udl
Outdated
u64? amount_msat; | ||
string description; | ||
u64? absolute_expiry; | ||
string? issuer; |
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 would remove the issuer for the first version of bolt12 feature.
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 starting to look very clean, I like it!
@@ -237,7 +237,7 @@ impl BreezServices { | |||
req: SendPaymentRequest, | |||
) -> Result<SendPaymentResponse, SendPaymentError> { | |||
self.start_node().await?; | |||
let parsed_invoice = parse_invoice(req.bolt11.as_str())?; | |||
let parsed_invoice = parse_invoice(req.invoice.as_str())?; |
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 believe this still parses a bolt11 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.
pay_offer
internally calls send_payment
, so I thought it would be appropriate to change the field to invoice
as we now know it can support both bolt11 and 12.
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 mean the parse_invoice
function expects a bolt11 invoice. So if a bolt12 invoice is passed here, the parsing will fail.
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.
Right. I think the best solution would be to make parse_invoice
compatible with either, returning either a bolt11 or a bolt12 invoice. Alternatively, I can just replicate the send_payment
flow on pay_offer
and create a separate parsing method for bolt 12 invoices. Let me know what you think
Adding CLN Bolt12 compat tracking issue here |
314feca
to
344ab0b
Compare
344ab0b
to
ad384b1
Compare
resolves #562 1,2
Note: In order to support these changes, the
gl_client
crate in sdk-core currently points to a locally-owned repository. Once greenlight and cln_grpc are both updated to support these features, we can opt-out back to the original crates. I suggest changes should be moved into a side branch until then.