17 changed files with 719 additions and 562 deletions
@ -0,0 +1,40 @@ |
|||
import QtQuick.Layouts 1.0 |
|||
import QtQuick.Controls 2.1 |
|||
|
|||
import ".." |
|||
|
|||
WizardComponent { |
|||
valid: true |
|||
last: serverconnectgroup.checkedButton.connecttype === 'auto' |
|||
|
|||
onAccept: { |
|||
wizard_data['autoconnect'] = serverconnectgroup.checkedButton.connecttype === 'auto' |
|||
} |
|||
|
|||
ColumnLayout { |
|||
width: parent.width |
|||
|
|||
InfoTextArea { |
|||
text: qsTr('Electrum communicates with remote servers to get information about your transactions and addresses. The servers all fulfill the same purpose only differing in hardware. In most cases you simply want to let Electrum pick one at random. However if you prefer feel free to select a server manually.') |
|||
Layout.fillWidth: true |
|||
} |
|||
|
|||
ButtonGroup { |
|||
id: serverconnectgroup |
|||
} |
|||
|
|||
RadioButton { |
|||
ButtonGroup.group: serverconnectgroup |
|||
property string connecttype: 'auto' |
|||
text: qsTr('Auto connect') |
|||
} |
|||
RadioButton { |
|||
ButtonGroup.group: serverconnectgroup |
|||
property string connecttype: 'manual' |
|||
checked: true |
|||
text: qsTr('Select servers manually') |
|||
} |
|||
|
|||
} |
|||
|
|||
} |
@ -0,0 +1,80 @@ |
|||
import QtQuick 2.6 |
|||
import QtQuick.Layouts 1.0 |
|||
import QtQuick.Controls 2.1 |
|||
|
|||
import org.electrum 1.0 |
|||
|
|||
import ".." |
|||
|
|||
WizardComponent { |
|||
valid: false |
|||
|
|||
onAccept: { |
|||
} |
|||
|
|||
function setDerivationPath() { |
|||
var addrtype = { |
|||
'p2pkh': 44, |
|||
'p2wpkh-p2sh': 49, |
|||
'p2wpkh': 84 |
|||
} |
|||
var nChain = Network.isTestNet ? 1 : 0 |
|||
derivationpathtext.text = |
|||
"m/" + addrtype[addresstypegroup.checkedButton.addresstype] + "'/" |
|||
+ (Network.isTestNet ? 1 : 0) + "'/0'" |
|||
} |
|||
|
|||
ButtonGroup { |
|||
id: addresstypegroup |
|||
onCheckedButtonChanged: { |
|||
console.log('button changed: ' + checkedButton.addresstype) |
|||
setDerivationPath() |
|||
} |
|||
} |
|||
|
|||
Flickable { |
|||
anchors.fill: parent |
|||
contentHeight: mainLayout.height |
|||
clip:true |
|||
interactive: height < contentHeight |
|||
|
|||
GridLayout { |
|||
id: mainLayout |
|||
width: parent.width |
|||
columns: 1 |
|||
|
|||
Label { text: qsTr('Script type and Derivation path') } |
|||
Button { |
|||
text: qsTr('Detect Existing Accounts') |
|||
enabled: false |
|||
} |
|||
Label { text: qsTr('Choose the type of addresses in your wallet.') } |
|||
RadioButton { |
|||
ButtonGroup.group: addresstypegroup |
|||
property string addresstype: 'p2pkh' |
|||
text: qsTr('legacy (p2pkh)') |
|||
} |
|||
RadioButton { |
|||
ButtonGroup.group: addresstypegroup |
|||
property string addresstype: 'p2wpkh-p2sh' |
|||
text: qsTr('wrapped segwit (p2wpkh-p2sh)') |
|||
} |
|||
RadioButton { |
|||
ButtonGroup.group: addresstypegroup |
|||
property string addresstype: 'p2wpkh' |
|||
checked: true |
|||
text: qsTr('native segwit (p2wpkh)') |
|||
} |
|||
InfoTextArea { |
|||
text: qsTr('You can override the suggested derivation path.') + ' ' + |
|||
qsTr('If you are not sure what this is, leave this field unchanged.') |
|||
} |
|||
TextField { |
|||
id: derivationpathtext |
|||
Layout.fillWidth: true |
|||
placeholderText: qsTr('Derivation path') |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
@ -0,0 +1,59 @@ |
|||
import QtQuick 2.6 |
|||
import QtQuick.Layouts 1.0 |
|||
import QtQuick.Controls 2.1 |
|||
|
|||
import org.electrum 1.0 |
|||
|
|||
import ".." |
|||
|
|||
WizardComponent { |
|||
valid: false |
|||
|
|||
function checkValid() { |
|||
var seedvalid = confirm.text == wizard_data['seed'] |
|||
var customwordsvalid = customwordstext.text == wizard_data['seed_extra_words'] |
|||
valid = seedvalid && (wizard_data['seed_extend'] ? customwordsvalid : true) |
|||
} |
|||
|
|||
Flickable { |
|||
anchors.fill: parent |
|||
contentHeight: mainLayout.height |
|||
clip:true |
|||
interactive: height < contentHeight |
|||
|
|||
GridLayout { |
|||
id: mainLayout |
|||
width: parent.width |
|||
columns: 1 |
|||
|
|||
InfoTextArea { |
|||
Layout.fillWidth: true |
|||
text: qsTr('Your seed is important!') + ' ' + |
|||
qsTr('If you lose your seed, your money will be permanently lost.') + ' ' + |
|||
qsTr('To make sure that you have properly saved your seed, please retype it here.') |
|||
} |
|||
Label { text: qsTr('Confirm your seed (re-enter)') } |
|||
SeedTextArea { |
|||
id: confirm |
|||
Layout.fillWidth: true |
|||
onTextChanged: { |
|||
checkValid() |
|||
} |
|||
} |
|||
TextField { |
|||
id: customwordstext |
|||
Layout.fillWidth: true |
|||
placeholderText: qsTr('Enter your custom word(s)') |
|||
echoMode: TextInput.Password |
|||
onTextChanged: { |
|||
checkValid() |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
onReadyChanged: { |
|||
if (ready) |
|||
customwordstext.visible = wizard_data['seed_extend'] |
|||
} |
|||
} |
@ -0,0 +1,88 @@ |
|||
import QtQuick 2.6 |
|||
import QtQuick.Layouts 1.0 |
|||
import QtQuick.Controls 2.1 |
|||
|
|||
import org.electrum 1.0 |
|||
|
|||
import ".." |
|||
|
|||
WizardComponent { |
|||
valid: seedtext.text != '' |
|||
|
|||
onAccept: { |
|||
wizard_data['seed'] = seedtext.text |
|||
wizard_data['seed_type'] = 'segwit' |
|||
wizard_data['seed_extend'] = extendcb.checked |
|||
wizard_data['seed_extra_words'] = extendcb.checked ? customwordstext.text : '' |
|||
} |
|||
|
|||
function setWarningText(numwords) { |
|||
var t = [ |
|||
'<p>', |
|||
qsTr('Please save these %1 words on paper (order is important).').arg(numwords), |
|||
qsTr('This seed will allow you to recover your wallet in case of computer failure.'), |
|||
'</p>', |
|||
'<b>' + qsTr('WARNING') + ':</b>', |
|||
'<ul>', |
|||
'<li>' + qsTr('Never disclose your seed.') + '</li>', |
|||
'<li>' + qsTr('Never type it on a website.') + '</li>', |
|||
'<li>' + qsTr('Do not store it electronically.') + '</li>', |
|||
'</ul>' |
|||
] |
|||
warningtext.text = t.join(' ') |
|||
} |
|||
|
|||
Flickable { |
|||
anchors.fill: parent |
|||
contentHeight: mainLayout.height |
|||
clip:true |
|||
interactive: height < contentHeight |
|||
|
|||
GridLayout { |
|||
id: mainLayout |
|||
width: parent.width |
|||
columns: 1 |
|||
|
|||
InfoTextArea { |
|||
id: warningtext |
|||
Layout.fillWidth: true |
|||
iconStyle: InfoTextArea.IconStyle.Warn |
|||
} |
|||
Label { text: qsTr('Your wallet generation seed is:') } |
|||
SeedTextArea { |
|||
id: seedtext |
|||
readOnly: true |
|||
Layout.fillWidth: true |
|||
|
|||
BusyIndicator { |
|||
anchors.centerIn: parent |
|||
height: parent.height * 2/3 |
|||
visible: seedtext.text == '' |
|||
} |
|||
} |
|||
CheckBox { |
|||
id: extendcb |
|||
text: qsTr('Extend seed with custom words') |
|||
} |
|||
TextField { |
|||
id: customwordstext |
|||
visible: extendcb.checked |
|||
Layout.fillWidth: true |
|||
placeholderText: qsTr('Enter your custom word(s)') |
|||
echoMode: TextInput.Password |
|||
} |
|||
Component.onCompleted : { |
|||
setWarningText(12) |
|||
bitcoin.generate_seed() |
|||
} |
|||
} |
|||
} |
|||
|
|||
Bitcoin { |
|||
id: bitcoin |
|||
onGeneratedSeedChanged: { |
|||
seedtext.text = generated_seed |
|||
setWarningText(generated_seed.split(' ').length) |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,151 @@ |
|||
import QtQuick 2.6 |
|||
import QtQuick.Layouts 1.0 |
|||
import QtQuick.Controls 2.1 |
|||
import QtQuick.Controls.Material 2.0 |
|||
|
|||
import org.electrum 1.0 |
|||
|
|||
import ".." |
|||
|
|||
WizardComponent { |
|||
id: root |
|||
valid: false |
|||
|
|||
onAccept: { |
|||
wizard_data['seed'] = seedtext.text |
|||
wizard_data['seed_type'] = bitcoin.seed_type |
|||
wizard_data['seed_extend'] = extendcb.checked |
|||
wizard_data['seed_extra_words'] = extendcb.checked ? customwordstext.text : '' |
|||
wizard_data['seed_bip39'] = seed_type.getTypeCode() == 'BIP39' |
|||
wizard_data['seed_slip39'] = seed_type.getTypeCode() == 'SLIP39' |
|||
} |
|||
|
|||
function setSeedTypeHelpText() { |
|||
var t = { |
|||
'Electrum': [ |
|||
qsTr('Electrum seeds are the default seed type.'), |
|||
qsTr('If you are restoring from a seed previously created by Electrum, choose this option') |
|||
].join(' '), |
|||
'BIP39': [ |
|||
qsTr('BIP39 seeds can be imported in Electrum, so that users can access funds locked in other wallets.'), |
|||
'<br/><br/>', |
|||
qsTr('However, we do not generate BIP39 seeds, because they do not meet our safety standard.'), |
|||
qsTr('BIP39 seeds do not include a version number, which compromises compatibility with future software.') |
|||
].join(' '), |
|||
'SLIP39': [ |
|||
qsTr('SLIP39 seeds can be imported in Electrum, so that users can access funds locked in other wallets.'), |
|||
'<br/><br/>', |
|||
qsTr('However, we do not generate SLIP39 seeds.') |
|||
].join(' ') |
|||
} |
|||
infotext.text = t[seed_type.currentText] |
|||
} |
|||
|
|||
function checkValid() { |
|||
bitcoin.verify_seed(seedtext.text, seed_type.getTypeCode() == 'BIP39', seed_type.getTypeCode() == 'SLIP39') |
|||
} |
|||
|
|||
Flickable { |
|||
anchors.fill: parent |
|||
contentHeight: mainLayout.height |
|||
clip:true |
|||
interactive: height < contentHeight |
|||
|
|||
GridLayout { |
|||
id: mainLayout |
|||
width: parent.width |
|||
columns: 2 |
|||
|
|||
Label { |
|||
text: qsTr('Seed Type') |
|||
Layout.fillWidth: true |
|||
} |
|||
ComboBox { |
|||
id: seed_type |
|||
model: ['Electrum', 'BIP39', 'SLIP39'] |
|||
onActivated: { |
|||
setSeedTypeHelpText() |
|||
checkValid() |
|||
} |
|||
function getTypeCode() { |
|||
return currentText |
|||
} |
|||
} |
|||
InfoTextArea { |
|||
id: infotext |
|||
Layout.fillWidth: true |
|||
Layout.columnSpan: 2 |
|||
} |
|||
Label { |
|||
text: qsTr('Enter your seed') |
|||
Layout.columnSpan: 2 |
|||
} |
|||
SeedTextArea { |
|||
id: seedtext |
|||
Layout.fillWidth: true |
|||
Layout.columnSpan: 2 |
|||
onTextChanged: { |
|||
validationTimer.restart() |
|||
} |
|||
|
|||
Rectangle { |
|||
anchors.fill: contentText |
|||
color: 'green' |
|||
border.color: Material.accentColor |
|||
radius: 2 |
|||
} |
|||
Label { |
|||
id: contentText |
|||
anchors.right: parent.right |
|||
anchors.bottom: parent.bottom |
|||
leftPadding: text != '' ? 16 : 0 |
|||
rightPadding: text != '' ? 16 : 0 |
|||
font.bold: false |
|||
font.pixelSize: 13 |
|||
} |
|||
} |
|||
TextArea { |
|||
id: validationtext |
|||
visible: text != '' |
|||
Layout.fillWidth: true |
|||
readOnly: true |
|||
wrapMode: TextInput.WordWrap |
|||
background: Rectangle { |
|||
color: 'transparent' |
|||
} |
|||
} |
|||
|
|||
CheckBox { |
|||
id: extendcb |
|||
Layout.columnSpan: 2 |
|||
text: qsTr('Extend seed with custom words') |
|||
} |
|||
TextField { |
|||
id: customwordstext |
|||
visible: extendcb.checked |
|||
Layout.fillWidth: true |
|||
Layout.columnSpan: 2 |
|||
placeholderText: qsTr('Enter your custom word(s)') |
|||
echoMode: TextInput.Password |
|||
} |
|||
} |
|||
} |
|||
|
|||
Bitcoin { |
|||
id: bitcoin |
|||
onSeedTypeChanged: contentText.text = bitcoin.seed_type |
|||
onSeedValidChanged: root.valid = bitcoin.seed_valid |
|||
onValidationMessageChanged: validationtext.text = bitcoin.validation_message |
|||
} |
|||
|
|||
Timer { |
|||
id: validationTimer |
|||
interval: 500 |
|||
repeat: false |
|||
onTriggered: checkValid() |
|||
} |
|||
|
|||
Component.onCompleted: { |
|||
setSeedTypeHelpText() |
|||
} |
|||
} |
@ -0,0 +1,43 @@ |
|||
import QtQuick.Layouts 1.0 |
|||
import QtQuick.Controls 2.1 |
|||
|
|||
WizardComponent { |
|||
valid: keystoregroup.checkedButton !== null |
|||
|
|||
onAccept: { |
|||
wizard_data['keystore_type'] = keystoregroup.checkedButton.keystoretype |
|||
} |
|||
|
|||
ButtonGroup { |
|||
id: keystoregroup |
|||
} |
|||
|
|||
GridLayout { |
|||
columns: 1 |
|||
Label { text: qsTr('What kind of wallet do you want to create?') } |
|||
RadioButton { |
|||
ButtonGroup.group: keystoregroup |
|||
property string keystoretype: 'createseed' |
|||
checked: true |
|||
text: qsTr('Create a new seed') |
|||
} |
|||
RadioButton { |
|||
ButtonGroup.group: keystoregroup |
|||
property string keystoretype: 'haveseed' |
|||
text: qsTr('I already have a seed') |
|||
} |
|||
RadioButton { |
|||
enabled: false |
|||
ButtonGroup.group: keystoregroup |
|||
property string keystoretype: 'masterkey' |
|||
text: qsTr('Use a master key') |
|||
} |
|||
RadioButton { |
|||
enabled: false |
|||
ButtonGroup.group: keystoregroup |
|||
property string keystoretype: 'hardware' |
|||
text: qsTr('Use a hardware device') |
|||
} |
|||
} |
|||
} |
|||
|
@ -0,0 +1,94 @@ |
|||
import QtQuick.Layouts 1.0 |
|||
import QtQuick.Controls 2.1 |
|||
|
|||
WizardComponent { |
|||
valid: true |
|||
|
|||
onAccept: { |
|||
var p = {} |
|||
p['enabled'] = proxy_enabled.checked |
|||
if (proxy_enabled.checked) { |
|||
var type = proxytype.currentValue.toLowerCase() |
|||
if (type == 'tor') |
|||
type = 'socks5' |
|||
p['mode'] = type |
|||
p['host'] = address.text |
|||
p['port'] = port.text |
|||
p['user'] = username.text |
|||
p['password'] = password.text |
|||
} |
|||
wizard_data['proxy'] = p |
|||
} |
|||
|
|||
ColumnLayout { |
|||
width: parent.width |
|||
|
|||
Label { |
|||
text: qsTr('Proxy settings') |
|||
} |
|||
|
|||
CheckBox { |
|||
id: proxy_enabled |
|||
text: qsTr('Enable Proxy') |
|||
} |
|||
|
|||
ComboBox { |
|||
id: proxytype |
|||
enabled: proxy_enabled.checked |
|||
model: ['TOR', 'SOCKS5', 'SOCKS4'] |
|||
onCurrentIndexChanged: { |
|||
if (currentIndex == 0) { |
|||
address.text = "127.0.0.1" |
|||
port.text = "9050" |
|||
} |
|||
} |
|||
} |
|||
|
|||
GridLayout { |
|||
columns: 4 |
|||
Layout.fillWidth: true |
|||
|
|||
Label { |
|||
text: qsTr("Address") |
|||
enabled: address.enabled |
|||
} |
|||
|
|||
TextField { |
|||
id: address |
|||
enabled: proxytype.enabled && proxytype.currentIndex > 0 |
|||
} |
|||
|
|||
Label { |
|||
text: qsTr("Port") |
|||
enabled: port.enabled |
|||
} |
|||
|
|||
TextField { |
|||
id: port |
|||
enabled: proxytype.enabled && proxytype.currentIndex > 0 |
|||
} |
|||
|
|||
Label { |
|||
text: qsTr("Username") |
|||
enabled: username.enabled |
|||
} |
|||
|
|||
TextField { |
|||
id: username |
|||
enabled: proxytype.enabled && proxytype.currentIndex > 0 |
|||
} |
|||
|
|||
Label { |
|||
text: qsTr("Password") |
|||
enabled: password.enabled |
|||
} |
|||
|
|||
TextField { |
|||
id: password |
|||
enabled: proxytype.enabled && proxytype.currentIndex > 0 |
|||
echoMode: TextInput.Password |
|||
} |
|||
} |
|||
} |
|||
|
|||
} |
@ -0,0 +1,42 @@ |
|||
import QtQuick.Layouts 1.0 |
|||
import QtQuick.Controls 2.1 |
|||
|
|||
WizardComponent { |
|||
valid: true |
|||
last: true |
|||
|
|||
onAccept: { |
|||
wizard_data['oneserver'] = !auto_server.checked |
|||
wizard_data['server'] = address.text |
|||
} |
|||
|
|||
ColumnLayout { |
|||
width: parent.width |
|||
|
|||
Label { |
|||
text: qsTr('Server settings') |
|||
} |
|||
|
|||
CheckBox { |
|||
id: auto_server |
|||
text: qsTr('Select server automatically') |
|||
checked: true |
|||
} |
|||
|
|||
GridLayout { |
|||
columns: 2 |
|||
Layout.fillWidth: true |
|||
|
|||
Label { |
|||
text: qsTr("Server") |
|||
enabled: address.enabled |
|||
} |
|||
|
|||
TextField { |
|||
id: address |
|||
enabled: !auto_server.checked |
|||
} |
|||
} |
|||
} |
|||
|
|||
} |
@ -0,0 +1,18 @@ |
|||
import QtQuick.Layouts 1.0 |
|||
import QtQuick.Controls 2.1 |
|||
|
|||
WizardComponent { |
|||
valid: wallet_name.text.length > 0 |
|||
|
|||
onAccept: { |
|||
wizard_data['wallet_name'] = wallet_name.text |
|||
} |
|||
|
|||
GridLayout { |
|||
columns: 1 |
|||
Label { text: qsTr('Wallet name') } |
|||
TextField { |
|||
id: wallet_name |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,29 @@ |
|||
import QtQuick.Layouts 1.0 |
|||
import QtQuick.Controls 2.1 |
|||
|
|||
WizardComponent { |
|||
valid: password1.text === password2.text |
|||
|
|||
onAccept: { |
|||
wizard_data['password'] = password1.text |
|||
wizard_data['encrypt'] = doencrypt.checked |
|||
} |
|||
|
|||
GridLayout { |
|||
columns: 1 |
|||
Label { text: qsTr('Password protect wallet?') } |
|||
TextField { |
|||
id: password1 |
|||
echoMode: TextInput.Password |
|||
} |
|||
TextField { |
|||
id: password2 |
|||
echoMode: TextInput.Password |
|||
} |
|||
CheckBox { |
|||
id: doencrypt |
|||
enabled: password1.text !== '' |
|||
text: qsTr('Encrypt wallet') |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,43 @@ |
|||
import QtQuick.Layouts 1.0 |
|||
import QtQuick.Controls 2.1 |
|||
|
|||
WizardComponent { |
|||
valid: wallettypegroup.checkedButton !== null |
|||
|
|||
onAccept: { |
|||
wizard_data['wallet_type'] = wallettypegroup.checkedButton.wallettype |
|||
} |
|||
|
|||
ButtonGroup { |
|||
id: wallettypegroup |
|||
} |
|||
|
|||
GridLayout { |
|||
columns: 1 |
|||
Label { text: qsTr('What kind of wallet do you want to create?') } |
|||
RadioButton { |
|||
ButtonGroup.group: wallettypegroup |
|||
property string wallettype: 'standard' |
|||
checked: true |
|||
text: qsTr('Standard Wallet') |
|||
} |
|||
RadioButton { |
|||
enabled: false |
|||
ButtonGroup.group: wallettypegroup |
|||
property string wallettype: '2fa' |
|||
text: qsTr('Wallet with two-factor authentication') |
|||
} |
|||
RadioButton { |
|||
enabled: false |
|||
ButtonGroup.group: wallettypegroup |
|||
property string wallettype: 'multisig' |
|||
text: qsTr('Multi-signature wallet') |
|||
} |
|||
RadioButton { |
|||
enabled: false |
|||
ButtonGroup.group: wallettypegroup |
|||
property string wallettype: 'import' |
|||
text: qsTr('Import Bitcoin addresses or private keys') |
|||
} |
|||
} |
|||
} |
Loading…
Reference in new issue