Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 30 additions & 8 deletions src/utils/networks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ export const networkParams = {

export async function isNetworkAdded(network: NetworkType): Promise<boolean> {
if (!(window as any).ethereum) return false;

try {
const chainId = await (window as any).ethereum.request({
method: "eth_chainId",
Expand All @@ -45,6 +44,8 @@ export async function isNetworkAdded(network: NetworkType): Promise<boolean> {

export type UseNetworkResponse = {
isWalletInstalled: boolean;
// isAdded is a heuristic: true if this chain is active, or was added/
// selected during this hook's lifetime. Resets on network change.
isAdded: boolean;
isSelected: boolean;
addNetwork: () => Promise<void>;
Expand All @@ -58,22 +59,28 @@ export function useNetwork(network: NetworkType): UseNetworkResponse {

// Check if network is added and selected on mount and when network changes
useEffect(() => {
setIsAdded(false);
setIsSelected(false);

let cancelled = false; // avoid stale writes if `network` changes mid-request

const checkNetwork = async () => {
if (window.ethereum) {
try {
const chainId = await window.ethereum.request({
method: "eth_chainId",
});
if (cancelled) return;
const isCurrentNetwork =
chainId.toLowerCase() ===
networkParams[network].chainId.toLowerCase();
setIsSelected(isCurrentNetwork);
setIsAdded((prev) => isCurrentNetwork || prev); // If we're on the network, it must be added
setIsAdded((prev) => isCurrentNetwork || prev);
} catch (error) {
console.error("Error checking network:", error);
if (!cancelled) console.error("Error checking network:", error);
}
}
setIsWalletInstalled(window.ethereum !== undefined);
if (!cancelled) setIsWalletInstalled(window.ethereum !== undefined);
};

checkNetwork();
Expand All @@ -82,36 +89,51 @@ export function useNetwork(network: NetworkType): UseNetworkResponse {
if (window.ethereum) {
window.ethereum.on("chainChanged", checkNetwork);
return () => {
cancelled = true;
window.ethereum.removeListener("chainChanged", checkNetwork);
};
}
return () => {
cancelled = true;
};
}, [network]);

async function addNetwork(): Promise<void> {
if (!window.ethereum) return;

try {
await window.ethereum.request({
method: "wallet_addEthereumChain",
params: [networkParams[network]],
});
setIsAdded(true);
await selectNetwork(); // Automatically switch to the network after adding
try {
await window.ethereum.request({
method: "wallet_switchEthereumChain",
params: [{ chainId: networkParams[network].chainId }],
});
setIsSelected(true);
} catch (switchError) {
console.error("Error selecting network after add:", switchError);
}
} catch (error) {
console.error("Error adding network:", error);
}
}

async function selectNetwork(): Promise<void> {
if (!window.ethereum) return;

try {
await window.ethereum.request({
method: "wallet_switchEthereumChain",
params: [{ chainId: networkParams[network].chainId }],
});
setIsSelected(true);
} catch (error) {
setIsAdded(true);
} catch (error: any) {
if (error?.code === 4902) {
await addNetwork(); // unknown chain: add it, addNetwork does its own switch
return;
}
console.error("Error switching network:", error);
}
}
Expand Down