Skip to content

Commit 32415ad

Browse files
fix(ramps): consolidate terminal order status checks behind controller export
TRAM-3703: Export TERMINAL_ORDER_STATUSES and isTerminalOrderStatus from @metamask/ramps-controller via a yarn patch until the upstream core release lands. Replace four hand-rolled terminal-status sets in OrderContent, BankDetails, useFiatOrderStatus, and ramps analytics with the shared predicate. BankDetails now treats IdExpired as terminal, matching the other call sites. Co-authored-by: Amitabh Aggarwal <amitabh94@users.noreply.github.com>
1 parent 955fd0a commit 32415ad

8 files changed

Lines changed: 156 additions & 42 deletions

File tree

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
diff --git a/dist/index.cjs b/dist/index.cjs
2+
index 40aae3dc544edbdbf492eaf3b513eb21c2919ab2..1aee8cdb6e1a4990feeaa18957dd6f7bf5b0e31e 100644
3+
--- a/dist/index.cjs
4+
+++ b/dist/index.cjs
5+
@@ -49,4 +49,7 @@ Object.defineProperty(exports, "TransakOrderIdTransformer", { enumerable: true,
6+
var transakApiErrorUtils_1 = require("./transakApiErrorUtils.cjs");
7+
Object.defineProperty(exports, "getTransakApiMessage", { enumerable: true, get: function () { return transakApiErrorUtils_1.getTransakApiMessage; } });
8+
Object.defineProperty(exports, "isTransakPhoneRegisteredError", { enumerable: true, get: function () { return transakApiErrorUtils_1.isTransakPhoneRegisteredError; } });
9+
+var orderStatus_1 = require("./orderStatus.cjs");
10+
+Object.defineProperty(exports, "TERMINAL_ORDER_STATUSES", { enumerable: true, get: function () { return orderStatus_1.TERMINAL_ORDER_STATUSES; } });
11+
+Object.defineProperty(exports, "isTerminalOrderStatus", { enumerable: true, get: function () { return orderStatus_1.isTerminalOrderStatus; } });
12+
//# sourceMappingURL=index.cjs.map
13+
\ No newline at end of file
14+
diff --git a/dist/index.d.cts b/dist/index.d.cts
15+
index 965895c55dad8fc609ae5eb84df09cc22f6b5057..032116e5d0e923e621bec8f89092c9ebb2c290b7 100644
16+
--- a/dist/index.d.cts
17+
+++ b/dist/index.d.cts
18+
@@ -19,5 +19,6 @@ export { getErrorMessage, extractExplicitTypedError, normalizeToTypedError, } fr
19+
export type { TransakServiceActions, TransakServiceEvents, TransakServiceMessenger, TransakAccessToken, TransakUserDetails, TransakUserDetailsAddress, TransakUserDetailsKycDetails, TransakBuyQuote, TransakKycRequirement, TransakAdditionalRequirement, TransakAdditionalRequirementsResponse, TransakOttResponse, TransakOrderPaymentMethod, TransakDepositOrder, TransakDepositNetwork, TransakDepositCryptoCurrency, TransakDepositPaymentMethod, TransakDepositRegion, TransakOrder, TransakQuoteTranslation, TransakTranslationRequest, TransakUserLimits, TransakIdProofStatus, PatchUserRequestBody as TransakPatchUserRequestBody, } from "./TransakService.cjs";
20+
export { TransakApiError, TransakService, TransakEnvironment, TransakOrderIdTransformer, } from "./TransakService.cjs";
21+
export { getTransakApiMessage, isTransakPhoneRegisteredError, } from "./transakApiErrorUtils.cjs";
22+
+export { TERMINAL_ORDER_STATUSES, isTerminalOrderStatus, } from "./orderStatus.cjs";
23+
export type { TransakServiceMethodActions, TransakServiceSendUserOtpAction, TransakServiceVerifyUserOtpAction, TransakServiceGetUserDetailsAction, TransakServiceGetBuyQuoteAction, TransakServiceGetKycRequirementAction, TransakServiceCreateOrderAction, TransakServiceGetOrderAction, TransakServiceRequestOttAction, TransakServiceGeneratePaymentWidgetUrlAction, } from "./TransakService-method-action-types.cjs";
24+
//# sourceMappingURL=index.d.cts.map
25+
\ No newline at end of file
26+
diff --git a/dist/index.d.mts b/dist/index.d.mts
27+
index ccb7079fb66a3a2c5c02d70c2d9e781ed8f0c7a8..e462cb8b6570e98c8524a68f99613f912b1592e2 100644
28+
--- a/dist/index.d.mts
29+
+++ b/dist/index.d.mts
30+
@@ -19,5 +19,6 @@ export { getErrorMessage, extractExplicitTypedError, normalizeToTypedError, } fr
31+
export type { TransakServiceActions, TransakServiceEvents, TransakServiceMessenger, TransakAccessToken, TransakUserDetails, TransakUserDetailsAddress, TransakUserDetailsKycDetails, TransakBuyQuote, TransakKycRequirement, TransakAdditionalRequirement, TransakAdditionalRequirementsResponse, TransakOttResponse, TransakOrderPaymentMethod, TransakDepositOrder, TransakDepositNetwork, TransakDepositCryptoCurrency, TransakDepositPaymentMethod, TransakDepositRegion, TransakOrder, TransakQuoteTranslation, TransakTranslationRequest, TransakUserLimits, TransakIdProofStatus, PatchUserRequestBody as TransakPatchUserRequestBody, } from "./TransakService.mjs";
32+
export { TransakApiError, TransakService, TransakEnvironment, TransakOrderIdTransformer, } from "./TransakService.mjs";
33+
export { getTransakApiMessage, isTransakPhoneRegisteredError, } from "./transakApiErrorUtils.mjs";
34+
+export { TERMINAL_ORDER_STATUSES, isTerminalOrderStatus, } from "./orderStatus.mjs";
35+
export type { TransakServiceMethodActions, TransakServiceSendUserOtpAction, TransakServiceVerifyUserOtpAction, TransakServiceGetUserDetailsAction, TransakServiceGetBuyQuoteAction, TransakServiceGetKycRequirementAction, TransakServiceCreateOrderAction, TransakServiceGetOrderAction, TransakServiceRequestOttAction, TransakServiceGeneratePaymentWidgetUrlAction, } from "./TransakService-method-action-types.mjs";
36+
//# sourceMappingURL=index.d.mts.map
37+
\ No newline at end of file
38+
diff --git a/dist/index.mjs b/dist/index.mjs
39+
index 8c74256d67dee57e5bcea0857f9aa1924a1907a6..f15dce8e89377d849e8816afabf3018eb20253eb 100644
40+
--- a/dist/index.mjs
41+
+++ b/dist/index.mjs
42+
@@ -9,4 +9,5 @@ export { isExternalBrowserQuote, isCustomActionQuote, isInAppOnlyQuote } from ".
43+
export { getErrorMessage, extractExplicitTypedError, normalizeToTypedError } from "./errorNormalization.mjs";
44+
export { TransakApiError, TransakService, TransakEnvironment, TransakOrderIdTransformer } from "./TransakService.mjs";
45+
export { getTransakApiMessage, isTransakPhoneRegisteredError } from "./transakApiErrorUtils.mjs";
46+
+export { TERMINAL_ORDER_STATUSES, isTerminalOrderStatus } from "./orderStatus.mjs";
47+
//# sourceMappingURL=index.mjs.map
48+
\ No newline at end of file
49+
diff --git a/dist/orderStatus.cjs b/dist/orderStatus.cjs
50+
new file mode 100644
51+
index 0000000000000000000000000000000000000000..72d0819672e92fe9e4934fe63644e7b179a7e643
52+
--- /dev/null
53+
+++ b/dist/orderStatus.cjs
54+
@@ -0,0 +1,14 @@
55+
+"use strict";
56+
+Object.defineProperty(exports, "__esModule", { value: true });
57+
+exports.isTerminalOrderStatus = exports.TERMINAL_ORDER_STATUSES = void 0;
58+
+const RampsService_1 = require("./RampsService.cjs");
59+
+exports.TERMINAL_ORDER_STATUSES = new Set([
60+
+ RampsService_1.RampsOrderStatus.Completed,
61+
+ RampsService_1.RampsOrderStatus.Failed,
62+
+ RampsService_1.RampsOrderStatus.Cancelled,
63+
+ RampsService_1.RampsOrderStatus.IdExpired,
64+
+]);
65+
+function isTerminalOrderStatus(status) {
66+
+ return exports.TERMINAL_ORDER_STATUSES.has(status);
67+
+}
68+
+exports.isTerminalOrderStatus = isTerminalOrderStatus;
69+
diff --git a/dist/orderStatus.d.cts b/dist/orderStatus.d.cts
70+
new file mode 100644
71+
index 0000000000000000000000000000000000000000..167fa02f3f9dd1fc464e3b2ba507e210a970117b
72+
--- /dev/null
73+
+++ b/dist/orderStatus.d.cts
74+
@@ -0,0 +1,7 @@
75+
+import type { RampsOrderStatus } from "./RampsService.cjs";
76+
+
77+
+export declare const TERMINAL_ORDER_STATUSES: ReadonlySet<RampsOrderStatus>;
78+
+
79+
+export declare function isTerminalOrderStatus(
80+
+ status: RampsOrderStatus,
81+
+): boolean;
82+
diff --git a/dist/orderStatus.d.mts b/dist/orderStatus.d.mts
83+
new file mode 100644
84+
index 0000000000000000000000000000000000000000..1db214f23ff516d326b6e0d40099c03c72435951
85+
--- /dev/null
86+
+++ b/dist/orderStatus.d.mts
87+
@@ -0,0 +1,7 @@
88+
+import type { RampsOrderStatus } from "./RampsService.mjs";
89+
+
90+
+export declare const TERMINAL_ORDER_STATUSES: ReadonlySet<RampsOrderStatus>;
91+
+
92+
+export declare function isTerminalOrderStatus(
93+
+ status: RampsOrderStatus,
94+
+): boolean;
95+
diff --git a/dist/orderStatus.mjs b/dist/orderStatus.mjs
96+
new file mode 100644
97+
index 0000000000000000000000000000000000000000..b70f2eeeb3542573642f090e3a01f246bc0bda72
98+
--- /dev/null
99+
+++ b/dist/orderStatus.mjs
100+
@@ -0,0 +1,12 @@
101+
+import { RampsOrderStatus } from "./RampsService.mjs";
102+
+
103+
+export const TERMINAL_ORDER_STATUSES = new Set([
104+
+ RampsOrderStatus.Completed,
105+
+ RampsOrderStatus.Failed,
106+
+ RampsOrderStatus.Cancelled,
107+
+ RampsOrderStatus.IdExpired,
108+
+]);
109+
+
110+
+export function isTerminalOrderStatus(status) {
111+
+ return TERMINAL_ORDER_STATUSES.has(status);
112+
+}

app/components/UI/Ramp/Views/NativeFlow/BankDetails.test.tsx

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -470,6 +470,19 @@ describe('V2BankDetails', () => {
470470
});
471471
});
472472

