Browse Source

add wallet type imported addresses/private keys to wizard

patch-4
Sander van Grieken 2 years ago
parent
commit
6ea3a16cc8
  1. 7
      electrum/gui/qml/components/Wallets.qml
  2. 102
      electrum/gui/qml/components/wizard/WCImport.qml
  3. 3
      electrum/gui/qml/components/wizard/WCWalletType.qml
  4. 4
      electrum/gui/qml/qeaddresslistmodel.py
  5. 9
      electrum/gui/qml/qebitcoin.py
  6. 5
      electrum/gui/qml/qewallet.py
  7. 1
      electrum/gui/qml/qewizard.py
  8. 42
      electrum/gui/wizard.py

7
electrum/gui/qml/components/Wallets.qml

@ -153,9 +153,14 @@ Pane {
Label { text: 'has Seed'; color: Material.accentColor }
Label { text: Daemon.currentWallet.hasSeed }
Label { Layout.columnSpan:4; text: qsTr('Master Public Key'); color: Material.accentColor }
Label {
visible: Daemon.currentWallet.masterPubkey
Layout.columnSpan:4; text: qsTr('Master Public Key'); color: Material.accentColor
}
TextHighlightPane {
visible: Daemon.currentWallet.masterPubkey
Layout.columnSpan: 4
Layout.fillWidth: true
padding: 0

102
electrum/gui/qml/components/wizard/WCImport.qml

@ -0,0 +1,102 @@
import QtQuick 2.6
import QtQuick.Layouts 1.0
import QtQuick.Controls 2.1
import org.electrum 1.0
import "../controls"
WizardComponent {
id: root
valid: false
onAccept: {
if (bitcoin.isAddressList(import_ta.text)) {
wizard_data['address_list'] = import_ta.text
} else if (bitcoin.isPrivateKeyList(import_ta.text)) {
wizard_data['private_key_list'] = import_ta.text
}
}
function verify(text) {
return bitcoin.isAddressList(text) || bitcoin.isPrivateKeyList(text)
}
ColumnLayout {
width: parent.width
Label { text: qsTr('Import Bitcoin Addresses') }
InfoTextArea {
text: qsTr('Enter a list of Bitcoin addresses (this will create a watching-only wallet), or a list of private keys.')
}
RowLayout {
TextArea {
id: import_ta
Layout.fillWidth: true
Layout.minimumHeight: 80
focus: true
wrapMode: TextEdit.WrapAnywhere
onTextChanged: valid = verify(text)
}
ColumnLayout {
Layout.alignment: Qt.AlignTop
ToolButton {
icon.source: '../../../icons/paste.png'
icon.height: constants.iconSizeMedium
icon.width: constants.iconSizeMedium
onClicked: {
if (verify(AppController.clipboardToText())) {
if (import_ta.text != '')
import_ta.text = import_ta.text + '\n'
import_ta.text = import_ta.text + AppController.clipboardToText()
}
}
}
ToolButton {
icon.source: '../../../icons/qrcode.png'
icon.height: constants.iconSizeMedium
icon.width: constants.iconSizeMedium
scale: 1.2
onClicked: {
var scan = qrscan.createObject(root)
scan.onFound.connect(function() {
if (verify(scan.scanData)) {
if (import_ta.text != '')
import_ta.text = import_ta.text + ',\n'
import_ta.text = import_ta.text + scan.scanData
}
scan.destroy()
})
}
}
}
}
}
Component {
id: qrscan
QRScan {
width: root.width
height: root.height
ToolButton {
icon.source: '../../../icons/closebutton.png'
icon.height: constants.iconSizeMedium
icon.width: constants.iconSizeMedium
anchors.right: parent.right
anchors.top: parent.top
onClicked: {
parent.destroy()
}
}
}
}
Bitcoin {
id: bitcoin
}
}

3
electrum/gui/qml/components/wizard/WCWalletType.qml

@ -38,9 +38,8 @@ WizardComponent {
text: qsTr('Multi-signature wallet')
}
RadioButton {
enabled: false
ButtonGroup.group: wallettypegroup
property string wallettype: 'import'
property string wallettype: 'imported'
text: qsTr('Import Bitcoin addresses or private keys')
}
}

4
electrum/gui/qml/qeaddresslistmodel.py

@ -65,7 +65,7 @@ class QEAddressListModel(QAbstractListModel):
def init_model(self):
r_addresses = self.wallet.get_receiving_addresses()
c_addresses = self.wallet.get_change_addresses()
n_addresses = len(r_addresses) + len(c_addresses)
n_addresses = len(r_addresses) + len(c_addresses) if self.wallet.use_change else 0
def insert_row(atype, alist, address, iaddr):
item = self.addr_to_model(address)
@ -80,7 +80,7 @@ class QEAddressListModel(QAbstractListModel):
insert_row('receive', self.receive_addresses, address, i)
i = i + 1
i = 0
for address in c_addresses:
for address in c_addresses if self.wallet.use_change else []:
insert_row('change', self.change_addresses, address, i)
i = i + 1
self.endInsertRows()

9
electrum/gui/qml/qebitcoin.py

@ -164,3 +164,12 @@ class QEBitcoin(QObject):
return True
except:
return False
@pyqtSlot(str, result=bool)
def isAddressList(self, csv: str):
return keystore.is_address_list(csv)
@pyqtSlot(str, result=bool)
def isPrivateKeyList(self, csv: str):
return keystore.is_private_key_list(csv)

5
electrum/gui/qml/qewallet.py

@ -319,6 +319,8 @@ class QEWallet(AuthMixin, QObject, QtEventListener):
@pyqtProperty(str, notify=dataChanged)
def txinType(self):
if self.wallet.wallet_type == 'imported':
return self.wallet.txin_type
return self.wallet.get_txin_type(self.wallet.dummy_address())
@pyqtProperty(bool, notify=dataChanged)
@ -342,6 +344,9 @@ class QEWallet(AuthMixin, QObject, QtEventListener):
keystores = self.wallet.get_keystores()
if len(keystores) > 1:
self._logger.debug('multiple keystores not supported yet')
if len(keystores) == 0:
self._logger.debug('no keystore')
return ''
return keystores[0].get_derivation_prefix()
@pyqtProperty(str, notify=dataChanged)

1
electrum/gui/qml/qewizard.py

@ -59,6 +59,7 @@ class QENewWalletWizard(NewWalletWizard, QEAbstractWizard):
'have_seed': { 'gui': 'WCHaveSeed' },
'bip39_refine': { 'gui': 'WCBIP39Refine' },
'have_master_key': { 'gui': 'WCHaveMasterKey' },
'imported': { 'gui': 'WCImport' },
'wallet_password': { 'gui': 'WCWalletPassword' }
})

