Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add erc20 helper #9620

Merged
merged 7 commits into from
Oct 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions libs/model/src/community/GetTopics.query.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ WITH topic_data AS (
weighted_voting,
token_symbol,
vote_weight_multiplier,
token_address,
created_at::text AS created_at,
updated_at::text AS updated_at,
deleted_at::text AS deleted_at,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,11 @@ export const Erc20Abi = [
stateMutability: 'nonpayable',
type: 'function',
},
{
inputs: [{ internalType: 'address', name: 'account', type: 'address' }],
stateMutability: 'view',
type: 'function',
name: 'balanceOf',
outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }],
},
];
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import Web3 from 'web3';
import { Erc20Abi } from './Abi/ERC20Abi';
import ContractBase from './ContractBase';
class ERC20Helper extends ContractBase {
constructor(contractAddress: string, rpc: string) {
super(contractAddress, Erc20Abi, rpc);
}
async getBalance(userAddress: string): Promise<string> {
if (!this.initialized) {
await this.initialize();
}
const balance = await this.contract.methods.balanceOf(userAddress).call();

return Web3.utils.fromWei(balance, 'ether');
}
}

export default ERC20Helper;
4 changes: 0 additions & 4 deletions packages/commonwealth/client/scripts/state/api/token/index.ts

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { useQuery } from '@tanstack/react-query';
import ERC20Helper from 'helpers/ContractHelpers/ERC20Helper';

const GET_ERC20_BALANCE_STALE_TIME = 60 * 1_000; // 1 min

interface UseGetERC20BalanceQueryProps {
userAddress: string;
tokenAddress: string;
nodeRpc: string;
}

const getERC20Balance = async ({
userAddress,
tokenAddress,
nodeRpc,
}: UseGetERC20BalanceQueryProps) => {
const helper = new ERC20Helper(tokenAddress, nodeRpc);

return await helper.getBalance(userAddress);
};

const useGetERC20BalanceQuery = ({
userAddress,
tokenAddress,
nodeRpc,
}: UseGetERC20BalanceQueryProps) => {
return useQuery({
queryKey: [userAddress, tokenAddress, nodeRpc],
queryFn: () => getERC20Balance({ userAddress, tokenAddress, nodeRpc }),
enabled: !!tokenAddress && !!userAddress && !!nodeRpc,
staleTime: GET_ERC20_BALANCE_STALE_TIME,
retry: false,
});
};

export default useGetERC20BalanceQuery;
12 changes: 11 additions & 1 deletion packages/commonwealth/client/scripts/state/api/tokens/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
import useCreateTokenMutation from './createToken';
import useFetchTokensQuery from './fetchTokens';
import useGetERC20BalanceQuery from './getERC20Balance';
import useTokenBalanceQuery from './getTokenBalance';
import useTokenMetadataQuery from './getTokenMetadata';

export { useTokenMetadataQuery };
export {
useCreateTokenMutation,
useFetchTokensQuery,
useGetERC20BalanceQuery,
useTokenBalanceQuery,
useTokenMetadataQuery,
};
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,10 @@
}
}
}

