Skip to content

Commit

Permalink
Refactor Dashboard with useWallet and useSettings composables (#271)
Browse files Browse the repository at this point in the history
* Refactor Dashboard with useWallet and useSettings composables

* Review changes
  • Loading branch information
Duddino committed Nov 25, 2023
1 parent 934f7aa commit 7c7c1da
Show file tree
Hide file tree
Showing 4 changed files with 145 additions and 58 deletions.
19 changes: 19 additions & 0 deletions scripts/composables/use_settings.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { getEventEmitter } from '../event_bus.js';
import { ref } from 'vue';
import { nDisplayDecimals, fAdvancedMode } from '../settings.js';

export function useSettings() {
const advancedMode = ref(fAdvancedMode);
const displayDecimals = ref(0);

getEventEmitter().on('advanced-mode', (fAdvancedMode) => {
advancedMode.value = fAdvancedMode;
});
getEventEmitter().on('balance-update', async () => {
displayDecimals.value = nDisplayDecimals;
});
return {
advancedMode,
displayDecimals,
};
}
74 changes: 74 additions & 0 deletions scripts/composables/use_wallet.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import { getEventEmitter } from '../event_bus.js';
import { hasEncryptedWallet, wallet } from '../wallet.js';
import { ref } from 'vue';
import { strCurrency } from '../settings.js';
import { mempool } from '../global.js';
import { cMarket } from '../settings.js';

/**
* This is the middle ground between vue and the wallet class
* It makes sure that everything is up to date and provides
* a reactive interface to it
*/
export function useWallet() {
// Eventually we want to create a new wallet
// For now we'll just import the existing one
// const wallet = new Wallet();

const isImported = ref(wallet.isLoaded());
const isViewOnly = ref(wallet.isViewOnly());
const getKeyToBackup = async () => await wallet.getKeyToBackup();
const isEncrypted = ref(true);

const setMasterKey = (mk) => {
wallet.setMasterKey(mk);
isImported.value = wallet.isLoaded();
isHardwareWallet.value = wallet.isHardwareWallet();
isHD.value = wallet.isHD();
isViewOnly.value = wallet.isViewOnly();
hasEncryptedWallet().then((i) => (isEncrypted.value = i));
};
const getAddress = () => wallet.getAddress();
const isHardwareWallet = ref(wallet.isHardwareWallet());
const isHD = ref(wallet.isHD());
const checkDecryptPassword = async (passwd) =>
await wallet.checkDecryptPassword(passwd);

hasEncryptedWallet().then((r) => {
isEncrypted.value = r;
});

const encrypt = async (passwd) => {
await wallet.encrypt(passwd);
isEncrypted.value = await hasEncryptedWallet();
};
const balance = ref(0);
const currency = ref('USD');
const price = ref(0.0);

getEventEmitter().on('balance-update', async () => {
balance.value = mempool.balance;
currency.value = strCurrency.toUpperCase();
price.value = await cMarket.getPrice(strCurrency);
});

return {
isImported,
isViewOnly,
isEncrypted,
getKeyToBackup,
setMasterKey,
isHardwareWallet,
checkDecryptPassword,
encrypt,
getAddress,
wipePrivateData: () => {
wallet.wipePrivateData();
isViewOnly.value = wallet.isViewOnly();
},
isHD,
balance,
currency,
price,
};
}
104 changes: 49 additions & 55 deletions scripts/dashboard/Dashboard.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,7 @@ import Activity from './Activity.vue';
import GenKeyWarning from './GenKeyWarning.vue';
import TransferMenu from './TransferMenu.vue';
import ExportPrivKey from './ExportPrivKey.vue';
import {
cleanAndVerifySeedPhrase,
hasEncryptedWallet,
wallet,
} from '../wallet.js';
import { cleanAndVerifySeedPhrase } from '../wallet.js';
import { parseWIF, verifyWIF } from '../encoding.js';
import {
createAlert,
Expand All @@ -26,7 +22,7 @@ import {
} from '../masterkey';
import { decrypt } from '../aes-gcm.js';
import { cChainParams, COIN } from '../chain_params';
import { onMounted, ref, watch } from 'vue';
import { onMounted, ref, watch, computed } from 'vue';
import { mnemonicToSeed } from 'bip39';
import { getEventEmitter } from '../event_bus';
import { Database } from '../database';
Expand All @@ -36,7 +32,6 @@ import {
updateEncryptionGUI,
updateLogOutButton,
} from '../global';
import { cMarket, nDisplayDecimals, strCurrency } from '../settings.js';
import { mempool, refreshChainData } from '../global.js';
import {
confirmPopup,
Expand All @@ -49,16 +44,22 @@ import { validateAmount, createAndSendTransaction } from '../transactions.js';
import { strHardwareName } from '../ledger';
import { guiAddContactPrompt } from '../contacts-book';
import { scanQRCode } from '../scanner';
import { useWallet } from '../composables/use_wallet.js';
import { useSettings } from '../composables/use_settings.js';
const isImported = ref(wallet.isLoaded());
const isViewOnly = ref(wallet.isViewOnly());
const wallet = useWallet();
const activity = ref(null);
const needsToEncrypt = ref(true);
const needsToEncrypt = computed(() => {
if (wallet.isHardwareWallet.value) {
return false;
} else {
return !wallet.isViewOnly.value && !wallet.isEncrypted.value;
}
});
const showTransferMenu = ref(false);
const advancedMode = ref(false);
const { advancedMode, displayDecimals } = useSettings();
const showExportModal = ref(false);
const showEncryptModal = ref(false);
const isEncrypt = ref(false);
const keyToBackup = ref('');
const jdenticonValue = ref('');
const transferAddress = ref('');
Expand All @@ -71,9 +72,6 @@ watch(showExportModal, async (showExportModal) => {
keyToBackup.value = '';
}
});
getEventEmitter().on('advanced-mode', (fAdvancedMode) => {
advancedMode.value = fAdvancedMode;
});
/**
* Parses whatever the secret is to a MasterKey
Expand Down Expand Up @@ -173,17 +171,9 @@ async function importWallet({ type, secret, password = '' }) {
}
if (key) {
wallet.setMasterKey(key);
isImported.value = true;
jdenticonValue.value = wallet.getAddress();
isEncrypt.value = await hasEncryptedWallet();
if (!wallet.isHardwareWallet()) {
needsToEncrypt.value = !wallet.isViewOnly() && !isEncrypt.value;
} else {
needsToEncrypt.value = false;
}
if (needsToEncrypt.value) showEncryptModal.value = true;
isViewOnly.value = wallet.isViewOnly();
await mempool.loadFromDisk();
getNetwork().walletFullSync();
getEventEmitter().emit('wallet-import');
Expand All @@ -199,7 +189,7 @@ async function importWallet({ type, secret, password = '' }) {
* @param {string} [currentPassword] - Current password with which the wallet is encrypted with, if any
*/
async function encryptWallet(password, currentPassword = '') {
if (await hasEncryptedWallet()) {
if (wallet.isEncrypted.value) {
if (!(await wallet.checkDecryptPassword(currentPassword))) {
createAlert('warning', ALERTS.INCORRECT_PASSWORD, 6000);
return false;
Expand All @@ -209,15 +199,13 @@ async function encryptWallet(password, currentPassword = '') {
if (res) {
createAlert('success', ALERTS.NEW_PASSWORD_SUCCESS, 5500);
}
needsToEncrypt.value = false;
isEncrypt.value = await hasEncryptedWallet();
// TODO: refactor once settings is written
await updateEncryptionGUI();
}
// TODO: This needs to be vueeifed a bit
async function restoreWallet(strReason) {
if (wallet.isHardwareWallet()) return true;
if (wallet.isHardwareWallet.value) return true;
// Build up the UI elements based upon conditions for the unlock prompt
let strHTML = '';
Expand All @@ -241,7 +229,6 @@ async function restoreWallet(strReason) {
const key = await parseSecret(encWif, strPassword);
if (key) {
wallet.setMasterKey(key);
isViewOnly.value = wallet.isViewOnly();
createAlert('success', ALERTS.WALLET_UNLOCKED, 1500);
return true;
} else {
Expand All @@ -258,7 +245,7 @@ async function restoreWallet(strReason) {
* Lock the wallet by deleting masterkey private data
*/
async function lockWallet() {
const isEncrypted = await hasEncryptedWallet();
const isEncrypted = wallet.isEncrypted.value;
const title = isEncrypted
? translation.popupWalletLock
: translation.popupWalletWipe;
Expand All @@ -272,7 +259,6 @@ async function lockWallet() {
})
) {
wallet.wipePrivateData();
isViewOnly.value = wallet.isViewOnly();
createAlert('success', ALERTS.WALLET_LOCKED, 1500);
}
}
Expand All @@ -284,11 +270,23 @@ async function lockWallet() {
*/
async function send(address, amount) {
// Ensure a wallet is loaded
if (!(await wallet.hasWalletUnlocked(true))) return;
if (wallet.isViewOnly.value) {
return createAlert(
'warning',
tr(ALERTS.WALLET_UNLOCK_IMPORT, [
{
unlock: wallet.isEncrypted.value
? 'unlock '
: 'import/create',
},
]),
3500
);
}
// Ensure the wallet is unlocked
if (
wallet.isViewOnly() &&
wallet.isViewOnly.value &&
!(await restoreWallet(translation.walletUnlockTx))
)
return;
Expand Down Expand Up @@ -365,17 +363,15 @@ async function send(address, amount) {
getEventEmitter().on('toggle-network', async () => {
const database = await Database.getInstance();
const account = await database.getAccount();
wallet.reset();
wallet.setMasterKey(null);
activity.value?.reset();
if (account) {
await importWallet({ type: 'hd', secret: account.publicKey });
} else {
isImported.value = false;
await (await Database.getInstance()).removeAllTxs();
}
await updateEncryptionGUI(wallet.isLoaded());
await updateEncryptionGUI(wallet.isImported.value);
updateLogOutButton();
// TODO: When tab component is written, simply emit an event
doms.domDashboard.click();
Expand All @@ -384,7 +380,7 @@ getEventEmitter().on('toggle-network', async () => {
onMounted(async () => {
await start();
if (await hasEncryptedWallet()) {
if (wallet.isEncrypted.value) {
const database = await Database.getInstance();
const { publicKey } = await database.getAccount();
await importWallet({ type: 'hd', secret: publicKey });
Expand All @@ -405,26 +401,16 @@ onMounted(async () => {
updateLogOutButton();
});
const balance = ref(0);
const currency = ref('USD');
const price = ref(0.0);
const displayDecimals = ref(0);
const { balance, currency, price } = wallet;
getEventEmitter().on('sync-status', (status) => {
if (status === 'stop') activity?.value?.update();
});
getEventEmitter().on('new-tx', (status) => {
getEventEmitter().on('new-tx', () => {
activity?.value?.update();
});
getEventEmitter().on('balance-update', async () => {
balance.value = mempool.balance;
currency.value = strCurrency.toUpperCase();
price.value = await cMarket.getPrice(strCurrency);
displayDecimals.value = nDisplayDecimals;
});
function changePassword() {
showEncryptModal.value = true;
}
Expand Down Expand Up @@ -485,7 +471,7 @@ defineExpose({
<div id="keypair" class="tabcontent">
<div class="row m-0">
<Login
v-show="!isImported"
v-show="!wallet.isImported.value"
:advancedMode="advancedMode"
@import-wallet="importWallet"
/>
Expand All @@ -495,7 +481,11 @@ defineExpose({
<!-- Unlock wallet -->
<div
class="col-12 p-0"
v-if="isViewOnly && !needsToEncrypt && isImported"
v-if="
wallet.isViewOnly.value &&
!needsToEncrypt &&
wallet.isImported.value
"
>
<center>
<div
Expand Down Expand Up @@ -530,7 +520,11 @@ defineExpose({
<!-- Lock wallet -->
<div
class="col-12"
v-if="!isViewOnly && !needsToEncrypt && isImported"
v-if="
!wallet.isViewOnly.value &&
!needsToEncrypt &&
wallet.isImported.value
"
>
<center>
<div class="dcWallet-warningMessage" @click="lockWallet()">
Expand Down Expand Up @@ -881,21 +875,21 @@ defineExpose({
@close="showExportModal = false"
/>
<!-- WALLET FEATURES -->
<div v-if="isImported">
<div v-if="wallet.isImported.value">
<GenKeyWarning
@onEncrypt="encryptWallet"
@close="showEncryptModal = false"
:showModal="showEncryptModal"
:showBox="needsToEncrypt"
:isEncrypt="isEncrypt"
:isEncrypt="wallet.isEncrypted.value"
/>
<div class="row p-0">
<!-- Balance in PIVX & USD-->
<WalletBalance
:balance="balance"
:jdenticonValue="jdenticonValue"
:isHdWallet="wallet.isHD()"
:isHardwareWallet="wallet.isHardwareWallet()"
:isHdWallet="wallet.isHD.value"
:isHardwareWallet="wallet.isHardwareWallet.value"
:currency="currency"
:price="price"
:displayDecimals="displayDecimals"
Expand Down
Loading

0 comments on commit 7c7c1da

Please sign in to comment.