fix(ramp): surface provider error messages for out-of-bounds amounts in V2 BuildQuote#28174
fix(ramp): surface provider error messages for out-of-bounds amounts in V2 BuildQuote#28174saustrie-consensys wants to merge 23 commits intomainfrom
Conversation
|
CLA Signature Action: All authors have signed the CLA. You may need to manually re-run the blocking PR check if it doesn't pass in a few minutes. |
5a4fadb to
00a89a7
Compare
…date limit wording Disable the Get Quotes button when the entered amount is below minimum, above maximum, exceeds balance, or exceeds balance minus gas. Update limit error messages from "Minimum/Maximum deposit is" to "Minimum/Maximum purchase is" to match Figma designs. Surface provider-specific error messages on the Quotes screen when all providers return errors instead of showing only the generic fallback text. Fix pre-existing test failure by adding a mock for @metamask/react-native-button (incompatible with RN 0.76).
…x-quote-limits-ux # Conflicts: # app/components/UI/Ramp/Aggregator/Views/BuildQuote/__snapshots__/BuildQuote.test.tsx.snap # app/components/UI/Ramp/Aggregator/Views/Quotes/__snapshots__/Quotes.test.tsx.snap
00a89a7 to
5ba027e
Compare
|
I have read the CLA Document and I hereby sign the CLA |
app/components/UI/Ramp/Aggregator/Views/BuildQuote/BuildQuote.test.tsx
Outdated
Show resolved
Hide resolved
|
We are touching the wrong files here. Make sure you check with cursor that we want to only improve the experience under the feature flag unifiedBuyV2. |
…in V2 BuildQuote Revert changes to legacy Aggregator views and apply the fix to the V2 unified buy flow (behind unifiedBuyV2 feature flag). When the quotes API returns provider errors with no successful quotes, display the provider's error message (e.g. minimum/maximum amount) instead of the generic "no quotes" fallback.
app/components/UI/Ramp/Aggregator/Views/BuildQuote/BuildQuote.test.tsx
Outdated
Show resolved
Hide resolved
Reverts unintended changes to legacy Aggregator files (pre-UB2) and adds comprehensive tests for provider error handling in the V2 BuildQuote flow.
…x-quote-limits-ux
…x-quote-limits-ux
… ternary - Narrow type assertion scope in getProviderBuyLimit (SonarCloud) - Remove isQuoteAmountSettled from quoteFetchEnabled so the Continue button no longer flashes disabled on every keystroke during debounce - Extract nested ternary in action section into an actionSectionMessage variable with explicit if/else logic (SonarCloud) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ranch) The RAMPS_BASE_URL_OVERRIDE feature now lives on saustrie-consensys/ramps-base-url-override. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #28174 +/- ##
==========================================
+ Coverage 82.13% 82.15% +0.02%
==========================================
Files 4942 4950 +8
Lines 129947 130101 +154
Branches 28977 29015 +38
==========================================
+ Hits 106732 106885 +153
- Misses 15917 15921 +4
+ Partials 7298 7295 -3 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
|
E2E fixtures updated. |
| const debouncedPollingAmount = useDebouncedValue(amountAsNumber, 500); | ||
| const hasAmount = amountAsNumber > 0; | ||
|
|
||
| const selectedProviderBuyLimit = useMemo( |
There was a problem hiding this comment.
Please move selectedProviderBuyLimit and amountLimitError to a useProviderLimits hook similar to what we have on aggregator:
There was a problem hiding this comment.
Quick update: I implemented it on Friday. By doing this, I'm now over the 1k lines limit: https://github.com/MetaMask/metamask-mobile/actions/runs/24293058001/job/70933469937?pr=28174
… quotes async, fix error placement - Revert unnecessary async/await in quotes.ts queryFn (no try/catch needed) - Extract selectedProviderBuyLimit and amountLimitError into useProviderLimits hook - Move inline limit error into actionSectionMessage IIFE inside actionSection - Remove custom limitErrorText style, use actionSection gap for spacing Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…x-quote-limits-ux
🔍 Smart E2E Test Selection
click to see 🤖 AI reasoning detailsE2E Test Selection: Performance Test Selection: |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 58363b6. Configure here.
| <Text | ||
| variant={TextVariant.BodySm} | ||
| color={TextColor.ErrorDefault} | ||
| style={{ textAlign: 'center' as const }} |
There was a problem hiding this comment.
Inline style object recreated on every render
Low Severity
The actionSectionMessage renders a Text component with an inline style object { textAlign: 'center' as const }, which creates a new object reference on every render. The rest of the component consistently uses StyleSheet.create for styles (e.g., styles.poweredByText). This inline object breaks the pattern and causes unnecessary style reconciliation on each render cycle.
Reviewed by Cursor Bugbot for commit 58363b6. Configure here.
|
|
✅ E2E Fixture Validation — Schema is up to date |










Description
Fix UX for out-of-bounds/limits quote errors in the UB2 (Unified Buy V2) flow. Two improvements:
/v2/regions/providersendpoint), validate the entered amount locally and show an inline error immediately — skipping the slow quotes API round-trip entirely.TruncatedError.Changes:
selectedProvider.limits.fiatand validate against the entered amount before enabling the quote fetchgetProviderBuyLimit()utility for looking up min/max by fiat + payment method<Text>withTextColor.ErrorDefault(no modal, no info icon)QuoteError.errorfrom the quotes response for server-side limit errorsquoteFetchEnabledwhen the debounced amount violates known limitsChangelog
CHANGELOG entry: Fixed a bug where out-of-bounds amounts on the V2 Buy screen showed a generic error instead of the provider's minimum/maximum amount message. Added client-side limit validation to skip unnecessary quote API calls.
Related issues
Fixes: TRAM-3338
Related PRs (deploy in order):
Manual testing steps
Prerequisites: Enable UB2 via MM_RAMPS_UNIFIED_BUY_V2_ENABLED=true in .js.env
```gherkin
Feature: V2 Buy flow amount limit error display
Scenario: User enters amount below provider minimum
Given user is on the V2 Buy amount input screen
When user enters an amount below the provider's minimum limit
Then the provider's error message is displayed inline
And the Continue button is disabled
And no quote API call is made
Scenario: User enters amount above provider maximum
Given user is on the V2 Buy amount input screen
When user enters an amount above the provider's maximum limit
Then the provider's error message is displayed inline
And the Continue button is disabled
And no quote API call is made
Scenario: Provider returns error without client-side limits
Given user is on the V2 Buy amount input screen
And the provider does not have limits data
When the quotes API returns a provider error
Then the provider's specific error message is displayed as inline text
And the change provider option is hidden
Scenario: Provider returns error without message
Given user is on the V2 Buy amount input screen
When the provider returns an error without a specific message
Then the generic no-quotes fallback is shown with change provider option
```
Screenshots/Recordings
Before
https://www.loom.com/share/7aa20837afa84a2b9cbfc05547016196
After
https://www.loom.com/share/a95ca6fcc346470596d2dd43e9b6f754
Pre-merge author checklist
Pre-merge reviewer checklist
Note
Medium Risk
Changes quote-fetch gating and continue-button enablement in the Unified Buy V2 amount screen based on provider min/max limits and provider-returned quote errors, which could affect conversion/flow if edge cases are missed. Covered by added unit tests for limits lookup, hook behavior, and BuildQuote UI states.
Overview
Improves Unified Buy V2
BuildQuoteUX for out-of-bounds amounts by validating provider fiat buy limits client-side (min/max) and disabling quote fetching and Continue when the entered amount is invalid.When no quotes are returned, the screen now surfaces the provider’s specific error message inline as plain error text (no info icon/modal), while still falling back to a generic
TruncatedError(with change-provider option) when errors lack provider messages.Adds
getProviderBuyLimitanduseProviderLimits(with tests), new i18n strings for min/max purchase limits, bumps@metamask/ramps-controllerto^13.1.0, and includes small test-only refactors inSafeAreaViewWithHookTopInset.test.tsx.Reviewed by Cursor Bugbot for commit 58363b6. Bugbot is set up for automated code reviews on this repo. Configure here.