#![deny(non_camel_case_types)]
#![deny(non_snake_case)]
#![deny(unused_mut)]
+#![deny(broken_intra_doc_links)]
#![cfg_attr(feature = "strict", deny(warnings))]
//! * For parsing use `str::parse::<Invoice>(&self)` (see the docs of `impl FromStr for Invoice`)
//! * For constructing invoices use the `InvoiceBuilder`
//! * For serializing invoices use the `Display`/`ToString` traits
+pub mod utils;
extern crate bech32;
extern crate bitcoin_hashes;
use bech32::u5;
use bitcoin_hashes::Hash;
use bitcoin_hashes::sha256;
+use lightning::ln::PaymentSecret;
use lightning::ln::features::InvoiceFeatures;
#[cfg(any(doc, test))]
use lightning::routing::network_graph::RoutingFees;
use secp256k1::key::PublicKey;
use secp256k1::{Message, Secp256k1};
use secp256k1::recovery::RecoverableSignature;
-use std::ops::Deref;
+use std::fmt::{Display, Formatter, self};
use std::iter::FilterMap;
+use std::ops::Deref;
use std::slice::Iter;
use std::time::{SystemTime, Duration, UNIX_EPOCH};
-use std::fmt::{Display, Formatter, self};
mod de;
mod ser;
#[derive(Eq, PartialEq, Debug, Clone)]
pub struct PayeePubKey(pub PublicKey);
-/// 256-bit payment secret
-#[derive(Eq, PartialEq, Debug, Clone)]
-pub struct PaymentSecret(pub [u8; 32]);
-
/// Positive duration that defines when (relatively to the timestamp) in the future the invoice
/// expires
///
#[allow(missing_docs)]
impl RawInvoice {
- /// Hash the HRP as bytes and signatureless data part.
- fn hash_from_parts(hrp_bytes: &[u8], data_without_signature: &[u5]) -> [u8; 32] {
+ /// Construct the invoice's HRP and signatureless data into a preimage to be hashed.
+ pub(crate) fn construct_invoice_preimage(hrp_bytes: &[u8], data_without_signature: &[u5]) -> Vec<u8> {
use bech32::FromBase32;
let mut preimage = Vec::<u8>::from(hrp_bytes);
preimage.extend_from_slice(&Vec::<u8>::from_base32(&data_part)
.expect("No padding error may occur due to appended zero above."));
+ preimage
+ }
+ /// Hash the HRP as bytes and signatureless data part.
+ fn hash_from_parts(hrp_bytes: &[u8], data_without_signature: &[u5]) -> [u8; 32] {
+ let preimage = RawInvoice::construct_invoice_preimage(hrp_bytes, data_without_signature);
let mut hash: [u8; 32] = Default::default();
hash.copy_from_slice(&sha256::Hash::hash(&preimage)[..]);
hash
/// When signing using a fallible method either an user-supplied `SignError` or a `CreationError`
/// may occur.
-///
-/// (C-not exported) As we don't support unbounded generics
#[derive(Eq, PartialEq, Debug, Clone)]
-pub enum SignOrCreationError<S> {
+pub enum SignOrCreationError<S = ()> {
/// An error occurred during signing
SignError(S),
let raw_invoice = builder.build_raw().unwrap();
assert_eq!(raw_invoice, *invoice.into_signed_raw().raw_invoice())
}
+
+ #[test]
+ fn test_default_values() {
+ use ::*;
+ use secp256k1::Secp256k1;
+ use secp256k1::key::SecretKey;
+
+ let signed_invoice = InvoiceBuilder::new(Currency::Bitcoin)
+ .description("Test".into())
+ .payment_hash(sha256::Hash::from_slice(&[0;32][..]).unwrap())
+ .current_timestamp()
+ .build_raw()
+ .unwrap()
+ .sign::<_, ()>(|hash| {
+ let privkey = SecretKey::from_slice(&[41; 32]).unwrap();
+ let secp_ctx = Secp256k1::new();
+ Ok(secp_ctx.sign_recoverable(hash, &privkey))
+ })
+ .unwrap();
+ let invoice = Invoice::from_signed(signed_invoice).unwrap();
+
+ assert_eq!(invoice.min_final_cltv_expiry(), DEFAULT_MIN_FINAL_CLTV_EXPIRY);
+ assert_eq!(invoice.expiry_time(), Duration::from_secs(DEFAULT_EXPIRY_TIME));
+ }
}