import Vue from 'vue'; import { getInstance } from '@/helpers/plugins/LockPlugin'; import { getScores } from '@/helpers/get-scores'; import client from '@/helpers/client'; import ipfs from '@/helpers/ipfs'; import { formatProposal, formatProposals, formatSpace } from '@/helpers/utils'; import { getBlockNumber, signMessage } from '@/helpers/web3'; import { waitZilPay } from '@/helpers/wait-zipay'; import { version } from '@/../package.json'; const state = { init: false, loading: false, spaces: {} }; const mutations = { SET(_state, payload) { Object.keys(payload).forEach(key => { Vue.set(_state, key, payload[key]); }); }, SEND_REQUEST() { console.debug('SEND_REQUEST'); }, SEND_SUCCESS() { console.debug('SEND_SUCCESS'); }, SEND_FAILURE(_state, payload) { console.debug('SEND_FAILURE', payload); }, GET_PROPOSALS_REQUEST() { console.debug('GET_PROPOSALS_REQUEST'); }, GET_PROPOSALS_SUCCESS() { console.debug('GET_PROPOSALS_SUCCESS'); }, GET_PROPOSALS_FAILURE(_state, payload) { console.debug('GET_PROPOSALS_FAILURE', payload); }, GET_PROPOSAL_REQUEST() { console.debug('GET_PROPOSAL_REQUEST'); }, GET_PROPOSAL_SUCCESS() { console.debug('GET_PROPOSAL_SUCCESS'); }, GET_PROPOSAL_FAILURE(_state, payload) { console.debug('GET_PROPOSAL_FAILURE', payload); }, GET_POWER_REQUEST() { console.debug('GET_POWER_REQUEST'); }, GET_POWER_SUCCESS() { console.debug('GET_POWER_SUCCESS'); }, GET_POWER_FAILURE(_state, payload) { console.debug('GET_POWER_FAILURE', payload); } }; const actions = { init: async ({ commit, dispatch }) => { commit('SET', { loading: true }); const connector = await Vue.prototype.$auth.getConnector(); if (connector) await dispatch('login', connector); await dispatch('getSpaces'); commit('SET', { loading: false, init: true }); }, loading: ({ commit }, payload) => { commit('SET', { loading: payload }); }, getSpaces: async ({ commit }) => { let spaces: any = await client.request('spaces'); spaces = Object.fromEntries( Object.entries(spaces).map(space => [ space[0], formatSpace(space[0], space[1]) ]) ); commit('SET', { spaces }); return spaces; }, send: async ({ commit, dispatch, rootState }, { token, type, payload }) => { const auth = getInstance(); commit('SEND_REQUEST'); try { const msg: any = { address: rootState.web3.account.base16, msg: JSON.stringify({ version, timestamp: (Date.now() / 1e3).toFixed(), token, type, payload }) }; msg.sig = await signMessage(auth.web3, msg.msg); const result = await client.request('message', msg); commit('SEND_SUCCESS'); dispatch('notify', ['green', `Your ${type} is in!`]); return result; } catch (e) { commit('SEND_FAILURE', e); const errorMessage = e && e.error_description ? `Oops, ${e.error_description}` : 'Oops, something went wrong!'; dispatch('notify', ['red', errorMessage]); return; } }, getProposals: async ({ commit }, space) => { commit('GET_PROPOSALS_REQUEST'); let zilPay = null; try { zilPay = await waitZilPay(); } catch { // } try { let proposals: any = await client.request(`${space.key}/proposals`); if (proposals) { const scores = await getScores( space.strategies, zilPay, Object.values(proposals).map((proposal: any) => proposal.address) ); proposals = Object.fromEntries( Object.entries(proposals).map((proposal: any) => { proposal[1].score = scores.reduce( (a, b) => a + Number(b[proposal[1].address]), 0 ); return [proposal[0], proposal[1]]; }) ); } commit('GET_PROPOSALS_SUCCESS'); return formatProposals(proposals); } catch (e) { commit('GET_PROPOSALS_FAILURE', e); } }, getProposal: async ({ commit }, payload) => { commit('GET_PROPOSAL_REQUEST'); let zilPay = {}; try { zilPay = await waitZilPay(); } catch { /// } try { const result: any = {}; const [proposal, votes] = await Promise.all([ ipfs.get(payload.id), client.request(`${payload.space.key}/proposal/${payload.id}`) ]); result.proposal = formatProposal(proposal); result.proposal.ipfsHash = payload.id; result.votes = votes; window['proposal'] = proposal; const scores: any = await getScores( payload.space.strategies, zilPay, Object.keys(result.votes) ); result.votes = Object.fromEntries( Object.entries(result.votes) .map((vote: any) => { vote[1].scores = payload.space.strategies.map((strategy, i) => { return scores[i][String(vote[1].address).toLowerCase()] || 0; }); vote[1].balance = vote[1].scores.reduce((a, b: any) => a + b, 0); return vote; }) .sort((a, b) => b[1].balance - a[1].balance) .filter(vote => Number(vote[1].balance) > 0) ); result.results = { totalVotes: result.proposal.msg.payload.choices.map( (choice, i) => Object.values(result.votes).filter( (vote: any) => vote.msg.payload.choice === i + 1 ).length ), totalBalances: result.proposal.msg.payload.choices.map((choice, i) => Object.values(result.votes) .filter((vote: any) => vote.msg.payload.choice === i + 1) .reduce((a, b: any) => a + b.balance, 0) ), totalScores: result.proposal.msg.payload.choices.map((choice, i) => payload.space.strategies.map((strategy, sI) => Object.values(result.votes) .filter((vote: any) => vote.msg.payload.choice === i + 1) .reduce((a, b: any) => a + b.scores[sI], 0) ) ), totalVotesBalances: Object.values(result.votes).reduce( (a, b: any) => Number(a) + Number(b.balance), 0 ) }; commit('GET_PROPOSAL_SUCCESS'); return result; } catch (e) { commit('GET_PROPOSAL_FAILURE', e); } }, getPower: async ({ commit }, { space, address, snapshot }) => { commit('GET_POWER_REQUEST'); try { const zilPay = await waitZilPay(); const blockNumber = await getBlockNumber(zilPay); const blockTag = snapshot > blockNumber ? 'latest' : parseInt(snapshot); let scores: any = await getScores( space.strategies, zilPay, [address], // @ts-ignore blockTag ); scores = scores.map((score: any) => Object.values(score).reduce((a, b: any) => a + b, 0) ); commit('GET_POWER_SUCCESS'); return { scores, totalScore: scores.reduce((a, b: any) => a + b, 0) }; } catch (e) { commit('GET_POWER_FAILURE', e); } } }; export default { state, mutations, actions };