Skip to content

Commit 37d38df

Browse files
committed
Add logic to connect to wallet or redirect to connect page if no wallet connected
1 parent b4f5a6a commit 37d38df

File tree

11 files changed

+158
-33
lines changed

11 files changed

+158
-33
lines changed

.vscode/settings.json

+1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
{
22
"cSpell.words": [
3+
"currentprovider",
34
"walletconnect"
45
]
56
}

components/connect/index.tsx

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import { useEffect } from "react";
2+
import { Button } from "@chakra-ui/react";
3+
import type { NextPage } from "next";
4+
import { useRouter } from "next/router";
5+
import { useWeb3Context } from "@/contexts/Web3Context";
6+
7+
const Connect: NextPage = () => {
8+
const { loading, account, connectWeb3, errors } = useWeb3Context();
9+
const router = useRouter();
10+
const handleConnect = () => {
11+
if (!account) {
12+
connectWeb3();
13+
router.push("/connected");
14+
}
15+
};
16+
17+
useEffect(() => {
18+
if (!loading && !errors && account) {
19+
router.push("/connected");
20+
}
21+
}, [account, errors, loading, router]);
22+
23+
return (
24+
<div>
25+
<Button onClick={handleConnect}>Connect</Button>
26+
</div>
27+
);
28+
};
29+
30+
export default Connect;

components/connected/index.tsx

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import { useEffect } from "react";
2+
import type { NextPage } from "next";
3+
import { useRouter } from "next/router";
4+
import { useWeb3Context } from "@/contexts/Web3Context";
5+
6+
const Connect: NextPage = () => {
7+
const { loading, account, errors } = useWeb3Context();
8+
const router = useRouter();
9+
10+
useEffect(() => {
11+
if (!loading && (!account || errors)) {
12+
router.push("/connect");
13+
}
14+
}, [account, router, loading, errors]);
15+
16+
return <div>CONNECTED</div>;
17+
};
18+
19+
export default Connect;

components/navigation/index.tsx

+14-9
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,14 @@ import Link from "next/link";
33
import React from "react";
44
import { Flex, Spacer, Box } from "@chakra-ui/react";
55
import { useRouter } from "next/router";
6+
import { useWeb3Context } from "@/contexts/Web3Context";
7+
import { formatAddress } from "@/utils/presentationHelper";
68

79
export const LOGO_HEIGHT = 64;
810

