Skip to content

Commit c7de9ba

Browse files
committed
WIP: Implement Display for Offer
1 parent d446c66 commit c7de9ba

File tree

2 files changed

+56
-10
lines changed

2 files changed

+56
-10
lines changed

lightning/src/offers/mod.rs

Lines changed: 55 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ use prelude::*;
3131
use std::time::SystemTime;
3232

3333
///
34-
#[derive(Debug)]
34+
#[derive(Clone, Debug)]
3535
pub struct Offer {
3636
chains: Option<Vec<BlockHash>>,
3737
amount: Option<Amount>,
@@ -113,11 +113,51 @@ impl Offer {
113113
pub fn signature(&self) -> Option<&Signature> {
114114
self.signature.as_ref()
115115
}
116+
117+
fn to_tlv_stream(&self) -> OfferTlvStream {
118+
let (currency, amount) = match self.amount.clone() {
119+
None => (None, None),
120+
Some(Amount::Bitcoin { amount_msats }) => (
121+
None, Some(HighZeroBytesDroppedVarInt(amount_msats))
122+
),
123+
Some(Amount::Currency { iso4217_code, amount }) => (
124+
Some(WithoutLength(iso4217_code)), Some(HighZeroBytesDroppedVarInt(amount))
125+
),
126+
};
127+
128+
let (paths, node_id) = match self.destination.clone() {
129+
Destination::NodeId(node_id) => (None, Some(node_id)),
130+
Destination::Paths(paths) => (Some(WithoutLength(paths)), None),
131+
};
132+
133+
let (send_invoice, refund_for) = match self.send_invoice.clone() {
134+
None => (None, None),
135+
Some(SendInvoice { refund_for }) => (Some(()), refund_for),
136+
};
137+
138+
OfferTlvStream {
139+
chains: self.chains.clone().map(|chains| WithoutLength(chains)),
140+
currency,
141+
amount,
142+
description: Some(WithoutLength(self.description.clone())),
143+
features: self.features.clone(),
144+
absolute_expiry: self.absolute_expiry.map(|d| HighZeroBytesDroppedVarInt(d.as_secs())),
145+
paths,
146+
issuer: self.issuer.clone().map(|issuer| WithoutLength(issuer)),
147+
quantity_min: self.quantity_min.map(|quantity| HighZeroBytesDroppedVarInt(quantity)),
148+
quantity_max: self.quantity_max.map(|quantity| HighZeroBytesDroppedVarInt(quantity)),
149+
recurrence: self.recurrence.clone(),
150+
node_id,
151+
send_invoice,
152+
refund_for,
153+
signature: self.signature,
154+
}
155+
}
116156
}
117157

118158
/// The amount required for an item in an [`Offer`] denominated in either bitcoin or another
119159
/// currency.
120-
#[derive(Debug)]
160+
#[derive(Clone, Debug)]
121161
pub enum Amount {
122162
/// An amount of bitcoin.
123163
Bitcoin {
@@ -136,7 +176,7 @@ pub enum Amount {
136176
const ISO4217_CODE_LEN: usize = 3;
137177

138178
///
139-
#[derive(Debug)]
179+
#[derive(Clone, Debug)]
140180
pub enum Destination {
141181
///
142182
NodeId(XOnlyPublicKey),
@@ -145,7 +185,7 @@ pub enum Destination {
145185
}
146186

147187
///
148-
#[derive(Debug)]
188+
#[derive(Clone, Debug)]
149189
pub struct SendInvoice {
150190
refund_for: Option<PaymentHash>,
151191
}
@@ -189,7 +229,7 @@ impl_writeable_tlv_stream!(OfferTlvStream, {
189229
(240, signature, option),
190230
});
191231

192-
#[derive(Debug)]
232+
#[derive(Clone, Debug)]
193233
///
194234
pub struct BlindedPath {
195235
blinding: PublicKey,
@@ -198,7 +238,7 @@ pub struct BlindedPath {
198238

199239
impl_writeable!(BlindedPath, { blinding, path });
200240

201-
#[derive(Debug)]
241+
#[derive(Clone, Debug)]
202242
struct OnionMessagePath {
203243
node_id: PublicKey,
204244
encrypted_recipient_data: Vec<u8>,
@@ -207,7 +247,7 @@ struct OnionMessagePath {
207247
impl_writeable!(OnionMessagePath, { node_id, encrypted_recipient_data });
208248

209249
// TODO: Remove once BOLT 12 test vectors are updated.
210-
#[derive(Debug)]
250+
#[derive(Clone, Debug)]
211251
struct Recurrence {
212252
time_unit: u8,
213253
period: HighZeroBytesDroppedVarInt<u32>,
@@ -398,6 +438,12 @@ impl FromStr for OfferTlvStream {
398438
}
399439
}
400440

441+
impl core::fmt::Display for Offer {
442+
fn fmt(&self, f: &mut core::fmt::Formatter) -> Result<(), core::fmt::Error> {
443+
self.to_tlv_stream().fmt(f)
444+
}
445+
}
446+
401447
impl core::fmt::Display for OfferTlvStream {
402448
fn fmt(&self, f: &mut core::fmt::Formatter) -> Result<(), core::fmt::Error> {
403449
use util::ser::Writeable;
@@ -421,9 +467,9 @@ mod tests {
421467
#[test]
422468
fn encodes_offer_as_bech32_without_checksum() {
423469
let encoded_offer = "lno1qcp4256ypqpq86q2pucnq42ngssx2an9wfujqerp0y2pqun4wd68jtn00fkxzcnn9ehhyec6qgqsz83qfwdpl28qqmc78ymlvhmxcsywdk5wrjnj36jryg488qwlrnzyjczlqsp9nyu4phcg6dqhlhzgxagfu7zh3d9re0sqp9ts2yfugvnnm9gxkcnnnkdpa084a6t520h5zhkxsdnghvpukvd43lastpwuh73k29qsy";
424-
let offer = dbg!(encoded_offer.parse::<OfferTlvStream>().unwrap());
470+
let offer = dbg!(encoded_offer.parse::<Offer>().unwrap());
425471
let reencoded_offer = offer.to_string();
426-
dbg!(reencoded_offer.parse::<OfferTlvStream>().unwrap());
472+
dbg!(reencoded_offer.parse::<Offer>().unwrap());
427473
assert_eq!(reencoded_offer, encoded_offer);
428474
}
429475

lightning/src/util/ser.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -393,7 +393,7 @@ impl Readable for BigSize {
393393
/// variable-length integer which is simply truncated by skipping high zero bytes. This type
394394
/// encapsulates such integers implementing Readable/Writeable for them.
395395
#[cfg_attr(test, derive(PartialEq))]
396-
#[derive(Debug)]
396+
#[derive(Clone, Debug)]
397397
pub(crate) struct HighZeroBytesDroppedVarInt<T>(pub T);
398398

399399
macro_rules! impl_writeable_primitive {

0 commit comments

Comments
 (0)