@@ -200,7 +200,7 @@ pub struct ExplicitSigningPubkey {}
200
200
/// [`Bolt12Invoice::signing_pubkey`] was derived.
201
201
///
202
202
/// This is not exported to bindings users as builder patterns don't map outside of move semantics.
203
- pub struct DerivedSigningPubkey ( KeyPair ) ;
203
+ pub struct DerivedSigningPubkey ( pub ( super ) KeyPair ) ;
204
204
205
205
impl SigningPubkeyStrategy for ExplicitSigningPubkey { }
206
206
impl SigningPubkeyStrategy for DerivedSigningPubkey { }
@@ -958,14 +958,7 @@ impl InvoiceContents {
958
958
959
959
#[ cfg( feature = "std" ) ]
960
960
fn is_expired ( & self ) -> bool {
961
- let absolute_expiry = self . created_at ( ) . checked_add ( self . relative_expiry ( ) ) ;
962
- match absolute_expiry {
963
- Some ( seconds_from_epoch) => match SystemTime :: UNIX_EPOCH . elapsed ( ) {
964
- Ok ( elapsed) => elapsed > seconds_from_epoch,
965
- Err ( _) => false ,
966
- } ,
967
- None => false ,
968
- }
961
+ is_expired ( self . created_at ( ) , self . relative_expiry ( ) )
969
962
}
970
963
971
964
fn payment_hash ( & self ) -> PaymentHash {
@@ -977,36 +970,9 @@ impl InvoiceContents {
977
970
}
978
971
979
972
fn fallbacks ( & self ) -> Vec < Address > {
980
- let chain = self . chain ( ) ;
981
- let network = if chain == ChainHash :: using_genesis_block ( Network :: Bitcoin ) {
982
- Network :: Bitcoin
983
- } else if chain == ChainHash :: using_genesis_block ( Network :: Testnet ) {
984
- Network :: Testnet
985
- } else if chain == ChainHash :: using_genesis_block ( Network :: Signet ) {
986
- Network :: Signet
987
- } else if chain == ChainHash :: using_genesis_block ( Network :: Regtest ) {
988
- Network :: Regtest
989
- } else {
990
- return Vec :: new ( )
991
- } ;
992
-
993
- let to_valid_address = |address : & FallbackAddress | {
994
- let version = match WitnessVersion :: try_from ( address. version ) {
995
- Ok ( version) => version,
996
- Err ( _) => return None ,
997
- } ;
998
-
999
- let program = & address. program ;
1000
- let witness_program = match WitnessProgram :: new ( version, program. clone ( ) ) {
1001
- Ok ( witness_program) => witness_program,
1002
- Err ( _) => return None ,
1003
- } ;
1004
- Some ( Address :: new ( network, Payload :: WitnessProgram ( witness_program) ) )
1005
- } ;
1006
-
1007
973
self . fields ( ) . fallbacks
1008
974
. as_ref ( )
1009
- . map ( |fallbacks| fallbacks . iter ( ) . filter_map ( to_valid_address ) . collect ( ) )
975
+ . map ( |fallbacks| filter_fallbacks ( self . chain ( ) , fallbacks ) )
1010
976
. unwrap_or_else ( Vec :: new)
1011
977
}
1012
978
@@ -1075,6 +1041,50 @@ impl InvoiceContents {
1075
1041
}
1076
1042
}
1077
1043
1044
+ #[ cfg( feature = "std" ) ]
1045
+ pub ( super ) fn is_expired ( created_at : Duration , relative_expiry : Duration ) -> bool {
1046
+ let absolute_expiry = created_at. checked_add ( relative_expiry) ;
1047
+ match absolute_expiry {
1048
+ Some ( seconds_from_epoch) => match SystemTime :: UNIX_EPOCH . elapsed ( ) {
1049
+ Ok ( elapsed) => elapsed > seconds_from_epoch,
1050
+ Err ( _) => false ,
1051
+ } ,
1052
+ None => false ,
1053
+ }
1054
+ }
1055
+
1056
+ pub ( super ) fn filter_fallbacks (
1057
+ chain : ChainHash , fallbacks : & Vec < FallbackAddress >
1058
+ ) -> Vec < Address > {
1059
+ let network = if chain == ChainHash :: using_genesis_block ( Network :: Bitcoin ) {
1060
+ Network :: Bitcoin
1061
+ } else if chain == ChainHash :: using_genesis_block ( Network :: Testnet ) {
1062
+ Network :: Testnet
1063
+ } else if chain == ChainHash :: using_genesis_block ( Network :: Signet ) {
1064
+ Network :: Signet
1065
+ } else if chain == ChainHash :: using_genesis_block ( Network :: Regtest ) {
1066
+ Network :: Regtest
1067
+ } else {
1068
+ return Vec :: new ( )
1069
+ } ;
1070
+
1071
+ let to_valid_address = |address : & FallbackAddress | {
1072
+ let version = match WitnessVersion :: try_from ( address. version ) {
1073
+ Ok ( version) => version,
1074
+ Err ( _) => return None ,
1075
+ } ;
1076
+
1077
+ let program = & address. program ;
1078
+ let witness_program = match WitnessProgram :: new ( version, program. clone ( ) ) {
1079
+ Ok ( witness_program) => witness_program,
1080
+ Err ( _) => return None ,
1081
+ } ;
1082
+ Some ( Address :: new ( network, Payload :: WitnessProgram ( witness_program) ) )
1083
+ } ;
1084
+
1085
+ fallbacks. iter ( ) . filter_map ( to_valid_address) . collect ( )
1086
+ }
1087
+
1078
1088
impl InvoiceFields {
1079
1089
fn as_tlv_stream ( & self ) -> InvoiceTlvStreamRef {
1080
1090
let features = {
@@ -1154,12 +1164,12 @@ tlv_stream!(InvoiceTlvStream, InvoiceTlvStreamRef, 160..240, {
1154
1164
( 176 , node_id: PublicKey ) ,
1155
1165
} ) ;
1156
1166
1157
- type BlindedPathIter < ' a > = core:: iter:: Map <
1167
+ pub ( super ) type BlindedPathIter < ' a > = core:: iter:: Map <
1158
1168
core:: slice:: Iter < ' a , ( BlindedPayInfo , BlindedPath ) > ,
1159
1169
for <' r > fn ( & ' r ( BlindedPayInfo , BlindedPath ) ) -> & ' r BlindedPath ,
1160
1170
> ;
1161
1171
1162
- type BlindedPayInfoIter < ' a > = core:: iter:: Map <
1172
+ pub ( super ) type BlindedPayInfoIter < ' a > = core:: iter:: Map <
1163
1173
core:: slice:: Iter < ' a , ( BlindedPayInfo , BlindedPath ) > ,
1164
1174
for <' r > fn ( & ' r ( BlindedPayInfo , BlindedPath ) ) -> & ' r BlindedPayInfo ,
1165
1175
> ;
@@ -1205,8 +1215,8 @@ impl_writeable!(BlindedPayInfo, {
1205
1215
/// Wire representation for an on-chain fallback address.
1206
1216
#[ derive( Clone , Debug , PartialEq ) ]
1207
1217
pub ( super ) struct FallbackAddress {
1208
- version : u8 ,
1209
- program : Vec < u8 > ,
1218
+ pub ( super ) version : u8 ,
1219
+ pub ( super ) program : Vec < u8 > ,
1210
1220
}
1211
1221
1212
1222
impl_writeable ! ( FallbackAddress , { version, program } ) ;
@@ -1294,17 +1304,7 @@ impl TryFrom<PartialInvoiceTlvStream> for InvoiceContents {
1294
1304
} ,
1295
1305
) = tlv_stream;
1296
1306
1297
- let payment_paths = match ( blindedpay, paths) {
1298
- ( _, None ) => return Err ( Bolt12SemanticError :: MissingPaths ) ,
1299
- ( None , _) => return Err ( Bolt12SemanticError :: InvalidPayInfo ) ,
1300
- ( _, Some ( paths) ) if paths. is_empty ( ) => return Err ( Bolt12SemanticError :: MissingPaths ) ,
1301
- ( Some ( blindedpay) , Some ( paths) ) if paths. len ( ) != blindedpay. len ( ) => {
1302
- return Err ( Bolt12SemanticError :: InvalidPayInfo ) ;
1303
- } ,
1304
- ( Some ( blindedpay) , Some ( paths) ) => {
1305
- blindedpay. into_iter ( ) . zip ( paths. into_iter ( ) ) . collect :: < Vec < _ > > ( )
1306
- } ,
1307
- } ;
1307
+ let payment_paths = construct_payment_paths ( blindedpay, paths) ?;
1308
1308
1309
1309
let created_at = match created_at {
1310
1310
None => return Err ( Bolt12SemanticError :: MissingCreationTime ) ,
@@ -1372,6 +1372,22 @@ impl TryFrom<PartialInvoiceTlvStream> for InvoiceContents {
1372
1372
}
1373
1373
}
1374
1374
1375
+ pub ( super ) fn construct_payment_paths (
1376
+ blinded_payinfos : Option < Vec < BlindedPayInfo > > , blinded_paths : Option < Vec < BlindedPath > >
1377
+ ) -> Result < Vec < ( BlindedPayInfo , BlindedPath ) > , Bolt12SemanticError > {
1378
+ match ( blinded_payinfos, blinded_paths) {
1379
+ ( _, None ) => Err ( Bolt12SemanticError :: MissingPaths ) ,
1380
+ ( None , _) => Err ( Bolt12SemanticError :: InvalidPayInfo ) ,
1381
+ ( _, Some ( paths) ) if paths. is_empty ( ) => Err ( Bolt12SemanticError :: MissingPaths ) ,
1382
+ ( Some ( blindedpay) , Some ( paths) ) if paths. len ( ) != blindedpay. len ( ) => {
1383
+ Err ( Bolt12SemanticError :: InvalidPayInfo )
1384
+ } ,
1385
+ ( Some ( blindedpay) , Some ( paths) ) => {
1386
+ Ok ( blindedpay. into_iter ( ) . zip ( paths. into_iter ( ) ) . collect :: < Vec < _ > > ( ) )
1387
+ } ,
1388
+ }
1389
+ }
1390
+
1375
1391
#[ cfg( test) ]
1376
1392
mod tests {
1377
1393
use super :: { Bolt12Invoice , DEFAULT_RELATIVE_EXPIRY , FallbackAddress , FullInvoiceTlvStreamRef , InvoiceTlvStreamRef , SIGNATURE_TAG , UnsignedBolt12Invoice } ;
0 commit comments