diff --git a/NftVotePlugin/NftProposalVoteState.tsx b/NftVotePlugin/NftProposalVoteState.tsx index 4043c3e39a..65c849c7bc 100644 --- a/NftVotePlugin/NftProposalVoteState.tsx +++ b/NftVotePlugin/NftProposalVoteState.tsx @@ -4,9 +4,10 @@ import { ProgramAccount, Proposal, ProposalState } from '@solana/spl-governance' import { useEffect } from 'react' import useVotePluginsClientStore from 'stores/useVotePluginsClientStore' import useNftProposalStore from './NftProposalStore' -import useNftPluginStore from './store/nftPluginStore' import { useRealmConfigQuery } from '@hooks/queries/realmConfig' import { useProposalVoteRecordQuery } from '@hooks/queries/voteRecord' +import { useGovernancePowerAsync } from '@hooks/queries/governancePower' +import { useVotingPop } from '@components/VotePanel/hooks' const NftProposalVoteState = ({ proposal, @@ -19,7 +20,8 @@ const NftProposalVoteState = ({ const getCountedNfts = useNftProposalStore((s) => s.getCountedNfts) const countedNfts = useNftProposalStore((s) => s.countedNftsForProposal) const wallet = useWalletOnePointOh() - const votingPower = useNftPluginStore((s) => s.state.votingPower) + const votingPop = useVotingPop() + const { result: votingPower } = useGovernancePowerAsync(votingPop) const isNftPlugin = config?.account.communityTokenConfig.voterWeightAddin && NFT_PLUGINS_PKS.includes( @@ -29,6 +31,7 @@ const NftProposalVoteState = ({ const ownVoteRecord = useProposalVoteRecordQuery('electoral').data?.result const showVoteRecords = + votingPower && countedNfts.length > 0 && countedNfts.length < votingPower.toNumber() && !ownVoteRecord diff --git a/NftVotePlugin/store/nftPluginStore.ts b/NftVotePlugin/store/nftPluginStore.ts index 4a78f841be..0332cfe8b9 100644 --- a/NftVotePlugin/store/nftPluginStore.ts +++ b/NftVotePlugin/store/nftPluginStore.ts @@ -1,14 +1,11 @@ -import { BN } from '@coral-xyz/anchor' import { MaxVoterWeightRecord, ProgramAccount } from '@solana/spl-governance' import { VotingClient } from '@utils/uiTypes/VotePlugin' import { DasNftObject } from '@hooks/queries/digitalAssets' import create, { State } from 'zustand' -import { ON_NFT_VOTER_V2 } from '@constants/flags' interface nftPluginStore extends State { state: { votingNfts: DasNftObject[] - votingPower: BN maxVoteRecord: ProgramAccount | null isLoadingNfts: boolean } @@ -17,7 +14,6 @@ interface nftPluginStore extends State { votingClient: VotingClient, nftMintRegistrar: any ) => void - setVotingPower: (nfts: DasNftObject[], nftMintRegistrar: any) => void setMaxVoterWeight: ( maxVoterRecord: ProgramAccount | null ) => void @@ -26,11 +22,14 @@ interface nftPluginStore extends State { const defaultState = { votingNfts: [], - votingPower: new BN(0), maxVoteRecord: null, isLoadingNfts: false, } +/** + * @deprecated + * instead of using this, query directly whatever it is you wanna query. we can make a query for getting voting NFTs. + */ const useNftPluginStore = create((set, _get) => ({ state: { ...defaultState, @@ -40,27 +39,13 @@ const useNftPluginStore = create((set, _get) => ({ s.state.isLoadingNfts = val }) }, - setVotingNfts: (nfts, votingClient, nftMintRegistrar) => { + setVotingNfts: (nfts, votingClient, _nftMintRegistrar) => { votingClient._setCurrentVoterNfts(nfts) set((s) => { s.state.votingNfts = nfts }) - _get().setVotingPower(nfts, nftMintRegistrar) - }, - setVotingPower: (nfts, nftMintRegistrar) => { - const votingPower = nfts - .filter((x) => ON_NFT_VOTER_V2 || !x.compression.compressed) - .map( - (x) => - nftMintRegistrar?.collectionConfigs?.find( - (j) => j.collection?.toBase58() === x.grouping[0].group_value - )?.weight || new BN(0) - ) - .reduce((prev, next) => prev.add(next), new BN(0)) - set((s) => { - s.state.votingPower = votingPower - }) }, + setMaxVoterWeight: (maxVoterRecord) => { set((s) => { s.state.maxVoteRecord = maxVoterRecord diff --git a/Strategies/components/psyfi/Deposit.tsx b/Strategies/components/psyfi/Deposit.tsx index 0273f5df06..08f3338e02 100644 --- a/Strategies/components/psyfi/Deposit.tsx +++ b/Strategies/components/psyfi/Deposit.tsx @@ -44,6 +44,7 @@ import { useRealmCouncilMintInfoQuery, } from '@hooks/queries/mintInfo' import useLegacyConnectionContext from '@hooks/useLegacyConnectionContext' +import { useLegacyVoterWeight } from '@hooks/queries/governancePower' const SOL_BUFFER = 0.02 @@ -65,7 +66,9 @@ export const Deposit: React.FC<{ const { symbol } = router.query const mint = useRealmCommunityMintInfoQuery().data?.result const councilMint = useRealmCouncilMintInfoQuery().data?.result - const { realmInfo, ownVoterWeight } = useRealm() + const { result: ownVoterWeight } = useLegacyVoterWeight() + + const { realmInfo } = useRealm() const { canUseTransferInstruction, governedTokenAccountsWithoutNfts, @@ -210,7 +213,7 @@ export const Deposit: React.FC<{ connection.current, connection.endpoint ) - const ownTokenRecord = ownVoterWeight.getTokenRecordToCreateProposal( + const ownTokenRecord = ownVoterWeight!.getTokenRecordToCreateProposal( governedTokenAccount!.governance!.account.config, voteByCouncil ) diff --git a/Strategies/components/solend/SolendDeposit.tsx b/Strategies/components/solend/SolendDeposit.tsx index ca9cb9be0d..f9edc05517 100644 --- a/Strategies/components/solend/SolendDeposit.tsx +++ b/Strategies/components/solend/SolendDeposit.tsx @@ -41,6 +41,7 @@ import { } from '@hooks/queries/mintInfo' import useLegacyConnectionContext from '@hooks/useLegacyConnectionContext' import { useRealmProposalsQuery } from '@hooks/queries/proposal' +import { useLegacyVoterWeight } from '@hooks/queries/governancePower' const SOL_BUFFER = 0.02 @@ -62,7 +63,8 @@ const SolendDeposit = ({ const config = useRealmConfigQuery().data?.result const mint = useRealmCommunityMintInfoQuery().data?.result const councilMint = useRealmCouncilMintInfoQuery().data?.result - const { realmInfo, ownVoterWeight } = useRealm() + const { result: ownVoterWeight } = useLegacyVoterWeight() + const { realmInfo } = useRealm() const proposals = useRealmProposalsQuery().data const [isDepositing, setIsDepositing] = useState(false) const [deposits, setDeposits] = useState<{ @@ -200,6 +202,7 @@ const SolendDeposit = ({ }, []) const handleDeposit = async () => { + if (ownVoterWeight === undefined) throw new Error() if (proposals === undefined) throw new Error() const isValid = await validateInstruction({ schema, form, setFormErrors }) if (!isValid) { diff --git a/Strategies/components/solend/SolendWithdraw.tsx b/Strategies/components/solend/SolendWithdraw.tsx index 5eb9e712a0..79afbfe3f1 100644 --- a/Strategies/components/solend/SolendWithdraw.tsx +++ b/Strategies/components/solend/SolendWithdraw.tsx @@ -40,6 +40,7 @@ import { } from '@hooks/queries/mintInfo' import useLegacyConnectionContext from '@hooks/useLegacyConnectionContext' import { useRealmProposalsQuery } from '@hooks/queries/proposal' +import { useLegacyVoterWeight } from '@hooks/queries/governancePower' const SolendWithdraw = ({ proposedInvestment, @@ -64,7 +65,8 @@ const SolendWithdraw = ({ const config = useRealmConfigQuery().data?.result const mint = useRealmCommunityMintInfoQuery().data?.result const councilMint = useRealmCouncilMintInfoQuery().data?.result - const { realmInfo, ownVoterWeight } = useRealm() + const { result: ownVoterWeight } = useLegacyVoterWeight() + const { realmInfo } = useRealm() const [isWithdrawing, setIsWithdrawing] = useState(false) const [voteByCouncil, setVoteByCouncil] = useState(false) const [deposits, setDeposits] = useState<{ @@ -199,6 +201,7 @@ const SolendWithdraw = ({ } const handleWithdraw = async () => { + if (ownVoterWeight === undefined) throw new Error() if (proposals === undefined) throw new Error() const isValid = await validateInstruction({ schema, form, setFormErrors }) if (!isValid) { diff --git a/components/AssetsList/AssetsCompactWrapper.tsx b/components/AssetsList/AssetsCompactWrapper.tsx index 530c8df2f2..edfa113512 100644 --- a/components/AssetsList/AssetsCompactWrapper.tsx +++ b/components/AssetsList/AssetsCompactWrapper.tsx @@ -1,4 +1,3 @@ -import React from 'react' import AssetsList from './AssetsList' import { ChevronRightIcon } from '@heroicons/react/solid' import useRealm from '@hooks/useRealm' @@ -17,21 +16,23 @@ import useGovernanceAssetsStore from 'stores/useGovernanceAssetsStore' import Loading from '@components/Loading' import useWalletOnePointOh from '@hooks/useWalletOnePointOh' import { useRealmQuery } from '@hooks/queries/realm' +import { useLegacyVoterWeight } from '@hooks/queries/governancePower' const AssetsCompactWrapper = () => { const router = useRouter() const { fmtUrlWithCluster } = useQueryContext() const realm = useRealmQuery().data?.result + const { result: ownVoterWeight } = useLegacyVoterWeight() const { symbol, - ownVoterWeight, + toManyCommunityOutstandingProposalsForUser, toManyCouncilOutstandingProposalsForUse, } = useRealm() const wallet = useWalletOnePointOh() const connected = !!wallet?.connected const canCreateGovernance = realm - ? ownVoterWeight.canCreateGovernance(realm) + ? ownVoterWeight?.canCreateGovernance(realm) : null const newAssetToolTip = renderAddNewAssetTooltip( diff --git a/components/AssetsList/NewProgramForm.tsx b/components/AssetsList/NewProgramForm.tsx index 96e0c7ac12..cd018639b1 100644 --- a/components/AssetsList/NewProgramForm.tsx +++ b/components/AssetsList/NewProgramForm.tsx @@ -4,7 +4,6 @@ import Input from 'components/inputs/Input' import PreviousRouteBtn from 'components/PreviousRouteBtn' import Tooltip from 'components/Tooltip' import useQueryContext from 'hooks/useQueryContext' -import useRealm from 'hooks/useRealm' import { Keypair, PublicKey, Transaction } from '@solana/web3.js' import { tryParseKey } from 'tools/validators/pubkey' import { isFormValid } from 'utils/formValidation' @@ -40,7 +39,6 @@ const NewProgramForm = () => { const realm = useRealmQuery().data?.result const realmMint = useRealmCommunityMintInfoQuery().data?.result const { symbol } = router.query - const { ownVoterWeight } = useRealm() const { assetAccounts } = useGovernanceAssetsStore() const wallet = useWalletOnePointOh() @@ -52,11 +50,6 @@ const NewProgramForm = () => { const prevFormProgramId = usePrevious(form.programId) const [isLoading, setIsLoading] = useState(false) const [formErrors, setFormErrors] = useState({}) - const tokenOwnerRecord = ownVoterWeight.canCreateGovernanceUsingCouncilTokens() - ? ownVoterWeight.councilTokenRecord - : realm && ownVoterWeight.canCreateGovernanceUsingCommunityTokens(realm) - ? ownVoterWeight.communityTokenRecord - : undefined const handleSetForm = useCallback(({ propertyName, value }) => { setFormErrors({}) @@ -70,9 +63,7 @@ const NewProgramForm = () => { if (!connected) { throw 'Please connect your wallet' } - if (!tokenOwnerRecord) { - throw "You don't have enough governance power to create a new program governance" - } + const { isValid, validationErrors } = await isFormValid(schema, form) setFormErrors(validationErrors) if (isValid && realmMint) { diff --git a/components/MultiChoiceForm.tsx b/components/MultiChoiceForm.tsx index 5595b03874..b1b605f845 100644 --- a/components/MultiChoiceForm.tsx +++ b/components/MultiChoiceForm.tsx @@ -1,160 +1,175 @@ -import { AddAlt } from "@carbon/icons-react"; -import { LinkButton } from "@components/Button"; -import { StyledLabel } from "@components/inputs/styles"; -import { XCircleIcon } from "@heroicons/react/solid"; -import useGovernanceAssets from "@hooks/useGovernanceAssets"; -import useRealm from "@hooks/useRealm"; -import Input from '@components/inputs/Input'; -import GovernedAccountSelect from "../pages/dao/[symbol]/proposal/components/GovernedAccountSelect"; -import { PublicKey } from "@solana/web3.js"; -import { AccountType, AssetAccount } from "@utils/uiTypes/assets"; +import { AddAlt } from '@carbon/icons-react' +import { LinkButton } from '@components/Button' +import { StyledLabel } from '@components/inputs/styles' +import { XCircleIcon } from '@heroicons/react/solid' +import useGovernanceAssets from '@hooks/useGovernanceAssets' +import Input from '@components/inputs/Input' +import GovernedAccountSelect from '../pages/dao/[symbol]/proposal/components/GovernedAccountSelect' +import { PublicKey } from '@solana/web3.js' +import { AccountType, AssetAccount } from '@utils/uiTypes/assets' +import { useLegacyVoterWeight } from '@hooks/queries/governancePower' const MultiChoiceForm = ({ - multiChoiceForm, - updateMultiChoiceForm, - isMultiFormValidated, - multiFormErrors, - updateMultiFormErrors -} : { - multiChoiceForm: { - governance: PublicKey | undefined - options: string[] - } - updateMultiChoiceForm: any - isMultiFormValidated: boolean - multiFormErrors: any - updateMultiFormErrors: any + multiChoiceForm, + updateMultiChoiceForm, + isMultiFormValidated, + multiFormErrors, + updateMultiFormErrors, +}: { + multiChoiceForm: { + governance: PublicKey | undefined + options: string[] + } + updateMultiChoiceForm: any + isMultiFormValidated: boolean + multiFormErrors: any + updateMultiFormErrors: any }) => { - const {ownVoterWeight} = useRealm() - const { assetAccounts } = useGovernanceAssets() - const nota = "$$_NOTA_$$"; - const lastOptIndex = multiChoiceForm.options.length - 1; - const governance = multiChoiceForm.governance; - const hideNotaButton = multiChoiceForm.options[lastOptIndex] === nota; + const { result: ownVoterWeight } = useLegacyVoterWeight() + const { assetAccounts } = useGovernanceAssets() + const nota = '$$_NOTA_$$' + const lastOptIndex = multiChoiceForm.options.length - 1 + const governance = multiChoiceForm.governance + const hideNotaButton = multiChoiceForm.options[lastOptIndex] === nota - const handleMultiForm = ({ propertyName, value }) => { - updateMultiFormErrors({}) - updateMultiChoiceForm({ ...multiChoiceForm, [propertyName]: value }) - } - - const handleNotaButton = () => { - const options = [...multiChoiceForm.options]; - options.push(nota); - handleMultiForm({propertyName: "options", value: options}); - } - - const updateOption = (odx: number, value: string) => { - const updatedOptions = [...multiChoiceForm.options]; - updatedOptions[odx] = value; - handleMultiForm({value: updatedOptions, propertyName: "options"}); - } + const handleMultiForm = ({ propertyName, value }) => { + updateMultiFormErrors({}) + updateMultiChoiceForm({ ...multiChoiceForm, [propertyName]: value }) + } - const removeOption = (odx: number) => { - const updatedOptions = [...multiChoiceForm.options]; - handleMultiForm({value: updatedOptions.filter((_o, i) => i !== odx), propertyName: "options"}); - } + const handleNotaButton = () => { + const options = [...multiChoiceForm.options] + options.push(nota) + handleMultiForm({ propertyName: 'options', value: options }) + } - const addOption = () => { - const updatedOptions = [...multiChoiceForm.options]; - const len = updatedOptions.length-1; + const updateOption = (odx: number, value: string) => { + const updatedOptions = [...multiChoiceForm.options] + updatedOptions[odx] = value + handleMultiForm({ value: updatedOptions, propertyName: 'options' }) + } - if (updatedOptions.length > 9) { - return; - } - if (updatedOptions[len] === nota) { - // insert new empty option at the second last position if NOTA exists - updatedOptions.splice(len, 0, ""); - } else { - // insert new empty option at the last position if not NOTA doesn't exist - updatedOptions.push(""); - } - handleMultiForm({value: updatedOptions, propertyName: "options"}); + const removeOption = (odx: number) => { + const updatedOptions = [...multiChoiceForm.options] + handleMultiForm({ + value: updatedOptions.filter((_o, i) => i !== odx), + propertyName: 'options', + }) + } + + const addOption = () => { + const updatedOptions = [...multiChoiceForm.options] + const len = updatedOptions.length - 1 + + if (updatedOptions.length > 9) { + return } - - return ( -
- - ownVoterWeight.canCreateProposal(x.governance.account.config)) - } - onChange={(value:AssetAccount) => { - handleMultiForm({ value: value.governance.pubkey, propertyName: 'governance' }) - }} - value={ - governance ? assetAccounts.find( - x => x.governance.pubkey.equals(governance) && - x.type === AccountType.SOL - ) - : null - } - error={multiFormErrors['governance']} - shouldBeGoverned={null} - governance={null} - /> -

Add Choices

- {multiChoiceForm.options.map((option, index) => { - // copy index to keep its value for onChange function - const odx = index; + if (updatedOptions[len] === nota) { + // insert new empty option at the second last position if NOTA exists + updatedOptions.splice(len, 0, '') + } else { + // insert new empty option at the last position if not NOTA doesn't exist + updatedOptions.push('') + } + handleMultiForm({ value: updatedOptions, propertyName: 'options' }) + } + + return ( +
+ + ownVoterWeight?.canCreateProposal(x.governance.account.config) + )} + onChange={(value: AssetAccount) => { + handleMultiForm({ + value: value.governance.pubkey, + propertyName: 'governance', + }) + }} + value={ + governance + ? assetAccounts.find( + (x) => + x.governance.pubkey.equals(governance) && + x.type === AccountType.SOL + ) + : null + } + error={multiFormErrors['governance']} + shouldBeGoverned={null} + governance={null} + /> +

Add Choices

+ {multiChoiceForm.options.map((option, index) => { + // copy index to keep its value for onChange function + const odx = index - return ( -
-
-

Choice {odx + 1}

- {odx > 1 ? - removeOption(odx)} - > - - Remove - - : null} -
- Add a Label -
- This is the text voters will see when they vote. -
- updateOption(odx, event.target.value)} - disabled={option === nota && index > 1 && index === lastOptIndex} - /> -
)} - )} + return ( +
-
+

Choice {odx + 1}

+ {odx > 1 ? ( addOption()} - disabled={multiChoiceForm.options.length > 9} - className='flex flex-row items-center gap-2 font-bold pt-2' + className="flex font-bold items-center ml-4 text-fgd-1 text-sm" + onClick={() => removeOption(odx)} > - -
Add another voting choice
+ + Remove
-
-
- handleNotaButton()} - disabled={hideNotaButton || multiChoiceForm.options.length > 9} - className='flex flex-row items-center gap-2 font-bold pt-2' - > - -
Add 'None of the Above' choice
-
-
+ ) : null}
+ Add a Label +
+ This is the text voters will see when they vote.
- - ) + updateOption(odx, event.target.value)} + disabled={option === nota && index > 1 && index === lastOptIndex} + /> +
+ ) + })} +
+
+ addOption()} + disabled={multiChoiceForm.options.length > 9} + className="flex flex-row items-center gap-2 font-bold pt-2" + > + +
Add another voting choice
+
+
+
+ handleNotaButton()} + disabled={hideNotaButton || multiChoiceForm.options.length > 9} + className="flex flex-row items-center gap-2 font-bold pt-2" + > + +
Add 'None of the Above' choice
+
+
+
+
+ ) } -export default MultiChoiceForm; \ No newline at end of file +export default MultiChoiceForm diff --git a/components/ProposalVotingPower/CommunityVotingPower.tsx b/components/ProposalVotingPower/CommunityVotingPower.tsx index 5d5a5b29bc..9a896368a9 100644 --- a/components/ProposalVotingPower/CommunityVotingPower.tsx +++ b/components/ProposalVotingPower/CommunityVotingPower.tsx @@ -16,6 +16,7 @@ import { useRealmQuery } from '@hooks/queries/realm' import { useRealmCommunityMintInfoQuery } from '@hooks/queries/mintInfo' import { useRouteProposalQuery } from '@hooks/queries/proposal' import { useConnection } from '@solana/wallet-adapter-react' +import { useLegacyVoterWeight } from '@hooks/queries/governancePower' interface Props { className?: string @@ -25,8 +26,8 @@ export default function CommunityVotingPower(props: Props) { const ownTokenRecord = useUserCommunityTokenOwnerRecord().data?.result const realm = useRealmQuery().data?.result const mint = useRealmCommunityMintInfoQuery().data?.result - - const { ownVoterWeight, realmInfo, realmTokenAccount } = useRealm() + const { result: ownVoterWeight } = useLegacyVoterWeight() + const { realmInfo, realmTokenAccount } = useRealm() const proposal = useRouteProposalQuery().data?.result const { connection } = useConnection() const wallet = useWalletOnePointOh() @@ -40,7 +41,9 @@ export default function CommunityVotingPower(props: Props) { const tokenName = getMintMetadata(depositMint)?.name ?? realm?.account.name ?? '' - const amount = getNumTokens(ownVoterWeight, ownTokenRecord, mint, realmInfo) + const amount = ownVoterWeight + ? getNumTokens(ownVoterWeight, ownTokenRecord, mint, realmInfo) + : new BigNumber(0) const max = realm && proposal && mint ? new BigNumber( diff --git a/components/ProposalVotingPower/CouncilVotingPower.tsx b/components/ProposalVotingPower/CouncilVotingPower.tsx index 66dde361b1..fec74cbf0c 100644 --- a/components/ProposalVotingPower/CouncilVotingPower.tsx +++ b/components/ProposalVotingPower/CouncilVotingPower.tsx @@ -16,6 +16,7 @@ import { useRealmQuery } from '@hooks/queries/realm' import { useRealmCouncilMintInfoQuery } from '@hooks/queries/mintInfo' import { useRouteProposalQuery } from '@hooks/queries/proposal' import { useConnection } from '@solana/wallet-adapter-react' +import { useLegacyVoterWeight } from '@hooks/queries/governancePower' interface Props { className?: string @@ -25,8 +26,8 @@ export default function CouncilVotingPower(props: Props) { const ownCouncilTokenRecord = useUserCouncilTokenOwnerRecord().data?.result const realm = useRealmQuery().data?.result const councilMint = useRealmCouncilMintInfoQuery().data?.result - - const { councilTokenAccount, ownVoterWeight, realmInfo } = useRealm() + const { result: ownVoterWeight } = useLegacyVoterWeight() + const { councilTokenAccount, realmInfo } = useRealm() const proposal = useRouteProposalQuery().data?.result const { connection } = useConnection() const wallet = useWalletOnePointOh() @@ -42,12 +43,14 @@ export default function CouncilVotingPower(props: Props) { const tokenName = getMintMetadata(depositMint)?.name ?? realm?.account.name ?? '' - const amount = getNumTokens( - ownVoterWeight, - ownCouncilTokenRecord, - councilMint, - realmInfo - ) + const amount = ownVoterWeight + ? getNumTokens( + ownVoterWeight, + ownCouncilTokenRecord, + councilMint, + realmInfo + ) + : new BigNumber(0) const max = realm && proposal && councilMint diff --git a/components/ProposalVotingPower/NftVotingPower.tsx b/components/ProposalVotingPower/NftVotingPower.tsx index 810b3ca353..07ca792403 100644 --- a/components/ProposalVotingPower/NftVotingPower.tsx +++ b/components/ProposalVotingPower/NftVotingPower.tsx @@ -20,6 +20,7 @@ import useWalletOnePointOh from '@hooks/useWalletOnePointOh' import { useUserCommunityTokenOwnerRecord } from '@hooks/queries/tokenOwnerRecord' import { useRealmQuery } from '@hooks/queries/realm' import useLegacyConnectionContext from '@hooks/useLegacyConnectionContext' +import { useGovernancePowerAsync } from '@hooks/queries/governancePower' interface Props { className?: string @@ -29,7 +30,7 @@ interface Props { export default function NftVotingPower(props: Props) { const nfts = useNftPluginStore((s) => s.state.votingNfts) - const votingPower = useNftPluginStore((s) => s.state.votingPower) + const { result: votingPower } = useGovernancePowerAsync('community') const maxWeight = useNftPluginStore((s) => s.state.maxVoteRecord) const isLoading = useNftPluginStore((s) => s.state.isLoadingNfts) const wallet = useWalletOnePointOh() @@ -47,7 +48,7 @@ export default function NftVotingPower(props: Props) { const max = maxWeight ? new BigNumber(maxWeight.account.maxVoterWeight.toString()) : null - const amount = new BigNumber(votingPower.toString()) + const amount = new BigNumber((votingPower ?? 0).toString()) const handleRegister = async () => { if (!realm || !wallet?.publicKey || !client.client || !realmInfo) diff --git a/components/TokenBalance/TokenBalanceCard.tsx b/components/TokenBalance/TokenBalanceCard.tsx index e5f9fcd9cc..4b3ec1e38d 100644 --- a/components/TokenBalance/TokenBalanceCard.tsx +++ b/components/TokenBalance/TokenBalanceCard.tsx @@ -54,6 +54,7 @@ import { useConnection } from '@solana/wallet-adapter-react' import queryClient from '@hooks/queries/queryClient' import { proposalQueryKeys } from '@hooks/queries/proposal' import asFindable from '@utils/queries/asFindable' +import { useLegacyVoterWeight } from '@hooks/queries/governancePower' const TokenBalanceCard = ({ proposal, @@ -172,18 +173,18 @@ export const TokenDeposit = ({ const realm = useRealmQuery().data?.result const config = useRealmConfigQuery().data?.result const councilMint = useRealmCouncilMintInfoQuery().data?.result + const { result: ownVoterWeight } = useLegacyVoterWeight() const { realmInfo, realmTokenAccount, - ownVoterWeight, councilTokenAccount, toManyCommunityOutstandingProposalsForUser, toManyCouncilOutstandingProposalsForUse, } = useRealm() - const amount = - councilMint && tokenRole === GoverningTokenRole.Council + const amount = ownVoterWeight + ? councilMint && tokenRole === GoverningTokenRole.Council ? getNumTokens( ownVoterWeight, ownCouncilTokenRecord, @@ -191,6 +192,7 @@ export const TokenDeposit = ({ realmInfo ) : getNumTokens(ownVoterWeight, ownCouncilTokenRecord, mint, realmInfo) + : new BigNumber(0) const max: BigNumber | undefined = councilMint && tokenRole === GoverningTokenRole.Council diff --git a/components/VotePanel/CastVoteButtons.tsx b/components/VotePanel/CastVoteButtons.tsx index 9d51b80ded..5ade48dafb 100644 --- a/components/VotePanel/CastVoteButtons.tsx +++ b/components/VotePanel/CastVoteButtons.tsx @@ -9,19 +9,20 @@ import { useVoterTokenRecord, useVotingPop, } from './hooks' -import useRealm from '@hooks/useRealm' import { VotingClientType } from '@utils/uiTypes/VotePlugin' import useVotePluginsClientStore from 'stores/useVotePluginsClientStore' import useWalletOnePointOh from '@hooks/useWalletOnePointOh' import { useProposalVoteRecordQuery } from '@hooks/queries/voteRecord' import { useSubmitVote } from '@hooks/useSubmitVote' import { useSelectedRealmInfo } from '@hooks/selectedRealm/useSelectedRealmRegistryEntry' +import { useGovernancePowerAsync } from '@hooks/queries/governancePower' export const useCanVote = () => { const client = useVotePluginsClientStore( (s) => s.state.currentRealmVotingClient ) - const { ownVoterWeight } = useRealm() + const votingPop = useVotingPop() + const { result: govPower } = useGovernancePowerAsync(votingPop) const wallet = useWalletOnePointOh() const connected = !!wallet?.connected @@ -30,11 +31,7 @@ export const useCanVote = () => { const isVoteCast = !!ownVoteRecord?.found - const hasMinAmountToVote = - voterTokenRecord && - ownVoterWeight.hasMinAmountToVote( - voterTokenRecord.account.governingTokenMint - ) + const hasMinAmountToVote = voterTokenRecord && govPower?.gtn(0) const canVote = connected && diff --git a/components/VotePanel/VetoButtons.tsx b/components/VotePanel/VetoButtons.tsx index 0750aa2978..597f6c6683 100644 --- a/components/VotePanel/VetoButtons.tsx +++ b/components/VotePanel/VetoButtons.tsx @@ -1,7 +1,6 @@ import Button from '@components/Button' import VoteCommentModal from '@components/VoteCommentModal' import { BanIcon } from '@heroicons/react/solid' -import useRealm from '@hooks/useRealm' import useWalletOnePointOh from '@hooks/useWalletOnePointOh' import { VoteKind } from '@solana/spl-governance' import { useState } from 'react' @@ -14,6 +13,7 @@ import { import { useProposalVoteRecordQuery } from '@hooks/queries/voteRecord' import { useSubmitVote } from '@hooks/useSubmitVote' import { useSelectedRealmInfo } from '@hooks/selectedRealm/useSelectedRealmRegistryEntry' +import { useGovernancePowerAsync } from '@hooks/queries/governancePower' const useIsVetoable = (): undefined | boolean => { const vetoingPop = useVetoingPop() @@ -29,7 +29,8 @@ const useCanVeto = (): | undefined | { canVeto: true } | { canVeto: false; message: string } => { - const { ownVoterWeight } = useRealm() + const vetoPop = useVetoingPop() + const { result: govPower } = useGovernancePowerAsync(vetoPop) const wallet = useWalletOnePointOh() const connected = !!wallet?.connected const isVetoable = useIsVetoable() @@ -52,11 +53,7 @@ const useCanVeto = (): return { canVeto: false, message: 'You already voted' } // Do you have any voting power? - const hasMinAmountToVote = - voterTokenRecord && - ownVoterWeight.hasMinAmountToVote( - voterTokenRecord.account.governingTokenMint - ) + const hasMinAmountToVote = voterTokenRecord && govPower?.gtn(0) if (hasMinAmountToVote === undefined) return undefined if (hasMinAmountToVote === false) return { diff --git a/components/VotePanel/hooks.ts b/components/VotePanel/hooks.ts index 6b16a9efd8..dd6a39a1be 100644 --- a/components/VotePanel/hooks.ts +++ b/components/VotePanel/hooks.ts @@ -89,11 +89,14 @@ export const useVetoingPop = () => { return tokenRole === 'community' ? governance?.account.config.councilVetoVoteThreshold.type !== VoteThresholdType.Disabled && - // if there is no council then there's not actually a vetoing population, in my opinion - realm?.account.config.councilMint !== undefined && - 'council' + // if there is no council then there's not actually a vetoing population, in my opinion + realm?.account.config.councilMint !== undefined + ? 'council' + : undefined : governance?.account.config.communityVetoVoteThreshold.type !== - VoteThresholdType.Disabled && 'community' + VoteThresholdType.Disabled + ? 'community' + : undefined }, [governance, tokenRole, realm?.account.config.councilMint]) return vetoingPop diff --git a/components/chat/DiscussionForm.tsx b/components/chat/DiscussionForm.tsx index 2f4846907c..72ec6830d3 100644 --- a/components/chat/DiscussionForm.tsx +++ b/components/chat/DiscussionForm.tsx @@ -18,13 +18,15 @@ import { useRealmQuery } from '@hooks/queries/realm' import { useRouteProposalQuery } from '@hooks/queries/proposal' import { useVotingPop } from '@components/VotePanel/hooks' import useLegacyConnectionContext from '@hooks/useLegacyConnectionContext' +import { useLegacyVoterWeight } from '@hooks/queries/governancePower' const DiscussionForm = () => { const [comment, setComment] = useState('') const ownTokenRecord = useUserCommunityTokenOwnerRecord().data?.result const ownCouncilTokenRecord = useUserCouncilTokenOwnerRecord().data?.result const realm = useRealmQuery().data?.result - const { ownVoterWeight, realmInfo } = useRealm() + const { result: ownVoterWeight } = useLegacyVoterWeight() + const { realmInfo } = useRealm() const client = useVotePluginsClientStore( (s) => s.state.currentRealmVotingClient ) @@ -83,11 +85,11 @@ const DiscussionForm = () => { } const postEnabled = - proposal && connected && ownVoterWeight.hasAnyWeight() && comment + proposal && connected && ownVoterWeight?.hasAnyWeight() && comment const tooltipContent = !connected ? 'Connect your wallet to send a comment' - : !ownVoterWeight.hasAnyWeight() + : !ownVoterWeight?.hasAnyWeight() ? 'You need to have deposited some tokens to submit your comment.' : !comment ? 'Write a comment to submit' diff --git a/components/treasuryV2/Details/DomainsDetails/Info/Domain.tsx b/components/treasuryV2/Details/DomainsDetails/Info/Domain.tsx index 0aaed72c52..05a8b5afee 100644 --- a/components/treasuryV2/Details/DomainsDetails/Info/Domain.tsx +++ b/components/treasuryV2/Details/DomainsDetails/Info/Domain.tsx @@ -15,6 +15,7 @@ import { Domain as DomainModel } from '@models/treasury/Domain' import useWalletOnePointOh from '@hooks/useWalletOnePointOh' import { useRealmQuery } from '@hooks/queries/realm' import { useRealmGovernancesQuery } from '@hooks/queries/governance' +import { useLegacyVoterWeight } from '@hooks/queries/governancePower' interface Props { domain: DomainModel @@ -26,9 +27,10 @@ const Domain: React.FC = (props) => { const connected = !!wallet?.connected const realm = useRealmQuery().data?.result const governanceItems = useRealmGovernancesQuery().data + const { result: ownVoterWeight } = useLegacyVoterWeight() + const { symbol, - ownVoterWeight, toManyCommunityOutstandingProposalsForUser, toManyCouncilOutstandingProposalsForUse, } = useRealm() @@ -36,7 +38,7 @@ const Domain: React.FC = (props) => { const canCreateProposal = realm && governanceItems?.some((g) => - ownVoterWeight.canCreateProposal(g.account.config) + ownVoterWeight?.canCreateProposal(g.account.config) ) && !toManyCommunityOutstandingProposalsForUser && !toManyCouncilOutstandingProposalsForUse @@ -46,7 +48,7 @@ const Domain: React.FC = (props) => { : governanceItems?.length === 0 ? 'There is no governance configuration to create a new proposal' : !governanceItems?.some((g) => - ownVoterWeight.canCreateProposal(g.account.config) + ownVoterWeight?.canCreateProposal(g.account.config) ) ? "You don't have enough governance power to create a new proposal" : toManyCommunityOutstandingProposalsForUser diff --git a/components/treasuryV2/Details/WalletDetails/AddAssetModal/index.tsx b/components/treasuryV2/Details/WalletDetails/AddAssetModal/index.tsx index dda44c7216..c5fa04ff0f 100644 --- a/components/treasuryV2/Details/WalletDetails/AddAssetModal/index.tsx +++ b/components/treasuryV2/Details/WalletDetails/AddAssetModal/index.tsx @@ -1,4 +1,3 @@ -import React from 'react' import cx from 'classnames' import { Wallet } from '@models/treasury/Wallet' @@ -9,6 +8,7 @@ import WalletQRCode from '@components/WalletQRCode' import Address from '@components/Address' import useWalletOnePointOh from '@hooks/useWalletOnePointOh' import { useRealmQuery } from '@hooks/queries/realm' +import { useLegacyVoterWeight } from '@hooks/queries/governancePower' interface TokenAccount { iconUrl?: string @@ -45,13 +45,15 @@ interface Props { export default function AddAssetModal(props: Props) { const realm = useRealmQuery().data?.result - const { ownVoterWeight, realmInfo } = useRealm() + const { result: ownVoterWeight } = useLegacyVoterWeight() + + const { realmInfo } = useRealm() const wallet = useWalletOnePointOh() const connected = !!wallet?.connected - const tokenOwnerRecord = ownVoterWeight.canCreateGovernanceUsingCouncilTokens() + const tokenOwnerRecord = ownVoterWeight?.canCreateGovernanceUsingCouncilTokens() ? ownVoterWeight.councilTokenRecord - : realm && ownVoterWeight.canCreateGovernanceUsingCommunityTokens(realm) + : realm && ownVoterWeight?.canCreateGovernanceUsingCommunityTokens(realm) ? ownVoterWeight.communityTokenRecord : undefined diff --git a/components/treasuryV2/Details/WalletDetails/Info/Rules/index.tsx b/components/treasuryV2/Details/WalletDetails/Info/Rules/index.tsx index 13ac95c792..b368de4132 100644 --- a/components/treasuryV2/Details/WalletDetails/Info/Rules/index.tsx +++ b/components/treasuryV2/Details/WalletDetails/Info/Rules/index.tsx @@ -10,12 +10,10 @@ import { } from '@heroicons/react/outline' import { VoteThresholdType, VoteTipping } from '@solana/spl-governance' import cx from 'classnames' -import React from 'react' import { useRouter } from 'next/router' import { ntext } from '@utils/ntext' import { Wallet } from '@models/treasury/Wallet' -import useRealm from '@hooks/useRealm' import Tooltip from '@components/Tooltip' import { DISABLED_VOTER_WEIGHT } from '@tools/constants' import Address from '@components/Address' @@ -30,6 +28,7 @@ import { useRealmCommunityMintInfoQuery, useRealmCouncilMintInfoQuery, } from '@hooks/queries/mintInfo' +import { useLegacyVoterWeight } from '@hooks/queries/governancePower' const UNIX_SECOND = 1 const UNIX_MINUTE = UNIX_SECOND * 60 @@ -90,7 +89,7 @@ interface Props { export default function Rules(props: Props) { const mint = useRealmCommunityMintInfoQuery().data?.result const councilMint = useRealmCouncilMintInfoQuery().data?.result - const { ownVoterWeight } = useRealm() + const { result: ownVoterWeight } = useLegacyVoterWeight() const router = useRouter() const { symbol } = router.query const { fmtUrlWithCluster } = useQueryContext() diff --git a/components/treasuryV2/WalletList/NewWalletButton.tsx b/components/treasuryV2/WalletList/NewWalletButton.tsx index 34b95ddec4..5981f2caf6 100644 --- a/components/treasuryV2/WalletList/NewWalletButton.tsx +++ b/components/treasuryV2/WalletList/NewWalletButton.tsx @@ -6,6 +6,7 @@ import { LinkButton } from '@components/Button' import useQueryContext from '@hooks/useQueryContext' import useWalletOnePointOh from '@hooks/useWalletOnePointOh' import { useRealmQuery } from '@hooks/queries/realm' +import { useGovernancePowerAsync } from '@hooks/queries/governancePower' const NEW_TREASURY_ROUTE = `/treasury/new` @@ -13,8 +14,11 @@ export default function NewWalletButton() { const wallet = useWalletOnePointOh() const connected = !!wallet?.connected const realm = useRealmQuery().data?.result + + const { result: councilGovPower } = useGovernancePowerAsync('council') + const { result: communityGovPower } = useGovernancePowerAsync('community') + const { - ownVoterWeight, symbol, toManyCommunityOutstandingProposalsForUser, toManyCouncilOutstandingProposalsForUse, @@ -22,9 +26,12 @@ export default function NewWalletButton() { const router = useRouter() const { fmtUrlWithCluster } = useQueryContext() - const canCreateGovernance = !!(realm - ? ownVoterWeight.canCreateGovernance(realm) - : null) + const canCreateGovernance = + councilGovPower?.gtn(0) || + (realm && + communityGovPower?.gt( + realm.account.config.minCommunityTokensToCreateGovernance + )) const addNewAssetTooltip = !connected ? 'Connect your wallet to create new asset' diff --git a/hooks/queries/digitalAssets.ts b/hooks/queries/digitalAssets.ts index 932876d77d..147283d936 100644 --- a/hooks/queries/digitalAssets.ts +++ b/hooks/queries/digitalAssets.ts @@ -234,7 +234,7 @@ const dasByOwnerQueryFn = async (network: Network, owner: PublicKey) => { }), }) const { result } = await response.json() - return result.items as any[] + return result.items as DasNftObject[] } export const fetchDigitalAssetsByOwner = (network: Network, owner: PublicKey) => diff --git a/hooks/queries/governancePower.ts b/hooks/queries/governancePower.ts new file mode 100644 index 0000000000..307d6f44a1 --- /dev/null +++ b/hooks/queries/governancePower.ts @@ -0,0 +1,235 @@ +import { Connection, PublicKey } from '@solana/web3.js' +import { + fetchTokenOwnerRecordByPubkey, + useUserCommunityTokenOwnerRecord, + useUserCouncilTokenOwnerRecord, +} from './tokenOwnerRecord' +import BN from 'bn.js' +import { fetchNftRegistrar } from './plugins/nftVoter' +import { fetchDigitalAssetsByOwner } from './digitalAssets' +import { getNetworkFromEndpoint } from '@utils/connection' +import { ON_NFT_VOTER_V2 } from '@constants/flags' +import { fetchRealmByPubkey, useRealmQuery } from './realm' +import { fetchRealmConfigQuery } from './realmConfig' +import { + GATEWAY_PLUGINS_PKS, + HELIUM_VSR_PLUGINS_PKS, + NFT_PLUGINS_PKS, + VSR_PLUGIN_PKS, +} from '@constants/plugins' +import useDepositStore from 'VoteStakeRegistry/stores/useDepositStore' +import useHeliumVsrStore from 'HeliumVotePlugin/hooks/useHeliumVsrStore' +import useGatewayPluginStore from 'GatewayPlugin/store/gatewayPluginStore' +import { useAsync } from 'react-async-hook' +import { useConnection } from '@solana/wallet-adapter-react' +import useSelectedRealmPubkey from '@hooks/selectedRealm/useSelectedRealmPubkey' +import { + useAddressQuery_CommunityTokenOwner, + useAddressQuery_CouncilTokenOwner, +} from './addresses/tokenOwnerRecord' +import { + SimpleGatedVoterWeight, + VoteNftWeight, + VoteRegistryVoterWeight, + VoterWeight, +} from '@models/voteWeights' + +export const getVanillaGovpower = async ( + connection: Connection, + tokenOwnerRecord: PublicKey +) => { + const torAccount = await fetchTokenOwnerRecordByPubkey( + connection, + tokenOwnerRecord + ) + return torAccount.result + ? torAccount.result.account.governingTokenDepositAmount + : new BN(0) +} + +export const getNftGovpower = async ( + connection: Connection, + realmPk: PublicKey, + tokenOwnerRecordPk: PublicKey +) => { + // figure out what collections are used + const { result: registrar } = await fetchNftRegistrar(connection, realmPk) + if (registrar === undefined) throw new Error() + const { collectionConfigs } = registrar + + // grab the owner of the TOR + const { result: TOR } = await fetchTokenOwnerRecordByPubkey( + connection, + tokenOwnerRecordPk + ) + if (TOR === undefined) throw new Error() + const owner = TOR.account.governingTokenOwner + + // grab the user nfts + const network = getNetworkFromEndpoint(connection.rpcEndpoint) + if (network === 'localnet') throw new Error() + const nfts = (await fetchDigitalAssetsByOwner(network, owner)) + // filter cnfts if not supported yet + .filter((nft) => ON_NFT_VOTER_V2 || !nft.compression.compressed) + + // map nfts to power and sum them + const power = nfts + .map( + (nft) => + // find collectionConfig such that the nft's `collection` grouping matches the collection id + collectionConfigs.find( + (x) => + x.collection.equals( + new PublicKey( + nft.grouping.find((y) => y.group_key === 'collection') + ?.group_value ?? 'dummy value hehehe' + ) + ) + // take the weight for that collection, or 0 if the nft matches none of the dao's collections + )?.weight ?? new BN(0) + ) + // sum + .reduce((partialSum, a) => partialSum.add(a), new BN(0)) + + return power +} + +export const determineVotingPowerType = async ( + connection: Connection, + realmPk: PublicKey, + kind: 'council' | 'community' +) => { + const realm = (await fetchRealmByPubkey(connection, realmPk)).result + if (!realm) throw new Error() + + const config = await fetchRealmConfigQuery(connection, realmPk) + const programId = + kind === 'community' + ? config.result?.account.communityTokenConfig.voterWeightAddin + : config.result?.account.councilTokenConfig.voterWeightAddin + + return programId === undefined + ? ('vanilla' as const) + : VSR_PLUGIN_PKS.includes(programId.toString()) + ? ('VSR' as const) + : HELIUM_VSR_PLUGINS_PKS.includes(programId.toString()) + ? 'HeliumVSR' + : NFT_PLUGINS_PKS.includes(programId.toString()) + ? 'NFT' + : GATEWAY_PLUGINS_PKS.includes(programId.toString()) + ? 'gateway' + : 'unknown' +} + +export const useGovernancePowerAsync = ( + kind: 'community' | 'council' | undefined +) => { + const { connection } = useConnection() + const realmPk = useSelectedRealmPubkey() + + const vsrVotingPower = useDepositStore((s) => s.state.votingPower) + const heliumVotingPower = useHeliumVsrStore((s) => s.state.votingPower) + const gatewayVotingPower = useGatewayPluginStore((s) => s.state.votingPower) + + const communityTOR = useAddressQuery_CommunityTokenOwner() + const councilTOR = useAddressQuery_CouncilTokenOwner() + const { data: TOR } = kind && kind === 'community' ? communityTOR : councilTOR + + const { result: plugin } = useAsync( + async () => + kind && realmPk && determineVotingPowerType(connection, realmPk, kind), + [connection, realmPk, kind] + ) + + return useAsync( + async () => + plugin === undefined + ? undefined + : realmPk && + TOR && + (plugin === 'vanilla' + ? getVanillaGovpower(connection, TOR) + : plugin === 'NFT' + ? getNftGovpower(connection, realmPk, TOR) + : plugin === 'VSR' + ? vsrVotingPower + : plugin === 'HeliumVSR' + ? heliumVotingPower + : plugin === 'gateway' + ? gatewayVotingPower + : new BN(0)), + [realmPk, TOR, plugin, connection] + ) +} + +/** + * @deprecated + * use useGovernancePowerAsync + */ +export const useLegacyVoterWeight = () => { + const { connection } = useConnection() + const realmPk = useSelectedRealmPubkey() + const realm = useRealmQuery().data?.result + + const vsrVotingPower = useDepositStore((s) => s.state.votingPower) + const heliumVotingPower = useHeliumVsrStore((s) => s.state.votingPower) + const gatewayVotingPower = useGatewayPluginStore((s) => s.state.votingPower) + + const { data: communityTOR } = useUserCommunityTokenOwnerRecord() + const { data: councilTOR } = useUserCouncilTokenOwnerRecord() + + const { result: plugin } = useAsync( + async () => + realmPk && determineVotingPowerType(connection, realmPk, 'community'), + [connection, realmPk] + ) + + const { result: shouldCareAboutCouncil } = useAsync( + async () => realm && realm.account.config.councilMint !== undefined, + [realm] + ) + + return useAsync( + async () => + realmPk && + communityTOR && + (shouldCareAboutCouncil === undefined + ? undefined + : shouldCareAboutCouncil === true && councilTOR === undefined + ? undefined + : plugin === 'vanilla' + ? new VoterWeight(communityTOR.result, councilTOR?.result) + : plugin === 'NFT' + ? communityTOR.result?.pubkey + ? new VoteNftWeight( + communityTOR.result, + councilTOR?.result, + await getNftGovpower( + connection, + realmPk, + communityTOR.result.pubkey + ) + ) + : undefined + : plugin === 'VSR' + ? new VoteRegistryVoterWeight( + communityTOR.result, + councilTOR?.result, + vsrVotingPower + ) + : plugin === 'HeliumVSR' + ? new VoteRegistryVoterWeight( + communityTOR.result, + councilTOR?.result, + heliumVotingPower + ) + : plugin === 'gateway' + ? new SimpleGatedVoterWeight( + communityTOR.result, + councilTOR?.result, + gatewayVotingPower + ) + : undefined), + [realmPk, communityTOR, councilTOR, plugin, connection] + ) +} diff --git a/hooks/queries/plugins/nftVoter.ts b/hooks/queries/plugins/nftVoter.ts new file mode 100644 index 0000000000..72a837f2b8 --- /dev/null +++ b/hooks/queries/plugins/nftVoter.ts @@ -0,0 +1,42 @@ +import { Connection, PublicKey } from '@solana/web3.js' +import { fetchRealmByPubkey } from '../realm' +import { getRegistrarPDA } from '@utils/plugin/accounts' +import { Program } from '@coral-xyz/anchor' +import { IDL, NftVoter } from 'idls/nft_voter' +import asFindable from '@utils/queries/asFindable' +import queryClient from '../queryClient' +import { fetchRealmConfigQuery } from '../realmConfig' + +const nftMintRegistrarQueryFn = async ( + connection: Connection, + realmPk: PublicKey +) => { + const realm = (await fetchRealmByPubkey(connection, realmPk)).result + if (!realm) throw new Error() + + const config = await fetchRealmConfigQuery(connection, realmPk) + const programId = config.result?.account.communityTokenConfig.voterWeightAddin + if (programId === undefined) + return { found: false, result: undefined } as const + + const { registrar: registrarPk } = await getRegistrarPDA( + realm.pubkey, + realm.account.communityMint, + programId + ) + + // use anchor to fetch registrar :-) + const program = new Program(IDL, programId, { connection }) + + return asFindable(() => program.account.registrar.fetch(registrarPk))() +} + +export const fetchNftRegistrar = (connection: Connection, realmPk: PublicKey) => + queryClient.fetchQuery({ + queryKey: [ + connection.rpcEndpoint, + 'Nft Plugin Registrar', + realmPk.toString(), + ], + queryFn: () => nftMintRegistrarQueryFn(connection, realmPk), + }) diff --git a/hooks/queries/realmConfig.ts b/hooks/queries/realmConfig.ts index 6d4bd147a4..6730078b25 100644 --- a/hooks/queries/realmConfig.ts +++ b/hooks/queries/realmConfig.ts @@ -5,30 +5,31 @@ import { getRealmConfig, getRealmConfigAddress, } from '@solana/spl-governance' -import { PublicKey } from '@solana/web3.js' +import { Connection, PublicKey } from '@solana/web3.js' import { useQuery } from '@tanstack/react-query' import asFindable from '@utils/queries/asFindable' -import { useRealmQuery } from './realm' -import useLegacyConnectionContext from '@hooks/useLegacyConnectionContext' +import { fetchRealmByPubkey, useRealmQuery } from './realm' import useSelectedRealmPubkey from '@hooks/selectedRealm/useSelectedRealmPubkey' +import { useConnection } from '@solana/wallet-adapter-react' +import queryClient from './queryClient' export const realmConfigQueryKeys = { - all: (cluster: string) => [cluster, 'RealmConfig'], - byRealm: (cluster: string, k: PublicKey) => [ - ...realmConfigQueryKeys.all(cluster), + all: (endpoint: string) => [endpoint, 'RealmConfig'], + byRealm: (endpoint: string, k: PublicKey) => [ + ...realmConfigQueryKeys.all(endpoint), 'for Realm', k, ], } export const useRealmConfigQuery = () => { - const connection = useLegacyConnectionContext() + const { connection } = useConnection() const realm = useRealmQuery().data?.result const enabled = realm !== undefined const query = useQuery({ queryKey: enabled - ? realmConfigQueryKeys.byRealm(connection.cluster, realm.pubkey) + ? realmConfigQueryKeys.byRealm(connection.rpcEndpoint, realm.pubkey) : undefined, queryFn: async () => { if (!enabled) throw new Error() @@ -37,7 +38,7 @@ export const useRealmConfigQuery = () => { realm.owner, realm.pubkey ) - return asFindable(getRealmConfig)(connection.current, realmConfigPk) + return asFindable(getRealmConfig)(connection, realmConfigPk) }, staleTime: 3600000, // 1 hour cacheTime: 3600000 * 24 * 10, @@ -47,6 +48,24 @@ export const useRealmConfigQuery = () => { return query } +export const fetchRealmConfigQuery = async ( + connection: Connection, + realmPk: PublicKey +) => + queryClient.fetchQuery({ + queryKey: realmConfigQueryKeys.byRealm(connection.rpcEndpoint, realmPk), + queryFn: async () => { + const { result: realm } = await fetchRealmByPubkey(connection, realmPk) + if (realm === undefined) throw new Error() + + const realmConfigPk = await getRealmConfigAddress( + realm.owner, + realm.pubkey + ) + return asFindable(getRealmConfig)(connection, realmConfigPk) + }, + }) + const DEFAULT_CONFIG_FOR_REALM = (realm: PublicKey): RealmConfigAccount => ({ accountType: GovernanceAccountType.RealmConfig, realm, diff --git a/hooks/queries/tokenOwnerRecord.ts b/hooks/queries/tokenOwnerRecord.ts index a6033f4a22..8aae0bc4d8 100644 --- a/hooks/queries/tokenOwnerRecord.ts +++ b/hooks/queries/tokenOwnerRecord.ts @@ -1,11 +1,10 @@ -import { EndpointTypes } from '@models/types' import { TokenOwnerRecord, getGovernanceAccounts, getTokenOwnerRecord, pubkeyFilter, } from '@solana/spl-governance' -import { PublicKey } from '@solana/web3.js' +import { Connection, PublicKey } from '@solana/web3.js' import { useQuery } from '@tanstack/react-query' import asFindable from '@utils/queries/asFindable' import { @@ -16,15 +15,16 @@ import { useRealmQuery } from './realm' import { useMemo } from 'react' import useLegacyConnectionContext from '@hooks/useLegacyConnectionContext' import useWalletOnePointOh from '@hooks/useWalletOnePointOh' +import queryClient from './queryClient' export const tokenOwnerRecordQueryKeys = { - all: (cluster: EndpointTypes) => [cluster, 'TokenOwnerRecord'], - byPubkey: (cluster: EndpointTypes, k: PublicKey) => [ - ...tokenOwnerRecordQueryKeys.all(cluster), + all: (endpoint: string) => [endpoint, 'TokenOwnerRecord'], + byPubkey: (endpoint: string, k: PublicKey) => [ + ...tokenOwnerRecordQueryKeys.all(endpoint), k.toString(), ], - byRealm: (cluster: EndpointTypes, realm: PublicKey) => [ - ...tokenOwnerRecordQueryKeys.all(cluster), + byRealm: (endpoint: string, realm: PublicKey) => [ + ...tokenOwnerRecordQueryKeys.all(endpoint), 'by Realm', realm, ], @@ -37,7 +37,10 @@ export const useTokenOwnerRecordsForRealmQuery = () => { const enabled = realm !== undefined const query = useQuery({ queryKey: enabled - ? tokenOwnerRecordQueryKeys.byRealm(connection.cluster, realm.pubkey) + ? tokenOwnerRecordQueryKeys.byRealm( + connection.current.rpcEndpoint, + realm.pubkey + ) : undefined, queryFn: async () => { if (!enabled) throw new Error() @@ -88,6 +91,9 @@ export const useTokenOwnerRecordsDelegatedToUser = () => { return delagatingTors } +const queryFn = (connection: Connection, pubkey: PublicKey) => + asFindable(getTokenOwnerRecord)(connection, pubkey) + export const useTokenOwnerRecordByPubkeyQuery = ( pubkey: PublicKey | undefined ) => { @@ -95,17 +101,32 @@ export const useTokenOwnerRecordByPubkeyQuery = ( const enabled = pubkey !== undefined const query = useQuery({ queryKey: enabled - ? tokenOwnerRecordQueryKeys.byPubkey(connection.cluster, pubkey) + ? tokenOwnerRecordQueryKeys.byPubkey( + connection.current.rpcEndpoint, + pubkey + ) : undefined, queryFn: async () => { if (!enabled) throw new Error() - return asFindable(getTokenOwnerRecord)(connection.current, pubkey) + return queryFn(connection.current, pubkey) }, enabled, }) return query } +export const fetchTokenOwnerRecordByPubkey = ( + connection: Connection, + pubkey: PublicKey +) => + queryClient.fetchQuery({ + queryKey: tokenOwnerRecordQueryKeys.byPubkey( + connection.rpcEndpoint, + pubkey + ), + queryFn: () => queryFn(connection, pubkey), + }) + export const useUserCommunityTokenOwnerRecord = () => { const { data: tokenOwnerRecordPubkey } = useAddressQuery_CommunityTokenOwner() return useTokenOwnerRecordByPubkeyQuery(tokenOwnerRecordPubkey) diff --git a/hooks/useCreateProposal.ts b/hooks/useCreateProposal.ts index a43a74f570..45337a8e6d 100644 --- a/hooks/useCreateProposal.ts +++ b/hooks/useCreateProposal.ts @@ -17,6 +17,7 @@ import useLegacyConnectionContext from './useLegacyConnectionContext' import queryClient from './queries/queryClient' import { proposalQueryKeys } from './queries/proposal' import { createLUTProposal } from 'actions/createLUTproposal' +import { useLegacyVoterWeight } from './queries/governancePower' export default function useCreateProposal() { const client = useVotePluginsClientStore( @@ -28,7 +29,9 @@ export default function useCreateProposal() { const config = useRealmConfigQuery().data?.result const mint = useRealmCommunityMintInfoQuery().data?.result const councilMint = useRealmCouncilMintInfoQuery().data?.result - const { ownVoterWeight, canChooseWhoVote } = useRealm() + const { result: ownVoterWeight } = useLegacyVoterWeight() + + const { canChooseWhoVote } = useRealm() const { getRpcContext } = useRpcContext() /** @deprecated because the api is goofy, use `propose` */ @@ -56,10 +59,10 @@ export default function useCreateProposal() { if (!selectedGovernance) throw new Error('governance not found') if (!realm) throw new Error() - const ownTokenRecord = ownVoterWeight.getTokenRecordToCreateProposal( + const ownTokenRecord = ownVoterWeight?.getTokenRecordToCreateProposal( selectedGovernance.account.config, voteByCouncil - ) + ) // TODO just get the token record the normal way const defaultProposalMint = !mint?.supply.isZero() || @@ -92,7 +95,7 @@ export default function useCreateProposal() { selectedGovernance.account.proposalCount, instructionsData, isDraft, - ["Approve"], + ['Approve'], client ) queryClient.invalidateQueries({ @@ -110,25 +113,23 @@ export default function useCreateProposal() { return handleCreateProposal({ ...rest, governance: { pubkey: governance } }) } - const proposeMultiChoice = async( - { - title, - description, - governance, - instructionsData, - voteByCouncil = false, - options, - isDraft = false, - }: { - title: string - description: string - governance: PublicKey - instructionsData: InstructionDataWithHoldUpTime[] - voteByCouncil?: boolean - options: string[] - isDraft?: boolean - } - ) => { + const proposeMultiChoice = async ({ + title, + description, + governance, + instructionsData, + voteByCouncil = false, + options, + isDraft = false, + }: { + title: string + description: string + governance: PublicKey + instructionsData: InstructionDataWithHoldUpTime[] + voteByCouncil?: boolean + options: string[] + isDraft?: boolean + }) => { const { result: selectedGovernance } = await fetchGovernanceByPubkey( connection.current, governance @@ -136,7 +137,7 @@ export default function useCreateProposal() { if (!selectedGovernance) throw new Error('governance not found') if (!realm) throw new Error() - const ownTokenRecord = ownVoterWeight.getTokenRecordToCreateProposal( + const ownTokenRecord = ownVoterWeight?.getTokenRecordToCreateProposal( selectedGovernance.account.config, voteByCouncil ) @@ -181,4 +182,4 @@ export default function useCreateProposal() { } return { handleCreateProposal, propose, proposeMultiChoice } -} \ No newline at end of file +} diff --git a/hooks/useGovernanceAssets.ts b/hooks/useGovernanceAssets.ts index be49340738..d840222d7f 100644 --- a/hooks/useGovernanceAssets.ts +++ b/hooks/useGovernanceAssets.ts @@ -1,13 +1,13 @@ import { AccountType, AssetAccount } from '@utils/uiTypes/assets' import { Instructions, PackageEnum } from '@utils/uiTypes/proposalCreationTypes' import useGovernanceAssetsStore from 'stores/useGovernanceAssetsStore' -import useRealm from './useRealm' import { HELIUM_VSR_PLUGINS_PKS, VSR_PLUGIN_PKS } from '../constants/plugins' import { useRealmQuery } from './queries/realm' import { useRealmConfigQuery } from './queries/realmConfig' import { useRouter } from 'next/router' import { useRealmGovernancesQuery } from './queries/governance' import { useMemo } from 'react' +import { useLegacyVoterWeight } from './queries/governancePower' type Package = { name: string @@ -44,7 +44,7 @@ export default function useGovernanceAssets() { const realm = useRealmQuery().data?.result const config = useRealmConfigQuery().data?.result const { symbol } = useRouter().query - const { ownVoterWeight } = useRealm() + const { result: ownVoterWeight } = useLegacyVoterWeight() const governedTokenAccounts: AssetAccount[] = useGovernanceAssetsStore( (s) => s.governedTokenAccounts @@ -68,7 +68,7 @@ export default function useGovernanceAssets() { assetAccounts .filter((x) => types.find((t) => t === x.type)) .some((govAcc) => - ownVoterWeight.canCreateProposal(govAcc.governance.account.config) + ownVoterWeight?.canCreateProposal(govAcc.governance.account.config) ) ) } @@ -85,7 +85,7 @@ export default function useGovernanceAssets() { ) return ( governance && - ownVoterWeight.canCreateProposal(governance?.account?.config) + ownVoterWeight?.canCreateProposal(governance?.account?.config) ) }) @@ -100,7 +100,7 @@ export default function useGovernanceAssets() { const canUseAnyInstruction = realm && governancesArray.some((gov) => - ownVoterWeight.canCreateProposal(gov.account.config) + ownVoterWeight?.canCreateProposal(gov.account.config) ) const realmAuth = @@ -109,7 +109,7 @@ export default function useGovernanceAssets() { (x) => x.pubkey.toBase58() === realm.account.authority?.toBase58() ) const canUseAuthorityInstruction = - realmAuth && ownVoterWeight.canCreateProposal(realmAuth?.account.config) + realmAuth && ownVoterWeight?.canCreateProposal(realmAuth?.account.config) const governedSPLTokenAccounts = governedTokenAccounts.filter( (x) => x.type === AccountType.TOKEN @@ -127,7 +127,7 @@ export default function useGovernanceAssets() { ) return ( governance && - ownVoterWeight.canCreateProposal(governance?.account?.config) + ownVoterWeight?.canCreateProposal(governance?.account?.config) ) } ) @@ -285,7 +285,7 @@ export default function useGovernanceAssets() { isVisible: realm && governancesArray.some((g) => - ownVoterWeight.canCreateProposal(g.account.config) + ownVoterWeight?.canCreateProposal(g.account.config) ), packageId: PackageEnum.Common, }, diff --git a/hooks/useProposalCreationButtonTooltip.ts b/hooks/useProposalCreationButtonTooltip.ts index bbb8a170b0..65b1640f40 100644 --- a/hooks/useProposalCreationButtonTooltip.ts +++ b/hooks/useProposalCreationButtonTooltip.ts @@ -1,14 +1,15 @@ import { Governance, ProgramAccount } from '@solana/spl-governance' import useRealm from './useRealm' import useWalletOnePointOh from './useWalletOnePointOh' +import { useLegacyVoterWeight } from './queries/governancePower' const useProposalCreationButtonTooltip = ( governances?: ProgramAccount[] ) => { const wallet = useWalletOnePointOh() const connected = !!wallet?.connected + const { result: ownVoterWeight } = useLegacyVoterWeight() const { - ownVoterWeight, toManyCommunityOutstandingProposalsForUser, toManyCouncilOutstandingProposalsForUse, } = useRealm() @@ -18,7 +19,7 @@ const useProposalCreationButtonTooltip = ( : !connected ? 'Connect your wallet to create new proposal' : !governances.some((g) => - ownVoterWeight.canCreateProposal(g.account.config) + ownVoterWeight?.canCreateProposal(g.account.config) ) ? "You don't have enough governance power to create a new proposal" : toManyCommunityOutstandingProposalsForUser diff --git a/hooks/useRealm.tsx b/hooks/useRealm.tsx index 88e44117fc..79302be337 100644 --- a/hooks/useRealm.tsx +++ b/hooks/useRealm.tsx @@ -1,24 +1,6 @@ -import { ProgramAccount, TokenOwnerRecord } from '@solana/spl-governance' import { useRouter } from 'next/router' -import useNftPluginStore from 'NftVotePlugin/store/nftPluginStore' import { useMemo } from 'react' -import useDepositStore from 'VoteStakeRegistry/stores/useDepositStore' -import { - SimpleGatedVoterWeight, - VoteNftWeight, - VoteRegistryVoterWeight, - VoterWeight, -} from '../models/voteWeights' -import { - NFT_PLUGINS_PKS, - VSR_PLUGIN_PKS, - GATEWAY_PLUGINS_PKS, - HELIUM_VSR_PLUGINS_PKS, -} from '../constants/plugins' -import useGatewayPluginStore from '../GatewayPlugin/store/gatewayPluginStore' -import useHeliumVsrStore from 'HeliumVotePlugin/hooks/useHeliumVsrStore' -import { BN } from '@coral-xyz/anchor' -import { PublicKey } from '@solana/web3.js' +import { NFT_PLUGINS_PKS } from '../constants/plugins' import { useVsrMode } from './useVsrMode' import { useRealmQuery } from './queries/realm' import { @@ -48,10 +30,6 @@ export default function useRealm() { const mint = useRealmCommunityMintInfoQuery().data?.result const councilMint = useRealmCouncilMintInfoQuery().data?.result - const votingPower = useDepositStore((s) => s.state.votingPower) - const heliumVotingPower = useHeliumVsrStore((s) => s.state.votingPower) - const nftVotingPower = useNftPluginStore((s) => s.state.votingPower) - const gatewayVotingPower = useGatewayPluginStore((s) => s.state.votingPower) const currentPluginPk = config?.account?.communityTokenConfig.voterWeightAddin const ownTokenRecord = useUserCommunityTokenOwnerRecord().data?.result @@ -97,15 +75,6 @@ export default function useRealm() { const vsrMode = useVsrMode() const isNftMode = currentPluginPk && NFT_PLUGINS_PKS.includes(currentPluginPk?.toBase58()) - const ownVoterWeight = getVoterWeight( - currentPluginPk, - ownTokenRecord, - votingPower, - nftVotingPower, - gatewayVotingPower, - ownCouncilTokenRecord, - heliumVotingPower - ) return useMemo( () => ({ @@ -127,7 +96,7 @@ export default function useRealm() { realmTokenAccount, councilTokenAccount, /** @deprecated just use the token owner record directly, ok? */ - ownVoterWeight, + //ownVoterWeight, //realmDisplayName: realmInfo?.displayName ?? realm?.account?.name, canChooseWhoVote, //councilTokenOwnerRecords, @@ -144,8 +113,6 @@ export default function useRealm() { councilTokenAccount, currentPluginPk, isNftMode, - - ownVoterWeight, realmInfo, realmTokenAccount, symbol, @@ -155,45 +122,3 @@ export default function useRealm() { ] ) } - -const getVoterWeight = ( - currentPluginPk: PublicKey | undefined, - ownTokenRecord: ProgramAccount | undefined, - votingPower: BN, - nftVotingPower: BN, - gatewayVotingPower: BN, - ownCouncilTokenRecord: ProgramAccount | undefined, - heliumVotingPower: BN -) => { - if (currentPluginPk) { - if (VSR_PLUGIN_PKS.includes(currentPluginPk.toBase58())) { - return new VoteRegistryVoterWeight( - ownTokenRecord, - ownCouncilTokenRecord, - votingPower - ) - } - if (HELIUM_VSR_PLUGINS_PKS.includes(currentPluginPk.toBase58())) { - return new VoteRegistryVoterWeight( - ownTokenRecord, - ownCouncilTokenRecord, - heliumVotingPower - ) - } - if (NFT_PLUGINS_PKS.includes(currentPluginPk.toBase58())) { - return new VoteNftWeight( - ownTokenRecord, - ownCouncilTokenRecord, - nftVotingPower - ) - } - if (GATEWAY_PLUGINS_PKS.includes(currentPluginPk.toBase58())) { - return new SimpleGatedVoterWeight( - ownTokenRecord, - ownCouncilTokenRecord, - gatewayVotingPower - ) - } - } - return new VoterWeight(ownTokenRecord, ownCouncilTokenRecord) -} diff --git a/hub/components/NewWallet/useNewWalletTransaction.ts b/hub/components/NewWallet/useNewWalletTransaction.ts index 14db1f817b..4aad202176 100644 --- a/hub/components/NewWallet/useNewWalletTransaction.ts +++ b/hub/components/NewWallet/useNewWalletTransaction.ts @@ -8,10 +8,10 @@ import { useCallback } from 'react'; import useVotePluginsClientStore from 'stores/useVotePluginsClientStore'; import { rules2governanceConfig } from '../EditWalletRules/createTransaction'; +import { useLegacyVoterWeight } from '@hooks/queries/governancePower'; import { useRealmQuery } from '@hooks/queries/realm'; import useLegacyConnectionContext from '@hooks/useLegacyConnectionContext'; import useProgramVersion from '@hooks/useProgramVersion'; -import useRealm from '@hooks/useRealm'; import useWalletOnePointOh from '@hooks/useWalletOnePointOh'; import { chunks } from '@utils/helpers'; import { trySentryLog } from '@utils/logs'; @@ -33,11 +33,11 @@ const useNewWalletCallback = ( ); const programVersion = useProgramVersion(); const realm = useRealmQuery().data?.result; - const { ownVoterWeight } = useRealm(); + const { result: ownVoterWeight } = useLegacyVoterWeight(); - const tokenOwnerRecord = ownVoterWeight.canCreateGovernanceUsingCouncilTokens() + const tokenOwnerRecord = ownVoterWeight?.canCreateGovernanceUsingCouncilTokens() ? ownVoterWeight.councilTokenRecord - : realm && ownVoterWeight.canCreateGovernanceUsingCommunityTokens(realm) + : realm && ownVoterWeight?.canCreateGovernanceUsingCommunityTokens(realm) ? ownVoterWeight.communityTokenRecord : undefined; diff --git a/models/voteWeights.ts b/models/voteWeights.ts index 8c32860123..90faca0ffb 100644 --- a/models/voteWeights.ts +++ b/models/voteWeights.ts @@ -34,6 +34,9 @@ interface VoterWeightInterface { } /// VoterWeight encapsulates logic to determine voter weights from token records (community or council) +/** + * @deprecated instead of using this, ask yourself what you are trying to do, and observe that there is no reason you'd need to use this class in order to do it. + */ export class VoteRegistryVoterWeight implements VoterWeightInterface { //TODO implement council communityTokenRecord: ProgramAccount | undefined @@ -137,6 +140,9 @@ export class VoteRegistryVoterWeight implements VoterWeightInterface { } } +/** + * @deprecated instead of using this, ask yourself what you are trying to do, and observe that there is no reason you'd need to use this class in order to do it. + */ export class VoteNftWeight implements VoterWeightInterface { //TODO implement council communityTokenRecord: ProgramAccount | undefined @@ -238,6 +244,9 @@ export class VoteNftWeight implements VoterWeightInterface { } } +/** + * @deprecated instead of using this, ask yourself what you are trying to do, and observe that there is no reason you'd need to use this class in order to do it. + */ export class VoterWeight implements VoterWeightInterface { communityTokenRecord: ProgramAccount | undefined councilTokenRecord: ProgramAccount | undefined @@ -341,6 +350,9 @@ export class VoterWeight implements VoterWeightInterface { } // TODO treat this as temporary - it should delegate to the governance VoterWeight (frontend and on-chain) +/** + * @deprecated instead of using this, ask yourself what you are trying to do, and observe that there is no reason you'd need to use this class in order to do it. + */ export class SimpleGatedVoterWeight implements VoterWeightInterface { constructor( public communityTokenRecord: ProgramAccount | undefined, diff --git a/pages/dao/[symbol]/assets/index.tsx b/pages/dao/[symbol]/assets/index.tsx index 8fd2e7f297..8f0db680d5 100644 --- a/pages/dao/[symbol]/assets/index.tsx +++ b/pages/dao/[symbol]/assets/index.tsx @@ -1,4 +1,3 @@ -import React from 'react' import AssetsList from '@components/AssetsList/AssetsList' import Tooltip from '@components/Tooltip' import useRealm from '@hooks/useRealm' @@ -9,14 +8,15 @@ import { LinkButton } from '@components/Button' import { PlusCircleIcon } from '@heroicons/react/outline' import useWalletOnePointOh from '@hooks/useWalletOnePointOh' import { useRealmQuery } from '@hooks/queries/realm' +import { useLegacyVoterWeight } from '@hooks/queries/governancePower' export const NEW_PROGRAM_VIEW = `/program/new` const Assets = () => { const router = useRouter() const realm = useRealmQuery().data?.result + const { result: ownVoterWeight } = useLegacyVoterWeight() const { symbol, - ownVoterWeight, toManyCommunityOutstandingProposalsForUser, toManyCouncilOutstandingProposalsForUse, } = useRealm() @@ -27,7 +27,7 @@ const Assets = () => { router.push(fmtUrlWithCluster(`/dao/${symbol}${NEW_PROGRAM_VIEW}`)) } const canCreateGovernance = realm - ? ownVoterWeight.canCreateGovernance(realm) + ? ownVoterWeight?.canCreateGovernance(realm) : null const newAssetToolTip = renderAddNewAssetTooltip( diff --git a/pages/dao/[symbol]/index.tsx b/pages/dao/[symbol]/index.tsx index 176b9d70da..9a75c69506 100644 --- a/pages/dao/[symbol]/index.tsx +++ b/pages/dao/[symbol]/index.tsx @@ -53,6 +53,7 @@ import { useRealmProposalsQuery, } from '@hooks/queries/proposal' import queryClient from '@hooks/queries/queryClient' +import { useLegacyVoterWeight } from '@hooks/queries/governancePower' const AccountsCompactWrapper = dynamic( () => import('@components/TreasuryAccount/AccountsCompactWrapper') @@ -76,7 +77,8 @@ const REALM = () => { const realmQuery = useRealmQuery() const mint = useRealmCommunityMintInfoQuery().data?.result const councilMint = useRealmCouncilMintInfoQuery().data?.result - const { realmInfo, ownVoterWeight } = useRealm() + const { result: ownVoterWeight } = useLegacyVoterWeight() + const { realmInfo } = useRealm() const proposalsPerPage = 20 const [filters, setFilters] = useState(InitialFilters) const [sorting, setSorting] = useState(InitialSorting) @@ -225,10 +227,12 @@ const REALM = () => { selectedProposals.length === votingProposals?.length const hasCommunityVoteWeight = ownTokenRecord && - ownVoterWeight.hasMinAmountToVote(ownTokenRecord.account.governingTokenMint) + ownVoterWeight?.hasMinAmountToVote( + ownTokenRecord.account.governingTokenMint + ) const hasCouncilVoteWeight = ownCouncilTokenRecord && - ownVoterWeight.hasMinAmountToVote( + ownVoterWeight?.hasMinAmountToVote( ownCouncilTokenRecord.account.governingTokenMint ) diff --git a/pages/dao/[symbol]/params/components/ParamsView.tsx b/pages/dao/[symbol]/params/components/ParamsView.tsx index 302fc9420b..d64dede9c4 100644 --- a/pages/dao/[symbol]/params/components/ParamsView.tsx +++ b/pages/dao/[symbol]/params/components/ParamsView.tsx @@ -1,4 +1,3 @@ -import useRealm from '@hooks/useRealm' import { fmtMintAmount, getHoursFromTimestamp } from '@tools/sdk/units' import { DISABLED_VOTER_WEIGHT } from '@tools/constants' import { getFormattedStringFromDays, SECS_PER_DAY } from '@utils/dateTools' @@ -14,12 +13,13 @@ import { useRealmCommunityMintInfoQuery, useRealmCouncilMintInfoQuery, } from '@hooks/queries/mintInfo' +import { useLegacyVoterWeight } from '@hooks/queries/governancePower' const ParamsView = ({ activeGovernance }) => { const realm = useRealmQuery().data?.result const mint = useRealmCommunityMintInfoQuery().data?.result const councilMint = useRealmCouncilMintInfoQuery().data?.result - const { ownVoterWeight } = useRealm() + const { result: ownVoterWeight } = useLegacyVoterWeight() const programVersion = useProgramVersion() const realmAccount = realm?.account const communityMint = realmAccount?.communityMint.toBase58() @@ -141,6 +141,7 @@ const ParamsView = ({ activeGovernance }) => {