void
@@ -72,15 +71,15 @@ export function ConfirmBankClaimView({
// fallback if conversion fails
const failedConversion = useMemo(() => {
- return currencyCode !== 'USD' && !isLoadingCurrency && (!price || isNaN(price))
+ return currencyCode !== 'USD' && !isLoadingCurrency && (!price?.sell || isNaN(price.sell))
}, [currencyCode, isLoadingCurrency, price])
// display amount in local currency
const displayAmount = useMemo(() => {
if (currencyCode === 'USD') return usdAmount
if (isLoadingCurrency) return '-'
- if (!price || isNaN(price)) return usdAmount
- const converted = (Number(usdAmount) * price).toFixed(2)
+ if (!price?.sell || isNaN(price.sell)) return usdAmount
+ const converted = (Number(usdAmount) * price.sell).toFixed(2)
return converted
}, [price, usdAmount, currencyCode, isLoadingCurrency])
@@ -88,7 +87,7 @@ export function ConfirmBankClaimView({
if (currencyCode === 'USD') return '$'
// fallback to $ if conversion fails
if (failedConversion) return '$'
- return resolvedSymbol ?? getCurrencySymbol(currencyCode)
+ return resolvedSymbol ?? currencyCode
}, [currencyCode, resolvedSymbol, failedConversion])
return (
diff --git a/src/components/Common/ActionListDaimoPayButton.tsx b/src/components/Common/ActionListDaimoPayButton.tsx
index aec0a7ea2..98b4e5774 100644
--- a/src/components/Common/ActionListDaimoPayButton.tsx
+++ b/src/components/Common/ActionListDaimoPayButton.tsx
@@ -52,7 +52,7 @@ const ActionListDaimoPayButton = () => {
? {
code: currencyCode,
symbol: currencySymbol || '',
- price: currencyPrice || 0,
+ price: currencyPrice?.buy || 0,
}
: undefined,
currencyAmount: usdAmount,
diff --git a/src/components/Global/DirectSendQR/index.tsx b/src/components/Global/DirectSendQR/index.tsx
index 0098213f0..c1105b656 100644
--- a/src/components/Global/DirectSendQR/index.tsx
+++ b/src/components/Global/DirectSendQR/index.tsx
@@ -294,9 +294,15 @@ export default function DirectSendQr({
}
break
case EQrType.MERCADO_PAGO:
+ case EQrType.PIX:
+ {
+ const timestamp = Date.now()
+ // Casing matters, so send original instead of normalized
+ redirectUrl = `/qr-pay?qrCode=${originalData}&t=${timestamp}`
+ }
+ break
case EQrType.BITCOIN_ONCHAIN:
case EQrType.BITCOIN_INVOICE:
- case EQrType.PIX:
case EQrType.TRON_ADDRESS:
case EQrType.SOLANA_ADDRESS:
case EQrType.XRP_ADDRESS: {
diff --git a/src/components/Global/DirectSendQR/utils.ts b/src/components/Global/DirectSendQR/utils.ts
index 302a00071..b20cab84b 100644
--- a/src/components/Global/DirectSendQR/utils.ts
+++ b/src/components/Global/DirectSendQR/utils.ts
@@ -50,7 +50,12 @@ const MP_AR_REGEX =
/^000201((?!6304).)*(?:(?:26|27|28|29|30|31|35|43)\d{2}(?:0015com\.mercadopago|0016com\.mercadolibre)).*5303032.*5802AR((?!6304).)*6304[0-9A-F]{4}$/i
/* PIX is also a emvco qr code */
-const PIX_REGEX = /^.*00020126.*0014br\.gov\.bcb\.pix.*5303986.*5802BR.*$/i
+const PIX_REGEX = /^.*000201.*0014br\.gov\.bcb\.pix.*5303986.*5802BR.*$/i
+
+export const PAYMENT_PROCESSOR_REGEXES: { [key in QrType]?: RegExp } = {
+ [EQrType.MERCADO_PAGO]: MP_AR_REGEX,
+ [EQrType.PIX]: PIX_REGEX,
+}
const EIP_681_REGEX = /^ethereum:(?:pay-)?([^@/?]+)(?:@([^/?]+))?(?:\/([^?]+))?(?:\?(.*))?$/i
@@ -88,6 +93,19 @@ export function recognizeQr(data: string): QrType | null {
return null
}
+/**
+ * Returns true if the given string is a payment processor QR code.
+ * For example, Mercado Pago, Pix, etc.
+ */
+export const isPaymentProcessorQR = (data: string): boolean => {
+ for (const [_type, regex] of Object.entries(PAYMENT_PROCESSOR_REGEXES)) {
+ if (regex.test(data)) {
+ return true
+ }
+ }
+ return false
+}
+
/**
* Extracts EIP-681 parameters from an Ethereum URI
* @param data The Ethereum URI string (e.g. "ethereum:0x123...?value=1e18")
diff --git a/src/components/Global/TokenAmountInput/index.tsx b/src/components/Global/TokenAmountInput/index.tsx
index bc3833434..5a3e6c96a 100644
--- a/src/components/Global/TokenAmountInput/index.tsx
+++ b/src/components/Global/TokenAmountInput/index.tsx
@@ -125,6 +125,10 @@ const TokenAmountInput = ({
[displayMode, currency?.price, selectedTokenData?.price, calculateAlternativeValue]
)
+ const showConversion = useMemo(() => {
+ return !hideCurrencyToggle && (displayMode === 'TOKEN' || displayMode === 'FIAT')
+ }, [hideCurrencyToggle, displayMode])
+
// This is needed because if we change the token we selected the value
// should change. This only depends on the price on purpose!! we don't want
// to change when we change the display mode or the value (we already call
@@ -152,11 +156,11 @@ const TokenAmountInput = ({
}
case 'FIAT': {
if (isInputUsd) {
- setDisplaySymbol('$')
+ setDisplaySymbol('USD')
setAlternativeDisplaySymbol(currency?.symbol || '')
} else {
setDisplaySymbol(currency?.symbol || '')
- setAlternativeDisplaySymbol('$')
+ setAlternativeDisplaySymbol('USD')
}
break
}
@@ -196,48 +200,62 @@ const TokenAmountInput = ({
return (