Skip to content

Commit 94d12f9

Browse files
committed
Bolt12Invoice for Offer without signing_pubkey
When parsing a Bolt12Invoice use both the Offer's signing_pubkey and paths to determine if it is for an Offer or a Refund. Previously, an Offer was required to have a signing_pubkey. But now that it is optional, the Offers paths can be used to make the determination. Additionally, check that the invoice matches one of the blinded node ids from the paths' last hops.
1 parent d20de39 commit 94d12f9

File tree

1 file changed

+17
-3
lines changed

1 file changed

+17
-3
lines changed

lightning/src/offers/invoice.rs

+17-3
Original file line numberDiff line numberDiff line change
@@ -1447,8 +1447,8 @@ impl TryFrom<PartialInvoiceTlvStream> for InvoiceContents {
14471447
features, signing_pubkey,
14481448
};
14491449

1450-
match offer_tlv_stream.node_id {
1451-
Some(expected_signing_pubkey) => {
1450+
match (offer_tlv_stream.node_id, &offer_tlv_stream.paths) {
1451+
(Some(expected_signing_pubkey), _) => {
14521452
if fields.signing_pubkey != expected_signing_pubkey {
14531453
return Err(Bolt12SemanticError::InvalidSigningPubkey);
14541454
}
@@ -1458,7 +1458,21 @@ impl TryFrom<PartialInvoiceTlvStream> for InvoiceContents {
14581458
)?;
14591459
Ok(InvoiceContents::ForOffer { invoice_request, fields })
14601460
},
1461-
None => {
1461+
(None, Some(paths)) => {
1462+
if !paths
1463+
.iter()
1464+
.filter_map(|path| path.blinded_hops.last())
1465+
.any(|last_hop| fields.signing_pubkey == last_hop.blinded_node_id)
1466+
{
1467+
return Err(Bolt12SemanticError::InvalidSigningPubkey);
1468+
}
1469+
1470+
let invoice_request = InvoiceRequestContents::try_from(
1471+
(payer_tlv_stream, offer_tlv_stream, invoice_request_tlv_stream)
1472+
)?;
1473+
Ok(InvoiceContents::ForOffer { invoice_request, fields })
1474+
},
1475+
(None, None) => {
14621476
let refund = RefundContents::try_from(
14631477
(payer_tlv_stream, offer_tlv_stream, invoice_request_tlv_stream)
14641478
)?;

0 commit comments

Comments
 (0)