From 900aa3ab7c9a36e61f72573262c0ba8bfe1cfed3 Mon Sep 17 00:00:00 2001 From: adrianvrj Date: Fri, 29 Nov 2024 09:34:13 -0600 Subject: [PATCH] feat-282 handling chain switch --- .../components/modules/Fund/FundDonate.tsx | 46 ++++++++------ .../components/modules/Fund/FundVote.tsx | 63 ++++++++++--------- .../components/ui/ConnectWalletButton.tsx | 5 +- .../gostarkme-web/state/connectedWallet.ts | 3 - 4 files changed, 60 insertions(+), 57 deletions(-) diff --git a/frontend/gostarkme-web/components/modules/Fund/FundDonate.tsx b/frontend/gostarkme-web/components/modules/Fund/FundDonate.tsx index 78c7ebc..472f4f4 100644 --- a/frontend/gostarkme-web/components/modules/Fund/FundDonate.tsx +++ b/frontend/gostarkme-web/components/modules/Fund/FundDonate.tsx @@ -3,11 +3,8 @@ import { calculatePorcentage } from "@/app/utils"; import ProgressBar from "@/components/ui/ProgressBar"; import { provider } from "@/constants"; -import { strkAbi } from "@/contracts/abis/strk"; import { addrSTRK } from "@/contracts/addresses"; import { - networkAtom, - networkEnvironmentAtom, walletStarknetkitLatestAtom, } from "@/state/connectedWallet"; import { useAtomValue } from "jotai"; @@ -28,10 +25,15 @@ const FundDonate = ({ currentBalance, goal, addr, icon }: FundDonateProps) => { const [isLoading, setIsLoading] = useState(false); const [localBalance, setLocalBalance] = useState(currentBalance); const wallet = useAtomValue(walletStarknetkitLatestAtom); - const network = useAtomValue(networkAtom); - const networkEnvironment = useAtomValue(networkEnvironmentAtom); + const [network, setNetwork] = useState(wallet?.chainId); + const networkEnvironment = process.env.NEXT_PUBLIC_CHAIN_ID; const progress = calculatePorcentage(localBalance, goal); + const handleNetwork = (chainId?: string, accounts?: string[]) => { + setNetwork(wallet?.chainId); + }; + wallet?.on('networkChanged', handleNetwork); + const handleAmountChange = (e: React.ChangeEvent) => { const value = e.target.value === "" ? "" : Number(e.target.value); setAmount(value); @@ -40,22 +42,22 @@ const FundDonate = ({ currentBalance, goal, addr, icon }: FundDonateProps) => { const waitForTransaction = async (hash: string) => { try { - await provider.waitForTransaction(hash); - return true; + await provider.waitForTransaction(hash); + return true; } catch (error) { - console.error("Error waiting for transaction:", error); - return false; + console.error("Error waiting for transaction:", error); + return false; } }; const handleDonateClick = async (e: React.MouseEvent) => { e.preventDefault(); - + if (amount === "") { setError("This field is required."); return; } - + if (typeof amount === "number" && amount < 0) { setError("The amount cannot be negative."); return; @@ -85,11 +87,11 @@ const FundDonate = ({ currentBalance, goal, addr, icon }: FundDonateProps) => { if (tx) { const isConfirmed = await waitForTransaction(tx.transaction_hash); - + if (isConfirmed) { if (typeof amount === 'number') { setLocalBalance(prev => Number(prev) + amount); - } + } setAmount(""); setError("Transaction successful!"); setTimeout(() => { @@ -126,26 +128,30 @@ const FundDonate = ({ currentBalance, goal, addr, icon }: FundDonateProps) => { /> {error && ( -

+

{error}

)}
- {wallet && !network && ( + {wallet && network !== networkEnvironment && (

Your wallet is currently connected to the wrong network. Please - switch to {networkEnvironment[1]} to continue. + switch to {networkEnvironment} to continue. +

+ )} + {!wallet && ( +

+ Please connect your wallet to donate.

)}
diff --git a/frontend/gostarkme-web/components/modules/Fund/FundVote.tsx b/frontend/gostarkme-web/components/modules/Fund/FundVote.tsx index 370165f..e89a441 100644 --- a/frontend/gostarkme-web/components/modules/Fund/FundVote.tsx +++ b/frontend/gostarkme-web/components/modules/Fund/FundVote.tsx @@ -3,15 +3,13 @@ import { Button } from "@/components/ui/Button"; import ProgressBar from "@/components/ui/ProgressBar"; import { fundAbi } from "@/contracts/abis/fund"; import { - networkAtom, - networkEnvironmentAtom, walletStarknetkitLatestAtom, } from "@/state/connectedWallet"; import { latestTxAtom } from "@/state/latestTx"; import { useAtomValue, useSetAtom } from "jotai"; -import { Contract, InvokeFunctionResponse } from "starknet"; +import { Contract } from "starknet"; import { useRouter } from "next/navigation"; -import {useState, useEffect} from "react"; +import { useState, useEffect } from "react"; interface FundVoteProps { upVotes: number, @@ -21,11 +19,11 @@ interface FundVoteProps { getDetails: () => void, } -export const FundVote = ({ upVotes, upVotesNeeded, addr, setLoading}: FundVoteProps) => { +export const FundVote = ({ upVotes, upVotesNeeded, addr, setLoading }: FundVoteProps) => { const wallet = useAtomValue(walletStarknetkitLatestAtom); - const network = useAtomValue(networkAtom); - const networkEnvironment = useAtomValue(networkEnvironmentAtom); + const [network, setNetwork] = useState(wallet?.chainId); + const networkEnvironment = process.env.NEXT_PUBLIC_CHAIN_ID; const progress = calculatePorcentage(upVotes, upVotesNeeded); @@ -33,26 +31,31 @@ export const FundVote = ({ upVotes, upVotesNeeded, addr, setLoading}: FundVotePr const router = useRouter(); - const [isChecking, setIsChecking] = useState(true); - const [voteStatus, setVoteStatus] = useState(false); + const [isChecking, setIsChecking] = useState(true); + const [voteStatus, setVoteStatus] = useState(false); const [isVoting, setIsVoting] = useState(false); + const handleNetwork = (chainId?: string, accounts?: string[]) => { + setNetwork(wallet?.chainId); + }; + wallet?.on('networkChanged', handleNetwork); + useEffect(() => { const checkVoteStatus = async () => { if (!wallet?.account) { - setIsChecking(false); + setIsChecking(false); return; } - + setIsChecking(true); try { const fundContract = new Contract(fundAbi, addr, wallet.account); - + try { await fundContract.estimate('receiveVote'); setVoteStatus(false); } catch (error: any) { - if (error?.toString().includes('User already voted')) { + if (error?.toString().includes('User already voted')) { setVoteStatus(true); } } @@ -65,7 +68,7 @@ export const FundVote = ({ upVotes, upVotesNeeded, addr, setLoading}: FundVotePr checkVoteStatus(); }, [wallet?.account, addr]); - + const handleVote = async () => { if (!wallet?.account) return; setLoading(true); @@ -97,19 +100,19 @@ export const FundVote = ({ upVotes, upVotesNeeded, addr, setLoading}: FundVotePr {isChecking ? ( //if isChecking is true render a button that checks the vote status
-
) : wallet ? ( // Check if a wallet is connected by evaluating 'wallet' condition voteStatus ? ( //if voteStatus is true button is disabled -
-
) ) : ( // If the wallet is not connected, render a disabled vote button with instructions -
-
)} diff --git a/frontend/gostarkme-web/components/ui/ConnectWalletButton.tsx b/frontend/gostarkme-web/components/ui/ConnectWalletButton.tsx index 24a900f..dc4ab78 100644 --- a/frontend/gostarkme-web/components/ui/ConnectWalletButton.tsx +++ b/frontend/gostarkme-web/components/ui/ConnectWalletButton.tsx @@ -1,12 +1,11 @@ "use client"; import { ARGENT_WEBWALLET_URL, CHAIN_ID, provider } from "@/constants"; -import { networkAtom, walletStarknetkitLatestAtom } from "@/state/connectedWallet"; +import { walletStarknetkitLatestAtom } from "@/state/connectedWallet"; import { useAtom, useSetAtom } from "jotai"; import { connect, disconnect } from "starknetkit"; export default function WalletConnector() { const [wallet, setWallet] = useAtom(walletStarknetkitLatestAtom) - const setNetworkAtom = useSetAtom(networkAtom) const handleConnect = async (event:any) => { try { @@ -22,8 +21,6 @@ export default function WalletConnector() { }, }) - wallet && setNetworkAtom(wallet?.chainId === process.env.NEXT_PUBLIC_NETWORK) - setWallet(wallet) } catch (e) { console.error(e) diff --git a/frontend/gostarkme-web/state/connectedWallet.ts b/frontend/gostarkme-web/state/connectedWallet.ts index 8fce7e8..204d011 100644 --- a/frontend/gostarkme-web/state/connectedWallet.ts +++ b/frontend/gostarkme-web/state/connectedWallet.ts @@ -5,6 +5,3 @@ import { StarknetWindowObject } from "starknetkit"; export const walletStarknetkitLatestAtom = atomWithReset< StarknetWindowObject | null | undefined >(undefined); - -export const networkAtom = atom(false); -export const networkEnvironmentAtom = atom(["Mainnet", "Sepolia", "Devnet"]);