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 { transferLNTTokens } from '@/services/laconicTransfer';
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');
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
let expectedTokenAmount: number;
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) {
console.error('Error calculating token amount:', error);
return NextResponse.json({
@ -223,7 +224,7 @@ export async function POST(request: NextRequest) {
}
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
const requiredEnvVars = [
@ -412,7 +413,7 @@ export async function POST(request: NextRequest) {
tx_hash: txHash,
pubkey: senderPublicKey
},
payment: finalTxHash,
payment: laconicTxHash,
};
console.log('Deployment request data:', deploymentRequestData);

View File

@ -7,7 +7,7 @@ import assert from 'assert';
import { Connection } from '@solana/web3.js';
import { sendSolanaTokenPayment } from '@/services/solana';
import { calculateTokenAmount, getTokenPrice } from '@/services/jupiterPrice';
import { GetRequiredTokenInfo } from '@/services/jupiterPrice';
import { PaymentModalProps } from '@/types';
assert(process.env.NEXT_PUBLIC_SOLANA_RPC_URL, 'SOLANA_RPC_URL is required');
@ -42,12 +42,9 @@ export default function PaymentModal({
setError('');
try {
const [amount, priceInfo] = await Promise.all([
calculateTokenAmount(targetUsdAmount, mintAddress),
getTokenPrice(mintAddress)
]);
setTokenAmount(amount);
setTokenDecimals(priceInfo.decimals);
const {requiredAmount, decimals} = await GetRequiredTokenInfo(targetUsdAmount, mintAddress)
setTokenAmount(requiredAmount);
setTokenDecimals(decimals);
} catch (error) {
console.error('Error fetching token price:', error);
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>
<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>
Calculating token amount...
Fetching token amount...
</div>
) : (
<input
@ -172,7 +169,7 @@ export default function PaymentModal({
</div>
</div>
<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>
</div>

View File

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