|
|
@@ -105,16 +105,70 @@ export class JupiterSwapper {
|
|
|
}
|
|
|
|
|
|
async getTokenPrices(tokenAddresses: string[]): Promise<Record<string, { price?: number; symbol?: string }>> {
|
|
|
+ const result: Record<string, { price?: number; symbol?: string }> = {}
|
|
|
+
|
|
|
+ // 1. 先尝试 Jupiter Price API
|
|
|
try {
|
|
|
const ids = tokenAddresses.join(',')
|
|
|
const response = await fetch(`https://api.jup.ag/price/v2?ids=${ids}`, {
|
|
|
headers: this.getHeaders(),
|
|
|
})
|
|
|
- const data = (await response.json()) as { data?: Record<string, { price?: number; symbol?: string }> }
|
|
|
- return data.data || {}
|
|
|
+ if (response.ok) {
|
|
|
+ const data = (await response.json()) as { data?: Record<string, { price?: number; symbol?: string }> }
|
|
|
+ if (data.data) {
|
|
|
+ Object.assign(result, data.data)
|
|
|
+ }
|
|
|
+ }
|
|
|
} catch (error) {
|
|
|
- console.error('Error fetching token prices:', error)
|
|
|
- return {}
|
|
|
+ console.error('[Jupiter] Error fetching prices:', error)
|
|
|
+ }
|
|
|
+
|
|
|
+ // 2. 对 Jupiter 没有返回价格的代币,尝试 DexScreener
|
|
|
+ const missingMints = tokenAddresses.filter((mint) => !result[mint]?.price)
|
|
|
+ if (missingMints.length > 0) {
|
|
|
+ try {
|
|
|
+ for (const mint of missingMints) {
|
|
|
+ const dsPrice = await this.getDexScreenerPrice(mint)
|
|
|
+ if (dsPrice) {
|
|
|
+ result[mint] = dsPrice
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } catch (error) {
|
|
|
+ console.error('[DexScreener] Error fetching prices:', error)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return result
|
|
|
+ }
|
|
|
+
|
|
|
+ private async getDexScreenerPrice(mint: string): Promise<{ price?: number; symbol?: string } | null> {
|
|
|
+ try {
|
|
|
+ const response = await fetch(`https://api.dexscreener.com/latest/dex/tokens/${mint}`)
|
|
|
+ if (!response.ok) return null
|
|
|
+
|
|
|
+ const data = (await response.json()) as {
|
|
|
+ pairs?: Array<{
|
|
|
+ priceUsd?: string
|
|
|
+ baseToken?: { symbol?: string }
|
|
|
+ liquidity?: { usd?: number }
|
|
|
+ }>
|
|
|
+ }
|
|
|
+
|
|
|
+ if (data.pairs && data.pairs.length > 0) {
|
|
|
+ // 选择流动性最高的交易对
|
|
|
+ const sortedPairs = data.pairs.sort((a, b) => (b.liquidity?.usd || 0) - (a.liquidity?.usd || 0))
|
|
|
+ const bestPair = sortedPairs[0]
|
|
|
+ const price = parseFloat(bestPair.priceUsd || '0')
|
|
|
+ if (price > 0) {
|
|
|
+ return {
|
|
|
+ price,
|
|
|
+ symbol: bestPair.baseToken?.symbol,
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return null
|
|
|
+ } catch {
|
|
|
+ return null
|
|
|
}
|
|
|
}
|
|
|
|