Closed hskang9 closed 1 year ago
This is using old version of packages and I don't see <Web3Modal />
component implemented, could you address these and let me know if issue still persists.
I don't understand versioning up into typescript, incompatible newest but deteriorated version will resolve this issue. I cannot even let my old code like useAccount
work outside of WagmiConfig
DOM element. I thought I just need to find what client-side exception happen in modal component, but why am I asked to update the entire codebase and see if it changes result?
Wagmi hooks have to be used within their config component as it creates context's for them. I'm still not clear on what your issue is, have you included actual Web3Modal component? From screenshot above, all warnings come from Intercom?
This is the _app.js I included for <Web3Modal/>
import { React, useState, useEffect } from "react";
import Head from "next/head";
import "styles/global.css";
import Navbar from "../components/navbar/Navbar";
import "utils/analytics";
import Chat from "components/misc/Chat";
import WrappedTokens from "inputs/wrapped_tokens.json";
import {
createClient,
configureChains,
WagmiConfig,
useAccount,
useNetwork,
} from "wagmi";
import {
EthereumClient,
w3mConnectors,
w3mProvider,
} from "@web3modal/ethereum";
import { Web3Modal, useWeb3Modal } from "@web3modal/react";
import {
arbitrum,
mainnet,
optimism,
evmos,
zkSync,
polygon,
} from "wagmi/chains";
import {
mantleTest,
baseGoerli,
KucoinCommunityChain,
LineaTestnet,
} from "consts/customChains";
import localFont from "next/font/local";
import { useRouter } from "next/router";
import { HeadTitle } from "enums";
import PageLoader from "components/loaders/PageLoader";
import { ToastContainer } from "react-toastify";
import "react-toastify/dist/ReactToastify.css";
const favorit = localFont({
src: "./fonts/Favorit/ABCFavoritVariable.woff2",
variable: "--font-favorit",
display: "swap",
});
const loginPaths = ["/signin", "/get-started", "/unsupported", "/"];
const nonLoginPaths = [
"/legal/terms-of-service",
"/legal/privacy-policy",
"/buy-sell-crypto",
];
// 1. Get projectID at https://cloud.walletconnect.com
if (!process.env.NEXT_PUBLIC_PROJECT_ID) {
throw new Error("You need to provide NEXT_PUBLIC_PROJECT_ID env variable");
}
export const projectId = process.env.NEXT_PUBLIC_PROJECT_ID;
// 2. Configure wagmi client
const chains = [
//mainnet,
//optimism,
//arbitrum,
//evmos,
//polygon,
//zkSync,
//baseGoerli,
//KucoinCommunityChain,
LineaTestnet,
];
const { provider } = configureChains(chains, [w3mProvider({ projectId })]);
export const wagmiClient = createClient({
autoConnect: true,
connectors: w3mConnectors({ version: 1, chains, projectId }),
provider,
});
// 3. Configure modal ethereum client
export const ethereumClient = new EthereumClient(wagmiClient, chains);
// 4. Wrap your app with WagmiProvider and add <Web3Modal /> component
function MyApp({ Component, pageProps }) {
const [ready, setReady] = useState(false);
const { isConnected } = useAccount();
const { chain } = useNetwork();
const [wasConnectedChain, setWasConnectedChain] = useState(undefined);
const router = useRouter();
// Web3.0 hooks and effects
useEffect(() => {
setReady(true);
}, []);
useEffect(() => {
if (!router.isReady) return;
const handleUnsupportedChain = () => {
if (chain && WrappedTokens[chain.name] === undefined) {
localStorage.setItem("path", router.asPath);
router.push({
pathname: "/unsupported",
});
}
};
const handleLoginRedirects = () => {
const path = localStorage.getItem("path");
if (isConnected) {
if (path) {
localStorage.removeItem("path");
router.push(path);
} else if (chain && chain.unsupported) {
localStorage.setItem("path", router.asPath);
router.push({
pathname: "/unsupported",
});
} else if (!wasConnectedChain && loginPaths.includes(router.pathname)) {
setWasConnectedChain(chain);
const prevLink = localStorage.getItem("path");
router.push(prevLink ?? "/swap");
}
} else {
localStorage.setItem("path", router.asPath);
if (!loginPaths.includes(router.pathname)) {
router.push({
pathname: wasConnectedChain ? "/signin" : "/",
});
}
}
};
const handleNetworkChange = () => {
if (wasConnectedChain && chain && wasConnectedChain.id !== chain.id) {
window.location.reload();
}
};
handleUnsupportedChain();
handleLoginRedirects();
handleNetworkChange();
}, [chain, router.isReady, isConnected]);
// Reload when network changes
useEffect(() => {
if (wasConnectedChain && chain && wasConnectedChain.id !== chain.id) {
window.location.reload();
}
}, [chain]);
function getTitleForPath(path) {
for (const key in HeadTitle) {
if (path.includes(key)) {
return HeadTitle[key];
}
}
return null; // Return null if no match is found
}
const renderHead = () => {
if (router.pathname.includes("/trade")) {
return (
// Make new Head in trade page
<></>
);
} else {
return (
<Head>
<title>{`${getTitleForPath(
router.asPath
)} | Standard - All in one app for Bitcoin, Ethereum & Altcoins`}</title>
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black" />
<meta name="apple-mobile-web-app-title" content="Standard" />
<meta name="view-transition cursor-pointer" content="same-origin" />
</Head>
);
}
};
const renderFooter = () => {
if (router.pathname.includes("/trade")) {
return (
// Make new Footer in trade page
<></>
);
} else {
return <Footer />;
}
};
const renderPage = () => {
if (loginPaths.includes(router.pathname)) {
return (
<>
<div className="w-screen h-screen flex-row justify-between contents">
<>
{/* show loader if you are connected */}
{router.pathname !== "/unsupported" && isConnected && !nonLoginPaths.includes(router.asPath) && (
<PageLoader
id="login"
isOpen={isConnected && !nonLoginPaths.includes(router.asPath)}
/>
)}
<Chat />
<main
className={`${favorit.variable} font-sans w-full h-full bg-[#F2F5F84D] `}
>
<Component {...pageProps} />
</main>
</>
</div>
</>
);
} else {
return (
<div className="w-screen h-screen flex flex-col justify-between overflow-auto">
<>
{/* show loader if you are disconnected */}
{!nonLoginPaths.includes(router.asPath) &&
!isConnected &&
!loginPaths.includes(router.asPath) && (
<PageLoader
id="logout"
isOpen={
!nonLoginPaths.includes(router.asPath) &&
!isConnected &&
!loginPaths.includes(router.asPath)
}
/>
)}
<Chat />
<main className={`${favorit.variable} font-sans w-full`}>
<Navbar
networkName={chain ? chain.name : "Ethereum"}
pathname={router.pathname}
/>
{nonLoginPaths.includes(router.asPath) ? (
<Component {...pageProps} className="h-full" />
) : (
isConnected && <Component {...pageProps} className="h-full" />
)}
</main>
<ToastContainer />
</>
</div>
);
}
};
return (
<>
{ready ? (
<WagmiConfig client={wagmiClient}>
{renderHead()}
{renderPage()}
</WagmiConfig>
) : null}
<Web3Modal
projectId={projectId}
ethereumClient={ethereumClient}
termsOfServiceUrl=""
privacyPolicyUrl=""
/>
</>
);
}
const Footer = () => {
return (
<footer
className={`w-screen ${favorit.variable} font-sans text-[#FEFBEB]`}
style={{ backgroundColor: "#121920" }}
>
<div className="w-full px-screen-5 py-20 flex xs:flex-col md:flex-row xs:space-x-0 space-x-4 xs:space-y-8">
<div className="xs:w-full w-1/2 flex flex-col justify-start items-start">
<img
src="/svgs/stnd_logo_cream.svg"
alt="logo"
className="w-[400px] h-[63px]"
/>
<span className="mt-5 font-normal text-center">
2023 Standard Labs. - All rights reserved
</span>
</div>
<div className="xs:w-full w-1/2 flex flex-row justify-between items-start">
<div className="flex flex-col justify-start space-y-3">
<span className="font-semibold">Products</span>
<span className="text-sm font-normal">App</span>
<span className="text-sm">Docs</span>
<span className="text-sm">Support</span>
</div>
<div className="flex flex-col justify-start space-y-3">
<span className="font-semibold">Explore</span>
<span className="text-sm">Buy Crypto</span>
<span className="text-sm">
<a href="/market">Swap</a>
</span>
<span className="text-sm">Trade</span>
<span className="text-sm">Learn</span>
</div>
<div className="flex flex-col justify-start space-y-3">
<span className="font-semibold">Connect</span>
<span className="text-sm">Twitter</span>
<span className="text-sm">Telegram</span>
<span className="text-sm">Discord</span>
<span className="text-sm">Linkedin</span>
</div>
</div>
</div>
</footer>
);
};
export default MyApp;
The issue is useWeb3Modal hook's isOpen variable shows true even when web3modal is not rendered fully.
Creating context does not matter, it is just Web3Modal having client side error not being able to handle its context given by Wagmi properly. Usually, it should be something where you did not check undefined variable, and prepare for alternative rendering.
I have very interisting error
When i try open web3Modal i have this error^
it worked correctly before
Using <w3m-qrcode>
on it's own is a more advanced use case, it expects uri for qrcode to be passed as an argument. You would need to get it from other sdk's like @walletconnect/ethereum-provider
or even @walletconnect/sign-client
. To simply use modal as intended (normal use case) you can follow example implementations in docs.
at least make this useWeb3modal hook check if that html element is rendered and set isOpen to true. This is all I want. I don't need these new wagmi v1 with useless type gymnastics while missing out original features which was in v0. Typescript was intended to prevent undefined property, but this code cannot even use it right.
Seriously, why in the world would you use Typescript when you cannot even handle undefined property or variables? It is made because of it.
I'm still confused about what exactly your issue is, mind putting together a codesandbox? What exactly is undefined
? You mentioned
I don't understand versioning up into typescript, incompatible newest but deteriorated version will resolve this issue.
Does this mean upgrading ts version resolves the issue or were you just complaining about ts?
You should be confused because you cannot find what is undefined and fails to render web3 modal.
I am complaining that you cannot even find that in your code when you are using typescript, because it is the tool for you to find if you have strongly defined types which are used in your web3modal. Instead of versioning up typescript or package and praying to your computer, I highly suggest you look at property which web3modal uses and check if there is any case it becomes undefined or strongly define types that are input to render the modal. From @DSapielkin’s error, it seems evident there is an missing property in some state of web3modal. You should update isOpen state to false corresponding to that situation.
Does this mean upgrading ts version resolves the issue or were you just complaining about ts?
🤦♂️… My suggestion in typescript configuration is this; I think you should include “strict” : true property in tsconfig.json on web3modal. I think this will make editor filled with red lines, but that should happen because ok undefined properties. Otherwise, I would highly recommend to use JSDoc to define types so that codes can be run, and replace original js code with typescript code. I would never use typescript code in the first place unless there are types that are strongly defined not to change.
Will be closing this now, as discussion is now unproductive. To leave you with few solutions / explanations (based on my best guess of what issue you are facing):
isOpen
state is what modal component reacts to, not vice versa
Link to minimal reproducible example
https://gist.github.com/hskang9/e37ee24589b3824dcaf770111d5b631a
Summary
This is my login page code to open modal once the page is rendered. but the modal opens with empty content. It does not even check if the modal has the right content.
isOpen in
useWeb3Modal
should be true when Modal is successfully rendered without missing values.At least it needs to check whether its html element
w3m-container
has its children element like this example below:this is the code.
List of related npm package versions
web3modal : "wagmi": "^0.12.10", "@web3modal/ethereum": "^2.2.0", "@web3modal/react": "^2.2.0",