911
const Navigation: React.FC = () => {
1012
const router = useRouter();
11-
const currentPath = router.asPath;
13+
const { account, loading, errors } = useWeb3Context();
1214

1315
return (
1416
<Flex
@@ -30,32 +32,35 @@ const Navigation: React.FC = () => {
3032
</a>
3133
</Box>
3234
<Flex p="4">
33-
<Box px="2" bg={currentPath === "/project" ? "yellow" : ""}>
35+
<Box px="2" bg={router.asPath === "/project" ? "yellow" : ""}>
3436
<Link href="/project">Project</Link>
3537
</Box>
36-
<Box px="2" bg={currentPath === "/robot" ? "yellow" : ""}>
38+
<Box px="2" bg={router.asPath === "/robot" ? "yellow" : ""}>
3739
<Link href="/robot">$Robot</Link>
3840
</Box>
39-
<Flex px="2" bg={currentPath === "/shop" ? "yellow" : ""}>
41+
<Flex px="2" bg={router.asPath === "/shop" ? "yellow" : ""}>
4042
<Box pr="1">
4143
<Image src="/arrow.svg" alt="" width="10px" height="10px" />
4244
</Box>
4345
<Link href="/shop">Shop</Link>
4446
</Flex>
45-
<Box px="2" bg={currentPath === "/curate" ? "yellow" : ""}>
47+
<Box px="2" bg={router.asPath === "/curate" ? "yellow" : ""}>
4648
<Link href="/curate">Curate</Link>
4749
</Box>
4850
</Flex>
4951
<Spacer />
5052
<Flex>
51-
<Box px="2" bg={currentPath === "/exchange" ? "yellow" : ""}>
53+
<Box px="2" bg={router.asPath === "/exchange" ? "yellow" : ""}>
5254
<Link href="/exchange">Exchange</Link>
5355
</Box>
54-
<Box px="2" bg={currentPath === "/claim" ? "yellow" : ""}>
56+
<Box px="2" bg={router.asPath === "/claim" ? "yellow" : ""}>
5557
<Link href="/claim">Claim</Link>
5658
</Box>
57-
<Box px="2" border="1px" bg={currentPath === "/connect" ? "yellow" : ""}>
58-
<Link href="/connect">Connect</Link>
59+
<Box px="2" border="1px" bg={router.asPath.indexOf("/connect") >= 0 ? "yellow" : ""}>
60+
{!loading && !errors && !!account && (
61+
<Link href="/connected">{formatAddress(account)}</Link>
62+
)}
63+
{!loading && !account && <Link href="/connect">Connect</Link>}
5964
</Box>
6065
<Box width={`${LOGO_HEIGHT}px`} />
6166
</Flex>

contexts/Web3Context.tsx

+21-20
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import WalletConnectProvider from "@walletconnect/web3-provider";
77
type Web3ContextType = {
88
account: null | string;
99
provider: null | ethers.providers.Web3Provider;
10+
errors: any
1011
};
1112

1213
const providerOptions: IProviderOptions = {
@@ -15,7 +16,7 @@ const providerOptions: IProviderOptions = {
1516
package: WalletConnectProvider,
1617
options: {
1718
rpc: {
18-
1: 'https://rinkeby.infura.io/v3/a2eae6b8a91442c8a6e3fe5e8c4ef4bd',
19+
1: "https://rinkeby.infura.io/v3/a2eae6b8a91442c8a6e3fe5e8c4ef4bd",
1920
},
2021
},
2122
},
@@ -29,6 +30,7 @@ const web3Modal =
2930
});
3031

3132
const Web3Context = createContext<Web3ContextType & { loading: boolean; connectWeb3: () => void }>({
33+
errors: null,
3234
account: null,
3335
provider: null,
3436
loading: false,
@@ -37,37 +39,36 @@ const Web3Context = createContext<Web3ContextType & { loading: boolean; connectW
3739

3840
const Web3ContextProvider: React.FC = ({ children }) => {
3941
const [loading, setLoading] = useState(false);
40-
const [{ account, provider }, setWeb3State] = useState<Web3ContextType>({
42+
const [{ account, provider, errors }, setWeb3State] = useState<Web3ContextType>({
4143
account: null,
4244
provider: null,
45+
errors: null,
4346
});
4447

4548
const connectWeb3 = useCallback(async () => {
46-
const modalProvider = web3Modal && (await web3Modal.connect());
47-
const currentprovider = new ethers.providers.Web3Provider(
48-
new Web3(modalProvider).currentProvider as ethers.providers.ExternalProvider,
49-
);
50-
const currentAccount = await currentprovider.getSigner().getAddress();
49+
try {
50+
const modalProvider = web3Modal && (await web3Modal.connect());
51+
const currentprovider = new ethers.providers.Web3Provider(
52+
new Web3(modalProvider).currentProvider as ethers.providers.ExternalProvider,
53+
);
54+
const currentAccount = await currentprovider.getSigner().getAddress();
5155

52-
modalProvider.on("accountsChanged", async (newAcc: string[]) =>
53-
setWeb3State((prev) => ({ ...prev, account: newAcc[0] })),
54-
);
56+
modalProvider.on("accountsChanged", async (newAcc: string[]) =>
57+
setWeb3State((prev) => ({ ...prev, account: newAcc[0] })),
58+
);
5559

56-
setWeb3State({ provider: currentprovider, account: currentAccount });
57-
setLoading(false);
60+
setWeb3State({ provider: currentprovider, account: currentAccount, errors: null });
61+
} catch (e) {
62+
setWeb3State({ provider: null, account: null, errors: e });
63+
} finally {
64+
setLoading(false);
65+
}
5866
}, []);
5967

60-
useEffect(() => {
61-
setLoading(true);
62-
if (window.ethereum) window.ethereum.autoRefreshOnNetworkChange = false;
63-
64-
// eslint-disable-next-line no-unused-expressions
65-
web3Modal && web3Modal.cachedProvider ? connectWeb3() : setLoading(false);
66-
}, [connectWeb3]);
67-
6868
return (
6969
<Web3Context.Provider
7070
value={{
71+
errors,
7172
account,
7273
provider,
7374
loading,

package.json

+2
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
"@chakra-ui/react": "^1.6.10",
1515
"@emotion/react": "^11.6.0",
1616
"@emotion/styled": "^11",
17+
"@ethersproject/bignumber": "^5.5.0",
18+
"@ethersproject/units": "^5.5.0",
1719
"@visx/event": "^2.1.2",
1820
"@visx/gradient": "^2.1.0",
1921
"@visx/grid": "^2.4.0",

pages/_app.tsx

+14-3
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { useRouter } from "next/router";
2+
import { useEffect, useState } from "react";
13
import "@/styles/globals.css";
24
import Head from "next/head";
35
import type { AppProps } from "next/app";
@@ -8,6 +10,13 @@ import Layout from "@/components/layout";
810
import Web3ContextProvider from "@/contexts/Web3Context";
911

1012
function MyApp({ Component, pageProps }: AppProps) {
13+
const router = useRouter();
14+
const [routerIsReady, setRouterIsReady] = useState(false);
15+
16+
useEffect(() => {
17+
setRouterIsReady(router.isReady);
18+
}, [router.isReady]);
19+
1120
return (
1221
<Web3ContextProvider>
1322
<ChakraProvider theme={customTheme}>
@@ -29,9 +38,11 @@ function MyApp({ Component, pageProps }: AppProps) {
2938
<link rel="preload" href="/fonts/188 Sans-Regular.otf" as="font" crossOrigin="" />
3039
<link rel="preload" href="/fonts/188 Sans-Thin Condensed.otf" as="font" crossOrigin="" />
3140
</Head>
32-
<Layout>
33-
<Component {...pageProps} />
34-
</Layout>
41+
{routerIsReady && (
42+
<Layout>
43+
<Component {...pageProps} />
44+
</Layout>
45+
)}
3546
</ChakraProvider>
3647
</Web3ContextProvider>
3748
);

pages/connect.tsx

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import Connect from "@/components/connect";
2+
3+
export default Connect;

pages/connected.tsx

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import Connected from "@/components/connected";
2+
3+
export default Connected;

utils/presentationHelper.ts

+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import { BigNumber } from "@ethersproject/bignumber";
2+
import { formatUnits } from "@ethersproject/units";
3+
4+
export const formatAddress = (
5+
address: string | null | undefined,
6+
ensName?: string | null,
7+
chars = 4,
8+
): string => {
9+
if (ensName) return ensName;
10+
if (address)
11+
return `${address.substring(0, chars)}...${address.substring(address.length - chars)}`;
12+
return "";
13+
};
14+
15+
export const formatNumber = (number: number): string => number.toLocaleString(undefined, {
16+
minimumFractionDigits: 0,
17+
maximumFractionDigits: 2,
18+
});
19+
20+
export const formatToUSD = ({ usdPrice, number }: { usdPrice: number; number?: BigNumber }) => {
21+
const usdValue = usdPrice * Number(formatToken(number));
22+
return formatNumber(usdValue);
23+
};
24+
25+
export const formatToken = (
26+
number?: BigNumber | string,
27+
decimals: string | number = 18,
28+
): string | undefined => {
29+
if (!number) {
30+
return;
31+
}
32+
const num = BigNumber.from(number);
33+
const formatted = formatUnits(num, Number(decimals));
34+
const split = formatted.split(".");
35+
if (split.length > 1) {
36+
// eslint-disable-next-line consistent-return
37+
return `${split[0]}.${split[1].substr(0, 6)}`;
38+
}
39+
// eslint-disable-next-line consistent-return
40+
return formatted;
41+
};

yarn.lock

+10-1
Original file line numberDiff line numberDiff line change
@@ -1207,7 +1207,7 @@
12071207

12081208
"@ethersproject/[email protected]", "@ethersproject/bignumber@^5.0.7", "@ethersproject/bignumber@^5.5.0":
12091209
version "5.5.0"
1210-
resolved "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.5.0.tgz"
1210+
resolved "https://registry.yarnpkg.com/@ethersproject/bignumber/-/bignumber-5.5.0.tgz#875b143f04a216f4f8b96245bde942d42d279527"
12111211
integrity sha512-6Xytlwvy6Rn3U3gKEc1vP7nR92frHkv6wtVr95LFR3jREXiCPzdWxKQ1cx4JGQBXxcguAwjA8murlYN2TSiEbg==
12121212
dependencies:
12131213
"@ethersproject/bytes" "^5.5.0"
@@ -1437,6 +1437,15 @@
14371437
"@ethersproject/constants" "^5.5.0"
14381438
"@ethersproject/logger" "^5.5.0"
14391439

1440+
"@ethersproject/units@^5.5.0":
1441+
version "5.5.0"
1442+
resolved "https://registry.yarnpkg.com/@ethersproject/units/-/units-5.5.0.tgz#104d02db5b5dc42cc672cc4587bafb87a95ee45e"
1443+
integrity sha512-7+DpjiZk4v6wrikj+TCyWWa9dXLNU73tSTa7n0TSJDxkYbV3Yf1eRh9ToMLlZtuctNYu9RDNNy2USq3AdqSbag==
1444+
dependencies:
1445+
"@ethersproject/bignumber" "^5.5.0"
1446+
"@ethersproject/constants" "^5.5.0"
1447+
"@ethersproject/logger" "^5.5.0"
1448+
14401449
"@ethersproject/[email protected]":
14411450
version "5.5.0"
14421451
resolved "https://registry.npmjs.org/@ethersproject/wallet/-/wallet-5.5.0.tgz"

0 commit comments

Comments
 (0)