} from "react-redux";
import { Web3 } from "web3";
import { connectSmart } from "../redux/blockchain/blockchainActions";
import {
refreshSmartContract,
updateAccount,
} from "../redux/blockchain/blockchainReducer";
import { switchNetworkIfRequired } from "../utils/utils";
import useError from "./useError";
const isInstalled = () => {
if (typeof window.ethereum !== "undefined") return true;
else return false;
};
const connectWallet = async (cb) => {
if (!isInstalled) throw new Error("Please install MetaMask plugin");
await window.ethereum.request({ method: "eth_requestAccounts" });
const provider = new Web3(window.ethereum);
const accounts = await provider.eth.getAccounts();
const chainId = await provider.eth.net.getId();
cb?.(provider, accounts, chainId);
};
const useMetamask = () => {
const listeners = [
{
type: "accountsChanged",
func: handleAccountsChanged,
},
{
type: "сhainChanged",
func: handleChainChanged,
},
{
type: "disconnect",
func: disconnect,
},
];
const [account, setAccount] = useState();
const [provider, setProvider] = useState();
const [chainId, setChainId] = useState();
const [network, setNetwork] = useState(97);
const [error, withErrorHandler] = useError();
const dispatch = useDispatch();
const connect = async () => {
await connectWallet((provider, accounts, chainId) => {
dispatch(connectSmart());
setProvider(provider);
handleChainChanged(chainId);
handleAccountsChanged(accounts);
});
};
const switchNetworkWrapped = withErrorHandler(
switchNetworkIfRequired(provider, chainId, network)
);
const listenersActions = useCallback(
(listener) => {
return () => {
listeners.map(({ type, func }) => {
return listener(type, func);
});
};
},
[listeners]
);
const refreshState = useCallback(() => {
setAccount();
setChainId();
setNetwork("");
setProvider("");
dispatch(refreshSmartContract());
}, [dispatch]);
const disconnect = useCallback(() => {
refreshState();
listenersActions(provider.removeListener());
}, [refreshState, listenersActions, provider]);
const handleAccountsChanged = useCallback(
(accounts) => {
if (accounts) {
setAccount(accounts[0]);
dispatch(updateAccount(accounts[0]));
}
},
[dispatch]
);
const handleChainChanged = useCallback(
(_hexChainId) => {
setChainId(_hexChainId);
switchNetworkWrapped();
},
[switchNetworkWrapped]
);
useEffect(() => {
if (!provider?.on) {
return;
}
listenersActions(provider.on());
}, [
listenersActions,
provider,
handleAccountsChanged,
handleChainChanged,
disconnect,
]);
return {
account,
connect,
disconnect,
};
};
export default useMetamask;
Удали
Обсуждают сегодня