X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning%2Fsrc%2Foffers%2Frefund.rs;h=1aa36167b94a14a81af7134da8e7a4630f8d5e97;hb=93afed56e8befba47199c19b4ca8263164eca36f;hp=582c5b7eb187560d02b1ee0f0c6af3fdef1e8263;hpb=259aa9aac37097c462a25cc39e83ebe2b86ac4bb;p=rust-lightning diff --git a/lightning/src/offers/refund.rs b/lightning/src/offers/refund.rs index 582c5b7e..1aa36167 100644 --- a/lightning/src/offers/refund.rs +++ b/lightning/src/offers/refund.rs @@ -32,7 +32,7 @@ //! use lightning::offers::refund::{Refund, RefundBuilder}; //! use lightning::util::ser::{Readable, Writeable}; //! -//! # use lightning::onion_message::BlindedPath; +//! # use lightning::blinded_path::BlindedPath; //! # #[cfg(feature = "std")] //! # use std::time::SystemTime; //! # @@ -80,17 +80,17 @@ use core::str::FromStr; use core::time::Duration; use crate::chain::keysinterface::EntropySource; use crate::io; +use crate::blinded_path::BlindedPath; use crate::ln::PaymentHash; use crate::ln::features::InvoiceRequestFeatures; use crate::ln::inbound_payment::{ExpandedKey, IV_LEN, Nonce}; use crate::ln::msgs::{DecodeError, MAX_VALUE_MSAT}; -use crate::offers::invoice::{BlindedPayInfo, InvoiceBuilder}; +use crate::offers::invoice::{BlindedPayInfo, DerivedSigningPubkey, ExplicitSigningPubkey, InvoiceBuilder}; use crate::offers::invoice_request::{InvoiceRequestTlvStream, InvoiceRequestTlvStreamRef}; use crate::offers::offer::{OfferTlvStream, OfferTlvStreamRef}; use crate::offers::parse::{Bech32Encode, ParseError, ParsedMessage, SemanticError}; use crate::offers::payer::{PayerContents, PayerTlvStream, PayerTlvStreamRef}; -use crate::offers::signer::{Metadata, MetadataMaterial}; -use crate::onion_message::BlindedPath; +use crate::offers::signer::{Metadata, MetadataMaterial, self}; use crate::util::ser::{SeekReadable, WithoutLength, Writeable, Writer}; use crate::util::string::PrintableString; @@ -392,7 +392,7 @@ impl Refund { pub fn respond_with( &self, payment_paths: Vec<(BlindedPath, BlindedPayInfo)>, payment_hash: PaymentHash, signing_pubkey: PublicKey, - ) -> Result { + ) -> Result, SemanticError> { let created_at = std::time::SystemTime::now() .duration_since(std::time::SystemTime::UNIX_EPOCH) .expect("SystemTime::now() should come after SystemTime::UNIX_EPOCH"); @@ -423,7 +423,7 @@ impl Refund { pub fn respond_with_no_std( &self, payment_paths: Vec<(BlindedPath, BlindedPayInfo)>, payment_hash: PaymentHash, signing_pubkey: PublicKey, created_at: Duration - ) -> Result { + ) -> Result, SemanticError> { if self.features().requires_unknown_bits() { return Err(SemanticError::UnknownRequiredFeatures); } @@ -431,6 +431,51 @@ impl Refund { InvoiceBuilder::for_refund(self, payment_paths, created_at, payment_hash, signing_pubkey) } + /// Creates an [`InvoiceBuilder`] for the refund using the given required fields and that uses + /// derived signing keys to sign the [`Invoice`]. + /// + /// See [`Refund::respond_with`] for further details. + /// + /// [`Invoice`]: crate::offers::invoice::Invoice + #[cfg(feature = "std")] + pub fn respond_using_derived_keys( + &self, payment_paths: Vec<(BlindedPath, BlindedPayInfo)>, payment_hash: PaymentHash, + expanded_key: &ExpandedKey, entropy_source: ES + ) -> Result, SemanticError> + where + ES::Target: EntropySource, + { + let created_at = std::time::SystemTime::now() + .duration_since(std::time::SystemTime::UNIX_EPOCH) + .expect("SystemTime::now() should come after SystemTime::UNIX_EPOCH"); + + self.respond_using_derived_keys_no_std( + payment_paths, payment_hash, created_at, expanded_key, entropy_source + ) + } + + /// Creates an [`InvoiceBuilder`] for the refund using the given required fields and that uses + /// derived signing keys to sign the [`Invoice`]. + /// + /// See [`Refund::respond_with_no_std`] for further details. + /// + /// [`Invoice`]: crate::offers::invoice::Invoice + pub fn respond_using_derived_keys_no_std( + &self, payment_paths: Vec<(BlindedPath, BlindedPayInfo)>, payment_hash: PaymentHash, + created_at: core::time::Duration, expanded_key: &ExpandedKey, entropy_source: ES + ) -> Result, SemanticError> + where + ES::Target: EntropySource, + { + if self.features().requires_unknown_bits() { + return Err(SemanticError::UnknownRequiredFeatures); + } + + let nonce = Nonce::from_entropy_source(entropy_source); + let keys = signer::derive_keys(nonce, expanded_key); + InvoiceBuilder::for_refund_using_keys(self, payment_paths, created_at, payment_hash, keys) + } + #[cfg(test)] fn as_tlv_stream(&self) -> RefundTlvStreamRef { self.contents.as_tlv_stream() @@ -652,6 +697,7 @@ mod tests { use bitcoin::secp256k1::{KeyPair, Secp256k1, SecretKey}; use core::convert::TryFrom; use core::time::Duration; + use crate::blinded_path::{BlindedHop, BlindedPath}; use crate::chain::keysinterface::KeyMaterial; use crate::ln::features::{InvoiceRequestFeatures, OfferFeatures}; use crate::ln::inbound_payment::ExpandedKey; @@ -661,7 +707,6 @@ mod tests { use crate::offers::parse::{ParseError, SemanticError}; use crate::offers::payer::PayerTlvStreamRef; use crate::offers::test_utils::*; - use crate::onion_message::{BlindedHop, BlindedPath}; use crate::util::ser::{BigSize, Writeable}; use crate::util::string::PrintableString;