Skip to content

Commit 34a226e

Browse files
committed
WIP: send invoice request encoding
1 parent bff159f commit 34a226e

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};
@@ -405,7 +405,10 @@ impl TryFrom<PartialInvoiceRequestTlvStream> for InvoiceRequestContents {
405405
) = tlv_stream;
406406

407407
let payer = PayerContents(metadata);
408-
let offer = OfferContents::try_from(offer_tlv_stream)?;
408+
let offer = match offer_tlv_stream.node_id {
409+
Some(_) => OfferContents::try_from(offer_tlv_stream)?,
410+
None => SendInvoiceOfferContents::try_from(offer_tlv_stream)?.0,
411+
};
409412

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

lightning/src/offers/offer.rs

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -603,6 +603,57 @@ impl TryFrom<OfferTlvStream> for OfferContents {
603603
}
604604
}
605605

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