diff --git a/android/app/build.gradle b/android/app/build.gradle index b35a4a2bac5..1f808b24750 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -179,7 +179,7 @@ android { applicationId "io.metamask" minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion - versionName "7.79.0" + versionName "7.80.0" versionCode 4532 testBuildType System.getProperty('testBuildType', 'debug') testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" diff --git a/app/actions/user/index.ts b/app/actions/user/index.ts index 4fc2100715e..a737b055ead 100644 --- a/app/actions/user/index.ts +++ b/app/actions/user/index.ts @@ -28,6 +28,7 @@ import { type ClearMusdConversionAssetDetailCtasSeenAction, type SetMoneyOnboardingSeenAction, type SetTokenOverviewChartTypeAction, + type SetOnboardingStepperStepAction, UserActionType, } from './types'; @@ -250,3 +251,18 @@ export function setTokenOverviewChartType( payload: { chartType }, }; } + +/** + * Action to set the current step for a named onboarding stepper. + * Keyed by stepperId to support multiple independent steppers without + * adding new Redux fields per product. + */ +export function setOnboardingStepperStep( + stepperId: string, + step: number, +): SetOnboardingStepperStepAction { + return { + type: UserActionType.SET_ONBOARDING_STEPPER_STEP, + payload: { stepperId, step }, + }; +} diff --git a/app/actions/user/types.ts b/app/actions/user/types.ts index 3c716b3838c..ada3714be53 100644 --- a/app/actions/user/types.ts +++ b/app/actions/user/types.ts @@ -31,6 +31,7 @@ export enum UserActionType { CLEAR_MUSD_CONVERSION_ASSET_DETAIL_CTAS_SEEN = 'CLEAR_MUSD_CONVERSION_ASSET_DETAIL_CTAS_SEEN', SET_MONEY_ONBOARDING_SEEN = 'SET_MONEY_ONBOARDING_SEEN', SET_TOKEN_OVERVIEW_CHART_TYPE = 'SET_TOKEN_OVERVIEW_CHART_TYPE', + SET_ONBOARDING_STEPPER_STEP = 'SET_ONBOARDING_STEPPER_STEP', } // User actions @@ -124,6 +125,11 @@ export type SetTokenOverviewChartTypeAction = payload: { chartType: ChartType }; }; +export type SetOnboardingStepperStepAction = + Action & { + payload: { stepperId: string; step: number }; + }; + /** * User actions union type */ @@ -154,4 +160,5 @@ export type UserAction = | SetMusdConversionAssetDetailCtaSeenAction | ClearMusdConversionAssetDetailCtasSeenAction | SetMoneyOnboardingSeenAction - | SetTokenOverviewChartTypeAction; + | SetTokenOverviewChartTypeAction + | SetOnboardingStepperStepAction; diff --git a/app/component-library/components-temp/ActionListItem/ActionListItem.tsx b/app/component-library/components-temp/ActionListItem/ActionListItem.tsx index 40cfd75a19d..04832bf07f3 100644 --- a/app/component-library/components-temp/ActionListItem/ActionListItem.tsx +++ b/app/component-library/components-temp/ActionListItem/ActionListItem.tsx @@ -18,6 +18,7 @@ import { import { useTailwind } from '@metamask/design-system-twrnc-preset'; // Internal dependencies +import { useElevatedSurface } from '../../../util/theme/themeUtils'; import { ActionListItemProps } from './ActionListItem.types'; /** @@ -38,6 +39,7 @@ const ActionListItem: React.FC = ({ ...pressableProps }) => { const tw = useTailwind(); + const surfaceClass = useElevatedSurface(); // Render label based on type const renderLabel = () => { @@ -98,11 +100,11 @@ const ActionListItem: React.FC = ({ const getStyle = useCallback( ({ pressed }: { pressed: boolean }) => tw.style( - 'bg-default px-4 py-3', + `${surfaceClass} px-4 py-3`, pressed && !isDisabled && 'bg-default-pressed', isDisabled && 'opacity-50', ), - [tw, isDisabled], + [tw, isDisabled, surfaceClass], ); return ( diff --git a/app/component-library/components-temp/ListItemMultiSelectButton/ListItemMultiSelectButton.styles.ts b/app/component-library/components-temp/ListItemMultiSelectButton/ListItemMultiSelectButton.styles.ts index cdf02ff4586..1ae30f84887 100644 --- a/app/component-library/components-temp/ListItemMultiSelectButton/ListItemMultiSelectButton.styles.ts +++ b/app/component-library/components-temp/ListItemMultiSelectButton/ListItemMultiSelectButton.styles.ts @@ -3,6 +3,7 @@ import { StyleSheet, ViewStyle } from 'react-native'; // External dependencies. import { Theme } from '../../../util/theme/models'; +import { getElevatedSurfaceColor } from '../../../util/theme/themeUtils'; // Internal dependencies. import { ListItemMultiSelectButtonStyleSheetVars } from './ListItemMultiSelectButton.types'; @@ -57,7 +58,7 @@ const styleSheet = (params: { container: { backgroundColor: isSelected ? colors.background.muted - : colors.background.default, + : getElevatedSurfaceColor(theme), flexDirection: 'row', alignItems: 'center', }, diff --git a/app/component-library/components-temp/SegmentedProgressBar/SegmentedProgressBar.test.tsx b/app/component-library/components-temp/SegmentedProgressBar/SegmentedProgressBar.test.tsx new file mode 100644 index 00000000000..b52f25d7866 --- /dev/null +++ b/app/component-library/components-temp/SegmentedProgressBar/SegmentedProgressBar.test.tsx @@ -0,0 +1,51 @@ +// Third party dependencies. +import React from 'react'; +import { render } from '@testing-library/react-native'; + +// Internal dependencies. +import SegmentedProgressBar from './SegmentedProgressBar'; + +describe('SegmentedProgressBar', () => { + it('renders the outer track with the provided testID', () => { + const { getByTestId } = render( + , + ); + expect(getByTestId('progress')).toBeOnTheScreen(); + }); + + it('renders the correct number of segment children for a given total', () => { + const total = 4; + const { getByTestId } = render( + , + ); + expect(getByTestId('progress').children).toHaveLength(total); + }); + + it('renders no segments when total is 0', () => { + const { getByTestId } = render( + , + ); + expect(getByTestId('progress').children).toHaveLength(0); + }); + + it('renders all segments when current is 0', () => { + const total = 3; + const { getByTestId } = render( + , + ); + expect(getByTestId('progress').children).toHaveLength(total); + }); + + it('renders all segments when current equals total', () => { + const total = 3; + const { getByTestId } = render( + , + ); + expect(getByTestId('progress').children).toHaveLength(total); + }); + + it('renders without a testID when testID prop is omitted', () => { + const { toJSON } = render(); + expect(toJSON()).not.toBeNull(); + }); +}); diff --git a/app/component-library/components-temp/SegmentedProgressBar/SegmentedProgressBar.tsx b/app/component-library/components-temp/SegmentedProgressBar/SegmentedProgressBar.tsx new file mode 100644 index 00000000000..e6503620e04 --- /dev/null +++ b/app/component-library/components-temp/SegmentedProgressBar/SegmentedProgressBar.tsx @@ -0,0 +1,46 @@ +import React from 'react'; +import { Box } from '@metamask/design-system-react-native'; + +export interface SegmentedProgressBarProps { + /** + * 1-based count of completed steps used to compute the filled segments. + */ + current: number; + /** + * Total number of steps. Guarded against non-positive values to avoid + * divide-by-zero when the caller hasn't wired this yet. + */ + total: number; + /** + * Optional testID forwarded to the outer track. + */ + testID?: string; +} + +enum SegmentState { + Completed = 'completed', + Upcoming = 'upcoming', +} + +const Segment = ({ state }: { state: SegmentState }) => ( + +); + +const SegmentedProgressBar = ({ + current, + total, + testID, +}: SegmentedProgressBarProps) => ( + + {Array.from({ length: total }, (_, index) => ( + + ))} + +); + +export default SegmentedProgressBar; diff --git a/app/component-library/components-temp/SegmentedProgressBar/index.ts b/app/component-library/components-temp/SegmentedProgressBar/index.ts new file mode 100644 index 00000000000..eec8e83a3f1 --- /dev/null +++ b/app/component-library/components-temp/SegmentedProgressBar/index.ts @@ -0,0 +1,2 @@ +export { default } from './SegmentedProgressBar'; +export type { SegmentedProgressBarProps } from './SegmentedProgressBar'; diff --git a/app/component-library/components-temp/StepperCard/StepperCard.test.tsx b/app/component-library/components-temp/StepperCard/StepperCard.test.tsx new file mode 100644 index 00000000000..a2eef0bc901 --- /dev/null +++ b/app/component-library/components-temp/StepperCard/StepperCard.test.tsx @@ -0,0 +1,227 @@ +// Third party dependencies. +import React from 'react'; +import { render, fireEvent } from '@testing-library/react-native'; + +// Internal dependencies. +import StepperCard from './StepperCard'; +import type { StepperCardStep } from './StepperCard.types'; + +jest.mock('@metamask/design-system-twrnc-preset', () => { + const tw = (..._args: unknown[]) => ({}); + tw.style = jest.fn(() => ({})); + return { useTailwind: () => tw }; +}); + +const mockImage = { uri: 'test-image' }; + +const makeStep = (overrides?: Partial): StepperCardStep => ({ + title: 'Test Title', + description: 'Test description', + image: mockImage, + primaryCta: { + text: 'Primary', + onPress: jest.fn(), + }, + ...overrides, +}); + +describe('StepperCard', () => { + beforeEach(() => { + jest.clearAllMocks(); + }); + + describe('content rendering', () => { + it('renders the current step title', () => { + const { getByTestId } = render( + , + ); + expect(getByTestId('card-title')).toHaveTextContent('Onboarding Step'); + }); + + it('renders the current step description', () => { + const { getByTestId } = render( + , + ); + expect(getByTestId('card-description')).toHaveTextContent( + 'Fund your account', + ); + }); + + it('renders the container with the derived testID', () => { + const { getByTestId } = render( + , + ); + expect(getByTestId('my-card-container')).toBeOnTheScreen(); + }); + + it('renders the step at the given currentStep index', () => { + const { getByTestId } = render( + , + ); + expect(getByTestId('card-title')).toHaveTextContent('Step 2'); + }); + }); + + describe('completion bounds guard', () => { + it('returns null when currentStep equals steps.length', () => { + const { toJSON } = render( + , + ); + expect(toJSON()).toBeNull(); + }); + + it('returns null when currentStep exceeds steps.length', () => { + const { toJSON } = render( + , + ); + expect(toJSON()).toBeNull(); + }); + + it('calls onComplete when currentStep reaches steps.length', () => { + const onComplete = jest.fn(); + render( + , + ); + expect(onComplete).toHaveBeenCalledTimes(1); + }); + }); + + describe('primary CTA', () => { + it('renders the primary CTA text', () => { + const { getByText } = render( + , + ); + expect(getByText('Get started')).toBeOnTheScreen(); + }); + + it('fires primaryCta.onPress when pressed', () => { + const onPress = jest.fn(); + const { getByText } = render( + , + ); + fireEvent.press(getByText('Go')); + expect(onPress).toHaveBeenCalledTimes(1); + }); + }); + + describe('secondary CTA', () => { + it('does not render secondary CTA when secondaryCta is absent', () => { + const { queryByText } = render( + , + ); + expect(queryByText('Skip')).toBeNull(); + }); + + it('renders secondary CTA when secondaryCta is provided', () => { + const { getByText } = render( + , + ); + expect(getByText('Skip')).toBeOnTheScreen(); + }); + + it('fires secondaryCta.onPress when pressed', () => { + const onSecondaryPress = jest.fn(); + const { getByText } = render( + , + ); + fireEvent.press(getByText('Skip')); + expect(onSecondaryPress).toHaveBeenCalledTimes(1); + }); + }); + + describe('description tooltip', () => { + it('does not render tooltip icon when onDescriptionTooltipPress is absent', () => { + const { queryByLabelText } = render( + , + ); + expect(queryByLabelText('More information')).toBeNull(); + }); + + it('renders tooltip icon when onDescriptionTooltipPress is provided', () => { + const { getByLabelText } = render( + , + ); + expect(getByLabelText('More information')).toBeOnTheScreen(); + }); + + it('uses the default accessibilityLabel when none is provided', () => { + const { getByLabelText } = render( + , + ); + expect(getByLabelText('More information')).toBeOnTheScreen(); + }); + + it('uses custom descriptionTooltipAccessibilityLabel when provided', () => { + const { getByLabelText } = render( + , + ); + expect(getByLabelText('APY information')).toBeOnTheScreen(); + }); + + it('fires onDescriptionTooltipPress when tooltip icon is pressed', () => { + const onTooltipPress = jest.fn(); + const { getByLabelText } = render( + , + ); + fireEvent.press(getByLabelText('More information')); + expect(onTooltipPress).toHaveBeenCalledTimes(1); + }); + }); +}); diff --git a/app/component-library/components-temp/StepperCard/StepperCard.tsx b/app/component-library/components-temp/StepperCard/StepperCard.tsx new file mode 100644 index 00000000000..f7bf5312ab0 --- /dev/null +++ b/app/component-library/components-temp/StepperCard/StepperCard.tsx @@ -0,0 +1,146 @@ +import React, { useEffect, useRef } from 'react'; +import { Image, TouchableOpacity } from 'react-native'; +import { + Box, + BoxAlignItems, + Button, + ButtonSize, + ButtonVariant, + FontWeight, + Icon, + IconColor, + IconName, + IconSize, + Text, + TextColor, + TextVariant, +} from '@metamask/design-system-react-native'; +import { useTailwind } from '@metamask/design-system-twrnc-preset'; +import { strings } from '../../../../locales/i18n'; +import { StepperCardProps } from './StepperCard.types'; +import SegmentedProgressBar from '../SegmentedProgressBar'; + +const StepperCard = ({ + steps, + currentStep, + onComplete, + testID, +}: StepperCardProps) => { + const tw = useTailwind(); + + const getTestId = (suffix: string) => + testID ? `${testID}-${suffix}` : undefined; + + const isComplete = currentStep >= steps.length; + + const onCompleteRef = useRef(onComplete); + onCompleteRef.current = onComplete; + + const hasFiredRef = useRef(false); + + useEffect(() => { + if (isComplete && !hasFiredRef.current) { + hasFiredRef.current = true; + onCompleteRef.current?.(); + } + }, [isComplete]); + + if (isComplete) { + return null; + } + + const step = steps[currentStep]; + const totalSteps = steps.length; + + return ( + + {/* Progress Bar */} + + + + + {/* Image */} + + + + + {/* Content */} + + + + {step.title} + + + {step.description} + {step.onDescriptionTooltipPress && ( + + + + )} + + + + {/* CTAs */} + + {step.secondaryCta && ( + + )} + + + + + ); +}; + +export default StepperCard; diff --git a/app/component-library/components-temp/StepperCard/StepperCard.types.ts b/app/component-library/components-temp/StepperCard/StepperCard.types.ts new file mode 100644 index 00000000000..6ba95ee17f9 --- /dev/null +++ b/app/component-library/components-temp/StepperCard/StepperCard.types.ts @@ -0,0 +1,43 @@ +import { ImageSourcePropType } from 'react-native'; + +export interface StepperCardCta { + text: string; + onPress: () => void; +} + +export interface StepperCardStep { + title: string; + description: string; + /** + * When provided, an info icon is rendered inline after the description text. + * The handler is called when the icon is pressed. + */ + onDescriptionTooltipPress?: () => void; + /** + * Accessibility label for the inline tooltip icon. + * Defaults to "More information" when not provided. + */ + descriptionTooltipAccessibilityLabel?: string; + image: ImageSourcePropType; + primaryCta: StepperCardCta; + secondaryCta?: StepperCardCta; +} + +export interface StepperCardProps { + steps: StepperCardStep[]; + /** + * 0-based index of the currently active step. + */ + currentStep: number; + /** + * Called once when currentStep reaches or exceeds steps.length. + * StepperCard returns null at that point — no consumer guard needed. + */ + onComplete?: () => void; + /** + * Optional prefix used to derive child testIDs: + * `${testID}-container`, `${testID}-progress-bar`, `${testID}-step-image`, + * `${testID}-title`, `${testID}-description`, `${testID}-cta-button` + */ + testID?: string; +} diff --git a/app/component-library/components-temp/StepperCard/index.ts b/app/component-library/components-temp/StepperCard/index.ts new file mode 100644 index 00000000000..08be16924be --- /dev/null +++ b/app/component-library/components-temp/StepperCard/index.ts @@ -0,0 +1,6 @@ +export { default } from './StepperCard'; +export type { + StepperCardProps, + StepperCardStep, + StepperCardCta, +} from './StepperCard.types'; diff --git a/app/component-library/components/BottomSheets/BottomSheet/foundation/BottomSheetDialog/BottomSheetDialog.styles.ts b/app/component-library/components/BottomSheets/BottomSheet/foundation/BottomSheetDialog/BottomSheetDialog.styles.ts index 9b91d26744e..9cf7d598565 100644 --- a/app/component-library/components/BottomSheets/BottomSheet/foundation/BottomSheetDialog/BottomSheetDialog.styles.ts +++ b/app/component-library/components/BottomSheets/BottomSheet/foundation/BottomSheetDialog/BottomSheetDialog.styles.ts @@ -4,6 +4,7 @@ import { Platform, StyleSheet, ViewStyle } from 'react-native'; // External dependencies. import { Theme } from '../../../../../../util/theme/models'; +import { getElevatedSurfaceColor } from '../../../../../../util/theme/themeUtils'; // Internal dependencies. import { BottomSheetDialogStyleSheetVars } from './BottomSheetDialog.types'; @@ -33,7 +34,7 @@ const styleSheet = (params: { } as ViewStyle) as ViewStyle, sheet: Object.assign( { - backgroundColor: colors.background.default, + backgroundColor: getElevatedSurfaceColor(theme), borderTopLeftRadius: 24, borderTopRightRadius: 24, maxHeight: maxSheetHeight, diff --git a/app/components/Nav/Main/MainNavigator.js b/app/components/Nav/Main/MainNavigator.js index 54dc4d65556..0ff319de12c 100644 --- a/app/components/Nav/Main/MainNavigator.js +++ b/app/components/Nav/Main/MainNavigator.js @@ -21,7 +21,6 @@ import NotificationSettingsSection from '../../Views/Settings/NotificationsSetti import RegionSelector from '../../UI/Ramp/Views/Settings/RegionSelector/RegionSelector'; import NotificationsView from '../../Views/Notifications'; import NotificationsDetails from '../../Views/Notifications/Details'; -import OptIn from '../../Views/Notifications/OptIn'; import AppInformation from '../../Views/Settings/AppInformation'; import DeveloperOptions from '../../Views/Settings/DeveloperOptions'; import Contacts from '../../Views/Settings/Contacts'; @@ -103,7 +102,11 @@ import { AccountPermissionsScreens } from '../../../components/Views/AccountPerm import { StakeModalStack, StakeScreenStack } from '../../UI/Stake/routes'; import { AssetLoader } from '../../Views/AssetLoader'; import { EarnScreenStack, EarnModalStack } from '../../UI/Earn/routes'; -import { MoneyAccountStackGate, MoneyModalStack } from '../../UI/Money/routes'; +import { + MoneyConfirmationScreenStack, + MoneyModalStack, + MoneyTabScreenStack, +} from '../../UI/Money/routes'; import MoneyOnboardingView from '../../UI/Money/Views/MoneyOnboardingView'; import { selectMoneyHomeScreenEnabledFlag } from '../../UI/Money/selectors/featureFlags'; import { BridgeTransactionDetails } from '../../UI/Bridge/components/TransactionDetails/TransactionDetails'; @@ -431,26 +434,6 @@ const SnapsSettingsStack = () => ( ); ///: END:ONLY_INCLUDE_IF -const NotificationsOptInStack = () => ( - - - - - -); - const SettingsFlow = () => { const { colors } = useTheme(); return ( @@ -893,7 +876,7 @@ const HomeTabs = () => { ) : ( ( component={NotificationSettingsSection} options={{ headerShown: false }} /> - { <> + { options={{ headerShown: false }} /> )} - { it('has notification routes defined', () => { expect(Routes.NOTIFICATIONS.VIEW).toBeDefined(); - expect(Routes.NOTIFICATIONS.OPT_IN).toBeDefined(); - expect(Routes.NOTIFICATIONS.OPT_IN_STACK).toBeDefined(); expect(Routes.NOTIFICATIONS.DETAILS).toBeDefined(); }); @@ -132,6 +130,26 @@ describe('MainNavigator Route Constants', () => { it('has market insights routes defined', () => { expect(Routes.MARKET_INSIGHTS.VIEW).toBeDefined(); }); + + it('has money routes defined', () => { + expect(Routes.MONEY.ROOT).toBeDefined(); + expect(Routes.MONEY.CONFIRMATIONS_ROOT).toBeDefined(); + expect(Routes.MONEY.HOME).toBeDefined(); + expect(Routes.MONEY.ACTIVITY).toBeDefined(); + expect(Routes.MONEY.HOW_IT_WORKS).toBeDefined(); + expect(Routes.MONEY.POTENTIAL_EARNINGS).toBeDefined(); + expect(Routes.MONEY.ONBOARDING).toBeDefined(); + expect(Routes.MONEY.MODALS.ROOT).toBeDefined(); + expect(Routes.MONEY.MODALS.ADD_MONEY_SHEET).toBeDefined(); + expect(Routes.MONEY.MODALS.MORE_SHEET).toBeDefined(); + expect(Routes.MONEY.MODALS.TRANSFER_MONEY_SHEET).toBeDefined(); + expect(Routes.MONEY.MODALS.APY_INFO_SHEET).toBeDefined(); + expect(Routes.MONEY.MODALS.EARNINGS_INFO_SHEET).toBeDefined(); + expect(Routes.MONEY.MODALS.MONEY_BALANCE_INFO_SHEET).toBeDefined(); + expect(Routes.MONEY.MODALS.LINK_CARD_SHEET).toBeDefined(); + expect(Routes.MONEY.MODALS.EARN_CRYPTO_INFO_SHEET).toBeDefined(); + expect(Routes.MONEY.MODALS.TRANSACTION_DETAILS_SHEET).toBeDefined(); + }); }); describe('MainNavigator Tab Options', () => { diff --git a/app/components/Nav/Main/MainNavigator.test.tsx b/app/components/Nav/Main/MainNavigator.test.tsx index df3ab890a9a..639cb233f38 100644 --- a/app/components/Nav/Main/MainNavigator.test.tsx +++ b/app/components/Nav/Main/MainNavigator.test.tsx @@ -1051,19 +1051,6 @@ describe('MainNavigator', () => { expect(screen).toBeDefined(); }); - it('includes NotificationsOptInStack screen', () => { - const container = renderWithProvider(, { - state: initialRootState, - }); - - const screenProps = getScreenProps(container); - const screen = screenProps?.find( - (s) => s?.name === Routes.NOTIFICATIONS.OPT_IN_STACK, - ); - - expect(screen).toBeDefined(); - }); - it('includes DeFiProtocolPositionDetails screen', () => { const container = renderWithProvider(, { state: initialRootState, @@ -1369,17 +1356,6 @@ describe('MainNavigator', () => { const Component = getScreenComponent(root, 'Asset'); expect(renderInner(Component).toJSON()).toBeTruthy(); }); - - it('renders NotificationsOptInStack navigator', () => { - const { root } = renderWithProvider(, { - state: initialRootState, - }); - const Component = getScreenComponent( - root, - Routes.NOTIFICATIONS.OPT_IN_STACK, - ); - expect(renderInner(Component).toJSON()).toBeTruthy(); - }); }); describe('HomeTabs child tab screens', () => { diff --git a/app/components/UI/BasicFunctionality/BasicFunctionalityModal/BasicFunctionalityModal.tsx b/app/components/UI/BasicFunctionality/BasicFunctionalityModal/BasicFunctionalityModal.tsx index 757cde63c43..86ada0a0ee7 100644 --- a/app/components/UI/BasicFunctionality/BasicFunctionalityModal/BasicFunctionalityModal.tsx +++ b/app/components/UI/BasicFunctionality/BasicFunctionalityModal/BasicFunctionalityModal.tsx @@ -94,10 +94,7 @@ const BasicFunctionalityModal = () => { .build(), ); }); - if ( - route.params.caller === Routes.SETTINGS.NOTIFICATIONS || - route.params.caller === Routes.NOTIFICATIONS.OPT_IN - ) { + if (route.params.caller === Routes.SETTINGS.NOTIFICATIONS) { await enableNotificationsFromModal(); } }; diff --git a/app/components/UI/Card/Views/CardAuthentication/CardAuthentication.testIds.ts b/app/components/UI/Card/Views/CardAuthentication/CardAuthentication.testIds.ts index 2c919f76935..df219d5f881 100644 --- a/app/components/UI/Card/Views/CardAuthentication/CardAuthentication.testIds.ts +++ b/app/components/UI/Card/Views/CardAuthentication/CardAuthentication.testIds.ts @@ -1,7 +1,16 @@ export const CardAuthenticationSelectors = { VERIFY_ACCOUNT_BUTTON: 'verify-account-button', SIGNUP_BUTTON: 'signup-button', - WELCOME_TO_CARD_TITLE_TEXT: 'welcome-to-card-title-text', - WELCOME_TO_CARD_DESCRIPTION_TEXT: 'welcome-to-card-description-text', - FOX_IMAGE: 'fox-image', + EMAIL_FIELD: 'email-field', + PASSWORD_FIELD: 'password-field', + PASSWORD_VISIBILITY_TOGGLE: 'password-visibility-toggle', + LOGIN_ERROR_TEXT: 'login-error-text', + US_LOCATION_BOX: 'us-location-box', + INTERNATIONAL_LOCATION_BOX: 'international-location-box', + OTP_CODE_FIELD: 'otp-code-field', + OTP_CODE_FIELD_ERROR: 'otp-code-field-error', + OTP_CONFIRM_BUTTON: 'otp-confirm-button', + OTP_BACK_TO_LOGIN_BUTTON: 'otp-back-to-login-button', + OTP_RESEND_VERIFICATION: 'otp-resend-verification', + OTP_ERROR_TEXT: 'otp-error-text', }; diff --git a/app/components/UI/Card/Views/CardAuthentication/CardAuthentication.tsx b/app/components/UI/Card/Views/CardAuthentication/CardAuthentication.tsx index 65a8c883948..b09c44a744b 100644 --- a/app/components/UI/Card/Views/CardAuthentication/CardAuthentication.tsx +++ b/app/components/UI/Card/Views/CardAuthentication/CardAuthentication.tsx @@ -320,12 +320,12 @@ const CardAuthentication = () => { accessibilityLabel: strings( 'card.card_otp_authentication.confirm_code_label', ), - testID: 'otp-code-field', + testID: CardAuthenticationSelectors.OTP_CODE_FIELD, }} /> {error && ( @@ -339,7 +339,7 @@ const CardAuthentication = () => { {resendCooldown > 0 ? ( strings('card.card_otp_authentication.resend_cooldown', { @@ -363,7 +363,7 @@ const CardAuthentication = () => { {otpError && ( @@ -386,7 +386,7 @@ const CardAuthentication = () => { > { > {countryCodeToFlag('US')} { accessibilityLabel: strings( 'card.card_authentication.email_label', ), - testID: 'email-field', + testID: CardAuthenticationSelectors.EMAIL_FIELD, }} /> @@ -445,7 +445,9 @@ const CardAuthentication = () => { endAccessory={ setIsPasswordVisible(!isPasswordVisible)} - testID="password-visibility-toggle" + testID={ + CardAuthenticationSelectors.PASSWORD_VISIBILITY_TOGGLE + } > { accessibilityLabel: strings( 'card.card_authentication.password_label', ), - testID: 'password-field', + testID: CardAuthenticationSelectors.PASSWORD_FIELD, }} /> @@ -504,13 +506,13 @@ const CardAuthentication = () => { loading || !confirmCode || confirmCode.length < CODE_LENGTH } isFullWidth - testID="otp-confirm-button" + testID={CardAuthenticationSelectors.OTP_CONFIRM_BUTTON} > {strings('card.card_otp_authentication.confirm_button')} { {error} diff --git a/app/components/UI/Card/Views/CardHome/CardHome.view.test.tsx b/app/components/UI/Card/Views/CardHome/CardHome.view.test.tsx new file mode 100644 index 00000000000..a045deef7af --- /dev/null +++ b/app/components/UI/Card/Views/CardHome/CardHome.view.test.tsx @@ -0,0 +1,230 @@ +import '../../../../../../tests/component-view/mocks'; +import { act, fireEvent, waitFor } from '@testing-library/react-native'; +import { Alert } from 'react-native'; +import Engine from '../../../../../core/Engine'; +import { renderCardHomeView } from '../../../../../../tests/component-view/renderers/cardViewRenderer'; +import { + createRouteParamsProbe, + getRouteParamsProbeTestId, +} from '../../../../../../tests/component-view/render'; +import { CardHomeSelectors } from './CardHome.testIds'; +import Routes from '../../../../../constants/navigation/Routes'; +import Cashback from '../Cashback/Cashback'; +import ChooseYourCard from '../ChooseYourCard/ChooseYourCard'; +import CardAuthentication from '../CardAuthentication/CardAuthentication'; +import { CashbackSelectors } from '../Cashback/Cashback.testIds'; +import { ChooseYourCardSelectors } from '../ChooseYourCard/ChooseYourCard.testIds'; +import { CardAuthenticationSelectors } from '../CardAuthentication/CardAuthentication.testIds'; + +describe('CardHome', () => { + describe('navigation', () => { + describe('when authenticated', () => { + it('opens Add Funds modal with the active USDC funding token when Add Funds button is pressed', async () => { + const { getByTestId, findByTestId } = renderCardHomeView({ + extraRoutes: [ + { + name: Routes.CARD.MODALS.ID, + Component: createRouteParamsProbe(Routes.CARD.MODALS.ID), + }, + ], + }); + + fireEvent.press(getByTestId(CardHomeSelectors.ADD_FUNDS_BUTTON)); + + const paramsEl = await findByTestId( + getRouteParamsProbeTestId(Routes.CARD.MODALS.ID), + ); + expect(paramsEl).toBeOnTheScreen(); + const params = JSON.parse(paramsEl.props.children as string); + expect(params.screen).toBe(Routes.CARD.MODALS.ADD_FUNDS); + expect(params.params.priorityToken.symbol).toBe('USDC'); + }); + + it('opens Asset Selection modal when Change Asset button is pressed', async () => { + const { getByTestId, findByTestId } = renderCardHomeView({ + extraRoutes: [ + { + name: Routes.CARD.MODALS.ID, + Component: createRouteParamsProbe(Routes.CARD.MODALS.ID), + }, + ], + }); + + fireEvent.press(getByTestId(CardHomeSelectors.CHANGE_ASSET_BUTTON)); + + const paramsEl = await findByTestId( + getRouteParamsProbeTestId(Routes.CARD.MODALS.ID), + ); + expect(paramsEl).toBeOnTheScreen(); + const params = JSON.parse(paramsEl.props.children as string); + expect(params.screen).toBe(Routes.CARD.MODALS.ASSET_SELECTION); + }); + + it('opens Spending Limit screen with flow=enable when Manage Spending Limit button is pressed', async () => { + const { getByTestId, findByTestId } = renderCardHomeView({ + extraRoutes: [ + { + name: Routes.CARD.SPENDING_LIMIT, + Component: createRouteParamsProbe(Routes.CARD.SPENDING_LIMIT), + }, + ], + }); + + fireEvent.press( + getByTestId(CardHomeSelectors.MANAGE_SPENDING_LIMIT_ITEM), + ); + + const paramsEl = await findByTestId( + getRouteParamsProbeTestId(Routes.CARD.SPENDING_LIMIT), + ); + expect(paramsEl).toBeOnTheScreen(); + const params = JSON.parse(paramsEl.props.children as string); + expect(params.flow).toBe('enable'); + }); + + it('opens Cashback screen showing balance and withdrawal button when Cashback button is pressed', async () => { + const { getByTestId, findByTestId } = renderCardHomeView({ + extraRoutes: [{ name: Routes.CARD.CASHBACK, Component: Cashback }], + }); + + fireEvent.press(getByTestId(CardHomeSelectors.CASHBACK_ITEM)); + + expect( + await findByTestId(CashbackSelectors.CONTAINER), + ).toBeOnTheScreen(); + expect( + await findByTestId(CashbackSelectors.BALANCE_TITLE), + ).toBeOnTheScreen(); + expect( + await findByTestId(CashbackSelectors.WITHDRAW_BUTTON), + ).toBeOnTheScreen(); + }); + + it('opens Choose Your Card screen showing card carousel and upgrade button when Order Metal Card button is pressed', async () => { + const { getByTestId, findByTestId } = renderCardHomeView({ + overrides: { + engine: { + backgroundState: { + RemoteFeatureFlagController: { + remoteFeatureFlags: { + metalCardCheckoutEnabled: { + enabled: true, + minimumVersion: '7.0.0', + }, + }, + }, + }, + }, + }, + extraRoutes: [ + { + name: Routes.CARD.CHOOSE_YOUR_CARD, + Component: ChooseYourCard, + }, + ], + }); + + fireEvent.press(getByTestId(CardHomeSelectors.ORDER_METAL_CARD_ITEM)); + + expect( + await findByTestId(ChooseYourCardSelectors.CONTAINER), + ).toBeOnTheScreen(); + expect( + await findByTestId(ChooseYourCardSelectors.TITLE), + ).toBeOnTheScreen(); + expect( + await findByTestId(ChooseYourCardSelectors.CARD_CAROUSEL), + ).toBeOnTheScreen(); + expect( + await findByTestId(ChooseYourCardSelectors.CONTINUE_BUTTON), + ).toBeOnTheScreen(); + }); + }); + + describe('when unauthenticated (teaser mode)', () => { + it('shows CardAuthentication login form when Change Asset button is pressed while unauthenticated', async () => { + const { getByTestId, findByTestId } = renderCardHomeView({ + overrides: { + engine: { + backgroundState: { + CardController: { isAuthenticated: false }, + }, + }, + }, + extraRoutes: [ + { + name: Routes.CARD.AUTHENTICATION, + Component: CardAuthentication, + }, + ], + }); + + fireEvent.press(getByTestId(CardHomeSelectors.CHANGE_ASSET_BUTTON)); + + expect( + await findByTestId(CardAuthenticationSelectors.VERIFY_ACCOUNT_BUTTON), + ).toBeOnTheScreen(); + expect( + await findByTestId(CardAuthenticationSelectors.SIGNUP_BUTTON), + ).toBeOnTheScreen(); + expect( + await findByTestId(CardAuthenticationSelectors.EMAIL_FIELD), + ).toBeOnTheScreen(); + expect( + await findByTestId(CardAuthenticationSelectors.PASSWORD_FIELD), + ).toBeOnTheScreen(); + }); + }); + }); + + describe('actions', () => { + it('calls fetchCardHomeData when Try Again is pressed on the error screen', async () => { + const fetchMock = Engine.context.CardController + .fetchCardHomeData as jest.Mock; + fetchMock.mockClear(); + + const { getByTestId } = renderCardHomeView({ + overrides: { + engine: { + backgroundState: { + CardController: { + cardHomeDataStatus: 'error', + cardHomeData: null, + }, + }, + }, + }, + }); + + fireEvent.press(getByTestId(CardHomeSelectors.TRY_AGAIN_BUTTON)); + + await waitFor(() => { + expect(fetchMock).toHaveBeenCalled(); + }); + }); + + it('calls CardController.logout when logout is confirmed', async () => { + const logoutMock = Engine.context.CardController.logout as jest.Mock; + logoutMock.mockClear(); + + let confirmHandler: (() => Promise) | undefined; + jest + .spyOn(Alert, 'alert') + .mockImplementationOnce((_title, _msg, buttons) => { + const destructive = buttons?.find((b) => b.style === 'destructive'); + confirmHandler = destructive?.onPress as () => Promise; + }); + + const { getByTestId } = renderCardHomeView(); + + fireEvent.press(getByTestId(CardHomeSelectors.LOGOUT_ITEM)); + + expect(Alert.alert).toHaveBeenCalled(); + await act(async () => { + await confirmHandler?.(); + }); + + expect(logoutMock).toHaveBeenCalled(); + }); + }); +}); diff --git a/app/components/UI/Card/Views/SpendingLimit/SpendingLimit.testIds.ts b/app/components/UI/Card/Views/SpendingLimit/SpendingLimit.testIds.ts new file mode 100644 index 00000000000..553cbcf0fb3 --- /dev/null +++ b/app/components/UI/Card/Views/SpendingLimit/SpendingLimit.testIds.ts @@ -0,0 +1,8 @@ +export const SpendingLimitSelectors = { + LOADING_INDICATOR: 'spending-limit-loading-indicator', + ACCOUNT_ROW: 'account-row', + ACCOUNT_ROW_MONEY_ACCOUNT: 'account-row-money-account', + TOKEN_ROW: 'token-row', + TOKEN_ROW_LOCKED: 'token-row-locked', + SPENDING_LIMIT_ROW: 'spending-limit-row', +}; diff --git a/app/components/UI/Card/Views/SpendingLimit/SpendingLimit.tsx b/app/components/UI/Card/Views/SpendingLimit/SpendingLimit.tsx index 3764ed4667f..5671f3165a9 100644 --- a/app/components/UI/Card/Views/SpendingLimit/SpendingLimit.tsx +++ b/app/components/UI/Card/Views/SpendingLimit/SpendingLimit.tsx @@ -42,6 +42,7 @@ import { safeFormatChainIdToHex } from '../../util/safeFormatChainIdToHex'; import { LINEA_CAIP_CHAIN_ID } from '../../util/buildTokenList'; import musdAssetIcon from '../../../../../images/musd-icon-2x.png'; import SpendAndEarnPromoCard from './components/SpendAndEarnPromoCard'; +import { SpendingLimitSelectors } from './SpendingLimit.testIds'; interface SpendingLimitRouteParams { flow?: 'manage' | 'enable' | 'onboarding'; @@ -195,7 +196,7 @@ const SpendingLimit: React.FC = ({ route }) => { > @@ -287,7 +288,7 @@ const SpendingLimit: React.FC = ({ route }) => { = ({ route }) => { {isMoneyAccountSource ? ( = ({ route }) => { {isMoneyAccountSource ? ( = ({ route }) => { = ({ route }) => { { expect(result.current.canLink).toBe(true); expect(result.current.hasMoneyAccountRequirements).toBe(true); expect(result.current.isCardAuthenticated).toBe(true); + expect(result.current.isCardLinkedToMoneyAccount).toBe(false); expect(result.current.moneyAccountCardToken).toBe(MOCK_TOKEN); expect(result.current.status).toBe('idle'); expect(result.current.isLinking).toBe(false); expect(result.current.error).toBeNull(); }); + it('reports isCardLinkedToMoneyAccount=true when the Money Account is already delegated for card', () => { + applySelectorMocks(buildSelectors({ isAlreadyDelegated: true })); + const { result } = renderLinkageHook(); + + expect(result.current.isCardLinkedToMoneyAccount).toBe(true); + }); + it('reports canLink=false when the card is not authenticated', () => { applySelectorMocks(buildSelectors({ isCardAuthenticated: false })); const { result } = renderLinkageHook(); diff --git a/app/components/UI/Card/hooks/useMoneyAccountCardLinkage.tsx b/app/components/UI/Card/hooks/useMoneyAccountCardLinkage.tsx index a6c6c8fb6d6..e42387641fd 100644 --- a/app/components/UI/Card/hooks/useMoneyAccountCardLinkage.tsx +++ b/app/components/UI/Card/hooks/useMoneyAccountCardLinkage.tsx @@ -62,6 +62,7 @@ export interface LinkFlowOrigin { export interface UseMoneyAccountCardLinkageReturn { hasMoneyAccountRequirements: boolean; isCardAuthenticated: boolean; + isCardLinkedToMoneyAccount: boolean; primaryMoneyAccount: MoneyAccount | undefined; moneyAccountCardToken: CardFundingToken | null; canLink: boolean; @@ -345,6 +346,7 @@ export const useMoneyAccountCardLinkage = return { hasMoneyAccountRequirements: hasRequirements, isCardAuthenticated, + isCardLinkedToMoneyAccount: isAlreadyDelegated, primaryMoneyAccount, moneyAccountCardToken, canLink, diff --git a/app/components/UI/FundActionMenu/FundActionMenu.tsx b/app/components/UI/FundActionMenu/FundActionMenu.tsx index edca2432f4b..1151bd877a4 100644 --- a/app/components/UI/FundActionMenu/FundActionMenu.tsx +++ b/app/components/UI/FundActionMenu/FundActionMenu.tsx @@ -35,10 +35,12 @@ import { getDetectedGeolocation } from '../../../reducers/fiatOrders'; import useRampsUnifiedV1Enabled from '../Ramp/hooks/useRampsUnifiedV1Enabled'; import useRampsUnifiedV2Enabled from '../Ramp/hooks/useRampsUnifiedV2Enabled'; import { useRampsButtonClickData } from '../Ramp/hooks/useRampsButtonClickData'; +import { useElevatedSurface } from '../../../util/theme/themeUtils'; const FundActionMenu = () => { const sheetRef = useRef(null); const navigation = useNavigation(); + const surfaceClass = useElevatedSurface(); const route = useRoute(); const customOnBuy = route.params?.onBuy; @@ -238,6 +240,7 @@ const FundActionMenu = () => { ref={sheetRef} goBack={navigation.goBack} testID="fund-action-menu-bottom-sheet" + twClassName={surfaceClass} > {actionConfigs.map( diff --git a/app/components/UI/Money/Views/MoneyHomeView/MoneyHomeView.test.tsx b/app/components/UI/Money/Views/MoneyHomeView/MoneyHomeView.test.tsx index ae252dcbef2..0761655277f 100644 --- a/app/components/UI/Money/Views/MoneyHomeView/MoneyHomeView.test.tsx +++ b/app/components/UI/Money/Views/MoneyHomeView/MoneyHomeView.test.tsx @@ -104,10 +104,48 @@ jest.mock('../../utils/moneyFormatFiat', () => ({ jest.mock('../../../../../selectors/cardController', () => ({ ...jest.requireActual('../../../../../selectors/cardController'), selectIsCardholder: jest.fn(), + selectIsMoneyAccountDelegatedForCard: jest.fn(() => false), })); jest.mock('../../../Card/hooks/useMoneyAccountCardLinkage', () => ({ - useMoneyAccountCardLinkage: jest.fn(), + __esModule: true, + useMoneyAccountCardLinkage: jest.fn(() => ({ + hasMoneyAccountRequirements: false, + isCardAuthenticated: false, + isCardLinkedToMoneyAccount: false, + primaryMoneyAccount: undefined, + moneyAccountCardToken: null, + canLink: false, + status: 'idle' as const, + isLinking: false, + error: null, + startLinkFlow: jest.fn(), + openLinkCardSheet: jest.fn(), + confirmLinkInBackground: jest.fn(() => Promise.resolve(false)), + reset: jest.fn(), + })), +})); + +jest.mock('../../../Earn/hooks/useMusdBalance', () => ({ + useMusdBalance: jest.fn(() => ({ tokenBalanceAggregated: '0' })), +})); + +jest.mock('../../hooks/useMoneyAccount', () => ({ + useMoneyAccountDeposit: jest.fn(() => ({ + initiateDeposit: jest.fn(() => Promise.resolve()), + })), + useMoneyAccountWithdrawal: jest.fn(() => ({ + initiateWithdrawal: jest.fn(() => Promise.resolve()), + })), +})); + +jest.mock('../../hooks/useOnboardingStep', () => ({ + useOnboardingStep: jest.fn(() => ({ + currentStep: 0, + incrementStep: jest.fn(), + isVisible: true, + })), + STEPPER_IDS: { MONEY: 'money-home-onboarding-stepper' }, })); jest.mock('../../../../../reducers/fiatOrders', () => ({ @@ -557,13 +595,6 @@ describe('MoneyHomeView', () => { }); }); - it('renders onboarding card with step 2', () => { - const { getByTestId } = renderWithProvider(); - expect( - getByTestId(MoneyOnboardingCardTestIds.STEP_LABEL), - ).toHaveTextContent('Step 2 of 2'); - }); - it('renders the activity list', () => { const { getByTestId } = renderWithProvider(); expect(getByTestId(MoneyActivityListTestIds.CONTAINER)).toBeOnTheScreen(); @@ -594,14 +625,6 @@ describe('MoneyHomeView', () => { const { getByTestId } = renderWithProvider(); expect(getByTestId(MoneyMetaMaskCardTestIds.CONTAINER)).toBeOnTheScreen(); }); - - it('navigates to Card root when onboarding CTA is tapped', () => { - const { getByTestId } = renderWithProvider(); - - fireEvent.press(getByTestId(MoneyOnboardingCardTestIds.CTA_BUTTON)); - - expect(mockNavigate).toHaveBeenCalledWith(Routes.CARD.ROOT); - }); }); describe('card-unlinked state (milestone + has cardholder)', () => { @@ -622,16 +645,6 @@ describe('MoneyHomeView', () => { mockGetDetectedGeolocation.mockReturnValue('GB'); }); - it('renders onboarding card with step 2 and link-card variant', () => { - const { getByTestId } = renderWithProvider(); - expect( - getByTestId(MoneyOnboardingCardTestIds.STEP_LABEL), - ).toHaveTextContent('Step 2 of 2'); - expect(getByTestId(MoneyOnboardingCardTestIds.TITLE)).toHaveTextContent( - strings('money.onboarding.link_card_title'), - ); - }); - it('renders MetaMask Card section in link mode', () => { const { getByTestId, queryByTestId } = renderWithProvider( , @@ -701,22 +714,6 @@ describe('MoneyHomeView', () => { expect(getByTestId(MoneyFooterTestIds.CONTAINER)).toBeOnTheScreen(); }); - it('delegates to startLinkFlow with the Money home origin when onboarding CTA is tapped', () => { - const { getByTestId } = renderWithProvider(); - - fireEvent.press(getByTestId(MoneyOnboardingCardTestIds.CTA_BUTTON)); - - expect(mockStartLinkFlow).toHaveBeenCalledTimes(1); - expect(mockStartLinkFlow).toHaveBeenCalledWith({ - screen: Routes.MONEY.ROOT, - params: { screen: Routes.MONEY.HOME }, - }); - expect(mockNavigate).not.toHaveBeenCalledWith(Routes.CARD.ROOT, { - screen: Routes.CARD.HOME, - }); - expect(mockOpenLinkCardSheet).not.toHaveBeenCalled(); - }); - it('delegates to startLinkFlow with the Money home origin when MetaMaskCard link button is tapped', () => { const { getByTestId } = renderWithProvider(); @@ -750,24 +747,6 @@ describe('MoneyHomeView', () => { } as unknown as ReturnType); }); - it('still calls startLinkFlow (not openLinkCardSheet directly) when onboarding CTA is tapped', async () => { - const { getByTestId } = renderWithProvider(); - - await act(async () => { - fireEvent.press(getByTestId(MoneyOnboardingCardTestIds.CTA_BUTTON)); - }); - - expect(mockStartLinkFlow).toHaveBeenCalledTimes(1); - expect(mockStartLinkFlow).toHaveBeenCalledWith({ - screen: Routes.MONEY.ROOT, - params: { screen: Routes.MONEY.HOME }, - }); - expect(mockOpenLinkCardSheet).not.toHaveBeenCalled(); - expect(mockNavigate).not.toHaveBeenCalledWith(Routes.CARD.ROOT, { - screen: Routes.CARD.HOME, - }); - }); - it('still calls startLinkFlow (not openLinkCardSheet directly) when MetaMaskCard link button is tapped', async () => { const { getByTestId } = renderWithProvider(); @@ -780,7 +759,6 @@ describe('MoneyHomeView', () => { screen: Routes.MONEY.ROOT, params: { screen: Routes.MONEY.HOME }, }); - expect(mockOpenLinkCardSheet).not.toHaveBeenCalled(); expect(mockNavigate).not.toHaveBeenCalledWith(Routes.CARD.ROOT, { screen: Routes.CARD.HOME, }); @@ -800,13 +778,6 @@ describe('MoneyHomeView', () => { }); }); - it('renders onboarding card with step 1', () => { - const { getByTestId } = renderWithProvider(); - expect( - getByTestId(MoneyOnboardingCardTestIds.STEP_LABEL), - ).toHaveTextContent('Step 1 of 2'); - }); - it('does not render the activity list', () => { const { queryByTestId } = renderWithProvider(); expect( @@ -831,18 +802,18 @@ describe('MoneyHomeView', () => { expect(getByTestId(MoneyWhatYouGetTestIds.CONTAINER)).toBeOnTheScreen(); }); - it.each([ - ['onboarding card CTA', MoneyOnboardingCardTestIds.CTA_BUTTON], - ['mUSD row Add', MoneyMusdTokenRowTestIds.ADD_BUTTON], - ])('opens the Add money sheet from the %s button', (_label, testId) => { - const { getByTestId } = renderWithProvider(); + it.each([['mUSD row Add', MoneyMusdTokenRowTestIds.ADD_BUTTON]])( + 'opens the Add money sheet from the %s button', + (_label, testId) => { + const { getByTestId } = renderWithProvider(); - fireEvent.press(getByTestId(testId)); + fireEvent.press(getByTestId(testId)); - expect(mockNavigate).toHaveBeenCalledWith(Routes.MONEY.MODALS.ROOT, { - screen: Routes.MONEY.MODALS.ADD_MONEY_SHEET, - }); - }); + expect(mockNavigate).toHaveBeenCalledWith(Routes.MONEY.MODALS.ROOT, { + screen: Routes.MONEY.MODALS.ADD_MONEY_SHEET, + }); + }, + ); it('navigates to Asset details when the mUSD token row is pressed', () => { const NavigationService = jest.requireMock( diff --git a/app/components/UI/Money/Views/MoneyHomeView/MoneyHomeView.tsx b/app/components/UI/Money/Views/MoneyHomeView/MoneyHomeView.tsx index 69fe978d7ca..c6690fba951 100644 --- a/app/components/UI/Money/Views/MoneyHomeView/MoneyHomeView.tsx +++ b/app/components/UI/Money/Views/MoneyHomeView/MoneyHomeView.tsx @@ -28,6 +28,7 @@ import { useMusdConversion } from '../../../Earn/hooks/useMusdConversion'; import { useMusdBalance } from '../../../Earn/hooks/useMusdBalance'; import { useMoneyAccountTransactions } from '../../hooks/useMoneyAccountTransactions'; import useMoneyAccountBalance from '../../hooks/useMoneyAccountBalance'; +import { useOnboardingStep, STEPPER_IDS } from '../../hooks/useOnboardingStep'; import { selectCurrentCurrency } from '../../../../../selectors/currencyRateController'; import { moneyFormatFiat } from '../../utils/moneyFormatFiat'; import { calculateProjectedEarnings } from '../../utils/projections'; @@ -41,7 +42,7 @@ import { getDetectedGeolocation } from '../../../../../reducers/fiatOrders'; import Logger from '../../../../../util/Logger'; import { AssetType } from '../../../../Views/confirmations/types/token'; import { Hex } from '@metamask/utils'; - +import { MONEY_ONBOARDING_TOTAL_STEPS } from '../../components/MoneyOnboardingCard/MoneyOnboardingCard'; const Divider = () => ; type MoneyHomeState = 'empty' | 'milestone' | 'filled'; @@ -78,6 +79,11 @@ const MoneyHomeView = () => { const geolocation = useSelector(getDetectedGeolocation); const isUS = geolocation?.toUpperCase().split('-')[0] === 'US'; + const { isVisible: isOnboardingCardVisible } = useOnboardingStep({ + stepperId: STEPPER_IDS.MONEY, + totalSteps: MONEY_ONBOARDING_TOTAL_STEPS, + }); + const homeState = getMoneyHomeState(allTransactions.length); const isMilestone = homeState === 'milestone' || homeState === 'filled'; const isCardholderWithMilestone = isMilestone && isCardholder; @@ -216,26 +222,6 @@ const MoneyHomeView = () => { [navigation], ); - const handleOnboardingCtaPress = useCallback(() => { - if (isCardholderWithMilestone) { - handleLinkCardPress(); - return; - } - - if (isMilestone) { - handleCardPress(); - return; - } - - handleAddPress(); - }, [ - isCardholderWithMilestone, - isMilestone, - handleLinkCardPress, - handleCardPress, - handleAddPress, - ]); - let metamaskCardMode: 'upsell' | 'link' | 'manage'; if (isCardholderWithMilestone && isUS) { metamaskCardMode = 'manage'; @@ -273,12 +259,8 @@ const MoneyHomeView = () => { onTransferPress={handleTransferPress} onCardPress={handleCardPress} /> - - + + {isOnboardingCardVisible && } StyleSheet.create({ list: { paddingBottom: 16, - backgroundColor: params.theme.colors.background.default, }, row: { flexDirection: 'row', diff --git a/app/components/UI/Money/components/MoneyAddMoneySheet/MoneyAddMoneySheet.tsx b/app/components/UI/Money/components/MoneyAddMoneySheet/MoneyAddMoneySheet.tsx index 7e1975eeaf6..81076cde909 100644 --- a/app/components/UI/Money/components/MoneyAddMoneySheet/MoneyAddMoneySheet.tsx +++ b/app/components/UI/Money/components/MoneyAddMoneySheet/MoneyAddMoneySheet.tsx @@ -26,6 +26,7 @@ import { } from '../../../Earn/constants/musd'; import { useRampNavigation } from '../../../Ramp/hooks/useRampNavigation'; import { useMoneyAccountDeposit } from '../../hooks/useMoneyAccount'; +import { useElevatedSurface } from '../../../../../util/theme/themeUtils'; import styleSheet from './MoneyAddMoneySheet.styles'; import { MoneyAddMoneySheetTestIds } from './MoneyAddMoneySheet.testIds'; @@ -42,6 +43,7 @@ const MoneyAddMoneySheet: React.FC = () => { const sheetRef = useRef(null); const navigation = useNavigation(); const { styles } = useStyles(styleSheet, {}); + const surfaceClass = useElevatedSurface(); const { fiatBalanceAggregated, @@ -136,6 +138,7 @@ const MoneyAddMoneySheet: React.FC = () => { goBack={handleGoBack} testID={MoneyAddMoneySheetTestIds.CONTAINER} keyboardAvoidingViewEnabled={false} + twClassName={surfaceClass} > sheetRef.current?.onCloseBottomSheet()}> diff --git a/app/components/UI/Money/components/MoneyBalanceCard/MoneyBalanceCard.tsx b/app/components/UI/Money/components/MoneyBalanceCard/MoneyBalanceCard.tsx index c4b1980a66b..bcb8b53c06c 100644 --- a/app/components/UI/Money/components/MoneyBalanceCard/MoneyBalanceCard.tsx +++ b/app/components/UI/Money/components/MoneyBalanceCard/MoneyBalanceCard.tsx @@ -50,7 +50,6 @@ const MoneyBalanceCard = () => { const walletHomeOnboardingFlowVisible = useSelector( selectWalletHomeOnboardingFlowVisible, ); - const isEmpty = totalFiatRaw === undefined || totalFiatRaw === '0'; const isNewUser = isEmpty && !hasSeenMoneyOnboarding; diff --git a/app/components/UI/Money/components/MoneyEarnings/MoneyEarnings.tsx b/app/components/UI/Money/components/MoneyEarnings/MoneyEarnings.tsx index 7bbfe13f471..639a42f1101 100644 --- a/app/components/UI/Money/components/MoneyEarnings/MoneyEarnings.tsx +++ b/app/components/UI/Money/components/MoneyEarnings/MoneyEarnings.tsx @@ -62,7 +62,7 @@ const MoneyEarnings = ({ isLoading = false, onInfoPress, }: MoneyEarningsProps) => ( - + - StyleSheet.create({ - coinIllustration: { - width: '100%', - height: '100%', - }, - }); - -export default stylesheet; diff --git a/app/components/UI/Money/components/MoneyOnboardingCard/MoneyOnboardingCard.test.tsx b/app/components/UI/Money/components/MoneyOnboardingCard/MoneyOnboardingCard.test.tsx index fd9bfcf4579..237b03f9b3d 100644 --- a/app/components/UI/Money/components/MoneyOnboardingCard/MoneyOnboardingCard.test.tsx +++ b/app/components/UI/Money/components/MoneyOnboardingCard/MoneyOnboardingCard.test.tsx @@ -1,158 +1,394 @@ import React from 'react'; import { render, fireEvent } from '@testing-library/react-native'; -import MoneyOnboardingCard from './MoneyOnboardingCard'; -import { MoneyOnboardingCardTestIds } from './MoneyOnboardingCard.testIds'; +import BigNumber from 'bignumber.js'; +import MoneyOnboardingCard, { + MONEY_ONBOARDING_TOTAL_STEPS, +} from './MoneyOnboardingCard'; +import { useOnboardingStep } from '../../hooks/useOnboardingStep'; +import { useMoneyAccountDeposit } from '../../hooks/useMoneyAccount'; +import { useMoneyAccountCardLinkage } from '../../../Card/hooks/useMoneyAccountCardLinkage'; import { strings } from '../../../../../../locales/i18n'; +import Routes from '../../../../../constants/navigation/Routes'; +import useMoneyAccountBalance from '../../hooks/useMoneyAccountBalance'; + +jest.mock('@metamask/design-system-twrnc-preset', () => { + const tw = (..._args: unknown[]) => ({}); + tw.style = jest.fn(() => ({})); + return { useTailwind: () => tw }; +}); + +jest.mock('../../hooks/useOnboardingStep', () => ({ + useOnboardingStep: jest.fn(), + STEPPER_IDS: { MONEY: 'money-home-onboarding-stepper' }, +})); + +jest.mock('../../hooks/useMoneyAccount', () => ({ + useMoneyAccountDeposit: jest.fn(), +})); + +jest.mock('../../hooks/useMoneyAccountBalance', () => ({ + __esModule: true, + default: jest.fn(), +})); + +jest.mock('../../../Card/hooks/useMoneyAccountCardLinkage', () => ({ + __esModule: true, + useMoneyAccountCardLinkage: jest.fn(), +})); + +const mockUseOnboardingStep = useOnboardingStep as jest.MockedFunction< + typeof useOnboardingStep +>; +const mockUseMoneyAccountDeposit = + useMoneyAccountDeposit as jest.MockedFunction; +const mockUseMoneyAccountBalance = jest.mocked(useMoneyAccountBalance); +const mockUseMoneyAccountCardLinkage = + useMoneyAccountCardLinkage as jest.MockedFunction< + typeof useMoneyAccountCardLinkage + >; + +const mockIncrementStep = jest.fn(); +const mockInitiateDeposit = jest.fn().mockResolvedValue(undefined); +const mockStartLinkFlow = jest.fn(); + +interface SetupOptions { + currentStep?: number; + isCardAuthenticated?: boolean; + isCardLinkedToMoneyAccount?: boolean; + isAggregatedBalanceLoading?: boolean; + tokenTotal?: BigNumber; +} + +const setupDefaultMocks = ({ + currentStep = 0, + isCardAuthenticated = false, + isCardLinkedToMoneyAccount = false, + isAggregatedBalanceLoading = false, + tokenTotal = new BigNumber(0), +}: SetupOptions = {}) => { + mockUseOnboardingStep.mockReturnValue({ + currentStep, + incrementStep: mockIncrementStep, + isVisible: currentStep < MONEY_ONBOARDING_TOTAL_STEPS, + }); + (mockUseMoneyAccountDeposit as jest.Mock).mockReturnValue({ + initiateDeposit: mockInitiateDeposit, + }); + mockUseMoneyAccountBalance.mockReturnValue({ + tokenTotal, + isAggregatedBalanceLoading, + } as ReturnType); + (mockUseMoneyAccountCardLinkage as jest.Mock).mockReturnValue({ + startLinkFlow: mockStartLinkFlow, + isCardAuthenticated, + isCardLinkedToMoneyAccount, + }); +}; describe('MoneyOnboardingCard', () => { - it('renders the step label with default step values', () => { - const { getByTestId } = render(); - - expect( - getByTestId(MoneyOnboardingCardTestIds.STEP_LABEL), - ).toHaveTextContent( - strings('money.onboarding.step_progress', { current: 1, total: 2 }), - ); + beforeEach(() => { + jest.clearAllMocks(); }); - it('renders the step label with custom step values', () => { - const { getByTestId } = render( - , - ); + describe('visibility guard', () => { + it('returns null when currentStep equals MONEY_ONBOARDING_TOTAL_STEPS', () => { + setupDefaultMocks({ currentStep: MONEY_ONBOARDING_TOTAL_STEPS }); - expect( - getByTestId(MoneyOnboardingCardTestIds.STEP_LABEL), - ).toHaveTextContent( - strings('money.onboarding.step_progress', { current: 2, total: 3 }), - ); - }); + const { toJSON } = render(); - it('renders the coin illustration slot', () => { - const { getByTestId } = render(); + expect(toJSON()).toBeNull(); + }); - expect( - getByTestId(MoneyOnboardingCardTestIds.COIN_ILLUSTRATION), - ).toBeOnTheScreen(); - }); + it('returns null when balance is loading', () => { + setupDefaultMocks({ isAggregatedBalanceLoading: true }); - it('renders the title and description copy', () => { - const { getByTestId } = render(); + const { toJSON } = render(); - expect(getByTestId(MoneyOnboardingCardTestIds.TITLE)).toHaveTextContent( - strings('money.onboarding.title'), - ); - expect( - getByTestId(MoneyOnboardingCardTestIds.DESCRIPTION), - ).toHaveTextContent(strings('money.onboarding.description')); - }); + expect(toJSON()).toBeNull(); + }); - it('calls onCtaPress when CTA is tapped', () => { - const mockCta = jest.fn(); - const { getByTestId } = render( - , - ); + it('renders the card container when currentStep is 0', () => { + setupDefaultMocks({ currentStep: 0 }); - fireEvent.press(getByTestId(MoneyOnboardingCardTestIds.CTA_BUTTON)); + const { getByTestId } = render(); - expect(mockCta).toHaveBeenCalledTimes(1); + expect(getByTestId('money-onboarding-card-container')).toBeOnTheScreen(); + }); }); - it('falls back to onAddPress when onCtaPress is not provided', () => { - const mockAdd = jest.fn(); - const { getByTestId } = render( - , - ); + describe('step 1 — fund your account', () => { + it('calls incrementStep on mount when balance is non-zero', () => { + setupDefaultMocks({ + currentStep: 0, + tokenTotal: new BigNumber(1), + }); - fireEvent.press(getByTestId(MoneyOnboardingCardTestIds.CTA_BUTTON)); + render(); - expect(mockAdd).toHaveBeenCalledTimes(1); - }); + expect(mockIncrementStep).toHaveBeenCalledTimes(1); + }); - it('does not throw when CTA is tapped without a handler', () => { - const { getByTestId } = render(); + it('does not call incrementStep while balance is loading', () => { + setupDefaultMocks({ + currentStep: 0, + isAggregatedBalanceLoading: true, + tokenTotal: new BigNumber(1), + }); - expect(() => { - fireEvent.press(getByTestId(MoneyOnboardingCardTestIds.CTA_BUTTON)); - }).not.toThrow(); - }); + render(); - it('renders step 2 title when currentStep is 2', () => { - const { getByTestId } = render(); + expect(mockIncrementStep).not.toHaveBeenCalled(); + }); - expect(getByTestId(MoneyOnboardingCardTestIds.TITLE)).toHaveTextContent( - strings('money.onboarding.step2_title'), - ); - }); + it('renders the step 1 title', () => { + setupDefaultMocks({ currentStep: 0 }); - it('renders step 2 description when currentStep is 2', () => { - const { getByTestId } = render(); + const { getByTestId } = render(); - expect( - getByTestId(MoneyOnboardingCardTestIds.DESCRIPTION), - ).toHaveTextContent(strings('money.onboarding.step2_description')); - }); + expect(getByTestId('money-onboarding-card-title')).toHaveTextContent( + strings('money.onboarding.step_1.title'), + ); + }); - it('renders step 2 CTA label when currentStep is 2', () => { - const { getByTestId } = render(); + it('renders the step 1 description', () => { + setupDefaultMocks({ currentStep: 0 }); - expect( - getByTestId(MoneyOnboardingCardTestIds.CTA_BUTTON), - ).toHaveTextContent(strings('money.onboarding.step2_cta')); - }); + const { getByTestId } = render(); - describe('link-card variant', () => { - it('renders link card title when variant is link-card and step is 2', () => { - const { getByTestId } = render( - , + expect( + getByTestId('money-onboarding-card-description'), + ).toHaveTextContent(strings('money.onboarding.step_1.description')); + }); + + it('renders the Add funds primary CTA', () => { + setupDefaultMocks({ currentStep: 0 }); + + const { getByTestId } = render(); + + expect(getByTestId('money-onboarding-card-cta-button')).toHaveTextContent( + strings('money.onboarding.step_1.cta'), ); + }); + + it('calls initiateDeposit when Add funds CTA is pressed', () => { + setupDefaultMocks({ currentStep: 0 }); + + const { getByTestId } = render(); + fireEvent.press(getByTestId('money-onboarding-card-cta-button')); + + expect(mockInitiateDeposit).toHaveBeenCalledTimes(1); + }); + }); + + describe('step 2 — no card yet', () => { + it('renders the no-card description', () => { + setupDefaultMocks({ currentStep: 1, isCardAuthenticated: false }); - expect(getByTestId(MoneyOnboardingCardTestIds.TITLE)).toHaveTextContent( - strings('money.onboarding.link_card_title'), + const { getByTestId } = render(); + + expect( + getByTestId('money-onboarding-card-description'), + ).toHaveTextContent( + strings('money.onboarding.step_2.no_card_account.description'), ); }); - it('renders link card description when variant is link-card and step is 2', () => { - const { getByTestId } = render( - , + it('renders the Get card primary CTA', () => { + setupDefaultMocks({ currentStep: 1, isCardAuthenticated: false }); + + const { getByTestId } = render(); + + expect(getByTestId('money-onboarding-card-cta-button')).toHaveTextContent( + strings('money.onboarding.step_2.no_card_account.cta_primary'), ); + }); + + it('renders the Skip secondary CTA', () => { + setupDefaultMocks({ currentStep: 1, isCardAuthenticated: false }); + + const { getByText } = render(); expect( - getByTestId(MoneyOnboardingCardTestIds.DESCRIPTION), - ).toHaveTextContent(strings('money.onboarding.link_card_description')); + getByText( + strings('money.onboarding.step_2.no_card_account.cta_secondary'), + ), + ).toBeOnTheScreen(); }); - it('renders link card CTA when variant is link-card and step is 2', () => { - const { getByTestId } = render( - , + it('calls startLinkFlow with Money home origin when Get card CTA is pressed', () => { + setupDefaultMocks({ currentStep: 1, isCardAuthenticated: false }); + + const { getByTestId } = render(); + fireEvent.press(getByTestId('money-onboarding-card-cta-button')); + + expect(mockStartLinkFlow).toHaveBeenCalledTimes(1); + expect(mockStartLinkFlow).toHaveBeenCalledWith({ + screen: Routes.MONEY.ROOT, + params: { screen: Routes.MONEY.HOME }, + }); + }); + + it('calls incrementStep when Skip CTA is pressed', () => { + setupDefaultMocks({ currentStep: 1, isCardAuthenticated: false }); + + const { getByText } = render(); + fireEvent.press( + getByText( + strings('money.onboarding.step_2.no_card_account.cta_secondary'), + ), ); - expect( - getByTestId(MoneyOnboardingCardTestIds.CTA_BUTTON), - ).toHaveTextContent(strings('money.onboarding.link_card_cta')); + expect(mockIncrementStep).toHaveBeenCalledTimes(1); + }); + }); + + describe('step 2 — cardholder with unlinked card', () => { + beforeEach(() => { + jest.clearAllMocks(); }); - it('falls back to get-card content for step 1 even with link-card variant', () => { - const { getByTestId } = render( - , + it('renders the unlinked-card title', () => { + setupDefaultMocks({ + currentStep: 1, + isCardAuthenticated: true, + isCardLinkedToMoneyAccount: false, + }); + + const { getByTestId } = render(); + + expect(getByTestId('money-onboarding-card-title')).toHaveTextContent( + strings('money.onboarding.step_2.unlinked_card_account.title'), ); + }); + + it('renders the unlinked-card description', () => { + setupDefaultMocks({ + currentStep: 1, + isCardAuthenticated: true, + isCardLinkedToMoneyAccount: false, + }); + + const { getByTestId } = render(); - expect(getByTestId(MoneyOnboardingCardTestIds.TITLE)).toHaveTextContent( - strings('money.onboarding.title'), + expect( + getByTestId('money-onboarding-card-description'), + ).toHaveTextContent( + strings('money.onboarding.step_2.unlinked_card_account.description'), + ); + }); + + it('renders the Link card primary CTA', () => { + setupDefaultMocks({ + currentStep: 1, + isCardAuthenticated: true, + isCardLinkedToMoneyAccount: false, + }); + + const { getByTestId } = render(); + + expect(getByTestId('money-onboarding-card-cta-button')).toHaveTextContent( + strings('money.onboarding.step_2.unlinked_card_account.cta_primary'), ); }); - it('calls onCtaPress when link card CTA is tapped', () => { - const mockCta = jest.fn(); - const { getByTestId } = render( - , + it('calls startLinkFlow with Money home origin when Link card CTA is pressed', () => { + setupDefaultMocks({ + currentStep: 1, + isCardAuthenticated: true, + isCardLinkedToMoneyAccount: false, + }); + + const { getByTestId } = render(); + fireEvent.press(getByTestId('money-onboarding-card-cta-button')); + + expect(mockStartLinkFlow).toHaveBeenCalledTimes(1); + expect(mockStartLinkFlow).toHaveBeenCalledWith({ + screen: Routes.MONEY.ROOT, + params: { screen: Routes.MONEY.HOME }, + }); + }); + + it('calls incrementStep when Skip CTA is pressed', () => { + setupDefaultMocks({ + currentStep: 1, + isCardAuthenticated: true, + isCardLinkedToMoneyAccount: false, + }); + + const { getByText } = render(); + fireEvent.press( + getByText( + strings( + 'money.onboarding.step_2.unlinked_card_account.cta_secondary', + ), + ), ); - fireEvent.press(getByTestId(MoneyOnboardingCardTestIds.CTA_BUTTON)); - expect(mockCta).toHaveBeenCalledTimes(1); + expect(mockIncrementStep).toHaveBeenCalledTimes(1); + }); + }); + + describe('step 2 — cardholder with linked card (auto-skip)', () => { + it('calls incrementStep on mount when card is authenticated and linked', () => { + setupDefaultMocks({ + currentStep: 1, + isCardAuthenticated: true, + isCardLinkedToMoneyAccount: true, + }); + + render(); + + expect(mockIncrementStep).toHaveBeenCalledTimes(1); + }); + + it('does not call incrementStep when card is authenticated but not linked', () => { + setupDefaultMocks({ + currentStep: 1, + isCardAuthenticated: true, + isCardLinkedToMoneyAccount: false, + }); + + render(); + + expect(mockIncrementStep).not.toHaveBeenCalled(); + }); + + it('does not call incrementStep when card is not authenticated', () => { + setupDefaultMocks({ + currentStep: 1, + isCardAuthenticated: false, + isCardLinkedToMoneyAccount: true, + }); + + render(); + + expect(mockIncrementStep).not.toHaveBeenCalled(); + }); + + it('does not call incrementStep when currentStep is not 1', () => { + setupDefaultMocks({ + currentStep: 0, + isCardAuthenticated: true, + isCardLinkedToMoneyAccount: true, + }); + + render(); + + expect(mockIncrementStep).not.toHaveBeenCalled(); + }); + }); + + describe('steps memo guard — card hidden', () => { + it('renders null and shows no step content when currentStep equals MONEY_ONBOARDING_TOTAL_STEPS', () => { + setupDefaultMocks({ currentStep: MONEY_ONBOARDING_TOTAL_STEPS }); + + const { toJSON, queryByText } = render(); + + expect(toJSON()).toBeNull(); + expect(queryByText(strings('money.onboarding.step_1.title'))).toBeNull(); + expect( + queryByText(strings('money.onboarding.step_2.no_card_account.title')), + ).toBeNull(); }); }); }); diff --git a/app/components/UI/Money/components/MoneyOnboardingCard/MoneyOnboardingCard.testIds.ts b/app/components/UI/Money/components/MoneyOnboardingCard/MoneyOnboardingCard.testIds.ts index 80e8bf8fd9f..527c08370c6 100644 --- a/app/components/UI/Money/components/MoneyOnboardingCard/MoneyOnboardingCard.testIds.ts +++ b/app/components/UI/Money/components/MoneyOnboardingCard/MoneyOnboardingCard.testIds.ts @@ -1,8 +1,7 @@ export const MoneyOnboardingCardTestIds = { CONTAINER: 'money-onboarding-card-container', - STEP_LABEL: 'money-onboarding-card-step-label', PROGRESS_BAR: 'money-onboarding-card-progress-bar', - COIN_ILLUSTRATION: 'money-onboarding-card-coin-illustration', + STEP_IMAGE: 'money-onboarding-card-step-image', TITLE: 'money-onboarding-card-title', DESCRIPTION: 'money-onboarding-card-description', CTA_BUTTON: 'money-onboarding-card-cta-button', diff --git a/app/components/UI/Money/components/MoneyOnboardingCard/MoneyOnboardingCard.tsx b/app/components/UI/Money/components/MoneyOnboardingCard/MoneyOnboardingCard.tsx index 45902a527bc..cfbb71020a9 100644 --- a/app/components/UI/Money/components/MoneyOnboardingCard/MoneyOnboardingCard.tsx +++ b/app/components/UI/Money/components/MoneyOnboardingCard/MoneyOnboardingCard.tsx @@ -1,149 +1,173 @@ -import React from 'react'; -import { Image, StyleSheet } from 'react-native'; -import { - Box, - BoxAlignItems, - BoxJustifyContent, - Button, - ButtonSize, - ButtonVariant, - FontWeight, - Text, - TextColor, - TextVariant, -} from '@metamask/design-system-react-native'; -import moneyAccountCoins from '../../../../../images/money-account-coins.png'; +import React, { useCallback, useEffect, useMemo } from 'react'; +import { Box } from '@metamask/design-system-react-native'; +import moneyOnboardingStepperStep1 from '../../../../../images/money-onboarding-stepper-step-1.png'; +import moneyOnboardingStepperStep2 from '../../../../../images/money-onboarding-stepper-step-2.png'; import { strings } from '../../../../../../locales/i18n'; -import MoneyProgressBar from '../MoneyProgressBar'; -import { MoneyOnboardingCardTestIds } from './MoneyOnboardingCard.testIds'; -import { useStyles } from '../../../../../component-library/hooks'; -import stylesheet from './MoneyOnboardingCard.styles'; - -const NOOP = () => undefined; - -interface MoneyOnboardingCardProps { - /** - * Handler fired when the CTA button is pressed. - */ - onCtaPress?: () => void; - /** - * @deprecated Use onCtaPress instead. - * Handler fired when the "Add" action is pressed. Opens the Add money sheet (MUSD-487). - */ - onAddPress?: () => void; - /** - * 1-based index of the currently completed step. Defaults to 1. - */ - currentStep?: number; - /** - * Total number of onboarding steps. Defaults to 2. - */ - totalSteps?: number; - /** - * Controls step 2 content: 'get-card' (default) shows card acquisition, - * 'link-card' shows card linking messaging. - */ - variant?: 'get-card' | 'link-card'; -} - -const STEP_CONTENT = { - 1: { - title: 'money.onboarding.title', - description: 'money.onboarding.description', - cta: 'money.onboarding.add', - }, - 2: { - title: 'money.onboarding.step2_title', - description: 'money.onboarding.step2_description', - cta: 'money.onboarding.step2_cta', - }, -} as const; - -const STEP_2_LINK_CARD = { - title: 'money.onboarding.link_card_title', - description: 'money.onboarding.link_card_description', - cta: 'money.onboarding.link_card_cta', -} as const; - -const MoneyOnboardingCard = ({ - onCtaPress, - onAddPress, - currentStep = 1, - totalSteps = 2, - variant = 'get-card', -}: MoneyOnboardingCardProps) => { - const { styles } = useStyles(stylesheet, {}); - - const isLinkCard = variant === 'link-card' && currentStep === 2; - const content = isLinkCard - ? STEP_2_LINK_CARD - : (STEP_CONTENT[currentStep as keyof typeof STEP_CONTENT] ?? - STEP_CONTENT[1]); - const handleCtaPress = onCtaPress ?? onAddPress ?? NOOP; +import Routes from '../../../../../constants/navigation/Routes'; +import { useMoneyAccountCardLinkage } from '../../../Card/hooks/useMoneyAccountCardLinkage'; +import { useOnboardingStep, STEPPER_IDS } from '../../hooks/useOnboardingStep'; +import StepperCard, { + type StepperCardStep, +} from '../../../../../component-library/components-temp/StepperCard'; +import { useMoneyAccountDeposit } from '../../hooks/useMoneyAccount'; +import useMoneyAccountBalance from '../../hooks/useMoneyAccountBalance'; + +// REMINDER: Must be updated when the number of steps is changed. +export const MONEY_ONBOARDING_TOTAL_STEPS = 2; + +const MoneyOnboardingCard = () => { + const { + currentStep, + incrementStep, + isVisible: isOnboardingCardVisible, + } = useOnboardingStep({ + stepperId: STEPPER_IDS.MONEY, + totalSteps: MONEY_ONBOARDING_TOTAL_STEPS, + }); + + const { initiateDeposit } = useMoneyAccountDeposit(); + const { tokenTotal, isAggregatedBalanceLoading } = useMoneyAccountBalance(); + + const { startLinkFlow, isCardAuthenticated, isCardLinkedToMoneyAccount } = + useMoneyAccountCardLinkage(); + + const handleRedirectToCryptoDeposit = useCallback(() => { + initiateDeposit().catch(() => undefined); + }, [initiateDeposit]); + + const handleCardCtaPress = useCallback(() => { + startLinkFlow({ + screen: Routes.MONEY.ROOT, + params: { screen: Routes.MONEY.HOME }, + }); + }, [startLinkFlow]); + + const handleSkipPress = useCallback(() => { + incrementStep(); + }, [incrementStep]); + + const targetStepFromCompletion = useMemo(() => { + // Step 1 completion is based on having a non-zero balance (after loading). + const isStep1Complete = Boolean( + !isAggregatedBalanceLoading && tokenTotal?.isGreaterThan(0), + ); + + // Step 2 completion can be evaluated if either: + // - persisted progress is already at step index ≥ 1 (auto-advanced on a + // previous session, or balance has since dropped back to zero), or + // - step 1 is complete right now (immediately advance funded users). + const canEvaluateStep2 = currentStep >= 1 || isStep1Complete; + const isStep2Complete = + canEvaluateStep2 && isCardAuthenticated && isCardLinkedToMoneyAccount; + + if (isStep2Complete) return 2; + if (isStep1Complete) return 1; + return 0; + }, [ + currentStep, + isAggregatedBalanceLoading, + tokenTotal, + isCardAuthenticated, + isCardLinkedToMoneyAccount, + ]); + + // Prevent a flash of earlier steps by rendering the computed step immediately, + // while still persisting progress back to Redux via incremental updates. + const effectiveCurrentStep = Math.max(currentStep, targetStepFromCompletion); + const isVisibleAfterAutoSkip = + effectiveCurrentStep < MONEY_ONBOARDING_TOTAL_STEPS; + + useEffect(() => { + if (currentStep < targetStepFromCompletion) { + incrementStep(); + } + }, [currentStep, targetStepFromCompletion, incrementStep]); + + // REMINDER: Update MONEY_ONBOARDING_TOTAL_STEPS when steps are added or removed. + const steps = useMemo((): StepperCardStep[] => { + if (!isOnboardingCardVisible || !isVisibleAfterAutoSkip) return []; + + const step1: StepperCardStep = { + title: strings('money.onboarding.step_1.title'), + description: strings('money.onboarding.step_1.description'), + primaryCta: { + text: strings('money.onboarding.step_1.cta'), + onPress: handleRedirectToCryptoDeposit, + }, + image: moneyOnboardingStepperStep1, + }; + + // Case 1: Has MetaMask card but not linked to Money account yet. + const step2: StepperCardStep = + isCardAuthenticated && !isCardLinkedToMoneyAccount + ? { + title: strings( + 'money.onboarding.step_2.unlinked_card_account.title', + ), + description: strings( + 'money.onboarding.step_2.unlinked_card_account.description', + ), + primaryCta: { + text: strings( + 'money.onboarding.step_2.unlinked_card_account.cta_primary', + ), + onPress: handleCardCtaPress, + }, + secondaryCta: { + text: strings( + 'money.onboarding.step_2.unlinked_card_account.cta_secondary', + ), + onPress: handleSkipPress, + }, + image: moneyOnboardingStepperStep2, + } + : // No MetaMask card yet. + { + title: strings('money.onboarding.step_2.no_card_account.title'), + description: strings( + 'money.onboarding.step_2.no_card_account.description', + ), + primaryCta: { + text: strings( + 'money.onboarding.step_2.no_card_account.cta_primary', + ), + onPress: handleCardCtaPress, + }, + secondaryCta: { + text: strings( + 'money.onboarding.step_2.no_card_account.cta_secondary', + ), + onPress: handleSkipPress, + }, + image: moneyOnboardingStepperStep2, + }; + + return [step1, step2]; + }, [ + isOnboardingCardVisible, + isVisibleAfterAutoSkip, + isCardAuthenticated, + isCardLinkedToMoneyAccount, + handleRedirectToCryptoDeposit, + handleCardCtaPress, + handleSkipPress, + ]); + + if ( + isAggregatedBalanceLoading || + !isOnboardingCardVisible || + !isVisibleAfterAutoSkip + ) { + return null; + } return ( - - - - {strings('money.onboarding.step_progress', { - current: currentStep, - total: totalSteps, - })} - - - - - - - - - - - - {strings(content.title)} - - - {strings(content.description)} - - - - + + ); }; diff --git a/app/components/UI/Money/components/MoneyProgressBar/MoneyProgressBar.test.tsx b/app/components/UI/Money/components/MoneyProgressBar/MoneyProgressBar.test.tsx deleted file mode 100644 index 4066746a6e0..00000000000 --- a/app/components/UI/Money/components/MoneyProgressBar/MoneyProgressBar.test.tsx +++ /dev/null @@ -1,35 +0,0 @@ -import React from 'react'; -import { render } from '@testing-library/react-native'; -import type { ReactTestInstance } from 'react-test-renderer'; -import MoneyProgressBar from './MoneyProgressBar'; - -const getFillWidth = (track: ReactTestInstance) => { - const fill = track.children[0] as ReactTestInstance; - return (fill.props.style as { width: string }).width; -}; - -describe('MoneyProgressBar', () => { - it('renders with the provided testID', () => { - const { getByTestId } = render( - , - ); - - expect(getByTestId('progress')).toBeOnTheScreen(); - }); - - it('clamps the fill to 100% when current exceeds total', () => { - const { getByTestId } = render( - , - ); - - expect(getFillWidth(getByTestId('progress'))).toBe('100%'); - }); - - it('guards against a zero total to avoid divide-by-zero', () => { - const { getByTestId } = render( - , - ); - - expect(getFillWidth(getByTestId('progress'))).toBe('0%'); - }); -}); diff --git a/app/components/UI/Money/components/MoneyProgressBar/MoneyProgressBar.tsx b/app/components/UI/Money/components/MoneyProgressBar/MoneyProgressBar.tsx deleted file mode 100644 index f0afceea416..00000000000 --- a/app/components/UI/Money/components/MoneyProgressBar/MoneyProgressBar.tsx +++ /dev/null @@ -1,41 +0,0 @@ -import React from 'react'; -import { Box } from '@metamask/design-system-react-native'; - -interface MoneyProgressBarProps { - /** - * 1-based count of completed steps used to compute the filled portion. - */ - current: number; - /** - * Total number of steps. Guarded against non-positive values to avoid - * divide-by-zero when the caller hasn't wired this yet. - */ - total: number; - /** - * Optional testID forwarded to the outer track. - */ - testID?: string; -} - -const MoneyProgressBar = ({ - current, - total, - testID, -}: MoneyProgressBarProps) => { - const safeTotal = Math.max(1, total); - const percent = Math.min(100, Math.max(0, (current / safeTotal) * 100)); - - return ( - - - - ); -}; - -export default MoneyProgressBar; diff --git a/app/components/UI/Money/components/MoneyProgressBar/index.ts b/app/components/UI/Money/components/MoneyProgressBar/index.ts deleted file mode 100644 index 7b24100d959..00000000000 --- a/app/components/UI/Money/components/MoneyProgressBar/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { default } from './MoneyProgressBar'; diff --git a/app/components/UI/Money/components/MoneyUiDeveloperOptionsSection.tsx b/app/components/UI/Money/components/MoneyUiDeveloperOptionsSection.tsx index 3fd547d88f5..0d8d96997bf 100644 --- a/app/components/UI/Money/components/MoneyUiDeveloperOptionsSection.tsx +++ b/app/components/UI/Money/components/MoneyUiDeveloperOptionsSection.tsx @@ -2,7 +2,10 @@ import React, { useCallback } from 'react'; import { useDispatch, useSelector } from 'react-redux'; import { useTheme } from '../../../../util/theme'; -import { setMoneyOnboardingSeen } from '../../../../actions/user'; +import { + setMoneyOnboardingSeen, + setOnboardingStepperStep, +} from '../../../../actions/user'; import { selectMoneyOnboardingSeen } from '../../../../reducers/user/selectors'; import { selectPrimaryMoneyAccount } from '../../../../selectors/moneyAccountController'; import { useStyles } from '../../../../component-library/hooks'; @@ -17,6 +20,7 @@ import { } from '@metamask/design-system-react-native'; import styleSheet from '../../../Views/Settings/DeveloperOptions/DeveloperOptions.styles'; import ClipboardManager from '../../../../core/ClipboardManager'; +import { STEPPER_IDS } from '../hooks/useOnboardingStep'; export const MoneyUiDeveloperOptionsSection = () => { const dispatch = useDispatch(); @@ -31,6 +35,10 @@ export const MoneyUiDeveloperOptionsSection = () => { dispatch(setMoneyOnboardingSeen(false)); }, [dispatch]); + const handleResetOnboardingStepperStep = useCallback(() => { + dispatch(setOnboardingStepperStep(STEPPER_IDS.MONEY, 0)); + }, [dispatch]); + const handleCopyAddress = useCallback(async () => { if (moneyAccountAddress) { await ClipboardManager.setString(moneyAccountAddress); @@ -79,6 +87,24 @@ export const MoneyUiDeveloperOptionsSection = () => { {'Copy Money Account Address'} + + + {'Reset Money home onboarding stepper'} + + + ); }; diff --git a/app/components/UI/Money/hooks/useMoneyAccount.test.ts b/app/components/UI/Money/hooks/useMoneyAccount.test.ts index efefe1a70ed..b53d3bf64d1 100644 --- a/app/components/UI/Money/hooks/useMoneyAccount.test.ts +++ b/app/components/UI/Money/hooks/useMoneyAccount.test.ts @@ -197,7 +197,7 @@ describe('useMoneyAccountDeposit', () => { expect(getNavigateToConfirmation()).toHaveBeenCalledWith({ loader: ConfirmationLoader.CustomAmount, - stack: Routes.MONEY.ROOT, + stack: Routes.MONEY.CONFIRMATIONS_ROOT, }); expect(mockAddTransactionBatch).toHaveBeenCalledWith( @@ -345,7 +345,7 @@ describe('useMoneyAccountWithdrawal', () => { expect(getNavigateToConfirmation()).toHaveBeenCalledWith({ loader: ConfirmationLoader.CustomAmount, - stack: Routes.MONEY.ROOT, + stack: Routes.MONEY.CONFIRMATIONS_ROOT, }); expect(mockAddTransactionBatch).toHaveBeenCalledWith( diff --git a/app/components/UI/Money/hooks/useMoneyAccount.ts b/app/components/UI/Money/hooks/useMoneyAccount.ts index 5518ec1a5f9..315f9b17919 100644 --- a/app/components/UI/Money/hooks/useMoneyAccount.ts +++ b/app/components/UI/Money/hooks/useMoneyAccount.ts @@ -71,7 +71,7 @@ export function useMoneyAccountDeposit() { // Navigate early for better UX; recover on failure below. navigateToConfirmation({ loader: ConfirmationLoader.CustomAmount, - stack: Routes.MONEY.ROOT, + stack: Routes.MONEY.CONFIRMATIONS_ROOT, }); try { @@ -145,7 +145,7 @@ export function useMoneyAccountWithdrawal() { // Navigate early for better UX; recover on failure below. navigateToConfirmation({ loader: ConfirmationLoader.CustomAmount, - stack: Routes.MONEY.ROOT, + stack: Routes.MONEY.CONFIRMATIONS_ROOT, }); try { diff --git a/app/components/UI/Money/hooks/useOnboardingStep.test.ts b/app/components/UI/Money/hooks/useOnboardingStep.test.ts new file mode 100644 index 00000000000..41121977776 --- /dev/null +++ b/app/components/UI/Money/hooks/useOnboardingStep.test.ts @@ -0,0 +1,121 @@ +import { renderHook, act } from '@testing-library/react-hooks'; +import { useSelector, useDispatch } from 'react-redux'; +import { useOnboardingStep, STEPPER_IDS } from './useOnboardingStep'; +import { setOnboardingStepperStep } from '../../../../actions/user'; + +jest.mock('react-redux', () => ({ + useSelector: jest.fn(), + useDispatch: jest.fn(), +})); + +jest.mock('../../../../actions/user', () => ({ + setOnboardingStepperStep: jest.fn(), +})); + +const mockUseSelector = useSelector as jest.MockedFunction; +const mockUseDispatch = useDispatch as jest.MockedFunction; +const mockSetOnboardingStepperStep = + setOnboardingStepperStep as jest.MockedFunction< + typeof setOnboardingStepperStep + >; + +describe('useOnboardingStep', () => { + const mockDispatch = jest.fn(); + + beforeEach(() => { + jest.clearAllMocks(); + mockUseDispatch.mockReturnValue(mockDispatch); + }); + + describe('STEPPER_IDS', () => { + it('exports a MONEY stepper ID', () => { + expect(STEPPER_IDS.MONEY).toBe('money-home-onboarding-stepper'); + }); + }); + + describe('currentStep', () => { + it('defaults to 0 when onboardingStepperProgress is empty', () => { + mockUseSelector.mockReturnValue({}); + + const { result } = renderHook(() => + useOnboardingStep({ stepperId: STEPPER_IDS.MONEY }), + ); + + expect(result.current.currentStep).toBe(0); + }); + + it('returns the stored step for the given stepperId', () => { + mockUseSelector.mockReturnValue({ [STEPPER_IDS.MONEY]: 2 }); + + const { result } = renderHook(() => + useOnboardingStep({ stepperId: STEPPER_IDS.MONEY }), + ); + + expect(result.current.currentStep).toBe(2); + }); + }); + + describe('incrementStep', () => { + it('dispatches setOnboardingStepperStep with stepperId and currentStep + 1', () => { + mockUseSelector.mockReturnValue({ [STEPPER_IDS.MONEY]: 1 }); + const mockAction = { type: 'SET_ONBOARDING_STEPPER_STEP' }; + mockSetOnboardingStepperStep.mockReturnValue(mockAction as never); + + const { result } = renderHook(() => + useOnboardingStep({ stepperId: STEPPER_IDS.MONEY }), + ); + + act(() => { + result.current.incrementStep(); + }); + + expect(mockSetOnboardingStepperStep).toHaveBeenCalledWith( + STEPPER_IDS.MONEY, + 2, + ); + expect(mockDispatch).toHaveBeenCalledWith(mockAction); + }); + }); + + describe('isVisible', () => { + it('returns undefined when totalSteps is not provided', () => { + mockUseSelector.mockReturnValue({}); + + const { result } = renderHook(() => + useOnboardingStep({ stepperId: STEPPER_IDS.MONEY }), + ); + + expect(result.current.isVisible).toBeUndefined(); + }); + + it('returns true when currentStep is less than totalSteps', () => { + mockUseSelector.mockReturnValue({ [STEPPER_IDS.MONEY]: 0 }); + + const { result } = renderHook(() => + useOnboardingStep({ stepperId: STEPPER_IDS.MONEY, totalSteps: 2 }), + ); + + expect(result.current.isVisible).toBe(true); + }); + + it('returns false when currentStep equals totalSteps', () => { + mockUseSelector.mockReturnValue({ [STEPPER_IDS.MONEY]: 2 }); + + const { result } = renderHook(() => + useOnboardingStep({ stepperId: STEPPER_IDS.MONEY, totalSteps: 2 }), + ); + + expect(result.current.isVisible).toBe(false); + }); + + it('returns false when currentStep exceeds totalSteps', () => { + mockUseSelector.mockReturnValue({ [STEPPER_IDS.MONEY]: 5 }); + + const { result } = renderHook(() => + useOnboardingStep({ stepperId: STEPPER_IDS.MONEY, totalSteps: 2 }), + ); + + expect(result.current.isVisible).toBe(false); + }); + }); +}); diff --git a/app/components/UI/Money/hooks/useOnboardingStep.ts b/app/components/UI/Money/hooks/useOnboardingStep.ts new file mode 100644 index 00000000000..34966b76bec --- /dev/null +++ b/app/components/UI/Money/hooks/useOnboardingStep.ts @@ -0,0 +1,40 @@ +import { useCallback } from 'react'; +import { useDispatch, useSelector } from 'react-redux'; +import { selectOnboardingStepperProgress } from '../../../../reducers/user/selectors'; +import { setOnboardingStepperStep } from '../../../../actions/user'; + +/** + * Registry of stepper IDs used across products. + * Add a new entry here when a new onboarding stepper is introduced. + */ +export const STEPPER_IDS = { + MONEY: 'money-home-onboarding-stepper', +} as const; + +/** + * Generic hook for tracking onboarding stepper progress. + * + * Keyed by `stepperId` so multiple independent steppers can coexist + * without adding new Redux fields per product. Pass `totalSteps` to + * derive the `isVisible` flag (true while `currentStep < totalSteps`). + */ +export const useOnboardingStep = ({ + stepperId, + totalSteps, +}: { + stepperId: string; + totalSteps?: number; +}) => { + const dispatch = useDispatch(); + const progress = useSelector(selectOnboardingStepperProgress); + const currentStep = progress[stepperId] ?? 0; + + const incrementStep = useCallback(() => { + dispatch(setOnboardingStepperStep(stepperId, currentStep + 1)); + }, [dispatch, stepperId, currentStep]); + + const isVisible = + totalSteps !== undefined ? currentStep < totalSteps : undefined; + + return { currentStep, incrementStep, isVisible }; +}; diff --git a/app/components/UI/Money/hooks/useUpgradeMoneyAccountOnMount.test.ts b/app/components/UI/Money/hooks/useUpgradeMoneyAccountOnMount.test.ts new file mode 100644 index 00000000000..9ac6e169dbe --- /dev/null +++ b/app/components/UI/Money/hooks/useUpgradeMoneyAccountOnMount.test.ts @@ -0,0 +1,45 @@ +import { renderHook } from '@testing-library/react-hooks'; +import { useUpgradeMoneyAccountOnMount } from './useUpgradeMoneyAccountOnMount'; +import { upgradeMoneyAccount } from '../../../../actions/money'; +import useThunkDispatch from '../../../hooks/useThunkDispatch'; + +jest.mock('../../../../actions/money', () => ({ + upgradeMoneyAccount: jest.fn(), +})); + +jest.mock('../../../hooks/useThunkDispatch', () => ({ + __esModule: true, + default: jest.fn(), +})); + +const mockUpgradeMoneyAccount = upgradeMoneyAccount as jest.MockedFunction< + typeof upgradeMoneyAccount +>; +const mockUseThunkDispatch = useThunkDispatch as jest.MockedFunction< + typeof useThunkDispatch +>; + +describe('useUpgradeMoneyAccountOnMount', () => { + const mockDispatch = jest.fn(); + const mockUpgradeAction = { type: 'UPGRADE_MONEY_ACCOUNT' }; + + beforeEach(() => { + jest.clearAllMocks(); + mockUseThunkDispatch.mockReturnValue(mockDispatch as never); + mockUpgradeMoneyAccount.mockReturnValue(mockUpgradeAction as never); + }); + + it('dispatches upgradeMoneyAccount on mount', () => { + renderHook(() => useUpgradeMoneyAccountOnMount()); + + expect(mockDispatch).toHaveBeenCalledWith(mockUpgradeAction); + }); + + it('does not dispatch again on re-render when dispatch reference is stable', () => { + const { rerender } = renderHook(() => useUpgradeMoneyAccountOnMount()); + + rerender(); + + expect(mockDispatch).toHaveBeenCalledTimes(1); + }); +}); diff --git a/app/components/UI/Money/hooks/useUpgradeMoneyAccountOnMount.ts b/app/components/UI/Money/hooks/useUpgradeMoneyAccountOnMount.ts new file mode 100644 index 00000000000..e558fe97aca --- /dev/null +++ b/app/components/UI/Money/hooks/useUpgradeMoneyAccountOnMount.ts @@ -0,0 +1,11 @@ +import { useEffect } from 'react'; +import { upgradeMoneyAccount } from '../../../../actions/money'; +import useThunkDispatch from '../../../hooks/useThunkDispatch'; + +export const useUpgradeMoneyAccountOnMount = () => { + const dispatch = useThunkDispatch(); + + useEffect(() => { + dispatch(upgradeMoneyAccount()); + }, [dispatch]); +}; diff --git a/app/components/UI/Money/routes/index.test.tsx b/app/components/UI/Money/routes/index.test.tsx index ed7a03a668a..3c13cf5a62a 100644 --- a/app/components/UI/Money/routes/index.test.tsx +++ b/app/components/UI/Money/routes/index.test.tsx @@ -2,20 +2,29 @@ import React from 'react'; import { Text as MockText, View as MockView } from 'react-native'; import renderWithProvider from '../../../../util/test/renderWithProvider'; import { mockTheme } from '../../../../util/theme'; -import { upgradeMoneyAccount } from '../../../../actions/money'; +import { useUpgradeMoneyAccountOnMount } from '../hooks/useUpgradeMoneyAccountOnMount'; import { - MoneyAccountStackGate, + MoneyConfirmationScreenStack, MoneyModalStack, - MoneyScreenStack, + MoneyTabScreenStack, } from './index'; -jest.mock('../../../../actions/money', () => ({ - upgradeMoneyAccount: jest.fn(() => () => undefined), +jest.mock('../hooks/useUpgradeMoneyAccountOnMount', () => ({ + useUpgradeMoneyAccountOnMount: jest.fn(), })); -const mockUpgradeMoneyAccount = jest.mocked(upgradeMoneyAccount); +const mockUseUpgradeMoneyAccountOnMount = jest.mocked( + useUpgradeMoneyAccountOnMount, +); -const EXPECTED_CARD_BACKGROUND = '#money-test-bg'; +jest.mock( + '../../../Views/confirmations/hooks/ui/useEmptyNavHeaderForConfirmations', + () => ({ + useEmptyNavHeaderForConfirmations: jest.fn(() => ({ headerShown: false })), + }), +); + +const EXPECTED_CARD_BACKGROUND = mockTheme.colors.background.default; const themeWithCustomBackground = { ...mockTheme, @@ -61,27 +70,66 @@ jest.mock('@react-navigation/native-stack', () => ({ jest.mock('../Views/MoneyHomeView', () => () => ( )); - jest.mock('../Views/MoneyActivityView', () => () => ( )); - +jest.mock('../Views/MoneyHowItWorksView', () => () => ( + +)); +jest.mock('../Views/MoneyPotentialEarningsView', () => () => ( + +)); jest.mock('../components/MoneyAddMoneySheet', () => () => ( )); +jest.mock('../components/MoneyMoreSheet', () => () => ( + +)); +jest.mock('../components/MoneyTransferSheet', () => () => ( + +)); +jest.mock('../components/MoneyApyInfoSheet', () => () => ( + +)); +jest.mock('../components/MoneyEarningsInfoSheet', () => () => ( + +)); +jest.mock('../components/MoneyBalanceInfoSheet', () => () => ( + +)); +jest.mock('../components/MoneyLinkCardSheet', () => () => ( + +)); +jest.mock('../components/MoneyEarnCryptoInfoSheet', () => () => ( + +)); +jest.mock('../components/MoneyTransactionDetailsSheet', () => () => ( + +)); +jest.mock('../../../Views/confirmations/components/confirm', () => ({ + Confirm: () => , +})); + +describe('MoneyTabScreenStack', () => { + beforeEach(() => { + jest.clearAllMocks(); + }); -describe('MoneyScreenStack', () => { - it('registers Money home and activity screens', () => { - const { getByTestId } = renderWithProvider(, { + it('registers Money home, activity, how-it-works, and potential-earnings screens', () => { + const { getByTestId } = renderWithProvider(, { theme: themeWithCustomBackground, }); expect(getByTestId('money-screen-MoneyHome')).toBeOnTheScreen(); expect(getByTestId('money-screen-MoneyActivity')).toBeOnTheScreen(); + expect(getByTestId('money-screen-MoneyHowItWorks')).toBeOnTheScreen(); + expect( + getByTestId('money-screen-MoneyPotentialEarnings'), + ).toBeOnTheScreen(); }); it('sets stack content background from theme to avoid flash during inner navigation', () => { - const { getByTestId } = renderWithProvider(, { + const { getByTestId } = renderWithProvider(, { theme: themeWithCustomBackground, }); @@ -91,33 +139,64 @@ describe('MoneyScreenStack', () => { }); it('hides the stack header', () => { - const { getByTestId } = renderWithProvider(, { + const { getByTestId } = renderWithProvider(, { theme: themeWithCustomBackground, }); expect(getByTestId('money-header-hidden')).toBeOnTheScreen(); }); + + it('calls useUpgradeMoneyAccountOnMount on mount', () => { + renderWithProvider(, { + theme: themeWithCustomBackground, + }); + + expect(mockUseUpgradeMoneyAccountOnMount).toHaveBeenCalledTimes(1); + }); }); -describe('MoneyAccountStackGate', () => { +describe('MoneyConfirmationScreenStack', () => { beforeEach(() => { - mockUpgradeMoneyAccount.mockClear(); + jest.clearAllMocks(); }); - it('dispatches upgradeMoneyAccount once when the stack mounts', () => { - renderWithProvider(, { - theme: themeWithCustomBackground, - }); + it('registers the redesigned confirmations screen', () => { + const { getByTestId } = renderWithProvider( + , + { theme: themeWithCustomBackground }, + ); + + expect( + getByTestId('money-screen-RedesignedConfirmations'), + ).toBeOnTheScreen(); + }); + + it('hides the stack header', () => { + const { getByTestId } = renderWithProvider( + , + { theme: themeWithCustomBackground }, + ); - expect(mockUpgradeMoneyAccount).toHaveBeenCalledTimes(1); + expect(getByTestId('money-header-hidden')).toBeOnTheScreen(); + }); + + it('sets stack content background from theme', () => { + const { getByTestId } = renderWithProvider( + , + { theme: themeWithCustomBackground }, + ); + + expect(getByTestId('money-content-background-color')).toHaveTextContent( + EXPECTED_CARD_BACKGROUND, + ); }); - it('renders the Money screen stack', () => { - const { getByTestId } = renderWithProvider(, { + it('calls useUpgradeMoneyAccountOnMount on mount', () => { + renderWithProvider(, { theme: themeWithCustomBackground, }); - expect(getByTestId('money-screen-MoneyHome')).toBeOnTheScreen(); + expect(mockUseUpgradeMoneyAccountOnMount).toHaveBeenCalledTimes(1); }); }); @@ -130,6 +209,40 @@ describe('MoneyModalStack', () => { expect(getByTestId('money-screen-MoneyAddMoneySheet')).toBeOnTheScreen(); }); + it('registers the More sheet as a modal screen', () => { + const { getByTestId } = renderWithProvider(, { + theme: themeWithCustomBackground, + }); + + expect(getByTestId('money-screen-MoneyMoreSheet')).toBeOnTheScreen(); + }); + + it('registers the Transfer money sheet as a modal screen', () => { + const { getByTestId } = renderWithProvider(, { + theme: themeWithCustomBackground, + }); + + expect(getByTestId('money-screen-MoneyTransferSheet')).toBeOnTheScreen(); + }); + + it('registers the APY info sheet as a modal screen', () => { + const { getByTestId } = renderWithProvider(, { + theme: themeWithCustomBackground, + }); + + expect(getByTestId('money-screen-MoneyApyInfoSheet')).toBeOnTheScreen(); + }); + + it('registers the Earnings info sheet as a modal screen', () => { + const { getByTestId } = renderWithProvider(, { + theme: themeWithCustomBackground, + }); + + expect( + getByTestId('money-screen-MoneyEarningsInfoSheet'), + ).toBeOnTheScreen(); + }); + it('registers the Money balance info sheet as a modal screen', () => { const { getByTestId } = renderWithProvider(, { theme: themeWithCustomBackground, @@ -137,4 +250,32 @@ describe('MoneyModalStack', () => { expect(getByTestId('money-screen-MoneyBalanceInfoSheet')).toBeOnTheScreen(); }); + + it('registers the Link card sheet as a modal screen', () => { + const { getByTestId } = renderWithProvider(, { + theme: themeWithCustomBackground, + }); + + expect(getByTestId('money-screen-MoneyLinkCardSheet')).toBeOnTheScreen(); + }); + + it('registers the Earn crypto info sheet as a modal screen', () => { + const { getByTestId } = renderWithProvider(, { + theme: themeWithCustomBackground, + }); + + expect( + getByTestId('money-screen-MoneyEarnCryptoInfoSheet'), + ).toBeOnTheScreen(); + }); + + it('registers the Transaction details sheet as a modal screen', () => { + const { getByTestId } = renderWithProvider(, { + theme: themeWithCustomBackground, + }); + + expect( + getByTestId('money-screen-MoneyTransactionDetailsSheet'), + ).toBeOnTheScreen(); + }); }); diff --git a/app/components/UI/Money/routes/index.tsx b/app/components/UI/Money/routes/index.tsx index 8469a81f993..3d14e2db844 100644 --- a/app/components/UI/Money/routes/index.tsx +++ b/app/components/UI/Money/routes/index.tsx @@ -1,4 +1,4 @@ -import React, { useEffect } from 'react'; +import React from 'react'; import { createNativeStackNavigator } from '@react-navigation/native-stack'; import Routes from '../../../../constants/navigation/Routes'; import { @@ -6,8 +6,6 @@ import { transparentModalScreenOptions, } from '../../../../constants/navigation/clearStackNavigatorOptions'; import { useTheme } from '../../../../util/theme'; -import useThunkDispatch from '../../../hooks/useThunkDispatch'; -import { upgradeMoneyAccount } from '../../../../actions/money'; import MoneyHomeView from '../Views/MoneyHomeView'; import MoneyActivityView from '../Views/MoneyActivityView'; import MoneyHowItWorksView from '../Views/MoneyHowItWorksView'; @@ -23,13 +21,16 @@ import MoneyEarnCryptoInfoSheet from '../components/MoneyEarnCryptoInfoSheet'; import MoneyTransactionDetailsSheet from '../components/MoneyTransactionDetailsSheet'; import { Confirm } from '../../../Views/confirmations/components/confirm'; import { useEmptyNavHeaderForConfirmations } from '../../../Views/confirmations/hooks/ui/useEmptyNavHeaderForConfirmations'; +import { useUpgradeMoneyAccountOnMount } from '../hooks/useUpgradeMoneyAccountOnMount'; const Stack = createNativeStackNavigator(); const ModalStack = createNativeStackNavigator(); -const MoneyScreenStack = () => { +// For Money screens that require bottom navbar. +const MoneyTabScreenStack = () => { const { colors } = useTheme(); - const emptyNavHeaderOptions = useEmptyNavHeaderForConfirmations(); + + useUpgradeMoneyAccountOnMount(); return ( { name={Routes.MONEY.POTENTIAL_EARNINGS} component={MoneyPotentialEarningsView} /> + + ); +}; + +// We separate the confirmation screen so we can define it separately in the MainNavigator outside of the HomeTabs. +// This way we don't want to show the bottom navbar. +const MoneyConfirmationScreenStack = () => { + const { colors } = useTheme(); + const emptyNavHeaderOptions = useEmptyNavHeaderForConfirmations(); + + useUpgradeMoneyAccountOnMount(); + + return ( + ( ); -const MoneyAccountStackGate = () => { - const dispatch = useThunkDispatch(); - - useEffect(() => { - dispatch(upgradeMoneyAccount()); - }, [dispatch]); - - return ; -}; - -export { MoneyAccountStackGate, MoneyScreenStack, MoneyModalStack }; +export { MoneyConfirmationScreenStack, MoneyModalStack, MoneyTabScreenStack }; diff --git a/app/components/UI/NetworkManager/index.styles.ts b/app/components/UI/NetworkManager/index.styles.ts index 7346b5ed6fd..24a614d68df 100644 --- a/app/components/UI/NetworkManager/index.styles.ts +++ b/app/components/UI/NetworkManager/index.styles.ts @@ -4,6 +4,7 @@ import { TextVariant, } from '../../../component-library/components/Texts/Text'; import { Theme } from '../../../util/theme/models'; +import { getElevatedSurfaceColor } from '../../../util/theme/themeUtils'; const UNDERLINE_HEIGHT = 2; const TAB_PADDING_BOTTOM = 8; @@ -42,6 +43,7 @@ const createStyles = (params: { theme: Theme }) => { }, tabBar: { borderColor: borderMuted, + backgroundColor: getElevatedSurfaceColor(theme), }, // edit network menu editNetworkMenu: { diff --git a/app/components/UI/NetworkMultiSelector/NetworkMultiSelector.styles.ts b/app/components/UI/NetworkMultiSelector/NetworkMultiSelector.styles.ts index 87ba90ed380..04c7b598c4d 100644 --- a/app/components/UI/NetworkMultiSelector/NetworkMultiSelector.styles.ts +++ b/app/components/UI/NetworkMultiSelector/NetworkMultiSelector.styles.ts @@ -1,9 +1,14 @@ import { StyleSheet } from 'react-native'; +import { Theme } from '../../../util/theme/models'; +import { getElevatedSurfaceColor } from '../../../util/theme/themeUtils'; -const stylesheet = () => - StyleSheet.create({ +const stylesheet = (params: { theme: Theme }) => { + const { theme } = params; + const { colors } = theme; + return StyleSheet.create({ bodyContainer: { flex: 1, + backgroundColor: getElevatedSurfaceColor(theme), }, // custom network customNetworkContainer: { @@ -12,7 +17,9 @@ const stylesheet = () => // select all popular networks cell selectAllPopularNetworksCell: { alignItems: 'center', + backgroundColor: getElevatedSurfaceColor(theme), }, }); +}; export default stylesheet; diff --git a/app/components/UI/NetworkMultiSelector/NetworkMultiSelector.tsx b/app/components/UI/NetworkMultiSelector/NetworkMultiSelector.tsx index f5ba8b8b9e8..ee852a851cd 100644 --- a/app/components/UI/NetworkMultiSelector/NetworkMultiSelector.tsx +++ b/app/components/UI/NetworkMultiSelector/NetworkMultiSelector.tsx @@ -11,6 +11,7 @@ import { useSafeAreaInsets } from 'react-native-safe-area-context'; // external dependencies import hideKeyFromUrl from '../../../util/hideKeyFromUrl'; +import { useTheme } from '../../../util/theme'; import { useStyles } from '../../../component-library/hooks/useStyles'; import { Box } from '@metamask/design-system-react-native'; import { ExtendedNetwork } from '../../Views/Settings/NetworksSettings/NetworkSettings/CustomNetworkView/CustomNetwork.types'; @@ -82,7 +83,8 @@ const NetworkMultiSelector = ({ openRpcModal, }: NetworkMultiSelectorProps) => { const insets = useSafeAreaInsets(); - const { styles } = useStyles(stylesheet, {}); + const theme = useTheme(); + const { styles } = useStyles(stylesheet, { theme }); const [modalState, setModalState] = useState(initialModalState); diff --git a/app/components/UI/Notification/Empty/index.test.tsx b/app/components/UI/Notification/Empty/index.test.tsx index 9217053ce88..9844443b8a4 100644 --- a/app/components/UI/Notification/Empty/index.test.tsx +++ b/app/components/UI/Notification/Empty/index.test.tsx @@ -1,4 +1,5 @@ import React from 'react'; +import { StyleSheet } from 'react-native'; import Empty from './'; import renderWithProvider from '../../../../util/test/renderWithProvider'; @@ -7,4 +8,16 @@ describe('Empty', () => { const { getByText } = renderWithProvider(); expect(getByText('Nothing to see here')).toBeOnTheScreen(); }); + + it('does not include the disabled notifications CTA offset', () => { + const { getByTestId } = renderWithProvider( + , + ); + + const wrapperStyle = StyleSheet.flatten( + getByTestId('empty-notifications').props.style, + ); + + expect(wrapperStyle.paddingBottom).toBeUndefined(); + }); }); diff --git a/app/components/UI/Notification/Empty/index.tsx b/app/components/UI/Notification/Empty/index.tsx index 0391da98780..8a7b0308448 100644 --- a/app/components/UI/Notification/Empty/index.tsx +++ b/app/components/UI/Notification/Empty/index.tsx @@ -1,27 +1,27 @@ import React from 'react'; import { View } from 'react-native'; -import Text, { - TextVariant, -} from '../../../../component-library/components/Texts/Text'; import { strings } from '../../../../../locales/i18n'; import { styles } from './styles'; -import Icon, { +import { + Icon, IconColor, IconName, IconSize, -} from '../../../../component-library/components/Icons/Icon'; + Text, + TextVariant, +} from '@metamask/design-system-react-native'; const Empty = ({ testID }: { testID?: string }) => ( - + {strings('notifications.empty.title')} - + {strings('notifications.empty.message')} diff --git a/app/components/UI/Predict/assets/world-cup-main-feed-banner.png b/app/components/UI/Predict/assets/world-cup-main-feed-banner.png index a0ef125f434..7b34c80da54 100644 Binary files a/app/components/UI/Predict/assets/world-cup-main-feed-banner.png and b/app/components/UI/Predict/assets/world-cup-main-feed-banner.png differ diff --git a/app/components/UI/Predict/components/PredictWorldCupMainFeedBanner/PredictWorldCupMainFeedBanner.test.tsx b/app/components/UI/Predict/components/PredictWorldCupMainFeedBanner/PredictWorldCupMainFeedBanner.test.tsx index 4ac7e58dcce..58fa43a6664 100644 --- a/app/components/UI/Predict/components/PredictWorldCupMainFeedBanner/PredictWorldCupMainFeedBanner.test.tsx +++ b/app/components/UI/Predict/components/PredictWorldCupMainFeedBanner/PredictWorldCupMainFeedBanner.test.tsx @@ -165,7 +165,7 @@ describe('getPredictWorldCupBannerImageAspectRatio', () => { }); it('returns default image aspect ratio when dimensions are missing', () => { - expect(getPredictWorldCupBannerImageAspectRatio()).toBe(2); + expect(getPredictWorldCupBannerImageAspectRatio()).toBe(360 / 177); }); it('returns default image aspect ratio when dimensions are invalid', () => { @@ -175,7 +175,7 @@ describe('getPredictWorldCupBannerImageAspectRatio', () => { width: 0, height: -200, }), - ).toBe(2); + ).toBe(360 / 177); }); }); diff --git a/app/components/UI/Predict/components/PredictWorldCupMainFeedBanner/PredictWorldCupMainFeedBanner.tsx b/app/components/UI/Predict/components/PredictWorldCupMainFeedBanner/PredictWorldCupMainFeedBanner.tsx index b92e2f68e63..117c4eace28 100644 --- a/app/components/UI/Predict/components/PredictWorldCupMainFeedBanner/PredictWorldCupMainFeedBanner.tsx +++ b/app/components/UI/Predict/components/PredictWorldCupMainFeedBanner/PredictWorldCupMainFeedBanner.tsx @@ -15,6 +15,7 @@ import { ButtonIconVariant, FontWeight, IconName, + IconSize, Text, TextColor, TextVariant, @@ -29,7 +30,7 @@ import { PredictWorldCupMainFeedBannerSelectorsIDs } from './PredictWorldCupMain import worldCupMainFeedBannerImage from '../../assets/world-cup-main-feed-banner.png'; -const WORLD_CUP_BANNER_DEFAULT_IMAGE_ASPECT_RATIO = 2; +const WORLD_CUP_BANNER_DEFAULT_IMAGE_ASPECT_RATIO = 360 / 177; const WORLD_CUP_BANNER_HORIZONTAL_MARGIN = 16; const WORLD_CUP_BANNER_HORIZONTAL_MARGIN_TOTAL = WORLD_CUP_BANNER_HORIZONTAL_MARGIN * 2; @@ -164,8 +165,9 @@ const PredictWorldCupMainFeedBanner: React.FC< diff --git a/app/components/UI/Predict/queries/worldCup.test.ts b/app/components/UI/Predict/queries/worldCup.test.ts index a2327605433..6e861f8d344 100644 --- a/app/components/UI/Predict/queries/worldCup.test.ts +++ b/app/components/UI/Predict/queries/worldCup.test.ts @@ -99,7 +99,7 @@ describe('worldCup queries', () => { }); }); - it('fetches stage markets with repeated event IDs and sorts by match start time', async () => { + it('fetches stage markets with repeated event IDs', async () => { const baseGame = { id: 'game-later', startTime: '2026-06-13T20:00:00.000Z', @@ -154,7 +154,7 @@ describe('worldCup queries', () => { 'active=true&archived=false&closed=false&id=123&id=456', limit: 2, }); - expect(result.map((market) => market.id)).toEqual(['earlier', 'later']); + expect(result.map((market) => market.id)).toEqual(['later', 'earlier']); }); it('uses lightweight availability requests for Live, Props, and stages', async () => { diff --git a/app/components/UI/Predict/queries/worldCup.ts b/app/components/UI/Predict/queries/worldCup.ts index 0fa222a9c9d..a56db99a4da 100644 --- a/app/components/UI/Predict/queries/worldCup.ts +++ b/app/components/UI/Predict/queries/worldCup.ts @@ -148,7 +148,6 @@ export const predictWorldCupOptions = { : fetchPredictWorldCupMarkets({ queryParams, limit, - sortByStartTime: true, }), staleTime: 10_000, }); diff --git a/app/components/UI/Predict/views/PredictMarketDetails/PredictMarketDetails.tsx b/app/components/UI/Predict/views/PredictMarketDetails/PredictMarketDetails.tsx index a395a9116f4..c5bc3f7fbfa 100644 --- a/app/components/UI/Predict/views/PredictMarketDetails/PredictMarketDetails.tsx +++ b/app/components/UI/Predict/views/PredictMarketDetails/PredictMarketDetails.tsx @@ -575,11 +575,10 @@ const PredictMarketDetails: React.FC = () => { )} {isFeeExemption && ( {strings('predict.market_details.fee_exemption')} diff --git a/app/components/UI/Predict/views/PredictMarketDetails/components/PredictMarketDetailsActions/PredictMarketDetailsActions.test.tsx b/app/components/UI/Predict/views/PredictMarketDetails/components/PredictMarketDetailsActions/PredictMarketDetailsActions.test.tsx index 0a5cb052b67..912e132dc1b 100644 --- a/app/components/UI/Predict/views/PredictMarketDetails/components/PredictMarketDetailsActions/PredictMarketDetailsActions.test.tsx +++ b/app/components/UI/Predict/views/PredictMarketDetails/components/PredictMarketDetailsActions/PredictMarketDetailsActions.test.tsx @@ -1,5 +1,9 @@ import React from 'react'; import { fireEvent, screen } from '@testing-library/react-native'; +import type { + ReactTestRendererJSON, + ReactTestRendererNode, +} from 'react-test-renderer'; import renderWithProvider from '../../../../../../../util/test/renderWithProvider'; import { PredictMarket, @@ -64,6 +68,40 @@ const createProps = ( ...overrides, }); +const flattenStyle = (style: unknown): Record => { + if (Array.isArray(style)) { + return Object.assign({}, ...style.map(flattenStyle)); + } + + if (style && typeof style === 'object') { + return style as Record; + } + + return {}; +}; + +type JsonTree = ReactTestRendererNode | ReactTestRendererNode[] | null; + +const findJsonNodes = ( + node: JsonTree, + predicate: (jsonNode: ReactTestRendererJSON) => boolean, +): ReactTestRendererJSON[] => { + if (Array.isArray(node)) { + return node.flatMap((child) => findJsonNodes(child, predicate)); + } + + if (!node || typeof node !== 'object') { + return []; + } + + const jsonNode = node as ReactTestRendererJSON; + + return [ + ...(predicate(jsonNode) ? [jsonNode] : []), + ...findJsonNodes(jsonNode.children ?? [], predicate), + ]; +}; + describe('PredictMarketDetailsActions', () => { beforeEach(() => { jest.clearAllMocks(); @@ -103,6 +141,25 @@ describe('PredictMarketDetailsActions', () => { expect(onBuyPress).toHaveBeenNthCalledWith(2, openOutcome.tokens[1]); }); + it('reserves button height in the action columns', () => { + const props = createProps(); + + const { toJSON } = renderWithProvider( + , + ); + + const actionColumns = findJsonNodes(toJSON(), (node) => { + const style = flattenStyle(node.props.style); + return ( + node.props.accessibilityRole !== 'button' && + style.flexGrow === 1 && + style.minHeight === 48 + ); + }); + + expect(actionColumns).toHaveLength(2); + }); + it('falls back to market tokens when open outcomes are unavailable', () => { const onBuyPress = jest.fn(); const fallbackMarket = createMarket(); diff --git a/app/components/UI/Predict/views/PredictMarketDetails/components/PredictMarketDetailsActions/PredictMarketDetailsActions.tsx b/app/components/UI/Predict/views/PredictMarketDetails/components/PredictMarketDetailsActions/PredictMarketDetailsActions.tsx index 6744d128aa5..f5e87bd198b 100644 --- a/app/components/UI/Predict/views/PredictMarketDetails/components/PredictMarketDetailsActions/PredictMarketDetailsActions.tsx +++ b/app/components/UI/Predict/views/PredictMarketDetails/components/PredictMarketDetailsActions/PredictMarketDetailsActions.tsx @@ -151,12 +151,16 @@ const PredictMarketDetailsActions = memo( tw.style( showPayoutEstimate ? 'w-full' : 'flex-1', backgroundClassName, + { minHeight: TALL_ACTION_BUTTON_MIN_HEIGHT }, useStackedLabels && { height: 'auto', minHeight: TALL_ACTION_BUTTON_MIN_HEIGHT, paddingVertical: 8, }, ); + const actionColumnStyle = { + minHeight: TALL_ACTION_BUTTON_MIN_HEIGHT, + }; const renderPayoutEstimate = ( token: PredictOutcomeToken | undefined, color: TextColor, @@ -178,7 +182,7 @@ const PredictMarketDetailsActions = memo( alignItems={BoxAlignItems.Center} twClassName="w-full mt-4 gap-3" > - + + +); + +export default DisabledNotifications; diff --git a/app/components/Views/Notifications/DisabledNotifications/styles.ts b/app/components/Views/Notifications/DisabledNotifications/styles.ts new file mode 100644 index 00000000000..5a8a1ae0725 --- /dev/null +++ b/app/components/Views/Notifications/DisabledNotifications/styles.ts @@ -0,0 +1,30 @@ +import { StyleSheet } from 'react-native'; + +const styles = StyleSheet.create({ + wrapper: { + flex: 1, + justifyContent: 'center', + alignItems: 'center', + paddingBottom: 56, + }, + icon: { + marginBottom: 16, + paddingHorizontal: 32, + textAlign: 'center', + }, + title: { + marginBottom: 4, + paddingHorizontal: 32, + textAlign: 'center', + }, + message: { + marginBottom: 16, + paddingHorizontal: 32, + textAlign: 'center', + }, + button: { + alignSelf: 'center', + }, +}); + +export default styles; diff --git a/app/components/Views/Notifications/NotificationsView.testIds.ts b/app/components/Views/Notifications/NotificationsView.testIds.ts index 01d64ce3ab8..0155c99518b 100644 --- a/app/components/Views/Notifications/NotificationsView.testIds.ts +++ b/app/components/Views/Notifications/NotificationsView.testIds.ts @@ -1,4 +1,7 @@ export const NotificationsViewSelectorsIDs = { NOTIFICATIONS_CONTAINER: 'notifications-container', NO_NOTIFICATIONS_CONTAINER: 'no-notifications-container', + DISABLED_NOTIFICATIONS_CONTAINER: 'disabled-notifications-container', + DISABLED_NOTIFICATIONS_ICON: 'disabled-notifications-icon', + ENABLE_NOTIFICATIONS_BUTTON: 'notifications-enable-button', }; diff --git a/app/components/Views/Notifications/OptIn/EnableNotificationModal.testIds.ts b/app/components/Views/Notifications/OptIn/EnableNotificationModal.testIds.ts deleted file mode 100644 index 29ce09ccad2..00000000000 --- a/app/components/Views/Notifications/OptIn/EnableNotificationModal.testIds.ts +++ /dev/null @@ -1,5 +0,0 @@ -export const EnableNotificationModalSelectorsIDs = { - TITLE: 'enable-notifications-modal-title', - BUTTON_CANCEL: 'enable-notifications-modal-button-cancel', - BUTTON_ENABLE: 'enable-notifications-modal-button-enable', -}; diff --git a/app/components/Views/Notifications/OptIn/OptIn.hooks.test.tsx b/app/components/Views/Notifications/OptIn/OptIn.hooks.test.tsx deleted file mode 100644 index 8656921efe9..00000000000 --- a/app/components/Views/Notifications/OptIn/OptIn.hooks.test.tsx +++ /dev/null @@ -1,242 +0,0 @@ -import { renderHook, act } from '@testing-library/react-hooks'; -import { NavigationProp, ParamListBase } from '@react-navigation/native'; -import { - useHandleOptInCancel, - useHandleOptInClick, - useOptimisticNavigationEffect, -} from './OptIn.hooks'; -import Routes from '../../../../constants/navigation/Routes'; -import { renderHookWithProvider } from '../../../../util/test/renderWithProvider'; -import type { UseAnalyticsHook } from '../../../hooks/useAnalytics/useAnalytics.types'; -import { MetaMetricsEvents } from '../../../../core/Analytics'; -// eslint-disable-next-line import-x/no-namespace -import * as Selectors from '../../../../selectors/identity'; - -describe('useOptimisticNavigationEffect', () => { - jest.useFakeTimers(); - - const arrange = (isCreatingNotifications: boolean) => { - const mockNavigate = jest.fn(); - const mockNavigation = { - navigate: mockNavigate, - } as unknown as NavigationProp; - - const hook = renderHook( - (props: { isCreatingNotifications: boolean }) => - useOptimisticNavigationEffect({ - isCreatingNotifications: props.isCreatingNotifications, - navigation: mockNavigation, - }), - { initialProps: { isCreatingNotifications } }, - ); - - return { hook, mockNavigate, mockNavigation }; - }; - - it('sets optimisticLoading to true when isCreatingNotifications is true', () => { - const { hook } = arrange(true); - expect(hook.result.current).toBe(true); - }); - - it('sets optimisticLoading to false when isCreatingNotifications is false', () => { - const { hook } = arrange(false); - expect(hook.result.current).toBe(false); - }); - - it('navigates to notification list page after timeout', () => { - const { hook, mockNavigate } = arrange(true); - - // Assert - We are optimistically loading - expect(hook.result.current).toBe(true); - - act(() => jest.advanceTimersByTime(5000)); - - // Assert - We have stopped optimistically loading - expect(mockNavigate).toHaveBeenCalledWith(Routes.NOTIFICATIONS.VIEW); - expect(hook.result.current).toBe(false); - }); - - it('clears timeout when isCreatingNotifications changes to false', () => { - const { hook, mockNavigate } = arrange(true); - - act(() => - hook.rerender({ - isCreatingNotifications: false, - }), - ); - - act(() => jest.advanceTimersByTime(5000)); - - expect(mockNavigate).not.toHaveBeenCalled(); - expect(hook.result.current).toBe(false); - }); - - it('clears timeout on unmount', () => { - const { hook, mockNavigate } = arrange(true); - - act(() => hook.unmount()); - - act(() => jest.advanceTimersByTime(5000)); - - expect(mockNavigate).not.toHaveBeenCalled(); - }); -}); - -describe('useHandleOptInClick', () => { - const arrange = (props = { basicFunctionalityEnabled: true }) => { - // Mock Navigation - const mockNavigate = jest.fn(); - const mockNavigation = { - navigate: mockNavigate, - } as unknown as NavigationProp; - - // Mock Metrics - const mockTrackEvent = jest.fn(); - const mockCreateEventBuilder = jest.fn().mockReturnValue({ - addProperties: jest.fn().mockReturnThis(), - build: jest.fn().mockReturnValue({}), - }); - const mockMetrics = { - trackEvent: mockTrackEvent, - createEventBuilder: mockCreateEventBuilder, - } as unknown as UseAnalyticsHook; - - const mockEnableNotifications = jest.fn().mockImplementation(jest.fn()); - - const mockSelectIsBackupAndSyncEnabled = jest.spyOn( - Selectors, - 'selectIsBackupAndSyncEnabled', - ); - - const hook = renderHookWithProvider( - () => - useHandleOptInClick({ - navigation: mockNavigation, - metrics: mockMetrics, - enableNotifications: mockEnableNotifications, - }), - { - state: { - settings: { - basicFunctionalityEnabled: props.basicFunctionalityEnabled, - }, - }, - }, - ); - - return { - hook, - mockNavigate, - mockTrackEvent, - mockCreateEventBuilder, - mockEnableNotifications, - mockSelectIsBackupAndSyncEnabled, - }; - }; - - it('navigates to Basic Functionality if not enabled', async () => { - const { hook, mockNavigate } = arrange({ - basicFunctionalityEnabled: false, - }); - - await hook.result.current(); - - expect(mockNavigate).toHaveBeenCalledWith(Routes.MODAL.ROOT_MODAL_FLOW, { - screen: Routes.SHEET.BASIC_FUNCTIONALITY, - params: { - caller: Routes.NOTIFICATIONS.OPT_IN, - }, - }); - }); - - it('enables notifications and tracks event if Basic Functionality is enabled', async () => { - const { - hook, - mockTrackEvent, - mockCreateEventBuilder, - mockEnableNotifications, - } = arrange({ basicFunctionalityEnabled: true }); - - await hook.result.current(); - - expect(mockEnableNotifications).toHaveBeenCalled(); - expect(mockTrackEvent).toHaveBeenCalledWith( - mockCreateEventBuilder(MetaMetricsEvents.NOTIFICATIONS_ACTIVATED) - .addProperties({ - action_type: 'completed', - is_profile_syncing_enabled: true, - }) - .build(), - ); - }); -}); - -describe('useHandleOptInCancel', () => { - const arrange = (props = { isCreatingNotifications: true }) => { - // Mock Navigation - const mockNavigate = jest.fn(); - const mockNavigation = { - navigate: mockNavigate, - } as unknown as NavigationProp; - - // Mock Metrics - const mockTrackEvent = jest.fn(); - const mockCreateEventBuilder = jest.fn().mockReturnValue({ - addProperties: jest.fn().mockReturnThis(), - build: jest.fn().mockReturnValue({}), - }); - const mockMetrics = { - trackEvent: mockTrackEvent, - createEventBuilder: mockCreateEventBuilder, - } as unknown as UseAnalyticsHook; - - const mockSelectIsBackupAndSyncEnabled = jest.spyOn( - Selectors, - 'selectIsBackupAndSyncEnabled', - ); - - const hook = renderHookWithProvider(() => - useHandleOptInCancel({ - navigation: mockNavigation, - metrics: mockMetrics, - isCreatingNotifications: props.isCreatingNotifications, - }), - ); - - return { - hook, - mockNavigate, - mockTrackEvent, - mockCreateEventBuilder, - mockSelectIsBackupAndSyncEnabled, - }; - }; - - it('tracks event and navigates to wallet view if not creating notifications', () => { - const { hook, mockNavigate, mockTrackEvent, mockCreateEventBuilder } = - arrange({ isCreatingNotifications: false }); - - hook.result.current(); - - expect(mockTrackEvent).toHaveBeenCalledWith( - mockCreateEventBuilder(MetaMetricsEvents.NOTIFICATIONS_ACTIVATED) - .addProperties({ - action_type: 'dismissed', - is_profile_syncing_enabled: true, - }) - .build(), - ); - expect(mockNavigate).toHaveBeenCalledWith(Routes.WALLET_VIEW); - }); - - it('only navigates to wallet view if creating notifications', () => { - const { hook, mockNavigate, mockTrackEvent } = arrange({ - isCreatingNotifications: true, - }); - - hook.result.current(); - - expect(mockTrackEvent).not.toHaveBeenCalled(); - expect(mockNavigate).toHaveBeenCalledWith(Routes.WALLET_VIEW); - }); -}); diff --git a/app/components/Views/Notifications/OptIn/OptIn.hooks.tsx b/app/components/Views/Notifications/OptIn/OptIn.hooks.tsx deleted file mode 100644 index 9a30b2c6b7e..00000000000 --- a/app/components/Views/Notifications/OptIn/OptIn.hooks.tsx +++ /dev/null @@ -1,130 +0,0 @@ -import { useCallback, useEffect, useState } from 'react'; -import { useSelector } from 'react-redux'; -import { RootState } from '../../../../reducers'; -import Routes from '../../../../constants/navigation/Routes'; -import type { UseAnalyticsHook } from '../../../hooks/useAnalytics/useAnalytics.types'; -import { MetaMetricsEvents } from '../../../../core/Analytics'; -import { selectIsBackupAndSyncEnabled } from '../../../../selectors/identity'; -import type { AppNavigationProp } from '../../../../core/NavigationService/types'; - -/** - * Creating wallet notifications can take time, so we will use optimistic loader - * to navigate to the notification list page if it takes too long - * @param props - props to determine if effect should run - */ -export function useOptimisticNavigationEffect(props: { - isCreatingNotifications: boolean; - navigation: AppNavigationProp; -}) { - const { isCreatingNotifications, navigation } = props; - const [optimisticLoading, setOptimisticLoading] = useState(false); - - useEffect(() => { - let timeOut: NodeJS.Timeout | undefined; - - if (isCreatingNotifications) { - setOptimisticLoading(true); - timeOut = setTimeout(() => { - setOptimisticLoading(false); - navigation.navigate(Routes.NOTIFICATIONS.VIEW); - }, 5000); - } else { - setOptimisticLoading(false); - if (timeOut) { - clearTimeout(timeOut); - } - } - - // Cleanup function to clear the timeout if the component unmounts or if isCreatingNotifications changes - return () => { - if (timeOut) { - clearTimeout(timeOut); - } - }; - }, [isCreatingNotifications, navigation]); - - return optimisticLoading; -} - -export function useHandleOptInClick(props: { - navigation: AppNavigationProp; - metrics: UseAnalyticsHook; - enableNotifications: () => Promise; -}) { - const { navigation, enableNotifications, metrics } = props; - const { trackEvent, createEventBuilder } = metrics; - - const basicFunctionalityEnabled = useSelector( - (state: RootState) => state.settings.basicFunctionalityEnabled, - ); - const isBackupAndSyncEnabled = useSelector(selectIsBackupAndSyncEnabled); - - const handleOptInClick = useCallback(async () => { - // Navigate to Basic Functionality if not enabled - if (!basicFunctionalityEnabled) { - navigation.navigate(Routes.MODAL.ROOT_MODAL_FLOW, { - screen: Routes.SHEET.BASIC_FUNCTIONALITY, - params: { - caller: Routes.NOTIFICATIONS.OPT_IN, - }, - }); - return; - } - - // Enable Notifications (+ push notifications) - await enableNotifications(); - - navigation.navigate(Routes.NOTIFICATIONS.VIEW); - - trackEvent( - createEventBuilder(MetaMetricsEvents.NOTIFICATIONS_ACTIVATED) - .addProperties({ - action_type: 'completed', - is_profile_syncing_enabled: isBackupAndSyncEnabled, - }) - .build(), - ); - }, [ - basicFunctionalityEnabled, - enableNotifications, - navigation, - isBackupAndSyncEnabled, - trackEvent, - createEventBuilder, - ]); - - return handleOptInClick; -} - -export function useHandleOptInCancel(props: { - navigation: AppNavigationProp; - metrics: UseAnalyticsHook; - isCreatingNotifications: boolean; -}) { - const { navigation, metrics, isCreatingNotifications } = props; - const { trackEvent, createEventBuilder } = metrics; - - const isBackupAndSyncEnabled = useSelector(selectIsBackupAndSyncEnabled); - - const handleOptInCancel = useCallback(() => { - if (!isCreatingNotifications) { - trackEvent( - createEventBuilder(MetaMetricsEvents.NOTIFICATIONS_ACTIVATED) - .addProperties({ - action_type: 'dismissed', - is_profile_syncing_enabled: isBackupAndSyncEnabled, - }) - .build(), - ); - } - navigation.navigate(Routes.WALLET_VIEW); - }, [ - createEventBuilder, - isCreatingNotifications, - isBackupAndSyncEnabled, - navigation, - trackEvent, - ]); - - return handleOptInCancel; -} diff --git a/app/components/Views/Notifications/OptIn/index.test.tsx b/app/components/Views/Notifications/OptIn/index.test.tsx deleted file mode 100644 index 7cee8a16fbe..00000000000 --- a/app/components/Views/Notifications/OptIn/index.test.tsx +++ /dev/null @@ -1,183 +0,0 @@ -import React from 'react'; -import { fireEvent, screen, act } from '@testing-library/react-native'; -import OptIn from '.'; -import { RootState } from '../../../../reducers'; -import { backgroundState } from '../../../../util/test/initial-root-state'; -import renderWithProvider, { - DeepPartial, -} from '../../../../util/test/renderWithProvider'; -import { strings } from '../../../../../locales/i18n'; -// eslint-disable-next-line import-x/no-namespace -import * as OptInHooksModule from './OptIn.hooks'; -// eslint-disable-next-line import-x/no-namespace -import * as UseNotificationsModule from '../../../../util/notifications/hooks/useNotifications'; - -const mockedDispatch = jest.fn(); - -const mockInitialState: DeepPartial = { - settings: {}, - engine: { - backgroundState: { - ...backgroundState, - NotificationServicesController: { - metamaskNotificationsList: [], - }, - }, - }, -}; - -jest.mock('react-redux', () => ({ - ...jest.requireActual('react-redux'), - useSelector: jest - .fn() - .mockImplementation((selector) => selector(mockInitialState)), -})); - -jest.mock('@react-navigation/native', () => { - const actualNav = jest.requireActual('@react-navigation/native'); - return { - ...actualNav, - useNavigation: () => ({ - navigate: jest.fn(), - dispatch: mockedDispatch, - }), - }; -}); - -jest.mock('react-native', () => ({ - Linking: { - openURL: jest.fn(), - }, -})); - -jest.mock('../../../../util/theme', () => ({ - useTheme: jest.fn(), -})); - -const arrangeMockOptInHooks = () => { - const mockCancel = jest.fn(); - const mockUseHandleOptInCancel = jest - .spyOn(OptInHooksModule, 'useHandleOptInCancel') - .mockReturnValue(mockCancel); - - const mockClick = jest.fn(); - const mockUseHadleOptInClick = jest - .spyOn(OptInHooksModule, 'useHandleOptInClick') - .mockReturnValue(mockClick); - - const mockUseOptimisticNavigationEffect = jest - .spyOn(OptInHooksModule, 'useOptimisticNavigationEffect') - .mockReturnValue(false); - - const mockUseEnableNotificationReturnVal = { - data: false, - enableNotifications: jest.fn(), - error: null, - isEnablingNotifications: false, - isEnablingPushNotifications: false, - loading: false, - }; - const mockUseEnableNotifications = jest - .spyOn(UseNotificationsModule, 'useEnableNotifications') - .mockReturnValue(mockUseEnableNotificationReturnVal); - - return { - mockCancel, - mockUseHandleOptInCancel, - mockClick, - mockUseHadleOptInClick, - mockUseOptimisticNavigationEffect, - mockUseEnableNotifications, - mockUseEnableNotificationReturnVal, - }; -}; - -describe('OptIn', () => { - beforeEach(() => { - jest.clearAllMocks(); - }); - - it('should render with the expected fields', () => { - arrangeMockOptInHooks(); - const { getByText } = renderWithProvider(); - - // Title - expect( - getByText(strings('notifications.activation_card.title')), - ).toBeTruthy(); - - // Main description - expect( - getByText(strings('notifications.activation_card.description_1')), - ).toBeTruthy(); - - // Secondary description - expect( - getByText(strings('notifications.activation_card.description_2'), { - exact: false, - }), - ).toBeTruthy(); - expect( - getByText(strings('notifications.activation_card.learn_more'), { - exact: false, - }), - ).toBeTruthy(); - - // Preference/Settings information - expect( - getByText(strings('notifications.activation_card.manage_preferences_1'), { - exact: false, - }), - ).toBeTruthy(); - expect( - getByText(strings('notifications.activation_card.manage_preferences_2'), { - exact: false, - }), - ).toBeTruthy(); - - // Buttons - expect( - getByText(strings('notifications.activation_card.cancel')), - ).toBeTruthy(); - expect( - getByText(strings('notifications.activation_card.cta')), - ).toBeTruthy(); - }); - - it('calls enableNotifications when the button is pressed', () => { - const mocks = arrangeMockOptInHooks(); - const { getByText } = renderWithProvider(); - - const button = getByText(strings('notifications.activation_card.cta')); - expect(button).toBeTruthy(); - act(() => fireEvent.press(button)); - - expect(mocks.mockClick).toHaveBeenCalled(); - }); - - it('calls navigate when the cancel button is pressed', () => { - const mocks = arrangeMockOptInHooks(); - const { getByText } = renderWithProvider(); - - const button = getByText(strings('notifications.activation_card.cancel')); - expect(button).toBeTruthy(); - act(() => fireEvent.press(button)); - - expect(mocks.mockCancel).toHaveBeenCalled(); - }); - - it('shows loading modal while enabling notifications', () => { - const mocks = arrangeMockOptInHooks(); - mocks.mockUseEnableNotifications.mockReturnValue({ - ...mocks.mockUseEnableNotificationReturnVal, - isEnablingNotifications: true, - loading: true, - }); - renderWithProvider(); - - const loader = screen.getByText( - strings('app_settings.enabling_notifications'), - ); - expect(loader).toBeTruthy(); - }); -}); diff --git a/app/components/Views/Notifications/OptIn/index.tsx b/app/components/Views/Notifications/OptIn/index.tsx deleted file mode 100644 index 0a27b8efd51..00000000000 --- a/app/components/Views/Notifications/OptIn/index.tsx +++ /dev/null @@ -1,126 +0,0 @@ -import React, { Fragment } from 'react'; -import { Image, View, Linking, ScrollView } from 'react-native'; -import { useNavigation } from '@react-navigation/native'; - -import { useAnalytics } from '../../../hooks/useAnalytics/useAnalytics'; -import { Button, ButtonVariant } from '@metamask/design-system-react-native'; -import { strings } from '../../../../../locales/i18n'; -import Text, { - TextColor, - TextVariant, -} from '../../../../component-library/components/Texts/Text'; -import { useTheme } from '../../../../util/theme'; -import EnableNotificationsCardPlaceholder from '../../../../images/enableNotificationsCard.png'; -import { createStyles } from './styles'; -import AppConstants from '../../../../core/AppConstants'; -import { useEnableNotifications } from '../../../../util/notifications/hooks/useNotifications'; -import SwitchLoadingModal from '../../../../components/UI/Notification/SwitchLoadingModal'; -import { useHandleOptInCancel, useHandleOptInClick } from './OptIn.hooks'; -import { EnableNotificationModalSelectorsIDs } from './EnableNotificationModal.testIds'; - -const OptIn = () => { - const metrics = useAnalytics(); - const theme = useTheme(); - const styles = createStyles(theme); - const navigation = useNavigation(); - - const { enableNotifications, loading } = useEnableNotifications({ - nudgeEnablePush: true, - }); - - const handleOptInCancel = useHandleOptInCancel({ - navigation, - metrics, - isCreatingNotifications: loading, - }); - - const handleOptInClick = useHandleOptInClick({ - navigation, - metrics, - enableNotifications, - }); - - const goToLearnMore = () => { - Linking.openURL(AppConstants.URLS.PROFILE_SYNC); - }; - - return ( - - - - {strings('notifications.activation_card.title')} - - - - - - - {strings('notifications.activation_card.description_1')} - - - - {strings('notifications.activation_card.description_2')}{' '} - - {strings('notifications.activation_card.learn_more')} - - - - - {strings('notifications.activation_card.manage_preferences_1')} - - {strings('notifications.activation_card.manage_preferences_2')} - - - - - - - - - - - - ); -}; - -export default OptIn; diff --git a/app/components/Views/Notifications/OptIn/styles.ts b/app/components/Views/Notifications/OptIn/styles.ts deleted file mode 100644 index dce2cb6894a..00000000000 --- a/app/components/Views/Notifications/OptIn/styles.ts +++ /dev/null @@ -1,49 +0,0 @@ -/* eslint-disable import-x/prefer-default-export */ -import { StyleSheet } from 'react-native'; -import type { Theme } from '@metamask/design-tokens'; -import Device from '../../../../util/device'; -import scaling from '../../../../util/scaling'; - -const HEIGHT = scaling.scale(240); - -export const createStyles = ({ colors }: Theme) => - StyleSheet.create({ - wrapper: { - flex: 1, - alignItems: 'flex-start', - backgroundColor: colors.background.default, - paddingTop: 60, - paddingHorizontal: 16, - }, - card: { - height: HEIGHT, - width: Device.getDeviceWidth() - 32, - alignSelf: 'center', - borderRadius: 12, - overflow: 'hidden', - marginBottom: 16, - }, - image: { - resizeMode: 'cover', - height: HEIGHT, - width: Device.getDeviceWidth() - 32, - }, - btnContainer: { - flexDirection: 'row', - justifyContent: 'space-between', - alignSelf: 'center', - marginBottom: 16, - }, - ctaBtn: { - margin: 4, - width: '48%', - alignSelf: 'center', - }, - textSpace: { - marginBottom: 16, - }, - textTitle: { - marginBottom: 16, - alignSelf: 'center', - }, - }); diff --git a/app/components/Views/Notifications/index.test.tsx b/app/components/Views/Notifications/index.test.tsx index 1d3d8647ec9..edf095cb327 100644 --- a/app/components/Views/Notifications/index.test.tsx +++ b/app/components/Views/Notifications/index.test.tsx @@ -58,6 +58,18 @@ const mockInitialState: DeepPartial = { }, }; +const mockNotificationsDisabledState: DeepPartial = { + engine: { + backgroundState: { + ...backgroundState, + NotificationServicesController: { + isNotificationServicesEnabled: false, + metamaskNotificationsList: [], + }, + }, + }, +}; + describe('NotificationsView - header', () => { beforeEach(() => { jest.clearAllMocks(); @@ -116,6 +128,10 @@ describe('NotificationsView - header', () => { }); describe('NotificationsView - content', () => { + beforeEach(() => { + jest.clearAllMocks(); + }); + it('shows empty container when no notifications are available', () => { const { getByTestId } = renderWithProvider( , @@ -125,6 +141,33 @@ describe('NotificationsView - content', () => { getByTestId(NotificationsViewSelectorsIDs.NO_NOTIFICATIONS_CONTAINER), ).toBeOnTheScreen(); }); + + it('shows enable prompt and opens settings when notifications are disabled', () => { + const { getByText, getByTestId } = renderWithProvider( + , + { state: mockNotificationsDisabledState }, + ); + + expect( + getByTestId( + NotificationsViewSelectorsIDs.DISABLED_NOTIFICATIONS_CONTAINER, + ), + ).toBeOnTheScreen(); + expect( + getByText(strings('notifications.disabled.title')), + ).toBeOnTheScreen(); + expect( + getByText(strings('notifications.disabled.message')), + ).toBeOnTheScreen(); + + fireEvent.press( + getByTestId(NotificationsViewSelectorsIDs.ENABLE_NOTIFICATIONS_BUTTON), + ); + + expect(navigationMock.navigate).toHaveBeenCalledWith( + Routes.SETTINGS.NOTIFICATIONS, + ); + }); }); describe('useMarkAsReadCallback', () => { diff --git a/app/components/Views/Notifications/index.tsx b/app/components/Views/Notifications/index.tsx index fd20b77ab03..f59ae1330aa 100644 --- a/app/components/Views/Notifications/index.tsx +++ b/app/components/Views/Notifications/index.tsx @@ -19,7 +19,7 @@ import { IconName, } from '@metamask/design-system-react-native'; -import Empty from '../../UI/Notification/Empty'; +import DisabledNotifications from './DisabledNotifications'; import { strings } from '../../../../locales/i18n'; import Routes from '../../../constants/navigation/Routes'; import { @@ -161,9 +161,7 @@ const NotificationsView = ({ )} ) : ( - + )} diff --git a/app/components/Views/Settings/NotificationsSettings/NotificationsSettings.view.test.tsx b/app/components/Views/Settings/NotificationsSettings/NotificationsSettings.view.test.tsx index b1a070ae0a5..8d9b361b851 100644 --- a/app/components/Views/Settings/NotificationsSettings/NotificationsSettings.view.test.tsx +++ b/app/components/Views/Settings/NotificationsSettings/NotificationsSettings.view.test.tsx @@ -36,9 +36,7 @@ const MOCK_NOTIFICATION_PREFERENCES = { }; /** - * Component-view coverage for smoke `notification-settings-flow`. - * - * Smoke spec: tests/smoke/notifications/notification-settings-flow.spec.ts + * Component-view coverage for notification settings toggles and section visibility. * * AUS-backed notification preferences are provided through Engine, matching * the component-view boundary for data-service calls. diff --git a/app/components/Views/TradeWalletActions/TradeWalletActions.tsx b/app/components/Views/TradeWalletActions/TradeWalletActions.tsx index 61815cad5ff..ce16e3d15e0 100644 --- a/app/components/Views/TradeWalletActions/TradeWalletActions.tsx +++ b/app/components/Views/TradeWalletActions/TradeWalletActions.tsx @@ -28,6 +28,7 @@ import { TextVariant, } from '@metamask/design-system-react-native'; import { useTailwind } from '@metamask/design-system-twrnc-preset'; +import { useElevatedSurface } from '../../../util/theme/themeUtils'; import { useSafeAreaFrame, useSafeAreaInsets, @@ -96,6 +97,7 @@ function TradeWalletActions() { const insetsTop = Platform.OS === 'android' ? insets.top : 0; const tw = useTailwind(); + const surfaceClass = useElevatedSurface(); const chainId = useSelector(selectChainId); const isSwapsEnabled = useSelector((state: RootState) => selectIsSwapsEnabled(state), @@ -291,7 +293,7 @@ function TradeWalletActions() { > )} {AppConstants.SWAPS.ACTIVE && ( @@ -333,6 +336,7 @@ function TradeWalletActions() { onPress={goToSwaps} testID={WalletActionsBottomSheetSelectorsIDs.SWAP_BUTTON} isDisabled={!isSwapsEnabled} + style={tw.style('bg-transparent')} /> )} {isPerpsEnabled && ( @@ -343,6 +347,7 @@ function TradeWalletActions() { onPress={onPerps} testID={WalletActionsBottomSheetSelectorsIDs.PERPS_BUTTON} isDisabled={!canSignTransactions} + style={tw.style('bg-transparent')} /> )} {isPredictEnabled && ( @@ -353,6 +358,7 @@ function TradeWalletActions() { onPress={onPredict} testID={WalletActionsBottomSheetSelectorsIDs.PREDICT_BUTTON} isDisabled={!canSignTransactions} + style={tw.style('bg-transparent')} /> )} {isEarnWalletActionEnabled && isEarnEligible && ( @@ -363,6 +369,7 @@ function TradeWalletActions() { onPress={onEarn} testID={WalletActionsBottomSheetSelectorsIDs.EARN_BUTTON} isDisabled={!canSignTransactions} + style={tw.style('bg-transparent')} /> )} diff --git a/app/constants/navigation/Routes.ts b/app/constants/navigation/Routes.ts index aab76ecfc84..397b9057933 100644 --- a/app/constants/navigation/Routes.ts +++ b/app/constants/navigation/Routes.ts @@ -402,8 +402,6 @@ const Routes = { CONFIRMATION_PAY_WITH_NETWORK_MODAL: 'ConfirmationPayWithNetworkModal', NOTIFICATIONS: { VIEW: 'NotificationsView', - OPT_IN: 'OptIn', - OPT_IN_STACK: 'OptInStack', DETAILS: 'NotificationsDetails', }, STAKING: { @@ -436,6 +434,7 @@ const Routes = { }, MONEY: { ROOT: 'MoneyScreens', + CONFIRMATIONS_ROOT: 'MoneyConfirmations', HOME: 'MoneyHome', ACTIVITY: 'MoneyActivity', HOW_IT_WORKS: 'MoneyHowItWorks', diff --git a/app/core/NavigationService/types.ts b/app/core/NavigationService/types.ts index fb471a309e6..b8fb9dd8e71 100644 --- a/app/core/NavigationService/types.ts +++ b/app/core/NavigationService/types.ts @@ -632,8 +632,6 @@ export interface RootStackParamList extends ParamListBase { // Notification routes NotificationsView: undefined; - OptIn: undefined; - OptInStack: undefined; NotificationsDetails: NotificationDetailsParams | undefined; // Staking routes diff --git a/app/core/SDKConnectV2/services/connection-registry.test.ts b/app/core/SDKConnectV2/services/connection-registry.test.ts index 3e95f9264cb..1698ea78750 100644 --- a/app/core/SDKConnectV2/services/connection-registry.test.ts +++ b/app/core/SDKConnectV2/services/connection-registry.test.ts @@ -10,6 +10,7 @@ import Engine from '../../Engine'; import { analytics } from '../../../util/analytics/analytics'; import { MetaMetricsEvents } from '../../Analytics'; import { TransportType } from '../../../components/hooks/useAnalytics/useAnalytics.types'; +import Logger from '../../../util/Logger'; jest.mock('../adapters/host-application-adapter'); jest.mock('../store/connection-store'); @@ -23,6 +24,13 @@ jest.mock('../../../util/analytics/analytics', () => ({ trackEvent: jest.fn(), }, })); +jest.mock('../../../util/Logger', () => ({ + __esModule: true, + default: { + error: jest.fn(), + log: jest.fn(), + }, +})); jest.mock('../../../store', () => ({ store: { dispatch: jest.fn(), @@ -33,6 +41,7 @@ jest.mock('../../../store', () => ({ })); const mockTrackEvent = analytics.trackEvent as jest.Mock; +const mockLoggerError = Logger.error as jest.Mock; // Factory functions for creating mock objects // eslint-disable-next-line @typescript-eslint/no-explicit-any @@ -267,6 +276,40 @@ describe('ConnectionRegistry', () => { 'Invalid MWP deeplink: [invalid URL]', ); }); + + it('should report dispatch failures to Sentry via Logger.error', async () => { + registry = new ConnectionRegistry( + RELAY_URL, + mockKeyManager, + mockHostApp, + mockStore, + ); + + const dispatchError = new Error('boom'); + const spyHandleConnectDeeplink = jest + .spyOn(registry, 'handleConnectDeeplink') + .mockRejectedValue(dispatchError); + + await registry.handleMwpDeeplink(validDeeplink); + + expect(mockLoggerError).toHaveBeenCalledWith( + dispatchError, + expect.objectContaining({ + tags: expect.objectContaining({ + feature: 'mm-connect', + operation: 'handle_mwp_deeplink', + }), + context: expect.objectContaining({ + name: 'mwp_deeplink', + data: expect.objectContaining({ + url: expect.stringContaining('[REDACTED]'), + }), + }), + }), + ); + + spyHandleConnectDeeplink.mockRestore(); + }); }); describe('handleSimpleDeeplink', () => { @@ -969,6 +1012,73 @@ describe('ConnectionRegistry', () => { expect(Connection.create).not.toHaveBeenCalled(); expect(mockStore.save).not.toHaveBeenCalled(); }); + + it('should report connect failures to Sentry with dapp/sdk context', async () => { + registry = new ConnectionRegistry( + RELAY_URL, + mockKeyManager, + mockHostApp, + mockStore, + ); + + const connectionError = new Error('Connection failed'); + mockConnection.connect.mockRejectedValue(connectionError); + + await registry.handleConnectDeeplink(validDeeplink); + + expect(mockLoggerError).toHaveBeenCalledWith( + connectionError, + expect.objectContaining({ + tags: expect.objectContaining({ + feature: 'mm-connect', + operation: 'handle_connect_deeplink', + }), + context: expect.objectContaining({ + name: 'mwp_deeplink', + data: expect.objectContaining({ + url: expect.stringContaining('[REDACTED]'), + dapp_url: 'https://test.dapp', + dapp_name: 'Test DApp', + sdk_version: '2.0.0', + sdk_platform: 'JavaScript', + }), + }), + }), + ); + }); + + it('should report parse failures to Sentry even when no connection request is available', async () => { + registry = new ConnectionRegistry( + RELAY_URL, + mockKeyManager, + mockHostApp, + mockStore, + ); + + const invalidDeeplink = 'metamask://connect/mwp?p=not-json'; + + await registry.handleConnectDeeplink(invalidDeeplink); + + expect(mockLoggerError).toHaveBeenCalledWith( + expect.any(Error), + expect.objectContaining({ + tags: expect.objectContaining({ + feature: 'mm-connect', + operation: 'handle_connect_deeplink', + }), + context: expect.objectContaining({ + name: 'mwp_deeplink', + data: expect.objectContaining({ + url: expect.stringContaining('[REDACTED]'), + dapp_url: undefined, + dapp_name: undefined, + sdk_version: undefined, + sdk_platform: undefined, + }), + }), + }), + ); + }); }); describe('disconnect', () => { diff --git a/app/core/SDKConnectV2/services/connection-registry.ts b/app/core/SDKConnectV2/services/connection-registry.ts index 704cb747fd3..66b3cfd6f70 100644 --- a/app/core/SDKConnectV2/services/connection-registry.ts +++ b/app/core/SDKConnectV2/services/connection-registry.ts @@ -18,6 +18,7 @@ import { whenStoreReady } from '../utils/when-store-ready'; import Engine from '../../Engine'; import { rpcErrors } from '@metamask/rpc-errors'; import { INTERNAL_ORIGINS } from '../../../constants/transaction'; +import Logger from '../../../util/Logger'; import { analytics } from '../../../util/analytics/analytics'; import { AnalyticsEventBuilder } from '../../../util/analytics/AnalyticsEventBuilder'; import type { IMetaMetricsEvent } from '../../Analytics/MetaMetrics.types'; @@ -168,6 +169,28 @@ export class ConnectionRegistry { await this.handleConnectDeeplink(url); } } catch (error) { + // Report to Sentry so we have visibility into deeplink dispatch failures. + // The local logger.error below is dev-only console output and never + // reaches Sentry on its own. + // + // NOTE: the `feature` tag is intentionally `mm-connect` even though + // this file lives under `SDKConnectV2/`. The product name has + // converged on "MetaMask Connect" (MMC); the internal directory, + // class, and logger names (`SDKConnectV2`, `ConnectionRegistry`, + // `[SDKConnectV2]` log prefix) still use the older nomenclature + // and need to migrate. Tagging Sentry with the public-facing + // feature name now avoids having to rename Sentry dashboards/ + // alerts later when the code catches up. + Logger.error(error as Error, { + tags: { + feature: 'mm-connect', + operation: 'handle_mwp_deeplink', + }, + context: { + name: 'mwp_deeplink', + data: { url: redactUrl(url) }, + }, + }); logger.error('Failed to handle MWP deeplink:', error); } } @@ -296,6 +319,30 @@ export class ConnectionRegistry { logger.debug('Handled connect deeplink.', connInfo?.id); } catch (error) { + // Report to Sentry so we have visibility into connect-deeplink + // failures. The local logger.error below is dev-only console output + // and never reaches Sentry on its own. + // + // NOTE: `feature: 'mm-connect'` is intentional — see the matching + // comment in handleMwpDeeplink above for why the tag uses the + // public-facing product name even though this directory is named + // `SDKConnectV2/`. + Logger.error(error as Error, { + tags: { + feature: 'mm-connect', + operation: 'handle_connect_deeplink', + }, + context: { + name: 'mwp_deeplink', + data: { + url: redactUrl(url), + dapp_url: connReq?.metadata?.dapp?.url, + dapp_name: connReq?.metadata?.dapp?.name, + sdk_version: connReq?.metadata?.sdk?.version, + sdk_platform: connReq?.metadata?.sdk?.platform, + }, + }, + }); logger.error('Failed to handle connect deeplink:', error, redactUrl(url)); this.hostapp.showConnectionError(); didConnectionFail = true; diff --git a/app/images/money-onboarding-stepper-step-1.png b/app/images/money-onboarding-stepper-step-1.png new file mode 100644 index 00000000000..f600b3edba1 Binary files /dev/null and b/app/images/money-onboarding-stepper-step-1.png differ diff --git a/app/images/money-onboarding-stepper-step-2.png b/app/images/money-onboarding-stepper-step-2.png new file mode 100644 index 00000000000..a3a4b36dbff Binary files /dev/null and b/app/images/money-onboarding-stepper-step-2.png differ diff --git a/app/reducers/user/index.test.ts b/app/reducers/user/index.test.ts index 8dca060d4da..69275c54f7f 100644 --- a/app/reducers/user/index.test.ts +++ b/app/reducers/user/index.test.ts @@ -3,6 +3,7 @@ import { UserActionType, type SetTokenOverviewChartTypeAction, type SetMoneyOnboardingSeenAction, + type SetOnboardingStepperStepAction, } from '../../actions/user/types'; import { ChartType } from '../../components/UI/Charts/AdvancedChart/AdvancedChart.types'; @@ -15,6 +16,10 @@ describe('user reducer', () => { it('has moneyOnboardingSeen as false', () => { expect(userInitialState.moneyOnboardingSeen).toBe(false); }); + + it('has onboardingStepperProgress as empty object', () => { + expect(userInitialState.onboardingStepperProgress).toEqual({}); + }); }); describe('SET_MONEY_ONBOARDING_SEEN', () => { @@ -61,6 +66,65 @@ describe('user reducer', () => { }); }); + describe('SET_ONBOARDING_STEPPER_STEP', () => { + it('sets step for a new stepperId', () => { + const action: SetOnboardingStepperStepAction = { + type: UserActionType.SET_ONBOARDING_STEPPER_STEP, + payload: { stepperId: 'money', step: 1 }, + }; + + const newState = userReducer(userInitialState, action); + + expect(newState.onboardingStepperProgress).toEqual({ money: 1 }); + }); + + it('updates step for an existing stepperId', () => { + const currentState = { + ...userInitialState, + onboardingStepperProgress: { money: 0 }, + }; + const action: SetOnboardingStepperStepAction = { + type: UserActionType.SET_ONBOARDING_STEPPER_STEP, + payload: { stepperId: 'money', step: 2 }, + }; + + const newState = userReducer(currentState, action); + + expect(newState.onboardingStepperProgress.money).toBe(2); + }); + + it('merges a new stepperId without overwriting existing ones', () => { + const currentState = { + ...userInitialState, + onboardingStepperProgress: { money: 1 }, + }; + const action: SetOnboardingStepperStepAction = { + type: UserActionType.SET_ONBOARDING_STEPPER_STEP, + payload: { stepperId: 'earn', step: 3 }, + }; + + const newState = userReducer(currentState, action); + + expect(newState.onboardingStepperProgress).toEqual({ money: 1, earn: 3 }); + }); + + it('does not modify other state properties', () => { + const currentState = { + ...userInitialState, + userLoggedIn: true, + }; + const action: SetOnboardingStepperStepAction = { + type: UserActionType.SET_ONBOARDING_STEPPER_STEP, + payload: { stepperId: 'money', step: 1 }, + }; + + const newState = userReducer(currentState, action); + + expect(newState.userLoggedIn).toBe(true); + expect(newState.onboardingStepperProgress.money).toBe(1); + }); + }); + describe('SET_TOKEN_OVERVIEW_CHART_TYPE', () => { it('updates tokenOverviewChartType to Candles', () => { const action: SetTokenOverviewChartTypeAction = { diff --git a/app/reducers/user/index.ts b/app/reducers/user/index.ts index 0feeb6dfc1c..d4af0775d30 100644 --- a/app/reducers/user/index.ts +++ b/app/reducers/user/index.ts @@ -31,6 +31,7 @@ export const userInitialState: UserState = { musdConversionAssetDetailCtasSeen: {}, moneyOnboardingSeen: false, tokenOverviewChartType: ChartType.Line, + onboardingStepperProgress: {}, }; /** @@ -166,6 +167,14 @@ const userReducer = ( ...state, tokenOverviewChartType: action.payload.chartType, }; + case UserActionType.SET_ONBOARDING_STEPPER_STEP: + return { + ...state, + onboardingStepperProgress: { + ...state.onboardingStepperProgress, + [action.payload.stepperId]: action.payload.step, + }, + }; default: return state; } diff --git a/app/reducers/user/selectors.test.ts b/app/reducers/user/selectors.test.ts index b82b95b0768..15b201aee4d 100644 --- a/app/reducers/user/selectors.test.ts +++ b/app/reducers/user/selectors.test.ts @@ -10,6 +10,7 @@ import { selectMusdConversionAssetDetailCtasSeen, selectMoneyOnboardingSeen, selectTokenOverviewChartType, + selectOnboardingStepperProgress, } from './selectors'; import { ChartType } from '../../components/UI/Charts/AdvancedChart/AdvancedChart.types'; @@ -23,6 +24,7 @@ const mockState = { musdConversionAssetDetailCtasSeen: {} as Record, moneyOnboardingSeen: false, tokenOverviewChartType: ChartType.Line as ChartType, + onboardingStepperProgress: {} as Record, }, }; @@ -189,4 +191,27 @@ describe('user state selectors', () => { expect(result.current).toBe(ChartType.Line); }); }); + + describe('selectOnboardingStepperProgress', () => { + it('returns empty object when onboardingStepperProgress is not set', () => { + // @ts-expect-error - Testing undefined state + mockState.user.onboardingStepperProgress = undefined; + + const { result } = renderHook(() => + useSelector(selectOnboardingStepperProgress), + ); + + expect(result.current).toEqual({}); + }); + + it('returns the stored progress record when populated', () => { + mockState.user.onboardingStepperProgress = { money: 1, earn: 2 }; + + const { result } = renderHook(() => + useSelector(selectOnboardingStepperProgress), + ); + + expect(result.current).toEqual({ money: 1, earn: 2 }); + }); + }); }); diff --git a/app/reducers/user/selectors.ts b/app/reducers/user/selectors.ts index 5413a933edf..cbb906a40c1 100644 --- a/app/reducers/user/selectors.ts +++ b/app/reducers/user/selectors.ts @@ -68,3 +68,9 @@ export const selectMoneyOnboardingSeen = (state: RootState) => */ export const selectTokenOverviewChartType = (state: RootState) => state.user?.tokenOverviewChartType ?? ChartType.Line; + +/** + * Selects the onboarding stepper progress record (keyed by stepper ID) + */ +export const selectOnboardingStepperProgress = (state: RootState) => + state.user?.onboardingStepperProgress ?? {}; diff --git a/app/reducers/user/types.ts b/app/reducers/user/types.ts index ed907e53a1e..02e2a2da16f 100644 --- a/app/reducers/user/types.ts +++ b/app/reducers/user/types.ts @@ -25,4 +25,5 @@ export interface UserState { musdConversionAssetDetailCtasSeen: Record; moneyOnboardingSeen: boolean; tokenOverviewChartType: ChartType; + onboardingStepperProgress: Record; } diff --git a/app/util/theme/themeUtils.ts b/app/util/theme/themeUtils.ts new file mode 100644 index 00000000000..140c5ee85d2 --- /dev/null +++ b/app/util/theme/themeUtils.ts @@ -0,0 +1,20 @@ +import { useTheme } from './index'; +import { AppThemeKey, Theme } from './models'; + +// When pure black is off, bg-section is the standard elevated surface color for +// both light and dark. When pure black is on, bg-default is overridden to +// #000000 so light mode still uses bg-default while dark mode uses bg-section. +export const isPureBlackEnabled = process.env.MM_PURE_BLACK_PREVIEW === 'true'; + +export const getElevatedSurfaceColor = (theme: Theme): string => { + if (!isPureBlackEnabled) return theme.colors.background.default; + return theme.themeAppearance === AppThemeKey.dark + ? theme.colors.background.section + : theme.colors.background.default; +}; + +export const useElevatedSurface = () => { + const { themeAppearance } = useTheme(); + if (!isPureBlackEnabled) return 'bg-default'; + return themeAppearance === AppThemeKey.dark ? 'bg-section' : 'bg-default'; +}; diff --git a/ios/MetaMask.xcodeproj/project.pbxproj b/ios/MetaMask.xcodeproj/project.pbxproj index 2969c332135..a85c57606f0 100644 --- a/ios/MetaMask.xcodeproj/project.pbxproj +++ b/ios/MetaMask.xcodeproj/project.pbxproj @@ -1028,7 +1028,7 @@ "${inherited}", ); LLVM_LTO = YES; - MARKETING_VERSION = 7.79.0; + MARKETING_VERSION = 7.80.0; ONLY_ACTIVE_ARCH = YES; OTHER_CFLAGS = "$(inherited)"; OTHER_LDFLAGS = ( @@ -1094,7 +1094,7 @@ "${inherited}", ); LLVM_LTO = YES; - MARKETING_VERSION = 7.79.0; + MARKETING_VERSION = 7.80.0; ONLY_ACTIVE_ARCH = NO; OTHER_CFLAGS = "$(inherited)"; OTHER_LDFLAGS = ( @@ -1163,7 +1163,7 @@ "\"$(SRCROOT)/MetaMask/System/Library/Frameworks\"", ); LLVM_LTO = YES; - MARKETING_VERSION = 7.79.0; + MARKETING_VERSION = 7.80.0; ONLY_ACTIVE_ARCH = YES; OTHER_CFLAGS = "$(inherited)"; OTHER_LDFLAGS = ( @@ -1227,7 +1227,7 @@ "\"$(SRCROOT)/MetaMask/System/Library/Frameworks\"", ); LLVM_LTO = YES; - MARKETING_VERSION = 7.79.0; + MARKETING_VERSION = 7.80.0; ONLY_ACTIVE_ARCH = NO; OTHER_CFLAGS = "$(inherited)"; OTHER_LDFLAGS = ( diff --git a/locales/languages/de.json b/locales/languages/de.json index e4a04b2fce2..82ced6ad637 100644 --- a/locales/languages/de.json +++ b/locales/languages/de.json @@ -120,6 +120,10 @@ "account_no_funds": { "message": "Keine Geldmittel verfügbar. Verwenden Sie ein anderes Konto." }, + "headless_buy_error": { + "title": "Fiat-Kauf fehlgeschlagen", + "message": "Bei Ihrem Fiat-Kauf ist etwas schiefgelaufen. Bitte versuchen Sie es erneut." + }, "mmpay_hardware_account": { "title": "Wallet wird nicht unterstützt", "message": "Hardware-Wallets werden nicht unterstützt.\nWechseln Sie die Wallets, um fortzufahren." @@ -133,8 +137,8 @@ "message": "Die Empfängeradresse unterstützt womöglich keine direkten Token-Übertragungen, was zu Geldverlusten führen kann. Fahren Sie nur fort, wenn Sie sicher sind, dass dieser Contract Ihre Übertragung empfangen kann." }, "gas_sponsorship_reserve_balance": { - "message": "Gas-Sponsoring ist für diese Transaktion nicht verfügbar. Sie benötigen mindestens %{minBalance} %{nativeTokenSymbol} auf Ihrem Konto.", - "title": "Gas-Sponsoring nicht verfügbar" + "message": "Dieses spezifische Netzwerk erfordert, dass Sie eine Reserve von %{minBalance} %{nativeTokenSymbol} auf Ihrem Konto aufrechterhalten.", + "title": "Reservesaldo ist erforderlich" }, "token_trust_signal": { "malicious": { @@ -708,6 +712,9 @@ "contractAddressError": "Sie senden Tokens an die Kontraktadresse des Tokens. Dies kann zum Verlust dieser Tokens führen.", "smart_contract_address": "Smart-Contract-Adresse", "smart_contract_address_warning": "Die Empfängeradresse unterstützt womöglich keine direkten Token-Übertragungen, was zu Geldverlusten führen kann. Fahren Sie nur fort, wenn Sie sicher sind, dass dieser Contract Ihre Übertragung empfangen kann.", + "unavailable_network_connection": "Unavailable network connection", + "unavailable_network_connection_description": "The connection with {{network}} is unreliable. Update network connectivity details before continuing or try again later.", + "update": "Update", "i_understand": "Ich verstehe", "cancel": "Stornieren", "new_address_title": "Neue Adresse", @@ -1068,7 +1075,7 @@ "sort": { "value": "Wert", "pnl_percent": "GuV %", - "recent": "Recent" + "recent": "Aktuell" } }, "trader_position": { @@ -1120,6 +1127,11 @@ "title": "Handeln Sie {{symbol}}-Perp", "subtitle": "Vervielfachen Sie Ihre GuV bis zu {{leverage}}" }, + "service_interruption": { + "title": "We're experiencing an outage", + "description": "Some services may be unavailable while the team works on a fix.", + "contact_support": "Support kontaktieren" + }, "today": "Heute", "yesterday": "Gestern", "unrealized_pnl": "Nicht realisierte GuV", @@ -1284,7 +1296,9 @@ "toast_completed_subtitle": "{{amount}} USDC wurden Ihre Wallet hinzugefügt", "toast_completed_any_token_subtitle": "{{amount}} {{token}} wurde Ihrer Wallet hinzugefügt", "toast_error_title": "Hoppla! Etwas ist schiefgelaufen ...", - "toast_error_description": "Fortfahren mit Auszahlung fehlgeschlagen" + "toast_error_description": "Fortfahren mit Auszahlung fehlgeschlagen", + "toast_start_error_description": "Your withdrawal wasn’t started.", + "try_again": "Erneut versuchen" }, "quote": { "network_fee": "Netzwerk-Gebühr", @@ -2227,35 +2241,35 @@ "predict": { "title": "MetaMask Predictions", "world_cup": { - "title": "World Cup", - "banner_title": "World Cup 2026", - "banner_description": "Trade on World Cup markets", + "title": "Weltmeisterschaft", + "banner_title": "Weltmeisterschaft 2026", + "banner_description": "Trade every match, every moment.", "tabs": { - "all": "All", + "all": "Alle", "props": "Props", "live": "Live" }, "stages": { - "group_stage": "Group Stage", - "round_of_32": "Round of 32", - "round_of_16": "Round of 16", - "quarterfinals": "Quarterfinals", - "semifinals": "Semifinals", - "third_place": "Third Place", - "final": "Final", - "group_a": "Group A", - "group_b": "Group B", - "group_c": "Group C", - "group_d": "Group D", - "group_e": "Group E", - "group_f": "Group F", - "group_g": "Group G", - "group_h": "Group H", - "group_i": "Group I", - "group_j": "Group J", - "group_k": "Group K", - "group_l": "Group L", - "third_place_match": "Third Place Match" + "group_stage": "Gruppenphase", + "round_of_32": "Sechzehntelfinale", + "round_of_16": "Achtelfinale", + "quarterfinals": "Viertelfinale", + "semifinals": "Halbfinale", + "third_place": "Dritter Platz", + "final": "Finale", + "group_a": "Gruppe A", + "group_b": "Gruppe B", + "group_c": "Gruppe C", + "group_d": "Gruppe D", + "group_e": "Gruppe E", + "group_f": "Gruppe F", + "group_g": "Gruppe G", + "group_h": "Gruppe H", + "group_i": "Gruppe I", + "group_j": "Gruppe J", + "group_k": "Gruppe K", + "group_l": "Gruppe L", + "third_place_match": "Spiel um Platz Drei" } }, "prediction_markets": "Prognosemärkte", @@ -2537,8 +2551,8 @@ "withdraw_completed": "Auszahlung abgeschlossen", "withdraw_completed_subtitle": "{{amount}} USDC wurden Ihre Wallet hinzugefügt", "withdraw_any_token_completed_subtitle": "{{amount}} {{token}} wurde Ihrer Wallet hinzugefügt", - "unavailable_title": "Withdrawals temporarily unavailable", - "unavailable_description": "For urgent assistance, please contact Customer Service.", + "unavailable_title": "Auszahlungen vorübergehend nicht verfügbar", + "unavailable_description": "Für dringende Unterstützung wenden Sie sich bitte an den Kundendienst.", "unavailable_got_it": "Verstanden", "error_title": "Hoppla! Etwas ist schiefgelaufen ...", "error_description": "Fortfahren mit Auszahlung fehlgeschlagen", @@ -2941,6 +2955,17 @@ "pna25_confirm_button": "Akzeptieren und schließen", "pna25_open_settings_button": "Einstellungen öffnen" }, + "onboarding_interest_questionnaire": { + "title": "Was möchten Sie mit MetaMask tun?", + "description": "Wählen Sie alles Zutreffende.", + "option_buy_and_sell_crypto": "Krypto kaufen und verkaufen", + "option_consolidate_wallets": "Fassen Sie Ihre Wallets zusammen", + "option_advanced_trades": "Tätigen Sie fortschrittliche Trades", + "option_predict_sports_events": "Tippen Sie auf Sport und Events", + "option_crypto_as_money": "Verwenden Sie Krypto als Geld", + "option_connect_apps_sites": "Verbinden Sie sich mit Apps oder Websites", + "continue": "Fortfahren" + }, "template_confirmation": { "ok": "OK", "cancel": "Stornieren" @@ -3261,8 +3286,27 @@ "notifications_desc": "Verwalten Sie Ihre Benachrichtigungen", "allow_notifications": "Benachrichtigungen erlauben", "enable_push_notifications": "Push-Benachrichtigungen aktivieren", - "allow_notifications_desc": "Bleiben Sie mit Benachrichtigungen stets darüber auf dem Laufenden, was in Ihrer Wallet passiert. Zur Nutzung von Benachrichtigungen verwenden wir ein Profil, um bestimmte Einstellungen auf Ihren Geräten zu synchronisieren.", + "allow_notifications_desc": "Choose what you're notified about and how.", "notifications_opts": { + "preferences_title": "Preferences", + "push_recommended": "Push", + "in_app": "In-app", + "status_push": "Push", + "status_in_app": "In app", + "status_off": "Aus", + "select_all": "Alle auswählen", + "deselect_all": "Alle abwählen", + "select_accounts_title": "Konten", + "select_accounts_desc": "Choose which accounts you'd like to get notifications for.", + "wallet_activity_title": "Wallet Activity", + "wallet_activity_desc": "Buy, sells, transfers, swaps and rewards", + "perps_title": "Trading Activity", + "perps_desc": "Perps position changes, liquidations, funding rates, and margin updates", + "social_ai_title": "Trading Signals", + "social_ai_desc": "Updates from traders and assets you follow, plus currated market news", + "marketing_title": "Updates and Rewards", + "marketing_desc": "Product updates, feature announcements, and new releases", + "marketing_disclaimer": "By turning this on, you agree to receive product news and marketing updates from MetaMask.", "customize_session_title": "Passen Sie Ihre Benachrichtigungen an", "customize_session_desc": "Schalten Sie die Arten von Benachrichtigungen ein, die Sie erhalten möchten:", "account_session_title": "Kontoaktivität", @@ -3276,8 +3320,7 @@ "snaps_title": "Snaps", "snaps_desc": "Neue Features und Updates", "products_announcements_title": "Produktankündigungen", - "products_announcements_desc": "Neue Produkte und Features", - "perps_title": "Perps-Trading" + "products_announcements_desc": "Neue Produkte und Features" }, "contacts_title": "Kontakte", "contacts_desc": "Konten hinzufügen, bearbeiten, entfernen und verwalten.", @@ -3640,7 +3683,15 @@ "card": { "title": "Karte", "reset_onboarding_description": "Setzen Sie den Onboarding-Status der Karte zurück, um den Onboarding-Prozess von vorn zu beginnen.", - "reset_onboarding_button": "Onboarding-Status zurücksetzen" + "reset_onboarding_button": "Onboarding-Status zurücksetzen", + "unlink_money_account_description": "Widerrufen Sie die USDC-Ausgabelimit-Erlaubnis, die der Karte gestattet, Ausgaben über Ihr Geldkonto zu tätigen. Dies übermittelt eine approve(0)-Transaktion und markiert das Geldkonto im Backend der Karte als „nicht delegiert“.", + "unlink_money_account_button": "Geldkonto von der Karte trennen", + "unlink_money_account_disabled_hint": "Keine aktive Verknüpfung zum Entfernen vorhanden." + }, + "identity": { + "title": "Identity", + "description": "Clears the persisted authentication session. Use this after toggling MM_DEV_API_ENV — otherwise a prod-minted JWT keeps being handed to dev-API consumers until it expires. Current MM_DEV_API_ENV: {{env}}.", + "clear_auth_session_button": "Clear persisted auth session" }, "haptics": { "title": "Haptik", @@ -3842,8 +3893,8 @@ "predict_button": "Prognosen", "add_collectible_button": "Hinzufügen", "info": "Info", - "batch_sell": "Batch Sell", - "batch_sell_new_label": "New", + "batch_sell": "Batch-Verkauf", + "batch_sell_new_label": "Neu", "swap": "Swappen", "convert": "Konvertieren", "bridge": "Bridge", @@ -3883,7 +3934,7 @@ "troubleshoot": "Problemlösung", "deposit_description": "Kostengünstige Bank- oder Kartenüberweisung", "buy_description": "Ideal für den Kauf eines speziellen Tokens", - "batch_sell_description": "Sell up to 5 tokens for a stablecoin", + "batch_sell_description": "Verkaufen Sie bis zu 5 Token gegen einen Stablecoin", "sell_description": "Krypto für Bargeld verkaufen", "swap_description": "Tausch zwischen Token", "bridge_description": "Tokens zwischen Netzwerken übertragen", @@ -5205,6 +5256,34 @@ "manage_preferences_2": "Einstellungen > Benachrichtigungen.", "cancel": "Stornieren", "cta": "Einschalten" + }, + "push_onboarding": { + "new_user": { + "title": "Verpassen Sie keine Bewegung", + "body": "Erhalten Sie Echtzeit-Benachrichtigungen, sobald Preise Ihre Zielwerte erreichen, Ihre Trades bestätigt werden und sich Ihr Portfolio verändert. Dazu gibt es Produkt-Updates und Belohnungen. Wir senden Ihnen Updates, die auf Ihren Interaktionen mit MetaMask basieren.", + "button_yes": "Ja", + "button_not_now": "Nicht jetzt", + "preview_card_1": { + "eyebrow": "METAMASK", + "time": "jetzt", + "title": "ETH ist heute um 4,2 % gestiegen", + "message": "Jetzt bei 2.668,51 $ – über Ihrer Preisbenachrichtigung" + }, + "preview_card_2": { + "eyebrow": "METAMASK", + "time": "Vor 1 Std.", + "title": "0,25 ETH empfangen", + "message": "Von 0x9a21…4f8c · 640,29 $" + } + }, + "existing_user": { + "title": "Vorstellung von personalisierten Benachrichtigungen", + "body": "Erhalten Sie Mitteilungen, die zu Ihrer Handelsweise passen. Jederzeit anpassbar.", + "card_title": "Was Sie erhalten werden", + "card_description": "Personalisierte Benachrichtigungen und Updates, zugeschnitten auf Ihre Handelsaktivitäten.", + "button_confirm": "Bestätigen", + "button_not_now": "Nicht jetzt" + } } }, "protect_your_wallet_modal": { @@ -5315,6 +5394,7 @@ "pay_with": "Bezahlen mit", "buying_via": "Kauf über {{providerName}}.", "change_provider": "Anbieter wechseln.", + "circuit_breaker_open": "This service is temporarily unavailable. Please try again in about 30 minutes.", "payment_error": "Etwas ist schiefgelaufen! Bitte versuchen Sie es erneut.", "no_payment_methods_available": "Es stehen keine Zahlungsmethoden zur Verfügung.", "error_fetching_quotes": "Etwas ist schiefgelaufen! Bitte versuchen Sie es erneut.", @@ -6520,6 +6600,8 @@ "convert_to_musd": "Zu mUSD konvertieren", "get_a_percentage_musd_bonus": "Erhalten Sie {{percentage}} % mUSD-Bonus", "convert": "Konvertieren", + "confirm": "Bestätigen", + "convert_tooltip_description": "Konvertieren Sie Ihre Stablecoins in mUSD und verdienen Sie einen Bonus von bis zu {{percentage}} % auf jährlicher Basis, den Sie täglich einfordern können. Angetrieben von Relay.", "fetching_quote": "Angebot einholen...", "you_convert": "Sie konvertieren", "network_fee": "Netzwerkgebühr", @@ -6597,7 +6679,7 @@ "step_progress": "Schritt {{current}} von {{total}}", "title": "Geld aufladen", "description": "Laden Sie Ihr Konto auf und beginnen Sie, Effektivvertrag zu verdienen.", - "add": "Hinzufügen", + "add": "Gelder hinzufügen", "step2_title": "Sichern Sie sich Ihre MetaMask Card", "step2_description": "Geben Sie Ihr Geldguthaben aus, während es Gewinne erwirtschaftet, überall dort, wo Mastercard akzeptiert wird.", "step2_cta": "Karte erhalten", @@ -6605,6 +6687,19 @@ "link_card_description": "Geben Sie Ihr Guthaben aus, während es Gewinne erwirtschaftet, überall dort, wo Mastercard akzeptiert wird.", "link_card_cta": "Karte verknüpfen" }, + "rive_onboarding": { + "step1_title": "Geldkonten sind hier", + "step1_body": "Verdienen Sie bis zu {{percentage}} % Effektivertrag auf Ihr Saldo – verfügbar für Ihre gesamte Wallet.", + "step1_footer_text": "Der Effektivertrag ist variabel und kann sich jederzeit ändern.", + "step2_title": "Automatisch verdienen", + "step2_body": "Bewegen Sie Stablecoins ohne Tauschgebühren. Ihre Gelder beginnen sofort, Erträge zu erwirtschaften.", + "step2_footer_text": "Provided by Veda and Steakhouse Financial.", + "step3_title": "Überall ausgeben", + "step3_body": "Erhalten Sie bis zu {{percentage}} % auf Ihre Einkäufe zurück, indem Sie Ihr Geldkonto mit einer MetaMask-Karte verknüpfen.", + "step4_title": "Handeln und verdienen an einem Ort", + "step4_body": "Nutzen Sie Ihren Geldsaldo, um über MetaMask zu handeln und dabei weiterhin Erträge zu erzielen.", + "continue": "Fortfahren" + }, "action": { "add": "Hinzufügen", "transfer": "Übertragung", @@ -6618,8 +6713,8 @@ }, "how_it_works": { "title": "Wie es funktioniert", - "description_prefix": "Deposit mUSD into your Money account and earn up to", - "description_suffix": ". Your balance is dollar-backed and ready to spend, trade, or send anytime." + "description_prefix": "Zahlen Sie mUSD auf Ihr Geldknto ein und verdienen Sie bis zu", + "description_suffix": ". Ihr Saldo ist durch US-Dollar gedeckt und jederzeit bereit zum Ausgeben, Handeln oder Versenden." }, "musd_row": { "add": "Hinzufügen" @@ -6627,16 +6722,16 @@ "balance_card": { "label": "Money-Saldo", "add": "Hinzufügen", - "info_sheet_title": "Money balance", - "info_sheet_body": "Your dollar-backed mUSD balance that's always available to spend, send, or trade anytime. We don't calculate this into your total account balance.\n\nWithdrawals process immediately, subject to standard network confirmation times on the relevant blockchain. If liquidity is tight, there may be temporary delays." + "info_sheet_title": "Money-Saldo", + "info_sheet_body": "Ihr durch US-Dollar gedecktes mUSD-Saldo steht Ihnen jederzeit zum Ausgeben, Senden oder Handeln zur Verfügung. Wir rechnen dies nicht in Ihren gesamten Kontostand ein.\n\nAuszahlungen werden umgehend bearbeitet, vorbehaltlich der üblichen Bestätigungszeiten des jeweiligen Blockchain-Netzwerks. Bei geringer Liquidität kann es zu vorübergehenden Verzögerungen kommen." }, "potential_earnings": { "title": "Verdienen Sie an Ihrem Krypto", "description": "Beobachten Sie, wie Ihr Geld mit der Zeit wächst, indem Sie Ihre Kryptowährung in mUSD konvertieren.", - "description_with_amounts_prefix": "Convert your {{total}} in assets and you could earn up to", - "description_with_amounts_suffix": "in one year.", + "description_with_amounts_prefix": "Wandeln Sie Ihr {{total}} in Vermögenswerte um und Sie könnten verdienen bis zu", + "description_with_amounts_suffix": "in einem Jahr.", "convert": "Konvertieren", - "convert_cta": "Convert your crypto", + "convert_cta": "Wandeln Sie Ihr Krypto um", "no_fee": "Keine MetaMask-Gebühr", "view_all": "Alle anzeigen", "view_potential_earnings": "Mögliche Einnahmen anzeigen" @@ -6649,41 +6744,44 @@ "cashback": "{{percentage}} % mUSD zurück", "get_now": "Jetzt sichern", "link_title": "MetaMask Card verknüpfen", - "link_subtitle": "Spend your Money balance and earn on purchases. Plus, up to {{apy}}% APY on your balance.", - "link_bullet_cashback": "Get {{percentage}}% mUSD back", - "link_bullet_apy": "Earn up to {{apy}}% APY", + "link_subtitle": "Geben Sie Ihren Geldsaldo aus und verdienen Sie bei Einkäufen. Plus: bis zu {{apy}} % Effektivertrag auf Ihr Guthaben.", + "link_subtitle_no_apy": "Spend your Money balance and earn on purchases.", + "link_bullet_cashback": "Erhalten Sie {{percentage}} % mUSD zurück", + "link_bullet_apy": "Verdienen Sie bis zu {{apy}} % Effektivertrag", "link_card": "Karte verknüpfen", - "link_pending_title": "Linking card", - "link_pending_description": "Approving spending limit…", - "link_success_title": "Card linked successfully", - "link_success_description": "You can now spend while you earn", - "link_error": "Couldn't link card", - "manage_card": "Manage", - "avail_balance": "Avail. balance" + "link_pending_title": "Linking your card", + "link_success_title": "Your card is ready to use", + "link_error": "Something went wrong linking your card", + "link_card_sheet_title": "Ausgeben und verdienen", + "link_card_sheet_description": "Link your card so you can spend your Money balance and earn mUSD back on purchases—all while earning up to {{apy}}% APY.", + "link_card_sheet_description_no_apy": "Link your card so you can spend your Money balance and earn mUSD back on purchases.", + "link_card_sheet_cta": "Karte verknüpfen", + "manage_card": "Verwalten", + "avail_balance": "Verfügbares Guthaben" }, "what_you_get": { "title": "Was Sie erhalten", - "benefit_auto_earn": "Auto-earn up to", + "benefit_auto_earn": "Automatisch verdienen bis zu", "benefit_dollar_backed": "Halten Sie Ihr Geld sicher in mUSD, einem 1:1 durch den Dollar gedeckten Stablecoin", "benefit_liquidity": "Erhalten Sie volle Liquidität ohne Sperrfristen, sodass Sie jederzeit handeln oder auszahlen können", "benefit_spend_prefix": "Geben Sie bei über 150 Mio. Händlern mit MetaMask Card aus und verdienen Sie dabei ", "benefit_spend_cashback": "1 bis 3 % mUSD zurück", - "benefit_transfer": "Transfer to any of your wallets across MetaMask", - "benefit_global": "Send and receive funds globally", + "benefit_transfer": "Überweisen Sie an jede Ihrer Wallets über MetaMask", + "benefit_global": "Senden und empfangen Sie Geld weltweit", "learn_more": "Mehr erfahren" }, "footer": { - "add_money": "Add funds" + "add_money": "Gelder hinzufügen" }, "add_money_sheet": { - "title": "Add funds", + "title": "Gelder hinzufügen", "convert_crypto": "Krypto umwandeln", - "convert_crypto_description": "From any account", + "convert_crypto_description": "Von jedem Konto", "deposit_funds": "Gelder einzahlen", - "deposit_funds_description": "From debit card or bank", - "move_musd": "Transfer your {{amount}} mUSD", - "move_musd_no_amount": "Transfer your mUSD", - "move_musd_description": "From your balance", + "deposit_funds_description": "Von Debitkarte oder Bank", + "move_musd": "Überweisen Sie Ihre {{amount}} mUSD", + "move_musd_no_amount": "Überweisen Sie Ihre mUSD", + "move_musd_description": "Von Ihrem Saldo", "receive_external": "Von externer Wallet erhalten", "coming_soon": "Demnächst verfügbar" }, @@ -6694,7 +6792,7 @@ "contact_support": "Support kontaktieren" }, "transfer_sheet": { - "title": "Transfer funds", + "title": "Geld überweisen", "between_accounts": "Zwischen Konten", "perps_account": "Perps-Konto", "predictions_account": "Predictions-Konto", @@ -6712,8 +6810,8 @@ "body": "Eine Schätzung, wie viel Sie über einen bestimmten Zeitraum basierend auf Ihrem aktuellen Saldo und dem heutigen Effektivvertrag verdienen könnten. Bei diesen Schätzungen handelt es sich nicht um garantierte Erträge; sie bleiben vorbehaltlich etwaiger Änderungen." }, "earn_crypto_info_sheet": { - "title": "Earn on your crypto", - "body": "Illustration assumes {{percentage}}% Annual Percentage Yield (APY) remains unchanged for one year. APY is variable and may change due to various factors. No guarantee of return." + "title": "Verdienen Sie an Ihrem Krypto", + "body": "Die Beispielrechnung geht davon aus, dass der Effektivertrag von {{percentage}} % über einen Zeitraum von einem Jahr unverändert bleibt. Der Effektivertrag ist variabel und kann sich aufgrund verschiedener Faktoren ändern. Es besteht keine Renditegarantie." }, "activity": { "title": "Aktivität", @@ -6725,7 +6823,7 @@ }, "condensed_cards": { "how_it_works_title": "Wie es funktioniert", - "how_it_works_subtitle": "Erleben Sie, wie Ihr Geld für Sie arbeitet", + "how_it_works_subtitle": "See how your money can grow", "musd_title": "MetaMask USD", "musd_subtitle": "Erfahren Sie mehr über mUSD", "what_you_get_title": "Was Sie erhalten", @@ -6738,7 +6836,8 @@ "sent": "Versendet", "transferred": "Überwiesen", "card_transaction": "Kartentransaktion", - "converted": "Konvertiert" + "converted": "Konvertiert", + "failed": "Fehlgeschlagen" }, "convert_stablecoins": { "title": "Konvertieren Sie Ihre Stablecoins", @@ -6757,11 +6856,11 @@ "how_it_works_page": { "header_title": "Money", "section_title": "Wie es funktioniert", - "description_1": "Deposit mUSD into your Money account and earn up to {{percentage}}% APY (variable) automatically. Funds go into a DeFi vault that generates returns across audited lending markets—no staking, no claiming, no lock-ups.", + "description_1": "Zahlen Sie mUSD auf Ihr Geldkonto ein und erhalten Sie automatisch bis zu {{percentage}} % Effektivertrag (variabel). Das Geld fließt in einen DeFi-Tresor, der auf geprüften Kreditmärkten Renditen erzielt – ganz ohne Staking, ohne Auszahlungsanträge und ohne Sperrfristen.", "description_2": "Ihr Geldguthaben ist Ihr Ausgabensaldo. Verknüpfen Sie Ihre MetaMask Card, um bei mehr als 150 Millionen Händlern weltweit zu bezahlen. Ihr Geld verdient so lange, bis Sie es nutzen.", - "faq_title": "Frequently asked questions", + "faq_title": "Häufig gestellte Fragen", "faq_placeholder_answer": "Demnächst verfügbar.", - "faq_q1": "How does the {{percentage}}% APY work?", + "faq_q1": "Wie funktioniert der {{percentage}}-%-Effektivertrag?", "faq_q2": "Was ist mUSD?", "faq_q3": "Woher kommt die Rendite?", "faq_q4": "Ist mein Geld gesperrt? Kann ich es jederzeit auszahlen lassen?", @@ -7030,11 +7129,12 @@ "confirm": "Bestätigen", "pay_with_bottom_sheet": { "title": "Bezahlen mit", - "last_used": "Last used", - "crypto": "Crypto", - "available_balance": "{{balance}} available", - "other_assets": "Other assets", - "other_assets_description": "Select from your tokens" + "last_used": "Zuletzt verwendet", + "bank_and_card": "Bank und Karte", + "crypto": "Krypto", + "available_balance": "{{balance}} verfügbar", + "other_assets": "Weitere Vermögenswerte", + "other_assets_description": "Wählen Sie aus Ihren Token" }, "staking_footer": { "part1": "Indem Sie fortfahren, bestätigen Sie unsere ", @@ -7120,7 +7220,7 @@ "transaction_fee": "Die Gebühren für die mUSD-Konvertierung beinhalten Netzwerkkosten und können Anbietergebühren beinhalten. Bei der Konvertierung in mUSD fällt keine MetaMask-Gebühr an." }, "money_account_withdraw": { - "transaction_fee": "MetaMask will swap your mUSD for your desired token. Swap providers may charge a fee, but MetaMask won't." + "transaction_fee": "MetaMask tauscht Ihre mUSD gegen das von Ihnen gewünschte Token. Swap-Anbieter können Gebühren erheben, MetaMask jedoch nicht." }, "title": { "transaction_fee": "Gebühren" @@ -7225,7 +7325,7 @@ "deposit_edit_amount_done": "Gelder hinzufügen", "deposit_edit_amount_predict_withdraw": "Auszahlen", "deposit_edit_amount_musd_conversion": "Zu mUSD konvertieren", - "preparing_order": "Preparing order" + "preparing_order": "Order wird vorbereitet" }, "change_in_simulation_modal": { "title": "Ergebnisse haben sich geändert", @@ -7250,20 +7350,33 @@ "confirm_swap": "Swap", "terms_and_conditions": "Geschäftsbedingungen", "select_token": "Token auswählen", - "batch_sell_select_title": "Select up to 5 tokens", - "batch_sell_select_subtitle": "All tokens need to be on the same network.", - "batch_sell_empty_state_title": "No tokens. No problem.", - "batch_sell_empty_state_description": "No tokens. No problem. Explore and buy tokens to batch sell.", - "batch_sell_continue_with_one_token": "Continue with (1) token", - "batch_sell_continue_with_tokens": "Continue with ({{tokenCount}}) tokens", - "batch_sell_max_tokens_allowed": "Max 5 tokens allowed", - "batch_sell_single_token_dialog_title": "High rate alert", - "batch_sell_single_token_dialog_description": "Batch selling one token could lead to a higher rate. Want to do a swap instead?", - "batch_sell_swap_instead": "Yes, swap", - "batch_sell_checkbox_label": "Batch Sell token", - "sort_balance": "Balance", - "next": "Next", - "explore_tokens": "Explore tokens", + "batch_sell_select_title": "Wählen Sie bis zu 5 Token", + "batch_sell_select_subtitle": "Alle Token müssen sich im selben Netzwerk befinden.", + "batch_sell_empty_state_title": "Keine Token. Kein Problem.", + "batch_sell_empty_state_description": "Keine Token. Kein Problem. Entdecken und kaufen Sie Token für den Batch-Verkauf.", + "batch_sell_continue_with_one_token": "Mit (1) Token fortfahren", + "batch_sell_continue_with_tokens": "Mit ({{tokenCount}}) Token fortfahren", + "batch_sell_max_tokens_allowed": "Max. 5 Token erlaubt", + "batch_sell_single_token_dialog_title": "Hochpreisbenachrichtigung", + "batch_sell_single_token_dialog_description": "Batch-Verkauf von einem Token könnte zu einem höheren Preis führen. Möchten Sie stattdessen swappen?", + "batch_sell_swap_instead": "Ja, swappen", + "batch_sell_review_title": "Batch-Verkauf-Review", + "batch_sell_select_stablecoin": "Stablecoin wählen", + "batch_sell_total_received": "Insgesamt empfangen", + "batch_sell_minimum_received": "Minimum received", + "batch_sell_quote_details_row": "{{tokenSymbol}} • {{slippage}} slippage", + "batch_sell_review": "Überprüfen", + "batch_sell_you_sell": "You sell", + "batch_sell_token_count": "{{tokenCount}} tokens", + "batch_sell_toggle_you_sell": "Toggle token details", + "batch_sell_sell_all": "Sell all", + "batch_sell_includes_metamask_fee": "Includes {{fee}}% MetaMask fee", + "batch_sell_customize_token": "{{tokenSymbol}} anpassen", + "batch_sell_remove_token": "{{tokenSymbol}} entfernen", + "batch_sell_checkbox_label": "Batch-Verkauf-Token", + "sort_balance": "Kontostand", + "next": "Weiter", + "explore_tokens": "Token erkunden", "no_tokens_found": "Keine Tokens gefunden", "no_tokens_found_description": "Wir konnten keine Tokens mit diesem Namen finden. Versuchen Sie eine andere Suche.", "select_network": "Netzwerk wählen", @@ -7332,6 +7445,7 @@ "price_impact_execution_description": "Sie verlieren bei diesem Swap etwa {{priceImpact}} des Wertes Ihres Tokens. Versuchen Sie, den Betrag zu senken oder eine liquidere Route zu wählen.", "proceed": "Fortfahren", "cancel": "Stornieren", + "close": "Schließen", "slippage_info_title": "Slippage", "slippage_info_description": "Die prozentuale Preisänderung, die Sie zuzulassen bereit sind, bevor Ihre Transaktion storniert wird.", "blockaid_error_title": "Diese Transaktion wird rückgängig gemacht", @@ -8107,7 +8221,14 @@ "retry": "Erneut versuchen", "on_linea": "auf Linea", "account_label": "Konto", - "token_label": "Token" + "token_label": "Token", + "money_account_label": "Money account", + "money_account_token_symbol": "mUSD", + "use_money_account_cta": "Use Money account", + "spend_and_earn_title": "Spend while you earn", + "spend_and_earn_description": "Spend with your Money account and earn up to {{apy}}% APY on your balance. Also get {{cashback}}% mUSD back.", + "spend_and_earn_description_no_apy": "Spend with your Money account and earn APY on your balance. Also get {{cashback}}% mUSD back.", + "spend_and_earn_cta": "Link to Money account" }, "cashback_screen": { "title": "mUSD zurück", @@ -8335,7 +8456,7 @@ }, "main_title": "Belohnungen", "vip": { - "bps_unit": "bps", + "bps_unit": "Basispunkte", "swaps_label": "Swaps", "perps_label": "Perps", "error_title": "We couldn’t load your VIP dashboard", @@ -8449,6 +8570,7 @@ "show_less": "Weniger anzeigen", "linking_progress": "Konten werden hinzufügen ... ({{current}}/{{total}})", "accounts_linked_count": "{{linked}}/{{total}} angemeldet", + "accounts_added": "Accounts added", "add_all_accounts": "Alle Konten hinzufügen", "environment_selector": "Umgebung", "environment_cancel": "Stornieren", @@ -8473,15 +8595,22 @@ }, "optout": { "title": "Rewards-Fortschritt löschen", - "description": "Dadurch werden Ihre Konten aus dem Rewards-Programm entfernt und Ihr Fortschritt gelöscht. Diese Aktion kann nicht rückgängig gemacht werden.", - "confirm": "Löschen", + "description": "This will remove your accounts from the Rewards program and your progress in any campaigns you've joined. Only do this if you are absolutely sure you want to erase your progress.", + "erase_button": "Erase progress", "modal": { "confirmation_title": "Sind Sie sicher?", - "confirmation_description": "Dadurch wird Ihr gesamter Fortschritt gelöscht und kann nicht rückgängig gemacht werden. Wenn Sie später wieder am Belohnungsprogramm teilnehmen, beginnen Sie wieder bei 0.", + "confirmation_description": "This will erase all your progress, and can't be reversed. If you rejoin the Rewards program later, you'll start back at 0.", + "type_to_confirm": "Type 'erase progress' to continue", + "confirm_phrase": "erase progress", "cancel": "Stornieren", "confirm": "Bestätigen", + "error_title": "Hoppla! Etwas ist schiefgelaufen ...", "error_message": "Abmeldung von Belohnungen fehlgeschlagen. Bitte versuchen Sie es erneut.", "processing": "Verarbeitung..." + }, + "request_received": { + "title": "Request received", + "description": "In about 7 days, your progress will be fully erased. If you made this request by mistake, please contact support through the app." } }, "toast_dismiss": "Verwerfen", @@ -8569,7 +8698,8 @@ "title_claim": "Vorteil einfordern", "action": "Einfordern", "empty-list": "Sie haben derzeit keine Vorteile.", - "powered_by": "Unterstützt durch" + "powered_by": "Unterstützt durch", + "available_count": "{{count}} verfügbar" }, "end_of_season_rewards": { "confirm_label_default": "Bestätigen", @@ -8702,7 +8832,7 @@ "label_your_rank": "Ihr Rang", "label_portfolio": "Portfolio", "label_net_inflow": "Nettozufluss", - "label_total_inflow": "Gesamtzufluss", + "label_total_inflow": "Gesamtzustrom", "label_outflow": "Kapitalabfluss", "label_days_held": "Tage gehalten", "qualified_title": "Sie sind qualifiziert", @@ -8887,9 +9017,11 @@ "musd_claim": "mUSD beanspruchen", "perps_deposit": "Gelder hinzufügen", "perps_withdraw": "Auszahlung", + "predict_withdraw": "{{sourceSymbol}} von {{sourceChain}} abheben", "predict_deposit": "Gelder hinzufügen", "swap": "Tokens tauschen", - "swap_approval": "Tokens genehmigen" + "swap_approval": "Tokens genehmigen", + "fiat_purchase": "{{token}} mit {{paymentMethod}} kaufen" }, "perps_deposit_solution": "Sie haben nun {{fiat}} von USDC auf Arbitrum. Versuchen Sie Ihre Einzahlung erneut." }, @@ -8965,7 +9097,7 @@ "high_to_low": "Hoch bis niedrig", "low_to_high": "Niedrig bis hoch", "apply": "Anwenden", - "search_placeholder": "Tokens, Websites, URLs suchen", + "search_placeholder": "Search tokens, markets and URLs", "cancel": "Stornieren", "perps": "Perps", "rwa_perps_section": "Perps", @@ -8978,11 +9110,15 @@ "crypto_perps_section": "Perps", "predictions": "Prognosen", "no_results": "Keine Ergebnisse gefunden", + "no_results_for_feed": "No {{feedName}} results for \"{{query}}\"", + "showing_all_results_for": "We found these results for \"{{query}}\"", "popular": "Beliebt", "sites": "Websites", "popular_sites": "Beliebte Websites", "search_sites": "Websites durchsuchen", "view_all": "Alle anzeigen", + "view_more": "Mehr anzeigen", + "view_x_more": "View {{count}} more", "enable_basic_functionality": "Grundlegende Funktionen aktivieren", "basic_functionality_disabled_title": "Entdecken ist nicht verfügbar", "basic_functionality_disabled_description": "Die erforderlichen Metadaten können nicht abgerufen werden, wenn die Basisfunktionalität deaktiviert ist.", @@ -9002,6 +9138,14 @@ "crypto": "Krypto", "sports": "Sport", "dapps": "Websites" + }, + "search_tabs": { + "all": "Alle", + "crypto": "Cryptos", + "perps": "Perps", + "stocks": "Aktien", + "predictions": "Prognosen", + "sites": "Websites" } }, "ota_update_modal": { @@ -9139,6 +9283,7 @@ "money_empty_description_network_filter": "Kein mUSD in diesem Netzwerk. Wechseln Sie das Netzwerk, um Ihre mUSD einzusehen.", "money_empty_state": { "get_started": "Erste Schritte", + "earn": "Verdienen", "earn_apy": "{{percentage}} % Effektivertrag verdienen" }, "money_filled_state": { @@ -9150,22 +9295,7 @@ "related_assets": "Zugehörige Assets", "perpetuals": "Perpetuals", "predictions": "Prognosen", - "whats_happening": "Was ist passiert?", - "whats_happening_ai": "KI", - "whats_happening_impact": { - "bullish": "Haussierend", - "bearish": "Baissierend", - "neutral": "Neutral" - }, "top_traders": "Top-Trader", - "whats_happening_categories": { - "geopolitical": "Geopolitisch", - "macro": "Makro", - "regulatory": "Regulatorisch", - "technical": "Technisch", - "social": "Sozial", - "other": "Sonstiges" - }, "defi": "DeFi", "nfts": "NFTs", "trending_tokens": "Angesagt", @@ -9185,5 +9315,22 @@ }, "sites": { "popular": "Beliebt" + }, + "whats_happening": { + "title": "Was ist passiert?", + "ai": "KI", + "impact": { + "bullish": "Haussierend", + "bearish": "Baissierend", + "neutral": "Neutral" + }, + "categories": { + "geopolitical": "Geopolitisch", + "macro": "Makro", + "regulatory": "Regulatorisch", + "technical": "Technisch", + "social": "Sozial", + "other": "Sonstiges" + } } } diff --git a/locales/languages/el.json b/locales/languages/el.json index bdc23bee911..448e7bb1e14 100644 --- a/locales/languages/el.json +++ b/locales/languages/el.json @@ -120,6 +120,10 @@ "account_no_funds": { "message": "Δεν υπάρχουν διαθέσιμα χρήματα. Δοκιμάστε με άλλον λογαριασμό." }, + "headless_buy_error": { + "title": "Η αγορά με παραδοσιακό νόμισμα απέτυχε", + "message": "Παρουσιάστηκε πρόβλημα με την αγορά σας με παραδοσιακό νόμισμα. Προσπαθήστε ξανά." + }, "mmpay_hardware_account": { "title": "Το πορτοφόλι δεν υποστηρίζεται", "message": "Τα πορτοφόλια υλικού δεν υποστηρίζονται. \nΑλλάξτε πορτοφόλι για να συνεχίσετε." @@ -133,8 +137,8 @@ "message": "Η διεύθυνση παραλήπτη ενδέχεται να μην υποστηρίζει άμεσες μεταφορές tokens, γεγονός που μπορεί να οδηγήσει σε απώλεια κεφαλαίων. Συνεχίστε μόνο εάν είστε βέβαιοι ότι το συγκεκριμένο συμβόλαιο μπορεί να λάβει τη μεταφορά." }, "gas_sponsorship_reserve_balance": { - "message": "Η κάλυψη των τελών δεν είναι διαθέσιμη για αυτή τη συναλλαγή. Θα χρειαστεί να διατηρείτε τουλάχιστον %{minBalance} %{nativeTokenSymbol} στον λογαριασμό σας.", - "title": "Η κάλυψη των τελών δεν είναι διαθέσιμη" + "message": "Αυτό το συγκεκριμένο δίκτυο απαιτεί τη διατήρηση ενός αποθεματικού ύψους %{minBalance} %{nativeTokenSymbol} στον λογαριασμό σας.", + "title": "Απαιτείται υπόλοιπο ως αποθεματικό" }, "token_trust_signal": { "malicious": { @@ -708,6 +712,9 @@ "contractAddressError": "Πρόκειται να στείλετε tokens στη διεύθυνση συμβολαίου του token. Αυτό μπορεί να οδηγήσει σε απώλεια των token.", "smart_contract_address": "Διεύθυνση έξυπνου συμβολαίου", "smart_contract_address_warning": "Η διεύθυνση παραλήπτη ενδέχεται να μην υποστηρίζει άμεσες μεταφορές tokens, γεγονός που μπορεί να οδηγήσει σε απώλεια κεφαλαίων. Συνεχίστε μόνο εάν είστε βέβαιοι ότι το συγκεκριμένο συμβόλαιο μπορεί να λάβει τη μεταφορά.", + "unavailable_network_connection": "Unavailable network connection", + "unavailable_network_connection_description": "The connection with {{network}} is unreliable. Update network connectivity details before continuing or try again later.", + "update": "Ενημέρωση", "i_understand": "Κατανοώ", "cancel": "Άκυρο", "new_address_title": "Νέα διεύθυνση", @@ -1068,7 +1075,7 @@ "sort": { "value": "Αξία", "pnl_percent": "Κ&Ζ %", - "recent": "Recent" + "recent": "Πρόσφατα" } }, "trader_position": { @@ -1120,6 +1127,11 @@ "title": "Κάντε συναλλαγές με perp του {{symbol}}", "subtitle": "Πολλαπλασιάστε τα κέρδη και τις ζημίες σας έως και {{leverage}}" }, + "service_interruption": { + "title": "We're experiencing an outage", + "description": "Some services may be unavailable while the team works on a fix.", + "contact_support": "Επικοινωνία με την υποστήριξη" + }, "today": "Σήμερα", "yesterday": "Χθες", "unrealized_pnl": "Μη οριστικοποιημένα κέρδη & ζημίες", @@ -1284,7 +1296,9 @@ "toast_completed_subtitle": "{{amount}} USDC μεταφέρθηκαν στο πορτοφόλι σας", "toast_completed_any_token_subtitle": "{{amount}} {{token}} μεταφέρθηκαν στο πορτοφόλι σας", "toast_error_title": "Κάτι πήγε στραβά", - "toast_error_description": "Δεν ήταν δυνατή η συνέχιση της ανάληψης" + "toast_error_description": "Δεν ήταν δυνατή η συνέχιση της ανάληψης", + "toast_start_error_description": "Your withdrawal wasn’t started.", + "try_again": "Προσπαθήστε ξανά" }, "quote": { "network_fee": "Τέλη δικτύου", @@ -2227,35 +2241,35 @@ "predict": { "title": "Προβλέψεις στο MetaMask", "world_cup": { - "title": "World Cup", - "banner_title": "World Cup 2026", - "banner_description": "Trade on World Cup markets", + "title": "Παγκόσμιο Κύπελλο", + "banner_title": "Παγκόσμιο Κύπελλο 2026", + "banner_description": "Trade every match, every moment.", "tabs": { - "all": "All", + "all": "Όλα", "props": "Props", - "live": "Live" + "live": "Ζωντανά" }, "stages": { - "group_stage": "Group Stage", - "round_of_32": "Round of 32", - "round_of_16": "Round of 16", - "quarterfinals": "Quarterfinals", - "semifinals": "Semifinals", - "third_place": "Third Place", - "final": "Final", - "group_a": "Group A", - "group_b": "Group B", - "group_c": "Group C", - "group_d": "Group D", - "group_e": "Group E", - "group_f": "Group F", - "group_g": "Group G", - "group_h": "Group H", - "group_i": "Group I", - "group_j": "Group J", - "group_k": "Group K", - "group_l": "Group L", - "third_place_match": "Third Place Match" + "group_stage": "Φάση ομίλων", + "round_of_32": "Φάση των 32", + "round_of_16": "Φάση των 16", + "quarterfinals": "Προημιτελικοί", + "semifinals": "Ημιτελικοί", + "third_place": "Μικρός τελικός", + "final": "Λήξη", + "group_a": "Όμιλος Α", + "group_b": "Όμιλος Β", + "group_c": "Όμιλος Γ", + "group_d": "Όμιλος Δ", + "group_e": "Όμιλος Ε", + "group_f": "Όμιλος ΣΤ", + "group_g": "Όμιλος Ζ", + "group_h": "Όμιλος Η", + "group_i": "Όμιλος Ι", + "group_j": "Όμιλος Θ", + "group_k": "Όμιλος Κ", + "group_l": "Όμιλος Λ", + "third_place_match": "Αγώνας για την 3η θέση" } }, "prediction_markets": "Αγορές προβλέψεων", @@ -2537,8 +2551,8 @@ "withdraw_completed": "Η ανάληψη ολοκληρώθηκε", "withdraw_completed_subtitle": "{{amount}} USDC μεταφέρθηκαν στο πορτοφόλι σας", "withdraw_any_token_completed_subtitle": "{{amount}} {{token}} μεταφέρθηκαν στο πορτοφόλι σας", - "unavailable_title": "Withdrawals temporarily unavailable", - "unavailable_description": "For urgent assistance, please contact Customer Service.", + "unavailable_title": "Οι αναλήψεις είναι προσωρινά μη διαθέσιμες", + "unavailable_description": "Για επείγουσα βοήθεια, επικοινωνήστε με την Εξυπηρέτηση Πελατών.", "unavailable_got_it": "Κατανοητό", "error_title": "Κάτι πήγε στραβά", "error_description": "Δεν ήταν δυνατή η συνέχιση της ανάληψης", @@ -2941,6 +2955,17 @@ "pna25_confirm_button": "Αποδοχή και κλείσιμο", "pna25_open_settings_button": "Άνοιγμα Ρυθμίσεων" }, + "onboarding_interest_questionnaire": { + "title": "Τι θέλετε να κάνετε στο MetaMask;", + "description": "Επιλέξτε όλα όσα ισχύουν.", + "option_buy_and_sell_crypto": "Αγορά και πώληση κρυπτονομισμάτων", + "option_consolidate_wallets": "Συγχώνευση πορτοφολιών", + "option_advanced_trades": "Εκτέλεση προχωρημένων συναλλαγών", + "option_predict_sports_events": "Προβλέψεις για αθλητικά γεγονότα", + "option_crypto_as_money": "Χρήση κρυπτονομισμάτων ως μέσο πληρωμής", + "option_connect_apps_sites": "Σύνδεση με εφαρμογές ή ιστότοπους", + "continue": "Συνεχίστε" + }, "template_confirmation": { "ok": "Εντάξει", "cancel": "Άκυρο" @@ -3261,8 +3286,27 @@ "notifications_desc": "Διαχειριστείτε τις ειδοποιήσεις σας", "allow_notifications": "Επιτρέψτε τις ειδοποιήσεις", "enable_push_notifications": "Ενεργοποίηση ειδοποιήσεων ώθησης", - "allow_notifications_desc": "Μείνετε ενήμεροι για ό, τι συμβαίνει στο πορτοφόλι σας με τις ειδοποιήσεις. Για να χρησιμοποιήσετε τις ειδοποιήσεις, κάνουμε χρήση ενός προφίλ για να συγχρονίσουμε ορισμένες ρυθμίσεις στις συσκευές σας.", + "allow_notifications_desc": "Choose what you're notified about and how.", "notifications_opts": { + "preferences_title": "Preferences", + "push_recommended": "Push", + "in_app": "In-app", + "status_push": "Push", + "status_in_app": "In app", + "status_off": "Απεν.", + "select_all": "Επιλογή όλων", + "deselect_all": "Αποεπιλογή όλων", + "select_accounts_title": "Λογαριασμοί", + "select_accounts_desc": "Choose which accounts you'd like to get notifications for.", + "wallet_activity_title": "Wallet Activity", + "wallet_activity_desc": "Buy, sells, transfers, swaps and rewards", + "perps_title": "Trading Activity", + "perps_desc": "Perps position changes, liquidations, funding rates, and margin updates", + "social_ai_title": "Trading Signals", + "social_ai_desc": "Updates from traders and assets you follow, plus currated market news", + "marketing_title": "Updates and Rewards", + "marketing_desc": "Product updates, feature announcements, and new releases", + "marketing_disclaimer": "By turning this on, you agree to receive product news and marketing updates from MetaMask.", "customize_session_title": "Προσαρμόστε τις ειδοποιήσεις σας", "customize_session_desc": "Ενεργοποιήστε τους τύπους ειδοποιήσεων που θέλετε να λαμβάνετε:", "account_session_title": "Δραστηριότητα λογαριασμού", @@ -3276,8 +3320,7 @@ "snaps_title": "Snaps", "snaps_desc": "Νέες λειτουργίες και ενημερώσεις", "products_announcements_title": "Ανακοινώσεις προϊόντων", - "products_announcements_desc": "Νέα προϊόντα και λειτουργίες", - "perps_title": "Συναλλαγές με συμβόλαια αορίστου διάρκειας" + "products_announcements_desc": "Νέα προϊόντα και λειτουργίες" }, "contacts_title": "Επαφές", "contacts_desc": "Προσθέστε, επεξεργαστείτε, αφαιρέστε και διαχειριστείτε τους λογαριασμούς σας.", @@ -3640,7 +3683,15 @@ "card": { "title": "Κάρτα", "reset_onboarding_description": "Επαναφορά της διαδικασίας ενεργοποίησης της Κάρτας για να ξεκινήσει η διαδικασία από την αρχή.", - "reset_onboarding_button": "Επαναφορά της διαδικασίας ενεργοποίησης" + "reset_onboarding_button": "Επαναφορά της διαδικασίας ενεργοποίησης", + "unlink_money_account_description": "Ανακαλέστε το όριο δαπανών σε USDC που επιτρέπει στην κάρτα να ξοδεύει από τον λογαριασμό σας. Αυτό υποβάλλει μια συναλλαγή έγκρισης(0) και επισημαίνει τον λογαριασμό σας ως μη εξουσιοδοτημένο για ανάθεση στο σύστημα της κάρτας.", + "unlink_money_account_button": "Αποσύνδεση του Λογαριασμού από την κάρτα", + "unlink_money_account_disabled_hint": "Δεν υπάρχει ενεργή σύνδεση για αφαίρεση." + }, + "identity": { + "title": "Identity", + "description": "Clears the persisted authentication session. Use this after toggling MM_DEV_API_ENV — otherwise a prod-minted JWT keeps being handed to dev-API consumers until it expires. Current MM_DEV_API_ENV: {{env}}.", + "clear_auth_session_button": "Clear persisted auth session" }, "haptics": { "title": "Απτική ανάδραση", @@ -3842,8 +3893,8 @@ "predict_button": "Προβλέψεις", "add_collectible_button": "Προσθήκη", "info": "Πληροφορίες", - "batch_sell": "Batch Sell", - "batch_sell_new_label": "New", + "batch_sell": "Μαζική πώληση", + "batch_sell_new_label": "Νέα", "swap": "Ανταλλαγή", "convert": "Μετατροπή", "bridge": "Διασύνδεση", @@ -3883,7 +3934,7 @@ "troubleshoot": "Αντιμετώπιση Προβλημάτων", "deposit_description": "Τραπεζική μεταφορά ή με κάρτα με χαμηλή χρέωση", "buy_description": "Κατάλληλο για την αγορά συγκεκριμένου token", - "batch_sell_description": "Sell up to 5 tokens for a stablecoin", + "batch_sell_description": "Πουλήστε έως 5 tokens για ένα stablecoin", "sell_description": "Πουλήστε κρυπτονομίσματα για μετρητά", "swap_description": "Ανταλλαγή μεταξύ tokens", "bridge_description": "Μεταφορά token μεταξύ δικτύων", @@ -5205,6 +5256,34 @@ "manage_preferences_2": "Ρυθμίσεις > Ειδοποιήσεις.", "cancel": "Άκυρο", "cta": "Ενεργοποίηση" + }, + "push_onboarding": { + "new_user": { + "title": "Μην χάνετε καμία κίνηση της αγοράς", + "body": "Λάβετε ειδοποιήσεις σε πραγματικό χρόνο όταν οι τιμές επιτυγχάνουν τους στόχους σας, οι συναλλαγές σας επιβεβαιώνονται και το χαρτοφυλάκιό σας μεταβάλλεται. Επιπλέον, θα λαμβάνετε ενημερώσεις προϊόντος και ανταμοιβές. Θα σας στέλνουμε ενημερώσεις βάσει των αλληλεπιδράσεών σας με το MetaMask.", + "button_yes": "Ναι", + "button_not_now": "Όχι τώρα", + "preview_card_1": { + "eyebrow": "METAMASK", + "time": "τώρα", + "title": "Το ETH έχει ανέβει 4,2% σήμερα", + "message": "Τώρα στα $2.668,51 — πάνω από το όριο ειδοποίησής σας" + }, + "preview_card_2": { + "eyebrow": "METAMASK", + "time": "1 ώρα πριν", + "title": "Λάβατε 0,25 ETH", + "message": "Από 0x9a21…4f8c · $640,29" + } + }, + "existing_user": { + "title": "Παρουσιάζουμε τις εξατομικευμένες ειδοποιήσεις", + "body": "Λάβετε ειδοποιήσεις σύμφωνα με τον τρόπο που κάνετε συναλλαγές. Μπορείτε να τις αλλάξετε οποιαδήποτε στιγμή.", + "card_title": "Τι θα λάβετε", + "card_description": "Εξατομικευμένες ειδοποιήσεις και ενημερώσεις προσαρμοσμένες στη δραστηριότητά σας στις συναλλαγές.", + "button_confirm": "Επιβεβαίωση", + "button_not_now": "Όχι τώρα" + } } }, "protect_your_wallet_modal": { @@ -5315,6 +5394,7 @@ "pay_with": "Πληρωμή με", "buying_via": "Αγορά μέσω {{providerName}}.", "change_provider": "Αλλαγή παρόχου.", + "circuit_breaker_open": "This service is temporarily unavailable. Please try again in about 30 minutes.", "payment_error": "Κάτι πήγε στραβά. Παρακαλούμε προσπαθήστε ξανά.", "no_payment_methods_available": "Δεν υπάρχουν διαθέσιμες μέθοδοι πληρωμής.", "error_fetching_quotes": "Κάτι πήγε στραβά. Παρακαλούμε προσπαθήστε ξανά.", @@ -6520,6 +6600,8 @@ "convert_to_musd": "Μετατροπή σε mUSD", "get_a_percentage_musd_bonus": "Κερδίστε {{percentage}}% μπόνους σε mUSD", "convert": "Μετατροπή", + "confirm": "Επιβεβαίωση", + "convert_tooltip_description": "Μετατρέψτε τα stablecoins σας σε mUSD και κερδίστε έως και {{percentage}}% ετήσιο μπόνους που μπορείτε να εξαργυρώσετε καθημερινά. Με την υποστήριξη της Relay.", "fetching_quote": "Λήψη προσφοράς...", "you_convert": "Μετατρέπετε", "network_fee": "Τέλη δικτύου", @@ -6597,7 +6679,7 @@ "step_progress": "Βήμα {{current}} από {{total}}", "title": "Προσθήκη χρημάτων", "description": "Χρηματοδοτήστε τον λογαριασμό σας και ξεκινήστε να κερδίζετε APY.", - "add": "Προσθήκη", + "add": "Προσθήκη κεφαλαίων", "step2_title": "Αποκτήστε την MetaMask Card", "step2_description": "Ξοδέψτε το υπόλοιπο του λογαριασμού σας όσο αυτό αποδίδει, οπουδήποτε γίνεται δεκτή η Mastercard.", "step2_cta": "Αποκτήστε την κάρτα", @@ -6605,6 +6687,19 @@ "link_card_description": "Ξοδέψτε το υπόλοιπό του λογαριασμού σας όσο αυτό αποδίδει, οπουδήποτε γίνεται δεκτή η Mastercard.", "link_card_cta": "Σύνδεση κάρτας" }, + "rive_onboarding": { + "step1_title": "Οι καταθετικοί λογαριασμοί είναι εδώ", + "step1_body": "Κερδίστε έως και {{percentage}}% APY στο υπόλοιπό σας, διαθέσιμο στο πορτοφόλι σας.", + "step1_footer_text": "Το APY μεταβάλλεται και μπορεί να αλλάξει ανά πάσα στιγμή.", + "step2_title": "Κερδίζετε αυτόματα", + "step2_body": "Μεταφέρετε τα stablecoins χωρίς προμήθειες ανταλλαγής. Τα κεφάλαιά σας αρχίζουν να αποδίδουν άμεσα.", + "step2_footer_text": "Provided by Veda and Steakhouse Financial.", + "step3_title": "Κάντε αγορές οπουδήποτε", + "step3_body": "Κερδίστε έως και {{percentage}}% επιστροφή στις αγορές σας συνδέοντας τον λογαριασμό σας με μια MetaMask Card.", + "step4_title": "Κάντε συναλλαγές και κερδίστε σε ένα μέρος", + "step4_body": "Χρησιμοποιήστε το υπόλοιπο του λογαριασμού σας για συναλλαγές στο MetaMask, ενώ συνεχίζετε να κερδίζετε σε απόδοση.", + "continue": "Συνεχίστε" + }, "action": { "add": "Προσθήκη", "transfer": "Μεταφορά", @@ -6618,8 +6713,8 @@ }, "how_it_works": { "title": "Πώς λειτουργεί", - "description_prefix": "Deposit mUSD into your Money account and earn up to", - "description_suffix": ". Your balance is dollar-backed and ready to spend, trade, or send anytime." + "description_prefix": "Καταθέστε mUSD στον λογαριασμό σας και κερδίστε έως και", + "description_suffix": ". Το υπόλοιπό σας είναι συνδεδεμένο με το δολάριο και έτοιμο για χρήση, συναλλαγές ή αποστολή οποιαδήποτε στιγμή." }, "musd_row": { "add": "Προσθήκη" @@ -6627,16 +6722,16 @@ "balance_card": { "label": "Υπόλοιπο χρημάτων", "add": "Προσθήκη", - "info_sheet_title": "Money balance", - "info_sheet_body": "Your dollar-backed mUSD balance that's always available to spend, send, or trade anytime. We don't calculate this into your total account balance.\n\nWithdrawals process immediately, subject to standard network confirmation times on the relevant blockchain. If liquidity is tight, there may be temporary delays." + "info_sheet_title": "Υπόλοιπο χρημάτων", + "info_sheet_body": "Το υπόλοιπό σας σε mUSD, συνδεδεμένο με το δολάριο, είναι πάντα διαθέσιμο για χρήση, αποστολή ή συναλλαγές. Δεν το υπολογίζουμε στο συνολικό υπόλοιπο του λογαριασμού σας.\n\nΟι αναλήψεις επεξεργάζονται άμεσα, με την επιφύλαξη των συνήθων χρόνων επιβεβαίωσης του δικτύου στο αντίστοιχο blockchain. Αν η ρευστότητα είναι περιορισμένη, ενδέχεται να υπάρξουν προσωρινές καθυστερήσεις." }, "potential_earnings": { "title": "Κερδίστε από τα κρυπτονομίσματά σας", "description": "Δείτε πώς τα χρήματά σας μπορούν να αυξηθούν με τον χρόνο, μετατρέποντας τα κρυπτονομίσματά σας σε mUSD.", - "description_with_amounts_prefix": "Convert your {{total}} in assets and you could earn up to", - "description_with_amounts_suffix": "in one year.", + "description_with_amounts_prefix": "Μετατρέψτε τα περιουσιακά σας στοιχεία αξίας {{total}} και μπορείτε να κερδίσετε έως και", + "description_with_amounts_suffix": "σε ένα έτος.", "convert": "Μετατροπή", - "convert_cta": "Convert your crypto", + "convert_cta": "Μετατρέψτε τα κρυπτονομίσματά σας", "no_fee": "Χωρίς χρεώσεις από το MetaMask", "view_all": "Προβολή όλων", "view_potential_earnings": "Δείτε τα πιθανά κέρδη" @@ -6649,41 +6744,44 @@ "cashback": "Απόδοση {{percentage}}% σε mUSD", "get_now": "Αποκτήστε την τώρα", "link_title": "Σύνδεση της MetaMask Card", - "link_subtitle": "Spend your Money balance and earn on purchases. Plus, up to {{apy}}% APY on your balance.", - "link_bullet_cashback": "Get {{percentage}}% mUSD back", - "link_bullet_apy": "Earn up to {{apy}}% APY", + "link_subtitle": "Ξοδέψτε το υπόλοιπο του λογαριασμού σας και κερδίστε από τις αγορές σας. Επιπλέον, έως και {{apy}}% APY στο υπόλοιπό σας.", + "link_subtitle_no_apy": "Spend your Money balance and earn on purchases.", + "link_bullet_cashback": "Κερδίστε {{percentage}}% mUSD ως επιστροφή", + "link_bullet_apy": "Κερδίστε έως και {{apy}}% APY", "link_card": "Σύνδεση κάρτας", - "link_pending_title": "Linking card", - "link_pending_description": "Approving spending limit…", - "link_success_title": "Card linked successfully", - "link_success_description": "You can now spend while you earn", - "link_error": "Couldn't link card", - "manage_card": "Manage", - "avail_balance": "Avail. balance" + "link_pending_title": "Linking your card", + "link_success_title": "Your card is ready to use", + "link_error": "Something went wrong linking your card", + "link_card_sheet_title": "Κάντε αγορές και κερδίστε", + "link_card_sheet_description": "Link your card so you can spend your Money balance and earn mUSD back on purchases—all while earning up to {{apy}}% APY.", + "link_card_sheet_description_no_apy": "Link your card so you can spend your Money balance and earn mUSD back on purchases.", + "link_card_sheet_cta": "Σύνδεση κάρτας", + "manage_card": "Διαχείριση", + "avail_balance": "Διαθέσιμο υπόλοιπο" }, "what_you_get": { "title": "Τι σας προσφέρει", - "benefit_auto_earn": "Auto-earn up to", + "benefit_auto_earn": "Αυτόματη απόδοση έως και", "benefit_dollar_backed": "Κρατήστε τα χρήματά σας ασφαλή σε mUSD, ένα stablecoin με αναλογία 1:1 σε δολάρια", "benefit_liquidity": "Πλήρης ρευστότητα χωρίς δεσμεύσεις, ώστε να μπορείτε να κάνετε συναλλαγές ή ανάληψη οποιαδήποτε στιγμή", "benefit_spend_prefix": "Κάντε αγορές με τη MetaMask Card σε 150M+ σημεία και κερδίστε ", "benefit_spend_cashback": "1-3% απόδοση σε mUSD", - "benefit_transfer": "Transfer to any of your wallets across MetaMask", - "benefit_global": "Send and receive funds globally", + "benefit_transfer": "Μεταφορά σε οποιοδήποτε από τα πορτοφόλια σας στο MetaMask", + "benefit_global": "Στείλτε και λάβετε κεφάλαια παγκοσμίως", "learn_more": "Μάθετε περισσότερα" }, "footer": { - "add_money": "Add funds" + "add_money": "Προσθήκη κεφαλαίων" }, "add_money_sheet": { - "title": "Add funds", + "title": "Προσθήκη κεφαλαίων", "convert_crypto": "Μετατροπή κρυπτονομισμάτων", - "convert_crypto_description": "From any account", + "convert_crypto_description": "Από οποιονδήποτε λογαριασμό", "deposit_funds": "Κατάθεση χρημάτων", - "deposit_funds_description": "From debit card or bank", - "move_musd": "Transfer your {{amount}} mUSD", - "move_musd_no_amount": "Transfer your mUSD", - "move_musd_description": "From your balance", + "deposit_funds_description": "Από χρεωστική κάρτα ή τραπεζικό λογαριασμό", + "move_musd": "Μεταφέρετε {{amount}} mUSD", + "move_musd_no_amount": "Μεταφέρετε mUSD", + "move_musd_description": "Από το διαθέσιμο υπόλοιπό σας", "receive_external": "Λήψη από εξωτερικό πορτοφόλι", "coming_soon": "Προσεχώς" }, @@ -6694,7 +6792,7 @@ "contact_support": "Επικοινωνία με την υποστήριξη" }, "transfer_sheet": { - "title": "Transfer funds", + "title": "Μεταφορά κεφαλαίων", "between_accounts": "Μεταξύ λογαριασμών", "perps_account": "Λογαριασμός Perps", "predictions_account": "Λογαριασμός προβλέψεων", @@ -6712,8 +6810,8 @@ "body": "Μια εκτίμηση για το πόσα θα μπορούσατε να κερδίσετε σε μια χρονική περίοδο, με βάση το τρέχον υπόλοιπό σας και το σημερινό APY. Οι εκτιμήσεις δεν αποτελούν εγγυημένες αποδόσεις και ενδέχεται να αλλάξουν." }, "earn_crypto_info_sheet": { - "title": "Earn on your crypto", - "body": "Illustration assumes {{percentage}}% Annual Percentage Yield (APY) remains unchanged for one year. APY is variable and may change due to various factors. No guarantee of return." + "title": "Κερδίστε από τα κρυπτονομίσματά σας", + "body": "Η απεικόνιση υποθέτει ότι το {{percentage}}% ετήσιο επιτόκιο (APY) παραμένει αμετάβλητο για ένα έτος. Το APY μεταβάλλεται και μπορεί να αλλάξει λόγω διαφόρων παραγόντων. Δεν υπάρχει εγγύηση απόδοσης." }, "activity": { "title": "Δραστηριότητα", @@ -6725,7 +6823,7 @@ }, "condensed_cards": { "how_it_works_title": "Πώς λειτουργεί", - "how_it_works_subtitle": "Δείτε πώς τα χρήματά σας αποδίδουν για εσάς", + "how_it_works_subtitle": "See how your money can grow", "musd_title": "MetaMask USD", "musd_subtitle": "Μάθετε περισσότερα για το mUSD", "what_you_get_title": "Τι σας προσφέρει", @@ -6738,7 +6836,8 @@ "sent": "Εστάλη", "transferred": "Μεταφέρθηκε", "card_transaction": "Συναλλαγή με κάρτα", - "converted": "Μετατράπηκε" + "converted": "Μετατράπηκε", + "failed": "Απέτυχε" }, "convert_stablecoins": { "title": "Μετατρέψτε τα stablecoins σας", @@ -6757,11 +6856,11 @@ "how_it_works_page": { "header_title": "Οικονομικά", "section_title": "Πώς λειτουργεί", - "description_1": "Deposit mUSD into your Money account and earn up to {{percentage}}% APY (variable) automatically. Funds go into a DeFi vault that generates returns across audited lending markets—no staking, no claiming, no lock-ups.", + "description_1": "Καταθέστε mUSD στον λογαριασμό σας και κερδίστε έως και {{percentage}}% APY (μεταβλητό) αυτόματα. Τα κεφάλαια τοποθετούνται σε ένα DeFi vault που παράγει αποδόσεις μέσω ελεγμένων αγορών δανεισμού — χωρίς δέσμευση κεφαλαίων, χωρίς απαιτήσεις, χωρίς χρονικές δεσμεύσεις.", "description_2": "Το υπόλοιπο του λογαριασμού σας είναι το διαθέσιμο υπόλοιπο για δαπάνες. Συνδέστε την MetaMask Card για να πραγματοποιείτε συναλλαγές σε περισσότερους από 150 εκατομμύρια εμπόρους παγκοσμίως. Τα χρήματά σας συνεχίζουν να αποδίδουν μέχρι τη στιγμή που θα τα χρησιμοποιήσετε.", - "faq_title": "Frequently asked questions", + "faq_title": "Συχνές ερωτήσεις", "faq_placeholder_answer": "Προσεχώς.", - "faq_q1": "How does the {{percentage}}% APY work?", + "faq_q1": "Πώς λειτουργεί το {{percentage}}% APY;", "faq_q2": "Τι είναι τα mUSD;", "faq_q3": "Από πού προέρχεται η απόδοση;", "faq_q4": "Είναι τα χρήματά μου δεσμευμένα; Μπορώ να κάνω ανάληψη οποιαδήποτε στιγμή;", @@ -7030,11 +7129,12 @@ "confirm": "Επιβεβαίωση", "pay_with_bottom_sheet": { "title": "Πληρωμή με", - "last_used": "Last used", - "crypto": "Crypto", - "available_balance": "{{balance}} available", - "other_assets": "Other assets", - "other_assets_description": "Select from your tokens" + "last_used": "Τελευταία χρήση", + "bank_and_card": "Τραπεζικός λογαριασμός και κάρτα", + "crypto": "Κρύπτο", + "available_balance": "{{balance}} διαθέσιμα", + "other_assets": "Άλλα περιουσιακά στοιχεία", + "other_assets_description": "Επιλέξτε από τα tokens σας" }, "staking_footer": { "part1": "Συνεχίζοντας, συμφωνείτε με τους ", @@ -7120,7 +7220,7 @@ "transaction_fee": "Τα τέλη μετατροπής σε mUSD περιλαμβάνουν τα έξοδα δικτύου και ενδέχεται να περιλαμβάνουν τα τέλη παρόχου. Δεν υπάρχει χρέωση στο MetaMask όταν μετατρέπετε σε mUSD." }, "money_account_withdraw": { - "transaction_fee": "MetaMask will swap your mUSD for your desired token. Swap providers may charge a fee, but MetaMask won't." + "transaction_fee": "Το MetaMask θα ανταλλάξει τα mUSD σας με το token που επιθυμείτε. Οι πάροχοι ανταλλαγών ενδέχεται να χρεώνουν προμήθεια, αλλά το MetaMask όχι." }, "title": { "transaction_fee": "Τέλη" @@ -7225,7 +7325,7 @@ "deposit_edit_amount_done": "Προσθήκη κεφαλαίων", "deposit_edit_amount_predict_withdraw": "Ανάληψη", "deposit_edit_amount_musd_conversion": "Μετατροπή σε mUSD", - "preparing_order": "Preparing order" + "preparing_order": "Προετοιμασία εντολής" }, "change_in_simulation_modal": { "title": "Τα αποτελέσματα έχουν αλλάξει", @@ -7250,20 +7350,33 @@ "confirm_swap": "Ανταλλαγή", "terms_and_conditions": "Όροι & Προϋποθέσεις", "select_token": "Επιλέξτε token", - "batch_sell_select_title": "Select up to 5 tokens", - "batch_sell_select_subtitle": "All tokens need to be on the same network.", - "batch_sell_empty_state_title": "No tokens. No problem.", - "batch_sell_empty_state_description": "No tokens. No problem. Explore and buy tokens to batch sell.", - "batch_sell_continue_with_one_token": "Continue with (1) token", - "batch_sell_continue_with_tokens": "Continue with ({{tokenCount}}) tokens", - "batch_sell_max_tokens_allowed": "Max 5 tokens allowed", - "batch_sell_single_token_dialog_title": "High rate alert", - "batch_sell_single_token_dialog_description": "Batch selling one token could lead to a higher rate. Want to do a swap instead?", - "batch_sell_swap_instead": "Yes, swap", - "batch_sell_checkbox_label": "Batch Sell token", - "sort_balance": "Balance", - "next": "Next", - "explore_tokens": "Explore tokens", + "batch_sell_select_title": "Επιλέξτε έως 5 tokens", + "batch_sell_select_subtitle": "Όλα τα tokens πρέπει να βρίσκονται στο ίδιο δίκτυο.", + "batch_sell_empty_state_title": "Δεν έχετε tokens. Κανένα πρόβλημα.", + "batch_sell_empty_state_description": "Δεν έχετε tokens. Κανένα πρόβλημα. Εξερευνήστε και αγοράστε tokens για μαζική πώληση.", + "batch_sell_continue_with_one_token": "Συνεχίστε με (1) token", + "batch_sell_continue_with_tokens": "Συνεχίστε με ({{tokenCount}}) tokens", + "batch_sell_max_tokens_allowed": "Επιτρέπονται έως 5 tokens", + "batch_sell_single_token_dialog_title": "Ειδοποίηση υψηλής μεταβλητότητας", + "batch_sell_single_token_dialog_description": "Η μαζική πώληση ενός token μπορεί να οδηγήσει σε υψηλότερη τιμή. Θέλετε να κάνετε ανταλλαγή αντί γι' αυτό;", + "batch_sell_swap_instead": "Ναι, ανταλλαγή", + "batch_sell_review_title": "Επισκόπηση μαζικής πώλησης", + "batch_sell_select_stablecoin": "Επιλέξτε ένα stablecoin", + "batch_sell_total_received": "Συνολικό ποσό που λάβατε", + "batch_sell_minimum_received": "Minimum received", + "batch_sell_quote_details_row": "{{tokenSymbol}} • {{slippage}} slippage", + "batch_sell_review": "Επισκόπηση", + "batch_sell_you_sell": "You sell", + "batch_sell_token_count": "{{tokenCount}} tokens", + "batch_sell_toggle_you_sell": "Toggle token details", + "batch_sell_sell_all": "Sell all", + "batch_sell_includes_metamask_fee": "Includes {{fee}}% MetaMask fee", + "batch_sell_customize_token": "Προσαρμογή {{tokenSymbol}}", + "batch_sell_remove_token": "Αφαίρεση του {{tokenSymbol}}", + "batch_sell_checkbox_label": "Μαζική πώληση token", + "sort_balance": "Υπόλοιπο", + "next": "Επόμενο", + "explore_tokens": "Εξερευνήστε tokens", "no_tokens_found": "Δεν βρέθηκαν token", "no_tokens_found_description": "Δεν βρέθηκαν token με αυτό το όνομα “{}”. Δοκιμάστε άλλη αναζήτηση.", "select_network": "Επιλέξτε δίκτυο", @@ -7332,6 +7445,7 @@ "price_impact_execution_description": "Θα χάσετε περίπου {{priceImpact}} από την αξία του token σας σε αυτή την ανταλλαγή. Προσπαθήστε να μειώσετε το ποσό ή να επιλέξετε ένα κανάλι με μεγαλύτερη ρευστότητα.", "proceed": "Συνεχίστε", "cancel": "Άκυρο", + "close": "Κλείσιμο", "slippage_info_title": "Απόκλιση", "slippage_info_description": "Το ποσοστό μεταβολής στην τιμή που είστε διατεθειμένοι να αποδεχθείτε πριν ακυρωθεί η συναλλαγή.", "blockaid_error_title": "Αυτή η συναλλαγή θα ακυρωθεί", @@ -8107,7 +8221,14 @@ "retry": "Προσπαθήστε ξανά", "on_linea": "στο δίκτυο Linea", "account_label": "Λογαριασμός", - "token_label": "Token" + "token_label": "Token", + "money_account_label": "Money account", + "money_account_token_symbol": "mUSD", + "use_money_account_cta": "Use Money account", + "spend_and_earn_title": "Spend while you earn", + "spend_and_earn_description": "Spend with your Money account and earn up to {{apy}}% APY on your balance. Also get {{cashback}}% mUSD back.", + "spend_and_earn_description_no_apy": "Spend with your Money account and earn APY on your balance. Also get {{cashback}}% mUSD back.", + "spend_and_earn_cta": "Link to Money account" }, "cashback_screen": { "title": "Απόδοση σε mUSD", @@ -8449,6 +8570,7 @@ "show_less": "Εμφάνιση λιγότερων", "linking_progress": "Προσθήκη λογαριασμών… ({{current}}/{{total}})", "accounts_linked_count": "{{linked}}/{{total}} εγγεγραμμένοι", + "accounts_added": "Accounts added", "add_all_accounts": "Προσθήκη όλων των λογαριασμών", "environment_selector": "Περιβάλλον", "environment_cancel": "Άκυρο", @@ -8473,15 +8595,22 @@ }, "optout": { "title": "Διαγραφή προόδου Ανταμοιβών", - "description": "Αυτό θα αφαιρέσει τους λογαριασμούς σας από το πρόγραμμα Ανταμοιβών και θα διαγράψει την πρόοδό σας. Δεν θα μπορείτε να το αναιρέσετε.", - "confirm": "Διαγραφή", + "description": "This will remove your accounts from the Rewards program and your progress in any campaigns you've joined. Only do this if you are absolutely sure you want to erase your progress.", + "erase_button": "Erase progress", "modal": { "confirmation_title": "Είστε σίγουροι;", - "confirmation_description": "Αυτό θα διαγράψει όλη την πρόοδό σας και δεν μπορεί να αναιρεθεί. Αν επανέλθετε αργότερα στο πρόγραμμα Ανταμοιβών, θα ξεκινήσετε από το 0.", + "confirmation_description": "This will erase all your progress, and can't be reversed. If you rejoin the Rewards program later, you'll start back at 0.", + "type_to_confirm": "Type 'erase progress' to continue", + "confirm_phrase": "erase progress", "cancel": "Άκυρο", "confirm": "Επιβεβαίωση", + "error_title": "Κάτι πήγε στραβά", "error_message": "Αποτυχία αποχώρησης από το πρόγραμμα Ανταμοιβών. Παρακαλούμε προσπαθήστε ξανά.", "processing": "Επεξεργασία..." + }, + "request_received": { + "title": "Request received", + "description": "In about 7 days, your progress will be fully erased. If you made this request by mistake, please contact support through the app." } }, "toast_dismiss": "Απόρριψη", @@ -8569,7 +8698,8 @@ "title_claim": "Εξαργύρωση ανταμοιβών", "action": "Εξαργύρωση", "empty-list": "Δεν έχετε διαθέσιμες ανταμοιβές αυτή τη στιγμή.", - "powered_by": "Με την υποστήριξη του" + "powered_by": "Με την υποστήριξη του", + "available_count": "{{count}} διαθέσιμα" }, "end_of_season_rewards": { "confirm_label_default": "Επιβεβαίωση", @@ -8887,9 +9017,11 @@ "musd_claim": "Κάντε εξαργύρωση σε mUSD", "perps_deposit": "Προσθήκη κεφαλαίων", "perps_withdraw": "Ανάληψη", + "predict_withdraw": "Ανάληψη {{sourceSymbol}} από {{sourceChain}}", "predict_deposit": "Προσθήκη κεφαλαίων", "swap": "Ανταλλαγή tokens", - "swap_approval": "Έγκριση token" + "swap_approval": "Έγκριση token", + "fiat_purchase": "Αγορά {{token}} με {{paymentMethod}}" }, "perps_deposit_solution": "Έχετε πλέον {{fiat}} σε USDC στο Arbitrum. Δοκιμάστε ξανά να κάνετε κατάθεση." }, @@ -8965,7 +9097,7 @@ "high_to_low": "Από το υψηλότερο στο χαμηλότερο", "low_to_high": "Από το χαμηλότερο στο υψηλότερο", "apply": "Εφαρμογή", - "search_placeholder": "Αναζήτηση token, ιστότοπων, διευθύνσεων URL", + "search_placeholder": "Search tokens, markets and URLs", "cancel": "Άκυρο", "perps": "Συμβ.αορ.", "rwa_perps_section": "Συμβ.αορ.", @@ -8978,11 +9110,15 @@ "crypto_perps_section": "Συμβ.αορ.", "predictions": "Προβλέψεις", "no_results": "Δεν βρέθηκαν αποτελέσματα", + "no_results_for_feed": "No {{feedName}} results for \"{{query}}\"", + "showing_all_results_for": "We found these results for \"{{query}}\"", "popular": "Δημοφιλή", "sites": "Ιστότοποι", "popular_sites": "Δημοφιλείς ιστότοποι", "search_sites": "Αναζήτηση ιστότοπων", "view_all": "Προβολή όλων", + "view_more": "Δείτε περισσότερα", + "view_x_more": "View {{count}} more", "enable_basic_functionality": "Ενεργοποίηση βασικής λειτουργικότητας", "basic_functionality_disabled_title": "Η Εξερεύνηση δεν είναι διαθέσιμη", "basic_functionality_disabled_description": "Δεν είναι δυνατή η ανάκτηση των απαιτούμενων μεταδεδομένων όταν η βασική λειτουργικότητα είναι απενεργοποιημένη.", @@ -9002,6 +9138,14 @@ "crypto": "Κρύπτο", "sports": "Αθλητικά", "dapps": "Ιστότοποι" + }, + "search_tabs": { + "all": "Όλα", + "crypto": "Cryptos", + "perps": "Συμβ.αορ.", + "stocks": "Μετοχές", + "predictions": "Προβλέψεις", + "sites": "Ιστότοποι" } }, "ota_update_modal": { @@ -9139,6 +9283,7 @@ "money_empty_description_network_filter": "Δεν έχετε mUSD σε αυτό το δίκτυο. Αλλάξτε δίκτυο για να δείτε τα mUSD σας.", "money_empty_state": { "get_started": "Ξεκινήστε", + "earn": "Κερδίστε", "earn_apy": "Κερδίστε {{percentage}}% APY" }, "money_filled_state": { @@ -9150,22 +9295,7 @@ "related_assets": "Σχετικά περιουσιακά στοιχεία", "perpetuals": "Συμβόλαια αορίστου διάρκειας", "predictions": "Προβλέψεις", - "whats_happening": "Τι συμβαίνει", - "whats_happening_ai": "AI", - "whats_happening_impact": { - "bullish": "Ανοδικό", - "bearish": "Πτωτικό", - "neutral": "Ουδέτερο" - }, "top_traders": "Κορυφαίοι Traders", - "whats_happening_categories": { - "geopolitical": "Γεωπολιτικά", - "macro": "Μακροοικονομικά", - "regulatory": "Κανονισμοί", - "technical": "Τεχνικά", - "social": "Κοινωνικά", - "other": "Άλλο" - }, "defi": "DeFi", "nfts": "NFT", "trending_tokens": "Δημοφιλή", @@ -9185,5 +9315,22 @@ }, "sites": { "popular": "Δημοφιλή" + }, + "whats_happening": { + "title": "Τι συμβαίνει", + "ai": "AI", + "impact": { + "bullish": "Ανοδικό", + "bearish": "Πτωτικό", + "neutral": "Ουδέτερο" + }, + "categories": { + "geopolitical": "Γεωπολιτικά", + "macro": "Μακροοικονομικά", + "regulatory": "Κανονισμοί", + "technical": "Τεχνικά", + "social": "Κοινωνικά", + "other": "Άλλο" + } } } diff --git a/locales/languages/en.json b/locales/languages/en.json index 8222bcdca86..e707e2f48a1 100644 --- a/locales/languages/en.json +++ b/locales/languages/en.json @@ -5282,6 +5282,11 @@ "title": "Nothing to see here", "message": "This is where you can find notifications once there’s activity in your wallet. " }, + "disabled": { + "title": "Turn on notifications", + "message": "Choose what you're notified about and how.", + "cta": "Notification settings" + }, "list": { "0": "All", "1": "Wallet", @@ -6719,16 +6724,25 @@ "apy_currency_suffix": " • mUSD", "apy_info_label": "APY info", "onboarding": { - "step_progress": "Step {{current}} of {{total}}", - "title": "Add money", - "description": "Fund your account and start earning APY.", - "add": "Add funds", - "step2_title": "Get your MetaMask Card", - "step2_description": "Spend your Money balance while it earns, anywhere Mastercard is accepted.", - "step2_cta": "Get card", - "link_card_title": "Link your MetaMask Card", - "link_card_description": "Spend your balance while it earns, anywhere Mastercard is accepted.", - "link_card_cta": "Link card" + "step_1": { + "title": "Fund your account", + "description": "Drop in some funds. Your Money account will handle the rest.", + "cta": "Add funds" + }, + "step_2": { + "no_card_account": { + "title": "Get your MetaMask Card", + "description": "Spend your balance while it earns, anywhere Mastercard is accepted.", + "cta_primary": "Get card", + "cta_secondary": "Skip" + }, + "unlinked_card_account": { + "title": "Link your MetaMask Card", + "description": "Spend your balance while it earns, anywhere Mastercard is accepted.", + "cta_primary": "Link card", + "cta_secondary": "Skip" + } + } }, "rive_onboarding": { "step1_title": "Money accounts are here", @@ -9390,5 +9404,8 @@ "social": "Social", "other": "Other" } + }, + "stepper_card": { + "more_information": "More information" } } diff --git a/locales/languages/es.json b/locales/languages/es.json index c68181c49d7..15b1f83a409 100644 --- a/locales/languages/es.json +++ b/locales/languages/es.json @@ -120,6 +120,10 @@ "account_no_funds": { "message": "No hay fondos disponibles. Usa otra cuenta." }, + "headless_buy_error": { + "title": "Error en la compra de moneda fiduciaria", + "message": "Se produjo un error en tu compra de moneda fiduciaria. Inténtalo de nuevo." + }, "mmpay_hardware_account": { "title": "Billetera no admitida", "message": "Las billeteras físicas no son compatibles.\nCambia de billetera para continuar." @@ -133,8 +137,8 @@ "message": "Es posible que la dirección del destinatario no admita transferencias directas de tokens, lo que podría provocar la pérdida de fondos. Continúa solo si estás seguro de que este contrato puede recibir tu transferencia." }, "gas_sponsorship_reserve_balance": { - "message": "El patrocinio de gas no está disponible para esta transacción. Deberás mantener al menos %{minBalance} %{nativeTokenSymbol} en tu cuenta.", - "title": "Patrocinio de gas no disponible" + "message": "Esta red en concreto requiere mantener una reserva de %{minBalance} %{nativeTokenSymbol} en tu cuenta.", + "title": "Se requiere un saldo de reserva" }, "token_trust_signal": { "malicious": { @@ -708,6 +712,9 @@ "contractAddressError": "Estás enviando tokens a la dirección del contrato del token. Esto podría resultar en la pérdida de estos tokens.", "smart_contract_address": "Dirección del contrato inteligente", "smart_contract_address_warning": "Es posible que la dirección del destinatario no admita transferencias directas de tokens, lo que podría provocar la pérdida de fondos. Continúa solo si estás seguro de que este contrato puede recibir tu transferencia.", + "unavailable_network_connection": "Unavailable network connection", + "unavailable_network_connection_description": "The connection with {{network}} is unreliable. Update network connectivity details before continuing or try again later.", + "update": "Actualizar", "i_understand": "Comprendo", "cancel": "Cancelar", "new_address_title": "Nueva dirección", @@ -1068,7 +1075,7 @@ "sort": { "value": "Valor", "pnl_percent": "P&L %", - "recent": "Recent" + "recent": "Recientes" } }, "trader_position": { @@ -1120,6 +1127,11 @@ "title": "Opera con contratos perpetuos de {{symbol}}", "subtitle": "Multiplica tus pérdidas y ganancias hasta {{leverage}}" }, + "service_interruption": { + "title": "We're experiencing an outage", + "description": "Some services may be unavailable while the team works on a fix.", + "contact_support": "Contactar a soporte" + }, "today": "Hoy", "yesterday": "Ayer", "unrealized_pnl": "P&L no realizado", @@ -1284,7 +1296,9 @@ "toast_completed_subtitle": "Se han transferido {{amount}} USDC a tu billetera", "toast_completed_any_token_subtitle": "Se transfirieron {{amount}} {{token}} a tu billetera", "toast_error_title": "Algo salió mal", - "toast_error_description": "Error al procesar el retiro" + "toast_error_description": "Error al procesar el retiro", + "toast_start_error_description": "Your withdrawal wasn’t started.", + "try_again": "Inténtalo de nuevo" }, "quote": { "network_fee": "Tarifa de red", @@ -2227,35 +2241,35 @@ "predict": { "title": "Predicciones de MetaMask", "world_cup": { - "title": "World Cup", - "banner_title": "World Cup 2026", - "banner_description": "Trade on World Cup markets", + "title": "Copa del Mundo", + "banner_title": "Copa del Mundo 2026", + "banner_description": "Trade every match, every moment.", "tabs": { - "all": "All", - "props": "Props", - "live": "Live" + "all": "Todas", + "props": "Apuestas especiales", + "live": "En vivo" }, "stages": { - "group_stage": "Group Stage", - "round_of_32": "Round of 32", - "round_of_16": "Round of 16", - "quarterfinals": "Quarterfinals", - "semifinals": "Semifinals", - "third_place": "Third Place", + "group_stage": "Fase de grupos", + "round_of_32": "Dieciseisavos de final", + "round_of_16": "Octavos de final", + "quarterfinals": "Cuartos de final", + "semifinals": "Semifinales", + "third_place": "Tercer puesto", "final": "Final", - "group_a": "Group A", - "group_b": "Group B", - "group_c": "Group C", - "group_d": "Group D", - "group_e": "Group E", - "group_f": "Group F", - "group_g": "Group G", - "group_h": "Group H", - "group_i": "Group I", - "group_j": "Group J", - "group_k": "Group K", - "group_l": "Group L", - "third_place_match": "Third Place Match" + "group_a": "Grupo A", + "group_b": "Grupo B", + "group_c": "Grupo C", + "group_d": "Grupo D", + "group_e": "Grupo E", + "group_f": "Grupo B", + "group_g": "Grupo G", + "group_h": "Grupo H", + "group_i": "Grupo I", + "group_j": "Grupo J", + "group_k": "Grupo K", + "group_l": "Grupo L", + "third_place_match": "Partido por el tercer puesto" } }, "prediction_markets": "Mercados de predicción", @@ -2537,8 +2551,8 @@ "withdraw_completed": "Retiro finalizado", "withdraw_completed_subtitle": "Se han transferido {{amount}} USDC a tu billetera", "withdraw_any_token_completed_subtitle": "Se transfirieron {{amount}} {{token}} a tu billetera", - "unavailable_title": "Withdrawals temporarily unavailable", - "unavailable_description": "For urgent assistance, please contact Customer Service.", + "unavailable_title": "Retiros temporalmente no disponibles", + "unavailable_description": "Para asistencia urgente, comuníquese con el servicio al cliente.", "unavailable_got_it": "Entendido", "error_title": "Algo salió mal", "error_description": "No se pudo proceder con el retiro", @@ -2941,6 +2955,17 @@ "pna25_confirm_button": "Aceptar y cerrar", "pna25_open_settings_button": "Abrir Configuración" }, + "onboarding_interest_questionnaire": { + "title": "¿Qué deseas hacer con MetaMask?", + "description": "Selecciona todas las opciones que correspondan.", + "option_buy_and_sell_crypto": "Comprar y vender criptomonedas", + "option_consolidate_wallets": "Consolidar tus billeteras", + "option_advanced_trades": "Realizar operaciones avanzadas", + "option_predict_sports_events": "Predecir resultados deportivos y eventos", + "option_crypto_as_money": "Usar criptomonedas como dinero", + "option_connect_apps_sites": "Conectarse a aplicaciones o sitios web", + "continue": "Continuar" + }, "template_confirmation": { "ok": "OK", "cancel": "Cancelar" @@ -3261,8 +3286,27 @@ "notifications_desc": "Administre sus notificaciones", "allow_notifications": "Permitir notificaciones", "enable_push_notifications": "Activar notificaciones push", - "allow_notifications_desc": "Manténgase informado sobre lo que sucede en su billetera con notificaciones. Para usar notificaciones, usamos un perfil para sincronizar algunas configuraciones en sus dispositivos.", + "allow_notifications_desc": "Choose what you're notified about and how.", "notifications_opts": { + "preferences_title": "Preferences", + "push_recommended": "Push", + "in_app": "In-app", + "status_push": "Push", + "status_in_app": "In app", + "status_off": "Desact.", + "select_all": "Seleccionar todo", + "deselect_all": "Deseleccionar todo", + "select_accounts_title": "Cuentas", + "select_accounts_desc": "Choose which accounts you'd like to get notifications for.", + "wallet_activity_title": "Wallet Activity", + "wallet_activity_desc": "Buy, sells, transfers, swaps and rewards", + "perps_title": "Trading Activity", + "perps_desc": "Perps position changes, liquidations, funding rates, and margin updates", + "social_ai_title": "Trading Signals", + "social_ai_desc": "Updates from traders and assets you follow, plus currated market news", + "marketing_title": "Updates and Rewards", + "marketing_desc": "Product updates, feature announcements, and new releases", + "marketing_disclaimer": "By turning this on, you agree to receive product news and marketing updates from MetaMask.", "customize_session_title": "Personalice sus notificaciones", "customize_session_desc": "Active los tipos de notificaciones que desea recibir:", "account_session_title": "Actividad de la cuenta", @@ -3276,8 +3320,7 @@ "snaps_title": "Snaps", "snaps_desc": "Nuevas características y actualizaciones", "products_announcements_title": "Anuncios de producto", - "products_announcements_desc": "Nuevos productos y características", - "perps_title": "Trading con contratos perpetuos" + "products_announcements_desc": "Nuevos productos y características" }, "contacts_title": "Contactos", "contacts_desc": "Agregar, editar, quitar y administrar tus cuentas.", @@ -3640,7 +3683,15 @@ "card": { "title": "Tarjeta", "reset_onboarding_description": "Restablecer el estado de incorporación de la tarjeta para iniciar el proceso de incorporación desde el principio.", - "reset_onboarding_button": "Restablecer estado de incorporación" + "reset_onboarding_button": "Restablecer estado de incorporación", + "unlink_money_account_description": "Revocar el límite de gasto de USDC que autoriza a la Tarjeta a gastar desde tu cuenta Finanzas. Esto envía una transacción approve(0) y marca la cuenta Finanzas como no delegada en el backend de la Tarjeta.", + "unlink_money_account_button": "Desvincular la cuenta Finanzas de la tarjeta", + "unlink_money_account_disabled_hint": "No hay ninguna vinculación activa para eliminar." + }, + "identity": { + "title": "Identity", + "description": "Clears the persisted authentication session. Use this after toggling MM_DEV_API_ENV — otherwise a prod-minted JWT keeps being handed to dev-API consumers until it expires. Current MM_DEV_API_ENV: {{env}}.", + "clear_auth_session_button": "Clear persisted auth session" }, "haptics": { "title": "Háptica", @@ -3842,8 +3893,8 @@ "predict_button": "Predicciones", "add_collectible_button": "Agregar", "info": "Información", - "batch_sell": "Batch Sell", - "batch_sell_new_label": "New", + "batch_sell": "Venta por lotes", + "batch_sell_new_label": "Nuevo", "swap": "Canjear", "convert": "Convertir", "bridge": "Puentear", @@ -3883,7 +3934,7 @@ "troubleshoot": "Solucionar problemas", "deposit_description": "Transferencia bancaria o con tarjeta con tarifas bajas", "buy_description": "Ideal para comprar un token específico", - "batch_sell_description": "Sell up to 5 tokens for a stablecoin", + "batch_sell_description": "Vende hasta 5 tokens por una moneda estable", "sell_description": "Vender cripto por dinero en efectivo", "swap_description": "Cambiar entre tokens", "bridge_description": "Transferir tokens entre redes", @@ -5205,6 +5256,34 @@ "manage_preferences_2": "Configuración > Notificaciones.", "cancel": "Cancelar", "cta": "Activar" + }, + "push_onboarding": { + "new_user": { + "title": "No te pierdas ningún movimiento", + "body": "Recibe alertas en tiempo real cuando los precios alcancen tus objetivos, se confirmen tus operaciones y se mueva tu portafolio. Además de actualizaciones de productos y recompensas mientras tanto. Compartiremos actualizaciones basadas en tus interacciones con MetaMask.", + "button_yes": "Sí", + "button_not_now": "Ahora no", + "preview_card_1": { + "eyebrow": "METAMASK", + "time": "ahora", + "title": "ETH ha subido un 4,2 % hoy", + "message": "Ahora está en $2668,51 — por encima de tu alerta de precio" + }, + "preview_card_2": { + "eyebrow": "METAMASK", + "time": "Hace 1 h", + "title": "Recibiste 0,25 ETH", + "message": "Desde 0x9a21…4f8c · $640,29" + } + }, + "existing_user": { + "title": "Presentamos las alertas personalizadas", + "body": "Recibe notificaciones que se adapten a tu forma de operar. Actualízalas en cualquier momento.", + "card_title": "Lo que recibirás", + "card_description": "Alertas personalizadas y actualizaciones adaptadas a tu actividad de trading.", + "button_confirm": "Confirmar", + "button_not_now": "Ahora no" + } } }, "protect_your_wallet_modal": { @@ -5315,6 +5394,7 @@ "pay_with": "Pagar con", "buying_via": "Comprando a través de {{providerName}}.", "change_provider": "Cambiar de proveedor.", + "circuit_breaker_open": "This service is temporarily unavailable. Please try again in about 30 minutes.", "payment_error": "Se produjo un error. Inténtalo de nuevo.", "no_payment_methods_available": "No hay métodos de pago disponibles.", "error_fetching_quotes": "Se produjo un error. Inténtalo de nuevo.", @@ -6520,6 +6600,8 @@ "convert_to_musd": "Convertir a mUSD", "get_a_percentage_musd_bonus": "Obtén un bono del {{percentage}} % en mUSD", "convert": "Convertir", + "confirm": "Confirmar", + "convert_tooltip_description": "Convierte tus monedas estables a mUSD y gana hasta un {{percentage}} % de bono anualizado que puedes reclamar diariamente.", "fetching_quote": "Obteniendo cotización...", "you_convert": "Conviertes", "network_fee": "Tarifa de red", @@ -6597,7 +6679,7 @@ "step_progress": "Paso {{current}} de {{total}}", "title": "Agregar dinero", "description": "Deposita fondos en tu cuenta y empieza a ganar APY.", - "add": "Agregar", + "add": "Agregar fondos", "step2_title": "Obtén tu tarjeta MetaMask", "step2_description": "Gasta tu saldo de Money mientras genera ganancias, en cualquier lugar donde se acepte Mastercard.", "step2_cta": "Obtener la tarjeta", @@ -6605,6 +6687,19 @@ "link_card_description": "Gasta tu saldo mientras genera ganancias, en cualquier lugar donde se acepte Mastercard.", "link_card_cta": "Vincular tarjeta" }, + "rive_onboarding": { + "step1_title": "Ya llegaron las cuentas Finanzas", + "step1_body": "Gana hasta un {{percentage}} % de APY sobre tu saldo, disponible en toda tu billetera.", + "step1_footer_text": "El APY es variable y puede cambiar en cualquier momento.", + "step2_title": "Gana automáticamente", + "step2_body": "Transfiere monedas estables sin comisiones de cambio. Los fondos comienzan a generar ganancias de inmediato.", + "step2_footer_text": "Provided by Veda and Steakhouse Financial.", + "step3_title": "Gasta en cualquier lugar", + "step3_body": "Obtén hasta un {{percentage}} % de cashback en tus compras vinculando tu cuenta Finanzas a una tarjeta MetaMask.", + "step4_title": "Opera y gana en un solo lugar", + "step4_body": "Usa tu saldo de Finanzas para operar en MetaMask mientras sigues obteniendo rendimiento.", + "continue": "Continuar" + }, "action": { "add": "Agregar", "transfer": "Transferir", @@ -6618,8 +6713,8 @@ }, "how_it_works": { "title": "Cómo funciona", - "description_prefix": "Deposit mUSD into your Money account and earn up to", - "description_suffix": ". Your balance is dollar-backed and ready to spend, trade, or send anytime." + "description_prefix": "Deposita mUSD en tu cuenta Finanzas y gana hasta", + "description_suffix": ". Tu saldo está respaldado por dólares y disponible para gastar, operar o enviar en cualquier momento." }, "musd_row": { "add": "Agregar" @@ -6627,16 +6722,16 @@ "balance_card": { "label": "Saldo de Finanzas", "add": "Agregar", - "info_sheet_title": "Money balance", - "info_sheet_body": "Your dollar-backed mUSD balance that's always available to spend, send, or trade anytime. We don't calculate this into your total account balance.\n\nWithdrawals process immediately, subject to standard network confirmation times on the relevant blockchain. If liquidity is tight, there may be temporary delays." + "info_sheet_title": "Saldo de Finanzas", + "info_sheet_body": "Tu saldo de mUSD respaldado por dólares, siempre disponible para gastar, enviar u operar en cualquier momento. No lo incluimos en el saldo total de tu cuenta.\n\nLos retiros se procesan de inmediato, sujetos a los tiempos de confirmación estándar de la red en la cadena de bloques correspondiente. Si la liquidez es escasa, puede haber retrasos temporales." }, "potential_earnings": { "title": "Gana con tus criptomonedas", "description": "Descubre cómo tu dinero puede crecer con el tiempo al convertir tus criptomonedas a mUSD.", - "description_with_amounts_prefix": "Convert your {{total}} in assets and you could earn up to", - "description_with_amounts_suffix": "in one year.", + "description_with_amounts_prefix": "Convierte tu {{total}} en activos y podrías ganar hasta", + "description_with_amounts_suffix": "en un año.", "convert": "Convertir", - "convert_cta": "Convert your crypto", + "convert_cta": "Convierte tus criptomonedas", "no_fee": "Sin tarifa de MetaMask", "view_all": "Ver todo", "view_potential_earnings": "Ver ganancias potenciales" @@ -6649,41 +6744,44 @@ "cashback": "{{percentage}} % de mUSD de cashback", "get_now": "Obtener ahora", "link_title": "Vincular la tarjeta MetaMask", - "link_subtitle": "Spend your Money balance and earn on purchases. Plus, up to {{apy}}% APY on your balance.", - "link_bullet_cashback": "Get {{percentage}}% mUSD back", - "link_bullet_apy": "Earn up to {{apy}}% APY", + "link_subtitle": "Gasta tu saldo de Finanzas y gana con tus compras. Además, hasta un {{apy}} % de APY sobre tu saldo.", + "link_subtitle_no_apy": "Spend your Money balance and earn on purchases.", + "link_bullet_cashback": "Obtén un {{percentage}} % de mUSD de cashback", + "link_bullet_apy": "Gana hasta un {{apy}} % de APY", "link_card": "Vincular tarjeta", - "link_pending_title": "Linking card", - "link_pending_description": "Approving spending limit…", - "link_success_title": "Card linked successfully", - "link_success_description": "You can now spend while you earn", - "link_error": "Couldn't link card", - "manage_card": "Manage", - "avail_balance": "Avail. balance" + "link_pending_title": "Linking your card", + "link_success_title": "Your card is ready to use", + "link_error": "Something went wrong linking your card", + "link_card_sheet_title": "Gasta y gana", + "link_card_sheet_description": "Link your card so you can spend your Money balance and earn mUSD back on purchases—all while earning up to {{apy}}% APY.", + "link_card_sheet_description_no_apy": "Link your card so you can spend your Money balance and earn mUSD back on purchases.", + "link_card_sheet_cta": "Vincular tarjeta", + "manage_card": "Gestionar", + "avail_balance": "Saldo disponible" }, "what_you_get": { "title": "Lo que obtienes", - "benefit_auto_earn": "Auto-earn up to", + "benefit_auto_earn": "Gana automáticamente hasta", "benefit_dollar_backed": "Mantén tu dinero seguro en mUSD, una moneda estable respaldada por el dólar en una proporción de 1:1", "benefit_liquidity": "Obtén liquidez total sin bloqueos, para que puedas operar o retirar fondos en cualquier momento", "benefit_spend_prefix": "Gasta en más de 150 millones de comercios con la tarjeta MetaMask y gana ", "benefit_spend_cashback": "1-3 % de mUSD de cashback", - "benefit_transfer": "Transfer to any of your wallets across MetaMask", - "benefit_global": "Send and receive funds globally", + "benefit_transfer": "Transfiere a cualquiera de tus billeteras en MetaMask", + "benefit_global": "Envía y recibe fondos a nivel mundial", "learn_more": "Conozca más" }, "footer": { - "add_money": "Add funds" + "add_money": "Agregar fondos" }, "add_money_sheet": { - "title": "Add funds", + "title": "Agregar fondos", "convert_crypto": "Convertir criptomonedas", - "convert_crypto_description": "From any account", + "convert_crypto_description": "Desde cualquier cuenta", "deposit_funds": "Depositar fondos", - "deposit_funds_description": "From debit card or bank", - "move_musd": "Transfer your {{amount}} mUSD", - "move_musd_no_amount": "Transfer your mUSD", - "move_musd_description": "From your balance", + "deposit_funds_description": "Desde tarjeta de débito o banco", + "move_musd": "Transfiere tus {{amount}} mUSD", + "move_musd_no_amount": "Transfiere tus mUSD", + "move_musd_description": "Desde tu saldo", "receive_external": "Recibir desde una billetera externa", "coming_soon": "Próximamente" }, @@ -6694,7 +6792,7 @@ "contact_support": "Contactar a soporte" }, "transfer_sheet": { - "title": "Transfer funds", + "title": "Transfiere fondos", "between_accounts": "Entre cuentas", "perps_account": "Cuenta de Perps", "predictions_account": "Cuenta de Predicciones", @@ -6712,8 +6810,8 @@ "body": "Una estimación de cuánto podrías ganar durante un período determinado, basada en tu saldo actual y el APY de hoy. Las estimaciones no son rendimientos garantizados y están sujetas a cambios." }, "earn_crypto_info_sheet": { - "title": "Earn on your crypto", - "body": "Illustration assumes {{percentage}}% Annual Percentage Yield (APY) remains unchanged for one year. APY is variable and may change due to various factors. No guarantee of return." + "title": "Gana con tus criptomonedas", + "body": "La ilustración asume que el {{percentage}}% de rendimiento porcentual anual (APY) se mantiene sin cambios durante un año. El APY es variable y puede cambiar debido a diversos factores. No hay garantía de rendimiento." }, "activity": { "title": "Actividad", @@ -6725,7 +6823,7 @@ }, "condensed_cards": { "how_it_works_title": "Cómo funciona", - "how_it_works_subtitle": "Observa cómo tu dinero trabaja para ti", + "how_it_works_subtitle": "See how your money can grow", "musd_title": "MetaMask USD", "musd_subtitle": "Más información sobre mUSD", "what_you_get_title": "Lo que obtienes", @@ -6738,7 +6836,8 @@ "sent": "Enviado", "transferred": "Transferido", "card_transaction": "Transacción con tarjeta", - "converted": "Convertido" + "converted": "Convertido", + "failed": "Fallido" }, "convert_stablecoins": { "title": "Convierte tus monedas estables", @@ -6757,11 +6856,11 @@ "how_it_works_page": { "header_title": "Money", "section_title": "Cómo funciona", - "description_1": "Deposit mUSD into your Money account and earn up to {{percentage}}% APY (variable) automatically. Funds go into a DeFi vault that generates returns across audited lending markets—no staking, no claiming, no lock-ups.", + "description_1": "Deposita mUSD en tu cuenta Finanzas y gana hasta un {{percentage}} % de APY (variable) automáticamente. Los fondos se depositan en una bóveda DeFi que genera rendimientos en mercados de préstamos auditados: sin staking, sin reclamaciones, sin bloqueos.", "description_2": "Tu saldo Money es tu saldo para gastar. Vincula tu tarjeta MetaMask para comprar en más de 150 millones de comercios en todo el mundo. Tu dinero sigue generando intereses hasta el momento en que lo uses.", - "faq_title": "Frequently asked questions", + "faq_title": "Preguntas frecuentes", "faq_placeholder_answer": "Próximamente.", - "faq_q1": "How does the {{percentage}}% APY work?", + "faq_q1": "¿Cómo funciona el {{percentage}} % de APY?", "faq_q2": "¿Qué es mUSD?", "faq_q3": "¿De dónde proviene el rendimiento?", "faq_q4": "¿Mi dinero está bloqueado? ¿Puedo retirarlo en cualquier momento?", @@ -7030,11 +7129,12 @@ "confirm": "Confirmar", "pay_with_bottom_sheet": { "title": "Pagar con", - "last_used": "Last used", - "crypto": "Crypto", - "available_balance": "{{balance}} available", - "other_assets": "Other assets", - "other_assets_description": "Select from your tokens" + "last_used": "Último uso", + "bank_and_card": "Banco y tarjeta", + "crypto": "Cripto", + "available_balance": "{{balance}} disponible(s)", + "other_assets": "Otros activos", + "other_assets_description": "Selecciona entre tus tokens" }, "staking_footer": { "part1": "Al continuar, acepta nuestros ", @@ -7120,7 +7220,7 @@ "transaction_fee": "Las tarifas de conversión a mUSD incluyen costos de red y pueden incluir tarifas del proveedor. No se aplica ninguna tarifa de MetaMask al convertir a mUSD." }, "money_account_withdraw": { - "transaction_fee": "MetaMask will swap your mUSD for your desired token. Swap providers may charge a fee, but MetaMask won't." + "transaction_fee": "MetaMask canjeará tus mUSD por el token que desees. Los proveedores de canje pueden cobrar una comisión, pero MetaMask no." }, "title": { "transaction_fee": "Tarifas" @@ -7225,7 +7325,7 @@ "deposit_edit_amount_done": "Agregar fondos", "deposit_edit_amount_predict_withdraw": "Retirar", "deposit_edit_amount_musd_conversion": "Convertir a mUSD", - "preparing_order": "Preparing order" + "preparing_order": "Preparando orden" }, "change_in_simulation_modal": { "title": "Los resultados cambiaron", @@ -7250,20 +7350,33 @@ "confirm_swap": "Canjear", "terms_and_conditions": "Términos y condiciones", "select_token": "Seleccione un token", - "batch_sell_select_title": "Select up to 5 tokens", - "batch_sell_select_subtitle": "All tokens need to be on the same network.", - "batch_sell_empty_state_title": "No tokens. No problem.", - "batch_sell_empty_state_description": "No tokens. No problem. Explore and buy tokens to batch sell.", - "batch_sell_continue_with_one_token": "Continue with (1) token", - "batch_sell_continue_with_tokens": "Continue with ({{tokenCount}}) tokens", - "batch_sell_max_tokens_allowed": "Max 5 tokens allowed", - "batch_sell_single_token_dialog_title": "High rate alert", - "batch_sell_single_token_dialog_description": "Batch selling one token could lead to a higher rate. Want to do a swap instead?", - "batch_sell_swap_instead": "Yes, swap", - "batch_sell_checkbox_label": "Batch Sell token", - "sort_balance": "Balance", - "next": "Next", - "explore_tokens": "Explore tokens", + "batch_sell_select_title": "Selecciona hasta 5 tokens", + "batch_sell_select_subtitle": "Todos los tokens deben estar en la misma red.", + "batch_sell_empty_state_title": "¿No tienes tokens? No hay problema.", + "batch_sell_empty_state_description": "No tienes tokens. No hay problema. Explora y compra tokens para venderlos en lote.", + "batch_sell_continue_with_one_token": "Continuar con (1) token", + "batch_sell_continue_with_tokens": "Continuar con ({{tokenCount}}) tokens", + "batch_sell_max_tokens_allowed": "Se permite un máximo de 5 tokens", + "batch_sell_single_token_dialog_title": "Alerta de tasa alta", + "batch_sell_single_token_dialog_description": "La venta en lote de un token podría generar una tasa más alta. ¿Prefieres hacer un canje?", + "batch_sell_swap_instead": "Sí, canjear", + "batch_sell_review_title": "Revisión de venta en lote", + "batch_sell_select_stablecoin": "Selecciona una moneda estable", + "batch_sell_total_received": "Total recibido", + "batch_sell_minimum_received": "Minimum received", + "batch_sell_quote_details_row": "{{tokenSymbol}} • {{slippage}} slippage", + "batch_sell_review": "Revisar", + "batch_sell_you_sell": "You sell", + "batch_sell_token_count": "{{tokenCount}} tokens", + "batch_sell_toggle_you_sell": "Toggle token details", + "batch_sell_sell_all": "Sell all", + "batch_sell_includes_metamask_fee": "Includes {{fee}}% MetaMask fee", + "batch_sell_customize_token": "Personalizar {{tokenSymbol}}", + "batch_sell_remove_token": "Eliminar {{tokenSymbol}}", + "batch_sell_checkbox_label": "Vender token en lote", + "sort_balance": "Saldo", + "next": "Siguiente", + "explore_tokens": "Explorar tokens", "no_tokens_found": "No se encontraron tokens", "no_tokens_found_description": "No encontramos ningún token con este nombre. Prueba con otra búsqueda.", "select_network": "Seleccionar red", @@ -7332,6 +7445,7 @@ "price_impact_execution_description": "Perderás aproximadamente {{priceImpact}} del valor de tu token en este canje. Intenta reducir el monto o elegir una ruta más líquida.", "proceed": "Continuar", "cancel": "Cancelar", + "close": "Cerrar", "slippage_info_title": "Deslizamiento", "slippage_info_description": "El % de cambio en el precio que estás dispuesto a permitir antes de que se cancele tu transacción.", "blockaid_error_title": "Esta transacción se revertirá", @@ -8107,7 +8221,14 @@ "retry": "Inténtalo de nuevo", "on_linea": "en Linea", "account_label": "Cuenta", - "token_label": "Token" + "token_label": "Token", + "money_account_label": "Money account", + "money_account_token_symbol": "mUSD", + "use_money_account_cta": "Use Money account", + "spend_and_earn_title": "Spend while you earn", + "spend_and_earn_description": "Spend with your Money account and earn up to {{apy}}% APY on your balance. Also get {{cashback}}% mUSD back.", + "spend_and_earn_description_no_apy": "Spend with your Money account and earn APY on your balance. Also get {{cashback}}% mUSD back.", + "spend_and_earn_cta": "Link to Money account" }, "cashback_screen": { "title": "Cashback en mUSD", @@ -8336,7 +8457,7 @@ "main_title": "Recompensas", "vip": { "bps_unit": "bps", - "swaps_label": "Swaps", + "swaps_label": "Canjes", "perps_label": "Perps", "error_title": "We couldn’t load your VIP dashboard", "error_description": "Check your connection and try again.", @@ -8449,6 +8570,7 @@ "show_less": "Mostrar menos", "linking_progress": "Agregando cuentas... ({{current}}/{{total}})", "accounts_linked_count": "{{linked}}/{{total}} inscritos", + "accounts_added": "Accounts added", "add_all_accounts": "Agregar todas las cuentas", "environment_selector": "Entorno", "environment_cancel": "Cancelar", @@ -8473,15 +8595,22 @@ }, "optout": { "title": "Eliminar del programa de Recompensas", - "description": "Esta acción eliminará tus cuentas del programa de Recompensas y borrará tu progreso. No podrás deshacer esta acción.", - "confirm": "Eliminar", + "description": "This will remove your accounts from the Rewards program and your progress in any campaigns you've joined. Only do this if you are absolutely sure you want to erase your progress.", + "erase_button": "Erase progress", "modal": { "confirmation_title": "¿Estás seguro?", - "confirmation_description": "Esto eliminará todo tu progreso y no se podrá revertir. Si te reincorporas al programa de Recompensas más adelante, comenzarás desde cero.", + "confirmation_description": "This will erase all your progress, and can't be reversed. If you rejoin the Rewards program later, you'll start back at 0.", + "type_to_confirm": "Type 'erase progress' to continue", + "confirm_phrase": "erase progress", "cancel": "Cancelar", "confirm": "Confirmar", + "error_title": "Algo salió mal", "error_message": "Error al excluirse del programa de Recompensas. Inténtalo de nuevo.", "processing": "Procesando..." + }, + "request_received": { + "title": "Request received", + "description": "In about 7 days, your progress will be fully erased. If you made this request by mistake, please contact support through the app." } }, "toast_dismiss": "Ignorar", @@ -8569,7 +8698,8 @@ "title_claim": "Reclamar beneficio", "action": "Reclamar", "empty-list": "No tienes ningún beneficio en este momento.", - "powered_by": "Impulsado por" + "powered_by": "Impulsado por", + "available_count": "{{count}} disponible(s)" }, "end_of_season_rewards": { "confirm_label_default": "Confirmar", @@ -8702,7 +8832,7 @@ "label_your_rank": "Tu rango", "label_portfolio": "Portfolio", "label_net_inflow": "Flujo neto de entrada", - "label_total_inflow": "Entrada total", + "label_total_inflow": "Flujo total de entrada", "label_outflow": "Flujo de salida", "label_days_held": "Días de retención", "qualified_title": "Estás calificado", @@ -8887,9 +9017,11 @@ "musd_claim": "Reclamar mUSD", "perps_deposit": "Agregar fondos", "perps_withdraw": "Retiro", + "predict_withdraw": "Retirar {{sourceSymbol}} desde {{sourceChain}}", "predict_deposit": "Agregar fondos", "swap": "Canjear tokens", - "swap_approval": "Aprobar tokens" + "swap_approval": "Aprobar tokens", + "fiat_purchase": "Comprar {{token}} con {{paymentMethod}}" }, "perps_deposit_solution": "Ya tienes {{fiat}} de USDC en Arbitrum. Vuelve a intentar realizar tu depósito." }, @@ -8965,7 +9097,7 @@ "high_to_low": "De máximo a mínimo", "low_to_high": "De mínimo a máximo", "apply": "Aplicar", - "search_placeholder": "Buscar tokens, sitios, URL", + "search_placeholder": "Search tokens, markets and URLs", "cancel": "Cancelar", "perps": "Perps", "rwa_perps_section": "Perps", @@ -8978,11 +9110,15 @@ "crypto_perps_section": "Perps", "predictions": "Predicciones", "no_results": "No se encontraron resultados", + "no_results_for_feed": "No {{feedName}} results for \"{{query}}\"", + "showing_all_results_for": "We found these results for \"{{query}}\"", "popular": "Populares", "sites": "Sitios", "popular_sites": "Sitios populares", "search_sites": "Sitios de búsqueda", "view_all": "Ver todo", + "view_more": "Ver más", + "view_x_more": "View {{count}} more", "enable_basic_functionality": "Activar la funcionalidad básica", "basic_functionality_disabled_title": "Explorar no está disponible", "basic_functionality_disabled_description": "No podemos obtener los metadatos necesarios cuando la funcionalidad básica está deshabilitada.", @@ -9002,6 +9138,14 @@ "crypto": "Cripto", "sports": "Deportes", "dapps": "Sitios" + }, + "search_tabs": { + "all": "Todas", + "crypto": "Cryptos", + "perps": "Perps", + "stocks": "Acciones", + "predictions": "Predicciones", + "sites": "Sitios" } }, "ota_update_modal": { @@ -9139,6 +9283,7 @@ "money_empty_description_network_filter": "No hay mUSD en esta red. Cambia de red para ver tus mUSD.", "money_empty_state": { "get_started": "Comenzar", + "earn": "Ganar", "earn_apy": "Gana un {{percentage}} % de APY" }, "money_filled_state": { @@ -9150,22 +9295,7 @@ "related_assets": "Activos relacionados", "perpetuals": "Contratos perpetuos", "predictions": "Predicciones", - "whats_happening": "Qué está pasando", - "whats_happening_ai": "IA", - "whats_happening_impact": { - "bullish": "Al alza", - "bearish": "A la baja", - "neutral": "Neutral" - }, "top_traders": "Traders principales", - "whats_happening_categories": { - "geopolitical": "Geopolítico", - "macro": "Macro", - "regulatory": "Regulatorio", - "technical": "Técnico", - "social": "Social", - "other": "Otro" - }, "defi": "DeFi", "nfts": "NFT", "trending_tokens": "Tendencias", @@ -9185,5 +9315,22 @@ }, "sites": { "popular": "Populares" + }, + "whats_happening": { + "title": "Qué está pasando", + "ai": "IA", + "impact": { + "bullish": "Al alza", + "bearish": "A la baja", + "neutral": "Neutral" + }, + "categories": { + "geopolitical": "Geopolítico", + "macro": "Macro", + "regulatory": "Regulatorio", + "technical": "Técnico", + "social": "Social", + "other": "Otro" + } } } diff --git a/locales/languages/fr.json b/locales/languages/fr.json index deee721a507..56b32046d3d 100644 --- a/locales/languages/fr.json +++ b/locales/languages/fr.json @@ -120,6 +120,10 @@ "account_no_funds": { "message": "Aucun fonds disponible. Veuillez utiliser un autre compte." }, + "headless_buy_error": { + "title": "Échec du règlement de l’achat en monnaie fiduciaire", + "message": "Une erreur s’est produite lors du règlement de votre achat en monnaie fiduciaire. Veuillez réessayer." + }, "mmpay_hardware_account": { "title": "Portefeuille non pris en charge", "message": "Les portefeuilles matériels ne sont pas pris en charge.\nChangez de portefeuille pour continuer." @@ -133,8 +137,8 @@ "message": "L’adresse du destinataire ne prend peut-être pas en charge les transferts directs de jetons, ce qui pourrait entraîner une perte de fonds. Ne poursuivez que si vous êtes certain que ce contrat est capable de recevoir votre transfert." }, "gas_sponsorship_reserve_balance": { - "message": "Le parrainage de gaz n’est pas disponible pour cette transaction. Vous devrez conserver au moins %{minBalance} %{nativeTokenSymbol} sur votre compte.", - "title": "Parrainage de gaz non disponible" + "message": "Ce réseau spécifique exige que vous mainteniez une réserve de %{minBalance} %{nativeTokenSymbol} sur votre compte.", + "title": "Un solde de réserve est requis" }, "token_trust_signal": { "malicious": { @@ -708,6 +712,9 @@ "contractAddressError": "Vous envoyez des jetons à l’adresse du contrat du jeton. Cela peut entraîner la perte de ces jetons.", "smart_contract_address": "Adresse du contrat intelligent", "smart_contract_address_warning": "L’adresse du destinataire ne prend peut-être pas en charge les transferts directs de jetons, ce qui pourrait entraîner une perte de fonds. Ne poursuivez que si vous êtes certain que ce contrat est capable de recevoir votre transfert.", + "unavailable_network_connection": "Unavailable network connection", + "unavailable_network_connection_description": "The connection with {{network}} is unreliable. Update network connectivity details before continuing or try again later.", + "update": "Mettre à jour", "i_understand": "Je comprends", "cancel": "Annuler", "new_address_title": "Nouvelle adresse", @@ -1068,7 +1075,7 @@ "sort": { "value": "Valeur", "pnl_percent": "Résultat %", - "recent": "Recent" + "recent": "Récents" } }, "trader_position": { @@ -1120,6 +1127,11 @@ "title": "Tradez un contrat à terme perpétuel sur {{symbol}}", "subtitle": "Multipliez vos pertes et profits jusqu’à {{leverage}} fois" }, + "service_interruption": { + "title": "We're experiencing an outage", + "description": "Some services may be unavailable while the team works on a fix.", + "contact_support": "Contacter le service d’assistance" + }, "today": "Aujourd’hui", "yesterday": "Hier", "unrealized_pnl": "Profits et pertes non réalisés", @@ -1284,7 +1296,9 @@ "toast_completed_subtitle": "{{amount}} USDC transféré vers votre portefeuille", "toast_completed_any_token_subtitle": "{{amount}} {{token}} transféré(s) vers votre portefeuille", "toast_error_title": "Quelque chose a mal tourné", - "toast_error_description": "Échec du retrait" + "toast_error_description": "Échec du retrait", + "toast_start_error_description": "Your withdrawal wasn’t started.", + "try_again": "Réessayez" }, "quote": { "network_fee": "Frais de réseau", @@ -1767,10 +1781,10 @@ "oracle_price": "Prix de l’oracle", "order_book": "Carnet d’ordres", "countdown": "Compte à rebours", - "long": "Position longue", - "short": "Position courte", - "long_lowercase": "position longue", - "short_lowercase": "position courte", + "long": "Long", + "short": "Courte", + "long_lowercase": "long", + "short_lowercase": "courte", "modify": "Modifier", "close_long": "Fermer la position longue", "close_short": "Fermer la position courte", @@ -2227,35 +2241,35 @@ "predict": { "title": "Prédictions MetaMask", "world_cup": { - "title": "World Cup", - "banner_title": "World Cup 2026", - "banner_description": "Trade on World Cup markets", + "title": "Coupe du monde", + "banner_title": "Coupe du monde 2026", + "banner_description": "Trade every match, every moment.", "tabs": { - "all": "All", + "all": "Tous", "props": "Props", - "live": "Live" + "live": "Active" }, "stages": { - "group_stage": "Group Stage", - "round_of_32": "Round of 32", - "round_of_16": "Round of 16", - "quarterfinals": "Quarterfinals", - "semifinals": "Semifinals", - "third_place": "Third Place", - "final": "Final", - "group_a": "Group A", - "group_b": "Group B", - "group_c": "Group C", - "group_d": "Group D", - "group_e": "Group E", - "group_f": "Group F", - "group_g": "Group G", - "group_h": "Group H", - "group_i": "Group I", - "group_j": "Group J", - "group_k": "Group K", - "group_l": "Group L", - "third_place_match": "Third Place Match" + "group_stage": "Phase de groupes", + "round_of_32": "Seizièmes de finale", + "round_of_16": "Huitièmes de finale", + "quarterfinals": "Quarts de finale", + "semifinals": "Demi-finales", + "third_place": "Troisième place", + "final": "Finale", + "group_a": "Groupe A", + "group_b": "Groupe B", + "group_c": "Groupe C", + "group_d": "Groupe D", + "group_e": "Groupe E", + "group_f": "Groupe F", + "group_g": "Groupe G", + "group_h": "Groupe H", + "group_i": "Groupe I", + "group_j": "Groupe J", + "group_k": "Groupe K", + "group_l": "Groupe L", + "third_place_match": "Match pour la troisième place" } }, "prediction_markets": "Marchés prédictifs", @@ -2537,8 +2551,8 @@ "withdraw_completed": "Retrait effectué", "withdraw_completed_subtitle": "{{amount}} USDC transféré vers votre portefeuille", "withdraw_any_token_completed_subtitle": "{{amount}} {{token}} transféré(s) vers votre portefeuille", - "unavailable_title": "Withdrawals temporarily unavailable", - "unavailable_description": "For urgent assistance, please contact Customer Service.", + "unavailable_title": "Retraits temporairement indisponibles", + "unavailable_description": "Pour une assistance urgente, veuillez contacter le service client.", "unavailable_got_it": "J’ai compris", "error_title": "Quelque chose a mal tourné", "error_description": "Échec du retrait", @@ -2941,6 +2955,17 @@ "pna25_confirm_button": "Accepter et fermer", "pna25_open_settings_button": "Ouvrir les paramètres" }, + "onboarding_interest_questionnaire": { + "title": "Que souhaitez-vous faire avec MetaMask ?", + "description": "Sélectionnez toutes les réponses pertinentes.", + "option_buy_and_sell_crypto": "Acheter et vendre des crypto-monnaies", + "option_consolidate_wallets": "Consolider vos portefeuilles", + "option_advanced_trades": "Effectuer du trading avancé", + "option_predict_sports_events": "Parier sur des événements sportifs, politiques, etc.", + "option_crypto_as_money": "Utiliser les crypto-monnaies comme moyen de paiement", + "option_connect_apps_sites": "Vous connecter à des applications ou des sites", + "continue": "Continuer" + }, "template_confirmation": { "ok": "OK", "cancel": "Annuler" @@ -3261,8 +3286,27 @@ "notifications_desc": "Gérez vos notifications", "allow_notifications": "Autoriser les notifications", "enable_push_notifications": "Activer les notifications push", - "allow_notifications_desc": "Restez au courant de ce qui se passe dans votre portefeuille grâce aux notifications. Pour activer les notifications, nous utilisons un profil pour synchroniser certains paramètres entre vos appareils.", + "allow_notifications_desc": "Choose what you're notified about and how.", "notifications_opts": { + "preferences_title": "Preferences", + "push_recommended": "Push", + "in_app": "In-app", + "status_push": "Push", + "status_in_app": "In app", + "status_off": "Off", + "select_all": "Tout sélectionner", + "deselect_all": "Désélectionner tout", + "select_accounts_title": "Comptes", + "select_accounts_desc": "Choose which accounts you'd like to get notifications for.", + "wallet_activity_title": "Wallet Activity", + "wallet_activity_desc": "Buy, sells, transfers, swaps and rewards", + "perps_title": "Trading Activity", + "perps_desc": "Perps position changes, liquidations, funding rates, and margin updates", + "social_ai_title": "Trading Signals", + "social_ai_desc": "Updates from traders and assets you follow, plus currated market news", + "marketing_title": "Updates and Rewards", + "marketing_desc": "Product updates, feature announcements, and new releases", + "marketing_disclaimer": "By turning this on, you agree to receive product news and marketing updates from MetaMask.", "customize_session_title": "Personnalisez vos notifications", "customize_session_desc": "Activez les types de notifications que vous souhaitez recevoir :", "account_session_title": "Activité du compte", @@ -3276,8 +3320,7 @@ "snaps_title": "Snaps", "snaps_desc": "Nouvelles fonctionnalités et mises à jour", "products_announcements_title": "Annonces de produits", - "products_announcements_desc": "Nouveaux produits et nouvelles fonctionnalités", - "perps_title": "Trading de contrats à terme perpétuels (perps)" + "products_announcements_desc": "Nouveaux produits et nouvelles fonctionnalités" }, "contacts_title": "Contacts", "contacts_desc": "Ajoutez, modifiez, supprimez et gérez vos contacts.", @@ -3640,7 +3683,15 @@ "card": { "title": "Card", "reset_onboarding_description": "Réinitialiser l’état d’intégration de « Card » pour recommencer le processus d’intégration depuis le début.", - "reset_onboarding_button": "Réinitialiser l’état d’intégration" + "reset_onboarding_button": "Réinitialiser l’état d’intégration", + "unlink_money_account_description": "Révoquer la limite de dépenses en USDC qui autorise Card à effectuer des paiements en débitant votre compte Money. Cela soumet une transaction « approve(0) » et marque le compte Money comme non délégué dans le back-end de Card.", + "unlink_money_account_button": "Dissocier le compte Money de Card", + "unlink_money_account_disabled_hint": "Aucun lien actif à supprimer." + }, + "identity": { + "title": "Identity", + "description": "Clears the persisted authentication session. Use this after toggling MM_DEV_API_ENV — otherwise a prod-minted JWT keeps being handed to dev-API consumers until it expires. Current MM_DEV_API_ENV: {{env}}.", + "clear_auth_session_button": "Clear persisted auth session" }, "haptics": { "title": "Retour haptique", @@ -3842,8 +3893,8 @@ "predict_button": "Prédictions", "add_collectible_button": "Ajouter", "info": "Infos", - "batch_sell": "Batch Sell", - "batch_sell_new_label": "New", + "batch_sell": "Vente par lot", + "batch_sell_new_label": "Nouveau", "swap": "Échanger", "convert": "Convertir", "bridge": "Passerelle", @@ -3883,7 +3934,7 @@ "troubleshoot": "Résoudre le problème", "deposit_description": "Virement bancaire ou par carte à frais réduits", "buy_description": "Convient pour acheter un jeton spécifique", - "batch_sell_description": "Sell up to 5 tokens for a stablecoin", + "batch_sell_description": "Vendez jusqu’à 5 jetons contre un stablecoin", "sell_description": "Vendre des cryptomonnaies", "swap_description": "Échange de jetons", "bridge_description": "Transférer des jetons entre différents réseaux", @@ -5205,6 +5256,34 @@ "manage_preferences_2": "Paramètres > Notifications.", "cancel": "Annuler", "cta": "Activer" + }, + "push_onboarding": { + "new_user": { + "title": "Ne manquez jamais une opportunité", + "body": "Recevez des alertes en temps réel lorsque les prix atteignent vos objectifs, que vos opérations de Bourse sont confirmées et que votre portefeuille évolue. Vous recevrez également des mises à jour sur les produits et des récompenses. Nous vous informerons des dernières mises à jour en fonction de vos interactions avec MetaMask.", + "button_yes": "Oui", + "button_not_now": "Pas maintenant", + "preview_card_1": { + "eyebrow": "METAMASK", + "time": "maintenant", + "title": "L’ETH affiche aujourd’hui une hausse de 4,2 %", + "message": "Cote 2 668,51 $ actuellement — au-dessus de votre alerte de prix" + }, + "preview_card_2": { + "eyebrow": "METAMASK", + "time": "Il y a 1 heure", + "title": "0,25 ETH reçus", + "message": "Provenant de 0x9a21…4f8c · 640,29 $" + } + }, + "existing_user": { + "title": "Présentation des alertes personnalisées", + "body": "Recevez des notifications adaptées à votre style de trading que vous pouvez modifier à tout moment.", + "card_title": "Ce que vous obtiendrez", + "card_description": "Des alertes et des mises à jour personnalisées, adaptées à votre activité de trading.", + "button_confirm": "Confirmer", + "button_not_now": "Pas maintenant" + } } }, "protect_your_wallet_modal": { @@ -5315,6 +5394,7 @@ "pay_with": "Payer avec", "buying_via": "Achat via {{providerName}}.", "change_provider": "Changer de fournisseur.", + "circuit_breaker_open": "This service is temporarily unavailable. Please try again in about 30 minutes.", "payment_error": "Un problème est survenu, veuillez réessayer.", "no_payment_methods_available": "Aucun moyen de paiement n’est disponible.", "error_fetching_quotes": "Un problème est survenu, veuillez réessayer.", @@ -6520,6 +6600,8 @@ "convert_to_musd": "Convertir en mUSD", "get_a_percentage_musd_bonus": "Obtenir {{percentage}} % de bonus en mUSD", "convert": "Convertir", + "confirm": "Confirmer", + "convert_tooltip_description": "Convertissez vos stablecoins en mUSD et gagnez jusqu’à {{percentage}} % de bonus annualisé que vous pouvez réclamer quotidiennement. Proposé par Relay.", "fetching_quote": "Récupération de la cotation...", "you_convert": "Vous convertissez", "network_fee": "Frais de réseau", @@ -6590,14 +6672,14 @@ "money": { "title": "Money", "your_balance": "Votre solde", - "apy_label": "Taux de rendement annuel de {{percentage}} %", + "apy_label": "APY {{percentage}} %", "apy_currency_suffix": " • mUSD", "apy_info_label": "Informations sur le taux de rendement annuel", "onboarding": { "step_progress": "Étape {{current}} sur {{total}}", "title": "Ajouter de l’argent", "description": "Approvisionnez votre compte et commencez à percevoir un rendement annuel.", - "add": "Ajouter", + "add": "Ajouter des fonds", "step2_title": "Obtenez votre carte MetaMask Card", "step2_description": "Dépensez l’argent que vous avez déposé sur votre compte Money tout en le faisant fructifier, partout où la carte Mastercard est acceptée.", "step2_cta": "Obtenir une carte", @@ -6605,6 +6687,19 @@ "link_card_description": "Dépensez votre argent tout en le faisant fructifier, partout où la carte Mastercard est acceptée.", "link_card_cta": "Associer une carte" }, + "rive_onboarding": { + "step1_title": "Les comptes Money sont disponibles", + "step1_body": "Gagnez jusqu’à {{percentage}} % de rendement annuel sur votre solde, disponible sur l’ensemble de votre portefeuille.", + "step1_footer_text": "Le taux de rendement annuel est variable et peut changer à tout moment.", + "step2_title": "Générez des revenus automatiquement", + "step2_body": "Transférez des stablecoins sans frais de change. Vos fonds commencent à générer des revenus immédiatement.", + "step2_footer_text": "Provided by Veda and Steakhouse Financial.", + "step3_title": "Dépensez partout", + "step3_body": "Bénéficiez d’un cashback allant jusqu’à {{percentage}} % sur vos achats en associant votre compte Money à une carte MetaMask.", + "step4_title": "Tradez et générez des revenus sur la même plateforme", + "step4_body": "Utilisez le solde de votre compte Money pour trader sur MetaMask tout en continuant à générer des revenus.", + "continue": "Continuer" + }, "action": { "add": "Ajouter", "transfer": "Transférer", @@ -6618,8 +6713,8 @@ }, "how_it_works": { "title": "Comment ça marche ", - "description_prefix": "Deposit mUSD into your Money account and earn up to", - "description_suffix": ". Your balance is dollar-backed and ready to spend, trade, or send anytime." + "description_prefix": "Déposez des mUSD sur votre compte Money et gagnez jusqu’à", + "description_suffix": ". Votre solde est adossé au dollar et vous pouvez l’utiliser à tout moment pour effectuer des achats, des transferts ou des opérations de Bourse." }, "musd_row": { "add": "Ajouter" @@ -6627,16 +6722,16 @@ "balance_card": { "label": "Solde du compte Money", "add": "Ajouter", - "info_sheet_title": "Money balance", - "info_sheet_body": "Your dollar-backed mUSD balance that's always available to spend, send, or trade anytime. We don't calculate this into your total account balance.\n\nWithdrawals process immediately, subject to standard network confirmation times on the relevant blockchain. If liquidity is tight, there may be temporary delays." + "info_sheet_title": "Solde du compte Money", + "info_sheet_body": "Votre solde qui est adossé au dollar et que vous pouvez utiliser à tout moment pour effectuer des achats, des transferts ou des opérations de Bourse n’est pas comptabilisé dans le solde total de votre compte.\n\nLes retraits sont traités immédiatement, sous réserve des délais de confirmation habituels du réseau de la blockchain utilisée. Des retards peuvent survenir en cas de manque de liquidités." }, "potential_earnings": { "title": "Gagnez de l’argent grâce à vos crypto-monnaies", "description": "Découvrez comment votre argent peut fructifier au fil du temps en convertissant vos crypto-monnaies en mUSD.", - "description_with_amounts_prefix": "Convert your {{total}} in assets and you could earn up to", - "description_with_amounts_suffix": "in one year.", + "description_with_amounts_prefix": "Convertissez vos {{total}} en actifs et vous pourriez gagner jusqu’à", + "description_with_amounts_suffix": "en un an.", "convert": "Convertir", - "convert_cta": "Convert your crypto", + "convert_cta": "Convertissez vos crypto-monnaies", "no_fee": "Pas de frais MetaMask", "view_all": "Tout afficher", "view_potential_earnings": "Afficher les gains potentiels" @@ -6649,41 +6744,44 @@ "cashback": "{{percentage}} % de cashback en mUSD", "get_now": "Obtenir maintenant", "link_title": "Associer une carte MetaMask Card", - "link_subtitle": "Spend your Money balance and earn on purchases. Plus, up to {{apy}}% APY on your balance.", - "link_bullet_cashback": "Get {{percentage}}% mUSD back", - "link_bullet_apy": "Earn up to {{apy}}% APY", + "link_subtitle": "Utilisez le solde de votre compte pour effectuer des achats et gagnez de l’argent. De plus, vous bénéficiez d’un taux de rendement annuel pouvant atteindre les {{apy}} % sur votre solde.", + "link_subtitle_no_apy": "Spend your Money balance and earn on purchases.", + "link_bullet_cashback": "Recevez {{percentage}} % de cashback en mUSD", + "link_bullet_apy": "Obtenez jusqu’à {{apy}} % de rendement annuel", "link_card": "Associer une carte", - "link_pending_title": "Linking card", - "link_pending_description": "Approving spending limit…", - "link_success_title": "Card linked successfully", - "link_success_description": "You can now spend while you earn", - "link_error": "Couldn't link card", - "manage_card": "Manage", - "avail_balance": "Avail. balance" + "link_pending_title": "Linking your card", + "link_success_title": "Your card is ready to use", + "link_error": "Something went wrong linking your card", + "link_card_sheet_title": "Dépensez\net générez des revenus", + "link_card_sheet_description": "Link your card so you can spend your Money balance and earn mUSD back on purchases—all while earning up to {{apy}}% APY.", + "link_card_sheet_description_no_apy": "Link your card so you can spend your Money balance and earn mUSD back on purchases.", + "link_card_sheet_cta": "Associer une carte", + "manage_card": "Gérer", + "avail_balance": "Solde disponible" }, "what_you_get": { "title": "Ce que vous obtenez", - "benefit_auto_earn": "Auto-earn up to", + "benefit_auto_earn": "Gagnez automatiquement jusqu'à", "benefit_dollar_backed": "Sécurisez vos fonds en achetant des mUSD, un stablecoin adossé au dollar à un ratio de 1:1", "benefit_liquidity": "Profitez d’une liquidité totale sans période de blocage, vous pourrez ainsi trader ou retirer des fonds à tout moment", "benefit_spend_prefix": "Effectuez vos achats chez plus de 150 millions de commerçants avec la MetaMask Card et bénéficiez de ", "benefit_spend_cashback": "1 à 3 % de cashback en mUSD", - "benefit_transfer": "Transfer to any of your wallets across MetaMask", - "benefit_global": "Send and receive funds globally", + "benefit_transfer": "Effectuez des transferts vers n’importe lequel de vos portefeuilles MetaMask", + "benefit_global": "Envoyez et recevez des fonds partout dans le monde", "learn_more": "En savoir plus" }, "footer": { - "add_money": "Add funds" + "add_money": "Ajouter des fonds" }, "add_money_sheet": { - "title": "Add funds", + "title": "Ajouter des fonds", "convert_crypto": "Convertir des crypto-monnaies", - "convert_crypto_description": "From any account", + "convert_crypto_description": "Depuis n’importe quel compte", "deposit_funds": "Déposer des fonds", - "deposit_funds_description": "From debit card or bank", - "move_musd": "Transfer your {{amount}} mUSD", - "move_musd_no_amount": "Transfer your mUSD", - "move_musd_description": "From your balance", + "deposit_funds_description": "Depuis une carte de débit ou un compte bancaire", + "move_musd": "Transférez vos {{amount}} mUSD", + "move_musd_no_amount": "Transférez vos mUSD", + "move_musd_description": "Depuis votre solde", "receive_external": "Recevoir depuis un portefeuille externe", "coming_soon": "Bientôt disponible" }, @@ -6694,7 +6792,7 @@ "contact_support": "Contacter le service d’assistance" }, "transfer_sheet": { - "title": "Transfer funds", + "title": "Transférez des fonds", "between_accounts": "Entre comptes", "perps_account": "Compte PERPS", "predictions_account": "Compte « Prédictions »", @@ -6712,8 +6810,8 @@ "body": "Estimation du montant que vous pourriez gagner sur une période donnée, basée sur votre solde actuel et le taux de rendement annuel applicable aujourd’hui. Les estimations ne constituent pas des rendements garantis et sont susceptibles de changer." }, "earn_crypto_info_sheet": { - "title": "Earn on your crypto", - "body": "Illustration assumes {{percentage}}% Annual Percentage Yield (APY) remains unchanged for one year. APY is variable and may change due to various factors. No guarantee of return." + "title": "Gagnez de l’argent grâce à vos crypto-monnaies", + "body": "L’illustration suppose que le taux de rendement annuel de {{percentage}} % restera inchangé pendant un an. Le taux de rendement annuel est variable et peut changer pour diverses raisons. Il n’y a aucune garantie de rendement." }, "activity": { "title": "Activité", @@ -6725,7 +6823,7 @@ }, "condensed_cards": { "how_it_works_title": "Comment ça marche ", - "how_it_works_subtitle": "Découvrez comment votre argent travaille pour vous", + "how_it_works_subtitle": "See how your money can grow", "musd_title": "MetaMask USD", "musd_subtitle": "En savoir plus sur le mUSD", "what_you_get_title": "Ce que vous obtenez", @@ -6738,7 +6836,8 @@ "sent": "Envoyé(s)", "transferred": "Transféré", "card_transaction": "Transaction Card", - "converted": "Converti" + "converted": "Converti", + "failed": "Échec" }, "convert_stablecoins": { "title": "Convertissez vos stablecoins", @@ -6757,11 +6856,11 @@ "how_it_works_page": { "header_title": "Money", "section_title": "Comment ça marche ", - "description_1": "Deposit mUSD into your Money account and earn up to {{percentage}}% APY (variable) automatically. Funds go into a DeFi vault that generates returns across audited lending markets—no staking, no claiming, no lock-ups.", + "description_1": "Déposez des mUSD sur votre compte Money et bénéficiez automatiquement d’un taux de rendement annuel (variable) pouvant atteindre les {{percentage}} %. Les fonds sont placés dans un coffre-fort DeFi qui génère des rendements sur des marchés de prêt audités — sans staking, sans réclamation, sans gel de fonds.", "description_2": "Le solde de votre compte Money correspond à votre solde disponible. Associez votre carte MetaMask Card pour effectuer des achats auprès de plus de 150 millions de commerçants dans le monde entier. Votre argent continue de générer des revenus jusqu’à ce que vous le dépensiez.", - "faq_title": "Frequently asked questions", + "faq_title": "Foire aux questions", "faq_placeholder_answer": "Bientôt disponible.", - "faq_q1": "How does the {{percentage}}% APY work?", + "faq_q1": "Comment fonctionne le taux de rendement annuel de {{percentage}} % ?", "faq_q2": "Qu’est-ce que le mUSD ?", "faq_q3": "D’où provient le rendement ?", "faq_q4": "Mon argent est-il bloqué ? Puis-je effectuer un retrait à tout moment ?", @@ -7030,11 +7129,12 @@ "confirm": "Confirmer", "pay_with_bottom_sheet": { "title": "Payer avec", - "last_used": "Last used", + "last_used": "Dernière utilisation", + "bank_and_card": "Banque et carte", "crypto": "Crypto", - "available_balance": "{{balance}} available", - "other_assets": "Other assets", - "other_assets_description": "Select from your tokens" + "available_balance": "{{balance}} disponibles", + "other_assets": "Autres actifs", + "other_assets_description": "Sélectionnez parmi vos jetons" }, "staking_footer": { "part1": "En continuant, vous acceptez nos ", @@ -7120,7 +7220,7 @@ "transaction_fee": "Les frais de conversion en mUSD comprennent les coûts de réseau et peuvent inclure des frais de fournisseur. Aucuns frais MetaMask ne s’appliquent lorsque vous effectuez un échange contre des mUSD." }, "money_account_withdraw": { - "transaction_fee": "MetaMask will swap your mUSD for your desired token. Swap providers may charge a fee, but MetaMask won't." + "transaction_fee": "MetaMask échangera vos mUSD contre le jeton de votre choix. Les prestataires de services d’échange peuvent facturer des frais, mais MetaMask ne le fera pas." }, "title": { "transaction_fee": "Frais" @@ -7225,7 +7325,7 @@ "deposit_edit_amount_done": "Ajouter des fonds", "deposit_edit_amount_predict_withdraw": "Retirer", "deposit_edit_amount_musd_conversion": "Convertir en mUSD", - "preparing_order": "Preparing order" + "preparing_order": "Préparation de l’ordre" }, "change_in_simulation_modal": { "title": "Les résultats ont changé", @@ -7250,20 +7350,33 @@ "confirm_swap": "Échanger", "terms_and_conditions": "Conditions générales", "select_token": "Sélectionnez un jeton", - "batch_sell_select_title": "Select up to 5 tokens", - "batch_sell_select_subtitle": "All tokens need to be on the same network.", - "batch_sell_empty_state_title": "No tokens. No problem.", - "batch_sell_empty_state_description": "No tokens. No problem. Explore and buy tokens to batch sell.", - "batch_sell_continue_with_one_token": "Continue with (1) token", - "batch_sell_continue_with_tokens": "Continue with ({{tokenCount}}) tokens", - "batch_sell_max_tokens_allowed": "Max 5 tokens allowed", - "batch_sell_single_token_dialog_title": "High rate alert", - "batch_sell_single_token_dialog_description": "Batch selling one token could lead to a higher rate. Want to do a swap instead?", - "batch_sell_swap_instead": "Yes, swap", - "batch_sell_checkbox_label": "Batch Sell token", - "sort_balance": "Balance", - "next": "Next", - "explore_tokens": "Explore tokens", + "batch_sell_select_title": "Sélectionnez jusqu’à 5 jetons", + "batch_sell_select_subtitle": "Tous les jetons doivent être sur le même réseau.", + "batch_sell_empty_state_title": "Vous n’avez pas de jetons ? Pas de problème.", + "batch_sell_empty_state_description": "Vous n’avez pas de jetons ? Pas de problème. Découvrez et achetez des jetons pour les vendre par lot.", + "batch_sell_continue_with_one_token": "Continuer avec (1) jeton", + "batch_sell_continue_with_tokens": "Continuer avec ({{tokenCount}}) jetons", + "batch_sell_max_tokens_allowed": "5 jetons au maximum", + "batch_sell_single_token_dialog_title": "Alerte de taux élevé", + "batch_sell_single_token_dialog_description": "La vente par lot d’un jeton pourrait entraîner un taux plus élevé. Souhaitez-vous effectuer un échange à la place ?", + "batch_sell_swap_instead": "Oui, procéder à l’échange", + "batch_sell_review_title": "Examen de la vente par lot", + "batch_sell_select_stablecoin": "Sélectionnez un stablecoin", + "batch_sell_total_received": "Total reçu", + "batch_sell_minimum_received": "Minimum received", + "batch_sell_quote_details_row": "{{tokenSymbol}} • {{slippage}} slippage", + "batch_sell_review": "Examiner", + "batch_sell_you_sell": "You sell", + "batch_sell_token_count": "{{tokenCount}} tokens", + "batch_sell_toggle_you_sell": "Toggle token details", + "batch_sell_sell_all": "Sell all", + "batch_sell_includes_metamask_fee": "Includes {{fee}}% MetaMask fee", + "batch_sell_customize_token": "Personnaliser {{tokenSymbol}}", + "batch_sell_remove_token": "Supprimer {{tokenSymbol}}", + "batch_sell_checkbox_label": "Vendre le jeton par lot", + "sort_balance": "Solde", + "next": "Suivant", + "explore_tokens": "Découvrir les jetons", "no_tokens_found": "Aucun jeton trouvé", "no_tokens_found_description": "Nous n’avons trouvé aucun jeton portant ce nom. Veuillez essayer un autre critère de recherche.", "select_network": "Sélectionnez le réseau", @@ -7332,6 +7445,7 @@ "price_impact_execution_description": "Vous perdrez environ {{priceImpact}} de la valeur de vos jetons lors de cet échange. Essayez de réduire le montant ou de choisir une voie plus liquide.", "proceed": "Continuer", "cancel": "Annuler", + "close": "Fermer", "slippage_info_title": "Slippage/effet de glissement", "slippage_info_description": "Le pourcentage de variation de prix que vous êtes prêt à accepter avant que votre transaction ne soit annulée.", "blockaid_error_title": "Cette transaction sera annulée", @@ -8107,7 +8221,14 @@ "retry": "Réessayez", "on_linea": "sur Linea", "account_label": "Compte", - "token_label": "Jeton" + "token_label": "Jeton", + "money_account_label": "Money account", + "money_account_token_symbol": "mUSD", + "use_money_account_cta": "Use Money account", + "spend_and_earn_title": "Spend while you earn", + "spend_and_earn_description": "Spend with your Money account and earn up to {{apy}}% APY on your balance. Also get {{cashback}}% mUSD back.", + "spend_and_earn_description_no_apy": "Spend with your Money account and earn APY on your balance. Also get {{cashback}}% mUSD back.", + "spend_and_earn_cta": "Link to Money account" }, "cashback_screen": { "title": "Cashback en mUSD", @@ -8335,8 +8456,8 @@ }, "main_title": "Récompenses", "vip": { - "bps_unit": "bps", - "swaps_label": "Swaps", + "bps_unit": "points de base", + "swaps_label": "Échanges", "perps_label": "Perps", "error_title": "We couldn’t load your VIP dashboard", "error_description": "Check your connection and try again.", @@ -8449,6 +8570,7 @@ "show_less": "Afficher moins", "linking_progress": "Ajout des comptes… ({{current}}/{{total}})", "accounts_linked_count": "{{linked}}/{{total}} inscrit(s)", + "accounts_added": "Accounts added", "add_all_accounts": "Ajouter tous les comptes", "environment_selector": "Environnement", "environment_cancel": "Annuler", @@ -8473,15 +8595,22 @@ }, "optout": { "title": "Supprimer la progression Rewards", - "description": "Cela supprimera vos comptes du programme de récompenses et effacera votre progression. Cette action est irréversible.", - "confirm": "Supprimer", + "description": "This will remove your accounts from the Rewards program and your progress in any campaigns you've joined. Only do this if you are absolutely sure you want to erase your progress.", + "erase_button": "Erase progress", "modal": { "confirmation_title": "En êtes-vous sûr(e) ?", - "confirmation_description": "Cette opération supprimera toute votre progression et ne pourra pas être annulée. Si vous rejoignez le programme « Rewards » ultérieurement, vous repartirez de zéro.", + "confirmation_description": "This will erase all your progress, and can't be reversed. If you rejoin the Rewards program later, you'll start back at 0.", + "type_to_confirm": "Type 'erase progress' to continue", + "confirm_phrase": "erase progress", "cancel": "Annuler", "confirm": "Confirmer", + "error_title": "Quelque chose a mal tourné", "error_message": "Échec de la désinscription du programme « Rewards ». Veuillez réessayer.", "processing": "Traitement en cours..." + }, + "request_received": { + "title": "Request received", + "description": "In about 7 days, your progress will be fully erased. If you made this request by mistake, please contact support through the app." } }, "toast_dismiss": "Ignorer", @@ -8569,7 +8698,8 @@ "title_claim": "Réclamer l’avantage", "action": "Réclamer", "empty-list": "Vous ne disposez d’aucun avantage pour le moment.", - "powered_by": "Fourni par" + "powered_by": "Fourni par", + "available_count": "{{count}} disponible(s)" }, "end_of_season_rewards": { "confirm_label_default": "Confirmer", @@ -8702,7 +8832,7 @@ "label_your_rank": "Votre classement", "label_portfolio": "Portfolio", "label_net_inflow": "Flux net entrant", - "label_total_inflow": "Entrées totales", + "label_total_inflow": "Apport total", "label_outflow": "Flux sortant", "label_days_held": "Jours de détention", "qualified_title": "Vous êtes qualifié", @@ -8887,9 +9017,11 @@ "musd_claim": "Réclamer mes mUSD", "perps_deposit": "Ajouter des fonds", "perps_withdraw": "Retrait", + "predict_withdraw": "Retirer {{sourceSymbol}} de {{sourceChain}}", "predict_deposit": "Ajouter des fonds", "swap": "Échanger des jetons", - "swap_approval": "Approuver les jetons" + "swap_approval": "Approuver les jetons", + "fiat_purchase": "Acheter des{{token}} avec {{paymentMethod}}" }, "perps_deposit_solution": "Vous disposez désormais de {{fiat}} d’USDC sur Arbitrum. Réessayez d’effectuer un dépôt." }, @@ -8965,7 +9097,7 @@ "high_to_low": "Du plus élevé au plus bas", "low_to_high": "Du plus bas au plus élevé", "apply": "Appliquer", - "search_placeholder": "Rechercher des jetons, des sites, des URL", + "search_placeholder": "Search tokens, markets and URLs", "cancel": "Annuler", "perps": "Perps", "rwa_perps_section": "Perps", @@ -8978,11 +9110,15 @@ "crypto_perps_section": "Perps", "predictions": "Prédictions", "no_results": "Aucun résultat trouvé", + "no_results_for_feed": "No {{feedName}} results for \"{{query}}\"", + "showing_all_results_for": "We found these results for \"{{query}}\"", "popular": "Populaire", "sites": "Sites", "popular_sites": "Sites populaires", "search_sites": "Rechercher des sites", "view_all": "Tout afficher", + "view_more": "Afficher plus", + "view_x_more": "View {{count}} more", "enable_basic_functionality": "Activer les fonctionnalités de base", "basic_functionality_disabled_title": "La section « Explorer » n’est pas disponible", "basic_functionality_disabled_description": "Nous ne pouvons pas récupérer les métadonnées requises lorsque les fonctionnalités de base sont désactivées.", @@ -9002,6 +9138,14 @@ "crypto": "Crypto", "sports": "Sports", "dapps": "Sites" + }, + "search_tabs": { + "all": "Tous", + "crypto": "Cryptos", + "perps": "Perps", + "stocks": "Actions", + "predictions": "Prédictions", + "sites": "Sites" } }, "ota_update_modal": { @@ -9139,33 +9283,19 @@ "money_empty_description_network_filter": "Pas de mUSD sur ce réseau. Changez de réseau pour consulter votre solde de mUSD.", "money_empty_state": { "get_started": "Commencer", + "earn": "Gagner", "earn_apy": "Obtenez un taux de rendement annuel de {{percentage}} %" }, "money_filled_state": { "add": "Ajouter", - "apy": "Taux de rendement annuel de {{percentage}} %" + "apy": "APY {{percentage}} %" }, "tokens": "Jetons", "perps": "Perps", "related_assets": "Actifs associés", "perpetuals": "Contrats perpétuels", "predictions": "Prédictions", - "whats_happening": "Actualités", - "whats_happening_ai": "IA", - "whats_happening_impact": { - "bullish": "Haussier", - "bearish": "Baissier", - "neutral": "Neutre" - }, "top_traders": "Meilleurs traders", - "whats_happening_categories": { - "geopolitical": "Géopolitique", - "macro": "Macroéconomie", - "regulatory": "Réglementation", - "technical": "Technique", - "social": "Réseaux sociaux", - "other": "Autre" - }, "defi": "DeFi", "nfts": "NFT", "trending_tokens": "Tendance", @@ -9185,5 +9315,22 @@ }, "sites": { "popular": "Populaire" + }, + "whats_happening": { + "title": "Actualités", + "ai": "IA", + "impact": { + "bullish": "Haussier", + "bearish": "Baissier", + "neutral": "Neutre" + }, + "categories": { + "geopolitical": "Géopolitique", + "macro": "Macroéconomie", + "regulatory": "Réglementation", + "technical": "Technique", + "social": "Réseaux sociaux", + "other": "Autre" + } } } diff --git a/locales/languages/hi.json b/locales/languages/hi.json index b51386e7bb7..a615affb1cb 100644 --- a/locales/languages/hi.json +++ b/locales/languages/hi.json @@ -120,6 +120,10 @@ "account_no_funds": { "message": "कोई फंड उपलब्ध नहीं है। कृपया किसी अन्य अकाउंट का इस्तेमाल करें।" }, + "headless_buy_error": { + "title": "फिएट की खरीद नहीं हो पाई", + "message": "आपकी फिएट खरीदारी में कुछ गड़बड़ हो गई है। कृपया फिर से कोशिश करें।" + }, "mmpay_hardware_account": { "title": "वॉलेट सपोर्टेड नहीं है", "message": "हार्डवेयर वॉलेट सपोर्टेड नहीं हैं।\nजारी रखने के लिए वॉलेट बदलें।" @@ -133,8 +137,8 @@ "message": "हो सकता है कि पाने वाले का पता सीधे टोकन ट्रांसफर को सपोर्ट न करे, जिससे फंड का नुकसान हो सकता है। तभी आगे बढ़ें जब आपको पक्का हो कि यह कॉन्ट्रैक्ट आपका ट्रांसफर प्राप्त कर सकता है।" }, "gas_sponsorship_reserve_balance": { - "message": "इस ट्रांसेक्शन के लिए गैस स्पॉन्सरशिप उपलब्ध नहीं है। आपको अपने अकाउंट में कम से कम %{minBalance} %{nativeTokenSymbol} रखना होगा।", - "title": "गैस स्पॉन्सरशिप उपलब्ध नहीं है" + "message": "इस खास नेटवर्क को आपके अकाउंट में %{minBalance} %{nativeTokenSymbol} का रिज़र्व बनाए रखना ज़रूरी है।", + "title": "रिज़र्व बैलेंस ज़रूरी है" }, "token_trust_signal": { "malicious": { @@ -708,6 +712,9 @@ "contractAddressError": "आप टोकन को टोकन के कॉन्ट्रैक्ट एड्रेस पर भेज रहे हैं। इससे इन टोकन को खोने की संभावना है।", "smart_contract_address": "स्मार्ट कॉन्ट्रैक्ट एड्रेस", "smart_contract_address_warning": "हो सकता है कि पाने वाले का पता सीधे टोकन ट्रांसफर को सपोर्ट न करे, जिससे फंड का नुकसान हो सकता है। तभी आगे बढ़ें जब आपको पक्का हो कि यह कॉन्ट्रैक्ट आपका ट्रांसफर प्राप्त कर सकता है।", + "unavailable_network_connection": "Unavailable network connection", + "unavailable_network_connection_description": "The connection with {{network}} is unreliable. Update network connectivity details before continuing or try again later.", + "update": "अपडेट करें", "i_understand": "मैं समझता हूं", "cancel": "कैंसिल करें", "new_address_title": "नया एड्रेस", @@ -1068,7 +1075,7 @@ "sort": { "value": "वैल्यू", "pnl_percent": "पी एंड एल %", - "recent": "Recent" + "recent": "हालिया" } }, "trader_position": { @@ -1120,6 +1127,11 @@ "title": "{{symbol}} पर्प ट्रेड करें", "subtitle": "अपने P&L को {{leverage}} तक कई गुना बढ़ाएँ" }, + "service_interruption": { + "title": "We're experiencing an outage", + "description": "Some services may be unavailable while the team works on a fix.", + "contact_support": "सपोर्ट टीम से कॉन्टेक्ट करें" + }, "today": "आज", "yesterday": "कल", "unrealized_pnl": "अनरियलाइज्ड P&L", @@ -1284,7 +1296,9 @@ "toast_completed_subtitle": "{{amount}} USDC आपके वॉलेट में भेज दिया गया", "toast_completed_any_token_subtitle": "{{amount}} {{token}} आपके वॉलेट में भेजा गया", "toast_error_title": "कुछ गलत हो गया", - "toast_error_description": "विदड्रॉवल नहीं हो पाया" + "toast_error_description": "विदड्रॉवल नहीं हो पाया", + "toast_start_error_description": "Your withdrawal wasn’t started.", + "try_again": "फिर से प्रयास करें" }, "quote": { "network_fee": "नेटवर्क फीस", @@ -2227,35 +2241,35 @@ "predict": { "title": "MetaMask प्रिडिक्शन्स", "world_cup": { - "title": "World Cup", - "banner_title": "World Cup 2026", - "banner_description": "Trade on World Cup markets", + "title": "वर्ल्ड कप", + "banner_title": "वर्ल्ड कप 2026", + "banner_description": "Trade every match, every moment.", "tabs": { - "all": "All", - "props": "Props", - "live": "Live" + "all": "सभी", + "props": "प्रॉप्स", + "live": "लाइव" }, "stages": { - "group_stage": "Group Stage", - "round_of_32": "Round of 32", - "round_of_16": "Round of 16", - "quarterfinals": "Quarterfinals", - "semifinals": "Semifinals", - "third_place": "Third Place", - "final": "Final", - "group_a": "Group A", - "group_b": "Group B", - "group_c": "Group C", - "group_d": "Group D", - "group_e": "Group E", - "group_f": "Group F", - "group_g": "Group G", - "group_h": "Group H", - "group_i": "Group I", - "group_j": "Group J", - "group_k": "Group K", - "group_l": "Group L", - "third_place_match": "Third Place Match" + "group_stage": "ग्रुप स्टेज", + "round_of_32": "राउंड ऑफ़ 32", + "round_of_16": "राउंड ऑफ़ 16", + "quarterfinals": "क्वार्टरफ़ाइनल्स", + "semifinals": "सेमीफ़ाइनल्स", + "third_place": "थर्ड प्लेस", + "final": "फाइनल", + "group_a": "ग्रुप ए", + "group_b": "ग्रुप बी", + "group_c": "ग्रुप सी", + "group_d": "ग्रुप डी", + "group_e": "ग्रुप ई", + "group_f": "ग्रुप एफ", + "group_g": "ग्रुप जी", + "group_h": "ग्रुप एच", + "group_i": "ग्रुप आई", + "group_j": "ग्रुप जे", + "group_k": "ग्रुप के", + "group_l": "ग्रुप एल", + "third_place_match": "थर्ड प्लेस मैच" } }, "prediction_markets": "प्रेडिक्शन मार्केट", @@ -2537,8 +2551,8 @@ "withdraw_completed": "विदड्रॉवल पूरा हुआ", "withdraw_completed_subtitle": "{{amount}} USDC आपके वॉलेट में भेज दिया गया", "withdraw_any_token_completed_subtitle": "{{amount}} {{token}} आपके वॉलेट में भेजा गया", - "unavailable_title": "Withdrawals temporarily unavailable", - "unavailable_description": "For urgent assistance, please contact Customer Service.", + "unavailable_title": "अभी विदड्रॉवल उपलब्ध नहीं है", + "unavailable_description": "अर्जेंट मदद के लिए, कृपया कस्टमर सर्विस से संपर्क करें।", "unavailable_got_it": "समझ गए", "error_title": "कुछ गलत हो गया", "error_description": "निकालना जारी नहीं हो पाया", @@ -2941,6 +2955,17 @@ "pna25_confirm_button": "स्वीकार करें और बंद करें", "pna25_open_settings_button": "सेटिंग्स खोलें" }, + "onboarding_interest_questionnaire": { + "title": "आप MetaMask के साथ क्या करना चाहते हैं?", + "description": "जो भी लागू हो, उसे चुनें।", + "option_buy_and_sell_crypto": "क्रिप्टो खरीदें और बेचें", + "option_consolidate_wallets": "अपने वॉलेट को कंसोलिडेट करें", + "option_advanced_trades": "एडवांस्ड ट्रेड करें", + "option_predict_sports_events": "स्पोर्ट्स और इवेंट्स प्रेडिक्ट करें", + "option_crypto_as_money": "क्रिप्टो को पैसे की तरह इस्तेमाल करें", + "option_connect_apps_sites": "ऐप्स या साइट से कनेक्ट करें", + "continue": "जारी रखें" + }, "template_confirmation": { "ok": "ठीक है", "cancel": "कैंसिल करें" @@ -3261,8 +3286,27 @@ "notifications_desc": "अपने नोटिफिकेशंस मैनेज करें", "allow_notifications": "नोटिफिकेशंस की अनुमति दें", "enable_push_notifications": "पुश नोटिफिकेशंस को चालू करें", - "allow_notifications_desc": "नोटिफिकेशंस के साथ आपके वॉलेट में क्या हो रहा है, इसकी जानकारी रखें। नोटिफिकेशंस का उपयोग करने के लिए, हम आपके डिवाइस में कुछ सेटिंग्स को सिंक करने के लिए एक प्रोफ़ाइल का उपयोग करते हैं।", + "allow_notifications_desc": "Choose what you're notified about and how.", "notifications_opts": { + "preferences_title": "Preferences", + "push_recommended": "Push", + "in_app": "In-app", + "status_push": "Push", + "status_in_app": "In app", + "status_off": "बंद", + "select_all": "सभी को चुनें", + "deselect_all": "सभी को अचयनित करें", + "select_accounts_title": "एकाउंट्स", + "select_accounts_desc": "Choose which accounts you'd like to get notifications for.", + "wallet_activity_title": "Wallet Activity", + "wallet_activity_desc": "Buy, sells, transfers, swaps and rewards", + "perps_title": "Trading Activity", + "perps_desc": "Perps position changes, liquidations, funding rates, and margin updates", + "social_ai_title": "Trading Signals", + "social_ai_desc": "Updates from traders and assets you follow, plus currated market news", + "marketing_title": "Updates and Rewards", + "marketing_desc": "Product updates, feature announcements, and new releases", + "marketing_disclaimer": "By turning this on, you agree to receive product news and marketing updates from MetaMask.", "customize_session_title": "अपने नोटिफिकेशंस कस्टमाइज़ करें", "customize_session_desc": "आप जिस प्रकार के नोटिफिकेशंस प्राप्त करना चाहते हैं, उन्हें चालू करें:", "account_session_title": "अकाउंट एक्टिविटी", @@ -3276,8 +3320,7 @@ "snaps_title": "Snaps", "snaps_desc": "नए फीचर्स और अपडेट", "products_announcements_title": "प्रॉडक्ट घोषणाएं", - "products_announcements_desc": "नए प्रॉडक्ट और फीचर्स", - "perps_title": "पर्प्स ट्रेडिंग" + "products_announcements_desc": "नए प्रॉडक्ट और फीचर्स" }, "contacts_title": "संपर्क", "contacts_desc": "अपने अकाउंट को बदलें, हटाएं, और मैनेज करें।", @@ -3640,7 +3683,15 @@ "card": { "title": "कार्ड", "reset_onboarding_description": "ऑनबोर्डिंग प्रक्रिया को शुरुआत से दोबारा शुरू करने के लिए कार्ड की ऑनबोर्डिंग स्टेट रीसेट करें।", - "reset_onboarding_button": "ऑनबोर्डिंग स्टेट रीसेट करें" + "reset_onboarding_button": "ऑनबोर्डिंग स्टेट रीसेट करें", + "unlink_money_account_description": "यूएसडीसी खर्च-लिमिट अलाउंस को रद्द करें जो कार्ड को आपके मनी अकाउंट से खर्च करने की अनुमति देता है। यह एक अप्रूव(0) ट्रांसेक्शन सबमिट करता है और मनी अकाउंट को कार्ड बैकएंड पर नॉट-डेलीगेटेड के रूप में मार्क करता है।", + "unlink_money_account_button": "कार्ड से मनी अकाउंट को अनलिंक करें", + "unlink_money_account_disabled_hint": "हटाने के लिए कोई एक्टिव लिंकेज नहीं है।" + }, + "identity": { + "title": "Identity", + "description": "Clears the persisted authentication session. Use this after toggling MM_DEV_API_ENV — otherwise a prod-minted JWT keeps being handed to dev-API consumers until it expires. Current MM_DEV_API_ENV: {{env}}.", + "clear_auth_session_button": "Clear persisted auth session" }, "haptics": { "title": "हैप्टिक्स", @@ -3842,8 +3893,8 @@ "predict_button": "प्रेडिक्शंस", "add_collectible_button": "जोड़ें", "info": "जानकारी", - "batch_sell": "Batch Sell", - "batch_sell_new_label": "New", + "batch_sell": "बैच सेल", + "batch_sell_new_label": "नया", "swap": "स्वैप", "convert": "कन्वर्ट करें", "bridge": "ब्रिज", @@ -3883,7 +3934,7 @@ "troubleshoot": "ट्रबलशूट", "deposit_description": "कम शुल्क वाले बैंक या कार्ड ट्रांसफर", "buy_description": "एक विशिष्ट टोकन खरीदने के लिए अच्छा है", - "batch_sell_description": "Sell up to 5 tokens for a stablecoin", + "batch_sell_description": "एक स्टेबलकॉइन के लिए 5 टोकन तक बेचें", "sell_description": "कैश के लिए क्रिप्टो बेचें", "swap_description": "टोकन के बीच विनिमय", "bridge_description": "अलग-अलग नेटवर्कों के बीच टोकन ट्रांसफर करें", @@ -5205,6 +5256,34 @@ "manage_preferences_2": "सेटिंग्स > नोटीफिकेशंस।", "cancel": "कैंसिल करें", "cta": "चालू करें" + }, + "push_onboarding": { + "new_user": { + "title": "कभी भी कोई मूव मिस न करें", + "body": "जब कीमतें आपके टारगेट तक पहुँचें, आपके ट्रेड कन्फर्म हों, और आपका पोर्टफ़ोलियो मूव करे तो रियल-टाइम अलर्ट पाएँ। साथ ही, प्रोडक्ट अपडेट और रिवॉर्ड भी मिलते रहेंगे। हम MetaMask के साथ आपके इंटरैक्शन के आधार पर अपडेट शेयर करेंगे।", + "button_yes": "हां", + "button_not_now": "अभी नहीं", + "preview_card_1": { + "eyebrow": "METAMASK", + "time": "अब", + "title": "ETH आज 4.2% बढ़ा", + "message": "अब $2,668.51 पर — आपके प्राइस अलर्ट से ऊपर" + }, + "preview_card_2": { + "eyebrow": "METAMASK", + "time": "1 घंटा पहले", + "title": "0.25 ETH मिला", + "message": "0x9a21…4f8c · $640.29 से" + } + }, + "existing_user": { + "title": "पेश है पर्सनलाइज़्ड अलर्ट", + "body": "अपने ट्रेड करने के तरीके से मैच करने वाले नोटिफ़िकेशन पाएं। कभी भी अपडेट करें।", + "card_title": "आपको क्या मिलता है", + "card_description": "आपकी ट्रेडिंग एक्टिविटी के हिसाब से पर्सनलाइज़्ड अलर्ट और अपडेट।", + "button_confirm": "कन्फर्म करें", + "button_not_now": "अभी नहीं" + } } }, "protect_your_wallet_modal": { @@ -5315,6 +5394,7 @@ "pay_with": "के साथ भुगतान करें", "buying_via": "{{providerName}} के ज़रिए खरीद रहे हैं।", "change_provider": "प्रोवाइडर बदलें।", + "circuit_breaker_open": "This service is temporarily unavailable. Please try again in about 30 minutes.", "payment_error": "कुछ गलत हो गया। कृपया फिर से कोशिश करें।", "no_payment_methods_available": "पेमेंट का कोई तरीका उपलब्ध नहीं है।", "error_fetching_quotes": "कुछ गलत हो गया। कृपया फिर से कोशिश करें।", @@ -6520,6 +6600,8 @@ "convert_to_musd": "mUSD में कन्वर्ट करें", "get_a_percentage_musd_bonus": "{{percentage}}% mUSD बोनस पाएं", "convert": "कन्वर्ट करें", + "confirm": "कन्फर्म करें", + "convert_tooltip_description": "अपने स्टेबलकॉइन्स को mUSD में बदलें और {{percentage}}% तक वार्षिक बोनस कमाएं, जिसे आप रोज़ाना क्लेम कर सकते हैं। रिले द्वारा पावर्ड।", "fetching_quote": "कोटेशन लाया जा रहा है...", "you_convert": "आप बदलते हैं", "network_fee": "नेटवर्क फीस", @@ -6597,7 +6679,7 @@ "step_progress": "{{total}} का स्टेप {{current}}", "title": "धन जोड़ें", "description": "अपना अकाउंट फंड करें और APY कमाना शुरू करें।", - "add": "जोड़ें", + "add": "फंड जोड़ें", "step2_title": "अपना MetaMask कार्ड पाएं", "step2_description": "अपना Money बैलेंस पाने के साथ उसे खर्च करें, जहां भी मास्टरकार्ड स्वीकार किया जाता हो।", "step2_cta": "कार्ड पाएं", @@ -6605,6 +6687,19 @@ "link_card_description": "अपना बैलेंस पाने के साथ उसे खर्च करें, जहां भी मास्टरकार्ड स्वीकार किया जाता हो।", "link_card_cta": "कार्ड लिंक करें" }, + "rive_onboarding": { + "step1_title": "मनी अकाउंट यहां हैं", + "step1_body": "अपने बैलेंस पर {{percentage}}% APY तक कमाएं, जो आपके पूरे वॉलेट में उपलब्ध है।", + "step1_footer_text": "APY वेरिएबल है और कभी भी बदल सकता है।", + "step2_title": "ऑटोमैटिकली कमाएं", + "step2_body": "बिना किसी एक्सचेंज फ़ीस के स्टेबलकॉइन मूव करें। फ़ंड तुरंत कमाना शुरू कर देते हैं।", + "step2_footer_text": "Provided by Veda and Steakhouse Financial.", + "step3_title": "कहीं भी खर्च करें", + "step3_body": "अपने मनी अकाउंट को MetaMask कार्ड से लिंक करके खरीदारी पर {{percentage}}% तक वापस पाएं।", + "step4_title": "एक ही जगह पर ट्रेड करें और कमाएं", + "step4_body": "अपने मनी बैलेंस का इस्तेमाल MetaMask पर ट्रेड करने के लिए करें और साथ ही यील्ड भी कमाएं।", + "continue": "जारी रखें" + }, "action": { "add": "जोड़ें", "transfer": "स्थानांतरण", @@ -6618,8 +6713,8 @@ }, "how_it_works": { "title": "ये कैसे काम करता है", - "description_prefix": "Deposit mUSD into your Money account and earn up to", - "description_suffix": ". Your balance is dollar-backed and ready to spend, trade, or send anytime." + "description_prefix": "अपने मनी अकाउंट में mUSD डिपॉज़िट करें और कमाएं", + "description_suffix": ". आपका बैलेंस डॉलर-बैक्ड है और कभी भी खर्च करने, ट्रेड करने या भेजने के लिए तैयार है।" }, "musd_row": { "add": "जोड़ें" @@ -6627,16 +6722,16 @@ "balance_card": { "label": "Money बैलेंस", "add": "जोड़ें", - "info_sheet_title": "Money balance", - "info_sheet_body": "Your dollar-backed mUSD balance that's always available to spend, send, or trade anytime. We don't calculate this into your total account balance.\n\nWithdrawals process immediately, subject to standard network confirmation times on the relevant blockchain. If liquidity is tight, there may be temporary delays." + "info_sheet_title": "Money बैलेंस", + "info_sheet_body": "आपका डॉलर-बैक्ड mUSD बैलेंस जो खर्च करने, भेजने या कभी भी ट्रेड करने के लिए हमेशा उपलब्ध रहता है। हम इसे आपके टोटल अकाउंट बैलेंस में कैलकुलेट नहीं करते हैं।\n\nविदड्रॉवल तुरंत प्रोसेस होता है, जो संबंधित ब्लॉकचेन पर स्टैंडर्ड नेटवर्क कन्फर्मेशन टाइम पर निर्भर करता है। अगर लिक्विडिटी टाइट है, तो कुछ समय के लिए देरी हो सकती है।" }, "potential_earnings": { "title": "अपने क्रिप्टो पर कमाएं", "description": "देखें कि अपने क्रिप्टो को mUSD में बदलकर आपका पैसा समय के साथ कैसे बढ़ सकता है।", - "description_with_amounts_prefix": "Convert your {{total}} in assets and you could earn up to", - "description_with_amounts_suffix": "in one year.", + "description_with_amounts_prefix": "अपने {{total}} को एसेट्स में कन्वर्ट करें और आप कमा सकते हैं", + "description_with_amounts_suffix": "एक साल में।", "convert": "कन्वर्ट करें", - "convert_cta": "Convert your crypto", + "convert_cta": "अपने क्रिप्टो को कन्वर्ट करें", "no_fee": "कोई MetaMask फीस नहीं", "view_all": "सभी देखें", "view_potential_earnings": "संभावित कमाई देखें" @@ -6649,41 +6744,44 @@ "cashback": "{{percentage}}% mUSD वापस", "get_now": "अभी पाएं", "link_title": "MetaMask कार्ड लिंक करें", - "link_subtitle": "Spend your Money balance and earn on purchases. Plus, up to {{apy}}% APY on your balance.", - "link_bullet_cashback": "Get {{percentage}}% mUSD back", - "link_bullet_apy": "Earn up to {{apy}}% APY", + "link_subtitle": "अपना मनी बैलेंस खर्च करें और खरीदारी पर कमाएं। साथ ही, आपके बैलेंस पर {{apy}}% APY तक।", + "link_subtitle_no_apy": "Spend your Money balance and earn on purchases.", + "link_bullet_cashback": "{{percentage}}% mUSD वापस पाएं", + "link_bullet_apy": "{{apy}}% APY तक कमाएं", "link_card": "कार्ड लिंक करें", - "link_pending_title": "Linking card", - "link_pending_description": "Approving spending limit…", - "link_success_title": "Card linked successfully", - "link_success_description": "You can now spend while you earn", - "link_error": "Couldn't link card", - "manage_card": "Manage", - "avail_balance": "Avail. balance" + "link_pending_title": "Linking your card", + "link_success_title": "Your card is ready to use", + "link_error": "Something went wrong linking your card", + "link_card_sheet_title": "खर्च करें और कमाएँ", + "link_card_sheet_description": "Link your card so you can spend your Money balance and earn mUSD back on purchases—all while earning up to {{apy}}% APY.", + "link_card_sheet_description_no_apy": "Link your card so you can spend your Money balance and earn mUSD back on purchases.", + "link_card_sheet_cta": "कार्ड लिंक करें", + "manage_card": "मैनेज करें", + "avail_balance": "उपलब्ध बैलेंस" }, "what_you_get": { "title": "आपको क्या मिलता है", - "benefit_auto_earn": "Auto-earn up to", + "benefit_auto_earn": "तक ऑटो-अर्न करें", "benefit_dollar_backed": "अपना पैसा mUSD में रखें, जो एक 1:1 डॉलर-बैक्ड स्टेबलकॉइन है", "benefit_liquidity": "बिना किसी लॉकअप के पूरी लिक्विडिटी पाएं, इसलिए आप कभी भी ट्रेड कर सकते हैं या निकाल सकते हैं", "benefit_spend_prefix": "MetaMask कार्ड के साथ 150M+ मर्चेंट पर खर्च करें और कमाएँ ", "benefit_spend_cashback": "1-3% mUSD वापस", - "benefit_transfer": "Transfer to any of your wallets across MetaMask", - "benefit_global": "Send and receive funds globally", + "benefit_transfer": "MetaMask पर अपने किसी भी वॉलेट में ट्रांसफर करें", + "benefit_global": "दुनिया भर में पैसे भेजें और प्राप्त करें", "learn_more": "ज़्यादा जानें" }, "footer": { - "add_money": "Add funds" + "add_money": "फंड जोड़ें" }, "add_money_sheet": { - "title": "Add funds", + "title": "फंड जोड़ें", "convert_crypto": "क्रिप्टो को कन्वर्ट करें", - "convert_crypto_description": "From any account", + "convert_crypto_description": "किसी भी अकाउंट से", "deposit_funds": "फंड्स डिपॉज़िट करें", - "deposit_funds_description": "From debit card or bank", - "move_musd": "Transfer your {{amount}} mUSD", - "move_musd_no_amount": "Transfer your mUSD", - "move_musd_description": "From your balance", + "deposit_funds_description": "डेबिट कार्ड या बैंक से", + "move_musd": "अपना {{amount}} mUSD ट्रांसफर करें", + "move_musd_no_amount": "अपना mUSD ट्रांसफर करें", + "move_musd_description": "आपके बैलेंस से", "receive_external": "बाहरी वॉलेट से प्राप्त करें", "coming_soon": "जल्द आ रहा है" }, @@ -6694,7 +6792,7 @@ "contact_support": "सपोर्ट टीम से कॉन्टेक्ट करें" }, "transfer_sheet": { - "title": "Transfer funds", + "title": "पैसा ट्रांसफर करें", "between_accounts": "एकाउंट्स के बीच", "perps_account": "पर्प्स अकाउंट", "predictions_account": "प्रेडिक्शंस अकाउंट", @@ -6712,8 +6810,8 @@ "body": "आपके वर्तमान बैलेंस और आज के APY के आधार पर किसी अवधि में आपकी संभावित कमाई का अनुमान। यह अनुमानित रिटर्न की गारंटी नहीं है और इसमें बदलाव हो सकता है।" }, "earn_crypto_info_sheet": { - "title": "Earn on your crypto", - "body": "Illustration assumes {{percentage}}% Annual Percentage Yield (APY) remains unchanged for one year. APY is variable and may change due to various factors. No guarantee of return." + "title": "अपने क्रिप्टो पर कमाएं", + "body": "उदाहरण में माना गया है कि {{percentage}}% एनुअल परसेंटेज यील्ड (APY) एक साल तक नहीं बदलेगा। APY बदलता रहता है और कई वजहों से बदल सकता है। रिटर्न की कोई गारंटी नहीं है।" }, "activity": { "title": "गतिविधि", @@ -6725,7 +6823,7 @@ }, "condensed_cards": { "how_it_works_title": "ये कैसे काम करता है", - "how_it_works_subtitle": "देखें कि आपका पैसा आपके लिए कैसे काम करता है", + "how_it_works_subtitle": "See how your money can grow", "musd_title": "MetaMask USD", "musd_subtitle": "mUSD के बारे में ज्यादा जानें", "what_you_get_title": "आपको क्या मिलता है", @@ -6738,7 +6836,8 @@ "sent": "भेजा गया", "transferred": "ट्रांसफर किया गया", "card_transaction": "कार्ड ट्रांसेक्शन", - "converted": "कन्वर्ट किया गया" + "converted": "कन्वर्ट किया गया", + "failed": "नहीं हो पाया" }, "convert_stablecoins": { "title": "अपने स्टेबलकॉइन कन्वर्ट करें", @@ -6757,11 +6856,11 @@ "how_it_works_page": { "header_title": "वित्त", "section_title": "ये कैसे काम करता है", - "description_1": "Deposit mUSD into your Money account and earn up to {{percentage}}% APY (variable) automatically. Funds go into a DeFi vault that generates returns across audited lending markets—no staking, no claiming, no lock-ups.", + "description_1": "अपने मनी अकाउंट में mUSD जमा करें और ऑटोमेटिकली {{percentage}}% APY (बदलने वाला) कमाएँ। फंड एक DeFi वॉल्ट में जाते हैं जो ऑडिट किए गए लेंडिंग मार्केट में रिटर्न देता है—कोई स्टेकिंग नहीं, कोई क्लेमिंग नहीं, कोई लॉक-अप नहीं।", "description_2": "आपका Money बैलेंस आपका खर्च करने का बैलेंस है। दुनिया भर में 150M+ मर्चेंट पर खर्च करने के लिए अपना MetaMask कार्ड लिंक करें। आपका पैसा तब तक कमाता रहता है जब तक आप इसका इस्तेमाल नहीं करते।", - "faq_title": "Frequently asked questions", + "faq_title": "अक्सर पूछे जाने वाले सवाल", "faq_placeholder_answer": "जल्द आ रहा है।", - "faq_q1": "How does the {{percentage}}% APY work?", + "faq_q1": "{{percentage}}% APY कैसे काम करता है?", "faq_q2": "mUSD क्या है?", "faq_q3": "यील्ड कहाँ से आती है?", "faq_q4": "क्या मेरा पैसा लॉक हो गया है? क्या मैं कभी भी निकाल सकता हूँ?", @@ -7030,11 +7129,12 @@ "confirm": "कन्फर्म करें", "pay_with_bottom_sheet": { "title": "के साथ भुगतान करें", - "last_used": "Last used", - "crypto": "Crypto", - "available_balance": "{{balance}} available", - "other_assets": "Other assets", - "other_assets_description": "Select from your tokens" + "last_used": "पिछली बार इस्तेमाल किया गया", + "bank_and_card": "बैंक और कार्ड", + "crypto": "क्रिप्टो", + "available_balance": "{{balance}} उपलब्ध है", + "other_assets": "अन्य एसेट्स", + "other_assets_description": "अपने टोकन में से चुनें" }, "staking_footer": { "part1": "जारी रखकर, आप हमारी ", @@ -7120,7 +7220,7 @@ "transaction_fee": "mUSD कन्वर्शन शुल्क में नेटवर्क लागत शामिल होती है और इसमें प्रदाता शुल्क भी शामिल हो सकता है। जब आप mUSD में कन्वर्ट करते हैं, तो कोई MetaMask शुल्क लागू नहीं होता।" }, "money_account_withdraw": { - "transaction_fee": "MetaMask will swap your mUSD for your desired token. Swap providers may charge a fee, but MetaMask won't." + "transaction_fee": "MetaMask आपके mUSD को आपके मनचाहे टोकन से स्वैप करेगा। स्वैप प्रोवाइडर फीस ले सकते हैं, लेकिन MetaMask नहीं लेगा।" }, "title": { "transaction_fee": "फीस" @@ -7225,7 +7325,7 @@ "deposit_edit_amount_done": "फंड जोड़ें", "deposit_edit_amount_predict_withdraw": "निकालें", "deposit_edit_amount_musd_conversion": "mUSD में कन्वर्ट करें", - "preparing_order": "Preparing order" + "preparing_order": "ऑर्डर तैयार किया जा रहा है" }, "change_in_simulation_modal": { "title": "परिणाम बदल गए हैं", @@ -7250,20 +7350,33 @@ "confirm_swap": "स्वैप करें", "terms_and_conditions": "नियम और शर्त", "select_token": "टोकन चुनें", - "batch_sell_select_title": "Select up to 5 tokens", - "batch_sell_select_subtitle": "All tokens need to be on the same network.", - "batch_sell_empty_state_title": "No tokens. No problem.", - "batch_sell_empty_state_description": "No tokens. No problem. Explore and buy tokens to batch sell.", - "batch_sell_continue_with_one_token": "Continue with (1) token", - "batch_sell_continue_with_tokens": "Continue with ({{tokenCount}}) tokens", - "batch_sell_max_tokens_allowed": "Max 5 tokens allowed", - "batch_sell_single_token_dialog_title": "High rate alert", - "batch_sell_single_token_dialog_description": "Batch selling one token could lead to a higher rate. Want to do a swap instead?", - "batch_sell_swap_instead": "Yes, swap", - "batch_sell_checkbox_label": "Batch Sell token", - "sort_balance": "Balance", - "next": "Next", - "explore_tokens": "Explore tokens", + "batch_sell_select_title": "5 टोकन तक चुनें", + "batch_sell_select_subtitle": "सभी टोकन एक ही नेटवर्क पर होने चाहिए।", + "batch_sell_empty_state_title": "कोई टोकन नहीं। कोई दिक्कत नहीं।", + "batch_sell_empty_state_description": "कोई टोकन नहीं। कोई प्रॉब्लम नहीं। बैच सेल के लिए टोकन एक्सप्लोर करें और खरीदें।", + "batch_sell_continue_with_one_token": "(1) टोकन के साथ जारी रखें", + "batch_sell_continue_with_tokens": "({{tokenCount}}) टोकन के साथ जारी रखें", + "batch_sell_max_tokens_allowed": "ज़्यादा से ज़्यादा 5 टोकन अलाउड हैं", + "batch_sell_single_token_dialog_title": "हाई रेट अलर्ट", + "batch_sell_single_token_dialog_description": "एक टोकन बैच में बेचने पर रेट ज़्यादा हो सकता है। क्या आप इसके बजाय स्वैप करना चाहते हैं?", + "batch_sell_swap_instead": "हाँ, स्वैप करें", + "batch_sell_review_title": "बैच सेल रिव्यू", + "batch_sell_select_stablecoin": "एक स्टेबलकॉइन चुनें", + "batch_sell_total_received": "टोटल प्राप्त हुआ", + "batch_sell_minimum_received": "Minimum received", + "batch_sell_quote_details_row": "{{tokenSymbol}} • {{slippage}} slippage", + "batch_sell_review": "समीक्षा करें", + "batch_sell_you_sell": "You sell", + "batch_sell_token_count": "{{tokenCount}} tokens", + "batch_sell_toggle_you_sell": "Toggle token details", + "batch_sell_sell_all": "Sell all", + "batch_sell_includes_metamask_fee": "Includes {{fee}}% MetaMask fee", + "batch_sell_customize_token": "{{tokenSymbol}} कस्टमाइज़ करें", + "batch_sell_remove_token": "{{tokenSymbol}} हटाएं", + "batch_sell_checkbox_label": "बैच सेल टोकन", + "sort_balance": "बैलेंस", + "next": "आगे", + "explore_tokens": "टोकन एक्सप्लोर करें", "no_tokens_found": "कोई टोकन नहीं मिला", "no_tokens_found_description": "हमें इस नाम का कोई टोकन नहीं मिला। कोई एक अलग सर्च से कोशिश करें।", "select_network": "नेटवर्क चुनें", @@ -7332,6 +7445,7 @@ "price_impact_execution_description": "इस स्वैप में आप अपने टोकन के मूल्य का लगभग {{priceImpact}} खो देंगे। राशि कम करने की कोशिश करें या अधिक लिक्विड रूट चुनें।", "proceed": "आगे बढ़ें", "cancel": "कैंसिल करें", + "close": "बंद करें", "slippage_info_title": "स्लिपेज (slippage)", "slippage_info_description": "ट्रांसेक्शन कैंसिल होने से पहले आप जो प्राइस में % परिवर्तन स्वीकार करने के लिए तैयार हैं।", "blockaid_error_title": "इस ट्रांसेक्शन को वापस किया जाएगा", @@ -8107,7 +8221,14 @@ "retry": "फिर से प्रयास करें", "on_linea": "Linea पर", "account_label": "अकाउंट", - "token_label": "टोकन" + "token_label": "टोकन", + "money_account_label": "Money account", + "money_account_token_symbol": "mUSD", + "use_money_account_cta": "Use Money account", + "spend_and_earn_title": "Spend while you earn", + "spend_and_earn_description": "Spend with your Money account and earn up to {{apy}}% APY on your balance. Also get {{cashback}}% mUSD back.", + "spend_and_earn_description_no_apy": "Spend with your Money account and earn APY on your balance. Also get {{cashback}}% mUSD back.", + "spend_and_earn_cta": "Link to Money account" }, "cashback_screen": { "title": "mUSD वापस", @@ -8449,6 +8570,7 @@ "show_less": "कम दिखाएं", "linking_progress": "एकाउंट्स जोड़ा जा रहा है... ({{current}}/{{total}})", "accounts_linked_count": "{{linked}}/{{total}} नामांकन किया गया", + "accounts_added": "Accounts added", "add_all_accounts": "सभी एकाउंट जोड़ें", "environment_selector": "वातावरण", "environment_cancel": "कैंसिल करें", @@ -8473,15 +8595,22 @@ }, "optout": { "title": "रिवॉर्ड्स प्रगति हटाएँ", - "description": "यह क्रिया आपके खाते को रिवॉर्ड्स प्रोग्राम से हटा देगी और आपकी प्रोग्रेस को मिटा देगी। यह कार्रवाई वापस नहीं की जा सकती।", - "confirm": "हटाएँ", + "description": "This will remove your accounts from the Rewards program and your progress in any campaigns you've joined. Only do this if you are absolutely sure you want to erase your progress.", + "erase_button": "Erase progress", "modal": { "confirmation_title": "क्या आप सुनिश्चित हैं?", - "confirmation_description": "इससे आपकी सभी प्रगति हट जाएगी और इसे वापस नहीं लाया जा सकता। यदि आप बाद में रिवॉर्ड्स प्रोग्राम में फिर से शामिल होते हैं, तो आपकी शुरुआत फिर से 0 से होगी।", + "confirmation_description": "This will erase all your progress, and can't be reversed. If you rejoin the Rewards program later, you'll start back at 0.", + "type_to_confirm": "Type 'erase progress' to continue", + "confirm_phrase": "erase progress", "cancel": "कैंसिल करें", "confirm": "कन्फर्म करें", + "error_title": "कुछ गलत हो गया", "error_message": "रिवॉर्ड्स से ऑप्ट आउट नहीं हो पाया। कृपया फिर से प्रयास करें।", "processing": "प्रोसेस हो रहा है..." + }, + "request_received": { + "title": "Request received", + "description": "In about 7 days, your progress will be fully erased. If you made this request by mistake, please contact support through the app." } }, "toast_dismiss": "खारिज करें", @@ -8569,7 +8698,8 @@ "title_claim": "फ़ायदे क्लेम करें", "action": "क्लेम करें", "empty-list": "अभी आपको कोई फ़ायदा नहीं मिल रहा है।", - "powered_by": "के द्वारा पावर्ड" + "powered_by": "के द्वारा पावर्ड", + "available_count": "{{count}} उपलब्ध है" }, "end_of_season_rewards": { "confirm_label_default": "कन्फर्म करें", @@ -8702,7 +8832,7 @@ "label_your_rank": "आपकी रैंक", "label_portfolio": "Portfolio", "label_net_inflow": "नेट इनफ्लो", - "label_total_inflow": "कुल इनफ्लो", + "label_total_inflow": "टोटल इनफ्लो", "label_outflow": "आउटफ्लो", "label_days_held": "दिनों तक होल्ड किया", "qualified_title": "आप क्वालिफ़ाई कर चुके हैं", @@ -8887,9 +9017,11 @@ "musd_claim": "mUSD क्लेम करें", "perps_deposit": "फंड जोड़ें", "perps_withdraw": "विदड्रॉवल", + "predict_withdraw": "{{sourceSymbol}} को {{sourceChain}} से विदड्रॉ करें", "predict_deposit": "फंड जोड़ें", "swap": "टोकन स्वैप करें", - "swap_approval": "टोकन एप्रूव करें" + "swap_approval": "टोकन एप्रूव करें", + "fiat_purchase": "{{paymentMethod}} के साथ {{token}} खरीदें" }, "perps_deposit_solution": "अब आपके पास Arbitrum पर USDC का {{fiat}} है। कृपया अपना डिपॉज़िट फिर से प्रयास करें।" }, @@ -8965,7 +9097,7 @@ "high_to_low": "ज़्यादा से कम", "low_to_high": "कम से ज़्यादा", "apply": "लागू करें", - "search_placeholder": "टोकन, साइट, URL ढूंढें", + "search_placeholder": "Search tokens, markets and URLs", "cancel": "कैंसिल करें", "perps": "पर्प्स", "rwa_perps_section": "पर्प्स", @@ -8978,11 +9110,15 @@ "crypto_perps_section": "पर्प्स", "predictions": "प्रेडिक्शंस", "no_results": "कोई रिज़ल्ट नहीं मिला", + "no_results_for_feed": "No {{feedName}} results for \"{{query}}\"", + "showing_all_results_for": "We found these results for \"{{query}}\"", "popular": "लोकप्रिय", "sites": "साइट्स", "popular_sites": "पॉपुलर साइटें", "search_sites": "साइट ढूंढें", "view_all": "सभी देखें", + "view_more": "अधिक देखें", + "view_x_more": "View {{count}} more", "enable_basic_functionality": "बेसिक फंक्शनलिटी को चालू करें", "basic_functionality_disabled_title": "एक्सप्लोर उपलब्ध नहीं है", "basic_functionality_disabled_description": "बेसिक फंक्शनलिटी बंद होने पर हम ज़रूरी मेटाडेटा नहीं ला सकते।", @@ -9002,6 +9138,14 @@ "crypto": "क्रिप्टो", "sports": "स्पोर्ट्स", "dapps": "साइट्स" + }, + "search_tabs": { + "all": "सभी", + "crypto": "Cryptos", + "perps": "पर्प्स", + "stocks": "स्टॉक्स", + "predictions": "प्रेडिक्शंस", + "sites": "साइट्स" } }, "ota_update_modal": { @@ -9139,6 +9283,7 @@ "money_empty_description_network_filter": "इस नेटवर्क पर कोई mUSD नहीं है। अपना mUSD देखने के लिए नेटवर्क बदलें।", "money_empty_state": { "get_started": "शुरू करें", + "earn": "कमाएं", "earn_apy": "{{percentage}}% APY कमाएं" }, "money_filled_state": { @@ -9150,22 +9295,7 @@ "related_assets": "संबंधित एसेट्स", "perpetuals": "परपेचुअल्स", "predictions": "प्रेडिक्शंस", - "whats_happening": "क्या हो रहा है", - "whats_happening_ai": "AI", - "whats_happening_impact": { - "bullish": "बुलिश", - "bearish": "बेयरिश", - "neutral": "न्यूट्रल" - }, "top_traders": "टॉप ट्रेडर्स", - "whats_happening_categories": { - "geopolitical": "जियोपॉलिटिकल", - "macro": "मैक्रो", - "regulatory": "रेगुलेटरी", - "technical": "टेक्निकल", - "social": "सोशल", - "other": "अन्य" - }, "defi": "DeFi", "nfts": "NFTs", "trending_tokens": "ट्रेंडिंग", @@ -9185,5 +9315,22 @@ }, "sites": { "popular": "लोकप्रिय" + }, + "whats_happening": { + "title": "क्या हो रहा है", + "ai": "AI", + "impact": { + "bullish": "बुलिश", + "bearish": "बेयरिश", + "neutral": "न्यूट्रल" + }, + "categories": { + "geopolitical": "जियोपॉलिटिकल", + "macro": "मैक्रो", + "regulatory": "रेगुलेटरी", + "technical": "टेक्निकल", + "social": "सोशल", + "other": "अन्य" + } } } diff --git a/locales/languages/id.json b/locales/languages/id.json index 43c5e949c54..03eb157bb9f 100644 --- a/locales/languages/id.json +++ b/locales/languages/id.json @@ -120,6 +120,10 @@ "account_no_funds": { "message": "Dana tidak tersedia. Gunakan akun lain." }, + "headless_buy_error": { + "title": "Pembelian fiat gagal", + "message": "Terjadi kesalahan pada pembelian fiat. Coba lagi." + }, "mmpay_hardware_account": { "title": "Dompet tidak didukung", "message": "Dompet perangkat keras tidak didukung.\nGanti dompet untuk melanjutkan." @@ -133,8 +137,8 @@ "message": "Alamat penerima mungkin tidak mendukung transfer token langsung, yang dapat mengakibatkan hilangnya dana. Lanjutkan hanya jika Anda yakin kontrak ini dapat menerima transfer." }, "gas_sponsorship_reserve_balance": { - "message": "Sponsor gas tidak tersedia untuk transaksi ini. Anda perlu mempertahankan saldo minimal %{minBalance} %{nativeTokenSymbol} di akun Anda.", - "title": "Sponsor gas tidak tersedia" + "message": "Jaringan khusus ini mengharuskan Anda untuk mempertahankan saldo cadangan sebesar %{minBalance} %{nativeTokenSymbol} di akun Anda.", + "title": "Saldo cadangan diperlukan" }, "token_trust_signal": { "malicious": { @@ -708,6 +712,9 @@ "contractAddressError": "Anda mengirimkan token ke alamat kontrak token. Hal ini dapat mengakibatkan hilangnya token tersebut.", "smart_contract_address": "Alamat kontrak cerdas", "smart_contract_address_warning": "Alamat penerima mungkin tidak mendukung transfer token langsung, yang dapat mengakibatkan hilangnya dana. Lanjutkan hanya jika Anda yakin kontrak ini dapat menerima transfer.", + "unavailable_network_connection": "Unavailable network connection", + "unavailable_network_connection_description": "The connection with {{network}} is unreliable. Update network connectivity details before continuing or try again later.", + "update": "Perbarui", "i_understand": "Saya mengerti", "cancel": "Batal", "new_address_title": "Alamat baru", @@ -1068,7 +1075,7 @@ "sort": { "value": "Nilai", "pnl_percent": "P&L %", - "recent": "Recent" + "recent": "Terbaru" } }, "trader_position": { @@ -1120,6 +1127,11 @@ "title": "Perdagangkan {{symbol}} perp", "subtitle": "Gandakan P&L Anda hingga {{leverage}}" }, + "service_interruption": { + "title": "We're experiencing an outage", + "description": "Some services may be unavailable while the team works on a fix.", + "contact_support": "Hubungi dukungan" + }, "today": "Hari ini", "yesterday": "Kemarin", "unrealized_pnl": "P&L Belum Terealisasi", @@ -1284,7 +1296,9 @@ "toast_completed_subtitle": "{{amount}} USDC dipindahkan ke dompet Anda", "toast_completed_any_token_subtitle": "{{amount}} {{token}} dipindahkan ke dompet Anda", "toast_error_title": "Terjadi kesalahan", - "toast_error_description": "Gagal memproses penarikan" + "toast_error_description": "Gagal memproses penarikan", + "toast_start_error_description": "Your withdrawal wasn’t started.", + "try_again": "Coba lagi" }, "quote": { "network_fee": "Biaya jaringan", @@ -2227,35 +2241,35 @@ "predict": { "title": "MetaMask Predictions", "world_cup": { - "title": "World Cup", - "banner_title": "World Cup 2026", - "banner_description": "Trade on World Cup markets", + "title": "Piala Dunia", + "banner_title": "Piala Dunia 2026", + "banner_description": "Trade every match, every moment.", "tabs": { - "all": "All", - "props": "Props", - "live": "Live" + "all": "Semua", + "props": "Prop", + "live": "Langsung" }, "stages": { - "group_stage": "Group Stage", - "round_of_32": "Round of 32", - "round_of_16": "Round of 16", - "quarterfinals": "Quarterfinals", - "semifinals": "Semifinals", - "third_place": "Third Place", + "group_stage": "Babak Penyisihan Grup", + "round_of_32": "Babak 32 besar", + "round_of_16": "Babak 16 besar", + "quarterfinals": "Perempat final", + "semifinals": "Semifinal", + "third_place": "Posisi Ketiga", "final": "Final", - "group_a": "Group A", - "group_b": "Group B", - "group_c": "Group C", - "group_d": "Group D", - "group_e": "Group E", - "group_f": "Group F", - "group_g": "Group G", - "group_h": "Group H", - "group_i": "Group I", - "group_j": "Group J", - "group_k": "Group K", - "group_l": "Group L", - "third_place_match": "Third Place Match" + "group_a": "Grup A", + "group_b": "Grup B", + "group_c": "Grup C", + "group_d": "Grup D", + "group_e": "Grup E", + "group_f": "Grup F", + "group_g": "Grup G", + "group_h": "Grup H", + "group_i": "Grup I", + "group_j": "Grup J", + "group_k": "Grup K", + "group_l": "Grup L", + "third_place_match": "Pertandingan Perebutan Posisi Ketiga" } }, "prediction_markets": "Pasar prediksi", @@ -2537,8 +2551,8 @@ "withdraw_completed": "Penarikan selesai", "withdraw_completed_subtitle": "{{amount}} USDC dipindahkan ke dompet Anda", "withdraw_any_token_completed_subtitle": "{{amount}} {{token}} dipindahkan ke dompet Anda", - "unavailable_title": "Withdrawals temporarily unavailable", - "unavailable_description": "For urgent assistance, please contact Customer Service.", + "unavailable_title": "Penarikan dana sementara tidak tersedia", + "unavailable_description": "Untuk bantuan mendesak, hubungi Layanan Pelanggan.", "unavailable_got_it": "Mengerti", "error_title": "Terjadi kesalahan", "error_description": "Gagal melanjutkan penarikan", @@ -2941,6 +2955,17 @@ "pna25_confirm_button": "Terima dan tutup", "pna25_open_settings_button": "Buka Pengaturan" }, + "onboarding_interest_questionnaire": { + "title": "Apa yang ingin Anda lakukan dengan MetaMask?", + "description": "Pilih semua yang sesuai.", + "option_buy_and_sell_crypto": "Membeli dan menjual kripto", + "option_consolidate_wallets": "Menggabungkan dompet Anda", + "option_advanced_trades": "Melakukan perdagangan lanjutan", + "option_predict_sports_events": "Memprediksi olahraga dan peristiwa", + "option_crypto_as_money": "Menggunakan kripto sebagai uang", + "option_connect_apps_sites": "Terhubung ke aplikasi atau situs", + "continue": "Lanjutkan" + }, "template_confirmation": { "ok": "Oke", "cancel": "Batal" @@ -3261,8 +3286,27 @@ "notifications_desc": "Kelola notifikasi", "allow_notifications": "Izinkan notifikasi", "enable_push_notifications": "Aktifkan notifikasi push", - "allow_notifications_desc": "Pantau terus segala yang terjadi di dompet Anda dengan notifikasi. Untuk menggunakan notifikasi, kami menggunakan profil untuk menyinkronkan beberapa pengaturan di seluruh perangkat Anda.", + "allow_notifications_desc": "Choose what you're notified about and how.", "notifications_opts": { + "preferences_title": "Preferences", + "push_recommended": "Push", + "in_app": "In-app", + "status_push": "Push", + "status_in_app": "In app", + "status_off": "Mati", + "select_all": "Pilih semua", + "deselect_all": "Batal pilih semua", + "select_accounts_title": "Akun", + "select_accounts_desc": "Choose which accounts you'd like to get notifications for.", + "wallet_activity_title": "Wallet Activity", + "wallet_activity_desc": "Buy, sells, transfers, swaps and rewards", + "perps_title": "Trading Activity", + "perps_desc": "Perps position changes, liquidations, funding rates, and margin updates", + "social_ai_title": "Trading Signals", + "social_ai_desc": "Updates from traders and assets you follow, plus currated market news", + "marketing_title": "Updates and Rewards", + "marketing_desc": "Product updates, feature announcements, and new releases", + "marketing_disclaimer": "By turning this on, you agree to receive product news and marketing updates from MetaMask.", "customize_session_title": "Sesuaikan notifikasi", "customize_session_desc": "Aktifkan jenis notifikasi yang ingin diterima:", "account_session_title": "Aktivitas akun", @@ -3276,8 +3320,7 @@ "snaps_title": "Snap", "snaps_desc": "Fitur dan pembaruan terkini", "products_announcements_title": "Pengumuman produk", - "products_announcements_desc": "Produk dan fitur baru", - "perps_title": "Perdagangan Perp" + "products_announcements_desc": "Produk dan fitur baru" }, "contacts_title": "Kontak", "contacts_desc": "Tambahkan, edit, hapus, dan kelola akun Anda.", @@ -3640,7 +3683,15 @@ "card": { "title": "Kartu", "reset_onboarding_description": "Reset status pendaftaran Kartu untuk memulai alur pendaftaran dari awal.", - "reset_onboarding_button": "Reset Status Pendaftaran" + "reset_onboarding_button": "Reset Status Pendaftaran", + "unlink_money_account_description": "Cabut izin batas penggunaan USDC yang mengizinkan Kartu untuk menggunakan saldo dari Akun Dana milik Anda. Ini mengirimkan transaksi persetujuan(0) dan menandai Akun Dana sebagai tidak didelegasikan di backend Kartu.", + "unlink_money_account_button": "Batalkan penautan Akun Dana dari kartu", + "unlink_money_account_disabled_hint": "Tidak ada tautan aktif yang perlu dihapus." + }, + "identity": { + "title": "Identity", + "description": "Clears the persisted authentication session. Use this after toggling MM_DEV_API_ENV — otherwise a prod-minted JWT keeps being handed to dev-API consumers until it expires. Current MM_DEV_API_ENV: {{env}}.", + "clear_auth_session_button": "Clear persisted auth session" }, "haptics": { "title": "Haptic", @@ -3842,8 +3893,8 @@ "predict_button": "Prediksi", "add_collectible_button": "Tambahkan", "info": "Informasi", - "batch_sell": "Batch Sell", - "batch_sell_new_label": "New", + "batch_sell": "Penjualan Massal", + "batch_sell_new_label": "Baru", "swap": "Tukar", "convert": "Konversikan", "bridge": "Bridge", @@ -3883,7 +3934,7 @@ "troubleshoot": "Troubleshoot", "deposit_description": "Transfer bank atau kartu dengan biaya rendah", "buy_description": "Cocok untuk membeli token tertentu", - "batch_sell_description": "Sell up to 5 tokens for a stablecoin", + "batch_sell_description": "Jual maksimal 5 token untuk mendapatkan stablecoin", "sell_description": "Jual kripto untuk dapat uang tunai", "swap_description": "Pertukaran antar token", "bridge_description": "Transfer token antar jaringan", @@ -5205,6 +5256,34 @@ "manage_preferences_2": "Pengaturan > Notifikasi.", "cancel": "Batal", "cta": "Aktifkan" + }, + "push_onboarding": { + "new_user": { + "title": "Jangan pernah melewatkan apa pun", + "body": "Dapatkan peringatan waktu nyata saat harga mencapai target Anda, perdagangan Anda dikonfirmasi, dan portofolio Anda bergerak. Plus pembaruan produk dan reward di sepanjang perjalanannya. Kami akan membagikan pembaruan berdasarkan interaksi Anda dengan MetaMask.", + "button_yes": "Ya", + "button_not_now": "Tidak sekarang", + "preview_card_1": { + "eyebrow": "METAMASK", + "time": "sekarang", + "title": "ETH naik 4,2% hari ini", + "message": "Sekarang seharga $2.668,51 — di atas peringatan harga Anda" + }, + "preview_card_2": { + "eyebrow": "METAMASK", + "time": "1 jam lalu", + "title": "Menerima 0,25 ETH", + "message": "Dari 0x9a21…4f8c · $640,29" + } + }, + "existing_user": { + "title": "Memperkenalkan peringatan yang dipersonalisasi", + "body": "Dapatkan notifikasi yang sesuai dengan cara Anda berdagang. Perbarui setiap saat.", + "card_title": "Yang akan Anda dapatkan", + "card_description": "Peringatan dan pembaruan yang dipersonalisasi dan disesuaikan dengan aktivitas perdagangan Anda.", + "button_confirm": "Konfirmasikan", + "button_not_now": "Tidak sekarang" + } } }, "protect_your_wallet_modal": { @@ -5315,6 +5394,7 @@ "pay_with": "Bayar melalui", "buying_via": "Membeli melalui {{providerName}}.", "change_provider": "Ubah penyedia.", + "circuit_breaker_open": "This service is temporarily unavailable. Please try again in about 30 minutes.", "payment_error": "Terjadi kesalahan. Coba lagi.", "no_payment_methods_available": "Tidak ada metode pembayaran yang tersedia.", "error_fetching_quotes": "Terjadi kesalahan. Coba lagi.", @@ -6520,6 +6600,8 @@ "convert_to_musd": "Konversikan ke mUSD", "get_a_percentage_musd_bonus": "Dapatkan bonus {{percentage}}% mUSD", "convert": "Konversikan", + "confirm": "Konfirmasikan", + "convert_tooltip_description": "Konversikan stablecoin Anda ke mUSD dan dapatkan bonus tahunan hingga {{percentage}}% yang dapat diklaim setiap hari. Didukung oleh Relay.", "fetching_quote": "Mengambil kuotasi...", "you_convert": "Anda mengonversi", "network_fee": "Biaya jaringan", @@ -6597,7 +6679,7 @@ "step_progress": "Langkah {{current}} dari {{total}}", "title": "Tambahkan uang", "description": "Danai akun Anda dan mulailah mendapatkan APY.", - "add": "Tambah", + "add": "Tambahkan dana", "step2_title": "Dapatkan Kartu MetaMask", "step2_description": "Gunakan saldo Dana selagi masih menghasilkan, di mana pun Mastercard diterima.", "step2_cta": "Dapatkan kartu", @@ -6605,6 +6687,19 @@ "link_card_description": "Gunakan saldo Anda selagi masih menghasilkan, di mana pun Mastercard diterima.", "link_card_cta": "Tautkan kartu" }, + "rive_onboarding": { + "step1_title": "Akun Dana telah hadir", + "step1_body": "Dapatkan hingga {{percentage}}% APY dari saldo Anda, tersedia di seluruh dompet Anda.", + "step1_footer_text": "APY bersifat variabel dan dapat berubah sewaktu-waktu.", + "step2_title": "Dapatkan secara otomatis", + "step2_body": "Pindahkan stablecoin tanpa biaya pertukaran. Dana mulai menghasilkan keuntungan segera.", + "step2_footer_text": "Provided by Veda and Steakhouse Financial.", + "step3_title": "Gunakan di mana pun", + "step3_body": "Dapatkan hingga {{percentage}}% pengembalian dari pembelian dengan menghubungkan akun Dana milik Anda ke kartu MetaMask.", + "step4_title": "Berdagang dan hasilkan keuntungan di satu tempat", + "step4_body": "Gunakan saldo Dana untuk bertransaksi di MetaMask sambil tetap mendapatkan keuntungan.", + "continue": "Lanjutkan" + }, "action": { "add": "Tambah", "transfer": "Transfer", @@ -6618,8 +6713,8 @@ }, "how_it_works": { "title": "Cara kerjanya", - "description_prefix": "Deposit mUSD into your Money account and earn up to", - "description_suffix": ". Your balance is dollar-backed and ready to spend, trade, or send anytime." + "description_prefix": "Depositkan mUSD ke akun Dana dan dapatkan hingga", + "description_suffix": ". Saldo Anda didukung dolar dan siap untuk digunakan, diperdagangkan, atau dikirim setiap saat." }, "musd_row": { "add": "Tambah" @@ -6627,16 +6722,16 @@ "balance_card": { "label": "Saldo dana", "add": "Tambah", - "info_sheet_title": "Money balance", - "info_sheet_body": "Your dollar-backed mUSD balance that's always available to spend, send, or trade anytime. We don't calculate this into your total account balance.\n\nWithdrawals process immediately, subject to standard network confirmation times on the relevant blockchain. If liquidity is tight, there may be temporary delays." + "info_sheet_title": "Saldo dana", + "info_sheet_body": "Saldo mUSD yang didukung dolar selalu tersedia untuk digunakan, dikirim, atau diperdagangkan setiap saat. Kami tidak menghitung ini ke dalam total saldo akun Anda.\n\nPenarikan diproses dengan segera, tergantung waktu konfirmasi jaringan standar pada blockchain yang relevan. Jika likuiditas ketat, penundaan sementara dapat terjadi." }, "potential_earnings": { "title": "Raih pendapatan dari kripto", "description": "Lihat bagaimana uang Anda dapat bertambah nilainya dari waktu ke waktu dengan mengonversikan kripto menjadi mUSD.", - "description_with_amounts_prefix": "Convert your {{total}} in assets and you could earn up to", - "description_with_amounts_suffix": "in one year.", + "description_with_amounts_prefix": "Konversikan {{total}} menjadi aset dan Anda bisa mendapatkan hingga", + "description_with_amounts_suffix": "dalam satu tahun.", "convert": "Konversikan", - "convert_cta": "Convert your crypto", + "convert_cta": "Konversikan kripto Anda", "no_fee": "Tidak ada biaya MetaMask", "view_all": "Lihat semua", "view_potential_earnings": "Lihat potensi penghasilan" @@ -6649,41 +6744,44 @@ "cashback": "pengembalian {{percentage}}% mUSD", "get_now": "Dapatkan sekarang", "link_title": "Tautkan Kartu MetaMask", - "link_subtitle": "Spend your Money balance and earn on purchases. Plus, up to {{apy}}% APY on your balance.", - "link_bullet_cashback": "Get {{percentage}}% mUSD back", - "link_bullet_apy": "Earn up to {{apy}}% APY", + "link_subtitle": "Gunakan saldo Dana dan dapatkan keuntungan dari pembelian. Plus, hingga {{apy}}% APY dari saldo Anda.", + "link_subtitle_no_apy": "Spend your Money balance and earn on purchases.", + "link_bullet_cashback": "Dapatkan pengembalian {{percentage}}% mUSD", + "link_bullet_apy": "Dapatkan hingga {{apy}}% APY", "link_card": "Tautkan kartu", - "link_pending_title": "Linking card", - "link_pending_description": "Approving spending limit…", - "link_success_title": "Card linked successfully", - "link_success_description": "You can now spend while you earn", - "link_error": "Couldn't link card", - "manage_card": "Manage", - "avail_balance": "Avail. balance" + "link_pending_title": "Linking your card", + "link_success_title": "Your card is ready to use", + "link_error": "Something went wrong linking your card", + "link_card_sheet_title": "Gunakan dan dapatkan", + "link_card_sheet_description": "Link your card so you can spend your Money balance and earn mUSD back on purchases—all while earning up to {{apy}}% APY.", + "link_card_sheet_description_no_apy": "Link your card so you can spend your Money balance and earn mUSD back on purchases.", + "link_card_sheet_cta": "Tautkan kartu", + "manage_card": "Kelola", + "avail_balance": "Saldo tersedia" }, "what_you_get": { "title": "Yang Anda dapatkan", - "benefit_auto_earn": "Auto-earn up to", + "benefit_auto_earn": "Dapatkan otomatis hingga", "benefit_dollar_backed": "Amankan uang Anda di mUSD, stablecoin yang didukung dolar dengan rasio 1:1", "benefit_liquidity": "Dapatkan likuiditas penuh tanpa penguncian, sehingga Anda dapat melakukan perdagangan atau penarikan setiap saat", "benefit_spend_prefix": "Gunakan di lebih dari 150 juta merchant dengan Kartu MetaMask dan dapatkan ", "benefit_spend_cashback": "Pengembalian 1-3% mUSD", - "benefit_transfer": "Transfer to any of your wallets across MetaMask", - "benefit_global": "Send and receive funds globally", + "benefit_transfer": "Transfer ke dompet mana pun di MetaMask", + "benefit_global": "Kirim dan terima dana secara global", "learn_more": "Pelajari selengkapnya" }, "footer": { - "add_money": "Add funds" + "add_money": "Tambahkan dana" }, "add_money_sheet": { - "title": "Add funds", + "title": "Tambahkan dana", "convert_crypto": "Konversikan kripto", - "convert_crypto_description": "From any account", + "convert_crypto_description": "Dari akun mana pun", "deposit_funds": "Depositkan dana", - "deposit_funds_description": "From debit card or bank", - "move_musd": "Transfer your {{amount}} mUSD", - "move_musd_no_amount": "Transfer your mUSD", - "move_musd_description": "From your balance", + "deposit_funds_description": "Dari kartu debit atau bank", + "move_musd": "Transfer {{amount}} mUSD", + "move_musd_no_amount": "Transfer mUSD", + "move_musd_description": "Dari saldo Anda", "receive_external": "Terima dari dompet eksternal", "coming_soon": "Segera hadir" }, @@ -6694,7 +6792,7 @@ "contact_support": "Hubungi dukungan" }, "transfer_sheet": { - "title": "Transfer funds", + "title": "Transfer dana", "between_accounts": "Antar akun", "perps_account": "Akun perp", "predictions_account": "Akun Predictions", @@ -6712,8 +6810,8 @@ "body": "Estimasi berapa banyak yang dapat Anda peroleh selama periode tertentu berdasarkan saldo saat ini dan APY (Persentase Hasil Tahunan) hari ini. Estimasi ini bukan jaminan pengembalian dan dapat berubah sewaktu-waktu." }, "earn_crypto_info_sheet": { - "title": "Earn on your crypto", - "body": "Illustration assumes {{percentage}}% Annual Percentage Yield (APY) remains unchanged for one year. APY is variable and may change due to various factors. No guarantee of return." + "title": "Raih pendapatan dari kripto", + "body": "Ilustrasi ini mengasumsikan Persentase Hasil Tahunan (APY) sebesar {{percentage}}% tetap tidak berubah selama satu tahun. APY bersifat variabel dan dapat berubah karena berbagai faktor. Tidak ada jaminan pengembalian." }, "activity": { "title": "Aktivitas", @@ -6725,7 +6823,7 @@ }, "condensed_cards": { "how_it_works_title": "Cara kerjanya", - "how_it_works_subtitle": "Lihat cara kerja dana Anda", + "how_it_works_subtitle": "See how your money can grow", "musd_title": "MetaMask USD", "musd_subtitle": "Pelajari lebih lanjut seputar mUSD", "what_you_get_title": "Yang Anda dapatkan", @@ -6738,7 +6836,8 @@ "sent": "Mengirim", "transferred": "Ditransfer", "card_transaction": "Transaksi kartu", - "converted": "Dikonversi" + "converted": "Dikonversi", + "failed": "Gagal" }, "convert_stablecoins": { "title": "Konversikan stablecoin Anda", @@ -6757,11 +6856,11 @@ "how_it_works_page": { "header_title": "Dana", "section_title": "Cara kerjanya", - "description_1": "Deposit mUSD into your Money account and earn up to {{percentage}}% APY (variable) automatically. Funds go into a DeFi vault that generates returns across audited lending markets—no staking, no claiming, no lock-ups.", + "description_1": "Depositkan mUSD ke akun Dana dan dapatkan hingga {{percentage}}% APY (variabel) secara otomatis. Dana masuk ke brankas DeFi yang menghasilkan keuntungan di pasar pinjaman yang diaudit—tanpa stake, tanpa klaim, tanpa penguncian.", "description_2": "Saldo Dana merupakan saldo penggunaan Anda. Hubungkan Kartu MetaMask untuk digunakan di lebih dari 150 juta merchant di seluruh dunia. Dana Anda terus menghasilkan keuntungan hingga saat Anda menggunakannya.", - "faq_title": "Frequently asked questions", + "faq_title": "Pertanyaan umum", "faq_placeholder_answer": "Segera hadir.", - "faq_q1": "How does the {{percentage}}% APY work?", + "faq_q1": "Bagaimana cara kerja {{percentage}}% APY?", "faq_q2": "Apa itu mUSD?", "faq_q3": "Dari mana hasil tersebut berasal?", "faq_q4": "Apakah dana saya terkunci? Bisakah saya menarik dana setiap saat?", @@ -7030,11 +7129,12 @@ "confirm": "Konfirmasikan", "pay_with_bottom_sheet": { "title": "Bayar melalui", - "last_used": "Last used", - "crypto": "Crypto", - "available_balance": "{{balance}} available", - "other_assets": "Other assets", - "other_assets_description": "Select from your tokens" + "last_used": "Terakhir digunakan", + "bank_and_card": "Bank dan kartu", + "crypto": "Kripto", + "available_balance": "{{balance}} tersedia", + "other_assets": "Aset lainnya", + "other_assets_description": "Pilih dari token Anda" }, "staking_footer": { "part1": "Dengan melanjutkan, Anda menyetujui ", @@ -7120,7 +7220,7 @@ "transaction_fee": "Biaya konversi mUSD mencakup biaya jaringan dan mungkin termasuk biaya penyedia. MetaMask tidak mengenakan biaya saat Anda mengonversi ke mUSD." }, "money_account_withdraw": { - "transaction_fee": "MetaMask will swap your mUSD for your desired token. Swap providers may charge a fee, but MetaMask won't." + "transaction_fee": "MetaMask akan menukar mUSD dengan token yang Anda inginkan. Penyedia layanan swap dapat mengenakan biaya, tetapi MetaMask tidak akan mengenakan biaya." }, "title": { "transaction_fee": "Biaya" @@ -7225,7 +7325,7 @@ "deposit_edit_amount_done": "Tambahkan dana", "deposit_edit_amount_predict_withdraw": "Tarik", "deposit_edit_amount_musd_conversion": "Konversikan ke mUSD", - "preparing_order": "Preparing order" + "preparing_order": "Mempersiapkan order" }, "change_in_simulation_modal": { "title": "Hasil telah berubah", @@ -7250,20 +7350,33 @@ "confirm_swap": "Swap", "terms_and_conditions": "Syarat & Ketentuan", "select_token": "Pilih token", - "batch_sell_select_title": "Select up to 5 tokens", - "batch_sell_select_subtitle": "All tokens need to be on the same network.", - "batch_sell_empty_state_title": "No tokens. No problem.", - "batch_sell_empty_state_description": "No tokens. No problem. Explore and buy tokens to batch sell.", - "batch_sell_continue_with_one_token": "Continue with (1) token", - "batch_sell_continue_with_tokens": "Continue with ({{tokenCount}}) tokens", - "batch_sell_max_tokens_allowed": "Max 5 tokens allowed", - "batch_sell_single_token_dialog_title": "High rate alert", - "batch_sell_single_token_dialog_description": "Batch selling one token could lead to a higher rate. Want to do a swap instead?", - "batch_sell_swap_instead": "Yes, swap", - "batch_sell_checkbox_label": "Batch Sell token", - "sort_balance": "Balance", - "next": "Next", - "explore_tokens": "Explore tokens", + "batch_sell_select_title": "Pilih maksimal 5 token", + "batch_sell_select_subtitle": "Semua token harus berada di jaringan yang sama.", + "batch_sell_empty_state_title": "Tidak punya token. Tidak masalah.", + "batch_sell_empty_state_description": "Tidak punya token? Tidak masalah. Jelajahi dan beli token untuk dijual secara massal.", + "batch_sell_continue_with_one_token": "Lanjutkan dengan (1) token", + "batch_sell_continue_with_tokens": "Lanjutkan dengan ({{tokenCount}}) token", + "batch_sell_max_tokens_allowed": "Maksimal 5 token diperbolehkan", + "batch_sell_single_token_dialog_title": "Peringatan harga tinggi", + "batch_sell_single_token_dialog_description": "Menjual satu token secara massal dapat menghasilkan harga yang lebih tinggi. Ingin melakukan swap saja?", + "batch_sell_swap_instead": "Ya, swap", + "batch_sell_review_title": "Ulasan Penjualan Massal", + "batch_sell_select_stablecoin": "Pilih stablecoin", + "batch_sell_total_received": "Total yang diterima", + "batch_sell_minimum_received": "Minimum received", + "batch_sell_quote_details_row": "{{tokenSymbol}} • {{slippage}} slippage", + "batch_sell_review": "Tinjau", + "batch_sell_you_sell": "You sell", + "batch_sell_token_count": "{{tokenCount}} tokens", + "batch_sell_toggle_you_sell": "Toggle token details", + "batch_sell_sell_all": "Sell all", + "batch_sell_includes_metamask_fee": "Includes {{fee}}% MetaMask fee", + "batch_sell_customize_token": "Sesuaikan {{tokenSymbol}}", + "batch_sell_remove_token": "Hapus {{tokenSymbol}}", + "batch_sell_checkbox_label": "Penjualan Massal token", + "sort_balance": "Saldo", + "next": "Berikutnya", + "explore_tokens": "Jelajahi token", "no_tokens_found": "Tidak ada token yang ditemukan", "no_tokens_found_description": "Kami tidak dapat menemukan token dengan nama ini. Coba pencarian lain.", "select_network": "Pilih jaringan", @@ -7332,6 +7445,7 @@ "price_impact_execution_description": "Anda akan kehilangan sekitar {{priceImpact}} dari nilai token Anda pada swap ini. Cobalah untuk mengurangi jumlahnya atau pilih rute yang lebih likuid.", "proceed": "Lanjutkan", "cancel": "Batal", + "close": "Tutup", "slippage_info_title": "Selip", "slippage_info_description": "% perubahan harga yang Anda bersedia izinkan sebelum transaksi dibatalkan.", "blockaid_error_title": "Transaksi ini akan dikembalikan", @@ -8107,7 +8221,14 @@ "retry": "Coba lagi", "on_linea": "di Linea", "account_label": "Akun", - "token_label": "Token" + "token_label": "Token", + "money_account_label": "Money account", + "money_account_token_symbol": "mUSD", + "use_money_account_cta": "Use Money account", + "spend_and_earn_title": "Spend while you earn", + "spend_and_earn_description": "Spend with your Money account and earn up to {{apy}}% APY on your balance. Also get {{cashback}}% mUSD back.", + "spend_and_earn_description_no_apy": "Spend with your Money account and earn APY on your balance. Also get {{cashback}}% mUSD back.", + "spend_and_earn_cta": "Link to Money account" }, "cashback_screen": { "title": "Pengembalian mUSD", @@ -8449,6 +8570,7 @@ "show_less": "Ciutkan", "linking_progress": "Menambahkan akun... ({{current}}/{{total}})", "accounts_linked_count": "{{linked}}/{{total}} terdaftar", + "accounts_added": "Accounts added", "add_all_accounts": "Tambahkan semua akun", "environment_selector": "Lingkungan", "environment_cancel": "Batal", @@ -8473,15 +8595,22 @@ }, "optout": { "title": "Hapus progres Rewards", - "description": "Tindakan ini akan menghapus akun Anda dari program Reward dan menghapus progres Anda. Tindakan ini tidak dapat dibatalkan.", - "confirm": "Hapus", + "description": "This will remove your accounts from the Rewards program and your progress in any campaigns you've joined. Only do this if you are absolutely sure you want to erase your progress.", + "erase_button": "Erase progress", "modal": { "confirmation_title": "Anda yakin?", - "confirmation_description": "Tindakan ini akan menghapus semua progres Anda dan tidak dapat dibatalkan. Jika bergabung kembali dengan program Reward nanti, Anda akan memulai dari 0.", + "confirmation_description": "This will erase all your progress, and can't be reversed. If you rejoin the Rewards program later, you'll start back at 0.", + "type_to_confirm": "Type 'erase progress' to continue", + "confirm_phrase": "erase progress", "cancel": "Batal", "confirm": "Konfirmasikan", + "error_title": "Terjadi kesalahan", "error_message": "Gagal keluar dari Reward. Coba lagi.", "processing": "Memproses..." + }, + "request_received": { + "title": "Request received", + "description": "In about 7 days, your progress will be fully erased. If you made this request by mistake, please contact support through the app." } }, "toast_dismiss": "Lewatkan", @@ -8569,7 +8698,8 @@ "title_claim": "Klaim Manfaat", "action": "Klaim", "empty-list": "Saat ini Anda tidak memiliki manfaat apa pun.", - "powered_by": "Didukung oleh" + "powered_by": "Didukung oleh", + "available_count": "{{count}} tersedia" }, "end_of_season_rewards": { "confirm_label_default": "Konfirmasikan", @@ -8887,9 +9017,11 @@ "musd_claim": "Klaim mUSD", "perps_deposit": "Tambahkan dana", "perps_withdraw": "Penarikan", + "predict_withdraw": "Tarik {{sourceSymbol}} dari {{sourceChain}}", "predict_deposit": "Tambahkan dana", "swap": "Tukar token", - "swap_approval": "Setujui token" + "swap_approval": "Setujui token", + "fiat_purchase": "Beli {{token}} dengan {{paymentMethod}}" }, "perps_deposit_solution": "Saat ini Anda memiliki {{fiat}} USDC di Arbitrum. Coba deposit lagi." }, @@ -8965,7 +9097,7 @@ "high_to_low": "Tinggi ke rendah", "low_to_high": "Rendah ke tinggi", "apply": "Terapkan", - "search_placeholder": "Cari token, situs, URL", + "search_placeholder": "Search tokens, markets and URLs", "cancel": "Batal", "perps": "Perps", "rwa_perps_section": "Perp", @@ -8978,11 +9110,15 @@ "crypto_perps_section": "Perp", "predictions": "Prediksi", "no_results": "Hasil tidak ditemukan", + "no_results_for_feed": "No {{feedName}} results for \"{{query}}\"", + "showing_all_results_for": "We found these results for \"{{query}}\"", "popular": "Populer", "sites": "Situs", "popular_sites": "Situs populer", "search_sites": "Cari situs", "view_all": "Lihat semua", + "view_more": "Lihat selengkapnya", + "view_x_more": "View {{count}} more", "enable_basic_functionality": "Aktifkan fungsi dasar", "basic_functionality_disabled_title": "Fitur Jelajahi tidak tersedia", "basic_functionality_disabled_description": "Kami tidak dapat mengakses metadata yang diperlukan saat fungsi dasar dinonaktifkan.", @@ -9002,6 +9138,14 @@ "crypto": "Kripto", "sports": "Olahraga", "dapps": "Situs" + }, + "search_tabs": { + "all": "Semua", + "crypto": "Cryptos", + "perps": "Perp", + "stocks": "Saham", + "predictions": "Prediksi", + "sites": "Situs" } }, "ota_update_modal": { @@ -9139,6 +9283,7 @@ "money_empty_description_network_filter": "Tidak ada mUSD di jaringan ini. Ganti jaringan untuk melihat mUSD milik Anda.", "money_empty_state": { "get_started": "Mulai", + "earn": "Dapatkan", "earn_apy": "Dapatkan APY {{percentage}}%" }, "money_filled_state": { @@ -9150,22 +9295,7 @@ "related_assets": "Aset Terkait", "perpetuals": "Abadi", "predictions": "Prediksi", - "whats_happening": "Apa yang sedang terjadi", - "whats_happening_ai": "AI", - "whats_happening_impact": { - "bullish": "Bullish", - "bearish": "Bearish", - "neutral": "Netral" - }, "top_traders": "Trader Top", - "whats_happening_categories": { - "geopolitical": "Geopolitik", - "macro": "Makro", - "regulatory": "Peraturan", - "technical": "Teknis", - "social": "Sosial", - "other": "Lainnya" - }, "defi": "DeFi", "nfts": "NFT", "trending_tokens": "Sedang tren", @@ -9185,5 +9315,22 @@ }, "sites": { "popular": "Populer" + }, + "whats_happening": { + "title": "Apa yang sedang terjadi", + "ai": "AI", + "impact": { + "bullish": "Bullish", + "bearish": "Bearish", + "neutral": "Netral" + }, + "categories": { + "geopolitical": "Geopolitik", + "macro": "Makro", + "regulatory": "Peraturan", + "technical": "Teknis", + "social": "Sosial", + "other": "Lainnya" + } } } diff --git a/locales/languages/ja.json b/locales/languages/ja.json index 42b0ac18e00..79939c70d26 100644 --- a/locales/languages/ja.json +++ b/locales/languages/ja.json @@ -120,6 +120,10 @@ "account_no_funds": { "message": "利用可能な資金がありません。別のアカウントをお試しください。" }, + "headless_buy_error": { + "title": "法定通貨の購入に失敗しました", + "message": "法定通貨の購入で問題が発生しました。もう一度お試しください。" + }, "mmpay_hardware_account": { "title": "未対応のウォレットです", "message": "ハードウェアウォレットには対応していません。\n続行するにはウォレットを切り替えてください。" @@ -133,8 +137,8 @@ "message": "この受取人のアドレスはトークンの直接送金に対応していない可能性があり、資金を失うおそれがあります。これが送金を受け取れるコントラクトであることを確信している場合のみ、続行してください。" }, "gas_sponsorship_reserve_balance": { - "message": "この取引でガススポンサーシップはご利用いただけません。アカウントに%{minBalance} %{nativeTokenSymbol}以上の残高が必要です。", - "title": "ガススポンサーシップは利用できません" + "message": "このネットワークでは、アカウントに%{minBalance} %{nativeTokenSymbol}の準備残高が必要です。", + "title": "準備残高が必要です" }, "token_trust_signal": { "malicious": { @@ -708,6 +712,9 @@ "contractAddressError": "トークンのコントラクトアドレスにトークンを送金しようとしています。これにより、当該トークンが失われる可能性があります。", "smart_contract_address": "スマートコントラクトアドレス", "smart_contract_address_warning": "この受取人のアドレスはトークンの直接送金に対応していない可能性があり、資金を失うおそれがあります。これが送金を受け取れるコントラクトであることを確信している場合のみ、続行してください。", + "unavailable_network_connection": "Unavailable network connection", + "unavailable_network_connection_description": "The connection with {{network}} is unreliable. Update network connectivity details before continuing or try again later.", + "update": "更新", "i_understand": "理解しています", "cancel": "キャンセル", "new_address_title": "新しいアドレス", @@ -1068,7 +1075,7 @@ "sort": { "value": "価値", "pnl_percent": "損益額 %", - "recent": "Recent" + "recent": "最近" } }, "trader_position": { @@ -1120,6 +1127,11 @@ "title": "{{symbol}}のパーペチュアルを取引", "subtitle": "損益を最大{{leverage}}増加" }, + "service_interruption": { + "title": "We're experiencing an outage", + "description": "Some services may be unavailable while the team works on a fix.", + "contact_support": "サポートへのお問い合わせ" + }, "today": "今日", "yesterday": "昨日", "unrealized_pnl": "含み損益", @@ -1284,7 +1296,9 @@ "toast_completed_subtitle": "{{amount}} USDCがウォレットに移動されました", "toast_completed_any_token_subtitle": "{{amount}} {{token}}がウォレットに移動されました", "toast_error_title": "問題が発生しました", - "toast_error_description": "出金に失敗しました" + "toast_error_description": "出金に失敗しました", + "toast_start_error_description": "Your withdrawal wasn’t started.", + "try_again": "もう一度お試しください" }, "quote": { "network_fee": "ネットワーク手数料", @@ -2227,35 +2241,35 @@ "predict": { "title": "MetaMask 予測", "world_cup": { - "title": "World Cup", - "banner_title": "World Cup 2026", - "banner_description": "Trade on World Cup markets", + "title": "ワールドカップ", + "banner_title": "ワールドカップ2026", + "banner_description": "Trade every match, every moment.", "tabs": { - "all": "All", - "props": "Props", - "live": "Live" + "all": "すべて", + "props": "プロップベット", + "live": "ライブ" }, "stages": { - "group_stage": "Group Stage", - "round_of_32": "Round of 32", - "round_of_16": "Round of 16", - "quarterfinals": "Quarterfinals", - "semifinals": "Semifinals", - "third_place": "Third Place", - "final": "Final", - "group_a": "Group A", - "group_b": "Group B", - "group_c": "Group C", - "group_d": "Group D", - "group_e": "Group E", - "group_f": "Group F", - "group_g": "Group G", - "group_h": "Group H", - "group_i": "Group I", - "group_j": "Group J", - "group_k": "Group K", - "group_l": "Group L", - "third_place_match": "Third Place Match" + "group_stage": "グループステージ", + "round_of_32": "ラウンド32", + "round_of_16": "ラウンド16", + "quarterfinals": "準々決勝", + "semifinals": "準決勝", + "third_place": "3位", + "final": "決勝", + "group_a": "グループA", + "group_b": "グループB", + "group_c": "グループC", + "group_d": "グループD", + "group_e": "グループE", + "group_f": "グループF", + "group_g": "グループG", + "group_h": "グループH", + "group_i": "グループI", + "group_j": "グループJ", + "group_k": "グループK", + "group_l": "グループL", + "third_place_match": "3位決定戦" } }, "prediction_markets": "予測市場", @@ -2537,8 +2551,8 @@ "withdraw_completed": "出金完了", "withdraw_completed_subtitle": "{{amount}} USDCがウォレットに移動されました", "withdraw_any_token_completed_subtitle": "{{amount}} {{token}}がウォレットに移動されました", - "unavailable_title": "Withdrawals temporarily unavailable", - "unavailable_description": "For urgent assistance, please contact Customer Service.", + "unavailable_title": "一時的に出金ができません", + "unavailable_description": "緊急でサポートが必要な場合は、カスタマーサービスまでお問い合わせください。", "unavailable_got_it": "了解", "error_title": "問題が発生しました", "error_description": "出金に失敗しました", @@ -2941,6 +2955,17 @@ "pna25_confirm_button": "承認して閉じる", "pna25_open_settings_button": "設定を開く" }, + "onboarding_interest_questionnaire": { + "title": "MetaMaskで何がしたいですか?", + "description": "該当するものをすべて選択してください。", + "option_buy_and_sell_crypto": "仮想通貨の売買", + "option_consolidate_wallets": "複数あるウォレットを1つにまとめたい", + "option_advanced_trades": "高度な取引がしたい", + "option_predict_sports_events": "スポーツや出来事を予測したい", + "option_crypto_as_money": "仮想通貨をお金として使いたい", + "option_connect_apps_sites": "アプリやサイトに接続したい", + "continue": "続行" + }, "template_confirmation": { "ok": "OK", "cancel": "キャンセル" @@ -3261,8 +3286,27 @@ "notifications_desc": "通知の管理", "allow_notifications": "通知を許可する", "enable_push_notifications": "プッシュ通知を有効にする", - "allow_notifications_desc": "通知を使えば、ウォレットで何が起きているか常に把握できます。通知を使用するために、プロファイルを使用してデバイス間で一部の設定が同期されます。", + "allow_notifications_desc": "Choose what you're notified about and how.", "notifications_opts": { + "preferences_title": "Preferences", + "push_recommended": "Push", + "in_app": "In-app", + "status_push": "Push", + "status_in_app": "In app", + "status_off": "オフ", + "select_all": "すべて選択", + "deselect_all": "すべて選択解除", + "select_accounts_title": "アカウント", + "select_accounts_desc": "Choose which accounts you'd like to get notifications for.", + "wallet_activity_title": "Wallet Activity", + "wallet_activity_desc": "Buy, sells, transfers, swaps and rewards", + "perps_title": "Trading Activity", + "perps_desc": "Perps position changes, liquidations, funding rates, and margin updates", + "social_ai_title": "Trading Signals", + "social_ai_desc": "Updates from traders and assets you follow, plus currated market news", + "marketing_title": "Updates and Rewards", + "marketing_desc": "Product updates, feature announcements, and new releases", + "marketing_disclaimer": "By turning this on, you agree to receive product news and marketing updates from MetaMask.", "customize_session_title": "通知のカスタマイズ", "customize_session_desc": "受け取る通知の種類をオンにします", "account_session_title": "アカウントのアクティビティ", @@ -3276,8 +3320,7 @@ "snaps_title": "Snap", "snaps_desc": "新機能や最新情報", "products_announcements_title": "製品に関するお知らせ", - "products_announcements_desc": "新しい製品や機能", - "perps_title": "パーペチュアル取引" + "products_announcements_desc": "新しい製品や機能" }, "contacts_title": "連絡先", "contacts_desc": "アカウントを追加、編集、削除、管理します.", @@ -3640,7 +3683,15 @@ "card": { "title": "カード", "reset_onboarding_description": "オンボーディングフローをやり直すには、カードのオンボーディングステータスをリセットしてください。", - "reset_onboarding_button": "オンボーディングステータスのリセット" + "reset_onboarding_button": "オンボーディングステータスのリセット", + "unlink_money_account_description": "カードがマネーカウントから支出できるUSDCの利用限度額を取り消します。これにより、approve(0)のトランザクションが送信され、カードのバックエンド側でマネーアカウントが委任解除済み (not-delegated) に変更されます。", + "unlink_money_account_button": "マネーアカウントとカードのリンクを解除", + "unlink_money_account_disabled_hint": "削除対象となる有効なリンクがありません。" + }, + "identity": { + "title": "Identity", + "description": "Clears the persisted authentication session. Use this after toggling MM_DEV_API_ENV — otherwise a prod-minted JWT keeps being handed to dev-API consumers until it expires. Current MM_DEV_API_ENV: {{env}}.", + "clear_auth_session_button": "Clear persisted auth session" }, "haptics": { "title": "ハプティクス", @@ -3842,8 +3893,8 @@ "predict_button": "予測", "add_collectible_button": "追加", "info": "情報", - "batch_sell": "Batch Sell", - "batch_sell_new_label": "New", + "batch_sell": "一括売却", + "batch_sell_new_label": "新登場", "swap": "スワップ", "convert": "変換", "bridge": "ブリッジ", @@ -3883,7 +3934,7 @@ "troubleshoot": "トラブルシューティング", "deposit_description": "手数料の少ない銀行またはカード送金", "buy_description": "特定のトークンの購入に適しています", - "batch_sell_description": "Sell up to 5 tokens for a stablecoin", + "batch_sell_description": "最大5つのトークンを売却してステーブルコインに交換できます", "sell_description": "仮想通貨を売って現金化します", "swap_description": "トークン同士を交換します", "bridge_description": "ネットワーク間でトークンを転送します", @@ -5205,6 +5256,34 @@ "manage_preferences_2": "「設定」>「通知」でいつでもオフにできます。", "cancel": "キャンセル", "cta": "オンにする" + }, + "push_onboarding": { + "new_user": { + "title": "価格変動を見逃さない", + "body": "目標価格への到達、取引の確定、ポートフォリオの動きをリアルタイムのアラートでお知らせします。また、製品の最新情報や特典に関する情報もお届けします。お届けする最新情報は、MetaMaskのご利用状況によって決まります。", + "button_yes": "はい", + "button_not_now": "後で", + "preview_card_1": { + "eyebrow": "MetaMask", + "time": "現在", + "title": "ETHは今日4.2%値上がりしています", + "message": "現在$2,668.51 — 価格アラートの金額を超えています" + }, + "preview_card_2": { + "eyebrow": "MetaMask", + "time": "1時間前", + "title": "0.25 ETHを受け取りました", + "message": "送金元: 0x9a21…4f8c · $640.29" + } + }, + "existing_user": { + "title": "個別アラートのご紹介", + "body": "取引スタイルに合った通知を受け取りましょう。いつでも更新可能です。", + "card_title": "得られる情報", + "card_description": "取引状況に合わせた個別のアラートと最新情報をお届けします。", + "button_confirm": "確定", + "button_not_now": "後で" + } } }, "protect_your_wallet_modal": { @@ -5315,6 +5394,7 @@ "pay_with": "支払方法:", "buying_via": "{{providerName}}で購入しようとしています。", "change_provider": "プロバイダーを変更します。", + "circuit_breaker_open": "This service is temporarily unavailable. Please try again in about 30 minutes.", "payment_error": "問題が発生しました。もう一度お試しください。", "no_payment_methods_available": "使用可能な支払方法がありません。", "error_fetching_quotes": "問題が発生しました。もう一度お試しください。", @@ -6520,6 +6600,8 @@ "convert_to_musd": "mUSDに変換", "get_a_percentage_musd_bonus": "{{percentage}}%のmUSDボーナスを獲得", "convert": "変換", + "confirm": "確定", + "convert_tooltip_description": "お持ちのステーブルコインをmUSDに換えて、年換算で最大{{percentage}}%のボーナスを獲得しましょう。ボーナスは毎日請求できます。このサービスはRelayの技術によって支えられています。", "fetching_quote": "クォートを取得中...", "you_convert": "変換するトークン", "network_fee": "ネットワーク手数料", @@ -6597,7 +6679,7 @@ "step_progress": "ステップ{{current}}/{{total}}", "title": "お金を追加", "description": "アカウントに入金して、毎年複利で利息を得ましょう。", - "add": "追加", + "add": "資金を追加", "step2_title": "MetaMaskカードを取得", "step2_description": "Mastercardの取扱店であればどこでも、収益を得ると同時にマネー残高を使用できます。", "step2_cta": "カードを取得", @@ -6605,6 +6687,19 @@ "link_card_description": "Mastercardの取扱店であればどこでも、収益を得ると同時に残高を使えます。", "link_card_cta": "カードをリンク" }, + "rive_onboarding": { + "step1_title": "マネーアカウントが新登場", + "step1_body": "残高に対して最大{{percentage}}%のAPYが得られ、ウォレット内で自由に利用できます。", + "step1_footer_text": "APYは変動制で、いつでも変わる可能性があります。", + "step2_title": "自動で報酬がもらえる", + "step2_body": "取引所手数料なしでステーブルコインを移動できます。報酬の獲得はすぐに開始されます。", + "step2_footer_text": "Provided by Veda and Steakhouse Financial.", + "step3_title": "どこでも使える", + "step3_body": "マネーアカウントをMetaMaskカードとリンクさせることで、購入額の最大{{percentage}}%が還元されます。", + "step4_title": "取引も報酬の獲得も1か所で", + "step4_body": "MetaMaskでの取引にマネー残高を利用しながら、引き続き利回りが得られます。", + "continue": "続行" + }, "action": { "add": "追加", "transfer": "送金", @@ -6618,8 +6713,8 @@ }, "how_it_works": { "title": "報酬獲得の仕組み", - "description_prefix": "Deposit mUSD into your Money account and earn up to", - "description_suffix": ". Your balance is dollar-backed and ready to spend, trade, or send anytime." + "description_prefix": "マネーアカウントにmUSDを入金すると、得られる利回りは最大", + "description_suffix": "。残高はドルの裏付けがあり、いつでもショッピング、取引、送金に利用できます。" }, "musd_row": { "add": "追加" @@ -6627,16 +6722,16 @@ "balance_card": { "label": "マネー残高", "add": "追加", - "info_sheet_title": "Money balance", - "info_sheet_body": "Your dollar-backed mUSD balance that's always available to spend, send, or trade anytime. We don't calculate this into your total account balance.\n\nWithdrawals process immediately, subject to standard network confirmation times on the relevant blockchain. If liquidity is tight, there may be temporary delays." + "info_sheet_title": "マネー残高", + "info_sheet_body": "ドルの裏付けのあるmUSD残高で、いつでもショッピング、送金、取引に利用できます。この残高は、アカウントの合計残高には算入されません。\n\n出金は即時処理され、対象となるブロックチェーンネットワークによる標準的な承認時間がかかります。流動性が低下している場合は、一時的に遅延が発生することがあります。" }, "potential_earnings": { "title": "仮想通貨を収益化", "description": "仮想通貨をmUSDに換えることで、時間の経過とともにお金がどのように増えるかをご覧ください。", - "description_with_amounts_prefix": "Convert your {{total}} in assets and you could earn up to", - "description_with_amounts_suffix": "in one year.", + "description_with_amounts_prefix": "お持ちの資産{{total}}を変換すると、1年間で最大", + "description_with_amounts_suffix": "の報酬を得られる可能性があります。", "convert": "変換", - "convert_cta": "Convert your crypto", + "convert_cta": "仮想通貨を変換", "no_fee": "MetaMaskの手数料なし", "view_all": "すべて表示", "view_potential_earnings": "獲得可能な収益を表示" @@ -6649,41 +6744,44 @@ "cashback": "{{percentage}}%のmUSDを還元", "get_now": "今すぐ入手", "link_title": "MetaMaskカードをリンク", - "link_subtitle": "Spend your Money balance and earn on purchases. Plus, up to {{apy}}% APY on your balance.", - "link_bullet_cashback": "Get {{percentage}}% mUSD back", - "link_bullet_apy": "Earn up to {{apy}}% APY", + "link_subtitle": "マネー残高で支払えば、購入額に対して報酬を獲得できます。さらに、残高に対して最大{{apy}}%のAPYが得られます。", + "link_subtitle_no_apy": "Spend your Money balance and earn on purchases.", + "link_bullet_cashback": "{{percentage}}%のmUSDを還元", + "link_bullet_apy": "最大{{apy}}%APYを獲得", "link_card": "カードをリンク", - "link_pending_title": "Linking card", - "link_pending_description": "Approving spending limit…", - "link_success_title": "Card linked successfully", - "link_success_description": "You can now spend while you earn", - "link_error": "Couldn't link card", - "manage_card": "Manage", - "avail_balance": "Avail. balance" + "link_pending_title": "Linking your card", + "link_success_title": "Your card is ready to use", + "link_error": "Something went wrong linking your card", + "link_card_sheet_title": "使えば貯まる", + "link_card_sheet_description": "Link your card so you can spend your Money balance and earn mUSD back on purchases—all while earning up to {{apy}}% APY.", + "link_card_sheet_description_no_apy": "Link your card so you can spend your Money balance and earn mUSD back on purchases.", + "link_card_sheet_cta": "カードをリンク", + "manage_card": "管理", + "avail_balance": "利用可能残高" }, "what_you_get": { "title": "得られるもの", - "benefit_auto_earn": "Auto-earn up to", + "benefit_auto_earn": "自動で得られる報酬は最大", "benefit_dollar_backed": "ドルと1対1で裏付けられたステーブルコイン、mUSDで、資金を安全に守れます", "benefit_liquidity": "ロックアップなしで完全な流動性が確保され、いつでも取引や引き出しが可能です", "benefit_spend_prefix": "1億5000万店舗を超える加盟店でMetaMaskカードを利用して、", "benefit_spend_cashback": "1~3%のmUSDを還元", - "benefit_transfer": "Transfer to any of your wallets across MetaMask", - "benefit_global": "Send and receive funds globally", + "benefit_transfer": "MetaMaskに登録した任意のウォレットに送金可能", + "benefit_global": "世界中と資金をやり取りできます", "learn_more": "詳細" }, "footer": { - "add_money": "Add funds" + "add_money": "資金を追加" }, "add_money_sheet": { - "title": "Add funds", + "title": "資金を追加", "convert_crypto": "仮想通貨を変換", - "convert_crypto_description": "From any account", + "convert_crypto_description": "任意のアカウントから", "deposit_funds": "資金を入金", - "deposit_funds_description": "From debit card or bank", - "move_musd": "Transfer your {{amount}} mUSD", - "move_musd_no_amount": "Transfer your mUSD", - "move_musd_description": "From your balance", + "deposit_funds_description": "デビットカードまたは銀行から", + "move_musd": "{{amount}} mUSDを送金", + "move_musd_no_amount": "mUSDを送金", + "move_musd_description": "残高から", "receive_external": "外部ウォレットから受け取る", "coming_soon": "近日追加予定" }, @@ -6694,7 +6792,7 @@ "contact_support": "サポートへのお問い合わせ" }, "transfer_sheet": { - "title": "Transfer funds", + "title": "送金", "between_accounts": "アカウント間", "perps_account": "パーペチュアルアカウント", "predictions_account": "予測市場アカウント", @@ -6712,8 +6810,8 @@ "body": "現在の残高および本日のAPYから算出された、一定期間内に獲得可能な金額の見積もり。見積もりはリターンを保証するものではなく、変更される可能性があります。" }, "earn_crypto_info_sheet": { - "title": "Earn on your crypto", - "body": "Illustration assumes {{percentage}}% Annual Percentage Yield (APY) remains unchanged for one year. APY is variable and may change due to various factors. No guarantee of return." + "title": "仮想通貨を収益化", + "body": "図では、{{percentage}}%の年換算利率 (APY) が1年間変わらないと仮定しています。APYは変動制で、さまざまな要因によって変わる可能性があります。利益が保証されるものではありません。" }, "activity": { "title": "アクティビティ", @@ -6725,7 +6823,7 @@ }, "condensed_cards": { "how_it_works_title": "報酬獲得の仕組み", - "how_it_works_subtitle": "資金がどのように働いてくれるのか、ご覧ください", + "how_it_works_subtitle": "See how your money can grow", "musd_title": "MetaMask USD", "musd_subtitle": "mUSDの詳細", "what_you_get_title": "得られるもの", @@ -6738,7 +6836,8 @@ "sent": "送信済み", "transferred": "送金済み", "card_transaction": "カードトランザクション", - "converted": "換金済み" + "converted": "換金済み", + "failed": "失敗" }, "convert_stablecoins": { "title": "ステーブルコインの換金", @@ -6757,11 +6856,11 @@ "how_it_works_page": { "header_title": "マネー", "section_title": "報酬獲得の仕組み", - "description_1": "Deposit mUSD into your Money account and earn up to {{percentage}}% APY (variable) automatically. Funds go into a DeFi vault that generates returns across audited lending markets—no staking, no claiming, no lock-ups.", + "description_1": "マネーアカウントにmUSDを入金すると、最大{{percentage}}%のAPY (変動式) が自動的に得られます。資金はDeFiヴォールトに入れられ、監査対象のレンディング市場で利益を生み出します。ステーキングや請求は不要で、ロックアップもありません。", "description_2": "マネー残高は使用可能な残高です。MetaMaskカードをリンクすれば、世界中の1億5千万以上のマーチャントで使用できます。資金は使うまで収益を生み続けます。", - "faq_title": "Frequently asked questions", + "faq_title": "よくある質問", "faq_placeholder_answer": "近日追加予定.", - "faq_q1": "How does the {{percentage}}% APY work?", + "faq_q1": "{{percentage}}%のAPYが得られる仕組みとは?", "faq_q2": "mUSDとは?", "faq_q3": "利益はどこから生まれるのですか?", "faq_q4": "資金はロックされますか?いつでも引き出せますか?", @@ -7030,11 +7129,12 @@ "confirm": "確定", "pay_with_bottom_sheet": { "title": "支払方法:", - "last_used": "Last used", - "crypto": "Crypto", - "available_balance": "{{balance}} available", - "other_assets": "Other assets", - "other_assets_description": "Select from your tokens" + "last_used": "前回の利用", + "bank_and_card": "銀行とカード", + "crypto": "仮想通貨", + "available_balance": "{{balance}}が利用可能", + "other_assets": "その他の資産", + "other_assets_description": "お持ちのトークンからお選びください" }, "staking_footer": { "part1": "続行することで、", @@ -7120,7 +7220,7 @@ "transaction_fee": "mUSD換算手数料にはネットワークコストが含まれるほか、プロバイダー手数料も含まれる場合があります。なお、mUSDへの換算時にMetaMaskの手数料は発生しません。" }, "money_account_withdraw": { - "transaction_fee": "MetaMask will swap your mUSD for your desired token. Swap providers may charge a fee, but MetaMask won't." + "transaction_fee": "MetaMaskはお持ちのmUSDをご希望のトークンに交換します。スワッププロバイダーは手数料を請求することがありますが、MetaMaskなら無料です。" }, "title": { "transaction_fee": "手数料" @@ -7225,7 +7325,7 @@ "deposit_edit_amount_done": "資金を追加", "deposit_edit_amount_predict_withdraw": "出金", "deposit_edit_amount_musd_conversion": "mUSDに変換", - "preparing_order": "Preparing order" + "preparing_order": "注文を準備しています" }, "change_in_simulation_modal": { "title": "結果が変更になりました", @@ -7250,20 +7350,33 @@ "confirm_swap": "スワップ", "terms_and_conditions": "利用規約", "select_token": "トークンを選択", - "batch_sell_select_title": "Select up to 5 tokens", - "batch_sell_select_subtitle": "All tokens need to be on the same network.", - "batch_sell_empty_state_title": "No tokens. No problem.", - "batch_sell_empty_state_description": "No tokens. No problem. Explore and buy tokens to batch sell.", - "batch_sell_continue_with_one_token": "Continue with (1) token", - "batch_sell_continue_with_tokens": "Continue with ({{tokenCount}}) tokens", - "batch_sell_max_tokens_allowed": "Max 5 tokens allowed", - "batch_sell_single_token_dialog_title": "High rate alert", - "batch_sell_single_token_dialog_description": "Batch selling one token could lead to a higher rate. Want to do a swap instead?", - "batch_sell_swap_instead": "Yes, swap", - "batch_sell_checkbox_label": "Batch Sell token", - "sort_balance": "Balance", - "next": "Next", - "explore_tokens": "Explore tokens", + "batch_sell_select_title": "トークンを最大5つまでお選びください", + "batch_sell_select_subtitle": "すべてのトークンが同一ネットワーク上にある必要があります。", + "batch_sell_empty_state_title": "トークンがありません。でも問題ありません。", + "batch_sell_empty_state_description": "トークンがありません。でも問題ありません。一括売却するトークンを検索して購入しましょう。", + "batch_sell_continue_with_one_token": "1つのトークンで続行", + "batch_sell_continue_with_tokens": "{{tokenCount}}つのトークンで続行", + "batch_sell_max_tokens_allowed": "最大で5つのトークンを売却できます", + "batch_sell_single_token_dialog_title": "割高レートに関するアラート", + "batch_sell_single_token_dialog_description": "一括売却するトークンが1種類の場合は、レートが高くなる可能性があります。代わりにスワップを行いますか?", + "batch_sell_swap_instead": "はい、スワップを行います", + "batch_sell_review_title": "一括売却の確認", + "batch_sell_select_stablecoin": "ステーブルコインを選択", + "batch_sell_total_received": "受取額合計", + "batch_sell_minimum_received": "Minimum received", + "batch_sell_quote_details_row": "{{tokenSymbol}} • {{slippage}} slippage", + "batch_sell_review": "確認", + "batch_sell_you_sell": "You sell", + "batch_sell_token_count": "{{tokenCount}} tokens", + "batch_sell_toggle_you_sell": "Toggle token details", + "batch_sell_sell_all": "Sell all", + "batch_sell_includes_metamask_fee": "Includes {{fee}}% MetaMask fee", + "batch_sell_customize_token": "{{tokenSymbol}}をカスタマイズ", + "batch_sell_remove_token": "{{tokenSymbol}}を削除", + "batch_sell_checkbox_label": "トークンを一括売却", + "sort_balance": "残高", + "next": "次へ", + "explore_tokens": "トークンの閲覧", "no_tokens_found": "トークンが見つかりませんでした", "no_tokens_found_description": "この名前のトークンが見つかりませんでした。別の検索をお試しください。", "select_network": "ネットワークを選択", @@ -7332,6 +7445,7 @@ "price_impact_execution_description": "このスワップにより、トークンの価値の約{{priceImpact}}が失われます。金額を下げるか、より流動性の高いルートを選択してください。", "proceed": "先に進む", "cancel": "キャンセル", + "close": "閉じる", "slippage_info_title": "スリッページ", "slippage_info_description": "トランザクションが取り消される前に許容する価格の変動率(%)。", "blockaid_error_title": "このトランザクションは取り消されます", @@ -8107,7 +8221,14 @@ "retry": "再試行してください", "on_linea": "Lineaで", "account_label": "アカウント", - "token_label": "トークン" + "token_label": "トークン", + "money_account_label": "Money account", + "money_account_token_symbol": "mUSD", + "use_money_account_cta": "Use Money account", + "spend_and_earn_title": "Spend while you earn", + "spend_and_earn_description": "Spend with your Money account and earn up to {{apy}}% APY on your balance. Also get {{cashback}}% mUSD back.", + "spend_and_earn_description_no_apy": "Spend with your Money account and earn APY on your balance. Also get {{cashback}}% mUSD back.", + "spend_and_earn_cta": "Link to Money account" }, "cashback_screen": { "title": "mUSDの還元", @@ -8449,6 +8570,7 @@ "show_less": "表示を戻す", "linking_progress": "アカウントを追加中… ({{current}}/{{total}})", "accounts_linked_count": "{{linked}}/{{total}}件を登録済み", + "accounts_added": "Accounts added", "add_all_accounts": "すべてのアカウントを追加", "environment_selector": "環境", "environment_cancel": "キャンセル", @@ -8473,15 +8595,22 @@ }, "optout": { "title": "リワードの進行状況を削除", - "description": "この操作を行うと、アカウントがRewardsプログラムから削除され、進行状況が失われます。この操作は元に戻せません。", - "confirm": "削除", + "description": "This will remove your accounts from the Rewards program and your progress in any campaigns you've joined. Only do this if you are absolutely sure you want to erase your progress.", + "erase_button": "Erase progress", "modal": { "confirmation_title": "よろしいですか?", - "confirmation_description": "これにより、進行状況はすべて削除され、元には戻せません。リワードプログラムに後で再び参加した場合は、最初から始めることになります。", + "confirmation_description": "This will erase all your progress, and can't be reversed. If you rejoin the Rewards program later, you'll start back at 0.", + "type_to_confirm": "Type 'erase progress' to continue", + "confirm_phrase": "erase progress", "cancel": "キャンセル", "confirm": "選択すると、", + "error_title": "問題が発生しました", "error_message": "リワードのオプトアウトに失敗しました。もう一度お試しください。", "processing": "処理中..." + }, + "request_received": { + "title": "Request received", + "description": "In about 7 days, your progress will be fully erased. If you made this request by mistake, please contact support through the app." } }, "toast_dismiss": "閉じる", @@ -8569,7 +8698,8 @@ "title_claim": "特典を請求", "action": "請求", "empty-list": "現在特典がありません。", - "powered_by": "提供元:" + "powered_by": "提供元:", + "available_count": "{{count}}件利用可能" }, "end_of_season_rewards": { "confirm_label_default": "確定", @@ -8702,7 +8832,7 @@ "label_your_rank": "ランク", "label_portfolio": "Portfolio", "label_net_inflow": "純流入額", - "label_total_inflow": "総流入額", + "label_total_inflow": "流入額合計", "label_outflow": "流出額", "label_days_held": "保有日数", "qualified_title": "対象となります", @@ -8887,9 +9017,11 @@ "musd_claim": "mUSDの請求", "perps_deposit": "資金を追加", "perps_withdraw": "出金", + "predict_withdraw": "{{sourceChain}}から{{sourceSymbol}}を出金", "predict_deposit": "資金を追加", "swap": "トークンをスワップ", - "swap_approval": "トークンを承認" + "swap_approval": "トークンを承認", + "fiat_purchase": "{{paymentMethod}}で{{token}}を購入" }, "perps_deposit_solution": "Arbitrumの残高が{{fiat}}のUSDCになりました。もう一度入金をお試しください。" }, @@ -8965,7 +9097,7 @@ "high_to_low": "高い順", "low_to_high": "低い順", "apply": "適用", - "search_placeholder": "トークン、サイト、URLを検索", + "search_placeholder": "Search tokens, markets and URLs", "cancel": "キャンセル", "perps": "パーペチュアル", "rwa_perps_section": "パーペチュアル", @@ -8978,11 +9110,15 @@ "crypto_perps_section": "パーペチュアル", "predictions": "予測", "no_results": "結果が見つかりませんでした", + "no_results_for_feed": "No {{feedName}} results for \"{{query}}\"", + "showing_all_results_for": "We found these results for \"{{query}}\"", "popular": "人気", "sites": "サイト", "popular_sites": "人気のサイト", "search_sites": "サイトを検索", "view_all": "すべて表示", + "view_more": "さらに表示", + "view_x_more": "View {{count}} more", "enable_basic_functionality": "基本機能を有効にする", "basic_functionality_disabled_title": "閲覧を利用できません", "basic_functionality_disabled_description": "基本機能が無効になっていると、必要なメタデータを取得できません。", @@ -9002,6 +9138,14 @@ "crypto": "仮想通貨", "sports": "スポーツ", "dapps": "サイト" + }, + "search_tabs": { + "all": "すべて", + "crypto": "Cryptos", + "perps": "パーペチュアル", + "stocks": "株式", + "predictions": "予測", + "sites": "サイト" } }, "ota_update_modal": { @@ -9139,6 +9283,7 @@ "money_empty_description_network_filter": "このネットワークにはmUSDがありません。ネットワークを切り替えてお持ちのmUSDをご確認ください。", "money_empty_state": { "get_started": "開始", + "earn": "獲得", "earn_apy": "年換算利率 (APY) {{percentage}}%を獲得" }, "money_filled_state": { @@ -9150,22 +9295,7 @@ "related_assets": "関連する資産", "perpetuals": "パーペチュアル", "predictions": "予測", - "whats_happening": "現在起きていること", - "whats_happening_ai": "AI", - "whats_happening_impact": { - "bullish": "強気", - "bearish": "弱気", - "neutral": "中立" - }, "top_traders": "トップトレーダー", - "whats_happening_categories": { - "geopolitical": "地政学", - "macro": "マクロ", - "regulatory": "規制", - "technical": "技術", - "social": "社会", - "other": "その他" - }, "defi": "DeFi", "nfts": "NFT", "trending_tokens": "人気上昇中", @@ -9185,5 +9315,22 @@ }, "sites": { "popular": "人気" + }, + "whats_happening": { + "title": "現在起きていること", + "ai": "AI", + "impact": { + "bullish": "強気", + "bearish": "弱気", + "neutral": "中立" + }, + "categories": { + "geopolitical": "地政学", + "macro": "マクロ", + "regulatory": "規制", + "technical": "技術", + "social": "社会", + "other": "その他" + } } } diff --git a/locales/languages/ko.json b/locales/languages/ko.json index d5dc8fd3d04..fa59271cfce 100644 --- a/locales/languages/ko.json +++ b/locales/languages/ko.json @@ -120,6 +120,10 @@ "account_no_funds": { "message": "사용 가능한 자금이 없습니다. 다른 계정을 사용하세요." }, + "headless_buy_error": { + "title": "법정화폐 구매 실패", + "message": "법정화폐 구매 시 오류가 발생했습니다. 다시 시도하세요." + }, "mmpay_hardware_account": { "title": "지원되지 않는 지갑", "message": "하드웨어 지갑이 지원되지 않습니다. 다른 지갑으로 전환하여 계속하세요." @@ -133,8 +137,8 @@ "message": "수신자 주소가 직접 토큰 전송을 지원하지 않을 수 있습니다. 이 경우 자금이 손실될 수 있습니다. 이 계약이 전송되는 토큰을 받을 수 있다는 확신이 있을 때만 계속하세요." }, "gas_sponsorship_reserve_balance": { - "message": "이 트랜잭션에는 가스 후원이 제공되지 않습니다. 계정에 최소 %{minBalance}의 %{nativeTokenSymbol} 토큰을 보유해야 합니다.", - "title": "가스 후원 이용 불가" + "message": "이 네트워크에서는 계정에 최소 %{minBalance} %{nativeTokenSymbol}의 잔액을 유지해야 합니다.", + "title": "최소 잔액이 필요합니다" }, "token_trust_signal": { "malicious": { @@ -708,6 +712,9 @@ "contractAddressError": "토큰의 계약 주소로 토큰을 보내고 있습니다. 이로 인해 해당 토큰이 손실될 수 있습니다.", "smart_contract_address": "스마트 계약 주소", "smart_contract_address_warning": "수신자 주소가 직접 토큰 전송을 지원하지 않을 수 있습니다. 이 경우 자금이 손실될 수 있습니다. 이 계약이 전송되는 토큰을 받을 수 있다는 확신이 있을 때만 계속하세요.", + "unavailable_network_connection": "Unavailable network connection", + "unavailable_network_connection_description": "The connection with {{network}} is unreliable. Update network connectivity details before continuing or try again later.", + "update": "업데이트", "i_understand": "견적은 다음 기간 전에 만료됨을", "cancel": "취소", "new_address_title": "새 주소", @@ -1067,8 +1074,8 @@ "twitter_link": "X(Twitter)에서 보기", "sort": { "value": "가격", - "pnl_percent": "P&L %", - "recent": "Recent" + "pnl_percent": "손익 %", + "recent": "최근" } }, "trader_position": { @@ -1120,6 +1127,11 @@ "title": "{{symbol}} 무기한 선물 거래", "subtitle": "최대 {{leverage}}까지 손익 확대" }, + "service_interruption": { + "title": "We're experiencing an outage", + "description": "Some services may be unavailable while the team works on a fix.", + "contact_support": "지원팀에 문의" + }, "today": "오늘", "yesterday": "어제", "unrealized_pnl": "미실현 손익", @@ -1284,7 +1296,9 @@ "toast_completed_subtitle": "{{amount}} USDC가 지갑으로 전송되었습니다", "toast_completed_any_token_subtitle": "{{amount}} {{token}}이(가) 지갑으로 이동했습니다", "toast_error_title": "문제가 발생했습니다", - "toast_error_description": "출금 실패" + "toast_error_description": "출금 실패", + "toast_start_error_description": "Your withdrawal wasn’t started.", + "try_again": "다시 시도" }, "quote": { "network_fee": "네트워크 수수료", @@ -2227,35 +2241,35 @@ "predict": { "title": "MetaMask 예측", "world_cup": { - "title": "World Cup", - "banner_title": "World Cup 2026", - "banner_description": "Trade on World Cup markets", + "title": "월드컵", + "banner_title": "월드컵 2026", + "banner_description": "Trade every match, every moment.", "tabs": { - "all": "All", - "props": "Props", - "live": "Live" + "all": "모두", + "props": "프롭", + "live": "진행 중" }, "stages": { - "group_stage": "Group Stage", - "round_of_32": "Round of 32", - "round_of_16": "Round of 16", - "quarterfinals": "Quarterfinals", - "semifinals": "Semifinals", - "third_place": "Third Place", - "final": "Final", - "group_a": "Group A", - "group_b": "Group B", - "group_c": "Group C", - "group_d": "Group D", - "group_e": "Group E", - "group_f": "Group F", - "group_g": "Group G", - "group_h": "Group H", - "group_i": "Group I", - "group_j": "Group J", - "group_k": "Group K", - "group_l": "Group L", - "third_place_match": "Third Place Match" + "group_stage": "조별 예선", + "round_of_32": "32강", + "round_of_16": "16강", + "quarterfinals": "8강", + "semifinals": "준결승", + "third_place": "3위", + "final": "종료", + "group_a": "A조", + "group_b": "B조", + "group_c": "C조", + "group_d": "D조", + "group_e": "E조", + "group_f": "F조", + "group_g": "G조", + "group_h": "H조", + "group_i": "I조", + "group_j": "J조", + "group_k": "K조", + "group_l": "L조", + "third_place_match": "3위 결정전" } }, "prediction_markets": "예측 시장", @@ -2537,8 +2551,8 @@ "withdraw_completed": "출금 완료", "withdraw_completed_subtitle": "{{amount}} USDC가 지갑으로 전송되었습니다", "withdraw_any_token_completed_subtitle": "{{amount}} {{token}}이(가) 지갑으로 이동했습니다", - "unavailable_title": "Withdrawals temporarily unavailable", - "unavailable_description": "For urgent assistance, please contact Customer Service.", + "unavailable_title": "출금 일시 불가", + "unavailable_description": "긴급한 지원이 필요한 경우 고객센터로 문의해 주세요.", "unavailable_got_it": "컨펌", "error_title": "문제가 발생했습니다", "error_description": "출금에 실패했습니다", @@ -2941,6 +2955,17 @@ "pna25_confirm_button": "동의하고 종료하기", "pna25_open_settings_button": "설정 열기" }, + "onboarding_interest_questionnaire": { + "title": "MetaMask에서 무엇을 하고 싶으세요?", + "description": "해당 사항을 모두 선택하세요.", + "option_buy_and_sell_crypto": "암호자산 매매", + "option_consolidate_wallets": "지갑 통합", + "option_advanced_trades": "고급 거래 기능 이용", + "option_predict_sports_events": "스포츠 및 이벤트 예측", + "option_crypto_as_money": "암호자산을 화폐로 사용", + "option_connect_apps_sites": "앱 또는 사이트에 연결", + "continue": "계속" + }, "template_confirmation": { "ok": "확인", "cancel": "취소" @@ -3261,8 +3286,27 @@ "notifications_desc": "알림 관리", "allow_notifications": "알림 허용", "enable_push_notifications": "푸시 알림 활성화", - "allow_notifications_desc": "알림을 통해 지갑에서 무슨 일이 일어나고 있는지 계속 확인하세요. 알림 기능을 사용하려면 프로필을 사용해 기기 간에 일부 설정을 동기화해야 합니다.", + "allow_notifications_desc": "Choose what you're notified about and how.", "notifications_opts": { + "preferences_title": "Preferences", + "push_recommended": "Push", + "in_app": "In-app", + "status_push": "Push", + "status_in_app": "In app", + "status_off": "비활성화", + "select_all": "전체 선택", + "deselect_all": "전체 선택 해제", + "select_accounts_title": "계정", + "select_accounts_desc": "Choose which accounts you'd like to get notifications for.", + "wallet_activity_title": "Wallet Activity", + "wallet_activity_desc": "Buy, sells, transfers, swaps and rewards", + "perps_title": "Trading Activity", + "perps_desc": "Perps position changes, liquidations, funding rates, and margin updates", + "social_ai_title": "Trading Signals", + "social_ai_desc": "Updates from traders and assets you follow, plus currated market news", + "marketing_title": "Updates and Rewards", + "marketing_desc": "Product updates, feature announcements, and new releases", + "marketing_disclaimer": "By turning this on, you agree to receive product news and marketing updates from MetaMask.", "customize_session_title": "알림 맞춤 설정", "customize_session_desc": "수신하려는 알림 유형 켜기:", "account_session_title": "계정 활동", @@ -3276,8 +3320,7 @@ "snaps_title": "Snap", "snaps_desc": "새 기능 및 업데이트", "products_announcements_title": "제품 공지", - "products_announcements_desc": "새 제품 및 기능", - "perps_title": "무기한 선물 거래" + "products_announcements_desc": "새 제품 및 기능" }, "contacts_title": "연락처", "contacts_desc": "계정 추가, 편집, 제거 및 관리.", @@ -3640,7 +3683,15 @@ "card": { "title": "카드", "reset_onboarding_description": "온보딩 흐름을 처음부터 다시 시작하려면 카드 온보딩 상태를 초기화하세요.", - "reset_onboarding_button": "온보딩 상태 초기화" + "reset_onboarding_button": "온보딩 상태 초기화", + "unlink_money_account_description": "카드에 부여된 머니 계정의 USDC 지출 한도 승인을 취소합니다. 이 작업을 통해 approve(0) 트랜잭션을 제출하고 카드 백엔드에서 머니 계정을 위임되지 않은 상태로 표시합니다.", + "unlink_money_account_button": "머니 계정과 카드의 연결 해제", + "unlink_money_account_disabled_hint": "제거할 활성 연결이 없습니다." + }, + "identity": { + "title": "Identity", + "description": "Clears the persisted authentication session. Use this after toggling MM_DEV_API_ENV — otherwise a prod-minted JWT keeps being handed to dev-API consumers until it expires. Current MM_DEV_API_ENV: {{env}}.", + "clear_auth_session_button": "Clear persisted auth session" }, "haptics": { "title": "햅틱", @@ -3842,8 +3893,8 @@ "predict_button": "예측", "add_collectible_button": "추가", "info": "정보", - "batch_sell": "Batch Sell", - "batch_sell_new_label": "New", + "batch_sell": "일괄 매도", + "batch_sell_new_label": "신규", "swap": "스왑", "convert": "전환", "bridge": "브릿지", @@ -3883,7 +3934,7 @@ "troubleshoot": "문제 해결", "deposit_description": "수수료가 낮은 은행 또는 카드 이체", "buy_description": "특정 토큰 매수에 적합", - "batch_sell_description": "Sell up to 5 tokens for a stablecoin", + "batch_sell_description": "최대 5개 토큰을 매도하여 스테이블코인 수령", "sell_description": "암호화폐를 현금에 매도", "swap_description": "토큰 간 교환", "bridge_description": "네트워크간 토큰 전송", @@ -5205,6 +5256,34 @@ "manage_preferences_2": "설정 > 알림", "cancel": "취소", "cta": "켜기" + }, + "push_onboarding": { + "new_user": { + "title": "매매 기회를 놓치지 마세요", + "body": "목표 가격 도달, 거래 체결, 포트폴리오 변동 시 실시간 알림을 받아보세요. 제품 업데이트와 보상 정보도 함께 확인할 수 있습니다. MetaMask 이용 내역을 기반으로 맞춤형 정보를 보내드립니다.", + "button_yes": "예", + "button_not_now": "나중에", + "preview_card_1": { + "eyebrow": "METAMASK", + "time": "지금", + "title": "오늘 ETH가 4.2% 상승했습니다", + "message": "현재 $2,668.51입니다. 설정한 가격 알림 기준을 넘어섰습니다" + }, + "preview_card_2": { + "eyebrow": "METAMASK", + "time": "1시간 전", + "title": "0.25 ETH 받음", + "message": "보낸 주소: 0x9a21…4f8c · $640.29" + } + }, + "existing_user": { + "title": "맞춤형 알림 소개", + "body": "거래 방식에 맞는 알림을 받으세요. 언제든지 설정을 변경할 수 있습니다.", + "card_title": "혜택", + "card_description": "맞춤형 알림과 거래 내역에 기반한 정보를 받을 수 있습니다.", + "button_confirm": "컨펌", + "button_not_now": "나중에" + } } }, "protect_your_wallet_modal": { @@ -5315,6 +5394,7 @@ "pay_with": "결제 수단:", "buying_via": "{{providerName}}을(를) 통해 구매", "change_provider": "공급자를 변경하세요.", + "circuit_breaker_open": "This service is temporarily unavailable. Please try again in about 30 minutes.", "payment_error": "오류가 발생했습니다. 다시 시도해 주세요.", "no_payment_methods_available": "사용 가능한 결제 방법이 없습니다.", "error_fetching_quotes": "오류가 발생했습니다. 다시 시도해 주세요.", @@ -6520,6 +6600,8 @@ "convert_to_musd": "mUSD로 전환", "get_a_percentage_musd_bonus": "{{percentage}}%의 mUSD 보너스 혜택", "convert": "전환", + "confirm": "컨펌", + "convert_tooltip_description": "스테이블코인을 mUSD로 전환하고 연간 최대 {{percentage}}% 보너스를 받으세요. 보너스는 매일 수령할 수 있습니다. Relay에서 제공합니다.", "fetching_quote": "견적 가져오기...", "you_convert": "전환 전:", "network_fee": "네트워크 수수료", @@ -6597,7 +6679,7 @@ "step_progress": "{{current}} 단계/{{total}} 단계", "title": "자금 추가", "description": "계정에 입금하고 연 수익(APY)을 버세요.", - "add": "추가", + "add": "자금 추가", "step2_title": "MetaMask 카드 받기", "step2_description": "Mastercard가 허용되는 모든 곳에서 수익이 쌓이는 동안 Money 잔액을 사용하세요.", "step2_cta": "카드 받기", @@ -6605,6 +6687,19 @@ "link_card_description": "Mastercard가 허용되는 모든 곳에서 수익이 쌓이는 동안 잔액을 사용하세요.", "link_card_cta": "카드 연결" }, + "rive_onboarding": { + "step1_title": "머니 계정을 소개합니다", + "step1_body": "지갑 전체에서 사용할 수 있는 잔액에 대해 최대 {{percentage}}% APY의 수익을 얻을 수 있습니다.", + "step1_footer_text": "APY는 변동형이므로 언제든지 변경될 수 있습니다.", + "step2_title": "자동으로 수익 얻기", + "step2_body": "환전 수수료 없이 스테이블코인을 이동하세요. 자금에 대한 수익 창출이 바로 시작됩니다.", + "step2_footer_text": "Provided by Veda and Steakhouse Financial.", + "step3_title": "어디서든 결제 가능", + "step3_body": "머니 계정을 MetaMask 카드에 연결하면 구매 시 최대 {{percentage}}%의 캐시백을 받을 수 있습니다.", + "step4_title": "한곳에서 거래하고 수익을 적립하세요", + "step4_body": "MetaMask에서 머니 계정 잔액으로 거래하면서 수익을 계속 적립할 수 있습니다.", + "continue": "계속" + }, "action": { "add": "추가", "transfer": "송금", @@ -6618,8 +6713,8 @@ }, "how_it_works": { "title": "작동 방식", - "description_prefix": "Deposit mUSD into your Money account and earn up to", - "description_suffix": ". Your balance is dollar-backed and ready to spend, trade, or send anytime." + "description_prefix": "머니 계정에 mUSD를 입금하면 적립할 수 있는 최대 수익은 다음과 같습니다", + "description_suffix": ". 잔액은 달러 연동 방식으로 유지되며 언제든지 결제, 거래, 송금에 사용될 수 있습니다." }, "musd_row": { "add": "추가" @@ -6627,16 +6722,16 @@ "balance_card": { "label": "머니 잔액", "add": "추가", - "info_sheet_title": "Money balance", - "info_sheet_body": "Your dollar-backed mUSD balance that's always available to spend, send, or trade anytime. We don't calculate this into your total account balance.\n\nWithdrawals process immediately, subject to standard network confirmation times on the relevant blockchain. If liquidity is tight, there may be temporary delays." + "info_sheet_title": "머니 잔액", + "info_sheet_body": "언제든지 결제, 송금, 거래에 사용할 수 있는 달러 연동 방식의 mUSD 잔액입니다. 이 금액은 총 계정 잔액 계산 시 포함되지 않습니다.\n\n출금은 해당 블록체인의 일반적인 네트워크 컨펌 시간을 기준으로 즉시 처리됩니다. 다만 유동성이 부족한 경우 일시적으로 지연될 수 있습니다." }, "potential_earnings": { "title": "암호화폐로 수익 얻기", "description": "암호화폐를 mUSD로 전환했을 때 자금이 시간에 따라 어떻게 늘어날 수 있는지 확인해 보세요.", - "description_with_amounts_prefix": "Convert your {{total}} in assets and you could earn up to", - "description_with_amounts_suffix": "in one year.", + "description_with_amounts_prefix": "자산 중 {{total}}을(를) 전환하여 적립할 수 있는 최대 수익은 다음과 같습니다", + "description_with_amounts_suffix": "1년 후.", "convert": "전환", - "convert_cta": "Convert your crypto", + "convert_cta": "암호자산 전환", "no_fee": "MetaMask 수수료 없음", "view_all": "모두 보기", "view_potential_earnings": "예상 수익 보기" @@ -6649,41 +6744,44 @@ "cashback": "{{percentage}}% mUSD 캐시백", "get_now": "지금 받기", "link_title": "MetaMask 카드 연결", - "link_subtitle": "Spend your Money balance and earn on purchases. Plus, up to {{apy}}% APY on your balance.", - "link_bullet_cashback": "Get {{percentage}}% mUSD back", - "link_bullet_apy": "Earn up to {{apy}}% APY", + "link_subtitle": "머니 계정 잔액 사용 시 구매 금액에 대해 캐시백을 받을 수 있습니다. 또한 잔액에 대해 {{apy}}% APY의 수익이 적립됩니다.", + "link_subtitle_no_apy": "Spend your Money balance and earn on purchases.", + "link_bullet_cashback": "{{percentage}}% mUSD 캐시백 적립", + "link_bullet_apy": "최대 {{apy}}% APY 수익 적립", "link_card": "카드 연결", - "link_pending_title": "Linking card", - "link_pending_description": "Approving spending limit…", - "link_success_title": "Card linked successfully", - "link_success_description": "You can now spend while you earn", - "link_error": "Couldn't link card", - "manage_card": "Manage", - "avail_balance": "Avail. balance" + "link_pending_title": "Linking your card", + "link_success_title": "Your card is ready to use", + "link_error": "Something went wrong linking your card", + "link_card_sheet_title": "지출하면서 수익을 올리세요", + "link_card_sheet_description": "Link your card so you can spend your Money balance and earn mUSD back on purchases—all while earning up to {{apy}}% APY.", + "link_card_sheet_description_no_apy": "Link your card so you can spend your Money balance and earn mUSD back on purchases.", + "link_card_sheet_cta": "카드 연결", + "manage_card": "관리", + "avail_balance": "사용 가능한 잔액" }, "what_you_get": { "title": "혜택", - "benefit_auto_earn": "Auto-earn up to", + "benefit_auto_earn": "자동으로 적립될 수 있는 최대 수익", "benefit_dollar_backed": "1:1 달러 연동 스테이블코인인 mUSD로 자금을 안전하게 보관하세요", "benefit_liquidity": "락업 없이 완전한 유동성을 제공하므로 언제든지 거래하거나 출금할 수 있습니다", "benefit_spend_prefix": "MetaMask Card로 1억 5천만 개 이상의 가맹점에서 결제하고 ", "benefit_spend_cashback": "1-3% mUSD 캐시백", - "benefit_transfer": "Transfer to any of your wallets across MetaMask", - "benefit_global": "Send and receive funds globally", + "benefit_transfer": "MetaMask의 모든 지갑으로 전송할 수 있습니다", + "benefit_global": "전 세계 어디서나 자금을 보내고 받을 수 있습니다", "learn_more": "더 보기" }, "footer": { - "add_money": "Add funds" + "add_money": "자금 추가" }, "add_money_sheet": { - "title": "Add funds", + "title": "자금 추가", "convert_crypto": "암호자산 전환", - "convert_crypto_description": "From any account", + "convert_crypto_description": "모든 계정에서", "deposit_funds": "자금 예치", - "deposit_funds_description": "From debit card or bank", - "move_musd": "Transfer your {{amount}} mUSD", - "move_musd_no_amount": "Transfer your mUSD", - "move_musd_description": "From your balance", + "deposit_funds_description": "직불카드 또는 은행에서", + "move_musd": "{{amount}} mUSD 전송", + "move_musd_no_amount": "mUSD 전송", + "move_musd_description": "잔액에서", "receive_external": "외부 지갑에서 받기", "coming_soon": "곧 추가 예정" }, @@ -6694,7 +6792,7 @@ "contact_support": "지원팀에 문의" }, "transfer_sheet": { - "title": "Transfer funds", + "title": "자금 전송", "between_accounts": "계좌 간", "perps_account": "무기한 선물 계정", "predictions_account": "예측 계정", @@ -6712,8 +6810,8 @@ "body": "현재 잔액과 오늘의 연간수익률을 기준으로 계산한 일정 기간의 예상 수익입니다. 예상 수익은 보장되지 않으며 변동될 수 있습니다." }, "earn_crypto_info_sheet": { - "title": "Earn on your crypto", - "body": "Illustration assumes {{percentage}}% Annual Percentage Yield (APY) remains unchanged for one year. APY is variable and may change due to various factors. No guarantee of return." + "title": "암호화폐로 수익 얻기", + "body": "본 예시는 {{percentage}}% 연이율(APY)이 1년 동안 유지된다는 가정하에 계산되었습니다. APY는 변동형이므로 다양한 요인에 따라 변경될 수 있습니다. 수익은 보장되지 않습니다." }, "activity": { "title": "활동", @@ -6725,7 +6823,7 @@ }, "condensed_cards": { "how_it_works_title": "작동 방식", - "how_it_works_subtitle": "자금이 어떻게 수익을 내는지 확인하세요", + "how_it_works_subtitle": "See how your money can grow", "musd_title": "MetaMask USD", "musd_subtitle": "mUSD 자세히 알아보기", "what_you_get_title": "혜택", @@ -6738,7 +6836,8 @@ "sent": "보낸", "transferred": "송금됨", "card_transaction": "카드 거래", - "converted": "전환됨" + "converted": "전환됨", + "failed": "실패" }, "convert_stablecoins": { "title": "스테이블코인 전환하기", @@ -6757,11 +6856,11 @@ "how_it_works_page": { "header_title": "머니", "section_title": "작동 방식", - "description_1": "Deposit mUSD into your Money account and earn up to {{percentage}}% APY (variable) automatically. Funds go into a DeFi vault that generates returns across audited lending markets—no staking, no claiming, no lock-ups.", + "description_1": "mUSD를 머니 계정에 입금하면 최대 {{percentage}}% APY(변동형)의 수익을 자동으로 적립할 수 있습니다. 자금은 검증된 대출 시장 전반에서 수익을 창출하는 디파이 볼트에 예치되며, 스테이킹, 수령, 락업 등의 과정을 거칠 필요 없이 이용할 수 있습니다.", "description_2": "Money 잔액은 결제에 사용할 수 있는 잔액입니다. MetaMask 카드를 연결하면 전 세계 1억 5천만 개 이상의 가맹점에서 사용할 수 있습니다. 자금은 사용하는 순간까지 계속 수익을 냅니다.", - "faq_title": "Frequently asked questions", + "faq_title": "자주 묻는 질문", "faq_placeholder_answer": "곧 추가 예정.", - "faq_q1": "How does the {{percentage}}% APY work?", + "faq_q1": "{{percentage}}% APY는 어떻게 적용되나요?", "faq_q2": "mUSD란 무엇인가요?", "faq_q3": "수익은 어디에서 발생하나요?", "faq_q4": "자금은 묶이나요? 언제든지 인출할 수 있나요?", @@ -7030,11 +7129,12 @@ "confirm": "컨펌", "pay_with_bottom_sheet": { "title": "결제 수단:", - "last_used": "Last used", - "crypto": "Crypto", - "available_balance": "{{balance}} available", - "other_assets": "Other assets", - "other_assets_description": "Select from your tokens" + "last_used": "마지막 사용", + "bank_and_card": "은행 및 카드", + "crypto": "암호화폐", + "available_balance": "{{balance}} 사용 가능", + "other_assets": "기타 자산", + "other_assets_description": "보유한 토큰 중에서 선택" }, "staking_footer": { "part1": "계속 진행하면 당사의 ", @@ -7120,7 +7220,7 @@ "transaction_fee": "mUSD 환전 수수료에는 네트워크 비용이 포함되며 제공업체 수수료가 포함될 수 있습니다. mUSD로 환전할 때 MetaMask 수수료는 적용되지 않습니다." }, "money_account_withdraw": { - "transaction_fee": "MetaMask will swap your mUSD for your desired token. Swap providers may charge a fee, but MetaMask won't." + "transaction_fee": "MetaMask가 mUSD를 원하는 토큰으로 스왑해 드립니다. 스왑 제공업체에서 수수료를 부과할 수 있지만, MetaMask는 수수료가 없습니다." }, "title": { "transaction_fee": "수수료" @@ -7225,7 +7325,7 @@ "deposit_edit_amount_done": "자금 추가", "deposit_edit_amount_predict_withdraw": "출금", "deposit_edit_amount_musd_conversion": "mUSD로 전환", - "preparing_order": "Preparing order" + "preparing_order": "주문 준비" }, "change_in_simulation_modal": { "title": "결과가 변경되었습니다", @@ -7250,20 +7350,33 @@ "confirm_swap": "스왑", "terms_and_conditions": "이용약관", "select_token": "토큰 선택", - "batch_sell_select_title": "Select up to 5 tokens", - "batch_sell_select_subtitle": "All tokens need to be on the same network.", - "batch_sell_empty_state_title": "No tokens. No problem.", - "batch_sell_empty_state_description": "No tokens. No problem. Explore and buy tokens to batch sell.", - "batch_sell_continue_with_one_token": "Continue with (1) token", - "batch_sell_continue_with_tokens": "Continue with ({{tokenCount}}) tokens", - "batch_sell_max_tokens_allowed": "Max 5 tokens allowed", - "batch_sell_single_token_dialog_title": "High rate alert", - "batch_sell_single_token_dialog_description": "Batch selling one token could lead to a higher rate. Want to do a swap instead?", - "batch_sell_swap_instead": "Yes, swap", - "batch_sell_checkbox_label": "Batch Sell token", - "sort_balance": "Balance", - "next": "Next", - "explore_tokens": "Explore tokens", + "batch_sell_select_title": "최대 5개 토큰 선택", + "batch_sell_select_subtitle": "모든 토큰은 동일한 네트워크에 있어야 합니다.", + "batch_sell_empty_state_title": "토큰이 없습니다. 그래도 문제없습니다.", + "batch_sell_empty_state_description": "토큰이 없습니다. 그래도 문제없습니다. 둘러보고 토큰을 매입한 후 일괄 매도하세요.", + "batch_sell_continue_with_one_token": "(1)개 토큰으로 계속하기", + "batch_sell_continue_with_tokens": "{{tokenCount}}개 토큰으로 계속하기", + "batch_sell_max_tokens_allowed": "최대 5개 토큰 허용됨", + "batch_sell_single_token_dialog_title": "높은 환율 알림", + "batch_sell_single_token_dialog_description": "하나의 토큰을 일괄 매도하면 환율이 높아질 수 있습니다. 그 대신 스왑을 하시겠습니까?", + "batch_sell_swap_instead": "예, 스왑하겠습니다", + "batch_sell_review_title": "일괄 매도 검토", + "batch_sell_select_stablecoin": "스테이블코인 선택", + "batch_sell_total_received": " 총 수령량", + "batch_sell_minimum_received": "Minimum received", + "batch_sell_quote_details_row": "{{tokenSymbol}} • {{slippage}} slippage", + "batch_sell_review": "검토", + "batch_sell_you_sell": "You sell", + "batch_sell_token_count": "{{tokenCount}} tokens", + "batch_sell_toggle_you_sell": "Toggle token details", + "batch_sell_sell_all": "Sell all", + "batch_sell_includes_metamask_fee": "Includes {{fee}}% MetaMask fee", + "batch_sell_customize_token": "{{tokenSymbol}} 맞춤 설정", + "batch_sell_remove_token": "{{tokenSymbol}} 제거", + "batch_sell_checkbox_label": "토큰 일괄 매도", + "sort_balance": "잔액", + "next": "다음", + "explore_tokens": "토큰 탐색", "no_tokens_found": "토큰을 찾을 수 없습니다", "no_tokens_found_description": "해당 이름의 토큰을 찾을 수 없습니다. 다른 검색어를 입력해 보세요.", "select_network": "네트워크 선택", @@ -7332,6 +7445,7 @@ "price_impact_execution_description": "이 스왑으로 토큰 가치의 약 {{priceImpact}}을(를) 잃게 됩니다. 금액을 낮추거나 유동성이 더 많은 경로를 선택해 보세요.", "proceed": "진행", "cancel": "취소", + "close": "닫기", "slippage_info_title": "슬리피지", "slippage_info_description": "사용자가 허용하는 가격 변동률(%)로, 가격이 이보다 크게 변동하면 트랜잭션이 취소됩니다.", "blockaid_error_title": "이 트랜잭션은 취소됩니다", @@ -8107,7 +8221,14 @@ "retry": "다시 시도", "on_linea": "Linea 네트워크에서", "account_label": "계정", - "token_label": "토큰" + "token_label": "토큰", + "money_account_label": "Money account", + "money_account_token_symbol": "mUSD", + "use_money_account_cta": "Use Money account", + "spend_and_earn_title": "Spend while you earn", + "spend_and_earn_description": "Spend with your Money account and earn up to {{apy}}% APY on your balance. Also get {{cashback}}% mUSD back.", + "spend_and_earn_description_no_apy": "Spend with your Money account and earn APY on your balance. Also get {{cashback}}% mUSD back.", + "spend_and_earn_cta": "Link to Money account" }, "cashback_screen": { "title": "mUSD 캐시백", @@ -8449,6 +8570,7 @@ "show_less": "요약 보기", "linking_progress": "계정 추가 중...({{current}}/{{total}})", "accounts_linked_count": "{{linked}}/{{total}} 등록됨", + "accounts_added": "Accounts added", "add_all_accounts": "모든 계정 추가", "environment_selector": "환경", "environment_cancel": "취소", @@ -8473,15 +8595,22 @@ }, "optout": { "title": "보상 프로그램 영구 탈퇴", - "description": "이 작업을 수행하면 보상 프로그램에서 계정이 지워지며 진행도도 삭제됩니다. 이 작업은 되돌릴 수 없습니다.", - "confirm": "영구 탈퇴", + "description": "This will remove your accounts from the Rewards program and your progress in any campaigns you've joined. Only do this if you are absolutely sure you want to erase your progress.", + "erase_button": "Erase progress", "modal": { "confirmation_title": "진행하시겠습니까?", - "confirmation_description": "이 작업을 수행하면 모든 진행 상황이 제거되며 복원할 수 없습니다. 보상 프로그램에 다시 참여할 경우 처음부터 다시 시작해야 합니다.", + "confirmation_description": "This will erase all your progress, and can't be reversed. If you rejoin the Rewards program later, you'll start back at 0.", + "type_to_confirm": "Type 'erase progress' to continue", + "confirm_phrase": "erase progress", "cancel": "취소", "confirm": "컨펌", + "error_title": "문제가 발생했습니다", "error_message": "보상 프로그램을 탈퇴할 수 없습니다. 다시 시도해 보세요.", "processing": "처리 중..." + }, + "request_received": { + "title": "Request received", + "description": "In about 7 days, your progress will be fully erased. If you made this request by mistake, please contact support through the app." } }, "toast_dismiss": "닫기", @@ -8569,7 +8698,8 @@ "title_claim": "혜택 수령하기", "action": "청구", "empty-list": "현재 보유한 혜택이 없습니다.", - "powered_by": "제공자:" + "powered_by": "제공자:", + "available_count": "{{count}}개 사용 가능" }, "end_of_season_rewards": { "confirm_label_default": "컨펌", @@ -8702,7 +8832,7 @@ "label_your_rank": "내 등급", "label_portfolio": "Portfolio", "label_net_inflow": "순유입", - "label_total_inflow": "총 유입", + "label_total_inflow": "총 유입액", "label_outflow": "순유출", "label_days_held": "보유 일수", "qualified_title": "자격 충족", @@ -8887,9 +9017,11 @@ "musd_claim": "mUSD 받기", "perps_deposit": "자금 추가", "perps_withdraw": "출금", + "predict_withdraw": "{{sourceChain}}에서 {{sourceSymbol}} 인출", "predict_deposit": "자금 추가", "swap": "토큰 스왑", - "swap_approval": "토큰 승인" + "swap_approval": "토큰 승인", + "fiat_purchase": "{{paymentMethod}}(으)로 {{token}} 매입" }, "perps_deposit_solution": "이제 Arbitrum에 {{fiat}} USDC가 있습니다. 다시 입금해 보세요." }, @@ -8965,7 +9097,7 @@ "high_to_low": "높은 순", "low_to_high": "낮은 순", "apply": "적용", - "search_placeholder": "토큰, 사이트 및 URL 검색", + "search_placeholder": "Search tokens, markets and URLs", "cancel": "취소", "perps": "무기한 선물", "rwa_perps_section": "무기한 선물", @@ -8978,11 +9110,15 @@ "crypto_perps_section": "무기한 선물", "predictions": "예측", "no_results": "검색 결과가 없습니다", + "no_results_for_feed": "No {{feedName}} results for \"{{query}}\"", + "showing_all_results_for": "We found these results for \"{{query}}\"", "popular": "인기", "sites": "사이트", "popular_sites": "인기 사이트", "search_sites": "사이트 검색", "view_all": "모두 보기", + "view_more": "더 보기", + "view_x_more": "View {{count}} more", "enable_basic_functionality": "기본 기능 활성화", "basic_functionality_disabled_title": "탐색 기능을 사용할 수 없습니다", "basic_functionality_disabled_description": "기본 기능이 비활성화되어 있어 필요한 메타데이터를 가져올 수 없습니다.", @@ -9002,6 +9138,14 @@ "crypto": "암호화폐", "sports": "스포츠", "dapps": "사이트" + }, + "search_tabs": { + "all": "모두", + "crypto": "Cryptos", + "perps": "무기한 선물", + "stocks": "주식", + "predictions": "예측", + "sites": "사이트" } }, "ota_update_modal": { @@ -9139,6 +9283,7 @@ "money_empty_description_network_filter": "이 네트워크에는 mUSD가 없습니다. mUSD를 확인하려면 네트워크를 전환하세요.", "money_empty_state": { "get_started": "지금 시작하세요", + "earn": "수익 창출", "earn_apy": "{{percentage}}% APY 수익 얻기" }, "money_filled_state": { @@ -9150,22 +9295,7 @@ "related_assets": "관련 자산", "perpetuals": "영구계약", "predictions": "예측", - "whats_happening": "주요 동향", - "whats_happening_ai": "AI", - "whats_happening_impact": { - "bullish": "강세", - "bearish": "약세", - "neutral": "중립" - }, "top_traders": "상위 트레이더", - "whats_happening_categories": { - "geopolitical": "지정학", - "macro": "거시 경제", - "regulatory": "규제", - "technical": "기술", - "social": "사회", - "other": "기타" - }, "defi": "디파이", "nfts": "NFT", "trending_tokens": "인기", @@ -9185,5 +9315,22 @@ }, "sites": { "popular": "인기" + }, + "whats_happening": { + "title": "주요 동향", + "ai": "AI", + "impact": { + "bullish": "강세", + "bearish": "약세", + "neutral": "중립" + }, + "categories": { + "geopolitical": "지정학", + "macro": "거시 경제", + "regulatory": "규제", + "technical": "기술", + "social": "사회", + "other": "기타" + } } } diff --git a/locales/languages/pt.json b/locales/languages/pt.json index 8e0f7c721ff..9e2659db944 100644 --- a/locales/languages/pt.json +++ b/locales/languages/pt.json @@ -120,6 +120,10 @@ "account_no_funds": { "message": "Não há fundos disponíveis. Use outra conta." }, + "headless_buy_error": { + "title": "A compra de moeda fiduciária falhou", + "message": "Ocorreu um erro em sua compra de moeda fiduciária. Tente novamente." + }, "mmpay_hardware_account": { "title": "Não há suporte para esta carteira", "message": "Não oferecemos suporte para carteiras de hardware.\nTroque de carteira para continuar." @@ -133,8 +137,8 @@ "message": "O endereço do destinatário pode não aceitar transferências diretas de tokens, o que pode resultar na perda de fundos. Prossiga apenas se tiver certeza de que este contrato pode receber sua transferência." }, "gas_sponsorship_reserve_balance": { - "message": "O patrocínio de gas não está disponível para esta transação. Você precisará manter pelo menos %{minBalance} %{nativeTokenSymbol} em sua conta.", - "title": "Patrocínio de gas não disponível" + "message": "Esta rede específica requer que você mantenha uma reserva de %{minBalance} %{nativeTokenSymbol} em sua conta.", + "title": "É obrigatório ter saldo de reserva" }, "token_trust_signal": { "malicious": { @@ -708,6 +712,9 @@ "contractAddressError": "Você está enviando tokens para o endereço do contrato do token. Isso pode levar à perda desses tokens.", "smart_contract_address": "Endereço de contrato inteligente", "smart_contract_address_warning": "O endereço do destinatário pode não aceitar transferências diretas de tokens, o que pode resultar na perda de fundos. Prossiga apenas se tiver certeza de que este contrato pode receber sua transferência.", + "unavailable_network_connection": "Unavailable network connection", + "unavailable_network_connection_description": "The connection with {{network}} is unreliable. Update network connectivity details before continuing or try again later.", + "update": "Atualizar", "i_understand": "Eu compreendo", "cancel": "Cancelar", "new_address_title": "Novo endereço", @@ -1068,7 +1075,7 @@ "sort": { "value": "Valor", "pnl_percent": "P&L %", - "recent": "Recent" + "recent": "Recente" } }, "trader_position": { @@ -1120,6 +1127,11 @@ "title": "Negociar perp de {{symbol}}", "subtitle": "Multiplique seu P&L até {{leverage}}" }, + "service_interruption": { + "title": "We're experiencing an outage", + "description": "Some services may be unavailable while the team works on a fix.", + "contact_support": "Falar com o suporte" + }, "today": "Hoje", "yesterday": "Ontem", "unrealized_pnl": "P&L não realizados", @@ -1284,7 +1296,9 @@ "toast_completed_subtitle": "{{amount}} USDC transferidos para sua carteira", "toast_completed_any_token_subtitle": "{{amount}} {{token}} transferidos para sua carteira", "toast_error_title": "Ocorreu algum erro", - "toast_error_description": "Não foi possível prosseguir com o saque" + "toast_error_description": "Não foi possível prosseguir com o saque", + "toast_start_error_description": "Your withdrawal wasn’t started.", + "try_again": "Tentar novamente" }, "quote": { "network_fee": "Taxa de rede", @@ -2227,35 +2241,35 @@ "predict": { "title": "Previsões da MetaMask", "world_cup": { - "title": "World Cup", - "banner_title": "World Cup 2026", - "banner_description": "Trade on World Cup markets", + "title": "Copa do Mundo", + "banner_title": "Copa do Mundo 2026", + "banner_description": "Trade every match, every moment.", "tabs": { - "all": "All", + "all": "Tudo", "props": "Props", - "live": "Live" + "live": "Em tempo real" }, "stages": { - "group_stage": "Group Stage", - "round_of_32": "Round of 32", - "round_of_16": "Round of 16", - "quarterfinals": "Quarterfinals", - "semifinals": "Semifinals", - "third_place": "Third Place", + "group_stage": "Fase de grupos", + "round_of_32": "Primeira fase eliminatória", + "round_of_16": "Oitavas de final", + "quarterfinals": "Quartas de final", + "semifinals": "Semifinais", + "third_place": "Terceiro lugar", "final": "Final", - "group_a": "Group A", - "group_b": "Group B", - "group_c": "Group C", - "group_d": "Group D", - "group_e": "Group E", - "group_f": "Group F", - "group_g": "Group G", - "group_h": "Group H", - "group_i": "Group I", - "group_j": "Group J", - "group_k": "Group K", - "group_l": "Group L", - "third_place_match": "Third Place Match" + "group_a": "Grupo A", + "group_b": "Grupo B", + "group_c": "Grupo C", + "group_d": "Grupo D", + "group_e": "Grupo E", + "group_f": "Grupo F", + "group_g": "Grupo G", + "group_h": "Grupo H", + "group_i": "Grupo I", + "group_j": "Grupo J", + "group_k": "Grupo K", + "group_l": "Grupo L", + "third_place_match": "Disputa pelo terceiro lugar" } }, "prediction_markets": "Mercados de previsão", @@ -2537,8 +2551,8 @@ "withdraw_completed": "Saque concluído", "withdraw_completed_subtitle": "{{amount}} USDC transferidos para sua carteira", "withdraw_any_token_completed_subtitle": "{{amount}} {{token}} transferidos para sua carteira", - "unavailable_title": "Withdrawals temporarily unavailable", - "unavailable_description": "For urgent assistance, please contact Customer Service.", + "unavailable_title": "Saques temporariamente indisponíveis", + "unavailable_description": "Para assistência urgente, entre em contato com o Serviço de Atendimento ao Cliente.", "unavailable_got_it": "Entendi", "error_title": "Ocorreu algum erro", "error_description": "Falha ao continuar com a retirada", @@ -2941,6 +2955,17 @@ "pna25_confirm_button": "Aceitar e fechar", "pna25_open_settings_button": "Abrir Configurações" }, + "onboarding_interest_questionnaire": { + "title": "O que você deseja fazer com a MetaMask?", + "description": "Selecione todas as opções aplicáveis.", + "option_buy_and_sell_crypto": "Comprar e vender criptomoedas", + "option_consolidate_wallets": "Consolidar suas carteiras", + "option_advanced_trades": "Fazer negociações avançadas", + "option_predict_sports_events": "Prever esportes e eventos", + "option_crypto_as_money": "Usar criptomoedas como dinheiro", + "option_connect_apps_sites": "Conectar-se a aplicativos ou sites", + "continue": "Continuar" + }, "template_confirmation": { "ok": "OK", "cancel": "Cancelar" @@ -3261,8 +3286,27 @@ "notifications_desc": "Gerencie suas notificações", "allow_notifications": "Permitir notificações", "enable_push_notifications": "Ativar notificações push", - "allow_notifications_desc": "Fique por dentro do que acontece na sua carteira com as notificações. Para fazer isso, usamos um perfil para sincronizar algumas configurações entre seus dispositivos.", + "allow_notifications_desc": "Choose what you're notified about and how.", "notifications_opts": { + "preferences_title": "Preferences", + "push_recommended": "Push", + "in_app": "In-app", + "status_push": "Push", + "status_in_app": "In app", + "status_off": "Off", + "select_all": "Marcar tudo", + "deselect_all": "Desmarcar tudo", + "select_accounts_title": "Contas", + "select_accounts_desc": "Choose which accounts you'd like to get notifications for.", + "wallet_activity_title": "Wallet Activity", + "wallet_activity_desc": "Buy, sells, transfers, swaps and rewards", + "perps_title": "Trading Activity", + "perps_desc": "Perps position changes, liquidations, funding rates, and margin updates", + "social_ai_title": "Trading Signals", + "social_ai_desc": "Updates from traders and assets you follow, plus currated market news", + "marketing_title": "Updates and Rewards", + "marketing_desc": "Product updates, feature announcements, and new releases", + "marketing_disclaimer": "By turning this on, you agree to receive product news and marketing updates from MetaMask.", "customize_session_title": "Personalize suas notificações", "customize_session_desc": "Ative os tipos de notificações que você deseja receber:", "account_session_title": "Atividade da conta", @@ -3276,8 +3320,7 @@ "snaps_title": "Snaps", "snaps_desc": "Novos recursos e atualizações", "products_announcements_title": "Comunicados sobre produtos", - "products_announcements_desc": "Novos produtos e recursos", - "perps_title": "Negociação de perps" + "products_announcements_desc": "Novos produtos e recursos" }, "contacts_title": "Contatos", "contacts_desc": "Adicione, edite, remova e gerencie suas contas.", @@ -3640,7 +3683,15 @@ "card": { "title": "Cartão", "reset_onboarding_description": "Redefina o estado de integração do Cartão para iniciar o fluxo de integração desde o início.", - "reset_onboarding_button": "Redefinir estado de integração" + "reset_onboarding_button": "Redefinir estado de integração", + "unlink_money_account_description": "Revogar a autorização de limite de gasto de USDC que permite ao Cartão gastar a partir da sua Conta Money. Isso envia uma transação de aprovar(0) e marca a Conta Money como não delegada no sistema interno do Cartão.", + "unlink_money_account_button": "Desvincular conta Money do Cartão", + "unlink_money_account_disabled_hint": "Nenhum vínculo ativo para remover." + }, + "identity": { + "title": "Identity", + "description": "Clears the persisted authentication session. Use this after toggling MM_DEV_API_ENV — otherwise a prod-minted JWT keeps being handed to dev-API consumers until it expires. Current MM_DEV_API_ENV: {{env}}.", + "clear_auth_session_button": "Clear persisted auth session" }, "haptics": { "title": "Háptica", @@ -3842,8 +3893,8 @@ "predict_button": "Previsões", "add_collectible_button": "Adicionar", "info": "Informações", - "batch_sell": "Batch Sell", - "batch_sell_new_label": "New", + "batch_sell": "Venda em lote", + "batch_sell_new_label": "Nova", "swap": "Troca", "convert": "Converter", "bridge": "Ponte", @@ -3883,7 +3934,7 @@ "troubleshoot": "Solução de problemas", "deposit_description": "Transferência bancária ou com cartão com taxas baixas", "buy_description": "Bom para comprar um token específico", - "batch_sell_description": "Sell up to 5 tokens for a stablecoin", + "batch_sell_description": "Venda até 5 tokens por uma moeda estável", "sell_description": "Venda criptoativos por dinheiro", "swap_description": "Faça câmbio entre tokens", "bridge_description": "Transferir tokens entre redes", @@ -5205,6 +5256,34 @@ "manage_preferences_2": "Configurações > Notificações.", "cancel": "Cancelar", "cta": "Ativar" + }, + "push_onboarding": { + "new_user": { + "title": "Não perca nenhum movimento", + "body": "Receba alertas em tempo real quando os preços atingirem suas metas, suas negociações forem confirmadas e seu portfólio for movimentado. Além disso, receba atualizações de produtos e recompensas ao longo do caminho. Compartilharemos atualizações com base em suas interações com a MetaMask.", + "button_yes": "Sim", + "button_not_now": "Agora não", + "preview_card_1": { + "eyebrow": "METAMASK", + "time": "agora", + "title": "O ETH subiu 4,2% hoje", + "message": "Agora está em $ 2.668,51 — acima do seu alerta de preço" + }, + "preview_card_2": { + "eyebrow": "METAMASK", + "time": "1 h atrás", + "title": "0,25 ETH recebido", + "message": "De 0x9a21…4f8c · $ 640,29" + } + }, + "existing_user": { + "title": "Apresentando alertas personalizados", + "body": "Receba notificações que correspondem à forma como você negocia. Atualize a qualquer momento.", + "card_title": "O que você receberá", + "card_description": "Alertas e atualizações personalizados, adaptados à sua atividade de negociação.", + "button_confirm": "Confirmar", + "button_not_now": "Agora não" + } } }, "protect_your_wallet_modal": { @@ -5315,6 +5394,7 @@ "pay_with": "Pagar com", "buying_via": "Comprando via {{providerName}}.", "change_provider": "Alterar fornecedor.", + "circuit_breaker_open": "This service is temporarily unavailable. Please try again in about 30 minutes.", "payment_error": "Algo deu errado. Tente novamente.", "no_payment_methods_available": "Nenhum método de pagamento disponível.", "error_fetching_quotes": "Algo deu errado. Tente novamente.", @@ -6520,6 +6600,8 @@ "convert_to_musd": "Converter para mUSD", "get_a_percentage_musd_bonus": "Ganhe {{percentage}}% de bônus em mUSD", "convert": "Converter", + "confirm": "Confirmar", + "convert_tooltip_description": "Converta suas moedas estáveis em mUSD e ganhe um bônus anualizado de até {{percentage}}% que pode ser resgatado diariamente. Desenvolvido por Relay.", "fetching_quote": "Buscando cotação...", "you_convert": "Você converte", "network_fee": "Taxa de rede", @@ -6597,7 +6679,7 @@ "step_progress": "Etapa {{current}} de {{total}}", "title": "Adicionar dinheiro", "description": "Deposite fundos em sua conta e comece a ganhar rendimento percentual anual (APY).", - "add": "Adicionar", + "add": "Adicionar fundos", "step2_title": "Peça o seu Cartão MetaMask", "step2_description": "Use o saldo do seu cartão Money enquanto ele rende, em qualquer lugar que aceite o Mastercard.", "step2_cta": "Peça o cartão", @@ -6605,6 +6687,19 @@ "link_card_description": "Use seu saldo enquanto ele rende, em qualquer lugar que aceite o Mastercard.", "link_card_cta": "Vincular cartão" }, + "rive_onboarding": { + "step1_title": "As contas Money chegaram", + "step1_body": "Ganhe até {{percentage}}% de APY sobre o seu saldo, disponível em toda a sua carteira.", + "step1_footer_text": "A APY é variável e pode ser alterada a qualquer momento.", + "step2_title": "Ganhe automaticamente", + "step2_body": "Transfira moedas estáveis sem taxas de câmbio. Seus fundos começam a render imediatamente.", + "step2_footer_text": "Provided by Veda and Steakhouse Financial.", + "step3_title": "Gaste em qualquer lugar", + "step3_body": "Receba até {{percentage}}% de cashback em compras ao vincular sua conta Money a um cartão MetaMask.", + "step4_title": "Negocie e ganhe em um só lugar", + "step4_body": "Use o saldo de sua conta Money para negociar na MetaMask e ainda obter rendimento.", + "continue": "Continuar" + }, "action": { "add": "Adicionar", "transfer": "Transferir", @@ -6618,8 +6713,8 @@ }, "how_it_works": { "title": "Como funciona", - "description_prefix": "Deposit mUSD into your Money account and earn up to", - "description_suffix": ". Your balance is dollar-backed and ready to spend, trade, or send anytime." + "description_prefix": "Deposite mUSD em sua conta Money e ganhe até", + "description_suffix": ". Seu saldo é lastreado em dólares e está pronto para ser gasto, negociado ou enviado a qualquer hora." }, "musd_row": { "add": "Adicionar" @@ -6627,16 +6722,16 @@ "balance_card": { "label": "Saldo monetário", "add": "Adicionar", - "info_sheet_title": "Money balance", - "info_sheet_body": "Your dollar-backed mUSD balance that's always available to spend, send, or trade anytime. We don't calculate this into your total account balance.\n\nWithdrawals process immediately, subject to standard network confirmation times on the relevant blockchain. If liquidity is tight, there may be temporary delays." + "info_sheet_title": "Saldo monetário", + "info_sheet_body": "Seu saldo em mUSD lastreado em dólares, sempre disponível para gastar, enviar ou negociar a qualquer hora. Não incluímos esse valor no saldo total da sua conta.\n\nSaques são processados ​​imediatamente, sujeitos aos períodos de confirmação padrão da rede na blockchain pertinente. Se a liquidez estiver baixa, podem ocorrer atrasos temporários." }, "potential_earnings": { "title": "Ganhe com suas criptomoedas", "description": "Veja como seu dinheiro pode render ao longo do tempo convertendo suas criptomoedas em mUSD.", - "description_with_amounts_prefix": "Convert your {{total}} in assets and you could earn up to", - "description_with_amounts_suffix": "in one year.", + "description_with_amounts_prefix": "Converta seu {{total}} em ativos e você poderá ganhar até", + "description_with_amounts_suffix": "em um ano.", "convert": "Converter", - "convert_cta": "Convert your crypto", + "convert_cta": "Converta suas criptomoedas", "no_fee": "Sem taxas da MetaMask", "view_all": "Exibir tudo", "view_potential_earnings": "Visualizar ganhos potenciais" @@ -6649,41 +6744,44 @@ "cashback": "{{percentage}}% de cashback em mUSD", "get_now": "Adquira já", "link_title": "Vincular cartão MetaMask", - "link_subtitle": "Spend your Money balance and earn on purchases. Plus, up to {{apy}}% APY on your balance.", - "link_bullet_cashback": "Get {{percentage}}% mUSD back", - "link_bullet_apy": "Earn up to {{apy}}% APY", + "link_subtitle": "Use o saldo da sua conta Money e ganhe em compras. Além disso, até {{apy}}% de APY sobre o seu saldo.", + "link_subtitle_no_apy": "Spend your Money balance and earn on purchases.", + "link_bullet_cashback": "Receba {{percentage}}% de mUSD em cashback", + "link_bullet_apy": "Ganhe até {{apy}}% de APY", "link_card": "Vincular cartão", - "link_pending_title": "Linking card", - "link_pending_description": "Approving spending limit…", - "link_success_title": "Card linked successfully", - "link_success_description": "You can now spend while you earn", - "link_error": "Couldn't link card", - "manage_card": "Manage", - "avail_balance": "Avail. balance" + "link_pending_title": "Linking your card", + "link_success_title": "Your card is ready to use", + "link_error": "Something went wrong linking your card", + "link_card_sheet_title": "Gaste e ganhe", + "link_card_sheet_description": "Link your card so you can spend your Money balance and earn mUSD back on purchases—all while earning up to {{apy}}% APY.", + "link_card_sheet_description_no_apy": "Link your card so you can spend your Money balance and earn mUSD back on purchases.", + "link_card_sheet_cta": "Vincular cartão", + "manage_card": "Gerenciar", + "avail_balance": "Saldo disponível" }, "what_you_get": { "title": "O que você recebe", - "benefit_auto_earn": "Auto-earn up to", + "benefit_auto_earn": "Ganhe automaticamente até", "benefit_dollar_backed": "Mantenha seu dinheiro seguro em mUSD, uma stablecoin lastreada em dólar na proporção de 1:1", "benefit_liquidity": "Obtenha liquidez total sem períodos de bloqueio, permitindo que você possa negociar ou sacar quando quiser", "benefit_spend_prefix": "Gaste em mais de 150 milhões de estabelecimentos comerciais com o cartão MetaMask e ganhe", "benefit_spend_cashback": "1-3% de cashback em mUSD", - "benefit_transfer": "Transfer to any of your wallets across MetaMask", - "benefit_global": "Send and receive funds globally", + "benefit_transfer": "Transfira para qualquer uma de suas carteiras na MetaMask", + "benefit_global": "Envie e receba fundos globalmente", "learn_more": "Saiba mais" }, "footer": { - "add_money": "Add funds" + "add_money": "Adicionar fundos" }, "add_money_sheet": { - "title": "Add funds", + "title": "Adicionar fundos", "convert_crypto": "Converter criptomoedas", - "convert_crypto_description": "From any account", + "convert_crypto_description": "A partir de qualquer conta", "deposit_funds": "Depositar fundos", - "deposit_funds_description": "From debit card or bank", - "move_musd": "Transfer your {{amount}} mUSD", - "move_musd_no_amount": "Transfer your mUSD", - "move_musd_description": "From your balance", + "deposit_funds_description": "De cartão de débito ou conta bancária", + "move_musd": "Transfira seus {{amount}} mUSD", + "move_musd_no_amount": "Transfira seus mUSD", + "move_musd_description": "Do seu saldo", "receive_external": "Receber de carteira externa", "coming_soon": "Em breve" }, @@ -6694,7 +6792,7 @@ "contact_support": "Falar com o suporte" }, "transfer_sheet": { - "title": "Transfer funds", + "title": "Transferir fundos", "between_accounts": "Entre contas", "perps_account": "Conta de perps", "predictions_account": "Conta de previsões", @@ -6712,8 +6810,8 @@ "body": "Uma estimativa de quanto você poderia ganhar ao longo de um determinado período, com base no seu saldo atual e na APY de hoje. Estimativas não são garantias de retorno e estão sujeitas a alterações." }, "earn_crypto_info_sheet": { - "title": "Earn on your crypto", - "body": "Illustration assumes {{percentage}}% Annual Percentage Yield (APY) remains unchanged for one year. APY is variable and may change due to various factors. No guarantee of return." + "title": "Ganhe com suas criptomoedas", + "body": "A ilustração pressupõe que {{percentage}}% da APY permaneça inalterada por um ano. A APY é variável e pode mudar devido a diversos fatores. Não há garantia de retorno." }, "activity": { "title": "Atividade", @@ -6725,7 +6823,7 @@ }, "condensed_cards": { "how_it_works_title": "Como funciona", - "how_it_works_subtitle": "Veja como seu dinheiro trabalha para você", + "how_it_works_subtitle": "See how your money can grow", "musd_title": "USD MetaMask", "musd_subtitle": "Saiba mais sobre mUSD", "what_you_get_title": "O que você recebe", @@ -6738,7 +6836,8 @@ "sent": "Enviados", "transferred": "Transferido", "card_transaction": "Transação com cartão", - "converted": "Convertido" + "converted": "Convertido", + "failed": "Falha" }, "convert_stablecoins": { "title": "Converta suas stablecoins", @@ -6757,11 +6856,11 @@ "how_it_works_page": { "header_title": "Money", "section_title": "Como funciona", - "description_1": "Deposit mUSD into your Money account and earn up to {{percentage}}% APY (variable) automatically. Funds go into a DeFi vault that generates returns across audited lending markets—no staking, no claiming, no lock-ups.", + "description_1": "Deposite mUSD em sua conta Money e ganhe até {{percentage}}% de APY (variável) automaticamente. Os fundos são colocados em um cofre DeFi que gera rendimentos em mercados de empréstimo auditados — sem staking, sem necessidade de resgate, sem bloqueios.", "description_2": "O saldo da sua conta Money é o seu saldo disponível para gastos. Vincule seu cartão MetaMask para gastar em mais de 150 milhões de estabelecimentos comerciais em todo o mundo. Seu dinheiro continua rendendo até o momento em que você o utiliza.", - "faq_title": "Frequently asked questions", + "faq_title": "Perguntas frequentes (FAQ)", "faq_placeholder_answer": "Em breve.", - "faq_q1": "How does the {{percentage}}% APY work?", + "faq_q1": "Como funciona a {{percentage}}% de APY?", "faq_q2": "O que é mUSD?", "faq_q3": "De onde vem o rendimento?", "faq_q4": "Meu dinheiro está bloqueado? Posso sacar a qualquer hora?", @@ -7030,11 +7129,12 @@ "confirm": "Confirmar", "pay_with_bottom_sheet": { "title": "Pagar com", - "last_used": "Last used", - "crypto": "Crypto", - "available_balance": "{{balance}} available", - "other_assets": "Other assets", - "other_assets_description": "Select from your tokens" + "last_used": "Usado pela última vez", + "bank_and_card": "Banco e cartão", + "crypto": "Cripto", + "available_balance": "{{balance}} disponíveis", + "other_assets": "Outros ativos", + "other_assets_description": "Selecione um de seus tokens" }, "staking_footer": { "part1": "Ao continuar, você concorda com os nossos ", @@ -7120,7 +7220,7 @@ "transaction_fee": "As taxas de conversão de mUSD incluem custos de rede e podem incluir taxas do provedor. A MetaMask não aplica taxas quando você converte para mUSD." }, "money_account_withdraw": { - "transaction_fee": "MetaMask will swap your mUSD for your desired token. Swap providers may charge a fee, but MetaMask won't." + "transaction_fee": "A MetaMask troca seus mUSD pelo token desejado. Provedores de troca podem cobrar uma taxa, mas a MetaMask não cobra." }, "title": { "transaction_fee": "Taxas" @@ -7225,7 +7325,7 @@ "deposit_edit_amount_done": "Adicionar fundos", "deposit_edit_amount_predict_withdraw": "Sacar", "deposit_edit_amount_musd_conversion": "Converter para mUSD", - "preparing_order": "Preparing order" + "preparing_order": "Preparando ordem" }, "change_in_simulation_modal": { "title": "Os resultados mudaram", @@ -7250,20 +7350,33 @@ "confirm_swap": "Swap", "terms_and_conditions": "Termos e condições", "select_token": "Selecionar token", - "batch_sell_select_title": "Select up to 5 tokens", - "batch_sell_select_subtitle": "All tokens need to be on the same network.", - "batch_sell_empty_state_title": "No tokens. No problem.", - "batch_sell_empty_state_description": "No tokens. No problem. Explore and buy tokens to batch sell.", - "batch_sell_continue_with_one_token": "Continue with (1) token", - "batch_sell_continue_with_tokens": "Continue with ({{tokenCount}}) tokens", - "batch_sell_max_tokens_allowed": "Max 5 tokens allowed", - "batch_sell_single_token_dialog_title": "High rate alert", - "batch_sell_single_token_dialog_description": "Batch selling one token could lead to a higher rate. Want to do a swap instead?", - "batch_sell_swap_instead": "Yes, swap", - "batch_sell_checkbox_label": "Batch Sell token", - "sort_balance": "Balance", - "next": "Next", - "explore_tokens": "Explore tokens", + "batch_sell_select_title": "Selecione até 5 tokens", + "batch_sell_select_subtitle": "É necessário que todos os tokens estejam na mesma rede.", + "batch_sell_empty_state_title": "Sem tokens. Sem problemas.", + "batch_sell_empty_state_description": "Sem tokens? Sem problema. Explore e compre tokens para vender em lote.", + "batch_sell_continue_with_one_token": "Continuar com (1) token", + "batch_sell_continue_with_tokens": "Continuar com ({{tokenCount}}) tokens", + "batch_sell_max_tokens_allowed": "Máximo de 5 tokens permitidos", + "batch_sell_single_token_dialog_title": "Alerta de taxa alta", + "batch_sell_single_token_dialog_description": "A venda em lote de apenas um token pode resultar em uma taxa mais alta. Em vez disso, quer fazer uma troca?", + "batch_sell_swap_instead": "Sim, trocar", + "batch_sell_review_title": "Análise de vendas em lote", + "batch_sell_select_stablecoin": "Selecione uma moeda estável", + "batch_sell_total_received": "Total recebido", + "batch_sell_minimum_received": "Minimum received", + "batch_sell_quote_details_row": "{{tokenSymbol}} • {{slippage}} slippage", + "batch_sell_review": "Revisar", + "batch_sell_you_sell": "You sell", + "batch_sell_token_count": "{{tokenCount}} tokens", + "batch_sell_toggle_you_sell": "Toggle token details", + "batch_sell_sell_all": "Sell all", + "batch_sell_includes_metamask_fee": "Includes {{fee}}% MetaMask fee", + "batch_sell_customize_token": "Personalizar {{tokenSymbol}}", + "batch_sell_remove_token": "Remover {{tokenSymbol}}", + "batch_sell_checkbox_label": "Venda de token em lote", + "sort_balance": "Saldo", + "next": "Avançar", + "explore_tokens": "Explorar tokens", "no_tokens_found": "Nenhum token encontrado", "no_tokens_found_description": "Não encontramos tokens com este nome. Tente outro termo de pesquisa.", "select_network": "Selecionar rede", @@ -7332,6 +7445,7 @@ "price_impact_execution_description": "Você perderá aproximadamente {{priceImpact}} do valor do seu token nesta troca. Tente reduzir o valor ou escolher uma rota com mais liquidez.", "proceed": "Prosseguir", "cancel": "Cancelar", + "close": "Fechar", "slippage_info_title": "Slippage", "slippage_info_description": "A % de alteração no preço que você está disposto a permitir antes que sua transação seja cancelada.", "blockaid_error_title": "Esta transação será estornada", @@ -8107,7 +8221,14 @@ "retry": "Tentar novamente", "on_linea": "na Linea", "account_label": "Conta", - "token_label": "Token" + "token_label": "Token", + "money_account_label": "Money account", + "money_account_token_symbol": "mUSD", + "use_money_account_cta": "Use Money account", + "spend_and_earn_title": "Spend while you earn", + "spend_and_earn_description": "Spend with your Money account and earn up to {{apy}}% APY on your balance. Also get {{cashback}}% mUSD back.", + "spend_and_earn_description_no_apy": "Spend with your Money account and earn APY on your balance. Also get {{cashback}}% mUSD back.", + "spend_and_earn_cta": "Link to Money account" }, "cashback_screen": { "title": "Cashback em mUSD", @@ -8336,7 +8457,7 @@ "main_title": "Recompensas", "vip": { "bps_unit": "bps", - "swaps_label": "Swaps", + "swaps_label": "Trocas", "perps_label": "Perps", "error_title": "We couldn’t load your VIP dashboard", "error_description": "Check your connection and try again.", @@ -8449,6 +8570,7 @@ "show_less": "Exibir menos", "linking_progress": "Adicionando contas... ({{current}}/{{total}})", "accounts_linked_count": "{{linked}}/{{total}} inscrita(s)", + "accounts_added": "Accounts added", "add_all_accounts": "Adicionar todas as contas", "environment_selector": "Ambiente", "environment_cancel": "Cancelar", @@ -8473,15 +8595,22 @@ }, "optout": { "title": "Sair do programa de recompensas", - "description": "Isso removerá suas contas do programa Recompensas e apagará seu progresso. Essa opção não poderá ser desfeita.", - "confirm": "Cancelar participação", + "description": "This will remove your accounts from the Rewards program and your progress in any campaigns you've joined. Only do this if you are absolutely sure you want to erase your progress.", + "erase_button": "Erase progress", "modal": { "confirmation_title": "Tem certeza?", - "confirmation_description": "Essa ação removerá todo o seu progresso e não poderá ser revertida. Se você voltar a participar do programa de recompensas mais tarde, começará do zero.", + "confirmation_description": "This will erase all your progress, and can't be reversed. If you rejoin the Rewards program later, you'll start back at 0.", + "type_to_confirm": "Type 'erase progress' to continue", + "confirm_phrase": "erase progress", "cancel": "Cancelar", "confirm": "Confirmar", + "error_title": "Ocorreu algum erro", "error_message": "Falha ao cancelar a participação no programa de recompensas. Tente novamente.", "processing": "Em processamento..." + }, + "request_received": { + "title": "Request received", + "description": "In about 7 days, your progress will be fully erased. If you made this request by mistake, please contact support through the app." } }, "toast_dismiss": "Ignorar", @@ -8569,7 +8698,8 @@ "title_claim": "Resgatar benefício", "action": "Resgatar", "empty-list": "Você não tem nenhum benefício no momento.", - "powered_by": "Com tecnologia da" + "powered_by": "Com tecnologia da", + "available_count": "{{count}} disponíveis" }, "end_of_season_rewards": { "confirm_label_default": "Confirmar", @@ -8702,7 +8832,7 @@ "label_your_rank": "Sua classificação", "label_portfolio": "Portfolio", "label_net_inflow": "Fluxo de entrada líquido", - "label_total_inflow": "Fluxo de entrada total", + "label_total_inflow": "Total de fluxo de entrada", "label_outflow": "Fluxo de saída", "label_days_held": "Dias mantidos", "qualified_title": "Você se qualifica", @@ -8887,9 +9017,11 @@ "musd_claim": "Reivindicar mUSD", "perps_deposit": "Adicionar fundos", "perps_withdraw": "Sacar", + "predict_withdraw": "Sacar {{sourceSymbol}} de {{sourceChain}}", "predict_deposit": "Adicionar fundos", "swap": "Trocar tokens", - "swap_approval": "Aprovar tokens" + "swap_approval": "Aprovar tokens", + "fiat_purchase": "Comprar {{token}} com {{paymentMethod}}" }, "perps_deposit_solution": "Agora você possui {{fiat}} de USDC na Arbitrum. Tente depositar novamente." }, @@ -8965,7 +9097,7 @@ "high_to_low": "Alta para baixa", "low_to_high": "Baixa para alta", "apply": "Aplicar", - "search_placeholder": "Pesquisar tokens, sites, URLs", + "search_placeholder": "Search tokens, markets and URLs", "cancel": "Cancelar", "perps": "Perps", "rwa_perps_section": "Perps", @@ -8978,11 +9110,15 @@ "crypto_perps_section": "Perps", "predictions": "Previsões", "no_results": "Nenhum resultado encontrado", + "no_results_for_feed": "No {{feedName}} results for \"{{query}}\"", + "showing_all_results_for": "We found these results for \"{{query}}\"", "popular": "Populares", "sites": "Sites", "popular_sites": "Websites populares", "search_sites": "Pesquisar websites", "view_all": "Exibir tudo", + "view_more": "Ver mais", + "view_x_more": "View {{count}} more", "enable_basic_functionality": "Ativar funcionalidade básica", "basic_functionality_disabled_title": "A opção Explorar não está disponível", "basic_functionality_disabled_description": "Não é possível obter os metadados necessários quando a funcionalidade básica está desativada.", @@ -9002,6 +9138,14 @@ "crypto": "Cripto", "sports": "Esportes", "dapps": "Sites" + }, + "search_tabs": { + "all": "Tudo", + "crypto": "Cryptos", + "perps": "Perps", + "stocks": "Ações", + "predictions": "Previsões", + "sites": "Sites" } }, "ota_update_modal": { @@ -9139,6 +9283,7 @@ "money_empty_description_network_filter": "Não há mUSD nesta rede. Mude de rede para ver seus mUSD.", "money_empty_state": { "get_started": "Comece já", + "earn": "Ganhe", "earn_apy": "Ganhe {{percentage}}% de APY" }, "money_filled_state": { @@ -9150,22 +9295,7 @@ "related_assets": "Ativos relacionados", "perpetuals": "Perpétuos", "predictions": "Previsões", - "whats_happening": "O que está acontecendo", - "whats_happening_ai": "IA", - "whats_happening_impact": { - "bullish": "Otimista", - "bearish": "Pessimista", - "neutral": "Neutro" - }, "top_traders": "Principais traders", - "whats_happening_categories": { - "geopolitical": "Geopolítica", - "macro": "Macro", - "regulatory": "Regulatório", - "technical": "Técnico", - "social": "Redes sociais", - "other": "Outro" - }, "defi": "DeFi", "nfts": "NFTs", "trending_tokens": "Tendência", @@ -9185,5 +9315,22 @@ }, "sites": { "popular": "Populares" + }, + "whats_happening": { + "title": "O que está acontecendo", + "ai": "IA", + "impact": { + "bullish": "Otimista", + "bearish": "Pessimista", + "neutral": "Neutro" + }, + "categories": { + "geopolitical": "Geopolítica", + "macro": "Macro", + "regulatory": "Regulatório", + "technical": "Técnico", + "social": "Redes sociais", + "other": "Outro" + } } } diff --git a/locales/languages/ru.json b/locales/languages/ru.json index 8aad0ba8474..20288952102 100644 --- a/locales/languages/ru.json +++ b/locales/languages/ru.json @@ -120,6 +120,10 @@ "account_no_funds": { "message": "Нет доступных средств. Используйте другой счет." }, + "headless_buy_error": { + "title": "Сбой покупки за фиатную фалюту", + "message": "Что-то пошло не так при покупке за фиатную валюту. Пожалуйста, попробуйте еще раз." + }, "mmpay_hardware_account": { "title": "Кошелек не поддерживается", "message": "Аппаратные кошельки не поддерживаются.\nЧтобы продолжить, смените кошелек." @@ -133,8 +137,8 @@ "message": "Адрес получателя может не поддерживать прямые переводы токенов, что может привести к потере средств. Продолжайте только в том случае, если вы уверены, что этот контракт может получить ваш перевод." }, "gas_sponsorship_reserve_balance": { - "message": "Для этой транзакции недоступна спонсорская оплата газа. Вам необходимо постоянно иметь на счету не менее %{minBalance} %{nativeTokenSymbol}.", - "title": "Спонсорская оплата газа недоступна" + "message": "Эта конкретная сеть требует поддержания резерва в размере %{minBalance} %{nativeTokenSymbol} на вашем счете.", + "title": "Требуется резервный баланс" }, "token_trust_signal": { "malicious": { @@ -708,6 +712,9 @@ "contractAddressError": "Вы отправляете токены на адрес контракта токена. Это может привести к потере этих токенов.", "smart_contract_address": "Адрес смарт-контракта", "smart_contract_address_warning": "Адрес получателя может не поддерживать прямые переводы токенов, что может привести к потере средств. Продолжайте только в том случае, если вы уверены, что этот контракт может получить ваш перевод.", + "unavailable_network_connection": "Unavailable network connection", + "unavailable_network_connection_description": "The connection with {{network}} is unreliable. Update network connectivity details before continuing or try again later.", + "update": "Обновить", "i_understand": "Я понимаю", "cancel": "Отмена", "new_address_title": "Новый адрес", @@ -1068,7 +1075,7 @@ "sort": { "value": "Значение", "pnl_percent": "П/У %", - "recent": "Recent" + "recent": "Недавние" } }, "trader_position": { @@ -1120,6 +1127,11 @@ "title": "Торгуйте перами на {{symbol}}", "subtitle": "Умножьте свои П/У на {{leverage}}" }, + "service_interruption": { + "title": "We're experiencing an outage", + "description": "Some services may be unavailable while the team works on a fix.", + "contact_support": "Связаться с поддержкой" + }, "today": "Сегодня", "yesterday": "Вчера", "unrealized_pnl": "Нереализованные П/У", @@ -1284,7 +1296,9 @@ "toast_completed_subtitle": "{{amount}} USDC переведены в ваш кошелек", "toast_completed_any_token_subtitle": "{{amount}} {{token}} переведены в ваш кошелек", "toast_error_title": "Что-то пошло не так", - "toast_error_description": "Не удалось продолжить вывод средств" + "toast_error_description": "Не удалось продолжить вывод средств", + "toast_start_error_description": "Your withdrawal wasn’t started.", + "try_again": "Повторить попытку" }, "quote": { "network_fee": "Комиссия сети", @@ -2227,35 +2241,35 @@ "predict": { "title": "Прогнозы MetaMask", "world_cup": { - "title": "World Cup", - "banner_title": "World Cup 2026", - "banner_description": "Trade on World Cup markets", + "title": "Чемпионат мира", + "banner_title": "Чемпионат мира 2026 г.", + "banner_description": "Trade every match, every moment.", "tabs": { - "all": "All", - "props": "Props", - "live": "Live" + "all": "Все", + "props": "Проп-ставки", + "live": "Идет сейчас" }, "stages": { - "group_stage": "Group Stage", - "round_of_32": "Round of 32", - "round_of_16": "Round of 16", - "quarterfinals": "Quarterfinals", - "semifinals": "Semifinals", - "third_place": "Third Place", - "final": "Final", - "group_a": "Group A", - "group_b": "Group B", - "group_c": "Group C", - "group_d": "Group D", - "group_e": "Group E", - "group_f": "Group F", - "group_g": "Group G", - "group_h": "Group H", - "group_i": "Group I", - "group_j": "Group J", - "group_k": "Group K", - "group_l": "Group L", - "third_place_match": "Third Place Match" + "group_stage": "Групповой этап", + "round_of_32": "1/16 финала", + "round_of_16": "1/8 финала", + "quarterfinals": "Четвертьфиналы", + "semifinals": "Полуфиналы", + "third_place": "Третье место", + "final": "Финал", + "group_a": "Группа A", + "group_b": "Группа B", + "group_c": "Группа C", + "group_d": "Группа D", + "group_e": "Группа E", + "group_f": "Группа F", + "group_g": "Группа G", + "group_h": "Группа H", + "group_i": "Группа I", + "group_j": "Группа J", + "group_k": "Группа K", + "group_l": "Группа L", + "third_place_match": "Матч за третье место" } }, "prediction_markets": "Рынки прогнозов", @@ -2537,8 +2551,8 @@ "withdraw_completed": "Вывод средств завершен", "withdraw_completed_subtitle": "{{amount}} USDC переведены в ваш кошелек", "withdraw_any_token_completed_subtitle": "{{amount}} {{token}} переведены в ваш кошелек", - "unavailable_title": "Withdrawals temporarily unavailable", - "unavailable_description": "For urgent assistance, please contact Customer Service.", + "unavailable_title": "Вывод средств временно недоступен", + "unavailable_description": "Для получения срочной помощи обратитесь в службу поддержки.", "unavailable_got_it": "Понятно", "error_title": "Что-то пошло не так", "error_description": "Не удалось продолжить вывод средств", @@ -2941,6 +2955,17 @@ "pna25_confirm_button": "Принять и закрыть", "pna25_open_settings_button": "Открыть Настройки" }, + "onboarding_interest_questionnaire": { + "title": "Что вы хотите делать с помощью MetaMask?", + "description": "Выберите все подходящие варианты.", + "option_buy_and_sell_crypto": "Покупать и продавать криптовалюту", + "option_consolidate_wallets": "Объединить свои кошельки", + "option_advanced_trades": "Совершать продвинутые сделки", + "option_predict_sports_events": "Делать прогнозы на спорт и события", + "option_crypto_as_money": "Использовать криптовалюту как деньги", + "option_connect_apps_sites": "Подключаться к приложениям или сайтам", + "continue": "Продолжить" + }, "template_confirmation": { "ok": "ОК", "cancel": "Отмена" @@ -3261,8 +3286,27 @@ "notifications_desc": "Управляйте своими уведомлениями", "allow_notifications": "Разрешить уведомления", "enable_push_notifications": "Включить push-уведомления", - "allow_notifications_desc": "Будьте в курсе того, что происходит в вашем кошельке, с помощью уведомлений. Чтобы использовать уведомления, мы используем профиль для синхронизации некоторых настроек на ваших устройствах.", + "allow_notifications_desc": "Choose what you're notified about and how.", "notifications_opts": { + "preferences_title": "Preferences", + "push_recommended": "Push", + "in_app": "In-app", + "status_push": "Push", + "status_in_app": "In app", + "status_off": "Выкл.", + "select_all": "Выбрать все", + "deselect_all": "Отменить выбор всех", + "select_accounts_title": "Счета", + "select_accounts_desc": "Choose which accounts you'd like to get notifications for.", + "wallet_activity_title": "Wallet Activity", + "wallet_activity_desc": "Buy, sells, transfers, swaps and rewards", + "perps_title": "Trading Activity", + "perps_desc": "Perps position changes, liquidations, funding rates, and margin updates", + "social_ai_title": "Trading Signals", + "social_ai_desc": "Updates from traders and assets you follow, plus currated market news", + "marketing_title": "Updates and Rewards", + "marketing_desc": "Product updates, feature announcements, and new releases", + "marketing_disclaimer": "By turning this on, you agree to receive product news and marketing updates from MetaMask.", "customize_session_title": "Настройте свои уведомления", "customize_session_desc": "Включите типы уведомлений, которые хотите получать:", "account_session_title": "Активность счета", @@ -3276,8 +3320,7 @@ "snaps_title": "Snaps", "snaps_desc": "Новые функции и обновления", "products_announcements_title": "Объявления о продуктах", - "products_announcements_desc": "Новые продукты и функции", - "perps_title": "Торговля бессрочными фьючерсами" + "products_announcements_desc": "Новые продукты и функции" }, "contacts_title": "Контакты", "contacts_desc": "Добавляйте, изменяйте и удаляйте счета и управляйте ими.", @@ -3640,7 +3683,15 @@ "card": { "title": "Карта", "reset_onboarding_description": "Сбросьте состояние начальной регистрации карты, чтобы начать процесс регистрации с самого начала.", - "reset_onboarding_button": "Сбросить состояние начальной регистрации" + "reset_onboarding_button": "Сбросить состояние начальной регистрации", + "unlink_money_account_description": "Отозвать разрешение на использование лимита трат USDC, которое позволяет карте расходовать средства с вашего денежного счета. Это отправляет транзакцию «одобрить (0)» и отмечает денежный счет как неделегированный в бэкенде карты.", + "unlink_money_account_button": "Отвязать денежный счет от карты", + "unlink_money_account_disabled_hint": "Нет активной привязки для удаления." + }, + "identity": { + "title": "Identity", + "description": "Clears the persisted authentication session. Use this after toggling MM_DEV_API_ENV — otherwise a prod-minted JWT keeps being handed to dev-API consumers until it expires. Current MM_DEV_API_ENV: {{env}}.", + "clear_auth_session_button": "Clear persisted auth session" }, "haptics": { "title": "Тактильный отклик", @@ -3842,8 +3893,8 @@ "predict_button": "Прогнозы", "add_collectible_button": "Добавить", "info": "Информация", - "batch_sell": "Batch Sell", - "batch_sell_new_label": "New", + "batch_sell": "Пакетная продажа", + "batch_sell_new_label": "Новые", "swap": "Обменять", "convert": "Конвертировать", "bridge": "Мост", @@ -3883,7 +3934,7 @@ "troubleshoot": "Устранение неполадок", "deposit_description": "Банковский перевод или перевод на карту с низкой комиссией", "buy_description": "Подходит для покупки определенного токена", - "batch_sell_description": "Sell up to 5 tokens for a stablecoin", + "batch_sell_description": "Продайте до 5 токенов за стейблкоин", "sell_description": "Продать криптовалюту за наличные", "swap_description": "Обменивайте одни токены на другие", "bridge_description": "Передача токенов между сетями", @@ -5205,6 +5256,34 @@ "manage_preferences_2": "Настройки > Уведомления.", "cancel": "Отмена", "cta": "Включить" + }, + "push_onboarding": { + "new_user": { + "title": "Не упускайте ни одного движения", + "body": "Получайте оповещения в реальном времени, когда цены достигают ваших целей, сделки подтверждаются, а портфель меняется. Плюс обновления продукта и бонусы по пути. Мы будем делиться обновлениями на основе вашего взаимодействия с MetaMask.", + "button_yes": "Да", + "button_not_now": "Не сейчас", + "preview_card_1": { + "eyebrow": "METAMASK", + "time": "сейчас", + "title": "ETH вырос на 4,2% сегодня", + "message": "Сейчас на уровне 2668,51 $ — выше вашего ценового оповещения" + }, + "preview_card_2": { + "eyebrow": "METAMASK", + "time": "1 ч назад", + "title": "Получено 0,25 ETH", + "message": "От 0x9a21…4f8c · $640.29" + } + }, + "existing_user": { + "title": "Представляем персонализированные оповещения", + "body": "Получайте оповещения, которые соответствуют вашему стилю торговли. Обновляйте в любое время.", + "card_title": "Что вы получите", + "card_description": "Персонализированные оповещения и обновления, адаптированные к вашей торговой активности.", + "button_confirm": "Подтвердить", + "button_not_now": "Не сейчас" + } } }, "protect_your_wallet_modal": { @@ -5315,6 +5394,7 @@ "pay_with": "Оплатить с помощью", "buying_via": "Покупка через {{providerName}}.", "change_provider": "Изменить поставщика.", + "circuit_breaker_open": "This service is temporarily unavailable. Please try again in about 30 minutes.", "payment_error": "Возникла какая-то проблема. Повторите попытку.", "no_payment_methods_available": "Нет доступных способов оплаты.", "error_fetching_quotes": "Возникла какая-то проблема. Повторите попытку.", @@ -6520,6 +6600,8 @@ "convert_to_musd": "Конвертировать в mUSD", "get_a_percentage_musd_bonus": "Получите бонус в размере {{percentage}}% в mUSD", "convert": "Конвертировать", + "confirm": "Подтвердить", + "convert_tooltip_description": "Конвертируйте свои стейблкоины в mUSD и получайте до {{percentage}}% годового бонуса, который можно запрашивать ежедневно. При поддержке Relay.", "fetching_quote": "Получение котировки...", "you_convert": "Вы конвертируете", "network_fee": "Комиссия сети", @@ -6597,7 +6679,7 @@ "step_progress": "Шаг {{current}} из {{total}}", "title": "Пополнить", "description": "Пополните свой счет и начните зарабатывать годовые.", - "add": "Добавить", + "add": "Внести средства", "step2_title": "Получите карту MetaMask Card", "step2_description": "Тратьте свой баланс Money, пока он приносит доход, везде, где принимают Mastercard.", "step2_cta": "Получить карту", @@ -6605,6 +6687,19 @@ "link_card_description": "Тратьте свой баланс, пока он приносит доход, везде, где принимают Mastercard.", "link_card_cta": "Привязать карту" }, + "rive_onboarding": { + "step1_title": "Денежные счета уже здесь", + "step1_body": "Получайте до {{percentage}}% годовых на свой баланс, доступный по всему вашему кошельку.", + "step1_footer_text": "Годовая процентная доходность является переменной величиной и может измениться в любое время.", + "step2_title": "Зарабатывайте автоматически", + "step2_body": "Переводите стейблкоины без комиссий за обмен. Средства начинают приносить доход сразу же.", + "step2_footer_text": "Provided by Veda and Steakhouse Financial.", + "step3_title": "Тратьте где угодно", + "step3_body": "Получайте до {{percentage}}% кэшбэка за покупки, привязав свой денежный счет к карте MetaMask.", + "step4_title": "Торгуйте и зарабатывайте в одном месте", + "step4_body": "Используйте свой денежный баланс для торговли в MetaMask, продолжая получать доходность.", + "continue": "Продолжить" + }, "action": { "add": "Добавить", "transfer": "Перевести", @@ -6618,8 +6713,8 @@ }, "how_it_works": { "title": "Как это работает", - "description_prefix": "Deposit mUSD into your Money account and earn up to", - "description_suffix": ". Your balance is dollar-backed and ready to spend, trade, or send anytime." + "description_prefix": "Внесите mUSD на свой денежный счет и получайте до", + "description_suffix": ". Ваш баланс обеспечен долларами и готов к тратам, торговле или отправке в любое время." }, "musd_row": { "add": "Добавить" @@ -6627,16 +6722,16 @@ "balance_card": { "label": "Баланс Money", "add": "Добавить", - "info_sheet_title": "Money balance", - "info_sheet_body": "Your dollar-backed mUSD balance that's always available to spend, send, or trade anytime. We don't calculate this into your total account balance.\n\nWithdrawals process immediately, subject to standard network confirmation times on the relevant blockchain. If liquidity is tight, there may be temporary delays." + "info_sheet_title": "Баланс Money", + "info_sheet_body": "Ваш обеспеченный долларами баланс mUSD, который всегда доступен для трат, отправки или торговли. Мы не учитываем его в общем балансе вашего счета. Вывод средств обрабатывается немедленно, в зависимости от стандартного времени подтверждения сети в соответствующем блокчейне. В случае нехватки ликвидности возможны временные задержки." }, "potential_earnings": { "title": "Зарабатывайте на своей криптовалюте", "description": "Посмотрите, как сумма ваших средств может вырасти со временем, если конвертировать вашу криптовалюту в mUSD.", - "description_with_amounts_prefix": "Convert your {{total}} in assets and you could earn up to", - "description_with_amounts_suffix": "in one year.", + "description_with_amounts_prefix": "Конвертируйте свои активы на сумму {{total}}, и вы сможете заработать до", + "description_with_amounts_suffix": "за один год.", "convert": "Конвертировать", - "convert_cta": "Convert your crypto", + "convert_cta": "Конвертировать криптовалюту", "no_fee": "Без комиссии MetaMask", "view_all": "Смотреть все", "view_potential_earnings": "Посмотреть потенциальный доход" @@ -6649,41 +6744,44 @@ "cashback": "{{percentage}}% кэшбэка в mUSD", "get_now": "Получить сейчас", "link_title": "Привязать карту MetaMask", - "link_subtitle": "Spend your Money balance and earn on purchases. Plus, up to {{apy}}% APY on your balance.", - "link_bullet_cashback": "Get {{percentage}}% mUSD back", - "link_bullet_apy": "Earn up to {{apy}}% APY", + "link_subtitle": "Тратьте свой денежный баланс и зарабатывайте на покупках. Плюс до {{apy}}% APY на ваш баланс.", + "link_subtitle_no_apy": "Spend your Money balance and earn on purchases.", + "link_bullet_cashback": "Получайте кэшбэк {{percentage}}% в mUSD", + "link_bullet_apy": "Получайте до {{apy}}% годовых", "link_card": "Привязать карту", - "link_pending_title": "Linking card", - "link_pending_description": "Approving spending limit…", - "link_success_title": "Card linked successfully", - "link_success_description": "You can now spend while you earn", - "link_error": "Couldn't link card", - "manage_card": "Manage", - "avail_balance": "Avail. balance" + "link_pending_title": "Linking your card", + "link_success_title": "Your card is ready to use", + "link_error": "Something went wrong linking your card", + "link_card_sheet_title": "Тратьте и зарабатывайте", + "link_card_sheet_description": "Link your card so you can spend your Money balance and earn mUSD back on purchases—all while earning up to {{apy}}% APY.", + "link_card_sheet_description_no_apy": "Link your card so you can spend your Money balance and earn mUSD back on purchases.", + "link_card_sheet_cta": "Привязать карту", + "manage_card": "Управление", + "avail_balance": "Доступ. баланс" }, "what_you_get": { "title": "Что вы получаете", - "benefit_auto_earn": "Auto-earn up to", + "benefit_auto_earn": "Автоматически зарабатывайте до", "benefit_dollar_backed": "Храните свои деньги в безопасности в mUSD, стейблкоине, обеспеченном долларом 1:1", "benefit_liquidity": "Получите полную ликвидность без блокировок, чтобы вы могли торговать или выводить средства в любое время", "benefit_spend_prefix": "Тратьте средства у более чем 150 млн продавцов с картой MetaMask и зарабатывайте ", "benefit_spend_cashback": "1-3% кэшбэка в mUSD", - "benefit_transfer": "Transfer to any of your wallets across MetaMask", - "benefit_global": "Send and receive funds globally", + "benefit_transfer": "Переводите на любые ваши кошельки в MetaMask", + "benefit_global": "Отправляйте и получайте средства по всему миру", "learn_more": "Подробнее" }, "footer": { - "add_money": "Add funds" + "add_money": "Внести средства" }, "add_money_sheet": { - "title": "Add funds", + "title": "Внести средства", "convert_crypto": "Конвертировать крипту", - "convert_crypto_description": "From any account", + "convert_crypto_description": "С любого счета", "deposit_funds": "Внести средства", - "deposit_funds_description": "From debit card or bank", - "move_musd": "Transfer your {{amount}} mUSD", - "move_musd_no_amount": "Transfer your mUSD", - "move_musd_description": "From your balance", + "deposit_funds_description": "С дебетовой карты или банковского счета", + "move_musd": "Перевести ваши {{amount}} mUSD", + "move_musd_no_amount": "Перевести ваши mUSD", + "move_musd_description": "С вашего баланса", "receive_external": "Получить с внешнего кошелька", "coming_soon": "Скоро появятся" }, @@ -6694,7 +6792,7 @@ "contact_support": "Связаться с поддержкой" }, "transfer_sheet": { - "title": "Transfer funds", + "title": "Перевести средства", "between_accounts": "Между счетами", "perps_account": "Счет перпов", "predictions_account": "Счет прогнозов", @@ -6712,8 +6810,8 @@ "body": "Оценка того, сколько вы могли бы заработать за период на основе вашего текущего баланса и сегодняшней APY. Оценки не гарантируют доходность и могут меняться." }, "earn_crypto_info_sheet": { - "title": "Earn on your crypto", - "body": "Illustration assumes {{percentage}}% Annual Percentage Yield (APY) remains unchanged for one year. APY is variable and may change due to various factors. No guarantee of return." + "title": "Зарабатывайте на своей криптовалюте", + "body": "В примере предполагается, что годовая процентная доходность или годовоые (APY) в размере {{percentage}}% останется неизменной в течение одного года. Годовая поцентная доходность является переменной величиной и может меняться под влиянием различных факторов. Гарантии возврата нет." }, "activity": { "title": "Деятельность", @@ -6725,7 +6823,7 @@ }, "condensed_cards": { "how_it_works_title": "Как это работает", - "how_it_works_subtitle": "Узнайте, как ваши деньги работают на вас", + "how_it_works_subtitle": "See how your money can grow", "musd_title": "MetaMask USD", "musd_subtitle": "Узнать больше о mUSD", "what_you_get_title": "Что вы получаете", @@ -6738,7 +6836,8 @@ "sent": "Отправлено", "transferred": "Переведено", "card_transaction": "Транзакция по карте", - "converted": "Конвертировано" + "converted": "Конвертировано", + "failed": "Ошибка" }, "convert_stablecoins": { "title": "Конвертируйте свои стейблкоины", @@ -6757,11 +6856,11 @@ "how_it_works_page": { "header_title": "Финансы", "section_title": "Как это работает", - "description_1": "Deposit mUSD into your Money account and earn up to {{percentage}}% APY (variable) automatically. Funds go into a DeFi vault that generates returns across audited lending markets—no staking, no claiming, no lock-ups.", + "description_1": "Внесите mUSD на свой денежный счет и автоматически получайте до {{percentage}}% годовых (переменная ставка). Средства поступают в DeFi vault, который генерирует доход на проверенных рынках кредитования — без стейкинга, без клейминга, без блокировок.", "description_2": "Ваш Денежный баланс — это ваш баланс для расходов. Привяжите свою карту MetaMask, чтобы расплачиваться в более чем 150 млн магазинов по всему миру. Ваши деньги продолжают приносить доход до того момента, пока вы их не потратите.", - "faq_title": "Frequently asked questions", + "faq_title": "Часто задаваемые вопросы", "faq_placeholder_answer": "Скоро появятся.", - "faq_q1": "How does the {{percentage}}% APY work?", + "faq_q1": "Как работает ставка {{percentage}}% годовых?", "faq_q2": "Что такое mUSD?", "faq_q3": "Откуда берется доходность?", "faq_q4": "Заблокированы ли мои деньги? Могу ли я вывести их в любое время?", @@ -7030,11 +7129,12 @@ "confirm": "Подтвердить", "pay_with_bottom_sheet": { "title": "Оплатить с помощью", - "last_used": "Last used", - "crypto": "Crypto", - "available_balance": "{{balance}} available", - "other_assets": "Other assets", - "other_assets_description": "Select from your tokens" + "last_used": "Использовалось последним", + "bank_and_card": "Банковский счет и карта", + "crypto": "Крипто", + "available_balance": "Доступно {{balance}}", + "other_assets": "Другие активы", + "other_assets_description": "Выберите из ваших токенов" }, "staking_footer": { "part1": "Продолжая, вы соглашаетесь с нашими ", @@ -7120,7 +7220,7 @@ "transaction_fee": "В стоимость конвертации mUSD входят расходы сети, а также могут входить комиссии поставщика. При обмене на mUSD комиссия MetaMask не взимается." }, "money_account_withdraw": { - "transaction_fee": "MetaMask will swap your mUSD for your desired token. Swap providers may charge a fee, but MetaMask won't." + "transaction_fee": "MetaMask выполнит своп ваших mUSD на нужный токен. Провайдеры свопов могут взимать комиссию, но MetaMask этого не делает." }, "title": { "transaction_fee": "Комиссии" @@ -7225,7 +7325,7 @@ "deposit_edit_amount_done": "Внести средства", "deposit_edit_amount_predict_withdraw": "Вывести средства", "deposit_edit_amount_musd_conversion": "Конвертировать в mUSD", - "preparing_order": "Preparing order" + "preparing_order": "Подготовка ордера" }, "change_in_simulation_modal": { "title": "Результаты изменились", @@ -7250,20 +7350,33 @@ "confirm_swap": "Обменять", "terms_and_conditions": "Положения и условия", "select_token": "Выберите токен", - "batch_sell_select_title": "Select up to 5 tokens", - "batch_sell_select_subtitle": "All tokens need to be on the same network.", - "batch_sell_empty_state_title": "No tokens. No problem.", - "batch_sell_empty_state_description": "No tokens. No problem. Explore and buy tokens to batch sell.", - "batch_sell_continue_with_one_token": "Continue with (1) token", - "batch_sell_continue_with_tokens": "Continue with ({{tokenCount}}) tokens", - "batch_sell_max_tokens_allowed": "Max 5 tokens allowed", - "batch_sell_single_token_dialog_title": "High rate alert", - "batch_sell_single_token_dialog_description": "Batch selling one token could lead to a higher rate. Want to do a swap instead?", - "batch_sell_swap_instead": "Yes, swap", - "batch_sell_checkbox_label": "Batch Sell token", - "sort_balance": "Balance", - "next": "Next", - "explore_tokens": "Explore tokens", + "batch_sell_select_title": "Выберите до 5 токенов", + "batch_sell_select_subtitle": "Все токены должны быть в одной сети.", + "batch_sell_empty_state_title": "Нет токенов. Нет проблем.", + "batch_sell_empty_state_description": "Нет токенов. Нет проблем. Ищите и покупайте токены для пакетной продажи.", + "batch_sell_continue_with_one_token": "Продолжить с (1) токеном", + "batch_sell_continue_with_tokens": "Продолжить с ({{tokenCount}}) токенами", + "batch_sell_max_tokens_allowed": "Разрешено не более 5 токенов", + "batch_sell_single_token_dialog_title": "Предупреждение о высоком курсе", + "batch_sell_single_token_dialog_description": "Пакетная продажа одного токена может привести к более высокому курсу. Хотите вместо этого выполнить своп?", + "batch_sell_swap_instead": "Да, выполнить своп", + "batch_sell_review_title": "Обзор пакетной продажи", + "batch_sell_select_stablecoin": "Выберите стейблкоин", + "batch_sell_total_received": "Всего получено", + "batch_sell_minimum_received": "Minimum received", + "batch_sell_quote_details_row": "{{tokenSymbol}} • {{slippage}} slippage", + "batch_sell_review": "Проверить", + "batch_sell_you_sell": "You sell", + "batch_sell_token_count": "{{tokenCount}} tokens", + "batch_sell_toggle_you_sell": "Toggle token details", + "batch_sell_sell_all": "Sell all", + "batch_sell_includes_metamask_fee": "Includes {{fee}}% MetaMask fee", + "batch_sell_customize_token": "Настроить {{tokenSymbol}}", + "batch_sell_remove_token": "Удалить {{tokenSymbol}}", + "batch_sell_checkbox_label": "Пакетная продажа токена", + "sort_balance": "Баланс", + "next": "Далее", + "explore_tokens": "Искать токены", "no_tokens_found": "Токены не найдены", "no_tokens_found_description": "Не удалось найти токены с этим именем. Попробуйте другой поисковый запрос.", "select_network": "Выбрать сеть", @@ -7332,6 +7445,7 @@ "price_impact_execution_description": "В результате этого обмена вы потеряете примерно {{priceImpact}} от стоимости вашего токена. Попробуйте уменьшить сумму или выбрать более ликвидный вариант.", "proceed": "Продолжить", "cancel": "Отмена", + "close": "Закрыть", "slippage_info_title": "Проскальзывание", "slippage_info_description": "Процент изменения цены, который вы готовы допустить, прежде чем транзакция будет отменена.", "blockaid_error_title": "Эта транзакция будет отменена", @@ -8107,7 +8221,14 @@ "retry": "Повторить попытку", "on_linea": "на Linea", "account_label": "Счет", - "token_label": "Токен" + "token_label": "Токен", + "money_account_label": "Money account", + "money_account_token_symbol": "mUSD", + "use_money_account_cta": "Use Money account", + "spend_and_earn_title": "Spend while you earn", + "spend_and_earn_description": "Spend with your Money account and earn up to {{apy}}% APY on your balance. Also get {{cashback}}% mUSD back.", + "spend_and_earn_description_no_apy": "Spend with your Money account and earn APY on your balance. Also get {{cashback}}% mUSD back.", + "spend_and_earn_cta": "Link to Money account" }, "cashback_screen": { "title": "Кэшбэк mUSD", @@ -8449,6 +8570,7 @@ "show_less": "Показать меньше", "linking_progress": "Добавляются счета... ({{current}} из {{total}})", "accounts_linked_count": "{{linked}}/{{total}} зарегистрировано", + "accounts_added": "Accounts added", "add_all_accounts": "Добавить все счета", "environment_selector": "Среда", "environment_cancel": "Отмена", @@ -8473,15 +8595,22 @@ }, "optout": { "title": "Отказаться от участия в программе вознаграждений", - "description": "Это приведет к удалению ваших счетов из программы вознаграждений, а также к потере прогресса. Отменить это действие будет невозможно.", - "confirm": "Отказаться", + "description": "This will remove your accounts from the Rewards program and your progress in any campaigns you've joined. Only do this if you are absolutely sure you want to erase your progress.", + "erase_button": "Erase progress", "modal": { "confirmation_title": "Вы уверены?", - "confirmation_description": "Это удалит весь ваш прогресс, и его нельзя будет восстановить. Если вы снова присоединитесь к Программе вознаграждений позже, вы начнете с нуля.", + "confirmation_description": "This will erase all your progress, and can't be reversed. If you rejoin the Rewards program later, you'll start back at 0.", + "type_to_confirm": "Type 'erase progress' to continue", + "confirm_phrase": "erase progress", "cancel": "Отмена", "confirm": "Подтвердить", + "error_title": "Что-то пошло не так", "error_message": "Не удалось отказаться от участия в Программе вознаграждений. Попробуйте еще раз.", "processing": "Обработка..." + }, + "request_received": { + "title": "Request received", + "description": "In about 7 days, your progress will be fully erased. If you made this request by mistake, please contact support through the app." } }, "toast_dismiss": "Отклонить", @@ -8569,7 +8698,8 @@ "title_claim": "Получить бонус", "action": "Получить", "empty-list": "У вас пока нет никаких бонусов.", - "powered_by": "На основе" + "powered_by": "На основе", + "available_count": "Доступно: {{count}}" }, "end_of_season_rewards": { "confirm_label_default": "Подтвердить", @@ -8887,9 +9017,11 @@ "musd_claim": "Получить mUSD", "perps_deposit": "Внести средства", "perps_withdraw": "Вывод средств", + "predict_withdraw": "Вывести {{sourceSymbol}} из {{sourceChain}}", "predict_deposit": "Внести средства", "swap": "Обменять токены", - "swap_approval": "Одобрить токены" + "swap_approval": "Одобрить токены", + "fiat_purchase": "Купить {{token}} с помощью {{paymentMethod}}" }, "perps_deposit_solution": "Теперь у вас есть {{fiat}} USDC на Arbitrum. Попробуйте снова внести депозит." }, @@ -8965,7 +9097,7 @@ "high_to_low": "От высокого к низкому", "low_to_high": "От низкого к высокому", "apply": "Применить", - "search_placeholder": "Поиск токенов, сайтов и URL-адресов", + "search_placeholder": "Search tokens, markets and URLs", "cancel": "Отмена", "perps": "Перпы", "rwa_perps_section": "Перпы", @@ -8978,11 +9110,15 @@ "crypto_perps_section": "Перпы", "predictions": "Прогнозы", "no_results": "Результаты не найдены", + "no_results_for_feed": "No {{feedName}} results for \"{{query}}\"", + "showing_all_results_for": "We found these results for \"{{query}}\"", "popular": "Популярные", "sites": "Сайты", "popular_sites": "Популярные сайты", "search_sites": "Поиск по сайтам", "view_all": "Смотреть все", + "view_more": "Показать еще", + "view_x_more": "View {{count}} more", "enable_basic_functionality": "Включить базовый функционал", "basic_functionality_disabled_title": "Обзор недоступен", "basic_functionality_disabled_description": "Мы не можем получить необходимые метаданные, когда базовый функционал отключен.", @@ -9002,6 +9138,14 @@ "crypto": "Крипто", "sports": "Спорт", "dapps": "Сайты" + }, + "search_tabs": { + "all": "Все", + "crypto": "Cryptos", + "perps": "Перпы", + "stocks": "Акции", + "predictions": "Прогнозы", + "sites": "Сайты" } }, "ota_update_modal": { @@ -9139,6 +9283,7 @@ "money_empty_description_network_filter": "В этой сети нет mUSD. Переключитесь на другую сеть, чтобы увидеть свои mUSD.", "money_empty_state": { "get_started": "С чего начать", + "earn": "Заработать", "earn_apy": "Зарабатывайте {{percentage}}% годовых" }, "money_filled_state": { @@ -9150,22 +9295,7 @@ "related_assets": "Связанные активы", "perpetuals": "Бессрочные контракты", "predictions": "Прогнозы", - "whats_happening": "Что происходит", - "whats_happening_ai": "ИИ", - "whats_happening_impact": { - "bullish": "Бычий", - "bearish": "Медвежий", - "neutral": "Нейтральный" - }, "top_traders": "Лучшие трейдеры", - "whats_happening_categories": { - "geopolitical": "Геополитика", - "macro": "Макро", - "regulatory": "Регулирование", - "technical": "Техника", - "social": "Социальные вопросы", - "other": "Другое" - }, "defi": "DeFi", "nfts": "NFT", "trending_tokens": "Популярное", @@ -9185,5 +9315,22 @@ }, "sites": { "popular": "Популярные" + }, + "whats_happening": { + "title": "Что происходит", + "ai": "ИИ", + "impact": { + "bullish": "Бычий", + "bearish": "Медвежий", + "neutral": "Нейтральный" + }, + "categories": { + "geopolitical": "Геополитика", + "macro": "Макро", + "regulatory": "Регулирование", + "technical": "Техника", + "social": "Социальные вопросы", + "other": "Другое" + } } } diff --git a/locales/languages/tl.json b/locales/languages/tl.json index 9328c706192..6a3b1cc468e 100644 --- a/locales/languages/tl.json +++ b/locales/languages/tl.json @@ -120,6 +120,10 @@ "account_no_funds": { "message": "Walang available na mga pondo. Gumamit ng ibang account." }, + "headless_buy_error": { + "title": "Nabigo ang pagbili ng fiat", + "message": "Nagkaproblema sa pagbili mo ng fiat. Pakisubukan muli." + }, "mmpay_hardware_account": { "title": "Hindi sinusuportahan ang wallet", "message": "Hindi pa sinusuportahan ang mga wallet na hardware.\nMagpalit ng wallet para magpatuloy." @@ -133,8 +137,8 @@ "message": "Maaaring hindi sinusuportahan ng address ng tatanggap ang direktang mga paglilipat ng token, na maaaring magresulta sa pagkalugi ng pondo. Magpatuloy lamang kung tiyak ka na matatanggap ng kontratang ito ang paglilipat mo." }, "gas_sponsorship_reserve_balance": { - "message": "Hindi available ang pag-iisponsor ng gas para sa transaksyong ito. Kakailanganin mo ng hindi bababa sa %{minBalance} %{nativeTokenSymbol} sa account mo.", - "title": "Hindi available ang pag-iisponsor ng gas" + "message": "Kailangan ng partikular na network na ito na magpanatili ng reserba ng %{minBalance} %{nativeTokenSymbol} sa iyong account.", + "title": "Kinakailangan ng reserbang balanse" }, "token_trust_signal": { "malicious": { @@ -708,6 +712,9 @@ "contractAddressError": "Nagpapadala ka ng mga token sa address ng kontrata ng token. Maaari itong magresulta sa pagkawala ng mga token na ito.", "smart_contract_address": "Address ng smart na kontrata", "smart_contract_address_warning": "Maaaring hindi sinusuportahan ng address ng tatanggap ang direktang mga paglilipat ng token, na maaaring magresulta sa pagkalugi ng pondo. Magpatuloy lamang kung tiyak ka na matatanggap ng kontratang ito ang paglilipat mo.", + "unavailable_network_connection": "Unavailable network connection", + "unavailable_network_connection_description": "The connection with {{network}} is unreliable. Update network connectivity details before continuing or try again later.", + "update": "I-update", "i_understand": "Nauunawaan ko", "cancel": "Kanselahin", "new_address_title": "Bagong address", @@ -1068,7 +1075,7 @@ "sort": { "value": "Value", "pnl_percent": "P&L %", - "recent": "Recent" + "recent": "Kamakailan" } }, "trader_position": { @@ -1120,6 +1127,11 @@ "title": "Mag-trade ng {{symbol}} perp", "subtitle": "I-multiply ang iyong P&L na hanggang {{leverage}}" }, + "service_interruption": { + "title": "We're experiencing an outage", + "description": "Some services may be unavailable while the team works on a fix.", + "contact_support": "Kontakin ang suporta" + }, "today": "Ngayong araw", "yesterday": "Kahapon", "unrealized_pnl": "Unrealized P&L", @@ -1284,7 +1296,9 @@ "toast_completed_subtitle": "Nailipat ang {{amount}} USDC sa iyong wallet", "toast_completed_any_token_subtitle": "Nailipat ang {{amount}}{{token}} sa iyong wallet", "toast_error_title": "Mayroong nang mali", - "toast_error_description": "Nabigong magpatuloy sa pag-withdraw" + "toast_error_description": "Nabigong magpatuloy sa pag-withdraw", + "toast_start_error_description": "Your withdrawal wasn’t started.", + "try_again": "Subukang muli" }, "quote": { "network_fee": "Bayad sa network", @@ -2229,33 +2243,33 @@ "world_cup": { "title": "World Cup", "banner_title": "World Cup 2026", - "banner_description": "Trade on World Cup markets", + "banner_description": "Trade every match, every moment.", "tabs": { - "all": "All", + "all": "Lahat", "props": "Props", "live": "Live" }, "stages": { "group_stage": "Group Stage", - "round_of_32": "Round of 32", - "round_of_16": "Round of 16", + "round_of_32": "Round na 32", + "round_of_16": "Round na 16", "quarterfinals": "Quarterfinals", "semifinals": "Semifinals", - "third_place": "Third Place", + "third_place": "Ikatlong Pwesto", "final": "Final", - "group_a": "Group A", - "group_b": "Group B", - "group_c": "Group C", - "group_d": "Group D", - "group_e": "Group E", - "group_f": "Group F", - "group_g": "Group G", - "group_h": "Group H", - "group_i": "Group I", - "group_j": "Group J", - "group_k": "Group K", - "group_l": "Group L", - "third_place_match": "Third Place Match" + "group_a": "Grupo A", + "group_b": "Grupo B", + "group_c": "Grupo C", + "group_d": "Grupo D", + "group_e": "Grupo E", + "group_f": "Grupo F", + "group_g": "Grupo G", + "group_h": "Grupo H", + "group_i": "Grupo I", + "group_j": "Grupo J", + "group_k": "Grupo K", + "group_l": "Grupo L", + "third_place_match": "Laban sa Ikatlong Pwesto" } }, "prediction_markets": "Mga market ng prediksyon", @@ -2537,8 +2551,8 @@ "withdraw_completed": "Tapos ng mag-withdraw", "withdraw_completed_subtitle": "Nailipat ang {{amount}} USDC sa iyong wallet", "withdraw_any_token_completed_subtitle": "Nailipat ang {{amount}}{{token}} sa iyong wallet", - "unavailable_title": "Withdrawals temporarily unavailable", - "unavailable_description": "For urgent assistance, please contact Customer Service.", + "unavailable_title": "Pansamantalang hindi available ang mga withdrawal", + "unavailable_description": "Para sa agarang tulong, kontakina ng Customer Service.", "unavailable_got_it": "Nakuha ko", "error_title": "Mayroong nang mali", "error_description": "Nabigong magpatuloy sa pag-withdraw", @@ -2941,6 +2955,17 @@ "pna25_confirm_button": "Tanggapin at isara", "pna25_open_settings_button": "Buksan ang Mga Setting" }, + "onboarding_interest_questionnaire": { + "title": "Ano ang gusto mong gawin sa MetaMask?", + "description": "Piliin ang lahat ng naaangkop.", + "option_buy_and_sell_crypto": "Bumili at magbenta ng crypto", + "option_consolidate_wallets": "Pagsama-samahin ang iyong mga wallet", + "option_advanced_trades": "Gumawa ng mga advanced na trade", + "option_predict_sports_events": "Hulaan ang mga sport at event", + "option_crypto_as_money": "Gamitin ang crypto bilang pera", + "option_connect_apps_sites": "Kumonekta sa mga app o site", + "continue": "Magpatuloy" + }, "template_confirmation": { "ok": "OK", "cancel": "Kanselahin" @@ -3261,8 +3286,27 @@ "notifications_desc": "Pamahalaan ang mga notipikasyon mo", "allow_notifications": "Payagan ang mga notipikasyon", "enable_push_notifications": "Paganahin ang mga push na notipikasyon", - "allow_notifications_desc": "Manatiling may-alam sa nangyayari sa iyong wallet gamit ang mga notification. Para gamitin ang mga notification, gumagamit kami ng profile para i-sync ang ilang mga setting sa lahat ng iyong mga device.", + "allow_notifications_desc": "Choose what you're notified about and how.", "notifications_opts": { + "preferences_title": "Preferences", + "push_recommended": "Push", + "in_app": "In-app", + "status_push": "Push", + "status_in_app": "In app", + "status_off": "I-off", + "select_all": "Piliin lahat", + "deselect_all": "Alisin ang pagkakapili sa lahat", + "select_accounts_title": "Mga Account", + "select_accounts_desc": "Choose which accounts you'd like to get notifications for.", + "wallet_activity_title": "Wallet Activity", + "wallet_activity_desc": "Buy, sells, transfers, swaps and rewards", + "perps_title": "Trading Activity", + "perps_desc": "Perps position changes, liquidations, funding rates, and margin updates", + "social_ai_title": "Trading Signals", + "social_ai_desc": "Updates from traders and assets you follow, plus currated market news", + "marketing_title": "Updates and Rewards", + "marketing_desc": "Product updates, feature announcements, and new releases", + "marketing_disclaimer": "By turning this on, you agree to receive product news and marketing updates from MetaMask.", "customize_session_title": "I-customize ang mga notipikasyon mo", "customize_session_desc": "I-on ang mga uri ng notipikasyon na nais mong matanggap:", "account_session_title": "Aktibidad ng account", @@ -3276,8 +3320,7 @@ "snaps_title": "Mga Snap", "snaps_desc": "Mga bagong tampok at update", "products_announcements_title": "Mga anunsiyo ng produkto", - "products_announcements_desc": "Mga bagong produkto at tampok", - "perps_title": "Perps trading" + "products_announcements_desc": "Mga bagong produkto at tampok" }, "contacts_title": "Mga Kontak", "contacts_desc": "Magdagdag, mag-edit, mag-alis, at mamahala ng iyong mga account.", @@ -3640,7 +3683,15 @@ "card": { "title": "Card", "reset_onboarding_description": "I-reset ang estado ng Card onboarding para simulan ang daloy ng onboarding mula sa simula.", - "reset_onboarding_button": "I-reset ang Estado ng Onboarding" + "reset_onboarding_button": "I-reset ang Estado ng Onboarding", + "unlink_money_account_description": "Bawiin ang allowance ng limitasyon sa paggastos ng USDC na nagpapahintulot sa Card na gumastos mula sa Money Account mo. Isinusumite nito ang aprubadong(0) transaksyon at minamarkahan ang Money Account bilang hindi na-delegate sa backend ng Card.", + "unlink_money_account_button": "I-unlink ang Money Account mula sa Card", + "unlink_money_account_disabled_hint": "Walang aalisin na aktibong pagka-link." + }, + "identity": { + "title": "Identity", + "description": "Clears the persisted authentication session. Use this after toggling MM_DEV_API_ENV — otherwise a prod-minted JWT keeps being handed to dev-API consumers until it expires. Current MM_DEV_API_ENV: {{env}}.", + "clear_auth_session_button": "Clear persisted auth session" }, "haptics": { "title": "Haptics", @@ -3842,8 +3893,8 @@ "predict_button": "Mga hula", "add_collectible_button": "Idagdag", "info": "Impormasyon", - "batch_sell": "Batch Sell", - "batch_sell_new_label": "New", + "batch_sell": "Magbenta nang Naka-batch", + "batch_sell_new_label": "Bago", "swap": "Mag-swap", "convert": "I-convert", "bridge": "Mag-bridge", @@ -3883,7 +3934,7 @@ "troubleshoot": "I-troubleshoot", "deposit_description": "Mababang bayad para sa bank o card transfer", "buy_description": "Mainam para sa pagbili ng partikular na token", - "batch_sell_description": "Sell up to 5 tokens for a stablecoin", + "batch_sell_description": "Magbenta ng hanggang 5 token para sa stablecoin", "sell_description": "Magbenta ng crypto para sa pera", "swap_description": "Palitan sa pagitan ng mga token", "bridge_description": "Maglipat ng mga token sa pagitan ng mga network", @@ -5205,6 +5256,34 @@ "manage_preferences_2": "Mga Setting > Mga notipikasyon.", "cancel": "Kanselahin", "cta": "I-on" + }, + "push_onboarding": { + "new_user": { + "title": "Walang dapat palampasin", + "body": "Kunin ang mga real-time na alerto kapag umabot ang mga presyo sa iyong mga target, mga trade na kinumpirma mo, at ang mga galaw ng iyong portfolio. Idagdag pa ang mga update sa produkto at mga reward na madadaanan. Ibabahagi namin ang mga update batay sa iyong mga interaksyon sa MetaMask.", + "button_yes": "Oo", + "button_not_now": "Hindi sa ngayon", + "preview_card_1": { + "eyebrow": "METAMASK", + "time": "ngayon", + "title": "Hanggang 4.2% ang ETH ngayon", + "message": "Ngayon ay nasa $2,668.51 — mas mataas sa iyong alerto sa presyo" + }, + "preview_card_2": { + "eyebrow": "METAMASK", + "time": "1 oras ang nakalipas", + "title": "Natanggap ang 0.25 ETH", + "message": "Mula sa 0x9a21…4f8c · $640.29" + } + }, + "existing_user": { + "title": "Ipinapakilala ang mga isinapersonal na alerto", + "body": "Makakuha ng mga notipikasyon na tumutugma sa kung paano ka nagti-trade. I-update anumang oras.", + "card_title": "Ano ang makukuha mo", + "card_description": "Mga isinapersonal na alerto at mga update na sinadya para sa iyong aktibidad sa pagti-trade.", + "button_confirm": "Kumpirmahin", + "button_not_now": "Hindi sa ngayon" + } } }, "protect_your_wallet_modal": { @@ -5315,6 +5394,7 @@ "pay_with": "Magbayad gamit ang", "buying_via": "Bumibili sa pamamagitan ng {{providerName}}.", "change_provider": "Magpalit ng provider.", + "circuit_breaker_open": "This service is temporarily unavailable. Please try again in about 30 minutes.", "payment_error": "Nagkaproblema. Subukang muli.", "no_payment_methods_available": "Walang available na mga paraan ng pagbabayad.", "error_fetching_quotes": "Nagkaproblema. Subukang muli.", @@ -6520,6 +6600,8 @@ "convert_to_musd": "I-convert sa mUSD", "get_a_percentage_musd_bonus": "Makakuha ng {{percentage}}% mUSD bonus", "convert": "I-convert", + "confirm": "Kumpirmahin", + "convert_tooltip_description": "I-convert ang mga stablecoin mo sa mUSD at kumita ng hanggang {{percentage}}% taunang bonus na puwede mong ma-claim araw-araw. Pinapagana ng Relay.", "fetching_quote": "Kumukuha ng quote...", "you_convert": "Nagko-convert ka ng", "network_fee": "Bayad sa network", @@ -6597,7 +6679,7 @@ "step_progress": "Hakbang {{current}} ng {{total}}", "title": "Magdagdag ng pera", "description": "Pondohan ang account mo at simulang kumita ng APY.", - "add": "Idagdag", + "add": "Magdagdag ng pondo", "step2_title": "Kunin ang MetaMask Card mo", "step2_description": "Gastusin ang balanse mo sa Money habang kumikita ito, saanman tinatanggap ang Mastercard.", "step2_cta": "Kunin ang card", @@ -6605,6 +6687,19 @@ "link_card_description": "Gastusin ang balanse mo habang kumikita ito, saanman tinatanggap ang Mastercard.", "link_card_cta": "I-link ang card" }, + "rive_onboarding": { + "step1_title": "Narito ang mga money account", + "step1_body": "Kumita ng hanggang {{percentage}}% APY sa iyong balanse, available sa iyong buong wallet.", + "step1_footer_text": "Nag-iiba-iba ang APY at maaari itong magbago anumang oras.", + "step2_title": "Kumita nang awtomatiko", + "step2_body": "Ilipat ang mga stablecoin nang walang mga babayaran sa palitan. Nagsisimulang kumita agad ang mga pondo.", + "step2_footer_text": "Provided by Veda and Steakhouse Financial.", + "step3_title": "Gastusin kahit saan", + "step3_body": "Makakuha ng hanggang {{percentage}}% pabalik sa mga pagbili sa pamamagitan ng pag-link sa Money account mo papunta sa MetaMask card.", + "step4_title": "Mag-trade at kumita sa iisang lugar", + "step4_body": "Gamitin ang balanse ng iyong Pera para mag-trade sa buong MetaMask habang kumikita pa rin ng yield.", + "continue": "Magpatuloy" + }, "action": { "add": "Idagdag", "transfer": "Maglipat", @@ -6618,8 +6713,8 @@ }, "how_it_works": { "title": "Paano ito gumagana", - "description_prefix": "Deposit mUSD into your Money account and earn up to", - "description_suffix": ". Your balance is dollar-backed and ready to spend, trade, or send anytime." + "description_prefix": "Magdeposito ng mUSD sa Money account mo at kumita ng hanggang", + "description_suffix": ". Ang iyong balanse ay sinusuportahan ng dolyar at handa na para gastusin, i-trade, o ipadala anumang oras." }, "musd_row": { "add": "Idagdag" @@ -6627,16 +6722,16 @@ "balance_card": { "label": "Balanse sa Money", "add": "Idagdag", - "info_sheet_title": "Money balance", - "info_sheet_body": "Your dollar-backed mUSD balance that's always available to spend, send, or trade anytime. We don't calculate this into your total account balance.\n\nWithdrawals process immediately, subject to standard network confirmation times on the relevant blockchain. If liquidity is tight, there may be temporary delays." + "info_sheet_title": "Balanse sa Money", + "info_sheet_body": "Ang balanse ng mUSD mo na sinusuportahan ng dolyar na laging available para gastusin, ipadala, o i-trade anumang oras. Hindi namin ito kinakalkula sa buong balanse ng account mo." }, "potential_earnings": { "title": "Kumita sa crypto mo", "description": "Tingnan kung paano maaaring lumago ang pera mo sa paglipas ng panahon sa pamamagitan ng pag-convert ng iyong crypto sa mUSD.", - "description_with_amounts_prefix": "Convert your {{total}} in assets and you could earn up to", - "description_with_amounts_suffix": "in one year.", + "description_with_amounts_prefix": "I-convert ang iyong {{total}} sa mga asset at maaari kang kumita ng hanggang", + "description_with_amounts_suffix": "sa isang taon.", "convert": "I-convert", - "convert_cta": "Convert your crypto", + "convert_cta": "I-convert ang iyong crypto", "no_fee": "Walang bayad sa MetaMask", "view_all": "Tingnan lahat", "view_potential_earnings": "Tingnan ang potensyal na kikitain" @@ -6649,41 +6744,44 @@ "cashback": "Ibabalik na {{percentage}}% mUSD", "get_now": "Kunin ngayon", "link_title": "I-link ang MetaMask Card", - "link_subtitle": "Spend your Money balance and earn on purchases. Plus, up to {{apy}}% APY on your balance.", - "link_bullet_cashback": "Get {{percentage}}% mUSD back", - "link_bullet_apy": "Earn up to {{apy}}% APY", + "link_subtitle": "Gastusin ang balanse ng Pera mo at kumita sa mga pagbili. At karagdagan, na hanggang {{apy}}% APY sa iyong balanse.", + "link_subtitle_no_apy": "Spend your Money balance and earn on purchases.", + "link_bullet_cashback": "Makakuha ng {{percentage}}% mUSD pabalik", + "link_bullet_apy": "Kumita ng hanggang {{apy}}% APY", "link_card": "I-link ang card", - "link_pending_title": "Linking card", - "link_pending_description": "Approving spending limit…", - "link_success_title": "Card linked successfully", - "link_success_description": "You can now spend while you earn", - "link_error": "Couldn't link card", - "manage_card": "Manage", - "avail_balance": "Avail. balance" + "link_pending_title": "Linking your card", + "link_success_title": "Your card is ready to use", + "link_error": "Something went wrong linking your card", + "link_card_sheet_title": "Gumastos at kumita", + "link_card_sheet_description": "Link your card so you can spend your Money balance and earn mUSD back on purchases—all while earning up to {{apy}}% APY.", + "link_card_sheet_description_no_apy": "Link your card so you can spend your Money balance and earn mUSD back on purchases.", + "link_card_sheet_cta": "I-link ang card", + "manage_card": "Pamahalaan", + "avail_balance": "Avail. na balanse" }, "what_you_get": { "title": "Ano ang makukuha mo", - "benefit_auto_earn": "Auto-earn up to", + "benefit_auto_earn": "Awtomatikong kumita ng hanggang", "benefit_dollar_backed": "Itabi nang ligtas ang pera mo sa mUSD, isang stablecoin na sinusuportahan ng dolyar nang 1:1", "benefit_liquidity": "Makakuha ng ganap na liquidity nang walang lockup, kaya maaari kang mag-trade o mag-withdraw anumang oras", "benefit_spend_prefix": "Gastusin sa 150M+ merchant gamit ang MetaMask Card at kumita ", "benefit_spend_cashback": "Ibabalik na 1-3% mUSD", - "benefit_transfer": "Transfer to any of your wallets across MetaMask", - "benefit_global": "Send and receive funds globally", + "benefit_transfer": "Maglipat sa alinman sa iyong mga wallet sa buong MetaMask", + "benefit_global": "Magpadala at makatanggap ng mga pondo saanman sa mundo", "learn_more": "Matuto pa" }, "footer": { - "add_money": "Add funds" + "add_money": "Magdagdag ng pondo" }, "add_money_sheet": { - "title": "Add funds", + "title": "Magdagdag ng pondo", "convert_crypto": "Mag-convert ng crypto", - "convert_crypto_description": "From any account", + "convert_crypto_description": "Mula sa anumang account", "deposit_funds": "Magdeposito ng mga pondo", - "deposit_funds_description": "From debit card or bank", - "move_musd": "Transfer your {{amount}} mUSD", - "move_musd_no_amount": "Transfer your mUSD", - "move_musd_description": "From your balance", + "deposit_funds_description": "Mula sa debit card o bangko", + "move_musd": "Ilipat ang iyong {{amount}} mUSD", + "move_musd_no_amount": "Ilipat ang iyong mUSD", + "move_musd_description": "Mula sa iyong balanse", "receive_external": "Tumanggap mula sa panlabas na wallet", "coming_soon": "Paparating na" }, @@ -6694,7 +6792,7 @@ "contact_support": "Kontakin ang suporta" }, "transfer_sheet": { - "title": "Transfer funds", + "title": "Ilipat ang mga pondo", "between_accounts": "Sa pagitan ng mga account", "perps_account": "Perps account", "predictions_account": "Account sa Predictions", @@ -6712,8 +6810,8 @@ "body": "Pagtataya ng puwede mong kitain sa loob ng isang yugto ng panahon batay sa kasalukuyan mong balanse at APY ngayong araw. Hindi garantisado ang mga return at posible pa ring magbago ang mga ito." }, "earn_crypto_info_sheet": { - "title": "Earn on your crypto", - "body": "Illustration assumes {{percentage}}% Annual Percentage Yield (APY) remains unchanged for one year. APY is variable and may change due to various factors. No guarantee of return." + "title": "Kumita sa crypto mo", + "body": "Ipinagpapalagay sa ilustrasyon na ang {{percentage}}% Annual Percentage Yield (APY) ay nananatiling hindi nagbabago sa loob ng isang taon. Nag-iiba-iba ang APY at posible itong magbago dahil sa iba't ibang salik. Hindi iginagarantiya ang return." }, "activity": { "title": "Aktibidad", @@ -6725,7 +6823,7 @@ }, "condensed_cards": { "how_it_works_title": "Paano ito gumagana", - "how_it_works_subtitle": "Alamin kung paano mo mapapakinabangan ang pera mo", + "how_it_works_subtitle": "See how your money can grow", "musd_title": "MetaMask USD", "musd_subtitle": "Matuto pa tungkol sa mUSD", "what_you_get_title": "Ano ang makukuha mo", @@ -6738,7 +6836,8 @@ "sent": "Nagpadala", "transferred": "Nailipat", "card_transaction": "Transaksyon sa card", - "converted": "Na-convert" + "converted": "Na-convert", + "failed": "Nabigo" }, "convert_stablecoins": { "title": "I-convert ang iyong mga stablecoin", @@ -6757,11 +6856,11 @@ "how_it_works_page": { "header_title": "Pera", "section_title": "Paano ito gumagana", - "description_1": "Deposit mUSD into your Money account and earn up to {{percentage}}% APY (variable) automatically. Funds go into a DeFi vault that generates returns across audited lending markets—no staking, no claiming, no lock-ups.", + "description_1": "Magdeposito ng mUSD sa Money account mo at kumita ng hanggang {{percentage}}% APY (variable) nang awtomatiko. Napupunta ang mga pondo sa DeFi vault na kumikita ng mga return sa lahat ng na-audit na lending market—nang walang pag-stake, pag-claim, mga lock-up.", "description_2": "Ang balanse mo sa Money ang balanseng puwede mong gastusin. I-link ang MetaMask Card mo para magamit ito sa 150M+ merchant sa buong mundo. Patuloy na kikita ang pera mo hanggang sa gastusin mo ito.", - "faq_title": "Frequently asked questions", + "faq_title": "Mga madalas itanong", "faq_placeholder_answer": "Paparating na.", - "faq_q1": "How does the {{percentage}}% APY work?", + "faq_q1": "Paano gumagana ang {{percentage}}% APY?", "faq_q2": "Ano ang mUSD?", "faq_q3": "Saan nanggagaling ang yield?", "faq_q4": "Naka-lock ba ang pera ko? Puwede ba akong mag-withdraw anumang oras?", @@ -7030,11 +7129,12 @@ "confirm": "Kumpirmahin", "pay_with_bottom_sheet": { "title": "Magbayad gamit ang", - "last_used": "Last used", + "last_used": "Huling ginamit", + "bank_and_card": "Bangko at card", "crypto": "Crypto", "available_balance": "{{balance}} available", - "other_assets": "Other assets", - "other_assets_description": "Select from your tokens" + "other_assets": "Iba ang mga asset", + "other_assets_description": "Pumili mula sa mga token mo" }, "staking_footer": { "part1": "Sa pagpapatuloy, sumasang-ayon ka sa aming ", @@ -7120,7 +7220,7 @@ "transaction_fee": "Kasama sa mga bayarin sa pag-convert ng mUSD ang mga bayad sa network at posible ring kasama ang mga bayarin sa provider. Walang hihinging bayad sa MetaMask kapag nag-convert ka sa mUSD." }, "money_account_withdraw": { - "transaction_fee": "MetaMask will swap your mUSD for your desired token. Swap providers may charge a fee, but MetaMask won't." + "transaction_fee": "Isu-swap ng MetaMask ang iyong mUSD sa token na gusto mo. Maaaring maningil ang mga provider sa pag-swap, ngunit hindi ang MetaMask." }, "title": { "transaction_fee": "Mga Bayarin" @@ -7225,7 +7325,7 @@ "deposit_edit_amount_done": "Magdagdag ng pondo", "deposit_edit_amount_predict_withdraw": "Mag-withdraw", "deposit_edit_amount_musd_conversion": "I-convert sa mUSD", - "preparing_order": "Preparing order" + "preparing_order": "Inihahanda ang order" }, "change_in_simulation_modal": { "title": "Nagbago ang mga resulta", @@ -7250,20 +7350,33 @@ "confirm_swap": "Mag-swap", "terms_and_conditions": "Mga Tuntunin at Kundisyon", "select_token": "Pumili ng token", - "batch_sell_select_title": "Select up to 5 tokens", - "batch_sell_select_subtitle": "All tokens need to be on the same network.", - "batch_sell_empty_state_title": "No tokens. No problem.", - "batch_sell_empty_state_description": "No tokens. No problem. Explore and buy tokens to batch sell.", - "batch_sell_continue_with_one_token": "Continue with (1) token", - "batch_sell_continue_with_tokens": "Continue with ({{tokenCount}}) tokens", - "batch_sell_max_tokens_allowed": "Max 5 tokens allowed", - "batch_sell_single_token_dialog_title": "High rate alert", - "batch_sell_single_token_dialog_description": "Batch selling one token could lead to a higher rate. Want to do a swap instead?", - "batch_sell_swap_instead": "Yes, swap", - "batch_sell_checkbox_label": "Batch Sell token", - "sort_balance": "Balance", - "next": "Next", - "explore_tokens": "Explore tokens", + "batch_sell_select_title": "Pumili ng hanggang 5 token", + "batch_sell_select_subtitle": "Ang lahat ng token ay kailangang nasa parehong network.", + "batch_sell_empty_state_title": "Walang mga token. Walang problema.", + "batch_sell_empty_state_description": "Walang mga token. Walang problema. Tuklasin at bumili ng mga token para magbenta nang naka-batch.", + "batch_sell_continue_with_one_token": "Magpatuloy gamit ang (1) token", + "batch_sell_continue_with_tokens": "Magpatuloy gamit ang ({{tokenCount}}) (na) token", + "batch_sell_max_tokens_allowed": "Max na 5 token ang pinapayagan", + "batch_sell_single_token_dialog_title": "Alerto sa mataas na rate", + "batch_sell_single_token_dialog_description": "Ang pagbebenta ng isang token nang naka-batch may maaaring humantong sa mas mataas na rate. Gusto mo bang mag-swap na lang?", + "batch_sell_swap_instead": "Oo, i-swap", + "batch_sell_review_title": "Suriin ang Pagbebenta nang Naka-batch", + "batch_sell_select_stablecoin": "Pumili ng stablecoin", + "batch_sell_total_received": "Kabuuang natanggap", + "batch_sell_minimum_received": "Minimum received", + "batch_sell_quote_details_row": "{{tokenSymbol}} • {{slippage}} slippage", + "batch_sell_review": "Suriin", + "batch_sell_you_sell": "You sell", + "batch_sell_token_count": "{{tokenCount}} tokens", + "batch_sell_toggle_you_sell": "Toggle token details", + "batch_sell_sell_all": "Sell all", + "batch_sell_includes_metamask_fee": "Includes {{fee}}% MetaMask fee", + "batch_sell_customize_token": "I-customize {{tokenSymbol}}", + "batch_sell_remove_token": "Alisin ang {{tokenSymbol}}", + "batch_sell_checkbox_label": "Ibenta nang Naka-batch ang token", + "sort_balance": "Balanse", + "next": "Susunod", + "explore_tokens": "Tuklasin ang mga token", "no_tokens_found": "Walang nakitang token", "no_tokens_found_description": "Wala kaming nakitang anumang token na may ganitong pangalan. Subukang maghanap ng iba.", "select_network": "Pumili ng network", @@ -7332,6 +7445,7 @@ "price_impact_execution_description": "Mawawalan ka ng tinatayang {{priceImpact}} ng halaga ng token mo sa swap na ito. Subukang ibaba ang halaga o pumili ng mas liquid na ruta.", "proceed": "Magpatuloy", "cancel": "Kanselahin", + "close": "Isara", "slippage_info_title": "Slippage", "slippage_info_description": "Ang % ng pagbabago sa presyo na handa mong payagan bago makansela ang iyong transaksyon.", "blockaid_error_title": "Babawiin ang transaksyong ito", @@ -8107,7 +8221,14 @@ "retry": "Subukang muli", "on_linea": "sa Linea", "account_label": "Account", - "token_label": "Token" + "token_label": "Token", + "money_account_label": "Money account", + "money_account_token_symbol": "mUSD", + "use_money_account_cta": "Use Money account", + "spend_and_earn_title": "Spend while you earn", + "spend_and_earn_description": "Spend with your Money account and earn up to {{apy}}% APY on your balance. Also get {{cashback}}% mUSD back.", + "spend_and_earn_description_no_apy": "Spend with your Money account and earn APY on your balance. Also get {{cashback}}% mUSD back.", + "spend_and_earn_cta": "Link to Money account" }, "cashback_screen": { "title": "cashback na mUSD", @@ -8336,7 +8457,7 @@ "main_title": "Mga Reward", "vip": { "bps_unit": "bps", - "swaps_label": "Swaps", + "swaps_label": "Mga Swap", "perps_label": "Perps", "error_title": "We couldn’t load your VIP dashboard", "error_description": "Check your connection and try again.", @@ -8449,6 +8570,7 @@ "show_less": "Magpakita ng mas kaunti", "linking_progress": "Idinadagdag ang mga account... ({{current}}/{{total}})", "accounts_linked_count": "{{linked}}/{{total}} ang na-enroll", + "accounts_added": "Accounts added", "add_all_accounts": "Idagdag ang lahat ng account", "environment_selector": "Environment", "environment_cancel": "Kanselahin", @@ -8473,15 +8595,22 @@ }, "optout": { "title": "Umalis sa Rewards program", - "description": "Dahil dito, maaalis ang iyong mga account mula sa programa ng Mga Reward at mawawala ang mga nagawa mo na. Hindi mo na ito mababawi.", - "confirm": "Permanenteng Tanggalin", + "description": "This will remove your accounts from the Rewards program and your progress in any campaigns you've joined. Only do this if you are absolutely sure you want to erase your progress.", + "erase_button": "Erase progress", "modal": { "confirmation_title": "Sigurado ka ba?", - "confirmation_description": "Aalisin nito ang lahat ng iyong progreso at hindi na ito maibabalik. Kung muli kang sasali sa programa ng mga Reward sa hinaharap, magsisimula ka muli sa 0.", + "confirmation_description": "This will erase all your progress, and can't be reversed. If you rejoin the Rewards program later, you'll start back at 0.", + "type_to_confirm": "Type 'erase progress' to continue", + "confirm_phrase": "erase progress", "cancel": "Kanselahin", "confirm": "Kumpirmahin", + "error_title": "Mayroong nang mali", "error_message": "Nabigong mag-opt-out sa mga Reward. Pakisubukang muli.", "processing": "Pinoproseso..." + }, + "request_received": { + "title": "Request received", + "description": "In about 7 days, your progress will be fully erased. If you made this request by mistake, please contact support through the app." } }, "toast_dismiss": "I-dismiss", @@ -8569,7 +8698,8 @@ "title_claim": "Mag-claim ng Benepisyo", "action": "I-claim", "empty-list": "Waala kang anumang benepisyo sa ngayon.", - "powered_by": "Pinapagana ng" + "powered_by": "Pinapagana ng", + "available_count": "{{count}} available" }, "end_of_season_rewards": { "confirm_label_default": "Kumpirmahin", @@ -8702,7 +8832,7 @@ "label_your_rank": "Rank mo", "label_portfolio": "Portfolio", "label_net_inflow": "Net inflow", - "label_total_inflow": "Total inflow", + "label_total_inflow": "Kabuuang inflow", "label_outflow": "Outflow", "label_days_held": "Mga araw na na-hold", "qualified_title": "Kwalipikado ka", @@ -8887,9 +9017,11 @@ "musd_claim": "I-claim ang mUSD", "perps_deposit": "Magdagdag ng pondo", "perps_withdraw": "Pag-withdraw", + "predict_withdraw": "Mag-withdraw ng {{sourceSymbol}} mula sa {{sourceChain}}", "predict_deposit": "Magdagdag ng pondo", "swap": "Ipagpalit ang mga token", - "swap_approval": "Aprubahan ang mga token" + "swap_approval": "Aprubahan ang mga token", + "fiat_purchase": "Bumili ng {{token}} gamit ang {{paymentMethod}}" }, "perps_deposit_solution": "Mayroon ka na ngayong {{fiat}} ng USDC sa Arbitrum. Subukang magdeposito ulit." }, @@ -8965,7 +9097,7 @@ "high_to_low": "Mataas Pababa", "low_to_high": "Mababa Pataas", "apply": "Ilapat", - "search_placeholder": "Maghanap ng mga token, site, URL", + "search_placeholder": "Search tokens, markets and URLs", "cancel": "Kanselahin", "perps": "Perps", "rwa_perps_section": "Perps", @@ -8978,11 +9110,15 @@ "crypto_perps_section": "Perps", "predictions": "Mga hula", "no_results": "Walang nahanap na mga resulta", + "no_results_for_feed": "No {{feedName}} results for \"{{query}}\"", + "showing_all_results_for": "We found these results for \"{{query}}\"", "popular": "Sikat", "sites": "Mga Site", "popular_sites": "Mga sikat na site", "search_sites": "Maghanap ng mga site", "view_all": "Tingnan lahat", + "view_more": "Tumingin ng higit pa", + "view_x_more": "View {{count}} more", "enable_basic_functionality": "Paganahin ang basic functionality", "basic_functionality_disabled_title": "Hindi available ang pagtuklas", "basic_functionality_disabled_description": "Hindi namin makukuha ang kinakailangang metadata kapag hindi pinapagana ang basic functionality.", @@ -9002,6 +9138,14 @@ "crypto": "Crypto", "sports": "Palakasan", "dapps": "Mga Site" + }, + "search_tabs": { + "all": "Lahat", + "crypto": "Cryptos", + "perps": "Perps", + "stocks": "Stocks", + "predictions": "Mga hula", + "sites": "Mga Site" } }, "ota_update_modal": { @@ -9139,6 +9283,7 @@ "money_empty_description_network_filter": "Walang mUSD sa network na ito. Lumipat ng network para makita ang mUSD mo.", "money_empty_state": { "get_started": "Magsimula", + "earn": "Kumita", "earn_apy": "Kumita ng {{percentage}}% APY" }, "money_filled_state": { @@ -9150,22 +9295,7 @@ "related_assets": "Mga Nauugnay na Asset", "perpetuals": "Perpetuals", "predictions": "Mga hula", - "whats_happening": "Ano ang nangyayari", - "whats_happening_ai": "AI", - "whats_happening_impact": { - "bullish": "Bullish", - "bearish": "Bearish", - "neutral": "Neutral" - }, "top_traders": "Mga Nangungunang Trader", - "whats_happening_categories": { - "geopolitical": "Heopolitikal", - "macro": "Makro", - "regulatory": "Regulatoryo", - "technical": "Teknikal", - "social": "Sosyal", - "other": "Iba pa" - }, "defi": "DeFi", "nfts": "Mga NFT", "trending_tokens": "Nagte-trend", @@ -9185,5 +9315,22 @@ }, "sites": { "popular": "Sikat" + }, + "whats_happening": { + "title": "Ano ang nangyayari", + "ai": "AI", + "impact": { + "bullish": "Bullish", + "bearish": "Bearish", + "neutral": "Neutral" + }, + "categories": { + "geopolitical": "Heopolitikal", + "macro": "Makro", + "regulatory": "Regulatoryo", + "technical": "Teknikal", + "social": "Sosyal", + "other": "Iba pa" + } } } diff --git a/locales/languages/tr.json b/locales/languages/tr.json index 3806766e212..bdf8154120e 100644 --- a/locales/languages/tr.json +++ b/locales/languages/tr.json @@ -69,7 +69,7 @@ "insufficient_balance": { "title": "Para yetersiz", "message": "Hesabınızda ağ ücretlerini ödemek için yeterli %{nativeCurrency} yok.", - "buy_action": "%{nativeCurrency} satın al" + "buy_action": "{nativeCurrency}% satın al" }, "signed_or_submitted": { "title": "İşlem devam ediyor", @@ -120,6 +120,10 @@ "account_no_funds": { "message": "Para mevcut değil. Farklı bir hesap kullanın." }, + "headless_buy_error": { + "title": "Fiat para satın alma işlemi başarısız oldu", + "message": "Fiat para satın alma işleminizle ilgili bir şeyler ters gitti. Lütfen tekrar deneyin." + }, "mmpay_hardware_account": { "title": "Cüzdan desteklenmiyor", "message": "Donanım cüzdanları desteklenmiyor.\nDevam etmek için cüzdan değiştirin." @@ -133,8 +137,8 @@ "message": "Alıcı adresi doğrudan token transferlerini desteklemiyor olabilir ve bu durum para kaybına neden olabilir. Yalnızca transferinizin bu sözleşmeye ulaşabileceğinden eminseniz devam edin." }, "gas_sponsorship_reserve_balance": { - "message": "Gaz sponsorluğu bu işlem için kullanılamıyor. Hesabınızda en az %{minBalance} %{nativeTokenSymbol} tutmanız gerekecek.", - "title": "Gaz sponsorluğu kullanılamıyor" + "message": "Bu ağ için hesabınızda {minBalance}% {nativeTokenSymbol}% rezerv bulunmalıdır.", + "title": "Rezerv bakiyesi gereklidir" }, "token_trust_signal": { "malicious": { @@ -431,7 +435,7 @@ "forgot_password": "Şifreyi mi unuttunuz?", "cant_proceed": "‘Sil’ sözcüğünü yazana kadar ilerleyemezsiniz. Bu eylemle geçerli cüzdanınızı silmeyi seçiyorsunuz.", "invalid_password": "Şifre yanlış, tekrar deneyin.", - "type_delete": "Onaylamak için ‘%{erase}’ yazın", + "type_delete": "Onaylamak için ‘{erase}%’ yazın", "erase_my": "Evet, cüzdanı sıfırla", "cancel": "İptal et", "are_you_sure": "Emin misiniz?", @@ -708,6 +712,9 @@ "contractAddressError": "Token'in sözleşme adresine token gönderiyorsunuz. Bu durum, bu token'lerin kaybedilmesine neden olabilir.", "smart_contract_address": "Akıllı sözleşme adresi", "smart_contract_address_warning": "Alıcı adresi doğrudan token transferlerini desteklemiyor olabilir ve bu durum para kaybına neden olabilir. Yalnızca transferinizin bu sözleşmeye ulaşabileceğinden eminseniz devam edin.", + "unavailable_network_connection": "Unavailable network connection", + "unavailable_network_connection_description": "The connection with {{network}} is unreliable. Update network connectivity details before continuing or try again later.", + "update": "Güncelle", "i_understand": "Anlıyorum", "cancel": "İptal", "new_address_title": "Yeni adres", @@ -991,7 +998,7 @@ "cancel_order_error": "Emrinizi iptal edemedik. Lütfen tekrar deneyin." }, "webview_modal": { - "error": "Webview hata aldı: %{code}" + "error": "Webview hata aldı: {code}%" }, "notifications": { "deposit_failed_title": "{{currency}} para yatırma işlemi başarısız oldu! Lütfen tekrar deneyin, verdiğimiz rahatsızlıktan dolayı özür dileriz!", @@ -1068,7 +1075,7 @@ "sort": { "value": "Değer", "pnl_percent": "K&Z %", - "recent": "Recent" + "recent": "Son Kullanılanlar" } }, "trader_position": { @@ -1120,6 +1127,11 @@ "title": "{{symbol}} sürekli vadeli işlemi yap", "subtitle": "K&Z'ni {{leverage}} kadar katla" }, + "service_interruption": { + "title": "We're experiencing an outage", + "description": "Some services may be unavailable while the team works on a fix.", + "contact_support": "Destek ile iletişime geç" + }, "today": "Bugün", "yesterday": "Dün", "unrealized_pnl": "Gerçekleşmemiş K&Z", @@ -1284,7 +1296,9 @@ "toast_completed_subtitle": "{{amount}} USDC cüzdanınıza aktarıldı", "toast_completed_any_token_subtitle": "{{amount}} {{token}} cüzdanınıza taşındı", "toast_error_title": "Bir şeyler ters gitti", - "toast_error_description": "Para çekme işlemine ilerlenemedi" + "toast_error_description": "Para çekme işlemine ilerlenemedi", + "toast_start_error_description": "Your withdrawal wasn’t started.", + "try_again": "Tekrar dene" }, "quote": { "network_fee": "Ağ ücreti", @@ -2205,7 +2219,7 @@ "got_it": "Anladım" }, "swap_button": "Takas", - "buy_button": "Al", + "buy_button": "Satın Al", "sources_count": "+{{count}} kaynak", "sources_title": "Haber kaynakları", "feedback_submitted": "Geri bildirim gönderildi", @@ -2227,35 +2241,35 @@ "predict": { "title": "MetaMask Tahminler", "world_cup": { - "title": "World Cup", - "banner_title": "World Cup 2026", - "banner_description": "Trade on World Cup markets", + "title": "Dünya Kupası", + "banner_title": "Dünya Kupası 2026", + "banner_description": "Trade every match, every moment.", "tabs": { - "all": "All", - "props": "Props", - "live": "Live" + "all": "Tümü", + "props": "Özel Bahisler", + "live": "Canlı" }, "stages": { - "group_stage": "Group Stage", - "round_of_32": "Round of 32", - "round_of_16": "Round of 16", - "quarterfinals": "Quarterfinals", - "semifinals": "Semifinals", - "third_place": "Third Place", + "group_stage": "Grup Aşaması", + "round_of_32": "Son 32 Tur", + "round_of_16": "Son 16 Tur", + "quarterfinals": "Çeyrek Finaller", + "semifinals": "Yarı Finaller", + "third_place": "Üçüncülük", "final": "Final", - "group_a": "Group A", - "group_b": "Group B", - "group_c": "Group C", - "group_d": "Group D", - "group_e": "Group E", - "group_f": "Group F", - "group_g": "Group G", - "group_h": "Group H", - "group_i": "Group I", - "group_j": "Group J", - "group_k": "Group K", - "group_l": "Group L", - "third_place_match": "Third Place Match" + "group_a": "Grup A", + "group_b": "Grup B", + "group_c": "Grup C", + "group_d": "Grup D", + "group_e": "Grup E", + "group_f": "Grup F", + "group_g": "Grup G", + "group_h": "Grup H", + "group_i": "Grup I", + "group_j": "Grup J", + "group_k": "Grup K", + "group_l": "Grup L", + "third_place_match": "Üçüncülük Maçı" } }, "prediction_markets": "Tahmin piyasaları", @@ -2537,8 +2551,8 @@ "withdraw_completed": "Çekme işlemi tamamlandı", "withdraw_completed_subtitle": "{{amount}} USDC cüzdanınıza aktarıldı", "withdraw_any_token_completed_subtitle": "{{amount}} {{token}} cüzdanınıza taşındı", - "unavailable_title": "Withdrawals temporarily unavailable", - "unavailable_description": "For urgent assistance, please contact Customer Service.", + "unavailable_title": "Para çekme işlemleri geçici olarak kullanılamıyor", + "unavailable_description": "Acil yardım için lütfen Müşteri Hizmetleri ile iletişime geçin.", "unavailable_got_it": "Anladım", "error_title": "Bir şeyler ters gitti", "error_description": "Çekme işlemine ilerlenemedi", @@ -2559,7 +2573,7 @@ "slippage": "Kayma", "price_details": "Fiyat bilgileri", "prediction_order": "Tahmin emri", - "prediction_order_description": "Her biri {{price}} fiyatta ~{{count}} sözleşme. Son tutar, emir defteri kullanılabilirliğe göre değişiklik gösterebilir ({{slippage}}% orana kadar).", + "prediction_order_description": "Her biri {{price}} fiyatta ~{{count}} sözleşme. Son tutar, emir defteri kullanılabilirliğe göre değişiklik gösterebilir ({{slippage}%} orana kadar).", "metamask_fee_description": "Bu tahmin işlemine yönelik hizmet ücreti", "exchange_fee": "Borsa ücreti", "exchange_fee_description": "Borsaya veya piyasaya ödenen ücret", @@ -2941,6 +2955,17 @@ "pna25_confirm_button": "Kabul et ve kapat", "pna25_open_settings_button": "Ayarları Aç" }, + "onboarding_interest_questionnaire": { + "title": "MetaMask ile ne yapmak istersiniz?", + "description": "Geçerli olanların tümünü seçin.", + "option_buy_and_sell_crypto": "Kripto alın ve satın", + "option_consolidate_wallets": "Cüzdanlarınızı birleştirin", + "option_advanced_trades": "Gelişmiş işlemler gerçekleştirin", + "option_predict_sports_events": "Spor ve etkinlik sonuçlarını tahmin edin", + "option_crypto_as_money": "Kriptoyu para olarak kullanın", + "option_connect_apps_sites": "Uygulamalara veya sitelere bağlanın", + "continue": "Devam et" + }, "template_confirmation": { "ok": "Tamam", "cancel": "İptal" @@ -3167,7 +3192,7 @@ "networks": "Ağlar", "log_out": "Oturumu kapat", "notifications": "Bildirimler", - "buy": "Al", + "buy": "Satın Al", "scan": "Tara" }, "app_settings": { @@ -3261,8 +3286,27 @@ "notifications_desc": "Bildirimlerinizi yönetin", "allow_notifications": "Bildirimlere izin ver", "enable_push_notifications": "Anlık bildirimleri etkinleştir", - "allow_notifications_desc": "Bildirimler ile cüzdanınızda neler olduğundan haberdar olun. Bildirimleri kullanmak için cihazlarınızdaki bazı ayarları senkronize etmek amacıyla bir profil kullanıyoruz.", + "allow_notifications_desc": "Choose what you're notified about and how.", "notifications_opts": { + "preferences_title": "Preferences", + "push_recommended": "Push", + "in_app": "In-app", + "status_push": "Push", + "status_in_app": "In app", + "status_off": "Kapalı", + "select_all": "Tümünü seç", + "deselect_all": "Tümünün seçimini kaldır", + "select_accounts_title": "Hesaplar", + "select_accounts_desc": "Choose which accounts you'd like to get notifications for.", + "wallet_activity_title": "Wallet Activity", + "wallet_activity_desc": "Buy, sells, transfers, swaps and rewards", + "perps_title": "Trading Activity", + "perps_desc": "Perps position changes, liquidations, funding rates, and margin updates", + "social_ai_title": "Trading Signals", + "social_ai_desc": "Updates from traders and assets you follow, plus currated market news", + "marketing_title": "Updates and Rewards", + "marketing_desc": "Product updates, feature announcements, and new releases", + "marketing_disclaimer": "By turning this on, you agree to receive product news and marketing updates from MetaMask.", "customize_session_title": "Bildirimlerinizi özelleştirin", "customize_session_desc": "Almak istediğiniz bildirim türlerini açın:", "account_session_title": "Hesap aktivitesi", @@ -3276,8 +3320,7 @@ "snaps_title": "Snap'ler", "snaps_desc": "Yeni özellikler ve güncellemeler", "products_announcements_title": "Ürün duyuruları", - "products_announcements_desc": "Yeni ürünler ve özellikler", - "perps_title": "Sürekli vadeli işlem sözleşmeleri ile işlem" + "products_announcements_desc": "Yeni ürünler ve özellikler" }, "contacts_title": "Kişiler", "contacts_desc": "Hesap ekle, düzenle, kaldır ve hesaplarını yönet.", @@ -3372,13 +3415,13 @@ "general_heading": "Genel", "privacy_heading": "Gizlilik", "failed_to_fetch_chain_id": "Zincir kimliği alınamadı. RPC URL adresiniz doğru mu?", - "endpoint_returned_different_chain_id": "Uç nokta farklı bir zincir kimliği getirdi: %{chainIdReturned}", + "endpoint_returned_different_chain_id": "Uç nokta farklı bir zincir kimliği getirdi: {chainIdReturned}%", "chain_id_required": "Zincir kimliği gereklidir. Ağ tarafından getirilen zincir kimliği ile uyumlu olmalıdır. Bir ondalık sayı veya '0x' ön ekli bir on altılı sayı girebilirsiniz.", "invalid_hex_number": "Geçersiz on altılı sayı.", "invalid_hex_number_leading_zeros": "Geçersiz on altılı sayı. Lütfen baştaki tüm sıfırları silin.", "invalid_number": "Geçersiz sayı. Ondalık sayısı veya '0x' ön ekli on altılı bir sayı girin.", "invalid_number_leading_zeros": "Geçersiz sayı. Baştaki tüm sıfırları silin.", - "invalid_number_range": "Geçersiz sayı. 1 ile %{maxSafeChainId} arasında bir sayı girin.", + "invalid_number_range": "Geçersiz sayı. 1 ile {maxSafeChainId}% arasında bir sayı girin.", "hide_zero_balance_tokens_title": "Bakiyesi olmayan tokenları gizle", "hide_zero_balance_tokens_desc": "Bakiyesi olmayan tokenlerin token listenizde gösterilmesini önler.", "haptic_feedback_title": "Dokunsal geri bildirim", @@ -3640,7 +3683,15 @@ "card": { "title": "Kart", "reset_onboarding_description": "Kayıt akışını baştan başlatmak için Kart kayıt durumunu sıfırlayın.", - "reset_onboarding_button": "Kayıt Durumunu Sıfırla" + "reset_onboarding_button": "Kayıt Durumunu Sıfırla", + "unlink_money_account_description": "Kartın, Para Hesabınızdan harcama yapmasına yetki veren USDC harcama limiti iznini iptal edin. Bu işlem bir approve(0) transferi gönderir ve Para Hesabını, Kart altyapısında yetkilendirilmemiş olarak işaretler.", + "unlink_money_account_button": "Para Hesabının Kart ile bağlantısını kesin", + "unlink_money_account_disabled_hint": "Kaldırılacak aktif bağlantı yok." + }, + "identity": { + "title": "Identity", + "description": "Clears the persisted authentication session. Use this after toggling MM_DEV_API_ENV — otherwise a prod-minted JWT keeps being handed to dev-API consumers until it expires. Current MM_DEV_API_ENV: {{env}}.", + "clear_auth_session_button": "Clear persisted auth session" }, "haptics": { "title": "Dokunsal bildirimler", @@ -3817,9 +3868,9 @@ "fund_actionmenu": { "deposit": "Para Yatır", "deposit_description": "Düşük ücretli banka veya kart transferi", - "buy": "Al", + "buy": "Satın al", "buy_description": "Belirli bir token'ı almak için iyi", - "buy_unified": "Al", + "buy_unified": "Satın al", "buy_unified_description": "Nakit ile kripto satın alın", "sell": "Sat", "sell_description": "Nakit karşılığı kripto sat" @@ -3842,8 +3893,8 @@ "predict_button": "Tahminler", "add_collectible_button": "Ekle", "info": "Bilgi", - "batch_sell": "Batch Sell", - "batch_sell_new_label": "New", + "batch_sell": "Toplu Satış", + "batch_sell_new_label": "Yeni", "swap": "Takas Et", "convert": "Dönüştür", "bridge": "Köprü", @@ -3883,7 +3934,7 @@ "troubleshoot": "Sorun Giderme", "deposit_description": "Düşük ücretli banka veya kart transferi", "buy_description": "Belirli bir token'ı almak için iyi", - "batch_sell_description": "Sell up to 5 tokens for a stablecoin", + "batch_sell_description": "Bir stabil kripto para karşılığında en fazla 5 token satışı yapın", "sell_description": "Nakit karşılığında kripto sat", "swap_description": "Tokenler arasında swap gerçekleştirin", "bridge_description": "Farklı ağlar arasında token transfer et", @@ -4234,8 +4285,8 @@ "confusable_msg": "ENS adında karıştırılabilir bir karakter algıladık. Olası bir dolandırıcılığı önlemek için ENS adını kontrol edin.", "similar_to": "şuna benzer:", "contains_zero_width": "sıfır genişlikli karakter içeriyor", - "dapp_suggested_gas": "Bu gaz ücreti %{origin} tarafından önerildi. Eski gaz tahminini kullanıyor ve bu yanlış olabilir. Ancak, bu gaz ücretinin düzenlenmesi işleminizde bir soruna neden olabilir. Sorularınız olursa lütfen %{origin} adresine ulaşın.", - "dapp_suggested_eip1559_gas": "Bu gaz ücreti %{origin} tarafından önerildi. Bunu geçersiz kılmak işleminizde bir soruna neden olabilir. Sorularınız olursa lütfen %{origin} adresine ulaşın.", + "dapp_suggested_gas": "Bu gaz ücreti {origin}% tarafından önerildi. Eski gaz tahminini kullanıyor ve bu yanlış olabilir. Ancak, bu gaz ücretinin düzenlenmesi işleminizde bir soruna neden olabilir. Sorularınız olursa lütfen {origin}% adresine ulaşın.", + "dapp_suggested_eip1559_gas": "Bu gaz ücreti {origin}% tarafından önerildi. Bunu geçersiz kılmak işleminizde bir soruna neden olabilir. Sorularınız olursa lütfen {origin}% adresine ulaşın.", "address_invalid": "Alıcı adresi geçersiz.", "ens_not_found": "Bu isim için hiçbir adres belirlenmemiş.", "unknown_qr_code": "Geçersiz OR kodu. Lütfen tekrar deneyin.", @@ -5205,6 +5256,34 @@ "manage_preferences_2": "Ayarlar > Bildirimler.", "cancel": "İptal", "cta": "Aç" + }, + "push_onboarding": { + "new_user": { + "title": "Hiçbir hamleyi kaçırmayın", + "body": "Fiyatlar hedeflerinize ulaştığında, işlemleriniz onaylandığında ve portföyünüz hareket ettiğinde gerçek zamanlı uyarılar alın. Ayrıca bu süreçte ürün güncellemeleri ve ödüller sunulur. MetaMask ile etkileşimlerinize göre güncellemeler paylaşacağız.", + "button_yes": "Evet", + "button_not_now": "Şimdi değil", + "preview_card_1": { + "eyebrow": "METAMASK", + "time": "şimdi", + "title": "ETH bugün %4,2 yükseldi", + "message": "Şu an $2.668,51 seviyesinde — fiyat uyarınızın üzerinde" + }, + "preview_card_2": { + "eyebrow": "METAMASK", + "time": "1sa önce", + "title": "0.25 ETH alındı", + "message": "Gönderen 0x9a21…4f8c · $640,29" + } + }, + "existing_user": { + "title": "Kişiselleştirilmiş uyarılar tanıtımı", + "body": "İşlem yapma tarzınıza uygun bildirimler alın. Dilediğiniz zaman güncelleyin.", + "card_title": "Alacağınız", + "card_description": "İşlem hareketlerinize özel olarak uyarlanmış kişiselleştirilmiş uyarılar ve güncellemeler.", + "button_confirm": "Onayla", + "button_not_now": "Şimdi değil" + } } }, "protect_your_wallet_modal": { @@ -5315,6 +5394,7 @@ "pay_with": "Ödeme aracı", "buying_via": "{{providerName}} aracılığıyla satın alınıyor.", "change_provider": "Sağlayıcı değiştirin.", + "circuit_breaker_open": "This service is temporarily unavailable. Please try again in about 30 minutes.", "payment_error": "Bir şeyler ters gitti. Lütfen tekrar deneyin.", "no_payment_methods_available": "Kullanılabilir ödeme yöntemi yok.", "error_fetching_quotes": "Bir şeyler ters gitti. Lütfen tekrar deneyin.", @@ -5442,7 +5522,7 @@ "change_provider_button": "Sağlayıcı değiştirin" }, "fiat_on_ramp_aggregator": { - "buy": "al", + "buy": "satın al", "sell": "sat", "orders": "Transferler", "All": "Tümü", @@ -5515,7 +5595,7 @@ "quotes_timeout": "Teklifler için zaman aşımı", "request_new_quotes": "En yeni en iyi oranı almak için lütfen yeni teklif talep edin.", "terms_of_service": "Hizmet Şartları", - "amount_to_buy": "Al", + "amount_to_buy": "Satın Al", "amount_to_sell": "Sat", "want_to_buy": "Şunu almak istiyorsun:", "want_to_sell": "Satmak istediğiniz", @@ -6520,6 +6600,8 @@ "convert_to_musd": "mUSD'ye dönüştür", "get_a_percentage_musd_bonus": "{{percentage}}% mUSD bonus al", "convert": "Dönüştür", + "confirm": "Onayla", + "convert_tooltip_description": "Stabil kripto paralarınızı mUSD'ye dönüştürün ve günlük olarak alabileceğiniz {{percentage}}% oranına varan yıllıklandırılmış bonus kazanın. Relay tarafından desteklenmektedir.", "fetching_quote": "Teklif alınıyor...", "you_convert": "Dönüştürdüğünüz tutar", "network_fee": "Ağ ücreti", @@ -6597,7 +6679,7 @@ "step_progress": "Adım {{current}}/{{total}}", "title": "Para ekle", "description": "Hesabınıza para yatırın ve APY kazanmaya başlayın.", - "add": "Ekle", + "add": "Bakiye ekleyin", "step2_title": "MetaMask Card'ınızı alın", "step2_description": "Para bakiyenizi Mastercard kabul edilen her yerde kazanırken harcamaya devam edin.", "step2_cta": "Kartı al", @@ -6605,6 +6687,19 @@ "link_card_description": "Bakiyenizi Mastercard kabul edilen her yerde kazanırken harcamaya devam edin.", "link_card_cta": "Kartı bağla" }, + "rive_onboarding": { + "step1_title": "Para hesapları burada", + "step1_body": "Tüm cüzdanınızda geçerli olmak üzere, bakiyenizden {{percentage}}% orana varan APY kazanın.", + "step1_footer_text": "APY değişkendir ve her zaman değişiklik gösterebilir.", + "step2_title": "Otomatik kazanın", + "step2_body": "Stabil kripto paraları işlem ücreti ödemeden transfer edin. Fonlarınız anında kazandırmaya başlar.", + "step2_footer_text": "Provided by Veda and Steakhouse Financial.", + "step3_title": "Dilediğiniz yerde harcama yapın", + "step3_body": "Para hesabınızı bir MetaMask karta bağlayarak satın alma işlemlerinde {{percentage}}% orana varan iade kazanın.", + "step4_title": "Tek yerden işlem yapın ve kazanın", + "step4_body": "Bir yandan getiri sağlamaya devam ederken diğer yandan Para hesabı bakiyenizi MetaMask genelinde işlem yapmak için kullanın.", + "continue": "Devam et" + }, "action": { "add": "Ekle", "transfer": "Transfer Et", @@ -6618,8 +6713,8 @@ }, "how_it_works": { "title": "Nasıl çalışır?", - "description_prefix": "Deposit mUSD into your Money account and earn up to", - "description_suffix": ". Your balance is dollar-backed and ready to spend, trade, or send anytime." + "description_prefix": "Para hesabınıza mUSD yatırım ve kazanın:", + "description_suffix": ". Bakiyeniz dolara endekslidir ve her zaman harcamaya, işlem yapmaya veya gönderime hazırdır." }, "musd_row": { "add": "Ekle" @@ -6627,16 +6722,16 @@ "balance_card": { "label": "Para bakiyesi", "add": "Ekle", - "info_sheet_title": "Money balance", - "info_sheet_body": "Your dollar-backed mUSD balance that's always available to spend, send, or trade anytime. We don't calculate this into your total account balance.\n\nWithdrawals process immediately, subject to standard network confirmation times on the relevant blockchain. If liquidity is tight, there may be temporary delays." + "info_sheet_title": "Para bakiyesi", + "info_sheet_body": "Dilediğiniz zaman harcamaya, gönderime veya işlem yapmaya hazır olan dolar endeksli mUSD bakiyeniz. Bunu toplam hesap bakiyenize dahil etmeyiz. \n\nPara çekme işlemleri, ilgili blokzincirindeki standart ağ onay sürelerine bağlı olarak anında işleme alınır. Likiditenin yetersiz olduğu durumlarda geçici gecikmeler yaşanabilir." }, "potential_earnings": { "title": "Kriptonuzdan kazanç sağlayın", "description": "Kriptonuzu mUSD'ye dönüştürerek paranızın zaman içinde nasıl artabileceğini görün.", - "description_with_amounts_prefix": "Convert your {{total}} in assets and you could earn up to", - "description_with_amounts_suffix": "in one year.", + "description_with_amounts_prefix": "{{total}} varlığınızı dönüştürün ve bir yılda", + "description_with_amounts_suffix": "tutara kadar kazanın.", "convert": "Dönüştür", - "convert_cta": "Convert your crypto", + "convert_cta": "Kriptonuzu dönüştürün", "no_fee": "MetaMask ücreti yok", "view_all": "Tümünü görüntüle", "view_potential_earnings": "Potansiyel kazançları görüntüle" @@ -6649,41 +6744,44 @@ "cashback": "{{percentage}}% mUSD iadesi", "get_now": "Hemen alın", "link_title": "MetaMask Card'ı bağla", - "link_subtitle": "Spend your Money balance and earn on purchases. Plus, up to {{apy}}% APY on your balance.", - "link_bullet_cashback": "Get {{percentage}}% mUSD back", - "link_bullet_apy": "Earn up to {{apy}}% APY", + "link_subtitle": "Para bakiyenizi harcayın ve satın alma işlemlerinizde kazanç sağlayın. Üstelik bakiyenizde {{apy}}% orana varan APY.", + "link_subtitle_no_apy": "Spend your Money balance and earn on purchases.", + "link_bullet_cashback": "{{percentage}}% mUSD iadesi alın", + "link_bullet_apy": "{{apy}}% orana varan APY kazanın", "link_card": "Kartı bağla", - "link_pending_title": "Linking card", - "link_pending_description": "Approving spending limit…", - "link_success_title": "Card linked successfully", - "link_success_description": "You can now spend while you earn", - "link_error": "Couldn't link card", - "manage_card": "Manage", - "avail_balance": "Avail. balance" + "link_pending_title": "Linking your card", + "link_success_title": "Your card is ready to use", + "link_error": "Something went wrong linking your card", + "link_card_sheet_title": "Harcayın ve kazanın", + "link_card_sheet_description": "Link your card so you can spend your Money balance and earn mUSD back on purchases—all while earning up to {{apy}}% APY.", + "link_card_sheet_description_no_apy": "Link your card so you can spend your Money balance and earn mUSD back on purchases.", + "link_card_sheet_cta": "Kartı bağla", + "manage_card": "Yönet", + "avail_balance": "Kull. bakiye" }, "what_you_get": { "title": "Alacağınız tutar", - "benefit_auto_earn": "Auto-earn up to", + "benefit_auto_earn": "Otomatik kazanın:", "benefit_dollar_backed": "Paranız 1:1 dolar destekli bir stabil kripto para olan mUSD'de güvende tutun", "benefit_liquidity": "Kilitleme olmadan tam likidite alarak dilediğiniz zaman işlem yapabilir veya para çekebilirsiniz", "benefit_spend_prefix": "MetaMask Card ile 150 milyondana fazla satıcıda harcama yapın ve şunu kazanın ", "benefit_spend_cashback": "%1-3 mUSD iadesi", - "benefit_transfer": "Transfer to any of your wallets across MetaMask", - "benefit_global": "Send and receive funds globally", + "benefit_transfer": "MetaMask genelindeki tüm cüzdanlarınıza transfer gerçekleştirin", + "benefit_global": "Dünya çapında para gönderin ve alın", "learn_more": "Daha fazla bilgi edin" }, "footer": { - "add_money": "Add funds" + "add_money": "Bakiye ekleyin" }, "add_money_sheet": { - "title": "Add funds", + "title": "Bakiye ekleyin", "convert_crypto": "Kripto dönüştür", - "convert_crypto_description": "From any account", + "convert_crypto_description": "Herhangi bir hesaptan", "deposit_funds": "Fon yatır", - "deposit_funds_description": "From debit card or bank", - "move_musd": "Transfer your {{amount}} mUSD", - "move_musd_no_amount": "Transfer your mUSD", - "move_musd_description": "From your balance", + "deposit_funds_description": "Banka kartından veya bankadan", + "move_musd": "{{amount}} mUSD'nizi transfer edin", + "move_musd_no_amount": "mUSD'nizi transfer edin", + "move_musd_description": "Bakiyenizden", "receive_external": "Harici cüzdandan al", "coming_soon": "Çok yakında" }, @@ -6694,7 +6792,7 @@ "contact_support": "Destek ile iletişime geç" }, "transfer_sheet": { - "title": "Transfer funds", + "title": "Fon transfer edin", "between_accounts": "Hesaplar arasında", "perps_account": "Perps hesabı", "predictions_account": "Tahminler hesabı", @@ -6712,8 +6810,8 @@ "body": "Güncel bakiyenize ve bugünkü APY'ye göre bir dönem boyunca ne kadar kazanabileceğinize dair bir tahmin. Tahminler garantili getiriler olmayıp değişikliğe tabidir." }, "earn_crypto_info_sheet": { - "title": "Earn on your crypto", - "body": "Illustration assumes {{percentage}}% Annual Percentage Yield (APY) remains unchanged for one year. APY is variable and may change due to various factors. No guarantee of return." + "title": "Kriptonuzdan kazanç sağlayın", + "body": "Gösterim, {{percentage}}% Yıllık Yüzde Getirinin (APY) bir yıl boyunca değişmeden kaldığı varsayımına dayanmaktadır. APY değişkendir ve çeşitli faktörlere bağlı olarak değişiklik gösterebilir. Getiri garantisi yoktur." }, "activity": { "title": "Aktivite", @@ -6725,7 +6823,7 @@ }, "condensed_cards": { "how_it_works_title": "Nasıl çalışır?", - "how_it_works_subtitle": "Paranızın sizin için nasıl çalıştığını görün", + "how_it_works_subtitle": "See how your money can grow", "musd_title": "MetaMask USD", "musd_subtitle": "mUSD hakkında daha fazla bilgi alın", "what_you_get_title": "Alacağınız tutar", @@ -6738,7 +6836,8 @@ "sent": "Gönderildi", "transferred": "Transfer Edildi", "card_transaction": "Kart işlemi", - "converted": "Dönüştürüldü" + "converted": "Dönüştürüldü", + "failed": "Başarısız oldu" }, "convert_stablecoins": { "title": "Stabil kripto paralarınızı dönüştürün", @@ -6752,16 +6851,16 @@ "convert_cta": "mUSD'ye dönüştür", "learn_more": "Daha fazla bilgi edin", "swap": "Takas", - "buy": "Al" + "buy": "Satın al" }, "how_it_works_page": { "header_title": "Para", "section_title": "Nasıl çalışır?", - "description_1": "Deposit mUSD into your Money account and earn up to {{percentage}}% APY (variable) automatically. Funds go into a DeFi vault that generates returns across audited lending markets—no staking, no claiming, no lock-ups.", + "description_1": "Para hesabınıza mUSD yatırın ve otomatik olarak {{percentage}}% orana varan APY (değişken) kazanın. Fonlar, denetlenmiş borç verme piyasalarında getiri sağlayan bir DeFi kasasına aktarılır; stake etme, talep etme veya kilitleme yoktur.", "description_2": "Para bakiyeniz, bakiyenizi harcıyor. MetaMask Card'ınızı bağlayarak dünya çapında 150 milyondan fazla satıcıda harcama yapabilirsiniz. Kullandığınız ana kadar para kazanmaya devam eder.", - "faq_title": "Frequently asked questions", + "faq_title": "Sıkça sorulan sorular", "faq_placeholder_answer": "Çok yakında.", - "faq_q1": "How does the {{percentage}}% APY work?", + "faq_q1": "{{percentage}}% APY nasıl çalışır?", "faq_q2": "mUSD nedir?", "faq_q3": "Getiri nereden gelir?", "faq_q4": "Param kilitli mi? Dilediğim zaman çekebilir miyim?", @@ -7030,11 +7129,12 @@ "confirm": "Onayla", "pay_with_bottom_sheet": { "title": "Ödeme aracı", - "last_used": "Last used", - "crypto": "Crypto", - "available_balance": "{{balance}} available", - "other_assets": "Other assets", - "other_assets_description": "Select from your tokens" + "last_used": "Son kullanılma", + "bank_and_card": "Banka ve kart", + "crypto": "Kripto", + "available_balance": "{{balance}} kullanılabilir", + "other_assets": "Diğer varlıklar", + "other_assets_description": "Tokenlarınızın arasından seçiminizi yapın" }, "staking_footer": { "part1": "Devam ederek şu bölümlerimizi kabul edersiniz: ", @@ -7120,7 +7220,7 @@ "transaction_fee": "mUSD dönüştürme işlemine ağ maliyetleri dahildir ve sağlayıcı ücretleri dahil olabilir. mUSD dönüştürürken MetaMask ücreti uygulanmaz." }, "money_account_withdraw": { - "transaction_fee": "MetaMask will swap your mUSD for your desired token. Swap providers may charge a fee, but MetaMask won't." + "transaction_fee": "MetaMask, istediğiniz token ile mUSD takası gerçekleştirecek. Takas sağlayıcıları ücret alabilir ancak MetaMask almaz." }, "title": { "transaction_fee": "Ücretler" @@ -7225,7 +7325,7 @@ "deposit_edit_amount_done": "Fon ekle", "deposit_edit_amount_predict_withdraw": "Çek", "deposit_edit_amount_musd_conversion": "mUSD'ye dönüştür", - "preparing_order": "Preparing order" + "preparing_order": "Emir hazırlanıyor" }, "change_in_simulation_modal": { "title": "Sonuçlar değişti", @@ -7250,20 +7350,33 @@ "confirm_swap": "Swap Yap", "terms_and_conditions": "Şart ve Koşullar", "select_token": "Token seç", - "batch_sell_select_title": "Select up to 5 tokens", - "batch_sell_select_subtitle": "All tokens need to be on the same network.", - "batch_sell_empty_state_title": "No tokens. No problem.", - "batch_sell_empty_state_description": "No tokens. No problem. Explore and buy tokens to batch sell.", - "batch_sell_continue_with_one_token": "Continue with (1) token", - "batch_sell_continue_with_tokens": "Continue with ({{tokenCount}}) tokens", - "batch_sell_max_tokens_allowed": "Max 5 tokens allowed", - "batch_sell_single_token_dialog_title": "High rate alert", - "batch_sell_single_token_dialog_description": "Batch selling one token could lead to a higher rate. Want to do a swap instead?", - "batch_sell_swap_instead": "Yes, swap", - "batch_sell_checkbox_label": "Batch Sell token", - "sort_balance": "Balance", - "next": "Next", - "explore_tokens": "Explore tokens", + "batch_sell_select_title": "En fazla 5 token seçin", + "batch_sell_select_subtitle": "Tüm tokenların aynı ağda olması gerekir.", + "batch_sell_empty_state_title": "Token yok. Sorun değil.", + "batch_sell_empty_state_description": "Token yok. Sorun değil. Toplu satış için tokenları keşfedin ve satın alın.", + "batch_sell_continue_with_one_token": "(1) token ile devam et", + "batch_sell_continue_with_tokens": "({{tokenCount}}) token ile devam et", + "batch_sell_max_tokens_allowed": "En fazla 5 tokena izin verilir", + "batch_sell_single_token_dialog_title": "Yüksek oran uyarısı", + "batch_sell_single_token_dialog_description": "Tek bir tokenın toplu satışı daha yüksek bir orana neden olabilir. Onun yerine takas işlemi gerçekleştirmek ister misiniz?", + "batch_sell_swap_instead": "Evet, takas et", + "batch_sell_review_title": "Toplu Satışı İncele", + "batch_sell_select_stablecoin": "Bir stabil kripto para seçin", + "batch_sell_total_received": "Toplam alınan", + "batch_sell_minimum_received": "Minimum received", + "batch_sell_quote_details_row": "{{tokenSymbol}} • {{slippage}} slippage", + "batch_sell_review": "İncele", + "batch_sell_you_sell": "You sell", + "batch_sell_token_count": "{{tokenCount}} tokens", + "batch_sell_toggle_you_sell": "Toggle token details", + "batch_sell_sell_all": "Sell all", + "batch_sell_includes_metamask_fee": "Includes {{fee}}% MetaMask fee", + "batch_sell_customize_token": "Özelleştir: {{tokenSymbol}}", + "batch_sell_remove_token": "{{tokenSymbol}} adlı snap'i kaldır", + "batch_sell_checkbox_label": "Toplu Token Satışı", + "sort_balance": "Bakiye", + "next": "Sonraki", + "explore_tokens": "Tokenları keşfedin", "no_tokens_found": "Token bulunamadı", "no_tokens_found_description": "Bu isimde token bulamadık. Farklı bir arama yapmayı deneyin.", "select_network": "Ağ seç", @@ -7332,6 +7445,7 @@ "price_impact_execution_description": "Bu takas işleminde tokenınızın değerinden yaklaşık {{priceImpact}} kaybedeceksiniz. Miktarı düşürmeyi veya daha likit bir rota seçmeyi deneyin.", "proceed": "Devam et", "cancel": "İptal", + "close": "Kapat", "slippage_info_title": "Kayma", "slippage_info_description": "İşleminiz iptal edilmeden önce izin vermek istediğiniz fiyat değişim % oranı.", "blockaid_error_title": "Bu işlem geri alınacak", @@ -8107,7 +8221,14 @@ "retry": "Tekrar dene", "on_linea": "Linea üzerinde", "account_label": "Hesap", - "token_label": "tokenlar" + "token_label": "tokenlar", + "money_account_label": "Money account", + "money_account_token_symbol": "mUSD", + "use_money_account_cta": "Use Money account", + "spend_and_earn_title": "Spend while you earn", + "spend_and_earn_description": "Spend with your Money account and earn up to {{apy}}% APY on your balance. Also get {{cashback}}% mUSD back.", + "spend_and_earn_description_no_apy": "Spend with your Money account and earn APY on your balance. Also get {{cashback}}% mUSD back.", + "spend_and_earn_cta": "Link to Money account" }, "cashback_screen": { "title": "mUSD İadesi", @@ -8449,6 +8570,7 @@ "show_less": "Daha az göster", "linking_progress": "Hesaplar ekleniyor... ({{current}}/{{total}})", "accounts_linked_count": "{{linked}}/{{total}} kayıtlı", + "accounts_added": "Accounts added", "add_all_accounts": "Tüm hesapları ekle", "environment_selector": "Ortam", "environment_cancel": "İptal", @@ -8473,15 +8595,22 @@ }, "optout": { "title": "Ödüller Programını Sil", - "description": "Bu işlem, hesaplarınızı Ödüller programından kaldırır ve ilerlemenizi siler. Bu işlemi geri alamazsınız.", - "confirm": "Sil", + "description": "This will remove your accounts from the Rewards program and your progress in any campaigns you've joined. Only do this if you are absolutely sure you want to erase your progress.", + "erase_button": "Erase progress", "modal": { "confirmation_title": "Emin misiniz?", - "confirmation_description": "Bu işlem tüm ilerlemenizi kaldırır ve geri alınamaz. Ödüller programına daha sonra tekrar katılırsanız 0'dan başlayacaksınız.", + "confirmation_description": "This will erase all your progress, and can't be reversed. If you rejoin the Rewards program later, you'll start back at 0.", + "type_to_confirm": "Type 'erase progress' to continue", + "confirm_phrase": "erase progress", "cancel": "İptal", "confirm": "Onayla", + "error_title": "Bir şeyler ters gitti", "error_message": "Ödüllerden ayrılma başarısız oldu. Lütfen tekrar deneyin.", "processing": "Gerçekleştiriliyor..." + }, + "request_received": { + "title": "Request received", + "description": "In about 7 days, your progress will be fully erased. If you made this request by mistake, please contact support through the app." } }, "toast_dismiss": "Yok say", @@ -8569,7 +8698,8 @@ "title_claim": "Faydayı Al", "action": "Al", "empty-list": "Şu anda faydanız yok.", - "powered_by": "Destekleyen" + "powered_by": "Destekleyen", + "available_count": "{{count}} kullanılabilir" }, "end_of_season_rewards": { "confirm_label_default": "Onayla", @@ -8887,9 +9017,11 @@ "musd_claim": "mUSD al", "perps_deposit": "Fon ekle", "perps_withdraw": "Çekme işlemi", + "predict_withdraw": "{{sourceChain}} üzerinden {{sourceSymbol}} çekin", "predict_deposit": "Fon ekle", "swap": "Token swap işlemi yapın", - "swap_approval": "Token'leri onayla" + "swap_approval": "Token'leri onayla", + "fiat_purchase": "{{paymentMethod}} ile {{token}} satın alın" }, "perps_deposit_solution": "Şu anda Arbitrum üzerinde {{fiat}} USDC'niz var. Yatırma işleminizi tekrar deneyin." }, @@ -8965,7 +9097,7 @@ "high_to_low": "Yüksekten düşüğe", "low_to_high": "Düşükten yükseğe", "apply": "Uygula", - "search_placeholder": "Token, site, URL ara", + "search_placeholder": "Search tokens, markets and URLs", "cancel": "İptal", "perps": "Sürekli Vadeli", "rwa_perps_section": "Sürekli Vadeli", @@ -8978,11 +9110,15 @@ "crypto_perps_section": "Sürekli Vadeli", "predictions": "Tahminler", "no_results": "Sonuç bulunamadı", + "no_results_for_feed": "No {{feedName}} results for \"{{query}}\"", + "showing_all_results_for": "We found these results for \"{{query}}\"", "popular": "Popüler", "sites": "Siteler", "popular_sites": "Popüler siteler", "search_sites": "Siteleri ara", "view_all": "Tümünü görüntüle", + "view_more": "Daha fazlasını görüntüle", + "view_x_more": "View {{count}} more", "enable_basic_functionality": "Temel işlevselliği etkinleştir", "basic_functionality_disabled_title": "Keşfet özelliği kullanılamıyor", "basic_functionality_disabled_description": "Temel işlevsellik devre dışıyken gerekli meta verileri getiremiyoruz.", @@ -9002,6 +9138,14 @@ "crypto": "Kripto", "sports": "Spor", "dapps": "Siteler" + }, + "search_tabs": { + "all": "Tümü", + "crypto": "Cryptos", + "perps": "Sürekli Vadeli", + "stocks": "Hisse Senetleri", + "predictions": "Tahminler", + "sites": "Siteler" } }, "ota_update_modal": { @@ -9139,6 +9283,7 @@ "money_empty_description_network_filter": "Bu ağda mUSD yok. mUSD'nizi görmek için ağ değiştirin.", "money_empty_state": { "get_started": "Başlarken", + "earn": "Kazan", "earn_apy": "{{percentage}}% APY kazan" }, "money_filled_state": { @@ -9150,22 +9295,7 @@ "related_assets": "İlgili Varlıklar", "perpetuals": "Sürekli Vadeli İşlemler", "predictions": "Tahminler", - "whats_happening": "Neler oluyor", - "whats_happening_ai": "Yapay Zeka", - "whats_happening_impact": { - "bullish": "Boğa", - "bearish": "Ayı", - "neutral": "Nötr" - }, "top_traders": "En İyi Yatırımcılar", - "whats_happening_categories": { - "geopolitical": "Jeopolitik", - "macro": "Makro", - "regulatory": "Mevzuat", - "technical": "Teknik", - "social": "Sosyal", - "other": "Diğer" - }, "defi": "DeFi", "nfts": "NFT'ler", "trending_tokens": "Trend", @@ -9185,5 +9315,22 @@ }, "sites": { "popular": "Popüler" + }, + "whats_happening": { + "title": "Neler oluyor", + "ai": "Yapay Zeka", + "impact": { + "bullish": "Boğa", + "bearish": "Ayı", + "neutral": "Nötr" + }, + "categories": { + "geopolitical": "Jeopolitik", + "macro": "Makro", + "regulatory": "Mevzuat", + "technical": "Teknik", + "social": "Sosyal", + "other": "Diğer" + } } } diff --git a/locales/languages/vi.json b/locales/languages/vi.json index 72ff0e5e244..5cbf553de61 100644 --- a/locales/languages/vi.json +++ b/locales/languages/vi.json @@ -120,6 +120,10 @@ "account_no_funds": { "message": "Không có tiền khả dụng. Hãy sử dụng tài khoản khác." }, + "headless_buy_error": { + "title": "Mua bằng tiền pháp định không thành công", + "message": "Đã xảy ra lỗi với giao dịch mua bằng tiền pháp định của bạn. Vui lòng thử lại." + }, "mmpay_hardware_account": { "title": "Ví không được hỗ trợ", "message": "Ví cứng hiện chưa được hỗ trợ.\nĐổi ví để tiếp tục." @@ -133,8 +137,8 @@ "message": "Địa chỉ người nhận có thể không hỗ trợ chuyển khoản token trực tiếp, điều này có thể dẫn đến mất tiền. Chỉ tiếp tục nếu bạn chắc chắn hợp đồng này có thể nhận khoản chuyển của bạn." }, "gas_sponsorship_reserve_balance": { - "message": "Tài trợ phí gas không khả dụng cho giao dịch này. Bạn cần giữ ít nhất %{minBalance} %{nativeTokenSymbol} trong tài khoản của mình.", - "title": "Tài trợ phí gas không khả dụng" + "message": "Mạng cụ thể này yêu cầu duy trì số dư dự trữ tối thiểu là %{minBalance} %{nativeTokenSymbol} trong tài khoản của bạn.", + "title": "Yêu cầu số dư dự trữ" }, "token_trust_signal": { "malicious": { @@ -708,6 +712,9 @@ "contractAddressError": "Bạn đang gửi token đến địa chỉ hợp đồng của token. Điều này có thể dẫn đến việc mất token đó.", "smart_contract_address": "Địa chỉ hợp đồng thông minh", "smart_contract_address_warning": "Địa chỉ người nhận có thể không hỗ trợ chuyển khoản token trực tiếp, điều này có thể dẫn đến mất tiền. Chỉ tiếp tục nếu bạn chắc chắn hợp đồng này có thể nhận khoản chuyển của bạn.", + "unavailable_network_connection": "Unavailable network connection", + "unavailable_network_connection_description": "The connection with {{network}} is unreliable. Update network connectivity details before continuing or try again later.", + "update": "Cập nhật", "i_understand": "Tôi hiểu", "cancel": "Hủy", "new_address_title": "Địa chỉ mới", @@ -1068,7 +1075,7 @@ "sort": { "value": "Giá trị", "pnl_percent": "Lãi/Lỗ %", - "recent": "Recent" + "recent": "Gần đây" } }, "trader_position": { @@ -1120,6 +1127,11 @@ "title": "Giao dịch hợp đồng vĩnh cửu {{symbol}}", "subtitle": "Nhân Lãi/Lỗ của bạn lên đến {{leverage}} lần" }, + "service_interruption": { + "title": "We're experiencing an outage", + "description": "Some services may be unavailable while the team works on a fix.", + "contact_support": "Liên hệ bộ phận hỗ trợ" + }, "today": "Hôm nay", "yesterday": "Hôm qua", "unrealized_pnl": "Lãi/Lỗ chưa thực hiện", @@ -1284,7 +1296,9 @@ "toast_completed_subtitle": "{{amount}} USDC đã được chuyển vào ví của bạn", "toast_completed_any_token_subtitle": "{{amount}} {{token}} đã được chuyển vào ví của bạn", "toast_error_title": "Đã xảy ra sự cố", - "toast_error_description": "Không thể tiến hành rút tiền" + "toast_error_description": "Không thể tiến hành rút tiền", + "toast_start_error_description": "Your withdrawal wasn’t started.", + "try_again": "Thử lại" }, "quote": { "network_fee": "Phí mạng", @@ -2227,35 +2241,35 @@ "predict": { "title": "MetaMask Dự đoán", "world_cup": { - "title": "World Cup", - "banner_title": "World Cup 2026", - "banner_description": "Trade on World Cup markets", + "title": "Giải vô địch bóng đá thế giới", + "banner_title": "Giải vô địch bóng đá thế giới 2026", + "banner_description": "Trade every match, every moment.", "tabs": { - "all": "All", - "props": "Props", - "live": "Live" + "all": "Tất cả", + "props": "Kèo phụ", + "live": "Đang diễn ra" }, "stages": { - "group_stage": "Group Stage", - "round_of_32": "Round of 32", - "round_of_16": "Round of 16", - "quarterfinals": "Quarterfinals", - "semifinals": "Semifinals", - "third_place": "Third Place", - "final": "Final", - "group_a": "Group A", - "group_b": "Group B", - "group_c": "Group C", - "group_d": "Group D", - "group_e": "Group E", - "group_f": "Group F", - "group_g": "Group G", - "group_h": "Group H", - "group_i": "Group I", - "group_j": "Group J", - "group_k": "Group K", - "group_l": "Group L", - "third_place_match": "Third Place Match" + "group_stage": "Vòng bảng", + "round_of_32": "Vòng 32 đội", + "round_of_16": "Vòng 16 đội", + "quarterfinals": "Tứ kết", + "semifinals": "Bán kết", + "third_place": "Tranh hạng ba", + "final": "Chung cuộc", + "group_a": "Bảng A", + "group_b": "Bảng B", + "group_c": "Bảng C", + "group_d": "Bảng D", + "group_e": "Bảng E", + "group_f": "Bảng F", + "group_g": "Bảng G", + "group_h": "Bảng H", + "group_i": "Bảng I", + "group_j": "Bảng J", + "group_k": "Bảng K", + "group_l": "Bảng L", + "third_place_match": "Trận tranh hạng ba" } }, "prediction_markets": "Thị trường dự đoán", @@ -2537,8 +2551,8 @@ "withdraw_completed": "Rút tiền hoàn tất", "withdraw_completed_subtitle": "{{amount}} USDC đã được chuyển vào ví của bạn", "withdraw_any_token_completed_subtitle": "{{amount}} {{token}} đã được chuyển vào ví của bạn", - "unavailable_title": "Withdrawals temporarily unavailable", - "unavailable_description": "For urgent assistance, please contact Customer Service.", + "unavailable_title": "Tính năng rút tiền tạm thời không khả dụng", + "unavailable_description": "Để được hỗ trợ khẩn cấp, vui lòng liên hệ Bộ phận Chăm sóc Khách hàng.", "unavailable_got_it": "Tôi đã hiểu", "error_title": "Đã xảy ra sự cố", "error_description": "Không thể thực hiện yêu cầu rút tiền", @@ -2941,6 +2955,17 @@ "pna25_confirm_button": "Chấp nhận và đóng", "pna25_open_settings_button": "Mở Cài đặt" }, + "onboarding_interest_questionnaire": { + "title": "Bạn muốn làm gì với MetaMask?", + "description": "Chọn tất cả các mục phù hợp.", + "option_buy_and_sell_crypto": "Mua và bán tiền mã hóa", + "option_consolidate_wallets": "Hợp nhất ví của bạn", + "option_advanced_trades": "Thực hiện giao dịch nâng cao", + "option_predict_sports_events": "Dự đoán thể thao và sự kiện", + "option_crypto_as_money": "Sử dụng tiền mã hóa như tiền tệ", + "option_connect_apps_sites": "Kết nối với ứng dụng hoặc trang web", + "continue": "Tiếp tục" + }, "template_confirmation": { "ok": "OK", "cancel": "Hủy" @@ -3261,8 +3286,27 @@ "notifications_desc": "Quản lý thông báo", "allow_notifications": "Cho phép thông báo", "enable_push_notifications": "Bật thông báo đẩy", - "allow_notifications_desc": "Nhận thông báo để cập nhật tình hình trong ví của bạn. Để sử dụng tính năng thông báo, chúng tôi sử dụng hồ sơ để đồng bộ một số chế độ cài đặt trên các thiết bị của bạn.", + "allow_notifications_desc": "Choose what you're notified about and how.", "notifications_opts": { + "preferences_title": "Preferences", + "push_recommended": "Push", + "in_app": "In-app", + "status_push": "Push", + "status_in_app": "In app", + "status_off": "Tắt", + "select_all": "Chọn tất cả", + "deselect_all": "Bỏ chọn tất cả", + "select_accounts_title": "Tài khoản", + "select_accounts_desc": "Choose which accounts you'd like to get notifications for.", + "wallet_activity_title": "Wallet Activity", + "wallet_activity_desc": "Buy, sells, transfers, swaps and rewards", + "perps_title": "Trading Activity", + "perps_desc": "Perps position changes, liquidations, funding rates, and margin updates", + "social_ai_title": "Trading Signals", + "social_ai_desc": "Updates from traders and assets you follow, plus currated market news", + "marketing_title": "Updates and Rewards", + "marketing_desc": "Product updates, feature announcements, and new releases", + "marketing_disclaimer": "By turning this on, you agree to receive product news and marketing updates from MetaMask.", "customize_session_title": "Tùy chỉnh thông báo", "customize_session_desc": "Bật các loại thông báo mà bạn muốn nhận:", "account_session_title": "Hoạt động của tài khoản", @@ -3276,8 +3320,7 @@ "snaps_title": "Snap", "snaps_desc": "Tính năng và cập nhật mới", "products_announcements_title": "Thông báo sản phẩm", - "products_announcements_desc": "Sản phẩm và tính năng mới", - "perps_title": "Giao dịch hợp đồng vĩnh cửu" + "products_announcements_desc": "Sản phẩm và tính năng mới" }, "contacts_title": "Danh bạ", "contacts_desc": "Thêm, sửa, xóa và quản lý các tài khoản của bạn.", @@ -3640,7 +3683,15 @@ "card": { "title": "Thẻ", "reset_onboarding_description": "Đặt lại trạng thái thiết lập Thẻ để bắt đầu lại quy trình thiết lập từ đầu.", - "reset_onboarding_button": "Đặt lại trạng thái thiết lập" + "reset_onboarding_button": "Đặt lại trạng thái thiết lập", + "unlink_money_account_description": "Thu hồi quyền cấp hạn mức chi tiêu USDC cho phép Thẻ sử dụng tiền từ Tài khoản Tài chính của bạn. Thao tác này sẽ gửi một giao dịch phê duyệt (0) và đánh dấu Tài khoản Tài chính là chưa được ủy quyền trên hệ thống phụ trợ của Thẻ.", + "unlink_money_account_button": "Hủy liên kết Tài khoản Tài chính khỏi Thẻ", + "unlink_money_account_disabled_hint": "Không có liên kết đang hoạt động để xóa." + }, + "identity": { + "title": "Identity", + "description": "Clears the persisted authentication session. Use this after toggling MM_DEV_API_ENV — otherwise a prod-minted JWT keeps being handed to dev-API consumers until it expires. Current MM_DEV_API_ENV: {{env}}.", + "clear_auth_session_button": "Clear persisted auth session" }, "haptics": { "title": "Phản hồi rung", @@ -3842,8 +3893,8 @@ "predict_button": "Dự đoán", "add_collectible_button": "Thêm", "info": "Thông tin", - "batch_sell": "Batch Sell", - "batch_sell_new_label": "New", + "batch_sell": "Bán hàng loạt", + "batch_sell_new_label": "Mới", "swap": "Hoán đổi", "convert": "Chuyển đổi", "bridge": "Cầu nối", @@ -3883,7 +3934,7 @@ "troubleshoot": "Khắc phục sự cố", "deposit_description": "Chuyển khoản ngân hàng hoặc thẻ với phí thấp", "buy_description": "Phù hợp để mua một token cụ thể", - "batch_sell_description": "Sell up to 5 tokens for a stablecoin", + "batch_sell_description": "Bán tối đa 5 token để đổi lấy một đồng ổn định", "sell_description": "Bán tiền mã hóa lấy tiền mặt", "swap_description": "Chuyển đổi giữa các token", "bridge_description": "Chuyển token giữa các mạng", @@ -5205,6 +5256,34 @@ "manage_preferences_2": "Cài đặt > Thông báo.", "cancel": "Hủy", "cta": "Bật" + }, + "push_onboarding": { + "new_user": { + "title": "Đừng bỏ lỡ bất kỳ biến động nào", + "body": "Nhận cảnh báo theo thời gian thực khi giá đạt mục tiêu, giao dịch được xác nhận và danh mục đầu tư của bạn có biến động. Ngoài ra còn có cập nhật sản phẩm và phần thưởng trong suốt quá trình sử dụng. Chúng tôi sẽ chia sẻ các cập nhật dựa trên tương tác của bạn với MetaMask.", + "button_yes": "Có", + "button_not_now": "Không phải bây giờ", + "preview_card_1": { + "eyebrow": "METAMASK", + "time": "ngay bây giờ", + "title": "Hôm nay ETH tăng 4,2%", + "message": "Hiện ở mức $2.668,51 — cao hơn mức cảnh báo giá của bạn" + }, + "preview_card_2": { + "eyebrow": "METAMASK", + "time": "1 giờ trước", + "title": "Đã nhận 0,25 ETH", + "message": "Từ 0x9a21…4f8c · $640,29" + } + }, + "existing_user": { + "title": "Giới thiệu về cảnh báo được cá nhân hóa", + "body": "Nhận thông báo phù hợp với cách bạn giao dịch. Có thể cập nhật bất cứ lúc nào.", + "card_title": "Bạn sẽ nhận được gì", + "card_description": "Cảnh báo và cập nhật được cá nhân hóa dựa trên hoạt động giao dịch của bạn.", + "button_confirm": "Xác nhận", + "button_not_now": "Không phải bây giờ" + } } }, "protect_your_wallet_modal": { @@ -5315,6 +5394,7 @@ "pay_with": "Thanh toán bằng", "buying_via": "Mua qua {{providerName}}.", "change_provider": "Thay đổi nhà cung cấp.", + "circuit_breaker_open": "This service is temporarily unavailable. Please try again in about 30 minutes.", "payment_error": "Đã xảy ra lỗi. Vui lòng thử lại.", "no_payment_methods_available": "Không có phương thức thanh toán khả dụng.", "error_fetching_quotes": "Đã xảy ra lỗi. Vui lòng thử lại.", @@ -6520,6 +6600,8 @@ "convert_to_musd": "Chuyển đổi sang mUSD", "get_a_percentage_musd_bonus": "Nhận thưởng {{percentage}}% mUSD", "convert": "Chuyển đổi", + "confirm": "Xác nhận", + "convert_tooltip_description": "Chuyển đổi đồng ổn định của bạn sang mUSD và nhận thưởng quy đổi theo năm lên đến {{percentage}}% mà bạn có thể nhận hằng ngày. Được hỗ trợ bởi Relay.", "fetching_quote": "Tìm nạp báo giá...", "you_convert": "Bạn chuyển đổi", "network_fee": "Phí mạng", @@ -6597,7 +6679,7 @@ "step_progress": "Bước {{current}}/{{total}}", "title": "Nạp tiền", "description": "Nạp tiền vào tài khoản của bạn và bắt đầu nhận APY.", - "add": "Thêm", + "add": "Nạp tiền", "step2_title": "Nhận Thẻ MetaMask của bạn", "step2_description": "Chi tiêu số dư Tài chính của bạn trong khi vẫn sinh lời, ở bất kỳ đâu chấp nhận Mastercard.", "step2_cta": "Nhận thẻ", @@ -6605,6 +6687,19 @@ "link_card_description": "Chi tiêu số dư của bạn trong khi vẫn sinh lời, ở bất kỳ đâu chấp nhận Mastercard.", "link_card_cta": "Liên kết thẻ" }, + "rive_onboarding": { + "step1_title": "Tài khoản Tài chính đã ra mắt", + "step1_body": "Sinh lời lên đến {{percentage}}% APY trên số dư của bạn, áp dụng cho toàn bộ ví của bạn.", + "step1_footer_text": "APY sẽ biến động và có thể thay đổi bất cứ lúc nào.", + "step2_title": "Tự động sinh lời", + "step2_body": "Chuyển đồng ổn định mà không mất phí chuyển đổi. Tài sản bắt đầu sinh lời ngay lập tức.", + "step2_footer_text": "Provided by Veda and Steakhouse Financial.", + "step3_title": "Chi tiêu ở bất kỳ đâu", + "step3_body": "Nhận hoàn tiền lên đến {{percentage}}% cho các giao dịch mua sắm khi liên kết Tài khoản Tài chính với thẻ MetaMask của bạn.", + "step4_title": "Giao dịch và sinh lời trong cùng một nơi", + "step4_body": "Sử dụng số dư tài khoản Tài chính của bạn để giao dịch trên MetaMask trong khi vẫn tiếp tục nhận lợi nhuận.", + "continue": "Tiếp tục" + }, "action": { "add": "Thêm", "transfer": "Chuyển", @@ -6618,8 +6713,8 @@ }, "how_it_works": { "title": "Cách hoạt động", - "description_prefix": "Deposit mUSD into your Money account and earn up to", - "description_suffix": ". Your balance is dollar-backed and ready to spend, trade, or send anytime." + "description_prefix": "Gửi mUSD vào tài khoản Tài chính của bạn và nhận lên đến", + "description_suffix": ". Số dư của bạn được bảo chứng theo USD, sẵn sàng để chi tiêu, giao dịch hoặc gửi bất cứ lúc nào." }, "musd_row": { "add": "Thêm" @@ -6627,16 +6722,16 @@ "balance_card": { "label": "Số dư Tài chính", "add": "Thêm", - "info_sheet_title": "Money balance", - "info_sheet_body": "Your dollar-backed mUSD balance that's always available to spend, send, or trade anytime. We don't calculate this into your total account balance.\n\nWithdrawals process immediately, subject to standard network confirmation times on the relevant blockchain. If liquidity is tight, there may be temporary delays." + "info_sheet_title": "Số dư Tài chính", + "info_sheet_body": "Số dư mUSD của bạn được bảo chứng theo USD, luôn sẵn sàng để chi tiêu, gửi hoặc giao dịch bất kỳ lúc nào. Chúng tôi không tính khoản này vào tổng số dư tài khoản của bạn.\n\nQuá trình rút tiền được xử lý ngay lập tức, tùy thuộc vào thời gian xác nhận mạng tiêu chuẩn trên chuỗi khối liên quan. Nếu thanh khoản bị hạn chế, có thể xảy ra chậm trễ tạm thời." }, "potential_earnings": { "title": "Kiếm lợi nhuận từ tiền mã hóa của bạn", "description": "Xem tiền của bạn có thể tăng trưởng theo thời gian như thế nào bằng cách chuyển đổi tiền mã hóa sang mUSD.", - "description_with_amounts_prefix": "Convert your {{total}} in assets and you could earn up to", - "description_with_amounts_suffix": "in one year.", + "description_with_amounts_prefix": "Chuyển đổi {{total}} tài sản của bạn và bạn có thể nhận được lên đến", + "description_with_amounts_suffix": "trong một năm.", "convert": "Chuyển đổi", - "convert_cta": "Convert your crypto", + "convert_cta": "Chuyển đổi tiền mã hóa của bạn", "no_fee": "Không có phí MetaMask", "view_all": "Xem tất cả", "view_potential_earnings": "Xem thu nhập tiềm năng" @@ -6649,41 +6744,44 @@ "cashback": "Hoàn tiền {{percentage}}% bằng mUSD", "get_now": "Nhận ngay", "link_title": "Liên kết Thẻ MetaMask", - "link_subtitle": "Spend your Money balance and earn on purchases. Plus, up to {{apy}}% APY on your balance.", - "link_bullet_cashback": "Get {{percentage}}% mUSD back", - "link_bullet_apy": "Earn up to {{apy}}% APY", + "link_subtitle": "Chi tiêu số dư tài khoản Tài chính của bạn và nhận thưởng khi mua sắm. Ngoài ra, còn có thể sinh lời lên đến {{apy}}% APY trên số dư của bạn.", + "link_subtitle_no_apy": "Spend your Money balance and earn on purchases.", + "link_bullet_cashback": "Nhận hoàn tiền {{percentage}}% bằng mUSD", + "link_bullet_apy": "Sinh lời lên đến {{apy}}% APY", "link_card": "Liên kết thẻ", - "link_pending_title": "Linking card", - "link_pending_description": "Approving spending limit…", - "link_success_title": "Card linked successfully", - "link_success_description": "You can now spend while you earn", - "link_error": "Couldn't link card", - "manage_card": "Manage", - "avail_balance": "Avail. balance" + "link_pending_title": "Linking your card", + "link_success_title": "Your card is ready to use", + "link_error": "Something went wrong linking your card", + "link_card_sheet_title": "Chi tiêu và sinh lời", + "link_card_sheet_description": "Link your card so you can spend your Money balance and earn mUSD back on purchases—all while earning up to {{apy}}% APY.", + "link_card_sheet_description_no_apy": "Link your card so you can spend your Money balance and earn mUSD back on purchases.", + "link_card_sheet_cta": "Liên kết thẻ", + "manage_card": "Quản lý", + "avail_balance": "Số dư khả dụng" }, "what_you_get": { "title": "Những gì bạn nhận được", - "benefit_auto_earn": "Auto-earn up to", + "benefit_auto_earn": "Tự động sinh lời lên đến", "benefit_dollar_backed": "Giữ tiền của bạn an toàn dưới dạng mUSD, một đồng ổn định được bảo chứng 1:1 theo USD", "benefit_liquidity": "Có khả năng thanh khoản cao, không bị khóa vốn, cho phép giao dịch hoặc rút tiền bất cứ lúc nào", "benefit_spend_prefix": "Chi tiêu tại hơn 150 triệu điểm chấp nhận với Thẻ MetaMask và được ", "benefit_spend_cashback": "Hoàn tiền 1-3% bằng mUSD", - "benefit_transfer": "Transfer to any of your wallets across MetaMask", - "benefit_global": "Send and receive funds globally", + "benefit_transfer": "Chuyển khoản đến bất kỳ ví nào của bạn trên MetaMask", + "benefit_global": "Gửi và nhận tiền trên toàn cầu", "learn_more": "Tìm hiểu thêm" }, "footer": { - "add_money": "Add funds" + "add_money": "Nạp tiền" }, "add_money_sheet": { - "title": "Add funds", + "title": "Nạp tiền", "convert_crypto": "Chuyển đổi tiền mã hóa", - "convert_crypto_description": "From any account", + "convert_crypto_description": "Từ bất kỳ tài khoản nào", "deposit_funds": "Nạp tiền", - "deposit_funds_description": "From debit card or bank", - "move_musd": "Transfer your {{amount}} mUSD", - "move_musd_no_amount": "Transfer your mUSD", - "move_musd_description": "From your balance", + "deposit_funds_description": "Từ thẻ ghi nợ hoặc tài khoản ngân hàng", + "move_musd": "Chuyển khoản {{amount}} mUSD của bạn", + "move_musd_no_amount": "Chuyển khoản mUSD của bạn", + "move_musd_description": "Từ số dư của bạn", "receive_external": "Nhận từ ví bên ngoài", "coming_soon": "Sắp ra mắt" }, @@ -6694,7 +6792,7 @@ "contact_support": "Liên hệ bộ phận hỗ trợ" }, "transfer_sheet": { - "title": "Transfer funds", + "title": "Chuyển tiền", "between_accounts": "Giữa các tài khoản", "perps_account": "Tài khoản hợp đồng vĩnh cửu", "predictions_account": "Tài khoản dự đoán", @@ -6712,8 +6810,8 @@ "body": "Ước tính số tiền bạn có thể kiếm được trong một khoảng thời gian dựa trên số dư hiện tại và APY hôm nay của bạn. Các khoản ước tính không phải là lợi nhuận được đảm bảo và vẫn có thể thay đổi." }, "earn_crypto_info_sheet": { - "title": "Earn on your crypto", - "body": "Illustration assumes {{percentage}}% Annual Percentage Yield (APY) remains unchanged for one year. APY is variable and may change due to various factors. No guarantee of return." + "title": "Kiếm lợi nhuận từ tiền mã hóa của bạn", + "body": "Hình minh họa giả định rằng Lợi suất phần trăm hằng năm (APY) {{percentage}}% không thay đổi trong vòng một năm. APY sẽ biến động và có thể thay đổi do nhiều yếu tố khác nhau. Không đảm bảo lợi nhuận." }, "activity": { "title": "Hoạt động", @@ -6725,7 +6823,7 @@ }, "condensed_cards": { "how_it_works_title": "Cách hoạt động", - "how_it_works_subtitle": "Xem cách tiền của bạn sinh lời", + "how_it_works_subtitle": "See how your money can grow", "musd_title": "MetaMask USD", "musd_subtitle": "Tìm hiểu thêm về mUSD", "what_you_get_title": "Những gì bạn nhận được", @@ -6738,7 +6836,8 @@ "sent": "Đã gửi", "transferred": "Đã chuyển", "card_transaction": "Giao dịch thẻ", - "converted": "Đã chuyển đổi" + "converted": "Đã chuyển đổi", + "failed": "Không thành công" }, "convert_stablecoins": { "title": "Chuyển đổi đồng ổn định của bạn", @@ -6757,11 +6856,11 @@ "how_it_works_page": { "header_title": "Tài chính", "section_title": "Cách hoạt động", - "description_1": "Deposit mUSD into your Money account and earn up to {{percentage}}% APY (variable) automatically. Funds go into a DeFi vault that generates returns across audited lending markets—no staking, no claiming, no lock-ups.", + "description_1": "Gửi mUSD vào tài khoản Tài chính của bạn và tự động sinh lời lên đến {{percentage}}% APY (biến động). Tài sản sẽ được đưa vào một kho DeFi tạo lợi nhuận trên các thị trường cho vay đã được kiểm toán — không cần ký gửi, không cần nhận, không bị khóa tài sản.", "description_2": "Số dư Tài chính của bạn là số dư để chi tiêu. Liên kết Thẻ MetaMask để chi tiêu tại hơn 150 triệu cửa hàng trên toàn cầu. Tiền của bạn vẫn sinh lời cho đến thời điểm bạn sử dụng.", - "faq_title": "Frequently asked questions", + "faq_title": "Câu hỏi thường gặp", "faq_placeholder_answer": "Sắp ra mắt.", - "faq_q1": "How does the {{percentage}}% APY work?", + "faq_q1": "APY {{percentage}}% hoạt động như thế nào?", "faq_q2": "mUSD là gì?", "faq_q3": "Lợi suất đến từ đâu?", "faq_q4": "Tiền của tôi có bị khóa không? Tôi có thể rút tiền bất cứ lúc nào không?", @@ -7030,11 +7129,12 @@ "confirm": "Xác nhận", "pay_with_bottom_sheet": { "title": "Thanh toán bằng", - "last_used": "Last used", + "last_used": "Sử dụng lần cuối", + "bank_and_card": "Ngân hàng và thẻ", "crypto": "Crypto", - "available_balance": "{{balance}} available", - "other_assets": "Other assets", - "other_assets_description": "Select from your tokens" + "available_balance": "{{balance}} khả dụng", + "other_assets": "Tài sản khác", + "other_assets_description": "Chọn từ các token của bạn" }, "staking_footer": { "part1": "Bằng cách tiếp tục, bạn đồng ý với ", @@ -7120,7 +7220,7 @@ "transaction_fee": "Phí chuyển đổi mUSD bao gồm phí mạng và có thể bao gồm phí từ nhà cung cấp. Không áp dụng phí MetaMask khi bạn chuyển đổi sang mUSD." }, "money_account_withdraw": { - "transaction_fee": "MetaMask will swap your mUSD for your desired token. Swap providers may charge a fee, but MetaMask won't." + "transaction_fee": "MetaMask sẽ hoán đổi mUSD của bạn sang token mong muốn. Nhà cung cấp dịch vụ hoán đổi có thể tính phí, nhưng MetaMask sẽ không tính phí." }, "title": { "transaction_fee": "Phí" @@ -7225,7 +7325,7 @@ "deposit_edit_amount_done": "Nạp tiền", "deposit_edit_amount_predict_withdraw": "Rút tiền", "deposit_edit_amount_musd_conversion": "Chuyển đổi sang mUSD", - "preparing_order": "Preparing order" + "preparing_order": "Đang chuẩn bị lệnh" }, "change_in_simulation_modal": { "title": "Kết quả đã thay đổi", @@ -7250,20 +7350,33 @@ "confirm_swap": "Hoán đổi", "terms_and_conditions": "Điều khoản và điều kiện", "select_token": "Chọn token", - "batch_sell_select_title": "Select up to 5 tokens", - "batch_sell_select_subtitle": "All tokens need to be on the same network.", - "batch_sell_empty_state_title": "No tokens. No problem.", - "batch_sell_empty_state_description": "No tokens. No problem. Explore and buy tokens to batch sell.", - "batch_sell_continue_with_one_token": "Continue with (1) token", - "batch_sell_continue_with_tokens": "Continue with ({{tokenCount}}) tokens", - "batch_sell_max_tokens_allowed": "Max 5 tokens allowed", - "batch_sell_single_token_dialog_title": "High rate alert", - "batch_sell_single_token_dialog_description": "Batch selling one token could lead to a higher rate. Want to do a swap instead?", - "batch_sell_swap_instead": "Yes, swap", - "batch_sell_checkbox_label": "Batch Sell token", - "sort_balance": "Balance", - "next": "Next", - "explore_tokens": "Explore tokens", + "batch_sell_select_title": "Chọn tối đa 5 token", + "batch_sell_select_subtitle": "Tất cả token phải nằm trên cùng một mạng.", + "batch_sell_empty_state_title": "Không có token? Không sao cả.", + "batch_sell_empty_state_description": "Không có token? Không sao cả. Khám phá và mua token để bán hàng loạt.", + "batch_sell_continue_with_one_token": "Tiếp tục với (1) token", + "batch_sell_continue_with_tokens": "Tiếp tục với ({{tokenCount}}) token", + "batch_sell_max_tokens_allowed": "Cho phép tối đa 5 token", + "batch_sell_single_token_dialog_title": "Cảnh báo tỷ giá cao", + "batch_sell_single_token_dialog_description": "Việc bán hàng loạt chỉ một token có thể dẫn đến tỷ giá cao hơn. Bạn có muốn thay bằng một giao dịch hoán đổi không?", + "batch_sell_swap_instead": "Có, hoán đổi", + "batch_sell_review_title": "Xem lại giao dịch bán hàng loạt", + "batch_sell_select_stablecoin": "Chọn một đồng ổn định", + "batch_sell_total_received": "Tổng số nhận được", + "batch_sell_minimum_received": "Minimum received", + "batch_sell_quote_details_row": "{{tokenSymbol}} • {{slippage}} slippage", + "batch_sell_review": "Xem lại", + "batch_sell_you_sell": "You sell", + "batch_sell_token_count": "{{tokenCount}} tokens", + "batch_sell_toggle_you_sell": "Toggle token details", + "batch_sell_sell_all": "Sell all", + "batch_sell_includes_metamask_fee": "Includes {{fee}}% MetaMask fee", + "batch_sell_customize_token": "Tùy chỉnh {{tokenSymbol}}", + "batch_sell_remove_token": "Xóa {{tokenSymbol}}", + "batch_sell_checkbox_label": "Bán hàng loạt token", + "sort_balance": "Số dư", + "next": "Tiếp theo", + "explore_tokens": "Khám phá token", "no_tokens_found": "Không tìm thấy token", "no_tokens_found_description": "Chúng tôi không tìm thấy token nào với tên này. Hãy thử từ khóa tìm kiếm khác.", "select_network": "Chọn mạng", @@ -7332,6 +7445,7 @@ "price_impact_execution_description": "Bạn sẽ mất khoảng {{priceImpact}} giá trị token trong lần hoán đổi này. Hãy thử giảm số lượng hoặc chọn tuyến thanh khoản tốt hơn.", "proceed": "Tiếp tục", "cancel": "Hủy", + "close": "Đóng", "slippage_info_title": "Trượt giá", "slippage_info_description": "Phần trăm thay đổi giá mà bạn chấp nhận trước khi giao dịch bị hủy.", "blockaid_error_title": "Giao dịch này sẽ được hoàn lại", @@ -8107,7 +8221,14 @@ "retry": "Thử lại", "on_linea": "trên Linea", "account_label": "Tài khoản", - "token_label": "Token" + "token_label": "Token", + "money_account_label": "Money account", + "money_account_token_symbol": "mUSD", + "use_money_account_cta": "Use Money account", + "spend_and_earn_title": "Spend while you earn", + "spend_and_earn_description": "Spend with your Money account and earn up to {{apy}}% APY on your balance. Also get {{cashback}}% mUSD back.", + "spend_and_earn_description_no_apy": "Spend with your Money account and earn APY on your balance. Also get {{cashback}}% mUSD back.", + "spend_and_earn_cta": "Link to Money account" }, "cashback_screen": { "title": "Hoàn tiền bằng mUSD", @@ -8449,6 +8570,7 @@ "show_less": "Thu gọn", "linking_progress": "Đang thêm tài khoản... ({{current}}/{{total}})", "accounts_linked_count": "{{linked}}/{{total}} đã đăng ký tham gia", + "accounts_added": "Accounts added", "add_all_accounts": "Thêm tất cả tài khoản", "environment_selector": "Môi trường", "environment_cancel": "Hủy", @@ -8473,15 +8595,22 @@ }, "optout": { "title": "Hủy tham gia chương trình Phần thưởng", - "description": "Thao tác này sẽ xóa các tài khoản của bạn khỏi chương trình Phần thưởng và xóa toàn bộ tiến trình của bạn. Bạn sẽ không thể hoàn tác.", - "confirm": "Xóa vĩnh viễn", + "description": "This will remove your accounts from the Rewards program and your progress in any campaigns you've joined. Only do this if you are absolutely sure you want to erase your progress.", + "erase_button": "Erase progress", "modal": { "confirmation_title": "Bạn có chắc chắn không?", - "confirmation_description": "Hành động này sẽ xóa toàn bộ tiến trình của bạn và không thể đảo ngược. Nếu bạn tham gia lại chương trình Phần thưởng sau này, bạn sẽ bắt đầu lại từ 0.", + "confirmation_description": "This will erase all your progress, and can't be reversed. If you rejoin the Rewards program later, you'll start back at 0.", + "type_to_confirm": "Type 'erase progress' to continue", + "confirm_phrase": "erase progress", "cancel": "Hủy", "confirm": "Xác nhận", + "error_title": "Đã xảy ra sự cố", "error_message": "Không thể rút khỏi chương trình Phần thưởng. Vui lòng thử lại.", "processing": "Đang xử lý..." + }, + "request_received": { + "title": "Request received", + "description": "In about 7 days, your progress will be fully erased. If you made this request by mistake, please contact support through the app." } }, "toast_dismiss": "Đóng", @@ -8569,7 +8698,8 @@ "title_claim": "Nhận quyền lợi", "action": "Nhận", "empty-list": "Bạn hiện không có quyền lợi nào.", - "powered_by": "Được cung cấp bởi" + "powered_by": "Được cung cấp bởi", + "available_count": "Có sẵn {{count}}" }, "end_of_season_rewards": { "confirm_label_default": "Xác nhận", @@ -8887,9 +9017,11 @@ "musd_claim": "Nhận mUSD", "perps_deposit": "Nạp tiền", "perps_withdraw": "Rút tiền", + "predict_withdraw": "Rút {{sourceSymbol}} từ {{sourceChain}}", "predict_deposit": "Nạp tiền", "swap": "Hoán đổi token", - "swap_approval": "Phê duyệt token" + "swap_approval": "Phê duyệt token", + "fiat_purchase": "Mua {{token}} bằng {{paymentMethod}}" }, "perps_deposit_solution": "Bạn hiện có {{fiat}} USDC trên Arbitrum. Hãy thử nạp tiền lại." }, @@ -8965,7 +9097,7 @@ "high_to_low": "Cao đến thấp", "low_to_high": "Thấp đến cao", "apply": "Áp dụng", - "search_placeholder": "Tìm kiếm token, trang web, URL", + "search_placeholder": "Search tokens, markets and URLs", "cancel": "Hủy", "perps": "Vĩnh cửu", "rwa_perps_section": "Vĩnh cửu", @@ -8978,11 +9110,15 @@ "crypto_perps_section": "Vĩnh cửu", "predictions": "Dự đoán", "no_results": "Không tìm thấy kết quả", + "no_results_for_feed": "No {{feedName}} results for \"{{query}}\"", + "showing_all_results_for": "We found these results for \"{{query}}\"", "popular": "Phổ biến", "sites": "Trang web", "popular_sites": "Trang web phổ biến", "search_sites": "Tìm kiếm trang web", "view_all": "Xem tất cả", + "view_more": "Xem thêm", + "view_x_more": "View {{count}} more", "enable_basic_functionality": "Bật chức năng cơ bản", "basic_functionality_disabled_title": "Khám phá không khả dụng", "basic_functionality_disabled_description": "Chúng tôi không thể tìm nạp siêu dữ liệu cần thiết khi chức năng cơ bản bị tắt.", @@ -9002,6 +9138,14 @@ "crypto": "Crypto", "sports": "Thể thao", "dapps": "Trang web" + }, + "search_tabs": { + "all": "Tất cả", + "crypto": "Cryptos", + "perps": "Vĩnh cửu", + "stocks": "Cổ phiếu", + "predictions": "Dự đoán", + "sites": "Trang web" } }, "ota_update_modal": { @@ -9139,6 +9283,7 @@ "money_empty_description_network_filter": "Không có mUSD trên mạng này. Hãy chuyển mạng để xem mUSD của bạn.", "money_empty_state": { "get_started": "Bắt đầu", + "earn": "Kiếm lợi nhuận", "earn_apy": "Nhận {{percentage}}% APY" }, "money_filled_state": { @@ -9150,22 +9295,7 @@ "related_assets": "Tài sản liên quan", "perpetuals": "Hợp đồng vĩnh cửu", "predictions": "Dự đoán", - "whats_happening": "Tình hình hiện nay", - "whats_happening_ai": "AI", - "whats_happening_impact": { - "bullish": "Xu hướng tăng", - "bearish": "Xu hướng giảm", - "neutral": "Trung lập" - }, "top_traders": "Nhà giao dịch hàng đầu", - "whats_happening_categories": { - "geopolitical": "Địa chính trị", - "macro": "Vĩ mô", - "regulatory": "Quy định", - "technical": "Kỹ thuật", - "social": "Xã hội", - "other": "Khác" - }, "defi": "DeFi", "nfts": "NFT", "trending_tokens": "Xu hướng", @@ -9185,5 +9315,22 @@ }, "sites": { "popular": "Phổ biến" + }, + "whats_happening": { + "title": "Tình hình hiện nay", + "ai": "AI", + "impact": { + "bullish": "Xu hướng tăng", + "bearish": "Xu hướng giảm", + "neutral": "Trung lập" + }, + "categories": { + "geopolitical": "Địa chính trị", + "macro": "Vĩ mô", + "regulatory": "Quy định", + "technical": "Kỹ thuật", + "social": "Xã hội", + "other": "Khác" + } } } diff --git a/locales/languages/zh.json b/locales/languages/zh.json index 0237c5d483e..cf6922afeba 100644 --- a/locales/languages/zh.json +++ b/locales/languages/zh.json @@ -120,6 +120,10 @@ "account_no_funds": { "message": "无可用资金。请使用其他账户。" }, + "headless_buy_error": { + "title": "法币购买失败", + "message": "您的法币购买出错了。请重试。" + }, "mmpay_hardware_account": { "title": "钱包不获支持", "message": "暂不支持硬件钱包。请切换钱包继续操作。" @@ -133,8 +137,8 @@ "message": "该代币接收地址可能不支持直接转账,这可能导致资金损失。建议仅在确认该合约能够接收转账的情况下继续操作。" }, "gas_sponsorship_reserve_balance": { - "message": "本次交易无法使用燃料赞助。您的账户中需要至少保留 %{minBalance} %{nativeTokenSymbol}。", - "title": "燃料赞助不可用" + "message": "此特定网络要求在您的账户中保留 %{minBalance} %{nativeTokenSymbol} 的储备金。", + "title": "需要维持储备金余额" }, "token_trust_signal": { "malicious": { @@ -708,6 +712,9 @@ "contractAddressError": "您正在向代币的合约地址发送代币。这可能导致这些代币丢失。", "smart_contract_address": "智能合约地址", "smart_contract_address_warning": "该代币接收地址可能不支持直接转账,这可能导致资金损失。建议仅在确认该合约能够接收转账的情况下继续操作。", + "unavailable_network_connection": "Unavailable network connection", + "unavailable_network_connection_description": "The connection with {{network}} is unreliable. Update network connectivity details before continuing or try again later.", + "update": "更新", "i_understand": "我理解", "cancel": "取消", "new_address_title": "新地址", @@ -1068,7 +1075,7 @@ "sort": { "value": "价值", "pnl_percent": "损益 %", - "recent": "Recent" + "recent": "最近" } }, "trader_position": { @@ -1120,6 +1127,11 @@ "title": "交易 {{symbol}} 永续合约", "subtitle": "将您的盈亏放大至 {{leverage}} 倍" }, + "service_interruption": { + "title": "We're experiencing an outage", + "description": "Some services may be unavailable while the team works on a fix.", + "contact_support": "联系支持团队" + }, "today": "今天", "yesterday": "昨天", "unrealized_pnl": "未实现盈亏", @@ -1284,7 +1296,9 @@ "toast_completed_subtitle": "{{amount}} USDC 已转移到您的钱包", "toast_completed_any_token_subtitle": "{{amount}} {{token}} 已转入您的钱包", "toast_error_title": "出错了......", - "toast_error_description": "提款处理失败" + "toast_error_description": "提款处理失败", + "toast_start_error_description": "Your withdrawal wasn’t started.", + "try_again": "请重试" }, "quote": { "network_fee": "网络费", @@ -2227,35 +2241,35 @@ "predict": { "title": "MetaMask 预测", "world_cup": { - "title": "World Cup", - "banner_title": "World Cup 2026", - "banner_description": "Trade on World Cup markets", + "title": "世界杯", + "banner_title": "2026 年世界杯", + "banner_description": "Trade every match, every moment.", "tabs": { - "all": "All", - "props": "Props", - "live": "Live" + "all": "所有", + "props": "命题投注", + "live": "进行中" }, "stages": { - "group_stage": "Group Stage", - "round_of_32": "Round of 32", - "round_of_16": "Round of 16", - "quarterfinals": "Quarterfinals", - "semifinals": "Semifinals", - "third_place": "Third Place", - "final": "Final", - "group_a": "Group A", - "group_b": "Group B", - "group_c": "Group C", - "group_d": "Group D", - "group_e": "Group E", - "group_f": "Group F", - "group_g": "Group G", - "group_h": "Group H", - "group_i": "Group I", - "group_j": "Group J", - "group_k": "Group K", - "group_l": "Group L", - "third_place_match": "Third Place Match" + "group_stage": "小组赛", + "round_of_32": "32 强赛", + "round_of_16": "16 强赛", + "quarterfinals": "四分之一决赛", + "semifinals": "半决赛", + "third_place": "季军赛", + "final": "终场", + "group_a": "A 组", + "group_b": "B 组", + "group_c": "C 组", + "group_d": "D 组", + "group_e": "E 组", + "group_f": "F 组", + "group_g": "G 组", + "group_h": "H 组", + "group_i": "I 组", + "group_j": "J 组", + "group_k": "K 组", + "group_l": "L 组", + "third_place_match": "季军赛" } }, "prediction_markets": "预测市场", @@ -2537,8 +2551,8 @@ "withdraw_completed": "提取完成", "withdraw_completed_subtitle": "{{amount}} USDC 已转移到您的钱包", "withdraw_any_token_completed_subtitle": "{{amount}} {{token}} 已转入您的钱包", - "unavailable_title": "Withdrawals temporarily unavailable", - "unavailable_description": "For urgent assistance, please contact Customer Service.", + "unavailable_title": "提现服务暂时不可用", + "unavailable_description": "如需紧急协助,请联系客服。", "unavailable_got_it": "知道了", "error_title": "出错了......", "error_description": "提款处理失败", @@ -2941,6 +2955,17 @@ "pna25_confirm_button": "接受并关闭", "pna25_open_settings_button": "打开设置" }, + "onboarding_interest_questionnaire": { + "title": "您想使用 MetaMask 做什么?", + "description": "请选择所有适用项。", + "option_buy_and_sell_crypto": "买卖加密货币", + "option_consolidate_wallets": "合并您的钱包", + "option_advanced_trades": "进行高级交易", + "option_predict_sports_events": "预测体育赛事和事件", + "option_crypto_as_money": "将加密货币用作货币", + "option_connect_apps_sites": "连接到应用或网站", + "continue": "继续" + }, "template_confirmation": { "ok": "OK", "cancel": "取消" @@ -3261,8 +3286,27 @@ "notifications_desc": "管理您的通知", "allow_notifications": "允许通知", "enable_push_notifications": "启用推送通知", - "allow_notifications_desc": "通过通知随时了解您的钱包动态。为了使用通知,我们使用配置文件在您的不同设备上同步某些设置。", + "allow_notifications_desc": "Choose what you're notified about and how.", "notifications_opts": { + "preferences_title": "Preferences", + "push_recommended": "Push", + "in_app": "In-app", + "status_push": "Push", + "status_in_app": "In app", + "status_off": "关闭", + "select_all": "全部选择", + "deselect_all": "取消全部选择", + "select_accounts_title": "账户", + "select_accounts_desc": "Choose which accounts you'd like to get notifications for.", + "wallet_activity_title": "Wallet Activity", + "wallet_activity_desc": "Buy, sells, transfers, swaps and rewards", + "perps_title": "Trading Activity", + "perps_desc": "Perps position changes, liquidations, funding rates, and margin updates", + "social_ai_title": "Trading Signals", + "social_ai_desc": "Updates from traders and assets you follow, plus currated market news", + "marketing_title": "Updates and Rewards", + "marketing_desc": "Product updates, feature announcements, and new releases", + "marketing_disclaimer": "By turning this on, you agree to receive product news and marketing updates from MetaMask.", "customize_session_title": "自定义您的通知", "customize_session_desc": "开启您想要接收的通知类型:", "account_session_title": "账户活动", @@ -3276,8 +3320,7 @@ "snaps_title": "Snap", "snaps_desc": "新功能和更新", "products_announcements_title": "产品公告", - "products_announcements_desc": "新产品和功能", - "perps_title": "永续合约交易" + "products_announcements_desc": "新产品和功能" }, "contacts_title": "联系方式", "contacts_desc": "添加、编辑、删除和管理您的账户.", @@ -3640,7 +3683,15 @@ "card": { "title": "卡", "reset_onboarding_description": "重设卡绑定状态,使绑定流程从头开始。", - "reset_onboarding_button": "重设绑定状态" + "reset_onboarding_button": "重设绑定状态", + "unlink_money_account_description": "撤销授权卡从您的 Money 账户中支出 USDC 的限额。此操作将提交一笔批准 (0) 交易,并在卡后端将 Money 账户标记为未委托。", + "unlink_money_account_button": "解除 Money 账户与卡的关联", + "unlink_money_account_disabled_hint": "没有可移除的活跃关联。" + }, + "identity": { + "title": "Identity", + "description": "Clears the persisted authentication session. Use this after toggling MM_DEV_API_ENV — otherwise a prod-minted JWT keeps being handed to dev-API consumers until it expires. Current MM_DEV_API_ENV: {{env}}.", + "clear_auth_session_button": "Clear persisted auth session" }, "haptics": { "title": "振动", @@ -3842,8 +3893,8 @@ "predict_button": "预测", "add_collectible_button": "添加", "info": "信息", - "batch_sell": "Batch Sell", - "batch_sell_new_label": "New", + "batch_sell": "批量卖出", + "batch_sell_new_label": "新增", "swap": "兑换", "convert": "兑换", "bridge": "桥接", @@ -3883,7 +3934,7 @@ "troubleshoot": "故障排除", "deposit_description": "低手续费的银行或卡转账", "buy_description": "适合购买特定代币", - "batch_sell_description": "Sell up to 5 tokens for a stablecoin", + "batch_sell_description": "卖出最多 5 个代币以换取稳定币", "sell_description": "卖出加密货币换取现金", "swap_description": "代币之间的兑换", "bridge_description": "在不同网络间传送代币", @@ -5205,6 +5256,34 @@ "manage_preferences_2": "设置 > 通知。", "cancel": "取消", "cta": "开启" + }, + "push_onboarding": { + "new_user": { + "title": "绝不错过任何市场行情", + "body": "当价格达到您的目标价位、交易确认以及投资组合发生变动时,您会收到实时提醒。此外,您还会在过程中获得产品更新和奖励。我们会根据您与 MetaMask 的互动情况推送相关更新。", + "button_yes": "是", + "button_not_now": "暂时不", + "preview_card_1": { + "eyebrow": "METAMASK", + "time": "立即", + "title": "ETH 今日上涨 4.2%", + "message": "现价 $2668.51——已超出您设置的价格提醒" + }, + "preview_card_2": { + "eyebrow": "METAMASK", + "time": "1 小时前", + "title": "已收到 0.25 ETH", + "message": "来自 0x9a21…4f8c · $640.29" + } + }, + "existing_user": { + "title": "推出个性化提醒", + "body": "获取与您的交易方式相匹配的通知。可随时更新。", + "card_title": "您将获得", + "card_description": "根据您的交易活动量身定制的个性化提醒和更新。", + "button_confirm": "确认", + "button_not_now": "暂时不" + } } }, "protect_your_wallet_modal": { @@ -5315,6 +5394,7 @@ "pay_with": "支付方式:", "buying_via": "正在通过 {{providerName}} 购买。", "change_provider": "更换提供商。", + "circuit_breaker_open": "This service is temporarily unavailable. Please try again in about 30 minutes.", "payment_error": "出错了。请重试。", "no_payment_methods_available": "无可用支付方式。", "error_fetching_quotes": "出错了。请重试。", @@ -6520,6 +6600,8 @@ "convert_to_musd": "兑换为 mUSD", "get_a_percentage_musd_bonus": "获取 {{percentage}}% mUSD 奖励", "convert": "兑换", + "confirm": "确认", + "convert_tooltip_description": "将您的稳定币兑换为 mUSD,即可赚取高达 {{percentage}}% 的年化奖励,该奖励每日可领取。由 Relay 提供支持。", "fetching_quote": "正在获取报价...", "you_convert": "您兑换", "network_fee": "网络费", @@ -6597,7 +6679,7 @@ "step_progress": "第 {{current}} 步(共 {{total}} 步)", "title": "存入资金", "description": "为您的账户充值并开始赚取收益(APY)。", - "add": "添加", + "add": "充值", "step2_title": "获取您的 MetaMask 卡", "step2_description": "在任何受理万事达卡的地方,使用您的 Money 账户余额消费,同时赚取收益。", "step2_cta": "获取卡", @@ -6605,6 +6687,19 @@ "link_card_description": "在任何受理万事达卡的地方,使用您的余额消费,同时赚取收益。", "link_card_cta": "关联卡" }, + "rive_onboarding": { + "step1_title": "Money 账户已上线", + "step1_body": "您的全部钱包余额均可享高达 {{percentage}}% 的年化收益率。", + "step1_footer_text": "年化收益率会变动,且可能随时更改。", + "step2_title": "自动赚取收益", + "step2_body": "转移稳定币无需兑换手续费。资金即刻开始赚取收益。", + "step2_footer_text": "Provided by Veda and Steakhouse Financial.", + "step3_title": "随处消费", + "step3_body": "将您的 Money 账户与 MetaMask 卡关联,消费可享高达 {{percentage}}% 的返现。", + "step4_title": "交易与赚取收益,一站完成", + "step4_body": "使用您的 Money 余额在 MetaMask 内进行交易,同时持续赚取收益。", + "continue": "继续" + }, "action": { "add": "添加", "transfer": "转账", @@ -6618,8 +6713,8 @@ }, "how_it_works": { "title": "如何运行", - "description_prefix": "Deposit mUSD into your Money account and earn up to", - "description_suffix": ". Your balance is dollar-backed and ready to spend, trade, or send anytime." + "description_prefix": "将 mUSD 存入您的 Money 账户,即可赚取高达", + "description_suffix": "。您的余额由美元支持,可随时用于消费、交易或转账。" }, "musd_row": { "add": "添加" @@ -6627,16 +6722,16 @@ "balance_card": { "label": "Money 余额", "add": "添加", - "info_sheet_title": "Money balance", - "info_sheet_body": "Your dollar-backed mUSD balance that's always available to spend, send, or trade anytime. We don't calculate this into your total account balance.\n\nWithdrawals process immediately, subject to standard network confirmation times on the relevant blockchain. If liquidity is tight, there may be temporary delays." + "info_sheet_title": "Money 余额", + "info_sheet_body": "您的美元支持 mUSD 余额,始终可随时用于消费、转账或交易。我们不将其计入您的总账户余额。\n\n提现即时处理,但需遵循相关区块链的标准网络确认时间。若流动性紧张,可能会出现暂时延迟。" }, "potential_earnings": { "title": "用您的加密货币赚取收益", "description": "了解将您的加密货币转换为 mUSD 后,资金如何随时间增值。", - "description_with_amounts_prefix": "Convert your {{total}} in assets and you could earn up to", - "description_with_amounts_suffix": "in one year.", + "description_with_amounts_prefix": "将您的 {{total}} 资产进行转换,即可赚取高达", + "description_with_amounts_suffix": "(每年)。", "convert": "兑换", - "convert_cta": "Convert your crypto", + "convert_cta": "兑换加密货币", "no_fee": "无 MetaMask 手续费", "view_all": "查看全部", "view_potential_earnings": "查看潜在收益" @@ -6649,41 +6744,44 @@ "cashback": "{{percentage}}% mUSD 返现", "get_now": "立即获取", "link_title": "关联 MetaMask 卡", - "link_subtitle": "Spend your Money balance and earn on purchases. Plus, up to {{apy}}% APY on your balance.", - "link_bullet_cashback": "Get {{percentage}}% mUSD back", - "link_bullet_apy": "Earn up to {{apy}}% APY", + "link_subtitle": "消费您的 Money 余额,消费即享收益。此外,余额还可享高达 {{apy}}% 的年化收益率。", + "link_subtitle_no_apy": "Spend your Money balance and earn on purchases.", + "link_bullet_cashback": "获得 {{percentage}}% mUSD 返现", + "link_bullet_apy": "享高达 {{apy}}% 年化收益率", "link_card": "关联卡", - "link_pending_title": "Linking card", - "link_pending_description": "Approving spending limit…", - "link_success_title": "Card linked successfully", - "link_success_description": "You can now spend while you earn", - "link_error": "Couldn't link card", - "manage_card": "Manage", - "avail_balance": "Avail. balance" + "link_pending_title": "Linking your card", + "link_success_title": "Your card is ready to use", + "link_error": "Something went wrong linking your card", + "link_card_sheet_title": "消费并赚取收益", + "link_card_sheet_description": "Link your card so you can spend your Money balance and earn mUSD back on purchases—all while earning up to {{apy}}% APY.", + "link_card_sheet_description_no_apy": "Link your card so you can spend your Money balance and earn mUSD back on purchases.", + "link_card_sheet_cta": "关联卡", + "manage_card": "管理", + "avail_balance": "可用余额" }, "what_you_get": { "title": "您将获得", - "benefit_auto_earn": "Auto-earn up to", + "benefit_auto_earn": "自动赚取高达", "benefit_dollar_backed": "将您的资金安全存放于 mUSD(一种 1:1 锚定美元的稳定币)", "benefit_liquidity": "享受完全流动性,无锁仓期限制,可随时交易或提现", "benefit_spend_prefix": "通过 MetaMask 卡可在超过 1.5 亿家商户消费,并赚取 ", "benefit_spend_cashback": "1-3% mUSD 返现", - "benefit_transfer": "Transfer to any of your wallets across MetaMask", - "benefit_global": "Send and receive funds globally", + "benefit_transfer": "转入您 MetaMask 中的任意钱包", + "benefit_global": "全球收发资金", "learn_more": "了解详情" }, "footer": { - "add_money": "Add funds" + "add_money": "充值" }, "add_money_sheet": { - "title": "Add funds", + "title": "充值", "convert_crypto": "兑换加密货币", - "convert_crypto_description": "From any account", + "convert_crypto_description": "从任何账户", "deposit_funds": "存入资金", - "deposit_funds_description": "From debit card or bank", - "move_musd": "Transfer your {{amount}} mUSD", - "move_musd_no_amount": "Transfer your mUSD", - "move_musd_description": "From your balance", + "deposit_funds_description": "从借记卡或银行", + "move_musd": "转账您的 {{amount}} mUSD", + "move_musd_no_amount": "转账您的 mUSD", + "move_musd_description": "从您的余额", "receive_external": "从外部钱包收款", "coming_soon": "即将推出" }, @@ -6694,7 +6792,7 @@ "contact_support": "联系支持团队" }, "transfer_sheet": { - "title": "Transfer funds", + "title": "转账", "between_accounts": "账户间转账", "perps_account": "永续合约(Perps)账户", "predictions_account": "预测(Predictions)账户", @@ -6712,8 +6810,8 @@ "body": "根据您当前的余额和今天的 APY,估算您在一段时间内可能赚取的收益。预估收益仅供参考,不代表实际到账收益,且可能随市场波动。" }, "earn_crypto_info_sheet": { - "title": "Earn on your crypto", - "body": "Illustration assumes {{percentage}}% Annual Percentage Yield (APY) remains unchanged for one year. APY is variable and may change due to various factors. No guarantee of return." + "title": "用您的加密货币赚取收益", + "body": "示例假设 {{percentage}}% 的年化收益率在一年内保持不变。年化收益率会浮动,并可能因多种因素而变动。收益不做保证。" }, "activity": { "title": "活动", @@ -6725,7 +6823,7 @@ }, "condensed_cards": { "how_it_works_title": "如何运行", - "how_it_works_subtitle": "了解您的资金如何为您创造收益", + "how_it_works_subtitle": "See how your money can grow", "musd_title": "MetaMask USD", "musd_subtitle": "了解 mUSD 详情", "what_you_get_title": "您将获得", @@ -6738,7 +6836,8 @@ "sent": "已发送", "transferred": "已转账", "card_transaction": "卡交易", - "converted": "已兑换" + "converted": "已兑换", + "failed": "失败" }, "convert_stablecoins": { "title": "兑换您的稳定币", @@ -6757,11 +6856,11 @@ "how_it_works_page": { "header_title": "Money", "section_title": "如何运行", - "description_1": "Deposit mUSD into your Money account and earn up to {{percentage}}% APY (variable) automatically. Funds go into a DeFi vault that generates returns across audited lending markets—no staking, no claiming, no lock-ups.", + "description_1": "将 mUSD 存入您的 Money 账户,即可自动赚取高达 {{percentage}}% 的年化收益率(可变动)。资金进入去中心化金融金库,通过经过审计的借贷市场产生收益——无需质押、无需领取、无锁定期。", "description_2": "您的 Money 账户余额即您的消费余额。关联您的 MetaMask 卡,即可在全球超过 1.5 亿家商户消费。您的资金在您使用之前会持续赚取收益。", - "faq_title": "Frequently asked questions", + "faq_title": "常见问题解答", "faq_placeholder_answer": "即将推出.", - "faq_q1": "How does the {{percentage}}% APY work?", + "faq_q1": "{{percentage}}% 年化收益率是如何计算的?", "faq_q2": "什么是 mUSD?", "faq_q3": "收益从何而来?", "faq_q4": "我的资金会被锁定吗?可以随时提现吗?", @@ -7030,11 +7129,12 @@ "confirm": "确认", "pay_with_bottom_sheet": { "title": "支付方式:", - "last_used": "Last used", - "crypto": "Crypto", - "available_balance": "{{balance}} available", - "other_assets": "Other assets", - "other_assets_description": "Select from your tokens" + "last_used": "上次使用", + "bank_and_card": "银行与卡", + "crypto": "加密货币", + "available_balance": "{{balance}} 可用", + "other_assets": "其他资产", + "other_assets_description": "从您的代币中选择" }, "staking_footer": { "part1": "继续即表示您同意我们的 ", @@ -7120,7 +7220,7 @@ "transaction_fee": "mUSD 兑换费用包含网络费用,并可能包含提供商费用。兑换为 mUSD 时,MetaMask 不收取任何费用。" }, "money_account_withdraw": { - "transaction_fee": "MetaMask will swap your mUSD for your desired token. Swap providers may charge a fee, but MetaMask won't." + "transaction_fee": "MetaMask 会将您的 mUSD 兑换为您想要的代币。兑换提供商可能会收取费用,但 MetaMask 不会。" }, "title": { "transaction_fee": "费用" @@ -7225,7 +7325,7 @@ "deposit_edit_amount_done": "充值", "deposit_edit_amount_predict_withdraw": "提取", "deposit_edit_amount_musd_conversion": "兑换为 mUSD", - "preparing_order": "Preparing order" + "preparing_order": "正在准备订单" }, "change_in_simulation_modal": { "title": "结果已发生变化", @@ -7250,20 +7350,33 @@ "confirm_swap": "交换", "terms_and_conditions": "条款和条件", "select_token": "选择代币", - "batch_sell_select_title": "Select up to 5 tokens", - "batch_sell_select_subtitle": "All tokens need to be on the same network.", - "batch_sell_empty_state_title": "No tokens. No problem.", - "batch_sell_empty_state_description": "No tokens. No problem. Explore and buy tokens to batch sell.", - "batch_sell_continue_with_one_token": "Continue with (1) token", - "batch_sell_continue_with_tokens": "Continue with ({{tokenCount}}) tokens", - "batch_sell_max_tokens_allowed": "Max 5 tokens allowed", - "batch_sell_single_token_dialog_title": "High rate alert", - "batch_sell_single_token_dialog_description": "Batch selling one token could lead to a higher rate. Want to do a swap instead?", - "batch_sell_swap_instead": "Yes, swap", - "batch_sell_checkbox_label": "Batch Sell token", - "sort_balance": "Balance", - "next": "Next", - "explore_tokens": "Explore tokens", + "batch_sell_select_title": "选择最多 5 个代币", + "batch_sell_select_subtitle": "所有代币需位于同一网络。", + "batch_sell_empty_state_title": "没有代币。没问题。", + "batch_sell_empty_state_description": "没有代币。没问题。浏览并购买代币,即可进行批量卖出。", + "batch_sell_continue_with_one_token": "继续使用 (1) 个代币", + "batch_sell_continue_with_tokens": "继续使用({{tokenCount}})个代币", + "batch_sell_max_tokens_allowed": "最多允许 5 个代币", + "batch_sell_single_token_dialog_title": "高费率提醒", + "batch_sell_single_token_dialog_description": "批量卖出一种代币可能导致更高费率。要改用兑换吗?", + "batch_sell_swap_instead": "是的,兑换", + "batch_sell_review_title": "批量卖出审核", + "batch_sell_select_stablecoin": "选择一种稳定币", + "batch_sell_total_received": "总计收到", + "batch_sell_minimum_received": "Minimum received", + "batch_sell_quote_details_row": "{{tokenSymbol}} • {{slippage}} slippage", + "batch_sell_review": "查看", + "batch_sell_you_sell": "You sell", + "batch_sell_token_count": "{{tokenCount}} tokens", + "batch_sell_toggle_you_sell": "Toggle token details", + "batch_sell_sell_all": "Sell all", + "batch_sell_includes_metamask_fee": "Includes {{fee}}% MetaMask fee", + "batch_sell_customize_token": "自定义 {{tokenSymbol}}", + "batch_sell_remove_token": "去除 {{tokenSymbol}}", + "batch_sell_checkbox_label": "批量卖出代币", + "sort_balance": "余额", + "next": "下一步", + "explore_tokens": "探索代币", "no_tokens_found": "找不到代币", "no_tokens_found_description": "我们未找到与此名称匹配的代币。请尝试其他搜索方式。", "select_network": "选择网络", @@ -7332,6 +7445,7 @@ "price_impact_execution_description": "在此兑换中,您将损失约 {{priceImpact}} 的代币价值。请尝试降低金额或选择流动性更高的路径。", "proceed": "继续", "cancel": "取消", + "close": "关闭", "slippage_info_title": "滑点", "slippage_info_description": "在交易取消前,您愿意接受的价格波动百分比。", "blockaid_error_title": "此交易将被撤销", @@ -8107,7 +8221,14 @@ "retry": "请重试", "on_linea": "在 Linea 上", "account_label": "账户", - "token_label": "代币" + "token_label": "代币", + "money_account_label": "Money account", + "money_account_token_symbol": "mUSD", + "use_money_account_cta": "Use Money account", + "spend_and_earn_title": "Spend while you earn", + "spend_and_earn_description": "Spend with your Money account and earn up to {{apy}}% APY on your balance. Also get {{cashback}}% mUSD back.", + "spend_and_earn_description_no_apy": "Spend with your Money account and earn APY on your balance. Also get {{cashback}}% mUSD back.", + "spend_and_earn_cta": "Link to Money account" }, "cashback_screen": { "title": "mUSD 返现", @@ -8449,6 +8570,7 @@ "show_less": "收起", "linking_progress": "正在添加账户……({{current}}/{{total}})", "accounts_linked_count": "{{linked}}{{total}} 已加入", + "accounts_added": "Accounts added", "add_all_accounts": "添加全部账户", "environment_selector": "环境", "environment_cancel": "取消", @@ -8473,15 +8595,22 @@ }, "optout": { "title": "注销奖励计划账户", - "description": "此操作会将您的账户移出奖励计划并清除所有进度。此操作无法撤销。", - "confirm": "注销", + "description": "This will remove your accounts from the Rewards program and your progress in any campaigns you've joined. Only do this if you are absolutely sure you want to erase your progress.", + "erase_button": "Erase progress", "modal": { "confirmation_title": "您确定吗?", - "confirmation_description": "此操作将清除您所有的进度,且无法撤销。若您日后重新加入奖励计划,将从 0 开始累积。", + "confirmation_description": "This will erase all your progress, and can't be reversed. If you rejoin the Rewards program later, you'll start back at 0.", + "type_to_confirm": "Type 'erase progress' to continue", + "confirm_phrase": "erase progress", "cancel": "取消", "confirm": "确认", + "error_title": "出错了......", "error_message": "注销奖励计划账户失败。请重试。", "processing": "处理中..." + }, + "request_received": { + "title": "Request received", + "description": "In about 7 days, your progress will be fully erased. If you made this request by mistake, please contact support through the app." } }, "toast_dismiss": "忽略", @@ -8569,7 +8698,8 @@ "title_claim": "领取福利", "action": "领取", "empty-list": "您当前暂无任何福利。", - "powered_by": "技术支持:" + "powered_by": "技术支持:", + "available_count": "{{count}} 可用" }, "end_of_season_rewards": { "confirm_label_default": "确认", @@ -8887,9 +9017,11 @@ "musd_claim": "领取 mUSD", "perps_deposit": "充值", "perps_withdraw": "提取", + "predict_withdraw": "从 {{sourceChain}} 提取 {{sourceSymbol}}", "predict_deposit": "充值", "swap": "兑换代币", - "swap_approval": "批准代币" + "swap_approval": "批准代币", + "fiat_purchase": "使用 {{paymentMethod}} 购买 {{token}}" }, "perps_deposit_solution": "您目前在 Arbitrum 网络上持有价值 {{fiat}} 的 USDC。请重新尝试存款。" }, @@ -8965,7 +9097,7 @@ "high_to_low": "从高到低", "low_to_high": "从低到高", "apply": "应用", - "search_placeholder": "搜索代币、网站、URL", + "search_placeholder": "Search tokens, markets and URLs", "cancel": "取消", "perps": "永续合约", "rwa_perps_section": "永续合约", @@ -8978,11 +9110,15 @@ "crypto_perps_section": "永续合约", "predictions": "预测", "no_results": "未找到结果", + "no_results_for_feed": "No {{feedName}} results for \"{{query}}\"", + "showing_all_results_for": "We found these results for \"{{query}}\"", "popular": "热门", "sites": "网站", "popular_sites": "热门网站", "search_sites": "搜索网站", "view_all": "查看全部", + "view_more": "查看更多", + "view_x_more": "View {{count}} more", "enable_basic_functionality": "启用基本功能", "basic_functionality_disabled_title": "探索功能不可用", "basic_functionality_disabled_description": "当基础功能被禁用时,我们无法获取所需的元数据。", @@ -9002,6 +9138,14 @@ "crypto": "加密货币", "sports": "体育", "dapps": "网站" + }, + "search_tabs": { + "all": "所有", + "crypto": "Cryptos", + "perps": "永续合约", + "stocks": "股票", + "predictions": "预测", + "sites": "网站" } }, "ota_update_modal": { @@ -9139,6 +9283,7 @@ "money_empty_description_network_filter": "此网络中没有 mUSD。请切换网络以查看您的 mUSD。", "money_empty_state": { "get_started": "开始", + "earn": "赚取", "earn_apy": "赚取{{percentage}}% APY" }, "money_filled_state": { @@ -9150,22 +9295,7 @@ "related_assets": "相关资产", "perpetuals": "永续合约", "predictions": "预测", - "whats_happening": "发生了什么", - "whats_happening_ai": "人工智能(AI)", - "whats_happening_impact": { - "bullish": "看涨", - "bearish": "看跌", - "neutral": "看平" - }, "top_traders": "顶尖交易者", - "whats_happening_categories": { - "geopolitical": "地缘政治", - "macro": "宏观", - "regulatory": "监管", - "technical": "技术", - "social": "社会", - "other": "其他" - }, "defi": "DeFi", "nfts": "NFT", "trending_tokens": "趋势", @@ -9185,5 +9315,22 @@ }, "sites": { "popular": "热门" + }, + "whats_happening": { + "title": "发生了什么", + "ai": "人工智能(AI)", + "impact": { + "bullish": "看涨", + "bearish": "看跌", + "neutral": "看平" + }, + "categories": { + "geopolitical": "地缘政治", + "macro": "宏观", + "regulatory": "监管", + "technical": "技术", + "social": "社会", + "other": "其他" + } } } diff --git a/package.json b/package.json index 4b806e4b6bd..5edc676e9b2 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "metamask", - "version": "7.79.0", + "version": "7.80.0", "private": true, "scripts": { "install:foundryup": "yarn mm-foundryup", diff --git a/tests/component-view/mocks.ts b/tests/component-view/mocks.ts index 09b765c6ef3..d2f9c48bcae 100644 --- a/tests/component-view/mocks.ts +++ b/tests/component-view/mocks.ts @@ -88,6 +88,23 @@ jest.mock('../../app/core/Engine', () => { setTokenNetworkFilter() { return undefined; }, + setPrivacyMode: jest.fn(), + }, + CardController: { + fetchCardHomeData: jest.fn().mockResolvedValue(undefined), + logout: jest.fn().mockResolvedValue(undefined), + getCapabilities: jest.fn().mockReturnValue({ + authMethod: 'otp', + supportsOTP: true, + supportsFundingApproval: true, + supportsFundingLimits: true, + fundingChains: ['eip155:59144'], + supportsFreeze: true, + supportsPushProvisioning: false, + onboarding: { requiresEmail: true }, + supportsPinView: true, + supportsCashback: true, + }), }, TokensController: { addTokens() { @@ -447,6 +464,7 @@ jest.mock('../../app/core/Engine', () => { async lookupEnabledNetworks() { return undefined; }, + setSelectedAddress: jest.fn(), }; return { __esModule: true, default: engine }; }); diff --git a/tests/component-view/presets/cardStatePreset.ts b/tests/component-view/presets/cardStatePreset.ts new file mode 100644 index 00000000000..11c6c6ea266 --- /dev/null +++ b/tests/component-view/presets/cardStatePreset.ts @@ -0,0 +1,107 @@ +import { createStateFixture } from '../stateFixture'; +import type { DeepPartial } from '../../../app/util/test/renderWithProvider'; +import type { RootState } from '../../../app/reducers'; +import { defaultCardFeatureFlag } from '../../../app/selectors/featureFlagController/card'; + +const DEFAULT_WALLET_ADDRESS = '0x0000000000000000000000000000000000000001'; + +/** + * Minimal CardHomeData with an active VIRTUAL card seeded with a non-zero + * USDC spendable balance so hasPriorityTokenBalance is true, which enables + * the ManageCardOptions section to render. + */ +const defaultCardHomeData = { + card: { + id: 'card-test-123', + status: 'ACTIVE', + type: 'VIRTUAL', + lastFour: '1234', + holderName: 'Test User', + isFreezable: true, + }, + account: { + verificationStatus: 'VERIFIED', + provisioningEligible: false, + holderName: 'Test User', + shippingAddress: { + line1: '123 Main St', + city: 'New York', + state: 'NY', + postalCode: '10001', + country: 'US', + }, + }, + primaryFundingAsset: { + symbol: 'USDC', + name: 'USD Coin', + address: '0x176211869cA2b568f2A7D4EE941E073a821EE1ff', + walletAddress: DEFAULT_WALLET_ADDRESS, + decimals: 6, + chainId: 'eip155:59144', + // Non-zero spendableBalance makes rawTokenBalance > 0 via useAssetBalances + spendableBalance: '100.000000', + spendingCap: '200.000000', + priority: 1, + // 'active' maps to FundingStatus.Enabled via toCardFundingToken + status: 'active', + }, + fundingAssets: [], + availableFundingAssets: [], + alerts: [], + // 'add_funds' action causes ADD_FUNDS_BUTTON to render + actions: [{ type: 'add_funds', enabled: true }], + delegationSettings: null, +}; + +/** + * Returns a StateFixtureBuilder seeded with minimal state for CardHome views. + * The default state includes: + * - An authenticated user with an active VIRTUAL card (USDC, Linea) + * - US location so Order Metal Card is eligible when the feature flag is enabled + * - Empty MoneyAccountController so the money-account linkage section is hidden + * + * Use `.withOverrides()` to override individual fields (e.g. isAuthenticated: false, + * cardHomeDataStatus: 'error'). + */ +export const initialStateCard = () => + createStateFixture() + .withMinimalAccounts() + .withMinimalKeyringController() + .withMinimalTokenRates() + .withMinimalMultichainBalances() + .withMinimalMultichainAssets() + .withMinimalMultichainAssetsRates() + .withMinimalMainnetNetwork() + .withMinimalMultichainNetwork(true) + .withMinimalAnalyticsController({ optedIn: false }) + .withOverrides({ + engine: { + backgroundState: { + CardController: { + isAuthenticated: true, + cardholderAccounts: [`eip155:0:${DEFAULT_WALLET_ADDRESS}`], + activeProviderId: 'baanx', + providerData: { baanx: { location: 'us' } }, + cardHomeData: defaultCardHomeData, + cardHomeDataStatus: 'success', + selectedCountry: null, + }, + MoneyAccountController: { moneyAccounts: {} }, + RemoteFeatureFlagController: { + remoteFeatureFlags: { + cardFeature: defaultCardFeatureFlag, + metalCardCheckoutEnabled: null, + }, + }, + PreferencesController: { + tokenSortConfig: { + key: 'tokenFiatAmount', + order: 'dsc', + sortCallback: 'stringNumeric', + }, + tokenNetworkFilter: {}, + privacyMode: false, + }, + }, + }, + } as unknown as DeepPartial); diff --git a/tests/component-view/render.tsx b/tests/component-view/render.tsx index c8f4d79a3fe..1837383d096 100644 --- a/tests/component-view/render.tsx +++ b/tests/component-view/render.tsx @@ -114,7 +114,7 @@ export function renderScreenWithRoutes( options: { name: string }, extraRoutes: { name: string; - Component?: React.ComponentType; + Component?: React.ComponentType; }[], providerValues?: ProviderValues, initialParams?: Record, diff --git a/tests/component-view/renderers/cardViewRenderer.tsx b/tests/component-view/renderers/cardViewRenderer.tsx new file mode 100644 index 00000000000..d767348d407 --- /dev/null +++ b/tests/component-view/renderers/cardViewRenderer.tsx @@ -0,0 +1,47 @@ +import '../mocks'; +import React from 'react'; +import { renderComponentViewScreen, renderScreenWithRoutes } from '../render'; +import { initialStateCard } from '../presets/cardStatePreset'; +import CardHome from '../../../app/components/UI/Card/Views/CardHome/CardHome'; +import Routes from '../../../app/constants/navigation/Routes'; +import type { DeepPartial } from '../../../app/util/test/renderWithProvider'; +import type { RootState } from '../../../app/reducers'; + +interface RenderCardViewOptions { + overrides?: DeepPartial; + initialParams?: Record; + extraRoutes?: { name: string; Component?: React.ComponentType }[]; +} + +/** + * Render CardHome inside a minimal navigation stack with real Redux state. + * + * Pass `extraRoutes` to register probe screens for navigation assertions. + * Pass `overrides` to adjust specific Redux state fields. + */ +export function renderCardHomeView(options: RenderCardViewOptions = {}) { + const { overrides, initialParams, extraRoutes } = options; + + const builder = initialStateCard(); + if (overrides) { + builder.withOverrides(overrides); + } + const state = builder.build(); + + if (extraRoutes?.length) { + return renderScreenWithRoutes( + CardHome, + { name: Routes.CARD.HOME }, + extraRoutes, + { state }, + initialParams, + ); + } + + return renderComponentViewScreen( + CardHome, + { name: Routes.CARD.HOME }, + { state }, + initialParams, + ); +} diff --git a/tests/helpers/analytics/expectations/card-button.analytics.ts b/tests/helpers/analytics/expectations/card-button.analytics.ts deleted file mode 100644 index 9e4e77ad78d..00000000000 --- a/tests/helpers/analytics/expectations/card-button.analytics.ts +++ /dev/null @@ -1,12 +0,0 @@ -import type { AnalyticsExpectations } from '../../../framework'; - -const CARD_BUTTON_VIEWED = 'Card Button Viewed'; -const CARD_HOME_CLICKED = 'Card Home Clicked'; - -/** - * Expected MetaMetrics payloads after opening Card Home via navbar button. - */ -export const cardButtonExpectations: AnalyticsExpectations = { - eventNames: [CARD_BUTTON_VIEWED, CARD_HOME_CLICKED], - events: [{ name: CARD_BUTTON_VIEWED }, { name: CARD_HOME_CLICKED }], -}; diff --git a/tests/page-objects/Notifications/EnableNotificationsModal.ts b/tests/page-objects/Notifications/EnableNotificationsModal.ts deleted file mode 100644 index 553c8d94fe1..00000000000 --- a/tests/page-objects/Notifications/EnableNotificationsModal.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { EnableNotificationModalSelectorsIDs } from '../../../app/components/Views/Notifications/OptIn/EnableNotificationModal.testIds'; -import Gestures from '../../framework/Gestures'; -import Matchers from '../../framework/Matchers'; - -class EnableNotificationsModal { - get title() { - return Matchers.getElementByID(EnableNotificationModalSelectorsIDs.TITLE); - } - get cancel_button() { - return Matchers.getElementByID( - EnableNotificationModalSelectorsIDs.BUTTON_CANCEL, - ); - } - get enable_button() { - return Matchers.getElementByID( - EnableNotificationModalSelectorsIDs.BUTTON_ENABLE, - ); - } - - async tapOnConfirm() { - await Gestures.waitAndTap(this.enable_button, { - elemDescription: 'Confirm Enable Notifications', - }); - } -} - -export default new EnableNotificationsModal(); diff --git a/tests/page-objects/Notifications/NotificationMenuView.ts b/tests/page-objects/Notifications/NotificationMenuView.ts index b5aa3dc3382..47b7cd910bd 100644 --- a/tests/page-objects/Notifications/NotificationMenuView.ts +++ b/tests/page-objects/Notifications/NotificationMenuView.ts @@ -5,7 +5,7 @@ import { import Gestures from '../../framework/Gestures'; import Matchers from '../../framework/Matchers'; -class EnableNotificationsModal { +class NotificationMenuView { get title() { return Matchers.getElementByID(NotificationMenuViewSelectorsIDs.TITLE); } @@ -53,4 +53,4 @@ class EnableNotificationsModal { } } -export default new EnableNotificationsModal(); +export default new NotificationMenuView(); diff --git a/tests/page-objects/Notifications/NotificationSettingsView.ts b/tests/page-objects/Notifications/NotificationSettingsView.ts deleted file mode 100644 index 0ab47d04412..00000000000 --- a/tests/page-objects/Notifications/NotificationSettingsView.ts +++ /dev/null @@ -1,156 +0,0 @@ -import { - NotificationSettingsViewSelectorsIDs, - NotificationSettingsViewSelectorsText, -} from '../../../app/components/Views/Settings/NotificationsSettings/NotificationSettingsView.testIds'; -import Gestures from '../../framework/Gestures'; -import Matchers from '../../framework/Matchers'; -import { Assertions, Utilities } from '../../framework'; - -type ToggleState = 'on' | 'off'; - -interface ToggleConfig { - element: DetoxElement; - description: string; - elemDescription: string; -} - -class NotificationsSettingsView { - get notificationToggle() { - return Matchers.getElementByID( - NotificationSettingsViewSelectorsIDs.NOTIFICATIONS_TOGGLE, - ); - } - - get pushNotificationsToggle() { - return Matchers.getElementByID( - NotificationSettingsViewSelectorsIDs.PUSH_NOTIFICATIONS_TOGGLE, - ); - } - - get featureAnnouncementsToggle() { - return Matchers.getElementByID( - NotificationSettingsViewSelectorsIDs.FEATURE_ANNOUNCEMENTS_TOGGLE, - ); - } - - get featureAnnouncementSeparator() { - return Matchers.getElementByID( - NotificationSettingsViewSelectorsIDs.FEATURE_ANNOUNCEMENT_SEPARATOR, - ); - } - - get accountActivitySection() { - return Matchers.getElementByText( - NotificationSettingsViewSelectorsText.ACCOUNT_ACTIVITY_SECTION, - ); - } - - accountNotificationToggle(address: string) { - return Matchers.getElementByID( - NotificationSettingsViewSelectorsIDs.ACCOUNT_NOTIFICATION_TOGGLE(address), - ); - } - - private async toggleElement( - config: ToggleConfig, - expectedToggleState: ToggleState = 'on', - ) { - return Utilities.executeWithRetry( - async () => { - const assertOn = Assertions.expectToggleToBeOn; - const assertOff = Assertions.expectToggleToBeOff; - - // Short read with graceful fallback on platforms where toggle state is flaky - const isAlreadyInState = async (): Promise => { - try { - if (expectedToggleState === 'on') { - await assertOn(config.element, { timeout: 500 }); - } else { - await assertOff(config.element, { timeout: 500 }); - } - return true; - } catch { - return false; - } - }; - - if (await isAlreadyInState()) { - return; - } - - await Gestures.waitAndTap(config.element, { - timeout: 3000, - checkEnabled: false, - elemDescription: config.elemDescription, - }); - - // Verify expected state with a more generous timeout - if (expectedToggleState === 'on') { - await assertOn(config.element, { timeout: 5000 }); - } else { - await assertOff(config.element, { timeout: 5000 }); - } - }, - { - timeout: 30000, - description: `${config.description} and verify it is ${expectedToggleState}`, - elemDescription: config.elemDescription, - }, - ); - } - - // Checking the toggle state within the method due to flaky behavior - - async tapPushNotificationsToggleAndVerifyState( - expectedToggleState: ToggleState, - ) { - return this.toggleElement( - { - element: this.pushNotificationsToggle, - description: 'Tap Push Notifications Toggle', - elemDescription: 'Notification Settings - Push Notifications Toggle', - }, - expectedToggleState, - ); - } - - async tapNotificationToggleAndVerifyState(expectedToggleState: ToggleState) { - return this.toggleElement( - { - element: this.notificationToggle, - description: 'Tap Notification Toggle', - elemDescription: 'Notification Settings - Main Toggle', - }, - expectedToggleState, - ); - } - - async tapFeatureAnnouncementsToggleAndVerifyState( - expectedToggleState: ToggleState, - ) { - return this.toggleElement( - { - element: this.featureAnnouncementsToggle, - description: 'Tap Feature Announcements Toggle', - elemDescription: 'Notification Settings - Feature Announcements Toggle', - }, - expectedToggleState, - ); - } - - async tapAccountNotificationsToggleAndVerifyState( - address: string, - expectedToggleState: ToggleState, - ) { - return this.toggleElement( - { - element: this.accountNotificationToggle(address), - description: 'Tap Account Notifications Toggle', - elemDescription: `Notification Settings - Account Notifications Toggle for ${address}`, - }, - expectedToggleState, - ); - } -} - -export default new NotificationsSettingsView(); diff --git a/tests/smoke/card/card-button.spec.ts b/tests/smoke/card/card-button.spec.ts deleted file mode 100644 index e7ffec531be..00000000000 --- a/tests/smoke/card/card-button.spec.ts +++ /dev/null @@ -1,50 +0,0 @@ -import WalletView from '../../page-objects/wallet/WalletView'; -import { SmokeMoney } from '../../tags'; -import Assertions from '../../framework/Assertions'; -import { loginToApp } from '../../flows/wallet.flow'; -import { withFixtures } from '../../framework/fixtures/FixtureHelper'; -import FixtureBuilder from '../../framework/fixtures/FixtureBuilder'; -import { testSpecificMock } from '../../api-mocking/mock-responses/cardholder-mocks'; -import CardHomeView from '../../page-objects/Card/CardHomeView'; -import { CustomNetworks } from '../../resources/networks.e2e'; -import { cardButtonExpectations } from '../../helpers/analytics/expectations/card-button.analytics'; - -describe(SmokeMoney('Card NavBar Button'), () => { - beforeEach(async () => { - jest.setTimeout(150000); - }); - - it('opens Card Home when pressing card navbar button', async () => { - await withFixtures( - { - fixture: new FixtureBuilder() - .withMetaMetricsOptIn() - .withNetworkController(CustomNetworks.Tenderly.Linea.providerConfig) - .withAccountTreeController() - .withTokens( - [ - { - address: '0x176211869cA2b568f2A7D4EE941E073a821EE1ff', - decimals: 18, - symbol: 'USDC', - chainId: '0xe708', - name: 'USDCoin', - }, - ], - '0xe708', - ) - .withCardController() - .build(), - restartDevice: true, - testSpecificMock, - analyticsExpectations: cardButtonExpectations, - }, - async () => { - await loginToApp(); - await Assertions.expectElementToBeVisible(WalletView.navbarCardButton); - await WalletView.tapNavbarCardButton(); - await Assertions.expectElementToBeVisible(CardHomeView.cardViewTitle); - }, - ); - }); -}); diff --git a/tests/smoke/notifications/notification-settings-flow.spec.ts b/tests/smoke/notifications/notification-settings-flow.spec.ts deleted file mode 100644 index b4dba61cb06..00000000000 --- a/tests/smoke/notifications/notification-settings-flow.spec.ts +++ /dev/null @@ -1,95 +0,0 @@ -/* eslint-disable jest/no-disabled-tests -- E2E skipped; covered by component view tests */ -import { SmokeNetworkAbstractions } from '../../tags'; -import Assertions from '../../framework/Assertions'; -import { withFixtures } from '../../framework/fixtures/FixtureHelper'; -import FixtureBuilder, { - DEFAULT_FIXTURE_ACCOUNT_CHECKSUM, -} from '../../framework/fixtures/FixtureBuilder'; -import { loginToApp } from '../../flows/wallet.flow'; -import TabBarComponent from '../../page-objects/wallet/TabBarComponent'; -import SettingsView from '../../page-objects/Settings/SettingsView'; -import NotificationSettingsView from '../../page-objects/Notifications/NotificationSettingsView'; -import { Gestures } from '../../framework'; - -describe(SmokeNetworkAbstractions('Notification Onboarding'), () => { - beforeAll(async () => { - jest.setTimeout(170000); - }); - - it.skip('should enable notifications and toggle feature announcements and account notifications', async () => { - await withFixtures( - { - fixture: new FixtureBuilder().withDefaultFixture().build(), - restartDevice: true, - permissions: { - notifications: 'YES', - }, - }, - async () => { - await loginToApp(); - - // Navigate to notification settings - await TabBarComponent.tapSettings(); - await SettingsView.tapNotifications(); - - // Verify initial state - notifications should be enabled - await Assertions.expectToggleToBeOn( - NotificationSettingsView.notificationToggle, - ); - - // Test push notifications toggle functionality - // On iOS this is OS-gated and flaky in CI; exercise only on Android - if (device.getPlatform() === 'android') { - await NotificationSettingsView.tapPushNotificationsToggleAndVerifyState( - 'off', - ); - await NotificationSettingsView.tapPushNotificationsToggleAndVerifyState( - 'on', - ); - } - - // Test feature announcements toggle functionality - await NotificationSettingsView.tapFeatureAnnouncementsToggleAndVerifyState( - 'off', - ); - await NotificationSettingsView.tapFeatureAnnouncementsToggleAndVerifyState( - 'on', - ); - - await Gestures.swipe( - NotificationSettingsView.featureAnnouncementSeparator, - 'up', - ); - - // Test account notifications toggle functionality - await NotificationSettingsView.tapAccountNotificationsToggleAndVerifyState( - DEFAULT_FIXTURE_ACCOUNT_CHECKSUM, - 'off', - ); - await NotificationSettingsView.tapAccountNotificationsToggleAndVerifyState( - DEFAULT_FIXTURE_ACCOUNT_CHECKSUM, - 'on', - ); - - await Gestures.swipe( - NotificationSettingsView.featureAnnouncementSeparator, - 'down', - ); - - // Disable main toggle and verify all sub-settings are hidden - await NotificationSettingsView.tapNotificationToggleAndVerifyState( - 'off', - ); - await Assertions.expectElementToNotBeVisible( - NotificationSettingsView.pushNotificationsToggle, - ); - await Assertions.expectElementToNotBeVisible( - NotificationSettingsView.featureAnnouncementsToggle, - ); - await Assertions.expectElementToNotBeVisible( - NotificationSettingsView.accountActivitySection, - ); - }, - ); - }); -});