@@ -117,7 +117,7 @@ pub struct DerivedPayerId {}
117
117
impl PayerIdStrategy for ExplicitPayerId { }
118
118
impl PayerIdStrategy for DerivedPayerId { }
119
119
120
- impl < ' a , ' b , T : secp256k1 :: Signing > InvoiceRequestBuilder < ' a , ' b , ExplicitPayerId , T > {
120
+ macro_rules! invoice_request_explicit_payer_id_builder_methods { ( $self : ident , $self_type : ty ) = > {
121
121
pub ( super ) fn new( offer: & ' a Offer , metadata: Vec <u8 >, payer_id: PublicKey ) -> Self {
122
122
Self {
123
123
offer,
@@ -147,14 +147,14 @@ impl<'a, 'b, T: secp256k1::Signing> InvoiceRequestBuilder<'a, 'b, ExplicitPayerI
147
147
148
148
/// Builds an unsigned [`InvoiceRequest`] after checking for valid semantics. It can be signed
149
149
/// by [`UnsignedInvoiceRequest::sign`].
150
- pub fn build ( self ) -> Result < UnsignedInvoiceRequest , Bolt12SemanticError > {
151
- let ( unsigned_invoice_request, keys, _) = self . build_with_checks ( ) ?;
150
+ pub fn build( $ self: $self_type ) -> Result <UnsignedInvoiceRequest , Bolt12SemanticError > {
151
+ let ( unsigned_invoice_request, keys, _) = $ self. build_with_checks( ) ?;
152
152
debug_assert!( keys. is_none( ) ) ;
153
153
Ok ( unsigned_invoice_request)
154
154
}
155
- }
155
+ } }
156
156
157
- impl < ' a , ' b , T : secp256k1 :: Signing > InvoiceRequestBuilder < ' a , ' b , DerivedPayerId , T > {
157
+ macro_rules! invoice_request_derived_payer_id_builder_methods { ( $self : ident , $self_type : ty ) = > {
158
158
pub ( super ) fn deriving_payer_id<ES : Deref >(
159
159
offer: & ' a Offer , expanded_key: & ExpandedKey , entropy_source: ES ,
160
160
secp_ctx: & ' b Secp256k1 <T >, payment_id: PaymentId
@@ -173,8 +173,8 @@ impl<'a, 'b, T: secp256k1::Signing> InvoiceRequestBuilder<'a, 'b, DerivedPayerId
173
173
}
174
174
175
175
/// Builds a signed [`InvoiceRequest`] after checking for valid semantics.
176
- pub fn build_and_sign ( self ) -> Result < InvoiceRequest , Bolt12SemanticError > {
177
- let ( unsigned_invoice_request, keys, secp_ctx) = self . build_with_checks ( ) ?;
176
+ pub fn build_and_sign( $ self: $self_type ) -> Result <InvoiceRequest , Bolt12SemanticError > {
177
+ let ( unsigned_invoice_request, keys, secp_ctx) = $ self. build_with_checks( ) ?;
178
178
debug_assert!( keys. is_some( ) ) ;
179
179
180
180
let secp_ctx = secp_ctx. unwrap( ) ;
@@ -186,9 +186,11 @@ impl<'a, 'b, T: secp256k1::Signing> InvoiceRequestBuilder<'a, 'b, DerivedPayerId
186
186
. unwrap( ) ;
187
187
Ok ( invoice_request)
188
188
}
189
- }
189
+ } }
190
190
191
- impl < ' a , ' b , P : PayerIdStrategy , T : secp256k1:: Signing > InvoiceRequestBuilder < ' a , ' b , P , T > {
191
+ macro_rules! invoice_request_builder_methods { (
192
+ $self: ident, $self_type: ty, $return_type: ty, $return_value: expr
193
+ ) => {
192
194
fn create_contents( offer: & Offer , metadata: Metadata ) -> InvoiceRequestContentsWithoutPayerId {
193
195
let offer = offer. contents. clone( ) ;
194
196
InvoiceRequestContentsWithoutPayerId {
@@ -202,22 +204,22 @@ impl<'a, 'b, P: PayerIdStrategy, T: secp256k1::Signing> InvoiceRequestBuilder<'a
202
204
/// by the offer.
203
205
///
204
206
/// Successive calls to this method will override the previous setting.
205
- pub fn chain ( self , network : Network ) -> Result < Self , Bolt12SemanticError > {
206
- self . chain_hash ( ChainHash :: using_genesis_block ( network) )
207
+ pub fn chain( $ self: $self_type , network: Network ) -> Result <$return_type , Bolt12SemanticError > {
208
+ $ self. chain_hash( ChainHash :: using_genesis_block( network) )
207
209
}
208
210
209
211
/// Sets the [`InvoiceRequest::chain`] for paying an invoice. If not called, the chain hash of
210
212
/// [`Network::Bitcoin`] is assumed. Errors if the chain for `network` is not supported by the
211
213
/// offer.
212
214
///
213
215
/// Successive calls to this method will override the previous setting.
214
- pub ( crate ) fn chain_hash ( mut self , chain : ChainHash ) -> Result < Self , Bolt12SemanticError > {
215
- if !self . offer . supports_chain ( chain) {
216
+ pub ( crate ) fn chain_hash( mut $ self: $self_type , chain: ChainHash ) -> Result <$return_type , Bolt12SemanticError > {
217
+ if !$ self. offer. supports_chain( chain) {
216
218
return Err ( Bolt12SemanticError :: UnsupportedChain ) ;
217
219
}
218
220
219
- self . invoice_request . chain = Some ( chain) ;
220
- Ok ( self )
221
+ $ self. invoice_request. chain = Some ( chain) ;
222
+ Ok ( $return_value )
221
223
}
222
224
223
225
/// Sets the [`InvoiceRequest::amount_msats`] for paying an invoice. Errors if `amount_msats` is
@@ -226,130 +228,147 @@ impl<'a, 'b, P: PayerIdStrategy, T: secp256k1::Signing> InvoiceRequestBuilder<'a
226
228
/// Successive calls to this method will override the previous setting.
227
229
///
228
230
/// [`quantity`]: Self::quantity
229
- pub fn amount_msats ( mut self , amount_msats : u64 ) -> Result < Self , Bolt12SemanticError > {
230
- self . invoice_request . offer . check_amount_msats_for_quantity (
231
- Some ( amount_msats) , self . invoice_request . quantity
231
+ pub fn amount_msats( mut $ self: $self_type , amount_msats: u64 ) -> Result <$return_type , Bolt12SemanticError > {
232
+ $ self. invoice_request. offer. check_amount_msats_for_quantity(
233
+ Some ( amount_msats) , $ self. invoice_request. quantity
232
234
) ?;
233
- self . invoice_request . amount_msats = Some ( amount_msats) ;
234
- Ok ( self )
235
+ $ self. invoice_request. amount_msats = Some ( amount_msats) ;
236
+ Ok ( $return_value )
235
237
}
236
238
237
239
/// Sets [`InvoiceRequest::quantity`] of items. If not set, `1` is assumed. Errors if `quantity`
238
240
/// does not conform to [`Offer::is_valid_quantity`].
239
241
///
240
242
/// Successive calls to this method will override the previous setting.
241
- pub fn quantity ( mut self , quantity : u64 ) -> Result < Self , Bolt12SemanticError > {
242
- self . invoice_request . offer . check_quantity ( Some ( quantity) ) ?;
243
- self . invoice_request . quantity = Some ( quantity) ;
244
- Ok ( self )
243
+ pub fn quantity( mut $ self: $self_type , quantity: u64 ) -> Result <$return_type , Bolt12SemanticError > {
244
+ $ self. invoice_request. offer. check_quantity( Some ( quantity) ) ?;
245
+ $ self. invoice_request. quantity = Some ( quantity) ;
246
+ Ok ( $return_value )
245
247
}
246
248
247
249
/// Sets the [`InvoiceRequest::payer_note`].
248
250
///
249
251
/// Successive calls to this method will override the previous setting.
250
- pub fn payer_note ( mut self , payer_note : String ) -> Self {
251
- self . invoice_request . payer_note = Some ( payer_note) ;
252
- self
252
+ pub fn payer_note( mut $ self: $self_type , payer_note: String ) -> $return_type {
253
+ $ self. invoice_request. payer_note = Some ( payer_note) ;
254
+ $return_value
253
255
}
254
256
255
- fn build_with_checks ( mut self ) -> Result <
257
+ fn build_with_checks( mut $ self: $self_type ) -> Result <
256
258
( UnsignedInvoiceRequest , Option <KeyPair >, Option <& ' b Secp256k1 <T >>) ,
257
259
Bolt12SemanticError
258
260
> {
259
261
#[ cfg( feature = "std" ) ] {
260
- if self . offer . is_expired ( ) {
262
+ if $ self. offer. is_expired( ) {
261
263
return Err ( Bolt12SemanticError :: AlreadyExpired ) ;
262
264
}
263
265
}
264
266
265
- let chain = self . invoice_request . chain ( ) ;
266
- if !self . offer . supports_chain ( chain) {
267
+ let chain = $ self. invoice_request. chain( ) ;
268
+ if !$ self. offer. supports_chain( chain) {
267
269
return Err ( Bolt12SemanticError :: UnsupportedChain ) ;
268
270
}
269
271
270
- if chain == self . offer . implied_chain ( ) {
271
- self . invoice_request . chain = None ;
272
+ if chain == $ self. offer. implied_chain( ) {
273
+ $ self. invoice_request. chain = None ;
272
274
}
273
275
274
- if self . offer . amount ( ) . is_none ( ) && self . invoice_request . amount_msats . is_none ( ) {
276
+ if $ self. offer. amount( ) . is_none( ) && $ self. invoice_request. amount_msats. is_none( ) {
275
277
return Err ( Bolt12SemanticError :: MissingAmount ) ;
276
278
}
277
279
278
- self . invoice_request . offer . check_quantity ( self . invoice_request . quantity ) ?;
279
- self . invoice_request . offer . check_amount_msats_for_quantity (
280
- self . invoice_request . amount_msats , self . invoice_request . quantity
280
+ $ self. invoice_request. offer. check_quantity( $ self. invoice_request. quantity) ?;
281
+ $ self. invoice_request. offer. check_amount_msats_for_quantity(
282
+ $ self. invoice_request. amount_msats, $ self. invoice_request. quantity
281
283
) ?;
282
284
283
- Ok ( self . build_without_checks ( ) )
285
+ Ok ( $ self. build_without_checks( ) )
284
286
}
285
287
286
- fn build_without_checks ( mut self ) ->
288
+ fn build_without_checks( mut $ self: $self_type ) ->
287
289
( UnsignedInvoiceRequest , Option <KeyPair >, Option <& ' b Secp256k1 <T >>)
288
290
{
289
291
// Create the metadata for stateless verification of a Bolt12Invoice.
290
292
let mut keys = None ;
291
- let secp_ctx = self . secp_ctx . clone ( ) ;
292
- if self . invoice_request . payer . 0 . has_derivation_material ( ) {
293
- let mut metadata = core:: mem:: take ( & mut self . invoice_request . payer . 0 ) ;
293
+ let secp_ctx = $ self. secp_ctx. clone( ) ;
294
+ if $ self. invoice_request. payer. 0 . has_derivation_material( ) {
295
+ let mut metadata = core:: mem:: take( & mut $ self. invoice_request. payer. 0 ) ;
294
296
295
- let mut tlv_stream = self . invoice_request . as_tlv_stream ( ) ;
297
+ let mut tlv_stream = $ self. invoice_request. as_tlv_stream( ) ;
296
298
debug_assert!( tlv_stream. 2 . payer_id. is_none( ) ) ;
297
299
tlv_stream. 0 . metadata = None ;
298
300
if !metadata. derives_payer_keys( ) {
299
- tlv_stream. 2 . payer_id = self . payer_id . as_ref ( ) ;
301
+ tlv_stream. 2 . payer_id = $ self. payer_id. as_ref( ) ;
300
302
}
301
303
302
- let ( derived_metadata, derived_keys) = metadata. derive_from ( tlv_stream, self . secp_ctx ) ;
304
+ let ( derived_metadata, derived_keys) = metadata. derive_from( tlv_stream, $ self. secp_ctx) ;
303
305
metadata = derived_metadata;
304
306
keys = derived_keys;
305
307
if let Some ( keys) = keys {
306
- debug_assert ! ( self . payer_id. is_none( ) ) ;
307
- self . payer_id = Some ( keys. public_key ( ) ) ;
308
+ debug_assert!( $ self. payer_id. is_none( ) ) ;
309
+ $ self. payer_id = Some ( keys. public_key( ) ) ;
308
310
}
309
311
310
- self . invoice_request . payer . 0 = metadata;
312
+ $ self. invoice_request. payer. 0 = metadata;
311
313
}
312
314
313
- debug_assert ! ( self . invoice_request. payer. 0 . as_bytes( ) . is_some( ) ) ;
314
- debug_assert ! ( self . payer_id. is_some( ) ) ;
315
- let payer_id = self . payer_id . unwrap ( ) ;
315
+ debug_assert!( $ self. invoice_request. payer. 0 . as_bytes( ) . is_some( ) ) ;
316
+ debug_assert!( $ self. payer_id. is_some( ) ) ;
317
+ let payer_id = $ self. payer_id. unwrap( ) ;
316
318
317
319
let invoice_request = InvoiceRequestContents {
318
- inner : self . invoice_request ,
320
+ inner: $ self. invoice_request,
319
321
payer_id,
320
322
} ;
321
- let unsigned_invoice_request = UnsignedInvoiceRequest :: new ( self . offer , invoice_request) ;
323
+ let unsigned_invoice_request = UnsignedInvoiceRequest :: new( $ self. offer, invoice_request) ;
322
324
323
325
( unsigned_invoice_request, keys, secp_ctx)
324
326
}
325
- }
327
+ } }
326
328
327
329
#[ cfg( test) ]
328
- impl < ' a , ' b , P : PayerIdStrategy , T : secp256k1:: Signing > InvoiceRequestBuilder < ' a , ' b , P , T > {
329
- fn chain_unchecked ( mut self , network : Network ) -> Self {
330
+ macro_rules! invoice_request_builder_test_methods { (
331
+ $self: ident, $self_type: ty, $return_type: ty, $return_value: expr
332
+ ) => {
333
+ fn chain_unchecked( mut $self: $self_type, network: Network ) -> $return_type {
330
334
let chain = ChainHash :: using_genesis_block( network) ;
331
- self . invoice_request . chain = Some ( chain) ;
332
- self
335
+ $ self. invoice_request. chain = Some ( chain) ;
336
+ $return_value
333
337
}
334
338
335
- fn amount_msats_unchecked ( mut self , amount_msats : u64 ) -> Self {
336
- self . invoice_request . amount_msats = Some ( amount_msats) ;
337
- self
339
+ fn amount_msats_unchecked( mut $ self: $self_type , amount_msats: u64 ) -> $return_type {
340
+ $ self. invoice_request. amount_msats = Some ( amount_msats) ;
341
+ $return_value
338
342
}
339
343
340
- fn features_unchecked ( mut self , features : InvoiceRequestFeatures ) -> Self {
341
- self . invoice_request . features = features;
342
- self
344
+ fn features_unchecked( mut $ self: $self_type , features: InvoiceRequestFeatures ) -> $return_type {
345
+ $ self. invoice_request. features = features;
346
+ $return_value
343
347
}
344
348
345
- fn quantity_unchecked ( mut self , quantity : u64 ) -> Self {
346
- self . invoice_request . quantity = Some ( quantity) ;
347
- self
349
+ fn quantity_unchecked( mut $ self: $self_type , quantity: u64 ) -> $return_type {
350
+ $ self. invoice_request. quantity = Some ( quantity) ;
351
+ $return_value
348
352
}
349
353
350
- pub ( super ) fn build_unchecked ( self ) -> UnsignedInvoiceRequest {
351
- self . build_without_checks ( ) . 0
354
+ pub ( super ) fn build_unchecked( $ self: $self_type ) -> UnsignedInvoiceRequest {
355
+ $ self. build_without_checks( ) . 0
352
356
}
357
+ } }
358
+
359
+ impl < ' a , ' b , T : secp256k1:: Signing > InvoiceRequestBuilder < ' a , ' b , ExplicitPayerId , T > {
360
+ invoice_request_explicit_payer_id_builder_methods ! ( self , Self ) ;
361
+ }
362
+
363
+ impl < ' a , ' b , T : secp256k1:: Signing > InvoiceRequestBuilder < ' a , ' b , DerivedPayerId , T > {
364
+ invoice_request_derived_payer_id_builder_methods ! ( self , Self ) ;
365
+ }
366
+
367
+ impl < ' a , ' b , P : PayerIdStrategy , T : secp256k1:: Signing > InvoiceRequestBuilder < ' a , ' b , P , T > {
368
+ invoice_request_builder_methods ! ( self , Self , Self , self ) ;
369
+
370
+ #[ cfg( test) ]
371
+ invoice_request_builder_test_methods ! ( self , Self , Self , self ) ;
353
372
}
354
373
355
374
/// A semantically valid [`InvoiceRequest`] that hasn't been signed.
@@ -385,31 +404,37 @@ impl UnsignedInvoiceRequest {
385
404
pub fn tagged_hash ( & self ) -> & TaggedHash {
386
405
& self . tagged_hash
387
406
}
407
+ }
388
408
409
+ macro_rules! unsigned_invoice_request_sign_method { ( $self: ident, $self_type: ty) => {
389
410
/// Signs the [`TaggedHash`] of the invoice request using the given function.
390
411
///
391
412
/// Note: The hash computation may have included unknown, odd TLV records.
392
413
///
393
414
/// This is not exported to bindings users as functions are not yet mapped.
394
- pub fn sign < F , E > ( mut self , sign : F ) -> Result < InvoiceRequest , SignError < E > >
415
+ pub fn sign<F , E >( mut $ self: $self_type , sign: F ) -> Result <InvoiceRequest , SignError <E >>
395
416
where
396
417
F : FnOnce ( & Self ) -> Result <Signature , E >
397
418
{
398
- let pubkey = self . contents . payer_id ;
399
- let signature = merkle:: sign_message ( sign, & self , pubkey) ?;
419
+ let pubkey = $ self. contents. payer_id;
420
+ let signature = merkle:: sign_message( sign, & $ self, pubkey) ?;
400
421
401
422
// Append the signature TLV record to the bytes.
402
423
let signature_tlv_stream = SignatureTlvStreamRef {
403
424
signature: Some ( & signature) ,
404
425
} ;
405
- signature_tlv_stream. write ( & mut self . bytes ) . unwrap ( ) ;
426
+ signature_tlv_stream. write( & mut $ self. bytes) . unwrap( ) ;
406
427
407
428
Ok ( InvoiceRequest {
408
- bytes : self . bytes ,
409
- contents : self . contents ,
429
+ bytes: $ self. bytes,
430
+ contents: $ self. contents,
410
431
signature,
411
432
} )
412
433
}
434
+ } }
435
+
436
+ impl UnsignedInvoiceRequest {
437
+ unsigned_invoice_request_sign_method ! ( self , Self ) ;
413
438
}
414
439
415
440
impl AsRef < TaggedHash > for UnsignedInvoiceRequest {
0 commit comments