diff --git a/.changeset/orange-turkeys-wait.md b/.changeset/orange-turkeys-wait.md
new file mode 100644
index 000000000000..0fbded1abcec
--- /dev/null
+++ b/.changeset/orange-turkeys-wait.md
@@ -0,0 +1,8 @@
+---
+"@ledgerhq/types-live": minor
+"ledger-live-desktop": minor
+"ledger-live-mobile": minor
+"@ledgerhq/live-common": minor
+---
+
+Add link param to mevProtection ff
diff --git a/apps/ledger-live-desktop/src/renderer/screens/settings/SettingsSection.tsx b/apps/ledger-live-desktop/src/renderer/screens/settings/SettingsSection.tsx
index 8245f8bd969c..e2f505a1c8b2 100644
--- a/apps/ledger-live-desktop/src/renderer/screens/settings/SettingsSection.tsx
+++ b/apps/ledger-live-desktop/src/renderer/screens/settings/SettingsSection.tsx
@@ -2,6 +2,9 @@ import React from "react";
import styled from "styled-components";
import { rgba } from "~/renderer/styles/helpers";
import Box, { Card } from "~/renderer/components/Box";
+import { Flex, Link } from "@ledgerhq/react-ui";
+import { openURL } from "~/renderer/linking";
+
export const SettingsSection = styled(Card).attrs(() => ({
p: 0,
}))``;
@@ -94,6 +97,8 @@ type SettingsSectionRowProps = {
childrenContainerStyle?: React.CSSProperties;
dataTestId?: string;
id?: string;
+ externalUrl?: string;
+ linkText?: string;
};
export const SettingsSectionRow = ({
title,
@@ -106,6 +111,8 @@ export const SettingsSectionRow = ({
childrenContainerStyle,
dataTestId,
id,
+ externalUrl,
+ linkText,
}: SettingsSectionRowProps) => (
{desc}
+ {externalUrl && (
+
+ openURL(externalUrl)}
+ >
+ {linkText}
+
+
+ )}
{children}
diff --git a/apps/ledger-live-desktop/src/renderer/screens/settings/sections/General/index.tsx b/apps/ledger-live-desktop/src/renderer/screens/settings/sections/General/index.tsx
index 5e81b0d0437d..45ef06c1de18 100644
--- a/apps/ledger-live-desktop/src/renderer/screens/settings/sections/General/index.tsx
+++ b/apps/ledger-live-desktop/src/renderer/screens/settings/sections/General/index.tsx
@@ -25,7 +25,8 @@ const SectionGeneral = () => {
const { t } = useTranslation();
useInitSupportedCounterValues();
const lldAnalyticsOptInPromptFlag = useFeature("lldAnalyticsOptInPrompt");
-
+ const llMevProtectionFeatureFlag = useFeature("llMevProtection");
+ const mevLearnMoreLink = llMevProtectionFeatureFlag?.params?.link?.trim() || undefined;
return (
<>
@@ -97,6 +98,8 @@ const SectionGeneral = () => {
desc={t("settings.display.mevProtectionDesc")}
dataTestId="setting-mevProtection"
id="setting-mevProtection"
+ linkText={t("settings.display.mevProtectionLearnMore")}
+ externalUrl={mevLearnMoreLink}
>
diff --git a/apps/ledger-live-desktop/static/i18n/en/app.json b/apps/ledger-live-desktop/static/i18n/en/app.json
index 638d6f09cb42..36cefc5c1f45 100644
--- a/apps/ledger-live-desktop/static/i18n/en/app.json
+++ b/apps/ledger-live-desktop/static/i18n/en/app.json
@@ -4154,7 +4154,8 @@
"walletSync": "Ledger Sync",
"walletSyncDesc": "Sync your Ledger Live crypto accounts across different phones and computers.",
"mevProtection": "MEV Protection",
- "mevProtectionDesc": "Enable MEV Protection for more reliable transactions on Ethereum",
+ "mevProtectionDesc": "Enable MEV Protection for more reliable transactions on Ethereum.",
+ "mevProtectionLearnMore": "Privacy notice",
"marketPerformanceWidget": "Market Performance Widget",
"marketPerformanceWidgetDesc": "Enable this feature to view the top gainers and losers over selected timeframes on the portfolio page."
},
diff --git a/apps/ledger-live-mobile/src/locales/en/common.json b/apps/ledger-live-mobile/src/locales/en/common.json
index 64487a73fa99..0aebe546e02d 100644
--- a/apps/ledger-live-mobile/src/locales/en/common.json
+++ b/apps/ledger-live-mobile/src/locales/en/common.json
@@ -2909,7 +2909,8 @@
"analytics": "Analytics",
"analyticsDesc": "Enable Ledger to collect app usage data to help measure Ledger Live’s performance and enhance both the app and your experience.",
"mevProtection": "MEV Protection",
- "mevProtectionDesc": "Enable MEV Protection for more reliable transactions on Ethereum",
+ "mevProtectionDesc": "Enable MEV Protection for more reliable transactions on Ethereum.",
+ "mevProtectionLearnMore": "Privacy notice",
"personalizedRecommendations": "Personalized experience",
"personalizedRecommendationsDesc": "Enable Ledger to collect app usage data to provide personalized recommendations and content that match your preferences and to help measure the performance of our marketing campaigns.",
"analyticsModal": {
diff --git a/apps/ledger-live-mobile/src/screens/Settings/General/MevProtection.tsx b/apps/ledger-live-mobile/src/screens/Settings/General/MevProtection.tsx
index 070ac9fb7502..8f733602c2d3 100644
--- a/apps/ledger-live-mobile/src/screens/Settings/General/MevProtection.tsx
+++ b/apps/ledger-live-mobile/src/screens/Settings/General/MevProtection.tsx
@@ -1,19 +1,33 @@
-import React, { useCallback } from "react";
+import React, { ReactNode, useCallback } from "react";
import { useSelector, useDispatch } from "react-redux";
import { useTranslation } from "react-i18next";
-import { Switch } from "@ledgerhq/native-ui";
+import { Flex, Text, Switch } from "@ledgerhq/native-ui";
import SettingsRow from "~/components/SettingsRow";
import { setMevProtection } from "~/actions/settings";
import { mevProtectionSelector } from "~/reducers/settings";
import Track from "~/analytics/Track";
import { track } from "~/analytics";
+import { useFeature } from "@ledgerhq/live-common/featureFlags/index";
+import { Linking } from "react-native";
+import styled from "styled-components/native";
+const StyledText = styled(Text).attrs(() => ({
+ color: "neutral.c70",
+}))`
+ text-decoration: underline;
+ text-decoration-color: ${({ theme }) => theme.colors.neutral.c70};
+`;
const MevProtectionRow = () => {
const { t } = useTranslation();
const mevProctection = useSelector(mevProtectionSelector);
const dispatch = useDispatch();
+ const llMevProtectionFeatureFlag = useFeature("llMevProtection");
+ const mevLearnMoreLink = llMevProtectionFeatureFlag?.params?.link?.trim() || undefined;
+
+ const onPressLink = (url: string) => Linking.openURL(url);
+
const toggleMevProtection = useCallback(
(value: boolean) => {
dispatch(setMevProtection(value));
@@ -31,13 +45,31 @@ const MevProtectionRow = () => {
[dispatch],
);
+ const description: ReactNode = (
+
+
+ {t("settings.display.mevProtectionDesc")}
+
+ {mevLearnMoreLink && (
+ onPressLink(mevLearnMoreLink)}
+ variant="body"
+ fontWeight="medium"
+ >
+ {t("settings.display.mevProtectionLearnMore")}
+
+ )}
+
+ );
+
return (
<>
toggleMevProtection(!mevProctection)} />
diff --git a/libs/ledger-live-common/src/featureFlags/defaultFeatures.ts b/libs/ledger-live-common/src/featureFlags/defaultFeatures.ts
index 99012d2e12e0..822398217688 100644
--- a/libs/ledger-live-common/src/featureFlags/defaultFeatures.ts
+++ b/libs/ledger-live-common/src/featureFlags/defaultFeatures.ts
@@ -501,7 +501,10 @@ export const DEFAULT_FEATURES: Features = {
warningVisible: true,
},
},
- llMevProtection: DEFAULT_FEATURE,
+ llMevProtection: {
+ ...DEFAULT_FEATURE,
+ params: { link: null },
+ },
llmNetworkBasedAddAccountFlow: DEFAULT_FEATURE,
llCounterValueGranularitiesRates: {
...DEFAULT_FEATURE,
diff --git a/libs/ledgerjs/packages/types-live/src/feature.ts b/libs/ledgerjs/packages/types-live/src/feature.ts
index 94f8faa7f052..ffc41a222f93 100644
--- a/libs/ledgerjs/packages/types-live/src/feature.ts
+++ b/libs/ledgerjs/packages/types-live/src/feature.ts
@@ -199,7 +199,7 @@ export type Features = CurrencyFeatures & {
llmMemoTag: Feature_MemoTag;
lldMemoTag: Feature_MemoTag;
ldmkTransport: Feature_LdmkTransport;
- llMevProtection: DefaultFeature;
+ llMevProtection: Feature_LlMevProtection;
llmNetworkBasedAddAccountFlow: DefaultFeature;
llCounterValueGranularitiesRates: Feature_LlCounterValueGranularitiesRates;
llmRebornLP: Feature_LlmRebornLP;
@@ -549,6 +549,10 @@ export type Feature_LlCounterValueGranularitiesRates = Feature<{
hourly: number;
}>;
+export type Feature_LlMevProtection = Feature<{
+ link: string | null;
+}>;
+
export type Feature_CounterValue = DefaultFeature;
export type Feature_MockFeature = DefaultFeature;
export type Feature_DisableNftSend = DefaultFeature;