473+
it('replaces current screen with RAMPS_ORDER_DETAILS when order status is ID_EXPIRED', () => {
474+
mockGetOrderById.mockReturnValue(
475+
createMockV2Order({ status: 'ID_EXPIRED' as RampsOrder['status'] }),
476+
);
477+
478+
renderWithTheme(<V2BankDetails />);
479+
480+
expect(mockReplace).toHaveBeenCalledWith('RampsOrderDetails', {
481+
orderId: 'test-order-id',
482+
showCloseButton: true,
483+
});
484+
});
485+
473486
it('replaces current screen with RAMPS_ORDER_DETAILS when order status is PENDING', () => {
474487
mockGetOrderById.mockReturnValue(
475488
createMockV2Order({ status: 'PENDING' as RampsOrder['status'] }),

app/components/UI/Ramp/Views/NativeFlow/BankDetails.tsx

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import BankDetailRow from '../../components/BankDetailRow';
2626
import {
2727
RampsOrderStatus,
2828
type TransakDepositOrder,
29+
isTerminalOrderStatus,
2930
} from '@metamask/ramps-controller';
3031
import { useTheme } from '../../../../../util/theme';
3132
import PrivacySection from '../../components/PrivacySection';
@@ -46,12 +47,6 @@ export interface BankDetailsParams {
4647
shouldUpdate?: boolean;
4748
}
4849

49-
const TERMINAL_STATUSES = new Set([
50-
RampsOrderStatus.Completed,
51-
RampsOrderStatus.Failed,
52-
RampsOrderStatus.Cancelled,
53-
]);
54-
5550
/**
5651
* V2 bank details screen. Reads order lifecycle from controller state
5752
* and fetches deposit-specific data (paymentDetails) from TransakService.
@@ -141,7 +136,7 @@ const V2BankDetails = () => {
141136
useEffect(() => {
142137
if (!order?.status) return;
143138
if (
144-
TERMINAL_STATUSES.has(order.status) ||
139+
isTerminalOrderStatus(order.status) ||
145140
order.status === RampsOrderStatus.Pending
146141
) {
147142
// @ts-expect-error navigation prop mismatch

app/components/UI/Ramp/Views/OrderDetails/OrderContent.tsx

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,11 @@ import { StyleSheet, TouchableOpacity } from 'react-native';
33
import InAppBrowser from 'react-native-inappbrowser-reborn';
44
import Clipboard from '@react-native-clipboard/clipboard';
55
import { useNavigation } from '@react-navigation/native';
6-
import { type RampsOrder, RampsOrderStatus } from '@metamask/ramps-controller';
6+
import {
7+
type RampsOrder,
8+
RampsOrderStatus,
9+
isTerminalOrderStatus,
10+
} from '@metamask/ramps-controller';
711
import { useAnalytics } from '../../../../hooks/useAnalytics/useAnalytics';
812
import { MetaMetricsEvents } from '../../../../../core/Analytics';
913
import { createProcessingInfoModalNavigationDetails } from '../Modals/ProcessingInfoModal/ProcessingInfoModal';
@@ -39,12 +43,6 @@ import Routes from '../../../../../constants/navigation/Routes';
3943
import { RampsOrderDetailsSelectorsIDs } from './OrderDetails.testIds';
4044

4145
const AMOUNT_PLACEHOLDER = '...';
42-
const TERMINAL_STATUSES = new Set([
43-
RampsOrderStatus.Completed,
44-
RampsOrderStatus.Failed,
45-
RampsOrderStatus.Cancelled,
46-
RampsOrderStatus.IdExpired,
47-
]);
4846

4947
const localStyles = StyleSheet.create({
5048
badgeWrapperCenter: {
@@ -190,7 +188,7 @@ const OrderContent: React.FC<OrderContentProps> = ({
190188
((order.fiatAmount != null && Number(order.fiatAmount) > 0) ||
191189
(order.cryptoAmount != null && Number(order.cryptoAmount) > 0)),
192190
);
193-
const isTerminal = TERMINAL_STATUSES.has(order.status);
191+
const isTerminal = isTerminalOrderStatus(order.status);
194192
const isLoading = !hasAmounts && !isTerminal;
195193

196194
const handleClose = useCallback(() => {

app/components/Views/confirmations/hooks/activity/useFiatOrderStatus.ts

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,12 @@
11
import { useEffect, useRef, useState } from 'react';
22
import { TransactionStatus } from '@metamask/transaction-controller';
3-
import { RampsOrderStatus } from '@metamask/ramps-controller';
3+
import { RampsOrderStatus, isTerminalOrderStatus } from '@metamask/ramps-controller';
44

55
import Engine from '../../../../../core/Engine';
66
import type { Severity } from '../../components/status-icon';
77

88
const POLL_INTERVAL_MS = 5000;
99

10-
const TERMINAL_STATUSES = new Set([
11-
RampsOrderStatus.Completed,
12-
RampsOrderStatus.Failed,
13-
RampsOrderStatus.Cancelled,
14-
RampsOrderStatus.IdExpired,
15-
]);
16-
1710
export interface FiatOrderStatusResult {
1811
severity: Severity;
1912
statusText: string;
@@ -52,7 +45,7 @@ export function useFiatOrderStatus(
5245
setCryptoSymbol(order.cryptoCurrency?.symbol);
5346
setPaymentMethodName(order.paymentMethod?.name);
5447

55-
if (TERMINAL_STATUSES.has(order.status)) {
48+
if (isTerminalOrderStatus(order.status)) {
5649
clearInterval(intervalRef.current);
5750
}
5851
})

app/core/Engine/controllers/ramps-controller/event-handlers/analytics.ts

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import {
22
type RampsOrder,
33
type RampsOrderStatus,
44
RampsOrderStatus as Status,
5+
isTerminalOrderStatus,
56
} from '@metamask/ramps-controller';
67
import { MetaMetricsEvents } from '../../../../Analytics';
78
import { AnalyticsEventBuilder } from '../../../../../util/analytics/AnalyticsEventBuilder';
@@ -21,18 +22,6 @@ import {
2122
// `useAnalytics` without importing the hook.
2223
import type { AnalyticsEvents } from '../../../../../components/UI/Ramp/types/depositAnalytics';
2324

24-
/**
25-
* Terminal order statuses. `@metamask/ramps-controller` keeps its
26-
* `TERMINAL_ORDER_STATUSES` internal, so mirror it here from the exported
27-
* `RampsOrderStatus` enum. Kept in lockstep with the controller's set.
28-
*/
29-
const TERMINAL_ORDER_STATUSES = new Set<RampsOrderStatus>([
30-
Status.Completed,
31-
Status.Failed,
32-
Status.Cancelled,
33-
Status.IdExpired,
34-
]);
35-
3625
/**
3726
* Builds the `RAMPS_TRANSACTION_FAILED` payload for a headless order. Mirrors
3827
* the headless `RAMPS_TRANSACTION_CONFIRMED` payload emitted by
@@ -191,7 +180,7 @@ export function handleOrderStatusChangedForMetrics({
191180
// subscription and the direct callback emit (`emitTerminalOrderAnalyticsFromCallback`),
192181
// so the two paths cannot double-emit regardless of arrival order.
193182
if (
194-
TERMINAL_ORDER_STATUSES.has(order.status) &&
183+
isTerminalOrderStatus(order.status) &&
195184
hasEmittedTerminalOrderAnalytics(order)
196185
) {
197186
return;
@@ -293,7 +282,7 @@ export function handleOrderStatusChangedForMetrics({
293282
export function emitTerminalOrderAnalyticsFromCallback(
294283
order: RampsOrder,
295284
): void {
296-
if (!TERMINAL_ORDER_STATUSES.has(order.status)) {
285+
if (!isTerminalOrderStatus(order.status)) {
297286
return;
298287
}
299288
try {

package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,8 @@
236236
"@metamask/assets-controllers@npm:^109.2.1": "patch:@metamask/assets-controllers@npm%3A109.4.0#~/.yarn/patches/@metamask-assets-controllers-npm-109.4.0-25a362106e.patch",
237237
"@metamask/assets-controllers@npm:^109.3.0": "patch:@metamask/assets-controllers@npm%3A109.4.0#~/.yarn/patches/@metamask-assets-controllers-npm-109.4.0-25a362106e.patch",
238238
"@metamask/assets-controllers@npm:^109.4.0": "patch:@metamask/assets-controllers@npm%3A109.4.0#~/.yarn/patches/@metamask-assets-controllers-npm-109.4.0-25a362106e.patch",
239-
"@metamask/network-enablement-controller@npm:^5.4.1": "patch:@metamask/network-enablement-controller@npm%3A5.4.1#~/.yarn/patches/@metamask-network-enablement-controller-npm-5.4.1-020a82a308.patch"
239+
"@metamask/network-enablement-controller@npm:^5.4.1": "patch:@metamask/network-enablement-controller@npm%3A5.4.1#~/.yarn/patches/@metamask-network-enablement-controller-npm-5.4.1-020a82a308.patch",
240+
"@metamask/ramps-controller@npm:^17.0.0": "patch:@metamask/ramps-controller@npm%3A17.0.0#~/.yarn/patches/@metamask-ramps-controller-npm-17.0.0-f649ad5caf.patch"
240241
},
241242
"dependencies": {
242243
"@braze/react-native-sdk": "patch:@braze/react-native-sdk@npm%3A19.1.0#~/.yarn/patches/@braze-react-native-sdk-npm-19.1.0-076-reactmoduleinfo.patch",
@@ -338,7 +339,7 @@
338339
"@metamask/preinstalled-example-snap": "^0.8.1",
339340
"@metamask/profile-metrics-controller": "^4.0.1",
340341
"@metamask/profile-sync-controller": "^28.3.0",
341-
"@metamask/ramps-controller": "^17.0.0",
342+
"@metamask/ramps-controller": "patch:@metamask/ramps-controller@npm%3A17.0.0#~/.yarn/patches/@metamask-ramps-controller-npm-17.0.0-f649ad5caf.patch",
342343
"@metamask/react-data-query": "^0.2.0",
343344
"@metamask/react-native-acm": "patch:@metamask/react-native-acm@npm%3A1.2.0#~/.yarn/patches/@metamask-react-native-acm-npm-1.2.0-944bf863eb.patch",
344345
"@metamask/react-native-actionsheet": "2.4.2",

yarn.lock

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9961,7 +9961,7 @@ __metadata:
99619961
languageName: node
99629962
linkType: hard
99639963

9964-
"@metamask/ramps-controller@npm:^17.0.0":
9964+
"@metamask/ramps-controller@npm:17.0.0":
99659965
version: 17.0.0
99669966
resolution: "@metamask/ramps-controller@npm:17.0.0"
99679967
dependencies:
@@ -9974,6 +9974,19 @@ __metadata:
99749974
languageName: node
99759975
linkType: hard
99769976

9977+
"@metamask/ramps-controller@patch:@metamask/ramps-controller@npm%3A17.0.0#~/.yarn/patches/@metamask-ramps-controller-npm-17.0.0-f649ad5caf.patch":
9978+
version: 17.0.0
9979+
resolution: "@metamask/ramps-controller@patch:@metamask/ramps-controller@npm%3A17.0.0#~/.yarn/patches/@metamask-ramps-controller-npm-17.0.0-f649ad5caf.patch::version=17.0.0&hash=bb4e84"
9980+
dependencies:
9981+
"@metamask/base-controller": "npm:^9.1.0"
9982+
"@metamask/controller-utils": "npm:^12.3.0"
9983+
"@metamask/messenger": "npm:^2.0.0"
9984+
"@metamask/profile-sync-controller": "npm:^28.3.0"
9985+
"@metamask/remote-feature-flag-controller": "npm:^4.2.2"
9986+
checksum: 10/ae12485de77ea07ee43db87254b11783e53db9e342386dfbff0b4db4423381bf9e3c8b9a54b382edca1fa9f591252b554155bcb7e7aaa3e9efceedec063870be
9987+
languageName: node
9988+
linkType: hard
9989+
99779990
"@metamask/react-data-query@npm:^0.2.0":
99789991
version: 0.2.0
99799992
resolution: "@metamask/react-data-query@npm:0.2.0"
@@ -35971,7 +35984,7 @@ __metadata:
3597135984
"@metamask/profile-metrics-controller": "npm:^4.0.1"
3597235985
"@metamask/profile-sync-controller": "npm:^28.3.0"
3597335986
"@metamask/providers": "npm:^18.3.1"
35974-
"@metamask/ramps-controller": "npm:^17.0.0"
35987+
"@metamask/ramps-controller": "patch:@metamask/ramps-controller@npm%3A17.0.0#~/.yarn/patches/@metamask-ramps-controller-npm-17.0.0-f649ad5caf.patch"
3597535988
"@metamask/react-data-query": "npm:^0.2.0"
3597635989
"@metamask/react-native-acm": "patch:@metamask/react-native-acm@npm%3A1.2.0#~/.yarn/patches/@metamask-react-native-acm-npm-1.2.0-944bf863eb.patch"
3597735990
"@metamask/react-native-actionsheet": "npm:2.4.2"

0 commit comments

Comments
 (0)