diff --git a/src/actions/proposals.js b/src/actions/proposals.js index 852865c..9d59feb 100644 --- a/src/actions/proposals.js +++ b/src/actions/proposals.js @@ -55,8 +55,8 @@ export const getProposals = (cb) => (dispatch) => { }, }) .then((res) => { - dispatch(fetchProposalsSuccess(res.data && res.data.proposals)); - cb(res.data && res.data.proposals); + dispatch(fetchProposalsSuccess(res.data)); + cb(res.data); }) .catch((error) => { dispatch(fetchProposalsError( @@ -156,7 +156,7 @@ export const fetchVoteDetails = (id, address) => (dispatch) => { }, }) .then((res) => { - dispatch(fetchVoteDetailsSuccess(res.data && res.data.vote)); + dispatch(fetchVoteDetailsSuccess(res.data)); }) .catch((error) => { dispatch(fetchVoteDetailsError( @@ -244,7 +244,7 @@ export const fetchProposalDetails = (id, cb) => (dispatch) => { }, }) .then((res) => { - dispatch(fetchProposalDetailsSuccess(res.data && res.data.txs, id)); + dispatch(fetchProposalDetailsSuccess(res.data, id)); if (cb) { cb(res); } diff --git a/src/constants/url.js b/src/constants/url.js index 50f47c8..120f1c3 100644 --- a/src/constants/url.js +++ b/src/constants/url.js @@ -9,7 +9,8 @@ export const urlFetchVestingBalance = (address) => `${REST_URL}/cosmos/auth/v1be export const urlFetchUnBondingDelegations = (address) => `${REST_URL}/cosmos/staking/v1beta1/delegators/${address}/unbonding_delegations`; export const urlFetchRewards = (address) => `${REST_URL}/api/v1/pos/reward/${address}`; -export const urlFetchVoteDetails = (proposalId, address) => `${REST_URL}/cosmos/gov/v1beta1/proposals/${proposalId}/votes/${address}`; +// export const urlFetchVoteDetails = (proposalId, address) => `${REST_URL}/api/v1/gov/voter/${proposalId}/votes/${address}` +export const urlFetchVoteDetails = (proposalId, address) => `${REST_URL}/api/v1/gov/voter/${address}/votes`; export const urlFetchRevealedPubkey = (address) => `${REST_URL}/api/v1/revealed-public-key/${address}`; export const VALIDATORS_LIST_URL = () => `${REST_URL}/api/v1/pos/validator/all?state=consensus`; @@ -17,10 +18,10 @@ export const GENESIS_VALIDATORS_LIST_URL = 'https://namada.info/shielded-expedit export const INACTIVE_VALIDATORS_URL = `${REST_URL}/api/v1/pos/validator/all?state=belowCapacity&state=belowThreshold&state=inactive&state=jailed&state=unknown`; export const INACTIVE_VALIDATORS_UNBONDING_URL = `${REST_URL}/cosmos/staking/v1beta1/validators?pagination.limit=1000&status=BOND_STATUS_UNBONDING`; export const getValidatorURL = (address) => `${REST_URL}/cosmos/staking/v1beta1/validators/${address}`; -export const PROPOSALS_LIST_URL = `${REST_URL}/cosmos/gov/v1/proposals?pagination.limit=1000`; +export const PROPOSALS_LIST_URL = `${REST_URL}/api/v1/gov/proposal/all`; export const getDelegatedValidatorsURL = (address) => `${REST_URL}/api/v1/pos/bond/${address}`; export const urlFetchProposalVotes = (id) => `${REST_URL}/cosmos/gov/v1beta1/proposals/${id}/votes`; export const urlFetchTallyDetails = (id) => `${REST_URL}/cosmos/gov/v1beta1/proposals/${id}/tally`; -export const urlFetchProposalDetails = (id) => `${REST_URL}/cosmos/gov/v1/proposals/${id}`; +export const urlFetchProposalDetails = (id) => `${REST_URL}/api/v1/gov/proposal/${id}`; export const validatorImageURL = (id) => `https://keybase.io/_/api/1.0/user/lookup.json?fields=pictures&key_suffix=${id}`; diff --git a/src/containers/Home/ClaimDialog/index.js b/src/containers/Home/ClaimDialog/index.js index 3569bff..72c928d 100644 --- a/src/containers/Home/ClaimDialog/index.js +++ b/src/containers/Home/ClaimDialog/index.js @@ -25,44 +25,32 @@ const ClaimDialog = (props) => { const handleClaimAll = () => { setInProgress(true); - let gasValue = gas.claim_reward; - if (props.rewards && props.rewards.rewards && props.rewards.rewards.length > 1) { - gasValue = props.rewards.rewards.length * gas.claim_reward / 1.1 + gas.claim_reward; + let gasValue = 1; + if (props.rewards && props.rewards.length) { + gasValue = props.rewards.length; } - const updatedTx = { - msgs: [], - fee: { - amount: [{ - amount: String(gasValue * config.GAS_PRICE_STEP_AVERAGE), - denom: config.COIN_MINIMAL_DENOM, - }], - gas: String(gasValue), - }, - memo: '', + const txs = { + token: config.TOKEN_ADDRESS, + feeAmount: new BigNumber(0.000010 * gasValue), + gasLimit: new BigNumber(50000 * gasValue), + chainId: config.CHAIN_ID, + publicKey: props.details && props.details.publicKey, }; - - if (props.rewards && props.rewards.rewards && - props.rewards.rewards.length) { - props.rewards.rewards.map((item) => { - updatedTx.msgs.push({ - typeUrl: '/cosmos.distribution.v1beta1.MsgWithdrawDelegatorReward', - value: { - delegatorAddress: props.address, - validatorAddress: item.validator_address, - }, + + const msg = []; + if (props.rewards && props.rewards.length) { + props.rewards.map((item) => { + msg.push({ + source: props.address, + validator: item.validator && item.validator.address, }); return null; }); } - if (localStorage.getItem('of_co_wallet') === 'cosmostation') { - cosmoStationSign(updatedTx, props.address, handleFetch); - return; - } - - signTxAndBroadcast(updatedTx, props.address, handleFetch); + claimTransaction(msg, txs, props.details && props.details.type, handleFetch); }; const handleFetch = (error, result) => { diff --git a/src/containers/Home/index.js b/src/containers/Home/index.js index 0ec0092..f11c594 100644 --- a/src/containers/Home/index.js +++ b/src/containers/Home/index.js @@ -11,8 +11,8 @@ import ClaimDialog from './ClaimDialog'; import ClaimDelegateDialog from './ClaimDialog/ClaimDelegateDialog'; import Table from '../Stake/Table'; import { Button } from '@material-ui/core'; -// import Cards from '../Proposals/Cards'; -// import ProposalDialog from '../Proposals/ProposalDialog'; +import Cards from '../Proposals/Cards'; +import ProposalDialog from '../Proposals/ProposalDialog'; import { connect } from 'react-redux'; import PendingDialog from '../Stake/DelegateDialog/PendingDialog'; // import MultiDelegateButton from '../Stake/MultiDelegateButton'; @@ -75,8 +75,8 @@ class Home extends Component { render () { const { active } = this.state; - // const filteredProposals = this.props.proposals && this.props.proposals.filter((item) => item.status === 2 || - // item.status === 'PROPOSAL_STATUS_VOTING_PERIOD'); + const filteredProposals = this.props.proposals && this.props.proposals.filter((item) => item.status === 2 || + item.status === 'voting'); return ( <> @@ -139,7 +139,7 @@ class Home extends Component { - {/*
+
{!this.props.open ?
@@ -159,7 +159,7 @@ class Home extends Component { :
{variables[this.props.lang]['no_data_found']}
}
: } -
*/} +
diff --git a/src/containers/NavBar/ConnectDialog/NamadaConnectButton.js b/src/containers/NavBar/ConnectDialog/NamadaConnectButton.js index 13a5363..7d58d93 100644 --- a/src/containers/NavBar/ConnectDialog/NamadaConnectButton.js +++ b/src/containers/NavBar/ConnectDialog/NamadaConnectButton.js @@ -37,18 +37,18 @@ const KeplrConnectButton = (props) => { props.setAccountDetails(addressList); props.hideConnectDialog(); // if (!props.proposalTab && !props.stake) { - // props.getUnBondingDelegations(addressList[0] && addressList[0].address); - // props.fetchRewards(addressList[0] && addressList[0].address); + // props.getUnBondingDelegations(addressList && addressList.address); + // props.fetchRewards(addressList && addressList.address); // } if (!props.proposalTab) { - props.getDelegations(addressList[0] && addressList[0].address); + props.getDelegations(addressList && addressList.address); } - props.getBalance(addressList[0] && addressList[0].address); - // props.fetchVestingBalance(addressList[0] && addressList[0].address); + props.getBalance(addressList && addressList.address); + // props.fetchVestingBalance(addressList && addressList.address); // if (!props.proposalTab) { - // props.getDelegatedValidatorsDetails(addressList[0] && addressList[0].address); + // props.getDelegatedValidatorsDetails(addressList && addressList.address); // } - localStorage.setItem('of_co_address', encode(addressList[0] && addressList[0].address)); + localStorage.setItem('of_co_address', encode(addressList && addressList.address)); localStorage.setItem('of_co_wallet', 'namada'); }); }; diff --git a/src/containers/NavBar/index.js b/src/containers/NavBar/index.js index bbfb991..8df6f34 100644 --- a/src/containers/NavBar/index.js +++ b/src/containers/NavBar/index.js @@ -78,53 +78,53 @@ class NavBar extends Component { }, 600); } - // if (this.props.proposals && !this.props.proposals.length && - // !this.props.proposalsInProgress && !this.props.stake && - // this.props.router && this.props.router.params && !this.props.router.params.proposalID) { - // this.props.getProposals((result) => { - // if (result && result.length) { - // const array = []; - // result.map((val) => { - // const filter = this.props.proposalDetails && Object.keys(this.props.proposalDetails).length && - // Object.keys(this.props.proposalDetails).find((key) => key === val.proposal_id); - // if (!filter) { - // if (this.props.home && (val.status !== 'PROPOSAL_STATUS_VOTING_PERIOD')) { - // return null; - // } - // - // array.push(val.proposal_id); - // } - // if (val.status === 2 || val.status === 'PROPOSAL_STATUS_VOTING_PERIOD') { - // this.props.fetchProposalTally(val.id); - // } - // - // return null; - // }); - // this.getProposalDetails(array && array.reverse()); - // } - // }); - // } else if (this.props.proposals && !this.props.proposalsInProgress && !this.props.stake && - // this.props.proposalDetails && Object.keys(this.props.proposalDetails).length === 1 && - // this.props.router && this.props.router.params && !this.props.router.params.proposalID) { - // const array = []; - // this.props.proposals.map((val) => { - // const filter = this.props.proposalDetails && Object.keys(this.props.proposalDetails).length && - // Object.keys(this.props.proposalDetails).find((key) => key === val.proposal_id); - // if (!filter) { - // if (this.props.home && (val.status !== 'PROPOSAL_STATUS_VOTING_PERIOD')) { - // return null; - // } - // - // array.push(val.proposal_id); - // } - // if (val.status === 2 || val.status === 'PROPOSAL_STATUS_VOTING_PERIOD') { - // this.props.fetchProposalTally(val.id); - // } - // - // return null; - // }); - // this.getProposalDetails(array && array.reverse()); - // } + if (this.props.proposals && !this.props.proposals.length && + !this.props.proposalsInProgress && !this.props.stake && + this.props.router && this.props.router.params && !this.props.router.params.proposalID) { + this.props.getProposals((result) => { + if (result && result.length) { + // const array = []; + // result.map((val) => { + // const filter = this.props.proposalDetails && Object.keys(this.props.proposalDetails).length && + // Object.keys(this.props.proposalDetails).find((key) => key === val.proposal_id); + // if (!filter) { + // if (this.props.home && (val.status !== 'PROPOSAL_STATUS_VOTING_PERIOD')) { + // return null; + // } + + // array.push(val.proposal_id); + // } + // if (val.status === 2 || val.status === 'PROPOSAL_STATUS_VOTING_PERIOD') { + // this.props.fetchProposalTally(val.id); + // } + + // return null; + // }); + // this.getProposalDetails(array && array.reverse()); + } + }); + } else if (this.props.proposals && !this.props.proposalsInProgress && !this.props.stake && + this.props.proposalDetails && Object.keys(this.props.proposalDetails).length === 1 && + this.props.router && this.props.router.params && !this.props.router.params.proposalID) { + const array = []; + this.props.proposals.map((val) => { + const filter = this.props.proposalDetails && Object.keys(this.props.proposalDetails).length && + Object.keys(this.props.proposalDetails).find((key) => key === val.proposal_id); + if (!filter) { + if (this.props.home && (val.status !== 'PROPOSAL_STATUS_VOTING_PERIOD')) { + return null; + } + + array.push(val.proposal_id); + } + if (val.status === 2 || val.status === 'PROPOSAL_STATUS_VOTING_PERIOD') { + this.props.fetchProposalTally(val.id); + } + + return null; + }); + this.getProposalDetails(array && array.reverse()); + } if (this.props.address) { this.handleFetch(this.props.address); @@ -182,7 +182,7 @@ class NavBar extends Component { const votedOption = this.props.voteDetails && this.props.voteDetails.length && val && val.proposal_id && this.props.voteDetails.filter((vote) => vote.proposal_id === val.proposal_id)[0]; - if ((val.status === 2 || val.status === 'PROPOSAL_STATUS_VOTING_PERIOD') && + if ((val.status === 2 || val.status === 'voting') && !votedOption && this.props.address) { this.props.fetchVoteDetails(val.id, this.props.address); } @@ -206,14 +206,14 @@ class NavBar extends Component { array.push(val.proposal_id); } - if (val.status === 2 || val.status === 'PROPOSAL_STATUS_VOTING_PERIOD') { + if (val.status === 2 || val.status === 'voting') { this.props.fetchProposalTally(val.id); this.props.fetchVoteDetails(val.id, this.props.address); } return null; }); - this.getProposalDetails(array && array.reverse()); + // this.getProposalDetails(array && array.reverse()); } }); } diff --git a/src/containers/Proposals/Cards.js b/src/containers/Proposals/Cards.js index 7738609..e842732 100644 --- a/src/containers/Proposals/Cards.js +++ b/src/containers/Proposals/Cards.js @@ -10,6 +10,7 @@ import moment from 'moment'; import { tally } from '../../utils/numberFormats'; import DotsLoading from '../../components/DotsLoading'; import withRouter from '../../components/WithRouter'; +import { fixDateString } from 'utils/date'; const Cards = (props) => { const [page, setPage] = useState(1); @@ -18,9 +19,9 @@ const Cards = (props) => { rowsPerPage = 6; } - const handleChangePage = (event, page) => { - setPage(page); - }; + // const handleChangePage = (event, page) => { + // setPage(page); + // }; const count = Math.ceil(props.proposals.length / rowsPerPage); @@ -48,15 +49,11 @@ const Cards = (props) => { return (props.tallyDetails && props.tallyDetails[proposal.id] && props.tallyDetails[proposal.id][val1] ? tally(props.tallyDetails[proposal.id][val1], sum) : '0%'); } else { - const sum = proposal.final_tally_result && proposal.final_tally_result.yes_count && - proposal.final_tally_result.no_count && proposal.final_tally_result.no_with_veto_count && - proposal.final_tally_result.abstain_count && - (parseInt(proposal.final_tally_result.yes_count) + parseInt(proposal.final_tally_result.no_count) + - parseInt(proposal.final_tally_result.no_with_veto_count) + parseInt(proposal.final_tally_result.abstain_count)); + const sum = proposal && proposal.yayVotes && proposal.nayVotes && proposal.abstainVotes && + (parseInt(proposal.yayVotes) + parseInt(proposal.nayVotes) + parseInt(proposal.abstainVotes)); - return (proposal && proposal.final_tally_result && - proposal.final_tally_result[val] - ? tally(proposal.final_tally_result[val], sum) : '0%'); + return (proposal && proposal[val] + ? tally(proposal[val], sum) : '0%'); } }; @@ -73,31 +70,16 @@ const Cards = (props) => { if (index < (page * rowsPerPage) && index >= (page - 1) * rowsPerPage) { let votedOption = props.voteDetails && props.voteDetails.length && proposal && proposal.id && - props.voteDetails.filter((vote) => vote && vote.proposal_id === proposal.id)[0]; - if (votedOption && votedOption.options && votedOption.options.length && votedOption.options[0]) { - votedOption = votedOption.options[0]; + props.voteDetails.filter((vote) => vote && ((String(vote.proposalId) === String(proposal.id)) || (String(vote.proposalId) === '0' && String(proposal.id) === '0'))); + if (votedOption && votedOption.length && votedOption[0]) { + votedOption = votedOption[0]; } - let proposer = proposal.proposer; - props.proposalDetails && Object.keys(props.proposalDetails).length && - Object.keys(props.proposalDetails).filter((key) => { - if (key === proposal.id) { - if (props.proposalDetails[key] && - props.proposalDetails[key][0] && - props.proposalDetails[key][0].tx && - props.proposalDetails[key][0].tx.value && - props.proposalDetails[key][0].tx.value.msg[0] && - props.proposalDetails[key][0].tx.value.msg[0].value && - props.proposalDetails[key][0].tx.value.msg[0].value.proposer) { - proposer = props.proposalDetails[key][0].tx.value.msg[0].value.proposer; - } - } - - return null; - }); let inProgress = props.proposalDetails && Object.keys(props.proposalDetails).length && Object.keys(props.proposalDetails).find((key) => key === proposal.proposal_id); inProgress = !inProgress && props.proposalDetailsInProgress; + const content = proposal && proposal.content + ? JSON.parse(proposal.content) : {}; return (
{

props.handleShow(proposal)}> { - proposal.title + content?.title }

- {proposal.status === 3 || proposal.status === 'PROPOSAL_STATUS_PASSED' + {proposal.status === 3 || proposal.status === 'passed' ? - : (proposal.status === 2 || proposal.status === 'PROPOSAL_STATUS_VOTING_PERIOD') && + : (proposal.status === 2 || proposal.status === 'voting') && votedOption ?

your vote is taken: - {votedOption && (votedOption.option === 1 || votedOption.option === 'VOTE_OPTION_YES') ? 'Yes' - : votedOption && (votedOption.option === 2 || votedOption.option === 'VOTE_OPTION_ABSTAIN') ? 'Abstain' - : votedOption && (votedOption.option === 3 || votedOption.option === 'VOTE_OPTION_NO') ? 'No' - : votedOption && (votedOption.option === 4 || votedOption.option === 'VOTE_OPTION_NO_WITH_VETO') ? 'NoWithVeto' - : votedOption && votedOption.option} + {votedOption && (votedOption.vote === 1 || votedOption.vote === 'yay') ? 'Yes' + : votedOption && (votedOption.vote === 2 || votedOption.vote === 'abstain') ? 'Abstain' + : votedOption && (votedOption.vote === 3 || votedOption.vote === 'nay') ? 'No' + : votedOption && (votedOption.vote === 4 || votedOption.vote === 'VOTE_OPTION_NO_WITH_VETO') ? 'NoWithVeto' + : votedOption && votedOption.vote}

: null}
-

{proposal.summary}

+

{content?.abstract}

Proposer  /  {inProgress ? - : proposer &&
-

{proposer}

- {proposer && - proposer.slice(proposer.length - 6, proposer.length)} + : proposal && proposal.author &&
+

{proposal.author}

+ {proposal.author && + proposal.author.slice(proposal.author.length - 6, proposal.author.length)}
}
-

Submitted on  /  {proposal.submit_time - ? moment(proposal.submit_time).format('DD-MMM-YYYY HH:mm:ss') : ''}

+

Submitted on  /  {content && content.created + ? moment(fixDateString(content.created)).format('DD-MMM-YYYY HH:mm:ss') : ''}

Voting Period

- {`${proposal && proposal.voting_start_time - ? moment(proposal.voting_start_time).format('DD-MMM-YYYY HH:mm:ss') : ''} -> - ${proposal && proposal.voting_end_time - ? moment(proposal.voting_end_time).format('DD-MMM-YYYY HH:mm:ss') : ''}`} + {`${proposal && proposal.startTime + ? moment.unix(proposal.startTime).format('DD-MMM-YYYY HH:mm:ss') : ''} -> + ${proposal && proposal.endTime + ? moment.unix(proposal.endTime).format('DD-MMM-YYYY HH:mm:ss') : ''}`}

Proposal Status: { proposal.status === 0 || - proposal.status === 'PROPOSAL_STATUS_UNSPECIFIED' ? 'Nil' + proposal.status === 'pending' ? 'Nil' : proposal.status === 1 || proposal.status === 'PROPOSAL_STATUS_DEPOSIT_PERIOD' ? 'DepositPeriod' : proposal.status === 2 || - proposal.status === 'PROPOSAL_STATUS_VOTING_PERIOD' ? 'VotingPeriod' + proposal.status === 'voting' ? 'VotingPeriod' : proposal.status === 3 || - proposal.status === 'PROPOSAL_STATUS_PASSED' ? 'Passed' + proposal.status === 'passed' ? 'Passed' : proposal.status === 4 || - proposal.status === 'PROPOSAL_STATUS_REJECTED' ? 'Rejected' + proposal.status === 'rejected' ? 'Rejected' : proposal.status === 5 || proposal.status === 'PROPOSAL_STATUS_FAILED' ? 'Failed' : '' }

@@ -191,19 +173,19 @@ const Cards = (props) => {
-

YES ({VoteCalculation(proposal, 'yes_count')})

+

YES ({VoteCalculation(proposal, 'yayVotes')})

-

NO ({VoteCalculation(proposal, 'no_count')})

+

NO ({VoteCalculation(proposal, 'nayVotes')})

-
+ {/*

NoWithVeto ({VoteCalculation(proposal, 'no_with_veto_count')})

-
+
*/}
-

Abstain ({VoteCalculation(proposal, 'abstain_count')})

+

Abstain ({VoteCalculation(proposal, 'abstainVotes')})

@@ -213,12 +195,12 @@ const Cards = (props) => { return null; })}
- {!props.home &&
+ {/* {!props.home &&
-
} +
} */}
); }; diff --git a/src/containers/Proposals/ProposalDialog/Voting.js b/src/containers/Proposals/ProposalDialog/Voting.js index 0b44444..79c4daa 100644 --- a/src/containers/Proposals/ProposalDialog/Voting.js +++ b/src/containers/Proposals/ProposalDialog/Voting.js @@ -4,7 +4,6 @@ import { fetchProposalTally, fetchVoteDetails, hideProposalDialog } from '../../ import { connect } from 'react-redux'; import { Button, FormControlLabel, Radio, RadioGroup } from '@material-ui/core'; import CircularProgress from '../../../components/CircularProgress'; -import { cosmoStationSign, signTxAndBroadcast } from '../../../helper'; import { config } from '../../../config'; import variables from '../../../utils/variables'; import { showMessage } from '../../../actions/snackbar'; @@ -14,8 +13,9 @@ import { showDelegateSuccessDialog, } from '../../../actions/stake'; import { fetchVestingBalance, getBalance } from '../../../actions/accounts'; -import { gas } from '../../../defaultGasValues'; import Long from 'long'; +import { voteTransaction } from 'helper'; +import BigNumber from 'bignumber.js'; const Voting = (props) => { const [value, setValue] = React.useState(''); @@ -39,36 +39,30 @@ const Voting = (props) => { setInProgress(true); - const option = value === 'Yes' ? 1 - : value === 'Abstain' ? 2 - : value === 'No' ? 3 - : value === 'NoWithVeto' ? 4 : null; + const option = value === 'Yes' ? 'yay' + : value === 'Abstain' ? 'abstain' + : value === 'No' ? 'nay' + : null; const tx = { - msgs: [{ - typeUrl: '/cosmos.gov.v1beta1.MsgVote', - value: { - option: option, - proposalId: Long.fromString(props.proposalId), - voter: props.address, - }, - }], - fee: { - amount: [{ - amount: String(gas.vote * config.GAS_PRICE_STEP_AVERAGE), - denom: config.COIN_MINIMAL_DENOM, - }], - gas: String(gas.vote), - }, - memo: '', + voter: props.address, + proposalId: Long.fromString(props.proposalId), + option: option, }; - if (localStorage.getItem('of_co_wallet') === 'cosmostation') { - cosmoStationSign(tx, props.address, handleFetch); - return; + if (props.name === 'Delegate' || props.name === 'Stake') { + tx.nativeToken = 'NAAN'; } - signTxAndBroadcast(tx, props.address, handleFetch); + const txs = { + token: config.TOKEN_ADDRESS, + feeAmount: new BigNumber(0.000001), + gasLimit: new BigNumber(50000), + chainId: config.CHAIN_ID, + publicKey: props.details && props.details.publicKey, + }; + + voteTransaction(tx, txs, props.details && props.details.type, handleFetch); }; const handleFetch = (error, result) => { @@ -83,7 +77,7 @@ const Voting = (props) => { return; } if (result) { - props.successDialog(result.transactionHash); + props.successDialog(value && value.hash); props.fetchVoteDetails(props.proposalId, props.address); props.fetchProposalTally(props.proposalId); props.getBalance(props.address); @@ -107,7 +101,7 @@ const Voting = (props) => { } label="Yes" value="Yes"/> } label="No" value="No"/> - } label="NoWithVeto" value="NoWithVeto"/> + {/* } label="NoWithVeto" value="NoWithVeto"/> */} } label="Abstain" value="Abstain"/>
@@ -132,6 +126,7 @@ const Voting = (props) => { }; Voting.propTypes = { + details: PropTypes.object.isRequired, failedDialog: PropTypes.func.isRequired, fetchProposalTally: PropTypes.func.isRequired, fetchVestingBalance: PropTypes.func.isRequired, @@ -150,6 +145,7 @@ const stateToProps = (state) => { return { address: state.accounts.address.value, lang: state.language, + details: state.accounts.address.details, }; }; diff --git a/src/containers/Proposals/ProposalDialog/index.js b/src/containers/Proposals/ProposalDialog/index.js index 6b769a6..a41328e 100644 --- a/src/containers/Proposals/ProposalDialog/index.js +++ b/src/containers/Proposals/ProposalDialog/index.js @@ -22,6 +22,7 @@ import UnSuccessDialog from '../../Stake/DelegateDialog/UnSuccessDialog'; import PendingDialog from '../../Stake/DelegateDialog/PendingDialog'; import SuccessDialog from '../../Stake/DelegateDialog/SuccessDialog'; import withRouter from '../../../components/WithRouter'; +import { fixDateString } from 'utils/date'; class ProposalDialog extends Component { constructor (props) { @@ -92,15 +93,11 @@ class ProposalDialog extends Component { return (this.props.tallyDetails && this.props.tallyDetails[proposal.id] && this.props.tallyDetails[proposal.id][val1] ? tally(this.props.tallyDetails[proposal.id][val1], sum) : '0%'); } else { - const sum = proposal && proposal.final_tally_result && proposal.final_tally_result.yes_count && - proposal.final_tally_result.no_count && proposal.final_tally_result.no_with_veto_count && - proposal.final_tally_result.abstain_count && - (parseInt(proposal.final_tally_result.yes_count) + parseInt(proposal.final_tally_result.no_count) + - parseInt(proposal.final_tally_result.no_with_veto_count) + parseInt(proposal.final_tally_result.abstain_count)); + const sum = proposal && proposal.yayVotes && proposal.nayVotes && proposal.abstainVotes && + (parseInt(proposal.yayVotes) + parseInt(proposal.nayVotes) + parseInt(proposal.abstainVotes)); - return (proposal && proposal.final_tally_result && - proposal.final_tally_result[val] - ? tally(proposal.final_tally_result[val], sum) : '0%'); + return (proposal && proposal[val] + ? tally(proposal[val], sum) : '0%'); } } @@ -112,31 +109,12 @@ class ProposalDialog extends Component { render () { let votedOption = this.props.voteDetails && this.props.voteDetails.length && this.props.proposal && this.props.proposal.id && - this.props.voteDetails.filter((vote) => vote && vote.proposal_id === this.props.proposal.id)[0]; - if (votedOption && votedOption.options && votedOption.options.length && votedOption.options[0]) { - votedOption = votedOption.options[0]; + this.props.voteDetails.filter((vote) => vote && ((String(vote.proposalId) === String(this.props.proposal.id)) || (String(vote.proposalId) === '0' && String(this.props.proposal.id) === '0'))); + if (votedOption && votedOption.length && votedOption[0]) { + votedOption = votedOption[0]; } - let proposer = this.props.proposal && this.props.proposal.proposer; - - this.props.proposalDetails && Object.keys(this.props.proposalDetails).length && - Object.keys(this.props.proposalDetails).filter((key) => { - if (this.props.proposal && key === this.props.proposal.id) { - if (this.props.proposalDetails[key] && - this.props.proposalDetails[key][0] && - this.props.proposalDetails[key][0].body && - this.props.proposalDetails[key][0].body.messages && - this.props.proposalDetails[key][0].body.messages.length && - this.props.proposalDetails[key][0].body.messages[0] && - this.props.proposalDetails[key][0].body.messages[0].proposer) { - proposer = this.props.proposalDetails[key][0].body.messages[0].proposer; - } - } - - return null; - }); - - const content = this.props.proposal && this.props.proposal.messages && this.props.proposal.messages[0] && this.props.proposal.messages[0].content; - + const content = this.props.proposal && this.props.proposal.content + ? JSON.parse(this.props.proposal.content) : {}; return (
@@ -152,26 +130,26 @@ class ProposalDialog extends Component {
{this.props.proposal && this.props.proposal.title}
+ className="proposal_dialog_section1_header">{content?.title}
Proposal Status:  {this.props.proposal && this.props.proposal.status ? this.props.proposal.status === 0 || - this.props.proposal.status === 'PROPOSAL_STATUS_UNSPECIFIED' ? 'Nil' + this.props.proposal.status === 'pending' ? 'Nil' : this.props.proposal.status === 1 || this.props.proposal.status === 'PROPOSAL_STATUS_DEPOSIT_PERIOD' ? 'DepositPeriod' : this.props.proposal.status === 2 || - this.props.proposal.status === 'PROPOSAL_STATUS_VOTING_PERIOD' ? 'VotingPeriod' + this.props.proposal.status === 'voting' ? 'VotingPeriod' : this.props.proposal.status === 3 || - this.props.proposal.status === 'PROPOSAL_STATUS_PASSED' ? 'Passed' + this.props.proposal.status === 'passed' ? 'Passed' : this.props.proposal.status === 4 || - this.props.proposal.status === 'PROPOSAL_STATUS_REJECTED' ? 'Rejected' + this.props.proposal.status === 'rejected' ? 'Rejected' : this.props.proposal.status === 5 || this.props.proposal.status === 'PROPOSAL_STATUS_FAILED' ? 'Failed' : '' : ''}
@@ -179,7 +157,9 @@ class ProposalDialog extends Component {
-                                        {this.props.proposal && this.props.proposal.summary}
+                                        {content?.abstract}
+                                        
+ {content?.details}

Proposer

- {proposer &&
-

{proposer}

- {proposer && - proposer.slice(proposer.length - 6, proposer.length)} + {this.props.proposal?.author &&
+

{this.props.proposal.author}

+ {this.props.proposal.author && + this.props.proposal.author.slice(this.props.proposal.author.length - 6, this.props.proposal.author.length)}
}

Submitted on

-

{this.props.proposal && this.props.proposal.submit_time - ? moment(this.props.proposal.submit_time).format('DD-MMM-YYYY HH:mm:ss') : ''}

+

{content && content.created + ? moment(fixDateString(content.created)).format('DD-MMM-YYYY HH:mm:ss') : ''}

Voting Period

-

{this.props.proposal && this.props.proposal.voting_start_time - ? moment(this.props.proposal.voting_start_time).format('DD-MMM-YYYY HH:mm:ss') : ''}

-

{this.props.proposal && this.props.proposal.voting_end_time - ? moment(this.props.proposal.voting_end_time).format('DD-MMM-YYYY HH:mm:ss') : ''}

+

{this.props.proposal && this.props.proposal.startTime + ? moment.unix(this.props.proposal.startTime).format('DD-MMM-YYYY HH:mm:ss') : ''}

+

{this.props.proposal && this.props.proposal.endTime + ? moment.unix(this.props.proposal.endTime).format('DD-MMM-YYYY HH:mm:ss') : ''}

@@ -220,44 +200,43 @@ class ProposalDialog extends Component { this.props.proposal.status === 'PROPOSAL_STATUS_VOTING_PERIOD') ? 'vote_in_progress' : '')}>
-

YES ({this.VoteCalculation('yes_count')})

+

YES ({this.VoteCalculation('yayVotes')})

-

NO ({this.VoteCalculation('no_count')})

+

NO ({this.VoteCalculation('nayVotes')})

-
+ {/*

NoWithVeto ({this.VoteCalculation('no_with_veto_count')})

-
+
*/}
-

Abstain ({this.VoteCalculation('abstain_count')})

+

Abstain ({this.VoteCalculation('abstainVotes')})

Type

-

{this.props.proposal && content && content.type - ? content.type - : this.props.proposal && content && content['@type'] - ? content['@type'] : null}

+

{this.props.proposal && this.props.proposal.type + ? this.props.proposal.type + : null}

{this.props.proposal && (this.props.proposal.status === 2 || - this.props.proposal.status === 'PROPOSAL_STATUS_VOTING_PERIOD') && !this.props.voteDetailsInProgress + this.props.proposal.status === 'voting') && !this.props.voteDetailsInProgress ? : null}
- {votedOption + {votedOption && votedOption.voterAddress ?

{`you voted “${ - votedOption && (votedOption.option === 1 || votedOption.option === 'VOTE_OPTION_YES') ? 'Yes' - : votedOption && (votedOption.option === 2 || votedOption.option === 'VOTE_OPTION_ABSTAIN') ? 'Abstain' - : votedOption && (votedOption.option === 3 || votedOption.option === 'VOTE_OPTION_NO') ? 'No' - : votedOption && (votedOption.option === 4 || votedOption.option === 'VOTE_OPTION_NO_WITH_VETO') ? 'NoWithVeto' - : votedOption && votedOption.option + votedOption && (votedOption.vote === 1 || votedOption.vote === 'yay') ? 'Yes' + : votedOption && (votedOption.vote === 2 || votedOption.vote === 'abstain') ? 'Abstain' + : votedOption && (votedOption.vote === 3 || votedOption.vote === 'nay') ? 'No' + : votedOption && (votedOption.vote === 4 || votedOption.vote === 'VOTE_OPTION_NO_WITH_VETO') ? 'NoWithVeto' + : votedOption && votedOption.vote }” for this proposal`}

: null} diff --git a/src/containers/Proposals/index.css b/src/containers/Proposals/index.css index fe26437..e8bd0ff 100644 --- a/src/containers/Proposals/index.css +++ b/src/containers/Proposals/index.css @@ -65,9 +65,9 @@ } .proposals .card { - background: #FFFFFF; + background: #000; border-radius: 20px; - color: #000000; + color: #fff; padding: 18px 28px; width: 31%; text-align: left; @@ -97,6 +97,8 @@ font-weight: 600; font-size: 24px; line-height: 130%; + color: #000; + background: #FFFF46; } .proposals .card_heading { @@ -111,7 +113,7 @@ font-weight: 600; font-size: 28px; line-height: 130%; - color: #000000; + color: #fff; margin: unset; white-space: nowrap; overflow: hidden; @@ -173,7 +175,7 @@ font-weight: 600; font-size: 18px; line-height: 130%; - color: #696969; + color: #ffffff9e; margin-bottom: 26px; display: -webkit-box; -webkit-line-clamp: 5; @@ -195,7 +197,7 @@ font-weight: 600; font-size: 14px; line-height: 130%; - color: #696969; + color: #ffffff9e; display: flex; } @@ -204,7 +206,7 @@ font-weight: 600; font-size: 14px; line-height: 130%; - color: #696969; + color: #ffffff9e; max-width: 110px; } @@ -299,7 +301,7 @@ font-weight: 600; font-size: 14px; line-height: 130%; - color: #000000; + color: #fff; display: flex; } diff --git a/src/containers/Proposals/index.js b/src/containers/Proposals/index.js index 9c8fa37..eeb1fed 100644 --- a/src/containers/Proposals/index.js +++ b/src/containers/Proposals/index.js @@ -1,10 +1,10 @@ import React, { useState } from 'react'; import NavBar from '../NavBar'; -// import variables from '../../utils/variables'; +import variables from '../../utils/variables'; import * as PropTypes from 'prop-types'; import { connect } from 'react-redux'; import './index.css'; -// import Cards from './Cards'; +import Cards from './Cards'; import { fetchProposalTally, fetchVoteDetails, getProposals } from '../../actions/proposals'; import UnSuccessDialog from '../Stake/DelegateDialog/UnSuccessDialog'; import PendingDialog from '../Stake/DelegateDialog/PendingDialog'; @@ -12,29 +12,26 @@ import SuccessDialog from '../Stake/DelegateDialog/SuccessDialog'; import withRouter from '../../components/WithRouter'; const Proposals = (props) => { - // const [active, setActive] = useState(1); - // const [filter, setFilter] = useState(null); + const [active, setActive] = useState(1); + const [filter, setFilter] = useState(null); - // const handleChange = (value) => { - // if (active === value) { - // return; - // } + const handleChange = (value) => { + if (active === value) { + return; + } - // setActive(value); - // setFilter(value === null ? 2 - // : value === 2 ? 'PROPOSAL_STATUS_PASSED' - // : value === 3 ? 'PROPOSAL_STATUS_VOTING_PERIOD' - // : value === 4 ? 'PROPOSAL_STATUS_REJECTED' : null); - // }; - // const filteredProposals = filter ? props.proposals.filter((item) => item.status === filter) : props.proposals; + setActive(value); + setFilter(value === null ? 2 + : value === 2 ? 'passed' + : value === 3 ? 'voting' + : value === 4 ? 'rejected' : null); + }; + const filteredProposals = filter ? props.proposals.filter((item) => item.status === filter) : props.proposals; return (
- Coming Soon... -
- {/*

handleChange(1)}> @@ -53,14 +50,14 @@ const Proposals = (props) => { {variables[props.lang].closed}

-

Voting Period: 8 Days

+ {/*

Voting Period: 8 Days

*/}
{props.proposalsInProgress || props.voteDetailsInProgress ?
Loading...
: filteredProposals && filteredProposals.length ? :
No data found
} -
*/} +
diff --git a/src/containers/Stake/DelegateDialog/SuccessDialog.js b/src/containers/Stake/DelegateDialog/SuccessDialog.js index aab3bda..663d07a 100644 --- a/src/containers/Stake/DelegateDialog/SuccessDialog.js +++ b/src/containers/Stake/DelegateDialog/SuccessDialog.js @@ -75,7 +75,7 @@ const SuccessDialog = (props) => { ?

{variables[props.lang].claimed_success}

:

{variables[props.lang].success}

}
- {props.router && props.router.params && props.router.params.proposalID && props.hash + {props.router && props.router.params && (props.router.params.proposalID || (props.router.params.proposalID === 0)) && props.hash ?

{variables[props.lang]['transaction_hash']}

( - value ? value + '%' : '0%' - ), - }, - }, + // { + // name: 'commission', + // label: 'Commission', + // options: { + // sort: true, + // customBodyRender: (value) => ( + // value ? value + '%' : '0%' + // ), + // }, + // }, { name: 'tokens_staked', label: 'Tokens Staked', @@ -230,8 +230,8 @@ class Table extends Component { // item, // parseFloat((Number(item.tokens) / (10 ** config.COIN_DECIMALS)).toFixed(1)), parseFloat((Number(item.votingPower)).toFixed(1)), - item.commission - ? parseFloat((Number(item.commission) * 100).toFixed(2)) : null, + // item.commission + // ? parseFloat((Number(item.commission) * 100).toFixed(2)) : null, item, item, ]) diff --git a/src/helper.js b/src/helper.js index cfc6bac..a165515 100644 --- a/src/helper.js +++ b/src/helper.js @@ -9,6 +9,7 @@ import { UnbondMsgValue, RedelegateMsgValue, ClaimRewardsMsgValue, + VoteProposalMsgValue, } from '@namada/types'; import { getSdk } from '@heliaxdev/namada-sdk/web'; @@ -448,7 +449,12 @@ export const unDelegateTransaction = (Tx, txs, type, cb) => { const encoded = await tx.buildUnbond(wrapperTxValue, bondMsgValue); newTxs.push(encoded); - const updateDate = tx.buildBatch(newTxs); + let updateDate; + if (type === 'ledger') { + updateDate = newTxs; + } else { + updateDate = tx.buildBatch(newTxs); + } client.sign(updateDate, Tx.source, checksums).then((signedBondTxBytes) => { rpc.broadcastTx(signedBondTxBytes && signedBondTxBytes.length && signedBondTxBytes[0], wrapperProps).then((result) => { @@ -534,7 +540,12 @@ export const reDelegateTransaction = (Tx, txs, type, cb) => { const encoded = await tx.buildRedelegate(wrapperTxValue, bondMsgValue); newTxs.push(encoded); - const updateDate = tx.buildBatch(newTxs); + let updateDate; + if (type === 'ledger') { + updateDate = newTxs; + } else { + updateDate = tx.buildBatch(newTxs); + } client.sign(updateDate, Tx.source, checksums).then((signedBondTxBytes) => { rpc.broadcastTx(signedBondTxBytes && signedBondTxBytes.length && signedBondTxBytes[0], wrapperProps).then((result) => { @@ -629,7 +640,12 @@ export const claimTransaction = (Tx, txs, type, cb) => { newTxs.push(encoded); } - const updateDate = tx.buildBatch(newTxs); + let updateDate; + if (type === 'ledger') { + updateDate = newTxs; + } else { + updateDate = tx.buildBatch(newTxs); + } client.sign(updateDate, Tx.source, checksums).then((signedBondTxBytes) => { rpc.broadcastTx(signedBondTxBytes && signedBondTxBytes.length && signedBondTxBytes[0], wrapperProps).then((result) => { @@ -661,3 +677,93 @@ export const claimTransaction = (Tx, txs, type, cb) => { } })(); }; + +export const voteTransaction = (Tx, txs, type, cb) => { + (async () => { + const isExtensionInstalled = typeof window.namada === 'object'; + if (!isExtensionInstalled || !window.namada) { + const error = 'Download the Namada Extension'; + cb(error); + } + + if (window.namada) { + const namada = window.namada; + const client = namada.getSigner(); + + const { cryptoMemory } = await init(); + const sdk = getSdk( + cryptoMemory, + config.RPC_URL, + config.MAPS_REST_URL, + '', + config.TOKEN_ADDRESS, + ); + + const { rpc, tx } = sdk; + + const checksums = await rpc.queryChecksums(); + if (checksums && Object.keys(checksums).length) { + Object.keys(checksums).map((key) => { + if (key && checksums[key]) { + checksums[key] = checksums[key].toLowerCase(); + } + }); + } + + const bondMsgValue = new VoteProposalMsgValue({ + signer: Tx.voter, + proposalId: Tx.proposalId, + vote: Tx.option, + }); + + const wrapperProps = { + token: txs.token, + feeAmount: txs.feeAmount, + gasLimit: txs.gasLimit, + chainId: txs.chainId, + publicKey: txs.publicKey, + memo: '', + }; + + const newTxs = []; + const wrapperTxValue = new WrapperTxMsgValue(wrapperProps); + const encoded = await tx.buildVoteProposal(wrapperTxValue, bondMsgValue); + newTxs.push(encoded); + + let updateDate; + if (type === 'ledger') { + updateDate = newTxs; + } else { + updateDate = tx.buildBatch(newTxs); + } + + client.sign(updateDate, Tx.voter, checksums).then((signedBondTxBytes) => { + rpc.broadcastTx(signedBondTxBytes && signedBondTxBytes.length && signedBondTxBytes[0], wrapperProps).then((result) => { + if (result && result.code !== undefined && result.code !== 0 && result.code !== '0') { + cb(result.info || result.log || result.rawLog); + } else { + cb(null, result); + } + }).catch((error) => { + console.error(`broadcast error: ${error}`); + const message = 'success'; + if (error && error.message === 'Invalid string. Length must be a multiple of 4') { + cb(null, message); + } else { + cb(error && error.message); + } + }); + }).catch((error) => { + console.error(`Transaction was rejected: ${error}`); + const message = 'success'; + if (error && error.message === 'Invalid string. Length must be a multiple of 4') { + cb(null, message); + } else { + cb(error && error.message); + } + }); + } else { + return null; + } + })(); +}; diff --git a/src/reducers/proposals.js b/src/reducers/proposals.js index df8d54a..076ed2b 100644 --- a/src/reducers/proposals.js +++ b/src/reducers/proposals.js @@ -104,17 +104,17 @@ const voteDetails = (state = { value: [], }; case VOTE_DETAILS_FETCH_SUCCESS: { - const arr = [...state.value]; - const filter = state.value && state.value.length && - action.value && action.value.proposal_id && - state.value.filter((val) => val.proposal_id === action.value.proposal_id); - if (!filter.length) { - arr.push(action.value); - } + // const arr = [...state.value]; + // const filter = state.value && state.value.length && + // action.value && action.value.proposal_id && + // state.value.filter((val) => val.proposal_id === action.value.proposal_id); + // if (!filter.length) { + // arr.push(action.value); + // } return { inProgress: false, - value: [...arr], + value: [...action.value], }; } case VOTE_DETAILS_FETCH_ERROR: diff --git a/src/utils/date.js b/src/utils/date.js new file mode 100644 index 0000000..01e619f --- /dev/null +++ b/src/utils/date.js @@ -0,0 +1,3 @@ +export const fixDateString = (input) => { + return input.replace(/T(\d{2}:\d{2}:\d)Z/, 'T$10Z'); // Ensure two digits for seconds +};