@@ -169,7 +169,7 @@ pub struct DerivedSigningPubkey(KeyPair);
169
169
impl SigningPubkeyStrategy for ExplicitSigningPubkey { }
170
170
impl SigningPubkeyStrategy for DerivedSigningPubkey { }
171
171
172
- impl < ' a > InvoiceBuilder < ' a , ExplicitSigningPubkey > {
172
+ macro_rules! invoice_explicit_signing_pubkey_builder_methods { ( $self : ident , $self_type : ty ) = > {
173
173
pub ( super ) fn for_offer(
174
174
invoice_request: & ' a InvoiceRequest , payment_paths: Vec <( BlindedPayInfo , BlindedPath ) >,
175
175
created_at: Duration , payment_hash: PaymentHash
@@ -203,25 +203,25 @@ impl<'a> InvoiceBuilder<'a, ExplicitSigningPubkey> {
203
203
204
204
/// Builds an unsigned [`Bolt12Invoice`] after checking for valid semantics. It can be signed by
205
205
/// [`UnsignedBolt12Invoice::sign`].
206
- pub fn build ( self ) -> Result < UnsignedBolt12Invoice , Bolt12SemanticError > {
206
+ pub fn build( $ self: $self_type ) -> Result <UnsignedBolt12Invoice , Bolt12SemanticError > {
207
207
#[ cfg( feature = "std" ) ] {
208
- if self . invoice . is_offer_or_refund_expired ( ) {
208
+ if $ self. invoice. is_offer_or_refund_expired( ) {
209
209
return Err ( Bolt12SemanticError :: AlreadyExpired ) ;
210
210
}
211
211
}
212
212
213
213
#[ cfg( not( feature = "std" ) ) ] {
214
- if self . invoice . is_offer_or_refund_expired_no_std ( self . invoice . created_at ( ) ) {
214
+ if $ self. invoice. is_offer_or_refund_expired_no_std( $ self. invoice. created_at( ) ) {
215
215
return Err ( Bolt12SemanticError :: AlreadyExpired ) ;
216
216
}
217
217
}
218
218
219
- let InvoiceBuilder { invreq_bytes, invoice, .. } = self ;
219
+ let InvoiceBuilder { invreq_bytes, invoice, .. } = $ self;
220
220
Ok ( UnsignedBolt12Invoice :: new( invreq_bytes, invoice) )
221
221
}
222
- }
222
+ } }
223
223
224
- impl < ' a > InvoiceBuilder < ' a , DerivedSigningPubkey > {
224
+ macro_rules! invoice_derived_signing_pubkey_builder_methods { ( $self : ident , $self_type : ty ) = > {
225
225
pub ( super ) fn for_offer_using_keys(
226
226
invoice_request: & ' a InvoiceRequest , payment_paths: Vec <( BlindedPayInfo , BlindedPath ) >,
227
227
created_at: Duration , payment_hash: PaymentHash , keys: KeyPair
@@ -256,23 +256,23 @@ impl<'a> InvoiceBuilder<'a, DerivedSigningPubkey> {
256
256
257
257
/// Builds a signed [`Bolt12Invoice`] after checking for valid semantics.
258
258
pub fn build_and_sign<T : secp256k1:: Signing >(
259
- self , secp_ctx : & Secp256k1 < T >
259
+ $ self: $self_type , secp_ctx: & Secp256k1 <T >
260
260
) -> Result <Bolt12Invoice , Bolt12SemanticError > {
261
261
#[ cfg( feature = "std" ) ] {
262
- if self . invoice . is_offer_or_refund_expired ( ) {
262
+ if $ self. invoice. is_offer_or_refund_expired( ) {
263
263
return Err ( Bolt12SemanticError :: AlreadyExpired ) ;
264
264
}
265
265
}
266
266
267
267
#[ cfg( not( feature = "std" ) ) ] {
268
- if self . invoice . is_offer_or_refund_expired_no_std ( self . invoice . created_at ( ) ) {
268
+ if $ self. invoice. is_offer_or_refund_expired_no_std( $ self. invoice. created_at( ) ) {
269
269
return Err ( Bolt12SemanticError :: AlreadyExpired ) ;
270
270
}
271
271
}
272
272
273
273
let InvoiceBuilder {
274
274
invreq_bytes, invoice, signing_pubkey_strategy: DerivedSigningPubkey ( keys)
275
- } = self ;
275
+ } = $ self;
276
276
let unsigned_invoice = UnsignedBolt12Invoice :: new( invreq_bytes, invoice) ;
277
277
278
278
let invoice = unsigned_invoice
@@ -282,9 +282,11 @@ impl<'a> InvoiceBuilder<'a, DerivedSigningPubkey> {
282
282
. unwrap( ) ;
283
283
Ok ( invoice)
284
284
}
285
- }
285
+ } }
286
286
287
- impl < ' a , S : SigningPubkeyStrategy > InvoiceBuilder < ' a , S > {
287
+ macro_rules! invoice_builder_methods { (
288
+ $self: ident, $self_type: ty, $return_type: ty, $return_value: expr
289
+ ) => {
288
290
pub ( crate ) fn amount_msats(
289
291
invoice_request: & InvoiceRequest
290
292
) -> Result <u64 , Bolt12SemanticError > {
@@ -326,57 +328,69 @@ impl<'a, S: SigningPubkeyStrategy> InvoiceBuilder<'a, S> {
326
328
/// [`Bolt12Invoice::is_expired`].
327
329
///
328
330
/// Successive calls to this method will override the previous setting.
329
- pub fn relative_expiry ( mut self , relative_expiry_secs : u32 ) -> Self {
331
+ pub fn relative_expiry( mut $ self: $self_type , relative_expiry_secs: u32 ) -> $return_type {
330
332
let relative_expiry = Duration :: from_secs( relative_expiry_secs as u64 ) ;
331
- self . invoice . fields_mut ( ) . relative_expiry = Some ( relative_expiry) ;
332
- self
333
+ $ self. invoice. fields_mut( ) . relative_expiry = Some ( relative_expiry) ;
334
+ $return_value
333
335
}
334
336
335
337
/// Adds a P2WSH address to [`Bolt12Invoice::fallbacks`].
336
338
///
337
339
/// Successive calls to this method will add another address. Caller is responsible for not
338
340
/// adding duplicate addresses and only calling if capable of receiving to P2WSH addresses.
339
- pub fn fallback_v0_p2wsh ( mut self , script_hash : & WScriptHash ) -> Self {
341
+ pub fn fallback_v0_p2wsh( mut $ self: $self_type , script_hash: & WScriptHash ) -> $return_type {
340
342
let address = FallbackAddress {
341
343
version: WitnessVersion :: V0 . to_num( ) ,
342
344
program: Vec :: from( script_hash. to_byte_array( ) ) ,
343
345
} ;
344
- self . invoice . fields_mut ( ) . fallbacks . get_or_insert_with ( Vec :: new) . push ( address) ;
345
- self
346
+ $ self. invoice. fields_mut( ) . fallbacks. get_or_insert_with( Vec :: new) . push( address) ;
347
+ $return_value
346
348
}
347
349
348
350
/// Adds a P2WPKH address to [`Bolt12Invoice::fallbacks`].
349
351
///
350
352
/// Successive calls to this method will add another address. Caller is responsible for not
351
353
/// adding duplicate addresses and only calling if capable of receiving to P2WPKH addresses.
352
- pub fn fallback_v0_p2wpkh ( mut self , pubkey_hash : & WPubkeyHash ) -> Self {
354
+ pub fn fallback_v0_p2wpkh( mut $ self: $self_type , pubkey_hash: & WPubkeyHash ) -> $return_type {
353
355
let address = FallbackAddress {
354
356
version: WitnessVersion :: V0 . to_num( ) ,
355
357
program: Vec :: from( pubkey_hash. to_byte_array( ) ) ,
356
358
} ;
357
- self . invoice . fields_mut ( ) . fallbacks . get_or_insert_with ( Vec :: new) . push ( address) ;
358
- self
359
+ $ self. invoice. fields_mut( ) . fallbacks. get_or_insert_with( Vec :: new) . push( address) ;
360
+ $return_value
359
361
}
360
362
361
363
/// Adds a P2TR address to [`Bolt12Invoice::fallbacks`].
362
364
///
363
365
/// Successive calls to this method will add another address. Caller is responsible for not
364
366
/// adding duplicate addresses and only calling if capable of receiving to P2TR addresses.
365
- pub fn fallback_v1_p2tr_tweaked ( mut self , output_key : & TweakedPublicKey ) -> Self {
367
+ pub fn fallback_v1_p2tr_tweaked( mut $ self: $self_type , output_key: & TweakedPublicKey ) -> $return_type {
366
368
let address = FallbackAddress {
367
369
version: WitnessVersion :: V1 . to_num( ) ,
368
370
program: Vec :: from( & output_key. serialize( ) [ ..] ) ,
369
371
} ;
370
- self . invoice . fields_mut ( ) . fallbacks . get_or_insert_with ( Vec :: new) . push ( address) ;
371
- self
372
+ $ self. invoice. fields_mut( ) . fallbacks. get_or_insert_with( Vec :: new) . push( address) ;
373
+ $return_value
372
374
}
373
375
374
376
/// Sets [`Bolt12Invoice::invoice_features`] to indicate MPP may be used. Otherwise, MPP is
375
377
/// disallowed.
376
- pub fn allow_mpp ( mut self ) -> Self {
377
- self . invoice . fields_mut ( ) . features . set_basic_mpp_optional ( ) ;
378
- self
378
+ pub fn allow_mpp( mut $ self: $self_type ) -> $return_type {
379
+ $ self. invoice. fields_mut( ) . features. set_basic_mpp_optional( ) ;
380
+ $return_value
379
381
}
382
+ } }
383
+
384
+ impl < ' a > InvoiceBuilder < ' a , ExplicitSigningPubkey > {
385
+ invoice_explicit_signing_pubkey_builder_methods ! ( self , Self ) ;
386
+ }
387
+
388
+ impl < ' a > InvoiceBuilder < ' a , DerivedSigningPubkey > {
389
+ invoice_derived_signing_pubkey_builder_methods ! ( self , Self ) ;
390
+ }
391
+
392
+ impl < ' a , S : SigningPubkeyStrategy > InvoiceBuilder < ' a , S > {
393
+ invoice_builder_methods ! ( self , Self , Self , self ) ;
380
394
}
381
395
382
396
/// A semantically valid [`Bolt12Invoice`] that hasn't been signed.
@@ -412,32 +426,38 @@ impl UnsignedBolt12Invoice {
412
426
pub fn tagged_hash ( & self ) -> & TaggedHash {
413
427
& self . tagged_hash
414
428
}
429
+ }
415
430
431
+ macro_rules! unsigned_invoice_sign_method { ( $self: ident, $self_type: ty) => {
416
432
/// Signs the [`TaggedHash`] of the invoice using the given function.
417
433
///
418
434
/// Note: The hash computation may have included unknown, odd TLV records.
419
435
///
420
436
/// This is not exported to bindings users as functions aren't currently mapped.
421
- pub fn sign < F , E > ( mut self , sign : F ) -> Result < Bolt12Invoice , SignError < E > >
437
+ pub fn sign<F , E >( mut $ self: $self_type , sign: F ) -> Result <Bolt12Invoice , SignError <E >>
422
438
where
423
439
F : FnOnce ( & Self ) -> Result <Signature , E >
424
440
{
425
- let pubkey = self . contents . fields ( ) . signing_pubkey ;
426
- let signature = merkle:: sign_message ( sign, & self , pubkey) ?;
441
+ let pubkey = $ self. contents. fields( ) . signing_pubkey;
442
+ let signature = merkle:: sign_message( sign, & $ self, pubkey) ?;
427
443
428
444
// Append the signature TLV record to the bytes.
429
445
let signature_tlv_stream = SignatureTlvStreamRef {
430
446
signature: Some ( & signature) ,
431
447
} ;
432
- signature_tlv_stream. write ( & mut self . bytes ) . unwrap ( ) ;
448
+ signature_tlv_stream. write( & mut $ self. bytes) . unwrap( ) ;
433
449
434
450
Ok ( Bolt12Invoice {
435
- bytes : self . bytes ,
436
- contents : self . contents ,
451
+ bytes: $ self. bytes,
452
+ contents: $ self. contents,
437
453
signature,
438
- tagged_hash : self . tagged_hash ,
454
+ tagged_hash: $ self. tagged_hash,
439
455
} )
440
456
}
457
+ } }
458
+
459
+ impl UnsignedBolt12Invoice {
460
+ unsigned_invoice_sign_method ! ( self , Self ) ;
441
461
}
442
462
443
463
impl AsRef < TaggedHash > for UnsignedBolt12Invoice {
0 commit comments