diff --git a/frontend/src/components/RampFeeCollapse/index.tsx b/frontend/src/components/RampFeeCollapse/index.tsx index ab1c5a9fe..9fbd6005b 100644 --- a/frontend/src/components/RampFeeCollapse/index.tsx +++ b/frontend/src/components/RampFeeCollapse/index.tsx @@ -4,7 +4,8 @@ import { useQuote } from '../../stores/ramp/useQuoteStore'; import { useFiatToken, useOnChainToken } from '../../stores/ramp/useRampFormStore'; import { useRampDirection } from '../../stores/rampDirectionStore'; import { RampDirection } from '../RampToggle'; -import { ArrowDownIcon, InformationCircleIcon } from '@heroicons/react/20/solid'; +import { InformationCircleIcon } from '@heroicons/react/20/solid'; +import { QuoteEndpoints } from 'shared'; interface FeeItem { label: string; @@ -12,6 +13,41 @@ interface FeeItem { value: string; } +// This function calculates the interbank exchange rate based on the quote response, neglecting any fees. +function calculateInterbankExchangeRate( + rampType: string, + inputAmountString: Big.BigSource, + outputAmountString: Big.BigSource, + fee: QuoteEndpoints.FeeStructure, +) { + const inputAmount = Big(inputAmountString); + const outputAmount = Big(outputAmountString); + + let effectiveInputAmount = inputAmount; + let effectiveOutputAmount = outputAmount; + + if (rampType === 'on') { + effectiveInputAmount = inputAmount.minus(fee.total); + } else { + effectiveOutputAmount = outputAmount.plus(fee.total); + } + + return effectiveInputAmount.gt(0) ? effectiveOutputAmount.div(effectiveInputAmount).toNumber() : 0; +} + +// Calculate all-in exchange rate +function calculateNetExchangeRate(inputAmountString: Big.BigSource, outputAmountString: Big.BigSource) { + const inputAmount = Big(inputAmountString); + const outputAmount = Big(outputAmountString); + + return inputAmount.gt(0) ? outputAmount.div(inputAmount).toNumber() : 0; +} + +// Helper function to format exchange rate strings +function formatExchangeRateString(rate: number, input: string, output: string) { + return `1 ${input} ≈ ${rate.toFixed(4)} ${output}`; +} + export function RampFeeCollapse() { const { t } = useTranslation(); @@ -24,21 +60,23 @@ export function RampFeeCollapse() { const quote = availableQuote ? availableQuote : { + rampType: 'on', inputAmount: 0, outputAmount: 0, inputCurrency: rampDirection === RampDirection.ONRAMP ? fiatToken : onChainToken, outputCurrency: rampDirection === RampDirection.ONRAMP ? onChainToken : fiatToken, - fee: { total: 0, network: 0, vortex: 0, anchor: 0, partnerMarkup: 0, currency: fiatToken }, + fee: { total: '0', network: '0', vortex: '0', anchor: '0', partnerMarkup: '0', currency: fiatToken }, }; - // Calculate exchange rate - const inputAmount = Big(quote.inputAmount); - const outputAmount = Big(quote.outputAmount); const inputCurrency = quote.inputCurrency.toUpperCase(); const outputCurrency = quote.outputCurrency.toUpperCase(); - - // Calculate exchange rate (how much outputCurrency you get for 1 inputCurrency) - const exchangeRate = inputAmount.gt(0) ? outputAmount.div(inputAmount).toNumber() : 0; + const interbankExchangeRate = calculateInterbankExchangeRate( + quote.rampType, + quote.inputAmount, + quote.outputAmount, + quote.fee, + ); + const netExchangeRate = calculateNetExchangeRate(quote.inputAmount, quote.outputAmount); // Generate fee items for display const feeItems: FeeItem[] = []; @@ -64,7 +102,7 @@ export function RampFeeCollapse() { return (
- {`1 ${inputCurrency} ≈ ${exchangeRate.toFixed(4)} ${outputCurrency}`} + {formatExchangeRateString(interbankExchangeRate, inputCurrency, outputCurrency)}
@@ -96,6 +134,19 @@ export function RampFeeCollapse() {
+
+
+ + {t('components.feeCollapse.netRate.label')} + +
+
+ {formatExchangeRateString(netExchangeRate, inputCurrency, outputCurrency)} +
+
diff --git a/frontend/src/translations/en.json b/frontend/src/translations/en.json index 5cdad06d0..d9f42292d 100644 --- a/frontend/src/translations/en.json +++ b/frontend/src/translations/en.json @@ -328,6 +328,10 @@ "tooltip": "The cost to transfer funds to your wallet, which varies with selected network and network congestion." }, "totalFee": "Total Fee", + "netRate": { + "label": "Effective Rate", + "tooltip": "This is the exchange rate you receive after all processing and network fees have been deducted." + }, "finalAmount": "Final Amount" }, "transactionStatusBanner": { diff --git a/frontend/src/translations/pt.json b/frontend/src/translations/pt.json index 28eaa805f..dc7530815 100644 --- a/frontend/src/translations/pt.json +++ b/frontend/src/translations/pt.json @@ -326,6 +326,10 @@ "label": "Taxa de rede", "tooltip": "O custo para transferir fundos para sua carteira, que varia conforme a rede selecionada e a congestão da rede." }, + "netRate": { + "label": "Câmbio Efetiva", + "tooltip": "Esta é a taxa de câmbio que você recebe após a dedução de todas as taxas de processamento e de rede." + }, "totalFee": "Taxa total", "finalAmount": "Valor final" },