Skip to content

Commit

Permalink
♻️ governance: get vp with snapshot api
Browse files Browse the repository at this point in the history
  • Loading branch information
JuampiRombola committed Sep 27, 2023
1 parent e033ce2 commit 13980ac
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 24 deletions.
2 changes: 1 addition & 1 deletion components/governance/Claimable/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -167,4 +167,4 @@ const NFT: FC = () => {
);
};

export default Claimable;
export default React.memo(Claimable);
2 changes: 1 addition & 1 deletion components/governance/Delegation/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -254,4 +254,4 @@ const Delegation = ({ amount }: Props) => {
);
};

export default Delegation;
export default React.memo(Delegation);
28 changes: 7 additions & 21 deletions components/governance/VotingPower/index.tsx
Original file line number Diff line number Diff line change
@@ -1,42 +1,28 @@
import React, { useMemo } from 'react';
import React, { FC } from 'react';
import { Box, Skeleton, Typography } from '@mui/material';
import { formatEther } from 'viem';
import { useTranslation } from 'react-i18next';
import { useEXAGetVotes, useEXADelegates } from 'hooks/useEXA';
import formatNumber from 'utils/formatNumber';
import { useWeb3 } from 'hooks/useWeb3';
import { useAirdropStreams } from 'hooks/useAirdrop';
import { useSablierV2LockupLinearGetWithdrawnAmount } from 'hooks/useSablier';

type Props = {
amount: bigint;
votingPower?: number;
};

const VotingPower = ({ amount }: Props) => {
const VotingPower: FC<Props> = ({ votingPower }) => {
const { t } = useTranslation();
const { walletAddress } = useWeb3();
const { data: votes, isLoading: isLoadingGetVotes } = useEXAGetVotes();
const { data: stream } = useAirdropStreams();
const { data: delegatee, isLoading: isLoadingDelegatee } = useEXADelegates();
const { data: withdrawn, isLoading: isLoadingWithdrawn } = useSablierV2LockupLinearGetWithdrawnAmount(stream);

const totalVotes = useMemo(() => {
return (votes ?? 0n) + (delegatee === walletAddress ? amount - (withdrawn ?? 0n) : 0n);
}, [votes, amount, walletAddress, delegatee, withdrawn]);

return (
<Box display="flex" flexDirection="column" gap={4}>
<Box display="flex" justifyContent="space-between" alignItems="center">
<Typography variant="h6">{t('Voting Power')}</Typography>
{votes === undefined || isLoadingDelegatee || isLoadingWithdrawn || isLoadingGetVotes ? (
{votingPower === undefined ? (
<Skeleton width={56} height={40} />
) : (
<Typography fontSize={28} color="grey.700">
{formatNumber(formatEther(totalVotes))}
{formatNumber(votingPower)}
</Typography>
)}
</Box>
{votes === 0n && (
{votingPower === 0 && (
<Typography fontSize={14} color="grey.500">
{t('You have no voting power in your connected wallet.')}
</Typography>
Expand All @@ -45,4 +31,4 @@ const VotingPower = ({ amount }: Props) => {
);
};

export default VotingPower;
export default React.memo(VotingPower);
49 changes: 49 additions & 0 deletions hooks/useGovernance.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import snapshot from '@snapshot-labs/snapshot.js';
import { useWeb3 } from './useWeb3';
import { useEffect, useMemo, useState } from 'react';
import optimismEXA from '@exactly/protocol/deployments/optimism/EXA.json';
import goerliEXA from '@exactly/protocol/deployments/goerli/EXA.json';

export default function useGovernance() {
const [votingPower, setVotingPower] = useState<number | undefined>(undefined);
const { chain, walletAddress } = useWeb3();

const exaAddress = useMemo(() => (chain.id === 10 ? optimismEXA.address : goerliEXA.address), [chain.id]);
const space = useMemo(() => (chain.id === 10 ? 'gov.exa.eth' : 'exa.eth'), [chain.id]);

const strategies = useMemo(
() => [
{
name: 'erc20-balance-of',
params: {
symbol: 'EXA',
address: exaAddress,
decimals: 18,
},
},
{
name: 'sablier-v2',
params: {
policy: 'reserved-recipient',
symbol: 'EXA',
address: exaAddress,
decimals: 18,
},
},
],
[exaAddress],
);

const delegation = true;
const url = 'https://score.snapshot.org/';

useEffect(() => {
if (!walletAddress) return;

snapshot.utils
.getVp(walletAddress, String(chain.id), strategies, 'latest', space, delegation, { url })
.then(({ vp }) => setVotingPower(vp));
}, [chain.id, chain.network, delegation, space, strategies, url, votingPower, walletAddress]);

return { votingPower };
}
4 changes: 3 additions & 1 deletion pages/governance.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { usePageView } from 'hooks/useAnalytics';
import { Box, Typography } from '@mui/material';
import { useTranslation, Trans } from 'react-i18next';
import { useWeb3 } from 'hooks/useWeb3';
import useGovernance from 'hooks/useGovernance';
import ConnectWalletGovernance from 'components/governance/ConnectWalletGovernance';
import Claimable from 'components/governance/Claimable';
import Delegation from 'components/governance/Delegation';
Expand All @@ -15,6 +16,7 @@ import useMerkleTree from 'hooks/useMerkleTree';
const Governance: NextPage = () => {
const { t } = useTranslation();
const { isConnected, walletAddress, impersonateActive } = useWeb3();
const { votingPower } = useGovernance();
const mTree = useMerkleTree(walletAddress);

usePageView('/governance', 'Governance');
Expand Down Expand Up @@ -44,7 +46,7 @@ const Governance: NextPage = () => {
bgcolor={({ palette }) => (palette.mode === 'dark' ? 'grey.100' : 'white')}
>
{mTree.canClaim && <Claimable amount={mTree.amount} proof={mTree.proof} />}
<VotingPower amount={mTree.canClaim ? mTree.amount : 0n} />
<VotingPower votingPower={votingPower} />
<Delegation amount={mTree.canClaim ? mTree.amount : 0n} />
<Proposals />
</Box>
Expand Down

0 comments on commit 13980ac

Please sign in to comment.