import { useMemo, useState } from "react"; import useBurnerSigner from "./BurnerSigner"; import { JsonRpcProvider, Web3Provider } from "@ethersproject/providers"; import { Signer } from "ethers"; /** * Parse TEthersProviderOrSigner to TProviderAndSigner * @param providerOrSigner TEthersProviderOrSigner * @returns TProviderAndSigner */ export const parseProviderOrSigner = async providerOrSigner => { let signer = undefined; let provider; let providerNetwork; if (providerOrSigner && (providerOrSigner instanceof JsonRpcProvider || providerOrSigner instanceof Web3Provider)) { const accounts = await providerOrSigner.listAccounts(); if (accounts && accounts.length > 0) { signer = providerOrSigner.getSigner(); } provider = providerOrSigner; providerNetwork = await providerOrSigner.getNetwork(); } if (!signer && providerOrSigner instanceof Signer) { signer = providerOrSigner; provider = signer.provider; providerNetwork = provider && (await provider.getNetwork()); } return { signer, provider, providerNetwork }; }; const syncBurnerKeyFromStorage = () => { if (window.location.pathname && window.location.pathname.includes("/pk")) { const incomingPK = window.location.hash.replace("#", ""); if (incomingPK.length === 64 || incomingPK.length === 66) { console.log("🔑 Incoming Private Key..."); const rawPK = incomingPK; window.history.pushState({}, "", "/"); const currentPrivateKey = window.localStorage.getItem("metaPrivateKey"); if (currentPrivateKey && currentPrivateKey !== rawPK) { window.localStorage.setItem(`metaPrivateKey_backup${Date.now()}`, currentPrivateKey); } window.localStorage.setItem("metaPrivateKey", rawPK); } } }; /** * Gets user provider/signer from injected provider or local provider * Use your injected provider from 🦊 Metamask * If you don't have it then instantly generate a 🔥 burner wallet from a local provider * ~ Features ~ - Specify the injected provider from Metamask - Specify the local provider - Usage examples: const tx = Transactor(userSigner, gasPrice) * @param injectedProviderOrSigner (TEthersProviderOrSigner) :: injected provider/signer from metamask etc.. * @param localProvider (TEthersProvider) local provider to generate a burner wallet from * @returns (TProviderAndSigner) */ const useUserProviderAndSigner = (injectedProviderOrSigner, localProvider) => { const [signer, setSigner] = useState(); const [provider, setProvider] = useState(); const [providerNetwork, setProviderNetwork] = useState(); const burnerSigner = useBurnerSigner(localProvider); useMemo(() => { if (injectedProviderOrSigner) { console.log("🦊 Using injected provider"); void parseProviderOrSigner(injectedProviderOrSigner).then(result => { if (result != null) setSigner(result.signer); }); } else if (!localProvider) { setSigner(undefined); } else { syncBurnerKeyFromStorage(); console.log("🔥 Using burner signer", burnerSigner); setSigner(burnerSigner); } }, [injectedProviderOrSigner, localProvider, burnerSigner]); useMemo(() => { if (signer) { const result = parseProviderOrSigner(signer); void result.then(r => { setProvider(r.provider); setProviderNetwork(r.providerNetwork); }); } }, [signer]); return { signer, provider, providerNetwork }; }; export default useUserProviderAndSigner;