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

[Issue | No Issue assigned] Various loading and error handling cleanup #2615

Merged
merged 67 commits into from
Dec 17, 2024
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
Show all changes
67 commits
Select commit Hold shift + click to select a range
5e64ab2
Refactor network configuration handling and introduce Zustand store f…
Da-Colon Dec 5, 2024
44e090b
Refactor network configuration imports to use new Zustand store
Da-Colon Dec 5, 2024
1915478
Remove unused network configuration hook and clean up imports
Da-Colon Dec 5, 2024
dae8741
Refactor SafeMenuItem and related hooks to simplify network handling …
Da-Colon Dec 5, 2024
dc95f17
Refactor DaoHierarchyNode to remove unused chainId and streamline net…
Da-Colon Dec 5, 2024
19dcca0
Merge branch 'develop' of github.com:decentdao/decent-interface into …
Da-Colon Dec 6, 2024
c894027
refactor: simplify WalletMenu component by removing containerRef prop
Da-Colon Dec 6, 2024
32e1ec5
refactor: update network config hook usage to useNetworkConfigStore
Da-Colon Dec 6, 2024
047d978
refactor: reorganize DAOInfoCard layout by grouping FavoriteIcon and …
Da-Colon Dec 6, 2024
2e3b524
refactor: add network icon to DAOInfoCard component
Da-Colon Dec 6, 2024
1091123
refactor: rename NetworkSelector component and update import paths
Da-Colon Dec 6, 2024
1845811
feat: add DropdownMenu component and remove obsolete NetworkSelector
Da-Colon Dec 6, 2024
d226d81
refactor: streamline DAOInfoCard component by enhancing layout and im…
Da-Colon Dec 6, 2024
0ff3f84
refactor: update network configuration to use mainnet instead of sepolia
Da-Colon Dec 6, 2024
736377c
feat: implement DropdownMenu for network selection in EstablishEssent…
Da-Colon Dec 6, 2024
30d8411
refactor: adjust label alignment in EstablishEssentials component
Da-Colon Dec 6, 2024
e2197ba
refactor: adjust icon size and text style in DropdownMenu component
Da-Colon Dec 6, 2024
f3f971e
Merge branch 'develop' of github.com:decentdao/decent-interface into …
Da-Colon Dec 6, 2024
56b0eda
feat: implement dynamic Wagmi configuration and update providers to u…
Da-Colon Dec 6, 2024
a3f879b
refactor: remove unused dynamic Wagmi configuration hook
Da-Colon Dec 7, 2024
999f0f6
feat: integrate automatic chain switching and update Wagmi configurat…
Da-Colon Dec 7, 2024
3d324ce
Refactor useHatsTree and useKeyValuePairs hooks to remove unused vari…
Da-Colon Dec 9, 2024
d1f5bb0
Add error handling for smart account predictions and validate smart a…
Da-Colon Dec 9, 2024
fb9c751
feat: integrate chain switching functionality in EstablishEssentials …
Da-Colon Dec 10, 2024
af55ec0
Merge branch 'issue/noIssue-state-loading-cleanup' of github.com:dece…
Da-Colon Dec 10, 2024
d11ff98
Merge branch 'issue/2565-network-config-updates' of github.com:decent…
Da-Colon Dec 10, 2024
5adc033
Update useHatsTree hook to accept safeAddress parameter and adjust re…
Da-Colon Dec 11, 2024
5337915
Merge branch 'issue/noIssue-state-loading-cleanup' of github.com:dece…
Da-Colon Dec 11, 2024
c05f818
Merge branch 'issue/2565-network-config-updates' of github.com:decent…
Da-Colon Dec 11, 2024
23cab88
Delay setting current config after switching chain to ensure proper s…
Da-Colon Dec 12, 2024
9094eb3
Remove SafesList component and its associated logic
Da-Colon Dec 12, 2024
17bc618
Add null check for modules and improve safeAddress validation in useG…
Da-Colon Dec 12, 2024
fc918d5
Merge branch 'issue/noIssue-state-loading-cleanup' of github.com:dece…
Da-Colon Dec 12, 2024
9f2ffaf
Merge branch 'issue/2565-network-config-updates' of github.com:decent…
Da-Colon Dec 12, 2024
32c9961
Add error handling for uninitialized modules in useGovernanceContract…
Da-Colon Dec 12, 2024
d76ec5b
Refactor loadGovernanceContracts to accept daoModules parameter
Da-Colon Dec 12, 2024
113d28f
Update error message for invalid DAO search to reflect support for al…
Da-Colon Dec 13, 2024
d2319e5
Enhance useIsSafe hook to search across all supported networks and re…
Da-Colon Dec 13, 2024
2bb83c1
Refactor DAOSearch to display multiple network prefixes in SearchDisp…
Da-Colon Dec 13, 2024
8dab85b
Refactor DAOSearch component to remove extra gap
Da-Colon Dec 13, 2024
25866db
Refactor useGovernanceContracts to streamline token address assignmen…
Da-Colon Dec 13, 2024
9dbe57e
Merge branch 'develop' of github.com:decentdao/decent-interface into …
Da-Colon Dec 13, 2024
ef7a3de
revert: changes made to hook.
Da-Colon Dec 13, 2024
2118a5d
Add useResolveAddressMultiChain hook for multi-chain address resolution
Da-Colon Dec 14, 2024
1e8292a
Refactor DAOSearch to use resolved addresses with chain IDs and updat…
Da-Colon Dec 14, 2024
a25fd55
move translation initialization
Da-Colon Dec 14, 2024
8dace81
Remove 'wrongNetwork' type from LoadingProblem component and its usag…
Da-Colon Dec 14, 2024
d4aff40
resetHats store when safeAddress changes
Da-Colon Dec 14, 2024
4e673cb
remove role store reset, since its not in useKeyValuePairs
Da-Colon Dec 14, 2024
359cb0e
Merge branch 'develop' of github.com:decentdao/decent-interface into …
Da-Colon Dec 14, 2024
0352fdd
Merge branch 'issue/noIssue-state-loading-cleanup' of github.com:dece…
Da-Colon Dec 14, 2024
5b8556b
Merge branch 'issue/2565-network-config-updates' of github.com:decent…
Da-Colon Dec 14, 2024
992c141
Merge branch 'issue/2565-network-config-extended' of github.com:decen…
Da-Colon Dec 14, 2024
89b2989
Merge pull request #2630 from decentdao/issue/2565-cross-chain-dao-se…
Da-Colon Dec 16, 2024
c7b41c5
Merge pull request #2609 from decentdao/issue/2565-network-config-ext…
Da-Colon Dec 16, 2024
cb0e07f
We only really need to search for ENS names on mainnet
adamgall Dec 16, 2024
cba45d2
Merge pull request #2636 from decentdao/only-mainnet-ens-search
Da-Colon Dec 16, 2024
c44efe8
Refactor useResolveAddressMultiChain to utilize mainnet client for EN…
Da-Colon Dec 16, 2024
6cdc66e
Rename useResolveAddressMultiChain to useResolveENSName and refactor …
Da-Colon Dec 16, 2024
8fc85e2
Refactor useSearchDao to utilize useResolveENSName for address resolu…
Da-Colon Dec 16, 2024
98d5e0a
Refactor useSearchDao to use resolveENSName for address resolution an…
Da-Colon Dec 16, 2024
30b14dc
remove try/catch
Da-Colon Dec 16, 2024
5d4c6fd
Merge pull request #2637 from decentdao/issue/2565-resolve-mainnet-ens
Da-Colon Dec 16, 2024
3a6d01e
wait for wallet to be fetch before trying to switch chain
Da-Colon Dec 17, 2024
63c1575
refactor: update useWalletClient to use isFetchedAfterMount for chain…
Da-Colon Dec 17, 2024
fec54ef
Merge pull request #2595 from decentdao/issue/2565-network-config-upd…
Da-Colon Dec 17, 2024
16f83aa
Merge branch 'develop' into issue/noIssue-state-loading-cleanup
Da-Colon Dec 17, 2024
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
47 changes: 0 additions & 47 deletions src/components/ui/menus/SafesMenu/SafesList.tsx
Da-Colon marked this conversation as resolved.
Show resolved Hide resolved

