diff --git a/src/background.js b/src/background.js index 4a6a0cd5..b9a5087b 100644 --- a/src/background.js +++ b/src/background.js @@ -46,6 +46,24 @@ const logger = new Logger(isDevMode ? 3 : 0); let tray = null; let regexBTS = /1.2.\d+/g; + +async function _readFile(filePath) { + return new Promise((resolve, reject) => { + if (!filePath || !filePath.includes(".bin")) { + return reject("Invalid file path"); + } + + fs.readFile(filePath, async (err, data) => { + if (err) { + console.log({ err }); + return reject(err); + } else { + return resolve(data); + } + }); + }); +} + /* * On modal popup this runs to create child browser window */ @@ -874,6 +892,7 @@ const createWindow = async () => { if (methods.includes("localFileUpload")) { const { allowedOperations, filePath } = arg; + fs.readFile(filePath, "utf-8", async (error, data) => { if (!error) { let apiobj; @@ -1060,38 +1079,45 @@ const createWindow = async () => { } } } - + if (methods.includes("decryptBackup")) { const { filePath, pass } = arg; - fs.readFile(filePath, async (err, data) => { - if (err) { - console.log({ err }); - } else { - let wh = new BTSWalletHandler(data); - let unlocked; + + let _data; + try { + _data = await _readFile(filePath); + } catch (error) { + console.log({ error }); + } + + if (_data) { + let wh = new BTSWalletHandler(_data); + + let unlocked; + try { + unlocked = await wh.unlock(pass); + } catch (error) { + console.log({ error }); + } + + if (unlocked) { + let retrievedAccounts; try { - unlocked = await wh.unlock(pass); + retrievedAccounts = await blockchain.lookupAccounts( + wh.public, + wh.keypairs + ); } catch (error) { console.log({ error }); - return; } - - if (unlocked) { - let retrievedAccounts; - try { - retrievedAccounts = await wh.lookupAccounts( - mainWindow.webContents - ); - } catch (error) { - console.log({ error }); - } - - if (retrievedAccounts) { - responses["decryptBackup"] = retrievedAccounts; - } + + if (retrievedAccounts) { + responses["decryptBackup"] = retrievedAccounts; } } - }); + + wh = null; + } } return responses; diff --git a/src/components/blockchains/bitshares/ImportBinFile.vue b/src/components/blockchains/bitshares/ImportBinFile.vue index 4a937ab2..fd74aab9 100644 --- a/src/components/blockchains/bitshares/ImportBinFile.vue +++ b/src/components/blockchains/bitshares/ImportBinFile.vue @@ -57,6 +57,7 @@ if (pickedAccounts && pickedAccounts.length) { console.log('importing accounts'); emit('imported', pickedAccounts); + emit('continue'); } } @@ -69,11 +70,11 @@ methods: ["decryptBackup"], location: 'importBinFile', chain: props.chain, - filePath: wallet_file.value, + filePath: wallet_file.value.path, pass: bin_file_password.value }); } catch (error) { - console.log(error); + console.log({error}); inProgress.value = false; window.electron.notify(t("common.error_text")); return; @@ -84,6 +85,7 @@ substep1.value = false; substep2.value = true; } + inProgress.value = false; } else { _getPickedAccounts(); diff --git a/src/lib/blockchains/BitShares.js b/src/lib/blockchains/BitShares.js index b1a98148..daa07177 100644 --- a/src/lib/blockchains/BitShares.js +++ b/src/lib/blockchains/BitShares.js @@ -820,6 +820,89 @@ export default class BitShares extends BlockchainAPI { return fastestPromise; } + /** + * Format account details for use in account lookup + */ + _buildMatrix(account_data, public_key_auths, keypairs) { + const getAccountDetails = (account, type) => { + let details = { + availWeight: 0, + canPropose: false, + canTransact: false + }; + for (let auth of account[type].key_auths) { + if (public_key_auths.includes(auth[0])) { + details.canPropose = true; + details.availWeight += auth[1]; + if (auth[1] >= account[type].weight_threshold) { + details.key = keypairs.find(x => x.pub == auth[0]).priv; + details.canTransact = true; + } + } + } + return details; + } + + return account_data.map(account => { + let account_details = { + id: account.id, + name: account.name + }; + account_details.active = getAccountDetails(account, 'active'); + account_details.owner = getAccountDetails(account, 'owner'); + account_details.importable = account_details.active.canTransact || account_details.owner.canTransact; + let memo = { + canSend: false + }; + if (public_key_auths.includes(account.options.memo_key)) { + memo.key = keypairs.find(x => x.pub == account.options.memo_key).priv; + memo.canSend = true; + } + account_details.memo = memo; + return account_details; + }); + } + + /** + * Used for BTS bin file import verification + */ + async lookupAccounts(public_key_auths, keyPairs) { + try { + await this.ensureConnection(); + + let account_ids = await Apis.instance() + .db_api() + .exec("get_key_references", [public_key_auths]); + + let accounts = new Set(account_ids.flat()); + + let refs = Array.from(accounts).map(account => + Apis.instance() + .db_api() + .exec("get_account_references", [account]) + .then(res => { + if (res.length > 0) { + res.forEach(ref => accounts.add(ref)); + } + }) + ); + + await Promise.all(refs); + + let finalAccounts = Array.from(accounts); + + let account_matrix = await Apis.instance() + .db_api() + .exec("get_accounts", [finalAccounts]) + .then(res => this._buildMatrix(res, public_key_auths, keyPairs)); + + return account_matrix; + } catch (error) { + console.log(error); + throw error; + } + } + /* * Get the associated Bitshares account name from the provided account ID * @param {String} accountId diff --git a/src/lib/blockchains/bitshares/BTSWalletHandler.js b/src/lib/blockchains/bitshares/BTSWalletHandler.js index f49946f0..5a3b9eef 100644 --- a/src/lib/blockchains/bitshares/BTSWalletHandler.js +++ b/src/lib/blockchains/bitshares/BTSWalletHandler.js @@ -6,17 +6,13 @@ import { import { decompress } from "lzma"; -import { - Apis -} from "bitsharesjs-ws"; - -import getBlockchainAPI from "../blockchainFactory.js"; class BTSWalletHandler { constructor(backup) { this.wallet_buffer = Buffer.from(backup, "binary"); } + unlock(wallet_pass) { try { this.wallet_pass = wallet_pass; @@ -57,114 +53,5 @@ class BTSWalletHandler { throw new Error('Could not decrypt wallet'); } } - - async lookupAccounts(webContents) { - - let blockchain = getBlockchainAPI('BTS'); - await blockchain.ensureConnection().then((connectedNode) => { - webContents.send('setNode', connectedNode); - }); - let account_ids = await Apis.instance() - .db_api() - .exec("get_key_references", [this.public]) - .then(res => { - return res; - }); - this.accounts = new Set(); - for (let i = 0; i < account_ids.length; i++) { - for (let j = 0; j < account_ids[i].length; j++) { - this.accounts.add(account_ids[i][j]); - } - } - let refs = []; - this.accounts.forEach((account) => { - refs.push( - Apis.instance() - .db_api() - .exec("get_account_references", [account]) - .then(res => { - if (res.length > 0) { - res.forEach((ref) => { - this.accounts.add(ref); - }) - } - }) - ); - }); - await Promise.all(refs); - let accounts = Array.from(this.accounts); - let account_matrix = await Apis.instance() - .db_api() - .exec("get_accounts", [accounts]) - .then(res => { - return this.buildMatrix(res); - }); - return account_matrix; - } - buildMatrix(account_data) { - let account_matrix = []; - let active_controlled_accounts = []; - let owner_controlled_accounts = []; - for (let i = 0; i < account_data.length; i++) { - let account_details = { - 'id': account_data[i].id, - 'name': account_data[i].name - }; - let active = {}; - let importable = false; - //Check active - active.availWeight = 0; - active.canPropose = false; - for (let j = 0; j < account_data[i].active.key_auths.length; j++) { - if (this.public.includes(account_data[i].active.key_auths[j][0])) { - active.canPropose = true; - active.availWeight = active.availWeight + account_data[i].active.key_auths[j][1]; - if (account_data[i].active.key_auths[j][1] >= account_data[i].active.weight_threshold) { - importable = true; - active.key = this.keypairs.filter(x => x.pub == account_data[i].active.key_auths[j][0])[0].priv; - } - } - } - if (active.availWeight >= account_data[i].active.weight_threshold) { - active.canTransact = true; - active_controlled_accounts.push(account_data[i].id); - } else { - active.canTransact = false; - } - account_details.active = active; - - let owner = {} - //Check owner - owner.availWeight = 0; - owner.canPropose = false; - for (let j = 0; j < account_data[i].owner.key_auths.length; j++) { - if (this.public.includes(account_data[i].owner.key_auths[j][0])) { - owner.canPropose = true; - owner.availWeight = owner.availWeight + account_data[i].owner.key_auths[j][1]; - if (account_data[i].owner.key_auths[j][1] >= account_data[i].owner.weight_threshold) { - owner.key = this.keypairs.filter(x => x.pub == account_data[i].owner.key_auths[j][0])[0].priv; - } - } - } - if (owner.availWeight >= account_data[i].owner.weight_threshold) { - owner.canTransact = true; - owner_controlled_accounts.push(account_data[i].id); - } else { - owner.canTransact = false; - } - account_details.owner = owner; - - let memo = {}; - memo.canSend = false; - if (this.public.includes(account_data[i].options.memo_key)) { - memo.key = this.keypairs.filter(x => x.pub == account_data[i].options.memo_key)[0].priv; - memo.canSend = true; - } - account_details.importable = importable; - account_details.memo = memo; - account_matrix[i] = account_details; - } - return account_matrix; - } } export default BTSWalletHandler;