+/// Fields sent in an [`InvoiceRequest`] message to include in [`PaymentContext::Bolt12Offer`].
+///
+/// [`PaymentContext::Bolt12Offer`]: crate::blinded_path::payment::PaymentContext::Bolt12Offer
+#[derive(Clone, Debug, Eq, PartialEq)]
+pub struct InvoiceRequestFields {
+ /// A possibly transient pubkey used to sign the invoice request.
+ pub payer_id: PublicKey,
+
+ /// The amount to pay in msats (i.e., the minimum lightning-payable unit for [`chain`]), which
+ /// must be greater than or equal to [`Offer::amount`], converted if necessary.
+ ///
+ /// [`chain`]: InvoiceRequest::chain
+ pub amount_msats: Option<u64>,
+
+ /// Features pertaining to requesting an invoice.
+ pub features: InvoiceRequestFeatures,
+
+ /// The quantity of the offer's item conforming to [`Offer::is_valid_quantity`].
+ pub quantity: Option<u64>,
+
+ /// A payer-provided note which will be seen by the recipient and reflected back in the invoice
+ /// response. Truncated to [`PAYER_NOTE_LIMIT`] characters.
+ pub payer_note_truncated: Option<UntrustedString>,
+}
+
+/// The maximum number of characters included in [`InvoiceRequestFields::payer_note_truncated`].
+pub const PAYER_NOTE_LIMIT: usize = 512;
+
+impl Writeable for InvoiceRequestFields {
+ fn write<W: Writer>(&self, writer: &mut W) -> Result<(), io::Error> {
+ write_tlv_fields!(writer, {
+ (0, self.payer_id, required),
+ (2, self.amount_msats.map(|v| HighZeroBytesDroppedBigSize(v)), option),
+ (4, WithoutLength(&self.features), required),
+ (6, self.quantity.map(|v| HighZeroBytesDroppedBigSize(v)), option),
+ (8, self.payer_note_truncated.as_ref().map(|s| WithoutLength(&s.0)), option),
+ });
+ Ok(())
+ }
+}
+
+impl Readable for InvoiceRequestFields {
+ fn read<R: io::Read>(reader: &mut R) -> Result<Self, DecodeError> {
+ _init_and_read_len_prefixed_tlv_fields!(reader, {
+ (0, payer_id, required),
+ (2, amount_msats, (option, encoding: (u64, HighZeroBytesDroppedBigSize))),
+ (4, features, (option, encoding: (InvoiceRequestFeatures, WithoutLength))),
+ (6, quantity, (option, encoding: (u64, HighZeroBytesDroppedBigSize))),
+ (8, payer_note_truncated, (option, encoding: (String, WithoutLength))),
+ });
+ let features = features.unwrap_or(InvoiceRequestFeatures::empty());
+
+ Ok(InvoiceRequestFields {
+ payer_id: payer_id.0.unwrap(), amount_msats, features, quantity,
+ payer_note_truncated: payer_note_truncated.map(|s| UntrustedString(s)),
+ })
+ }
+}
+