feat: add currency setting with fiat conversion, display prices in user's preferred currency

This commit is contained in:
2026-02-05 17:02:03 +01:00
parent 84493942fe
commit 56cf5a63c3
9 changed files with 125 additions and 20 deletions

View File

@@ -165,14 +165,44 @@ export function convertFromXmr(xmrAmount, currency, rates) {
return xmrAmount * rates[currency]
}
/**
* Converts between fiat currencies using XMR as bridge
* @param {number} amount - Amount in source currency
* @param {string} fromCurrency - Source currency
* @param {string} toCurrency - Target currency
* @param {Object} rates - Rates from getXmrRates() (XMR -> Fiat)
* @returns {number} Amount in target currency
*/
export function convertFiat(amount, fromCurrency, toCurrency, rates) {
if (fromCurrency === toCurrency) return amount
if (!rates[fromCurrency] || !rates[toCurrency]) return amount
// Use XMR as bridge: EUR -> XMR -> USD
// 1 XMR = rates[EUR] EUR, so 1 EUR = 1/rates[EUR] XMR
// 1 XMR = rates[USD] USD
// Therefore: 1 EUR = rates[USD] / rates[EUR] USD
return amount * (rates[toCurrency] / rates[fromCurrency])
}
/**
* Get user's preferred display currency from settings
* @returns {string} Currency code (default: 'USD')
*/
export function getDisplayCurrency() {
return localStorage.getItem('dgray_currency') || 'USD'
}
/**
* Formats a price for display
* Shows price in user's preferred currency with XMR equivalent
* @param {Object} listing - Listing with price, currency, price_mode
* @param {Object} rates - Rates from getXmrRates()
* @param {string} [displayCurrency] - Override display currency
* @returns {Object} { primary, secondary, xmrAmount }
*/
export function formatPrice(listing, rates) {
export function formatPrice(listing, rates, displayCurrency = null) {
const { price, currency, price_mode } = listing
const userCurrency = displayCurrency || getDisplayCurrency()
if (!price || price === 0) {
return {
@@ -185,20 +215,25 @@ export function formatPrice(listing, rates) {
// XMR mode: XMR is the reference price
if (price_mode === 'xmr' || currency === 'XMR') {
const xmrPrice = currency === 'XMR' ? price : convertToXmr(price, currency, rates)
const fiatEquivalent = currency !== 'XMR' ? price : convertFromXmr(price, 'EUR', rates)
const fiatEquivalent = convertFromXmr(xmrPrice, userCurrency, rates)
return {
primary: formatXmr(xmrPrice),
secondary: currency !== 'XMR' ? `${formatFiat(price, currency)}` : `${formatFiat(fiatEquivalent, 'EUR')}`,
primary: formatFiat(fiatEquivalent, userCurrency),
secondary: `${formatXmr(xmrPrice)}`,
xmrAmount: xmrPrice
}
}
// Fiat mode: Fiat is the reference price
// Fiat mode: Convert to user's preferred currency
const xmrEquivalent = convertToXmr(price, currency, rates)
// Always show in user's currency as primary
const displayPrice = userCurrency === currency
? price
: convertFiat(price, currency, userCurrency, rates)
return {
primary: formatFiat(price, currency),
primary: formatFiat(displayPrice, userCurrency),
secondary: `${formatXmr(xmrEquivalent)}`,
xmrAmount: xmrEquivalent
}
@@ -253,8 +288,10 @@ export const SUPPORTED_CURRENCIES = ['XMR', 'EUR', 'CHF', 'USD', 'GBP', 'JPY']
export default {
getXmrRates,
getDisplayCurrency,
convertToXmr,
convertFromXmr,
convertFiat,
formatPrice,
formatXmr,
formatFiat,