@@ -1071,6 +1071,66 @@ impl<S: MutinyStorage> MutinyWallet<S> {
1071
1071
}
1072
1072
}
1073
1073
1074
+ /// Estimates the lightning fee for a transaction. Amount is either from the invoice
1075
+ /// if one is available or a passed in amount (priority). It will try to predict either
1076
+ /// sending the payment through a federation or through lightning, depending on balances.
1077
+ /// The amount and fee is in satoshis.
1078
+ /// Returns None if it has no good way to calculate fee.
1079
+ pub async fn estimate_ln_fee (
1080
+ & self ,
1081
+ inv : Option < & Bolt11Invoice > ,
1082
+ amt_sats : Option < u64 > ,
1083
+ ) -> Result < Option < u64 > , MutinyError > {
1084
+ let amt = if let Some ( a) = amt_sats {
1085
+ a
1086
+ } else if let Some ( i) = inv {
1087
+ if let Some ( a) = i. amount_milli_satoshis ( ) {
1088
+ a
1089
+ } else {
1090
+ return Err ( MutinyError :: BadAmountError ) ;
1091
+ }
1092
+ } else {
1093
+ return Err ( MutinyError :: BadAmountError ) ;
1094
+ } ;
1095
+
1096
+ // check balances first
1097
+ let total_balances = self . get_balance ( ) . await ?;
1098
+ if total_balances. federation > amt {
1099
+ let federation_ids = self . list_federation_ids ( ) . await ?;
1100
+ for federation_id in federation_ids {
1101
+ // Check if the federation has enough balance
1102
+ if let Some ( fedimint_client) = self . federations . read ( ) . await . get ( & federation_id) {
1103
+ let current_balance = fedimint_client. get_balance ( ) . await ?;
1104
+ log_info ! (
1105
+ self . logger,
1106
+ "current fedimint client balance: {}" ,
1107
+ current_balance
1108
+ ) ;
1109
+
1110
+ let fees = fedimint_client. gateway_fee ( ) . await ?;
1111
+ let max_spendable = max_spendable_amount ( current_balance, fees. clone ( ) )
1112
+ . map_or ( Err ( MutinyError :: InsufficientBalance ) , Ok ) ?;
1113
+
1114
+ if max_spendable >= amt {
1115
+ let prop_fee_msat =
1116
+ ( amt as f64 * 1_000.0 * fees. proportional_millionths as f64 )
1117
+ / 1_000_000.0 ;
1118
+
1119
+ let total_fee = fees. base_msat as f64 + prop_fee_msat;
1120
+ return Ok ( Some ( ( total_fee / 1_000.0 ) . floor ( ) as u64 ) ) ;
1121
+ }
1122
+ }
1123
+ }
1124
+ }
1125
+
1126
+ if total_balances. lightning > amt {
1127
+ // TODO try something to try to get lightning fee
1128
+ return Ok ( None ) ;
1129
+ }
1130
+
1131
+ Err ( MutinyError :: InsufficientBalance )
1132
+ }
1133
+
1074
1134
/// Creates a BIP 21 invoice. This creates a new address and a lightning invoice.
1075
1135
/// The lightning invoice may return errors related to the LSP. Check the error and
1076
1136
/// fallback to `get_new_address` and warn the user that Lightning is not available.
0 commit comments