diff --git a/packages/nextjs/app/[id]/page.tsx b/packages/nextjs/app/[id]/page.tsx index a61ab78..8b2267e 100644 --- a/packages/nextjs/app/[id]/page.tsx +++ b/packages/nextjs/app/[id]/page.tsx @@ -19,7 +19,11 @@ const Multisig: FC = () => { contractAddress: multisigAddress, }); - const { profile, loading: profileLoading } = useProfileMetadata({ + const { + profile, + loading: profileLoading, + refetch: refetchProfile, + } = useProfileMetadata({ address: upAddress as `0x${string}`, enabled: true, }); @@ -36,7 +40,7 @@ const Multisig: FC = () => { />
- +
); diff --git a/packages/nextjs/app/multisig_components/Pool.tsx b/packages/nextjs/app/multisig_components/Pool.tsx index c8d15dc..76c1619 100644 --- a/packages/nextjs/app/multisig_components/Pool.tsx +++ b/packages/nextjs/app/multisig_components/Pool.tsx @@ -10,9 +10,11 @@ import { notification } from "~~/utils/scaffold-eth"; export const Pool = ({ multisigAddress, isHistory = false, + refetchProfile, }: { multisigAddress: `0x${string}`; isHistory?: boolean; + refetchProfile: () => Promise; }) => { const queryClient = useQueryClient(); const { targetNetwork } = useTargetNetwork(); @@ -85,7 +87,12 @@ export const Pool = ({
) : ( filteredTransactions.map(tx => ( - queryClient.invalidateQueries({ queryKey })} /> + queryClient.invalidateQueries({ queryKey })} + refetchProfile={refetchProfile} + /> )) )}
diff --git a/packages/nextjs/app/multisig_components/TransactionItem.tsx b/packages/nextjs/app/multisig_components/TransactionItem.tsx index bc945a1..c2bdf63 100644 --- a/packages/nextjs/app/multisig_components/TransactionItem.tsx +++ b/packages/nextjs/app/multisig_components/TransactionItem.tsx @@ -18,9 +18,9 @@ import { getPoolServerUrl } from "~~/utils/getPoolServerUrl"; import { truncateString } from "~~/utils/helpers"; import { notification } from "~~/utils/scaffold-eth"; -type TransactionItemProps = { tx: TransactionData; onRefetch?: () => void }; +type TransactionItemProps = { tx: TransactionData; onRefetch?: () => void; refetchProfile: () => Promise }; -export const TransactionItem: FC = ({ tx, onRefetch }) => { +export const TransactionItem: FC = ({ tx, onRefetch, refetchProfile }) => { const { address } = useAccount(); const { data: walletClient } = useWalletClient(); const publicClient = usePublicClient(); @@ -138,6 +138,7 @@ export const TransactionItem: FC = ({ tx, onRefetch }) => const executeTransaction = async () => { try { setIsExecuting(true); + if (!contractInfo || !metaMultiSigWallet) { console.log("No contract info"); return; @@ -191,7 +192,12 @@ export const TransactionItem: FC = ({ tx, onRefetch }) => if (onRefetch) { onRefetch(); + + refetchProfile(); } + } else { + notification.error("Error executing transaction"); + setIsExecuting(false); } } catch (e) { //notification.error("Error executing transaction"); @@ -398,8 +404,9 @@ export const TransactionItem: FC = ({ tx, onRefetch }) => ))} - -
{truncateString(formatEther(BigInt(tx.amount)), 9)} LYX
+ {tx.title.trim().toLowerCase() === "transfer funds" && ( +
{truncateString(formatEther(BigInt(tx.amount)), 9)} LYX
+ )} diff --git a/packages/nextjs/app/page.tsx b/packages/nextjs/app/page.tsx index a98d483..6e3686d 100644 --- a/packages/nextjs/app/page.tsx +++ b/packages/nextjs/app/page.tsx @@ -4,6 +4,7 @@ import { useEffect, useState } from "react"; import Link from "next/link"; import WelcomeUI from "./_components/WelcomeUI"; import type { NextPage } from "next"; +import { useIsMounted } from "usehooks-ts"; import { useAccount } from "wagmi"; import { MultisigCard } from "~~/components/cards/MultisigCard"; import { useUPProvider } from "~~/contexts/UPProviderContext"; @@ -11,6 +12,7 @@ import { useScaffoldReadContract } from "~~/hooks/scaffold-eth"; import { getController } from "~~/utils/helpers"; const Home: NextPage = () => { + const isMounted = useIsMounted(); const { address: connectedAddress } = useAccount(); const [controller, setController] = useState(undefined); @@ -41,14 +43,14 @@ const Home: NextPage = () => { })(); }, [connectedAddress, contextAccounts]); - return ( + return isMounted() ? (
{multisigsLoading || registryAddressLoading ? (
- ) : !multisigs || multisigs.length === 0 ? ( + ) : multisigs && multisigs.length === 0 ? (
@@ -77,7 +79,7 @@ const Home: NextPage = () => { )}
- ); + ) : null; }; export default Home; diff --git a/packages/nextjs/hooks/useProfileMetadata.ts b/packages/nextjs/hooks/useProfileMetadata.ts index 5ac43f7..6507066 100644 --- a/packages/nextjs/hooks/useProfileMetadata.ts +++ b/packages/nextjs/hooks/useProfileMetadata.ts @@ -1,7 +1,7 @@ -import { useCallback, useEffect, useMemo, useState } from "react"; import { useTargetNetwork } from "./scaffold-eth"; import { ERC725, ERC725JSONSchema } from "@erc725/erc725.js"; import lsp3ProfileSchema from "@erc725/erc725.js/schemas/LSP3ProfileMetadata.json"; +import { useQuery, useQueryClient } from "@tanstack/react-query"; export interface Profile { name: string; @@ -53,6 +53,7 @@ interface UseProfileMetadataOptions { interface UseProfileMetadataResult { profile: Profile | null; loading: boolean; + refetch: () => Promise; fetchProfile: (address: `0x${string}`) => Promise; } @@ -64,61 +65,54 @@ interface UseProfileMetadataResult { */ export function useProfileMetadata(options: UseProfileMetadataOptions = { enabled: true }): UseProfileMetadataResult { const { address, enabled = true } = options; - const [profile, setProfile] = useState(null); - const [loading, setLoading] = useState(false); - const { targetNetwork } = useTargetNetwork(); - - // Fetch profile data - const fetchProfile = useCallback( - async (address: `0x${string}`): Promise => { - const erc725js = new ERC725( - lsp3ProfileSchema as ERC725JSONSchema[], - address, - targetNetwork.rpcUrls.default.http[0], - { - ipfsGateway: "https://api.universalprofile.cloud/ipfs/", - }, - ); - - try { - setLoading(true); - const profileMetaData = await erc725js.fetchData("LSP3Profile"); - - if ( - profileMetaData.value && - typeof profileMetaData.value === "object" && - "LSP3Profile" in profileMetaData.value - ) { - const fetchedProfile = profileMetaData.value.LSP3Profile; - setProfile(fetchedProfile); - - return fetchedProfile; - } - } catch (error) { - console.log("Cannot fetch universal profile data: ", error); - } finally { - setLoading(false); + const queryClient = useQueryClient(); + + const fetchProfile = async (address: `0x${string}`): Promise => { + const erc725js = new ERC725( + lsp3ProfileSchema as ERC725JSONSchema[], + address, + targetNetwork.rpcUrls.default.http[0], + { + ipfsGateway: "https://api.universalprofile.cloud/ipfs/", + }, + ); + + try { + const profileMetaData = await erc725js.fetchData("LSP3Profile"); + + if ( + profileMetaData.value && + typeof profileMetaData.value === "object" && + "LSP3Profile" in profileMetaData.value + ) { + return profileMetaData.value.LSP3Profile; } - - return null; - }, - [address], - ); - - // Fetch profile automatically if enabled - useEffect(() => { - if (enabled && address) { - fetchProfile(address); + } catch (error) { + console.log("Cannot fetch universal profile data: ", error); } - }, [address, fetchProfile, enabled]); - return useMemo( - () => ({ - profile, - loading, - fetchProfile, - }), - [profile, loading, fetchProfile], - ); + return null; + }; + + const queryKey = ["profile", address]; + + const { + data: profile, + isLoading: loading, + refetch, + } = useQuery({ + queryKey: ["profile", address], + queryFn: () => (address ? fetchProfile(address) : null), + enabled: enabled && !!address, + }); + + return { + profile: profile ?? null, + loading, + refetch: async () => { + queryClient.invalidateQueries({ queryKey }); + }, + fetchProfile, + }; }