From a8666c94e3e231234aa5cff024bb6975fbdf72b1 Mon Sep 17 00:00:00 2001
From: zramsay
Date: Wed, 22 Jan 2025 17:01:29 -0500
Subject: [PATCH] fixes
---
src/app/page.tsx | 58 +---------
src/components/AIServiceCard.tsx | 125 --------------------
src/components/ImageAnalysisCard.tsx | 20 +---
src/components/TextGenerationCard.tsx | 131 ---------------------
src/components/WalletHeader.tsx | 41 -------
src/services/googleVisionService.ts | 2 -
src/services/laconicQueryService.ts | 14 ++-
src/services/laconicService.ts | 2 +-
src/services/paymentService.ts | 159 --------------------------
src/services/types.ts | 20 ----
src/services/walletService.ts | 65 -----------
src/types/records.ts | 1 +
12 files changed, 19 insertions(+), 619 deletions(-)
delete mode 100644 src/components/AIServiceCard.tsx
delete mode 100644 src/components/TextGenerationCard.tsx
delete mode 100644 src/components/WalletHeader.tsx
delete mode 100644 src/services/paymentService.ts
delete mode 100644 src/services/types.ts
delete mode 100644 src/services/walletService.ts
diff --git a/src/app/page.tsx b/src/app/page.tsx
index 47e619d..0bcf95b 100644
--- a/src/app/page.tsx
+++ b/src/app/page.tsx
@@ -2,66 +2,20 @@
'use client'
import React, { useState } from 'react'
-import WalletHeader from '../components/WalletHeader'
import ImageAnalysisCard from '../components/ImageAnalysisCard'
import Navigation from '../components/Navigation'
import { analyzeImage, VisionAnalysisResult, VISION_CONFIG } from '../services/googleVisionService'
-import { processMTMPayment } from '../services/paymentService'
-import { connectWallet, WalletState } from '../services/walletService'
-import { WalletType } from '../services/types'
-import { FREE_MODE } from '../config/freeMode'
import { APP_CONFIG, getThemeColors } from '../config/appConfig'
-console.log('NEXT_PUBLIC_FREE_MODE value:', process.env.NEXT_PUBLIC_FREE_MODE)
-console.log('FREE_MODE computed value:', FREE_MODE)
const Page: React.FC = (): React.ReactElement => {
- const [walletState, setWalletState] = useState({
- connected: FREE_MODE ? true : false, // Always "connected" in free mode
- publicKey: null,
- type: null
- })
const theme = getThemeColors(APP_CONFIG.theme)
-
- const handleConnect = async (walletType: WalletType): Promise => {
- if (FREE_MODE) return
- try {
- const newWalletState = await connectWallet(walletType)
- setWalletState(newWalletState)
- } catch (error) {
- console.error('Wallet connection error:', error)
- setWalletState({
- connected: false,
- publicKey: null,
- type: null
- })
- }
- }
-
- const handleImageAnalysis = (cost: number) => {
+ const handleImageAnalysis = () => {
return async (imageFile: File): Promise => {
- // In free mode, skip wallet checks and payment
- if (!FREE_MODE && (!walletState.connected || !walletState.publicKey || !walletState.type)) {
- return { error: 'Wallet not connected' }
- }
- // Only process payment if not in free mode
- if (!FREE_MODE) {
- const paymentResult = await processMTMPayment(
- walletState.publicKey!,
- cost,
- walletState.type!
- )
-
- if (!paymentResult.success) {
- return { error: paymentResult.error }
- }
- }
-
- // Then analyze the image
return analyzeImage(imageFile)
}
}
@@ -79,12 +33,6 @@ const Page: React.FC = (): React.ReactElement => {
{APP_CONFIG.description}
- {!FREE_MODE && (
-
- )}
{/* Single Analysis Card */}
@@ -96,9 +44,7 @@ const Page: React.FC = (): React.ReactElement => {
diff --git a/src/components/AIServiceCard.tsx b/src/components/AIServiceCard.tsx
deleted file mode 100644
index 7ddfa5f..0000000
--- a/src/components/AIServiceCard.tsx
+++ /dev/null
@@ -1,125 +0,0 @@
-'use client'
-
-import React, { useState } from 'react'
-
-interface AIServiceCardProps {
- title: string
- description: string
- tokenCost: number
- isWalletConnected: boolean
- onGenerate: (prompt: string) => Promise<{ response?: string, error?: string }>
-}
-
-interface GenerationState {
- loading: boolean
- response: string | null
- error: string | null
-}
-
-const AIServiceCard: React.FC = ({
- title,
- description,
- tokenCost,
- isWalletConnected,
- onGenerate
-}) => {
- const [inputText, setInputText] = useState('')
- const [generationState, setGenerationState] = useState({
- loading: false,
- response: null,
- error: null,
- })
-
- const handleGenerate = async (): Promise => {
- if (!inputText || !isWalletConnected) return
-
- setGenerationState({
- ...generationState,
- loading: true,
- error: null,
- })
-
- try {
- const result = await onGenerate(inputText)
-
- if (result.error) {
- setGenerationState({
- ...generationState,
- loading: false,
- error: result.error,
- })
- return
- }
-
- if (result.response) {
- setGenerationState({
- loading: false,
- response: result.response,
- error: null,
- })
- } else {
- throw new Error('No response received')
- }
- } catch (error) {
- setGenerationState({
- ...generationState,
- loading: false,
- error: error instanceof Error ? error.message : 'Generation failed',
- })
- }
- }
-
- return (
-
-
-
-
- {title}
-
-
{description}
-
- Cost: {tokenCost} MTM
-
-
-
-
-
-
- {generationState.error && (
-
- {generationState.error}
-
- )}
-
- {generationState.response && (
-
-
{generationState.response}
-
- )}
-
-
- )
-}
-
-export default AIServiceCard
diff --git a/src/components/ImageAnalysisCard.tsx b/src/components/ImageAnalysisCard.tsx
index 6ba8f11..25d5001 100644
--- a/src/components/ImageAnalysisCard.tsx
+++ b/src/components/ImageAnalysisCard.tsx
@@ -3,16 +3,11 @@
import React, { useState, useRef } from 'react'
import { Leaf } from 'lucide-react'
-import { FREE_MODE } from '../config/freeMode'
-
-console.log('ImageAnalysisCard FREE_MODE value:', FREE_MODE)
interface ImageAnalysisCardProps {
title: string
description: string
- tokenCost: number
- isWalletConnected: boolean
onAnalyze: (file: File) => Promise<{ description?: string, error?: string }>
}
@@ -26,8 +21,6 @@ interface AnalysisState {
const ImageAnalysisCard: React.FC = ({
title,
description,
- tokenCost,
- isWalletConnected,
onAnalyze
}) => {
const fileInputRef = useRef(null)
@@ -53,7 +46,8 @@ const ImageAnalysisCard: React.FC = ({
const handleAnalyze = async () => {
const file = fileInputRef.current?.files?.[0]
- if (!file || (!FREE_MODE && !isWalletConnected)) return
+
+ if (!file) return
setAnalysisState({
...analysisState,
@@ -103,11 +97,6 @@ const ImageAnalysisCard: React.FC = ({
{description}
- {!FREE_MODE && (
-
- Cost: {tokenCost} MTM
-
- )}
@@ -122,7 +111,6 @@ const ImageAnalysisCard: React.FC = ({
type="file"
accept="image/*"
onChange={handleFileSelect}
- disabled={!FREE_MODE && !isWalletConnected}
className="absolute inset-0 w-full h-full opacity-0 cursor-pointer
disabled:cursor-not-allowed"
/>
@@ -143,13 +131,13 @@ const ImageAnalysisCard: React.FC = ({
diff --git a/src/components/TextGenerationCard.tsx b/src/components/TextGenerationCard.tsx
deleted file mode 100644
index d4af425..0000000
--- a/src/components/TextGenerationCard.tsx
+++ /dev/null
@@ -1,131 +0,0 @@
-'use client'
-
-import React, { useState } from 'react'
-
-interface TextGenerationCardProps {
- title: string
- description: string
- tokenCost: number
- isWalletConnected: boolean
- onGenerate: (prompt: string) => Promise<{ textResponse?: string, error?: string }>
-}
-
-interface GenerationState {
- loading: boolean
- processing: boolean
- textResponse: string | null
- error: string | null
-}
-
-const TextGenerationCard: React.FC = ({
- title,
- description,
- tokenCost,
- isWalletConnected,
- onGenerate
-}) => {
- const [inputText, setInputText] = useState('')
- const [generationState, setGenerationState] = useState({
- loading: false,
- processing: false,
- textResponse: null,
- error: null,
- })
-
- const handleGenerate = async (): Promise => {
- if (!inputText || !isWalletConnected) return
-
- setGenerationState({
- ...generationState,
- loading: true,
- error: null,
- })
-
- try {
- const result = await onGenerate(inputText)
-
- if (result.error) {
- setGenerationState({
- ...generationState,
- loading: false,
- error: result.error,
- })
- return
- }
-
- if (result.textResponse) {
- setGenerationState({
- loading: false,
- processing: false,
- textResponse: result.textResponse,
- error: null,
- })
- } else {
- throw new Error('No response received')
- }
- } catch (error) {
- setGenerationState({
- ...generationState,
- loading: false,
- error: error instanceof Error ? error.message : 'Generation failed',
- })
- }
- }
-
- return (
-
-
-
-
- {title}
-
-
{description}
-
- Cost: {tokenCost} MTM
-
-
-
-
-
-
- {generationState.error && (
-
- {generationState.error}
-
- )}
-
- {generationState.textResponse && (
-
-
Response:
-
- {generationState.textResponse}
-
-
- )}
-
-
- )
-}
-
-export default TextGenerationCard
diff --git a/src/components/WalletHeader.tsx b/src/components/WalletHeader.tsx
deleted file mode 100644
index f5a51d5..0000000
--- a/src/components/WalletHeader.tsx
+++ /dev/null
@@ -1,41 +0,0 @@
-'use client'
-
-import React from 'react'
-import { WalletState, SUPPORTED_WALLETS } from '../services/walletService'
-import { WalletType } from '../services/types'
-
-interface WalletHeaderProps {
- walletState: WalletState
- onConnect: (walletType: WalletType) => Promise
-}
-
-const WalletHeader: React.FC = ({ walletState, onConnect }) => {
- return (
-
- {!walletState.connected ? (
-
- {SUPPORTED_WALLETS.map((wallet) => (
-
- ))}
-
- ) : (
-
- Connected Wallet
-
- {walletState.publicKey?.slice(0, 22)}...
-
-
- )}
-
- )
-}
-
-export default WalletHeader
diff --git a/src/services/googleVisionService.ts b/src/services/googleVisionService.ts
index d06d4dd..5e01b59 100644
--- a/src/services/googleVisionService.ts
+++ b/src/services/googleVisionService.ts
@@ -11,14 +11,12 @@ export interface VisionConfig {
modelId: string
name: string
description: string
- cost: number
}
export const VISION_CONFIG: VisionConfig = {
modelId: "google-vision-v1",
name: "Worldwide Animal Oracle",
description: "Upload photos of your wildlife encounters from the real world. Verified animal images will be added to the Animal Registry.",
- cost: 3
}
export async function analyzeImage(imageFile: File): Promise {
diff --git a/src/services/laconicQueryService.ts b/src/services/laconicQueryService.ts
index e559e43..0428c73 100644
--- a/src/services/laconicQueryService.ts
+++ b/src/services/laconicQueryService.ts
@@ -31,6 +31,9 @@ const ANIMAL_RECORDS_QUERY = `
... on FloatValue {
float: value
}
+ ... on StringValue {
+ string: value
+ }
}
}
}
@@ -44,7 +47,7 @@ export async function fetchAnimalRecords(portalName: string): Promise record.attributes.imageUrl !== null && record.attributes.imageUrl.trim() !== '');
+ // Filter out records without an imageUrl or non matching portalName
+ .filter((record: AnimalRecord) =>
+ record.attributes.imageUrl !== null &&
+ record.attributes.imageUrl.trim() !== '' &&
+ record.attributes.portalName === process.env.NEXT_PUBLIC_PORTAL_NAME
+ );
console.log('Processed animal records:', records);
diff --git a/src/services/laconicService.ts b/src/services/laconicService.ts
index 7a1589f..157084a 100644
--- a/src/services/laconicService.ts
+++ b/src/services/laconicService.ts
@@ -27,7 +27,7 @@ export async function publishAnimalRecord(
longitude: number,
description: string,
imageUrl: string,
- portalName: string = process.env.NEXT_PUBLIC_PORTAL_NAME
+ portalName: string
): Promise {
try {
// Verify config file exists
diff --git a/src/services/paymentService.ts b/src/services/paymentService.ts
deleted file mode 100644
index 42c55ff..0000000
--- a/src/services/paymentService.ts
+++ /dev/null
@@ -1,159 +0,0 @@
-import { Connection, PublicKey, Transaction, SystemProgram } from '@solana/web3.js'
-import {
- TOKEN_PROGRAM_ID,
- createTransferInstruction,
- getAssociatedTokenAddress,
- createAssociatedTokenAccountInstruction,
- ASSOCIATED_TOKEN_PROGRAM_ID
-} from '@solana/spl-token'
-import { WalletType } from './types'
-
-const MTM_TOKEN_MINT: string = '97RggLo3zV5kFGYW4yoQTxr4Xkz4Vg2WPHzNYXXWpump'
-const PAYMENT_RECEIVER_ADDRESS: string = 'FFDx3SdAEeXrp6BTmStB4BDHpctGsaasZq4FFcowRobY'
-const SOLANA_RPC_URL: string = 'https://young-radial-orb.solana-mainnet.quiknode.pro/67612b364664616c29514e551bf5de38447ca3d4'
-const SOLANA_WEBSOCKET_URL: string = 'wss://young-radial-orb.solana-mainnet.quiknode.pro/67612b364664616c29514e551bf5de38447ca3d4'
-
-const connection = new Connection(
- SOLANA_RPC_URL,
- {
- commitment: 'confirmed',
- wsEndpoint: SOLANA_WEBSOCKET_URL,
- confirmTransactionInitialTimeout: 60000,
- }
-)
-
-export interface PaymentResult {
- success: boolean
- error?: string
-}
-
-async function findAssociatedTokenAddress(
- walletAddress: PublicKey,
- tokenMintAddress: PublicKey
-): Promise {
- return PublicKey.findProgramAddressSync(
- [
- walletAddress.toBuffer(),
- TOKEN_PROGRAM_ID.toBuffer(),
- tokenMintAddress.toBuffer(),
- ],
- ASSOCIATED_TOKEN_PROGRAM_ID
- )[0]
-}
-
-interface WalletAdapter {
- signAndSendTransaction(transaction: Transaction): Promise<{ signature: string }>
-}
-
-export async function processMTMPayment(
- walletPublicKey: string,
- tokenAmount: number,
- walletType: WalletType
-): Promise {
- try {
- let wallet: WalletAdapter | null = null;
-
- if (walletType === 'phantom') {
- wallet = window.phantom?.solana || null;
- } else if (walletType === 'solflare') {
- wallet = window.solflare || null;
- }
-
- if (!wallet) {
- throw new Error(`${walletType} wallet not found`)
- }
-
- const senderPublicKey = new PublicKey(walletPublicKey)
- const mintPublicKey = new PublicKey(MTM_TOKEN_MINT)
- const receiverPublicKey = new PublicKey(PAYMENT_RECEIVER_ADDRESS)
-
- console.log('Processing payment with keys:', {
- sender: senderPublicKey.toBase58(),
- mint: mintPublicKey.toBase58(),
- receiver: receiverPublicKey.toBase58(),
- })
-
- const senderATA = await findAssociatedTokenAddress(
- senderPublicKey,
- mintPublicKey
- )
-
- const receiverATA = await findAssociatedTokenAddress(
- receiverPublicKey,
- mintPublicKey
- )
-
- console.log('Token accounts:', {
- senderATA: senderATA.toBase58(),
- receiverATA: receiverATA.toBase58(),
- })
-
- const transaction = new Transaction()
-
- const [senderATAInfo, receiverATAInfo] = await Promise.all([
- connection.getAccountInfo(senderATA),
- connection.getAccountInfo(receiverATA),
- ])
-
- if (!receiverATAInfo) {
- console.log('Creating receiver token account')
- transaction.add(
- createAssociatedTokenAccountInstruction(
- senderPublicKey,
- receiverATA,
- receiverPublicKey,
- mintPublicKey
- )
- )
- }
-
- if (!senderATAInfo) {
- console.log('Creating sender token account')
- transaction.add(
- createAssociatedTokenAccountInstruction(
- senderPublicKey,
- senderATA,
- senderPublicKey,
- mintPublicKey
- )
- )
- }
-
- transaction.add(
- createTransferInstruction(
- senderATA,
- receiverATA,
- senderPublicKey,
- BigInt(tokenAmount * (10 ** 6))
- )
- )
-
- const latestBlockhash = await connection.getLatestBlockhash('confirmed')
- transaction.recentBlockhash = latestBlockhash.blockhash
- transaction.feePayer = senderPublicKey
-
- console.log('Sending transaction...')
- const { signature } = await wallet.signAndSendTransaction(transaction)
- console.log('Transaction sent:', signature)
-
- const confirmation = await connection.confirmTransaction({
- signature,
- blockhash: latestBlockhash.blockhash,
- lastValidBlockHeight: latestBlockhash.lastValidBlockHeight,
- }, 'confirmed')
-
- if (confirmation.value.err) {
- console.error('Transaction error:', confirmation.value.err)
- throw new Error(`Transaction failed: ${JSON.stringify(confirmation.value.err)}`)
- }
-
- return { success: true }
- } catch (error) {
- console.error('Payment error:', error)
- return {
- success: false,
- error: error instanceof Error ? error.message : 'Payment failed'
- }
- }
-}
-
diff --git a/src/services/types.ts b/src/services/types.ts
deleted file mode 100644
index 869857b..0000000
--- a/src/services/types.ts
+++ /dev/null
@@ -1,20 +0,0 @@
-export type WalletType = 'solflare' | 'phantom'
-
-declare global {
- interface Window {
- solflare?: {
- connect(): Promise
- disconnect(): Promise
- publicKey?: { toString(): string }
- signAndSendTransaction(transaction: any): Promise<{ signature: string }>
- }
- phantom?: {
- solana?: {
- connect(): Promise<{ publicKey: { toString(): string } }>
- disconnect(): Promise
- signAndSendTransaction(transaction: any): Promise<{ signature: string }>
- }
- }
- }
-}
-
diff --git a/src/services/walletService.ts b/src/services/walletService.ts
deleted file mode 100644
index 48b3d73..0000000
--- a/src/services/walletService.ts
+++ /dev/null
@@ -1,65 +0,0 @@
-import { WalletType } from './types'
-
-export interface WalletState {
- connected: boolean
- publicKey: string | null
- type: WalletType | null
-}
-
-export interface WalletConfig {
- type: WalletType
- name: string
- connect: () => Promise<{ publicKey: string } | null>
-}
-
-const connectSolflare = async (): Promise<{ publicKey: string } | null> => {
- if (!window.solflare) return null
- await window.solflare.connect()
- return window.solflare.publicKey ? { publicKey: window.solflare.publicKey.toString() } : null
-}
-
-const connectPhantom = async (): Promise<{ publicKey: string } | null> => {
- if (!window.phantom?.solana) return null
- try {
- const response = await window.phantom.solana.connect()
- return response.publicKey ? { publicKey: response.publicKey.toString() } : null
- } catch {
- return null
- }
-}
-
-export const SUPPORTED_WALLETS: WalletConfig[] = [
- // {
- // type: 'solflare',
- // name: 'Solflare',
- // connect: connectSolflare
- // },
- {
- type: 'phantom',
- name: 'Phantom',
- connect: connectPhantom
- }
-]
-
-export async function connectWallet(type: WalletType): Promise {
- const wallet = SUPPORTED_WALLETS.find(w => w.type === type)
- if (!wallet) throw new Error('Unsupported wallet')
-
- try {
- const result = await wallet.connect()
- if (!result) throw new Error(`${wallet.name} not found`)
-
- return {
- connected: true,
- publicKey: result.publicKey,
- type: wallet.type
- }
- } catch (error) {
- return {
- connected: false,
- publicKey: null,
- type: null
- }
- }
-}
-
diff --git a/src/types/records.ts b/src/types/records.ts
index 4d6db6f..0cbdb43 100644
--- a/src/types/records.ts
+++ b/src/types/records.ts
@@ -10,6 +10,7 @@ export interface AnimalRecord {
}
description: string
imageUrl: string
+ portalName: string
}
bondId?: string
createTime: string