Fix jupiter price methods

This commit is contained in:
Shreerang Kale 2025-07-22 14:46:57 +05:30
parent 527d8431bd
commit fb78e67633
3 changed files with 31 additions and 44 deletions

View File

@ -10,7 +10,7 @@ import { DENOM as ALNT_DENOM } from '@cerc-io/registry-sdk';
import { verifyUnusedSolanaPayment } from '@/utils/solanaVerify'; import { verifyUnusedSolanaPayment } from '@/utils/solanaVerify';
import { transferLNTTokens } from '@/services/laconicTransfer'; import { transferLNTTokens } from '@/services/laconicTransfer';
import { getRegistry, getRegistryConfig } from '@/config'; import { getRegistry, getRegistryConfig } from '@/config';
import { calculateTokenAmount } from '@/services/jupiterPrice'; import { GetRequiredTokenInfo } from '@/services/jupiterPrice';
assert(process.env.NEXT_PUBLIC_SOLANA_RPC_URL, 'SOLANA_RPC_URL is required'); assert(process.env.NEXT_PUBLIC_SOLANA_RPC_URL, 'SOLANA_RPC_URL is required');
const SOLANA_RPC_URL = process.env.NEXT_PUBLIC_SOLANA_RPC_URL; const SOLANA_RPC_URL = process.env.NEXT_PUBLIC_SOLANA_RPC_URL;
@ -185,7 +185,8 @@ export async function POST(request: NextRequest) {
// Calculate expected token amount based on current price // Calculate expected token amount based on current price
let expectedTokenAmount: number; let expectedTokenAmount: number;
try { try {
expectedTokenAmount = await calculateTokenAmount(targetUsdAmount, mintAddress); const { requiredAmount } = await GetRequiredTokenInfo(targetUsdAmount, mintAddress);
expectedTokenAmount = Math.round(requiredAmount - 0.2 * requiredAmount); // Allow 20% slippage due to price fluctuations
} catch (error) { } catch (error) {
console.error('Error calculating token amount:', error); console.error('Error calculating token amount:', error);
return NextResponse.json({ return NextResponse.json({
@ -223,7 +224,7 @@ export async function POST(request: NextRequest) {
} }
console.log('LNT transfer completed:', lntTransferResult.transactionHash); console.log('LNT transfer completed:', lntTransferResult.transactionHash);
const finalTxHash = lntTransferResult.transactionHash!; // Use LNT transfer hash for registry const laconicTxHash = lntTransferResult.transactionHash!; // Use LNT transfer hash for registry
// Validate required environment variables for Solana payments // Validate required environment variables for Solana payments
const requiredEnvVars = [ const requiredEnvVars = [
@ -412,7 +413,7 @@ export async function POST(request: NextRequest) {
tx_hash: txHash, tx_hash: txHash,
pubkey: senderPublicKey pubkey: senderPublicKey
}, },
payment: finalTxHash, payment: laconicTxHash,
}; };
console.log('Deployment request data:', deploymentRequestData); console.log('Deployment request data:', deploymentRequestData);

View File

@ -7,7 +7,7 @@ import assert from 'assert';
import { Connection } from '@solana/web3.js'; import { Connection } from '@solana/web3.js';
import { sendSolanaTokenPayment } from '@/services/solana'; import { sendSolanaTokenPayment } from '@/services/solana';
import { calculateTokenAmount, getTokenPrice } from '@/services/jupiterPrice'; import { GetRequiredTokenInfo } from '@/services/jupiterPrice';
import { PaymentModalProps } from '@/types'; import { PaymentModalProps } from '@/types';
assert(process.env.NEXT_PUBLIC_SOLANA_RPC_URL, 'SOLANA_RPC_URL is required'); assert(process.env.NEXT_PUBLIC_SOLANA_RPC_URL, 'SOLANA_RPC_URL is required');
@ -42,12 +42,9 @@ export default function PaymentModal({
setError(''); setError('');
try { try {
const [amount, priceInfo] = await Promise.all([ const {requiredAmount, decimals} = await GetRequiredTokenInfo(targetUsdAmount, mintAddress)
calculateTokenAmount(targetUsdAmount, mintAddress), setTokenAmount(requiredAmount);
getTokenPrice(mintAddress) setTokenDecimals(decimals);
]);
setTokenAmount(amount);
setTokenDecimals(priceInfo.decimals);
} catch (error) { } catch (error) {
console.error('Error fetching token price:', error); console.error('Error fetching token price:', error);
setError('Unable to fetch current token price. Please try again.'); setError('Unable to fetch current token price. Please try again.');
@ -147,7 +144,7 @@ export default function PaymentModal({
<circle className="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="4"></circle> <circle className="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="4"></circle>
<path className="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path> <path className="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
</svg> </svg>
Calculating token amount... Fetching token amount...
</div> </div>
) : ( ) : (
<input <input
@ -172,7 +169,7 @@ export default function PaymentModal({
</div> </div>
</div> </div>
<p className="text-xs mt-1" style={{ color: 'var(--muted)' }}> <p className="text-xs mt-1" style={{ color: 'var(--muted)' }}>
Token amount calculated from current market price Token information fetched from <a className='text-blue-400 underline' href={`https://jup.ag/tokens/${process.env.NEXT_PUBLIC_SOLANA_TOKEN_MINT_ADDRESS}`}>Jupiter</a>
</p> </p>
</div> </div>

View File

@ -12,27 +12,32 @@ interface TokenPriceInfo {
decimals: number; decimals: number;
} }
interface RequiredTokenInfo {
requiredAmount: number;
decimals: number;
}
/** /**
* Fetches token price from Jupiter aggregator API * Fetches token price from Jupiter aggregator API
* @param mintAddress The Solana token mint address * @param mintAddress The Solana token mint address
* @returns Token price information including USD price and decimals * @returns Token price information including USD price and decimals
*/ */
export async function getTokenPrice(mintAddress: string): Promise<TokenPriceInfo> { export async function getTokenInfo(mintAddress: string): Promise<TokenPriceInfo> {
try { try {
const response = await fetch(`https://lite-api.jup.ag/price/v3?ids=${mintAddress}`); const response = await fetch(`https://lite-api.jup.ag/price/v3?ids=${mintAddress}`);
if (!response.ok) { if (!response.ok) {
throw new Error(`Jupiter API error: ${response.status} ${response.statusText}`); throw new Error(`Jupiter API error: ${response.status} ${response.statusText}`);
} }
const data: JupiterPriceResponse = await response.json(); const data: JupiterPriceResponse = await response.json();
if (!data[mintAddress]) { if (!data[mintAddress]) {
throw new Error(`Price not found for token: ${mintAddress}`); throw new Error(`Price not found for token: ${mintAddress}`);
} }
const tokenInfo = data[mintAddress]; const tokenInfo = data[mintAddress];
return { return {
usdPrice: tokenInfo.usdPrice, usdPrice: tokenInfo.usdPrice,
decimals: tokenInfo.decimals decimals: tokenInfo.decimals
@ -47,32 +52,16 @@ export async function getTokenPrice(mintAddress: string): Promise<TokenPriceInfo
* Calculates the token amount needed for a given USD price * Calculates the token amount needed for a given USD price
* @param targetUsdAmount The target amount in USD * @param targetUsdAmount The target amount in USD
* @param mintAddress The Solana token mint address * @param mintAddress The Solana token mint address
* @returns The token amount (in smallest units) needed * @returns The token amount (in smallest units) needed and token decimals
*/ */
export async function calculateTokenAmount(targetUsdAmount: number, mintAddress: string): Promise<number> { export async function GetRequiredTokenInfo(targetUsdAmount: number, mintAddress: string): Promise<RequiredTokenInfo> {
const priceInfo = await getTokenPrice(mintAddress); const priceInfo = await getTokenInfo(mintAddress);
// Calculate token amount needed // Calculate token amount needed
const tokenAmount = targetUsdAmount / priceInfo.usdPrice; const tokenAmount = targetUsdAmount / priceInfo.usdPrice;
// Convert to smallest units (considering decimals)
const amountInSmallestUnits = Math.ceil(tokenAmount * Math.pow(10, priceInfo.decimals));
return amountInSmallestUnits;
}
/** // Convert to smallest units (considering decimals)
* Gets the current USD value of a token amount const amountInSmallestUnits = Math.round(tokenAmount * Math.pow(10, priceInfo.decimals));
* @param tokenAmount Token amount in smallest units
* @param mintAddress The Solana token mint address return {requiredAmount: amountInSmallestUnits, decimals: priceInfo.decimals};
* @returns USD value of the token amount }
*/
export async function getTokenValueInUSD(tokenAmount: number, mintAddress: string): Promise<number> {
const priceInfo = await getTokenPrice(mintAddress);
// Convert from smallest units to token units
const actualTokens = tokenAmount / Math.pow(10, priceInfo.decimals);
// Calculate USD value
return actualTokens * priceInfo.usdPrice;
}