From 8df175fc32ce0e2f9f45beee9ec2596f04cb71b9 Mon Sep 17 00:00:00 2001 From: selankon Date: Wed, 7 Feb 2024 11:45:31 +0100 Subject: [PATCH] Implement balance for non wrapped tokens --- src/hooks/useCensus3.tsx | 81 ++++++++++++++++++++++++++++++++++++- src/hooks/useDaoMembers.tsx | 29 +++++++++++-- src/pages/community.tsx | 2 + 3 files changed, 108 insertions(+), 4 deletions(-) diff --git a/src/hooks/useCensus3.tsx b/src/hooks/useCensus3.tsx index 590df86b3..5ade895af 100644 --- a/src/hooks/useCensus3.tsx +++ b/src/hooks/useCensus3.tsx @@ -1,7 +1,15 @@ import {useClient} from '@vocdoni/react-providers'; import {useCallback, useEffect, useState} from 'react'; -import {GaselessPluginName, usePluginClient} from './usePluginClient'; +import { + GaselessPluginName, + PluginTypes, + usePluginClient, +} from './usePluginClient'; import {ErrTokenAlreadyExists} from '@vocdoni/sdk'; +import {useParams} from 'react-router-dom'; +import {useProposal} from '../services/aragon-sdk/queries/use-proposal'; +import {GaslessVotingProposal} from '@vocdoni/gasless-voting'; +import {DaoMember, TokenDaoMember} from './useDaoMembers'; const CENSUS3_URL = 'https://census3-stg.vocdoni.net/api'; @@ -59,3 +67,74 @@ export const useCensus3CreateToken = ({chainId}: {chainId: number}) => { return {createToken}; }; + +// Hook that return census3 census id if is gasless plugin +export const useGaslessCensusId = ({ + pluginType, + enable = true, +}: { + pluginType?: PluginTypes; + enable?: boolean; +}) => { + const {dao, id: proposalId} = useParams(); + + const isGasless = pluginType === GaselessPluginName; + const _enable: boolean = enable && !!dao && !!proposalId && isGasless; + + const {data: proposalData} = useProposal( + { + pluginType: pluginType, + id: proposalId ?? '', + }, + { + enabled: _enable, + } + ); + + let censusId: string | null = null; + let censusSize: number | null = null; + if (_enable && proposalData) { + const census = (proposalData as GaslessVotingProposal).vochain.metadata + .census; + censusId = census.censusId; + censusSize = census.size; + } + + return {censusId, censusSize}; +}; + +export const useNonWrappedDaoMemberBalance = ({ + isGovernanceEnabled, + censusId, + subgraphMembers, +}: { + isGovernanceEnabled: boolean; + censusId: string | null; + subgraphMembers: TokenDaoMember[]; +}) => { + // State to store DaoMembers[] + const [members, setMembers] = useState(subgraphMembers); + const {client: vocdoniClient} = useClient(); + + // UseEffect to calculate the vocdoni client fetchProof function + useEffect(() => { + if (vocdoniClient && isGovernanceEnabled && censusId) { + (async () => { + const members = await Promise.all( + subgraphMembers.map(async member => { + const proof = await vocdoniClient.fetchProof( + censusId, + member.address + ); + member.balance = Number(proof.weight); + member.votingPower = Number(proof.weight); + return member; + }) + ); + setMembers(members); + })(); + } + }, [censusId, isGovernanceEnabled, subgraphMembers, vocdoniClient]); + + return {members}; +}; diff --git a/src/hooks/useDaoMembers.tsx b/src/hooks/useDaoMembers.tsx index 90de4840b..f466a5189 100644 --- a/src/hooks/useDaoMembers.tsx +++ b/src/hooks/useDaoMembers.tsx @@ -9,6 +9,8 @@ import {useMembers} from 'services/aragon-sdk/queries/use-members'; import {Address, useBalance} from 'wagmi'; import {useDaoToken} from './useDaoToken'; import {useWallet} from './useWallet'; +import {useGaslessGovernanceEnabled} from './useGaslessGovernanceEnabled'; +import {useGaslessCensusId, useNonWrappedDaoMemberBalance} from './useCensus3'; export type MultisigDaoMember = { address: string; @@ -122,6 +124,15 @@ export const useDaoMembers = ( const {address} = useWallet(); const {data: daoToken} = useDaoToken(pluginAddress); + const {isGovernanceEnabled} = useGaslessGovernanceEnabled({ + pluginAddress, + pluginType, + }); + const {censusId, censusSize: nonWrappedCensusSize} = useGaslessCensusId({ + pluginType, + enable: !isGovernanceEnabled, + }); + const isTokenBased = pluginType === 'token-voting.plugin.dao.eth' || pluginType === GaselessPluginName; @@ -154,6 +165,12 @@ export const useDaoMembers = ( sdkToDaoMember(member, daoToken?.decimals) ); + const {members: nonGovernanceMemebers} = useNonWrappedDaoMemberBalance({ + isGovernanceEnabled, + subgraphMembers: parsedSubgraphData as TokenDaoMember[], + censusId, + }); + const {data: userBalance} = useBalance({ address: address as Address, token: daoToken?.address as Address, @@ -245,6 +262,9 @@ export const useDaoMembers = ( }, ]; } else { + if (!isGovernanceEnabled) { + return nonGovernanceMemebers; + } return parsedSubgraphData; } } else { @@ -255,9 +275,12 @@ export const useDaoMembers = ( const sortedData = opts?.sort ? [...getCombinedData()].sort(sortDaoMembers(opts.sort, address)) : getCombinedData(); - memberCount = useSubgraph - ? sortedData.length - : graphqlData?.holders.totalHolders || sortedData.length; + memberCount = + nonWrappedCensusSize !== null + ? nonWrappedCensusSize + : useSubgraph + ? sortedData.length + : graphqlData?.holders.totalHolders || sortedData.length; const searchTerm = opts?.searchTerm; const filteredData = !searchTerm ? sortedData diff --git a/src/pages/community.tsx b/src/pages/community.tsx index dcf4f0ab5..88c29ba10 100644 --- a/src/pages/community.tsx +++ b/src/pages/community.tsx @@ -64,6 +64,8 @@ export const Community: React.FC = () => { } ); + console.log('AAAAAAAAAAAAAA', members); + const {isDAOTokenWrapped, isTokenMintable} = useExistingToken({ daoToken, daoDetails,