From 127a20ba86f0d5a3760da35b899d741f1d35ffa2 Mon Sep 17 00:00:00 2001 From: zramsay Date: Fri, 21 Mar 2025 16:54:03 -0400 Subject: [PATCH] ok --- src/app/api/tokens/claim/route.ts | 109 ------------- src/app/page.tsx | 146 ++---------------- src/components/ImageAnalysisCard.tsx | 8 + src/components/WildlifeIdentifier.tsx | 13 +- src/components/wallet/WalletButton.tsx | 2 +- src/services/blockchain/tokenRewardService.ts | 4 +- 6 files changed, 29 insertions(+), 253 deletions(-) delete mode 100644 src/app/api/tokens/claim/route.ts diff --git a/src/app/api/tokens/claim/route.ts b/src/app/api/tokens/claim/route.ts deleted file mode 100644 index 27018a3..0000000 --- a/src/app/api/tokens/claim/route.ts +++ /dev/null @@ -1,109 +0,0 @@ -// src/app/api/tokens/claim/route.ts -import { NextRequest, NextResponse } from 'next/server' -import { getSessionFromCookie, getUserFromHeaders } from '../../../../lib/auth' -import { getUserPoints } from '../../../../services/userPointsService' -import { awardTokensForSighting } from '../../../../services/blockchain/tokenRewardService' -import { isWalletConnected, getWalletAddress } from '../../../../services/blockchain/seiService' - -export async function POST(req: NextRequest): Promise { - try { - // Log request info - console.log('Token Claim API Request:', { - path: req.url, - method: req.method, - headers: Object.fromEntries(req.headers.entries()), - hasCookies: req.headers.has('cookie') - }); - - // Get user from session - const session = await getSessionFromCookie(req); - const headerUser = getUserFromHeaders(req); - - // Check authentication - require session OR header authentication - const isAuthenticated = !!session || !!headerUser; - - if (!isAuthenticated) { - console.log('Unauthorized access attempt to token claim API'); - return NextResponse.json( - { success: false, error: 'Unauthorized. Please sign in to claim tokens.' }, - { status: 401 } - ); - } - - // Get user info - const userId = session?.user?.id || headerUser?.id || ''; - const userEmail = session?.user?.email || headerUser?.email || ''; - - // Log user identification - console.log('User identification for token claim:', { userId, userEmail }); - - // Check if wallet is connected (client should check this too, but double-check) - if (!req.headers.get('x-wallet-address')) { - return NextResponse.json( - { success: false, error: 'No wallet address provided. Please connect your wallet first.' }, - { status: 400 } - ); - } - - const walletAddress = req.headers.get('x-wallet-address'); - - // Get user's points - const userPoints = await getUserPoints(userId || userEmail); - console.log('User points:', userPoints); - - // Check if user has points to claim - if (!userPoints || userPoints < 1) { - return NextResponse.json( - { success: false, error: 'You need at least 1 point to claim tokens.' }, - { status: 400 } - ); - } - - // Parse the request body - const requestData = await req.json(); - console.log('Request data:', requestData); - - // Get species - const species = requestData.species || 'animal'; - - // Award tokens based on points (1 point = 1 token) - try { - // Award tokens through blockchain service - const rewardResult = await awardTokensForSighting(species, requestData.points); - - if (rewardResult.success) { - return NextResponse.json({ - success: true, - message: `Successfully claimed WILD tokens for your wildlife points!`, - tokenAmount: rewardResult.tokenAmount, - txHash: rewardResult.txHash - }); - } else { - throw new Error(rewardResult.error || 'Failed to award tokens'); - } - } catch (err) { - console.error('Error awarding tokens:', err); - return NextResponse.json( - { - success: false, - error: err instanceof Error ? err.message : 'Error processing token reward' - }, - { status: 500 } - ); - } - } catch (error) { - console.error('Token claim failed:', { - errorName: error instanceof Error ? error.name : 'Unknown Error', - errorMessage: error instanceof Error ? error.message : String(error), - errorStack: error instanceof Error ? error.stack : 'No stack trace' - }); - - return NextResponse.json( - { success: false, error: 'Failed to claim tokens' }, - { status: 500 } - ); - } -} - -// Ensure dynamic routing -export const dynamic = 'force-dynamic' \ No newline at end of file diff --git a/src/app/page.tsx b/src/app/page.tsx index 1c904bf..c93f15f 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -17,15 +17,8 @@ const Page: React.FC = (): React.ReactElement => { const { data: session, status } = useSession() const isAuthenticated = status === 'authenticated' && !!session - // State for user points and token claim + // State for user points const [userPoints, setUserPoints] = useState(null) - const [isClaimingTokens, setIsClaimingTokens] = useState(false) - const [claimResult, setClaimResult] = useState<{ - success: boolean; - message: string; - tokenAmount?: number; - txHash?: string; - } | null>(null) // Effect to fetch user points React.useEffect(() => { @@ -105,68 +98,7 @@ const Page: React.FC = (): React.ReactElement => { } } - // Handle token claim - const handleClaimTokens = async () => { - if (!isAuthenticated || !session?.user) { - console.error('User not authenticated'); - return; - } - - if (!isWalletConnected()) { - console.error('Wallet not connected'); - return; - } - - if (!userPoints || userPoints < 1) { - console.error('No points to claim'); - return; - } - - setIsClaimingTokens(true); - setClaimResult(null); - - try { - // Call our new token claim API - const response = await fetch('/api/tokens/claim', { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - 'x-wallet-address': getWalletAddress() || '' - }, - body: JSON.stringify({ - points: userPoints, - species: 'wildlife' // Generic species for point-based claims - }) - }); - - const result = await response.json(); - - if (result.success) { - setClaimResult({ - success: true, - message: 'Successfully claimed WILD tokens!', - tokenAmount: result.tokenAmount, - txHash: result.txHash - }); - - // Reset points to 0 after successful claim - setUserPoints(0); - } else { - setClaimResult({ - success: false, - message: result.error || 'Failed to claim tokens' - }); - } - } catch (error) { - console.error('Error claiming tokens:', error); - setClaimResult({ - success: false, - message: error instanceof Error ? error.message : 'Error claiming tokens' - }); - } finally { - setIsClaimingTokens(false); - } - }; + // No token claim needed - tokens are automatically awarded when uploading wildlife images // Auth-locked content const renderAuthContent = () => { @@ -184,88 +116,34 @@ const Page: React.FC = (): React.ReactElement => { onAnalyze={handleImageAnalysis()} /> - {/* Points & token claim section */} + {/* Points display section */} {userPoints !== null && (
- -

