qml: add import additional addresses/keys to import wallet
This commit is contained in:
130
electrum/gui/qml/components/ImportAddressesKeysDialog.qml
Normal file
130
electrum/gui/qml/components/ImportAddressesKeysDialog.qml
Normal file
@@ -0,0 +1,130 @@
|
|||||||
|
import QtQuick 2.6
|
||||||
|
import QtQuick.Layouts 1.0
|
||||||
|
import QtQuick.Controls 2.3
|
||||||
|
|
||||||
|
import org.electrum 1.0
|
||||||
|
|
||||||
|
import "controls"
|
||||||
|
|
||||||
|
ElDialog {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
property bool valid: false
|
||||||
|
|
||||||
|
standardButtons: Dialog.Close
|
||||||
|
modal: true
|
||||||
|
parent: Overlay.overlay
|
||||||
|
Overlay.modal: Rectangle {
|
||||||
|
color: "#aa000000"
|
||||||
|
}
|
||||||
|
width: parent.width
|
||||||
|
height: parent.height
|
||||||
|
|
||||||
|
title: Daemon.currentWallet.isWatchOnly
|
||||||
|
? qsTr('Import additional addresses')
|
||||||
|
: qsTr('Import additional keys')
|
||||||
|
|
||||||
|
function verify(text) {
|
||||||
|
if (Daemon.currentWallet.isWatchOnly)
|
||||||
|
return bitcoin.isAddressList(text)
|
||||||
|
else
|
||||||
|
return bitcoin.isPrivateKeyList(text)
|
||||||
|
}
|
||||||
|
|
||||||
|
onAccepted: {
|
||||||
|
if (Daemon.currentWallet.isWatchOnly)
|
||||||
|
Daemon.currentWallet.importAddresses(import_ta.text)
|
||||||
|
else
|
||||||
|
Daemon.currentWallet.importPrivateKeys(import_ta.text)
|
||||||
|
}
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
width: parent.width
|
||||||
|
height: parent.height
|
||||||
|
|
||||||
|
Label {
|
||||||
|
text: Daemon.currentWallet.isWatchOnly
|
||||||
|
? qsTr('Import additional addresses')
|
||||||
|
: qsTr('Import additional 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.contentItem) // can't use dialog as parent?
|
||||||
|
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()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
Layout.preferredWidth: 1
|
||||||
|
Layout.fillHeight: true
|
||||||
|
}
|
||||||
|
|
||||||
|
FlatButton {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
text: qsTr('Import')
|
||||||
|
enabled: valid
|
||||||
|
onClicked: accept()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: qrscan
|
||||||
|
QRScan {
|
||||||
|
width: parent.width
|
||||||
|
height: parent.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
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -36,6 +36,10 @@ Pane {
|
|||||||
Daemon.start_change_password()
|
Daemon.start_change_password()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function importAddressesKeys() {
|
||||||
|
var dialog = importAddressesKeysDialog.createObject(rootItem)
|
||||||
|
dialog.open()
|
||||||
|
}
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
id: rootLayout
|
id: rootLayout
|
||||||
@@ -202,34 +206,37 @@ Pane {
|
|||||||
color: Material.accentColor
|
color: Material.accentColor
|
||||||
}
|
}
|
||||||
|
|
||||||
ColumnLayout {
|
TextHighlightPane {
|
||||||
Layout.columnSpan: 2
|
Layout.columnSpan: 2
|
||||||
Layout.leftMargin: constants.paddingMedium
|
Layout.fillWidth: true
|
||||||
spacing: 0
|
|
||||||
|
|
||||||
ButtonGroup {
|
ColumnLayout {
|
||||||
id: billinggroup
|
spacing: 0
|
||||||
onCheckedButtonChanged: {
|
|
||||||
Config.trustedcoinPrepay = checkedButton.value
|
ButtonGroup {
|
||||||
|
id: billinggroup
|
||||||
|
onCheckedButtonChanged: {
|
||||||
|
Config.trustedcoinPrepay = checkedButton.value
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
Repeater {
|
Repeater {
|
||||||
model: AppController.plugin('trustedcoin').billingModel
|
model: AppController.plugin('trustedcoin').billingModel
|
||||||
delegate: RowLayout {
|
delegate: RowLayout {
|
||||||
RadioButton {
|
RadioButton {
|
||||||
ButtonGroup.group: billinggroup
|
ButtonGroup.group: billinggroup
|
||||||
property string value: modelData.value
|
property string value: modelData.value
|
||||||
text: modelData.text
|
text: modelData.text
|
||||||
checked: modelData.value == Config.trustedcoinPrepay
|
checked: modelData.value == Config.trustedcoinPrepay
|
||||||
}
|
}
|
||||||
Label {
|
Label {
|
||||||
text: Config.formatSats(modelData.sats_per_tx)
|
text: Config.formatSats(modelData.sats_per_tx)
|
||||||
font.family: FixedFont
|
font.family: FixedFont
|
||||||
}
|
}
|
||||||
Label {
|
Label {
|
||||||
text: Config.baseUnit + '/tx'
|
text: Config.baseUnit + '/tx'
|
||||||
color: Material.accentColor
|
color: Material.accentColor
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -294,19 +301,27 @@ Pane {
|
|||||||
|
|
||||||
FlatButton {
|
FlatButton {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
text: qsTr('Change Password');
|
visible: Daemon.currentWallet.walletType == 'imported'
|
||||||
|
text: Daemon.currentWallet.isWatchOnly
|
||||||
|
? qsTr('Import additional addresses')
|
||||||
|
: qsTr('Import additional keys')
|
||||||
|
onClicked: rootItem.importAddressesKeys()
|
||||||
|
}
|
||||||
|
FlatButton {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
text: qsTr('Change Password')
|
||||||
onClicked: rootItem.changePassword()
|
onClicked: rootItem.changePassword()
|
||||||
icon.source: '../../icons/lock.png'
|
icon.source: '../../icons/lock.png'
|
||||||
}
|
}
|
||||||
FlatButton {
|
FlatButton {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
text: qsTr('Delete Wallet');
|
text: qsTr('Delete Wallet')
|
||||||
onClicked: rootItem.deleteWallet()
|
onClicked: rootItem.deleteWallet()
|
||||||
icon.source: '../../icons/delete.png'
|
icon.source: '../../icons/delete.png'
|
||||||
}
|
}
|
||||||
FlatButton {
|
FlatButton {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
text: qsTr('Enable Lightning');
|
text: qsTr('Enable Lightning')
|
||||||
onClicked: rootItem.enableLightning()
|
onClicked: rootItem.enableLightning()
|
||||||
visible: Daemon.currentWallet && Daemon.currentWallet.canHaveLightning && !Daemon.currentWallet.isLightning
|
visible: Daemon.currentWallet && Daemon.currentWallet.canHaveLightning && !Daemon.currentWallet.isLightning
|
||||||
icon.source: '../../icons/lightning.png'
|
icon.source: '../../icons/lightning.png'
|
||||||
@@ -372,6 +387,15 @@ Pane {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: importAddressesKeysDialog
|
||||||
|
ImportAddressesKeysDialog {
|
||||||
|
width: parent.width
|
||||||
|
height: parent.height
|
||||||
|
onClosed: destroy()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
piechart.updateSlices()
|
piechart.updateSlices()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ WizardComponent {
|
|||||||
Label { text: qsTr('Import Bitcoin Addresses') }
|
Label { text: qsTr('Import Bitcoin Addresses') }
|
||||||
|
|
||||||
InfoTextArea {
|
InfoTextArea {
|
||||||
|
Layout.preferredWidth: parent.width
|
||||||
text: qsTr('Enter a list of Bitcoin addresses (this will create a watching-only wallet), or a list of private keys.')
|
text: qsTr('Enter a list of Bitcoin addresses (this will create a watching-only wallet), or a list of private keys.')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -348,6 +348,8 @@ class QEWallet(AuthMixin, QObject, QtEventListener):
|
|||||||
if len(keystores) == 0:
|
if len(keystores) == 0:
|
||||||
self._logger.debug('no keystore')
|
self._logger.debug('no keystore')
|
||||||
return ''
|
return ''
|
||||||
|
if not self.isDeterministic:
|
||||||
|
return ''
|
||||||
return keystores[0].get_derivation_prefix()
|
return keystores[0].get_derivation_prefix()
|
||||||
|
|
||||||
@pyqtProperty(str, notify=dataChanged)
|
@pyqtProperty(str, notify=dataChanged)
|
||||||
@@ -660,3 +662,12 @@ class QEWallet(AuthMixin, QObject, QtEventListener):
|
|||||||
self.password = password
|
self.password = password
|
||||||
except InvalidPassword as e:
|
except InvalidPassword as e:
|
||||||
self._logger.exception(repr(e))
|
self._logger.exception(repr(e))
|
||||||
|
|
||||||
|
@pyqtSlot(str)
|
||||||
|
def importAddresses(self, addresslist):
|
||||||
|
self.wallet.import_addresses(addresslist.split())
|
||||||
|
|
||||||
|
@pyqtSlot(str)
|
||||||
|
def importPrivateKeys(self, keyslist):
|
||||||
|
self.wallet.import_private_keys(keyslist.split(), self.password)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user