diff --git a/src/app/page.tsx b/src/app/page.tsx index 4ed1f68..ec3d0ce 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -1,10 +1,10 @@ 'use client' -import React, { useState } from 'react' +import React, { useState, useEffect } from 'react' import WalletHeader from '../components/WalletHeader' import AIServiceCard from '../components/AIServiceCard' import { generateWithFlux, FluxGenerationResult, FLUX_MODELS } from '../services/fluxService' -import { processMTMPayment } from '../services/paymentService' +import { getUSDCToMTMQuote, processMTMPayment } from '../services/paymentService' import { connectWallet, disconnectWallet, WalletState } from '../services/walletService' import { WalletType } from '../services/types' @@ -15,6 +15,25 @@ const Page: React.FC = (): React.ReactElement => { type: null }) + const [usdcPrice, setUsdcPrice] = useState(0); + + useEffect(() => { + + const fetchPrice = async () => { + try { + const price = await getUSDCToMTMQuote(); + setUsdcPrice(price); + } catch (error) { + console.error('Failed to fetch price:', error); + } + }; + + fetchPrice(); + const interval = setInterval(fetchPrice, 10000); + + return () => clearInterval(interval); + }, []); + const handleConnect = async (walletType: WalletType): Promise => { try { const newWalletState = await connectWallet(walletType) @@ -100,6 +119,7 @@ const Page: React.FC = (): React.ReactElement => { tokenCost={model.cost} isWalletConnected={walletState.connected} onGenerate={handleFluxGeneration(model.modelId, model.cost)} + mtmPrice={model.cost * usdcPrice} /> ))} diff --git a/src/components/AIServiceCard.tsx b/src/components/AIServiceCard.tsx index c078973..aaf48ca 100644 --- a/src/components/AIServiceCard.tsx +++ b/src/components/AIServiceCard.tsx @@ -8,6 +8,7 @@ interface AIServiceCardProps { tokenCost: number isWalletConnected: boolean onGenerate: (prompt: string) => Promise<{ imageUrl?: string, error?: string }> + mtmPrice: number | null } interface GenerationState { @@ -22,7 +23,8 @@ const AIServiceCard: React.FC = ({ description, tokenCost, isWalletConnected, - onGenerate + onGenerate, + mtmPrice }) => { const [inputText, setInputText] = useState('') const [generationState, setGenerationState] = useState({ @@ -81,7 +83,7 @@ const AIServiceCard: React.FC = ({

{description}

- Cost: {tokenCost} MTM + Cost: {mtmPrice ? mtmPrice.toFixed(2) : '...'} MTM
@@ -105,7 +107,7 @@ const AIServiceCard: React.FC = ({ transition-all duration-200 shadow-lg hover:shadow-green-500/25 disabled:opacity-50 disabled:cursor-not-allowed disabled:hover:shadow-none" > - {generationState.loading ? 'Processing...' : `Pay ${tokenCost} MTM & Generate`} + {generationState.loading ? 'Processing...' : `Pay ${mtmPrice ? mtmPrice.toFixed(2) : '...'} MTM & Generate`} diff --git a/src/services/paymentService.ts b/src/services/paymentService.ts index ffd281e..49956e1 100644 --- a/src/services/paymentService.ts +++ b/src/services/paymentService.ts @@ -19,6 +19,8 @@ const PAYMENT_RECEIVER_ADDRESS = process.env.NEXT_PUBLIC_PAYMENT_RECEIVER_ADDRES const SOLANA_RPC_URL = process.env.NEXT_PUBLIC_SOLANA_RPC_URL; const SOLANA_WEBSOCKET_URL = process.env.NEXT_PUBLIC_SOLANA_WEBSOCKET_URL; +const USDC_MINT = 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v'; // USDC mint address + const connection = new Connection( SOLANA_RPC_URL, { @@ -48,6 +50,21 @@ async function findAssociatedTokenAddress( )[0] } +export async function getUSDCToMTMQuote() { + const url = `https://api.jup.ag/price/v2?ids=${USDC_MINT}&vsToken=${MTM_TOKEN_MINT}`; + + const response = await fetch(url); + + if (!response.ok) { + throw new Error(`Failed to fetch quote: ${response.statusText}`); + } + + const quoteResponse = await response.json(); + const price = quoteResponse['data'][USDC_MINT]['price'] + + return price; +} + interface WalletAdapter { signAndSendTransaction(transaction: Transaction): Promise<{ signature: string }> }