@@ -134,9 +134,12 @@ pub struct ExplicitMetadata {}
134
134
pub struct DerivedMetadata { }
135
135
136
136
impl MetadataStrategy for ExplicitMetadata { }
137
+
137
138
impl MetadataStrategy for DerivedMetadata { }
138
139
139
- impl < ' a > OfferBuilder < ' a , ExplicitMetadata , secp256k1:: SignOnly > {
140
+ macro_rules! offer_explicit_metadata_builder_methods { (
141
+ $self: ident, $self_type: ty, $return_type: ty, $return_value: expr
142
+ ) => {
140
143
/// Creates a new builder for an offer setting the [`Offer::description`] and using the
141
144
/// [`Offer::signing_pubkey`] for signing invoices. The associated secret key must be remembered
142
145
/// while the offer is valid.
@@ -151,7 +154,7 @@ impl<'a> OfferBuilder<'a, ExplicitMetadata, secp256k1::SignOnly> {
151
154
/// [`ChannelManager`]: crate::ln::channelmanager::ChannelManager
152
155
/// [`ChannelManager::create_offer_builder`]: crate::ln::channelmanager::ChannelManager::create_offer_builder
153
156
pub fn new( description: String , signing_pubkey: PublicKey ) -> Self {
154
- OfferBuilder {
157
+ Self {
155
158
offer: OfferContents {
156
159
chains: None , metadata: None , amount: None , description,
157
160
features: OfferFeatures :: empty( ) , absolute_expiry: None , issuer: None , paths: None ,
@@ -165,13 +168,13 @@ impl<'a> OfferBuilder<'a, ExplicitMetadata, secp256k1::SignOnly> {
165
168
/// Sets the [`Offer::metadata`] to the given bytes.
166
169
///
167
170
/// Successive calls to this method will override the previous setting.
168
- pub fn metadata ( mut self , metadata : Vec < u8 > ) -> Result < Self , Bolt12SemanticError > {
169
- self . offer . metadata = Some ( Metadata :: Bytes ( metadata) ) ;
170
- Ok ( self )
171
+ pub fn metadata( mut $ self: $self_type , metadata: Vec <u8 >) -> Result <$return_type , Bolt12SemanticError > {
172
+ $ self. offer. metadata = Some ( Metadata :: Bytes ( metadata) ) ;
173
+ Ok ( $return_value )
171
174
}
172
- }
175
+ } }
173
176
174
- impl < ' a , T : secp256k1 :: Signing > OfferBuilder < ' a , DerivedMetadata , T > {
177
+ macro_rules! offer_derived_metadata_builder_methods { ( ) = > {
175
178
/// Similar to [`OfferBuilder::new`] except, if [`OfferBuilder::path`] is called, the signing
176
179
/// pubkey is derived from the given [`ExpandedKey`] and [`EntropySource`]. This provides
177
180
/// recipient privacy by using a different signing pubkey for each offer. Otherwise, the
@@ -190,7 +193,7 @@ impl<'a, T: secp256k1::Signing> OfferBuilder<'a, DerivedMetadata, T> {
190
193
let nonce = Nonce :: from_entropy_source( entropy_source) ;
191
194
let derivation_material = MetadataMaterial :: new( nonce, expanded_key, IV_BYTES , None ) ;
192
195
let metadata = Metadata :: DerivedSigningPubkey ( derivation_material) ;
193
- OfferBuilder {
196
+ Self {
194
197
offer: OfferContents {
195
198
chains: None , metadata: Some ( metadata) , amount: None , description,
196
199
features: OfferFeatures :: empty( ) , absolute_expiry: None , issuer: None , paths: None ,
@@ -200,17 +203,19 @@ impl<'a, T: secp256k1::Signing> OfferBuilder<'a, DerivedMetadata, T> {
200
203
secp_ctx: Some ( secp_ctx) ,
201
204
}
202
205
}
203
- }
206
+ } }
204
207
205
- impl < ' a , M : MetadataStrategy , T : secp256k1:: Signing > OfferBuilder < ' a , M , T > {
208
+ macro_rules! offer_builder_methods { (
209
+ $self: ident, $self_type: ty, $return_type: ty, $return_value: expr
210
+ ) => {
206
211
/// Adds the chain hash of the given [`Network`] to [`Offer::chains`]. If not called,
207
212
/// the chain hash of [`Network::Bitcoin`] is assumed to be the only one supported.
208
213
///
209
214
/// See [`Offer::chains`] on how this relates to the payment currency.
210
215
///
211
216
/// Successive calls to this method will add another chain hash.
212
- pub fn chain ( self , network : Network ) -> Self {
213
- self . chain_hash ( ChainHash :: using_genesis_block ( network) )
217
+ pub fn chain( $ self: $self_type , network: Network ) -> $return_type {
218
+ $ self. chain_hash( ChainHash :: using_genesis_block( network) )
214
219
}
215
220
216
221
/// Adds the [`ChainHash`] to [`Offer::chains`]. If not called, the chain hash of
@@ -219,69 +224,69 @@ impl<'a, M: MetadataStrategy, T: secp256k1::Signing> OfferBuilder<'a, M, T> {
219
224
/// See [`Offer::chains`] on how this relates to the payment currency.
220
225
///
221
226
/// Successive calls to this method will add another chain hash.
222
- pub ( crate ) fn chain_hash ( mut self , chain : ChainHash ) -> Self {
223
- let chains = self . offer . chains . get_or_insert_with ( Vec :: new) ;
227
+ pub ( crate ) fn chain_hash( mut $ self: $self_type , chain: ChainHash ) -> $return_type {
228
+ let chains = $ self. offer. chains. get_or_insert_with( Vec :: new) ;
224
229
if !chains. contains( & chain) {
225
230
chains. push( chain) ;
226
231
}
227
232
228
- self
233
+ $return_value
229
234
}
230
235
231
236
/// Sets the [`Offer::amount`] as an [`Amount::Bitcoin`].
232
237
///
233
238
/// Successive calls to this method will override the previous setting.
234
- pub fn amount_msats ( self , amount_msats : u64 ) -> Self {
235
- self . amount ( Amount :: Bitcoin { amount_msats } )
239
+ pub fn amount_msats( $ self: $self_type , amount_msats: u64 ) -> $return_type {
240
+ $ self. amount( Amount :: Bitcoin { amount_msats } )
236
241
}
237
242
238
243
/// Sets the [`Offer::amount`].
239
244
///
240
245
/// Successive calls to this method will override the previous setting.
241
- pub ( super ) fn amount ( mut self , amount : Amount ) -> Self {
242
- self . offer . amount = Some ( amount) ;
243
- self
246
+ pub ( super ) fn amount( mut $ self: $self_type , amount: Amount ) -> $return_type {
247
+ $ self. offer. amount = Some ( amount) ;
248
+ $return_value
244
249
}
245
250
246
251
/// Sets the [`Offer::absolute_expiry`] as seconds since the Unix epoch. Any expiry that has
247
252
/// already passed is valid and can be checked for using [`Offer::is_expired`].
248
253
///
249
254
/// Successive calls to this method will override the previous setting.
250
- pub fn absolute_expiry ( mut self , absolute_expiry : Duration ) -> Self {
251
- self . offer . absolute_expiry = Some ( absolute_expiry) ;
252
- self
255
+ pub fn absolute_expiry( mut $ self: $self_type , absolute_expiry: Duration ) -> $return_type {
256
+ $ self. offer. absolute_expiry = Some ( absolute_expiry) ;
257
+ $return_value
253
258
}
254
259
255
260
/// Sets the [`Offer::issuer`].
256
261
///
257
262
/// Successive calls to this method will override the previous setting.
258
- pub fn issuer ( mut self , issuer : String ) -> Self {
259
- self . offer . issuer = Some ( issuer) ;
260
- self
263
+ pub fn issuer( mut $ self: $self_type , issuer: String ) -> $return_type {
264
+ $ self. offer. issuer = Some ( issuer) ;
265
+ $return_value
261
266
}
262
267
263
268
/// Adds a blinded path to [`Offer::paths`]. Must include at least one path if only connected by
264
269
/// private channels or if [`Offer::signing_pubkey`] is not a public node id.
265
270
///
266
271
/// Successive calls to this method will add another blinded path. Caller is responsible for not
267
272
/// adding duplicate paths.
268
- pub fn path ( mut self , path : BlindedPath ) -> Self {
269
- self . offer . paths . get_or_insert_with ( Vec :: new) . push ( path) ;
270
- self
273
+ pub fn path( mut $ self: $self_type , path: BlindedPath ) -> $return_type {
274
+ $ self. offer. paths. get_or_insert_with( Vec :: new) . push( path) ;
275
+ $return_value
271
276
}
272
277
273
278
/// Sets the quantity of items for [`Offer::supported_quantity`]. If not called, defaults to
274
279
/// [`Quantity::One`].
275
280
///
276
281
/// Successive calls to this method will override the previous setting.
277
- pub fn supported_quantity ( mut self , quantity : Quantity ) -> Self {
278
- self . offer . supported_quantity = quantity;
279
- self
282
+ pub fn supported_quantity( mut $ self: $self_type , quantity: Quantity ) -> $return_type {
283
+ $ self. offer. supported_quantity = quantity;
284
+ $return_value
280
285
}
281
286
282
287
/// Builds an [`Offer`] from the builder's settings.
283
- pub fn build ( mut self ) -> Result < Offer , Bolt12SemanticError > {
284
- match self . offer . amount {
288
+ pub fn build( mut $ self: $self_type ) -> Result <Offer , Bolt12SemanticError > {
289
+ match $ self. offer. amount {
285
290
Some ( Amount :: Bitcoin { amount_msats } ) => {
286
291
if amount_msats > MAX_VALUE_MSAT {
287
292
return Err ( Bolt12SemanticError :: InvalidAmount ) ;
@@ -291,62 +296,79 @@ impl<'a, M: MetadataStrategy, T: secp256k1::Signing> OfferBuilder<'a, M, T> {
291
296
None => { } ,
292
297
}
293
298
294
- if let Some ( chains) = & self . offer . chains {
295
- if chains. len ( ) == 1 && chains[ 0 ] == self . offer . implied_chain ( ) {
296
- self . offer . chains = None ;
299
+ if let Some ( chains) = & $ self. offer. chains {
300
+ if chains. len( ) == 1 && chains[ 0 ] == $ self. offer. implied_chain( ) {
301
+ $ self. offer. chains = None ;
297
302
}
298
303
}
299
304
300
- Ok ( self . build_without_checks ( ) )
305
+ Ok ( $ self. build_without_checks( ) )
301
306
}
302
307
303
- fn build_without_checks ( mut self ) -> Offer {
308
+ fn build_without_checks( mut $ self: $self_type ) -> Offer {
304
309
// Create the metadata for stateless verification of an InvoiceRequest.
305
- if let Some ( mut metadata) = self . offer . metadata . take ( ) {
310
+ if let Some ( mut metadata) = $ self. offer. metadata. take( ) {
306
311
if metadata. has_derivation_material( ) {
307
- if self . offer . paths . is_none ( ) {
312
+ if $ self. offer. paths. is_none( ) {
308
313
metadata = metadata. without_keys( ) ;
309
314
}
310
315
311
- let mut tlv_stream = self . offer . as_tlv_stream ( ) ;
316
+ let mut tlv_stream = $ self. offer. as_tlv_stream( ) ;
312
317
debug_assert_eq!( tlv_stream. metadata, None ) ;
313
318
tlv_stream. metadata = None ;
314
319
if metadata. derives_recipient_keys( ) {
315
320
tlv_stream. node_id = None ;
316
321
}
317
322
318
- let ( derived_metadata, keys) = metadata. derive_from ( tlv_stream, self . secp_ctx ) ;
323
+ let ( derived_metadata, keys) = metadata. derive_from( tlv_stream, $ self. secp_ctx) ;
319
324
metadata = derived_metadata;
320
325
if let Some ( keys) = keys {
321
- self . offer . signing_pubkey = keys. public_key ( ) ;
326
+ $ self. offer. signing_pubkey = keys. public_key( ) ;
322
327
}
323
328
}
324
329
325
- self . offer . metadata = Some ( metadata) ;
330
+ $ self. offer. metadata = Some ( metadata) ;
326
331
}
327
332
328
333
let mut bytes = Vec :: new( ) ;
329
- self . offer . write ( & mut bytes) . unwrap ( ) ;
334
+ $ self. offer. write( & mut bytes) . unwrap( ) ;
330
335
331
- Offer { bytes, contents : self . offer }
336
+ Offer { bytes, contents: $ self. offer }
332
337
}
333
- }
338
+ } }
334
339
335
340
#[ cfg( test) ]
336
- impl < ' a , M : MetadataStrategy , T : secp256k1:: Signing > OfferBuilder < ' a , M , T > {
337
- fn features_unchecked ( mut self , features : OfferFeatures ) -> Self {
338
- self . offer . features = features;
339
- self
341
+ macro_rules! offer_builder_test_methods { (
342
+ $self: ident, $self_type: ty, $return_type: ty, $return_value: expr
343
+ ) => {
344
+ fn features_unchecked( mut $self: $self_type, features: OfferFeatures ) -> $return_type {
345
+ $self. offer. features = features;
346
+ $return_value
340
347
}
341
348
342
- pub ( crate ) fn clear_paths ( mut self ) -> Self {
343
- self . offer . paths = None ;
344
- self
349
+ pub ( crate ) fn clear_paths( mut $ self: $self_type ) -> $return_type {
350
+ $ self. offer. paths = None ;
351
+ $return_value
345
352
}
346
353
347
- pub ( super ) fn build_unchecked ( self ) -> Offer {
348
- self . build_without_checks ( )
354
+ pub ( super ) fn build_unchecked( $ self: $self_type ) -> Offer {
355
+ $ self. build_without_checks( )
349
356
}
357
+ } }
358
+
359
+ impl < ' a , M : MetadataStrategy , T : secp256k1:: Signing > OfferBuilder < ' a , M , T > {
360
+ offer_builder_methods ! ( self , Self , Self , self ) ;
361
+
362
+ #[ cfg( test) ]
363
+ offer_builder_test_methods ! ( self , Self , Self , self ) ;
364
+ }
365
+
366
+ impl < ' a > OfferBuilder < ' a , ExplicitMetadata , secp256k1:: SignOnly > {
367
+ offer_explicit_metadata_builder_methods ! ( self , Self , Self , self ) ;
368
+ }
369
+
370
+ impl < ' a , T : secp256k1:: Signing > OfferBuilder < ' a , DerivedMetadata , T > {
371
+ offer_derived_metadata_builder_methods ! ( ) ;
350
372
}
351
373
352
374
/// An `Offer` is a potentially long-lived proposal for payment of a good or service.
0 commit comments