Skip to content

Commit df08d93

Browse files
committed
WIP: send invoice request encoding
1 parent 49871a1 commit df08d93

File tree

3 files changed

+63
-3
lines changed

3 files changed

+63
-3
lines changed

lightning/src/offers/invoice_request.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ use crate::io;
5858
use crate::ln::features::OfferFeatures;
5959
use crate::ln::msgs::DecodeError;
6060
use crate::offers::merkle::{SignatureTlvStream, SignatureTlvStreamRef, self};
61-
use crate::offers::offer::{Amount, Offer, OfferContents, OfferTlvStream, OfferTlvStreamRef};
61+
use crate::offers::offer::{Amount, Offer, OfferContents, OfferTlvStream, OfferTlvStreamRef, SendInvoiceOfferContents};
6262
use crate::offers::parse::{ParseError, SemanticError};
6363
use crate::offers::payer::{PayerContents, PayerTlvStream, PayerTlvStreamRef};
6464
use crate::util::ser::{HighZeroBytesDroppedBigSize, SeekReadable, WithoutLength, Writeable, Writer};
@@ -411,7 +411,10 @@ impl TryFrom<PartialInvoiceRequestTlvStream> for InvoiceRequestContents {
411411
) = tlv_stream;
412412

413413
let payer = PayerContents(metadata);
414-
let offer = OfferContents::try_from(offer_tlv_stream)?;
414+
let offer = match offer_tlv_stream.node_id {
415+
Some(_) => OfferContents::try_from(offer_tlv_stream)?,
416+
None => SendInvoiceOfferContents::try_from(offer_tlv_stream)?.0,
417+
};
415418

416419
if !offer.supports_chain(chain.unwrap_or_else(|| offer.implied_chain())) {
417420
return Err(SemanticError::UnsupportedChain);

lightning/src/offers/offer.rs

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -621,6 +621,57 @@ impl TryFrom<OfferTlvStream> for OfferContents {
621621
}
622622
}
623623

624+
/// [`OfferContents`] used with a "send invoice" offer (i.e., a published [`InvoiceRequest`]).
625+
///
626+
/// [`InvoiceRequest`]: crate::offers::invoice_request::InvoiceRequest
627+
pub(super) struct SendInvoiceOfferContents(pub OfferContents);
628+
629+
impl TryFrom<OfferTlvStream> for SendInvoiceOfferContents {
630+
type Error = SemanticError;
631+
632+
fn try_from(tlv_stream: OfferTlvStream) -> Result<Self, Self::Error> {
633+
let OfferTlvStream {
634+
chains, metadata, currency, amount, description, features, absolute_expiry, paths,
635+
issuer, quantity_max, node_id,
636+
} = tlv_stream;
637+
assert!(node_id.is_none());
638+
639+
if chains.is_some() {
640+
return Err(SemanticError::UnexpectedChain);
641+
}
642+
643+
if currency.is_some() || amount.is_some() {
644+
return Err(SemanticError::UnexpectedAmount);
645+
}
646+
647+
let description = match description {
648+
None => return Err(SemanticError::MissingDescription),
649+
Some(description) => description,
650+
};
651+
652+
let features = match features {
653+
None => OfferFeatures::empty(),
654+
Some(_) => return Err(SemanticError::UnexpectedFeatures),
655+
};
656+
657+
let absolute_expiry = absolute_expiry.map(Duration::from_secs);
658+
659+
let paths = match paths {
660+
Some(paths) if paths.is_empty() => return Err(SemanticError::MissingPaths),
661+
paths => paths,
662+
};
663+
664+
if quantity_max.is_some() {
665+
return Err(SemanticError::UnexpectedQuantity);
666+
}
667+
668+
Ok(SendInvoiceOfferContents(OfferContents {
669+
chains: None, metadata, amount: None, description, features, absolute_expiry, issuer,
670+
paths, supported_quantity: Quantity::one(), signing_pubkey: None,
671+
}))
672+
}
673+
}
674+
624675
impl core::fmt::Display for Offer {
625676
fn fmt(&self, f: &mut core::fmt::Formatter) -> Result<(), core::fmt::Error> {
626677
self.fmt_bech32_str(f)

lightning/src/offers/parse.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,16 +77,22 @@ pub enum ParseError {
7777
pub enum SemanticError {
7878
/// The provided chain hash does not correspond to a supported chain.
7979
UnsupportedChain,
80-
/// An amount was expected but was missing.
80+
/// A chain was provided but was not expected.
81+
UnexpectedChain,
82+
/// An amount was not provided.
8183
MissingAmount,
8284
/// An amount exceeded the maximum number of bitcoin.
8385
InvalidAmount,
8486
/// An amount was provided but was not sufficient in value.
8587
InsufficientAmount,
88+
/// An amount was provided but was not expected.
89+
UnexpectedAmount,
8690
/// A currency was provided that is not supported.
8791
UnsupportedCurrency,
8892
/// A feature was required but is unknown.
8993
UnknownRequiredFeatures,
94+
/// Features were provided but were not expected.
95+
UnexpectedFeatures,
9096
/// A required description was not provided.
9197
MissingDescription,
9298
/// A node id was not provided.

0 commit comments

Comments
 (0)