diff --git a/packages/ramps-controller/CHANGELOG.md b/packages/ramps-controller/CHANGELOG.md index 57f07c4838..6edd622bd0 100644 --- a/packages/ramps-controller/CHANGELOG.md +++ b/packages/ramps-controller/CHANGELOG.md @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Added + +- Export `getTransakApiMessage` and `isTransakPhoneRegisteredError` for consumers handling `TransakApiError`, and centralize known Transak API error codes in `transakErrorCodes.ts` ([#9135](https://github.com/MetaMask/core/pull/9135)) + ### Changed - Bump `@metamask/profile-sync-controller` from `^28.1.1` to `^28.2.0` ([#9119](https://github.com/MetaMask/core/pull/9119)) diff --git a/packages/ramps-controller/src/TransakService.ts b/packages/ramps-controller/src/TransakService.ts index a88e5b6c70..515cfb5581 100644 --- a/packages/ramps-controller/src/TransakService.ts +++ b/packages/ramps-controller/src/TransakService.ts @@ -5,6 +5,7 @@ import type { import { createServicePolicy, HttpError } from '@metamask/controller-utils'; import type { Messenger } from '@metamask/messenger'; +import { TRANSAK_ERROR_CODES } from './transakErrorCodes'; import type { TransakServiceMethodActions } from './TransakService-method-action-types'; // === TYPES === @@ -429,8 +430,6 @@ function getPaymentWidgetBaseUrl(environment: TransakEnvironment): string { // === TRANSAK API ERROR === -const TRANSAK_ORDER_EXISTS_CODE = '4005'; - export class TransakApiError extends HttpError { readonly errorCode: string | undefined; @@ -915,7 +914,7 @@ export class TransakService { if ( error instanceof TransakApiError && error.httpStatus === 409 && - error.errorCode === TRANSAK_ORDER_EXISTS_CODE + error.errorCode === TRANSAK_ERROR_CODES.ORDER_EXISTS ) { await this.cancelAllActiveOrders(); await new Promise((resolve) => diff --git a/packages/ramps-controller/src/index.ts b/packages/ramps-controller/src/index.ts index 7cc2d69e2a..84ab48769e 100644 --- a/packages/ramps-controller/src/index.ts +++ b/packages/ramps-controller/src/index.ts @@ -173,6 +173,10 @@ export { TransakEnvironment, TransakOrderIdTransformer, } from './TransakService'; +export { + getTransakApiMessage, + isTransakPhoneRegisteredError, +} from './transakApiErrorUtils'; export type { TransakServiceMethodActions, TransakServiceSendUserOtpAction, diff --git a/packages/ramps-controller/src/transakApiErrorUtils.test.ts b/packages/ramps-controller/src/transakApiErrorUtils.test.ts new file mode 100644 index 0000000000..418b88ea0a --- /dev/null +++ b/packages/ramps-controller/src/transakApiErrorUtils.test.ts @@ -0,0 +1,27 @@ +import { + getTransakApiMessage, + isTransakPhoneRegisteredError, +} from './transakApiErrorUtils'; +import { TRANSAK_ERROR_CODES } from './transakErrorCodes'; +import { TransakApiError } from './TransakService'; + +describe('transakApiErrorUtils', () => { + const phoneRegisteredError = new TransakApiError( + 400, + "Fetching 'https://api.transak.com/user' failed with status '400'", + TRANSAK_ERROR_CODES.PHONE_ALREADY_REGISTERED, + 'Phone registered with t***@test.com', + ); + + it('reads apiMessage from TransakApiError', () => { + expect(getTransakApiMessage(phoneRegisteredError)).toBe( + 'Phone registered with t***@test.com', + ); + expect(getTransakApiMessage(new Error('generic'))).toBeUndefined(); + }); + + it('detects phone already registered errors', () => { + expect(isTransakPhoneRegisteredError(phoneRegisteredError)).toBe(true); + expect(isTransakPhoneRegisteredError(new Error('generic'))).toBe(false); + }); +}); diff --git a/packages/ramps-controller/src/transakApiErrorUtils.ts b/packages/ramps-controller/src/transakApiErrorUtils.ts new file mode 100644 index 0000000000..dad971fc1e --- /dev/null +++ b/packages/ramps-controller/src/transakApiErrorUtils.ts @@ -0,0 +1,13 @@ +import { TRANSAK_ERROR_CODES } from './transakErrorCodes'; +import { TransakApiError } from './TransakService'; + +export function getTransakApiMessage(error: unknown): string | undefined { + return error instanceof TransakApiError ? error.apiMessage : undefined; +} + +export function isTransakPhoneRegisteredError(error: unknown): boolean { + return ( + error instanceof TransakApiError && + error.errorCode === TRANSAK_ERROR_CODES.PHONE_ALREADY_REGISTERED + ); +} diff --git a/packages/ramps-controller/src/transakErrorCodes.ts b/packages/ramps-controller/src/transakErrorCodes.ts new file mode 100644 index 0000000000..5b8b6d1436 --- /dev/null +++ b/packages/ramps-controller/src/transakErrorCodes.ts @@ -0,0 +1,13 @@ +/** + * Known Transak API error codes surfaced by {@link TransakApiError}. + * + * Values are normalized to strings because TransakService stringifies numeric + * codes when parsing API responses. + */ +export const TRANSAK_ERROR_CODES = { + ORDER_EXISTS: '4005', + PHONE_ALREADY_REGISTERED: '2020', +} as const; + +export type TransakErrorCode = + (typeof TRANSAK_ERROR_CODES)[keyof typeof TRANSAK_ERROR_CODES];