1import React, { useCallback, useMemo, useEffect, useState } from 'react';
2import { Grid, Text, P, LinkButton } from 'indigo-react';
3import * as azimuth from 'azimuth-js';
5import { useNetwork } from 'store/network';
6import { usePointCursor } from 'store/pointCursor';
8import * as need from 'lib/need';
9import useEthereumTransaction from 'lib/useEthereumTransaction';
10import { GAS_LIMITS } from 'lib/constants';
11import { useLocalRouter } from 'lib/LocalRouter';
13import ViewHeader from 'components/ViewHeader';
14import InlineEthereumTransaction from 'components/InlineEthereumTransaction';
15import View from 'components/View';
16import BridgeForm from 'form/BridgeForm';
17import convertToInt from 'lib/convertToInt';
19function useCastUpgradeVote() {
20 const { contracts } = useNetwork();
21 const { pointCursor } = usePointCursor();
23 const _contracts = need.contracts(contracts);
24 const _point = need.point(pointCursor);
26 return useEthereumTransaction(
28 (address, accept) => {
29 return azimuth.ecliptic.castUpgradeVote(
38 useCallback(() => null, []), //TODO update polls[address].hasVoted ?
39 GAS_LIMITS.DEFAULT //TODO update once we have a decent sample size
43export default function Upgrades() {
44 const { pop } = useLocalRouter();
45 const { contracts } = useNetwork();
46 const { pointCursor } = usePointCursor();
48 const _contracts = need.contracts(contracts);
49 const _point = convertToInt(need.point(pointCursor), 10);
51 const { construct, reset, unconstruct, bind } = useCastUpgradeVote();
53 const [proposals, setProposals] = useState([]);
54 const [polls, setPolls] = useState({});
55 const [loading, setLoading] = useState(true);
56 const [votingOn, setVotingOn] = useState({});
58 //TODO update every second?
59 const now = Math.round(new Date().getTime() / 1000);
63 let proposals = await azimuth.polls.getUpgradeProposals(_contracts);
65 for (let address of proposals) {
66 let poll = await azimuth.polls.getUpgradePoll(_contracts, address);
67 poll.endTime = convertToInt(poll.start) + convertToInt(poll.duration);
68 poll.hasVoted = await azimuth.polls.hasVotedOnUpgradePoll(
73 polls[address] = poll;
75 setProposals(proposals);
79 }, [_contracts, _point]);
81 // eslint-disable-next-line
82 const [open, closed] = useMemo(() => {
85 if (loading) return [open, closed];
86 for (let address of proposals) {
87 if (now > polls[address].endTime) {
93 return [open, closed];
94 }, [loading, proposals, polls, now]);
96 const doVote = useCallback(
97 (address, accept) => {
98 construct(address, accept);
99 setVotingOn({ address, accept });
104 const didVote = useCallback(() => {
108 polls[votingOn.address].hasVoted = true;
112 }, [votingOn, reset, unconstruct]);
114 const openList = useMemo(() => {
115 return open.map(address => {
116 const hasVoted = polls[address].hasVoted;
119 <Grid.Item full className="mv2" as={Text}>
122 rel="noopener noreferrer"
123 href={`https://etherscan.io/address/${address}#code`}
124 class="mb4 mono wrap pre">
129 'Your vote has been cast.'
132 <LinkButton onClick={() => doVote(address, true)}>
133 {votingOn.address === address && votingOn.accept ? (
140 <LinkButton onClick={() => doVote(address, false)}>
141 {votingOn.address === address && !votingOn.accept ? (
155 }, [open, polls, votingOn, doVote]);
158 <View pop={pop} inset>
160 <Grid.Item full as={ViewHeader}>
161 Senate: Upgrade Proposals
164 <Grid.Item full as={Grid}>
165 <Grid.Item full as={P}>
168 <Grid.Item full className="mv2 mb4 mono wrap pre" as={P}>
169 {_contracts.ecliptic.address}
173 {openList.length > 0 && (
175 <Grid.Divider className="mv4" />
177 <Grid.Item full as={Grid}>
178 <Grid.Item full as={P}>
185 {({ onSubmit, values }) => (
188 as={InlineEthereumTransaction}
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list