This file was deleted.

196 changes: 101 additions & 95 deletions src/hooks/DAO/loaders/useGovernanceContracts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import LockReleaseAbi from '../../../assets/abi/LockRelease';
import { useFractal } from '../../../providers/App/AppProvider';
import { GovernanceContractAction } from '../../../providers/App/governanceContracts/action';
import { useDaoInfoStore } from '../../../store/daoInfo/useDaoInfoStore';
import { DecentModule } from '../../../types';
import { getAzoriusModuleFromModules } from '../../../utils';
import { useAddressContractType } from '../../utils/useAddressContractType';
import useVotingStrategyAddress from '../../utils/useVotingStrategiesAddresses';
Expand All @@ -23,114 +24,119 @@ export const useGovernanceContracts = () => {

const safeAddress = safe?.address;

const loadGovernanceContracts = useCallback(async () => {
const azoriusModule = getAzoriusModuleFromModules(modules ?? []);
const loadGovernanceContracts = useCallback(
async (daoModules: DecentModule[]) => {
const azoriusModule = getAzoriusModuleFromModules(daoModules);

const votingStrategies = await getVotingStrategies();

if (!azoriusModule || !votingStrategies) {
action.dispatch({
type: GovernanceContractAction.SET_GOVERNANCE_CONTRACT_ADDRESSES,
payload: {},
});
return;
}

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

let linearVotingErc20Address: Address | undefined;
let linearVotingErc721Address: Address | undefined;
let linearVotingErc20WithHatsWhitelistingAddress: Address | undefined;
let linearVotingErc721WithHatsWhitelistingAddress: Address | undefined;
let votesTokenAddress: Address | undefined;
let lockReleaseAddress: Address | undefined;

const setGovTokenAddress = async (erc20VotingStrategyAddress: Address) => {
if (votesTokenAddress) {
const votingStrategies = await getVotingStrategies();
if (!azoriusModule || !votingStrategies) {
action.dispatch({
type: GovernanceContractAction.SET_GOVERNANCE_CONTRACT_ADDRESSES,
payload: {},
});
return;
}
const ozLinearVotingContract = getContract({
abi: abis.LinearERC20Voting,
address: erc20VotingStrategyAddress,
client: publicClient,
});

const govTokenAddress = await ozLinearVotingContract.read.governanceToken();
// govTokenAddress might be either
// - a valid VotesERC20 contract
// - a valid LockRelease contract
// - or none of these which is against business logic
if (!publicClient) {
throw new Error('Public Client is not set!');
}

const { isVotesErc20 } = await getAddressContractType(govTokenAddress);
let linearVotingErc20Address: Address | undefined;
let linearVotingErc721Address: Address | undefined;
let linearVotingErc20WithHatsWhitelistingAddress: Address | undefined;
let linearVotingErc721WithHatsWhitelistingAddress: Address | undefined;
let votesTokenAddress: Address | undefined;
let lockReleaseAddress: Address | undefined;

if (isVotesErc20) {
votesTokenAddress = govTokenAddress;
} else {
const possibleLockRelease = getContract({
address: govTokenAddress,
abi: LockReleaseAbi,
client: { public: publicClient },
const setGovTokenAddress = async (erc20VotingStrategyAddress: Address) => {
if (votesTokenAddress) {
return;
}
const ozLinearVotingContract = getContract({
abi: abis.LinearERC20Voting,
address: erc20VotingStrategyAddress,
client: publicClient,
});

try {
const lockedTokenAddress = await possibleLockRelease.read.token();
lockReleaseAddress = govTokenAddress;
votesTokenAddress = lockedTokenAddress;
} catch {
throw new Error('Unknown governance token type');
const govTokenAddress = await ozLinearVotingContract.read.governanceToken();
// govTokenAddress might be either
// - a valid VotesERC20 contract
// - a valid LockRelease contract
// - or none of these which is against business logic

const { isVotesErc20 } = await getAddressContractType(govTokenAddress);

if (isVotesErc20) {
votesTokenAddress = govTokenAddress;
} else {
const possibleLockRelease = getContract({
address: govTokenAddress,
abi: LockReleaseAbi,
client: { public: publicClient },
});

try {
votesTokenAddress = await possibleLockRelease.read.token();
lockReleaseAddress = govTokenAddress;
} catch {
throw new Error('Unknown governance token type');
}
}
};

await Promise.all(
votingStrategies.map(async votingStrategy => {
const {
strategyAddress,
isLinearVotingErc20,
isLinearVotingErc721,
isLinearVotingErc20WithHatsProposalCreation,
isLinearVotingErc721WithHatsProposalCreation,
} = votingStrategy;
if (isLinearVotingErc20) {
linearVotingErc20Address = strategyAddress;
await setGovTokenAddress(strategyAddress);
} else if (isLinearVotingErc721) {
linearVotingErc721Address = strategyAddress;
} else if (isLinearVotingErc20WithHatsProposalCreation) {
linearVotingErc20WithHatsWhitelistingAddress = strategyAddress;
await setGovTokenAddress(strategyAddress);
} else if (isLinearVotingErc721WithHatsProposalCreation) {
linearVotingErc721WithHatsWhitelistingAddress = strategyAddress;
}
}),
);

if (
linearVotingErc20Address ||
linearVotingErc20WithHatsWhitelistingAddress ||
linearVotingErc721Address ||
linearVotingErc721WithHatsWhitelistingAddress
) {
action.dispatch({
type: GovernanceContractAction.SET_GOVERNANCE_CONTRACT_ADDRESSES,
payload: {
linearVotingErc20Address,
linearVotingErc20WithHatsWhitelistingAddress,
linearVotingErc721Address,
linearVotingErc721WithHatsWhitelistingAddress,
votesTokenAddress,
lockReleaseAddress,
moduleAzoriusAddress: azoriusModule.moduleAddress,
},
});
}
};

await Promise.all(
votingStrategies.map(async votingStrategy => {
const {
strategyAddress,
isLinearVotingErc20,
isLinearVotingErc721,
isLinearVotingErc20WithHatsProposalCreation,
isLinearVotingErc721WithHatsProposalCreation,
} = votingStrategy;
if (isLinearVotingErc20) {
linearVotingErc20Address = strategyAddress;
await setGovTokenAddress(strategyAddress);
} else if (isLinearVotingErc721) {
linearVotingErc721Address = strategyAddress;
} else if (isLinearVotingErc20WithHatsProposalCreation) {
linearVotingErc20WithHatsWhitelistingAddress = strategyAddress;
await setGovTokenAddress(strategyAddress);
} else if (isLinearVotingErc721WithHatsProposalCreation) {
linearVotingErc721WithHatsWhitelistingAddress = strategyAddress;
}
}),
);
},
[action, getVotingStrategies, publicClient, getAddressContractType],
);

useEffect(() => {
if (
linearVotingErc20Address ||
linearVotingErc20WithHatsWhitelistingAddress ||
linearVotingErc721Address ||
linearVotingErc721WithHatsWhitelistingAddress
safeAddress !== undefined &&
currentValidAddress.current !== safeAddress &&
modules !== null
) {
action.dispatch({
type: GovernanceContractAction.SET_GOVERNANCE_CONTRACT_ADDRESSES,
payload: {
linearVotingErc20Address,
linearVotingErc20WithHatsWhitelistingAddress,
linearVotingErc721Address,
linearVotingErc721WithHatsWhitelistingAddress,
votesTokenAddress,
lockReleaseAddress,
moduleAzoriusAddress: azoriusModule.moduleAddress,
},
});
}
}, [action, modules, getVotingStrategies, publicClient, getAddressContractType]);

useEffect(() => {
if (currentValidAddress.current !== safeAddress && modules !== null) {
loadGovernanceContracts();
loadGovernanceContracts(modules);
currentValidAddress.current = safeAddress;
}
if (!safeAddress) {
Expand Down
11 changes: 0 additions & 11 deletions src/hooks/DAO/loaders/useHatsTree.ts
Da-Colon marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -10,35 +10,30 @@ import { SablierV2LockupLinearAbi } from '../../../assets/abi/SablierV2LockupLin
import { useFractal } from '../../../providers/App/AppProvider';
import useIPFSClient from '../../../providers/App/hooks/useIPFSClient';
import { useNetworkConfig } from '../../../providers/NetworkConfig/NetworkConfigProvider';
import { useDaoInfoStore } from '../../../store/daoInfo/useDaoInfoStore';
import { DecentHatsError } from '../../../store/roles/rolesStoreUtils';
import { useRolesStore } from '../../../store/roles/useRolesStore';
import { SablierPayment } from '../../../types/roles';
import { convertStreamIdToBigInt } from '../../streams/useCreateSablierStream';
import { CacheExpiry, CacheKeys } from '../../utils/cache/cacheDefaults';
import { getValue, setValue } from '../../utils/cache/useLocalStorage';
import { useParseSafeAddress } from '../useParseSafeAddress';

const hatsSubgraphClient = new HatsSubgraphClient({});

const useHatsTree = () => {
const { t } = useTranslation('roles');
const { safeAddress } = useParseSafeAddress();
const {
governanceContracts: {
linearVotingErc20WithHatsWhitelistingAddress,
linearVotingErc721WithHatsWhitelistingAddress,
},
} = useFractal();
const { safe } = useDaoInfoStore();
const {
hatsTreeId,
contextChainId,
hatsTree,
streamsFetched,
setHatsTree,
updateRolesWithStreams,
resetHatsStore,
} = useRolesStore();

const ipfsClient = useIPFSClient();
Expand Down Expand Up @@ -301,12 +296,6 @@ const useHatsTree = () => {

getHatsStreams();
}, [hatsTree, updateRolesWithStreams, getPaymentStreams, streamsFetched]);

useEffect(() => {
if (safeAddress && safe?.address && safeAddress !== safe.address && hatsTree) {
resetHatsStore();
}
}, [resetHatsStore, safeAddress, safe?.address, hatsTree]);
Da-Colon marked this conversation as resolved.
Show resolved Hide resolved
};

export { useHatsTree };
17 changes: 10 additions & 7 deletions src/hooks/DAO/useKeyValuePairs.ts
Da-Colon marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { abis } from '@fractal-framework/fractal-contracts';
import { hatIdToTreeId } from '@hatsprotocol/sdk-v1-core';
import { useEffect } from 'react';
import { useSearchParams } from 'react-router-dom';
import { Address, GetContractEventsReturnType, getContract } from 'viem';
import { usePublicClient } from 'wagmi';
import { logError } from '../../helpers/errorLogging';
Expand Down Expand Up @@ -98,15 +97,12 @@ const useKeyValuePairs = () => {
chain,
contracts: { keyValuePairs, sablierV2LockupLinear },
} = useNetworkConfig();
const { setHatKeyValuePairData } = useRolesStore();
const [searchParams] = useSearchParams();
const { setHatKeyValuePairData, resetHatsStore } = useRolesStore();

const safeAddress = node.safe?.address;

useEffect(() => {
const safeParam = searchParams.get('dao');

if (!publicClient || !safeAddress || safeAddress !== safeParam?.split(':')[1]) {
if (!safeAddress || !publicClient) {
return;
}

Expand Down Expand Up @@ -160,10 +156,17 @@ const useKeyValuePairs = () => {
keyValuePairs,
safeAddress,
publicClient,
searchParams,
setHatKeyValuePairData,
sablierV2LockupLinear,
]);

useEffect(() => {
if (!safeAddress) {
return;
}

resetHatsStore();
}, [resetHatsStore, safeAddress]);
};

export { useKeyValuePairs };
3 changes: 3 additions & 0 deletions src/hooks/utils/useCreateRoles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -915,6 +915,9 @@ export default function useCreateRoles() {
throw new Error('Cannot prepare transactions for edited role without smart address');
}
const newPredictedHatSmartAccount = await predictSmartAccount(BigInt(formHat.id));
if (!newPredictedHatSmartAccount) {
throw new Error('Cannot predict smart account');
}
const newStreamTxData = createBatchLinearStreamCreationTx(
newStreamsOnHat.map(stream => ({ ...stream, recipient: newPredictedHatSmartAccount })),
);
Expand Down
Loading
Loading