diff --git a/.env.template b/.env.template index 05124e09..88d3fa94 100644 --- a/.env.template +++ b/.env.template @@ -5,7 +5,7 @@ DISCORD_CHANNEL_NAME=devnode MYSQL_URL=mysql://root:testpassword@localhost/devnode NEXTAUTH_URL=http://localhost:3000/ NEXT_PUBLIC_DISCORD_BOT_URL=http://localhost:4000/ -DISCORD_SERVER_URL= +DISCORD_SERVER_URL= #Staging DISCORD_BOT_NAME=devnode-bot-staging @@ -23,5 +23,14 @@ DISCORD_BOT_NAME=devnode-bot #CERAMIC_NODE=https://ceramic-daemon-production.up.railway.app #NEXTAUTH_URL=https://devnode-production.up.railway.app/ +# discord user oauth creds +NEXT_PUBLIC_APP_HOME=http://localhost:3000 +NEXT_PUBLIC_DISCORD_OAUTH_CLIENT_ID= +NEXT_PUBLIC_DISCORD_OAUTH_CLIENT_SECRET= +NEXT_PUBLIC_DISCORD_OAUTH_REDIRECT_URL=$NEXT_PUBLIC_APP_HOME + +# wallet connect project id +NEXT_PUBLIC_WALLET_CONNECT_PROJECT_ID= + NODE_VERSION=16.18.0 -NIXPACKS_NODE_VERSION=16 \ No newline at end of file +NIXPACKS_NODE_VERSION=16 diff --git a/.gitignore b/.gitignore index eec6942b..2a4936ca 100644 --- a/.gitignore +++ b/.gitignore @@ -36,4 +36,5 @@ apps/indexer/tsconfig.tsbuildinfo prisma/dev.db .env -packages/composedb/.ceramic \ No newline at end of file +packages/composedb/.ceramic +.idea/ diff --git a/apps/web/package.json b/apps/web/package.json index 6ce07e5b..fdbd547a 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -29,6 +29,9 @@ "@trpc/next": "10.7.0", "@trpc/react-query": "10.7.0", "@trpc/server": "10.7.0", + "@web3modal/ethereum": "^2.1.2", + "@web3modal/react": "^2.1.2", + "axios": "^1.3.4", "did-session": "^1.0.0", "ethers": "^5.7.2", "graphql-request": "^5.1.0", diff --git a/apps/web/src/components/Button/ConnectWalletButton.tsx b/apps/web/src/components/Button/ConnectWalletButton.tsx new file mode 100644 index 00000000..9b065ebf --- /dev/null +++ b/apps/web/src/components/Button/ConnectWalletButton.tsx @@ -0,0 +1,33 @@ +import {useWeb3Modal} from '@web3modal/react'; +import {useState} from 'react'; +import {useAccount, useDisconnect} from 'wagmi'; + +export const ConnectWalletButton = () => { + const {open} = useWeb3Modal() + const {disconnect} = useDisconnect() + const {isConnected, address} = useAccount() + const [loading, setLoading] = useState(false) + + const onOpen = async () => { + setLoading(true) + await open() + setLoading(false) + } + + const onClick = async () => { + isConnected ? disconnect() : await onOpen() + } + + const getAddress = () => { + return address ? address.slice(0, 8).concat("...") : ""; + } + + return ( + + ) +} diff --git a/apps/web/src/components/Button/index.ts b/apps/web/src/components/Button/index.ts new file mode 100644 index 00000000..f0725a9c --- /dev/null +++ b/apps/web/src/components/Button/index.ts @@ -0,0 +1 @@ +export * from './ConnectWalletButton'; diff --git a/apps/web/src/components/NavBar/NavBar.tsx b/apps/web/src/components/NavBar/NavBar.tsx index 12926912..ffcbe25a 100644 --- a/apps/web/src/components/NavBar/NavBar.tsx +++ b/apps/web/src/components/NavBar/NavBar.tsx @@ -1,18 +1,17 @@ import { Popover, Transition } from "@headlessui/react"; -import { useConnect, useAccount, useDisconnect } from "wagmi"; +import { useAccount } from "wagmi"; import Image from "next/image"; -import { Fragment, useState } from "react"; +import {Fragment, useEffect, useState} from "react"; import { EthereumWebAuth, getAccountId } from "@didtools/pkh-ethereum"; import { DIDSession } from "did-session"; import useLocalStorage from "../../hooks/useLocalStorage"; -import { Resolver } from "did-resolver"; -import { getResolver } from "pkh-did-resolver"; import { trpc } from "../../utils/trpc"; import { Modal } from "../Modal"; import Link from "next/link"; - -const pkhResolver = getResolver(); -const resolver = new Resolver(pkhResolver); +import {getDiscordAuthUrl} from "../../config"; +import {useRouter} from "next/router"; +import {toast} from "react-toastify"; +import {ConnectWalletButton} from "../Button"; function classNames(...classes: string[]) { return classes.filter(Boolean).join(" "); @@ -21,8 +20,8 @@ function classNames(...classes: string[]) { const navigation = [{ name: "Ask a question", href: "#", current: true }]; const NavBar = (props) => { - const { disconnectAsync } = useDisconnect(); - const { connectors, connectAsync } = useConnect(); + const router = useRouter(); + const code = router.query.code as string; const { address, isConnected } = useAccount(); const [did, setDid] = useLocalStorage("did", ""); @@ -36,13 +35,13 @@ const NavBar = (props) => { const discordUserName = authorDiscord.data?.discordUsername; discordUserName && props.handleDiscordUser(true); - const connectWallet = async () => { - await Promise.all( - connectors.map(async (connector) => { - if (!isConnected) await connectAsync({ connector }); - }) - ); - }; + + useEffect(() => { + const profile = localStorage.getItem("discord"); + if (code && !profile) { + handleDiscordAuthCallback(code).catch((e) => { console.error(e) }) + } + }, [code]); const handleDIDSession = async () => { if (!isConnected) return; @@ -74,6 +73,19 @@ const NavBar = (props) => { setOpen((state) => !state); }; + const handleDiscordConnect = () => { + const redirect = getDiscordAuthUrl() + window.location.replace(redirect) + } + + const handleDiscordAuthCallback = async (code: string) => { + const response = await fetch(`/api/user/discord-auth/profile?code=${code}`); + const profile = await response.json(); + localStorage.setItem("discord", JSON.stringify(profile)); + toast.success("Successfully logged in with discord"); + props.handleDiscordUser(true); + } + return ( <> {/* When the mobile menu is open, add `overflow-hidden` to the `body` element to prevent double scrollbars */} @@ -146,25 +158,7 @@ const NavBar = (props) => { */}
- {isConnected ? ( - - ) : ( - - )} + {isConnected && did.length > 0 ? ( @@ -233,7 +227,7 @@ const NavBar = (props) => { ) : (