2020-05-19 13:22:38 +00:00
|
|
|
import libstatus
|
2020-05-21 17:51:07 +00:00
|
|
|
import core
|
2020-05-19 13:22:38 +00:00
|
|
|
import json
|
|
|
|
import utils
|
2020-05-21 18:52:41 +00:00
|
|
|
import accounts/constants
|
2020-05-21 19:59:09 +00:00
|
|
|
import nimcrypto
|
2020-05-20 17:11:30 +00:00
|
|
|
import os
|
2020-05-21 19:44:07 +00:00
|
|
|
import uuids
|
2020-05-25 07:45:29 +00:00
|
|
|
import types
|
|
|
|
import json_serialization
|
|
|
|
import chronicles
|
2020-05-19 13:22:38 +00:00
|
|
|
|
2020-05-21 17:51:07 +00:00
|
|
|
proc queryAccounts*(): string =
|
2020-05-22 23:33:36 +00:00
|
|
|
var response = callPrivateRPC("eth_accounts")
|
2020-05-21 17:51:07 +00:00
|
|
|
result = parseJson(response)["result"][0].getStr()
|
|
|
|
|
2020-05-25 07:45:29 +00:00
|
|
|
proc generateAddresses*(): seq[GeneratedAccount] =
|
2020-05-19 13:22:38 +00:00
|
|
|
let multiAccountConfig = %* {
|
|
|
|
"n": 5,
|
|
|
|
"mnemonicPhraseLength": 12,
|
|
|
|
"bip39Passphrase": "",
|
2020-05-25 07:45:29 +00:00
|
|
|
"paths": [PATH_WHISPER, PATH_WALLET_ROOT, PATH_DEFAULT_WALLET]
|
2020-05-19 13:22:38 +00:00
|
|
|
}
|
2020-05-25 07:45:29 +00:00
|
|
|
result = Json.decode($libstatus.multiAccountGenerateAndDeriveAddresses($multiAccountConfig), seq[GeneratedAccount])
|
2020-05-19 13:22:38 +00:00
|
|
|
|
|
|
|
proc generateAlias*(publicKey: string): string =
|
|
|
|
result = $libstatus.generateAlias(publicKey.toGoString)
|
2020-05-20 17:11:30 +00:00
|
|
|
|
2020-05-21 21:41:27 +00:00
|
|
|
proc generateIdenticon*(publicKey: string): string =
|
|
|
|
result = $libstatus.identicon(publicKey.toGoString)
|
|
|
|
|
2020-05-20 17:11:30 +00:00
|
|
|
proc ensureDir(dirname: string) =
|
|
|
|
if not existsDir(dirname):
|
|
|
|
# removeDir(dirname)
|
|
|
|
createDir(dirname)
|
|
|
|
|
2020-05-27 07:15:42 +00:00
|
|
|
proc initNodeAccounts*(): seq[NodeAccount] =
|
2020-05-20 17:11:30 +00:00
|
|
|
const datadir = "./data/"
|
|
|
|
const keystoredir = "./data/keystore/"
|
|
|
|
const nobackupdir = "./noBackup/"
|
|
|
|
|
|
|
|
ensureDir(datadir)
|
|
|
|
ensureDir(keystoredir)
|
|
|
|
ensureDir(nobackupdir)
|
|
|
|
|
|
|
|
discard $libstatus.initKeystore(keystoredir);
|
2020-05-27 07:15:42 +00:00
|
|
|
let strNodeAccounts = $libstatus.openAccounts(datadir);
|
|
|
|
result = Json.decode(strNodeAccounts, seq[NodeAccount])
|
|
|
|
|
|
|
|
proc saveAccountAndLogin*(
|
|
|
|
multiAccounts: MultiAccounts,
|
|
|
|
alias: string,
|
|
|
|
identicon: string,
|
|
|
|
accountData: string,
|
|
|
|
password: string,
|
|
|
|
configJSON: string,
|
|
|
|
settingsJSON: string): Account =
|
2020-05-21 19:59:09 +00:00
|
|
|
let hashedPassword = "0x" & $keccak_256.digest(password)
|
2020-05-21 18:52:41 +00:00
|
|
|
let subaccountData = %* [
|
|
|
|
{
|
2020-05-25 07:45:29 +00:00
|
|
|
"public-key": multiAccounts.defaultWallet.publicKey,
|
|
|
|
"address": multiAccounts.defaultWallet.address,
|
2020-05-21 18:52:41 +00:00
|
|
|
"color": "#4360df",
|
|
|
|
"wallet": true,
|
|
|
|
"path": constants.PATH_DEFAULT_WALLET,
|
|
|
|
"name": "Status account"
|
|
|
|
},
|
|
|
|
{
|
2020-05-25 07:45:29 +00:00
|
|
|
"public-key": multiAccounts.whisper.publicKey,
|
|
|
|
"address": multiAccounts.whisper.address,
|
2020-05-21 18:52:41 +00:00
|
|
|
"name": alias,
|
|
|
|
"photo-path": identicon,
|
|
|
|
"path": constants.PATH_WHISPER,
|
|
|
|
"chat": true
|
|
|
|
}
|
|
|
|
]
|
|
|
|
|
2020-05-21 19:59:09 +00:00
|
|
|
var savedResult = $libstatus.saveAccountAndLogin(accountData, hashedPassword, settingsJSON, configJSON, $subaccountData)
|
2020-05-21 18:52:41 +00:00
|
|
|
let parsedSavedResult = savedResult.parseJson
|
2020-05-27 07:15:42 +00:00
|
|
|
let error = parsedSavedResult["error"].getStr
|
2020-05-21 18:52:41 +00:00
|
|
|
|
2020-05-27 07:15:42 +00:00
|
|
|
if error == "":
|
2020-05-25 07:45:29 +00:00
|
|
|
debug "Account saved succesfully"
|
2020-05-27 07:15:42 +00:00
|
|
|
result = Account(name: alias, photoPath: identicon)
|
|
|
|
return
|
2020-05-21 18:52:41 +00:00
|
|
|
|
2020-05-27 07:15:42 +00:00
|
|
|
raise newException(LoginError, "Error saving account and logging in: " & error)
|
2020-05-25 07:45:29 +00:00
|
|
|
|
|
|
|
proc generateMultiAccounts*(account: GeneratedAccount, password: string): MultiAccounts =
|
2020-05-21 19:59:09 +00:00
|
|
|
let hashedPassword = "0x" & $keccak_256.digest(password)
|
2020-05-21 17:51:07 +00:00
|
|
|
let multiAccount = %* {
|
2020-05-25 07:45:29 +00:00
|
|
|
"accountID": account.id,
|
|
|
|
"paths": [PATH_WALLET_ROOT, PATH_EIP_1581, PATH_WHISPER, PATH_DEFAULT_WALLET],
|
2020-05-21 19:59:09 +00:00
|
|
|
"password": hashedPassword
|
2020-05-21 17:51:07 +00:00
|
|
|
}
|
2020-05-21 19:13:49 +00:00
|
|
|
var response = $libstatus.multiAccountStoreDerivedAccounts($multiAccount);
|
2020-05-25 07:45:29 +00:00
|
|
|
result = Json.decode($response, MultiAccounts)
|
2020-05-21 19:13:49 +00:00
|
|
|
|
2020-05-25 07:45:29 +00:00
|
|
|
proc getAccountData*(account: GeneratedAccount, alias: string, identicon: string): JsonNode =
|
2020-05-21 19:54:25 +00:00
|
|
|
result = %* {
|
|
|
|
"name": alias,
|
2020-05-25 07:45:29 +00:00
|
|
|
"address": account.address,
|
2020-05-21 19:54:25 +00:00
|
|
|
"photo-path": identicon,
|
2020-05-25 07:45:29 +00:00
|
|
|
"key-uid": account.keyUid,
|
2020-05-21 19:54:25 +00:00
|
|
|
"keycard-pairing": nil
|
|
|
|
}
|
|
|
|
|
2020-05-25 07:45:29 +00:00
|
|
|
proc getAccountSettings*(account: GeneratedAccount, alias: string, identicon: string, multiAccounts: MultiAccounts, defaultNetworks: JsonNode): JsonNode =
|
2020-05-21 19:44:07 +00:00
|
|
|
result = %* {
|
2020-05-25 07:45:29 +00:00
|
|
|
"key-uid": account.keyUid,
|
|
|
|
"mnemonic": account.mnemonic,
|
|
|
|
"public-key": multiAccounts.whisper.publicKey,
|
2020-05-21 19:44:07 +00:00
|
|
|
"name": alias,
|
2020-05-25 07:45:29 +00:00
|
|
|
"address": account.address,
|
|
|
|
"eip1581-address": multiAccounts.eip1581.address,
|
|
|
|
"dapps-address": multiAccounts.defaultWallet.address,
|
|
|
|
"wallet-root-address": multiAccounts.walletRoot.address,
|
2020-05-21 19:44:07 +00:00
|
|
|
"preview-privacy?": true,
|
|
|
|
"signing-phrase": generateSigningPhrase(3),
|
|
|
|
"log-level": "INFO",
|
|
|
|
"latest-derived-path": 0,
|
|
|
|
"networks/networks": defaultNetworks,
|
|
|
|
"currency": "usd",
|
|
|
|
"photo-path": identicon,
|
|
|
|
"waku-enabled": true,
|
|
|
|
"wallet/visible-tokens": {
|
|
|
|
"mainnet": ["SNT"]
|
|
|
|
},
|
|
|
|
"appearance": 0,
|
|
|
|
"networks/current-network": "mainnet_rpc",
|
|
|
|
"installation-id": $genUUID()
|
|
|
|
}
|
|
|
|
|
2020-05-25 07:45:29 +00:00
|
|
|
proc setupAccount*(account: GeneratedAccount, password: string): Account =
|
2020-05-21 20:15:44 +00:00
|
|
|
let multiAccounts = generateMultiAccounts(account, password)
|
2020-05-21 19:13:49 +00:00
|
|
|
|
2020-05-25 07:45:29 +00:00
|
|
|
let whisperPubKey = account.derived.whisper.publicKey
|
|
|
|
let alias = generateAlias(whisperPubKey)
|
|
|
|
let identicon =generateIdenticon(whisperPubKey)
|
2020-05-21 17:51:07 +00:00
|
|
|
|
2020-05-21 20:15:44 +00:00
|
|
|
let accountData = getAccountData(account, alias, identicon)
|
|
|
|
var settingsJSON = getAccountSettings(account, alias, identicon, multiAccounts, constants.DEFAULT_NETWORKS)
|
2020-05-21 17:51:07 +00:00
|
|
|
|
2020-05-25 19:55:36 +00:00
|
|
|
result = saveAccountAndLogin(multiAccounts, alias, identicon, $accountData, password, $constants.NODE_CONFIG, $settingsJSON)
|
|
|
|
|
|
|
|
# TODO this is needed for now for the retrieving of past messages. We'll either move or remove it later
|
|
|
|
let peer = "enode://44160e22e8b42bd32a06c1532165fa9e096eebedd7fa6d6e5f8bbef0440bc4a4591fe3651be68193a7ec029021cdb496cfe1d7f9f1dc69eb99226e6f39a7a5d4@35.225.221.245:443"
|
|
|
|
discard libstatus.addPeer(peer)
|
2020-05-27 07:15:42 +00:00
|
|
|
|
|
|
|
proc login*(nodeAccount: NodeAccount, password: string): NodeAccount =
|
|
|
|
let hashedPassword = "0x" & $keccak_256.digest(password)
|
|
|
|
let account = nodeAccount.toAccount
|
|
|
|
let loginResult = $libstatus.login($toJson(account), hashedPassword)
|
|
|
|
let error = parseJson(loginResult)["error"].getStr
|
|
|
|
|
|
|
|
if error == "":
|
|
|
|
debug "Login requested", user=nodeAccount.name
|
|
|
|
result = nodeAccount
|
|
|
|
return
|
|
|
|
|
|
|
|
raise newException(LoginError, "Error logging in: " & error)
|