- Earn WILD Tokens + +

+ Your Wildlife Points

- Convert your wildlife identification points to WILD tokens on the Sei blockchain + You earn points for identifying wildlife in photos

{/* Points display */}
- {userPoints} - Available Points -
- - {/* Token claim button */} -
- + {userPoints} + Total Points
{/* Wallet connection notice */} {!isWalletConnected() && ( -
- Connect your wallet using the button in the navigation bar to claim WILD tokens -
- )} - - {/* Claim result message */} - {claimResult && ( -
-

{claimResult.message}

- - {/* Token reward details */} - {claimResult.success && claimResult.tokenAmount && ( -
- -
-

- {claimResult.tokenAmount} WILD tokens claimed! -

- {claimResult.txHash && ( -

- Transaction: - {claimResult.txHash.substring(0, 10)}... - -

- )} -
-
- )} +
+ + Connect your wallet using the button in the navigation bar to also earn WILD tokens
)}
diff --git a/src/components/ImageAnalysisCard.tsx b/src/components/ImageAnalysisCard.tsx index 430ac1b..80b1f30 100644 --- a/src/components/ImageAnalysisCard.tsx +++ b/src/components/ImageAnalysisCard.tsx @@ -4,6 +4,7 @@ import React, { useState, useRef } from 'react' import { Leaf, Coins } from 'lucide-react' import { APP_CONFIG } from '../config/appConfig' +import { isWalletConnected } from '../services/blockchain/seiService' interface TokenReward { amount?: number; @@ -157,6 +158,13 @@ const ImageAnalysisCard: React.FC = ({ > {analysisState.loading ? 'Processing...' : 'Analyze' } + + {!isWalletConnected() && ( +
+ + Connect your wallet to also earn WILD tokens +
+ )}
{analysisState.error && ( diff --git a/src/components/WildlifeIdentifier.tsx b/src/components/WildlifeIdentifier.tsx index 3a5033c..c609b9f 100644 --- a/src/components/WildlifeIdentifier.tsx +++ b/src/components/WildlifeIdentifier.tsx @@ -56,11 +56,8 @@ const WildlifeIdentifier: React.FC = () => { return; } - // Check if wallet is connected - if (!isWalletConnected()) { - setError('Please connect your wallet first to receive rewards'); - return; - } + // No need to check for wallet connection - the process works for both user types + // Tokens will be awarded automatically if wallet is connected setIsProcessing(true); setError(null); @@ -214,19 +211,19 @@ const WildlifeIdentifier: React.FC = () => { {!isWalletConnected() && (
- Please connect your wallet to earn token rewards + Connect your wallet to also earn WILD tokens
)} diff --git a/src/components/wallet/WalletButton.tsx b/src/components/wallet/WalletButton.tsx index 322def3..e8ca30a 100644 --- a/src/components/wallet/WalletButton.tsx +++ b/src/components/wallet/WalletButton.tsx @@ -102,7 +102,7 @@ const WalletButton: React.FC = () => { : 'bg-amber-500/20 text-amber-300 hover:bg-amber-500/30' } transition-colors`} > - {isConnecting ? 'Connecting...' : 'Connect Wallet'} + {isConnecting ? 'Connecting...' : 'Connect for WILD'} )} diff --git a/src/services/blockchain/tokenRewardService.ts b/src/services/blockchain/tokenRewardService.ts index e94df4d..5279c98 100644 --- a/src/services/blockchain/tokenRewardService.ts +++ b/src/services/blockchain/tokenRewardService.ts @@ -50,8 +50,10 @@ export const awardTokensForSighting = async (species: string, points?: number): walletConnected: boolean; }> => { try { - // Check if wallet is connected + // Check if wallet is connected - silently skip token award if not connected + // This allows the same flow to work for both types of users if (!isWalletConnected()) { + console.log('No wallet connected, skipping token award.'); return { success: false, error: 'No wallet connected',