feat(ramps-controller): add NeoBankService and wallet registration HTTP client - #10031
Conversation
Land the proxy HTTP client (autoramp, Pix, quotes, customer lookup, and self-hosted wallet registration) without controller state, and skip retries on mutating POSTs so a 5xx cannot duplicate creates without an idempotency key. Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
PR Review SummaryI've completed a thorough review of this PR. The implementation is well-structured and comprehensive, with excellent test coverage (99.7%). Here's my detailed assessment: ✅ Strengths
🔴 Critical Issue: Type Safety ProblemThere's a type safety bug in the function isRetryableError(error: unknown): boolean {
if (error instanceof HttpError) {
if (error.httpStatus === 429) {
return true;
}
return error.httpStatus < 400 || error.httpStatus >= 500;
}
return true;
}Problem: Lines 44 and 47 access Fix: The logic is actually correct, but needs restructuring: function isRetryableError(error: unknown): boolean {
if (error instanceof HttpError) {
return error.httpStatus === 429 ||
error.httpStatus < 400 ||
error.httpStatus >= 500;
}
return true;
}📝 Minor Observations
✅ Test QualityThe test suites are exemplary:
🎯 RecommendationFix the type safety issue in |
There was a problem hiding this comment.
Pull request overview
Adds a new neo-bank client surface to @metamask/ramps-controller, introducing a NeoBankService that targets the Ramp API’s neobank-proxy endpoints under /neobank, plus a dedicated wallet-registration HTTP client used for Money Account self-hosted wallet registration.
Changes:
- Add
NeoBankServicewith retry/no-retry policies (GET retries on 429/5xx/network; POST does not retry) and corresponding messenger action types. - Add
WalletRegistrationServiceto handle MoonPay/Iron customer lookup and self-hosted address registration/status reconciliation, plus typed errors. - Export new service/types via
src/index.tsand document the addition in the package changelog.
Reviewed changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated 3 comments.
Show a summary per file
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Wrap response-body read failures as lookup errors and restore test globals reliably so callers and test isolation retain their documented guarantees. Co-authored-by: Cursor <cursoragent@cursor.com>



Summary
NeoBankService(GET/POST under/neobank) andWalletRegistrationServicefor the neobank-proxy HTTP contract.TransakService), so a 5xx or network failure cannot duplicate a mutating request without anIdempotency-Key.id(malformedResponse). Snapshot types live inautoramp-types.tsonly — noRampsControllerchanges.Supersedes the client slice of #9930. Stacked follow-up: controller methods + last-seen cursor (no User Storage).
Test plan
yarn workspace @metamask/ramps-controller run testidthrowsmalformedResponseMade with Cursor