diff --git a/packages/nextjs/components/wallet/ERC20TokenBalance.tsx b/packages/nextjs/components/wallet/ERC20TokenBalance.tsx index cf51213..a19f5a5 100644 --- a/packages/nextjs/components/wallet/ERC20TokenBalance.tsx +++ b/packages/nextjs/components/wallet/ERC20TokenBalance.tsx @@ -2,6 +2,7 @@ import { useEffect, useState } from "react"; import { publicClientSelector } from "./publicClientSelector"; import { formatEther } from "viem"; import { parseAbi } from "viem"; +import { useSharedState } from "~~/sharedStateContext"; interface ERC20TokensProps { networkName: string; @@ -16,6 +17,7 @@ const abi = parseAbi([ export const ERC20TokenBalance = ({ networkName, tokenAddress, address }: ERC20TokensProps) => { const [balance, setBalance] = useState(0); + const { isConfirmed } = useSharedState(); const publicClient = publicClientSelector(networkName); @@ -37,6 +39,9 @@ export const ERC20TokenBalance = ({ networkName, tokenAddress, address }: ERC20T useEffect(() => { getBalance(); + if (isConfirmed) { + getBalance(); + } }); return ( diff --git a/packages/nextjs/components/wallet/ERC20TokenTransaction.tsx b/packages/nextjs/components/wallet/ERC20TokenTransaction.tsx index 6fe6908..b0cd537 100644 --- a/packages/nextjs/components/wallet/ERC20TokenTransaction.tsx +++ b/packages/nextjs/components/wallet/ERC20TokenTransaction.tsx @@ -6,6 +6,7 @@ import { parseAbi, parseEther } from "viem"; import { EnvelopeIcon } from "@heroicons/react/24/outline"; import { Spinner } from "~~/components/assets/Spinner"; import { AddressInput } from "~~/components/scaffold-eth/Input"; +import { useSharedState } from "~~/sharedStateContext"; import { notification } from "~~/utils/scaffold-eth"; interface ERC20TokenTransactionProps { @@ -24,7 +25,8 @@ export const ERC20TokenTransaction = ({ account, tokenAddress, selectedChain }: const [to, setTo] = useState(""); const [amount, setAmount] = useState(""); const [isSent, setIsSent] = useState(false); - const [isConfirmed, setIsConfirmed] = useState(false); + // const [isConfirmed, setIsConfirmed] = useState(false); + const { isConfirmed, setIsConfirmed } = useSharedState(); const [isLoading, setIsLoading] = useState(false); const walletClient = walletClientSelector(selectedChain, account); diff --git a/packages/nextjs/components/wallet/NativeTokenBalance.tsx b/packages/nextjs/components/wallet/NativeTokenBalance.tsx index 5bbdd6a..eb044b4 100644 --- a/packages/nextjs/components/wallet/NativeTokenBalance.tsx +++ b/packages/nextjs/components/wallet/NativeTokenBalance.tsx @@ -1,6 +1,7 @@ import { useEffect, useState } from "react"; import { publicClientSelector } from "./publicClientSelector"; import { formatEther } from "viem"; +import { useSharedState } from "~~/sharedStateContext"; interface NativeTokenBalanceProps { address: string; @@ -9,6 +10,7 @@ interface NativeTokenBalanceProps { export const NativeTokenBalance = ({ address, networkName }: NativeTokenBalanceProps) => { const [balance, setBalance] = useState(BigInt(0)); + const { isConfirmed } = useSharedState(); useEffect(() => { const fetchBalance = async () => { @@ -21,8 +23,11 @@ export const NativeTokenBalance = ({ address, networkName }: NativeTokenBalanceP if (address) { fetchBalance(); + if (isConfirmed) { + fetchBalance(); + } } - }, [address, networkName]); + }, [address, networkName, isConfirmed]); return <>{formatEther(balance)}; }; diff --git a/packages/nextjs/components/wallet/NativeTokenTransaction.tsx b/packages/nextjs/components/wallet/NativeTokenTransaction.tsx index b456603..03d5e8c 100644 --- a/packages/nextjs/components/wallet/NativeTokenTransaction.tsx +++ b/packages/nextjs/components/wallet/NativeTokenTransaction.tsx @@ -1,7 +1,12 @@ -import { useState } from "react"; +import { useEffect, useState } from "react"; +import { publicClientSelector } from "./publicClientSelector"; import { walletClientSelector } from "./walletClientSelector"; import { parseEther } from "viem"; +import { EnvelopeIcon } from "@heroicons/react/24/outline"; +import { Spinner } from "~~/components/assets/Spinner"; import { AddressInput, EtherInput } from "~~/components/scaffold-eth/Input"; +import { useSharedState } from "~~/sharedStateContext"; +import { notification } from "~~/utils/scaffold-eth"; interface NativeTokenTransactionProps { account: any; @@ -11,19 +16,42 @@ interface NativeTokenTransactionProps { export const NativeTokenTransaction = ({ account, selectedChain }: NativeTokenTransactionProps) => { const [to, setTo] = useState(""); const [amount, setAmount] = useState(""); + const { isConfirmed, setIsConfirmed } = useSharedState(); + const [isLoading, setIsLoading] = useState(false); + const [isSent, setIsSent] = useState(false); const walletClient = walletClientSelector(selectedChain, account); + const publicClient = publicClientSelector(selectedChain); const txRequest = async () => { - if (walletClient) { + if (walletClient && publicClient) { const transaction = await walletClient.sendTransaction({ to: to, value: parseEther(amount), }); console.log(transaction); + setIsSent(true); + setIsLoading(true); + + const tx = await publicClient.waitForTransactionReceipt({ hash: transaction }); + if (tx.status === "success") { + setIsConfirmed(true); + setIsLoading(false); + } } }; + useEffect(() => { + if (isSent) { + notification.success("Transaction successfully submitted"); + setIsSent(false); + } + if (isConfirmed && !isSent) { + notification.success("Transaction successfully confirmed"); + setIsConfirmed(false); + } + }, [isSent, isConfirmed, setIsConfirmed]); + return ( <> @@ -38,7 +66,16 @@ export const NativeTokenTransaction = ({ account, selectedChain }: NativeTokenTr txRequest(); }} > - Send + {!isConfirmed && isLoading ? ( +
+ +
+ ) : ( +
+ + Send +
+ )} ); diff --git a/packages/nextjs/sharedStateContext.tsx b/packages/nextjs/sharedStateContext.tsx index 082b6a4..2824bf3 100644 --- a/packages/nextjs/sharedStateContext.tsx +++ b/packages/nextjs/sharedStateContext.tsx @@ -7,6 +7,8 @@ interface SharedStateContextProps { setSelectedTokenAddress: (value: string) => void; selectedTokenName: string; setSelectedTokenName: (value: string) => void; + isConfirmed: boolean; + setIsConfirmed: (value: boolean) => void; } const SharedStateContext = createContext(undefined); @@ -15,6 +17,7 @@ export const SharedStateProvider: React.FC<{ children: ReactNode }> = ({ childre const [selectedChain, setSelectedChain] = useState("mainnet"); const [selectedTokenAddress, setSelectedTokenAddress] = useState("nativeToken"); const [selectedTokenName, setSelectedTokenName] = useState("ETH"); + const [isConfirmed, setIsConfirmed] = useState(false); return ( = ({ childre setSelectedTokenAddress, selectedTokenName, setSelectedTokenName, + isConfirmed, + setIsConfirmed, }} > {children}