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

[ENG-113 | Public Client] Swap wagmi's usePublicClient with custom client #2677

Merged
merged 17 commits into from
Jan 22, 2025
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
09d31ad
Prototype "wallet client" that automatically switches to the right ch…
adamgall Jan 16, 2025
db74280
Optimize useNetworkPublicClient hook by memoizing the public client c…
Da-Colon Jan 17, 2025
5596497
Refactor hooks to use useNetworkPublicClient instead of usePublicClient
Da-Colon Jan 17, 2025
ae19fae
Rename useWaletClient to useNetworkWalletClient and update chainId ha…
Da-Colon Jan 17, 2025
c1d3dc6
Refactor useDeployDAO to replace useWaletClient with useNetworkWallet…
Da-Colon Jan 17, 2025
3a79c69
Replace useWalletClient with useNetworkWalletClient across multiple h…
Da-Colon Jan 17, 2025
f0c4a30
Merge branch 'eng-113-swap-usePublicClient' of github.com:decentdao/d…
Da-Colon Jan 17, 2025
249e6b5
Refactor useAutomaticSwitchChain to remove wallet client dependencies…
Da-Colon Jan 17, 2025
90ab26d
Update ABISelector and useGetAccountName to utilize chainId from netw…
Da-Colon Jan 17, 2025
202af38
Update multicall configuration in useNetworkPublicClient to include a…
Da-Colon Jan 17, 2025
39d3000
bump
adamgall Jan 17, 2025
329f905
Remove publicClient checks from various components and hooks to simpl…
Da-Colon Jan 17, 2025
ffe9f24
Reduce wait time in multicall configuration for useNetworkPublicClient
Da-Colon Jan 20, 2025
661baba
Merge pull request #2679 from decentdao/eng-113-various-network-cleanup
Da-Colon Jan 21, 2025
ec1a3e8
Merge branch 'develop' into eng-113-swap-usePublicClient
adamgall Jan 22, 2025
e2fb363
catch and display, wrong network toast, when fails to switch
Da-Colon Jan 22, 2025
198330b
Merge pull request #2678 from decentdao/use-walet-client
Da-Colon Jan 22, 2025
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
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { useEffect, useState } from 'react';
import { getContract } from 'viem';
import { usePublicClient } from 'wagmi';
import LidoWithdrawalQueueAbi from '../../../assets/abi/LidoWithdrawalQueueAbi';
import useLidoStaking from '../../../hooks/stake/lido/useLidoStaking';
import useNetworkPublicClient from '../../../hooks/useNetworkPublicClient';
import { useCanUserCreateProposal } from '../../../hooks/utils/useCanUserSubmitProposal';
import { useFractal } from '../../../providers/App/AppProvider';
import { useNetworkConfigStore } from '../../../providers/NetworkConfig/useNetworkConfigStore';
Expand All @@ -17,7 +17,7 @@ export default function useTreasuryLidoInteractions() {
const { handleUnstake, handleClaimUnstakedETH } = useLidoStaking();
const { canUserCreateProposal } = useCanUserCreateProposal();
const { staking } = useNetworkConfigStore();
const publicClient = usePublicClient();
const publicClient = useNetworkPublicClient();

// --- Lido Stake button setup ---
const showStakeButton =
Expand Down Expand Up @@ -48,7 +48,7 @@ export default function useTreasuryLidoInteractions() {

useEffect(() => {
const getLidoClaimableStatus = async () => {
if (!staking.lido?.withdrawalQueueContractAddress || !lidoWithdrawalNFT || !publicClient) {
if (!staking.lido?.withdrawalQueueContractAddress || !lidoWithdrawalNFT) {
return;
}

Expand Down
7 changes: 4 additions & 3 deletions src/components/DaoDashboard/ERC20Claim.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@ import { abis } from '@fractal-framework/fractal-contracts';
import { useCallback, useEffect, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { getContract } from 'viem';
import { useAccount, usePublicClient, useWalletClient } from 'wagmi';
import { useAccount, useWalletClient } from 'wagmi';
import { Alert as AlertIcon } from '../../assets/theme/custom/icons/Alert';
import useNetworkPublicClient from '../../hooks/useNetworkPublicClient';
import { useTransaction } from '../../hooks/utils/useTransaction';
import { useFractal } from '../../providers/App/AppProvider';
import { AzoriusGovernance } from '../../types';
Expand All @@ -19,11 +20,11 @@ export function ERCO20Claim() {
const { t } = useTranslation(['dashboard', 'transaction']);
const [contractCall, pending] = useTransaction();
const azoriusGovernance = governance as AzoriusGovernance;
const publicClient = usePublicClient();
const publicClient = useNetworkPublicClient();
const { data: walletClient } = useWalletClient();

const loadClaim = useCallback(async () => {
if (!tokenClaimContractAddress || !type || !account || !publicClient) {
if (!tokenClaimContractAddress || !type || !account) {
return;
}
const tokenClaimContract = getContract({
Expand Down
13 changes: 6 additions & 7 deletions src/components/DaoDashboard/Info/InfoGovernance.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ import { Bank } from '@phosphor-icons/react';
import { useEffect, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { getContract } from 'viem';
import { usePublicClient } from 'wagmi';

import useNetworkPublicClient from '../../../hooks/useNetworkPublicClient';
import { useTimeHelpers } from '../../../hooks/utils/useTimeHelpers';
import { useFractal } from '../../../providers/App/AppProvider';
import { useDaoInfoStore } from '../../../store/daoInfo/useDaoInfoStore';
Expand All @@ -19,7 +20,7 @@ export function InfoGovernance({ showTitle = true }: { showTitle?: boolean }) {
guardContracts: { freezeGuardType, freezeGuardContractAddress },
} = useFractal();
const { safe } = useDaoInfoStore();
const publicClient = usePublicClient();
const publicClient = useNetworkPublicClient();
const { getTimeDuration } = useTimeHelpers();
const [timelockPeriod, setTimelockPeriod] = useState<string>();
const [executionPeriod, setExecutionPeriod] = useState<string>();
Expand All @@ -28,11 +29,9 @@ export function InfoGovernance({ showTitle = true }: { showTitle?: boolean }) {

useEffect(() => {
const setTimelockInfo = async () => {
const formatBlocks = async (blocks: number): Promise<string | undefined> => {
if (publicClient) {
return getTimeDuration(await blocksToSeconds(blocks, publicClient));
}
};
const formatBlocks = async (blocks: number): Promise<string | undefined> =>
getTimeDuration(await blocksToSeconds(blocks, publicClient));

if (freezeGuardType == FreezeGuardType.MULTISIG) {
if (freezeGuardContractAddress && publicClient) {
const freezeGuardContract = getContract({
Expand Down
14 changes: 3 additions & 11 deletions src/components/DaoHierarchy/DaoHierarchyNode.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ import { useCallback, useEffect, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { Link as RouterLink } from 'react-router-dom';
import { Address, getContract, zeroAddress } from 'viem';
import { usePublicClient } from 'wagmi';
import { DAOQueryDocument } from '../../../.graphclient';
import { SENTINEL_ADDRESS } from '../../constants/common';
import { DAO_ROUTES } from '../../constants/routes';
import { useDecentModules } from '../../hooks/DAO/loaders/useDecentModules';
import useNetworkPublicClient from '../../hooks/useNetworkPublicClient';
import { CacheKeys } from '../../hooks/utils/cache/cacheDefaults';
import { setValue, getValue } from '../../hooks/utils/cache/useLocalStorage';
import { useAddressContractType } from '../../hooks/utils/useAddressContractType';
Expand Down Expand Up @@ -44,7 +44,7 @@ export function DaoHierarchyNode({
const [hierarchyNode, setHierarchyNode] = useState<DaoHierarchyInfo>();
const [hasErrorLoading, setErrorLoading] = useState<boolean>(false);
const { addressPrefix, subgraph, chain } = useNetworkConfigStore();
const publicClient = usePublicClient();
const publicClient = useNetworkPublicClient();

const { getAddressContractType } = useAddressContractType();
const lookupModules = useDecentModules();
Expand All @@ -59,10 +59,6 @@ export function DaoHierarchyNode({

const getVotingStrategies = useCallback(
async (azoriusModule: DecentModule) => {
if (!publicClient) {
throw new Error('Public Client is not set!');
}

const azoriusContract = getContract({
abi: abis.Azorius,
address: azoriusModule.moduleAddress,
Expand Down Expand Up @@ -98,10 +94,6 @@ export function DaoHierarchyNode({
throw new Error('No voting strategies found');
}

if (!publicClient) {
throw new Error('Public Client is not set!');
}

let governanceTypes: DaoHierarchyStrategyType[] = [];

await Promise.all(
Expand All @@ -125,7 +117,7 @@ export function DaoHierarchyNode({
);
return governanceTypes.filter((value, index, self) => self.indexOf(value) === index);
},
[getVotingStrategies, publicClient],
[getVotingStrategies],
);

const loadDao = useCallback(
Expand Down
9 changes: 5 additions & 4 deletions src/components/Proposals/ProposalSummary.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@ import { formatInTimeZone } from 'date-fns-tz';
import { useCallback, useEffect, useMemo, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { erc721Abi, getContract } from 'viem';
import { useAccount, usePublicClient } from 'wagmi';
import { useAccount } from 'wagmi';
import { TOOLTIP_MAXW } from '../../constants/common';
import useNetworkPublicClient from '../../hooks/useNetworkPublicClient';
import useBlockTimestamp from '../../hooks/utils/useBlockTimestamp';
import { useFractal } from '../../providers/App/AppProvider';
import { AzoriusGovernance, AzoriusProposal, GovernanceType } from '../../types';
Expand Down Expand Up @@ -58,10 +59,10 @@ export function AzoriusProposalSummary({ proposal }: { proposal: AzoriusProposal

const toggleShowVotingPower = () => setShowVotingPower(prevState => !prevState);

const publicClient = usePublicClient();
const publicClient = useNetworkPublicClient();

const getErc721VotingWeight = useCallback(async () => {
if (!address || !azoriusGovernance.erc721Tokens || !publicClient) {
if (!address || !azoriusGovernance.erc721Tokens) {
return 0n;
}
const userVotingWeight = (
Expand All @@ -88,7 +89,7 @@ export function AzoriusProposalSummary({ proposal }: { proposal: AzoriusProposal

useEffect(() => {
async function loadProposalVotingWeight() {
if (address && publicClient) {
if (address) {
if (isERC20) {
const strategyContract = getContract({
abi: abis.LinearERC20Voting,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,10 @@ import {
useState,
} from 'react';
import { Address, erc721Abi, getContract } from 'viem';
import { useAccount, usePublicClient } from 'wagmi';
import { useAccount } from 'wagmi';
import useSnapshotProposal from '../../../../hooks/DAO/loaders/snapshot/useSnapshotProposal';
import useUserERC721VotingTokens from '../../../../hooks/DAO/proposal/useUserERC721VotingTokens';
import useNetworkPublicClient from '../../../../hooks/useNetworkPublicClient';
import { useFractal } from '../../../../providers/App/AppProvider';
import { useDaoInfoStore } from '../../../../store/daoInfo/useDaoInfoStore';
import {
Expand Down Expand Up @@ -67,7 +68,7 @@ export function VoteContextProvider({
const { loadVotingWeight } = useSnapshotProposal(proposal as SnapshotProposal);
const { remainingTokenIds } = useUserERC721VotingTokens(null, proposal.proposalId, true);
const { snapshotProposal } = useSnapshotProposal(proposal);
const publicClient = usePublicClient();
const publicClient = useNetworkPublicClient();

const getHasVoted = useCallback(() => {
setHasVotedLoading(true);
Expand Down Expand Up @@ -101,7 +102,7 @@ export function VoteContextProvider({
const erc721VotingWeight = useCallback(async () => {
const account = userAccount.address;
const azoriusGovernance = governance as AzoriusGovernance;
if (!account || !azoriusGovernance.erc721Tokens || !publicClient) {
if (!account || !azoriusGovernance.erc721Tokens) {
return 0n;
}
const userVotingWeight = (
Expand All @@ -123,7 +124,7 @@ export function VoteContextProvider({
const getCanVote = useCallback(async () => {
setCanVoteLoading(true);
let newCanVote = false;
if (userAccount.address && publicClient) {
if (userAccount.address) {
if (snapshotProposal) {
const votingWeightData = await loadVotingWeight();
newCanVote = votingWeightData.votingWeight >= 1;
Expand Down
13 changes: 4 additions & 9 deletions src/components/Roles/RolePaymentDetails.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@ import { TouchEvent, useCallback, useEffect, useMemo, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { useNavigate } from 'react-router-dom';
import { Address, getAddress, Hex } from 'viem';
import { useAccount, usePublicClient } from 'wagmi';
import { useAccount } from 'wagmi';
import { DETAILS_BOX_SHADOW } from '../../constants/common';
import { DAO_ROUTES } from '../../constants/routes';
import useNetworkPublicClient from '../../hooks/useNetworkPublicClient';
import { useNetworkConfigStore } from '../../providers/NetworkConfig/useNetworkConfigStore';
import { useDaoInfoStore } from '../../store/daoInfo/useDaoInfoStore';
import { useRolesStore } from '../../store/roles/useRolesStore';
Expand Down Expand Up @@ -145,7 +146,7 @@ export function RolePaymentDetails({
const { addressPrefix } = useNetworkConfigStore();
const { refreshWithdrawableAmount } = useRolesStore();
const navigate = useNavigate();
const publicClient = usePublicClient();
const publicClient = useNetworkPublicClient();
const canWithdraw = useMemo(() => {
if (
connectedAccount &&
Expand All @@ -162,13 +163,7 @@ export function RolePaymentDetails({
}, [payment.endDate, roleTerms]);

const [modalType, props] = useMemo(() => {
if (
!payment.streamId ||
!payment.contractAddress ||
!roleHatWearerAddress ||
!publicClient ||
!roleHatId
) {
if (!payment.streamId || !payment.contractAddress || !roleHatWearerAddress || !roleHatId) {
return [ModalType.NONE] as const;
}
let recipient = roleHatWearerAddress;
Expand Down
7 changes: 2 additions & 5 deletions src/components/Roles/forms/RoleFormTerms.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ import { useEffect, useMemo } from 'react';
import { useTranslation } from 'react-i18next';
import { toast } from 'sonner';
import { getAddress, Hex } from 'viem';
import { usePublicClient } from 'wagmi';
import { DETAILS_BOX_SHADOW } from '../../../constants/common';
import useNetworkPublicClient from '../../../hooks/useNetworkPublicClient';
import { useRolesStore } from '../../../store/roles/useRolesStore';
import { RoleFormTermStatus, RoleFormValues } from '../../../types/roles';
import { DatePicker } from '../../ui/forms/DatePicker';
Expand Down Expand Up @@ -95,15 +95,12 @@ function RoleTermCreate({
}) {
const { t } = useTranslation('roles');
const { values, errors, setFieldValue } = useFormikContext<RoleFormValues>();
const publicClient = usePublicClient();
const publicClient = useNetworkPublicClient();

const handleAddTerm = async () => {
if (!values.newRoleTerm?.nominee || !values.newRoleTerm?.termEndDate) {
throw new Error('Nominee and Term End Date are required');
}
if (!publicClient) {
throw new Error('Public client is not available');
}
let nomineeAddress = values.newRoleTerm.nominee;
if (!values.newRoleTerm.nominee.startsWith('0x') && !getAddress(values.newRoleTerm.nominee)) {
const ens = await publicClient.getEnsAddress({
Expand Down
6 changes: 3 additions & 3 deletions src/components/SafeSettings/Signers/modals/AddSignerModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ import { Field, FieldAttributes, Formik } from 'formik';
import { useCallback, useRef } from 'react';
import { useTranslation } from 'react-i18next';
import { Address, getAddress } from 'viem';
import { usePublicClient } from 'wagmi';
import * as Yup from 'yup';
import { useValidationAddress } from '../../../../hooks/schemas/common/useValidationAddress';
import useNetworkPublicClient from '../../../../hooks/useNetworkPublicClient';
import { useDaoInfoStore } from '../../../../store/daoInfo/useDaoInfoStore';
import { validateENSName } from '../../../../utils/url';
import SupportTooltip from '../../../ui/badges/SupportTooltip';
Expand All @@ -31,7 +31,7 @@ function AddSignerModal({
}

const { t } = useTranslation(['modals', 'common']);
const publicClient = usePublicClient();
const publicClient = useNetworkPublicClient();
const { addressValidationTest, newSignerValidationTest } = useValidationAddress();
const tooltipContainer = useRef<HTMLDivElement>(null);

Expand All @@ -41,7 +41,7 @@ function AddSignerModal({
async (values: { address: string; threshold: number; nonce: number }) => {
const { address, nonce, threshold } = values;
let validAddress = address;
if (validateENSName(validAddress) && publicClient) {
if (validateENSName(validAddress)) {
const maybeEnsAddress = await publicClient.getEnsAddress({ name: address });
if (maybeEnsAddress) {
validAddress = maybeEnsAddress;
Expand Down
7 changes: 4 additions & 3 deletions src/components/ui/forms/ABISelector.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@ import detectProxyTarget from 'evm-proxy-detection';
import { useEffect, useMemo, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { isAddress } from 'viem';
import { useEnsAddress, usePublicClient } from 'wagmi';
import { useEnsAddress } from 'wagmi';
import { logError } from '../../../helpers/errorLogging';
import useNetworkPublicClient from '../../../hooks/useNetworkPublicClient';
import { useNetworkConfigStore } from '../../../providers/NetworkConfig/useNetworkConfigStore';
import { LabelComponent } from './InputComponent';

Expand All @@ -29,11 +30,11 @@ export default function ABISelector({ target, onChange }: IABISelector) {
const { etherscanAPIUrl } = useNetworkConfigStore();
const { t } = useTranslation('common');
const { data: ensAddress } = useEnsAddress({ name: target?.toLowerCase() });
const client = usePublicClient();
const client = useNetworkPublicClient();

useEffect(() => {
const loadABI = async () => {
if (client && target && ((ensAddress && isAddress(ensAddress)) || isAddress(target))) {
if (target && ((ensAddress && isAddress(ensAddress)) || isAddress(target))) {
try {
const requestFunc = ({ method, params }: { method: any; params: any }) =>
client.request({ method, params });
Expand Down
9 changes: 5 additions & 4 deletions src/components/ui/modals/DelegateModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@ import { abis } from '@fractal-framework/fractal-contracts';
import { Field, FieldAttributes, Formik } from 'formik';
import { useTranslation } from 'react-i18next';
import { getAddress, getContract, zeroAddress } from 'viem';
import { useAccount, usePublicClient, useWalletClient } from 'wagmi';
import { useAccount, useWalletClient } from 'wagmi';
import * as Yup from 'yup';
import LockReleaseAbi from '../../../assets/abi/LockRelease';
import { useValidationAddress } from '../../../hooks/schemas/common/useValidationAddress';
import useNetworkPublicClient from '../../../hooks/useNetworkPublicClient';
import { useGetAccountName } from '../../../hooks/utils/useGetAccountName';
import { useTransaction } from '../../../hooks/utils/useTransaction';
import { useFractal } from '../../../providers/App/AppProvider';
Expand Down Expand Up @@ -36,12 +37,12 @@ export function DelegateModal({ close }: { close: Function }) {
const [contractCall, pending] = useTransaction();
const { addressValidationTest } = useValidationAddress();
const { data: walletClient } = useWalletClient();
const publicClient = usePublicClient();
const publicClient = useNetworkPublicClient();

const submitDelegation = async (values: { address: string }) => {
if (!votesTokenAddress || !walletClient) return;
let validAddress = values.address;
if (validateENSName(validAddress) && publicClient) {
if (validateENSName(validAddress)) {
const maybeEnsAddress = await publicClient.getEnsAddress({ name: values.address });
if (maybeEnsAddress) {
validAddress = maybeEnsAddress;
Expand All @@ -65,7 +66,7 @@ export function DelegateModal({ close }: { close: Function }) {
});
};
const submitLockedDelegation = async (values: { address: string }) => {
if (!lockReleaseAddress || !publicClient || !walletClient) return;
if (!lockReleaseAddress || !walletClient) return;
let validAddress = values.address;
if (validateENSName(validAddress)) {
const maybeEnsAddress = await publicClient.getEnsAddress({ name: values.address });
Expand Down
6 changes: 3 additions & 3 deletions src/components/ui/modals/ForkProposalTemplateModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ import { ChangeEventHandler, useState, useCallback, useEffect } from 'react';
import { useTranslation } from 'react-i18next';
import { useNavigate } from 'react-router-dom';
import { getAddress } from 'viem';
import { usePublicClient } from 'wagmi';
import { DAO_ROUTES } from '../../../constants/routes';
import { useIsSafe } from '../../../hooks/safe/useIsSafe';
import { validateAddress } from '../../../hooks/schemas/common/useValidationAddress';
import useNetworkPublicClient from '../../../hooks/useNetworkPublicClient';
import { useCanUserCreateProposal } from '../../../hooks/utils/useCanUserSubmitProposal';
import { useNetworkConfigStore } from '../../../providers/NetworkConfig/useNetworkConfigStore';
import { useDaoInfoStore } from '../../../store/daoInfo/useDaoInfoStore';
Expand All @@ -31,7 +31,7 @@ export default function ForkProposalTemplateModal({

const { t } = useTranslation('proposalTemplate');
const navigate = useNavigate();
const publicClient = usePublicClient();
const publicClient = useNetworkPublicClient();
const { chain, addressPrefix } = useNetworkConfigStore();
const { subgraphInfo } = useDaoInfoStore();

Expand All @@ -44,7 +44,7 @@ export default function ForkProposalTemplateModal({
};

const validateDAOAddress = useCallback(async () => {
if (!inputValue || isSafeLoading || !publicClient) {
if (!inputValue || isSafeLoading) {
setError('');
return false;
}
Expand Down
Loading
Loading