@@ -411,6 +411,17 @@ impl MutinyInvoice {
411
411
}
412
412
}
413
413
414
+ /// FedimintSweepResult is the result of how much was swept and the fees paid.
415
+ #[ derive( Serialize , Deserialize , Clone , Debug ) ]
416
+ pub struct FedimintSweepResult {
417
+ /// The final amount that was swept.
418
+ /// This should be the amount specified if it was not max.
419
+ pub amount : u64 ,
420
+
421
+ /// The total fees paid for the sweep.
422
+ pub fees : Option < u64 > ,
423
+ }
424
+
414
425
pub struct MutinyWalletConfigBuilder {
415
426
xprivkey : ExtendedPrivKey ,
416
427
#[ cfg( target_arch = "wasm32" ) ]
@@ -1185,7 +1196,10 @@ impl<S: MutinyStorage> MutinyWallet<S> {
1185
1196
} )
1186
1197
}
1187
1198
1188
- pub async fn sweep_federation_balance ( & self , amount : Option < u64 > ) -> Result < ( ) , MutinyError > {
1199
+ pub async fn sweep_federation_balance (
1200
+ & self ,
1201
+ amount : Option < u64 > ,
1202
+ ) -> Result < FedimintSweepResult , MutinyError > {
1189
1203
// Attempt to create federation invoice if available and below max amount
1190
1204
let federation_ids = self . list_federation_ids ( ) . await ?;
1191
1205
if federation_ids. is_empty ( ) {
@@ -1202,10 +1216,13 @@ impl<S: MutinyStorage> MutinyWallet<S> {
1202
1216
// if the user provided amount, this is easy
1203
1217
if let Some ( amt) = amount {
1204
1218
let inv = self . node_manager . create_invoice ( amt) . await ?;
1205
- let _ = fedimint_client
1219
+ let pay_res = fedimint_client
1206
1220
. pay_invoice ( inv. bolt11 . expect ( "create inv had one job" ) , vec ! [ ] )
1207
1221
. await ?;
1208
- return Ok ( ( ) ) ;
1222
+ return Ok ( FedimintSweepResult {
1223
+ amount : amt,
1224
+ fees : pay_res. fees_paid ,
1225
+ } ) ;
1209
1226
}
1210
1227
1211
1228
// If no amount, figure out the amount to send over
@@ -1219,29 +1236,43 @@ impl<S: MutinyStorage> MutinyWallet<S> {
1219
1236
let fees = fedimint_client. gateway_fee ( ) . await ?;
1220
1237
let amt = max_spendable_amount ( current_balance, fees. clone ( ) )
1221
1238
. map_or ( Err ( MutinyError :: InsufficientBalance ) , Ok ) ?;
1222
- log_info ! ( self . logger, "max spendable: {}" , amt) ;
1239
+ log_debug ! ( self . logger, "max spendable: {}" , amt) ;
1223
1240
1224
1241
// try to get an invoice for this exact amount
1225
1242
let inv = self . node_manager . create_invoice ( amt) . await ?;
1226
1243
1244
+ // check if we can afford that invoice
1227
1245
let inv_amt = inv. amount_sats . ok_or ( MutinyError :: BadAmountError ) ?;
1228
- let inv_to_pay = if inv_amt > amt {
1229
- let new_amt = inv_amt - ( inv_amt - amt) ;
1230
- log_info ! ( self . logger, "adjusting amount to swap to: {}" , amt) ;
1231
- self . node_manager . create_invoice ( new_amt) . await ?
1246
+ let first_invoice_amount = if inv_amt > amt {
1247
+ log_debug ! ( self . logger, "adjusting amount to swap to: {}" , amt) ;
1248
+ inv_amt - ( inv_amt - amt)
1249
+ } else {
1250
+ inv_amt
1251
+ } ;
1252
+
1253
+ // if invoice amount changed, create a new invoice
1254
+ let inv_to_pay = if first_invoice_amount != inv_amt {
1255
+ self . node_manager
1256
+ . create_invoice ( first_invoice_amount)
1257
+ . await ?
1232
1258
} else {
1233
1259
inv. clone ( )
1234
1260
} ;
1235
1261
1236
- log_info ! ( self . logger, "attempting payment from fedimint client" ) ;
1237
- let _ = fedimint_client
1262
+ log_debug ! ( self . logger, "attempting payment from fedimint client" ) ;
1263
+ let mut final_result = FedimintSweepResult {
1264
+ amount : first_invoice_amount,
1265
+ fees : None ,
1266
+ } ;
1267
+ let first_invoice_res = fedimint_client
1238
1268
. pay_invoice ( inv_to_pay. bolt11 . expect ( "create inv had one job" ) , vec ! [ ] )
1239
1269
. await ?;
1270
+ final_result. fees = first_invoice_res. fees_paid ;
1240
1271
1241
1272
// pay_invoice returns invoice if Succeeded or Err if something else
1242
1273
// it's safe to assume that it went through and we can check remaining balance
1243
1274
let remaining_balance = fedimint_client. get_balance ( ) . await ?;
1244
- log_info ! (
1275
+ log_debug ! (
1245
1276
self . logger,
1246
1277
"remaining fedimint balance: {}" ,
1247
1278
remaining_balance
@@ -1250,7 +1281,7 @@ impl<S: MutinyStorage> MutinyWallet<S> {
1250
1281
// the fee for existing channel is voltage 1 sat + base fee + ppm
1251
1282
let remaining_balance_minus_fee = max_spendable_amount ( remaining_balance - 1 , fees) ;
1252
1283
if remaining_balance_minus_fee. is_none ( ) {
1253
- return Ok ( ( ) ) ;
1284
+ return Ok ( final_result ) ;
1254
1285
}
1255
1286
let remaining_balance_minus_fee = remaining_balance_minus_fee. unwrap ( ) ;
1256
1287
@@ -1263,8 +1294,14 @@ impl<S: MutinyStorage> MutinyWallet<S> {
1263
1294
. pay_invoice ( inv. bolt11 . expect ( "create inv had one job" ) , vec ! [ ] )
1264
1295
. await
1265
1296
{
1266
- Ok ( _) => {
1267
- log_info ! ( self . logger, "paid remaining balance" )
1297
+ Ok ( r) => {
1298
+ log_debug ! ( self . logger, "paid remaining balance" ) ;
1299
+ final_result. amount += remaining_balance_minus_fee;
1300
+ final_result. fees = final_result. fees . map_or ( r. fees_paid , |val| {
1301
+ r. fees_paid
1302
+ . map ( |add_val| val + add_val)
1303
+ . map_or ( Some ( val) , |_| None )
1304
+ } ) ;
1268
1305
}
1269
1306
Err ( e) => {
1270
1307
// Don't want to return this error since it's just "incomplete",
@@ -1274,7 +1311,7 @@ impl<S: MutinyStorage> MutinyWallet<S> {
1274
1311
}
1275
1312
}
1276
1313
1277
- Ok ( ( ) )
1314
+ Ok ( final_result )
1278
1315
}
1279
1316
1280
1317
async fn create_lightning_invoice (
0 commit comments