//! Data structures and encoding for `invoice` messages.
//!
-//! An [`Invoice`] can be built from a parsed [`InvoiceRequest`] for the "offer to be paid" flow or
-//! from a [`Refund`] as an "offer for money" flow. The expected recipient of the payment then sends
-//! the invoice to the intended payer, who will then pay it.
+//! A [`Bolt12Invoice`] can be built from a parsed [`InvoiceRequest`] for the "offer to be paid"
+//! flow or from a [`Refund`] as an "offer for money" flow. The expected recipient of the payment
+//! then sends the invoice to the intended payer, who will then pay it.
//!
//! The payment recipient must include a [`PaymentHash`], so as to reveal the preimage upon payment
//! receipt, and one or more [`BlindedPath`]s for the payer to use when sending the payment.
//! # use lightning::offers::invoice::BlindedPayInfo;
//! # use lightning::blinded_path::BlindedPath;
//! #
-//! # fn create_payment_paths() -> Vec<(BlindedPath, BlindedPayInfo)> { unimplemented!() }
+//! # fn create_payment_paths() -> Vec<(BlindedPayInfo, BlindedPath)> { unimplemented!() }
//! # fn create_payment_hash() -> PaymentHash { unimplemented!() }
//! #
-//! # fn parse_invoice_request(bytes: Vec<u8>) -> Result<(), lightning::offers::parse::ParseError> {
+//! # fn parse_invoice_request(bytes: Vec<u8>) -> Result<(), lightning::offers::parse::Bolt12ParseError> {
//! let payment_paths = create_payment_paths();
//! let payment_hash = create_payment_hash();
//! let secp_ctx = Secp256k1::new();
//! # Ok(())
//! # }
//!
-//! # fn parse_refund(bytes: Vec<u8>) -> Result<(), lightning::offers::parse::ParseError> {
+//! # fn parse_refund(bytes: Vec<u8>) -> Result<(), lightning::offers::parse::Bolt12ParseError> {
//! # let payment_paths = create_payment_paths();
//! # let payment_hash = create_payment_hash();
//! # let secp_ctx = Secp256k1::new();
use crate::offers::invoice_request::{INVOICE_REQUEST_PAYER_ID_TYPE, INVOICE_REQUEST_TYPES, IV_BYTES as INVOICE_REQUEST_IV_BYTES, InvoiceRequest, InvoiceRequestContents, InvoiceRequestTlvStream, InvoiceRequestTlvStreamRef};
use crate::offers::merkle::{SignError, SignatureTlvStream, SignatureTlvStreamRef, TlvStream, WithoutSignatures, self};
use crate::offers::offer::{Amount, OFFER_TYPES, OfferTlvStream, OfferTlvStreamRef};
-use crate::offers::parse::{ParseError, ParsedMessage, SemanticError};
+use crate::offers::parse::{Bolt12ParseError, Bolt12SemanticError, ParsedMessage};
use crate::offers::payer::{PAYER_METADATA_TYPE, PayerTlvStream, PayerTlvStreamRef};
use crate::offers::refund::{IV_BYTES as REFUND_IV_BYTES, Refund, RefundContents};
use crate::offers::signer;
pub(super) const SIGNATURE_TAG: &'static str = concat!("lightning", "invoice", "signature");
-/// Builds an [`Invoice`] from either:
+/// Builds a [`Bolt12Invoice`] from either:
/// - an [`InvoiceRequest`] for the "offer to be paid" flow or
/// - a [`Refund`] for the "offer for money" flow.
///
signing_pubkey_strategy: core::marker::PhantomData<S>,
}
-/// Indicates how [`Invoice::signing_pubkey`] was set.
+/// Indicates how [`Bolt12Invoice::signing_pubkey`] was set.
///
/// This is not exported to bindings users as builder patterns don't map outside of move semantics.
pub trait SigningPubkeyStrategy {}
-/// [`Invoice::signing_pubkey`] was explicitly set.
+/// [`Bolt12Invoice::signing_pubkey`] was explicitly set.
///
/// This is not exported to bindings users as builder patterns don't map outside of move semantics.
pub struct ExplicitSigningPubkey {}
-/// [`Invoice::signing_pubkey`] was derived.
+/// [`Bolt12Invoice::signing_pubkey`] was derived.
///
/// This is not exported to bindings users as builder patterns don't map outside of move semantics.
pub struct DerivedSigningPubkey {}
impl<'a> InvoiceBuilder<'a, ExplicitSigningPubkey> {
pub(super) fn for_offer(
- invoice_request: &'a InvoiceRequest, payment_paths: Vec<(BlindedPath, BlindedPayInfo)>,
+ invoice_request: &'a InvoiceRequest, payment_paths: Vec<(BlindedPayInfo, BlindedPath)>,
created_at: Duration, payment_hash: PaymentHash
- ) -> Result<Self, SemanticError> {
+ ) -> Result<Self, Bolt12SemanticError> {
let amount_msats = Self::check_amount_msats(invoice_request)?;
let signing_pubkey = invoice_request.contents.inner.offer.signing_pubkey();
let contents = InvoiceContents::ForOffer {
}
pub(super) fn for_refund(
- refund: &'a Refund, payment_paths: Vec<(BlindedPath, BlindedPayInfo)>, created_at: Duration,
+ refund: &'a Refund, payment_paths: Vec<(BlindedPayInfo, BlindedPath)>, created_at: Duration,
payment_hash: PaymentHash, signing_pubkey: PublicKey
- ) -> Result<Self, SemanticError> {
+ ) -> Result<Self, Bolt12SemanticError> {
let amount_msats = refund.amount_msats();
let contents = InvoiceContents::ForRefund {
refund: refund.contents.clone(),
impl<'a> InvoiceBuilder<'a, DerivedSigningPubkey> {
pub(super) fn for_offer_using_keys(
- invoice_request: &'a InvoiceRequest, payment_paths: Vec<(BlindedPath, BlindedPayInfo)>,
+ invoice_request: &'a InvoiceRequest, payment_paths: Vec<(BlindedPayInfo, BlindedPath)>,
created_at: Duration, payment_hash: PaymentHash, keys: KeyPair
- ) -> Result<Self, SemanticError> {
+ ) -> Result<Self, Bolt12SemanticError> {
let amount_msats = Self::check_amount_msats(invoice_request)?;
let signing_pubkey = invoice_request.contents.inner.offer.signing_pubkey();
let contents = InvoiceContents::ForOffer {
}
pub(super) fn for_refund_using_keys(
- refund: &'a Refund, payment_paths: Vec<(BlindedPath, BlindedPayInfo)>, created_at: Duration,
+ refund: &'a Refund, payment_paths: Vec<(BlindedPayInfo, BlindedPath)>, created_at: Duration,
payment_hash: PaymentHash, keys: KeyPair,
- ) -> Result<Self, SemanticError> {
+ ) -> Result<Self, Bolt12SemanticError> {
let amount_msats = refund.amount_msats();
let signing_pubkey = keys.public_key();
let contents = InvoiceContents::ForRefund {
}
impl<'a, S: SigningPubkeyStrategy> InvoiceBuilder<'a, S> {
- fn check_amount_msats(invoice_request: &InvoiceRequest) -> Result<u64, SemanticError> {
+ fn check_amount_msats(invoice_request: &InvoiceRequest) -> Result<u64, Bolt12SemanticError> {
match invoice_request.amount_msats() {
Some(amount_msats) => Ok(amount_msats),
None => match invoice_request.contents.inner.offer.amount() {
Some(Amount::Bitcoin { amount_msats }) => {
amount_msats.checked_mul(invoice_request.quantity().unwrap_or(1))
- .ok_or(SemanticError::InvalidAmount)
+ .ok_or(Bolt12SemanticError::InvalidAmount)
},
- Some(Amount::Currency { .. }) => Err(SemanticError::UnsupportedCurrency),
- None => Err(SemanticError::MissingAmount),
+ Some(Amount::Currency { .. }) => Err(Bolt12SemanticError::UnsupportedCurrency),
+ None => Err(Bolt12SemanticError::MissingAmount),
},
}
}
fn fields(
- payment_paths: Vec<(BlindedPath, BlindedPayInfo)>, created_at: Duration,
+ payment_paths: Vec<(BlindedPayInfo, BlindedPath)>, created_at: Duration,
payment_hash: PaymentHash, amount_msats: u64, signing_pubkey: PublicKey
) -> InvoiceFields {
InvoiceFields {
fn new(
invreq_bytes: &'a Vec<u8>, contents: InvoiceContents, keys: Option<KeyPair>
- ) -> Result<Self, SemanticError> {
+ ) -> Result<Self, Bolt12SemanticError> {
if contents.fields().payment_paths.is_empty() {
- return Err(SemanticError::MissingPaths);
+ return Err(Bolt12SemanticError::MissingPaths);
}
Ok(Self {
})
}
- /// Sets the [`Invoice::relative_expiry`] as seconds since [`Invoice::created_at`]. Any expiry
- /// that has already passed is valid and can be checked for using [`Invoice::is_expired`].
+ /// Sets the [`Bolt12Invoice::relative_expiry`] as seconds since [`Bolt12Invoice::created_at`].
+ /// Any expiry that has already passed is valid and can be checked for using
+ /// [`Bolt12Invoice::is_expired`].
///
/// Successive calls to this method will override the previous setting.
pub fn relative_expiry(mut self, relative_expiry_secs: u32) -> Self {
self
}
- /// Adds a P2WSH address to [`Invoice::fallbacks`].
+ /// Adds a P2WSH address to [`Bolt12Invoice::fallbacks`].
///
/// Successive calls to this method will add another address. Caller is responsible for not
/// adding duplicate addresses and only calling if capable of receiving to P2WSH addresses.
self
}
- /// Adds a P2WPKH address to [`Invoice::fallbacks`].
+ /// Adds a P2WPKH address to [`Bolt12Invoice::fallbacks`].
///
/// Successive calls to this method will add another address. Caller is responsible for not
/// adding duplicate addresses and only calling if capable of receiving to P2WPKH addresses.
self
}
- /// Adds a P2TR address to [`Invoice::fallbacks`].
+ /// Adds a P2TR address to [`Bolt12Invoice::fallbacks`].
///
/// Successive calls to this method will add another address. Caller is responsible for not
/// adding duplicate addresses and only calling if capable of receiving to P2TR addresses.
self
}
- /// Sets [`Invoice::features`] to indicate MPP may be used. Otherwise, MPP is disallowed.
+ /// Sets [`Bolt12Invoice::features`] to indicate MPP may be used. Otherwise, MPP is disallowed.
pub fn allow_mpp(mut self) -> Self {
self.invoice.fields_mut().features.set_basic_mpp_optional();
self
}
impl<'a> InvoiceBuilder<'a, ExplicitSigningPubkey> {
- /// Builds an unsigned [`Invoice`] after checking for valid semantics. It can be signed by
- /// [`UnsignedInvoice::sign`].
- pub fn build(self) -> Result<UnsignedInvoice<'a>, SemanticError> {
+ /// Builds an unsigned [`Bolt12Invoice`] after checking for valid semantics. It can be signed by
+ /// [`UnsignedBolt12Invoice::sign`].
+ pub fn build(self) -> Result<UnsignedBolt12Invoice<'a>, Bolt12SemanticError> {
#[cfg(feature = "std")] {
if self.invoice.is_offer_or_refund_expired() {
- return Err(SemanticError::AlreadyExpired);
+ return Err(Bolt12SemanticError::AlreadyExpired);
}
}
let InvoiceBuilder { invreq_bytes, invoice, .. } = self;
- Ok(UnsignedInvoice { invreq_bytes, invoice })
+ Ok(UnsignedBolt12Invoice { invreq_bytes, invoice })
}
}
impl<'a> InvoiceBuilder<'a, DerivedSigningPubkey> {
- /// Builds a signed [`Invoice`] after checking for valid semantics.
+ /// Builds a signed [`Bolt12Invoice`] after checking for valid semantics.
pub fn build_and_sign<T: secp256k1::Signing>(
self, secp_ctx: &Secp256k1<T>
- ) -> Result<Invoice, SemanticError> {
+ ) -> Result<Bolt12Invoice, Bolt12SemanticError> {
#[cfg(feature = "std")] {
if self.invoice.is_offer_or_refund_expired() {
- return Err(SemanticError::AlreadyExpired);
+ return Err(Bolt12SemanticError::AlreadyExpired);
}
}
let InvoiceBuilder { invreq_bytes, invoice, keys, .. } = self;
- let unsigned_invoice = UnsignedInvoice { invreq_bytes, invoice };
+ let unsigned_invoice = UnsignedBolt12Invoice { invreq_bytes, invoice };
let keys = keys.unwrap();
let invoice = unsigned_invoice
}
}
-/// A semantically valid [`Invoice`] that hasn't been signed.
-pub struct UnsignedInvoice<'a> {
+/// A semantically valid [`Bolt12Invoice`] that hasn't been signed.
+pub struct UnsignedBolt12Invoice<'a> {
invreq_bytes: &'a Vec<u8>,
invoice: InvoiceContents,
}
-impl<'a> UnsignedInvoice<'a> {
+impl<'a> UnsignedBolt12Invoice<'a> {
/// The public key corresponding to the key needed to sign the invoice.
pub fn signing_pubkey(&self) -> PublicKey {
self.invoice.fields().signing_pubkey
/// Signs the invoice using the given function.
///
/// This is not exported to bindings users as functions aren't currently mapped.
- pub fn sign<F, E>(self, sign: F) -> Result<Invoice, SignError<E>>
+ pub fn sign<F, E>(self, sign: F) -> Result<Bolt12Invoice, SignError<E>>
where
F: FnOnce(&Message) -> Result<Signature, E>
{
};
signature_tlv_stream.write(&mut bytes).unwrap();
- Ok(Invoice {
+ Ok(Bolt12Invoice {
bytes,
contents: self.invoice,
signature,
}
}
-/// An `Invoice` is a payment request, typically corresponding to an [`Offer`] or a [`Refund`].
+/// A `Bolt12Invoice` is a payment request, typically corresponding to an [`Offer`] or a [`Refund`].
///
/// An invoice may be sent in response to an [`InvoiceRequest`] in the case of an offer or sent
/// directly after scanning a refund. It includes all the information needed to pay a recipient.
///
-/// This is not exported to bindings users as its name conflicts with the BOLT 11 Invoice type.
-///
/// [`Offer`]: crate::offers::offer::Offer
/// [`Refund`]: crate::offers::refund::Refund
/// [`InvoiceRequest`]: crate::offers::invoice_request::InvoiceRequest
#[derive(Clone, Debug)]
#[cfg_attr(test, derive(PartialEq))]
-pub struct Invoice {
+pub struct Bolt12Invoice {
bytes: Vec<u8>,
contents: InvoiceContents,
signature: Signature,
}
-/// The contents of an [`Invoice`] for responding to either an [`Offer`] or a [`Refund`].
+/// The contents of an [`Bolt12Invoice`] for responding to either an [`Offer`] or a [`Refund`].
///
/// [`Offer`]: crate::offers::offer::Offer
/// [`Refund`]: crate::offers::refund::Refund
#[derive(Clone, Debug)]
#[cfg_attr(test, derive(PartialEq))]
enum InvoiceContents {
- /// Contents for an [`Invoice`] corresponding to an [`Offer`].
+ /// Contents for an [`Bolt12Invoice`] corresponding to an [`Offer`].
///
/// [`Offer`]: crate::offers::offer::Offer
ForOffer {
invoice_request: InvoiceRequestContents,
fields: InvoiceFields,
},
- /// Contents for an [`Invoice`] corresponding to a [`Refund`].
+ /// Contents for an [`Bolt12Invoice`] corresponding to a [`Refund`].
///
/// [`Refund`]: crate::offers::refund::Refund
ForRefund {
/// Invoice-specific fields for an `invoice` message.
#[derive(Clone, Debug, PartialEq)]
struct InvoiceFields {
- payment_paths: Vec<(BlindedPath, BlindedPayInfo)>,
+ payment_paths: Vec<(BlindedPayInfo, BlindedPath)>,
created_at: Duration,
relative_expiry: Option<Duration>,
payment_hash: PaymentHash,
signing_pubkey: PublicKey,
}
-impl Invoice {
+impl Bolt12Invoice {
/// A complete description of the purpose of the originating offer or refund. Intended to be
/// displayed to the user but with the caveat that it has not been verified in any way.
pub fn description(&self) -> PrintableString {
/// needed for routing payments across them.
///
/// Blinded paths provide recipient privacy by obfuscating its node id. Note, however, that this
- /// privacy is lost if a public node id is used for [`Invoice::signing_pubkey`].
- pub fn payment_paths(&self) -> &[(BlindedPath, BlindedPayInfo)] {
+ /// privacy is lost if a public node id is used for [`Bolt12Invoice::signing_pubkey`].
+ pub fn payment_paths(&self) -> &[(BlindedPayInfo, BlindedPath)] {
&self.contents.fields().payment_paths[..]
}
self.contents.fields().created_at
}
- /// Duration since [`Invoice::created_at`] when the invoice has expired and therefore should no
- /// longer be paid.
+ /// Duration since [`Bolt12Invoice::created_at`] when the invoice has expired and therefore
+ /// should no longer be paid.
pub fn relative_expiry(&self) -> Duration {
self.contents.fields().relative_expiry.unwrap_or(DEFAULT_RELATIVE_EXPIRY)
}
self.contents.fields().signing_pubkey
}
- /// Signature of the invoice verified using [`Invoice::signing_pubkey`].
+ /// Signature of the invoice verified using [`Bolt12Invoice::signing_pubkey`].
pub fn signature(&self) -> Signature {
self.signature
}
};
InvoiceTlvStreamRef {
- paths: Some(Iterable(self.payment_paths.iter().map(|(path, _)| path))),
- blindedpay: Some(Iterable(self.payment_paths.iter().map(|(_, payinfo)| payinfo))),
+ paths: Some(Iterable(self.payment_paths.iter().map(|(_, path)| path))),
+ blindedpay: Some(Iterable(self.payment_paths.iter().map(|(payinfo, _)| payinfo))),
created_at: Some(self.created_at.as_secs()),
relative_expiry: self.relative_expiry.map(|duration| duration.as_secs() as u32),
payment_hash: Some(&self.payment_hash),
}
}
-impl Writeable for Invoice {
+impl Writeable for Bolt12Invoice {
fn write<W: Writer>(&self, writer: &mut W) -> Result<(), io::Error> {
WithoutLength(&self.bytes).write(writer)
}
}
}
-impl TryFrom<Vec<u8>> for Invoice {
- type Error = ParseError;
+impl TryFrom<Vec<u8>> for Bolt12Invoice {
+ type Error = Bolt12ParseError;
fn try_from(bytes: Vec<u8>) -> Result<Self, Self::Error> {
let parsed_invoice = ParsedMessage::<FullInvoiceTlvStream>::try_from(bytes)?;
- Invoice::try_from(parsed_invoice)
+ Bolt12Invoice::try_from(parsed_invoice)
}
}
});
type BlindedPathIter<'a> = core::iter::Map<
- core::slice::Iter<'a, (BlindedPath, BlindedPayInfo)>,
- for<'r> fn(&'r (BlindedPath, BlindedPayInfo)) -> &'r BlindedPath,
+ core::slice::Iter<'a, (BlindedPayInfo, BlindedPath)>,
+ for<'r> fn(&'r (BlindedPayInfo, BlindedPath)) -> &'r BlindedPath,
>;
type BlindedPayInfoIter<'a> = core::iter::Map<
- core::slice::Iter<'a, (BlindedPath, BlindedPayInfo)>,
- for<'r> fn(&'r (BlindedPath, BlindedPayInfo)) -> &'r BlindedPayInfo,
+ core::slice::Iter<'a, (BlindedPayInfo, BlindedPath)>,
+ for<'r> fn(&'r (BlindedPayInfo, BlindedPath)) -> &'r BlindedPayInfo,
>;
/// Information needed to route a payment across a [`BlindedPath`].
InvoiceTlvStreamRef<'a>,
);
-impl TryFrom<ParsedMessage<FullInvoiceTlvStream>> for Invoice {
- type Error = ParseError;
+impl TryFrom<ParsedMessage<FullInvoiceTlvStream>> for Bolt12Invoice {
+ type Error = Bolt12ParseError;
fn try_from(invoice: ParsedMessage<FullInvoiceTlvStream>) -> Result<Self, Self::Error> {
let ParsedMessage { bytes, tlv_stream } = invoice;
)?;
let signature = match signature {
- None => return Err(ParseError::InvalidSemantics(SemanticError::MissingSignature)),
+ None => return Err(Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::MissingSignature)),
Some(signature) => signature,
};
let pubkey = contents.fields().signing_pubkey;
merkle::verify_signature(&signature, SIGNATURE_TAG, &bytes, pubkey)?;
- Ok(Invoice { bytes, contents, signature })
+ Ok(Bolt12Invoice { bytes, contents, signature })
}
}
impl TryFrom<PartialInvoiceTlvStream> for InvoiceContents {
- type Error = SemanticError;
+ type Error = Bolt12SemanticError;
fn try_from(tlv_stream: PartialInvoiceTlvStream) -> Result<Self, Self::Error> {
let (
},
) = tlv_stream;
- let payment_paths = match (paths, blindedpay) {
- (None, _) => return Err(SemanticError::MissingPaths),
- (_, None) => return Err(SemanticError::InvalidPayInfo),
- (Some(paths), _) if paths.is_empty() => return Err(SemanticError::MissingPaths),
- (Some(paths), Some(blindedpay)) if paths.len() != blindedpay.len() => {
- return Err(SemanticError::InvalidPayInfo);
+ let payment_paths = match (blindedpay, paths) {
+ (_, None) => return Err(Bolt12SemanticError::MissingPaths),
+ (None, _) => return Err(Bolt12SemanticError::InvalidPayInfo),
+ (_, Some(paths)) if paths.is_empty() => return Err(Bolt12SemanticError::MissingPaths),
+ (Some(blindedpay), Some(paths)) if paths.len() != blindedpay.len() => {
+ return Err(Bolt12SemanticError::InvalidPayInfo);
},
- (Some(paths), Some(blindedpay)) => {
- paths.into_iter().zip(blindedpay.into_iter()).collect::<Vec<_>>()
+ (Some(blindedpay), Some(paths)) => {
+ blindedpay.into_iter().zip(paths.into_iter()).collect::<Vec<_>>()
},
};
let created_at = match created_at {
- None => return Err(SemanticError::MissingCreationTime),
+ None => return Err(Bolt12SemanticError::MissingCreationTime),
Some(timestamp) => Duration::from_secs(timestamp),
};
.map(Duration::from_secs);
let payment_hash = match payment_hash {
- None => return Err(SemanticError::MissingPaymentHash),
+ None => return Err(Bolt12SemanticError::MissingPaymentHash),
Some(payment_hash) => payment_hash,
};
let amount_msats = match amount {
- None => return Err(SemanticError::MissingAmount),
+ None => return Err(Bolt12SemanticError::MissingAmount),
Some(amount) => amount,
};
let features = features.unwrap_or_else(Bolt12InvoiceFeatures::empty);
let signing_pubkey = match node_id {
- None => return Err(SemanticError::MissingSigningPubkey),
+ None => return Err(Bolt12SemanticError::MissingSigningPubkey),
Some(node_id) => node_id,
};
match offer_tlv_stream.node_id {
Some(expected_signing_pubkey) => {
if fields.signing_pubkey != expected_signing_pubkey {
- return Err(SemanticError::InvalidSigningPubkey);
+ return Err(Bolt12SemanticError::InvalidSigningPubkey);
}
let invoice_request = InvoiceRequestContents::try_from(
#[cfg(test)]
mod tests {
- use super::{DEFAULT_RELATIVE_EXPIRY, FallbackAddress, FullInvoiceTlvStreamRef, Invoice, InvoiceTlvStreamRef, SIGNATURE_TAG};
+ use super::{Bolt12Invoice, DEFAULT_RELATIVE_EXPIRY, FallbackAddress, FullInvoiceTlvStreamRef, InvoiceTlvStreamRef, SIGNATURE_TAG};
use bitcoin::blockdata::script::Script;
use bitcoin::hashes::Hash;
use crate::offers::invoice_request::InvoiceRequestTlvStreamRef;
use crate::offers::merkle::{SignError, SignatureTlvStreamRef, self};
use crate::offers::offer::{OfferBuilder, OfferTlvStreamRef, Quantity};
- use crate::offers::parse::{ParseError, SemanticError};
+ use crate::offers::parse::{Bolt12ParseError, Bolt12SemanticError};
use crate::offers::payer::PayerTlvStreamRef;
use crate::offers::refund::RefundBuilder;
use crate::offers::test_utils::*;
payer_note: None,
},
InvoiceTlvStreamRef {
- paths: Some(Iterable(payment_paths.iter().map(|(path, _)| path))),
- blindedpay: Some(Iterable(payment_paths.iter().map(|(_, payinfo)| payinfo))),
+ paths: Some(Iterable(payment_paths.iter().map(|(_, path)| path))),
+ blindedpay: Some(Iterable(payment_paths.iter().map(|(payinfo, _)| payinfo))),
created_at: Some(now.as_secs()),
relative_expiry: None,
payment_hash: Some(&payment_hash),
),
);
- if let Err(e) = Invoice::try_from(buffer) {
+ if let Err(e) = Bolt12Invoice::try_from(buffer) {
panic!("error parsing invoice: {:?}", e);
}
}
payer_note: None,
},
InvoiceTlvStreamRef {
- paths: Some(Iterable(payment_paths.iter().map(|(path, _)| path))),
- blindedpay: Some(Iterable(payment_paths.iter().map(|(_, payinfo)| payinfo))),
+ paths: Some(Iterable(payment_paths.iter().map(|(_, path)| path))),
+ blindedpay: Some(Iterable(payment_paths.iter().map(|(payinfo, _)| payinfo))),
created_at: Some(now.as_secs()),
relative_expiry: None,
payment_hash: Some(&payment_hash),
),
);
- if let Err(e) = Invoice::try_from(buffer) {
+ if let Err(e) = Bolt12Invoice::try_from(buffer) {
panic!("error parsing invoice: {:?}", e);
}
}
.build()
{
Ok(_) => panic!("expected error"),
- Err(e) => assert_eq!(e, SemanticError::AlreadyExpired),
+ Err(e) => assert_eq!(e, Bolt12SemanticError::AlreadyExpired),
}
}
.build()
{
Ok(_) => panic!("expected error"),
- Err(e) => assert_eq!(e, SemanticError::AlreadyExpired),
+ Err(e) => assert_eq!(e, Bolt12SemanticError::AlreadyExpired),
}
}
payment_paths(), payment_hash(), now(), &expanded_key, &secp_ctx
) {
Ok(_) => panic!("expected error"),
- Err(e) => assert_eq!(e, SemanticError::InvalidMetadata),
+ Err(e) => assert_eq!(e, Bolt12SemanticError::InvalidMetadata),
}
let desc = "foo".to_string();
payment_paths(), payment_hash(), now(), &expanded_key, &secp_ctx
) {
Ok(_) => panic!("expected error"),
- Err(e) => assert_eq!(e, SemanticError::InvalidMetadata),
+ Err(e) => assert_eq!(e, Bolt12SemanticError::InvalidMetadata),
}
}
.respond_with_no_std(payment_paths(), payment_hash(), now())
{
Ok(_) => panic!("expected error"),
- Err(e) => assert_eq!(e, SemanticError::InvalidAmount),
+ Err(e) => assert_eq!(e, Bolt12SemanticError::InvalidAmount),
}
}
let mut buffer = Vec::new();
invoice.write(&mut buffer).unwrap();
- if let Err(e) = Invoice::try_from(buffer) {
+ if let Err(e) = Bolt12Invoice::try_from(buffer) {
panic!("error parsing invoice: {:?}", e);
}
let mut tlv_stream = invoice.as_tlv_stream();
tlv_stream.3.paths = None;
- match Invoice::try_from(tlv_stream.to_bytes()) {
+ match Bolt12Invoice::try_from(tlv_stream.to_bytes()) {
Ok(_) => panic!("expected error"),
- Err(e) => assert_eq!(e, ParseError::InvalidSemantics(SemanticError::MissingPaths)),
+ Err(e) => assert_eq!(e, Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::MissingPaths)),
}
let mut tlv_stream = invoice.as_tlv_stream();
tlv_stream.3.blindedpay = None;
- match Invoice::try_from(tlv_stream.to_bytes()) {
+ match Bolt12Invoice::try_from(tlv_stream.to_bytes()) {
Ok(_) => panic!("expected error"),
- Err(e) => assert_eq!(e, ParseError::InvalidSemantics(SemanticError::InvalidPayInfo)),
+ Err(e) => assert_eq!(e, Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::InvalidPayInfo)),
}
let empty_payment_paths = vec![];
let mut tlv_stream = invoice.as_tlv_stream();
- tlv_stream.3.paths = Some(Iterable(empty_payment_paths.iter().map(|(path, _)| path)));
+ tlv_stream.3.paths = Some(Iterable(empty_payment_paths.iter().map(|(_, path)| path)));
- match Invoice::try_from(tlv_stream.to_bytes()) {
+ match Bolt12Invoice::try_from(tlv_stream.to_bytes()) {
Ok(_) => panic!("expected error"),
- Err(e) => assert_eq!(e, ParseError::InvalidSemantics(SemanticError::MissingPaths)),
+ Err(e) => assert_eq!(e, Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::MissingPaths)),
}
let mut payment_paths = payment_paths();
payment_paths.pop();
let mut tlv_stream = invoice.as_tlv_stream();
- tlv_stream.3.blindedpay = Some(Iterable(payment_paths.iter().map(|(_, payinfo)| payinfo)));
+ tlv_stream.3.blindedpay = Some(Iterable(payment_paths.iter().map(|(payinfo, _)| payinfo)));
- match Invoice::try_from(tlv_stream.to_bytes()) {
+ match Bolt12Invoice::try_from(tlv_stream.to_bytes()) {
Ok(_) => panic!("expected error"),
- Err(e) => assert_eq!(e, ParseError::InvalidSemantics(SemanticError::InvalidPayInfo)),
+ Err(e) => assert_eq!(e, Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::InvalidPayInfo)),
}
}
let mut buffer = Vec::new();
invoice.write(&mut buffer).unwrap();
- if let Err(e) = Invoice::try_from(buffer) {
+ if let Err(e) = Bolt12Invoice::try_from(buffer) {
panic!("error parsing invoice: {:?}", e);
}
let mut tlv_stream = invoice.as_tlv_stream();
tlv_stream.3.created_at = None;
- match Invoice::try_from(tlv_stream.to_bytes()) {
+ match Bolt12Invoice::try_from(tlv_stream.to_bytes()) {
Ok(_) => panic!("expected error"),
Err(e) => {
- assert_eq!(e, ParseError::InvalidSemantics(SemanticError::MissingCreationTime));
+ assert_eq!(e, Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::MissingCreationTime));
},
}
}
let mut buffer = Vec::new();
invoice.write(&mut buffer).unwrap();
- match Invoice::try_from(buffer) {
+ match Bolt12Invoice::try_from(buffer) {
Ok(invoice) => assert_eq!(invoice.relative_expiry(), Duration::from_secs(3600)),
Err(e) => panic!("error parsing invoice: {:?}", e),
}
let mut buffer = Vec::new();
invoice.write(&mut buffer).unwrap();
- if let Err(e) = Invoice::try_from(buffer) {
+ if let Err(e) = Bolt12Invoice::try_from(buffer) {
panic!("error parsing invoice: {:?}", e);
}
let mut tlv_stream = invoice.as_tlv_stream();
tlv_stream.3.payment_hash = None;
- match Invoice::try_from(tlv_stream.to_bytes()) {
+ match Bolt12Invoice::try_from(tlv_stream.to_bytes()) {
Ok(_) => panic!("expected error"),
Err(e) => {
- assert_eq!(e, ParseError::InvalidSemantics(SemanticError::MissingPaymentHash));
+ assert_eq!(e, Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::MissingPaymentHash));
},
}
}
let mut buffer = Vec::new();
invoice.write(&mut buffer).unwrap();
- if let Err(e) = Invoice::try_from(buffer) {
+ if let Err(e) = Bolt12Invoice::try_from(buffer) {
panic!("error parsing invoice: {:?}", e);
}
let mut tlv_stream = invoice.as_tlv_stream();
tlv_stream.3.amount = None;
- match Invoice::try_from(tlv_stream.to_bytes()) {
+ match Bolt12Invoice::try_from(tlv_stream.to_bytes()) {
Ok(_) => panic!("expected error"),
- Err(e) => assert_eq!(e, ParseError::InvalidSemantics(SemanticError::MissingAmount)),
+ Err(e) => assert_eq!(e, Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::MissingAmount)),
}
}
let mut buffer = Vec::new();
invoice.write(&mut buffer).unwrap();
- match Invoice::try_from(buffer) {
+ match Bolt12Invoice::try_from(buffer) {
Ok(invoice) => {
let mut features = Bolt12InvoiceFeatures::empty();
features.set_basic_mpp_optional();
let mut buffer = Vec::new();
invoice.write(&mut buffer).unwrap();
- match Invoice::try_from(buffer) {
+ match Bolt12Invoice::try_from(buffer) {
Ok(invoice) => {
assert_eq!(
invoice.fallbacks(),
let mut buffer = Vec::new();
invoice.write(&mut buffer).unwrap();
- if let Err(e) = Invoice::try_from(buffer) {
+ if let Err(e) = Bolt12Invoice::try_from(buffer) {
panic!("error parsing invoice: {:?}", e);
}
let mut tlv_stream = invoice.as_tlv_stream();
tlv_stream.3.node_id = None;
- match Invoice::try_from(tlv_stream.to_bytes()) {
+ match Bolt12Invoice::try_from(tlv_stream.to_bytes()) {
Ok(_) => panic!("expected error"),
Err(e) => {
- assert_eq!(e, ParseError::InvalidSemantics(SemanticError::MissingSigningPubkey));
+ assert_eq!(e, Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::MissingSigningPubkey));
},
}
let mut tlv_stream = invoice.as_tlv_stream();
tlv_stream.3.node_id = Some(&invalid_pubkey);
- match Invoice::try_from(tlv_stream.to_bytes()) {
+ match Bolt12Invoice::try_from(tlv_stream.to_bytes()) {
Ok(_) => panic!("expected error"),
Err(e) => {
- assert_eq!(e, ParseError::InvalidSemantics(SemanticError::InvalidSigningPubkey));
+ assert_eq!(e, Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::InvalidSigningPubkey));
},
}
}
.invoice
.write(&mut buffer).unwrap();
- match Invoice::try_from(buffer) {
+ match Bolt12Invoice::try_from(buffer) {
Ok(_) => panic!("expected error"),
- Err(e) => assert_eq!(e, ParseError::InvalidSemantics(SemanticError::MissingSignature)),
+ Err(e) => assert_eq!(e, Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::MissingSignature)),
}
}
let mut buffer = Vec::new();
invoice.write(&mut buffer).unwrap();
- match Invoice::try_from(buffer) {
+ match Bolt12Invoice::try_from(buffer) {
Ok(_) => panic!("expected error"),
Err(e) => {
- assert_eq!(e, ParseError::InvalidSignature(secp256k1::Error::InvalidSignature));
+ assert_eq!(e, Bolt12ParseError::InvalidSignature(secp256k1::Error::InvalidSignature));
},
}
}
BigSize(32).write(&mut encoded_invoice).unwrap();
[42u8; 32].write(&mut encoded_invoice).unwrap();
- match Invoice::try_from(encoded_invoice) {
+ match Bolt12Invoice::try_from(encoded_invoice) {
Ok(_) => panic!("expected error"),
- Err(e) => assert_eq!(e, ParseError::Decode(DecodeError::InvalidValue)),
+ Err(e) => assert_eq!(e, Bolt12ParseError::Decode(DecodeError::InvalidValue)),
}
}
}