42
electrum/gui/wizard.py

@ -8,6 +8,7 @@ from electrum.storage import WalletStorage, StorageEncryptionVersion
from electrum.wallet_db import WalletDB
from electrum.bip32 import normalize_bip32_derivation, xpub_type
from electrum import keystore
from electrum import bitcoin
class WizardViewState(NamedTuple):
view: str
@ -162,6 +163,10 @@ class NewWalletWizard(AbstractWizard):
'next': 'wallet_password',
'last': self.last_if_single_password
},
'imported': {
'next': 'wallet_password',
'last': self.last_if_single_password
},
'wallet_password': {
'last': True
}
@ -180,10 +185,12 @@ class NewWalletWizard(AbstractWizard):
return self.last_if_single_password(view, wizard_data) and not wizard_data['seed_type'] == 'bip39'
def on_wallet_type(self, wizard_data):
if wizard_data['wallet_type'] == '2fa':
return 'trustedcoin_start'
return 'keystore_type'
t = wizard_data['wallet_type']
return {
'standard': 'keystore_type',
'2fa': 'trustedcoin_start',
'imported': 'imported'
}.get(t)
def on_keystore_type(self, wizard_data):
t = wizard_data['keystore_type']
@ -205,13 +212,28 @@ class NewWalletWizard(AbstractWizard):
def create_storage(self, path, data):
# only standard and 2fa wallets for now
assert data['wallet_type'] in ['standard', '2fa']
assert data['wallet_type'] in ['standard', '2fa', 'imported']
if os.path.exists(path):
raise Exception('file already exists at path')
storage = WalletStorage(path)
if data['keystore_type'] in ['createseed', 'haveseed']:
k = None
if not 'keystore_type' in data:
assert data['wallet_type'] == 'imported'
addresses = {}
if 'private_key_list' in data:
k = keystore.Imported_KeyStore({})
keys = keystore.get_private_keys(data['private_key_list'])
for pk in keys:
assert bitcoin.is_private_key(pk)
txin_type, pubkey = k.import_privkey(pk, None)
addr = bitcoin.pubkey_to_address(txin_type, pubkey)
addresses[addr] = {'type': txin_type, 'pubkey': pubkey}
elif 'address_list' in data:
for addr in data['address_list'].split():
addresses[addr] = {}
elif data['keystore_type'] in ['createseed', 'haveseed']:
if data['seed_type'] in ['old', 'standard', 'segwit']: #2fa, 2fa-segwit
self._logger.debug('creating keystore from electrum seed')
k = keystore.from_seed(data['seed'], data['seed_extra_words'], data['wallet_type'] == 'multisig')
@ -237,7 +259,7 @@ class NewWalletWizard(AbstractWizard):
raise Exception('unsupported/unknown keystore_type %s' % data['keystore_type'])
if data['encrypt']:
if k.may_have_password():
if k and k.may_have_password():
k.update_password(None, data['password'])
storage.set_password(data['password'], enc_version=StorageEncryptionVersion.USER_PASSWORD)
@ -255,8 +277,12 @@ class NewWalletWizard(AbstractWizard):
db.put('x2/', data['x2/'])
db.put('x3/', data['x3/'])
db.put('use_trustedcoin', True)
elif data['wallet_type'] == 'imported':
if k:
db.put('keystore', k.dump())
db.put('addresses', addresses)
if k.can_have_deterministic_lightning_xprv():
if k and k.can_have_deterministic_lightning_xprv():
db.put('lightning_xprv', k.get_lightning_xprv(data['password'] if data['encrypt'] else None))
db.load_plugins()

Loading…
Cancel
Save