-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Expand file tree
/
Copy pathdeterminePreferredProvider.ts
More file actions
124 lines (111 loc) · 3.61 KB
/
Copy pathdeterminePreferredProvider.ts
File metadata and controls
124 lines (111 loc) · 3.61 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
import { Order } from '@consensys/on-ramp-sdk';
import {
type Provider,
type RampsOrder,
RampsOrderStatus,
} from '@metamask/ramps-controller';
import type { FiatOrder } from '../../../../reducers/fiatOrders/types';
import {
FIAT_ORDER_PROVIDERS,
FIAT_ORDER_STATES,
} from '../../../../constants/on-ramp';
import { rampIdsEqual } from './rampIdMatch';
/**
* Minimal representation of a completed order used for provider selection
* and "previously used" logic. Both FiatOrder and RampsOrder map into this.
*/
export interface CompletedOrderInfo {
providerId: string;
completedAt: number;
}
export function completedOrdersFromFiatOrders(
orders: FiatOrder[],
): CompletedOrderInfo[] {
return orders
.filter((order) => order.state === FIAT_ORDER_STATES.COMPLETED)
.reduce<CompletedOrderInfo[]>((acc, order) => {
let providerId: string | undefined;
if (
order.provider === FIAT_ORDER_PROVIDERS.AGGREGATOR ||
order.provider === FIAT_ORDER_PROVIDERS.RAMPS_V2
) {
const orderData =
order.provider === FIAT_ORDER_PROVIDERS.RAMPS_V2
? (order.data as RampsOrder)
: (order.data as Order);
providerId = orderData?.provider?.id;
} else if (
order.provider === FIAT_ORDER_PROVIDERS.DEPOSIT ||
order.provider === FIAT_ORDER_PROVIDERS.TRANSAK
) {
providerId = 'TRANSAK';
} else {
providerId = order.provider;
}
if (providerId) {
acc.push({ providerId, completedAt: order.createdAt });
}
return acc;
}, []);
}
export function completedOrdersFromRampsOrders(
orders: RampsOrder[],
): CompletedOrderInfo[] {
return orders
.filter((order) => order.status === RampsOrderStatus.Completed)
.reduce<CompletedOrderInfo[]>((acc, order) => {
const providerId = order.provider?.id;
if (providerId) {
acc.push({ providerId, completedAt: order.createdAt });
}
return acc;
}, []);
}
export interface PreferredProviderResult {
provider: Provider;
autoSelected: boolean;
}
/**
* Determines the preferred provider based on user's completed order history.
*
* Fallback order:
* 1. Provider from most recent completed order (autoSelected: false)
* 2. Transak (autoSelected: false)
* 3. null — no preselection; wait for the user to pick a token, then
* choose the first provider that supports it.
*
* @param completedOrders - Completed orders from any source (legacy + controller)
* @param availableProviders - Available providers from RampsController
* @returns The preferred provider with its selection source, or null if no
* providers are available or no signal exists to pick one.
*/
export function determinePreferredProvider(
completedOrders: CompletedOrderInfo[],
availableProviders: Provider[],
): PreferredProviderResult | null {
if (availableProviders.length === 0) {
return null;
}
if (completedOrders.length > 0) {
const [mostRecent] = [...completedOrders].sort(
(a, b) => b.completedAt - a.completedAt,
);
const foundProvider = availableProviders.find(
(provider) =>
rampIdsEqual(provider.id, mostRecent.providerId) ||
provider.name?.toLowerCase() === mostRecent.providerId.toLowerCase(),
);
if (foundProvider) {
return { provider: foundProvider, autoSelected: false };
}
}
const transakProvider = availableProviders.find(
(provider) =>
provider.id?.toLowerCase().includes('transak') ||
provider.name?.toLowerCase().includes('transak'),
);
if (transakProvider) {
return { provider: transakProvider, autoSelected: false };
}
return null;
}