+ pub fn is_expired(&$self) -> bool {
+ $contents.is_expired()
+ }
+
+ /// SHA256 hash of the payment preimage that will be given in return for paying the invoice.
+ pub fn payment_hash(&$self) -> PaymentHash {
+ $contents.payment_hash()
+ }
+
+ /// The minimum amount required for a successful payment of the invoice.
+ pub fn amount_msats(&$self) -> u64 {
+ $contents.amount_msats()
+ }
+
+ /// Fallback addresses for paying the invoice on-chain, in order of most-preferred to
+ /// least-preferred.
+ pub fn fallbacks(&$self) -> Vec<Address> {
+ $contents.fallbacks()
+ }
+
+ /// Features pertaining to paying an invoice.
+ pub fn invoice_features(&$self) -> &Bolt12InvoiceFeatures {
+ $contents.features()
+ }
+
+ /// The public key corresponding to the key used to sign the invoice.
+ pub fn signing_pubkey(&$self) -> PublicKey {
+ $contents.signing_pubkey()
+ }
+} }
+
+impl UnsignedBolt12Invoice {
+ invoice_accessors!(self, self.contents);
+}
+
+impl Bolt12Invoice {
+ invoice_accessors!(self, self.contents);
+
+ /// Signature of the invoice verified using [`Bolt12Invoice::signing_pubkey`].
+ pub fn signature(&self) -> Signature {
+ self.signature
+ }
+
+ /// Hash that was used for signing the invoice.
+ pub fn signable_hash(&self) -> [u8; 32] {
+ merkle::message_digest(SIGNATURE_TAG, &self.bytes).as_ref().clone()
+ }
+
+ /// Verifies that the invoice was for a request or refund created using the given key. Returns
+ /// the associated [`PaymentId`] to use when sending the payment.
+ pub fn verify<T: secp256k1::Signing>(
+ &self, key: &ExpandedKey, secp_ctx: &Secp256k1<T>
+ ) -> Result<PaymentId, ()> {
+ self.contents.verify(TlvStream::new(&self.bytes), key, secp_ctx)
+ }
+
+ #[cfg(test)]
+ pub(super) fn as_tlv_stream(&self) -> FullInvoiceTlvStreamRef {
+ let (payer_tlv_stream, offer_tlv_stream, invoice_request_tlv_stream, invoice_tlv_stream) =
+ self.contents.as_tlv_stream();
+ let signature_tlv_stream = SignatureTlvStreamRef {
+ signature: Some(&self.signature),
+ };
+ (payer_tlv_stream, offer_tlv_stream, invoice_request_tlv_stream, invoice_tlv_stream,
+ signature_tlv_stream)
+ }
+}
+
+impl InvoiceContents {
+ /// Whether the original offer or refund has expired.
+ #[cfg(feature = "std")]
+ fn is_offer_or_refund_expired(&self) -> bool {
+ match self {
+ InvoiceContents::ForOffer { invoice_request, .. } =>
+ invoice_request.inner.offer.is_expired(),
+ InvoiceContents::ForRefund { refund, .. } => refund.is_expired(),
+ }
+ }
+
+ fn offer_chains(&self) -> Option<Vec<ChainHash>> {
+ match self {
+ InvoiceContents::ForOffer { invoice_request, .. } =>
+ Some(invoice_request.inner.offer.chains()),
+ InvoiceContents::ForRefund { .. } => None,
+ }
+ }
+
+ fn chain(&self) -> ChainHash {
+ match self {
+ InvoiceContents::ForOffer { invoice_request, .. } => invoice_request.chain(),
+ InvoiceContents::ForRefund { refund, .. } => refund.chain(),
+ }
+ }
+
+ fn metadata(&self) -> Option<&Vec<u8>> {
+ match self {
+ InvoiceContents::ForOffer { invoice_request, .. } =>
+ invoice_request.inner.offer.metadata(),
+ InvoiceContents::ForRefund { .. } => None,
+ }
+ }
+
+ fn amount(&self) -> Option<&Amount> {
+ match self {
+ InvoiceContents::ForOffer { invoice_request, .. } =>
+ invoice_request.inner.offer.amount(),
+ InvoiceContents::ForRefund { .. } => None,
+ }
+ }
+
+ fn description(&self) -> PrintableString {
+ match self {
+ InvoiceContents::ForOffer { invoice_request, .. } => {
+ invoice_request.inner.offer.description()
+ },
+ InvoiceContents::ForRefund { refund, .. } => refund.description(),
+ }
+ }
+
+ fn offer_features(&self) -> Option<&OfferFeatures> {
+ match self {
+ InvoiceContents::ForOffer { invoice_request, .. } => {
+ Some(invoice_request.inner.offer.features())
+ },
+ InvoiceContents::ForRefund { .. } => None,
+ }
+ }
+
+ fn absolute_expiry(&self) -> Option<Duration> {
+ match self {
+ InvoiceContents::ForOffer { invoice_request, .. } => {
+ invoice_request.inner.offer.absolute_expiry()
+ },
+ InvoiceContents::ForRefund { refund, .. } => refund.absolute_expiry(),
+ }
+ }
+
+ fn issuer(&self) -> Option<PrintableString> {
+ match self {
+ InvoiceContents::ForOffer { invoice_request, .. } => {
+ invoice_request.inner.offer.issuer()
+ },
+ InvoiceContents::ForRefund { refund, .. } => refund.issuer(),
+ }
+ }
+
+ fn message_paths(&self) -> &[BlindedPath] {
+ match self {
+ InvoiceContents::ForOffer { invoice_request, .. } => {
+ invoice_request.inner.offer.paths()
+ },
+ InvoiceContents::ForRefund { refund, .. } => refund.paths(),
+ }
+ }
+
+ fn supported_quantity(&self) -> Option<Quantity> {
+ match self {
+ InvoiceContents::ForOffer { invoice_request, .. } => {
+ Some(invoice_request.inner.offer.supported_quantity())
+ },
+ InvoiceContents::ForRefund { .. } => None,
+ }
+ }
+
+ fn payer_metadata(&self) -> &[u8] {
+ match self {
+ InvoiceContents::ForOffer { invoice_request, .. } => invoice_request.metadata(),
+ InvoiceContents::ForRefund { refund, .. } => refund.metadata(),
+ }
+ }
+
+ fn invoice_request_features(&self) -> &InvoiceRequestFeatures {
+ match self {
+ InvoiceContents::ForOffer { invoice_request, .. } => invoice_request.features(),
+ InvoiceContents::ForRefund { refund, .. } => refund.features(),
+ }
+ }
+
+ fn quantity(&self) -> Option<u64> {
+ match self {
+ InvoiceContents::ForOffer { invoice_request, .. } => invoice_request.quantity(),
+ InvoiceContents::ForRefund { refund, .. } => refund.quantity(),
+ }
+ }
+
+ fn payer_id(&self) -> PublicKey {
+ match self {
+ InvoiceContents::ForOffer { invoice_request, .. } => invoice_request.payer_id(),
+ InvoiceContents::ForRefund { refund, .. } => refund.payer_id(),
+ }
+ }
+
+ fn payer_note(&self) -> Option<PrintableString> {
+ match self {
+ InvoiceContents::ForOffer { invoice_request, .. } => invoice_request.payer_note(),
+ InvoiceContents::ForRefund { refund, .. } => refund.payer_note(),
+ }
+ }
+
+ fn payment_paths(&self) -> &[(BlindedPayInfo, BlindedPath)] {
+ &self.fields().payment_paths[..]
+ }
+
+ fn created_at(&self) -> Duration {
+ self.fields().created_at
+ }
+
+ fn relative_expiry(&self) -> Duration {
+ self.fields().relative_expiry.unwrap_or(DEFAULT_RELATIVE_EXPIRY)
+ }
+
+ #[cfg(feature = "std")]
+ fn is_expired(&self) -> bool {