Skip to content

Commit

Permalink
Fix wallet connection and balance validation
Browse files Browse the repository at this point in the history
  • Loading branch information
Jennievon committed Aug 6, 2024
1 parent 56ffa28 commit e419680
Show file tree
Hide file tree
Showing 5 changed files with 115 additions and 106 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useEffect } from "react";
import React from "react";
import {
CardHeader,
CardTitle,
Expand Down Expand Up @@ -58,6 +58,13 @@ export default function Dashboard() {

const onSubmit = React.useCallback(
async (data: any) => {
if (amount > fromTokenBalance) {
setError("amount", {
type: "manual",
message: "Amount must be less than balance",
});
return;
}
try {
setLoading(true);
const transactionData = { ...data, receiver: receiver || address };
Expand Down Expand Up @@ -143,10 +150,8 @@ export default function Dashboard() {

React.useEffect(() => {
const storedReceiver = handleStorage.get("tenBridgeReceiver");
if (storedReceiver) {
setValue("receiver", storedReceiver);
}
}, []);
setValue("receiver", storedReceiver ? storedReceiver : address);
}, [address]);

React.useEffect(() => {
const fetchTokenBalance = async (token: Token) => {
Expand All @@ -169,7 +174,13 @@ export default function Dashboard() {
fetchTokenBalance(selectedToken);
}
}
}, [fromChain, token, amount, receiver, provider, isL1ToL2]);
}, [fromChain, token, amount, receiver, provider, isL1ToL2, walletConnected]);

React.useEffect(() => {
setValue("fromChain", isL1ToL2 ? L1CHAINS[0].value : L2CHAINS[0].value);
setValue("toChain", isL1ToL2 ? L2CHAINS[0].value : L1CHAINS[0].value);
setValue("token", isL1ToL2 ? L1TOKENS[0].value : L2TOKENS[0].value);
}, [isL1ToL2]);

return (
<div className="h-full flex flex-col space-y-4 justify-center items-center">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,50 +25,37 @@ const WalletProvider = ({ children }: WalletConnectionProviderProps) => {
const [address, setAddress] = useState<string>("");
const [isL1ToL2, setIsL1ToL2] = useState<boolean>(true);

useEffect(() => {
const storedAddress = handleStorage.get("walletAddress");
const storedIsL1ToL2 = handleStorage.get("isL1ToL2") === "true";

if (storedAddress) {
setAddress(storedAddress);
setIsWalletConnected(true);
setIsL1ToL2(storedIsL1ToL2);
}
const initializeProvider = async () => {
const detectedProvider = await getEthereumProvider();
setProvider(detectedProvider);

const initializeProvider = async () => {
const detectedProvider = await getEthereumProvider();
setProvider(detectedProvider);
const newSigner = initializeSigner(provider);
setSigner(newSigner);

const chainId = await detectedProvider.request({
method: requestMethods.getChainId,
});

const isL1 = chainId === WalletNetwork.L1_SEPOLIA;
setIsL1ToL2(isL1);
};
const chainId = await detectedProvider.send(requestMethods.getChainId, []);

initializeProvider();
}, []);
const isL1 = chainId === WalletNetwork.L1_SEPOLIA;
setIsL1ToL2(isL1);
};

const connectWallet = async () => {
try {
const detectedProvider = await getEthereumProvider();
setProvider(detectedProvider);

const chainId = await detectedProvider.request({
method: requestMethods.getChainId,
});
const accounts = await detectedProvider.send(
requestMethods.connectAccounts,
[]
);

const isL1 = chainId === WalletNetwork.L1_SEPOLIA;
setIsL1ToL2(isL1);
const newSigner = initializeSigner(detectedProvider);
setSigner(newSigner);

const accounts = await detectedProvider.request({
method: requestMethods.connectAccounts,
});
setIsWalletConnected(true);
setAddress(accounts[0]);
handleStorage.save("walletAddress", accounts[0]);
handleStorage.save("isL1ToL2", isL1.toString());
handleStorage.save("isL1ToL2", isL1ToL2.toString());

toast({
title: "Connected",
description: "Connected to wallet! Account: " + accounts[0],
Expand All @@ -94,6 +81,9 @@ const WalletProvider = ({ children }: WalletConnectionProviderProps) => {
setIsWalletConnected(false);
handleStorage.remove("walletAddress");
handleStorage.remove("isL1ToL2");
handleStorage.remove("tenBridgeReceiver");
window.location.reload();

toast({
title: "Disconnected",
description: "Disconnected from wallet",
Expand All @@ -111,14 +101,17 @@ const WalletProvider = ({ children }: WalletConnectionProviderProps) => {
};

useEffect(() => {
if (provider) {
const newSigner = initializeSigner(provider);
setSigner(newSigner);
const storedAddress = handleStorage.get("walletAddress");
const storedIsL1ToL2 = handleStorage.get("isL1ToL2") === "true";

const cleanup = setupEventListeners(provider, setAddress);
return cleanup;
if (storedAddress) {
setAddress(storedAddress);
setIsWalletConnected(true);
setIsL1ToL2(storedIsL1ToL2);
}
}, [provider]);

initializeProvider();
}, []);

const switchNetwork = async () => {
if (!provider) {
Expand All @@ -133,13 +126,15 @@ const WalletProvider = ({ children }: WalletConnectionProviderProps) => {
const desiredNetwork = isL1ToL2
? WalletNetwork.L2_TEN_TESTNET
: WalletNetwork.L1_SEPOLIA;
await provider.request({
method: requestMethods.switchNetwork,
params: [{ chainId: desiredNetwork }],
});

await provider.request(requestMethods.switchNetwork, [
{ chainId: desiredNetwork },
]);

const isL1 = desiredNetwork === WalletNetwork.L1_SEPOLIA;
setIsL1ToL2(isL1);
handleStorage.save("isL1ToL2", isL1.toString());

toast({
title: "Network Switched",
description: `Switched to ${
Expand Down Expand Up @@ -167,6 +162,16 @@ const WalletProvider = ({ children }: WalletConnectionProviderProps) => {
}
};

useEffect(() => {
if (provider) {
const newSigner = initializeSigner(provider);
setSigner(newSigner);

const cleanup = setupEventListeners(provider, setAddress);
return cleanup;
}
}, [provider]);

const value = {
provider,
signer,
Expand Down
102 changes: 45 additions & 57 deletions contracts/src/bridge/frontend/src/hooks/useContract.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import Bridge from "../../artifacts/IBridge.sol/IBridge.json";
import ManagementContractAbi from "../../artifacts/ManagementContract.sol/ManagementContract.json";
import IMessageBusAbi from "../../artifacts/IMessageBus.sol/IMessageBus.json";
import { useWalletStore } from "../components/providers/wallet-provider";
import { showToast, toast } from "../components/ui/use-toast";
import { toast } from "../components/ui/use-toast";
import { ContractState, ToastType } from "../types";
import { useGeneralService } from "../services/useGeneralService";
import { StandardMerkleTree } from "@openzeppelin/merkle-tree";
Expand All @@ -26,64 +26,56 @@ export const useContract = () => {
}, [obscuroConfig, isObscuroConfigLoading]);

useEffect(() => {
if (isObscuroConfigLoading) {
return;
}
if (!obscuroConfig) {
showToast(ToastType.DESTRUCTIVE, "Config not found");
return;
}
const setupContracts = async () => {
if (!memoizedConfig || !provider || !signer) {
return;
}

if (!memoizedConfig) {
showToast(ToastType.DESTRUCTIVE, "Config not found");
return;
}
const l1BridgeAddress = memoizedConfig.ImportantContracts.L1Bridge;
const l2BridgeAddress = memoizedConfig.ImportantContracts.L2Bridge;
const l1MessageBusAddress = memoizedConfig.MessageBusAddress;
const l2MessageBusAddress = memoizedConfig.L2MessageBusAddress;
const managementContractAddress =
memoizedConfig.ManagementContractAddress;

const wallet = new ethers.Wallet(privateKey as string, provider);

const address = isL1ToL2 ? l1BridgeAddress : l2BridgeAddress;
const messageBusAddress = isL1ToL2
? l1MessageBusAddress
: l2MessageBusAddress;

const bridgeContract = new ethers.Contract(address, Bridge.abi, wallet);
const messageBusContract = new ethers.Contract(
messageBusAddress,
IMessageBusAbi,
wallet
);
const managementContract = new ethers.Contract(
managementContractAddress,
ManagementContractAbi,
wallet
);

const l1BridgeAddress = memoizedConfig.ImportantContracts.L1Bridge;
const l2BridgeAddress = memoizedConfig.ImportantContracts.L2Bridge;
const l1MessageBusAddress = memoizedConfig.MessageBusAddress;
const l2MessageBusAddress = memoizedConfig.L2MessageBusAddress;
const managementContractAddress = memoizedConfig.ManagementContractAddress;
setContractState({
bridgeContract,
managementContract,
messageBusContract,
wallet,
messageBusAddress,
});
};

if (!provider) {
showToast(ToastType.DESTRUCTIVE, "Provider not found");
return;
}
const p = new ethers.providers.Web3Provider(provider);
const wallet = new ethers.Wallet(privateKey as string, p);
const address = isL1ToL2 ? l1BridgeAddress : l2BridgeAddress;
const messageBusAddress = isL1ToL2
? l1MessageBusAddress
: l2MessageBusAddress;
const bridgeContract = new ethers.Contract(
address as string,
Bridge.abi,
wallet
);
const messageBusContract = new ethers.Contract(
messageBusAddress as string,
IMessageBusAbi,
wallet
);
const managementContract = new ethers.Contract(
managementContractAddress as string,
ManagementContractAbi,
wallet
);
setContractState({
bridgeContract,
managementContract,
messageBusContract,
wallet,
messageBusAddress,
});
}, [isObscuroConfigLoading, memoizedConfig, provider, isL1ToL2]);
setupContracts();
}, [memoizedConfig, provider, isL1ToL2, signer]);

const sendNative = async (receiver: string, value: string) => {
const { bridgeContract, managementContract, messageBusContract, wallet } =
contractState;

if (!bridgeContract || !signer || !wallet || !managementContract) {
console.error("Contract or signer not found");
console.log("🚀 ~ sendNative ~ signer", signer, provider);
throw new Error("Contract or signer not found");
}

Expand Down Expand Up @@ -308,8 +300,7 @@ export const useContract = () => {
}

try {
const p = new ethers.providers.Web3Provider(provider);
const balance = await p.getBalance(walletAddress);
const balance = await provider.getBalance(walletAddress);
return ethers.utils.formatEther(balance);
} catch (error) {
console.error("Error checking Ether balance:", error);
Expand All @@ -328,14 +319,13 @@ export const useContract = () => {
}

try {
const p = new ethers.providers.Web3Provider(provider);
const tokenContract = new ethers.Contract(
tokenAddress,
[
"function balanceOf(address owner) view returns (uint256)",
"function decimals() view returns (uint8)",
],
p
provider
);

const balance = await tokenContract.balanceOf(walletAddress);
Expand All @@ -356,8 +346,6 @@ export const useContract = () => {
}

try {
const p = new ethers.providers.Web3Provider(provider);

const topics = [
ethers.utils.id("ValueTransfer(address,address,uint256)"),
ethers.utils.hexZeroPad(userAddress, 32),
Expand All @@ -369,7 +357,7 @@ export const useContract = () => {
fromBlock: 5868682,
};

return await p.getLogs(filter);
return await provider.getLogs(filter);
} catch (error) {
console.error("Error fetching transactions:", error);
throw error;
Expand Down
8 changes: 6 additions & 2 deletions contracts/src/bridge/frontend/src/lib/utils/walletEvents.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ethers } from "ethers";
import { ethereum } from ".";

export const setupEventListeners = (
provider: any,
Expand All @@ -23,5 +23,9 @@ export const setupEventListeners = (
};

export const initializeSigner = (provider: any) => {
return new ethers.providers.Web3Provider(provider).getSigner();
if (!provider) {
return null;
}

return provider.getSigner();
};
3 changes: 2 additions & 1 deletion contracts/src/bridge/frontend/src/lib/utils/walletUtils.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import detectEthereumProvider from "@metamask/detect-provider";
import { ethers } from "ethers";
import { ethereum } from ".";

export const getEthereumProvider = async () => {
const provider = await detectEthereumProvider();
const provider = new ethers.providers.Web3Provider(ethereum);
if (!provider) {
throw new Error("No Ethereum provider detected");
}
Expand Down

0 comments on commit e419680

Please sign in to comment.