Skip to content

Commit

Permalink
Merge pull request #36 from 0xChijioke/main
Browse files Browse the repository at this point in the history
Updated auth files
  • Loading branch information
0xChijioke authored Sep 8, 2024
2 parents f48ef1a + 6c6cbf0 commit 63dbfe0
Show file tree
Hide file tree
Showing 5 changed files with 225 additions and 0 deletions.
70 changes: 70 additions & 0 deletions packages/nextjs/app/api/auth/[...nextauth]/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
// app/api/auth/[...nextauth]/route.ts
import { createAppClient, viemConnector } from "@farcaster/auth-client";
import NextAuth from "next-auth";
import CredentialsProvider from "next-auth/providers/credentials";

export const authOptions = {
providers: [
CredentialsProvider({
name: "Sign in with Farcaster",
credentials: {
message: {
label: "Message",
type: "text",
placeholder: "0x0",
},
signature: {
label: "Signature",
type: "text",
placeholder: "0x0",
},
name: {
label: "Name",
type: "text",
placeholder: "0x0",
},
pfp: {
label: "Pfp",
type: "text",
placeholder: "0x0",
},
nonce: {
label: "Nonce",
type: "text",
placeholder: "0x0",
},
},
async authorize(credentials) {
if (!credentials) return null;

const appClient = createAppClient({
ethereum: viemConnector(),
});

const verifyResponse = await appClient.verifySignInMessage({
message: credentials.message,
signature: credentials.signature as `0x${string}`,
domain: "localhost:3000",
nonce: credentials.nonce,
});

const { success, fid } = verifyResponse;

if (!success) {
return null;
}

return {
id: fid.toString(),
name: credentials.name,
image: credentials.pfp,
};
},
}),
],
secret: process.env.NEXTAUTH_SECRET,
};

const handler = NextAuth(authOptions);

export { handler as GET, handler as POST };
10 changes: 10 additions & 0 deletions packages/nextjs/app/api/auth/session/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// app/api/auth/session/route.ts
import { NextResponse } from "next/server";
import { authOptions } from "../[...nextauth]/route";
import { getServerSession } from "next-auth";

export async function GET() {
const session = await getServerSession(authOptions);
if (!session) return NextResponse.json({});
return NextResponse.json(session);
}
29 changes: 29 additions & 0 deletions packages/nextjs/app/api/login/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { NextRequest, NextResponse } from "next/server";
import jwt from "jsonwebtoken";

export async function POST(req: NextRequest) {
try {
const { userData } = await req.json();
const privateKey = process.env.PRIVATE_KEY!;

const jwtToken = jwt.sign(
{
sub: userData?.fid.toString(),
name: userData?.displayName,
username: userData?.username,
profileImage: userData?.pfpUrl,
custody: userData?.custody,
aud: "w3a:farcaster-server",
iss: "https://web3auth.io",
iat: Math.floor(Date.now() / 1000),
exp: Math.floor(Date.now() / 1000) + 60 * 60,
},
privateKey,
{ algorithm: "RS256", keyid: "02e626b5-600c-48c3-a812-2ff0edd8f12f" },
);

return NextResponse.json({ token: jwtToken });
} catch (error) {
return NextResponse.json({ error: "Failed to generate token" }, { status: 500 });
}
}
79 changes: 79 additions & 0 deletions packages/nextjs/app/auth/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
"use client";

import { useEffect, useState } from "react";
import { useRouter } from "next/navigation";
import { COREKIT_STATUS } from "@web3auth/mpc-core-kit";
import { useWeb3Auth } from "~~/context/Web3Context";
import { getWeb3AuthInstance } from "~~/helpers/web3Auth";

const getHashParams = () => {
const hash = window.location.hash.substring(1);
const params = new URLSearchParams(hash);
return {
idToken: params.get("id_token"),
};
};

const Auth = () => {
const router = useRouter();
const { signInWithJWT, setUser } = useWeb3Auth();
const [web3AuthInstance, setWeb3AuthInstance] = useState<any>();
const [idToken, setIdToken] = useState<any>();

useEffect(() => {
const initWeb3Auth = async () => {
try {
const web3AuthInstance = await getWeb3AuthInstance();

if (web3AuthInstance.status === COREKIT_STATUS.LOGGED_IN) {
const userInfo = await web3AuthInstance.getUserInfo();
setUser(userInfo);
router.push("/harvest");
return;
}

web3AuthInstance.status === COREKIT_STATUS.INITIALIZED && setWeb3AuthInstance(web3AuthInstance);
} catch (error) {
console.error("Web3Auth initialization error:", error);
}
};
initWeb3Auth();
}, []);

useEffect(() => {
const { idToken } = getHashParams();
if (idToken) {
setIdToken(idToken);
} else {
console.log("No id_token found in URL hash");
}
}, []);

useEffect(() => {
const handleAuthRedirect = async () => {
if (web3AuthInstance && idToken) {
try {
if (web3AuthInstance.status === COREKIT_STATUS.INITIALIZED) {
await signInWithJWT(idToken, "google");
router.push("/manage");
} else {
console.error("Web3Auth instance is not initialized.");
}
} catch (error) {
console.error("Error handling redirect result:", error);
}
}
};

handleAuthRedirect();
}, [web3AuthInstance, idToken, router]);

return (
<div className="w-full h-full flex flex-col justify-center items-center my-auto">
<p className="text-center text-lg italic">Authenticating... Please wait.</p>
<progress className="progress w-56"></progress>
</div>
);
};

export default Auth;
37 changes: 37 additions & 0 deletions packages/nextjs/components/hyperharvest/Balance.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { useBalances } from "~~/hooks/useBalances";
import { useGlobalState } from "~~/services/store/store";

type BalanceProps = {
address?: string;
className?: string;
usdMode?: boolean;
};

export const Balance = ({ address, className = "", usdMode }: BalanceProps) => {
const { ethBalance, usdcBalance } = useBalances(address);
const nativeCurrencyPrice = useGlobalState(state => state.nativeCurrency.price);
const displayUsdMode = usdMode || false;

if (!ethBalance || !usdcBalance) {
return (
<div className="animate-pulse flex space-x-4">
<div className="rounded-md bg-slate-300 h-6 w-6"></div>
<div className="flex items-center space-y-6">
<div className="h-2 w-28 bg-slate-300 rounded"></div>
</div>
</div>
);
}

const ethBalanceInUsd = parseFloat(ethBalance) * nativeCurrencyPrice;

return (
<div className={`flex ${className}`}>
<div className="text-sm">
{parseFloat(ethBalance).toFixed(3)} {"Ξ"}
{displayUsdMode && <span className="text-sm text-gray-500"> ({ethBalanceInUsd.toFixed(3)} USD)</span>}
</div>
<div className="text-sm">{parseFloat(usdcBalance).toFixed(2)} USDC</div>
</div>
);
};

0 comments on commit 63dbfe0

Please sign in to comment.