commit 1d187d36f0a90b13a88c8bd2f8e4f89f518b451d
parent 97c79d52f96cfcb191b75439185e068d37ca9f90
Author: SomberNight <somber.night@protonmail.com>
Date: Thu, 15 Oct 2020 14:20:51 +0200
(fix) allow opening LN wallet with --offline
Diffstat:
4 files changed, 33 insertions(+), 11 deletions(-)
diff --git a/electrum/gui/qt/channels_list.py b/electrum/gui/qt/channels_list.py
@@ -79,7 +79,7 @@ class ChannelsList(MyTreeView):
labels[subject] = label
status = chan.get_state_for_GUI()
closed = chan.is_closed()
- if self.parent.network.is_lightning_running():
+ if self.network and self.network.is_lightning_running():
node_info = self.parent.network.channel_db.get_node_info_for_node_id(chan.node_id)
node_alias = (node_info.alias if node_info else '') or ''
else:
diff --git a/electrum/gui/qt/swap_dialog.py b/electrum/gui/qt/swap_dialog.py
@@ -194,6 +194,9 @@ class SwapDialog(WindowModalDialog):
self.fee_label.repaint() # macOS hack for #6269
def run(self):
+ if not self.network:
+ self.window.show_error(_("You are offline."))
+ return
self.window.run_coroutine_from_thread(self.swap_manager.get_pairs(), lambda x: self.update())
if not self.exec_():
return
diff --git a/electrum/lnworker.py b/electrum/lnworker.py
@@ -522,6 +522,8 @@ class LNWallet(LNWorker):
self.pending_payments = defaultdict(asyncio.Future) # type: Dict[bytes, asyncio.Future[BarePaymentAttemptLog]]
+ self.swap_manager = SwapManager(wallet=self.wallet, lnworker=self)
+
@property
def channels(self) -> Mapping[bytes, Channel]:
"""Returns a read-only copy of channels."""
@@ -581,7 +583,7 @@ class LNWallet(LNWorker):
self.lnwatcher = LNWalletWatcher(self, network)
self.lnwatcher.start_network(network)
self.network = network
- self.swap_manager = SwapManager(self.wallet, network)
+ self.swap_manager.start_network(network=network, lnwatcher=self.lnwatcher)
for chan in self.channels.values():
self.lnwatcher.add_channel(chan.funding_outpoint.to_str(), chan.get_funding_address())
@@ -703,7 +705,7 @@ class LNWallet(LNWorker):
out[closing_txid] = item
# add info about submarine swaps
settled_payments = self.get_settled_payments()
- current_height = self.network.get_local_height()
+ current_height = self.wallet.get_local_height()
for payment_hash_hex, swap in self.swap_manager.swaps.items():
txid = swap.spending_txid if swap.is_reverse else swap.funding_txid
if txid is None:
diff --git a/electrum/submarine_swaps.py b/electrum/submarine_swaps.py
@@ -21,6 +21,8 @@ from . import constants
if TYPE_CHECKING:
from .network import Network
from .wallet import Abstract_Wallet
+ from .lnwatcher import LNWalletWatcher
+ from .lnworker import LNWallet
API_URL_MAINNET = 'https://swaps.electrum.org/api'
@@ -113,25 +115,23 @@ def create_claim_tx(
class SwapManager(Logger):
- def __init__(self, wallet: 'Abstract_Wallet', network: 'Network'):
+ network: Optional['Network'] = None
+ lnwatcher: Optional['LNWalletWatcher'] = None
+
+ def __init__(self, *, wallet: 'Abstract_Wallet', lnworker: 'LNWallet'):
Logger.__init__(self)
self.normal_fee = 0
self.lockup_fee = 0
self.percentage = 0
self.min_amount = 0
self._max_amount = 0
- self.network = network
self.wallet = wallet
- self.lnworker = wallet.lnworker
- self.lnwatcher = self.wallet.lnworker.lnwatcher
+ self.lnworker = lnworker
self.swaps = self.wallet.db.get_dict('submarine_swaps') # type: Dict[str, SwapData]
self.prepayments = {} # type: Dict[bytes, bytes] # fee_preimage -> preimage
for k, swap in self.swaps.items():
if swap.is_reverse and swap.prepay_hash is not None:
self.prepayments[swap.prepay_hash] = bytes.fromhex(k)
- if swap.is_redeemed:
- continue
- self.add_lnwatcher_callback(swap)
# api url
if constants.net == constants.BitcoinMainnet:
self.api_url = API_URL_MAINNET
@@ -140,8 +140,20 @@ class SwapManager(Logger):
else:
self.api_url = API_URL_REGTEST
+ def start_network(self, *, network: 'Network', lnwatcher: 'LNWalletWatcher'):
+ assert network
+ assert lnwatcher
+ self.network = network
+ self.lnwatcher = lnwatcher
+ for k, swap in self.swaps.items():
+ if swap.is_redeemed:
+ continue
+ self.add_lnwatcher_callback(swap)
+
@log_exceptions
async def _claim_swap(self, swap: SwapData) -> None:
+ assert self.network
+ assert self.lnwatcher
if not self.lnwatcher.is_up_to_date():
return
current_height = self.network.get_local_height()
@@ -189,7 +201,7 @@ class SwapManager(Logger):
self.wallet.set_label(tx.txid(), 'Swap refund')
def get_claim_fee(self):
- return self.lnwatcher.config.estimate_fee(136, allow_fallback_to_static_rates=True)
+ return self.wallet.config.estimate_fee(136, allow_fallback_to_static_rates=True)
def get_swap(self, payment_hash: bytes) -> Optional[SwapData]:
# for history
@@ -207,6 +219,8 @@ class SwapManager(Logger):
async def normal_swap(self, lightning_amount: int, expected_onchain_amount: int,
password, *, tx: PartialTransaction = None) -> str:
"""send on-chain BTC, receive on Lightning"""
+ assert self.network
+ assert self.lnwatcher
privkey = os.urandom(32)
pubkey = ECPrivkey(privkey).get_public_key_bytes(compressed=True)
lnaddr, invoice = await self.lnworker.create_invoice(lightning_amount, 'swap', expiry=3600*24)
@@ -283,6 +297,8 @@ class SwapManager(Logger):
async def reverse_swap(self, amount_sat: int, expected_amount: int) -> bool:
"""send on Lightning, receive on-chain"""
+ assert self.network
+ assert self.lnwatcher
privkey = os.urandom(32)
pubkey = ECPrivkey(privkey).get_public_key_bytes(compressed=True)
preimage = os.urandom(32)
@@ -370,6 +386,7 @@ class SwapManager(Logger):
return success
async def get_pairs(self) -> None:
+ assert self.network
response = await self.network._send_http_on_proxy(
'get',
self.api_url + '/getpairs',