feat: enable adding an account with a seed phrase

This commit is contained in:
Jonathan Rainville 2020-06-08 14:35:48 -04:00 committed by Iuri Matias
parent f3ff229bf8
commit 50c10d38dd
8 changed files with 129 additions and 13 deletions

View File

@ -95,6 +95,9 @@ QtObject:
proc generateNewAccount*(self: WalletView, password: string, accountName: string, color: string) {.slot.} =
self.status.wallet.generateNewAccount(password, accountName, color)
proc addAccountsFromSeed*(self: WalletView, seed: string, password: string, accountName: string, color: string) {.slot.} =
self.status.wallet.addAccountsFromSeed(seed, password, accountName, color)
proc getAccountList(self: WalletView): QVariant {.slot.} =
return newQVariant(self.accounts)

View File

@ -174,21 +174,29 @@ proc multiAccountImportMnemonic*(mnemonic: string): GeneratedAccount =
let importResult = $libstatus.multiAccountImportMnemonic($mnemonicJson)
result = Json.decode(importResult, GeneratedAccount)
proc saveAccount*(account: GeneratedAccount, password: string, color: string): void =
proc saveAccount*(account: GeneratedAccount, password: string, color: string, accountType: string): DerivedAccount =
let storeDerivedResult = storeDerivedAccounts(account, password)
var address = account.derived.defaultWallet.address
var publicKey = account.derived.defaultWallet.publicKey
if (address == ""):
address = account.address
publicKey = account.publicKey
discard callPrivateRPC("accounts_saveAccounts", %* [
[{
"color": color,
"name": account.name,
"address": account.derived.defaultWallet.address,
"public-key": account.derived.defaultWallet.publicKey,
# Do we need to update those?
"type": "generated",
"address": address,
"public-key": publicKey,
"type": accountType,
"path": "m/44'/60'/0'/0/1"
}]
])
result = DerivedAccount(address: address, publicKey: publicKey)
proc deriveAccounts*(accountId: string): MultiAccounts =
let deriveJson = %* {
"accountID": accountId,

View File

@ -1,5 +1,9 @@
import json
const GENERATED* = "generated"
const SEED* = "seed"
const KEY* = "key"
const PATH_WALLET_ROOT* = "m/44'/60'/0'/0"
# EIP1581 Root Key, the extended key from which any whisper key/encryption key can be derived
const PATH_EIP_1581* = "m/43'/60'/1581'"

View File

@ -5,6 +5,8 @@ import strutils
import libstatus/wallet as status_wallet
import libstatus/settings as status_settings
import libstatus/accounts as status_accounts
import libstatus/accounts/constants as constants
import libstatus/types
import chronicles
import libstatus/tokens as status_tokens
@ -131,27 +133,35 @@ proc getTotalFiatBalance*(self: WalletModel): string =
var newBalance = 0.0
fmt"{newBalance:.2f} {self.defaultCurrency}"
# TODO get a real address that we unlock with the password
proc generateNewAccount*(self: WalletModel, password: string, accountName: string, color: string) =
let accounts = status_accounts.generateAddresses(1)
var generatedAccount = accounts[0]
proc addNewGeneratedAccount(self: WalletModel, generatedAccount: GeneratedAccount, password: string, accountName: string, color: string, accountType: string) =
generatedAccount.name = accountName
var derivedAccount: DerivedAccount
try:
status_accounts.saveAccount(generatedAccount, password, color)
derivedAccount = status_accounts.saveAccount(generatedAccount, password, color, accountType)
except:
error "Error sotring the new account. Bad password?"
error "Error storing the new account. Bad password?"
return
var symbol = "SNT"
var asset = Asset(name:"Status", symbol: symbol, value: fmt"0.0", fiatValue: "$" & fmt"0.0", image: fmt"../../img/token-icons/{toLowerAscii(symbol)}.svg")
var assets: seq[Asset] = self.generateAccountConfiguredAssets()
var account = Account(name: accountName, address: generatedAccount.derived.defaultWallet.address, iconColor: color, balance: fmt"0.00 {self.defaultCurrency}", assetList: assets, realFiatBalance: 0.0)
var account = Account(name: accountName, address: derivedAccount.address, iconColor: color, balance: fmt"0.00 {self.defaultCurrency}", assetList: assets, realFiatBalance: 0.0)
self.accounts.add(account)
self.events.emit("newAccountAdded", AccountArgs(account: account))
proc generateNewAccount*(self: WalletModel, password: string, accountName: string, color: string) =
let accounts = status_accounts.generateAddresses(1)
let generatedAccount = accounts[0]
self.addNewGeneratedAccount(generatedAccount, password, accountName, color, constants.GENERATED)
proc addAccountsFromSeed*(self: WalletModel, seed: string, password: string, accountName: string, color: string) =
let mnemonic = replace(seed, ',', ' ')
let generatedAccount = status_accounts.multiAccountImportMnemonic(mnemonic)
self.addNewGeneratedAccount(generatedAccount, password, accountName, color, constants.SEED)
proc toggleAsset*(self: WalletModel, symbol: string, enable: bool, address: string, name: string, decimals: int, color: string) =
if enable:
discard status_tokens.addCustomToken(address, name, symbol, decimals, color)

View File

@ -80,6 +80,9 @@ Rectangle {
GenerateAccountModal {
id: generateAccountModal
}
AddAccountWithSeed {
id: addAccountWithSeedModal
}
PopupMenu {
id: newAccountMenu
@ -102,7 +105,7 @@ Rectangle {
text: qsTr("Enter a seed phrase")
icon.source: "../../../img/enter_seed_phrase.svg"
onTriggered: {
console.log("TODO: Enter a seed phrase")
addAccountWithSeedModal.open()
}
}
QQC2.Action {

View File

@ -0,0 +1,86 @@
import QtQuick 2.12
import QtQuick.Controls 2.3
import QtQuick.Layouts 1.3
import "../../../../imports"
import "../../../../shared"
ModalPopup {
id: popup
title: qsTr("Add account with a seed phrase")
property int marginBetweenInputs: 38
property string selectedColor: Constants.accountColors[0]
onOpened: {
passwordInput.text = ""
passwordInput.forceActiveFocus(Qt.MouseFocusReason)
}
Input {
id: passwordInput
placeholderText: qsTr("Enter your password…")
label: qsTr("Password")
textField.echoMode: TextInput.Password
}
Input {
// TODO use a Textarea
id: accountSeedInput
anchors.top: passwordInput.bottom
anchors.topMargin: marginBetweenInputs
placeholderText: qsTr("Enter your seed phrase, separate words with commas or spaces...")
label: qsTr("Seed phrase")
}
Input {
id: accountNameInput
anchors.top: accountSeedInput.bottom
anchors.topMargin: marginBetweenInputs
placeholderText: qsTr("Enter an account name...")
label: qsTr("Account name")
}
Input {
id: accountColorInput
anchors.top: accountNameInput.bottom
anchors.topMargin: marginBetweenInputs
bgColor: selectedColor
label: qsTr("Account color")
selectOptions: Constants.accountColors.map(color => {
return {
text: "",
bgColor: color,
height: 52,
onClicked: function () {
selectedColor = color
}
}
})
}
footer: StyledButton {
anchors.top: parent.top
anchors.topMargin: Theme.padding
anchors.right: parent.right
anchors.rightMargin: Theme.padding
label: "Add account >"
disabled: passwordInput.text === "" && accountNameInput === "" || accountSeedInput.text == ""
onClicked : {
// TODO add message to show validation errors
if (passwordInput.text === "" || accountNameInput.text === "" || accountSeedInput.text == "") return;
walletModel.addAccountsFromSeed(accountSeedInput.text, passwordInput.text, accountNameInput.text, selectedColor)
// TODO manage errors adding account
popup.close();
}
}
}
/*##^##
Designer {
D{i:0;formeditorColor:"#ffffff";height:500;width:400}
}
##^##*/

View File

@ -3,3 +3,4 @@ SetCurrencyModalContent 1.0 SetCurrencyModalContent.qml
TokenSettingsModalContent 1.0 TokenSettingsModalContent.qml
AddAccount 1.0 AddAccount.qml
GenerateAccountModal 1.0 GenerateAccountModal.qml
AddAccountWithSeed 1.0 AddAccountWithSeed.qml

View File

@ -80,6 +80,7 @@ DISTFILES += \
app/AppLayouts/Wallet/AssetsTab.qml \
app/AppLayouts/Wallet/CollectiblesTab.qml \
app/AppLayouts/Wallet/Components/AddAccount.qml \
app/AppLayouts/Wallet/Components/AddAccountWithSeed.qml \
app/AppLayouts/Wallet/Components/GenerateAccountModal.qml \
app/AppLayouts/Wallet/Components/SendModalContent.qml \
app/AppLayouts/Wallet/Components/SetCurrencyModalContent.qml \