Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Governance vue #375

Open
wants to merge 66 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 53 commits
Commits
Show all changes
66 commits
Select commit Hold shift + click to select a range
e428ac3
Initial rewrite
Duddino Aug 6, 2024
f9d2310
Desktop governance page
Duddino Aug 7, 2024
515e7a3
Finish governance table for mobile
Duddino Aug 8, 2024
eb5ea8e
Change useSettings to store
Duddino Aug 8, 2024
c68853a
Add use_masternode
Duddino Aug 12, 2024
b3b47ee
Split masternode component and implement CreateMasternode
Duddino Aug 12, 2024
cc5c34c
Move import wallet inside RestoreWallet component
Duddino Aug 13, 2024
d797f95
Add import masternode form
Duddino Aug 13, 2024
9e0c14c
Add import wallet box
Duddino Aug 14, 2024
f92e32d
Fix masternode import page
Duddino Aug 14, 2024
3af033e
Add controller
Duddino Aug 14, 2024
8a34a6e
Finish mn controller
Duddino Aug 14, 2024
4a6a289
Add create proposal modal
Duddino Aug 20, 2024
7e6badb
Add automatic proposal confirmation
Duddino Aug 21, 2024
13b9500
Fix start error
Duddino Aug 21, 2024
d779e20
Add Create Proposal row
Duddino Aug 23, 2024
d92f6ac
Add proposal finalisation
Duddino Aug 23, 2024
c17d5f7
Add vote popup
Duddino Aug 23, 2024
676c6be
Flipdown reactive
Duddino Aug 23, 2024
de06304
Split BudgetAllocated and MonthlyBudget components
Duddino Aug 26, 2024
beb4c1e
Clean up some dom elements
Duddino Aug 26, 2024
aab7745
Fix over budget calculation
Aug 29, 2024
2783ef5
Add i18n mock
Aug 29, 2024
09973af
Add governance tests and test-ids.
Aug 29, 2024
230d373
Remove unused component
Aug 30, 2024
b7d7269
Fix stake balance clearing mocks instead of returing function
Aug 30, 2024
ddd0330
Improve translation mock
Aug 30, 2024
5a0d4ef
Add masternode component tests
Aug 30, 2024
a910aab
Merge remote-tracking branch 'origin/master' into governance-vue
Duddino Sep 30, 2024
6886414
Re-apply #394 to vue (Remove governance dots on mobile)
Duddino Sep 30, 2024
2a92f88
Fix minor merge errors
Duddino Sep 30, 2024
181e43d
Fix local proposal status
Duddino Oct 2, 2024
d92ba63
Merge remote-tracking branch 'origin/master' into governance-vue
Duddino Oct 2, 2024
c66b466
Add actual currency
Duddino Oct 2, 2024
a10993f
Add finalizeProposalButton v-if to tests
Duddino Oct 2, 2024
46d4ab2
Clean up code
Duddino Oct 2, 2024
437bf45
Remove should be fine
Duddino Oct 2, 2024
468f1bf
Clean up masternode code and update when tab is clicked
Duddino Oct 2, 2024
cb85aa2
Update governance when tab is clicked
Duddino Oct 2, 2024
2efd09d
Remove legacy exports
Duddino Oct 2, 2024
df2f4de
Add mastenrode and governance tab to tests
Duddino Oct 2, 2024
88174c9
Fix test not passing on machines with different timezones
Duddino Oct 2, 2024
4c094e5
Fix eslint warnings
Duddino Oct 2, 2024
f1917a5
Merge branch 'master' into governance-vue
Duddino Oct 7, 2024
a99051c
Merge remote-tracking branch 'origin/master' into governance-vue
Duddino Oct 28, 2024
dfc723b
Apply #392 to vue
Duddino Oct 28, 2024
a1bf514
Merge branch 'master' into governance-vue
Duddino Oct 28, 2024
83d7a03
Remove console.logs
Duddino Oct 28, 2024
403cbfd
Fix eslint
Duddino Oct 28, 2024
7dfb079
Fix tests
Duddino Oct 28, 2024
9a9a9c6
Change createAlert
Duddino Oct 28, 2024
4ed2104
Fix overbudget bug
Duddino Oct 28, 2024
3a0458a
Fix undefined alert
Duddino Oct 28, 2024
9b7acf0
Merge remote-tracking branch 'origin/master' into governance-vue
Duddino Nov 4, 2024
98ee373
Fix post-merge import
Duddino Nov 4, 2024
9519c0f
Add alert when trying to vote without a masternode
Duddino Nov 4, 2024
dc4bc80
Open explorer when clicking on address
Duddino Nov 4, 2024
47e03f7
Remove openExplorer event
Duddino Nov 4, 2024
a781f45
Update test
Duddino Nov 4, 2024
742f369
Revert createMasternode logic
Duddino Nov 4, 2024
e619789
Teleport confirmVoteModal and style cancel button
Duddino Nov 4, 2024
1fbd660
Fix teleport test
Duddino Nov 4, 2024
5225010
Merge remote-tracking branch 'origin/master' into governance-vue
Duddino Nov 5, 2024
796a9ba
Fix mn starting not working
Duddino Nov 5, 2024
3f4a343
Fix button height being different
Duddino Nov 5, 2024
5156940
Fix close bug
Duddino Nov 5, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions assets/icons/icon-arrow.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
302 changes: 2 additions & 300 deletions index.template.html

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions locale/en/translation.toml
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,7 @@ MN_BAD_IP = "The IP address is invalid!" # The IP address is invalid!
MN_BAD_PRIVKEY = "The private key is invalid" # The private key is invalid
MN_NOT_ENOUGH_COLLAT = "You need <b>{amount} more {ticker}</b> to create a Masternode!" # You need <b>{amount} more {ticker}</b> to create a Masternode!
MN_ENOUGH_BUT_NO_COLLAT = "You have enough balance for a Masternode, but no valid collateral UTXO of {amount} {ticker}" # You have enough balance for a Masternode, but no valid collateral UTXO of {amount} {ticker}
MN_UNLOCK_WALLET = "Please import your <b> COLLATERAL WALLET</b> first."
MN_COLLAT_NOT_SUITABLE = "This is not a suitable UTXO for a Masternode" # This is not a suitable UTXO for a Masternode
MN_CANT_CONNECT = "Unable to connect to RPC node!" # Unable to connect to RPC node!
CONTACTS_ENCRYPT_FIRST = "You need to hit \"{button}\" before you can use Contacts!" # You need to hit "{button}" before you can use Contacts!
Expand Down
1 change: 1 addition & 0 deletions locale/template/translation.toml
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,7 @@ MN_BAD_IP = "The IP address is invalid!"
MN_BAD_PRIVKEY = "The private key is invalid"
MN_NOT_ENOUGH_COLLAT = "You need <b>{amount} more {ticker}</b> to create a Masternode!"
MN_ENOUGH_BUT_NO_COLLAT = "You have enough balance for a Masternode, but no valid collateral UTXO of {amount} {ticker}"
MN_UNLOCK_WALLET = "Please import your <b> COLLATERAL WALLET</b> first."
MN_COLLAT_NOT_SUITABLE = "This is not a suitable UTXO for a Masternode"
MN_CANT_CONNECT = "Unable to connect to RPC node!"
CONTACTS_ENCRYPT_FIRST = "You need to hit \"{button}\" before you can use Contacts!"
Expand Down
20 changes: 17 additions & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@
"pivx-shield-rust-multicore": "^1.1.10",
"qr-scanner": "^1.4.2",
"qrcode-generator": "^1.4.4",
"uuid": "^10.0.0",
"vue": "^3.3.4",
"vue-router": "^4.2.4"
},
Expand Down
29 changes: 29 additions & 0 deletions scripts/__mocks__/i18n.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
export const ALERTS = new Proxy(
{},
{
get(_target, prop) {
// Return the proxy itself if trying to access ALERTS
if (prop === 'ALERTS') return translation;
// Return key in tests so they aren't affected by translation changes
return prop;
},
}
);

