Skip to content

Commit 204dd42

Browse files
Expose methods for ChannelManager-less phantom invoice generation
1 parent 847f260 commit 204dd42

File tree

2 files changed

+39
-10
lines changed

2 files changed

+39
-10
lines changed

lightning-invoice/src/utils.rs

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,16 +38,20 @@ use sync::Mutex;
3838
/// may be too long for QR code scanning. To fix this, `PhantomRouteHints::channels` may be pared
3939
/// down
4040
///
41-
/// `payment_hash` and `payment_secret` come from [`ChannelManager::create_inbound_payment`] or
41+
/// `payment_hash` and `payment_secret` can come from [`ChannelManager::create_inbound_payment`] or
4242
/// [`ChannelManager::create_inbound_payment_for_hash`]. These values can be retrieved from any
43-
/// participating node.
43+
/// participating node. Alternatively, [`inbound_payment::create`] or
44+
/// [`inbound_payment::create_from_hash`] may be used to retrieve these values without a
45+
/// `ChannelManager`.
4446
///
4547
/// Note that the provided `keys_manager`'s `KeysInterface` implementation must support phantom
4648
/// invoices in its `sign_invoice` implementation ([`PhantomKeysManager`] satisfies this
4749
/// requirement).
4850
///
4951
/// [`PhantomKeysManager`]: lightning::chain::keysinterface::PhantomKeysManager
5052
/// [`ChannelManager::get_phantom_route_hints`]: lightning::ln::channelmanager::ChannelManager::get_phantom_route_hints
53+
/// [`inbound_payment::create`]: lightning::ln::inbound_payment::create
54+
/// [`inbound_payment::create_from_hash`]: lightning::ln::inbound_payment::create_from_hash
5155
/// [`PhantomRouteHints::channels`]: lightning::ln::channelmanager::PhantomRouteHints::channels
5256
pub fn create_phantom_invoice<Signer: Sign, K: Deref>(
5357
amt_msat: Option<u64>, description: String, payment_hash: PaymentHash, payment_secret: PaymentSecret,
@@ -76,16 +80,20 @@ pub fn create_phantom_invoice<Signer: Sign, K: Deref>(
7680
///
7781
/// `description_hash` is a SHA-256 hash of the description text
7882
///
79-
/// `payment_hash` and `payment_secret` come from [`ChannelManager::create_inbound_payment`] or
83+
/// `payment_hash` and `payment_secret` can come from [`ChannelManager::create_inbound_payment`] or
8084
/// [`ChannelManager::create_inbound_payment_for_hash`]. These values can be retrieved from any
81-
/// participating node.
85+
/// participating node. Alternatively, [`inbound_payment::create`] or
86+
/// [`inbound_payment::create_from_hash`] may be used to retrieve these values without a
87+
/// `ChannelManager`.
8288
///
8389
/// Note that the provided `keys_manager`'s `KeysInterface` implementation must support phantom
8490
/// invoices in its `sign_invoice` implementation ([`PhantomKeysManager`] satisfies this
8591
/// requirement).
8692
///
8793
/// [`PhantomKeysManager`]: lightning::chain::keysinterface::PhantomKeysManager
8894
/// [`ChannelManager::get_phantom_route_hints`]: lightning::ln::channelmanager::ChannelManager::get_phantom_route_hints
95+
/// [`inbound_payment::create`]: lightning::ln::inbound_payment::create
96+
/// [`inbound_payment::create_from_hash`]: lightning::ln::inbound_payment::create_from_hash
8997
/// [`PhantomRouteHints::channels`]: lightning::ln::channelmanager::PhantomRouteHints::channels
9098
pub fn create_phantom_invoice_with_description_hash<Signer: Sign, K: Deref>(
9199
amt_msat: Option<u64>, description_hash: Sha256, payment_hash: PaymentHash,

lightning/src/ln/inbound_payment.rs

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ const METHOD_TYPE_OFFSET: usize = 5;
3838
/// [`KeysInterface::get_inbound_payment_key_material`].
3939
///
4040
/// [`KeysInterface::get_inbound_payment_key_material`]: crate::chain::keysinterface::KeysInterface::get_inbound_payment_key_material
41-
pub(super) struct ExpandedKey {
41+
pub struct ExpandedKey {
4242
/// The key used to encrypt the bytes containing the payment metadata (i.e. the amount and
4343
/// expiry, included for payment verification on decryption).
4444
metadata_key: [u8; 32],
@@ -51,7 +51,10 @@ pub(super) struct ExpandedKey {
5151
}
5252

5353
impl ExpandedKey {
54-
pub(super) fn new(key_material: &KeyMaterial) -> ExpandedKey {
54+
/// Create a new [`ExpandedKey`] for generating an inbound payment hash and secret.
55+
///
56+
/// It is recommended to cache this value and not regenerate it for each new inbound payment.
57+
pub fn new(key_material: &KeyMaterial) -> ExpandedKey {
5558
let (metadata_key, ldk_pmt_hash_key, user_pmt_hash_key) =
5659
hkdf_extract_expand_thrice(b"LDK Inbound Payment Key Expansion", &key_material.0);
5760
Self {
@@ -77,10 +80,21 @@ impl Method {
7780
}
7881
}
7982

80-
pub(super) fn create<Signer: Sign, K: Deref>(keys: &ExpandedKey, min_value_msat: Option<u64>, invoice_expiry_delta_secs: u32, keys_manager: &K, highest_seen_timestamp: u64) -> Result<(PaymentHash, PaymentSecret), ()>
83+
/// Equivalent to [`crate::ln::channelmanager::ChannelManager::create_inbound_payment`], but no
84+
/// `ChannelManager` is required. Useful for generating invoices for [phantom node payments] without
85+
/// a `ChannelManager`.
86+
///
87+
/// `keys` is generated by calling [`KeysInterface::get_inbound_payment_key_material`] and then
88+
/// calling [`ExpandedKey::new`] with its result. It is recommended to cache this value and not
89+
/// regenerate it for each new inbound payment.
90+
///
91+
/// `current_time` is a Unix timestamp representing the current time.
92+
///
93+
/// [phantom node payments]: crate::chain::keysinterface::PhantomKeysManager
94+
pub fn create<Signer: Sign, K: Deref>(keys: &ExpandedKey, min_value_msat: Option<u64>, invoice_expiry_delta_secs: u32, keys_manager: &K, current_time: u64) -> Result<(PaymentHash, PaymentSecret), ()>
8195
where K::Target: KeysInterface<Signer = Signer>
8296
{
83-
let metadata_bytes = construct_metadata_bytes(min_value_msat, Method::LdkPaymentHash, invoice_expiry_delta_secs, highest_seen_timestamp)?;
97+
let metadata_bytes = construct_metadata_bytes(min_value_msat, Method::LdkPaymentHash, invoice_expiry_delta_secs, current_time)?;
8498

8599
let mut iv_bytes = [0 as u8; IV_LEN];
86100
let rand_bytes = keys_manager.get_secure_random_bytes();
@@ -96,8 +110,15 @@ pub(super) fn create<Signer: Sign, K: Deref>(keys: &ExpandedKey, min_value_msat:
96110
Ok((ldk_pmt_hash, payment_secret))
97111
}
98112

99-
pub(super) fn create_from_hash(keys: &ExpandedKey, min_value_msat: Option<u64>, payment_hash: PaymentHash, invoice_expiry_delta_secs: u32, highest_seen_timestamp: u64) -> Result<PaymentSecret, ()> {
100-
let metadata_bytes = construct_metadata_bytes(min_value_msat, Method::UserPaymentHash, invoice_expiry_delta_secs, highest_seen_timestamp)?;
113+
/// Equivalent to [`crate::ln::channelmanager::ChannelManager::create_inbound_payment_for_hash`],
114+
/// but no `ChannelManager` is required. Useful for generating invoices for [phantom node payments]
115+
/// without a `ChannelManager`.
116+
///
117+
/// See [`create`] for information on the `keys` and `current_time` parameters.
118+
///
119+
/// [phantom node payments]: crate::chain::keysinterface::PhantomKeysManager
120+
pub fn create_from_hash(keys: &ExpandedKey, min_value_msat: Option<u64>, payment_hash: PaymentHash, invoice_expiry_delta_secs: u32, current_time: u64) -> Result<PaymentSecret, ()> {
121+
let metadata_bytes = construct_metadata_bytes(min_value_msat, Method::UserPaymentHash, invoice_expiry_delta_secs, current_time)?;
101122

102123
let mut hmac = HmacEngine::<Sha256>::new(&keys.user_pmt_hash_key);
103124
hmac.input(&metadata_bytes);

0 commit comments

Comments
 (0)