Skip to content

Commit

Permalink
Merge pull request #19 from farcasterxyz/nickcherry/mobile-auth
Browse files Browse the repository at this point in the history
Remove Next Auth
  • Loading branch information
nickcherry authored Jan 30, 2024
2 parents 7ff97b7 + b168f77 commit e1728b1
Show file tree
Hide file tree
Showing 20 changed files with 317 additions and 86 deletions.
2 changes: 1 addition & 1 deletion mobile/.eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ module.exports = {
'react/react-in-jsx-scope': 'off',
'simple-import-sort/exports': 'error',
'simple-import-sort/imports': 'error',
'tailwindcss/no-custom-classname': 'error',
'tailwindcss/no-custom-classname': 'off',
'unused-imports/no-unused-imports': 'error',
},
};
Binary file modified mobile/bun.lockb
Binary file not shown.
4 changes: 3 additions & 1 deletion mobile/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"typecheck": "tsc -p tsconfig.json --noEmit"
},
"dependencies": {
"@farcaster/auth-kit": "0.2.0",
"@react-navigation/native": "^6.1.9",
"@react-navigation/native-stack": "^6.9.17",
"@shopify/flash-list": "^1.6.3",
Expand All @@ -23,7 +24,8 @@
"react": "18.2.0",
"react-native": "0.73.2",
"react-native-safe-area-context": "4.8.2",
"react-native-screens": "~3.29.0"
"react-native-screens": "~3.29.0",
"text-encoding-polyfill": "^0.6.7"
},
"devDependencies": {
"@babel/core": "^7.20.0",
Expand Down
5 changes: 4 additions & 1 deletion mobile/src/components/app/App.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { FullscreenLoader } from '@mobile/components/loader/FullscreenLoader';
import { Navigator } from '@mobile/components/navigation/Navigator';
import { AuthProvider } from '@mobile/contexts/AuthProvider';
import { NavigationContainer } from '@react-navigation/native';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { StatusBar } from 'expo-status-bar';
Expand All @@ -15,7 +16,9 @@ export function App() {
<QueryClientProvider client={queryClient}>
<StatusBar style="auto" />
<Suspense fallback={<FullscreenLoader />}>
<Navigator />
<AuthProvider>
<Navigator />
</AuthProvider>
</Suspense>
</QueryClientProvider>
</NavigationContainer>
Expand Down
46 changes: 31 additions & 15 deletions mobile/src/components/navigation/Navigator.tsx
Original file line number Diff line number Diff line change
@@ -1,28 +1,44 @@
import { useAuth } from '@mobile/contexts/AuthProvider';
import { FeedScreen } from '@mobile/screens/FeedScreen';
import { LandingScreen } from '@mobile/screens/LandingScreen';
import { ProfileScreen } from '@mobile/screens/ProfileScreen';
import { RootParamList } from '@mobile/types/navigation';
import { createNativeStackNavigator } from '@react-navigation/native-stack';

const Stack = createNativeStackNavigator<RootParamList>();

export function Navigator() {
const { isSignedIn } = useAuth();

return (
<Stack.Navigator>
<Stack.Screen
name="Feed"
component={FeedScreen}
options={{ headerShown: false }}
/>
<Stack.Screen
name="Profile"
component={ProfileScreen}
options={({ route }) => {
const { displayName } = route.params as RootParamList['Profile'];
return {
headerTitle: displayName,
};
}}
/>
{isSignedIn ? (
<>
<Stack.Screen
name="Feed"
component={FeedScreen}
options={{ headerShown: false }}
/>
<Stack.Screen
name="Profile"
component={ProfileScreen}
options={({ route }) => {
const { displayName } = route.params as RootParamList['Profile'];
return {
headerTitle: displayName,
};
}}
/>
</>
) : (
<>
<Stack.Screen
name="Landing"
component={LandingScreen}
options={{ headerShown: false }}
/>
</>
)}
</Stack.Navigator>
);
}
73 changes: 73 additions & 0 deletions mobile/src/contexts/AuthProvider.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import { AuthKitProvider, useSignIn } from '@farcaster/auth-kit';
import {
createContext,
ReactNode,
useCallback,
useContext,
useState,
} from 'react';
import { Linking } from 'react-native';

const AuthContext = createContext<{
isSignedIn: boolean;
signIn: () => Promise<void>;
token: string | undefined;
}>({
isSignedIn: false,
signIn: async () => {
throw new Error(
'You need to add an AuthProvider to the top of your React tree.',
);
},
token: undefined,
});

type AuthProviderProps = {
children: ReactNode;
};

function AuthProviderContent({ children }: AuthProviderProps) {
const [token, setToken] = useState<string>();

const {
connect,
url,
signIn: authKitSignIn,
} = useSignIn({
onSuccess: (res) => {
// setToken(res);
},
});
const signIn = useCallback(async () => {
// if (url) {
await connect();
await authKitSignIn(); // Starts polling
Linking.openURL(url);
// }
}, [authKitSignIn, connect, url]);

return (
<AuthContext.Provider value={{ isSignedIn: !!token, signIn, token }}>
{children}
</AuthContext.Provider>
);
}

export function AuthProvider(props: AuthProviderProps) {
return (
<AuthKitProvider
config={{
relay: 'https://relay.farcaster.xyz',
rpcUrl: 'https://mainnet.optimism.io',
siweUri: 'http://localhost:3000',
domain: 'localhost:3000',
}}
>
<AuthProviderContent {...props} />
</AuthKitProvider>
);
}

export function useAuth() {
return useContext(AuthContext);
}
2 changes: 2 additions & 0 deletions mobile/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import 'text-encoding-polyfill';

import { App } from '@mobile/components/app/App';
import { registerRootComponent } from 'expo';

Expand Down
36 changes: 36 additions & 0 deletions mobile/src/screens/LandingScreen.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { Loader } from '@mobile/components/loader/Loader';
import { useAuth } from '@mobile/contexts/AuthProvider';
import { buildScreen } from '@mobile/utils/buildScreen';
import { useState } from 'react';
import { Pressable, Text, View } from 'react-native';

export const LandingScreen = buildScreen(() => {
const { signIn } = useAuth();
const [isSigningIn, setIsSigningIn] = useState(false);

return (
<View className="flex-1 items-center justify-center">
<Pressable
onPress={async () => {
setIsSigningIn(true);

try {
await signIn();
} catch (error) {
console.error(error);
} finally {
setIsSigningIn(false);
}
}}
>
<View className="bg-fc-purple min-h-[60px] min-w-[120px] flex-row items-center justify-center rounded-lg p-4">
{isSigningIn ? (
<Loader />
) : (
<Text className="text-lg font-bold text-white">Login</Text>
)}
</View>
</Pressable>
</View>
);
});
1 change: 1 addition & 0 deletions mobile/src/types/navigation.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
export type RootParamList = {
Feed: NoParams;
Landing: NoParams;
Profile: { displayName: string; fid: string };
};

Expand Down
6 changes: 5 additions & 1 deletion mobile/tailwind.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@
module.exports = {
content: ['./src/**/*.{js,jsx,ts,tsx}'],
theme: {
extend: {},
extend: {
colors: {
'fc-purple': '#7c65c1',
},
},
},
plugins: [],
};
18 changes: 9 additions & 9 deletions web/.eslintrc.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
module.exports = {
extends: ["next/core-web-vitals", "plugin:tailwindcss/recommended"],
plugins: ["simple-import-sort", "unused-imports"],
extends: ['next/core-web-vitals', 'plugin:tailwindcss/recommended'],
plugins: ['simple-import-sort', 'unused-imports'],
rules: {
"@next/next/no-img-element": "off",
"jsx-a11y/alt-text": "off",
"no-duplicate-imports": "error",
"simple-import-sort/exports": "error",
"simple-import-sort/imports": "error",
"tailwindcss/no-custom-classname": "error",
"unused-imports/no-unused-imports": "error",
'@next/next/no-img-element': 'off',
'jsx-a11y/alt-text': 'off',
'no-duplicate-imports': 'error',
'simple-import-sort/exports': 'error',
'simple-import-sort/imports': 'error',
'tailwindcss/no-custom-classname': 'off',
'unused-imports/no-unused-imports': 'error',
},
};
Binary file modified web/bun.lockb
Binary file not shown.
3 changes: 1 addition & 2 deletions web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,12 @@
"db:codegen": "kysely-codegen --dialect postgres --out-file ./src/lib/database/types.ts"
},
"dependencies": {
"@farcaster/auth-kit": "^0.2.0",
"@farcaster/auth-kit": "0.2.0",
"@farcaster/core": "^0.13.4",
"date-fns": "^3.3.1",
"linkify-it": "^5.0.0",
"linkify-react": "^4.1.3",
"next": "14.1.0",
"next-auth": "^4.24.5",
"react": "^18",
"react-dom": "^18"
},
Expand Down
36 changes: 36 additions & 0 deletions web/src/app/api/auth/sign-in/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { createAppClient, viemConnector } from '@farcaster/auth-kit';
import { NextResponse } from 'next/server';

type RequestBody = {
message: string;
signature: `0x${string}`;
nonce: string;
};

export async function POST(request: Request) {
const { message, signature, nonce }: RequestBody = await request.json();

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

const verifyResult = await appClient.verifySignInMessage({
domain: 'localhost:3000',
message,
nonce,
signature,
});

if (!verifyResult.success) {
return NextResponse.json(verifyResult.error || 'Sign in failed', {
status: 401,
});
}

const token = window.crypto.randomUUID();

return NextResponse.json({
id: verifyResult.fid.toString(),
token,
});
}
14 changes: 7 additions & 7 deletions web/src/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import "./globals.css";
import "@farcaster/auth-kit/styles.css";
import './globals.css';
import '@farcaster/auth-kit/styles.css';

import type { Metadata } from "next";
import { Inter } from "next/font/google";
import type { Metadata } from 'next';
import { Inter } from 'next/font/google';

const inter = Inter({ subsets: ["latin"], weight: ["400", "600"] });
const inter = Inter({ subsets: ['latin'], weight: ['400', '600'] });

export const metadata: Metadata = {
title: "Quikcast",
description: "Farcaster client boilerplate",
title: 'Quikcast',
description: 'Farcaster client boilerplate',
};

export default function RootLayout({
Expand Down
28 changes: 11 additions & 17 deletions web/src/app/page.tsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,16 @@
import { FeedPage } from "@components/feed/FeedPage";
import { LandingPage } from "@components/landing/LandingPage";
import { getServerSession } from "next-auth";

import { authOptions } from "./api/auth/[...nextauth]/route";
import { LandingPage } from '@components/landing/LandingPage';

export default async function Home() {
const session = await getServerSession(authOptions);

if (session) {
const {
user: { fid },
} = session;
return (
<div>
<FeedPage fid={fid} />
</div>
);
}
// if (session) {
// const {
// user: { fid },
// } = session;
// return (
// <div>
// <FeedPage fid={fid} />
// </div>
// );
// }

return <LandingPage />;
}
Loading

0 comments on commit e1728b1

Please sign in to comment.