export const translation = ALERTS;

export const tr = (message, vars) => {
return (
message +
' ' +
vars
.map((v) => {
let varStr = '';
for (const key in v) {
varStr += key + ' ' + v[key];
}
return varStr;
})
.join(' ')
);
};
50 changes: 50 additions & 0 deletions scripts/composables/use_masternode.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { ref, watch, toRaw } from 'vue';
import { defineStore } from 'pinia';
import { Database } from '../database.js';
import { getEventEmitter } from '../event_bus.js';

export const useMasternode = defineStore('masternode', () => {
/**
* @type{import('vue').Ref<import('../masternode.js').default?>}
*/
const masternode = ref(null);
const localProposals = ref([]);
watch(
localProposals,
async () => {
const database = await Database.getInstance();
const account = await database.getAccount();
if (account) {
account.localProposals = toRaw(localProposals.value);
await database.updateAccount(account);
}
},
{
// We need deep reactivity to detect proposal changes e.g. proposalHeight update when it gets confirmed
deep: true,
}
);
const fetchProposalsFromDatabase = async () => {
const database = await Database.getInstance();
const account = await database.getAccount();
localProposals.value = account?.localProposals ?? [];
};

const fetchMasternodeFromDatabase = async () => {
const database = await Database.getInstance();
masternode.value = await database.getMasternode();
};

watch(masternode, async () => {
const database = await Database.getInstance();
await database.addMasternode(toRaw(masternode.value));
});

fetchProposalsFromDatabase().then(() => {});
fetchMasternodeFromDatabase().then(() => {});
getEventEmitter().on('toggle-network', () => {
fetchProposalsFromDatabase().then(() => {});
fetchMasternodeFromDatabase().then(() => {});
});
return { masternode, localProposals };
});
5 changes: 3 additions & 2 deletions scripts/composables/use_settings.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { defineStore } from 'pinia';
import { getEventEmitter } from '../event_bus.js';
import { ref, watch } from 'vue';
import { watchIgnorable } from '@vueuse/core';
Expand All @@ -11,7 +12,7 @@ import {
} from '../settings.js';
import { cChainParams } from '../chain_params.js';

