From bade04b7856b38dca9f1c32e23332fe3a313e03b Mon Sep 17 00:00:00 2001 From: Shreyaschorge Date: Fri, 18 Jul 2025 22:55:10 +0530 Subject: [PATCH] fix-deploy-and-manifest-issue --- .eslintrc.json | 31 ++++++++++++++++++++++++++- package.json | 2 +- src/app/layout.tsx | 1 - src/app/providers.tsx | 29 +++++++++++++++++-------- src/components/ui/tabs/ActionsTab.tsx | 10 ++++----- src/lib/constants.ts | 26 +++++++++++----------- src/lib/kv.ts | 24 +++++++++++---------- src/lib/utils.ts | 26 +++++++++------------- 8 files changed, 92 insertions(+), 57 deletions(-) diff --git a/.eslintrc.json b/.eslintrc.json index 3722418..24a1239 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -1,3 +1,32 @@ { - "extends": ["next/core-web-vitals", "next/typescript"] + "extends": ["next/core-web-vitals", "next/typescript"], + "rules": { + // Disable img warnings since you're using them intentionally in specific contexts + "@next/next/no-img-element": "off", + + // Allow @ts-ignore comments (though @ts-expect-error is preferred) + "@typescript-eslint/ban-ts-comment": "off", + + // Allow explicit any types (sometimes necessary for dynamic imports and APIs) + "@typescript-eslint/no-explicit-any": "off", + + // Allow unused variables that start with underscore + "@typescript-eslint/no-unused-vars": [ + "warn", + { + "argsIgnorePattern": "^_", + "varsIgnorePattern": "^_", + "caughtErrorsIgnorePattern": "^_" + } + ], + + // Make display name warnings instead of errors for dynamic components + "react/display-name": "warn", + + // Allow module assignment for dynamic imports + "@next/next/no-assign-module-variable": "warn", + + // Make exhaustive deps a warning instead of error for complex hooks + "react-hooks/exhaustive-deps": "warn" + } } diff --git a/package.json b/package.json index 60cf744..e7340c5 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@neynar/create-farcaster-mini-app", - "version": "1.7.9", + "version": "1.7.10", "type": "module", "private": false, "access": "public", diff --git a/src/app/layout.tsx b/src/app/layout.tsx index c42d41a..30368ab 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -22,7 +22,6 @@ export default async function RootLayout({ let session = null; if (shouldUseSession) { try { - // @ts-ignore - auth module may not exist in all template variants const authModule = eval('require("~/auth")'); session = await authModule.getSession(); } catch (error) { diff --git a/src/app/providers.tsx b/src/app/providers.tsx index d9c19fa..429a147 100644 --- a/src/app/providers.tsx +++ b/src/app/providers.tsx @@ -12,14 +12,12 @@ const WagmiProvider = dynamic( } ); - - export function Providers({ session, children, shouldUseSession = false, }: { - session: any | null; + session: unknown | null; children: React.ReactNode; shouldUseSession?: boolean; }) { @@ -34,18 +32,31 @@ export function Providers({ return Promise.resolve().then(() => { // Use eval to avoid build-time module resolution try { - // @ts-ignore - These modules may not exist in all template variants const nextAuth = eval('require("next-auth/react")'); const authKit = eval('require("@farcaster/auth-kit")'); - - return ({ children }: { children: React.ReactNode }) => ( + + const AuthWrapper = ({ + children, + }: { + children: React.ReactNode; + }) => ( - {children} + + {children} + ); - } catch (error) { + AuthWrapper.displayName = 'AuthWrapper'; + return AuthWrapper; + } catch (_error) { // Fallback component when auth modules aren't available - return ({ children }: { children: React.ReactNode }) => <>{children}; + const FallbackWrapper = ({ + children, + }: { + children: React.ReactNode; + }) => <>{children}; + FallbackWrapper.displayName = 'FallbackWrapper'; + return FallbackWrapper; } }); }, diff --git a/src/components/ui/tabs/ActionsTab.tsx b/src/components/ui/tabs/ActionsTab.tsx index bc7880d..c633ed9 100644 --- a/src/components/ui/tabs/ActionsTab.tsx +++ b/src/components/ui/tabs/ActionsTab.tsx @@ -1,7 +1,7 @@ 'use client'; import dynamic from 'next/dynamic'; -import { useCallback, useState, type ComponentType } from 'react'; +import { useCallback, useState } from 'react'; import { useMiniApp } from '@neynar/react'; import { ShareButton } from '../Share'; import { Button } from '../Button'; @@ -14,10 +14,9 @@ const NeynarAuthButton = dynamic( () => { return Promise.resolve().then(() => { try { - // @ts-ignore - NeynarAuthButton may not exist in all template variants - const module = eval('require("../NeynarAuthButton/index")'); - return module.default || module.NeynarAuthButton; - } catch (error) { + const authModule = eval('require("../NeynarAuthButton/index")'); + return authModule.default || authModule.NeynarAuthButton; + } catch (_error) { // Return null component when module doesn't exist return () => null; } @@ -26,7 +25,6 @@ const NeynarAuthButton = dynamic( { ssr: false } ); - /** * ActionsTab component handles mini app actions like sharing, notifications, and haptic feedback. * diff --git a/src/lib/constants.ts b/src/lib/constants.ts index 4938795..2666d8b 100644 --- a/src/lib/constants.ts +++ b/src/lib/constants.ts @@ -1,4 +1,4 @@ -import { type AccountAssociation } from '@farcaster/miniapp-node'; +import { type AccountAssociation } from '@farcaster/miniapp-core/src/manifest'; /** * Application constants and configuration values. @@ -22,25 +22,25 @@ export const APP_URL: string = process.env.NEXT_PUBLIC_URL!; * The name of the mini app as displayed to users. * Used in titles, headers, and app store listings. */ -export const APP_NAME: string = 'Starter Kit'; +export const APP_NAME = 'idk2'; /** * A brief description of the mini app's functionality. * Used in app store listings and metadata. */ -export const APP_DESCRIPTION: string = 'A demo of the Neynar Starter Kit'; +export const APP_DESCRIPTION = 'A Farcaster mini app created with Neynar'; /** * The primary category for the mini app. * Used for app store categorization and discovery. */ -export const APP_PRIMARY_CATEGORY: string = 'developer-tools'; +export const APP_PRIMARY_CATEGORY = ''; /** * Tags associated with the mini app. * Used for search and discovery in app stores. */ -export const APP_TAGS: string[] = ['neynar', 'starter-kit', 'demo']; +export const APP_TAGS = ['neynar', 'starter-kit', 'demo']; // --- Asset URLs --- /** @@ -65,21 +65,22 @@ export const APP_SPLASH_URL: string = `${APP_URL}/splash.png`; * Background color for the splash screen. * Used as fallback when splash image is loading. */ -export const APP_SPLASH_BACKGROUND_COLOR: string = "#f7f7f7"; +export const APP_SPLASH_BACKGROUND_COLOR: string = '#f7f7f7'; /** * Account association for the mini app. * Used to associate the mini app with a Farcaster account. * If not provided, the mini app will be unsigned and have limited capabilities. */ -export const APP_ACCOUNT_ASSOCIATION: AccountAssociation | undefined = undefined; +export const APP_ACCOUNT_ASSOCIATION: AccountAssociation | undefined = + undefined; // --- UI Configuration --- /** * Text displayed on the main action button. * Used for the primary call-to-action in the mini app. */ -export const APP_BUTTON_TEXT: string = 'Launch NSK'; +export const APP_BUTTON_TEXT = 'Launch Mini App'; // --- Integration Configuration --- /** @@ -89,7 +90,8 @@ export const APP_BUTTON_TEXT: string = 'Launch NSK'; * Neynar webhook endpoint. Otherwise, falls back to a local webhook * endpoint for development and testing. */ -export const APP_WEBHOOK_URL: string = process.env.NEYNAR_API_KEY && process.env.NEYNAR_CLIENT_ID +export const APP_WEBHOOK_URL: string = + process.env.NEYNAR_API_KEY && process.env.NEYNAR_CLIENT_ID ? `https://api.neynar.com/f/app/${process.env.NEYNAR_CLIENT_ID}/event` : `${APP_URL}/api/webhook`; @@ -100,7 +102,7 @@ export const APP_WEBHOOK_URL: string = process.env.NEYNAR_API_KEY && process.env * When false, wallet functionality is completely hidden from the UI. * Useful for mini apps that don't require wallet integration. */ -export const USE_WALLET: boolean = true; +export const USE_WALLET = false; /** * Flag to enable/disable analytics tracking. @@ -109,7 +111,7 @@ export const USE_WALLET: boolean = true; * When false, analytics collection is disabled. * Useful for privacy-conscious users or development environments. */ -export const ANALYTICS_ENABLED: boolean = true; +export const ANALYTICS_ENABLED = true; /** * Required chains for the mini app. @@ -117,7 +119,7 @@ export const ANALYTICS_ENABLED: boolean = true; * Contains an array of CAIP-2 identifiers for blockchains that the mini app requires. * If the host does not support all chains listed here, it will not render the mini app. * If empty or undefined, the mini app will be rendered regardless of chain support. - * + * * Supported chains: eip155:1, eip155:137, eip155:42161, eip155:10, eip155:8453, * solana:mainnet, solana:devnet */ diff --git a/src/lib/kv.ts b/src/lib/kv.ts index eefc680..28f0982 100644 --- a/src/lib/kv.ts +++ b/src/lib/kv.ts @@ -1,16 +1,18 @@ -import { FrameNotificationDetails } from "@farcaster/miniapp-sdk"; -import { Redis } from "@upstash/redis"; -import { APP_NAME } from "./constants"; +import { MiniAppNotificationDetails } from '@farcaster/miniapp-sdk'; +import { Redis } from '@upstash/redis'; +import { APP_NAME } from './constants'; // In-memory fallback storage -const localStore = new Map(); +const localStore = new Map(); // Use Redis if KV env vars are present, otherwise use in-memory const useRedis = process.env.KV_REST_API_URL && process.env.KV_REST_API_TOKEN; -const redis = useRedis ? new Redis({ - url: process.env.KV_REST_API_URL!, - token: process.env.KV_REST_API_TOKEN!, -}) : null; +const redis = useRedis + ? new Redis({ + url: process.env.KV_REST_API_URL!, + token: process.env.KV_REST_API_TOKEN!, + }) + : null; function getUserNotificationDetailsKey(fid: number): string { return `${APP_NAME}:user:${fid}`; @@ -18,17 +20,17 @@ function getUserNotificationDetailsKey(fid: number): string { export async function getUserNotificationDetails( fid: number -): Promise { +): Promise { const key = getUserNotificationDetailsKey(fid); if (redis) { - return await redis.get(key); + return await redis.get(key); } return localStore.get(key) || null; } export async function setUserNotificationDetails( fid: number, - notificationDetails: FrameNotificationDetails + notificationDetails: MiniAppNotificationDetails ): Promise { const key = getUserNotificationDetailsKey(fid); if (redis) { diff --git a/src/lib/utils.ts b/src/lib/utils.ts index 89e8b8c..dffb165 100644 --- a/src/lib/utils.ts +++ b/src/lib/utils.ts @@ -1,6 +1,6 @@ import { type ClassValue, clsx } from 'clsx'; import { twMerge } from 'tailwind-merge'; -import { type Manifest } from '@farcaster/miniapp-node'; +import { Manifest } from '@farcaster/miniapp-core/src/manifest'; import { APP_BUTTON_TEXT, APP_DESCRIPTION, @@ -10,7 +10,8 @@ import { APP_PRIMARY_CATEGORY, APP_SPLASH_BACKGROUND_COLOR, APP_SPLASH_URL, - APP_TAGS, APP_URL, + APP_TAGS, + APP_URL, APP_WEBHOOK_URL, APP_ACCOUNT_ASSOCIATION, APP_REQUIRED_CHAINS, @@ -22,7 +23,7 @@ export function cn(...inputs: ClassValue[]) { export function getMiniAppEmbedMetadata(ogImageUrl?: string) { return { - version: "next", + version: 'next', imageUrl: ogImageUrl ?? APP_OG_IMAGE_URL, ogTitle: APP_NAME, ogDescription: APP_DESCRIPTION, @@ -30,7 +31,7 @@ export function getMiniAppEmbedMetadata(ogImageUrl?: string) { button: { title: APP_BUTTON_TEXT, action: { - type: "launch_frame", + type: 'launch_frame', name: APP_NAME, url: APP_URL, splashImageUrl: APP_SPLASH_URL, @@ -46,24 +47,17 @@ export function getMiniAppEmbedMetadata(ogImageUrl?: string) { export async function getFarcasterDomainManifest(): Promise { return { - accountAssociation: APP_ACCOUNT_ASSOCIATION, + accountAssociation: APP_ACCOUNT_ASSOCIATION!, miniapp: { - version: "1", - name: APP_NAME ?? "Neynar Starter Kit", - iconUrl: APP_ICON_URL, + version: '1', + name: APP_NAME ?? 'Neynar Starter Kit', homeUrl: APP_URL, + iconUrl: APP_ICON_URL, imageUrl: APP_OG_IMAGE_URL, - buttonTitle: APP_BUTTON_TEXT ?? "Launch Mini App", + buttonTitle: APP_BUTTON_TEXT ?? 'Launch Mini App', splashImageUrl: APP_SPLASH_URL, splashBackgroundColor: APP_SPLASH_BACKGROUND_COLOR, webhookUrl: APP_WEBHOOK_URL, - description: APP_DESCRIPTION, - primaryCategory: APP_PRIMARY_CATEGORY, - tags: APP_TAGS, - requiredChains: APP_REQUIRED_CHAINS.length > 0 ? APP_REQUIRED_CHAINS : undefined, - ogTitle: APP_NAME, - ogDescription: APP_DESCRIPTION, - ogImageUrl: APP_OG_IMAGE_URL, }, }; }