Skip to content

Commit

Permalink
feat: state mgt - add contract and wallet stores
Browse files Browse the repository at this point in the history
  • Loading branch information
Jennievon committed Aug 13, 2024
1 parent 2f1da92 commit a369f72
Show file tree
Hide file tree
Showing 11 changed files with 2,286 additions and 10,407 deletions.
12,207 changes: 2,022 additions & 10,185 deletions contracts/src/bridge/frontend/package-lock.json

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions contracts/src/bridge/frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,17 +39,17 @@
"next": "14.0.1",
"next-themes": "^0.2.1",
"path-to-regexp": "^6.2.1",
"react": "^18",
"react": "^18.2.0",
"react-day-picker": "^8.9.1",
"react-dom": "^18",
"react-dom": "^18.2.0",
"react-hook-form": "^7.51.3",
"react-json-pretty": "^2.2.0",
"recharts": "^2.9.3",
"tailwind-merge": "^2.0.0",
"tailwindcss-animate": "^1.0.7",
"vaul": "^0.9.0",
"yup": "^1.4.0",
"zustand": "^4.4.6"
"zustand": "^4.5.4"
},
"devDependencies": {
"@nomicfoundation/hardhat-toolbox": "^2.0.2",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import { DrawerDialog } from "../common/drawer-dialog";
import { L1CHAINS, L1TOKENS, L2CHAINS, L2TOKENS } from "@/src/lib/constants";
import { useWatch } from "react-hook-form";
import useCustomHookForm from "@/src/hooks/useCustomHookForm";
import { useWalletStore } from "../../providers/wallet-provider";
import { ToastType, Token } from "@/src/types";
import { useContract } from "@/src/hooks/useContract";
import { TransferFromSection } from "./transfer-from-section";
Expand All @@ -22,6 +21,7 @@ import { SwitchNetworkButton } from "./switch-network-button";
import { TransferToSection } from "./transfer-to-section";
import { bridgeSchema } from "@/src/schemas/bridge";
import { handleStorage } from "@/src/lib/utils/walletUtils";
import useWalletStore from "@/src/stores/wallet-store";

export default function Dashboard() {
const { provider, address, walletConnected, switchNetwork, isL1ToL2 } =
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { useWalletStore } from "../../providers/wallet-provider";
import { Button } from "../../ui/button";
import { Link2Icon, LinkBreak2Icon } from "@radix-ui/react-icons";
import React from "react";
import { cn, downloadMetaMask, ethereum } from "@/src/lib/utils";
import useWalletStore from "@/src/stores/wallet-store";

const ConnectWalletButton = ({ className, text, variant }: any) => {
const { walletConnected, connectWallet, disconnectWallet } = useWalletStore();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,199 +1,32 @@
import React, { createContext, useState, useContext, useEffect } from "react";
import { toast } from "../ui/use-toast";
import React, { createContext, useContext, useEffect } from "react";
import useWalletStore from "@/src/stores/wallet-store";
import {
ToastType,
WalletConnectionContextType,
WalletConnectionProviderProps,
WalletNetwork,
} from "@/src/types";
import { requestMethods } from "@/src/routes";
import {
getEthereumProvider,
handleStorage,
} from "@/src/lib/utils/walletUtils";
import {
setupEventListeners,
initializeSigner,
} from "@/src/lib/utils/walletEvents";

const WalletContext = createContext<WalletConnectionContextType | null>(null);

const WalletProvider = ({ children }: WalletConnectionProviderProps) => {
const [provider, setProvider] = useState<any>(null);
const [isWalletConnected, setIsWalletConnected] = useState<boolean>(false);
const [signer, setSigner] = useState<any>(null);
const [address, setAddress] = useState<string>("");
const [isL1ToL2, setIsL1ToL2] = useState<boolean>(true);

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

const newSigner = initializeSigner(provider);
setSigner(newSigner);

const chainId = await detectedProvider.send(requestMethods.getChainId, []);

const isL1 = chainId === WalletNetwork.L1_SEPOLIA;
setIsL1ToL2(isL1);
};

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

const accounts = await detectedProvider.send(
requestMethods.connectAccounts,
[]
);

const newSigner = initializeSigner(detectedProvider);
setSigner(newSigner);

setIsWalletConnected(true);
setAddress(accounts[0]);
handleStorage.save("walletAddress", accounts[0]);
handleStorage.save("isL1ToL2", isL1ToL2.toString());

toast({
title: "Connected",
description: "Connected to wallet! Account: " + accounts[0],
variant: ToastType.SUCCESS,
});
} catch (error) {
console.error("Error connecting to wallet:", error);
toast({
title: "Error",
description: "Error connecting to wallet",
variant: ToastType.DESTRUCTIVE,
});
}
};

const disconnectWallet = () => {
try {
if (provider) {
provider.removeAllListeners();
setProvider(null);
setSigner(null);
setAddress("");
setIsWalletConnected(false);
handleStorage.remove("walletAddress");
handleStorage.remove("isL1ToL2");
handleStorage.remove("tenBridgeReceiver");
window.location.reload();

toast({
title: "Disconnected",
description: "Disconnected from wallet",
variant: ToastType.INFO,
});
}
} catch (error) {
console.error("Error disconnecting from wallet:", error);
toast({
title: "Error",
description: "Error disconnecting from wallet",
variant: ToastType.DESTRUCTIVE,
});
}
};
const { restoreWalletState } = useWalletStore();

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

if (storedAddress) {
setAddress(storedAddress);
setIsWalletConnected(true);
setIsL1ToL2(storedIsL1ToL2);
}

initializeProvider();
restoreWalletState();
}, []);

const switchNetwork = async () => {
if (!provider) {
toast({
title: "Error",
description: "Please connect to wallet first",
variant: ToastType.DESTRUCTIVE,
});
return;
}
try {
const desiredNetwork = isL1ToL2
? WalletNetwork.L2_TEN_TESTNET
: WalletNetwork.L1_SEPOLIA;

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 ${
desiredNetwork === WalletNetwork.L2_TEN_TESTNET
? "L2 TEN Testnet"
: "L1 Sepolia"
}`,
variant: ToastType.SUCCESS,
});
} catch (error: any) {
console.error("Error switching network:", error);
if (error.code === 4902) {
toast({
title: "Network Not Found",
description: "Network not found in wallet",
variant: ToastType.INFO,
});
} else {
toast({
title: "Error",
description: error.message || "Error switching network",
variant: ToastType.DESTRUCTIVE,
});
}
}
};

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

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

const value = {
provider,
signer,
address,
walletConnected: isWalletConnected,
isL1ToL2,
connectWallet,
disconnectWallet,
switchNetwork,
};
const value = {};

return (
<WalletContext.Provider value={value}>{children}</WalletContext.Provider>
);
};

const useWalletStore = () => {
const useWallet = () => {
const context = useContext(WalletContext);
if (!context) {
throw new Error("useWalletStore must be used within a WalletProvider");
throw new Error("useWallet must be used within a WalletProvider");
}
return context;
};

export { WalletProvider, useWalletStore };
export { WalletProvider, useWallet };
Loading

0 comments on commit a369f72

Please sign in to comment.