Browse Source

Qt: add JMExportPrivkeysDialog, use open/async code

add_frost_channel_encryption
zebra-lucky 2 months ago
parent
commit
6f6d51e058
  1. 74
      scripts/joinmarket-qt.py
  2. 34
      scripts/qtsupport.py

74
scripts/joinmarket-qt.py

@ -21,7 +21,7 @@ Some widgets copied and modified from https://github.com/spesmilo/electrum
import asyncio import asyncio
import sys, datetime, os, logging import sys, datetime, os, logging
import platform, json, threading, time import platform, json, time
from optparse import OptionParser from optparse import OptionParser
from typing import Optional, Tuple from typing import Optional, Tuple
@ -82,7 +82,7 @@ from qtsupport import ScheduleWizard, TumbleRestartWizard, config_tips,\
config_types, QtHandler, XStream, Buttons, OkButton, CancelButton,\ config_types, QtHandler, XStream, Buttons, OkButton, CancelButton,\
JMPasswordDialog, MyTreeWidget, JMQtMessageBox, BLUE_FG,\ JMPasswordDialog, MyTreeWidget, JMQtMessageBox, BLUE_FG,\
donation_more_message, BitcoinAmountEdit, JMIntValidator,\ donation_more_message, BitcoinAmountEdit, JMIntValidator,\
ReceiveBIP78Dialog, QRCodePopup ReceiveBIP78Dialog, QRCodePopup, JMExportPrivkeysDialog
from twisted.internet import task from twisted.internet import task
@ -1909,47 +1909,28 @@ class JMMainWindow(QMainWindow):
title="Error")) title="Error"))
return return
#TODO add password protection; too critical #TODO add password protection; too critical
d = QDialog(self) d = JMExportPrivkeysDialog(self)
d.setWindowTitle('Private keys') d.finished.connect(d.on_finished)
d.setMinimumSize(850, 300) d.open()
vbox = QVBoxLayout(d)
msg = "%s\n%s\n%s" % (
"WARNING: ALL your private keys are secret.",
"Exposing a single private key can compromise your entire wallet!",
"In particular, DO NOT use 'redeem private key' services proposed by third parties."
)
vbox.addWidget(QLabel(msg))
e = QTextEdit()
e.setReadOnly(True)
vbox.addWidget(e)
b = OkButton(d, 'Export')
b.setEnabled(False)
vbox.addLayout(Buttons(CancelButton(d), b))
private_keys = {} private_keys = {}
#prepare list of addresses with non-zero balance
#TODO: consider adding a 'export insanely huge amount'
#option for anyone with gaplimit troubles, although
#that is a complete mess for a user, mostly changing
#the gaplimit in the Settings tab should address it.
rows = await get_wallet_printout(self.wallet_service)
addresses = [] addresses = []
for forchange in rows[0]:
for mixdepth in forchange:
for addr_info in mixdepth:
if float(addr_info[2]) > 0:
addresses.append(addr_info[0])
done = False done = False
def privkeys_thread(): async def gather_privkeys():
# To explain this (given setting was already done in # prepare list of addresses with non-zero balance
# load_program_config), see: # TODO: consider adding a 'export insanely huge amount'
# https://github.com/Simplexum/python-bitcointx/blob/9f1fa67a5445f8c187ef31015a4008bc5a048eea/bitcointx/__init__.py#L242-L243 # option for anyone with gaplimit troubles, although
# note, we ignore the return value as we only want to apply # that is a complete mess for a user, mostly changing
# the chainparams setting logic: # the gaplimit in the Settings tab should address it.
get_blockchain_interface_instance(jm_single().config) rows = await get_wallet_printout(self.wallet_service)
for forchange in rows[0]:
for mixdepth in forchange:
for addr_info in mixdepth:
# FIXME if float(addr_info[2]) > 0:
addresses.append(addr_info[0])
for addr in addresses: for addr in addresses:
time.sleep(0.1) await asyncio.sleep(0.1) # FIXME
if done: if done:
break break
priv = self.wallet_service.get_key_from_addr(addr) priv = self.wallet_service.get_key_from_addr(addr)
@ -1958,19 +1939,22 @@ class JMMainWindow(QMainWindow):
self.show_privkeys_signal.emit() self.show_privkeys_signal.emit()
def show_privkeys(): def show_privkeys():
s = "\n".join(map(lambda x: x[0] + "\t" + x[1], private_keys.items( s = "\n".join(map(
))) lambda x: x[0] + "\t" + x[1], private_keys.items()))
e.setText(s) d.e.setText(s)
b.setEnabled(True) d.b.setEnabled(True)
self.computing_privkeys_signal.connect(lambda: e.setText( self.computing_privkeys_signal.connect(lambda: d.e.setText(
"Please wait... %d/%d" % (len(private_keys), len(addresses)))) "Please wait... %d/%d" % (len(private_keys), len(addresses))))
self.show_privkeys_signal.connect(show_privkeys) self.show_privkeys_signal.connect(show_privkeys)
threading.Thread(target=privkeys_thread).start() gather_privkeys_task = asyncio.ensure_future(gather_privkeys())
if not d.exec_(): await gather_privkeys_task
result = await d.result()
if result == QDialog.Rejected:
done = True done = True
return return
privkeys_fn_base = 'joinmarket-private-keys' privkeys_fn_base = 'joinmarket-private-keys'
i = 0 i = 0
privkeys_fn = privkeys_fn_base privkeys_fn = privkeys_fn_base

34
scripts/qtsupport.py

@ -395,6 +395,40 @@ def make_password_dialog(self, msg):
return vbox return vbox
class JMExportPrivkeysDialog(QDialog):
def __init__(self, parent=None):
super().__init__(parent=parent)
self.result_fut = asyncio.get_event_loop().create_future()
self.initUI()
def initUI(self):
self.setWindowTitle('Private keys')
self.setMinimumSize(850, 300)
vbox = QVBoxLayout(self)
msg = "%s\n%s\n%s" % (
"WARNING: ALL your private keys are secret.",
"Exposing a single private key can compromise your entire wallet!",
"In particular, DO NOT use 'redeem private key' services proposed by third parties."
)
vbox.addWidget(QLabel(msg))
self.e = QTextEdit()
self.e.setReadOnly(True)
vbox.addWidget(self.e)
self.b = OkButton(self, 'Export')
self.b.setEnabled(False)
vbox.addLayout(Buttons(CancelButton(self), self.b))
@QtCore.Slot(QMessageBox.StandardButton)
def on_finished(self, result):
self.result_fut.set_result(result)
async def result(self):
await self.result_fut
return self.result_fut.result()
async def JMPasswordDialog(parent): async def JMPasswordDialog(parent):
class PasswordDialog(QDialog): class PasswordDialog(QDialog):

Loading…
Cancel
Save