Compare commits

..

2 Commits

Author SHA1 Message Date
Shreyaschorge
20c6113b8f fix qoutes 2025-09-18 21:01:36 +05:30
Shreyaschorge
343d64a77c Enfore resolutions 2025-09-18 20:58:47 +05:30
3 changed files with 53 additions and 58 deletions

View File

@@ -515,7 +515,7 @@ export async function init(
'@farcaster/miniapp-wagmi-connector': '^1.0.0',
'@farcaster/mini-app-solana': '>=0.0.17 <1.0.0',
'@farcaster/quick-auth': '>=0.0.7 <1.0.0',
'@neynar/react': '^1.2.14',
'@neynar/react': '^1.2.13',
'@radix-ui/react-label': '^2.1.1',
'@solana/wallet-adapter-react': '^0.15.38',
'@tanstack/react-query': '^5.61.0',
@@ -584,7 +584,9 @@ export async function init(
"supports-color": "10.2.0",
"strip-ansi": "7.1.0",
"chalk": "5.6.0",
"ansi-styles": "6.2.1"
"ansi-styles": "6.2.1",
"axios@^1": ">=1 <2",
"axios@^0": ">=0 <1",
};
// npm v8.3+ overrides

4
package-lock.json generated
View File

@@ -1,12 +1,12 @@
{
"name": "@neynar/create-farcaster-mini-app",
"version": "1.8.13",
"version": "1.8.8",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "@neynar/create-farcaster-mini-app",
"version": "1.8.13",
"version": "1.8.8",
"dependencies": {
"dotenv": "^16.4.7",
"inquirer": "^12.4.3",

View File

@@ -1,12 +1,5 @@
'use client';
/**
* This authentication system is designed to work both in a regular web browser and inside a miniapp.
* In other words, it supports authentication when the miniapp context is not present (web browser) as well as when the app is running inside the miniapp.
* If you only need authentication for a web application, follow the Webapp flow;
* if you only need authentication inside a miniapp, follow the Miniapp flow.
*/
import '@farcaster/auth-kit/styles.css';
import { useSignIn, UseSignInData } from '@farcaster/auth-kit';
import { useCallback, useEffect, useState, useRef } from 'react';
@@ -17,8 +10,8 @@ import { AuthDialog } from '~/components/ui/NeynarAuthButton/AuthDialog';
import { getItem, removeItem, setItem } from '~/lib/localStorage';
import { useMiniApp } from '@neynar/react';
import {
signIn as miniappSignIn,
signOut as miniappSignOut,
signIn as backendSignIn,
signOut as backendSignOut,
useSession,
} from 'next-auth/react';
import sdk, { SignIn as SignInCore } from '@farcaster/miniapp-sdk';
@@ -123,7 +116,7 @@ export function NeynarAuthButton() {
const signerFlowStartedRef = useRef(false);
// Determine which flow to use based on context
const useMiniappFlow = context !== undefined;
const useBackendFlow = context !== undefined;
// Helper function to create a signer
const createSigner = useCallback(async () => {
@@ -144,16 +137,16 @@ export function NeynarAuthButton() {
}
}, []);
// Helper function to update session with signers (miniapp flow only)
// Helper function to update session with signers (backend flow only)
const updateSessionWithSigners = useCallback(
async (
signers: StoredAuthState['signers'],
user: StoredAuthState['user']
) => {
if (!useMiniappFlow) return;
if (!useBackendFlow) return;
try {
// For miniapp flow, we need to sign in again with the additional data
// For backend flow, we need to sign in again with the additional data
if (message && signature) {
const signInData = {
message,
@@ -165,13 +158,13 @@ export function NeynarAuthButton() {
user: JSON.stringify(user),
};
await miniappSignIn('neynar', signInData);
await backendSignIn('neynar', signInData);
}
} catch (error) {
console.error('❌ Error updating session with signers:', error);
}
},
[useMiniappFlow, message, signature, nonce]
[useBackendFlow, message, signature, nonce]
);
// Helper function to fetch user data from Neynar API
@@ -238,7 +231,7 @@ export function NeynarAuthButton() {
try {
setSignersLoading(true);
const endpoint = useMiniappFlow
const endpoint = useBackendFlow
? `/api/auth/session-signers?message=${encodeURIComponent(
message
)}&signature=${signature}`
@@ -250,8 +243,8 @@ export function NeynarAuthButton() {
const signerData = await response.json();
if (response.ok) {
if (useMiniappFlow) {
// For miniapp flow, update session with signers
if (useBackendFlow) {
// For backend flow, update session with signers
if (signerData.signers && signerData.signers.length > 0) {
const user =
signerData.user ||
@@ -260,7 +253,7 @@ export function NeynarAuthButton() {
}
return signerData.signers;
} else {
// For webapp flow, store in localStorage
// For frontend flow, store in localStorage
let user: StoredAuthState['user'] | null = null;
if (signerData.signers && signerData.signers.length > 0) {
@@ -292,7 +285,7 @@ export function NeynarAuthButton() {
setSignersLoading(false);
}
},
[useMiniappFlow, fetchUserData, updateSessionWithSigners]
[useBackendFlow, fetchUserData, updateSessionWithSigners]
);
// Helper function to poll signer status
@@ -391,21 +384,21 @@ export function NeynarAuthButton() {
generateNonce();
}, []);
// Load stored auth state on mount (only for webapp flow)
// Load stored auth state on mount (only for frontend flow)
useEffect(() => {
if (!useMiniappFlow) {
if (!useBackendFlow) {
const stored = getItem<StoredAuthState>(STORAGE_KEY);
if (stored && stored.isAuthenticated) {
setStoredAuth(stored);
}
}
}, [useMiniappFlow]);
}, [useBackendFlow]);
// Success callback - this is critical!
const onSuccessCallback = useCallback(
async (res: UseSignInData) => {
if (!useMiniappFlow) {
// Only handle localStorage for webapp flow
if (!useBackendFlow) {
// Only handle localStorage for frontend flow
const existingAuth = getItem<StoredAuthState>(STORAGE_KEY);
const user = res.fid ? await fetchUserData(res.fid) : null;
const authState: StoredAuthState = {
@@ -417,9 +410,9 @@ export function NeynarAuthButton() {
setItem<StoredAuthState>(STORAGE_KEY, authState);
setStoredAuth(authState);
}
// For miniapp flow, the session will be handled by NextAuth
// For backend flow, the session will be handled by NextAuth
},
[useMiniappFlow, fetchUserData]
[useBackendFlow, fetchUserData]
);
// Error callback
@@ -434,8 +427,8 @@ export function NeynarAuthButton() {
});
const {
signIn: webappSignIn,
signOut: webappSignOut,
signIn: frontendSignIn,
signOut: frontendSignOut,
connect,
reconnect,
isSuccess,
@@ -457,12 +450,12 @@ export function NeynarAuthButton() {
}
}, [data?.message, data?.signature]);
// Connect for webapp flow when nonce is available
// Connect for frontend flow when nonce is available
useEffect(() => {
if (!useMiniappFlow && nonce && !channelToken) {
if (!useBackendFlow && nonce && !channelToken) {
connect();
}
}, [useMiniappFlow, nonce, channelToken, connect]);
}, [useBackendFlow, nonce, channelToken, connect]);
// Handle fetching signers after successful authentication
useEffect(() => {
@@ -485,14 +478,14 @@ export function NeynarAuthButton() {
// Step 1: Change to loading state
setDialogStep('loading');
// Show dialog if not using miniapp flow or in browser farcaster
if ((useMiniappFlow && !isMobileContext) || !useMiniappFlow)
// Show dialog if not using backend flow or in browser farcaster
if ((useBackendFlow && !isMobileContext) || !useBackendFlow)
setShowDialog(true);
// First, fetch existing signers
const signers = await fetchAllSigners(message, signature);
if (useMiniappFlow && isMobileContext) setSignersLoading(true);
if (useBackendFlow && isMobileContext) setSignersLoading(true);
// Check if no signers exist or if we have empty signers
if (!signers || signers.length === 0) {
@@ -545,10 +538,10 @@ export function NeynarAuthButton() {
}
}, [message, signature]); // Simplified dependencies
// Miniapp flow using NextAuth
const handleMiniappSignIn = useCallback(async () => {
// Backend flow using NextAuth
const handleBackendSignIn = useCallback(async () => {
if (!nonce) {
console.error('❌ No nonce available for miniapp sign-in');
console.error('❌ No nonce available for backend sign-in');
return;
}
@@ -563,7 +556,7 @@ export function NeynarAuthButton() {
nonce: nonce,
};
const nextAuthResult = await miniappSignIn('neynar', signInData);
const nextAuthResult = await backendSignIn('neynar', signInData);
if (nextAuthResult?.ok) {
setMessage(result.message);
setSignature(result.signature);
@@ -574,34 +567,34 @@ export function NeynarAuthButton() {
if (e instanceof SignInCore.RejectedByUser) {
console.log(' Sign-in rejected by user');
} else {
console.error('❌ Miniapp sign-in error:', e);
console.error('❌ Backend sign-in error:', e);
}
} finally {
setSignersLoading(false);
}
}, [nonce]);
const handleWebappSignIn = useCallback(() => {
const handleFrontEndSignIn = useCallback(() => {
if (isError) {
reconnect();
}
setDialogStep('signin');
setShowDialog(true);
webappSignIn();
}, [isError, reconnect, webappSignIn]);
frontendSignIn();
}, [isError, reconnect, frontendSignIn]);
const handleSignOut = useCallback(async () => {
try {
setSignersLoading(true);
if (useMiniappFlow) {
if (useBackendFlow) {
// Only sign out from NextAuth if the current session is from Neynar provider
if (session?.provider === 'neynar') {
await miniappSignOut({ redirect: false });
await backendSignOut({ redirect: false });
}
} else {
// Webapp flow sign out
webappSignOut();
// Frontend flow sign out
frontendSignOut();
removeItem(STORAGE_KEY);
setStoredAuth(null);
}
@@ -627,9 +620,9 @@ export function NeynarAuthButton() {
} finally {
setSignersLoading(false);
}
}, [useMiniappFlow, webappSignOut, pollingInterval, session]);
}, [useBackendFlow, frontendSignOut, pollingInterval, session]);
const authenticated = useMiniappFlow
const authenticated = useBackendFlow
? !!(
session?.provider === 'neynar' &&
session?.user?.fid &&
@@ -639,7 +632,7 @@ export function NeynarAuthButton() {
: ((isSuccess && validSignature) || storedAuth?.isAuthenticated) &&
!!(storedAuth?.signers && storedAuth.signers.length > 0);
const userData = useMiniappFlow
const userData = useBackendFlow
? {
fid: session?.user?.fid,
username: session?.user?.username || '',
@@ -671,16 +664,16 @@ export function NeynarAuthButton() {
<ProfileButton userData={userData} onSignOut={handleSignOut} />
) : (
<Button
onClick={useMiniappFlow ? handleMiniappSignIn : handleWebappSignIn}
disabled={!useMiniappFlow && !url}
onClick={useBackendFlow ? handleBackendSignIn : handleFrontEndSignIn}
disabled={!useBackendFlow && !url}
className={cn(
'btn btn-primary flex items-center gap-3',
'disabled:opacity-50 disabled:cursor-not-allowed',
'transform transition-all duration-200 active:scale-[0.98]',
!url && !useMiniappFlow && 'cursor-not-allowed'
!url && !useBackendFlow && 'cursor-not-allowed'
)}
>
{!useMiniappFlow && !url ? (
{!useBackendFlow && !url ? (
<>
<div className="spinner-primary w-5 h-5" />
<span>Initializing...</span>