22
22
//!
23
23
//! use bitcoin::hashes::Hash;
24
24
//! use bitcoin::secp256k1::{KeyPair, PublicKey, Secp256k1, SecretKey};
25
+ //! # use lightning::offers::invoice::{ExplicitSigningPubkey, InvoiceBuilder};
25
26
//! use core::convert::{Infallible, TryFrom};
26
27
//! use lightning::offers::invoice_request::InvoiceRequest;
27
28
//! use lightning::offers::refund::Refund;
44
45
//! let mut buffer = Vec::new();
45
46
//!
46
47
//! // Invoice for the "offer to be paid" flow.
48
+ //! # <InvoiceBuilder<ExplicitSigningPubkey>>::from(
47
49
//! InvoiceRequest::try_from(bytes)?
48
50
#![ cfg_attr( feature = "std" , doc = "
49
51
.respond_with(payment_paths, payment_hash)?
50
52
" ) ]
51
53
#![ cfg_attr( not( feature = "std" ) , doc = "
52
54
.respond_with_no_std(payment_paths, payment_hash, core::time::Duration::from_secs(0))?
53
55
" ) ]
56
+ //! # )
54
57
//! .relative_expiry(3600)
55
58
//! .allow_mpp()
56
59
//! .fallback_v0_p2wpkh(&wpubkey_hash)
74
77
//! # let mut buffer = Vec::new();
75
78
//!
76
79
//! // Invoice for the "offer for money" flow.
80
+ //! # <InvoiceBuilder<ExplicitSigningPubkey>>::from(
77
81
//! "lnr1qcp4256ypq"
78
82
//! .parse::<Refund>()?
79
83
#![ cfg_attr( feature = "std" , doc = "
82
86
#![ cfg_attr( not( feature = "std" ) , doc = "
83
87
.respond_with_no_std(payment_paths, payment_hash, pubkey, core::time::Duration::from_secs(0))?
84
88
" ) ]
89
+ //! # )
85
90
//! .relative_expiry(3600)
86
91
//! .allow_mpp()
87
92
//! .fallback_v0_p2wpkh(&wpubkey_hash)
@@ -151,6 +156,38 @@ pub struct InvoiceBuilder<'a, S: SigningPubkeyStrategy> {
151
156
signing_pubkey_strategy : S ,
152
157
}
153
158
159
+ /// Builds a [`Bolt12Invoice`] from either:
160
+ /// - an [`InvoiceRequest`] for the "offer to be paid" flow or
161
+ /// - a [`Refund`] for the "offer for money" flow.
162
+ ///
163
+ /// See [module-level documentation] for usage.
164
+ ///
165
+ /// [`InvoiceRequest`]: crate::offers::invoice_request::InvoiceRequest
166
+ /// [`Refund`]: crate::offers::refund::Refund
167
+ /// [module-level documentation]: self
168
+ #[ cfg( c_bindings) ]
169
+ pub struct InvoiceWithExplicitSigningPubkeyBuilder < ' a > {
170
+ invreq_bytes : & ' a Vec < u8 > ,
171
+ invoice : InvoiceContents ,
172
+ signing_pubkey_strategy : ExplicitSigningPubkey ,
173
+ }
174
+
175
+ /// Builds a [`Bolt12Invoice`] from either:
176
+ /// - an [`InvoiceRequest`] for the "offer to be paid" flow or
177
+ /// - a [`Refund`] for the "offer for money" flow.
178
+ ///
179
+ /// See [module-level documentation] for usage.
180
+ ///
181
+ /// [`InvoiceRequest`]: crate::offers::invoice_request::InvoiceRequest
182
+ /// [`Refund`]: crate::offers::refund::Refund
183
+ /// [module-level documentation]: self
184
+ #[ cfg( c_bindings) ]
185
+ pub struct InvoiceWithDerivedSigningPubkeyBuilder < ' a > {
186
+ invreq_bytes : & ' a Vec < u8 > ,
187
+ invoice : InvoiceContents ,
188
+ signing_pubkey_strategy : DerivedSigningPubkey ,
189
+ }
190
+
154
191
/// Indicates how [`Bolt12Invoice::signing_pubkey`] was set.
155
192
///
156
193
/// This is not exported to bindings users as builder patterns don't map outside of move semantics.
@@ -216,8 +253,13 @@ macro_rules! invoice_explicit_signing_pubkey_builder_methods { ($self: ident, $s
216
253
}
217
254
}
218
255
219
- let InvoiceBuilder { invreq_bytes, invoice, .. } = $self;
220
- Ok ( UnsignedBolt12Invoice :: new( invreq_bytes, invoice) )
256
+ let Self { invreq_bytes, invoice, .. } = $self;
257
+ #[ cfg( not( c_bindings) ) ] {
258
+ Ok ( UnsignedBolt12Invoice :: new( invreq_bytes, invoice) )
259
+ }
260
+ #[ cfg( c_bindings) ] {
261
+ Ok ( UnsignedBolt12Invoice :: new( invreq_bytes, invoice. clone( ) ) )
262
+ }
221
263
}
222
264
} }
223
265
@@ -272,10 +314,13 @@ macro_rules! invoice_derived_signing_pubkey_builder_methods { (
272
314
}
273
315
}
274
316
275
- let InvoiceBuilder {
317
+ let Self {
276
318
invreq_bytes, invoice, signing_pubkey_strategy: DerivedSigningPubkey ( keys)
277
319
} = $self;
320
+ #[ cfg( not( c_bindings) ) ]
278
321
let unsigned_invoice = UnsignedBolt12Invoice :: new( invreq_bytes, invoice) ;
322
+ #[ cfg( c_bindings) ]
323
+ let unsigned_invoice = UnsignedBolt12Invoice :: new( invreq_bytes, invoice. clone( ) ) ;
279
324
280
325
let invoice = unsigned_invoice
281
326
. sign:: <_, Infallible >(
@@ -287,7 +332,7 @@ macro_rules! invoice_derived_signing_pubkey_builder_methods { (
287
332
} }
288
333
289
334
macro_rules! invoice_builder_methods { (
290
- $self: ident, $self_type: ty, $return_type: ty, $return_value: expr
335
+ $self: ident, $self_type: ty, $return_type: ty, $return_value: expr, $type_param : ty
291
336
) => {
292
337
pub ( crate ) fn amount_msats(
293
338
invoice_request: & InvoiceRequest
@@ -316,7 +361,7 @@ macro_rules! invoice_builder_methods { (
316
361
}
317
362
318
363
fn new(
319
- invreq_bytes: & ' a Vec <u8 >, contents: InvoiceContents , signing_pubkey_strategy: S
364
+ invreq_bytes: & ' a Vec <u8 >, contents: InvoiceContents , signing_pubkey_strategy: $type_param
320
365
) -> Result <Self , Bolt12SemanticError > {
321
366
if contents. fields( ) . payment_paths. is_empty( ) {
322
367
return Err ( Bolt12SemanticError :: MissingPaths ) ;
@@ -392,7 +437,59 @@ impl<'a> InvoiceBuilder<'a, DerivedSigningPubkey> {
392
437
}
393
438
394
439
impl < ' a , S : SigningPubkeyStrategy > InvoiceBuilder < ' a , S > {
395
- invoice_builder_methods ! ( self , Self , Self , self ) ;
440
+ invoice_builder_methods ! ( self , Self , Self , self , S ) ;
441
+ }
442
+
443
+ #[ cfg( all( c_bindings, not( test) ) ) ]
444
+ impl < ' a > InvoiceWithExplicitSigningPubkeyBuilder < ' a > {
445
+ invoice_explicit_signing_pubkey_builder_methods ! ( self , & mut Self ) ;
446
+ invoice_builder_methods ! ( self , & mut Self , ( ) , ( ) , ExplicitSigningPubkey ) ;
447
+ }
448
+
449
+ #[ cfg( all( c_bindings, test) ) ]
450
+ impl < ' a > InvoiceWithExplicitSigningPubkeyBuilder < ' a > {
451
+ invoice_explicit_signing_pubkey_builder_methods ! ( self , & mut Self ) ;
452
+ invoice_builder_methods ! ( self , & mut Self , & mut Self , self , ExplicitSigningPubkey ) ;
453
+ }
454
+
455
+ #[ cfg( all( c_bindings, not( test) ) ) ]
456
+ impl < ' a > InvoiceWithDerivedSigningPubkeyBuilder < ' a > {
457
+ invoice_derived_signing_pubkey_builder_methods ! ( self , & mut Self , secp256k1:: All ) ;
458
+ invoice_builder_methods ! ( self , & mut Self , ( ) , ( ) , DerivedSigningPubkey ) ;
459
+ }
460
+
461
+ #[ cfg( all( c_bindings, test) ) ]
462
+ impl < ' a > InvoiceWithDerivedSigningPubkeyBuilder < ' a > {
463
+ invoice_derived_signing_pubkey_builder_methods ! ( self , & mut Self , secp256k1:: All ) ;
464
+ invoice_builder_methods ! ( self , & mut Self , & mut Self , self , DerivedSigningPubkey ) ;
465
+ }
466
+
467
+ #[ cfg( c_bindings) ]
468
+ impl < ' a > From < InvoiceWithExplicitSigningPubkeyBuilder < ' a > >
469
+ for InvoiceBuilder < ' a , ExplicitSigningPubkey > {
470
+ fn from ( builder : InvoiceWithExplicitSigningPubkeyBuilder < ' a > ) -> Self {
471
+ let InvoiceWithExplicitSigningPubkeyBuilder {
472
+ invreq_bytes, invoice, signing_pubkey_strategy,
473
+ } = builder;
474
+
475
+ Self {
476
+ invreq_bytes, invoice, signing_pubkey_strategy,
477
+ }
478
+ }
479
+ }
480
+
481
+ #[ cfg( c_bindings) ]
482
+ impl < ' a > From < InvoiceWithDerivedSigningPubkeyBuilder < ' a > >
483
+ for InvoiceBuilder < ' a , DerivedSigningPubkey > {
484
+ fn from ( builder : InvoiceWithDerivedSigningPubkeyBuilder < ' a > ) -> Self {
485
+ let InvoiceWithDerivedSigningPubkeyBuilder {
486
+ invreq_bytes, invoice, signing_pubkey_strategy,
487
+ } = builder;
488
+
489
+ Self {
490
+ invreq_bytes, invoice, signing_pubkey_strategy,
491
+ }
492
+ }
396
493
}
397
494
398
495
/// A semantically valid [`Bolt12Invoice`] that hasn't been signed.
@@ -1685,7 +1782,7 @@ mod tests {
1685
1782
if let Err ( e) = invoice_request. clone ( )
1686
1783
. verify ( & expanded_key, & secp_ctx) . unwrap ( )
1687
1784
. respond_using_derived_keys_no_std ( payment_paths ( ) , payment_hash ( ) , now ( ) ) . unwrap ( )
1688
- . build_and_sign ( & secp_ctx)
1785
+ . build_and_sign :: < secp256k1 :: All > ( & secp_ctx)
1689
1786
{
1690
1787
panic ! ( "error building invoice: {:?}" , e) ;
1691
1788
}
@@ -1726,7 +1823,7 @@ mod tests {
1726
1823
payment_paths ( ) , payment_hash ( ) , now ( ) , & expanded_key, & entropy
1727
1824
)
1728
1825
. unwrap ( )
1729
- . build_and_sign ( & secp_ctx)
1826
+ . build_and_sign :: < secp256k1 :: All > ( & secp_ctx)
1730
1827
{
1731
1828
panic ! ( "error building invoice: {:?}" , e) ;
1732
1829
}
@@ -2122,8 +2219,13 @@ mod tests {
2122
2219
. request_invoice ( vec ! [ 1 ; 32 ] , payer_pubkey ( ) ) . unwrap ( )
2123
2220
. build ( ) . unwrap ( )
2124
2221
. sign ( payer_sign) . unwrap ( ) ;
2222
+ #[ cfg( not( c_bindings) ) ]
2223
+ let invoice_builder = invoice_request
2224
+ . respond_with_no_std ( payment_paths ( ) , payment_hash ( ) , now ( ) ) . unwrap ( ) ;
2225
+ #[ cfg( c_bindings) ]
2125
2226
let mut invoice_builder = invoice_request
2126
- . respond_with_no_std ( payment_paths ( ) , payment_hash ( ) , now ( ) ) . unwrap ( )
2227
+ . respond_with_no_std ( payment_paths ( ) , payment_hash ( ) , now ( ) ) . unwrap ( ) ;
2228
+ let mut invoice_builder = invoice_builder
2127
2229
. fallback_v0_p2wsh ( & script. wscript_hash ( ) )
2128
2230
. fallback_v0_p2wpkh ( & pubkey. wpubkey_hash ( ) . unwrap ( ) )
2129
2231
. fallback_v1_p2tr_tweaked ( & tweaked_pubkey) ;
0 commit comments