diff --git a/.changeset/tricky-dryers-check.md b/.changeset/tricky-dryers-check.md
new file mode 100644
index 000000000000..e0bc0c71ba1f
--- /dev/null
+++ b/.changeset/tricky-dryers-check.md
@@ -0,0 +1,7 @@
+---
+"@ledgerhq/types-live": minor
+"ledger-live-desktop": minor
+"@ledgerhq/live-common": minor
+---
+
+remove legacy swap code on LLD
diff --git a/apps/ledger-live-desktop/src/renderer/analytics/segment.ts b/apps/ledger-live-desktop/src/renderer/analytics/segment.ts
index 079074319398..a6acf0eb6ed2 100644
--- a/apps/ledger-live-desktop/src/renderer/analytics/segment.ts
+++ b/apps/ledger-live-desktop/src/renderer/analytics/segment.ts
@@ -99,16 +99,6 @@ const getPtxAttributes = () => {
const fetchAdditionalCoins = analyticsFeatureFlagMethod("fetchAdditionalCoins");
const stakingProviders = analyticsFeatureFlagMethod("ethStakingProviders");
const ptxCard = analyticsFeatureFlagMethod("ptxCard");
- const ptxSwapMoonpayProviderFlag = analyticsFeatureFlagMethod("ptxSwapMoonpayProvider");
-
- const ptxSwapLiveAppDemoZero = analyticsFeatureFlagMethod("ptxSwapLiveAppDemoZero")?.enabled;
- const ptxSwapLiveAppDemoOne = analyticsFeatureFlagMethod("ptxSwapLiveAppDemoOne")?.enabled;
- const ptxSwapLiveAppDemoThree = analyticsFeatureFlagMethod("ptxSwapLiveAppDemoThree")?.enabled;
- const ptxSwapExodusProvider = analyticsFeatureFlagMethod("ptxSwapExodusProvider")?.enabled;
- const ptxSwapCoreExperimentFlag = analyticsFeatureFlagMethod("ptxSwapCoreExperiment");
- const ptxSwapCoreExperiment = ptxSwapCoreExperimentFlag?.enabled
- ? ptxSwapCoreExperimentFlag?.params?.variant
- : undefined;
const isBatch1Enabled: boolean =
!!fetchAdditionalCoins?.enabled && fetchAdditionalCoins?.params?.batch === 1;
@@ -122,19 +112,13 @@ const getPtxAttributes = () => {
stakingProviders?.params?.listProvider?.length > 0
? stakingProviders?.params?.listProvider.length
: "flag not loaded";
- const ptxSwapMoonpayProviderEnabled: boolean = !!ptxSwapMoonpayProviderFlag?.enabled;
+
return {
isBatch1Enabled,
isBatch2Enabled,
isBatch3Enabled,
stakingProvidersEnabled,
ptxCard,
- ptxSwapMoonpayProviderEnabled,
- ptxSwapLiveAppDemoZero,
- ptxSwapLiveAppDemoOne,
- ptxSwapLiveAppDemoThree,
- ptxSwapCoreExperiment,
- ptxSwapExodusProvider,
};
};
diff --git a/apps/ledger-live-desktop/src/renderer/components/AnimatedCountdown.tsx b/apps/ledger-live-desktop/src/renderer/components/AnimatedCountdown.tsx
deleted file mode 100644
index 05e5714226a2..000000000000
--- a/apps/ledger-live-desktop/src/renderer/components/AnimatedCountdown.tsx
+++ /dev/null
@@ -1,37 +0,0 @@
-import React, { memo } from "react";
-import styled from "styled-components";
-
-const WrappedSvg = styled.svg`
- transform: rotate(-90deg);
- border-radius: 50%;
- background-clip: padding-box;
-`;
-
-type Props = {
- size: number;
- bgColor?: string;
- fillColor?: string;
- duration?: number;
-};
-const AnimatedCountdown = ({
- size = 10,
- bgColor = "#8A9199",
- fillColor = "white",
- duration = 60000,
-}: Props) => {
- return (
-
-
-
-
-
-
- );
-};
-export default memo(AnimatedCountdown);
diff --git a/apps/ledger-live-desktop/src/renderer/hooks/swap-migrations/useSwapLiveAppHook.tsx b/apps/ledger-live-desktop/src/renderer/hooks/swap-migrations/useSwapLiveAppHook.tsx
deleted file mode 100644
index 7fcc3a521cfe..000000000000
--- a/apps/ledger-live-desktop/src/renderer/hooks/swap-migrations/useSwapLiveAppHook.tsx
+++ /dev/null
@@ -1,108 +0,0 @@
-import { getFeesCurrency, getMainAccount } from "@ledgerhq/live-common/account/index";
-import { formatCurrencyUnit } from "@ledgerhq/live-common/currencies/index";
-import { SwapTransactionType } from "@ledgerhq/live-common/exchange/swap/types";
-import { getProviderName } from "@ledgerhq/live-common/exchange/swap/utils/index";
-import { accountToWalletAPIAccount } from "@ledgerhq/live-common/wallet-api/converters";
-import { getEnv } from "@ledgerhq/live-env";
-import BigNumber from "bignumber.js";
-import isEqual from "lodash/isEqual";
-import { useEffect, useMemo, useRef } from "react";
-import { useSelector } from "react-redux";
-import { rateSelector } from "~/renderer/actions/swap";
-import { walletSelector } from "~/renderer/reducers/wallet";
-import {
- SwapProps,
- SwapWebManifestIDs,
- SwapWebProps,
-} from "~/renderer/screens/exchange/Swap2/Form/SwapWebView";
-import { useMaybeAccountUnit } from "../useAccountUnit";
-
-export type UseSwapLiveAppHookProps = {
- manifestID?: string;
- isSwapLiveAppEnabled: boolean;
- swapTransaction: SwapTransactionType;
- swapError?: Error;
- updateSwapWebProps: React.Dispatch | undefined>>;
- getExchangeSDKParams: () => Partial;
- getProviderRedirectURLSearch: () => URLSearchParams;
-};
-
-const SWAP_API_BASE = getEnv("SWAP_API_BASE");
-
-export const useSwapLiveAppHook = (props: UseSwapLiveAppHookProps) => {
- const {
- isSwapLiveAppEnabled,
- manifestID,
- swapTransaction,
- swapError,
- updateSwapWebProps,
- getExchangeSDKParams,
- getProviderRedirectURLSearch,
- } = props;
- const exchangeRate = useSelector(rateSelector);
- const provider = exchangeRate?.provider;
- const exchangeRatesState = swapTransaction.swap?.rates;
- const swapWebPropsRef = useRef(undefined);
- const mainFromAccount =
- swapTransaction.swap.from.account &&
- getMainAccount(swapTransaction.swap.from.account, swapTransaction.swap.from.parentAccount);
- const estimatedFeesUnit = mainFromAccount && getFeesCurrency(mainFromAccount);
-
- const unit = useMaybeAccountUnit(mainFromAccount);
- const estimatedFees = useMemo(() => {
- return unit && BigNumber(formatCurrencyUnit(unit, swapTransaction.status.estimatedFees));
- }, [swapTransaction.status.estimatedFees, unit]);
-
- const walletState = useSelector(walletSelector);
-
- useEffect(() => {
- if (isSwapLiveAppEnabled) {
- const providerRedirectURLSearch = getProviderRedirectURLSearch();
- const { parentAccount: fromParentAccount } = swapTransaction.swap.from;
- const fromParentAccountId = fromParentAccount
- ? accountToWalletAPIAccount(walletState, fromParentAccount)?.id
- : undefined;
- const providerRedirectURL = `ledgerlive://discover/${getProviderName(
- provider ?? "",
- ).toLowerCase()}?${providerRedirectURLSearch.toString()}`;
-
- let loading = swapTransaction.bridgePending;
-
- if (manifestID === SwapWebManifestIDs.Demo0) {
- loading = swapTransaction.bridgePending || exchangeRatesState.status === "loading";
- }
-
- const newSwapWebProps = {
- provider,
- ...getExchangeSDKParams(),
- fromParentAccountId,
- error: !!swapError,
- loading,
- providerRedirectURL,
- swapApiBase: SWAP_API_BASE,
- estimatedFees: estimatedFees?.toString(),
- estimatedFeesUnit: estimatedFeesUnit?.id,
- };
-
- if (!isEqual(newSwapWebProps, swapWebPropsRef.current)) {
- swapWebPropsRef.current = newSwapWebProps;
- updateSwapWebProps(newSwapWebProps);
- }
- }
- }, [
- walletState,
- provider,
- manifestID,
- isSwapLiveAppEnabled,
- getExchangeSDKParams,
- getProviderRedirectURLSearch,
- swapTransaction.swap.from,
- swapTransaction.swap.from.amount,
- swapError,
- swapTransaction.bridgePending,
- exchangeRatesState.status,
- updateSwapWebProps,
- estimatedFees,
- estimatedFeesUnit?.id,
- ]);
-};
diff --git a/apps/ledger-live-desktop/src/renderer/icons/ArrowsUpDown.tsx b/apps/ledger-live-desktop/src/renderer/icons/ArrowsUpDown.tsx
deleted file mode 100644
index 5a1959946298..000000000000
--- a/apps/ledger-live-desktop/src/renderer/icons/ArrowsUpDown.tsx
+++ /dev/null
@@ -1,16 +0,0 @@
-import React from "react";
-const ArrowsUpDown = ({ size = 16, color = "currentColor" }: { size: number; color?: string }) => (
-
-);
-export default ArrowsUpDown;
diff --git a/apps/ledger-live-desktop/src/renderer/modals/Platform/Exchange/CompleteExchange/Body.tsx b/apps/ledger-live-desktop/src/renderer/modals/Platform/Exchange/CompleteExchange/Body.tsx
index d57f19560a1c..89c6b60487ff 100644
--- a/apps/ledger-live-desktop/src/renderer/modals/Platform/Exchange/CompleteExchange/Body.tsx
+++ b/apps/ledger-live-desktop/src/renderer/modals/Platform/Exchange/CompleteExchange/Body.tsx
@@ -13,10 +13,17 @@ import React, { useCallback, useEffect, useMemo, useRef, useState } from "react"
import { useDispatch } from "react-redux";
import styled from "styled-components";
import { updateAccountWithUpdater } from "~/renderer/actions/accounts";
-import { useIsSwapLiveFlagEnabled } from "~/renderer/screens/exchange/Swap2/hooks/useIsSwapLiveFlagEnabled";
+
import { useRedirectToSwapHistory } from "~/renderer/screens/exchange/Swap2/utils";
import { BodyContent } from "./BodyContent";
+export enum ExchangeModeEnum {
+ Sell = "sell",
+ Swap = "swap",
+}
+
+export type ExchangeMode = "sell" | "swap";
+
export type Data = {
provider: string;
exchange: Exchange;
@@ -32,13 +39,6 @@ export type Data = {
magnitudeAwareRate?: BigNumber;
};
-export enum ExchangeModeEnum {
- Sell = "sell",
- Swap = "swap",
-}
-
-export type ExchangeMode = "sell" | "swap";
-
type ResultsState = {
mode: ExchangeMode;
swapId?: string;
@@ -195,7 +195,6 @@ const Body = ({ data, onClose }: { data: Data; onClose?: () => void | undefined
const handleSellTransaction = (operation: Operation, result: ResultsState) => {
handleTransactionResult(result, operation);
};
- const isDemo3Enabled = useIsSwapLiveFlagEnabled("ptxSwapLiveAppDemoThree");
const onBroadcastSuccess = useCallback(
(operation: Operation) => {
@@ -209,7 +208,7 @@ const Body = ({ data, onClose }: { data: Data; onClose?: () => void | undefined
const result = getResultByTransactionType(isSwapTransaction);
if (getEnv("DISABLE_TRANSACTION_BROADCAST")) {
- if (!isSwapTransaction || (isSwapTransaction && !isDemo3Enabled)) {
+ if (!isSwapTransaction) {
const error = new DisabledTransactionBroadcastError();
setError(error);
onCancel(error);
diff --git a/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/App/App.tsx b/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/App/App.tsx
index ecbb5d8de74b..348c47bf1f8d 100644
--- a/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/App/App.tsx
+++ b/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/App/App.tsx
@@ -1,4 +1,5 @@
import { useSwapLiveConfig } from "@ledgerhq/live-common/exchange/swap/hooks/index";
+import { DEFAULT_FEATURES } from "@ledgerhq/live-common/featureFlags/index";
import { useRemoteLiveAppManifest } from "@ledgerhq/live-common/platform/providers/RemoteLiveAppProvider/index";
import { useLocalLiveAppManifest } from "@ledgerhq/live-common/wallet-api/LocalLiveAppProvider/index";
import React, { useState } from "react";
@@ -26,10 +27,16 @@ const ErrorWrapper = styled.div`
font-weight: 500;
`;
+// set the default manifest ID for the production swap live app
+// in case the FF is failing to load the manifest ID
+// "swap-live-app-demo-3" points to production vercel URL for the swap live app
+const DEFAULT_MANIFEST_ID =
+ process.env.DEFAULT_SWAP_MANIFEST_ID || DEFAULT_FEATURES.ptxSwapLiveApp.params?.manifest_id;
+
export function SwapApp() {
const [unavailable, setUnavailable] = useState(false);
const swapLiveEnabledFlag = useSwapLiveConfig();
- const swapLiveAppManifestID = swapLiveEnabledFlag?.params?.manifest_id;
+ const swapLiveAppManifestID = swapLiveEnabledFlag?.params?.manifest_id || DEFAULT_MANIFEST_ID;
const localManifest = useLocalLiveAppManifest(swapLiveAppManifestID || undefined);
const remoteManifest = useRemoteLiveAppManifest(swapLiveAppManifestID || undefined);
diff --git a/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/DrawerTitle.tsx b/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/DrawerTitle.tsx
deleted file mode 100644
index 123bbd9e45a9..000000000000
--- a/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/DrawerTitle.tsx
+++ /dev/null
@@ -1,18 +0,0 @@
-import React from "react";
-import { Trans } from "react-i18next";
-import Box from "~/renderer/components/Box/Box";
-import { Separator } from "./Separator";
-import Text from "~/renderer/components/Text";
-
-export function DrawerTitle({ i18nKey }: { i18nKey: string }) {
- return (
- <>
-
-
-
-
-
-
- >
- );
-}
diff --git a/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/ExchangeDrawer/SwapAction.tsx b/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/ExchangeDrawer/SwapAction.tsx
deleted file mode 100644
index a260b8a66c53..000000000000
--- a/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/ExchangeDrawer/SwapAction.tsx
+++ /dev/null
@@ -1,183 +0,0 @@
-import { getEnv } from "@ledgerhq/live-env";
-import {
- ExchangeSwap,
- ExchangeRate,
- InitSwapResult,
- SwapTransaction,
- SwapTransactionType,
-} from "@ledgerhq/live-common/exchange/swap/types";
-import { useBroadcast } from "@ledgerhq/live-common/hooks/useBroadcast";
-import { createAction as initSwapCreateAction } from "@ledgerhq/live-common/hw/actions/initSwap";
-import { createAction as transactionCreateAction } from "@ledgerhq/live-common/hw/actions/transaction";
-import { Operation, SignedOperation } from "@ledgerhq/types-live";
-import React, { useEffect, useMemo, useRef, useState } from "react";
-import { Trans } from "react-i18next";
-import { useSelector } from "react-redux";
-import BigSpinner from "~/renderer/components/BigSpinner";
-import Box from "~/renderer/components/Box";
-import { mockedEventEmitter } from "~/renderer/components/debug/DebugMock";
-import DeviceAction from "~/renderer/components/DeviceAction";
-import Text from "~/renderer/components/Text";
-import { getCurrentDevice } from "~/renderer/reducers/devices";
-import { mevProtectionSelector } from "~/renderer/reducers/settings";
-import connectApp from "@ledgerhq/live-common/hw/connectApp";
-import initSwap from "@ledgerhq/live-common/exchange/swap/initSwap";
-import { Device } from "@ledgerhq/types-devices";
-import { BigNumber } from "bignumber.js";
-
-const transactionAction = transactionCreateAction(getEnv("MOCK") ? mockedEventEmitter : connectApp);
-const initAction = initSwapCreateAction(
- getEnv("MOCK") ? mockedEventEmitter : connectApp,
- getEnv("MOCK") ? mockedEventEmitter : initSwap,
-);
-
-const TransactionResult = (
- props:
- | { signedOperation: SignedOperation; device?: Device; swapId?: string | undefined }
- | { transactionSignError?: Error },
-) => {
- if (!("signedOperation" in props) || !props.signedOperation) return null;
- return (
-
-
-
-
-
-
- );
-};
-
-type Props = {
- swapTransaction: SwapTransactionType;
- exchangeRate: ExchangeRate;
- onCompletion: (a: {
- operation: Operation;
- swapId: string;
- magnitudeAwareRate: BigNumber;
- }) => void;
- onError: (a: { error: Error; swapId?: string }) => void;
-};
-
-export default function SwapAction({
- swapTransaction,
- exchangeRate,
- onCompletion,
- onError,
-}: Props) {
- const [initData, setInitData] = useState(null);
- const [signedOperation, setSignedOperation] = useState(null);
- const mevProtected = useSelector(mevProtectionSelector);
- const device = useSelector(getCurrentDevice);
- const deviceRef = useRef(device);
- const { account: fromAccount, parentAccount: fromParentAccount } = swapTransaction.swap.from;
- const { account: toAccount, parentAccount: toParentAccount } = swapTransaction.swap.to;
- const { transaction, status } = swapTransaction;
- const tokenCurrency =
- fromAccount && fromAccount.type === "TokenAccount" ? fromAccount.token : null;
-
- const broadcast = useBroadcast({
- account: fromAccount,
- parentAccount: fromParentAccount,
- broadcastConfig: { mevProtected },
- });
-
- const exchange = useMemo(
- () => ({
- fromParentAccount,
- fromAccount,
- toParentAccount,
- toAccount,
- }),
- [fromAccount, fromParentAccount, toAccount, toParentAccount],
- );
-
- useEffect(() => {
- if (initData && signedOperation) {
- const { swapId, magnitudeAwareRate } = initData;
- broadcast(signedOperation).then(
- operation => {
- onCompletion({
- operation,
- swapId,
- magnitudeAwareRate,
- });
- },
- error => {
- onError({
- error,
- swapId,
- });
- },
- );
- }
- }, [broadcast, onCompletion, onError, initData, signedOperation]);
-
- const request = useMemo(
- () => ({
- exchange: exchange as ExchangeSwap,
- exchangeRate,
- transaction: transaction as SwapTransaction,
- status,
- device: deviceRef,
- }),
- [exchange, exchangeRate, status, transaction],
- );
-
- const signRequest = useMemo(
- () => ({
- tokenCurrency,
- parentAccount: fromParentAccount,
- account: fromAccount!,
- transaction: initData?.transaction,
- appName: "Exchange",
- }),
- [fromAccount, fromParentAccount, initData?.transaction, tokenCurrency],
- );
-
- return !initData || !transaction ? (
- {
- if ("initSwapError" in result && result.initSwapError) {
- onError({
- error: result.initSwapError,
- swapId: result.swapId,
- });
- } else if ("initSwapResult" in result) {
- setInitData(result.initSwapResult);
- }
- }}
- analyticsPropertyFlow="swap"
- />
- ) : !signedOperation ? (
- {
- if ("transactionSignError" in result) {
- onError({
- error: result.transactionSignError,
- swapId: initData.swapId,
- });
- } else {
- setSignedOperation(result.signedOperation);
- }
- }}
- analyticsPropertyFlow="swap"
- />
- ) : (
-
- );
-}
diff --git a/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/ExchangeDrawer/index.tsx b/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/ExchangeDrawer/index.tsx
deleted file mode 100644
index 1a1318267193..000000000000
--- a/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/ExchangeDrawer/index.tsx
+++ /dev/null
@@ -1,246 +0,0 @@
-import { postSwapCancelled } from "@ledgerhq/live-common/exchange/swap/index";
-import { setBroadcastTransaction } from "@ledgerhq/live-common/exchange/swap/setBroadcastTransaction";
-import { getUpdateAccountWithUpdaterParams } from "@ledgerhq/live-common/exchange/swap/getUpdateAccountWithUpdaterParams";
-import { CompleteExchangeError } from "@ledgerhq/live-common/exchange/error";
-import {
- ExchangeSwap,
- SwapTransactionType,
- ExchangeRate,
-} from "@ledgerhq/live-common/exchange/swap/types";
-import React, { useCallback, useMemo, useState } from "react";
-import { Trans } from "react-i18next";
-import { useDispatch, useSelector } from "react-redux";
-import styled from "styled-components";
-import TrackPage from "~/renderer/analytics/TrackPage";
-import { track } from "~/renderer/analytics/segment";
-import { updateAccountWithUpdater } from "~/renderer/actions/accounts";
-import Box from "~/renderer/components/Box";
-import Button from "~/renderer/components/Button";
-import {
- Footer as DeviceActionFooter,
- Header as DeviceActionHeader,
-} from "~/renderer/components/DeviceAction/rendering";
-import ErrorDisplay from "~/renderer/components/ErrorDisplay";
-import { setDrawer } from "~/renderer/drawers/Provider";
-import { useGetSwapTrackingProperties, useRedirectToSwapHistory } from "../../utils/index";
-import { DrawerTitle } from "../DrawerTitle";
-import { Separator } from "../Separator";
-import SwapAction from "./SwapAction";
-import SwapCompleted from "./SwapCompleted";
-import { Operation } from "@ledgerhq/types-live";
-import { BigNumber } from "bignumber.js";
-import { getCurrentDevice } from "~/renderer/reducers/devices";
-import { rateSelector } from "~/renderer/actions/swap";
-
-const ContentBox = styled(Box)`
- ${DeviceActionHeader} {
- flex: 0;
- }
- ${DeviceActionFooter} {
- flex: 0;
- }
-`;
-
-type Props = {
- swapTransaction: SwapTransactionType;
- exchangeRate: ExchangeRate;
- onCompleteSwap?: () => void;
-};
-
-export default function ExchangeDrawer({ swapTransaction, exchangeRate, onCompleteSwap }: Props) {
- const dispatch = useDispatch();
- const [error, setError] = useState(null);
- const [result, setResult] = useState<{
- operation: Operation;
- swapId: string;
- } | null>(null);
- const swapDefaultTrack = useGetSwapTrackingProperties();
- const device = useSelector(getCurrentDevice);
- const selectedExchangeRate = useSelector(rateSelector);
- const redirectToHistory = useRedirectToSwapHistory();
- const {
- transaction,
- swap: {
- from: { account: fromAccount, parentAccount: fromParentAccount, currency: sourceCurrency },
- to: { account: toAccount, parentAccount: toParentAccount, currency: targetCurrency },
- },
- } = swapTransaction;
-
- const exchange = useMemo(
- () => ({
- fromParentAccount,
- fromAccount,
- toParentAccount,
- toAccount,
- }),
- [fromAccount, fromParentAccount, toAccount, toParentAccount],
- ) as ExchangeSwap;
-
- const onError = useCallback(
- (errorResult: { error: Error; swapId?: string }) => {
- const { error, swapId } = errorResult;
- // Consider the swap as cancelled (on provider perspective) in case of error
- postSwapCancelled({
- provider: exchangeRate.provider,
- swapId: swapId ?? "",
- ...((error as CompleteExchangeError).step
- ? { swapStep: (error as CompleteExchangeError).step }
- : {}),
- statusCode: error.name,
- errorMessage: error.message,
- sourceCurrencyId: swapTransaction.swap.from.currency?.id,
- targetCurrencyId: swapTransaction.swap.to.currency?.id,
- hardwareWalletType: device?.modelId,
- swapType: selectedExchangeRate?.tradeMethod,
- });
- track("error_message", {
- message: "drawer_error",
- page: "Page Swap Drawer",
- ...swapDefaultTrack,
- error,
- });
- setError(error);
- },
- // eslint-disable-next-line react-hooks/exhaustive-deps
- [exchangeRate.provider, swapDefaultTrack],
- );
-
- const onCompletion = useCallback(
- ({
- magnitudeAwareRate,
- ...result
- }: {
- operation: Operation;
- swapId: string;
- magnitudeAwareRate: BigNumber;
- }) => {
- const { provider } = exchangeRate;
-
- setBroadcastTransaction({
- result,
- provider,
- sourceCurrencyId: swapTransaction.swap.from.currency?.id,
- targetCurrencyId: swapTransaction.swap.to.currency?.id,
- hardwareWalletType: device?.modelId,
- swapType: selectedExchangeRate?.tradeMethod,
- });
- const params = getUpdateAccountWithUpdaterParams({
- result,
- exchange,
- transaction,
- magnitudeAwareRate,
- provider,
- });
- if (!params.length) return;
- const dispatchAction = updateAccountWithUpdater(...params);
- dispatch(dispatchAction);
- setResult(result);
- onCompleteSwap && onCompleteSwap();
- },
- // eslint-disable-next-line react-hooks/exhaustive-deps
- [dispatch, exchange, exchangeRate, transaction, onCompleteSwap],
- );
-
- const onViewDetails = useCallback(
- () => {
- if (!result) return;
- const { operation } = result;
- const concernedOperation = operation
- ? operation.subOperations && operation.subOperations.length > 0
- ? operation.subOperations[0]
- : operation
- : null;
- if (fromAccount && concernedOperation) {
- redirectToHistory({
- swapId: result?.swapId,
- });
- }
- },
- // eslint-disable-next-line react-hooks/exhaustive-deps
- [fromAccount, fromParentAccount, result?.operation],
- );
-
- const closeDrawer = useCallback(() => setDrawer(), []);
-
- if (error) {
- return (
-
-
-
-
-
-
-
-
-
-
-
-
- );
- }
- if (result) {
- return (
-
-
- {targetCurrency && (
-
-
-
- )}
-
-
-
-
-
-
-
- );
- }
- return (
-
-
-
-
-
-
- );
-}
diff --git a/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/FeesDrawer/index.tsx b/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/FeesDrawer/index.tsx
deleted file mode 100644
index d8e26517429c..000000000000
--- a/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/FeesDrawer/index.tsx
+++ /dev/null
@@ -1,78 +0,0 @@
-import React, { useCallback } from "react";
-import { useSelector } from "react-redux";
-import Box from "~/renderer/components/Box";
-import SendAmountFields from "~/renderer/modals/Send/SendAmountFields";
-import { transactionSelector } from "~/renderer/actions/swap";
-import {
- SwapTransactionType,
- SwapSelectorStateType,
-} from "@ledgerhq/live-common/exchange/swap/types";
-import { DrawerTitle } from "../DrawerTitle";
-import TrackPage from "~/renderer/analytics/TrackPage";
-import { useGetSwapTrackingProperties } from "../../utils/index";
-import { Account, FeeStrategy } from "@ledgerhq/types-live";
-
-type Props = {
- setTransaction: SwapTransactionType["setTransaction"];
- updateTransaction: SwapTransactionType["updateTransaction"];
- mainAccount: SwapSelectorStateType["account"];
- parentAccount: SwapSelectorStateType["parentAccount"];
- currency: SwapSelectorStateType["currency"];
- status: SwapTransactionType["status"];
- disableSlowStrategy?: boolean;
- provider: string | undefined | null;
-};
-
-export default function FeesDrawer({
- setTransaction,
- updateTransaction,
- mainAccount,
- parentAccount,
- status,
- provider,
- disableSlowStrategy = false,
-}: Props) {
- const swapDefaultTrack = useGetSwapTrackingProperties();
- const transaction = useSelector(transactionSelector);
-
- const mapStrategies = useCallback(
- (strategy: FeeStrategy) =>
- strategy.label === "slow" && disableSlowStrategy
- ? {
- ...strategy,
- disabled: true,
- }
- : strategy,
- [disableSlowStrategy],
- );
-
- return (
-
-
-
-
- {transaction && mainAccount && (
-
- )}
-
-
- );
-}
diff --git a/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/FormRates/ProvidersSection.tsx b/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/FormRates/ProvidersSection.tsx
deleted file mode 100644
index 1e8131780af1..000000000000
--- a/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/FormRates/ProvidersSection.tsx
+++ /dev/null
@@ -1,15 +0,0 @@
-import React from "react";
-import styled from "styled-components";
-
-const Container = styled.div`
- display: flex;
- flex-direction: row;
- justify-content: space-between;
- min-height: 20px;
-`;
-type ProvidersSectionProps = {
- children: React.ReactNode;
-};
-
-const ProvidersSection = ({ children }: ProvidersSectionProps) => {children};
-export default ProvidersSection;
diff --git a/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/FormRates/SectionRate.tsx b/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/FormRates/SectionRate.tsx
deleted file mode 100644
index a2717986655f..000000000000
--- a/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/FormRates/SectionRate.tsx
+++ /dev/null
@@ -1,40 +0,0 @@
-import {
- RatesReducerState,
- SwapSelectorStateType,
-} from "@ledgerhq/live-common/exchange/swap/types";
-import React from "react";
-import Rates from "../Rates";
-import ProvidersSection from "./ProvidersSection";
-
-export type SectionRateProps = {
- provider?: string;
- ratesState: RatesReducerState;
- fromCurrency: SwapSelectorStateType["currency"];
- toCurrency: SwapSelectorStateType["currency"];
- countdownSecondsToRefresh: number | undefined;
-};
-
-const SectionRate = ({
- provider,
- fromCurrency,
- toCurrency,
- ratesState,
- countdownSecondsToRefresh,
-}: SectionRateProps) => {
- const rates = ratesState.value;
-
- return (
-
-
-
- );
-};
-export default React.memo(SectionRate);
diff --git a/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/FormRates/index.tsx b/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/FormRates/index.tsx
deleted file mode 100644
index 3a1a7023c215..000000000000
--- a/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/FormRates/index.tsx
+++ /dev/null
@@ -1,37 +0,0 @@
-import { SwapDataType } from "@ledgerhq/live-common/exchange/swap/types";
-import React from "react";
-import styled from "styled-components";
-import SectionRate from "./SectionRate";
-
-const Form = styled.section`
- display: grid;
- row-gap: 1.375rem;
- color: white;
-`;
-type SwapFormProvidersProps = {
- swap: SwapDataType;
- countdownSecondsToRefresh: number | undefined;
- provider?: string;
-};
-
-const SwapFormProviders = ({
- swap,
- provider,
- countdownSecondsToRefresh,
-}: SwapFormProvidersProps) => {
- const { currency: fromCurrency } = swap.from;
- const { currency: toCurrency } = swap.to;
-
- return (
-
- );
-};
-export default React.memo(SwapFormProviders);
diff --git a/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/FormRates/types.ts b/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/FormRates/types.ts
deleted file mode 100644
index 82625ce5fe8d..000000000000
--- a/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/FormRates/types.ts
+++ /dev/null
@@ -1,12 +0,0 @@
-import { SwapTransactionType } from "@ledgerhq/live-common/exchange/swap/types";
-
-export type FormProvidersSections = "provider" | "fees" | "rate" | "target";
-export type FormProvidersProps = {
- provider?: string;
- rate?: string;
- fees?: string;
- onProviderChange: Function;
- onFeesChange: Function;
- onTargetChange: Function;
- swapTransaction: SwapTransactionType;
-};
diff --git a/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/FormSelectors/FormInputs.tsx b/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/FormSelectors/FormInputs.tsx
deleted file mode 100644
index 4ca1d2258d46..000000000000
--- a/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/FormSelectors/FormInputs.tsx
+++ /dev/null
@@ -1,140 +0,0 @@
-import {
- SwapDataType,
- SwapSelectorStateType,
- SwapTransactionType,
-} from "@ledgerhq/live-common/exchange/swap/types";
-import BigNumber from "bignumber.js";
-import React from "react";
-import styled from "styled-components";
-import { track } from "~/renderer/analytics/segment";
-import Box from "~/renderer/components/Box";
-import Button from "~/renderer/components/Button";
-import ArrowsUpDown from "~/renderer/icons/ArrowsUpDown";
-import { useGetSwapTrackingProperties } from "../../utils/index";
-import FromRow from "./FromRow";
-import ToRow from "./ToRow";
-
-type FormInputsProps = {
- fromAccount: SwapSelectorStateType["account"];
- toAccount: SwapSelectorStateType["account"];
- fromAmount: SwapSelectorStateType["amount"];
- toCurrency: SwapSelectorStateType["currency"];
- toAmount: SwapSelectorStateType["amount"];
- setFromAccount: SwapTransactionType["setFromAccount"];
- setFromAmount: SwapTransactionType["setFromAmount"];
- setToCurrency: SwapTransactionType["setToCurrency"];
- toggleMax: SwapTransactionType["toggleMax"];
- reverseSwap: SwapTransactionType["reverseSwap"];
- isMaxEnabled?: boolean;
- fromAmountError?: Error;
- fromAmountWarning?: Error;
- isSwapReversable: boolean;
- provider: string | undefined | null;
- loadingRates: boolean;
- isSendMaxLoading: boolean;
- updateSelectedRate: SwapDataType["updateSelectedRate"];
- counterValue?: BigNumber;
-};
-
-type SwapButtonProps = {
- onClick: SwapTransactionType["reverseSwap"];
- disabled: boolean;
-};
-
-const RoundButton = styled(Button)`
- padding: 8px;
- border-radius: 9999px;
- height: initial;
-`;
-
-const Main = styled.section`
- display: flex;
- flex-direction: column;
- margin-bottom: 5px;
- row-gap: 12px;
-`;
-
-function SwapButton({ onClick, disabled }: SwapButtonProps): JSX.Element {
- return (
-
-
-
- );
-}
-
-export default function FormInputs({
- fromAccount = undefined,
- toAccount,
- fromAmount = undefined,
- isMaxEnabled = false,
- setFromAccount,
- setFromAmount,
- toCurrency,
- toAmount,
- setToCurrency,
- toggleMax,
- fromAmountError,
- fromAmountWarning,
- reverseSwap,
- isSwapReversable,
- provider,
- loadingRates,
- isSendMaxLoading,
- updateSelectedRate,
- counterValue,
-}: FormInputsProps) {
- const swapDefaultTrack = useGetSwapTrackingProperties();
- const reverseSwapAndTrack = () => {
- track("button_clicked2", {
- button: "switch",
- page: "Page Swap Form",
- ...swapDefaultTrack,
- });
- reverseSwap();
- };
-
- return (
-
-
-
-
-
-
-
-
-
-
-
- );
-}
diff --git a/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/FormSelectors/FormLabel.tsx b/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/FormSelectors/FormLabel.tsx
deleted file mode 100644
index 2f87f004bf75..000000000000
--- a/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/FormSelectors/FormLabel.tsx
+++ /dev/null
@@ -1,10 +0,0 @@
-import React from "react";
-import Text from "~/renderer/components/Text";
-
-export function FormLabel({ children }: { children?: React.ReactNode }) {
- return (
-
- {children}
-
- );
-}
diff --git a/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/FormSelectors/FromRow.tsx b/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/FormSelectors/FromRow.tsx
deleted file mode 100644
index 2280c012937b..000000000000
--- a/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/FormSelectors/FromRow.tsx
+++ /dev/null
@@ -1,242 +0,0 @@
-import React, { useEffect } from "react";
-import { useTranslation } from "react-i18next";
-import styled from "styled-components";
-import { getAccountCurrency } from "@ledgerhq/live-common/account/index";
-import Box from "~/renderer/components/Box";
-import InputCurrency from "~/renderer/components/InputCurrency";
-import { ErrorContainer } from "~/renderer/components/Input";
-import { SelectAccount } from "~/renderer/components/SelectAccount";
-import Switch from "~/renderer/components/Switch";
-import Text from "~/renderer/components/Text";
-import { amountInputContainerProps, renderAccountValue, selectRowStylesMap } from "./utils";
-import { FormLabel } from "./FormLabel";
-import {
- SwapSelectorStateType,
- SwapTransactionType,
- SwapDataType,
-} from "@ledgerhq/live-common/exchange/swap/types";
-import { track } from "~/renderer/analytics/segment";
-import { useGetSwapTrackingProperties } from "../../utils/index";
-import { useCurrenciesByMarketcap } from "@ledgerhq/live-common/currencies/hooks";
-import { listCryptoCurrencies, listTokens } from "@ledgerhq/live-common/currencies/index";
-import { AccountLike } from "@ledgerhq/types-live";
-import BigNumber from "bignumber.js";
-import { TranslatedError } from "~/renderer/components/TranslatedError/TranslatedError";
-import { WarningSolidMedium } from "@ledgerhq/react-ui/assets/icons";
-import { useSwapableAccounts } from "@ledgerhq/live-common/exchange/swap/hooks/index";
-import { useSelector } from "react-redux";
-import { flattenAccountsSelector } from "~/renderer/reducers/accounts";
-import { useMaybeAccountUnit } from "~/renderer/hooks/useAccountUnit";
-import { getDefaultAccountName } from "@ledgerhq/live-wallet/accountName";
-
-const SwapStatusContainer = styled.div<{ isError: boolean }>(
- ({ theme: { space, colors }, isError }) => `
- margin-top: ${space[1]}px;
- display: grid;
- grid-template-columns: 16px auto;
- align-items: center;
- column-gap: ${space[1]}px;
- color: ${isError ? colors.error.c70 : colors.warning};
-`,
-);
-
-const SwapStatusText = styled(Text)(
- () => `
- & button, a {
- text-decoration: underline;
- cursor: pointer;
- }
-`,
-);
-
-/* @dev: Yeah, Im sorry if you read this, design asked us to
- override the input component when it is called from the swap form. */
-const InputSection = styled(Box)`
- & ${ErrorContainer} {
- font-weight: 500;
- font-size: 11px;
- text-align: right;
- margin-left: calc(calc(100% + 30px) * -1);
- margin-top: 6px;
- align-self: flex-end;
- margin-right: -15px;
- }
-`;
-
-// Pick a default source account if none are selected.
-// TODO use live-common once its ready
-const usePickDefaultAccount = (
- accounts: AccountLike[],
- fromAccount: AccountLike | undefined,
- setFromAccount: (acc?: AccountLike) => void,
-): void => {
- const list = [...listCryptoCurrencies(), ...listTokens()];
- const allCurrencies = useCurrenciesByMarketcap(list);
- useEffect(() => {
- if (!fromAccount && allCurrencies.length > 0) {
- allCurrencies.some(({ id }) => {
- const filteredAcc = accounts.filter(
- acc =>
- getAccountCurrency(acc)?.id === id &&
- acc.balance.gt(0) &&
- (!("disabled" in acc) || !acc.disabled),
- );
- if (filteredAcc.length > 0) {
- const defaultAccount = filteredAcc
- .sort((a, b) => b.balance.minus(a.balance).toNumber())
- .find(Boolean);
- setFromAccount(defaultAccount);
- return true;
- }
- return false;
- });
- }
- }, [accounts, allCurrencies, fromAccount, setFromAccount]);
-};
-
-type Props = {
- fromAccount: SwapSelectorStateType["account"];
- setFromAccount: SwapTransactionType["setFromAccount"];
- toggleMax: SwapTransactionType["toggleMax"];
- fromAmount: SwapSelectorStateType["amount"];
- setFromAmount: SwapTransactionType["setFromAmount"];
- isMaxEnabled: boolean;
- fromAmountError?: Error;
- fromAmountWarning?: Error;
- provider: string | undefined | null;
- isSendMaxLoading: boolean;
- updateSelectedRate: SwapDataType["updateSelectedRate"];
-};
-
-function FromRow({
- fromAmount,
- setFromAmount,
- fromAccount,
- setFromAccount,
- isMaxEnabled,
- toggleMax,
- fromAmountError,
- fromAmountWarning,
- isSendMaxLoading,
- updateSelectedRate,
-}: Props) {
- const swapDefaultTrack = useGetSwapTrackingProperties();
- const flattenedAccounts = useSelector(flattenAccountsSelector);
- const accounts = useSwapableAccounts({ accounts: flattenedAccounts });
- const unit = useMaybeAccountUnit(fromAccount);
- const { t } = useTranslation();
- usePickDefaultAccount(accounts, fromAccount, setFromAccount);
-
- if (!fromAccount) return null;
-
- const trackEditAccount = () => {
- track("button_clicked2", {
- button: "Edit source account",
- page: "Page Swap Form",
- ...swapDefaultTrack,
- });
- };
-
- const setAccountAndTrack = (account: AccountLike) => {
- updateSelectedRate();
- const name = account ? getDefaultAccountName(account) : undefined;
- track("button_clicked2", {
- button: "New source account",
- page: "Page Swap Form",
- ...swapDefaultTrack,
- account: name,
- });
- setFromAccount(account);
- };
-
- const setValue = (fromAmount: BigNumber) => {
- track("button_clicked2", {
- button: "Amount input",
- page: "Page Swap Form",
- ...swapDefaultTrack,
- amount: null,
- });
- updateSelectedRate();
- setFromAmount(fromAmount);
- };
-
- const toggleMaxAndTrack = (state: unknown) => {
- track("button_clicked2", {
- button: "max",
- page: "Page Swap Form",
- ...swapDefaultTrack,
- state,
- });
- toggleMax();
- };
-
- return (
- <>
-
- {t("swap2.form.from.title")}
-
-
- {t("swap2.form.from.max")}
-
-
-
-
-
-
-
-
-
-
-
-
-
- {(!!fromAmountError || !!fromAmountWarning) && (
-
-
-
-
-
-
- )}
- >
- );
-}
-
-export default React.memo(FromRow);
diff --git a/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/FormSelectors/ToRow.tsx b/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/FormSelectors/ToRow.tsx
deleted file mode 100644
index 4a88bcba7fa9..000000000000
--- a/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/FormSelectors/ToRow.tsx
+++ /dev/null
@@ -1,153 +0,0 @@
-import {
- useFetchCurrencyTo,
- usePickDefaultCurrency,
- useSelectableCurrencies,
-} from "@ledgerhq/live-common/exchange/swap/hooks/index";
-import {
- SwapDataType,
- SwapSelectorStateType,
- SwapTransactionType,
-} from "@ledgerhq/live-common/exchange/swap/types";
-import { CryptoOrTokenCurrency } from "@ledgerhq/types-cryptoassets";
-import BigNumber from "bignumber.js";
-import React from "react";
-import { Trans } from "react-i18next";
-import styled from "styled-components";
-import { track } from "~/renderer/analytics/segment";
-import Box from "~/renderer/components/Box/Box";
-import CounterValue from "~/renderer/components/CounterValue";
-import {
- BaseContainer as BaseInputContainer,
- Container as InputContainer,
-} from "~/renderer/components/Input";
-import InputCurrency from "~/renderer/components/InputCurrency";
-import SelectCurrency from "~/renderer/components/SelectCurrency";
-import { useGetSwapTrackingProperties } from "../../utils/index";
-import { FormLabel } from "./FormLabel";
-import { amountInputContainerProps, renderCurrencyValue, selectRowStylesMap } from "./utils";
-
-type Props = {
- fromAccount: SwapSelectorStateType["account"];
- toAccount: SwapSelectorStateType["account"];
- toCurrency: SwapSelectorStateType["currency"];
- setToCurrency: SwapTransactionType["setToCurrency"];
- toAmount: SwapSelectorStateType["amount"];
- provider: string | undefined | null;
- loadingRates: boolean;
- updateSelectedRate: SwapDataType["updateSelectedRate"];
- counterValue?: BigNumber;
-};
-
-const InputCurrencyContainer = styled(Box)`
- ${InputContainer} {
- display: flex;
- background: none;
- flex-direction: column;
- align-items: flex-end;
- justify-content: center;
- }
-
- ${BaseInputContainer} {
- flex: 0;
- }
-`;
-
-function ToRow({
- toCurrency,
- setToCurrency,
- toAmount,
- fromAccount,
- loadingRates,
- updateSelectedRate,
- counterValue,
-}: Props) {
- const { data: currenciesTo, isLoading: currenciesToIsLoading } = useFetchCurrencyTo({
- fromCurrencyAccount: fromAccount,
- });
- const swapDefaultTrack = useGetSwapTrackingProperties();
- const currencies = useSelectableCurrencies({
- allCurrencies: currenciesTo ?? [],
- });
- const unit = toCurrency?.units[0];
- usePickDefaultCurrency(currencies, toCurrency, setToCurrency);
- const trackEditCurrency = () =>
- track("button_clicked2", {
- button: "Edit target currency",
- page: "Page Swap Form",
- ...swapDefaultTrack,
- });
- const setCurrencyAndTrack = (currency: CryptoOrTokenCurrency | null | undefined) => {
- updateSelectedRate();
- track("button_clicked2", {
- button: "New target currency",
- page: "Page Swap Form",
- ...swapDefaultTrack,
- currency: currency?.ticker || currency?.name,
- });
- setToCurrency(currency || undefined);
- };
-
- return (
- <>
-
-
-
-
-
-
-
-
-
-
- null}
- data-testid="destination-currency-amount"
- value={unit ? toAmount : null}
- disabled
- placeholder="-"
- textAlign="right"
- fontWeight={600}
- color="palette.text.shade40"
- containerProps={amountInputContainerProps}
- unit={unit}
- loading={loadingRates}
- renderRight={
- toCurrency &&
- unit &&
- toAmount &&
- !loadingRates && (
-
- )
- }
- />
-
-
- >
- );
-}
-export default React.memo(ToRow);
diff --git a/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/FormSelectors/index.ts b/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/FormSelectors/index.ts
deleted file mode 100644
index 562594714958..000000000000
--- a/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/FormSelectors/index.ts
+++ /dev/null
@@ -1 +0,0 @@
-export { default } from "./FormInputs";
diff --git a/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/FormSelectors/utils.tsx b/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/FormSelectors/utils.tsx
deleted file mode 100644
index 9730883893c1..000000000000
--- a/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/FormSelectors/utils.tsx
+++ /dev/null
@@ -1,41 +0,0 @@
-import React from "react";
-import { CryptoOrTokenCurrency } from "@ledgerhq/types-cryptoassets";
-import { CreateStylesReturnType } from "~/renderer/components/Select/createStyles";
-import { AccountOption, Option as SelectAccountOption } from "~/renderer/components/SelectAccount";
-import { CurrencyOption } from "~/renderer/components/SelectCurrency";
-import { OptionTypeBase } from "react-select";
-import { ThemeConfig } from "react-select/src/theme";
-
-export const selectRowStylesMap: (
- a: CreateStylesReturnType & ThemeConfig,
-) => CreateStylesReturnType = styles => ({
- ...styles,
- control: (provided, state) => ({
- ...styles?.control?.(provided, state),
- borderTopRightRadius: 0,
- borderBottomRightRadius: 0,
- }),
- menu: (provided, state) => ({
- ...styles?.menu?.(provided, state),
- width: "200%",
- }),
- valueContainer: (styles: object) => ({
- ...styles,
- height: "100%",
- }),
-});
-
-export const amountInputContainerProps = {
- noBorderLeftRadius: true,
-};
-
-export const renderAccountValue = ({ data }: { data: SelectAccountOption }) =>
- data.account ? (
-
- ) : null;
-
-export const renderCurrencyValue = ({ data: currency }: { data: CryptoOrTokenCurrency }) => {
- return currency ? (
-
- ) : null;
-};
diff --git a/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/FormSummary/SectionFees.tsx b/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/FormSummary/SectionFees.tsx
deleted file mode 100644
index 00bbbd5890af..000000000000
--- a/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/FormSummary/SectionFees.tsx
+++ /dev/null
@@ -1,193 +0,0 @@
-import React, { useMemo, useEffect } from "react";
-import { useTranslation } from "react-i18next";
-import { useSelector } from "react-redux";
-import { getMainAccount } from "@ledgerhq/live-common/account/index";
-import { context } from "~/renderer/drawers/Provider";
-import SummaryLabel from "./SummaryLabel";
-import SummaryValue, { NoValuePlaceholder } from "./SummaryValue";
-import SummarySection from "./SummarySection";
-import FeesDrawer from "../FeesDrawer";
-import {
- SwapTransactionType,
- SwapSelectorStateType,
-} from "@ledgerhq/live-common/exchange/swap/types";
-import { track } from "~/renderer/analytics/segment";
-import { rateSelector } from "~/renderer/actions/swap";
-import FormattedVal from "~/renderer/components/FormattedVal";
-import Box from "~/renderer/components/Box";
-import Text from "~/renderer/components/Text";
-import TachometerHigh from "~/renderer/icons/TachometerHigh";
-import TachometerLow from "~/renderer/icons/TachometerLow";
-import TachometerMedium from "~/renderer/icons/TachometerMedium";
-import styled from "styled-components";
-import { useGetSwapTrackingProperties } from "../../utils/index";
-import { EDITABLE_FEE_FAMILIES } from "@ledgerhq/live-common/exchange/swap/const/blockchain";
-import { useMaybeAccountUnit } from "~/renderer/hooks/useAccountUnit";
-
-type Strategies = "slow" | "medium" | "fast" | "advanced";
-
-const FEES_STRATEGY_ICONS: {
- [x in Strategies]: (a: { color?: string; size?: number }) => React.ReactElement<"svg">;
-} = {
- slow: TachometerLow,
- medium: TachometerMedium,
- fast: TachometerHigh,
- advanced: TachometerHigh,
-};
-const IconSection = styled(Box)`
- flex-direction: row;
- column-gap: 0.25rem;
- color: ${props => props.theme.colors.palette.text.shade40};
-`;
-const Separator = styled.div`
- width: 3px;
- height: 3px;
- background-color: ${props => props.theme.colors.palette.text.shade40};
- border-radius: 9999px;
- align-self: center;
- margin-left: 2px;
-`;
-
-type Props = {
- transaction: SwapTransactionType["transaction"];
- account: SwapSelectorStateType["account"];
- parentAccount: SwapSelectorStateType["parentAccount"];
- currency: SwapSelectorStateType["currency"];
- status: SwapTransactionType["status"];
- updateTransaction: SwapTransactionType["updateTransaction"];
- setTransaction: SwapTransactionType["setTransaction"];
- provider: string | undefined | null;
- hasRates: boolean;
-};
-
-const SectionFees = ({
- transaction,
- account,
- parentAccount,
- currency,
- status,
- updateTransaction,
- setTransaction,
- provider,
- hasRates,
-}: Props) => {
- const { t } = useTranslation();
- const { setDrawer } = React.useContext(context);
- const exchangeRate = useSelector(rateSelector);
- const mainFromAccount = account && getMainAccount(account, parentAccount);
- const mainAccountUnit = useMaybeAccountUnit(mainFromAccount);
- const estimatedFees = status?.estimatedFees;
- const showSummaryValue = mainFromAccount && estimatedFees && estimatedFees.gt(0);
- const family = mainFromAccount?.currency.family;
- const canEdit =
- hasRates && showSummaryValue && transaction && family && EDITABLE_FEE_FAMILIES.includes(family);
- const swapDefaultTrack = useGetSwapTrackingProperties();
-
- const StrategyIcon = useMemo(
- () =>
- (transaction?.feesStrategy &&
- FEES_STRATEGY_ICONS[transaction?.feesStrategy as keyof typeof FEES_STRATEGY_ICONS]) ||
- undefined,
- [transaction?.feesStrategy],
- );
-
- // Deselect slow strategy if the exchange rate is changed to fixed.
- useEffect(
- () => {
- if (exchangeRate?.tradeMethod === "fixed" && transaction?.feesStrategy === "slow") {
- updateTransaction(t => ({
- ...t,
- feesStrategy: "medium",
- }));
- }
- },
- // eslint-disable-next-line
- [transaction?.feesStrategy, exchangeRate?.tradeMethod, updateTransaction],
- );
-
- const handleChange = useMemo(
- () =>
- (canEdit &&
- (() => {
- track("button_clicked2", {
- button: "change network fees",
- page: "Page Swap Form",
- ...swapDefaultTrack,
- });
- setDrawer(
- FeesDrawer,
- {
- setTransaction,
- updateTransaction,
- mainAccount: mainFromAccount,
- parentAccount: parentAccount,
- currency,
- status,
- disableSlowStrategy: exchangeRate?.tradeMethod === "fixed",
- provider,
- },
- {
- forceDisableFocusTrap: true,
- },
- );
- })) ||
- undefined,
- [
- canEdit,
- swapDefaultTrack,
- setDrawer,
- setTransaction,
- updateTransaction,
- mainFromAccount,
- parentAccount,
- currency,
- status,
- exchangeRate?.tradeMethod,
- provider,
- ],
- );
-
- const summaryValue = canEdit ? (
- <>
-
- {StrategyIcon ? : null}
-
- {t(`fees.${transaction?.feesStrategy ?? "custom"}`)}
-
-
-
-
- >
- ) : estimatedFees ? (
-
- ) : (
-
- );
-
- return (
-
-
- {summaryValue}
-
- );
-};
-
-export default React.memo(SectionFees);
diff --git a/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/FormSummary/SectionInformative.tsx b/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/FormSummary/SectionInformative.tsx
deleted file mode 100644
index bfef46709e54..000000000000
--- a/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/FormSummary/SectionInformative.tsx
+++ /dev/null
@@ -1,54 +0,0 @@
-import React from "react";
-import styled from "styled-components";
-import { rgba } from "~/renderer/styles/helpers";
-import Button from "~/renderer/components/Button";
-import TextBase from "~/renderer/components/Text";
-
-const Container = styled.div`
- display: flex;
- justify-content: space-between;
- background-color: ${p => rgba(p.theme.colors.palette.primary.main, 0.1)};
- color: ${p => p.theme.colors.palette.primary.main};
- column-gap: 0.75rem;
- padding: 0.75rem;
- border-radius: 4px;
- align-items: center;
-`;
-const Text = styled(TextBase).attrs(() => ({
- ff: "Inter",
- fontSize: "0.875rem",
- fontWeight: 500,
- lineHeight: "1.4",
-}))`
- &:first-letter {
- text-transform: uppercase;
- }
-`;
-const TextWrappper = styled.div`
- max-width: 28rem;
-`;
-const ButtonAddAccount = styled(Button).attrs(() => ({
- primary: true,
- small: true,
-}))`
- height: 40px;
-`;
-
-type SectionInformativeProps = {
- message: string;
- ctaLabel: string;
- onClick: () => void;
-};
-
-const SectionInformative = ({ message, ctaLabel, onClick }: SectionInformativeProps) => (
-
-
- {message}
-
-
- {ctaLabel}
-
-
-);
-
-export default SectionInformative;
diff --git a/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/FormSummary/SectionTarget.tsx b/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/FormSummary/SectionTarget.tsx
deleted file mode 100644
index 29400edebe52..000000000000
--- a/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/FormSummary/SectionTarget.tsx
+++ /dev/null
@@ -1,162 +0,0 @@
-import {
- SwapSelectorStateType,
- SwapTransactionType,
-} from "@ledgerhq/live-common/exchange/swap/types";
-import { CryptoCurrency, TokenCurrency } from "@ledgerhq/types-cryptoassets";
-import { AccountLike } from "@ledgerhq/types-live";
-import React, { useCallback, useEffect, useRef } from "react";
-import { useTranslation } from "react-i18next";
-import { useDispatch } from "react-redux";
-import { openModal } from "~/renderer/actions/modals";
-import { track } from "~/renderer/analytics/segment";
-import CryptoCurrencyIcon from "~/renderer/components/CryptoCurrencyIcon";
-import { context } from "~/renderer/drawers/Provider";
-import { useMaybeAccountName } from "~/renderer/reducers/wallet";
-import { useGetSwapTrackingProperties } from "../../utils/index";
-import TargetAccountDrawer from "../TargetAccountDrawer";
-import { useIsSwapLiveFlagEnabled } from "../../hooks/useIsSwapLiveFlagEnabled";
-import SectionInformative from "./SectionInformative";
-import SummaryLabel from "./SummaryLabel";
-import SummarySection from "./SummarySection";
-import SummaryValue, { Container, Text, NoValuePlaceholder } from "./SummaryValue";
-import styled from "styled-components";
-
-const AccountSectionContainer = styled(SummarySection)`
- column-gap: 12px;
- display: grid;
- grid-template-columns: 1fr 1fr;
-
- ${Container}, ${Text} {
- flex-shrink: 1;
- }
-
- ${Container} ${Text} {
- overflow: hidden;
- text-overflow: ellipsis;
- }
-`;
-
-const AccountSection = ({
- account,
- currency,
- handleChange,
-}: {
- account: SwapSelectorStateType["account"];
- currency: TokenCurrency | CryptoCurrency;
- handleChange?: () => void;
-}) => {
- const { t } = useTranslation();
- const accountName = useMaybeAccountName(account);
-
- const swapDefaultTrack = useGetSwapTrackingProperties();
-
- const handleChangeAndTrack = useCallback(() => {
- track("button_clicked2", {
- button: "change target account",
- page: "Page Swap Form",
- ...swapDefaultTrack,
- });
-
- if (handleChange) {
- handleChange();
- }
- }, [handleChange, swapDefaultTrack]);
-
- return (
-
-
-
- {currency ? : null}
-
-
- );
-};
-
-const PlaceholderSection = () => {
- const { t } = useTranslation();
-
- return (
-
-
-
-
-
-
- );
-};
-
-type SectionTargetProps = {
- account: SwapSelectorStateType["account"];
- currency: SwapSelectorStateType["currency"];
- setToAccount: SwapTransactionType["setToAccount"];
- targetAccounts: AccountLike[] | undefined;
- hasRates: boolean;
-};
-
-type SetDrawerStateRef = (args: {
- selectedAccount: AccountLike | undefined;
- targetAccounts: AccountLike[] | undefined;
-}) => void;
-const SectionTarget = ({
- account,
- currency,
- setToAccount,
- targetAccounts,
- hasRates,
-}: SectionTargetProps) => {
- const { t } = useTranslation();
- const dispatch = useDispatch();
- const { setDrawer } = React.useContext(context);
- const swapDefaultTrack = useGetSwapTrackingProperties();
- const isDemo0Enabled = useIsSwapLiveFlagEnabled("ptxSwapLiveAppDemoZero");
-
- const handleAddAccount = () => {
- track("button_clicked2", {
- button: "add account",
- page: "Page Swap Form",
- ...swapDefaultTrack,
- });
- dispatch(openModal("MODAL_ADD_ACCOUNTS", { currency, ...swapDefaultTrack }));
- };
-
- const hideEdit = !targetAccounts || targetAccounts.length < 2;
-
- // Using a ref to keep the drawer state synced.
- const setDrawerStateRef = useRef(null);
- useEffect(() => {
- setDrawerStateRef.current &&
- setDrawerStateRef.current({
- selectedAccount: account,
- targetAccounts,
- });
- }, [account, targetAccounts]);
-
- const showDrawer = () => {
- setDrawer(TargetAccountDrawer, {
- accounts: targetAccounts,
- selectedAccount: account,
- setToAccount: setToAccount,
- setDrawerStateRef: setDrawerStateRef,
- });
- };
-
- const handleEditAccount = hideEdit ? undefined : showDrawer;
-
- if (!currency || (isDemo0Enabled && !hasRates)) return ;
-
- if (!account)
- return (
-
- );
-
- return ;
-};
-
-export default React.memo(SectionTarget);
diff --git a/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/FormSummary/SummaryLabel.tsx b/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/FormSummary/SummaryLabel.tsx
deleted file mode 100644
index 714f5b5e776f..000000000000
--- a/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/FormSummary/SummaryLabel.tsx
+++ /dev/null
@@ -1,49 +0,0 @@
-import React from "react";
-import styled from "styled-components";
-import Text from "~/renderer/components/Text";
-import Tooltip from "~/renderer/components/Tooltip";
-import IconInfoCircle from "~/renderer/icons/InfoCircle";
-
-const Container = styled.div`
- display: flex;
- align-items: end;
- column-gap: 0.25rem;
- color: ${p => p.theme.colors.palette.text.shade40};
-`;
-const Label = styled(Text).attrs(() => ({
- ff: "Inter",
- fontSize: "13px",
- fontWeight: 500,
- lineHeight: "1.4",
-}))`
- &:first-letter {
- text-transform: uppercase;
- }
-`;
-
-type DetailsProps = {
- details?: string;
-};
-
-const Details = ({ details }: DetailsProps) => {
- if (!details) return null;
- return (
-
-
-
- );
-};
-
-/* This component fetch the current label and the optional details from the section's
- ** context and render them if possible.
- */
-const SummaryLabel = ({ label, details }: { label: string; details?: string }) => {
- return (
-
-
- {details ? : null}
-
- );
-};
-
-export default SummaryLabel;
diff --git a/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/FormSummary/SummarySection.tsx b/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/FormSummary/SummarySection.tsx
deleted file mode 100644
index 4da8687ed089..000000000000
--- a/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/FormSummary/SummarySection.tsx
+++ /dev/null
@@ -1,19 +0,0 @@
-import React, { HTMLAttributes } from "react";
-import styled from "styled-components";
-
-const Container = styled.div`
- display: flex;
- flex-direction: row;
- justify-content: space-between;
- min-height: 20px;
-`;
-
-type SummarySectionProps = {
- children: React.ReactNode;
-} & HTMLAttributes;
-
-const SummarySection = ({ children, ...rest }: SummarySectionProps) => (
- {children}
-);
-
-export default SummarySection;
diff --git a/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/FormSummary/SummaryValue.tsx b/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/FormSummary/SummaryValue.tsx
deleted file mode 100644
index 773ff5cf0941..000000000000
--- a/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/FormSummary/SummaryValue.tsx
+++ /dev/null
@@ -1,69 +0,0 @@
-import React from "react";
-import { useTranslation } from "react-i18next";
-import styled from "styled-components";
-import ButtonBase from "~/renderer/components/Button";
-import TextBase from "~/renderer/components/Text";
-
-export const Container = styled.div`
- display: flex;
- flex-direction: row;
- column-gap: 0.375rem;
- align-items: center;
- color: ${p => p.theme.colors.palette.text.shade100};
- justify-content: flex-end;
-`;
-export const Text = styled(TextBase).attrs(() => ({
- ff: "Inter",
- fontSize: "13px",
- fontWeight: 600,
- lineHeight: "1.4",
-}))`
- display: inline-block;
- color: ${p => p.theme.colors.palette.secondary.main};
-
- &:first-letter {
- text-transform: uppercase;
- }
-`;
-const Button = styled(ButtonBase).attrs(() => ({
- color: "palette.primary.main",
-}))`
- padding: 0;
- height: unset;
-`;
-
-export const NoValuePlaceholder = () => (
-
- {"-"}
-
-);
-
-const SummaryValue = ({
- value,
- handleChange,
- children,
-}: {
- value?: string;
- handleChange?: (() => void) | null;
- children?: React.ReactNode;
-}) => {
- const { t } = useTranslation();
-
- return (
-
- {children}
- {value && (
-
- {value}
-
- )}
- {handleChange ? (
-
- ) : null}
-
- );
-};
-
-export default SummaryValue;
diff --git a/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/FormSummary/index.tsx b/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/FormSummary/index.tsx
deleted file mode 100644
index ebc31449d6bd..000000000000
--- a/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/FormSummary/index.tsx
+++ /dev/null
@@ -1,82 +0,0 @@
-import { SwapTransactionType } from "@ledgerhq/live-common/exchange/swap/types";
-import React from "react";
-import styled from "styled-components";
-import { useIsSwapLiveFlagEnabled } from "../../hooks/useIsSwapLiveFlagEnabled";
-import SectionFees from "./SectionFees";
-import SectionTarget from "./SectionTarget";
-
-// TODO fix the any types
-const Form = styled.section.attrs<{ ready?: boolean }>(({ ready }) => ({
- style: ready
- ? {
- opacity: 1,
- maxHeight: "100vh",
- overflow: "auto",
- }
- : {},
-}))<{ ready?: boolean }>`
- display: grid;
- row-gap: 1.25rem;
- color: white;
- transition:
- max-height 800ms cubic-bezier(0.47, 0, 0.75, 0.72),
- opacity 400ms 400ms cubic-bezier(0.47, 0, 0.75, 0.72);
- transform-origin: top;
- height: auto;
- opacity: 0;
- max-height: 0;
- overflow: hidden;
-`;
-
-type SwapFormSummaryProps = {
- swapTransaction: SwapTransactionType;
- provider?: string;
-};
-
-const SwapFormSummary = ({ swapTransaction, provider }: SwapFormSummaryProps) => {
- const {
- transaction,
- status,
- updateTransaction,
- setTransaction,
- setToAccount,
- swap: { targetAccounts },
- } = swapTransaction;
-
- const {
- currency: fromCurrency,
- account: fromAccount,
- parentAccount: fromParentAccount,
- } = swapTransaction.swap.from;
-
- const { currency: toCurrency, account: toAccount } = swapTransaction.swap.to;
- const ratesState = swapTransaction.swap.rates;
- const hasRates = ratesState?.value?.length && ratesState?.value?.length > 0;
- const isDemo1Enabled = useIsSwapLiveFlagEnabled("ptxSwapLiveAppDemoOne");
-
- return (
-
- );
-};
-export default React.memo(SwapFormSummary);
diff --git a/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/FormSummary/types.ts b/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/FormSummary/types.ts
deleted file mode 100644
index 1d8be912d667..000000000000
--- a/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/FormSummary/types.ts
+++ /dev/null
@@ -1,12 +0,0 @@
-import { SwapTransactionType } from "@ledgerhq/live-common/exchange/swap/types";
-
-export type FormSummarySections = "provider" | "fees" | "rate" | "target";
-export type FormSummaryProps = {
- provider?: string;
- rate?: string;
- fees?: string;
- onProviderChange: Function;
- onFeesChange: Function;
- onTargetChange: Function;
- swapTransaction: SwapTransactionType;
-};
diff --git a/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/Migrations/SwapMigrationUI.tsx b/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/Migrations/SwapMigrationUI.tsx
deleted file mode 100644
index ad1cd2620491..000000000000
--- a/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/Migrations/SwapMigrationUI.tsx
+++ /dev/null
@@ -1,124 +0,0 @@
-import React from "react";
-import { useTranslation } from "react-i18next";
-import styled from "styled-components";
-
-import { usePageState } from "@ledgerhq/live-common/exchange/swap/hooks/index";
-import { SwapTransactionType } from "@ledgerhq/live-common/exchange/swap/types";
-import { Box } from "@ledgerhq/react-ui";
-import ButtonBase from "~/renderer/components/Button";
-import SwapFormRates from "../FormRates";
-import SwapFormSummary from "../FormSummary";
-import LoadingState from "../Rates/LoadingState";
-import { SwapWebManifestIDs } from "../SwapWebView";
-import { useIsSwapLiveFlagEnabled } from "../../hooks/useIsSwapLiveFlagEnabled";
-
-const Button = styled(ButtonBase)`
- width: 100%;
- justify-content: center;
-`;
-
-type SwapMigrationUIProps = {
- liveAppEnabled: boolean;
- liveApp: React.ReactNode;
- manifestID: string | undefined;
- // Demo 1 props
- pageState: ReturnType;
- swapTransaction: SwapTransactionType;
- provider?: string;
- // Demo 0 props
- disabled: boolean;
- onClick: () => void;
-};
-
-export const SwapMigrationUI = (props: SwapMigrationUIProps) => {
- const {
- liveAppEnabled,
- liveApp,
- manifestID,
- pageState,
- swapTransaction,
- provider,
- disabled,
- onClick,
- } = props;
- const { t } = useTranslation();
- const isDemo1Enabled = useIsSwapLiveFlagEnabled("ptxSwapLiveAppDemoOne");
-
- const nativeLoadingUI = pageState === "loading" ? : null;
- const nativeNetworkFeesUI =
- pageState === "loaded" || isDemo1Enabled ? (
-
- ) : null;
-
- const nativeQuotesUI =
- pageState === "loaded" && !isDemo1Enabled ? (
-
- ) : null;
-
- const nativeExchangeButtonUI = (
-
-
-
- );
-
- /**
- * Fall back to show all native UI. (without webview)
- */
- const allNativeUI = (
- <>
- {nativeLoadingUI}
- {nativeNetworkFeesUI}
- {nativeQuotesUI}
- {nativeExchangeButtonUI}
- >
- );
-
- /**
- * Live app disabled or unavailable, fallback to native UI
- */
- if (!liveAppEnabled || !liveApp) {
- return allNativeUI;
- }
-
- switch (true) {
- case manifestID?.startsWith(SwapWebManifestIDs.Demo0):
- /**
- * Demo 0 live app should only contain Exchange Button
- * Rest should be in native UI (e.g quotes)
- */
- return (
- <>
- {nativeLoadingUI}
- {nativeNetworkFeesUI}
- {nativeQuotesUI}
- {liveApp}
- >
- );
-
- case manifestID?.startsWith(SwapWebManifestIDs.Demo1):
- case manifestID?.startsWith(SwapWebManifestIDs.Demo3):
- /**
- * Demo 1 live app should contain:
- * - Exchange Button
- * - Quotes UI
- */
- return (
- <>
- {nativeNetworkFeesUI}
- {liveApp}
- >
- );
-
- /**
- * Fall back to show all native UI
- */
- default:
- return allNativeUI;
- }
-};
diff --git a/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/Rates/Countdown.tsx b/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/Rates/Countdown.tsx
deleted file mode 100644
index 25742ce14284..000000000000
--- a/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/Rates/Countdown.tsx
+++ /dev/null
@@ -1,45 +0,0 @@
-import React from "react";
-import { Trans } from "react-i18next";
-import styled from "styled-components";
-import Box from "~/renderer/components/Box";
-import Text from "~/renderer/components/Text";
-import AnimatedCountdown from "~/renderer/components/AnimatedCountdown";
-import { formatCountdown } from "~/renderer/screens/exchange/Swap2/Form/Rates/utils/formatCountdown";
-import { DEFAULT_SWAP_RATES_INTERVAL_MS } from "@ledgerhq/live-common/exchange/swap/const/timeout";
-
-export type Props = {
- countdown: number;
-};
-
-const CountdownText = styled(Text)`
- color: ${p => p.theme.colors.neutral.c70};
-`;
-
-export default function Countdown({ countdown }: Props) {
- return (
- <>
- {countdown >= 0 ? (
-
-
-
-
-
-
-
-
- {formatCountdown(countdown)}
-
-
- ) : (
-
-
-
- )}
- >
- );
-}
diff --git a/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/Rates/EmptyState.tsx b/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/Rates/EmptyState.tsx
deleted file mode 100644
index def65430840e..000000000000
--- a/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/Rates/EmptyState.tsx
+++ /dev/null
@@ -1,25 +0,0 @@
-import React from "react";
-import Box from "~/renderer/components/Box";
-import Text from "~/renderer/components/Text";
-import { Trans } from "react-i18next";
-
-function EmptyState() {
- return (
-
-
-
-
-
- );
-}
-export default React.memo(EmptyState);
diff --git a/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/Rates/LoadingState.tsx b/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/Rates/LoadingState.tsx
deleted file mode 100644
index a4b857d07133..000000000000
--- a/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/Rates/LoadingState.tsx
+++ /dev/null
@@ -1,60 +0,0 @@
-import React, { useEffect, useState } from "react";
-import Box from "~/renderer/components/Box";
-import Text from "~/renderer/components/Text";
-import { useTranslation } from "react-i18next";
-
-function Loader() {
- const [dots, setDots] = useState("");
- useEffect(() => {
- const interval = window.setInterval(() => {
- setDots(dots => (dots.length < 3 ? dots + "." : ""));
- }, 500);
- return () => clearInterval(interval);
- }, []);
-
- return (
-
- {dots}
-
- );
-}
-
-function LoadingState() {
- const { t } = useTranslation();
-
- return (
-
-
- {t("swap2.form.rates.loadingQuotes")}
-
-
-
- {t("swap2.form.rates.loadingDescription")}
-
-
- );
-}
-
-export default LoadingState;
diff --git a/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/Rates/NoQuoteSwapRate.tsx b/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/Rates/NoQuoteSwapRate.tsx
deleted file mode 100644
index 2de60b16b09f..000000000000
--- a/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/Rates/NoQuoteSwapRate.tsx
+++ /dev/null
@@ -1,44 +0,0 @@
-import React from "react";
-import { Text } from "@ledgerhq/react-ui";
-import styled from "styled-components";
-import { ExchangeRate } from "@ledgerhq/live-common/exchange/swap/types";
-import { Trans } from "react-i18next";
-import Rate from "./Rate";
-import { getProviderName } from "@ledgerhq/live-common/exchange/swap/utils/index";
-
-export type Props = {
- value: ExchangeRate;
- onSelect: (a: ExchangeRate) => void;
- selected?: boolean | null;
- icon?: string;
-};
-
-const SecondaryText = styled(Text)`
- color: ${p => p.theme.colors.neutral.c70};
-`;
-
-function NoQuoteSwapRate({ value, selected, onSelect, icon }: Props) {
- return (
- }
- rightContainer={
-
-
-
- }
- >
- );
-}
-
-export default React.memo(NoQuoteSwapRate);
diff --git a/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/Rates/Rate.tsx b/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/Rates/Rate.tsx
deleted file mode 100644
index 244cf65ddfc3..000000000000
--- a/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/Rates/Rate.tsx
+++ /dev/null
@@ -1,89 +0,0 @@
-import React, { useCallback } from "react";
-import styled from "styled-components";
-import { Text } from "@ledgerhq/react-ui";
-import Box from "~/renderer/components/Box";
-import ProviderIcon from "~/renderer/components/ProviderIcon";
-import { ExchangeRate } from "@ledgerhq/live-common/exchange/swap/types";
-
-const ProviderContainer = styled(Box).attrs({
- horizontal: true,
- alignItems: "center",
- ff: "Inter|SemiBold",
-})<{ selected?: boolean | null }>`
- border: 1px solid ${p => p.theme.colors.palette.divider};
- border-radius: 4px;
- cursor: pointer;
- ${p =>
- p.selected
- ? `
- border-color: ${p.theme.colors.palette.primary.main};
- box-shadow: 0px 0px 0px 4px ${p.theme.colors.primary.c60};
- background-color: ${p.theme.colors.primary.c20};
- `
- : `
- :hover {
- box-shadow: 0px 0px 2px 1px ${p.theme.colors.palette.divider};
- }`}
-`;
-const SecondaryText = styled(Text)`
- color: ${p => p.theme.colors.neutral.c70};
-`;
-
-export type Props = {
- value: ExchangeRate;
- onSelect: (a: ExchangeRate) => void;
- selected?: boolean | null;
- icon?: string;
- title: string;
- subtitle: React.ReactNode;
- centerContainer?: JSX.Element;
- rightContainer: JSX.Element;
-};
-
-function Rate({
- value,
- selected,
- onSelect,
- icon,
- title,
- subtitle,
- centerContainer,
- rightContainer,
-}: Props) {
- const handleSelection = useCallback(() => onSelect(value), [value, onSelect]);
-
- return (
-
- {icon && (
-
-
-
- )}
-
-
-
- {title}
-
- {subtitle}
-
-
-
- {centerContainer}
-
-
- {rightContainer}
-
-
-
-
- );
-}
-
-export default React.memo(Rate);
diff --git a/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/Rates/SwapRate.tsx b/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/Rates/SwapRate.tsx
deleted file mode 100644
index 4167b5052bd2..000000000000
--- a/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/Rates/SwapRate.tsx
+++ /dev/null
@@ -1,109 +0,0 @@
-import React from "react";
-import styled from "styled-components";
-import { Text } from "@ledgerhq/react-ui";
-import Box from "~/renderer/components/Box";
-import FormattedVal from "~/renderer/components/FormattedVal";
-import { ExchangeRate, SwapSelectorStateType } from "@ledgerhq/live-common/exchange/swap/types";
-import { getProviderName } from "@ledgerhq/live-common/exchange/swap/utils/index";
-import Price from "~/renderer/components/Price";
-import CounterValue from "~/renderer/components/CounterValue";
-import { Trans } from "react-i18next";
-import Rate from "./Rate";
-import { Currency } from "@ledgerhq/types-cryptoassets";
-
-export type Props = {
- value: ExchangeRate;
- onSelect: (a: ExchangeRate) => void;
- selected?: boolean | null;
- fromCurrency?: SwapSelectorStateType["currency"];
- toCurrency?: SwapSelectorStateType["currency"];
- isRegistrationRequired: boolean;
-};
-
-const SecondaryText = styled(Text)`
- color: ${p => p.theme.colors.neutral.c70};
-`;
-const StyledCounterValue = styled(CounterValue)`
- color: ${p => p.theme.colors.neutral.c70};
-`;
-
-function SwapRate({
- value,
- selected,
- onSelect,
- fromCurrency,
- toCurrency,
- isRegistrationRequired,
-}: Props) {
- const { toAmount: amount, provider } = value;
- return (
-
- }
- centerContainer={
-
-
-
-
-
-
-
-
- }
- rightContainer={
- <>
-
-
- >
- }
- >
- );
-}
-
-export default React.memo(SwapRate);
diff --git a/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/Rates/filterRates.spec.ts b/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/Rates/filterRates.spec.ts
deleted file mode 100644
index 135b0e4dc521..000000000000
--- a/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/Rates/filterRates.spec.ts
+++ /dev/null
@@ -1,141 +0,0 @@
-import { ExchangeRate } from "@ledgerhq/live-common/exchange/swap/types";
-import { filterRates } from "~/renderer/screens/exchange/Swap2/Form/Rates/filterRates";
-import { FILTER } from "@ledgerhq/live-common/exchange/swap/utils/index";
-
-const rates: Partial[] = [
- {
- providerType: "CEX",
- tradeMethod: "fixed",
- provider: "changelly",
- },
- {
- providerType: "DEX",
- tradeMethod: "fixed",
- provider: "oneinch",
- },
- {
- providerType: "CEX",
- tradeMethod: "float",
- provider: "other-cex-provider",
- },
- {
- providerType: "DEX",
- tradeMethod: "float",
- provider: "other-dex-provider",
- },
-];
-
-describe("filterRates", () => {
- it("does not apply any filters", () => {
- const filtered = filterRates(rates as ExchangeRate[], []);
- expect(filtered).toEqual(rates);
- });
-
- it("filters centralised rates", () => {
- const filtered = filterRates(rates as ExchangeRate[], [FILTER.centralised]);
- expect(filtered).toEqual([
- {
- providerType: "CEX",
- tradeMethod: "fixed",
- provider: "changelly",
- },
- {
- providerType: "CEX",
- tradeMethod: "float",
- provider: "other-cex-provider",
- },
- ]);
- });
-
- it("filters centralised floating rates", () => {
- const filtered = filterRates(rates as ExchangeRate[], [FILTER.centralised, FILTER.float]);
- expect(filtered).toEqual([
- {
- providerType: "CEX",
- tradeMethod: "float",
- provider: "other-cex-provider",
- },
- ]);
- });
-
- it("filters centralised fixed rates", () => {
- const filtered = filterRates(rates as ExchangeRate[], [FILTER.centralised, FILTER.fixed]);
- expect(filtered).toEqual([
- {
- providerType: "CEX",
- tradeMethod: "fixed",
- provider: "changelly",
- },
- ]);
- });
-
- it("filters decentralised rates", () => {
- const filtered = filterRates(rates as ExchangeRate[], [FILTER.decentralised]);
- expect(filtered).toEqual([
- {
- providerType: "DEX",
- tradeMethod: "fixed",
- provider: "oneinch",
- },
- {
- providerType: "DEX",
- tradeMethod: "float",
- provider: "other-dex-provider",
- },
- ]);
- });
-
- it("filters decentralised floating rates", () => {
- const filtered = filterRates(rates as ExchangeRate[], [FILTER.decentralised, FILTER.float]);
- expect(filtered).toEqual([
- {
- providerType: "DEX",
- tradeMethod: "float",
- provider: "other-dex-provider",
- },
- ]);
- });
-
- it("filters decentralised fixed rates", () => {
- const filtered = filterRates(rates as ExchangeRate[], [FILTER.decentralised, FILTER.fixed]);
- expect(filtered).toEqual([
- {
- providerType: "DEX",
- tradeMethod: "fixed",
- provider: "oneinch",
- },
- ]);
- });
-
- it("filters fixed rates", () => {
- const filtered = filterRates(rates as ExchangeRate[], [FILTER.fixed]);
- expect(filtered).toEqual([
- {
- providerType: "CEX",
- tradeMethod: "fixed",
- provider: "changelly",
- },
- {
- providerType: "DEX",
- tradeMethod: "fixed",
- provider: "oneinch",
- },
- ]);
- });
-
- it("filters floating rates", () => {
- const filtered = filterRates(rates as ExchangeRate[], [FILTER.float]);
- expect(filtered).toEqual([
- {
- providerType: "CEX",
- tradeMethod: "float",
- provider: "other-cex-provider",
- },
- {
- providerType: "DEX",
- tradeMethod: "float",
- provider: "other-dex-provider",
- },
- ]);
- });
-});
diff --git a/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/Rates/filterRates.ts b/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/Rates/filterRates.ts
deleted file mode 100644
index 569a2f388052..000000000000
--- a/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/Rates/filterRates.ts
+++ /dev/null
@@ -1,25 +0,0 @@
-import { ExchangeRate } from "@ledgerhq/live-common/exchange/swap/types";
-import { FILTER } from "@ledgerhq/live-common/exchange/swap/utils/index";
-
-export const filterRates = (
- rates: ExchangeRate[] | undefined,
- filters: string[],
-): ExchangeRate[] => {
- let filteredRates = rates ?? [];
- for (const filter of filters) {
- switch (filter) {
- case FILTER.centralised:
- filteredRates = filteredRates.filter(rate => rate.providerType === "CEX");
- break;
- case FILTER.decentralised:
- filteredRates = filteredRates.filter(rate => rate.providerType === "DEX");
- break;
- case FILTER.float:
- filteredRates = filteredRates.filter(rate => rate.tradeMethod === "float");
- break;
- case FILTER.fixed:
- filteredRates = filteredRates.filter(rate => rate.tradeMethod === "fixed");
- }
- }
- return filteredRates;
-};
diff --git a/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/Rates/index.tsx b/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/Rates/index.tsx
deleted file mode 100644
index bd94f6ae9f22..000000000000
--- a/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/Rates/index.tsx
+++ /dev/null
@@ -1,258 +0,0 @@
-import { getFeesUnit } from "@ledgerhq/live-common/account/index";
-import { formatCurrencyUnit } from "@ledgerhq/live-common/currencies/index";
-import {
- ExchangeRate,
- RatesReducerState,
- SwapSelectorStateType,
-} from "@ledgerhq/live-common/exchange/swap/types";
-import { isRegistrationRequired } from "@ledgerhq/live-common/exchange/swap/utils/index";
-import React, { useCallback, useEffect, useMemo, useState } from "react";
-import { Trans } from "react-i18next";
-import { useDispatch, useSelector } from "react-redux";
-import styled from "styled-components";
-import { rateSelector, updateRateAction } from "~/renderer/actions/swap";
-import { track } from "~/renderer/analytics/segment";
-import TrackPage from "~/renderer/analytics/TrackPage";
-import Box from "~/renderer/components/Box";
-import Text from "~/renderer/components/Text";
-import Tooltip from "~/renderer/components/Tooltip";
-import IconInfoCircle from "~/renderer/icons/InfoCircle";
-import { useGetSwapTrackingProperties } from "../../utils/index";
-import Countdown from "./Countdown";
-import { filterRates } from "./filterRates";
-import LoadingState from "./LoadingState";
-import NoQuoteSwapRate from "./NoQuoteSwapRate";
-import SwapRate from "./SwapRate";
-
-type Props = {
- fromCurrency: SwapSelectorStateType["currency"];
- toCurrency: SwapSelectorStateType["currency"];
- rates: RatesReducerState["value"];
- provider: string | undefined | null;
- countdownSecondsToRefresh: number | undefined;
-};
-
-const TableHeader = styled(Box).attrs({
- horizontal: true,
- alignItems: "center",
- ff: "Inter|SemiBold",
- justifyContent: "space-between",
- fontWeight: "500",
- fontSize: 3,
- color: "palette.text.shade40",
- pl: 3,
- pr: 2,
- mt: 3,
- pb: 10,
-})`
- border-bottom: 1px solid ${p => p.theme.colors.neutral.c30};
-`;
-
-export default function ProviderRate({
- fromCurrency,
- toCurrency,
- rates,
- provider,
- countdownSecondsToRefresh,
-}: Props) {
- const swapDefaultTrack = useGetSwapTrackingProperties();
- const dispatch = useDispatch();
- const [filter] = useState([]);
- const [defaultPartner, setDefaultPartner] = useState(null);
- const [isRegistrationRequiredMap, setIsRegistrationRequiredMap] = useState<{
- [x: string]: boolean;
- }>({});
- const selectedRate = useSelector(rateSelector);
- const filteredRates = useMemo(() => filterRates(rates, filter), [rates, filter]);
- const providers = useMemo(() => [...new Set(rates?.map(rate => rate.provider) ?? [])], [rates]);
- const exchangeRates = useMemo(() => {
- return toCurrency && rates
- ? rates.map(({ toAmount }) => formatCurrencyUnit(getFeesUnit(toCurrency), toAmount))
- : [];
- }, [toCurrency, rates]);
- useEffect(() => {
- if (providers) {
- const fetchlol = async () => {
- const results = await Promise.all(
- providers.map(async provider => {
- const isRequired = await isRegistrationRequired(provider);
- return { [provider]: isRequired };
- }),
- );
-
- const resultsMap = results.reduce((acc, result) => ({ ...acc, ...result }), {});
- setIsRegistrationRequiredMap(resultsMap);
- };
- fetchlol();
- }
- }, [providers]);
- const updateRate = useCallback(
- (rate: ExchangeRate) => {
- const value = rate.rate ?? rate.provider;
- track("partner_clicked", {
- page: "Page Swap Form",
- ...swapDefaultTrack,
- swap_type: rate.tradeMethod,
- value,
- partner: rate.provider,
- defaultPartner,
- });
- dispatch(updateRateAction(rate));
- },
- [defaultPartner, dispatch, swapDefaultTrack],
- );
-
- useEffect(() => {
- // if the selected rate in redux is not in the filtered rates, we need to update it
- if (
- selectedRate &&
- filteredRates.length > 0 &&
- !filteredRates.some(
- r => r.provider === selectedRate.provider && r.tradeMethod === selectedRate.tradeMethod,
- )
- ) {
- const firstRate = filteredRates[0];
- setDefaultPartner(firstRate?.provider);
- dispatch(updateRateAction(firstRate));
- }
-
- // if there is no selected rate but there is a filtered rate, we need to update it
- if (!selectedRate && filteredRates.length > 0) {
- const firstRate = filteredRates[0];
- setDefaultPartner(firstRate?.provider);
- dispatch(updateRateAction(firstRate));
- }
-
- // if there are no filtered rates, we need to unset the selected rate
- if (selectedRate && filteredRates.length === 0) {
- setDefaultPartner(null);
- dispatch(updateRateAction(null));
- }
- }, [filteredRates, selectedRate, dispatch]);
-
- return (
-
-
-
-
-
-
- {countdownSecondsToRefresh && (
-
-
-
- )}
-
-
-
-
-
-
-
-
-
- }
- >
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- }
- >
-
-
-
-
-
-
-
-
-
-
-
-
- }
- >
-
-
-
-
-
-
-
- {filteredRates.map(rate => {
- const isSelected =
- selectedRate &&
- selectedRate.provider === rate.provider &&
- selectedRate.tradeMethod === rate.tradeMethod;
- return rate.providerType === "DEX" && rate.rate === undefined ? (
-
- ) : (
-
- );
- })}
-
- {!filteredRates.length && }
-
- );
-}
diff --git a/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/Rates/utils/formatCountdown.test.ts b/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/Rates/utils/formatCountdown.test.ts
deleted file mode 100644
index 2fc824bf9619..000000000000
--- a/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/Rates/utils/formatCountdown.test.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-import { formatCountdown } from "~/renderer/screens/exchange/Swap2/Form/Rates/utils/formatCountdown";
-
-describe("formatCountdown", () => {
- it("formats countdown to timer", () => {
- expect(formatCountdown(1)).toBe("00:01");
- expect(formatCountdown(10)).toBe("00:10");
- expect(formatCountdown(60)).toBe("01:00");
- expect(formatCountdown(61)).toBe("01:01");
- });
-});
diff --git a/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/Rates/utils/formatCountdown.ts b/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/Rates/utils/formatCountdown.ts
deleted file mode 100644
index b8981ce37f90..000000000000
--- a/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/Rates/utils/formatCountdown.ts
+++ /dev/null
@@ -1,5 +0,0 @@
-export const formatCountdown = (timeS: number) => {
- const minutes = Math.floor(timeS / 60);
- const seconds = timeS % 60;
- return `${minutes.toString().padStart(2, "0")}:${seconds.toString().padStart(2, "0")}`;
-};
diff --git a/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/SwapWebView.tsx b/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/SwapWebView.tsx
deleted file mode 100644
index 44d35880b5bd..000000000000
--- a/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/SwapWebView.tsx
+++ /dev/null
@@ -1,585 +0,0 @@
-import {
- getAccountCurrency,
- getMainAccount,
- getParentAccount,
-} from "@ledgerhq/live-common/account/helpers";
-import { handlers as loggerHandlers } from "@ledgerhq/live-common/wallet-api/CustomLogger/server";
-import { getAccountIdFromWalletAccountId } from "@ledgerhq/live-common/wallet-api/converters";
-import { SubAccount } from "@ledgerhq/types-live";
-import { SwapOperation } from "@ledgerhq/types-live/lib/swap";
-import BigNumber from "bignumber.js";
-import React, { useEffect, useMemo, useRef, useState } from "react";
-import { useDispatch, useSelector } from "react-redux";
-import styled from "styled-components";
-import { updateAccountWithUpdater } from "~/renderer/actions/accounts";
-import { Web3AppWebview } from "~/renderer/components/Web3AppWebview";
-import { initialWebviewState } from "~/renderer/components/Web3AppWebview/helpers";
-import { WebviewAPI, WebviewProps, WebviewState } from "~/renderer/components/Web3AppWebview/types";
-import { TopBar } from "~/renderer/components/WebPlatformPlayer/TopBar";
-import { context } from "~/renderer/drawers/Provider";
-import useTheme from "~/renderer/hooks/useTheme";
-import {
- counterValueCurrencySelector,
- discreetModeSelector,
- enablePlatformDevToolsSelector,
- languageSelector,
-} from "~/renderer/reducers/settings";
-import {
- transformToBigNumbers,
- useGetSwapTrackingProperties,
- useRedirectToSwapHistory,
-} from "../utils/index";
-import WebviewErrorDrawer from "./WebviewErrorDrawer/index";
-
-import { NetworkDown } from "@ledgerhq/errors";
-import { getAccountBridge } from "@ledgerhq/live-common/bridge/impl";
-import { formatCurrencyUnit } from "@ledgerhq/live-common/currencies/index";
-import { SwapExchangeRateAmountTooLow } from "@ledgerhq/live-common/errors";
-import { useSwapLiveConfig } from "@ledgerhq/live-common/exchange/swap/hooks/index";
-import { getAbandonSeedAddress } from "@ledgerhq/live-common/exchange/swap/hooks/useFromState";
-import { SwapLiveError } from "@ledgerhq/live-common/exchange/swap/types";
-import {
- convertToAtomicUnit,
- convertToNonAtomicUnit,
- getCustomFeesPerFamily,
-} from "@ledgerhq/live-common/exchange/swap/webApp/utils";
-import { LiveAppManifest } from "@ledgerhq/live-common/platform/types";
-import { CryptoCurrency, TokenCurrency } from "@ledgerhq/types-cryptoassets";
-import { useTranslation } from "react-i18next";
-import { track } from "~/renderer/analytics/segment";
-import { usePTXCustomHandlers } from "~/renderer/components/WebPTXPlayer/CustomHandlers";
-import { NetworkStatus, useNetworkStatus } from "~/renderer/hooks/useNetworkStatus";
-import { flattenAccountsSelector } from "~/renderer/reducers/accounts";
-import { captureException } from "~/sentry/renderer";
-import { CustomSwapQuotesState } from "../hooks/useSwapLiveAppQuoteState";
-import FeesDrawerLiveApp from "./FeesDrawerLiveApp";
-
-export class UnableToLoadSwapLiveError extends Error {
- constructor(message: string) {
- const name = "UnableToLoadSwapLiveError";
- super(message || name);
- this.name = name;
- this.message = message;
- }
-}
-
-export type SwapProps = {
- provider: string;
- fromAccountId: string;
- fromParentAccountId?: string;
- toAccountId: string;
- fromAmount: string;
- toAmount?: string;
- quoteId: string;
- rate: string;
- feeStrategy: string;
- customFeeConfig: string;
- cacheKey: string;
- loading: boolean;
- error: boolean;
- providerRedirectURL: string;
- toNewTokenId: string;
- swapApiBase: string;
- estimatedFees: string;
- estimatedFeesUnit: string;
-};
-
-export type SwapWebProps = {
- manifest: LiveAppManifest;
- liveAppUnavailable: () => void;
- setQuoteState?: (next: CustomSwapQuotesState) => void;
- swapState?: Partial;
- isMaxEnabled?: boolean;
- sourceCurrency?: TokenCurrency | CryptoCurrency;
- targetCurrency?: TokenCurrency | CryptoCurrency;
-};
-
-export const SwapWebManifestIDs = {
- Demo0: "swap-live-app-demo-0",
- Demo1: "swap-live-app-demo-1",
- Demo3: "swap-live-app-demo-3",
-};
-
-const SwapWebAppWrapper = styled.div`
- width: 100%;
- flex: 1;
-`;
-
-const getSegWitAbandonSeedAddress = (): string => "bc1qed3mqr92zvq2s782aqkyx785u23723w02qfrgs";
-
-const defaultContentSize: Record = {};
-
-const SwapWebView = ({
- manifest,
- swapState,
- liveAppUnavailable,
- isMaxEnabled,
- sourceCurrency,
- targetCurrency,
- setQuoteState,
-}: SwapWebProps) => {
- const {
- colors: {
- palette: { type: themeType },
- },
- } = useTheme();
- const dispatch = useDispatch();
- const { t } = useTranslation();
- const webviewAPIRef = useRef(null);
- const { setDrawer } = React.useContext(context);
- const accounts = useSelector(flattenAccountsSelector);
- const [webviewState, setWebviewState] = useState(initialWebviewState);
- const discreetMode = useSelector(discreetModeSelector);
- const fiatCurrency = useSelector(counterValueCurrencySelector);
- const locale = useSelector(languageSelector);
- const redirectToHistory = useRedirectToSwapHistory();
- const enablePlatformDevTools = useSelector(enablePlatformDevToolsSelector);
- const { networkStatus } = useNetworkStatus();
- const isOffline = networkStatus === NetworkStatus.OFFLINE;
- const swapDefaultTrack = useGetSwapTrackingProperties();
- const swapLiveEnabledFlag = useSwapLiveConfig();
-
- const hasSwapState = !!swapState;
- const customPTXHandlers = usePTXCustomHandlers(manifest, accounts);
-
- const { fromCurrency, addressFrom, addressTo } = useMemo(() => {
- const [, , fromCurrency, addressFrom] =
- getAccountIdFromWalletAccountId(swapState?.fromAccountId || "")?.split(":") || [];
-
- const [, , toCurrency, addressTo] =
- getAccountIdFromWalletAccountId(swapState?.toAccountId || "")?.split(":") || [];
-
- return {
- fromCurrency,
- addressFrom,
- toCurrency,
- addressTo,
- };
- }, [swapState?.fromAccountId, swapState?.toAccountId]);
-
- const [windowContentSize, setWindowContentSize] = useState(defaultContentSize);
-
- const customHandlers = useMemo(() => {
- return {
- ...loggerHandlers,
- ...customPTXHandlers,
- "custom.swapStateGet": () => {
- return Promise.resolve(swapState);
- },
- "custom.setContentSize": ({ params }: { params?: Record }) => {
- if (params) {
- setWindowContentSize(params);
- }
- return Promise.resolve();
- },
- "custom.setQuote": (quote: {
- params?: {
- amountTo?: number;
- amountToCounterValue?: { value: number; fiat: string };
- code?: string;
- parameter: { minAmount: string; maxAmount: string };
- };
- }) => {
- const toUnit = targetCurrency?.units[0];
- const fromUnit = sourceCurrency?.units[0];
-
- if (!quote.params) {
- setQuoteState?.({
- amountTo: undefined,
- swapError: undefined,
- counterValue: undefined,
- });
- return Promise.resolve();
- }
-
- if (quote.params?.code && fromUnit) {
- switch (quote.params.code) {
- case "minAmountError":
- setQuoteState?.({
- amountTo: undefined,
- counterValue: undefined,
- swapError: new SwapExchangeRateAmountTooLow(undefined, {
- minAmountFromFormatted: formatCurrencyUnit(
- fromUnit,
- new BigNumber(quote.params.parameter.minAmount).times(10 ** fromUnit.magnitude),
- {
- alwaysShowSign: false,
- disableRounding: true,
- showCode: true,
- },
- ),
- }),
- });
- return Promise.resolve();
- case "maxAmountError":
- setQuoteState?.({
- amountTo: undefined,
- counterValue: undefined,
- swapError: new SwapExchangeRateAmountTooLow(undefined, {
- minAmountFromFormatted: formatCurrencyUnit(
- fromUnit,
- new BigNumber(quote.params.parameter.maxAmount).times(10 ** fromUnit.magnitude),
- {
- alwaysShowSign: false,
- disableRounding: true,
- showCode: true,
- },
- ),
- }),
- });
- return Promise.resolve();
- }
- }
-
- if (toUnit && quote?.params?.amountTo) {
- const amountTo = BigNumber(quote?.params?.amountTo).times(10 ** toUnit.magnitude);
- const counterValue = quote?.params?.amountToCounterValue?.value
- ? BigNumber(quote.params.amountToCounterValue.value).times(
- 10 ** fiatCurrency.units[0].magnitude,
- )
- : undefined;
-
- setQuoteState?.({
- amountTo,
- counterValue: counterValue,
- swapError: undefined,
- });
- }
-
- return Promise.resolve();
- },
- // TODO: when we need bidirectional communication
- // "custom.swapStateSet": (params: CustomHandlersParams) => {
- // return Promise.resolve();
- // },
- "custom.saveSwapToHistory": ({
- params,
- }: {
- params: { swap: SwapProps; transaction_id: string };
- }) => {
- const { swap, transaction_id } = params;
- if (!swap || !transaction_id || !swap.provider || !swap.fromAmount || !swap.toAmount) {
- return Promise.reject("Cannot save swap missing params");
- }
- const fromId = getAccountIdFromWalletAccountId(swap.fromAccountId);
- const toId = getAccountIdFromWalletAccountId(swap.toAccountId);
- if (!fromId || !toId) return Promise.reject("Accounts not found");
- const operationId = `${fromId}-${transaction_id}-OUT`;
-
- const swapOperation: SwapOperation = {
- status: "pending",
- provider: swap.provider,
- operationId,
- swapId: transaction_id,
- receiverAccountId: toId,
- tokenId: toId,
- fromAmount: new BigNumber(swap.fromAmount),
- toAmount: new BigNumber(swap.toAmount),
- };
-
- dispatch(
- updateAccountWithUpdater(fromId, account => {
- const fromCurrency = getAccountCurrency(account);
- const isFromToken = fromCurrency.type === "TokenCurrency";
- const subAccounts = account.type === "Account" && account.subAccounts;
- return isFromToken && subAccounts
- ? {
- ...account,
- subAccounts: subAccounts.map((a: SubAccount) => {
- const subAccount = {
- ...a,
- swapHistory: [...a.swapHistory, swapOperation],
- };
- return a.id === fromId ? subAccount : a;
- }),
- }
- : { ...account, swapHistory: [...account.swapHistory, swapOperation] };
- }),
- );
- return Promise.resolve();
- },
- "custom.swapRedirectToHistory": () => {
- redirectToHistory();
- },
- "custom.getFee": async ({
- params,
- }: {
- params: {
- fromAccountId: string;
- fromAmount: string;
- feeStrategy: string;
- openDrawer: boolean;
- customFeeConfig: object;
- SWAP_VERSION: string;
- };
- }): Promise<{
- feesStrategy: string;
- estimatedFees: BigNumber | undefined;
- errors: object;
- warnings: object;
- customFeeConfig: object;
- }> => {
- const realFromAccountId = getAccountIdFromWalletAccountId(params.fromAccountId);
- if (!realFromAccountId) {
- return Promise.reject(new Error(`accountId ${params.fromAccountId} unknown`));
- }
-
- const fromAccount = accounts.find(acc => acc.id === realFromAccountId);
- if (!fromAccount) {
- return Promise.reject(new Error(`accountId ${params.fromAccountId} unknown`));
- }
- const fromParentAccount = getParentAccount(fromAccount, accounts);
-
- const mainAccount = getMainAccount(fromAccount, fromParentAccount);
- const bridge = getAccountBridge(fromAccount, fromParentAccount);
-
- const subAccountId = fromAccount.type !== "Account" && fromAccount.id;
- const transaction = bridge.createTransaction(mainAccount);
-
- const preparedTransaction = await bridge.prepareTransaction(mainAccount, {
- ...transaction,
- subAccountId,
- recipient:
- mainAccount.currency.id === "bitcoin"
- ? getSegWitAbandonSeedAddress()
- : getAbandonSeedAddress(mainAccount.currency.id),
- amount: convertToAtomicUnit({
- amount: new BigNumber(params.fromAmount),
- account: fromAccount,
- }),
- feesStrategy: params.feeStrategy || "medium",
- ...transformToBigNumbers(params.customFeeConfig),
- });
- let status = await bridge.getTransactionStatus(mainAccount, preparedTransaction);
- const statusInit = status;
- let finalTx = preparedTransaction;
- let customFeeConfig = transaction && getCustomFeesPerFamily(finalTx);
- const setTransaction = async (newTransaction: Transaction): Promise => {
- status = await bridge.getTransactionStatus(mainAccount, newTransaction);
- customFeeConfig = transaction && getCustomFeesPerFamily(newTransaction);
- finalTx = newTransaction;
- return newTransaction;
- };
-
- if (!params.openDrawer) {
- // filters out the custom fee config for chains without drawer
- const config = ["evm", "bitcoin"].includes(transaction.family)
- ? { hasDrawer: true, ...customFeeConfig }
- : {};
- return {
- feesStrategy: finalTx.feesStrategy,
- estimatedFees: convertToNonAtomicUnit({
- amount: status.estimatedFees,
- account: mainAccount,
- }),
- errors: status.errors,
- warnings: status.warnings,
- customFeeConfig: config,
- };
- }
-
- return new Promise<{
- feesStrategy: string;
- estimatedFees: BigNumber | undefined;
- errors: object;
- warnings: object;
- customFeeConfig: object;
- }>(resolve => {
- const performClose = (save: boolean) => {
- track("button_clicked2", {
- button: save ? "continueNetworkFees" : "closeNetworkFees",
- page: "quoteSwap",
- ...swapDefaultTrack,
- swapVersion: params.SWAP_VERSION,
- value: finalTx.feesStrategy || "custom",
- });
- setDrawer(undefined);
- if (!save) {
- resolve({
- feesStrategy: params.feeStrategy,
- estimatedFees: convertToNonAtomicUnit({
- amount: statusInit.estimatedFees,
- account: mainAccount,
- }),
- errors: statusInit.errors,
- warnings: statusInit.warnings,
- customFeeConfig,
- });
- }
- resolve({
- // little hack to make sure we do not return null (for bitcoin for instance)
- feesStrategy: finalTx.feesStrategy || "custom",
- estimatedFees: convertToNonAtomicUnit({
- amount: status.estimatedFees,
- account: mainAccount,
- }),
- errors: status.errors,
- warnings: status.warnings,
- customFeeConfig,
- });
- };
-
- setDrawer(
- FeesDrawerLiveApp,
- {
- setTransaction,
- account: fromAccount,
- parentAccount: fromParentAccount,
- status: status,
- provider: undefined,
- disableSlowStrategy: true,
- transaction: preparedTransaction,
- onRequestClose: (save: boolean) => performClose(save),
- },
- {
- title: t("swap2.form.details.label.fees"),
- forceDisableFocusTrap: true,
- onRequestClose: () => performClose(false),
- },
- );
- });
- },
- };
- // eslint-disable-next-line react-hooks/exhaustive-deps
- }, [swapState]);
-
- useEffect(() => {
- if (webviewState.url.includes("/unknown-error")) {
- // the live app has re-directed to /unknown-error. Handle this in callback, probably wallet-api failure.
- onSwapWebviewError();
- }
- // eslint-disable-next-line react-hooks/exhaustive-deps
- }, [webviewState.url]);
-
- const hashString = useMemo(() => {
- const searchParams = new URLSearchParams();
-
- const swapParams = {
- addressFrom: addressFrom,
- addressTo: addressTo,
- amountFrom: swapState?.fromAmount,
- from: sourceCurrency?.id,
- hasError: swapState?.error ? "true" : undefined, // append param only if error is true
- isMaxEnabled: isMaxEnabled,
- loading: swapState?.loading,
- fromParentAccountId: swapState?.fromParentAccountId,
- swapApiBase: process.env.SWAP_API_BASE,
- networkFees: swapState?.estimatedFees,
- networkFeesCurrency: fromCurrency,
- provider: swapState?.provider,
- to: targetCurrency?.id,
- toAccountId: swapState?.toAccountId,
- fromAccountId: swapState?.fromAccountId,
- toNewTokenId: swapState?.toNewTokenId,
- feeStrategy: swapState?.feeStrategy,
- customFeeConfig: swapState?.customFeeConfig,
- ...(swapLiveEnabledFlag?.params &&
- "variant" in swapLiveEnabledFlag.params &&
- swapLiveEnabledFlag.params.variant === "Demo0"
- ? { ptxSwapCoreExperiment: "Demo0" }
- : {}),
- };
-
- Object.entries(swapParams).forEach(([key, value]) => {
- if (value != null) {
- // Convert all values to string as URLSearchParams expects string values
- searchParams.append(key, String(value));
- }
- });
-
- return searchParams.toString();
- }, [
- addressFrom,
- addressTo,
- swapState?.fromAmount,
- swapState?.error,
- swapState?.loading,
- swapState?.fromParentAccountId,
- swapState?.estimatedFees,
- swapState?.provider,
- swapState?.toAccountId,
- swapState?.fromAccountId,
- swapState?.toNewTokenId,
- swapState?.feeStrategy,
- swapState?.customFeeConfig,
- sourceCurrency?.id,
- isMaxEnabled,
- fromCurrency,
- targetCurrency?.id,
- swapLiveEnabledFlag?.params,
- ]);
-
- useEffect(() => {
- // Determine the new quote state based on network status
- setQuoteState?.({
- amountTo: undefined,
- counterValue: undefined,
- ...{
- swapError: isOffline ? new NetworkDown() : undefined,
- },
- });
-
- // This effect runs when the network status changes or the target account changes
- // when the toAccountId has changed, quote state should be reset
- // eslint-disable-next-line react-hooks/exhaustive-deps
- }, [networkStatus, swapState?.toAccountId]);
-
- const webviewStyle = useMemo(
- () => ({ minHeight: windowContentSize.scrollHeight }),
- [windowContentSize.scrollHeight],
- );
-
- // return loader???
- if (!hasSwapState || isOffline) {
- return null;
- }
-
- const onSwapWebviewError = (error?: SwapLiveError) => {
- console.error("onSwapWebviewError", error);
- setDrawer(WebviewErrorDrawer, error);
- };
-
- const onStateChange: WebviewProps["onStateChange"] = state => {
- setWebviewState(state);
-
- if (!state.loading && state.isAppUnavailable) {
- liveAppUnavailable();
- captureException(
- new UnableToLoadSwapLiveError(
- '"Failed to load swap live app using WebPlatformPlayer in SwapWeb",',
- ),
- );
- }
- };
-
- return (
- <>
- {enablePlatformDevTools && (
-
- )}
-
-
-
-
- >
- );
-};
-
-export default SwapWebView;
diff --git a/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/SwapWebViewDemo3.tsx b/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/SwapWebViewDemo3.tsx
index a4ecf0c9a84f..59d09c3a3854 100644
--- a/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/SwapWebViewDemo3.tsx
+++ b/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/SwapWebViewDemo3.tsx
@@ -7,7 +7,6 @@ import { getEnv } from "@ledgerhq/live-env";
import { getNodeApi } from "@ledgerhq/coin-evm/api/node/index";
import { getMainAccount, getParentAccount } from "@ledgerhq/live-common/account/helpers";
import { getAccountBridge } from "@ledgerhq/live-common/bridge/impl";
-import { useSwapLiveConfig } from "@ledgerhq/live-common/exchange/swap/hooks/live-app-migration/useSwapLiveConfig";
import { getAbandonSeedAddress } from "@ledgerhq/live-common/exchange/swap/hooks/useFromState";
import {
convertToAtomicUnit,
@@ -53,6 +52,7 @@ import {
} from "../utils/index";
import FeesDrawerLiveApp from "./FeesDrawerLiveApp";
import WebviewErrorDrawer from "./WebviewErrorDrawer/index";
+
export class UnableToLoadSwapLiveError extends Error {
constructor(message: string) {
const name = "UnableToLoadSwapLiveError";
@@ -128,8 +128,6 @@ const SwapWebView = ({ manifest, liveAppUnavailable }: SwapWebProps) => {
defaultParentAccount?: Account;
from?: string;
}>();
- const swapLiveEnabledFlag = useSwapLiveConfig();
-
const { networkStatus } = useNetworkStatus();
const isOffline = networkStatus === NetworkStatus.OFFLINE;
@@ -406,20 +404,8 @@ const SwapWebView = ({ manifest, liveAppUnavailable }: SwapWebProps) => {
}
: {}),
...(state?.from ? { fromPath: simplifyFromPath(state?.from) } : {}),
- ...(swapLiveEnabledFlag?.params && "variant" in swapLiveEnabledFlag.params
- ? {
- ptxSwapCoreExperiment: swapLiveEnabledFlag.params?.variant as string,
- }
- : {}),
}).toString(),
- [
- isOffline,
- state?.defaultAccount,
- state?.defaultParentAccount,
- state?.from,
- walletState,
- swapLiveEnabledFlag,
- ],
+ [isOffline, state?.defaultAccount, state?.defaultParentAccount, state?.from, walletState],
);
const onSwapWebviewError = (error?: SwapLiveError) => {
diff --git a/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/TargetAccountDrawer/index.tsx b/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/TargetAccountDrawer/index.tsx
deleted file mode 100644
index 3201edc1d968..000000000000
--- a/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/TargetAccountDrawer/index.tsx
+++ /dev/null
@@ -1,286 +0,0 @@
-import React, { memo, useState, useEffect, useCallback, useMemo } from "react";
-import styled, { useTheme } from "styled-components";
-import { Trans } from "react-i18next";
-import { DrawerTitle } from "../DrawerTitle";
-import Box from "~/renderer/components/Box";
-import Text from "~/renderer/components/Text";
-import FormattedVal from "~/renderer/components/FormattedVal";
-import CryptoCurrencyIcon from "~/renderer/components/CryptoCurrencyIcon";
-import { AccountLike } from "@ledgerhq/types-live";
-import { getAccountCurrency } from "@ledgerhq/live-common/account/index";
-import Check from "~/renderer/icons/Check";
-import { SwapTransactionType } from "@ledgerhq/live-common/exchange/swap/types";
-import Tabbable from "~/renderer/components/Box/Tabbable";
-import { useDispatch, useSelector } from "react-redux";
-import { openModal } from "~/renderer/actions/modals";
-import Plus from "~/renderer/icons/Plus";
-import { rgba } from "~/renderer/styles/helpers";
-import { shallowAccountsSelector } from "~/renderer/reducers/accounts";
-import { context } from "~/renderer/drawers/Provider";
-import { track } from "~/renderer/analytics/segment";
-import { useGetSwapTrackingProperties } from "../../utils/index";
-import { useAccountUnit } from "~/renderer/hooks/useAccountUnit";
-import { getDefaultAccountName } from "@ledgerhq/live-wallet/accountName";
-import { useAccountName, useMaybeAccountName } from "~/renderer/reducers/wallet";
-
-const NonSelectableAccountWrapper = styled(Box)`
- column-gap: 8px;
-`;
-
-const AccountWrapper = styled(Tabbable)<{ selected?: boolean }>`
- cursor: pointer;
- column-gap: 8px;
- &:hover {
- background-color: ${p => p.theme.colors.palette.text.shade10};
- }
- ${p =>
- p.selected
- ? `
- background-color: ${p.theme.colors.palette.background.default};
- `
- : ""};
-`;
-const AddAccountIconContainer = styled(Tabbable)`
- padding: 5px;
- border-radius: 9999px;
- color: ${p => p.theme.colors.palette.primary.main};
- background: ${p => rgba(p.theme.colors.palette.primary.main, 0.2)};
-`;
-
-const AccountBox = styled(Box)`
- &,
- ${Text} {
- flex-shrink: 1;
- }
-
- ${Text} {
- overflow: hidden;
- text-overflow: ellipsis;
- }
-`;
-
-function AddAccountIcon() {
- return (
-
-
-
- );
-}
-
-const TargetAccount = memo(function TargetAccount({
- account,
- selected,
- setAccount,
- isChild,
-}: {
- account: AccountLike;
- selected?: boolean;
- setAccount?: Props["setToAccount"];
- isChild?: boolean;
-}) {
- const swapDefaultTrack = useGetSwapTrackingProperties();
- const allAccounts = useSelector(shallowAccountsSelector);
- const theme = useTheme();
- const currency = getAccountCurrency(account);
- const unit = useAccountUnit(account);
- const name = useAccountName(account);
- const parentAccount =
- account?.type !== "Account" ? allAccounts?.find(a => a.id === account?.parentId) : undefined;
- const parentName = useMaybeAccountName(parentAccount);
- const balance = account.spendableBalance || account.balance;
-
- const onClick = useCallback(() => {
- track("button_clicked2", {
- page: "Swap accounts",
- ...swapDefaultTrack,
- button: "account",
- currency,
- account: name,
- parentAccount: parentName,
- });
- setAccount && setAccount(currency, account, parentAccount || undefined);
- }, [swapDefaultTrack, currency, name, parentName, setAccount, account, parentAccount]);
-
- const Wrapper: React.ComponentType<
- React.ComponentProps & React.ComponentProps
- > = setAccount ? AccountWrapper : NonSelectableAccountWrapper;
-
- return (
-
-
- {isChild && (
-
- )}
-
-
-
-
- {name}
-
-
-
-
- {selected && (
-
-
-
- )}
-
-
- );
-});
-type Props = {
- accounts: AccountLike[] | undefined;
- selectedAccount: AccountLike | undefined;
- setToAccount: SwapTransactionType["setToAccount"];
- setDrawerStateRef: {
- current:
- | ((a: { selectedAccount: AccountLike; targetAccounts: AccountLike[] }) => void)
- | undefined
- | null;
- };
-};
-
-export default function TargetAccountDrawer({
- accounts,
- selectedAccount: initialSelectedAccount,
- setToAccount,
- setDrawerStateRef,
-}: Props) {
- const swapDefaultTrack = useGetSwapTrackingProperties();
- const allAccounts = useSelector(shallowAccountsSelector);
- const dispatch = useDispatch();
- const { setDrawer } = React.useContext(context);
- const [{ selectedAccount, targetAccounts }, setState] = useState({
- selectedAccount: initialSelectedAccount,
- targetAccounts: accounts,
- });
- const currency = getAccountCurrency(selectedAccount);
- useEffect(() => {
- setDrawerStateRef.current = setState;
- return () => {
- setDrawerStateRef.current = null;
- };
- }, [setDrawerStateRef]);
- const handleAddAccount = () =>
- dispatch(
- openModal("MODAL_ADD_ACCOUNTS", {
- currency,
- ...swapDefaultTrack,
- }),
- );
- const handleAccountPick: Props["setToAccount"] = (currency, account, parentAccount) => {
- setToAccount(currency, account, parentAccount);
- setDrawer(undefined);
- };
-
- const accountsList:
- | {
- account: AccountLike;
- subAccounts: AccountLike[];
- }[]
- | undefined = useMemo(
- () =>
- targetAccounts &&
- Object.values(
- targetAccounts.reduce(
- (result, account) => {
- const parentId = "parentId" in account && account.parentId;
- if (parentId) {
- result[parentId] = result[parentId] ?? {
- account: allAccounts.find(acc => acc.id === parentId),
- subAccounts: [],
- };
- result[parentId].subAccounts.push(account);
- return result;
- } else {
- result[account.id] = result[account.id] ?? {
- account,
- subAccounts: [],
- };
- return result;
- }
- },
- {} as Record<
- string,
- {
- account: AccountLike;
- subAccounts: AccountLike[];
- }
- >,
- ),
- ),
- [targetAccounts, allAccounts],
- );
-
- return (
-
-
-
- {accountsList?.map(({ account, subAccounts }) => (
- <>
-
- {subAccounts.map(account => (
-
- ))}
- >
- ))}
-
-
-
-
-
-
-
-
-
-
- );
-}
diff --git a/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/index.tsx b/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/index.tsx
deleted file mode 100644
index 60673be70446..000000000000
--- a/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/Form/index.tsx
+++ /dev/null
@@ -1,527 +0,0 @@
-import { NotEnoughBalance, NotEnoughBalanceSwap } from "@ledgerhq/errors";
-import { getParentAccount, isTokenAccount } from "@ledgerhq/live-common/account/index";
-import {
- SetExchangeRateCallback,
- useIsSwapLiveApp,
- usePageState,
- useSwapLiveConfig,
- useSwapTransaction,
-} from "@ledgerhq/live-common/exchange/swap/hooks/index";
-import {
- maybeKeepTronAccountAlive,
- maybeTezosAccountUnrevealedAccount,
- maybeTronEmptyAccount,
-} from "@ledgerhq/live-common/exchange/swap/index";
-import { OnNoRatesCallback } from "@ledgerhq/live-common/exchange/swap/types";
-import { getProviderName } from "@ledgerhq/live-common/exchange/swap/utils/index";
-import {
- convertToNonAtomicUnit,
- getCustomFeesPerFamily,
-} from "@ledgerhq/live-common/exchange/swap/webApp/index";
-import useFeature from "@ledgerhq/live-common/featureFlags/useFeature";
-import { useRemoteLiveAppManifest } from "@ledgerhq/live-common/platform/providers/RemoteLiveAppProvider/index";
-import { useLocalLiveAppManifest } from "@ledgerhq/live-common/wallet-api/LocalLiveAppProvider/index";
-import { accountToWalletAPIAccount } from "@ledgerhq/live-common/wallet-api/converters";
-import { CryptoCurrency, TokenCurrency } from "@ledgerhq/types-cryptoassets";
-import { AccountLike } from "@ledgerhq/types-live";
-import BigNumber from "bignumber.js";
-import React, { useCallback, useEffect, useMemo, useRef, useState } from "react";
-import { useDispatch, useSelector } from "react-redux";
-import { useHistory, useLocation } from "react-router-dom";
-import styled from "styled-components";
-import { rateSelector, updateRateAction, updateTransactionAction } from "~/renderer/actions/swap";
-import TrackPage from "~/renderer/analytics/TrackPage";
-import { track } from "~/renderer/analytics/segment";
-import { context } from "~/renderer/drawers/Provider";
-import { useSwapLiveAppHook } from "~/renderer/hooks/swap-migrations/useSwapLiveAppHook";
-import { flattenAccountsSelector, shallowAccountsSelector } from "~/renderer/reducers/accounts";
-import { languageSelector } from "~/renderer/reducers/settings";
-import { walletSelector } from "~/renderer/reducers/wallet";
-import { useIsSwapLiveFlagEnabled } from "../hooks/useIsSwapLiveFlagEnabled";
-import { useSwapLiveAppQuoteState } from "../hooks/useSwapLiveAppQuoteState";
-import { trackSwapError, useGetSwapTrackingProperties } from "../utils/index";
-import ExchangeDrawer from "./ExchangeDrawer/index";
-import SwapFormSelectors from "./FormSelectors";
-import { SwapMigrationUI } from "./Migrations/SwapMigrationUI";
-import EmptyState from "./Rates/EmptyState";
-import SwapWebView, { SwapWebProps } from "./SwapWebView";
-
-const DAPP_PROVIDERS = ["paraswap", "oneinch", "moonpay"];
-
-const Wrapper = styled.div`
- display: flex;
- flex-direction: column;
- max-width: 37rem;
- padding: 0.75rem ${({ theme }) => theme.space[4]}px 0;
- row-gap: 1rem;
- @media screen and (min-height: 1200px) {
- padding-top: 1rem;
- row-gap: 1.5rem;
- }
-`;
-
-const idleTime = 60 * 60000; // 1 hour
-
-const SwapForm = () => {
- const language = useSelector(languageSelector);
- const [idleState, setIdleState] = useState(false);
- const dispatch = useDispatch();
- const { state: locationState } = useLocation();
- const history = useHistory();
- const totalListedAccounts = useSelector(flattenAccountsSelector);
- const accounts = useSelector(shallowAccountsSelector);
- const exchangeRate = useSelector(rateSelector);
- const walletApiPartnerList = useFeature("swapWalletApiPartnerList");
- const ptxSwapReceiveTRC20WithoutTrx = useFeature("ptxSwapReceiveTRC20WithoutTrx");
- const swapDefaultTrack = useGetSwapTrackingProperties();
-
- const setExchangeRate: SetExchangeRateCallback = useCallback(
- rate => {
- dispatch(updateRateAction(rate));
- },
- [dispatch],
- );
-
- const onNoRates: OnNoRatesCallback = useCallback(
- ({ toState }) => {
- track("error_message", {
- message: "no_rates",
- page: "Page Swap Form",
- ...swapDefaultTrack,
- sourceCurrency: toState.currency?.name,
- });
- },
- [swapDefaultTrack],
- );
-
- const swapLiveEnabledFlag = useSwapLiveConfig();
- const swapLiveAppManifestID = swapLiveEnabledFlag?.params?.manifest_id;
- const isDemo1Enabled = useIsSwapLiveFlagEnabled("ptxSwapLiveAppDemoOne");
-
- const swapTransaction = useSwapTransaction({
- accounts,
- setExchangeRate,
- onNoRates,
- isEnabled: !isDemo1Enabled,
- ...(locationState as object),
- });
-
- const isSwapLiveAppEnabled = useIsSwapLiveApp({
- currencyFrom: swapTransaction.swap.from.currency,
- });
-
- // @TODO: Try to check if we can directly have the right state from `useSwapTransaction`
- // Used to set the fake transaction recipient
- // As of today, we need to call setFromAccount to trigger an updateTransaction
- // in order to set the correct recipient address (abandonSeed address)
- // cf. https://github.com/LedgerHQ/ledger-live/blob/c135c887b313ecc9f4a3b3a421ced0e3a081dc37/libs/ledger-live-common/src/exchange/swap/hooks/useFromState.ts#L50-L57
- useEffect(() => {
- if (swapTransaction.account) {
- swapTransaction.setFromAccount(swapTransaction.account);
- }
- // eslint-disable-next-line react-hooks/exhaustive-deps
- }, []);
-
- const exchangeRatesState = swapTransaction.swap?.rates;
- const keepTronAccountAliveError = maybeKeepTronAccountAlive(swapTransaction);
- const swapError = keepTronAccountAliveError
- ? keepTronAccountAliveError
- : swapTransaction.fromAmountError instanceof NotEnoughBalance
- ? new NotEnoughBalanceSwap(swapTransaction.fromAmountError?.message)
- : swapTransaction.fromAmountError ||
- exchangeRatesState?.error ||
- maybeTezosAccountUnrevealedAccount(swapTransaction) ||
- (ptxSwapReceiveTRC20WithoutTrx?.enabled
- ? undefined
- : maybeTronEmptyAccount(swapTransaction));
-
- const swapWarning = swapTransaction.fromAmountWarning;
- const pageState = usePageState(swapTransaction, swapError);
- const provider = useMemo(() => exchangeRate?.provider, [exchangeRate?.provider]);
- const idleTimeout = useRef();
- const [swapWebProps, setSwapWebProps] = useState(
- undefined,
- );
- const { setDrawer } = React.useContext(context);
- const walletState = useSelector(walletSelector);
-
- const getExchangeSDKParams = useCallback(() => {
- const { swap, transaction } = swapTransaction;
- const { to, from } = swap;
- const { account: fromAccount, parentAccount: fromParentAccount } = from;
- const { account: toAccount, parentAccount: toParentAccount } = to;
- const { feesStrategy } = transaction || {};
- const { rate, rateId } = exchangeRate || {};
-
- const isToAccountValid = totalListedAccounts.some(account => account.id === toAccount?.id);
- const fromAccountId =
- fromAccount && accountToWalletAPIAccount(walletState, fromAccount, fromParentAccount)?.id;
- const toAccountId = isToAccountValid
- ? toAccount && accountToWalletAPIAccount(walletState, toAccount, toParentAccount)?.id
- : toParentAccount && accountToWalletAPIAccount(walletState, toParentAccount, undefined)?.id;
- const toNewTokenId =
- !isToAccountValid && toAccount?.type === "TokenAccount" ? toAccount.token?.id : undefined;
- const fromAmount =
- fromAccount &&
- convertToNonAtomicUnit({
- amount: transaction?.amount,
- account: fromAccount,
- });
-
- const customFeeConfig = transaction && getCustomFeesPerFamily(transaction);
- // The Swap web app will automatically recreate the transaction with "default" fees.
- // However, if you wish to use a different fee type, you will need to set it as custom.
- const feeStrategyParam =
- feesStrategy && ["slow", "fast", "custom"].includes(feesStrategy) ? "CUSTOM" : "MEDIUM";
-
- return {
- fromAccountId,
- toAccountId,
- fromAmount: fromAmount?.toString(),
- quoteId: rateId ? rateId : undefined,
- rate: rate?.toString(),
- feeStrategy: feeStrategyParam,
- customFeeConfig: customFeeConfig ? JSON.stringify(customFeeConfig) : undefined,
- toNewTokenId,
- };
- // eslint-disable-next-line react-hooks/exhaustive-deps
- }, [
- provider,
- swapTransaction.swap.from.account?.id,
- swapTransaction.swap.to.currency?.id,
- swapTransaction.swap.to.account?.id,
- swapTransaction.swap.from.amount,
- exchangeRate?.providerType,
- exchangeRate?.tradeMethod,
- exchangeRate?.providerURL,
- exchangeRate,
- totalListedAccounts,
- ]);
-
- const generateMoonpayUrl = useCallback(
- ({ base = "", args = {} }: { base: string; args: { [key: string]: string | undefined } }) => {
- const moonpayURL = new URL(base || "");
- moonpayURL.searchParams.append("ledgerlive", `${true}`);
- Object.entries(args).forEach(
- ([key, value]) =>
- // customFeeConfig is an object
- value &&
- moonpayURL.searchParams.append(
- ...[key, typeof value === "object" ? JSON.stringify(value) : value],
- ),
- );
- moonpayURL.searchParams.set("language", language);
-
- // Theme ID is defined by moonpay to tweak styling to more more closely match
- // the existing theming within ledger live.
- moonpayURL.searchParams.set("themeId", "92be4cb6-a57f-407b-8b1f-bc8055b60c9b");
- return moonpayURL;
- },
- [language],
- );
-
- const getProviderRedirectURLSearch = useCallback(() => {
- const { account: fromAccount, parentAccount: fromParentAccount } = swapTransaction.swap.from;
- const providerRedirectFromAccountId =
- fromAccount &&
- provider &&
- walletApiPartnerList?.enabled &&
- walletApiPartnerList?.params?.list.includes(provider)
- ? accountToWalletAPIAccount(walletState, fromAccount, fromParentAccount)?.id
- : fromAccount?.id;
-
- const providerRedirectURLSearch = new URLSearchParams();
-
- providerRedirectFromAccountId &&
- providerRedirectURLSearch.set("accountId", providerRedirectFromAccountId);
-
- if (provider === "moonpay") {
- const moonpayURL = generateMoonpayUrl({
- base: exchangeRate?.providerURL || "",
- args: getExchangeSDKParams(),
- });
-
- exchangeRate?.providerURL && providerRedirectURLSearch.set("goToURL", moonpayURL.toString());
- } else {
- exchangeRate?.providerURL &&
- providerRedirectURLSearch.set("customDappUrl", exchangeRate.providerURL || "");
- }
-
- providerRedirectURLSearch.set("returnTo", "/swap");
- return providerRedirectURLSearch;
- }, [
- walletState,
- provider,
- swapTransaction.swap.from,
- exchangeRate?.providerURL,
- generateMoonpayUrl,
- getExchangeSDKParams,
- walletApiPartnerList?.enabled,
- walletApiPartnerList?.params?.list,
- ]);
-
- const refreshIdle = useCallback(() => {
- idleState && setIdleState(false);
- idleTimeout.current && clearInterval(idleTimeout.current);
- idleTimeout.current = setTimeout(() => {
- setIdleState(true);
- }, idleTime);
- }, [idleState]);
-
- const redirectToProviderApp = useCallback(
- (provider: string = ""): void => {
- const { providerURL } = exchangeRate ?? {};
- const from = swapTransaction.swap.from;
- const fromAccountId = from.parentAccount?.id || from.account?.id;
-
- const pathname = `/platform/${getProviderName(provider).toLowerCase()}`;
-
- const account = accounts.find(a => a.id === fromAccountId);
- if (!account) return;
- const parentAccount = isTokenAccount(account)
- ? getParentAccount(account, accounts)
- : undefined;
-
- const accountId =
- walletApiPartnerList?.enabled && walletApiPartnerList?.params?.list.includes(provider)
- ? accountToWalletAPIAccount(walletState, account, parentAccount)?.id
- : fromAccountId;
-
- const state: {
- returnTo: string;
- accountId?: string;
- goToURL?: string;
- customDappUrl?: string;
- } = {
- returnTo: "/swap",
- accountId,
- customDappUrl: providerURL,
- };
-
- if (provider === "moonpay") {
- const moonpayURL = generateMoonpayUrl({
- base: exchangeRate?.providerURL || "",
- args: getExchangeSDKParams(),
- });
- state.customDappUrl = undefined;
- state.goToURL = moonpayURL.toString();
- }
-
- history.push({
- // This looks like an issue, the proper signature is: push(path, [state]) - (function) Pushes a new entry onto the history stack
- pathname,
- state,
- });
- },
- [
- walletState,
- accounts,
- exchangeRate,
- generateMoonpayUrl,
- getExchangeSDKParams,
- history,
- swapTransaction.swap.from,
- walletApiPartnerList?.enabled,
- walletApiPartnerList?.params?.list,
- ],
- );
-
- useEffect(() => {
- if (swapTransaction.swap.rates.status === "success") {
- refreshIdle();
- }
- }, [refreshIdle, swapTransaction.swap.rates.status]);
-
- useEffect(() => {
- dispatch(updateTransactionAction(swapTransaction.transaction));
- }, [swapTransaction.transaction, dispatch]);
-
- useEffect(() => {
- // Whenever an account is added, reselect the currency to pick a default target account.
- // (possibly the one that got created)
- if (swapTransaction.swap.to.currency && !swapTransaction.swap.to.account) {
- swapTransaction.setToCurrency(swapTransaction.swap.to.currency);
- }
- // eslint-disable-next-line react-hooks/exhaustive-deps
- }, [accounts]);
-
- // Track errors
- useEffect(
- () => {
- (swapError || swapWarning) &&
- trackSwapError(swapError! || swapWarning!, {
- page: "Page Swap Form",
- ...swapDefaultTrack,
- sourcecurrency: swapTransaction.swap.from.currency?.name,
- provider,
- });
- },
- // eslint-disable-next-line react-hooks/exhaustive-deps
- [swapError, swapWarning],
- );
-
- const isSwapReady =
- !swapTransaction.bridgePending &&
- exchangeRatesState.status !== "loading" &&
- swapTransaction.transaction &&
- !swapError &&
- exchangeRate &&
- swapTransaction.swap.to.account &&
- swapTransaction.swap.from.amount &&
- swapTransaction.swap.from.amount.gt(0);
-
- const onSubmit = () => {
- if (!exchangeRate) return;
-
- track("button_clicked2", {
- button: "Request",
- page: "Page Swap Form",
- ...swapDefaultTrack,
- sourceCurrency: sourceCurrency?.name,
- targetCurrency: targetCurrency?.name,
- partner: provider,
- });
-
- if (provider && DAPP_PROVIDERS.includes(provider)) {
- redirectToProviderApp(provider);
- } else {
- // Fix LIVE-9064, prevent the transaction from being updated when using useAllAmount
- // FIX LIVE-11283, Do not do this for polkadot as it is required to have transferAllowDeath set checked
- swapTransaction.transaction && swapTransaction.transaction.family !== "polkadot"
- ? (swapTransaction.transaction.useAllAmount = false)
- : null;
- // Fix LIVE-11660, remove the margin from thec fees
- swapTransaction.transaction && swapTransaction.transaction.family === "evm"
- ? (swapTransaction.transaction.additionalFees = undefined)
- : null;
- setDrawer(
- ExchangeDrawer,
- {
- swapTransaction,
- exchangeRate,
- },
- {
- preventBackdropClick: true,
- },
- );
- }
- };
-
- const sourceAccount = swapTransaction.swap.from.account;
- const sourceCurrency = swapTransaction.swap.from.currency;
- const targetCurrency = swapTransaction.swap.to.currency;
-
- useEffect(() => {
- if (!exchangeRate) {
- return;
- }
- swapTransaction.swap.updateSelectedRate(exchangeRate);
- // suppressing as swapTransaction is not memoized and causes infinite loop
- // eslint-disable-next-line
- }, [exchangeRate]);
-
- const untickMax = () => {
- swapTransaction.transaction?.useAllAmount ? swapTransaction.toggleMax() : null;
- };
-
- const setFromAccount = (account: AccountLike | undefined) => {
- untickMax();
- swapTransaction.setFromAccount(account);
- };
-
- const setFromAmount = useCallback(
- (amount: BigNumber) => {
- swapTransaction.setFromAmount(amount);
- },
- [swapTransaction],
- );
-
- const setToCurrency = (currency: TokenCurrency | CryptoCurrency | undefined) => {
- swapTransaction.setToCurrency(currency);
- };
-
- const toggleMax = () => {
- swapTransaction.toggleMax();
- };
-
- const reverseSwap = () => {
- untickMax();
- swapTransaction.reverseSwap();
- };
-
- const localManifest = useLocalLiveAppManifest(swapLiveAppManifestID || undefined);
- const remoteManifest = useRemoteLiveAppManifest(swapLiveAppManifestID || undefined);
-
- const manifest = localManifest || remoteManifest;
- useSwapLiveAppHook({
- isSwapLiveAppEnabled: isSwapLiveAppEnabled.enabled,
- manifestID: swapLiveAppManifestID,
- swapTransaction,
- updateSwapWebProps: setSwapWebProps,
- swapError,
- getExchangeSDKParams,
- getProviderRedirectURLSearch,
- });
-
- // used to get the Quotes Status from Demo 1 swap live app
- const [quoteState, setQuoteState] = useSwapLiveAppQuoteState({
- amountTo: exchangeRate?.toAmount,
- swapError,
- counterValue: undefined,
- });
-
- return (
-
-
-
- {pageState === "empty" && }
-
- ) : null
- }
- // Demo 1 props
- pageState={pageState}
- swapTransaction={swapTransaction}
- provider={provider}
- // Demo 0 props
- disabled={!isSwapReady}
- onClick={onSubmit}
- />
-
- );
-};
-
-export default SwapForm;
diff --git a/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/hooks/useIsSwapLiveFlagEnabled.ts b/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/hooks/useIsSwapLiveFlagEnabled.ts
deleted file mode 100644
index b427ffcce66f..000000000000
--- a/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/hooks/useIsSwapLiveFlagEnabled.ts
+++ /dev/null
@@ -1,25 +0,0 @@
-import { useFeature } from "@ledgerhq/live-common/featureFlags/index";
-
-// used to get the value of the Swap Live App flag
-export const useIsSwapLiveFlagEnabled = (flag: string): boolean => {
- const demoZero = useFeature("ptxSwapLiveAppDemoZero");
- const demoThree = useFeature("ptxSwapLiveAppDemoThree");
- const coreExperiment = useFeature("ptxSwapCoreExperiment");
- const coreExperimentVariant = coreExperiment?.enabled && coreExperiment?.params?.variant;
-
- if (flag === "ptxSwapLiveAppDemoThree") {
- return (
- !!demoThree?.enabled || ["Demo3", "Demo3Thorswap"].includes(coreExperimentVariant as string)
- );
- }
-
- if (flag === "ptxSwapLiveAppDemoZero") {
- return !!demoZero?.enabled || coreExperimentVariant === "Demo0";
- }
-
- if (flag === "ptxSwapLiveAppDemoOne") {
- return false;
- }
-
- throw new Error(`Unknown Swap Live App flag ${flag}`);
-};
diff --git a/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/hooks/useSwapLiveAppQuoteState.ts b/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/hooks/useSwapLiveAppQuoteState.ts
deleted file mode 100644
index 3258901c62f7..000000000000
--- a/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/hooks/useSwapLiveAppQuoteState.ts
+++ /dev/null
@@ -1,31 +0,0 @@
-import BigNumber from "bignumber.js";
-import { useCallback, useState } from "react";
-
-export type CustomSwapQuotesState = {
- amountTo: BigNumber | undefined;
- swapError: Error | undefined;
- counterValue: BigNumber | undefined;
-};
-
-export function useSwapLiveAppQuoteState({
- amountTo,
- swapError,
- counterValue,
-}: CustomSwapQuotesState): [CustomSwapQuotesState, (next: CustomSwapQuotesState) => void] {
- const [state, setQuoteState] = useState({
- amountTo,
- swapError,
- counterValue,
- });
-
- const updateQuoteState = useCallback(
- (next: CustomSwapQuotesState) => {
- setQuoteState({
- ...next, // Apply updates provided to function
- swapError: swapError || next.swapError,
- });
- },
- [swapError],
- );
- return [state, updateQuoteState];
-}
diff --git a/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/index.tsx b/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/index.tsx
index 58c10bd36595..bdba909f4cd3 100644
--- a/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/index.tsx
+++ b/apps/ledger-live-desktop/src/renderer/screens/exchange/Swap2/index.tsx
@@ -2,12 +2,10 @@ import React from "react";
import { Route } from "react-router-dom";
import styled, { createGlobalStyle } from "styled-components";
import Box from "~/renderer/components/Box";
-import SwapForm from "./Form";
import SwapHistory from "./History";
import SwapNavbar from "./Navbar";
import { SwapApp } from "./App";
-import { useIsSwapLiveFlagEnabled } from "./hooks/useIsSwapLiveFlagEnabled";
const Body = styled(Box)`
flex: 1;
`;
@@ -48,16 +46,12 @@ const GlobalStyle = createGlobalStyle`
`;
const Swap2 = () => {
- const isDemo3Enabled = useIsSwapLiveFlagEnabled("ptxSwapLiveAppDemoThree");
-
- const SwapPage = isDemo3Enabled ? SwapApp : SwapForm;
-
return (
-
+
diff --git a/apps/ledger-live-desktop/src/renderer/screens/swapWeb/index.tsx b/apps/ledger-live-desktop/src/renderer/screens/swapWeb/index.tsx
index 4b238e995e5f..81e2947e26c0 100644
--- a/apps/ledger-live-desktop/src/renderer/screens/swapWeb/index.tsx
+++ b/apps/ledger-live-desktop/src/renderer/screens/swapWeb/index.tsx
@@ -1,16 +1,16 @@
+import { useDebounce } from "@ledgerhq/live-common/hooks/useDebounce";
+import { useRemoteLiveAppManifest } from "@ledgerhq/live-common/platform/providers/RemoteLiveAppProvider/index";
+import { useLocalLiveAppManifest } from "@ledgerhq/live-common/wallet-api/LocalLiveAppProvider/index";
import React from "react";
import { useSelector } from "react-redux";
+import { useHistory, useLocation } from "react-router-dom";
import Card from "~/renderer/components/Box/Card";
-import { counterValueCurrencySelector, languageSelector } from "~/renderer/reducers/settings";
-import { useRemoteLiveAppManifest } from "@ledgerhq/live-common/platform/providers/RemoteLiveAppProvider/index";
+import { WebviewProps } from "~/renderer/components/Web3AppWebview/types";
import WebPlatformPlayer from "~/renderer/components/WebPlatformPlayer";
import useTheme from "~/renderer/hooks/useTheme";
-import { useHistory, useLocation } from "react-router-dom";
-import { WebviewProps } from "~/renderer/components/Web3AppWebview/types";
-import { useDebounce } from "@ledgerhq/live-common/hooks/useDebounce";
+import { counterValueCurrencySelector, languageSelector } from "~/renderer/reducers/settings";
+import { UnableToLoadSwapLiveError } from "~/renderer/screens/exchange/Swap2/Form/SwapWebViewDemo3";
import { captureException } from "~/sentry/renderer";
-import { UnableToLoadSwapLiveError } from "~/renderer/screens/exchange/Swap2/Form/SwapWebView";
-import { useLocalLiveAppManifest } from "@ledgerhq/live-common/wallet-api/LocalLiveAppProvider/index";
const DEFAULT_SWAP_APP_ID = "swapWeb";
diff --git a/libs/ledger-live-common/src/exchange/swap/hooks/live-app-migration/useIsCurrencySupported.ts b/libs/ledger-live-common/src/exchange/swap/hooks/live-app-migration/useIsCurrencySupported.ts
deleted file mode 100644
index 8629941a598b..000000000000
--- a/libs/ledger-live-common/src/exchange/swap/hooks/live-app-migration/useIsCurrencySupported.ts
+++ /dev/null
@@ -1,34 +0,0 @@
-import { CryptoOrTokenCurrency } from "@ledgerhq/types-cryptoassets";
-import { isCryptoCurrency } from "../../../../currencies";
-
-type UseIsCurrencySupportedProps = {
- currencyFrom?: CryptoOrTokenCurrency;
- params: {
- families?: Array;
- currencies?: Array;
- };
- defaultValue: boolean;
-};
-
-export function useIsCurrencySupported({
- currencyFrom,
- params,
- defaultValue,
-}: UseIsCurrencySupportedProps) {
- const { families, currencies } = params || {};
-
- if (!currencyFrom || (!families && !currencies)) {
- return defaultValue;
- }
-
- const familyOfCurrencyFrom = isCryptoCurrency(currencyFrom)
- ? currencyFrom.family
- : currencyFrom.parentCurrency.family;
-
- const familyOrCurrencyIsEnabled =
- families?.includes(familyOfCurrencyFrom) || currencies?.includes(currencyFrom.id);
-
- // if families or currencies are defined then check if a family or currency is
- // enabled. If neither of these are defined or of length 0 then assume everything is enabled.
- return families?.length || currencies?.length ? familyOrCurrencyIsEnabled : true;
-}
diff --git a/libs/ledger-live-common/src/exchange/swap/hooks/live-app-migration/useIsSwapLiveApp.test.ts b/libs/ledger-live-common/src/exchange/swap/hooks/live-app-migration/useIsSwapLiveApp.test.ts
index 6c2db751c44c..6f474cba4bb3 100644
--- a/libs/ledger-live-common/src/exchange/swap/hooks/live-app-migration/useIsSwapLiveApp.test.ts
+++ b/libs/ledger-live-common/src/exchange/swap/hooks/live-app-migration/useIsSwapLiveApp.test.ts
@@ -1,7 +1,6 @@
/**
* @jest-environment jsdom
*/
-import { cryptocurrenciesById } from "@ledgerhq/cryptoassets/currencies";
import { renderHook } from "@testing-library/react";
import { useFeature } from "../../../../featureFlags";
import { useIsSwapLiveApp } from "./useIsSwapLiveApp";
@@ -11,8 +10,6 @@ jest.mock("../../../../featureFlags");
const useMockFeature = useFeature as jest.Mock;
-const bitcoin = cryptocurrenciesById["bitcoin"];
-
describe("useIsSwapLiveApp hook", () => {
afterEach(() => {
jest.clearAllMocks();
@@ -20,90 +17,60 @@ describe("useIsSwapLiveApp hook", () => {
it("returns the enabled flag when currencyFrom is not defined", () => {
// Set up the mock to return different values based on input
useMockFeature.mockImplementation(flagName => {
- if (flagName === "ptxSwapLiveAppDemoZero") {
- return { enabled: true };
- }
- if (flagName === "ptxSwapLiveAppDemoOne") {
+ if (flagName === "ptxSwapLiveApp") {
return { enabled: false };
}
});
- const { result } = renderHook(() => useIsSwapLiveApp({ currencyFrom: undefined }));
+ const { result } = renderHook(() => useIsSwapLiveApp());
expect(result.current.enabled).toBe(true);
});
it("returns the enabled flag when families and currencies are not defined", () => {
useMockFeature.mockImplementation(flagName => {
- if (flagName === "ptxSwapLiveAppDemoZero") {
- return { enabled: true, params: { families: undefined, currencies: undefined } };
- }
- if (flagName === "ptxSwapLiveAppDemoOne") {
+ if (flagName === "ptxSwapLiveApp") {
return { enabled: false };
}
});
- const { result } = renderHook(() => useIsSwapLiveApp({ currencyFrom: bitcoin }));
+ const { result } = renderHook(() => useIsSwapLiveApp());
expect(result.current.enabled).toBe(true);
});
it("returns true when currencyFrom family is in families array and feature is enabled", () => {
useMockFeature.mockImplementation(flagName => {
- if (flagName === "ptxSwapLiveAppDemoZero") {
- return { enabled: true, params: { families: ["bitcoin"], currencies: [] } };
- }
- if (flagName === "ptxSwapLiveAppDemoOne") {
+ if (flagName === "ptxSwapLiveApp") {
return { enabled: false };
}
});
- const { result } = renderHook(() => useIsSwapLiveApp({ currencyFrom: bitcoin }));
+ const { result } = renderHook(() => useIsSwapLiveApp());
expect(result.current.enabled).toBe(true);
});
it("returns true when currencyFrom is in currencies array and feature is enabled", () => {
useMockFeature.mockImplementation(flagName => {
- if (flagName === "ptxSwapLiveAppDemoZero") {
- return { enabled: true, params: { families: [], currencies: ["bitcoin"] } };
- }
- if (flagName === "ptxSwapLiveAppDemoOne") {
+ if (flagName === "ptxSwapLiveApp") {
return { enabled: false };
}
});
- const { result } = renderHook(() => useIsSwapLiveApp({ currencyFrom: bitcoin }));
+ const { result } = renderHook(() => useIsSwapLiveApp());
expect(result.current.enabled).toBe(true);
});
- it("returns false when currencyFrom family is not in families, currencyFrom is not in currencies, and feature is disabled", () => {
- useMockFeature.mockImplementation(flagName => {
- if (flagName === "ptxSwapLiveAppDemoZero") {
- return { enabled: false, params: { families: ["ethereum"], currencies: ["ethereum"] } };
- }
- if (flagName === "ptxSwapLiveAppDemoOne") {
- return { enabled: false };
- }
- });
-
- const { result } = renderHook(() => useIsSwapLiveApp({ currencyFrom: bitcoin }));
-
- expect(result.current.enabled).toBe(false);
- });
-
it("returns enabled flag if both families and currencies are empty arrays", () => {
useMockFeature.mockImplementation(flagName => {
- if (flagName === "ptxSwapLiveAppDemoZero") {
- return { enabled: true, params: { families: [], currencies: [] } };
- }
- if (flagName === "ptxSwapLiveAppDemoOne") {
+ if (flagName === "ptxSwapLiveApp") {
return { enabled: false };
}
});
- const { result } = renderHook(() => useIsSwapLiveApp({ currencyFrom: bitcoin }));
+ const { result } = renderHook(() => useIsSwapLiveApp());
expect(result.current.enabled).toBe(true);
});
diff --git a/libs/ledger-live-common/src/exchange/swap/hooks/live-app-migration/useIsSwapLiveApp.ts b/libs/ledger-live-common/src/exchange/swap/hooks/live-app-migration/useIsSwapLiveApp.ts
index 6bbcfeaac2c4..cf014703d50d 100644
--- a/libs/ledger-live-common/src/exchange/swap/hooks/live-app-migration/useIsSwapLiveApp.ts
+++ b/libs/ledger-live-common/src/exchange/swap/hooks/live-app-migration/useIsSwapLiveApp.ts
@@ -1,34 +1,12 @@
-import { CryptoOrTokenCurrency } from "@ledgerhq/types-cryptoassets";
import { useCallback, useState } from "react";
-import { useIsCurrencySupported } from "./useIsCurrencySupported";
-import { useSwapLiveConfig } from "./useSwapLiveConfig";
-type Props = {
- currencyFrom?: CryptoOrTokenCurrency;
-};
-
-export function useIsSwapLiveApp({ currencyFrom }: Props) {
- const ptxSwapLiveApp = useSwapLiveConfig();
- const [crashed, setHasCrashed] = useState(false);
+export function useIsSwapLiveApp() {
+ const [, setHasCrashed] = useState(false);
const onLiveAppCrashed = useCallback(() => setHasCrashed(true), []);
- const isEnabled = !!ptxSwapLiveApp?.enabled;
- const { families, currencies } = ptxSwapLiveApp?.params ?? {};
-
- const isCurrencySupported = useIsCurrencySupported({
- params: {
- families,
- currencies,
- },
- currencyFrom,
- defaultValue: !!isEnabled,
- });
-
- const liveAppAvailable = Boolean(isEnabled && isCurrencySupported && !crashed);
-
return {
- enabled: liveAppAvailable,
+ enabled: true,
onLiveAppCrashed,
};
}
diff --git a/libs/ledger-live-common/src/exchange/swap/hooks/live-app-migration/useSwapLiveConfig.test.ts b/libs/ledger-live-common/src/exchange/swap/hooks/live-app-migration/useSwapLiveConfig.test.ts
index f67fe374f076..68d727593447 100644
--- a/libs/ledger-live-common/src/exchange/swap/hooks/live-app-migration/useSwapLiveConfig.test.ts
+++ b/libs/ledger-live-common/src/exchange/swap/hooks/live-app-migration/useSwapLiveConfig.test.ts
@@ -18,12 +18,7 @@ describe("useSwapLiveConfig", () => {
{ enabled: boolean; params: { manifest_id: string; variant?: string } } | undefined
>[],
) => {
- const flagsKeys = [
- "ptxSwapLiveAppDemoZero",
- "ptxSwapLiveAppDemoOne",
- "ptxSwapLiveAppDemoThree",
- "ptxSwapCoreExperiment",
- ];
+ const flagsKeys = ["ptxSwapLiveApp"];
useMockFeature.mockImplementation(flagName => flags[flagsKeys.indexOf(flagName)] ?? null);
};
@@ -32,167 +27,12 @@ describe("useSwapLiveConfig", () => {
jest.clearAllMocks();
});
- it("should highest priority flag if all features have the same enabled state", () => {
- setupFeatureFlagsMock([
- { enabled: true, params: { manifest_id: "demo_0" } },
- { enabled: true, params: { manifest_id: "demo_1" } },
- { enabled: true, params: { manifest_id: "demo_3" } },
- ]);
- const { result } = renderHook(() => useSwapLiveConfig());
-
- expect(result.current).not.toBeNull();
-
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
- expect((result.current?.params as any)?.manifest_id).toEqual("demo_0");
- });
-
- it("should return null if both features are disabled", () => {
- setupFeatureFlagsMock([{ enabled: false }, { enabled: false }, { enabled: false }]);
- const { result } = renderHook(() => useSwapLiveConfig());
- expect(result.current).toBeNull();
- });
-
- it("should return demoZero if only demoZero is enabled", () => {
- setupFeatureFlagsMock([
- {
- enabled: true,
- params: { manifest_id: "swap-live-app-demo-0" },
- },
- { enabled: false },
- { enabled: false },
- ]);
- const { result } = renderHook(() => useSwapLiveConfig());
- expect(result.current).toEqual({
- enabled: true,
- params: { manifest_id: "swap-live-app-demo-0" },
- });
- });
-
- it("should return demoOne if only demoOne is enabled", () => {
- setupFeatureFlagsMock([
- { enabled: false },
- {
- enabled: true,
- params: { manifest_id: "swap-live-app-demo-1" },
- },
- { enabled: false },
- ]);
- const { result } = renderHook(() => useSwapLiveConfig());
- expect(result.current).toEqual({
- enabled: true,
- params: { manifest_id: "swap-live-app-demo-1" },
- });
- });
-
- it("should return demoThree if only demoOne is enabled", () => {
- setupFeatureFlagsMock([
- { enabled: false },
- {
- enabled: true,
- params: { manifest_id: "swap-live-app-demo-3" },
- },
- { enabled: false },
- ]);
-
+ it("should return demoThree config", () => {
+ setupFeatureFlagsMock([{ enabled: true, params: { manifest_id: "swap-live-app-demo-3" } }]);
const { result } = renderHook(() => useSwapLiveConfig());
expect(result.current).toEqual({
enabled: true,
params: { manifest_id: "swap-live-app-demo-3" },
});
});
-
- it("should return config when ptxSwapCoreExperiment has valid variant Demo0", () => {
- const expected = {
- enabled: true,
- params: { manifest_id: "swap-live-app-demo-0", variant: "Demo0" },
- };
- setupFeatureFlagsMock([{ enabled: false }, { enabled: false }, { enabled: false }, expected]);
- const { result } = renderHook(() => useSwapLiveConfig());
- expect(result.current).toEqual(expected);
- });
-
- it("should return config when ptxSwapCoreExperiment has valid variant Demo3", () => {
- setupFeatureFlagsMock([
- { enabled: false },
- { enabled: false },
- { enabled: false },
- { enabled: true, params: { manifest_id: "swap-live-app-demo-3", variant: "Demo3" } },
- ]);
- const { result } = renderHook(() => useSwapLiveConfig());
- expect(result.current).toEqual({
- enabled: true,
- params: { manifest_id: "swap-live-app-demo-3", variant: "Demo3" },
- });
- });
-
- it("should return config when ptxSwapCoreExperiment has valid variant Demo3Thorswap", () => {
- setupFeatureFlagsMock([
- { enabled: false },
- { enabled: false },
- { enabled: false },
- { enabled: true, params: { manifest_id: "swap-live-app-demo-3", variant: "Demo3Thorswap" } },
- ]);
- const { result } = renderHook(() => useSwapLiveConfig());
- expect(result.current).toEqual({
- enabled: true,
- params: { manifest_id: "swap-live-app-demo-3", variant: "Demo3Thorswap" },
- });
- });
-
- it("should return demoZero if demoThree and are enabled", () => {
- setupFeatureFlagsMock([
- { enabled: true, params: { manifest_id: "swap-live-app-demo-0" } },
- { enabled: false },
- { enabled: true, params: { manifest_id: "swap-live-app-demo-3" } },
- ]);
- const { result } = renderHook(() => useSwapLiveConfig());
- expect(result.current).toEqual({
- enabled: true,
- params: { manifest_id: "swap-live-app-demo-0" },
- });
- });
-
- it("should return demoZero if all demo flags are enabled", () => {
- setupFeatureFlagsMock([
- { enabled: true, params: { manifest_id: "swap-live-app-demo-0" } },
- { enabled: true, params: { manifest_id: "swap-live-app-demo-1" } },
- { enabled: true, params: { manifest_id: "swap-live-app-demo-3" } },
- ]);
- const { result } = renderHook(() => useSwapLiveConfig());
- expect(result.current).toEqual({
- enabled: true,
- params: { manifest_id: "swap-live-app-demo-0" },
- });
- });
-
- it("should prioritize demoZero over demo flags if all are enabled", () => {
- setupFeatureFlagsMock([
- { enabled: true, params: { manifest_id: "swap-live-app-demo-0" } },
- { enabled: true, params: { manifest_id: "swap-live-app-demo-1" } },
- { enabled: true, params: { manifest_id: "swap-live-app-demo-3" } },
- { enabled: true, params: { manifest_id: "swap-live-app-demo-3", variant: "Demo3" } },
- ]);
- const { result } = renderHook(() => useSwapLiveConfig());
- expect(result.current).toEqual({
- enabled: true,
- params: { manifest_id: "swap-live-app-demo-0" },
- });
- });
-
- it("should return null when coreExperiment is enabled but has no variant", () => {
- setupFeatureFlagsMock([
- { enabled: false },
- { enabled: false },
- { enabled: false },
- { enabled: true, params: { manifest_id: "core-experiment" } },
- ]);
- const { result } = renderHook(() => useSwapLiveConfig());
- expect(result.current).toBeNull();
- });
-
- it("should return null when all flags are undefined", () => {
- setupFeatureFlagsMock([undefined, undefined, undefined, undefined]);
- const { result } = renderHook(() => useSwapLiveConfig());
- expect(result.current).toBeNull();
- });
});
diff --git a/libs/ledger-live-common/src/exchange/swap/hooks/live-app-migration/useSwapLiveConfig.ts b/libs/ledger-live-common/src/exchange/swap/hooks/live-app-migration/useSwapLiveConfig.ts
index 648628bf8ccb..cb66910105dc 100644
--- a/libs/ledger-live-common/src/exchange/swap/hooks/live-app-migration/useSwapLiveConfig.ts
+++ b/libs/ledger-live-common/src/exchange/swap/hooks/live-app-migration/useSwapLiveConfig.ts
@@ -1,38 +1,15 @@
-import { Feature_PtxSwapCoreExperiment } from "@ledgerhq/types-live/lib/feature";
import { useFeature } from "../../../../featureFlags";
-// check if the variant is valid for core rollout experiment
-export type CoreExperimentParams = NonNullable;
-export type ValidVariant = CoreExperimentParams["variant"];
-
-// used to enable the Swap Live App globally
+/**
+ * This hook is used to retrieve the configuration for the Swap Live App.
+ * The `ptxSwapLiveApp` feature flag is always true, but it is used
+ * to obtain the manifest ID that loads the URL for the live app in production,
+ * stg, or ppr environments.
+ *
+ * @returns The feature flag configuration for `ptxSwapLiveApp`.
+ */
export function useSwapLiveConfig() {
- const demoThree = useFeature("ptxSwapLiveAppDemoThree");
- const demoOne = useFeature("ptxSwapLiveAppDemoOne");
- const demoZero = useFeature("ptxSwapLiveAppDemoZero");
- const coreExperiment = useFeature("ptxSwapCoreExperiment");
-
- // const validVariants: readonly ValidVariant[] = ["Demo0", "Demo3", "Demo3Thorswap"] as const;
-
- if (demoZero?.enabled) {
- return demoZero;
- }
-
- if (demoThree?.enabled) {
- return demoThree;
- }
-
- if (coreExperiment?.enabled) {
- const variant = coreExperiment?.params?.variant;
- if (!variant || !(variant satisfies ValidVariant)) {
- return null;
- }
- return coreExperiment;
- }
-
- if (demoOne?.enabled) {
- return demoOne;
- }
+ const config = useFeature("ptxSwapLiveApp");
- return null;
+ return config;
}
diff --git a/libs/ledger-live-common/src/exchange/swap/hooks/v5/useFilteredProviders.ts b/libs/ledger-live-common/src/exchange/swap/hooks/v5/useFilteredProviders.ts
index dccab89f981e..33a10ce8f496 100644
--- a/libs/ledger-live-common/src/exchange/swap/hooks/v5/useFilteredProviders.ts
+++ b/libs/ledger-live-common/src/exchange/swap/hooks/v5/useFilteredProviders.ts
@@ -1,16 +1,12 @@
+import { getEnv } from "@ledgerhq/live-env";
import { useCallback, useEffect, useState } from "react";
-import { useFeature } from "../../../../featureFlags";
import { fetchAndMergeProviderData } from "../../../providers/swap";
-import { getEnv } from "@ledgerhq/live-env";
export const useFilteredProviders = () => {
const [providers, setProviders] = useState([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
- const ptxSwapMoonpayProviderFlag = useFeature("ptxSwapMoonpayProvider");
- const ptxSwapExodusProviderFlag = useFeature("ptxSwapExodusProvider");
-
const fetchProviders = useCallback(async () => {
try {
const ledgerSignatureEnv = getEnv("MOCK_EXCHANGE_TEST_CONFIG") ? "test" : "prod";
@@ -18,13 +14,7 @@ export const useFilteredProviders = () => {
const data = await fetchAndMergeProviderData({ ledgerSignatureEnv, partnerSignatureEnv });
- let filteredProviders = Object.keys(data);
- if (!ptxSwapMoonpayProviderFlag?.enabled) {
- filteredProviders = filteredProviders.filter(provider => provider !== "moonpay");
- }
- if (!ptxSwapExodusProviderFlag?.enabled) {
- filteredProviders = filteredProviders.filter(provider => provider !== "exodus");
- }
+ const filteredProviders = Object.keys(data);
setProviders(filteredProviders);
} catch (error) {
@@ -32,7 +22,7 @@ export const useFilteredProviders = () => {
} finally {
setLoading(false);
}
- }, [ptxSwapMoonpayProviderFlag, ptxSwapExodusProviderFlag]);
+ }, []);
useEffect(() => {
fetchProviders();
diff --git a/libs/ledger-live-common/src/featureFlags/defaultFeatures.ts b/libs/ledger-live-common/src/featureFlags/defaultFeatures.ts
index 51c16cd292f3..f4389da7820a 100644
--- a/libs/ledger-live-common/src/featureFlags/defaultFeatures.ts
+++ b/libs/ledger-live-common/src/featureFlags/defaultFeatures.ts
@@ -90,7 +90,6 @@ export const CURRENCY_DEFAULT_FEATURES = {
*/
export const DEFAULT_FEATURES: Features = {
...CURRENCY_DEFAULT_FEATURES,
-
brazeLearn: DEFAULT_FEATURE,
portfolioExchangeBanner: DEFAULT_FEATURE,
postOnboardingAssetsTransfer: DEFAULT_FEATURE,
@@ -399,38 +398,13 @@ export const DEFAULT_FEATURES: Features = {
},
ptxCard: DEFAULT_FEATURE,
- ptxSwapLiveAppDemoZero: {
- enabled: false,
- params: {
- manifest_id: "swap-live-app-demo-0",
- },
- },
-
- ptxSwapLiveAppDemoOne: {
- enabled: false,
- params: {
- manifest_id: "swap-live-app-demo-1",
- },
- },
-
- ptxSwapLiveAppDemoThree: {
- enabled: false,
+ ptxSwapLiveApp: {
+ enabled: true,
params: {
manifest_id: "swap-live-app-demo-3",
},
},
- ptxSwapCoreExperiment: {
- enabled: false,
- params: {
- variant: "Demo0",
- manifest_id: "swap-live-app-demo-0",
- },
- },
-
- ptxSwapMoonpayProvider: DEFAULT_FEATURE,
- ptxSwapExodusProvider: DEFAULT_FEATURE,
-
llmAnalyticsOptInPrompt: {
enabled: false,
params: {
diff --git a/libs/ledgerjs/packages/types-live/src/feature.ts b/libs/ledgerjs/packages/types-live/src/feature.ts
index 235167b57f03..ae95db518700 100644
--- a/libs/ledgerjs/packages/types-live/src/feature.ts
+++ b/libs/ledgerjs/packages/types-live/src/feature.ts
@@ -168,12 +168,7 @@ export type Features = CurrencyFeatures & {
fetchAdditionalCoins: Feature_FetchAdditionalCoins;
ptxCard: DefaultFeature;
ptxSwapLiveAppMobile: DefaultFeature;
- ptxSwapLiveAppDemoZero: Feature_PtxSwapLiveAppDemoZero;
- ptxSwapLiveAppDemoOne: Feature_PtxSwapLiveAppDemoZero;
- ptxSwapLiveAppDemoThree: Feature_PtxSwapLiveAppDemoZero;
- ptxSwapCoreExperiment: Feature_PtxSwapCoreExperiment;
- ptxSwapMoonpayProvider: Feature_PtxSwapMoonpayProvider;
- ptxSwapExodusProvider: Feature_PtxSwapExodusProvider;
+ ptxSwapLiveApp: Feature_PtxSwapLiveApp;
ptxSwapReceiveTRC20WithoutTrx: Feature_PtxSwapReceiveTRC20WithoutTrx;
flexibleContentCards: Feature_FlexibleContentCards;
llmAnalyticsOptInPrompt: Feature_LlmAnalyticsOptInPrompt;
@@ -471,18 +466,6 @@ export type Feature_RatingsPrompt = Feature<{
}>;
export type Feature_PtxSwapLiveApp = Feature<{
- currencies?: Array;
- families?: Array;
-}>;
-
-export type Feature_PtxSwapLiveAppDemoZero = Feature<{
- manifest_id: string;
- currencies?: string[];
- families?: string[];
-}>;
-
-export type Feature_PtxSwapCoreExperiment = Feature<{
- variant: "Demo0" | "Demo3" | "Demo3Thorswap";
manifest_id: string;
currencies?: string[];
families?: string[];
@@ -556,8 +539,6 @@ export type Feature_PtxServiceCtaExchangeDrawer = DefaultFeature;
export type Feature_PtxServiceCtaScreens = DefaultFeature;
export type Feature_PortfolioExchangeBanner = DefaultFeature;
export type Feature_BrazeLearn = DefaultFeature;
-export type Feature_PtxSwapMoonpayProvider = DefaultFeature;
-export type Feature_PtxSwapExodusProvider = DefaultFeature;
export type Feature_PtxSwapReceiveTRC20WithoutTrx = DefaultFeature;
export type Feature_FlexibleContentCards = DefaultFeature;
export type Feature_MyLedgerDisplayAppDeveloperName = DefaultFeature;