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) => {
) : (