export function useSettings() {
export const useSettings = defineStore('settings', () => {
const advancedMode = ref(fAdvancedMode);
const displayDecimals = ref(0);
const autoLockWallet = ref(false);
Expand Down Expand Up @@ -59,4 +60,4 @@ export function useSettings() {
debug,
isTestnet,
};
}
});
14 changes: 14 additions & 0 deletions scripts/composables/use_wallet.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { cOracle } from '../prices.js';
import { ledgerSignTransaction } from '../ledger.js';
import { defineStore } from 'pinia';
import { lockableFunction } from '../lock.js';
import { blockCount as rawBlockCount } from '../global.js';
import { doms } from '../global.js';
import {
RECEIVE_TYPES,
Expand Down Expand Up @@ -54,6 +55,8 @@ export const useWallet = defineStore('wallet', () => {
const isEncrypted = ref(true);
const loadFromDisk = () => wallet.loadFromDisk();
const hasShield = ref(wallet.hasShield());
const getNewAddress = (nReceiving) => wallet.getNewAddress(nReceiving);
const blockCount = ref(0);

const setMasterKey = async ({ mk, extsk }) => {
await wallet.setMasterKey({ mk, extsk });
Expand Down Expand Up @@ -122,9 +125,12 @@ export const useWallet = defineStore('wallet', () => {
}
);
const isCreatingTransaction = () => createAndSendTransaction.isLocked();
const getMasternodeUTXOs = () => wallet.getMasternodeUTXOs();
const getPath = (script) => wallet.getPath(script);

getEventEmitter().on('toggle-network', async () => {
isEncrypted.value = await hasEncryptedWallet();
blockCount.value = rawBlockCount;
});

getEventEmitter().on('wallet-import', async () => {
Expand All @@ -141,6 +147,10 @@ export const useWallet = defineStore('wallet', () => {
price.value = cOracle.getCachedPrice(strCurrency);
});

getEventEmitter().on('new-block', () => {
blockCount.value = rawBlockCount;
});

return {
publicMode,
isImported,
Expand All @@ -156,6 +166,7 @@ export const useWallet = defineStore('wallet', () => {
checkDecryptPassword,
encrypt,
getAddress,
getNewAddress,
wipePrivateData: () => {
wallet.wipePrivateData();
isViewOnly.value = wallet.isViewOnly();
Expand All @@ -173,5 +184,8 @@ export const useWallet = defineStore('wallet', () => {
createAndSendTransaction,
loadFromDisk,
coldBalance,
getMasternodeUTXOs,
getPath,
blockCount,
};
});
20 changes: 4 additions & 16 deletions scripts/dashboard/Dashboard.vue
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,9 @@ const needsToEncrypt = computed(() => {
}
});
const showTransferMenu = ref(false);
const { advancedMode, displayDecimals, autoLockWallet } = useSettings();
const { advancedMode, displayDecimals, autoLockWallet } = storeToRefs(
useSettings()
);
const showExportModal = ref(false);
const showEncryptModal = ref(false);
const keyToBackup = ref('');
Expand Down Expand Up @@ -186,20 +188,6 @@ async function restoreWallet(strReason) {
});
}

async function importWif(wif, extsk) {
const secret = await ParsedSecret.parse(wif);
if (secret.masterKey) {
await wallet.setMasterKey({ mk: secret.masterKey, extsk });
if (wallet.hasShield && !extsk) {
createAlert(
'warning',
'Could not decrypt sk even if password is correct, please contact a developer'
);
}
createAlert('success', ALERTS.WALLET_UNLOCKED, 1500);
}
}

/**
* Lock the wallet by deleting masterkey private data, after user confirmation
*/
Expand Down Expand Up @@ -948,7 +936,7 @@ defineExpose({
<RestoreWallet
:show="showRestoreWallet"
:reason="restoreWalletReason"
:wallet="wallet"
@close="showRestoreWallet = false"
@import="importWif"
/>
</template>
20 changes: 19 additions & 1 deletion scripts/dashboard/RestoreWallet.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,17 @@ import Password from '../Password.vue';
import { ALERTS, translation } from '../i18n.js';
import { Database } from '../database.js';
import { decrypt } from '../aes-gcm';
import { ParsedSecret } from '../parsed_secret';
import { useAlerts } from '../composables/use_alerts.js';

const { createAlert } = useAlerts();

const props = defineProps({
show: Boolean,
reason: String,
wallet: Object,
});
const { show, reason } = toRefs(props);
const { show, reason, wallet } = toRefs(props);
const emit = defineEmits(['close', 'import']);
const password = ref('');
const passwordInput = ref(null);
Expand All @@ -24,12 +27,27 @@ watch(show, (show) => {
if (!show) password.value = '';
});

async function importWif(wif, extsk) {
const secret = await ParsedSecret.parse(wif);
if (secret.masterKey) {
await wallet.value.setMasterKey({ mk: secret.masterKey, extsk });
if (wallet.value.hasShield && !extsk) {
createAlert(
'warning',
'Could not decrypt sk even if password is correct, please contact a developer'
);
}
createAlert('success', ALERTS.WALLET_UNLOCKED, 1500);
}
}

async function submit() {
const db = await Database.getInstance();
const account = await db.getAccount();
const wif = await decrypt(account.encWif, password.value);
const extsk = await decrypt(account.encExtsk, password.value);
if (wif) {
await importWif(wif, extsk);
emit('import', wif, extsk);
} else {
createAlert('warning', ALERTS.FAILED_TO_IMPORT);
Expand Down
Loading
Loading