From a73f817d1d850297d0a500d56c988064ae2f6e95 Mon Sep 17 00:00:00 2001 From: jin <57248516+chickick@users.noreply.github.com> Date: Wed, 23 Jul 2025 14:57:02 +0800 Subject: [PATCH 01/23] feat: add vote status bar & modify response structure --- src/assets/icons/no.svg | 3 + src/assets/icons/yes.svg | 3 + src/config/testnet.ts | 2 +- src/containers/vote/index.ts | 6 +- src/pages/details/index.tsx | 16 +- src/pages/home/components/Countdown.tsx | 6 +- src/pages/home/index.tsx | 193 ++++++++++++++++-------- 7 files changed, 159 insertions(+), 70 deletions(-) create mode 100644 src/assets/icons/no.svg create mode 100644 src/assets/icons/yes.svg diff --git a/src/assets/icons/no.svg b/src/assets/icons/no.svg new file mode 100644 index 0000000..7e55d34 --- /dev/null +++ b/src/assets/icons/no.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/icons/yes.svg b/src/assets/icons/yes.svg new file mode 100644 index 0000000..0f40b62 --- /dev/null +++ b/src/assets/icons/yes.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/config/testnet.ts b/src/config/testnet.ts index c473219..84574b1 100644 --- a/src/config/testnet.ts +++ b/src/config/testnet.ts @@ -1,5 +1,5 @@ const config: App.AppConfig = { - proposalContractId: 'reduce-inflation.testnet', + proposalContractId: 'mock-proposal-alpha.testnet', validatorApi: 'https://validator-voting-api.linearprotocol.org', near: { network: { diff --git a/src/containers/vote/index.ts b/src/containers/vote/index.ts index 478c62c..f5f0b01 100644 --- a/src/containers/vote/index.ts +++ b/src/containers/vote/index.ts @@ -12,7 +12,7 @@ interface VoteState { isLoading: boolean; deadline: number | null; voteFinishedAt: number | null; - votes: Record; + votes: Record; votesCount: number | null; votedStakeAmount: Big.Big; totalVotedStakeAmount: Big.Big; @@ -23,7 +23,7 @@ interface VoteComputed { progressList: number[]; } -const PROGRESS = [66.67]; +const PROGRESS = [33.3]; type UseVoteContainer = VoteState & VoteComputed; const contractId = config.proposalContractId; @@ -33,7 +33,7 @@ function useVoteContainer(): UseVoteContainer { const [deadline, setDeadline] = useState(null); const [voteFinishedAt, setVoteFinishedAt] = useState(null); - const [votes, setVotes] = useState>({}); + const [votes, setVotes] = useState>({}); const [votedStakeAmount, setVotedStakeAmount] = useState(Big(0)); const [totalVotedStakeAmount, setTotalVotedStakeAmount] = useState(Big(0)); diff --git a/src/pages/details/index.tsx b/src/pages/details/index.tsx index 76339da..9bc5d35 100644 --- a/src/pages/details/index.tsx +++ b/src/pages/details/index.tsx @@ -46,8 +46,18 @@ export default function Details() { // }); return list.sort((a, b) => { - const aVote = a.vote === 'yes' ? votes[a.accountId] || '0' : a.totalStakedBalance; - const bVote = b.vote === 'yes' ? votes[b.accountId] || '0' : b.totalStakedBalance; + const aVote = + a.vote === 'yes' + ? votes[a.accountId] + ? votes[a.accountId][1] + : '0' + : a.totalStakedBalance; + const bVote = + b.vote === 'yes' + ? votes[b.accountId] + ? votes[b.accountId][1] + : '0' + : b.totalStakedBalance; const aDate = a.lastVoteTimestamp || 0; const bDate = b.lastVoteTimestamp || 0; @@ -82,7 +92,7 @@ export default function Details() { const data: Record = {}; tableList.forEach((item) => { const isYesVote = item.vote === 'yes'; - let power = votes[item.accountId] || '0'; + let power = votes[item.accountId] ? votes[item.accountId][1] : '0'; if (!isYesVote) { power = item.totalStakedBalance || '0'; } diff --git a/src/pages/home/components/Countdown.tsx b/src/pages/home/components/Countdown.tsx index a4e2e54..86c9d5d 100644 --- a/src/pages/home/components/Countdown.tsx +++ b/src/pages/home/components/Countdown.tsx @@ -8,7 +8,7 @@ export interface CountdownProps { deadline: number | null; } -export default function Countdown({ votedPercent, deadline }: CountdownProps) { +export default function Countdown({ deadline }: CountdownProps) { const [isPageVisible, setPageVisibility] = useState(!document.hidden); const [countdownSeconds, setCountdownSeconds] = useState(null); @@ -64,9 +64,9 @@ export default function Countdown({ votedPercent, deadline }: CountdownProps) { return (
-

+ {/*

{votedPercent}% of Stake Voted for YEA -

+ */}
diff --git a/src/pages/home/index.tsx b/src/pages/home/index.tsx index b4be144..285e1bd 100644 --- a/src/pages/home/index.tsx +++ b/src/pages/home/index.tsx @@ -17,10 +17,13 @@ import config from '@/config'; import VoteContainer from '@/containers/vote'; import { cn, formatBigNumber, isNotNullAndNumber } from '@/lib/utils'; import { article } from './article'; +import YesIcon from '@/assets/icons/yes.svg?react'; +import NoIcon from '@/assets/icons/no.svg?react'; import Countdown from './components/Countdown'; import dayjs from 'dayjs'; import utc from 'dayjs/plugin/utc'; +import Big from 'big.js'; dayjs.extend(utc); @@ -57,6 +60,7 @@ export default function Home() { const { isLoading, deadline, + votes, votesCount, votedPercent, progressList, @@ -82,42 +86,145 @@ export default function Home() { return (
-

+ {/*

{votedPercent}% of Stake Voted for YEA -

+ */}
); }; const renderProgress = () => { - const _percent = Number(votedPercent); + const votedPercentNum = Number(votedPercent); + const targetPercent = 33.3; + const passed = votedPercentNum >= targetPercent; + + const currentProgressPercent = passed + ? 100 + : Math.round((votedPercentNum / targetPercent) * 100); + const totalProgressPercentText = passed ? votedPercentNum : targetPercent; + + const targetBadge = ( +
+ Target + + + +
+ ); + return ( -
-
- {progressList.map((p) => ( +
+

+ Voter Turnout +

+
+
- ))} -
- {!!votedPercent && ( + className="h-full bg-[hsla(158,100%,43%,1)] rounded-full flex items-center" + style={{ width: `${currentProgressPercent}%` }} + > + {/* {!!votedPercentNum && ( +
20, + 'text-app-black pl-1.5': currentProgressPercent <= 20, + })} + > + {votedPercentNum}% +
+ )} */} +
+
+
+
+
0%
+ + {passed ? ( + <>
20, - 'text-app-black pl-1.5': _percent <= 20, - })} + className="absolute -translate-x-1/2" + style={{ left: `${Math.round((targetPercent / votedPercentNum) * 100)}%` }} > - {votedPercent}% + {targetPercent}%{targetBadge} +
- )} +
+ {totalProgressPercentText}% +
+ + ) : ( +
+ {targetPercent}%{targetBadge} +
+ )} +
+
+ ); + }; + + const renderVoteBar = () => { + const voteData = Object.values(votes).reduce( + (acc, [vote, stake]) => { + if (!acc[vote]) { + acc[vote] = Big(stake); + } else { + acc[vote] = acc[vote].plus(Big(stake)); + } + return acc; + }, + {} as Record<'yes' | 'no', Big.Big>, + ); + const voteTotal = voteData.yes?.plus(voteData.no) || Big(0); + const yesPercent = voteTotal.eq(0) ? 0 : voteData.yes.div(voteTotal).times(100).toFixed(2); + const noPercent = voteTotal.eq(0) ? 0 : voteData.no.div(voteTotal).times(100).toFixed(2); + + return ( +
+
+ + YEA +
+
+
+
+ {yesPercent}% +
+
+
+
+ {noPercent}% +
+
+
+
+ + NAY
); @@ -135,44 +242,10 @@ export default function Home() { return ( <> {/* progress bar */} -
-
- Pass - - - -
- - {renderProgress()} -
-
0%
- {progressList.map((p) => ( -
- {p}% -
- ))} + {renderProgress()} -
100%
-
-
+ {/* vote bar */} + {renderVoteBar()} {/* voting process status */} {renderVoteProgressStatus()} From 2c1175606cb4b1604de38b1f1bc831457221fe9c Mon Sep 17 00:00:00 2001 From: jin <57248516+chickick@users.noreply.github.com> Date: Wed, 23 Jul 2025 16:05:30 +0800 Subject: [PATCH 02/23] feat: modify some styles --- src/pages/home/index.tsx | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/pages/home/index.tsx b/src/pages/home/index.tsx index 285e1bd..276a0b4 100644 --- a/src/pages/home/index.tsx +++ b/src/pages/home/index.tsx @@ -102,7 +102,7 @@ export default function Home() { const currentProgressPercent = passed ? 100 : Math.round((votedPercentNum / targetPercent) * 100); - const totalProgressPercentText = passed ? votedPercentNum : targetPercent; + // const totalProgressPercentText = passed ? votedPercentNum : targetPercent; const targetBadge = (
-

+

Voter Turnout

@@ -141,7 +141,7 @@ export default function Home() { className="h-full bg-[hsla(158,100%,43%,1)] rounded-full flex items-center" style={{ width: `${currentProgressPercent}%` }} > - {/* {!!votedPercentNum && ( + {!!votedPercentNum && (
{votedPercentNum}%
- )} */} + )}
@@ -167,9 +167,9 @@ export default function Home() { {targetPercent}%{targetBadge}
-
+ {/*
{totalProgressPercentText}% -
+
*/} ) : (
From ae1e38df33eb7494354f0f4514f0825f19a5f235 Mon Sep 17 00:00:00 2001 From: jin <57248516+chickick@users.noreply.github.com> Date: Wed, 23 Jul 2025 19:43:49 +0800 Subject: [PATCH 03/23] feat: hide tooltip --- src/pages/home/index.tsx | 70 +++------------------------------------- 1 file changed, 4 insertions(+), 66 deletions(-) diff --git a/src/pages/home/index.tsx b/src/pages/home/index.tsx index 276a0b4..3599480 100644 --- a/src/pages/home/index.tsx +++ b/src/pages/home/index.tsx @@ -1,8 +1,6 @@ import './index.css'; -import { useMemo } from 'react'; - -import { ArrowRight, CircleHelp } from 'lucide-react'; +import { ArrowRight } from 'lucide-react'; import { useNavigate } from 'react-router-dom'; import { PulseLoader } from 'react-spinners'; @@ -12,7 +10,6 @@ import Bg1 from '@/assets/images/home-star-bg1.png'; import Bg2 from '@/assets/images/home-star-bg2.png'; import Markdown from '@/components/markdown'; import { Button } from '@/components/ui/button'; -import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover'; import config from '@/config'; import VoteContainer from '@/containers/vote'; import { cn, formatBigNumber, isNotNullAndNumber } from '@/lib/utils'; @@ -27,58 +24,13 @@ import Big from 'big.js'; dayjs.extend(utc); -function toFraction(x: number): string { - if (!x) return '2/3'; - if (x > 1) x = x / 100; - try { - const tolerance = 0.01; - let h1 = 1, - h2 = 0, - k1 = 0, - k2 = 1, - b = x; - do { - const a = Math.floor(b); - let aux = h1; - h1 = a * h1 + h2; - h2 = aux; - aux = k1; - k1 = a * k1 + k2; - k2 = aux; - b = 1 / (b - a); - } while (Math.abs(x - h1 / k1) > x * tolerance); - - return h1 + '/' + k1; - } catch (error) { - console.error('Error converting to fraction:', error); - return '2/3'; - } -} - export default function Home() { const navigate = useNavigate(); - const { - isLoading, - deadline, - votes, - votesCount, - votedPercent, - progressList, - voteFinishedAt, - votedStakeAmount, - } = VoteContainer.useContainer(); + const { isLoading, deadline, votes, votesCount, votedPercent, voteFinishedAt, votedStakeAmount } = + VoteContainer.useContainer(); const NEAR_ENV = config.proposalContractId?.split('.').pop() === 'near' ? 'mainnet' : 'testnet'; - const passed = useMemo(() => { - return Number(votedPercent) >= progressList[progressList.length - 1]; - }, [votedPercent, progressList]); - - const showTooltip = useMemo(() => { - if (voteFinishedAt) return false; - return passed; - }, [voteFinishedAt, passed]); - const renderVoteProgressStatus = () => { if (!voteFinishedAt) { return ; @@ -254,21 +206,7 @@ export default function Home() { {isNotNullAndNumber(votesCount) ? votesCount : '-'} Votes &{' '} {formatBigNumber(votedStakeAmount)} near -
- Voting Power for YEA - {showTooltip && ( - - - - - - The proposal will pass if the total voted stake keeps above{' '} - {toFraction(Number(votedPercent))} at the beginning of next epoch or a new vote - comes in. - - - )} -
+
Voting Power for YEA
From 1961709d1146f1d98810e1a5949a749e1c28f4ea Mon Sep 17 00:00:00 2001 From: jin <57248516+chickick@users.noreply.github.com> Date: Thu, 24 Jul 2025 10:51:37 +0800 Subject: [PATCH 04/23] feat: minor changes --- src/containers/vote/index.ts | 14 +++++++------- src/pages/home/index.tsx | 15 +++++++++++---- 2 files changed, 18 insertions(+), 11 deletions(-) diff --git a/src/containers/vote/index.ts b/src/containers/vote/index.ts index f5f0b01..64caefe 100644 --- a/src/containers/vote/index.ts +++ b/src/containers/vote/index.ts @@ -13,7 +13,7 @@ interface VoteState { deadline: number | null; voteFinishedAt: number | null; votes: Record; - votesCount: number | null; + yesVotesCount: number | null; votedStakeAmount: Big.Big; totalVotedStakeAmount: Big.Big; } @@ -59,12 +59,12 @@ function useVoteContainer(): UseVoteContainer { method: 'get_total_voted_stake', }); logger.debug('get_total_voted_stake', data); - if (!Array.isArray(data) && data.length !== 2) { + if (!Array.isArray(data) || data.length !== 3) { logger.error('get_total_voted_stake error', data); return; } - setVotedStakeAmount(Big(data[0])); - setTotalVotedStakeAmount(Big(data[1])); + setVotedStakeAmount(Big(data[1])); + setTotalVotedStakeAmount(Big(data[2])); }, [viewFunction]); const getResult = useCallback(async () => { @@ -113,9 +113,9 @@ function useVoteContainer(): UseVoteContainer { // revalidateOnReconnect: false, // }, ); - const votesCount = useMemo(() => { + const yesVotesCount = useMemo(() => { if (error) return null; - return Object.keys(votes).length; + return Object.values(votes).filter(([vote]) => vote === 'yes').length; }, [votes, error]); useEffect(() => { @@ -129,7 +129,7 @@ function useVoteContainer(): UseVoteContainer { deadline, voteFinishedAt, votes, - votesCount, + yesVotesCount, votedStakeAmount, totalVotedStakeAmount, votedPercent, diff --git a/src/pages/home/index.tsx b/src/pages/home/index.tsx index 3599480..e09cddc 100644 --- a/src/pages/home/index.tsx +++ b/src/pages/home/index.tsx @@ -26,8 +26,15 @@ dayjs.extend(utc); export default function Home() { const navigate = useNavigate(); - const { isLoading, deadline, votes, votesCount, votedPercent, voteFinishedAt, votedStakeAmount } = - VoteContainer.useContainer(); + const { + isLoading, + deadline, + votes, + yesVotesCount, + votedPercent, + voteFinishedAt, + votedStakeAmount, + } = VoteContainer.useContainer(); const NEAR_ENV = config.proposalContractId?.split('.').pop() === 'near' ? 'mainnet' : 'testnet'; @@ -85,7 +92,7 @@ export default function Home() { return (

- Voter Turnout + {votedPercentNum}% of STAKE VOTED

@@ -203,7 +210,7 @@ export default function Home() { {renderVoteProgressStatus()}
- {isNotNullAndNumber(votesCount) ? votesCount : '-'} Votes &{' '} + {isNotNullAndNumber(yesVotesCount) ? yesVotesCount : '-'} Votes &{' '} {formatBigNumber(votedStakeAmount)} near
Voting Power for YEA
From 747d334a01ea10e63001fbbb48583f6289f7ba46 Mon Sep 17 00:00:00 2001 From: jinmax2024 <57248516+chickick@users.noreply.github.com> Date: Thu, 24 Jul 2025 11:28:33 +0800 Subject: [PATCH 05/23] feat(home): update vote data render logic --- src/containers/vote/index.ts | 4 ++++ src/pages/home/index.tsx | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/containers/vote/index.ts b/src/containers/vote/index.ts index 64caefe..840d833 100644 --- a/src/containers/vote/index.ts +++ b/src/containers/vote/index.ts @@ -14,6 +14,7 @@ interface VoteState { voteFinishedAt: number | null; votes: Record; yesVotesCount: number | null; + votedYeaStakeAmount: Big.Big; votedStakeAmount: Big.Big; totalVotedStakeAmount: Big.Big; } @@ -35,6 +36,7 @@ function useVoteContainer(): UseVoteContainer { const [voteFinishedAt, setVoteFinishedAt] = useState(null); const [votes, setVotes] = useState>({}); const [votedStakeAmount, setVotedStakeAmount] = useState(Big(0)); + const [votedYeaStakeAmount, setVotedYeaStakeAmount] = useState(Big(0)); const [totalVotedStakeAmount, setTotalVotedStakeAmount] = useState(Big(0)); const _votedPercent = useMemo(() => { @@ -63,6 +65,7 @@ function useVoteContainer(): UseVoteContainer { logger.error('get_total_voted_stake error', data); return; } + setVotedYeaStakeAmount(Big(data[0])); setVotedStakeAmount(Big(data[1])); setTotalVotedStakeAmount(Big(data[2])); }, [viewFunction]); @@ -131,6 +134,7 @@ function useVoteContainer(): UseVoteContainer { votes, yesVotesCount, votedStakeAmount, + votedYeaStakeAmount, totalVotedStakeAmount, votedPercent, progressList: PROGRESS, diff --git a/src/pages/home/index.tsx b/src/pages/home/index.tsx index e09cddc..6ba8ba7 100644 --- a/src/pages/home/index.tsx +++ b/src/pages/home/index.tsx @@ -34,6 +34,7 @@ export default function Home() { votedPercent, voteFinishedAt, votedStakeAmount, + votedYeaStakeAmount, } = VoteContainer.useContainer(); const NEAR_ENV = config.proposalContractId?.split('.').pop() === 'near' ? 'mainnet' : 'testnet'; @@ -211,7 +212,7 @@ export default function Home() {
{isNotNullAndNumber(yesVotesCount) ? yesVotesCount : '-'} Votes &{' '} - {formatBigNumber(votedStakeAmount)} + {formatBigNumber(votedYeaStakeAmount)} near
Voting Power for YEA
@@ -260,7 +261,6 @@ export default function Home() { `- This voting ends when **2/3 of stake votes yes** or when **the deadline (${dayjs.utc(deadline).format('MM/DD/YYYY HH:mm:ss')} UTC) passes**.\n` + '- Replace **<validator-account-id>** and **<validator-owner-id>** in the commands below with your own account IDs.\n' + "- [The indexer](https://thegraph.com/explorer/subgraphs/3EbPN5sxnMtSof4M8LuaSKLcNzvzDLrY3eyrRKBhVGaK?view=Query&chain=arbitrum-one) that tracks the voting results may have several minutes delay. If you don't see your vote in the details page, please refresh the page after a while.\n" + - "- If the voting power of your validator is **0** on the details page, it's probably because your validator is kicked out in recent epochs. This is a known limitation of the current voting contract. Please try **vote again** after your validator is back online for such case.\n" + '\n' + 'Vote **yes** with the below command, if you support this proposal. \n' + '\n' + From bba1cb7a14da7b16ec75c41c6a4e5f2c42b198eb Mon Sep 17 00:00:00 2001 From: jinmax2024 <57248516+chickick@users.noreply.github.com> Date: Thu, 24 Jul 2025 11:38:33 +0800 Subject: [PATCH 06/23] refactor: updated mock contract and perf renderVoteBar --- src/config/testnet.ts | 2 +- src/pages/home/index.tsx | 13 +++++++++---- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/config/testnet.ts b/src/config/testnet.ts index 84574b1..b5a23c4 100644 --- a/src/config/testnet.ts +++ b/src/config/testnet.ts @@ -1,5 +1,5 @@ const config: App.AppConfig = { - proposalContractId: 'mock-proposal-alpha.testnet', + proposalContractId: 'mock-proposal-gamma.testnet', validatorApi: 'https://validator-voting-api.linearprotocol.org', near: { network: { diff --git a/src/pages/home/index.tsx b/src/pages/home/index.tsx index 6ba8ba7..7d4c059 100644 --- a/src/pages/home/index.tsx +++ b/src/pages/home/index.tsx @@ -33,7 +33,6 @@ export default function Home() { yesVotesCount, votedPercent, voteFinishedAt, - votedStakeAmount, votedYeaStakeAmount, } = VoteContainer.useContainer(); @@ -153,9 +152,15 @@ export default function Home() { }, {} as Record<'yes' | 'no', Big.Big>, ); - const voteTotal = voteData.yes?.plus(voteData.no) || Big(0); - const yesPercent = voteTotal.eq(0) ? 0 : voteData.yes.div(voteTotal).times(100).toFixed(2); - const noPercent = voteTotal.eq(0) ? 0 : voteData.no.div(voteTotal).times(100).toFixed(2); + + const safeBig = (val: any): Big => val instanceof Big ? val : Big(val || 0); + + const yes = safeBig(voteData?.yes); + const no = safeBig(voteData?.no); + const voteTotal = yes.plus(no); + + const yesPercent = voteTotal.eq(0) ? "0.00" : yes.div(voteTotal).times(100).toFixed(2); + const noPercent = voteTotal.eq(0) ? "0.00" : no.div(voteTotal).times(100).toFixed(2); return (
From 2cd37089853128a4df070529226dd61ee0ec02f2 Mon Sep 17 00:00:00 2001 From: jinmax2024 <57248516+chickick@users.noreply.github.com> Date: Thu, 24 Jul 2025 11:40:31 +0800 Subject: [PATCH 07/23] fix: minor type --- src/pages/home/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/home/index.tsx b/src/pages/home/index.tsx index 7d4c059..7e423dc 100644 --- a/src/pages/home/index.tsx +++ b/src/pages/home/index.tsx @@ -153,7 +153,7 @@ export default function Home() { {} as Record<'yes' | 'no', Big.Big>, ); - const safeBig = (val: any): Big => val instanceof Big ? val : Big(val || 0); + const safeBig = (val: Big.Big | undefined): Big => val instanceof Big ? val : Big(val || 0); const yes = safeBig(voteData?.yes); const no = safeBig(voteData?.no); From 602cd9ffd8bf91f4eee7584c500ffa1d8c9a9c1e Mon Sep 17 00:00:00 2001 From: jinmax2024 <57248516+chickick@users.noreply.github.com> Date: Thu, 24 Jul 2025 15:05:18 +0800 Subject: [PATCH 08/23] chore: update mainnet config --- src/config/mainnet.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/config/mainnet.ts b/src/config/mainnet.ts index 36026e9..83bcfec 100644 --- a/src/config/mainnet.ts +++ b/src/config/mainnet.ts @@ -1,6 +1,6 @@ const config: App.AppConfig = { proposalContractId: 'reduce-inflation.near', - validatorApi: 'https://validator-voting-api.linearprotocol.org', + validatorApi: 'https://nearblocks.io/address/test-proposal.near', near: { network: { networkId: 'mainnet', From 807428ff656de471b0863c08d5a7400fcce32a43 Mon Sep 17 00:00:00 2001 From: jinmax2024 <57248516+chickick@users.noreply.github.com> Date: Thu, 24 Jul 2025 15:07:25 +0800 Subject: [PATCH 09/23] chore: mainnet config --- src/config/mainnet.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/config/mainnet.ts b/src/config/mainnet.ts index 83bcfec..e850ac3 100644 --- a/src/config/mainnet.ts +++ b/src/config/mainnet.ts @@ -1,6 +1,6 @@ const config: App.AppConfig = { - proposalContractId: 'reduce-inflation.near', - validatorApi: 'https://nearblocks.io/address/test-proposal.near', + proposalContractId: 'test-proposal.near', + validatorApi: 'https://validator-voting-api.linearprotocol.org', near: { network: { networkId: 'mainnet', From 1da68117928341b1f382a96fd9ecf7bb358a9021 Mon Sep 17 00:00:00 2001 From: jin <57248516+chickick@users.noreply.github.com> Date: Thu, 24 Jul 2025 17:57:14 +0800 Subject: [PATCH 10/23] feat: minor changes --- src/containers/vote/index.ts | 30 +++++++++---------------- src/pages/home/components/Countdown.tsx | 14 ++++++++++++ src/pages/home/index.tsx | 25 +++------------------ 3 files changed, 28 insertions(+), 41 deletions(-) diff --git a/src/containers/vote/index.ts b/src/containers/vote/index.ts index 64caefe..04a56d3 100644 --- a/src/containers/vote/index.ts +++ b/src/containers/vote/index.ts @@ -11,7 +11,6 @@ import { toast } from 'sonner'; interface VoteState { isLoading: boolean; deadline: number | null; - voteFinishedAt: number | null; votes: Record; yesVotesCount: number | null; votedStakeAmount: Big.Big; @@ -32,7 +31,7 @@ function useVoteContainer(): UseVoteContainer { const { viewFunction } = useNear(); const [deadline, setDeadline] = useState(null); - const [voteFinishedAt, setVoteFinishedAt] = useState(null); + // const [voteFinishedAt, setVoteFinishedAt] = useState(null); const [votes, setVotes] = useState>({}); const [votedStakeAmount, setVotedStakeAmount] = useState(Big(0)); const [totalVotedStakeAmount, setTotalVotedStakeAmount] = useState(Big(0)); @@ -44,14 +43,8 @@ function useVoteContainer(): UseVoteContainer { }, [votedStakeAmount, totalVotedStakeAmount]); const votedPercent = useMemo(() => { - const _percent = Number(_votedPercent); - const lastProgress = PROGRESS[PROGRESS.length - 1]; - if (voteFinishedAt) { - if (_percent >= lastProgress) return _votedPercent; - return lastProgress.toFixed(2); - } return _votedPercent; - }, [_votedPercent, voteFinishedAt]); + }, [_votedPercent]); const getTotalVotedStake = useCallback(async () => { const data = await viewFunction({ @@ -67,14 +60,14 @@ function useVoteContainer(): UseVoteContainer { setTotalVotedStakeAmount(Big(data[2])); }, [viewFunction]); - const getResult = useCallback(async () => { - const data = await viewFunction({ - contractId: contractId, - method: 'get_result', - }); - logger.debug('get_result', data); - setVoteFinishedAt(data || null); - }, [viewFunction]); + // const getResult = useCallback(async () => { + // const data = await viewFunction({ + // contractId: contractId, + // method: 'get_result', + // }); + // logger.debug('get_result', data); + // setVoteFinishedAt(data || null); + // }, [viewFunction]); const getVotes = useCallback(async () => { const data = await viewFunction({ @@ -105,7 +98,7 @@ function useVoteContainer(): UseVoteContainer { const { isLoading, error } = useSWR( 'vote_data', async () => { - const promises = Promise.all([getTotalVotedStake(), getResult(), getVotes(), getDeadline()]); + const promises = Promise.all([getTotalVotedStake(), getVotes(), getDeadline()]); return await promises; }, // { @@ -127,7 +120,6 @@ function useVoteContainer(): UseVoteContainer { return { isLoading, deadline, - voteFinishedAt, votes, yesVotesCount, votedStakeAmount, diff --git a/src/pages/home/components/Countdown.tsx b/src/pages/home/components/Countdown.tsx index 86c9d5d..5d4de47 100644 --- a/src/pages/home/components/Countdown.tsx +++ b/src/pages/home/components/Countdown.tsx @@ -2,6 +2,7 @@ import { useEffect, useMemo, useState } from 'react'; import dayjs from 'dayjs'; import { useInterval } from 'react-use'; +import ApprovedImg from '@/assets/images/approved.png'; export interface CountdownProps { votedPercent: string; @@ -12,6 +13,8 @@ export default function Countdown({ deadline }: CountdownProps) { const [isPageVisible, setPageVisibility] = useState(!document.hidden); const [countdownSeconds, setCountdownSeconds] = useState(null); + const finished = deadline && Date.now() > deadline; + const deadlineFromNow = useMemo(() => { if (!countdownSeconds) return null; const diffSeconds = countdownSeconds; @@ -62,6 +65,17 @@ export default function Countdown({ deadline }: CountdownProps) { if (!deadlineFromNow) return null; + if (finished) { + return ( +
+ {/*

+ {votedPercent}% of Stake Voted for YEA +

*/} + +
+ ); + } + return (
{/*

diff --git a/src/pages/home/index.tsx b/src/pages/home/index.tsx index e09cddc..68330ba 100644 --- a/src/pages/home/index.tsx +++ b/src/pages/home/index.tsx @@ -5,7 +5,6 @@ import { useNavigate } from 'react-router-dom'; import { PulseLoader } from 'react-spinners'; import NEARLogo from '@/assets/images/near-green.jpg'; -import ApprovedImg from '@/assets/images/approved.png'; import Bg1 from '@/assets/images/home-star-bg1.png'; import Bg2 from '@/assets/images/home-star-bg2.png'; import Markdown from '@/components/markdown'; @@ -26,31 +25,13 @@ dayjs.extend(utc); export default function Home() { const navigate = useNavigate(); - const { - isLoading, - deadline, - votes, - yesVotesCount, - votedPercent, - voteFinishedAt, - votedStakeAmount, - } = VoteContainer.useContainer(); + const { isLoading, deadline, votes, yesVotesCount, votedPercent, votedStakeAmount } = + VoteContainer.useContainer(); const NEAR_ENV = config.proposalContractId?.split('.').pop() === 'near' ? 'mainnet' : 'testnet'; const renderVoteProgressStatus = () => { - if (!voteFinishedAt) { - return ; - } - - return ( -
- {/*

- {votedPercent}% of Stake Voted for YEA -

*/} - -
- ); + return ; }; const renderProgress = () => { From ebdd29031ff84a421148869db25100c07ad26869 Mon Sep 17 00:00:00 2001 From: jinmax2024 <57248516+chickick@users.noreply.github.com> Date: Thu, 24 Jul 2025 18:09:10 +0800 Subject: [PATCH 11/23] fix: minor --- src/pages/home/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/home/index.tsx b/src/pages/home/index.tsx index aeb6cc3..8d58492 100644 --- a/src/pages/home/index.tsx +++ b/src/pages/home/index.tsx @@ -25,7 +25,7 @@ dayjs.extend(utc); export default function Home() { const navigate = useNavigate(); - const { isLoading, deadline, votes, yesVotesCount, votedPercent } = VoteContainer.useContainer(); + const { isLoading, deadline, votes, yesVotesCount, votedYeaStakeAmount, votedPercent } = VoteContainer.useContainer(); const NEAR_ENV = config.proposalContractId?.split('.').pop() === 'near' ? 'mainnet' : 'testnet'; From 6fa6d80ac5fb169646f7446bd8f039731097e73e Mon Sep 17 00:00:00 2001 From: jinmax2024 <57248516+chickick@users.noreply.github.com> Date: Thu, 24 Jul 2025 19:00:16 +0800 Subject: [PATCH 12/23] chore: update mainnet api --- src/config/mainnet.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/config/mainnet.ts b/src/config/mainnet.ts index e850ac3..ae16012 100644 --- a/src/config/mainnet.ts +++ b/src/config/mainnet.ts @@ -1,6 +1,7 @@ const config: App.AppConfig = { proposalContractId: 'test-proposal.near', - validatorApi: 'https://validator-voting-api.linearprotocol.org', + // validatorApi: 'https://validator-voting-api.linearprotocol.org', + validatorApi: "https://validator-voting-api-dev-7d3e8c25989f.herokuapp.com", near: { network: { networkId: 'mainnet', From 14d10567b082ba4ad19f89d8dac407873a97cfea Mon Sep 17 00:00:00 2001 From: jin <57248516+chickick@users.noreply.github.com> Date: Thu, 24 Jul 2025 19:15:58 +0800 Subject: [PATCH 13/23] feat: fetch vote result data --- src/containers/vote/index.ts | 22 ++++++++++++---------- src/pages/home/components/Countdown.tsx | 13 +------------ src/pages/home/index.tsx | 13 ++++++++++++- 3 files changed, 25 insertions(+), 23 deletions(-) diff --git a/src/containers/vote/index.ts b/src/containers/vote/index.ts index 04a56d3..d58921c 100644 --- a/src/containers/vote/index.ts +++ b/src/containers/vote/index.ts @@ -10,6 +10,7 @@ import { toast } from 'sonner'; interface VoteState { isLoading: boolean; + voteResult: boolean; deadline: number | null; votes: Record; yesVotesCount: number | null; @@ -31,7 +32,7 @@ function useVoteContainer(): UseVoteContainer { const { viewFunction } = useNear(); const [deadline, setDeadline] = useState(null); - // const [voteFinishedAt, setVoteFinishedAt] = useState(null); + const [voteResult, setVoteResult] = useState(false); const [votes, setVotes] = useState>({}); const [votedStakeAmount, setVotedStakeAmount] = useState(Big(0)); const [totalVotedStakeAmount, setTotalVotedStakeAmount] = useState(Big(0)); @@ -60,14 +61,14 @@ function useVoteContainer(): UseVoteContainer { setTotalVotedStakeAmount(Big(data[2])); }, [viewFunction]); - // const getResult = useCallback(async () => { - // const data = await viewFunction({ - // contractId: contractId, - // method: 'get_result', - // }); - // logger.debug('get_result', data); - // setVoteFinishedAt(data || null); - // }, [viewFunction]); + const getResult = useCallback(async () => { + const data = await viewFunction({ + contractId: contractId, + method: 'get_result', + }); + logger.debug('get_result', data); + setVoteResult(data || false); + }, [viewFunction]); const getVotes = useCallback(async () => { const data = await viewFunction({ @@ -98,7 +99,7 @@ function useVoteContainer(): UseVoteContainer { const { isLoading, error } = useSWR( 'vote_data', async () => { - const promises = Promise.all([getTotalVotedStake(), getVotes(), getDeadline()]); + const promises = Promise.all([getTotalVotedStake(), getVotes(), getDeadline(), getResult()]); return await promises; }, // { @@ -119,6 +120,7 @@ function useVoteContainer(): UseVoteContainer { return { isLoading, + voteResult, deadline, votes, yesVotesCount, diff --git a/src/pages/home/components/Countdown.tsx b/src/pages/home/components/Countdown.tsx index 5d4de47..a0491fa 100644 --- a/src/pages/home/components/Countdown.tsx +++ b/src/pages/home/components/Countdown.tsx @@ -2,7 +2,6 @@ import { useEffect, useMemo, useState } from 'react'; import dayjs from 'dayjs'; import { useInterval } from 'react-use'; -import ApprovedImg from '@/assets/images/approved.png'; export interface CountdownProps { votedPercent: string; @@ -64,17 +63,7 @@ export default function Countdown({ deadline }: CountdownProps) { ); if (!deadlineFromNow) return null; - - if (finished) { - return ( -
- {/*

- {votedPercent}% of Stake Voted for YEA -

*/} - -
- ); - } + if (finished) return null; return (
diff --git a/src/pages/home/index.tsx b/src/pages/home/index.tsx index 68330ba..d4f1a11 100644 --- a/src/pages/home/index.tsx +++ b/src/pages/home/index.tsx @@ -15,6 +15,7 @@ import { cn, formatBigNumber, isNotNullAndNumber } from '@/lib/utils'; import { article } from './article'; import YesIcon from '@/assets/icons/yes.svg?react'; import NoIcon from '@/assets/icons/no.svg?react'; +import ApprovedImg from '@/assets/images/approved.png'; import Countdown from './components/Countdown'; import dayjs from 'dayjs'; @@ -25,12 +26,22 @@ dayjs.extend(utc); export default function Home() { const navigate = useNavigate(); - const { isLoading, deadline, votes, yesVotesCount, votedPercent, votedStakeAmount } = + const { isLoading, deadline, votes, voteResult, yesVotesCount, votedPercent, votedStakeAmount } = VoteContainer.useContainer(); const NEAR_ENV = config.proposalContractId?.split('.').pop() === 'near' ? 'mainnet' : 'testnet'; const renderVoteProgressStatus = () => { + if (voteResult) { + return ( +
+ {/*

+ {votedPercent}% of Stake Voted for YEA +

*/} + +
+ ); + } return ; }; From 551f239301f1cd18b7d78efffe78fffa3b15d31f Mon Sep 17 00:00:00 2001 From: Linguists <95207870+linguists@users.noreply.github.com> Date: Fri, 25 Jul 2025 12:11:36 +0800 Subject: [PATCH 14/23] feat: update voting instructions --- src/pages/home/index.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pages/home/index.tsx b/src/pages/home/index.tsx index 4c799a3..54113b5 100644 --- a/src/pages/home/index.tsx +++ b/src/pages/home/index.tsx @@ -254,8 +254,8 @@ export default function Home() { '## Vote with NEAR CLI\n' + 'Instructions for Validator Voting:\n' + '- If you are a validator, please use the CLI commands shown below to vote. We do not support voting through wallet for security considerations. This page is only used to display voting results.\n' + - '- You can vote **yes** or **no** for the proposal. You can change your vote before the voting ends.\n' + - `- This voting ends when **2/3 of stake votes yes** or when **the deadline (${dayjs.utc(deadline).format('MM/DD/YYYY HH:mm:ss')} UTC) passes**.\n` + + `- You can vote **yes** or **no** for the proposal. You can change your vote before the deadline (**${dayjs.utc(deadline).format('MM/DD/YYYY HH:mm:ss')} UTC**).\n` + + '- This proposal will be approved when more than 1/3 of total stake joins the voting and more than 2/3 of stake participating in the voting is **yes**.\n' + '- Replace **<validator-account-id>** and **<validator-owner-id>** in the commands below with your own account IDs.\n' + "- [The indexer](https://thegraph.com/explorer/subgraphs/3EbPN5sxnMtSof4M8LuaSKLcNzvzDLrY3eyrRKBhVGaK?view=Query&chain=arbitrum-one) that tracks the voting results may have several minutes delay. If you don't see your vote in the details page, please refresh the page after a while.\n" + '\n' + From cef61ee4c48b593a62ac9f6a37726969c88a87de Mon Sep 17 00:00:00 2001 From: Linguists <95207870+linguists@users.noreply.github.com> Date: Fri, 25 Jul 2025 12:13:33 +0800 Subject: [PATCH 15/23] feat: update voting instructions --- src/pages/home/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/home/index.tsx b/src/pages/home/index.tsx index 54113b5..2514aea 100644 --- a/src/pages/home/index.tsx +++ b/src/pages/home/index.tsx @@ -255,7 +255,7 @@ export default function Home() { 'Instructions for Validator Voting:\n' + '- If you are a validator, please use the CLI commands shown below to vote. We do not support voting through wallet for security considerations. This page is only used to display voting results.\n' + `- You can vote **yes** or **no** for the proposal. You can change your vote before the deadline (**${dayjs.utc(deadline).format('MM/DD/YYYY HH:mm:ss')} UTC**).\n` + - '- This proposal will be approved when more than 1/3 of total stake joins the voting and more than 2/3 of stake participating in the voting is **yes**.\n' + + '- This proposal will be approved when more than **1/3 of total stake** joins the voting and more than **2/3 of stake participating in the voting** is **yes**.\n' + '- Replace **<validator-account-id>** and **<validator-owner-id>** in the commands below with your own account IDs.\n' + "- [The indexer](https://thegraph.com/explorer/subgraphs/3EbPN5sxnMtSof4M8LuaSKLcNzvzDLrY3eyrRKBhVGaK?view=Query&chain=arbitrum-one) that tracks the voting results may have several minutes delay. If you don't see your vote in the details page, please refresh the page after a while.\n" + '\n' + From e3d8b687798ef177d21fd227444ec0a51c4ee8ba Mon Sep 17 00:00:00 2001 From: Linguists <95207870+linguists@users.noreply.github.com> Date: Fri, 25 Jul 2025 15:13:14 +0800 Subject: [PATCH 16/23] chore: change tesnet contract ID --- src/config/testnet.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/config/testnet.ts b/src/config/testnet.ts index b5a23c4..92a9f67 100644 --- a/src/config/testnet.ts +++ b/src/config/testnet.ts @@ -1,5 +1,5 @@ const config: App.AppConfig = { - proposalContractId: 'mock-proposal-gamma.testnet', + proposalContractId: 'mock-proposal-delta.testnet', validatorApi: 'https://validator-voting-api.linearprotocol.org', near: { network: { From b97dafc23c8c4af2de2d969d13d409063bf3ae72 Mon Sep 17 00:00:00 2001 From: jin <57248516+chickick@users.noreply.github.com> Date: Fri, 25 Jul 2025 16:40:56 +0800 Subject: [PATCH 17/23] chore: optimize codes --- src/containers/vote/index.ts | 16 ++++++++-------- src/pages/details/index.tsx | 10 +++++----- src/pages/home/index.tsx | 21 ++++++++++++--------- 3 files changed, 25 insertions(+), 22 deletions(-) diff --git a/src/containers/vote/index.ts b/src/containers/vote/index.ts index 2bdd356..7d9c64f 100644 --- a/src/containers/vote/index.ts +++ b/src/containers/vote/index.ts @@ -16,7 +16,7 @@ interface VoteState { yesVotesCount: number | null; votedYeaStakeAmount: Big.Big; votedStakeAmount: Big.Big; - totalVotedStakeAmount: Big.Big; + totalStakeAmount: Big.Big; } interface VoteComputed { @@ -37,13 +37,13 @@ function useVoteContainer(): UseVoteContainer { const [votes, setVotes] = useState>({}); const [votedStakeAmount, setVotedStakeAmount] = useState(Big(0)); const [votedYeaStakeAmount, setVotedYeaStakeAmount] = useState(Big(0)); - const [totalVotedStakeAmount, setTotalVotedStakeAmount] = useState(Big(0)); + const [totalStakeAmount, setTotalStakeAmount] = useState(Big(0)); const _votedPercent = useMemo(() => { - if (!totalVotedStakeAmount) return '0'; - if (totalVotedStakeAmount.eq(0)) return '0'; - return votedStakeAmount.div(totalVotedStakeAmount).times(100).toFixed(2) || '0'; - }, [votedStakeAmount, totalVotedStakeAmount]); + if (!totalStakeAmount) return '0'; + if (totalStakeAmount.eq(0)) return '0'; + return votedStakeAmount.div(totalStakeAmount).times(100).toFixed(2) || '0'; + }, [votedStakeAmount, totalStakeAmount]); const votedPercent = useMemo(() => { return _votedPercent; @@ -61,7 +61,7 @@ function useVoteContainer(): UseVoteContainer { } setVotedYeaStakeAmount(Big(data[0])); setVotedStakeAmount(Big(data[1])); - setTotalVotedStakeAmount(Big(data[2])); + setTotalStakeAmount(Big(data[2])); }, [viewFunction]); const getResult = useCallback(async () => { @@ -129,7 +129,7 @@ function useVoteContainer(): UseVoteContainer { yesVotesCount, votedStakeAmount, votedYeaStakeAmount, - totalVotedStakeAmount, + totalStakeAmount, votedPercent, progressList: PROGRESS, }; diff --git a/src/pages/details/index.tsx b/src/pages/details/index.tsx index 9bc5d35..8f53364 100644 --- a/src/pages/details/index.tsx +++ b/src/pages/details/index.tsx @@ -33,7 +33,7 @@ interface VotingPowerItem { export default function Details() { const navigate = useNavigate(); - const { isLoading: voteDataLoading, votes, totalVotedStakeAmount } = VoteContainer.useContainer(); + const { isLoading: voteDataLoading, votes, totalStakeAmount } = VoteContainer.useContainer(); const [loading, setLoading] = useState(false); const [list, setList] = useState([]); const [powerOrder, setPowerOrder] = useState<'asc' | 'desc' | undefined>(); @@ -81,11 +81,11 @@ export default function Details() { const getPercent = useCallback( (n: string | number) => { - if (!totalVotedStakeAmount || !n) return '0'; - if (Big(totalVotedStakeAmount).eq(0)) return '0'; - return Big(n).div(totalVotedStakeAmount).times(100).toFixed(2); + if (!totalStakeAmount || !n) return '0'; + if (Big(totalStakeAmount).eq(0)) return '0'; + return Big(n).div(totalStakeAmount).times(100).toFixed(2); }, - [totalVotedStakeAmount], + [totalStakeAmount], ); const votingPowerMap: Record = useMemo(() => { diff --git a/src/pages/home/index.tsx b/src/pages/home/index.tsx index 2514aea..b53977a 100644 --- a/src/pages/home/index.tsx +++ b/src/pages/home/index.tsx @@ -26,8 +26,15 @@ dayjs.extend(utc); export default function Home() { const navigate = useNavigate(); - const { isLoading, deadline, votes, voteResult, yesVotesCount, votedPercent, votedYeaStakeAmount } = - VoteContainer.useContainer(); + const { + isLoading, + deadline, + votes, + voteResult, + yesVotesCount, + votedPercent, + votedYeaStakeAmount, + } = VoteContainer.useContainer(); const NEAR_ENV = config.proposalContractId?.split('.').pop() === 'near' ? 'mainnet' : 'testnet'; @@ -53,7 +60,6 @@ export default function Home() { const currentProgressPercent = passed ? 100 : Math.round((votedPercentNum / targetPercent) * 100); - // const totalProgressPercentText = passed ? votedPercentNum : targetPercent; const targetBadge = (
- {/*
- {totalProgressPercentText}% -
*/} ) : (
@@ -145,14 +148,14 @@ export default function Home() { {} as Record<'yes' | 'no', Big.Big>, ); - const safeBig = (val: Big.Big | undefined): Big => val instanceof Big ? val : Big(val || 0); + const safeBig = (val: Big.Big | undefined): Big => (val instanceof Big ? val : Big(val || 0)); const yes = safeBig(voteData?.yes); const no = safeBig(voteData?.no); const voteTotal = yes.plus(no); - const yesPercent = voteTotal.eq(0) ? "0.00" : yes.div(voteTotal).times(100).toFixed(2); - const noPercent = voteTotal.eq(0) ? "0.00" : no.div(voteTotal).times(100).toFixed(2); + const yesPercent = voteTotal.eq(0) ? '0.00' : yes.div(voteTotal).times(100).toFixed(2); + const noPercent = voteTotal.eq(0) ? '0.00' : no.div(voteTotal).times(100).toFixed(2); return (
From f3053a295036a35233309175968ec1bfb47e38e0 Mon Sep 17 00:00:00 2001 From: jin <57248516+chickick@users.noreply.github.com> Date: Fri, 25 Jul 2025 16:53:51 +0800 Subject: [PATCH 18/23] chore: optimize codes --- src/pages/details/index.tsx | 20 +++----------------- 1 file changed, 3 insertions(+), 17 deletions(-) diff --git a/src/pages/details/index.tsx b/src/pages/details/index.tsx index 8f53364..fcac50c 100644 --- a/src/pages/details/index.tsx +++ b/src/pages/details/index.tsx @@ -46,18 +46,8 @@ export default function Details() { // }); return list.sort((a, b) => { - const aVote = - a.vote === 'yes' - ? votes[a.accountId] - ? votes[a.accountId][1] - : '0' - : a.totalStakedBalance; - const bVote = - b.vote === 'yes' - ? votes[b.accountId] - ? votes[b.accountId][1] - : '0' - : b.totalStakedBalance; + const aVote = votes[a.accountId] ? votes[a.accountId][1] : '0'; + const bVote = votes[b.accountId] ? votes[b.accountId][1] : '0'; const aDate = a.lastVoteTimestamp || 0; const bDate = b.lastVoteTimestamp || 0; @@ -92,11 +82,7 @@ export default function Details() { const data: Record = {}; tableList.forEach((item) => { const isYesVote = item.vote === 'yes'; - let power = votes[item.accountId] ? votes[item.accountId][1] : '0'; - if (!isYesVote) { - power = item.totalStakedBalance || '0'; - } - + const power = votes[item.accountId] ? votes[item.accountId][1] : '0'; const formattedPower = power ? formatBigNumber(power, 24) : '0'; const percent = getPercent(power); From d6f1755fdfcb57f33a17a39d5e8aea0aa0333db2 Mon Sep 17 00:00:00 2001 From: jin <57248516+chickick@users.noreply.github.com> Date: Fri, 25 Jul 2025 18:12:20 +0800 Subject: [PATCH 19/23] chore: modify the number of decimal places --- src/containers/vote/index.ts | 2 +- src/pages/home/index.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/containers/vote/index.ts b/src/containers/vote/index.ts index 7d9c64f..a1ce8ac 100644 --- a/src/containers/vote/index.ts +++ b/src/containers/vote/index.ts @@ -24,7 +24,7 @@ interface VoteComputed { progressList: number[]; } -const PROGRESS = [33.3]; +const PROGRESS = [33.33]; type UseVoteContainer = VoteState & VoteComputed; const contractId = config.proposalContractId; diff --git a/src/pages/home/index.tsx b/src/pages/home/index.tsx index b53977a..813f659 100644 --- a/src/pages/home/index.tsx +++ b/src/pages/home/index.tsx @@ -54,7 +54,7 @@ export default function Home() { const renderProgress = () => { const votedPercentNum = Number(votedPercent); - const targetPercent = 33.3; + const targetPercent = 33.33; const passed = votedPercentNum >= targetPercent; const currentProgressPercent = passed From 22ffbee16aa7beafcf0c4dfaa3c4ca2e7836b59d Mon Sep 17 00:00:00 2001 From: jinmax2024 <57248516+chickick@users.noreply.github.com> Date: Fri, 25 Jul 2025 18:14:52 +0800 Subject: [PATCH 20/23] chore: update testnet contract --- src/config/testnet.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/config/testnet.ts b/src/config/testnet.ts index 92a9f67..84574b1 100644 --- a/src/config/testnet.ts +++ b/src/config/testnet.ts @@ -1,5 +1,5 @@ const config: App.AppConfig = { - proposalContractId: 'mock-proposal-delta.testnet', + proposalContractId: 'mock-proposal-alpha.testnet', validatorApi: 'https://validator-voting-api.linearprotocol.org', near: { network: { From 605d64e07793cfd346b9416e28abc3b1f7b25b03 Mon Sep 17 00:00:00 2001 From: Linguists <95207870+linguists@users.noreply.github.com> Date: Fri, 25 Jul 2025 18:31:19 +0800 Subject: [PATCH 21/23] Update src/pages/home/index.tsx --- src/pages/home/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/home/index.tsx b/src/pages/home/index.tsx index 813f659..a8d39e9 100644 --- a/src/pages/home/index.tsx +++ b/src/pages/home/index.tsx @@ -258,7 +258,7 @@ export default function Home() { 'Instructions for Validator Voting:\n' + '- If you are a validator, please use the CLI commands shown below to vote. We do not support voting through wallet for security considerations. This page is only used to display voting results.\n' + `- You can vote **yes** or **no** for the proposal. You can change your vote before the deadline (**${dayjs.utc(deadline).format('MM/DD/YYYY HH:mm:ss')} UTC**).\n` + - '- This proposal will be approved when more than **1/3 of total stake** joins the voting and more than **2/3 of stake participating in the voting** is **yes**.\n' + + '- This proposal will be approved if more than **1/3 of total stake** joins the voting and more than **2/3 of stake participating in the voting** is **yes** when the deadline is reached.\n' + '- Replace **<validator-account-id>** and **<validator-owner-id>** in the commands below with your own account IDs.\n' + "- [The indexer](https://thegraph.com/explorer/subgraphs/3EbPN5sxnMtSof4M8LuaSKLcNzvzDLrY3eyrRKBhVGaK?view=Query&chain=arbitrum-one) that tracks the voting results may have several minutes delay. If you don't see your vote in the details page, please refresh the page after a while.\n" + '\n' + From 566c3a7a39ed28393bd6d8744efc4ae2e300947a Mon Sep 17 00:00:00 2001 From: jin <57248516+chickick@users.noreply.github.com> Date: Wed, 30 Jul 2025 13:22:51 +0800 Subject: [PATCH 22/23] feat: Modify progress bar --- src/pages/home/index.tsx | 36 +++++++++++++++--------------------- 1 file changed, 15 insertions(+), 21 deletions(-) diff --git a/src/pages/home/index.tsx b/src/pages/home/index.tsx index 813f659..b0501a8 100644 --- a/src/pages/home/index.tsx +++ b/src/pages/home/index.tsx @@ -55,11 +55,11 @@ export default function Home() { const renderProgress = () => { const votedPercentNum = Number(votedPercent); const targetPercent = 33.33; - const passed = votedPercentNum >= targetPercent; - - const currentProgressPercent = passed + const gt50Percent = votedPercentNum >= 50; + const totalPercent = gt50Percent ? votedPercentNum : 50; + const currentProgressPercent = gt50Percent ? 100 - : Math.round((votedPercentNum / targetPercent) * 100); + : Math.round((votedPercentNum / totalPercent) * 100); const targetBadge = (
0%
- {passed ? ( - <> -
- {targetPercent}%{targetBadge} -
-
- - ) : ( -
- {targetPercent}%{targetBadge} -
- )} +
+ {targetPercent}%{targetBadge} +
+
+ + {!gt50Percent &&
50%
}
); From ec17c8647d9c20d0c7a52f93430174d28dbb6d74 Mon Sep 17 00:00:00 2001 From: jinmax2024 <57248516+chickick@users.noreply.github.com> Date: Wed, 30 Jul 2025 13:58:02 +0800 Subject: [PATCH 23/23] chore: update text copy --- src/pages/home/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/home/index.tsx b/src/pages/home/index.tsx index 5d7d5f4..60e6bc6 100644 --- a/src/pages/home/index.tsx +++ b/src/pages/home/index.tsx @@ -67,7 +67,7 @@ export default function Home() { 'absolute flex items-center justify-center text-white w-[68px] h-[30px] left-1/2 -top-[70px] text-sm bg-app-black rounded-full -translate-x-1/2', )} > - Target + Quorum