I'm new to web3 development and am getting the following error in 2 places.
Error 1)
Argument of type '(accounts: string[]) => void' is not assignable to parameter of type '(...args: unknown[]) => void'.
Types of parameters 'accounts' and 'args' are incompatible.
Type 'unknown' is not assignable to type 'string[]'.
Error 2)
Argument of type '(network: string) => void' is not assignable to parameter of type '(...args: unknown[]) => void'.
Types of parameters 'network' and 'args' are incompatible.
Type 'unknown' is not assignable to type 'string'.ts(2345)
Code
import { BrowserProvider, ethers, JsonRpcSigner} from "ethers";
import { useToast } from "@chakra-ui/react";
import { useCallback, useEffect, useState } from "react";
import { MetaMaskInpageProvider } from "@metamask/providers";
declare global {
interface Window{
ethereum?:MetaMaskInpageProvider
}
}
export interface IWeb3State {
address: string | null;
currentChain: number | null;
signer: JsonRpcSigner | null;
provider: BrowserProvider | null;
isAuthenticated: boolean;
}
const useWeb3Provider = () => {
const initialWeb3State = {
address: null,
currentChain: null,
signer: null,
provider: null,
isAuthenticated: false,
};
const toast = useToast();
const [state, setState] = useState<IWeb3State>(initialWeb3State);
const connectWallet = useCallback(async () => {
if (state.isAuthenticated) return;
try {
const { ethereum } = window;
if (!ethereum) {
return toast({
status: "error",
position: "top-right",
title: "Error",
description: "No ethereum wallet found",
});
}
const provider = new ethers.BrowserProvider(ethereum);
const accounts: string[] = await provider.send("eth_requestAccounts", []) as string[];
if (accounts.length > 0) {
const signer = await provider.getSigner();
const chain = Number(await (await provider.getNetwork()).chainId);
//once we have the wallet, are we exporting the variables "provider" & accounts outside this try?
setState({
...state,
address: accounts[0],
signer,
currentChain: chain,
provider,
isAuthenticated: true,
});
localStorage.setItem("isAuthenticated", "true");
}
} catch {}
}, [state, toast]);
const disconnect = () => {
setState(initialWeb3State);
localStorage.removeItem("isAuthenticated");
};
useEffect(() => {
if (window == null) return;
if (localStorage.hasOwnProperty("isAuthenticated")) {
connectWallet();
}
}, [connectWallet, state.isAuthenticated]);
useEffect(() => {
if (typeof window.ethereum === "undefined") return;
window.ethereum.on("accountsChanged", (accounts: string[]) => {
setState({ ...state, address: accounts[0] });
});
window.ethereum.on("networkChanged", (network: string) => {
setState({ ...state, currentChain: network });
});
return () => {
window.ethereum?.removeAllListeners();
};
}, [state]);
return {
connectWallet,
disconnect,
state,
};
};
export default useWeb3Provider;
If it helps, I'm following this tutorial and have been trouble shooting for the past 3 days. Insert crying emoji
I'm not particularly sure how to even ask this question so if any further clarification is needed, just holler!
This doesn't have much to do with web3. It's more of a typescript question. See fixes below with comments:
An alternative fix would be to use typescript generics:
Here:
And here: