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