.vote-weight-label {
color: $neutral-500;
.vote-weight {
margin-left: 8px;
.vote-weight-label {
color: $neutral-500;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ interface TokenBannerProps {
change?: number;
isLoading?: boolean;
popover?: Pick<CWPopoverProps, 'title' | 'body'>;
voteWeight?: number;
voteWeight?: string;
}

const TokenBanner = ({
Expand Down Expand Up @@ -76,7 +76,7 @@ const TokenBanner = ({
)}

{voteWeight && (
<div>
<div className="vote-weight">
<CWText className="vote-weight-label" type="caption">
Your vote weight
</CWText>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import useCreateCommunityMutation, {
} from 'state/api/communities/createCommunity';
import { generateImage } from 'state/api/general/generateImage';
import { useLaunchTokenMutation } from 'state/api/launchPad';
import { useCreateTokenMutation } from 'state/api/token';
import { useCreateTokenMutation } from 'state/api/tokens';
import useUserStore from 'state/ui/user';
import PageCounter from 'views/components/PageCounter';
import { CWText } from 'views/components/component_kit/cw_text';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@ import {
useGetUserEthBalanceQuery,
} from 'state/api/communityStake';
import { useGetContestBalanceQuery } from 'state/api/contests';
import { useTokenMetadataQuery } from 'state/api/tokens';
import useTokenBalanceQuery from 'state/api/tokens/getTokenBalance';
import { useTokenBalanceQuery, useTokenMetadataQuery } from 'state/api/tokens';
import { convertTokenAmountToUsd } from 'views/modals/ManageCommunityStakeModal/utils';
import { calculateNewContractBalance, getAmountError } from './utils';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -232,9 +232,10 @@ const SignTransactionsStep = ({
<div className="SignTransactionsStep">
<CWText type="h2">Sign transactions to launch contest</CWText>
<CWText type="b1" className="description">
You must sign two (2) transactions to launch your community contest.
The first is to route the fees generated from stake to the contest
address. The second is to launch the contest contract onchain.
You must sign this transaction to deploy the contest.{' '}
{isContestRecurring
? 'It routes the fees generated from stake to the contest address and launchs the contest contract onchain.'
: 'It launchs the contest contract onchain.'}
</CWText>

<CWText fontWeight="medium" type="b1" className="description">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { ChainBase, commonProtocol } from '@hicommonwealth/shared';
import React from 'react';
import { useUpdateCommunityMutation } from 'state/api/communities';
import { useLaunchTokenMutation } from 'state/api/launchPad';
import { useCreateTokenMutation } from 'state/api/token';
import { useCreateTokenMutation } from 'state/api/tokens';
import useUserStore from 'state/ui/user';
import { CWDivider } from 'views/components/component_kit/cw_divider';
import { CWText } from 'views/components/component_kit/cw_text';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
MixpanelCommunityCreationEvent,
MixpanelLoginPayload,
} from 'shared/analytics/types';
import { useFetchTokensQuery } from 'state/api/token';
import { useFetchTokensQuery } from 'state/api/tokens';
import useUserStore from 'state/ui/user';
import { useDebounce } from 'usehooks-ts';
import {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import { ThreadCard } from './ThreadCard';
import { sortByFeaturedFilter, sortPinned } from './helpers';

import { slugify, splitAndDecodeURL } from '@hicommonwealth/shared';
import { useGetERC20BalanceQuery } from 'client/scripts/state/api/tokens';
import { formatAddressShort } from 'helpers';
import { getThreadActionTooltipText } from 'helpers/threads';
import useBrowserWindow from 'hooks/useBrowserWindow';
Expand All @@ -38,6 +39,7 @@ import { isContestActive } from 'views/pages/CommunityManagement/Contests/utils'
import useTokenMetadataQuery from '../../../state/api/tokens/getTokenMetadata';
import { AdminOnboardingSlider } from '../../components/AdminOnboardingSlider';
import { UserTrainingSlider } from '../../components/UserTrainingSlider';
import { CWText } from '../../components/component_kit/cw_text';
import { DiscussionsFeedDiscovery } from './DiscussionsFeedDiscovery';
import { EmptyThreadsPlaceholder } from './EmptyThreadsPlaceholder';

Expand Down Expand Up @@ -99,6 +101,12 @@ const DiscussionsPage = ({ topicName }: DiscussionsPageProps) => {

const { contestsData } = useCommunityContests();

const { data: erc20Balance } = useGetERC20BalanceQuery({
tokenAddress: topicObj?.token_address || '',
userAddress: user.activeAccount?.address || '',
nodeRpc: app?.chain.meta?.ChainNode?.url || '',
});

const { dateCursor } = useDateCursor({
dateRange: searchParams.get('dateRange') as ThreadTimelineFilterTypes,
});
Expand Down Expand Up @@ -185,6 +193,15 @@ const DiscussionsPage = ({ topicName }: DiscussionsPageProps) => {
return isContestInTopic && isActive;
});

const voteWeight =
isTopicWeighted && erc20Balance
? String(
(
(topicObj?.vote_weight_multiplier || 1) * Number(erc20Balance)
).toFixed(0),
)
: '';

return (
// @ts-expect-error <StrictNullChecks/>
<CWPageLayout ref={containerRef} className="DiscussionsPageLayout">
Expand Down Expand Up @@ -323,9 +340,15 @@ const DiscussionsPage = ({ topicName }: DiscussionsPageProps) => {
name={tokenMetadata?.name}
ticker={topicObj?.token_symbol}
avatarUrl={tokenMetadata?.logo}
voteWeight={voteWeight}
popover={{
title: tokenMetadata?.name,
body: formatAddressShort(topicObj.token_address!, 6, 6),
body: (
<CWText type="b2">
This topic has weighted voting enabled using{' '}
{formatAddressShort(topicObj.token_address!, 6, 6)}
</CWText>
),
}}
/>
)}
Expand Down
Loading