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;
use crate::onion_message::BlindedPath;
use crate::util::ser::{SeekReadable, WithoutLength, Writeable, Writer};
use crate::util::string::PrintableString;
return Err(SemanticError::InvalidAmount);
}
+ let metadata = Metadata::Bytes(metadata);
let refund = RefundContents {
payer: PayerContents(metadata), description, absolute_expiry: None, issuer: None,
paths: None, chain: None, amount_msats, features: InvoiceRequestFeatures::empty(),
///
/// [`Invoice`]: crate::offers::invoice::Invoice
/// [`Offer`]: crate::offers::offer::Offer
-#[derive(Clone, Debug, PartialEq)]
+#[derive(Clone, Debug)]
+#[cfg_attr(test, derive(PartialEq))]
pub struct Refund {
pub(super) bytes: Vec<u8>,
pub(super) contents: RefundContents,
/// The contents of a [`Refund`], which may be shared with an [`Invoice`].
///
/// [`Invoice`]: crate::offers::invoice::Invoice
-#[derive(Clone, Debug, PartialEq)]
+#[derive(Clone, Debug)]
+#[cfg_attr(test, derive(PartialEq))]
pub(super) struct RefundContents {
payer: PayerContents,
// offer fields
///
/// [`payer_id`]: Self::payer_id
pub fn metadata(&self) -> &[u8] {
- &self.contents.payer.0
+ &self.contents.payer.0.as_bytes().unwrap()[..]
}
/// A chain that the refund is valid for.
self.contents.payer_note.as_ref().map(|payer_note| PrintableString(payer_note.as_str()))
}
- /// Creates an [`Invoice`] for the refund with the given required fields and using the
+ /// Creates an [`InvoiceBuilder`] for the refund with the given required fields and using the
/// [`Duration`] since [`std::time::SystemTime::UNIX_EPOCH`] as the creation time.
///
/// See [`Refund::respond_with_no_std`] for further details where the aforementioned creation
/// time is used for the `created_at` parameter.
///
- /// [`Invoice`]: crate::offers::invoice::Invoice
/// [`Duration`]: core::time::Duration
#[cfg(feature = "std")]
pub fn respond_with(
self.respond_with_no_std(payment_paths, payment_hash, signing_pubkey, created_at)
}
- /// Creates an [`Invoice`] for the refund with the given required fields.
+ /// Creates an [`InvoiceBuilder`] for the refund with the given required fields.
///
/// Unless [`InvoiceBuilder::relative_expiry`] is set, the invoice will expire two hours after
/// `created_at`, which is used to set [`Invoice::created_at`]. Useful for `no-std` builds where
///
/// Errors if the request contains unknown required features.
///
- /// [`Invoice`]: crate::offers::invoice::Invoice
/// [`Invoice::created_at`]: crate::offers::invoice::Invoice::created_at
pub fn respond_with_no_std(
&self, payment_paths: Vec<(BlindedPath, BlindedPayInfo)>, payment_hash: PaymentHash,
pub(super) fn as_tlv_stream(&self) -> RefundTlvStreamRef {
let payer = PayerTlvStreamRef {
- metadata: Some(&self.payer.0),
+ metadata: self.payer.0.as_bytes(),
};
let offer = OfferTlvStreamRef {
let payer = match payer_metadata {
None => return Err(SemanticError::MissingPayerMetadata),
- Some(metadata) => PayerContents(metadata),
+ Some(metadata) => PayerContents(Metadata::Bytes(metadata)),
};
if metadata.is_some() {
use bitcoin::blockdata::constants::ChainHash;
use bitcoin::network::constants::Network;
- use bitcoin::secp256k1::{KeyPair, PublicKey, Secp256k1, SecretKey};
+ use bitcoin::secp256k1::{KeyPair, Secp256k1, SecretKey};
use core::convert::TryFrom;
use core::time::Duration;
use crate::ln::features::{InvoiceRequestFeatures, OfferFeatures};
use crate::offers::offer::OfferTlvStreamRef;
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;
- fn payer_pubkey() -> PublicKey {
- let secp_ctx = Secp256k1::new();
- KeyPair::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap()).public_key()
- }
-
- fn pubkey(byte: u8) -> PublicKey {
- let secp_ctx = Secp256k1::new();
- PublicKey::from_secret_key(&secp_ctx, &privkey(byte))
- }
-
- fn privkey(byte: u8) -> SecretKey {
- SecretKey::from_slice(&[byte; 32]).unwrap()
- }
-
trait ToBytes {
fn to_bytes(&self) -> Vec<u8>;
}
assert_eq!(tlv_stream.payer_note, Some(&String::from("baz")));
}
+ #[test]
+ fn fails_responding_with_unknown_required_features() {
+ match RefundBuilder::new("foo".into(), vec![1; 32], payer_pubkey(), 1000).unwrap()
+ .features_unchecked(InvoiceRequestFeatures::unknown())
+ .build().unwrap()
+ .respond_with_no_std(payment_paths(), payment_hash(), recipient_pubkey(), now())
+ {
+ Ok(_) => panic!("expected error"),
+ Err(e) => assert_eq!(e, SemanticError::UnknownRequiredFeatures),
+ }
+ }
+
#[test]
fn parses_refund_with_metadata() {
let refund = RefundBuilder::new("foo".into(), vec![1; 32], payer_pubkey(), 1000).unwrap()