forked from solana-labs/governance-ui
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Delegation & Govpower rework part 1 (solana-labs#1781)
- Loading branch information
Showing
42 changed files
with
1,093 additions
and
855 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
import { ChevronRightIcon } from '@heroicons/react/solid' | ||
import { useGovernancePowerAsync } from '@hooks/queries/governancePower' | ||
import useQueryContext from '@hooks/useQueryContext' | ||
import useWalletOnePointOh from '@hooks/useWalletOnePointOh' | ||
import Link from 'next/link' | ||
import { useRouter } from 'next/router' | ||
import GovernancePowerForRole from './GovernancePowerForRole' | ||
|
||
const GovernancePowerTitle = () => { | ||
const { symbol } = useRouter().query | ||
const { fmtUrlWithCluster } = useQueryContext() | ||
const connected = useWalletOnePointOh()?.connected ?? undefined | ||
|
||
return ( | ||
<div className="flex items-center justify-between mb-4"> | ||
<h3 className="mb-0">My governance power</h3> | ||
<Link href={fmtUrlWithCluster(`/dao/${symbol}/account/me`)}> | ||
<a | ||
className={`default-transition flex items-center text-fgd-2 text-sm transition-all hover:text-fgd-3 ${ | ||
!connected ? 'opacity-50 pointer-events-none' : '' | ||
}`} | ||
> | ||
View | ||
<ChevronRightIcon className="flex-shrink-0 w-6 h-6" /> | ||
</a> | ||
</Link> | ||
</div> | ||
) | ||
} | ||
|
||
const GovernancePowerCard = () => { | ||
const connected = useWalletOnePointOh()?.connected ?? false | ||
|
||
const communityPower = useGovernancePowerAsync('community') | ||
const councilPower = useGovernancePowerAsync('council') | ||
|
||
const bothLoading = communityPower.loading && councilPower.loading | ||
|
||
const bothZero = | ||
communityPower.result !== undefined && | ||
councilPower.result !== undefined && | ||
communityPower.result.isZero() && | ||
councilPower.result.isZero() | ||
|
||
return ( | ||
<div> | ||
<GovernancePowerTitle /> | ||
{!connected ? ( | ||
<div className={'text-xs text-white/50 mt-8'}> | ||
Connect your wallet to see governance power | ||
</div> | ||
) : bothLoading ? ( | ||
<> | ||
<div className="h-12 mb-4 rounded-lg animate-pulse bg-bkg-3" /> | ||
<div className="h-10 rounded-lg animate-pulse bg-bkg-3" /> | ||
</> | ||
) : bothZero ? ( | ||
<div className={'text-xs text-white/50 mt-8'}> | ||
You do not have any governance power in this dao | ||
</div> | ||
) : ( | ||
<div className="flex flex-col gap-2"> | ||
<GovernancePowerForRole role="community" /> | ||
<GovernancePowerForRole role="council" /> | ||
</div> | ||
)} | ||
</div> | ||
) | ||
} | ||
|
||
export default GovernancePowerCard |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
import classNames from 'classnames' | ||
|
||
import useWalletOnePointOh from '@hooks/useWalletOnePointOh' | ||
import { useAsync } from 'react-async-hook' | ||
import { determineVotingPowerType } from '@hooks/queries/governancePower' | ||
import { useConnection } from '@solana/wallet-adapter-react' | ||
import useSelectedRealmPubkey from '@hooks/selectedRealm/useSelectedRealmPubkey' | ||
import LockedCommunityVotingPower from '@components/ProposalVotingPower/LockedCommunityVotingPower' | ||
import NftVotingPower from '@components/ProposalVotingPower/NftVotingPower' | ||
import LockedCommunityNFTRecordVotingPower from '@components/ProposalVotingPower/LockedCommunityNFTRecordVotingPower' | ||
import VanillaVotingPower from './Vanilla/VanillaVotingPower' | ||
|
||
export default function GovernancePowerForRole({ | ||
role, | ||
...props | ||
}: { | ||
role: 'community' | 'council' | ||
className?: string | ||
}) { | ||
const { connection } = useConnection() | ||
|
||
const realmPk = useSelectedRealmPubkey() | ||
|
||
const wallet = useWalletOnePointOh() | ||
const connected = !!wallet?.connected | ||
|
||
const { result: kind } = useAsync(async () => { | ||
if (realmPk === undefined) return undefined | ||
|
||
return determineVotingPowerType(connection, realmPk, role) | ||
}, [connection, realmPk, role]) | ||
|
||
if (connected && kind === undefined) { | ||
return ( | ||
<div className="animate-pulse bg-bkg-1 col-span-1 h-[76px] rounded-lg" /> | ||
) | ||
} | ||
|
||
return ( | ||
<div className={classNames(props.className)}> | ||
{role === 'community' ? ( | ||
kind === 'vanilla' ? ( | ||
<VanillaVotingPower role="community" /> | ||
) : kind === 'VSR' ? ( | ||
<LockedCommunityVotingPower /> | ||
) : kind === 'NFT' ? ( | ||
<NftVotingPower /> | ||
) : kind === 'HeliumVSR' ? ( | ||
<LockedCommunityNFTRecordVotingPower /> | ||
) : null | ||
) : kind === 'vanilla' ? ( | ||
<VanillaVotingPower role="council" /> | ||
) : null} | ||
</div> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
import { BigNumber } from 'bignumber.js' | ||
import { SecondaryButton } from '@components/Button' | ||
import useWalletOnePointOh from '@hooks/useWalletOnePointOh' | ||
import { useRealmQuery } from '@hooks/queries/realm' | ||
import { useConnection } from '@solana/wallet-adapter-react' | ||
import { useAsync } from 'react-async-hook' | ||
import { | ||
ASSOCIATED_TOKEN_PROGRAM_ID, | ||
Token, | ||
TOKEN_PROGRAM_ID, | ||
} from '@solana/spl-token' | ||
import BN from 'bn.js' | ||
import { fetchMintInfoByPubkey } from '@hooks/queries/mintInfo' | ||
import { fetchTokenAccountByPubkey } from '@hooks/queries/tokenAccount' | ||
import { useDepositCallback } from './useDepositCallback' | ||
import { getMintMetadata } from '@components/instructions/programs/splToken' | ||
|
||
export const Deposit = ({ role }: { role: 'community' | 'council' }) => { | ||
const realm = useRealmQuery().data?.result | ||
const wallet = useWalletOnePointOh() | ||
const walletPk = wallet?.publicKey ?? undefined | ||
|
||
const { connection } = useConnection() | ||
|
||
const { result } = useAsync(async () => { | ||
if (realm === undefined || walletPk === undefined) return undefined | ||
const mint = | ||
role === 'community' | ||
? realm.account.communityMint | ||
: realm.account.config.councilMint | ||
if (mint === undefined) return undefined | ||
|
||
const userAtaPk = await Token.getAssociatedTokenAddress( | ||
ASSOCIATED_TOKEN_PROGRAM_ID, // always ASSOCIATED_TOKEN_PROGRAM_ID | ||
TOKEN_PROGRAM_ID, // always TOKEN_PROGRAM_ID | ||
mint, // mint | ||
walletPk // owner | ||
) | ||
|
||
const { result: userAta } = await fetchTokenAccountByPubkey( | ||
connection, | ||
userAtaPk | ||
) | ||
const { result: mintInfo } = await fetchMintInfoByPubkey(connection, mint) | ||
return { mint, userAta, mintInfo } as const | ||
}, [connection, realm, role, walletPk]) | ||
|
||
const depositAmount = result?.userAta?.amount | ||
? new BigNumber(result.userAta.amount.toString()) | ||
: new BigNumber(0) | ||
|
||
const tokenName = | ||
getMintMetadata(result?.mint)?.name ?? realm?.account.name ?? '' | ||
|
||
const deposit = useDepositCallback(role) | ||
|
||
return !depositAmount.isGreaterThan(0) ? null : ( | ||
<> | ||
<div className="mt-3 text-xs text-white/50"> | ||
You have{' '} | ||
{result?.mintInfo | ||
? depositAmount.shiftedBy(-result.mintInfo.decimals).toFormat() | ||
: depositAmount.toFormat()}{' '} | ||
more {tokenName} votes in your wallet. Do you want to deposit them to | ||
increase your voting power in this Dao? | ||
</div> | ||
<SecondaryButton | ||
className="mt-4 w-48" | ||
onClick={() => deposit(new BN(depositAmount.toString()))} | ||
> | ||
Deposit | ||
</SecondaryButton> | ||
</> | ||
) | ||
} |
Oops, something went wrong.