session_privs: HashSet<[u8; 32]>,
payment_hash: PaymentHash,
payment_secret: Option<PaymentSecret>,
+ payment_metadata: Option<Vec<u8>>,
keysend_preimage: Option<PaymentPreimage>,
pending_amt_msat: u64,
/// Used to track the fee paid. Only present if the payment was serialized on 0.0.103+.
/// receives, thus you should generally never be providing a secret here for spontaneous
/// payments.
pub payment_secret: Option<PaymentSecret>,
+ /// The payment metadata serves a similar purpose as [`Self::payment_secret`] but is of
+ /// arbitrary length. This gives recipients substantially more flexibility to receive
+ /// additional data.
+ ///
+ /// In LDK, while the [`Self::payment_secret`] is fixed based on an internal authentication
+ /// scheme to authenticate received payments against expected payments and invoices, this field
+ /// is not used in LDK for received payments, and can be used to store arbitrary data in
+ /// invoices which will be received with the payment.
+ ///
+ /// Note that this field was added to the lightning specification more recently than
+ /// [`Self::payment_secret`] and while nearly all lightning senders support secrets, metadata
+ /// may not be supported as universally.
+ pub payment_metadata: Option<Vec<u8>>,
}
impl RecipientOnionFields {
/// set of onion fields for today's BOLT11 invoices - most nodes require a [`PaymentSecret`]
/// but do not require or provide any further data.
pub fn secret_only(payment_secret: PaymentSecret) -> Self {
- Self { payment_secret: Some(payment_secret) }
+ Self { payment_secret: Some(payment_secret), payment_metadata: None }
}
/// Creates a new [`RecipientOnionFields`] with no fields. This generally does not create
///
/// [`ChannelManager::send_spontaneous_payment`]: super::channelmanager::ChannelManager::send_spontaneous_payment
pub fn spontaneous_empty() -> Self {
- Self { payment_secret: None }
+ Self { payment_secret: None, payment_metadata: None }
}
}
hash_map::Entry::Occupied(mut payment) => {
let res = match payment.get() {
PendingOutboundPayment::Retryable {
- total_msat, keysend_preimage, payment_secret, pending_amt_msat, ..
+ total_msat, keysend_preimage, payment_secret, payment_metadata, pending_amt_msat, ..
} => {
let retry_amt_msat: u64 = route.paths.iter().map(|path| path.last().unwrap().fee_msat).sum();
if retry_amt_msat + *pending_amt_msat > *total_msat * (100 + RETRY_OVERFLOW_PERCENTAGE) / 100 {
}
(*total_msat, RecipientOnionFields {
payment_secret: *payment_secret,
+ payment_metadata: payment_metadata.clone(),
}, *keysend_preimage)
},
PendingOutboundPayment::Legacy { .. } => {
pending_fee_msat: Some(0),
payment_hash,
payment_secret: recipient_onion.payment_secret,
+ payment_metadata: recipient_onion.payment_metadata,
keysend_preimage,
starting_block_height: best_block_height,
total_msat: route.get_total_amount(),
(4, payment_secret, option),
(5, keysend_preimage, option),
(6, total_msat, required),
+ (7, payment_metadata, option),
(8, pending_amt_msat, required),
(10, starting_block_height, required),
(not_written, retry_strategy, (static_value, None)),