From e85b6b3c657271510a2fd0a582668e858fbe7cf3 Mon Sep 17 00:00:00 2001 From: Jonathan Tzeng Date: Wed, 19 Aug 2026 15:40:15 -0700 Subject: [PATCH] Show ramp crypto amounts at the asset's own decimal precision The buy/sell amount field capped the crypto value at six decimals, which was fine while every provider quoted at or below that. MoonPay raises its buy-flow precision on September 1, 2026 (BTC to eight decimals, ETH and SOL to nine), so the cap would start silently truncating the amount the user is quoted. Derive the cap from the selected asset's denomination instead, bounded at nine decimals. Assets with more precision than a quote can express, such as ETH at eighteen, would otherwise surface the rounding noise of the float exchange rate the field divides by while a fiat amount is typed. --- CHANGELOG.md | 1 + src/components/scenes/RampCreateScene.tsx | 24 ++++++++++++++++++++++- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cfba92d8c57..3f4218b1fae 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ - changed: Refresh the buy, sell, sort, scan-QR and FIO names icons to the updated design. - changed: Display "MoonPay" instead of "Moonpay" wherever the partner name appears in the app. - changed: Use a custom chart icon for the side menu Markets row, so it matches the rest of the menu. +- changed: The buy/sell crypto amount field now shows as many decimals as the asset itself supports, up to nine, instead of a fixed six. MoonPay raises its buy-flow precision to eight decimals for BTC and nine for ETH and SOL on September 1, 2026, which the old limit would have truncated. - changed: Use the UI4 warning card for the Reveal Raw Keys and Reveal Master Private Key password confirmation warnings. - changed: Tron resource staking now describes its claim action as reclaiming your own TRX, instead of claiming a reward. - changed: Deep links now wait only for the account state they actually use, so a link that just opens a scene, such as the buy/sell entry, follows immediately after login instead of waiting for every wallet to finish loading. diff --git a/src/components/scenes/RampCreateScene.tsx b/src/components/scenes/RampCreateScene.tsx index 4e7c3746df0..d5b6f3f346d 100644 --- a/src/components/scenes/RampCreateScene.tsx +++ b/src/components/scenes/RampCreateScene.tsx @@ -85,6 +85,13 @@ import { EdgeText } from '../themed/EdgeText' import { FilledTextInput } from '../themed/FilledTextInput' import { RampRegionSelect } from './RampCreateScene/RampRegionSelect' +/** + * Upper bound on the decimals the crypto amount field renders, for assets whose + * own precision goes beyond what a ramp quote can express. See + * `cryptoMaxDecimals`. + */ +const MAX_CRYPTO_ENTRY_DECIMALS = 9 + export interface RampCreateParams { forcedWalletResult?: WalletListWalletResult regionCode?: string @@ -592,6 +599,21 @@ export const RampCreateScene: React.FC = (props: Props) => { denomination ]) + // How many decimals the crypto field renders. Providers quote each asset at + // its own precision and change it over time (Moonpay moves BTC 5 -> 8 and + // ETH/SOL to 9 decimals on the buy flow in September 2026), so this follows + // the asset instead of assuming a count. The 9-decimal ceiling keeps the + // field readable for high-precision assets such as ETH, whose 18 decimals + // would expose the rounding noise of the float exchange rate that + // `displayCryptoAmount` divides by while the user types a fiat amount. + const cryptoMaxDecimals = React.useMemo(() => { + if (denomination == null) return MAX_CRYPTO_ENTRY_DECIMALS + return Math.min( + mulToPrecision(denomination.multiplier), + MAX_CRYPTO_ENTRY_DECIMALS + ) + }, [denomination]) + // Log the quote event only when the scene is focused useFocusEffect(() => { dispatch(logEvent(direction === 'buy' ? 'Buy_Quote' : 'Sell_Quote')) @@ -1091,7 +1113,7 @@ export const RampCreateScene: React.FC = (props: Props) => { placeholder={cryptoAmountPlaceholder} keyboardType="decimal-pad" numeric - maxDecimals={6} + maxDecimals={cryptoMaxDecimals} returnKeyType="done" showSpinner={isFetchingQuotes && lastUsedInput === 'fiat'} disabled={cryptoInputDisabled}