feat: update legal pages, add Kraken API as primary rate source, clarify listing fee

This commit is contained in:
2026-02-11 15:13:47 +01:00
parent a4d960b752
commit 2d7d22b22f
13 changed files with 178 additions and 82 deletions

View File

@@ -1,10 +1,12 @@
/**
* Currency Service - XMR/Fiat Conversion
*
* Uses CoinGecko API for real-time exchange rates (CORS-friendly)
* Primary: Kraken API (no key required, reliable)
* Fallback: CoinGecko API
* Supports two modes: fiat-fix and xmr-fix
*/
const KRAKEN_API = 'https://api.kraken.com/0/public/Ticker'
const COINGECKO_API = 'https://api.coingecko.com/api/v3/simple/price'
const CURRENCY_SYMBOLS = {
@@ -90,25 +92,68 @@ export async function getXmrRates() {
async function fetchRates() {
lastRequestTime = Date.now()
// Try Kraken first, then CoinGecko as fallback
const rates = await fetchFromKraken() || await fetchFromCoinGecko()
if (rates) {
cachedRates = rates
cacheTimestamp = Date.now()
saveToStorage()
return rates
}
return cachedRates || getDefaultRates()
}
async function fetchFromKraken() {
try {
const pairs = 'XMREUR,XMRUSD,XMRGBP,XMRJPY'
const response = await fetch(`${KRAKEN_API}?pair=${pairs}`)
if (!response.ok) return null
const data = await response.json()
if (data.error?.length > 0) return null
const r = data.result
const getPrice = (key) => {
const entry = r[key]
return entry ? parseFloat(entry.c[0]) : null
}
const eur = getPrice('XXMRZEUR') || getPrice('XMREUR')
const usd = getPrice('XXMRZUSD') || getPrice('XMRUSD')
const gbp = getPrice('XXMRGBP') || getPrice('XMRGBP')
const jpy = getPrice('XXMRJPY') || getPrice('XMRJPY')
if (!eur || !usd) return null
// Kraken doesn't have CHF/RUB/BRL pairs for XMR — derive from EUR
const chf = eur * 0.97
const rub = eur * 100
const brl = usd * 5.5
return { EUR: eur, USD: usd, GBP: gbp || eur * 0.86, CHF: chf, JPY: jpy || eur * 162, RUB: rub, BRL: brl }
} catch (e) {
console.warn('Kraken API failed, trying CoinGecko:', e.message)
return null
}
}
async function fetchFromCoinGecko() {
try {
const currencies = 'eur,usd,gbp,chf,jpy,rub,brl'
const response = await fetch(`${COINGECKO_API}?ids=monero&vs_currencies=${currencies}`)
// Handle rate limit response
if (response.status === 429) {
console.warn('CoinGecko rate limit hit, using cached rates')
return cachedRates || getDefaultRates()
console.warn('CoinGecko rate limit hit')
return null
}
const data = await response.json()
if (!data.monero) return null
if (!data.monero) {
console.error('CoinGecko API Error: No data returned')
return cachedRates || getDefaultRates()
}
const rates = {
return {
EUR: data.monero.eur,
USD: data.monero.usd,
GBP: data.monero.gbp,
@@ -117,16 +162,9 @@ async function fetchRates() {
RUB: data.monero.rub,
BRL: data.monero.brl
}
// Update cache
cachedRates = rates
cacheTimestamp = Date.now()
saveToStorage()
return rates
} catch (error) {
console.error('Failed to fetch XMR rates:', error)
return cachedRates || getDefaultRates()
} catch (e) {
console.error('CoinGecko API failed:', e.message)
return null
}
}