@@ -1596,31 +1596,47 @@ impl<S: MutinyStorage> MutinyWallet<S> {
1596
1596
pub async fn sweep_federation_balance (
1597
1597
& self ,
1598
1598
amount : Option < u64 > ,
1599
+ from_federation_id : Option < FederationId > ,
1600
+ to_federation_id : Option < FederationId > ,
1599
1601
) -> Result < FedimintSweepResult , MutinyError > {
1600
- // TODO support more than one federation
1601
1602
let federation_ids = self . list_federation_ids ( ) . await ?;
1602
1603
if federation_ids. is_empty ( ) {
1603
1604
return Err ( MutinyError :: NotFound ) ;
1604
1605
}
1605
- let federation_id = & federation_ids[ 0 ] ;
1606
+ let from_federation_id = from_federation_id . unwrap_or ( federation_ids[ 0 ] ) ;
1606
1607
let federation_lock = self . federations . read ( ) . await ;
1607
- let fedimint_client = federation_lock
1608
- . get ( federation_id )
1608
+ let from_fedimint_client = federation_lock
1609
+ . get ( & from_federation_id )
1609
1610
. ok_or ( MutinyError :: NotFound ) ?;
1610
1611
1612
+ // decide to sweep to secondary federation or lightning node
1613
+ let to_federation_client = match to_federation_id {
1614
+ Some ( f) => Some ( federation_lock. get ( & f) . ok_or ( MutinyError :: NotFound ) ?) ,
1615
+ None => None ,
1616
+ } ;
1617
+
1611
1618
let labels = vec ! [ SWAP_LABEL . to_string( ) ] ;
1612
1619
1613
1620
// if the user provided amount, this is easy
1614
1621
if let Some ( amt) = amount {
1615
- let ( inv, fee) = self
1616
- . node_manager
1617
- . create_invoice ( amt, labels. clone ( ) )
1618
- . await ?;
1622
+ let ( inv, fee) = match to_federation_client {
1623
+ Some ( f) => {
1624
+ // swap from one federation to another
1625
+ let inv = f. get_invoice ( amt, labels. clone ( ) ) . await ?;
1626
+ ( inv, 0 )
1627
+ }
1628
+ None => {
1629
+ // use the lightning node if no to federation selected
1630
+ self . node_manager
1631
+ . create_invoice ( amt, labels. clone ( ) )
1632
+ . await ?
1633
+ }
1634
+ } ;
1619
1635
1620
1636
let bolt_11 = inv. bolt11 . expect ( "create inv had one job" ) ;
1621
1637
self . storage
1622
1638
. set_invoice_labels ( bolt_11. clone ( ) , labels. clone ( ) ) ?;
1623
- let pay_res = fedimint_client . pay_invoice ( bolt_11, labels) . await ?;
1639
+ let pay_res = from_fedimint_client . pay_invoice ( bolt_11, labels) . await ?;
1624
1640
let total_fees_paid = pay_res. fees_paid . unwrap_or ( 0 ) + fee;
1625
1641
1626
1642
return Ok ( FedimintSweepResult {
@@ -1630,24 +1646,33 @@ impl<S: MutinyStorage> MutinyWallet<S> {
1630
1646
}
1631
1647
1632
1648
// If no amount, figure out the amount to send over
1633
- let current_balance = fedimint_client . get_balance ( ) . await ?;
1649
+ let current_balance = from_fedimint_client . get_balance ( ) . await ?;
1634
1650
log_debug ! (
1635
1651
self . logger,
1636
1652
"current fedimint client balance: {}" ,
1637
1653
current_balance
1638
1654
) ;
1639
1655
1640
- let fees = fedimint_client . gateway_fee ( ) . await ?;
1656
+ let fees = from_fedimint_client . gateway_fee ( ) . await ?;
1641
1657
// FIXME: this is still producing off by one. check round down
1642
1658
let amt = max_spendable_amount ( current_balance, & fees)
1643
1659
. map_or ( Err ( MutinyError :: InsufficientBalance ) , Ok ) ?;
1644
1660
log_debug ! ( self . logger, "max spendable: {}" , amt) ;
1645
1661
1646
1662
// try to get an invoice for this exact amount
1647
- let ( inv, fee) = self
1648
- . node_manager
1649
- . create_invoice ( amt, labels. clone ( ) )
1650
- . await ?;
1663
+ let ( inv, fee) = match to_federation_client {
1664
+ Some ( f) => {
1665
+ // swap from one federation to another
1666
+ let inv = f. get_invoice ( amt, labels. clone ( ) ) . await ?;
1667
+ ( inv, 0 )
1668
+ }
1669
+ None => {
1670
+ // use the lightning node if no to federation selected
1671
+ self . node_manager
1672
+ . create_invoice ( amt, labels. clone ( ) )
1673
+ . await ?
1674
+ }
1675
+ } ;
1651
1676
1652
1677
// check if we can afford that invoice
1653
1678
let inv_amt = inv. amount_sats . ok_or ( MutinyError :: BadAmountError ) ?;
@@ -1660,9 +1685,19 @@ impl<S: MutinyStorage> MutinyWallet<S> {
1660
1685
1661
1686
// if invoice amount changed, create a new invoice
1662
1687
let ( inv_to_pay, fee) = if first_invoice_amount != inv_amt {
1663
- self . node_manager
1664
- . create_invoice ( first_invoice_amount, labels. clone ( ) )
1665
- . await ?
1688
+ match to_federation_client {
1689
+ Some ( f) => {
1690
+ // swap from one federation to another
1691
+ let inv = f. get_invoice ( amt, labels. clone ( ) ) . await ?;
1692
+ ( inv, 0 )
1693
+ }
1694
+ None => {
1695
+ // use the lightning node if no to federation selected
1696
+ self . node_manager
1697
+ . create_invoice ( amt, labels. clone ( ) )
1698
+ . await ?
1699
+ }
1700
+ }
1666
1701
} else {
1667
1702
( inv. clone ( ) , fee)
1668
1703
} ;
@@ -1671,9 +1706,9 @@ impl<S: MutinyStorage> MutinyWallet<S> {
1671
1706
let bolt_11 = inv_to_pay. bolt11 . expect ( "create inv had one job" ) ;
1672
1707
self . storage
1673
1708
. set_invoice_labels ( bolt_11. clone ( ) , labels. clone ( ) ) ?;
1674
- let first_invoice_res = fedimint_client . pay_invoice ( bolt_11, labels) . await ?;
1709
+ let first_invoice_res = from_fedimint_client . pay_invoice ( bolt_11, labels) . await ?;
1675
1710
1676
- let remaining_balance = fedimint_client . get_balance ( ) . await ?;
1711
+ let remaining_balance = from_fedimint_client . get_balance ( ) . await ?;
1677
1712
if remaining_balance > 0 {
1678
1713
// there was a remainder when there shouldn't have been
1679
1714
// for now just log this, it is probably just a millisat/1 sat difference
@@ -1695,31 +1730,38 @@ impl<S: MutinyStorage> MutinyWallet<S> {
1695
1730
pub async fn estimate_sweep_federation_fee (
1696
1731
& self ,
1697
1732
amount : Option < u64 > ,
1733
+ from_federation_id : Option < FederationId > ,
1734
+ to_federation_id : Option < FederationId > ,
1698
1735
) -> Result < Option < u64 > , MutinyError > {
1699
1736
if let Some ( 0 ) = amount {
1700
1737
return Ok ( None ) ;
1701
1738
}
1702
1739
1703
- // TODO support more than one federation
1704
1740
let federation_ids = self . list_federation_ids ( ) . await ?;
1705
1741
if federation_ids. is_empty ( ) {
1706
1742
return Err ( MutinyError :: NotFound ) ;
1707
1743
}
1708
1744
1709
- let federation_id = & federation_ids[ 0 ] ;
1745
+ let from_federation_id = from_federation_id . unwrap_or ( federation_ids[ 0 ] ) ;
1710
1746
let federation_lock = self . federations . read ( ) . await ;
1711
1747
let fedimint_client = federation_lock
1712
- . get ( federation_id )
1748
+ . get ( & from_federation_id )
1713
1749
. ok_or ( MutinyError :: NotFound ) ?;
1714
1750
let fees = fedimint_client. gateway_fee ( ) . await ?;
1715
1751
1716
1752
let ( lsp_fee, federation_fee) = {
1717
1753
if let Some ( amt) = amount {
1718
1754
// if the user provided amount, this is easy
1719
- (
1720
- self . node_manager . get_lsp_fee ( amt) . await ?,
1721
- ( calc_routing_fee_msat ( amt as f64 * 1_000.0 , & fees) / 1_000.0 ) . floor ( ) as u64 ,
1722
- )
1755
+ let incoming_fee = if to_federation_id. is_some ( ) {
1756
+ 0
1757
+ } else {
1758
+ self . node_manager . get_lsp_fee ( amt) . await ?
1759
+ } ;
1760
+
1761
+ let outgoing_fee =
1762
+ ( calc_routing_fee_msat ( amt as f64 * 1_000.0 , & fees) / 1_000.0 ) . floor ( ) as u64 ;
1763
+
1764
+ ( incoming_fee, outgoing_fee)
1723
1765
} else {
1724
1766
// If no amount, figure out the amount to send over
1725
1767
let current_balance = fedimint_client. get_balance ( ) . await ?;
@@ -1733,11 +1775,15 @@ impl<S: MutinyStorage> MutinyWallet<S> {
1733
1775
. map_or ( Err ( MutinyError :: InsufficientBalance ) , Ok ) ?;
1734
1776
log_debug ! ( self . logger, "max spendable: {}" , amt) ;
1735
1777
1736
- // try to get an invoice for this exact amount
1737
- (
1738
- self . node_manager . get_lsp_fee ( amt) . await ?,
1739
- current_balance - amt,
1740
- )
1778
+ let incoming_fee = if to_federation_id. is_some ( ) {
1779
+ 0
1780
+ } else {
1781
+ self . node_manager . get_lsp_fee ( amt) . await ?
1782
+ } ;
1783
+
1784
+ let outgoing_fee = current_balance - amt;
1785
+
1786
+ ( incoming_fee, outgoing_fee)
1741
1787
}
1742
1788
} ;
1743
1789
0 commit comments