-
- {getReorderedCryptoCurrencies().map(currency => (
-
- ))}
-
-
+ <>
+
+
+ {getReorderedCryptoCurrencies().map(currency => (
+
+ ))}
+
+
+ {deposit_target === routes.cashier_onramp && (
+
+ )}
+ >
) : (
{
+ return (
+
+
+ {message}
+
+
+ );
+};
+
+export default AddCurrencyNote;
diff --git a/packages/core/src/App/Containers/RealAccountSignup/add-currency.jsx b/packages/core/src/App/Containers/RealAccountSignup/add-currency.jsx
index 90dc2109888f..cf18b3164730 100644
--- a/packages/core/src/App/Containers/RealAccountSignup/add-currency.jsx
+++ b/packages/core/src/App/Containers/RealAccountSignup/add-currency.jsx
@@ -8,6 +8,7 @@ import { localize } from '@deriv/translations';
import { isMobile, reorderCurrencies, routes } from '@deriv/shared';
import { CurrencyRadioButtonGroup, CurrencyRadioButton } from '@deriv/account';
import AddCryptoCurrency from './add-crypto-currency.jsx';
+import AddCurrencyNote from './add-currency-note.jsx';
import CurrencyProvider from './choose-currency';
import { observer, useStore } from '@deriv/stores';
import './currency-selector.scss';
@@ -202,11 +203,9 @@ const AddCurrency = observer(({ onSubmit, hasNoAvailableCrypto, is_add_crypto, i
-
-
- {localize('Some currencies may not be supported by payment agents in your country.')}
-
-
+
{
+ return legal_allowed_currencies.filter(({ platform }) => platform.ramp.length > 0);
+};
+
export default {
+ currenciesOnRampAvailability,
currenciesPaymentAgentAvailability,
};
diff --git a/packages/core/src/App/Containers/RealAccountSignup/choose-currency.jsx b/packages/core/src/App/Containers/RealAccountSignup/choose-currency.jsx
index 635f7151f384..8c534e237226 100644
--- a/packages/core/src/App/Containers/RealAccountSignup/choose-currency.jsx
+++ b/packages/core/src/App/Containers/RealAccountSignup/choose-currency.jsx
@@ -35,7 +35,7 @@ const ChooseCurrency = observer(() => {
return () => setShouldShowAllAvailableCurrencies(false);
}, [setShouldShowAllAvailableCurrencies]);
- const getReorderedCryptoCurrencies = React.useMemo(() => {
+ const memoized_reordered_crypto_currencies = React.useMemo(() => {
const hasAllCryptos = () => {
return (
legal_allowed_currencies?.filter(
@@ -49,33 +49,60 @@ const ChooseCurrency = observer(() => {
openRealAccountSignup(deposit_target === routes.cashier_pa ? 'add_currency' : 'add_crypto');
setShouldShowCancel(true);
};
-
const allowed_currencies_payment_agent_availability = CurrencyProvider.currenciesPaymentAgentAvailability(
legal_allowed_currencies,
all_payment_agent_list,
account_list
);
- const reorderCryptoCurrencies = should_show_all_available_currencies
- ? reorderCurrencies(
- allowed_currencies_payment_agent_availability?.filter(currency =>
- account_list.some(x => x.title === currency.value)
- ),
- CRYPTO_CURRENCY_TYPE
- )
- : reorderCurrencies(
- allowed_currencies_payment_agent_availability?.filter(
- currency =>
- currency.type === CRYPTO_CURRENCY_TYPE &&
- !available_crypto_currencies.some(x => x.value === currency.value)
- ),
- CRYPTO_CURRENCY_TYPE
- );
-
- const show_add_button = deposit_target === routes.cashier_pa ? !has_fiat || !hasAllCryptos() : !hasAllCryptos();
-
- if (show_add_button) {
- reorderCryptoCurrencies.push({
+ const allowed_currencies_onramp_availability =
+ CurrencyProvider.currenciesOnRampAvailability(legal_allowed_currencies);
+
+ const getReorderCryptoCurrencies = () => {
+ let currencies_to_filter;
+
+ if (deposit_target === routes.cashier_onramp) {
+ currencies_to_filter = allowed_currencies_onramp_availability;
+ } else if (should_show_all_available_currencies) {
+ currencies_to_filter = allowed_currencies_payment_agent_availability;
+ } else {
+ currencies_to_filter = allowed_currencies_payment_agent_availability?.filter(
+ currency =>
+ currency.type === CRYPTO_CURRENCY_TYPE &&
+ !available_crypto_currencies.some(x => x.value === currency.value)
+ );
+ }
+
+ const filtered_currencies = currencies_to_filter?.filter(currency =>
+ account_list.some(x => x.title === currency.value)
+ );
+
+ return reorderCurrencies(filtered_currencies, CRYPTO_CURRENCY_TYPE);
+ };
+
+ const shouldShowAddButton = () => {
+ switch (deposit_target) {
+ case routes.cashier_pa:
+ return !has_fiat || !hasAllCryptos();
+ case routes.cashier_onramp: {
+ const can_add_onramp_supported_crypto_account =
+ legal_allowed_currencies.filter(
+ currency =>
+ currency.type === CRYPTO_CURRENCY_TYPE &&
+ currency.platform.ramp.length > 0 &&
+ !account_list.some(x => x.title === currency.value)
+ ).length > 0;
+ return can_add_onramp_supported_crypto_account;
+ }
+ default:
+ return !hasAllCryptos();
+ }
+ };
+
+ const reordered_crypto_currencies = getReorderCryptoCurrencies();
+
+ if (shouldShowAddButton()) {
+ reordered_crypto_currencies.push({
value: 'plus',
name: deposit_target === routes.cashier_pa ? localize('Add a new') : localize('Add new'),
second_line_label:
@@ -86,7 +113,7 @@ const ChooseCurrency = observer(() => {
});
}
- return reorderCryptoCurrencies;
+ return reordered_crypto_currencies;
}, [
account_list,
all_payment_agent_list,
@@ -140,9 +167,9 @@ const ChooseCurrency = observer(() => {
- {getReorderedCryptoCurrencies.map(currency => (
+ {memoized_reordered_crypto_currencies.map(currency => (
!values.includes(acc.value) && acc.type === 'crypto');
}
+ get available_onramp_currencies() {
+ return Object.entries(this.website_status?.currencies_config).reduce((currencies, [currency, values]) => {
+ if (values.platform.ramp.length > 0) {
+ currencies.push(currency);
+ }
+ return currencies;
+ }, []);
+ }
+
get has_fiat() {
return Object.values(this.accounts).some(
item =>
diff --git a/packages/hooks/src/__tests__/useOnrampVisible.spec.tsx b/packages/hooks/src/__tests__/useOnrampVisible.spec.tsx
index d5468f039237..47c5087790d2 100644
--- a/packages/hooks/src/__tests__/useOnrampVisible.spec.tsx
+++ b/packages/hooks/src/__tests__/useOnrampVisible.spec.tsx
@@ -4,10 +4,19 @@ import { renderHook } from '@testing-library/react-hooks';
import useOnrampVisible from '../useOnrampVisible';
describe('useOnrampVisible', () => {
- test("should return false if client's currency is not crypto", () => {
+ test('returns false if onramp is not available for current currency', () => {
const mock = mockStore({
client: {
- is_crypto: jest.fn(() => false),
+ currency: 'USD',
+ is_virtual: false,
+ website_status: {
+ currencies_config: {
+ //@ts-expect-error we only need partial values
+ USD: { platform: { cashier: ['doughflow'], ramp: [] } },
+ //@ts-expect-error we only need partial values
+ BTC: { platform: { cashier: ['crypto'], ramp: ['ramp'] } },
+ },
+ },
},
});
@@ -20,11 +29,19 @@ describe('useOnrampVisible', () => {
expect(result.current).toBe(false);
});
- test("should return false if client's currency is crypto but client is virtual", () => {
+ test("returns false if client's account is virtual", () => {
const mock = mockStore({
client: {
- is_crypto: jest.fn(() => true),
+ currency: 'USD',
is_virtual: true,
+ website_status: {
+ currencies_config: {
+ //@ts-expect-error we only need partial values
+ USD: { platform: { cashier: ['doughflow'], ramp: [] } },
+ //@ts-expect-error we only need partial values
+ BTC: { platform: { cashier: ['crypto'], ramp: ['ramp'] } },
+ },
+ },
},
});
@@ -37,11 +54,19 @@ describe('useOnrampVisible', () => {
expect(result.current).toBe(false);
});
- test("should return true if client's currency is crypto and client is not virtual", () => {
+ test("returns true if onramp is available for current currency and client's account is not virtual", () => {
const mock = mockStore({
client: {
- is_crypto: jest.fn(() => true),
+ currency: 'BTC',
is_virtual: false,
+ website_status: {
+ currencies_config: {
+ //@ts-expect-error we only need partial values
+ USD: { platform: { cashier: ['doughflow'], ramp: [] } },
+ //@ts-expect-error we only need partial values
+ BTC: { platform: { cashier: ['crypto'], ramp: ['ramp'] } },
+ },
+ },
},
});
diff --git a/packages/hooks/src/useOnrampVisible.ts b/packages/hooks/src/useOnrampVisible.ts
index 57763c4319ea..47af250021a8 100644
--- a/packages/hooks/src/useOnrampVisible.ts
+++ b/packages/hooks/src/useOnrampVisible.ts
@@ -2,8 +2,10 @@ import { useStore } from '@deriv/stores';
const useOnrampVisible = () => {
const { client } = useStore();
- const { is_virtual, is_crypto } = client;
- const is_onramp_visible = !is_virtual && is_crypto();
+ const { website_status, currency, is_virtual } = client;
+
+ //@ts-expect-error need to update `@deriv/api-types` library to the latest version
+ const is_onramp_visible = !is_virtual && website_status?.currencies_config?.[currency].platform.ramp.length > 0;
return is_onramp_visible;
};
diff --git a/packages/stores/src/mockStore.ts b/packages/stores/src/mockStore.ts
index a7a21d8df939..74a520842b50 100644
--- a/packages/stores/src/mockStore.ts
+++ b/packages/stores/src/mockStore.ts
@@ -249,8 +249,9 @@ const mock = (): TStores & { is_mock: boolean } => {
demo: false,
},
dxtrade_accounts_list_error: null,
+ //@ts-expect-error we only need partial values
website_status: {
- dx_trade_status: {
+ dxtrade_status: {
all: 0,
demo: 0,
real: 0,
diff --git a/packages/stores/types.ts b/packages/stores/types.ts
index 7e354dd727ac..20a32f8bf7e8 100644
--- a/packages/stores/types.ts
+++ b/packages/stores/types.ts
@@ -416,6 +416,7 @@ export type TClientStore = {
account_status: Omit &
Partial> & { p2p_poa_required: number };
available_crypto_currencies: Array;
+ available_onramp_currencies: Array;
balance?: string | number;
can_change_fiat_currency: boolean;
clients_country: string;
@@ -527,7 +528,7 @@ export type TClientStore = {
trading_platform_dxtrade_password_reset: string;
trading_platform_mt5_password_reset: string;
};
- website_status: { mt5_status: TMt5StatusServer; dx_trade_status: TDXTraderStatusServerType };
+ website_status: WebsiteStatus;
email: string;
setVerificationCode: (code: string, action: string) => void;
updateAccountStatus: () => Promise;
diff --git a/packages/wallets/src/features/cashier/WalletCashier.scss b/packages/wallets/src/features/cashier/WalletCashier.scss
index 3ffd9b9c10cc..07a43d278585 100644
--- a/packages/wallets/src/features/cashier/WalletCashier.scss
+++ b/packages/wallets/src/features/cashier/WalletCashier.scss
@@ -9,12 +9,15 @@
}
.wallets-cashier-content {
+ width: 100%;
+ max-width: 128rem;
display: flex;
position: relative;
justify-content: center;
gap: 2.4rem;
flex: 1;
padding: 4.8rem 1.6rem 0;
+ margin: 0 auto;
background-color: #ffffff;
overflow: scroll;
//prevent content bouncing on scroll on iPhone devices
diff --git a/packages/wallets/src/features/cashier/flows/WalletFiatOnRamp/WalletFiatOnRamp.tsx b/packages/wallets/src/features/cashier/flows/WalletFiatOnRamp/WalletFiatOnRamp.tsx
index 1afaceddbe06..14273f064223 100644
--- a/packages/wallets/src/features/cashier/flows/WalletFiatOnRamp/WalletFiatOnRamp.tsx
+++ b/packages/wallets/src/features/cashier/flows/WalletFiatOnRamp/WalletFiatOnRamp.tsx
@@ -1,20 +1,18 @@
-import React, { useEffect, useMemo } from 'react';
+import React, { useEffect } from 'react';
import { useHistory } from 'react-router-dom';
import { useActiveWalletAccount } from '@deriv/api-v2';
import { FiatOnRampModule } from '../../modules';
const WalletFiatOnRamp = () => {
- const { data } = useActiveWalletAccount();
+ const { data: activeWallet } = useActiveWalletAccount();
const history = useHistory();
- const isCrypto = useMemo(() => {
- return data?.currency_config ? data.currency_config.is_crypto : true;
- }, [data?.currency_config]);
+ const isOnrampAvailable = activeWallet?.currency_config && activeWallet.currency_config.platform.ramp.length > 0;
useEffect(() => {
- if (!isCrypto) {
+ if (!isOnrampAvailable) {
history.push('/wallet/deposit');
}
- }, [history, isCrypto]);
+ }, [history, isOnrampAvailable]);
return ;
};
diff --git a/packages/wallets/src/features/cashier/flows/WalletFiatOnRamp/__tests__/WalletFiatOnRamp.spec.tsx b/packages/wallets/src/features/cashier/flows/WalletFiatOnRamp/__tests__/WalletFiatOnRamp.spec.tsx
index d30c333a7e1f..53aeaa86c653 100644
--- a/packages/wallets/src/features/cashier/flows/WalletFiatOnRamp/__tests__/WalletFiatOnRamp.spec.tsx
+++ b/packages/wallets/src/features/cashier/flows/WalletFiatOnRamp/__tests__/WalletFiatOnRamp.spec.tsx
@@ -29,11 +29,14 @@ describe('WalletFiatOnRamp', () => {
jest.clearAllMocks();
});
- it('should redirect to /wallet/deposit when isCrypto is false', () => {
+ it('redirects to /wallet/deposit if onramp is not available for current currency', () => {
mockUseActiveWalletAccount.mockReturnValue({
data: {
currency_config: {
- is_crypto: false,
+ platform: {
+ cashier: ['doughflow'],
+ ramp: [],
+ },
},
},
});
@@ -46,11 +49,14 @@ describe('WalletFiatOnRamp', () => {
expect(pushMock).toHaveBeenCalledWith('/wallet/deposit');
});
- it('should render FiatOnRampModule when isCrypto is true', () => {
+ it('renders FiatOnRampModule when if onramp is available for current currency', () => {
mockUseActiveWalletAccount.mockReturnValue({
data: {
currency_config: {
- is_crypto: true,
+ platform: {
+ cashier: ['crypto'],
+ ramp: ['ramp'],
+ },
},
},
});
diff --git a/packages/wallets/src/features/cashier/modules/DepositCrypto/DepositCrypto.tsx b/packages/wallets/src/features/cashier/modules/DepositCrypto/DepositCrypto.tsx
index 57e18f4ec007..b3e5c01d53c4 100644
--- a/packages/wallets/src/features/cashier/modules/DepositCrypto/DepositCrypto.tsx
+++ b/packages/wallets/src/features/cashier/modules/DepositCrypto/DepositCrypto.tsx
@@ -1,6 +1,6 @@
import React from 'react';
import { useActiveWalletAccount, useCurrencyConfig, useDepositCryptoAddress } from '@deriv/api-v2';
-import { Divider, Loader } from '@deriv-com/ui';
+import { Divider, Loader, useDevice } from '@deriv-com/ui';
import { isServerError } from '../../../../utils/utils';
import { DepositErrorScreen } from '../../screens';
import { TransactionStatus } from '../TransactionStatus';
@@ -15,9 +15,11 @@ const DepositCrypto = () => {
const { data: depositCryptoAddress, error, isLoading } = useDepositCryptoAddress();
const { data: activeWallet } = useActiveWalletAccount();
const { getConfig } = useCurrencyConfig();
+ const { isDesktop } = useDevice();
const depositCryptoError = error?.error;
const isTUSDT = activeWallet?.currency && getConfig(activeWallet.currency)?.is_tUSDT;
+ const isOnrampAvailable = activeWallet?.currency_config && activeWallet.currency_config.platform.ramp.length > 0;
if (isLoading) return ;
@@ -33,8 +35,8 @@ const DepositCrypto = () => {
-
-
+ {(!isDesktop || isOnrampAvailable) && }
+ {isOnrampAvailable && }