Skip to content

Commit e3c2e1e

Browse files
committed
WIP: send invoice request encoding
1 parent 19f3053 commit e3c2e1e

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
@@ -615,6 +615,57 @@ impl TryFrom<OfferTlvStream> for OfferContents {
615615
}
616616
}
617617

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