X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning%2Fsrc%2Foffers%2Foffer.rs;h=f6aa354b9e4f3d6c9efd2aee4ac47a04c8741dc0;hb=3dffe54258a374d15571d4ec72f5faa02477b770;hp=d801be9d26fb969c0b89af9b84a5e7408726efea;hpb=7a63ab77da7e0be35b1c5d87643e5461cd593b94;p=rust-lightning diff --git a/lightning/src/offers/offer.rs b/lightning/src/offers/offer.rs index d801be9d..f6aa354b 100644 --- a/lightning/src/offers/offer.rs +++ b/lightning/src/offers/offer.rs @@ -358,77 +358,86 @@ pub(super) struct OfferContents { signing_pubkey: PublicKey, } -impl Offer { +macro_rules! offer_accessors { ($self: ident, $contents: expr) => { // TODO: Return a slice once ChainHash has constants. // - https://github.com/rust-bitcoin/rust-bitcoin/pull/1283 // - https://github.com/rust-bitcoin/rust-bitcoin/pull/1286 /// The chains that may be used when paying a requested invoice (e.g., bitcoin mainnet). /// Payments must be denominated in units of the minimal lightning-payable unit (e.g., msats) /// for the selected chain. - pub fn chains(&self) -> Vec { - self.contents.chains() - } - - pub(super) fn implied_chain(&self) -> ChainHash { - self.contents.implied_chain() - } - - /// Returns whether the given chain is supported by the offer. - pub fn supports_chain(&self, chain: ChainHash) -> bool { - self.contents.supports_chain(chain) + pub fn chains(&$self) -> Vec<$crate::bitcoin::blockdata::constants::ChainHash> { + $contents.chains() } // TODO: Link to corresponding method in `InvoiceRequest`. /// Opaque bytes set by the originator. Useful for authentication and validating fields since it /// is reflected in `invoice_request` messages along with all the other fields from the `offer`. - pub fn metadata(&self) -> Option<&Vec> { - self.contents.metadata() + pub fn metadata(&$self) -> Option<&Vec> { + $contents.metadata() } /// The minimum amount required for a successful payment of a single item. - pub fn amount(&self) -> Option<&Amount> { - self.contents.amount() + pub fn amount(&$self) -> Option<&$crate::offers::offer::Amount> { + $contents.amount() } /// A complete description of the purpose of the payment. 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 { - self.contents.description() + pub fn description(&$self) -> $crate::util::string::PrintableString { + $contents.description() } /// Features pertaining to the offer. - pub fn features(&self) -> &OfferFeatures { - &self.contents.features + pub fn offer_features(&$self) -> &$crate::ln::features::OfferFeatures { + &$contents.features() } /// Duration since the Unix epoch when an invoice should no longer be requested. /// /// If `None`, the offer does not expire. - pub fn absolute_expiry(&self) -> Option { - self.contents.absolute_expiry - } - - /// Whether the offer has expired. - #[cfg(feature = "std")] - pub fn is_expired(&self) -> bool { - self.contents.is_expired() + pub fn absolute_expiry(&$self) -> Option { + $contents.absolute_expiry() } /// The issuer of the offer, possibly beginning with `user@domain` or `domain`. Intended to be /// displayed to the user but with the caveat that it has not been verified in any way. - pub fn issuer(&self) -> Option { - self.contents.issuer.as_ref().map(|issuer| PrintableString(issuer.as_str())) + pub fn issuer(&$self) -> Option<$crate::util::string::PrintableString> { + $contents.issuer() } /// Paths to the recipient originating from publicly reachable nodes. Blinded paths provide /// recipient privacy by obfuscating its node id. - pub fn paths(&self) -> &[BlindedPath] { - self.contents.paths.as_ref().map(|paths| paths.as_slice()).unwrap_or(&[]) + pub fn paths(&$self) -> &[$crate::blinded_path::BlindedPath] { + $contents.paths() } /// The quantity of items supported. - pub fn supported_quantity(&self) -> Quantity { - self.contents.supported_quantity() + pub fn supported_quantity(&$self) -> $crate::offers::offer::Quantity { + $contents.supported_quantity() + } + + /// The public key used by the recipient to sign invoices. + pub fn signing_pubkey(&$self) -> $crate::bitcoin::secp256k1::PublicKey { + $contents.signing_pubkey() + } +} } + +impl Offer { + offer_accessors!(self, self.contents); + + pub(super) fn implied_chain(&self) -> ChainHash { + self.contents.implied_chain() + } + + /// Returns whether the given chain is supported by the offer. + pub fn supports_chain(&self, chain: ChainHash) -> bool { + self.contents.supports_chain(chain) + } + + /// Whether the offer has expired. + #[cfg(feature = "std")] + pub fn is_expired(&self) -> bool { + self.contents.is_expired() } /// Returns whether the given quantity is valid for the offer. @@ -443,24 +452,19 @@ impl Offer { self.contents.expects_quantity() } - /// The public key used by the recipient to sign invoices. - pub fn signing_pubkey(&self) -> PublicKey { - self.contents.signing_pubkey() - } - /// Similar to [`Offer::request_invoice`] except it: /// - derives the [`InvoiceRequest::payer_id`] such that a different key can be used for each /// request, and - /// - sets the [`InvoiceRequest::metadata`] when [`InvoiceRequestBuilder::build`] is called such - /// that it can be used by [`Bolt12Invoice::verify`] to determine if the invoice was requested - /// using a base [`ExpandedKey`] from which the payer id was derived. + /// - sets the [`InvoiceRequest::payer_metadata`] when [`InvoiceRequestBuilder::build`] is + /// called such that it can be used by [`Bolt12Invoice::verify`] to determine if the invoice + /// was requested using a base [`ExpandedKey`] from which the payer id was derived. /// /// Useful to protect the sender's privacy. /// /// This is not exported to bindings users as builder patterns don't map outside of move semantics. /// /// [`InvoiceRequest::payer_id`]: crate::offers::invoice_request::InvoiceRequest::payer_id - /// [`InvoiceRequest::metadata`]: crate::offers::invoice_request::InvoiceRequest::metadata + /// [`InvoiceRequest::payer_metadata`]: crate::offers::invoice_request::InvoiceRequest::payer_metadata /// [`Bolt12Invoice::verify`]: crate::offers::invoice::Bolt12Invoice::verify /// [`ExpandedKey`]: crate::ln::inbound_payment::ExpandedKey pub fn request_invoice_deriving_payer_id<'a, 'b, ES: Deref, T: secp256k1::Signing>( @@ -469,7 +473,7 @@ impl Offer { where ES::Target: EntropySource, { - if self.features().requires_unknown_bits() { + if self.offer_features().requires_unknown_bits() { return Err(Bolt12SemanticError::UnknownRequiredFeatures); } @@ -490,7 +494,7 @@ impl Offer { where ES::Target: EntropySource, { - if self.features().requires_unknown_bits() { + if self.offer_features().requires_unknown_bits() { return Err(Bolt12SemanticError::UnknownRequiredFeatures); } @@ -515,7 +519,7 @@ impl Offer { pub fn request_invoice( &self, metadata: Vec, payer_id: PublicKey ) -> Result, Bolt12SemanticError> { - if self.features().requires_unknown_bits() { + if self.offer_features().requires_unknown_bits() { return Err(Bolt12SemanticError::UnknownRequiredFeatures); } @@ -551,10 +555,22 @@ impl OfferContents { self.metadata.as_ref().and_then(|metadata| metadata.as_bytes()) } + pub fn amount(&self) -> Option<&Amount> { + self.amount.as_ref() + } + pub fn description(&self) -> PrintableString { PrintableString(&self.description) } + pub fn features(&self) -> &OfferFeatures { + &self.features + } + + pub fn absolute_expiry(&self) -> Option { + self.absolute_expiry + } + #[cfg(feature = "std")] pub(super) fn is_expired(&self) -> bool { match self.absolute_expiry { @@ -566,8 +582,12 @@ impl OfferContents { } } - pub fn amount(&self) -> Option<&Amount> { - self.amount.as_ref() + pub fn issuer(&self) -> Option { + self.issuer.as_ref().map(|issuer| PrintableString(issuer.as_str())) + } + + pub fn paths(&self) -> &[BlindedPath] { + self.paths.as_ref().map(|paths| paths.as_slice()).unwrap_or(&[]) } pub(super) fn check_amount_msats_for_quantity( @@ -874,7 +894,7 @@ mod tests { assert_eq!(offer.metadata(), None); assert_eq!(offer.amount(), None); assert_eq!(offer.description(), PrintableString("foo")); - assert_eq!(offer.features(), &OfferFeatures::empty()); + assert_eq!(offer.offer_features(), &OfferFeatures::empty()); assert_eq!(offer.absolute_expiry(), None); #[cfg(feature = "std")] assert!(!offer.is_expired()); @@ -1115,7 +1135,7 @@ mod tests { .features_unchecked(OfferFeatures::unknown()) .build() .unwrap(); - assert_eq!(offer.features(), &OfferFeatures::unknown()); + assert_eq!(offer.offer_features(), &OfferFeatures::unknown()); assert_eq!(offer.as_tlv_stream().features, Some(&OfferFeatures::unknown())); let offer = OfferBuilder::new("foo".into(), pubkey(42)) @@ -1123,7 +1143,7 @@ mod tests { .features_unchecked(OfferFeatures::empty()) .build() .unwrap(); - assert_eq!(offer.features(), &OfferFeatures::empty()); + assert_eq!(offer.offer_features(), &OfferFeatures::empty()); assert_eq!(offer.as_tlv_stream().features, None); }