diff --git a/src/app/providers.tsx b/src/app/providers.tsx
index 2b335d8..90584eb 100644
--- a/src/app/providers.tsx
+++ b/src/app/providers.tsx
@@ -32,9 +32,7 @@ export function Providers({
backButtonEnabled={true}
>
-
- {children}
-
+ {children}
diff --git a/src/auth.ts b/src/auth.ts
index 8c39468..4d06956 100644
--- a/src/auth.ts
+++ b/src/auth.ts
@@ -1,8 +1,8 @@
-import { AuthOptions, getServerSession } from "next-auth"
-import CredentialsProvider from "next-auth/providers/credentials";
-import { createAppClient, viemConnector } from "@farcaster/auth-client";
+import { AuthOptions, getServerSession } from 'next-auth';
+import CredentialsProvider from 'next-auth/providers/credentials';
+import { createAppClient, viemConnector } from '@farcaster/auth-client';
-declare module "next-auth" {
+declare module 'next-auth' {
interface Session {
user: {
fid: number;
@@ -26,43 +26,50 @@ function getDomainFromUrl(urlString: string | undefined): string {
}
export const authOptions: AuthOptions = {
- // Configure one or more authentication providers
+ // Configure one or more authentication providers
providers: [
CredentialsProvider({
- name: "Sign in with Farcaster",
+ name: 'Sign in with Farcaster',
credentials: {
message: {
- label: "Message",
- type: "text",
- placeholder: "0x0",
+ label: 'Message',
+ type: 'text',
+ placeholder: '0x0',
},
signature: {
- label: "Signature",
- type: "text",
- placeholder: "0x0",
+ label: 'Signature',
+ type: 'text',
+ placeholder: '0x0',
+ },
+ nonce: {
+ label: 'Nonce',
+ type: 'text',
+ placeholder: 'Custom nonce (optional)',
},
// In a production app with a server, these should be fetched from
// your Farcaster data indexer rather than have them accepted as part
// of credentials.
// question: should these natively use the Neynar API?
name: {
- label: "Name",
- type: "text",
- placeholder: "0x0",
+ label: 'Name',
+ type: 'text',
+ placeholder: '0x0',
},
pfp: {
- label: "Pfp",
- type: "text",
- placeholder: "0x0",
+ label: 'Pfp',
+ type: 'text',
+ placeholder: '0x0',
},
},
async authorize(credentials, req) {
const csrfToken = req?.body?.csrfToken;
- if (!csrfToken) {
- console.error('CSRF token is missing from request');
+
+ const nonce = credentials?.nonce || csrfToken;
+
+ if (!nonce) {
+ console.error('No nonce or CSRF token provided');
return null;
}
-
const appClient = createAppClient({
ethereum: viemConnector(),
});
@@ -73,8 +80,9 @@ export const authOptions: AuthOptions = {
message: credentials?.message as string,
signature: credentials?.signature as `0x${string}`,
domain,
- nonce: csrfToken,
+ nonce,
});
+
const { success, fid } = verifyResponse;
if (!success) {
@@ -100,30 +108,30 @@ export const authOptions: AuthOptions = {
name: `next-auth.session-token`,
options: {
httpOnly: true,
- sameSite: "none",
- path: "/",
- secure: true
- }
+ sameSite: 'none',
+ path: '/',
+ secure: true,
+ },
},
callbackUrl: {
name: `next-auth.callback-url`,
options: {
- sameSite: "none",
- path: "/",
- secure: true
- }
+ sameSite: 'none',
+ path: '/',
+ secure: true,
+ },
},
csrfToken: {
name: `next-auth.csrf-token`,
options: {
httpOnly: true,
- sameSite: "none",
- path: "/",
- secure: true
- }
- }
- }
-}
+ sameSite: 'none',
+ path: '/',
+ secure: true,
+ },
+ },
+ },
+};
export const getSession = async () => {
try {
@@ -132,4 +140,4 @@ export const getSession = async () => {
console.error('Error getting server session:', error);
return null;
}
-}
+};
diff --git a/src/components/ui/NeynarAuthButton/AuthDialog.tsx b/src/components/ui/NeynarAuthButton/AuthDialog.tsx
index 2fc64d3..69c2c9a 100644
--- a/src/components/ui/NeynarAuthButton/AuthDialog.tsx
+++ b/src/components/ui/NeynarAuthButton/AuthDialog.tsx
@@ -12,7 +12,7 @@ export function AuthDialog({
}: {
open: boolean;
onClose: () => void;
- url: string;
+ url?: string;
isError: boolean;
error?: Error | null;
step: 'signin' | 'access' | 'loading';
@@ -47,49 +47,49 @@ export function AuthDialog({
return {
title: 'Grant Access',
description: (
-
-
+
+
Allow this app to access your Farcaster account:
-
-
-
+
+
+
-
+
Read Access
-
+
View your profile and public information
-
-
+
+
-
+
Write Access
-
+
Post casts, likes, and update your profile
@@ -118,43 +118,43 @@ export function AuthDialog({
const content = getStepContent();
return (
-
-
-
-
+
+
+
+
{isError ? 'Error' : content.title}
{isError ? (
-
-
+
+
{error?.message || 'Unknown error, please try again.'}
) : (
-
-
+
+
{typeof content.description === 'string' ? (
-
+
{content.description}
) : (
@@ -162,23 +162,23 @@ export function AuthDialog({
)}
-
+
{content.showQR && content.qrUrl ? (
-
+
{/* eslint-disable-next-line @next/next/no-img-element */}
) : step === 'loading' || isLoading ? (
-
-
-
-
+
+
+
+
{step === 'loading'
? 'Setting up access...'
: 'Loading...'}
@@ -204,7 +204,7 @@ export function AuthDialog({
'_blank'
)
}
- className='btn btn-outline flex items-center justify-center gap-2 w-full'
+ className="btn btn-outline flex items-center justify-center gap-2 w-full"
>
I'm using my phone →
diff --git a/src/components/ui/NeynarAuthButton/ProfileButton.tsx b/src/components/ui/NeynarAuthButton/ProfileButton.tsx
index daec476..bcf1ca7 100644
--- a/src/components/ui/NeynarAuthButton/ProfileButton.tsx
+++ b/src/components/ui/NeynarAuthButton/ProfileButton.tsx
@@ -20,7 +20,7 @@ export function ProfileButton({
const pfpUrl = userData?.pfpUrl ?? 'https://farcaster.xyz/avatar.png';
return (
-
+
{showDropdown && (
-
+