Fetch USDC price in MTM using jupiter API

This commit is contained in:
Adw8 2025-01-28 11:20:18 +05:30
parent 5d42d281a0
commit 36a140734a
3 changed files with 44 additions and 5 deletions

View File

@ -1,10 +1,10 @@
'use client' 'use client'
import React, { useState } from 'react' import React, { useState, useEffect } from 'react'
import WalletHeader from '../components/WalletHeader' import WalletHeader from '../components/WalletHeader'
import AIServiceCard from '../components/AIServiceCard' import AIServiceCard from '../components/AIServiceCard'
import { generateWithFlux, FluxGenerationResult, FLUX_MODELS } from '../services/fluxService' 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 { connectWallet, disconnectWallet, WalletState } from '../services/walletService'
import { WalletType } from '../services/types' import { WalletType } from '../services/types'
@ -15,6 +15,25 @@ const Page: React.FC = (): React.ReactElement => {
type: null type: null
}) })
const [usdcPrice, setUsdcPrice] = useState<number>(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<void> => { const handleConnect = async (walletType: WalletType): Promise<void> => {
try { try {
const newWalletState = await connectWallet(walletType) const newWalletState = await connectWallet(walletType)
@ -100,6 +119,7 @@ const Page: React.FC = (): React.ReactElement => {
tokenCost={model.cost} tokenCost={model.cost}
isWalletConnected={walletState.connected} isWalletConnected={walletState.connected}
onGenerate={handleFluxGeneration(model.modelId, model.cost)} onGenerate={handleFluxGeneration(model.modelId, model.cost)}
mtmPrice={model.cost * usdcPrice}
/> />
))} ))}

View File

@ -8,6 +8,7 @@ interface AIServiceCardProps {
tokenCost: number tokenCost: number
isWalletConnected: boolean isWalletConnected: boolean
onGenerate: (prompt: string) => Promise<{ imageUrl?: string, error?: string }> onGenerate: (prompt: string) => Promise<{ imageUrl?: string, error?: string }>
mtmPrice: number | null
} }
interface GenerationState { interface GenerationState {
@ -22,7 +23,8 @@ const AIServiceCard: React.FC<AIServiceCardProps> = ({
description, description,
tokenCost, tokenCost,
isWalletConnected, isWalletConnected,
onGenerate onGenerate,
mtmPrice
}) => { }) => {
const [inputText, setInputText] = useState<string>('') const [inputText, setInputText] = useState<string>('')
const [generationState, setGenerationState] = useState<GenerationState>({ const [generationState, setGenerationState] = useState<GenerationState>({
@ -81,7 +83,7 @@ const AIServiceCard: React.FC<AIServiceCardProps> = ({
</h2> </h2>
<p className="text-gray-400 mt-2">{description}</p> <p className="text-gray-400 mt-2">{description}</p>
<div className="mt-2 inline-block px-3 py-1 bg-green-500/20 rounded-full text-green-300 text-sm"> <div className="mt-2 inline-block px-3 py-1 bg-green-500/20 rounded-full text-green-300 text-sm">
Cost: {tokenCost} MTM Cost: {mtmPrice ? mtmPrice.toFixed(2) : '...'} MTM
</div> </div>
</div> </div>
@ -105,7 +107,7 @@ const AIServiceCard: React.FC<AIServiceCardProps> = ({
transition-all duration-200 shadow-lg hover:shadow-green-500/25 transition-all duration-200 shadow-lg hover:shadow-green-500/25
disabled:opacity-50 disabled:cursor-not-allowed disabled:hover:shadow-none" 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`}
</button> </button>
</div> </div>

View File

@ -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_RPC_URL = process.env.NEXT_PUBLIC_SOLANA_RPC_URL;
const SOLANA_WEBSOCKET_URL = process.env.NEXT_PUBLIC_SOLANA_WEBSOCKET_URL; const SOLANA_WEBSOCKET_URL = process.env.NEXT_PUBLIC_SOLANA_WEBSOCKET_URL;
const USDC_MINT = 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v'; // USDC mint address
const connection = new Connection( const connection = new Connection(
SOLANA_RPC_URL, SOLANA_RPC_URL,
{ {
@ -48,6 +50,21 @@ async function findAssociatedTokenAddress(
)[0] )[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 { interface WalletAdapter {
signAndSendTransaction(transaction: Transaction): Promise<{ signature: string }> signAndSendTransaction(transaction: Transaction): Promise<{ signature: string }>
} }