diff --git a/.github/workflows/performance-test-runner.yml b/.github/workflows/performance-test-runner.yml index 26e147055475..ccbee938c5be 100644 --- a/.github/workflows/performance-test-runner.yml +++ b/.github/workflows/performance-test-runner.yml @@ -40,6 +40,11 @@ on: type: string default: test description: 'Sentry DSN target: test or real' + build_variant: + required: false + type: string + default: rc + description: 'Build variant for app artifacts (rc or exp)' secrets: BROWSERSTACK_USERNAME: required: true @@ -163,6 +168,12 @@ jobs: SENTRY_REAL_DSN="${{ secrets.MM_SENTRY_DSN }}" SELECTED_SENTRY_DSN="" SENTRY_ENVIRONMENT="github-actions-performance-e2e" + BUILD_VARIANT="${{ inputs.build_variant }}" + + if [[ "$BUILD_VARIANT" != "rc" && "$BUILD_VARIANT" != "exp" ]]; then + echo "❌ Invalid build_variant '$BUILD_VARIANT'. Expected 'rc' or 'exp'." + exit 1 + fi # Validate that we have a BrowserStack URL if [ -z "${{ inputs.browserstack_app_url }}" ]; then @@ -210,6 +221,7 @@ jobs: echo "E2E_PERFORMANCE_SENTRY_DSN=$SELECTED_SENTRY_DSN" echo "E2E_PERFORMANCE_SENTRY_ENVIRONMENT=$SENTRY_ENVIRONMENT" echo "E2E_PERFORMANCE_SENTRY_RELEASE=${{ github.sha }}" + echo "E2E_PERFORMANCE_BUILD_VARIANT=$BUILD_VARIANT" echo "DISABLE_VIDEO_DOWNLOAD=true" } >> "$GITHUB_ENV" diff --git a/.github/workflows/run-performance-e2e.yml b/.github/workflows/run-performance-e2e.yml index 7e01251a6f58..c7f4203bc1ef 100644 --- a/.github/workflows/run-performance-e2e.yml +++ b/.github/workflows/run-performance-e2e.yml @@ -235,6 +235,7 @@ jobs: platform: android build_type: onboarding sentry_target: ${{ inputs.sentry_target || 'test' }} + build_variant: ${{ inputs.build_variant || 'rc' }} device_matrix: ${{ needs.read-device-matrix.outputs.android_matrix }} browserstack_app_url: ${{ needs.trigger-android-dual-versions.outputs.without-srp-browserstack-url || inputs.browserstack_app_url_android_onboarding }} app_version: ${{ needs.trigger-android-dual-versions.outputs.without-srp-version || 'Manual-Input' }} @@ -257,6 +258,7 @@ jobs: platform: ios build_type: onboarding sentry_target: ${{ inputs.sentry_target || 'test' }} + build_variant: ${{ inputs.build_variant || 'rc' }} device_matrix: ${{ needs.read-device-matrix.outputs.ios_matrix }} browserstack_app_url: ${{ needs.trigger-ios-dual-versions.outputs.without-srp-browserstack-url || inputs.browserstack_app_url_ios_onboarding }} app_version: ${{ needs.trigger-ios-dual-versions.outputs.without-srp-version || 'Manual-Input' }} @@ -295,6 +297,7 @@ jobs: platform: android build_type: imported-wallet sentry_target: ${{ inputs.sentry_target || 'test' }} + build_variant: ${{ inputs.build_variant || 'rc' }} device_matrix: ${{ needs.read-device-matrix.outputs.android_matrix }} browserstack_app_url: ${{ needs.trigger-android-dual-versions.outputs.with-srp-browserstack-url || inputs.browserstack_app_url_android_imported_wallet }} app_version: ${{ needs.trigger-android-dual-versions.outputs.with-srp-version || 'Manual-Input' }} @@ -318,6 +321,7 @@ jobs: platform: ios build_type: imported-wallet sentry_target: ${{ inputs.sentry_target || 'test' }} + build_variant: ${{ inputs.build_variant || 'rc' }} device_matrix: ${{ needs.read-device-matrix.outputs.ios_matrix }} browserstack_app_url: ${{ needs.trigger-ios-dual-versions.outputs.with-srp-browserstack-url || inputs.browserstack_app_url_ios_imported_wallet }} app_version: ${{ needs.trigger-ios-dual-versions.outputs.with-srp-version || 'Manual-Input' }} @@ -377,6 +381,7 @@ jobs: platform: android build_type: mm-connect sentry_target: ${{ inputs.sentry_target || 'test' }} + build_variant: ${{ inputs.build_variant || 'rc' }} device_matrix: ${{ needs.read-device-matrix.outputs.android_matrix }} browserstack_app_url: ${{ needs.trigger-android-dual-versions.outputs.with-srp-browserstack-url || inputs.browserstack_app_url_android_imported_wallet }} app_version: ${{ needs.trigger-android-dual-versions.outputs.with-srp-version || 'Manual-Input' }} diff --git a/app/components/UI/Bridge/components/BridgeTokenSelector/BridgeTokenSelector.tsx b/app/components/UI/Bridge/components/BridgeTokenSelector/BridgeTokenSelector.tsx index d474e0c41336..db4af91618a4 100644 --- a/app/components/UI/Bridge/components/BridgeTokenSelector/BridgeTokenSelector.tsx +++ b/app/components/UI/Bridge/components/BridgeTokenSelector/BridgeTokenSelector.tsx @@ -420,7 +420,7 @@ export const BridgeTokenSelector: React.FC = () => { > handleInfoButtonPress(item)} iconProps={{ color: IconColor.IconAlternative }} /> diff --git a/app/components/UI/Bridge/components/TokenSelectorItem.tsx b/app/components/UI/Bridge/components/TokenSelectorItem.tsx index 3461fefb76cd..21104d26c354 100644 --- a/app/components/UI/Bridge/components/TokenSelectorItem.tsx +++ b/app/components/UI/Bridge/components/TokenSelectorItem.tsx @@ -158,7 +158,7 @@ const FiatBalanceView = ({ return ( @@ -272,7 +272,7 @@ export const TokenSelectorItem: React.FC = ({ > @@ -297,7 +297,7 @@ export const TokenSelectorItem: React.FC = ({ ) : ( = ({ justifyContent={JustifyContent.spaceBetween} > ({ + getVersion: jest.fn().mockReturnValue('7.70.0'), +})); + jest.mock('./usePerpsPaymentTokens', () => ({ usePerpsPaymentTokens: jest.fn(() => []), })); @@ -18,6 +22,7 @@ function getState( allowlistAssets?: string[]; isTestnet?: boolean; activeProvider?: 'hyperliquid' | 'myx' | 'aggregated'; + defaultPayTokenWhenNoBalanceEnabled?: boolean; } = {}, ) { const { @@ -25,6 +30,7 @@ function getState( allowlistAssets = [], isTestnet = false, activeProvider, + defaultPayTokenWhenNoBalanceEnabled = true, } = overrides; return { engine: { @@ -37,6 +43,10 @@ function getState( RemoteFeatureFlagController: { remoteFeatureFlags: { perpsPayWithAnyTokenAllowlistAssets: allowlistAssets, + perpsDefaultPayTokenWhenNoBalanceEnabled: + defaultPayTokenWhenNoBalanceEnabled + ? { enabled: true, minimumVersion: '0.0.0' } + : { enabled: false, minimumVersion: '0.0.0' }, }, }, }, @@ -80,6 +90,27 @@ describe('useDefaultPayWithTokenWhenNoPerpsBalance', () => { expect(result.current).toBeNull(); }); + it('returns null when feature flag is disabled', () => { + mockUsePerpsPaymentTokens.mockReturnValue([ + { + address: '0xusdc', + chainId: '0xa4b1', + symbol: 'USDC', + balanceFiat: 'US$500', + decimals: 6, + }, + ] as PerpsToken[]); + + const { result } = runHook( + getState({ + allowlistAssets: ['0xa4b1.0xusdc'], + defaultPayTokenWhenNoBalanceEnabled: false, + }), + ); + + expect(result.current).toBeNull(); + }); + it('returns null when allowlist is empty', () => { const { result } = runHook(getState({ allowlistAssets: [] })); diff --git a/app/components/UI/Perps/hooks/useDefaultPayWithTokenWhenNoPerpsBalance.ts b/app/components/UI/Perps/hooks/useDefaultPayWithTokenWhenNoPerpsBalance.ts index 5cc8346e582a..ba1bc3765069 100644 --- a/app/components/UI/Perps/hooks/useDefaultPayWithTokenWhenNoPerpsBalance.ts +++ b/app/components/UI/Perps/hooks/useDefaultPayWithTokenWhenNoPerpsBalance.ts @@ -7,7 +7,10 @@ import { PERPS_MIN_BALANCE_THRESHOLD, PROVIDER_CONFIG, } from '../constants/perpsConfig'; -import { selectPerpsPayWithAnyTokenAllowlistAssets } from '../selectors/featureFlags'; +import { + selectPerpsDefaultPayTokenWhenNoBalanceEnabledFlag, + selectPerpsPayWithAnyTokenAllowlistAssets, +} from '../selectors/featureFlags'; import { selectPerpsAccountState, selectPerpsProvider, @@ -21,6 +24,9 @@ import { usePerpsPaymentTokens } from './usePerpsPaymentTokens'; * Otherwise returns null (caller should default to "Perps balance"). */ export function useDefaultPayWithTokenWhenNoPerpsBalance(): PerpsSelectedPaymentToken | null { + const featureEnabled = useSelector( + selectPerpsDefaultPayTokenWhenNoBalanceEnabledFlag, + ); const perpsAccount = useSelector(selectPerpsAccountState); const allowlistAssets = useSelector( selectPerpsPayWithAnyTokenAllowlistAssets, @@ -30,6 +36,9 @@ export function useDefaultPayWithTokenWhenNoPerpsBalance(): PerpsSelectedPayment const paymentTokens = usePerpsPaymentTokens(); return useMemo(() => { + if (!featureEnabled) { + return null; + } const availableBalance = Number.parseFloat( perpsAccount?.availableBalance?.toString() ?? '0', ); @@ -82,6 +91,7 @@ export function useDefaultPayWithTokenWhenNoPerpsBalance(): PerpsSelectedPayment description: top.symbol, }; }, [ + featureEnabled, perpsAccount?.availableBalance, allowlistAssets, activeProvider, diff --git a/app/components/UI/Perps/mocks/remoteFeatureFlagMocks.ts b/app/components/UI/Perps/mocks/remoteFeatureFlagMocks.ts index 2da2ec4a416a..0e0646efd85a 100644 --- a/app/components/UI/Perps/mocks/remoteFeatureFlagMocks.ts +++ b/app/components/UI/Perps/mocks/remoteFeatureFlagMocks.ts @@ -14,4 +14,5 @@ export const mockedPerpsFeatureFlagsEnabledState: Record< perpsOrderBookEnabled: mockEnabledPerpsLDFlag, perpsFeedbackEnabled: mockEnabledPerpsLDFlag, perpsMyxProviderEnabled: mockEnabledPerpsLDFlag, + perpsDefaultPayTokenWhenNoBalanceEnabled: mockEnabledPerpsLDFlag, }; diff --git a/app/components/UI/Perps/selectors/featureFlags/index.test.ts b/app/components/UI/Perps/selectors/featureFlags/index.test.ts index 179b31f357cf..bb44ee4b1030 100644 --- a/app/components/UI/Perps/selectors/featureFlags/index.test.ts +++ b/app/components/UI/Perps/selectors/featureFlags/index.test.ts @@ -5,6 +5,7 @@ import { selectPerpsOrderBookEnabledFlag, selectPerpsButtonColorTestVariant, selectHip3ConfigVersion, + selectPerpsDefaultPayTokenWhenNoBalanceEnabledFlag, selectPerpsFeedbackEnabledFlag, selectPerpsTradeWithAnyTokenEnabledFlag, selectPerpsPayWithAnyTokenAllowlistAssets, @@ -894,6 +895,99 @@ describe('Perps Feature Flag Selectors', () => { }); }); + describe('selectPerpsDefaultPayTokenWhenNoBalanceEnabledFlag', () => { + const createEmptyFlagsState = () => ({ + engine: { + backgroundState: { + RemoteFeatureFlagController: { + remoteFeatureFlags: {}, + cacheTimestamp: 0, + }, + }, + }, + }); + + it('returns true when remote flag is not set (default)', () => { + const result = selectPerpsDefaultPayTokenWhenNoBalanceEnabledFlag( + createEmptyFlagsState(), + ); + expect(result).toBe(true); + }); + + it('uses remote flag when valid and enabled', () => { + mockHasMinimumRequiredVersion.mockReturnValue(true); + + const stateWithEnabledRemoteFlag = { + engine: { + backgroundState: { + RemoteFeatureFlagController: { + remoteFeatureFlags: { + perpsDefaultPayTokenWhenNoBalanceEnabled: { + enabled: true, + minimumVersion: '1.0.0', + }, + }, + cacheTimestamp: 0, + }, + }, + }, + }; + + const result = selectPerpsDefaultPayTokenWhenNoBalanceEnabledFlag( + stateWithEnabledRemoteFlag, + ); + expect(result).toBe(true); + }); + + it('uses remote flag when valid but disabled', () => { + mockHasMinimumRequiredVersion.mockReturnValue(true); + + const stateWithDisabledRemoteFlag = { + engine: { + backgroundState: { + RemoteFeatureFlagController: { + remoteFeatureFlags: { + perpsDefaultPayTokenWhenNoBalanceEnabled: { + enabled: false, + minimumVersion: '1.0.0', + }, + }, + cacheTimestamp: 0, + }, + }, + }, + }; + + const result = selectPerpsDefaultPayTokenWhenNoBalanceEnabledFlag( + stateWithDisabledRemoteFlag, + ); + expect(result).toBe(false); + }); + + it('returns true when remote flag is invalid (default fallback)', () => { + const stateWithInvalidRemoteFlag = { + engine: { + backgroundState: { + RemoteFeatureFlagController: { + remoteFeatureFlags: { + perpsDefaultPayTokenWhenNoBalanceEnabled: { + enabled: 'invalid', + minimumVersion: 123, + }, + }, + cacheTimestamp: 0, + }, + }, + }, + }; + + const result = selectPerpsDefaultPayTokenWhenNoBalanceEnabledFlag( + stateWithInvalidRemoteFlag, + ); + expect(result).toBe(true); + }); + }); + describe('selectPerpsRewardsReferralCodeEnabledFlag', () => { it('returns false when flag is not set', () => { const result = selectPerpsRewardsReferralCodeEnabledFlag( diff --git a/app/components/UI/Perps/selectors/featureFlags/index.ts b/app/components/UI/Perps/selectors/featureFlags/index.ts index c7b7648478a2..009c5f9c8771 100644 --- a/app/components/UI/Perps/selectors/featureFlags/index.ts +++ b/app/components/UI/Perps/selectors/featureFlags/index.ts @@ -278,3 +278,20 @@ export const selectPerpsMYXProviderEnabledFlag = createSelector( selectRemoteFeatureFlags, (remoteFeatureFlags) => resolvePerpsMyxProviderEnabled(remoteFeatureFlags), ); + +/** + * Selector for default pay token when no perps balance feature flag. + * When enabled: preselect allowlist token with highest balance in Pay row when user has no perps balance, + * and show "Add funds" CTA on market details when no token can be preselected. + * When disabled: no default token preselection and no Add funds CTA (legacy behavior). + * Controlled only by remote flag; when remote is missing or invalid, defaults to true. + * + * @returns boolean - true if feature is enabled, false otherwise + */ +export const selectPerpsDefaultPayTokenWhenNoBalanceEnabledFlag = + createSelector(selectRemoteFeatureFlags, (remoteFeatureFlags) => { + const remoteFlag = + remoteFeatureFlags?.perpsDefaultPayTokenWhenNoBalanceEnabled as unknown as VersionGatedFeatureFlag; + + return validatedVersionGatedFeatureFlag(remoteFlag) ?? true; + }); diff --git a/app/components/UI/Transactions/index.js b/app/components/UI/Transactions/index.js index f2648e414b2e..0f77cbb705cd 100644 --- a/app/components/UI/Transactions/index.js +++ b/app/components/UI/Transactions/index.js @@ -204,12 +204,9 @@ class Transactions extends PureComponent { ready: false, refreshing: false, cancelIsOpen: false, - cancel1559IsOpen: false, - cancelConfirmDisabled: false, speedUpIsOpen: false, - speedUp1559IsOpen: false, retryIsOpen: false, - speedUpConfirmDisabled: false, + confirmDisabled: false, rpcBlockExplorer: undefined, errorMsg: undefined, isQRHardwareAccount: false, @@ -281,8 +278,7 @@ class Transactions extends PureComponent { ({ id }) => id === this.existingTx?.id, ) ) { - this.onSpeedUpCompleted(); - this.onCancelCompleted(); + this.closeSpeedUpCancelModal(); } } @@ -424,7 +420,7 @@ class Transactions extends PureComponent { onSpeedUpAction = (speedUpAction, tx) => { if (!speedUpAction) { - this.setState({ speedUp1559IsOpen: false, speedUpIsOpen: false }); + this.setState({ speedUpIsOpen: false, cancelIsOpen: false }); this.speedUpTxId = null; this.existingTx = null; return; @@ -432,23 +428,28 @@ class Transactions extends PureComponent { if (!tx) return; this.speedUpTxId = tx.id; this.existingTx = tx; - const speedUpConfirmDisabled = validateTransactionActionBalance( + const confirmDisabled = validateTransactionActionBalance( tx, SPEED_UP_RATE, this.props.accounts, ); - this.setState({ speedUpIsOpen: speedUpAction, speedUpConfirmDisabled }); + this.setState({ + speedUpIsOpen: true, + cancelIsOpen: false, + confirmDisabled, + }); }; - onSpeedUpCompleted = () => { - this.setState({ speedUp1559IsOpen: false, speedUpIsOpen: false }); + closeSpeedUpCancelModal = () => { + this.setState({ speedUpIsOpen: false, cancelIsOpen: false }); this.speedUpTxId = null; + this.cancelTxId = null; this.existingTx = null; }; onCancelAction = (cancelAction, tx) => { if (!cancelAction) { - this.setState({ cancel1559IsOpen: false, cancelIsOpen: false }); + this.setState({ speedUpIsOpen: false, cancelIsOpen: false }); this.cancelTxId = null; this.existingTx = null; return; @@ -456,18 +457,16 @@ class Transactions extends PureComponent { if (!tx) return; this.cancelTxId = tx.id; this.existingTx = tx; - const cancelConfirmDisabled = validateTransactionActionBalance( + const confirmDisabled = validateTransactionActionBalance( tx, CANCEL_RATE, this.props.accounts, ); - this.setState({ cancelIsOpen: cancelAction, cancelConfirmDisabled }); - }; - - onCancelCompleted = () => { - this.setState({ cancel1559IsOpen: false, cancelIsOpen: false }); - this.cancelTxId = null; - this.existingTx = null; + this.setState({ + speedUpIsOpen: false, + cancelIsOpen: true, + confirmDisabled, + }); }; getParamsToSend = (transactionObject) => { @@ -503,10 +502,7 @@ class Transactions extends PureComponent { const message = e instanceof TransactionError ? e.message : undefined; Logger.error(e, { message: `speedUpTransaction failed `, speedUpTxId }); InteractionManager.runAfterInteractions(this.toggleRetry(message)); - this.setState({ - speedUp1559IsOpen: false, - speedUpIsOpen: false, - }); + this.setState({ speedUpIsOpen: false, cancelIsOpen: false }); }; handleCancelTransactionFailure = (e) => { @@ -514,10 +510,7 @@ class Transactions extends PureComponent { const message = e instanceof TransactionError ? e.message : undefined; Logger.error(e, { message: `cancelTransaction failed `, cancelTxId }); InteractionManager.runAfterInteractions(this.toggleRetry(message)); - this.setState({ - cancel1559IsOpen: false, - cancelIsOpen: false, - }); + this.setState({ speedUpIsOpen: false, cancelIsOpen: false }); }; speedUpTransaction = async (transactionObject) => { @@ -546,7 +539,7 @@ class Transactions extends PureComponent { } else { await speedUpTransaction(this.speedUpTxId, params); } - this.onSpeedUpCompleted(); + this.closeSpeedUpCancelModal(); } catch (e) { this.handleSpeedUpTransactionFailure(e); } @@ -571,10 +564,7 @@ class Transactions extends PureComponent { const onConfirmation = (isComplete) => { if (isComplete) { - transaction.speedUpParams && - transaction.speedUpParams?.type === 'SpeedUp' - ? this.onSpeedUpCompleted() - : this.onCancelCompleted(); + this.closeSpeedUpCancelModal(); } }; @@ -625,7 +615,7 @@ class Transactions extends PureComponent { params, ); } - this.onCancelCompleted(); + this.closeSpeedUpCancelModal(); } catch (e) { this.handleCancelTransactionFailure(e); } @@ -701,7 +691,7 @@ class Transactions extends PureComponent { header, isSigningQRObject, } = this.props; - const { cancelConfirmDisabled, speedUpConfirmDisabled } = this.state; + const { confirmDisabled } = this.state; const { colors } = this.context || mockTheme; const styles = createStyles(colors); @@ -755,22 +745,16 @@ class Transactions extends PureComponent { {!isSigningQRObject && ( - )} - {!isSigningQRObject && ( - )} diff --git a/app/components/UI/Transactions/index.test.tsx b/app/components/UI/Transactions/index.test.tsx index 0adbedad31a3..e83af62696ac 100644 --- a/app/components/UI/Transactions/index.test.tsx +++ b/app/components/UI/Transactions/index.test.tsx @@ -19,6 +19,7 @@ import NotificationManager from '../../../core/NotificationManager'; import { updateIncomingTransactions } from '../../../util/transaction-controller'; import Engine from '../../../core/Engine'; import Logger from '../../../util/Logger'; +import { CancelSpeedupModal } from '../../../components/Views/confirmations/components/modals/cancel-speedup-modal'; // Mock the navigation and other dependencies const mockNavigationPush = jest.fn(); @@ -1549,37 +1550,25 @@ describe('UnconnectedTransactions Component Direct Method Testing', () => { expect(instance.cancelTxId).toBe('tx-456'); expect(instance.existingTx).toBe(tx); expect(instance.setState).toHaveBeenCalledWith({ - cancelConfirmDisabled: false, + speedUpIsOpen: false, cancelIsOpen: true, + confirmDisabled: false, }); }); - it('should test onSpeedUpCompleted method directly', () => { + it('should test closeSpeedUpCancelModal method directly', () => { instance.setState = jest.fn(); instance.speedUpTxId = 'tx-123'; + instance.cancelTxId = 'tx-456'; instance.existingTx = { id: 'tx-123' }; - instance.onSpeedUpCompleted(); + instance.closeSpeedUpCancelModal(); expect(instance.setState).toHaveBeenCalledWith({ - speedUp1559IsOpen: false, speedUpIsOpen: false, - }); - expect(instance.speedUpTxId).toBeNull(); - expect(instance.existingTx).toBeNull(); - }); - - it('should test onCancelCompleted method directly', () => { - instance.setState = jest.fn(); - instance.cancelTxId = 'tx-456'; - instance.existingTx = { id: 'tx-456' }; - - instance.onCancelCompleted(); - - expect(instance.setState).toHaveBeenCalledWith({ - cancel1559IsOpen: false, cancelIsOpen: false, }); + expect(instance.speedUpTxId).toBeNull(); expect(instance.cancelTxId).toBeNull(); expect(instance.existingTx).toBeNull(); }); @@ -1861,8 +1850,7 @@ describe('UnconnectedTransactions Component Direct Method Testing', () => { it('should test componentDidUpdate method directly', () => { instance.updateBlockExplorer = jest.fn(); - instance.onSpeedUpCompleted = jest.fn(); - instance.onCancelCompleted = jest.fn(); + instance.closeSpeedUpCancelModal = jest.fn(); instance.existingTx = { id: 'tx-123' }; instance.props = { ...defaultTestProps, @@ -1872,8 +1860,7 @@ describe('UnconnectedTransactions Component Direct Method Testing', () => { instance.componentDidUpdate(); expect(instance.updateBlockExplorer).toHaveBeenCalled(); - expect(instance.onSpeedUpCompleted).toHaveBeenCalled(); - expect(instance.onCancelCompleted).toHaveBeenCalled(); + expect(instance.closeSpeedUpCancelModal).toHaveBeenCalled(); }); it('should test init method directly', () => { @@ -1939,7 +1926,7 @@ describe('UnconnectedTransactions Component Direct Method Testing', () => { maxFeePerGas: '0x123', maxPriorityFeePerGas: '0x456', }); - instance.onSpeedUpCompleted = jest.fn(); + instance.closeSpeedUpCancelModal = jest.fn(); const transactionObject = { maxFeePerGas: '0x123', @@ -1948,7 +1935,7 @@ describe('UnconnectedTransactions Component Direct Method Testing', () => { await instance.speedUpTransaction(transactionObject); - expect(instance.onSpeedUpCompleted).toHaveBeenCalled(); + expect(instance.closeSpeedUpCancelModal).toHaveBeenCalled(); }); it('should test cancelTransaction method directly', async () => { @@ -1958,7 +1945,7 @@ describe('UnconnectedTransactions Component Direct Method Testing', () => { maxFeePerGas: '0x123', maxPriorityFeePerGas: '0x456', }); - instance.onCancelCompleted = jest.fn(); + instance.closeSpeedUpCancelModal = jest.fn(); const transactionObject = { maxFeePerGas: '0x123', @@ -1970,7 +1957,7 @@ describe('UnconnectedTransactions Component Direct Method Testing', () => { expect( Engine.context.TransactionController.stopTransaction, ).toHaveBeenCalled(); - expect(instance.onCancelCompleted).toHaveBeenCalled(); + expect(instance.closeSpeedUpCancelModal).toHaveBeenCalled(); }); it('should test renderLoader method directly', () => { @@ -2052,6 +2039,56 @@ describe('UnconnectedTransactions Component Direct Method Testing', () => { expect(result).toBeDefined(); }); + it('renders single CancelSpeedupModal with correct props when speed up or cancel is open', () => { + instance.context = { + colors: { + background: { default: '#fff' }, + text: { muted: '#999' }, + primary: { default: '#037dd6' }, + icon: { default: '#24272a' }, + }, + typography: {}, + }; + instance.state = { + refreshing: false, + confirmDisabled: false, + }; + instance.props = { + ...defaultTestProps, + submittedTransactions: [], + confirmedTransactions: [], + transactions: [{ id: 'tx-1' }], + isSigningQRObject: false, + }; + instance.existingTx = { id: 'tx-1', chainId: '0x1' }; + + // When both closed: modal mounted but not visible (exit animation can run) + instance.state.speedUpIsOpen = false; + instance.state.cancelIsOpen = false; + let listResult = instance.renderList(); + let listWrapper = shallow(listResult); + expect(listWrapper.find(CancelSpeedupModal)).toHaveLength(1); + expect(listWrapper.find(CancelSpeedupModal).prop('isVisible')).toBe(false); + + // When speed up open: one modal, isVisible true, isCancel false + instance.state.speedUpIsOpen = true; + instance.state.cancelIsOpen = false; + listResult = instance.renderList(); + listWrapper = shallow(listResult); + expect(listWrapper.find(CancelSpeedupModal)).toHaveLength(1); + expect(listWrapper.find(CancelSpeedupModal).prop('isVisible')).toBe(true); + expect(listWrapper.find(CancelSpeedupModal).prop('isCancel')).toBe(false); + + // When cancel open: one modal, isVisible true, isCancel true + instance.state.speedUpIsOpen = false; + instance.state.cancelIsOpen = true; + listResult = instance.renderList(); + listWrapper = shallow(listResult); + expect(listWrapper.find(CancelSpeedupModal)).toHaveLength(1); + expect(listWrapper.find(CancelSpeedupModal).prop('isVisible')).toBe(true); + expect(listWrapper.find(CancelSpeedupModal).prop('isCancel')).toBe(true); + }); + it('should test render method directly', () => { instance.context = { colors: { @@ -2062,8 +2099,6 @@ describe('UnconnectedTransactions Component Direct Method Testing', () => { }; instance.state = { ready: true, - speedUp1559IsOpen: false, - cancel1559IsOpen: false, retryIsOpen: false, errorMsg: null, }; @@ -2302,7 +2337,7 @@ describe('UnconnectedTransactions Component Direct Method Testing', () => { mockIsHardwareAccount.mockReturnValue(true); instance.speedUpTxId = 'tx-123'; instance.signLedgerTransaction = jest.fn().mockResolvedValue(undefined); - instance.onSpeedUpCompleted = jest.fn(); + instance.closeSpeedUpCancelModal = jest.fn(); const transactionObject = { suggestedMaxFeePerGasHex: '123', @@ -2317,7 +2352,7 @@ describe('UnconnectedTransactions Component Direct Method Testing', () => { mockIsHardwareAccount.mockReturnValue(true); instance.cancelTxId = 'tx-456'; instance.signLedgerTransaction = jest.fn().mockResolvedValue(undefined); - instance.onCancelCompleted = jest.fn(); + instance.closeSpeedUpCancelModal = jest.fn(); await instance.cancelTransaction(transactionObject); diff --git a/app/components/Views/UnifiedTransactionsView/UnifiedTransactionsView.test.tsx b/app/components/Views/UnifiedTransactionsView/UnifiedTransactionsView.test.tsx index 11631db31a6a..5ee291123d80 100644 --- a/app/components/Views/UnifiedTransactionsView/UnifiedTransactionsView.test.tsx +++ b/app/components/Views/UnifiedTransactionsView/UnifiedTransactionsView.test.tsx @@ -1,10 +1,12 @@ import React, { ComponentType } from 'react'; +import { RefreshControl } from 'react-native'; import { TransactionStatus } from '@metamask/transaction-controller'; import { Hex } from '@metamask/utils'; import UnifiedTransactionsView from './UnifiedTransactionsView'; import renderWithProvider from '../../../util/test/renderWithProvider'; import { backgroundState } from '../../../util/test/initial-root-state'; import { updateIncomingTransactions } from '../../../util/transaction-controller'; +import { useUnifiedTxActions } from './useUnifiedTxActions'; // Type helper for UNSAFE_queryByType with mocked string components const asComponentType = (name: string) => name as unknown as ComponentType; @@ -53,30 +55,28 @@ jest.mock('../../UI/Bridge/hooks/useBridgeHistoryItemBySrcTxHash', () => ({ }), })); +const mockDefaultUnifiedTxActionsReturn = { + retryIsOpen: false, + retryErrorMsg: '', + speedUpIsOpen: false, + cancelIsOpen: false, + confirmDisabled: false, + existingTx: null, + speedUpTxId: null, + cancelTxId: null, + toggleRetry: jest.fn(), + onSpeedUpAction: jest.fn(), + onCancelAction: jest.fn(), + onSpeedUpCancelCompleted: jest.fn(), + speedUpTransaction: jest.fn(), + cancelTransaction: jest.fn(), + signQRTransaction: jest.fn(), + signLedgerTransaction: jest.fn(), + cancelUnsignedQRTransaction: jest.fn(), +}; + jest.mock('./useUnifiedTxActions', () => ({ - useUnifiedTxActions: () => ({ - retryIsOpen: false, - retryErrorMsg: '', - speedUpIsOpen: false, - cancelIsOpen: false, - speedUp1559IsOpen: false, - cancel1559IsOpen: false, - speedUpConfirmDisabled: false, - cancelConfirmDisabled: false, - existingTx: null, - speedUpTxId: null, - cancelTxId: null, - toggleRetry: jest.fn(), - onSpeedUpAction: jest.fn(), - onCancelAction: jest.fn(), - onSpeedUpCompleted: jest.fn(), - onCancelCompleted: jest.fn(), - speedUpTransaction: jest.fn(), - cancelTransaction: jest.fn(), - signQRTransaction: jest.fn(), - signLedgerTransaction: jest.fn(), - cancelUnsignedQRTransaction: jest.fn(), - }), + useUnifiedTxActions: jest.fn(() => mockDefaultUnifiedTxActionsReturn), })); jest.mock('./useTransactionAutoScroll', () => ({ @@ -107,14 +107,22 @@ jest.mock('../confirmations/components/modals/cancel-speedup-modal', () => { const ReactActual = jest.requireActual('react'); const { Text } = jest.requireActual('react-native'); return { - CancelSpeedupModal: ({ isCancel }: { isCancel: boolean }) => - ReactActual.createElement( - Text, - { - testID: isCancel ? 'cancel-modal' : 'speedup-modal', - }, - isCancel ? 'Cancel Transaction' : 'Speed Up Transaction', - ), + CancelSpeedupModal: ({ + isVisible, + isCancel, + }: { + isVisible: boolean; + isCancel: boolean; + }) => + isVisible + ? ReactActual.createElement( + Text, + { + testID: isCancel ? 'cancel-modal' : 'speedup-modal', + }, + isCancel ? 'Cancel Transaction' : 'Speed Up Transaction', + ) + : null, }; }); jest.mock('../../UI/Transactions/RetryModal', () => 'RetryModal'); @@ -164,6 +172,9 @@ describe('UnifiedTransactionsView', () => { beforeEach(() => { jest.clearAllMocks(); + (useUnifiedTxActions as jest.Mock).mockImplementation( + () => mockDefaultUnifiedTxActionsReturn, + ); }); afterEach(() => { @@ -313,6 +324,9 @@ describe('UnifiedTransactionsView with transactions', () => { beforeEach(() => { jest.clearAllMocks(); + (useUnifiedTxActions as jest.Mock).mockImplementation( + () => mockDefaultUnifiedTxActionsReturn, + ); }); it('renders TransactionElement for EVM transactions', () => { @@ -332,6 +346,91 @@ describe('UnifiedTransactionsView with transactions', () => { }); }); +describe('UnifiedTransactionsView - Speed up / Cancel modal', () => { + const initialState = { + engine: { + backgroundState, + }, + }; + + beforeEach(() => { + jest.clearAllMocks(); + (useUnifiedTxActions as jest.Mock).mockImplementation( + () => mockDefaultUnifiedTxActionsReturn, + ); + }); + + it('does not render CancelSpeedupModal when both speed up and cancel are closed', () => { + const { queryByTestId } = renderWithProvider(, { + state: initialState, + }); + + expect(queryByTestId('speedup-modal')).toBeNull(); + expect(queryByTestId('cancel-modal')).toBeNull(); + }); + + it('renders CancelSpeedupModal as speed up when speedUpIsOpen is true', () => { + (useUnifiedTxActions as jest.Mock).mockReturnValue({ + ...mockDefaultUnifiedTxActionsReturn, + speedUpIsOpen: true, + existingTx: { id: 'tx-1', chainId: '0x1' }, + }); + + const { getByTestId, getByText } = renderWithProvider( + , + { state: initialState }, + ); + + expect(getByTestId('speedup-modal')).toBeOnTheScreen(); + expect(getByText('Speed Up Transaction')).toBeOnTheScreen(); + }); + + it('renders CancelSpeedupModal as cancel when cancelIsOpen is true', () => { + (useUnifiedTxActions as jest.Mock).mockReturnValue({ + ...mockDefaultUnifiedTxActionsReturn, + cancelIsOpen: true, + existingTx: { id: 'tx-1', chainId: '0x1' }, + }); + + const { getByTestId, getByText } = renderWithProvider( + , + { state: initialState }, + ); + + expect(getByTestId('cancel-modal')).toBeOnTheScreen(); + expect(getByText('Cancel Transaction')).toBeOnTheScreen(); + }); +}); + +describe('UnifiedTransactionsView - refresh', () => { + const initialState = { + engine: { + backgroundState, + }, + }; + + beforeEach(() => { + jest.clearAllMocks(); + (useUnifiedTxActions as jest.Mock).mockImplementation( + () => mockDefaultUnifiedTxActionsReturn, + ); + }); + + it('calls updateIncomingTransactions when refresh is triggered', async () => { + const { UNSAFE_getByType } = renderWithProvider( + , + { state: initialState }, + ); + + const refreshControl = UNSAFE_getByType(RefreshControl); + expect(refreshControl.props.onRefresh).toBeDefined(); + + await refreshControl.props.onRefresh(); + + expect(updateIncomingTransactions).toHaveBeenCalled(); + }); +}); + describe('UnifiedTransactionsView - token poisoning protection', () => { const { buildTrustedAddressSet: mockBuildTrustedAddressSet, @@ -377,6 +476,9 @@ describe('UnifiedTransactionsView - token poisoning protection', () => { beforeEach(() => { jest.clearAllMocks(); + (useUnifiedTxActions as jest.Mock).mockImplementation( + () => mockDefaultUnifiedTxActionsReturn, + ); // Re-set implementations after any prior resetAllMocks() calls (mockBuildTrustedAddressSet as jest.Mock).mockReturnValue( new Set(), diff --git a/app/components/Views/UnifiedTransactionsView/UnifiedTransactionsView.tsx b/app/components/Views/UnifiedTransactionsView/UnifiedTransactionsView.tsx index 6cb11d074a1b..14e6dcc4fb53 100644 --- a/app/components/Views/UnifiedTransactionsView/UnifiedTransactionsView.tsx +++ b/app/components/Views/UnifiedTransactionsView/UnifiedTransactionsView.tsx @@ -536,16 +536,14 @@ const UnifiedTransactionsView = ({ retryErrorMsg, speedUpIsOpen, cancelIsOpen, - speedUpConfirmDisabled, - cancelConfirmDisabled, + confirmDisabled, existingTx, speedUpTxId, cancelTxId, toggleRetry, onSpeedUpAction, onCancelAction, - onSpeedUpCompleted, - onCancelCompleted, + onSpeedUpCancelCompleted, speedUpTransaction, cancelTransaction, signQRTransaction, @@ -678,22 +676,14 @@ const UnifiedTransactionsView = ({ /> )} - {/* Speed up / Cancel modals */} + {/* Speed up / Cancel modals*/} - toggleRetry(undefined)} diff --git a/app/components/Views/UnifiedTransactionsView/useUnifiedTxActions.test.ts b/app/components/Views/UnifiedTransactionsView/useUnifiedTxActions.test.ts index 677b18e557a8..d9c940caf6fd 100644 --- a/app/components/Views/UnifiedTransactionsView/useUnifiedTxActions.test.ts +++ b/app/components/Views/UnifiedTransactionsView/useUnifiedTxActions.test.ts @@ -153,10 +153,7 @@ describe('useUnifiedTxActions', () => { expect(result.current.retryErrorMsg).toBeUndefined(); expect(result.current.speedUpIsOpen).toBe(false); expect(result.current.cancelIsOpen).toBe(false); - expect(result.current.speedUp1559IsOpen).toBe(false); - expect(result.current.cancel1559IsOpen).toBe(false); - expect(result.current.speedUpConfirmDisabled).toBe(false); - expect(result.current.cancelConfirmDisabled).toBe(false); + expect(result.current.confirmDisabled).toBe(false); expect(result.current.existingTx).toBeNull(); expect(result.current.speedUpTxId).toBeNull(); expect(result.current.cancelTxId).toBeNull(); @@ -164,8 +161,7 @@ describe('useUnifiedTxActions', () => { expect(typeof result.current.toggleRetry).toBe('function'); expect(typeof result.current.onSpeedUpAction).toBe('function'); expect(typeof result.current.onCancelAction).toBe('function'); - expect(typeof result.current.onSpeedUpCompleted).toBe('function'); - expect(typeof result.current.onCancelCompleted).toBe('function'); + expect(typeof result.current.onSpeedUpCancelCompleted).toBe('function'); expect(typeof result.current.speedUpTransaction).toBe('function'); expect(typeof result.current.cancelTransaction).toBe('function'); expect(typeof result.current.signQRTransaction).toBe('function'); @@ -190,7 +186,6 @@ describe('useUnifiedTxActions', () => { act(() => result.current.onSpeedUpAction(false)); expect(result.current.speedUpIsOpen).toBe(false); - expect(result.current.speedUp1559IsOpen).toBe(false); }); it('opens speed up modal when isEIP1559Transaction=true', () => { @@ -218,9 +213,8 @@ describe('useUnifiedTxActions', () => { '1.1', expect.any(Object), ); - expect(result.current.speedUpConfirmDisabled).toBe(true); + expect(result.current.confirmDisabled).toBe(true); expect(result.current.speedUpIsOpen).toBe(true); - expect(result.current.speedUp1559IsOpen).toBe(false); }); }); @@ -230,7 +224,6 @@ describe('useUnifiedTxActions', () => { act(() => result.current.onCancelAction(false)); expect(result.current.cancelIsOpen).toBe(false); - expect(result.current.cancel1559IsOpen).toBe(false); }); it('opens cancel modal when isEIP1559Transaction=true', () => { @@ -258,9 +251,8 @@ describe('useUnifiedTxActions', () => { '1.1', expect.any(Object), ); - expect(result.current.cancelConfirmDisabled).toBe(false); + expect(result.current.confirmDisabled).toBe(false); expect(result.current.cancelIsOpen).toBe(true); - expect(result.current.cancel1559IsOpen).toBe(false); }); }); @@ -279,7 +271,6 @@ describe('useUnifiedTxActions', () => { expect(speedUpTx).toHaveBeenCalledWith('5', undefined); expect(result.current.speedUpIsOpen).toBe(false); - expect(result.current.speedUp1559IsOpen).toBe(false); expect(result.current.speedUpTxId).toBeNull(); expect(result.current.existingTx).toBeNull(); }); @@ -334,7 +325,9 @@ describe('useUnifiedTxActions', () => { expect(result.current.retryIsOpen).toBe(true); expect(result.current.retryErrorMsg).toBe('failed'); expect(result.current.speedUpIsOpen).toBe(false); - expect(result.current.speedUp1559IsOpen).toBe(false); + // Tx IDs and existingTx preserved so Retry can reopen the same action + expect(result.current.speedUpTxId).toBe('8'); + expect(result.current.existingTx).toBe(tx); }); it('uses GasFeeController estimates when type is missing', async () => { @@ -386,7 +379,6 @@ describe('useUnifiedTxActions', () => { engineContext.TransactionController.stopTransaction, ).toHaveBeenCalledWith('9', undefined); expect(result.current.cancelIsOpen).toBe(false); - expect(result.current.cancel1559IsOpen).toBe(false); expect(result.current.cancelTxId).toBeNull(); expect(result.current.existingTx).toBeNull(); }); @@ -426,7 +418,9 @@ describe('useUnifiedTxActions', () => { expect(result.current.retryIsOpen).toBe(true); expect(result.current.retryErrorMsg).toBe('nope'); expect(result.current.cancelIsOpen).toBe(false); - expect(result.current.cancel1559IsOpen).toBe(false); + // Tx IDs and existingTx preserved so Retry can reopen the same action + expect(result.current.cancelTxId).toBe('11'); + expect(result.current.existingTx).toBe(tx); }); }); @@ -494,7 +488,6 @@ describe('useUnifiedTxActions', () => { }); expect(result.current.speedUpIsOpen).toBe(false); - expect(result.current.speedUp1559IsOpen).toBe(false); }); it('navigates to ledger modal and resolves completion for cancel', async () => { @@ -528,7 +521,6 @@ describe('useUnifiedTxActions', () => { }); expect(result.current.cancelIsOpen).toBe(false); - expect(result.current.cancel1559IsOpen).toBe(false); }); describe('Ledger account transactions', () => { @@ -577,7 +569,7 @@ describe('useUnifiedTxActions', () => { expect(speedUpTx).not.toHaveBeenCalled(); }); - it('returns early after calling signLedgerTransaction without calling onSpeedUpCompleted', async () => { + it('returns early after calling signLedgerTransaction without calling onSpeedUpCancelCompleted', async () => { const { result } = renderHook(() => useUnifiedTxActions()); const tx = { id: 'ledger-speedup-2' } as unknown as TransactionMeta; @@ -747,7 +739,7 @@ describe('useUnifiedTxActions', () => { ).not.toHaveBeenCalled(); }); - it('returns early after calling signLedgerTransaction without calling onCancelCompleted', async () => { + it('returns early after calling signLedgerTransaction without calling onSpeedUpCancelCompleted for cancel', async () => { const { result } = renderHook(() => useUnifiedTxActions()); const tx = { id: 'ledger-cancel-2' } as unknown as TransactionMeta; diff --git a/app/components/Views/UnifiedTransactionsView/useUnifiedTxActions.ts b/app/components/Views/UnifiedTransactionsView/useUnifiedTxActions.ts index f3bbb290491f..1205f473e687 100644 --- a/app/components/Views/UnifiedTransactionsView/useUnifiedTxActions.ts +++ b/app/components/Views/UnifiedTransactionsView/useUnifiedTxActions.ts @@ -57,6 +57,15 @@ interface LedgerSignRequest { const getErrorMessage = (error: unknown) => error instanceof Error ? error.message : undefined; +export const SpeedUpCancelModalState = { + Closed: 'closed', + SpeedUp: 'speedUp', + Cancel: 'cancel', +} as const; + +export type SpeedUpCancelModalState = + (typeof SpeedUpCancelModalState)[keyof typeof SpeedUpCancelModalState]; + export function useUnifiedTxActions() { const navigation = useNavigation(); @@ -70,12 +79,9 @@ export function useUnifiedTxActions() { const [retryErrorMsg, setRetryErrorMsg] = useState( undefined, ); - const [speedUpIsOpen, setSpeedUpIsOpen] = useState(false); - const [cancelIsOpen, setCancelIsOpen] = useState(false); - const [speedUp1559IsOpen, setSpeedUp1559IsOpen] = useState(false); - const [cancel1559IsOpen, setCancel1559IsOpen] = useState(false); - const [speedUpConfirmDisabled, setSpeedUpConfirmDisabled] = useState(false); - const [cancelConfirmDisabled, setCancelConfirmDisabled] = useState(false); + const [speedUpCancelModalState, setSpeedUpCancelModalState] = + useState(SpeedUpCancelModalState.Closed); + const [confirmDisabled, setConfirmDisabled] = useState(false); const [existingTx, setExistingTx] = useState(null); const [speedUpTxId, setSpeedUpTxId] = useState>(null); const [cancelTxId, setCancelTxId] = useState>(null); @@ -89,20 +95,17 @@ export function useUnifiedTxActions() { setRetryErrorMsg(msg); }; - const onSpeedUpCompleted = useCallback(() => { - setSpeedUp1559IsOpen(false); - setSpeedUpIsOpen(false); + const closeSpeedUpCancelModal = useCallback(() => { + setSpeedUpCancelModalState(SpeedUpCancelModalState.Closed); setSpeedUpTxId(null); - setExistingTx(null); - }, []); - - const onCancelCompleted = useCallback(() => { - setCancel1559IsOpen(false); - setCancelIsOpen(false); setCancelTxId(null); setExistingTx(null); }, []); + const onSpeedUpCancelCompleted = useCallback(() => { + closeSpeedUpCancelModal(); + }, [closeSpeedUpCancelModal]); + const signLedgerTransaction = useCallback( async (transaction: LedgerSignRequest) => { const deviceId = await getDeviceId(); @@ -110,12 +113,7 @@ export function useUnifiedTxActions() { // Clean up modal state regardless of whether the user confirmed or rejected. // Without this, rejecting on the Ledger modal leaves stale state that can // cause the speed up/cancel modal to reappear unexpectedly. - const isSpeedUp = transaction.speedUpParams?.type === 'SpeedUp'; - if (isSpeedUp) { - onSpeedUpCompleted(); - } else { - onCancelCompleted(); - } + onSpeedUpCancelCompleted(); }; navigation.navigate( ...createLedgerTransactionModalNavDetails({ @@ -126,7 +124,7 @@ export function useUnifiedTxActions() { }), ); }, - [navigation, onSpeedUpCompleted, onCancelCompleted], + [navigation, onSpeedUpCancelCompleted], ); const getGasPriceEstimate = () => getMediumGasPriceHex(gasFeeEstimates); @@ -148,8 +146,7 @@ export function useUnifiedTxActions() { const onSpeedUpAction = (open: boolean, tx?: TransactionMeta) => { if (!open) { - setSpeedUpIsOpen(false); - setSpeedUp1559IsOpen(false); + setSpeedUpCancelModalState(SpeedUpCancelModalState.Closed); return; } if (!tx) { @@ -157,17 +154,21 @@ export function useUnifiedTxActions() { } setExistingTx(tx); setSpeedUpTxId(tx.id ?? null); - const disabled = Boolean( - validateTransactionActionBalance(tx, SPEED_UP_RATE.toString(), accounts), + setConfirmDisabled( + Boolean( + validateTransactionActionBalance( + tx, + SPEED_UP_RATE.toString(), + accounts, + ), + ), ); - setSpeedUpConfirmDisabled(disabled); - setSpeedUpIsOpen(true); + setSpeedUpCancelModalState(SpeedUpCancelModalState.SpeedUp); }; const onCancelAction = (open: boolean, tx?: TransactionMeta) => { if (!open) { - setCancelIsOpen(false); - setCancel1559IsOpen(false); + setSpeedUpCancelModalState(SpeedUpCancelModalState.Closed); return; } if (!tx) { @@ -175,11 +176,12 @@ export function useUnifiedTxActions() { } setExistingTx(tx); setCancelTxId(tx.id ?? null); - const disabled = Boolean( - validateTransactionActionBalance(tx, CANCEL_RATE.toString(), accounts), + setConfirmDisabled( + Boolean( + validateTransactionActionBalance(tx, CANCEL_RATE.toString(), accounts), + ), ); - setCancelConfirmDisabled(disabled); - setCancelIsOpen(true); + setSpeedUpCancelModalState(SpeedUpCancelModalState.Cancel); }; const getParamsToSend = ( @@ -229,11 +231,10 @@ export function useUnifiedTxActions() { } await speedUpTx(speedUpTxId, getParamsToSend(params)); - onSpeedUpCompleted(); + onSpeedUpCancelCompleted(); } catch (error: unknown) { toggleRetry(getErrorMessage(error)); - setSpeedUp1559IsOpen(false); - setSpeedUpIsOpen(false); + setSpeedUpCancelModalState(SpeedUpCancelModalState.Closed); } }; @@ -266,11 +267,10 @@ export function useUnifiedTxActions() { cancelTxId, getParamsToSend(params), ); - onCancelCompleted(); + onSpeedUpCancelCompleted(); } catch (error: unknown) { toggleRetry(getErrorMessage(error)); - setCancel1559IsOpen(false); - setCancelIsOpen(false); + setSpeedUpCancelModalState(SpeedUpCancelModalState.Closed); } }; @@ -298,20 +298,16 @@ export function useUnifiedTxActions() { return { retryIsOpen, retryErrorMsg, - speedUpIsOpen, - cancelIsOpen, - speedUp1559IsOpen, - cancel1559IsOpen, - speedUpConfirmDisabled, - cancelConfirmDisabled, + speedUpIsOpen: speedUpCancelModalState === SpeedUpCancelModalState.SpeedUp, + cancelIsOpen: speedUpCancelModalState === SpeedUpCancelModalState.Cancel, + confirmDisabled, existingTx, speedUpTxId, cancelTxId, toggleRetry, onSpeedUpAction, onCancelAction, - onSpeedUpCompleted, - onCancelCompleted, + onSpeedUpCancelCompleted, speedUpTransaction, cancelTransaction, signQRTransaction, diff --git a/app/components/Views/Wallet/hooks/useBalanceRefresh.test.ts b/app/components/Views/Wallet/hooks/useBalanceRefresh.test.ts index 623564fc590d..d28d8cc3f67d 100644 --- a/app/components/Views/Wallet/hooks/useBalanceRefresh.test.ts +++ b/app/components/Views/Wallet/hooks/useBalanceRefresh.test.ts @@ -38,6 +38,10 @@ jest.mock('../../../../selectors/networkEnablementController', () => ({ selectEVMEnabledNetworks: jest.fn(() => []), })); +jest.mock('../../../../selectors/preferencesController', () => ({ + selectUseNftDetection: jest.fn(() => true), +})); + jest.mock('../../../../core/Engine', () => ({ context: { AccountTrackerController: { @@ -52,6 +56,9 @@ jest.mock('../../../../core/Engine', () => ({ TokenBalancesController: { updateBalances: jest.fn(() => Promise.resolve()), }, + NftDetectionController: { + detectNfts: jest.fn(() => Promise.resolve()), + }, }, })); @@ -64,6 +71,18 @@ describe('useBalanceRefresh', () => { beforeEach(() => { jest.clearAllMocks(); mockPopularEvmNetworks = ['0x1', '0x89']; + const { selectHomepageSectionsV1Enabled } = jest.requireMock( + '../../../../selectors/featureFlagController/homepage', + ); + const { selectEVMEnabledNetworks } = jest.requireMock( + '../../../../selectors/networkEnablementController', + ); + const { selectUseNftDetection } = jest.requireMock( + '../../../../selectors/preferencesController', + ); + (selectHomepageSectionsV1Enabled as jest.Mock).mockReturnValue(true); + (selectEVMEnabledNetworks as jest.Mock).mockReturnValue([]); + (selectUseNftDetection as jest.Mock).mockReturnValue(true); ( Engine.context.AccountTrackerController.refresh as jest.Mock ).mockResolvedValue(undefined); @@ -76,6 +95,9 @@ describe('useBalanceRefresh', () => { ( Engine.context.TokenBalancesController.updateBalances as jest.Mock ).mockResolvedValue(undefined); + ( + Engine.context.NftDetectionController.detectNfts as jest.Mock + ).mockResolvedValue(undefined); }); it('returns refreshBalance, handleRefresh, and refreshing', () => { @@ -125,6 +147,58 @@ describe('useBalanceRefresh', () => { ).toHaveBeenCalledWith({ chainIds: ['0x1', '0x89'] }); }); + describe('NftDetectionController', () => { + it('calls detectNfts with popular chain IDs and firstPageOnly when sections v1 is enabled', async () => { + const { result } = renderHook(() => useBalanceRefresh()); + + await act(async () => { + await result.current.refreshBalance(); + }); + + expect( + Engine.context.NftDetectionController.detectNfts, + ).toHaveBeenCalledWith(['0x1', '0x89'], { firstPageOnly: true }); + }); + + it('does not call detectNfts when sections v1 is disabled', async () => { + const { selectHomepageSectionsV1Enabled } = jest.requireMock( + '../../../../selectors/featureFlagController/homepage', + ); + const { selectEVMEnabledNetworks } = jest.requireMock( + '../../../../selectors/networkEnablementController', + ); + (selectHomepageSectionsV1Enabled as jest.Mock).mockReturnValue(false); + (selectEVMEnabledNetworks as jest.Mock).mockReturnValue(['0x1']); + + const { result } = renderHook(() => useBalanceRefresh()); + + await act(async () => { + await result.current.refreshBalance(); + }); + + expect( + Engine.context.NftDetectionController.detectNfts, + ).not.toHaveBeenCalled(); + }); + + it('does not call detectNfts when user has disabled NFT detection in settings', async () => { + const { selectUseNftDetection } = jest.requireMock( + '../../../../selectors/preferencesController', + ); + (selectUseNftDetection as jest.Mock).mockReturnValue(false); + + const { result } = renderHook(() => useBalanceRefresh()); + + await act(async () => { + await result.current.refreshBalance(); + }); + + expect( + Engine.context.NftDetectionController.detectNfts, + ).not.toHaveBeenCalled(); + }); + }); + it('calls CurrencyRateController.updateExchangeRate with native currencies', async () => { const { result } = renderHook(() => useBalanceRefresh()); diff --git a/app/components/Views/Wallet/hooks/useBalanceRefresh.ts b/app/components/Views/Wallet/hooks/useBalanceRefresh.ts index 270142554d2b..9586e44b4b99 100644 --- a/app/components/Views/Wallet/hooks/useBalanceRefresh.ts +++ b/app/components/Views/Wallet/hooks/useBalanceRefresh.ts @@ -9,6 +9,7 @@ import { import { useNetworkEnablement } from '../../../hooks/useNetworkEnablement/useNetworkEnablement'; import { selectHomepageSectionsV1Enabled } from '../../../../selectors/featureFlagController/homepage'; import { selectEVMEnabledNetworks } from '../../../../selectors/networkEnablementController'; +import { selectUseNftDetection } from '../../../../selectors/preferencesController'; const REFRESH_TIMEOUT_MS = 5000; const REFRESH_TIMEOUT_ERROR_MESSAGE = 'Balance refresh timed out'; @@ -32,6 +33,8 @@ export const useBalanceRefresh = () => { selectHomepageSectionsV1Enabled, ); + const isNftDetectionEnabled = useSelector(selectUseNftDetection); + const evmEnabledChainIds = useSelector(selectEVMEnabledNetworks); const evmNetworkConfigurations = useSelector( @@ -62,6 +65,7 @@ export const useBalanceRefresh = () => { CurrencyRateController, TokenBalancesController, TokenDetectionController, + NftDetectionController, } = Engine.context; const networkClientIds = Object.values(evmNetworkConfigurationsFiltered) .map( @@ -81,6 +85,13 @@ export const useBalanceRefresh = () => { TokenBalancesController.updateBalances({ chainIds: evmChainIdsForRefresh, }), + ...(isHomepageSectionsV1Enabled && isNftDetectionEnabled + ? [ + NftDetectionController.detectNfts(evmChainIdsForRefresh, { + firstPageOnly: true, + }), + ] + : []), ]), new Promise((_, reject) => setTimeout( @@ -101,6 +112,8 @@ export const useBalanceRefresh = () => { evmNetworkConfigurationsFiltered, evmChainIdsForRefresh, nativeCurrencies, + isHomepageSectionsV1Enabled, + isNftDetectionEnabled, ]); const handleRefresh = useCallback(async () => { diff --git a/app/components/Views/confirmations/components/UI/bottom-modal/bottom-modal.tsx b/app/components/Views/confirmations/components/UI/bottom-modal/bottom-modal.tsx index e48ec8483744..0749748df2cb 100644 --- a/app/components/Views/confirmations/components/UI/bottom-modal/bottom-modal.tsx +++ b/app/components/Views/confirmations/components/UI/bottom-modal/bottom-modal.tsx @@ -2,11 +2,13 @@ import React, { ReactChild } from 'react'; import Modal from 'react-native-modal'; import { View } from 'react-native'; +import { brandColor } from '@metamask/design-tokens'; + import { useTheme } from '../../../../../../util/theme'; import { useStyles } from '../../../../../hooks/useStyles'; import styleSheet from './bottom-modal.styles'; -const OPAQUE_GRAY = '#414141'; +const OPAQUE_GRAY = brandColor.grey600; interface BottomModalProps { avoidKeyboard?: boolean; children: ReactChild; diff --git a/app/components/Views/confirmations/components/UI/info-row/divider/divider.test.tsx b/app/components/Views/confirmations/components/UI/info-row/divider/divider.test.tsx index 8fc793a658b7..c99c0ef16309 100644 --- a/app/components/Views/confirmations/components/UI/info-row/divider/divider.test.tsx +++ b/app/components/Views/confirmations/components/UI/info-row/divider/divider.test.tsx @@ -1,14 +1,14 @@ import React from 'react'; import { InfoRowDivider } from './divider'; import renderWithProvider from '../../../../../../../util/test/renderWithProvider'; -import { lightTheme } from '@metamask/design-tokens'; +import { mockTheme } from '../../../../../../../util/theme'; describe('InfoRowDivider', () => { it('should use correct styles from useStyles hook', () => { const wrapper = renderWithProvider(); expect(wrapper.root.props.style).toEqual({ height: 1, - backgroundColor: lightTheme.colors.border.muted, + backgroundColor: mockTheme.colors.border.muted, marginHorizontal: -8, }); }); diff --git a/app/components/Views/confirmations/components/UI/nft/nft.test.tsx b/app/components/Views/confirmations/components/UI/nft/nft.test.tsx index 88f36afd6956..3eaa117a5ec2 100644 --- a/app/components/Views/confirmations/components/UI/nft/nft.test.tsx +++ b/app/components/Views/confirmations/components/UI/nft/nft.test.tsx @@ -29,6 +29,7 @@ describe('Nft', () => { const mockNft = createMockNft({ standard: 'ERC721', collectionName: 'Bored Apes', + // eslint-disable-next-line @metamask/design-tokens/color-no-hex name: 'Ape #456', tokenId: '456', balance: '0', @@ -39,6 +40,7 @@ describe('Nft', () => { ); expect(getByText('Bored Apes')).toBeOnTheScreen(); + // eslint-disable-next-line @metamask/design-tokens/color-no-hex expect(getByText('#456')).toBeOnTheScreen(); }); @@ -55,6 +57,7 @@ describe('Nft', () => { ); expect(getByText('CryptoPunks')).toBeOnTheScreen(); + // eslint-disable-next-line @metamask/design-tokens/color-no-hex expect(getByText('#789')).toBeOnTheScreen(); }); @@ -104,6 +107,7 @@ describe('Nft', () => { ); expect(getByText('Zero Balance')).toBeOnTheScreen(); + // eslint-disable-next-line @metamask/design-tokens/color-no-hex expect(getByText('#303')).toBeOnTheScreen(); expect(queryByText('(0)')).not.toBeOnTheScreen(); }); @@ -121,6 +125,7 @@ describe('Nft', () => { ); expect(getByText('No Balance')).toBeOnTheScreen(); + // eslint-disable-next-line @metamask/design-tokens/color-no-hex expect(getByText('#404')).toBeOnTheScreen(); expect(queryByText(/^\(/)).not.toBeOnTheScreen(); }); @@ -150,6 +155,7 @@ describe('Nft', () => { ); expect(getByText('Simple Collection')).toBeOnTheScreen(); + // eslint-disable-next-line @metamask/design-tokens/color-no-hex expect(getByText('#123')).toBeOnTheScreen(); }); }); diff --git a/app/components/Views/confirmations/components/hero-nft/hero-nft.test.tsx b/app/components/Views/confirmations/components/hero-nft/hero-nft.test.tsx index 740ab0757c57..44c7999ac711 100644 --- a/app/components/Views/confirmations/components/hero-nft/hero-nft.test.tsx +++ b/app/components/Views/confirmations/components/hero-nft/hero-nft.test.tsx @@ -66,6 +66,7 @@ describe('HeroNft', () => { }), }); + // eslint-disable-next-line @metamask/design-tokens/color-no-hex expect(queryAllByText('#12345')).toHaveLength(2); expect(getByTestId('hero-nft-placeholder')).toBeOnTheScreen(); @@ -108,6 +109,7 @@ describe('HeroNft', () => { expect(getByTestId('nft-image')).toBeDefined(); expect(getByTestId('network-avatar-image')).toBeDefined(); expect(getByText('Test Dapp NFTs')).toBeDefined(); + // eslint-disable-next-line @metamask/design-tokens/color-no-hex expect(getByText('#12345')).toBeDefined(); fireEvent.press(getByTestId('nft-image')); @@ -157,6 +159,7 @@ describe('HeroNft', () => { expect(getByTestId('nft-image')).toBeDefined(); expect(getByTestId('network-avatar-image')).toBeDefined(); expect(getByText('Test Dapp NFTs')).toBeDefined(); + // eslint-disable-next-line @metamask/design-tokens/color-no-hex expect(getByText('#12345')).toBeDefined(); fireEvent.press(getByTestId('nft-image')); diff --git a/app/components/Views/confirmations/components/info/typed-sign-v3v4/simulation/typed-sign-decoded/typed-sign-decoded.test.tsx b/app/components/Views/confirmations/components/info/typed-sign-v3v4/simulation/typed-sign-decoded/typed-sign-decoded.test.tsx index bef70d4b6dac..1bc949c965c9 100644 --- a/app/components/Views/confirmations/components/info/typed-sign-v3v4/simulation/typed-sign-decoded/typed-sign-decoded.test.tsx +++ b/app/components/Views/confirmations/components/info/typed-sign-v3v4/simulation/typed-sign-decoded/typed-sign-decoded.test.tsx @@ -198,6 +198,7 @@ describe('DecodedSimulation', () => { expect(await findByText('Estimated changes')).toBeOnTheScreen(); expect(await findByText('Listing price')).toBeOnTheScreen(); expect(await findByText('You list')).toBeOnTheScreen(); + // eslint-disable-next-line @metamask/design-tokens/color-no-hex expect(await findByText('#22222')).toBeOnTheScreen(); }); @@ -209,6 +210,7 @@ describe('DecodedSimulation', () => { expect(await findByText('Estimated changes')).toBeOnTheScreen(); expect(await findByText('You receive')).toBeOnTheScreen(); expect(await findByText('You list')).toBeOnTheScreen(); + // eslint-disable-next-line @metamask/design-tokens/color-no-hex expect(await findByText('#77789')).toBeOnTheScreen(); }); diff --git a/app/components/Views/confirmations/components/modals/edit-spending-cap-modal/edit-spending-cap-modal.test.tsx b/app/components/Views/confirmations/components/modals/edit-spending-cap-modal/edit-spending-cap-modal.test.tsx index bd8c0e92f902..e2d62ccb6f18 100644 --- a/app/components/Views/confirmations/components/modals/edit-spending-cap-modal/edit-spending-cap-modal.test.tsx +++ b/app/components/Views/confirmations/components/modals/edit-spending-cap-modal/edit-spending-cap-modal.test.tsx @@ -10,23 +10,20 @@ jest.mock('../../../../../../../locales/i18n', () => ({ })); jest.mock('../../../../../../component-library/hooks', () => ({ - useStyles: jest.fn(() => ({ - styles: { - container: {}, - title: {}, - description: {}, - balanceInfo: {}, - buttonsContainer: {}, - button: {}, - }, - theme: { - colors: { - text: { - alternative: '#6a737d', - }, + useStyles: jest.fn(() => { + const { mockTheme } = jest.requireActual('../../../../../../util/theme'); + return { + styles: { + container: {}, + title: {}, + description: {}, + balanceInfo: {}, + buttonsContainer: {}, + button: {}, }, - }, - })), + theme: mockTheme, + }; + }), })); jest.mock('../../../utils/validations/approve', () => ({ diff --git a/app/components/Views/confirmations/components/modals/pay-with-modal/pay-with-modal.test.tsx b/app/components/Views/confirmations/components/modals/pay-with-modal/pay-with-modal.test.tsx index 2c3a210479ff..efd73262f5fd 100644 --- a/app/components/Views/confirmations/components/modals/pay-with-modal/pay-with-modal.test.tsx +++ b/app/components/Views/confirmations/components/modals/pay-with-modal/pay-with-modal.test.tsx @@ -20,7 +20,11 @@ import { } from '@metamask/transaction-controller'; import { AssetType, TokenStandard } from '../../../types/token'; import { TransactionPayRequiredToken } from '@metamask/transaction-pay-controller'; -import { useTransactionPayRequiredTokens } from '../../../hooks/pay/useTransactionPayData'; +import { + useTransactionPayFiatPayment, + useTransactionPayRequiredTokens, +} from '../../../hooks/pay/useTransactionPayData'; +import { useFiatPaymentHighlightedActions } from '../../../hooks/pay/useFiatPaymentHighlightedActions'; import { EthAccountType, SolAccountType } from '@metamask/keyring-api'; import { Hex } from '@metamask/utils'; import { useTransactionMetadataRequest } from '../../../hooks/transactions/useTransactionMetadataRequest'; @@ -50,6 +54,7 @@ jest.mock('../../../../../../core/Engine', () => ({ jest.mock('../../../hooks/pay/useTransactionPayToken'); jest.mock('../../../hooks/pay/useTransactionPayData'); jest.mock('../../../hooks/pay/useTransactionPayWithdraw'); +jest.mock('../../../hooks/pay/useFiatPaymentHighlightedActions'); jest.mock('../../../hooks/pay/useWithdrawTokenFilter'); jest.mock('../../../hooks/transactions/useTransactionMetadataRequest'); jest.mock('../../../utils/transaction-pay'); @@ -221,6 +226,9 @@ describe('PayWithModal', () => { canSelectWithdrawToken: false, }); + jest.mocked(useTransactionPayFiatPayment).mockReturnValue(undefined); + jest.mocked(useFiatPaymentHighlightedActions).mockReturnValue([]); + getAvailableTokensMock.mockReturnValue(TOKENS_MOCK); useWithdrawTokenFilterMock.mockReturnValue( jest.fn((tokens: AssetType[]) => tokens), @@ -392,4 +400,39 @@ describe('PayWithModal', () => { expect(setPayTokenMock).toHaveBeenCalled(); }); }); + + describe('fiat payment', () => { + it('passes fiatPayment to getAvailableTokens', () => { + const fiatPaymentMock = { selectedPaymentMethodId: 'pm-card' }; + jest + .mocked(useTransactionPayFiatPayment) + .mockReturnValue(fiatPaymentMock); + + render(); + + expect(getAvailableTokensMock).toHaveBeenCalledWith( + expect.objectContaining({ fiatPayment: fiatPaymentMock }), + ); + }); + + it('prepends fiat highlighted actions to token list', () => { + const fiatAction = { + position: 'outside_of_asset_list' as const, + icon: 'card-icon', + paymentType: 'debit-credit-card', + name: 'Credit Card', + name_description: '5-10 min', + action: jest.fn(), + isSelected: false, + }; + + jest + .mocked(useFiatPaymentHighlightedActions) + .mockReturnValue([fiatAction]); + + const { getByText } = render(); + + expect(getByText('Credit Card')).toBeDefined(); + }); + }); }); diff --git a/app/components/Views/confirmations/components/modals/pay-with-modal/pay-with-modal.tsx b/app/components/Views/confirmations/components/modals/pay-with-modal/pay-with-modal.tsx index 814659f62f87..6a2e0aa7dfc1 100644 --- a/app/components/Views/confirmations/components/modals/pay-with-modal/pay-with-modal.tsx +++ b/app/components/Views/confirmations/components/modals/pay-with-modal/pay-with-modal.tsx @@ -17,7 +17,11 @@ import { isHighlightedItemOutsideAssetList, TokenListItem, } from '../../../types/token'; -import { useTransactionPayRequiredTokens } from '../../../hooks/pay/useTransactionPayData'; +import { + useTransactionPayFiatPayment, + useTransactionPayRequiredTokens, +} from '../../../hooks/pay/useTransactionPayData'; +import { useFiatPaymentHighlightedActions } from '../../../hooks/pay/useFiatPaymentHighlightedActions'; import { getAvailableTokens } from '../../../utils/transaction-pay'; import { useTransactionPayBlockedTokens } from '../../../hooks/pay/useTransactionPayBlockedTokens'; import { useTransactionMetadataRequest } from '../../../hooks/transactions/useTransactionMetadataRequest'; @@ -41,6 +45,8 @@ export function PayWithModal() { const { payToken, setPayToken } = useTransactionPayToken(); const { isWithdraw } = useTransactionPayWithdraw(); const requiredTokens = useTransactionPayRequiredTokens(); + const fiatPayment = useTransactionPayFiatPayment(); + const fiatHighlightedActions = useFiatPaymentHighlightedActions(); const bottomSheetRef = useRef(null); const { filterAllowedTokens: musdTokenFilter } = useMusdConversionTokens(); const { onPaymentTokenChange: onMusdPaymentTokenChange } = @@ -156,6 +162,7 @@ export function PayWithModal() { requiredTokens, tokens, blockedTokens, + fiatPayment, }); let filteredTokens: TokenListItem[] = availableTokens; @@ -172,10 +179,17 @@ export function PayWithModal() { filteredTokens = perpsBalanceTokenFilter(availableTokens); } - return wrapHighlightedItemCallbacks(filteredTokens); + const wrappedTokens = wrapHighlightedItemCallbacks(filteredTokens); + const wrappedFiatActions = wrapHighlightedItemCallbacks( + fiatHighlightedActions, + ); + + return [...wrappedFiatActions, ...wrappedTokens]; }, [ blockedTokens, + fiatHighlightedActions, + fiatPayment, withdrawTokenFilter, musdTokenFilter, payToken, diff --git a/app/components/Views/confirmations/components/rows/pay-with-row/pay-with-row.test.tsx b/app/components/Views/confirmations/components/rows/pay-with-row/pay-with-row.test.tsx index 62737d2e507b..5436e6c0377c 100644 --- a/app/components/Views/confirmations/components/rows/pay-with-row/pay-with-row.test.tsx +++ b/app/components/Views/confirmations/components/rows/pay-with-row/pay-with-row.test.tsx @@ -4,6 +4,8 @@ import { TokenIconProps } from '../../token-icon'; import { useTransactionPayToken } from '../../../hooks/pay/useTransactionPayToken'; import { useTransactionPayWithdraw } from '../../../hooks/pay/useTransactionPayWithdraw'; import { useTransactionPayRequiredTokens } from '../../../hooks/pay/useTransactionPayData'; +import { useTransactionPaySelectedFiatPaymentMethod } from '../../../hooks/pay/useTransactionPaySelectedFiatPaymentMethod'; +import { type PaymentMethod } from '@metamask/ramps-controller'; import { useNavigation } from '@react-navigation/native'; import { act, fireEvent } from '@testing-library/react-native'; import Routes from '../../../../../../constants/navigation/Routes'; @@ -21,6 +23,7 @@ jest.mock('@react-navigation/native', () => ({ jest.mock('../../../hooks/pay/useTransactionPayToken'); jest.mock('../../../hooks/pay/useTransactionPayWithdraw'); jest.mock('../../../hooks/pay/useTransactionPayData'); +jest.mock('../../../hooks/pay/useTransactionPaySelectedFiatPaymentMethod'); jest.mock('../../../../../../util/address'); jest.mock('../../../hooks/metrics/useConfirmationMetricEvents'); @@ -69,6 +72,10 @@ describe('PayWithRow', () => { useTransactionPayRequiredTokensMock.mockReturnValue(undefined as never); + jest + .mocked(useTransactionPaySelectedFiatPaymentMethod) + .mockReturnValue(undefined); + jest.mocked(useTransactionPayToken).mockReturnValue({ payToken: { address: ADDRESS_MOCK, @@ -196,4 +203,40 @@ describe('PayWithRow', () => { expect(getByTestId('pay-with-row-skeleton')).toBeDefined(); }); }); + + describe('fiat payment method', () => { + const FIAT_PAYMENT_METHOD_MOCK = { + id: 'pm-card', + paymentType: 'debit-credit-card', + name: 'Credit Card', + score: 1, + icon: 'card-icon', + } as PaymentMethod; + + it('renders fiat payment method row when selected', () => { + jest + .mocked(useTransactionPaySelectedFiatPaymentMethod) + .mockReturnValue(FIAT_PAYMENT_METHOD_MOCK); + + const { getByText } = render(); + + expect(getByText('Pay with Credit Card')).toBeDefined(); + }); + + it('navigates to modal when fiat payment method row is pressed', async () => { + jest + .mocked(useTransactionPaySelectedFiatPaymentMethod) + .mockReturnValue(FIAT_PAYMENT_METHOD_MOCK); + + const { getByText } = render(); + + await act(() => { + fireEvent.press(getByText('Pay with Credit Card')); + }); + + expect(navigateMock).toHaveBeenCalledWith( + Routes.CONFIRMATION_PAY_WITH_MODAL, + ); + }); + }); }); diff --git a/app/components/Views/confirmations/components/rows/pay-with-row/pay-with-row.tsx b/app/components/Views/confirmations/components/rows/pay-with-row/pay-with-row.tsx index dc30088e3add..b378100ad424 100644 --- a/app/components/Views/confirmations/components/rows/pay-with-row/pay-with-row.tsx +++ b/app/components/Views/confirmations/components/rows/pay-with-row/pay-with-row.tsx @@ -1,10 +1,12 @@ import React, { useCallback, useMemo } from 'react'; import { useNavigation } from '@react-navigation/native'; +import { PaymentType } from '@consensys/on-ramp-sdk'; import Routes from '../../../../../../constants/navigation/Routes'; import { TokenIcon } from '../../token-icon'; import { useTransactionPayToken } from '../../../hooks/pay/useTransactionPayToken'; import { useTransactionPayWithdraw } from '../../../hooks/pay/useTransactionPayWithdraw'; import { useTransactionPayRequiredTokens } from '../../../hooks/pay/useTransactionPayData'; +import { useTransactionPaySelectedFiatPaymentMethod } from '../../../hooks/pay/useTransactionPaySelectedFiatPaymentMethod'; import { TouchableOpacity } from 'react-native'; import { Box } from '../../../../../UI/Box/Box'; import { @@ -28,17 +30,21 @@ import Icon, { IconName, IconSize, } from '../../../../../../component-library/components/Icons/Icon'; +import PaymentMethodIcon from '../../../../../UI/Ramp/Aggregator/components/PaymentMethodIcon'; import useFiatFormatter from '../../../../../UI/SimulationDetails/FiatDisplay/useFiatFormatter'; import { ConfirmationRowComponentIDs, TransactionPayComponentIDs, } from '../../../ConfirmationView.testIds'; import { useConfirmationMetricEvents } from '../../../hooks/metrics/useConfirmationMetricEvents'; +import { type PaymentMethod } from '@metamask/ramps-controller'; export function PayWithRow() { const navigation = useNavigation(); const { payToken } = useTransactionPayToken(); const { isWithdraw } = useTransactionPayWithdraw(); const requiredTokens = useTransactionPayRequiredTokens(); + const selectedFiatPaymentMethod = + useTransactionPaySelectedFiatPaymentMethod(); const formatFiat = useFiatFormatter({ currency: 'usd' }); const { styles } = useStyles(styleSheet, {}); const { setConfirmationMetric } = useConfirmationMetricEvents(); @@ -83,6 +89,18 @@ export function PayWithRow() { [formatFiat, payToken?.balanceUsd], ); + if (selectedFiatPaymentMethod) { + return ( + + ); + } + if (!displayToken) { return ; } @@ -133,6 +151,57 @@ export function PayWithRow() { ); } +function PayWithFiatPaymentMethodRow({ + paymentMethod, + label, + canEdit, + hasFrom, + onPress, +}: { + paymentMethod: PaymentMethod; + label: string; + canEdit: boolean; + hasFrom: boolean; + onPress: () => void; +}) { + const { styles } = useStyles(styleSheet, {}); + + return ( + + + + + {`${label} ${paymentMethod.name}`} + + {canEdit && hasFrom && ( + + )} + + + ); +} + export function PayWithRowSkeleton() { const { styles } = useStyles(styleSheet, {}); diff --git a/app/components/Views/confirmations/components/send/amount/amount-keyboard/amount-keyboard.test.tsx b/app/components/Views/confirmations/components/send/amount/amount-keyboard/amount-keyboard.test.tsx index 531bde20fef0..7cb54d28133f 100644 --- a/app/components/Views/confirmations/components/send/amount/amount-keyboard/amount-keyboard.test.tsx +++ b/app/components/Views/confirmations/components/send/amount/amount-keyboard/amount-keyboard.test.tsx @@ -1,7 +1,6 @@ import React from 'react'; import { fireEvent } from '@testing-library/react-native'; import { merge } from 'lodash'; - import { mockTheme } from '../../../../../../../util/theme'; import renderWithProvider, { ProviderValues, diff --git a/app/components/Views/confirmations/hooks/nft/useNft.test.ts b/app/components/Views/confirmations/hooks/nft/useNft.test.ts index 8b79be001b3e..0e2ead3f977f 100644 --- a/app/components/Views/confirmations/hooks/nft/useNft.test.ts +++ b/app/components/Views/confirmations/hooks/nft/useNft.test.ts @@ -31,6 +31,7 @@ describe('useNft', () => { expect(result.current.name).toBe('Test Dapp NFTs'); expect(result.current.nft).toBeDefined(); expect(result.current.nft?.tokenId).toBe('12345'); + // eslint-disable-next-line @metamask/design-tokens/color-no-hex expect(result.current.nft?.name).toBe('Test Dapp NFTs #12345'); expect(result.current.tokenId?.toString()).toBe('12345'); }); @@ -105,6 +106,7 @@ describe('useNft', () => { expect(result.current.name).toBe('Test Dapp NFTs'); expect(result.current.nft).toBeDefined(); expect(result.current.nft?.tokenId).toBe('12345'); + // eslint-disable-next-line @metamask/design-tokens/color-no-hex expect(result.current.nft?.name).toBe('Test Dapp NFTs #12345'); expect(result.current.tokenId?.toString()).toBe('12345'); }); diff --git a/app/components/Views/confirmations/hooks/send/useTokenSearch.test.ts b/app/components/Views/confirmations/hooks/send/useTokenSearch.test.ts index 09050e7d66d1..97229719a56b 100644 --- a/app/components/Views/confirmations/hooks/send/useTokenSearch.test.ts +++ b/app/components/Views/confirmations/hooks/send/useTokenSearch.test.ts @@ -44,6 +44,7 @@ const mockNfts: Nft[] = [ { address: '0x2222222222222222222222222222222222222222', standard: 'ERC721', + // eslint-disable-next-line @metamask/design-tokens/color-no-hex name: 'CryptoPunk #1000', collectionName: 'CryptoPunks', chainId: '0x1', @@ -65,6 +66,7 @@ const mockNfts: Nft[] = [ { address: '0x4444444444444444444444444444444444444444', standard: 'ERC721', + // eslint-disable-next-line @metamask/design-tokens/color-no-hex name: 'Ape Avatar #200', collectionName: 'Ape Avatars', chainId: '0x89', @@ -265,6 +267,7 @@ describe('useTokenSearch', () => { expect(result.current.filteredNfts).toHaveLength(2); expect(result.current.filteredNfts.map((nft) => nft.name)).toEqual([ 'Bored Ape #1', + // eslint-disable-next-line @metamask/design-tokens/color-no-hex 'Ape Avatar #200', ]); }); @@ -281,6 +284,7 @@ describe('useTokenSearch', () => { result.current.filteredNfts.every((nft) => nft.chainId === '0x89'), ).toBe(true); expect(result.current.filteredNfts.map((nft) => nft.name)).toEqual([ + // eslint-disable-next-line @metamask/design-tokens/color-no-hex 'Ape Avatar #200', ]); }); diff --git a/app/components/Views/confirmations/hooks/ui/useEmptyNavHeaderForConfirmations.test.tsx b/app/components/Views/confirmations/hooks/ui/useEmptyNavHeaderForConfirmations.test.tsx index 798b6ba167eb..0040ca4c67aa 100644 --- a/app/components/Views/confirmations/hooks/ui/useEmptyNavHeaderForConfirmations.test.tsx +++ b/app/components/Views/confirmations/hooks/ui/useEmptyNavHeaderForConfirmations.test.tsx @@ -4,19 +4,23 @@ import { Theme } from '../../../../../util/theme/models'; import { getEmptyNavHeader } from '../../components/UI/navbar/navbar'; import { useEmptyNavHeaderForConfirmations } from './useEmptyNavHeaderForConfirmations'; -jest.mock('../../../../../util/theme', () => ({ - useTheme: jest.fn().mockReturnValue({ - colors: { background: { alternative: '#ffffff' } }, - typography: {}, - shadows: {}, - brandColors: {}, - themeAppearance: 'light' as const, - } as Theme), -})); +jest.mock('../../../../../util/theme', () => { + const { mockTheme } = jest.requireActual('../../../../../util/theme'); + return { + useTheme: jest.fn().mockReturnValue({ + colors: mockTheme.colors, + typography: {}, + shadows: {}, + brandColors: mockTheme.brandColors, + themeAppearance: 'light' as const, + } as Theme), + }; +}); jest.mock('../../components/UI/navbar/navbar'); describe('useEmptyNavHeaderForConfirmations', () => { const mockGetEmptyNavHeader = jest.mocked(getEmptyNavHeader); + const { mockTheme } = jest.requireActual('../../../../../util/theme'); const mockNavbarOptions = { headerTitle: () => <>, @@ -24,7 +28,7 @@ describe('useEmptyNavHeaderForConfirmations', () => { headerRight: () => <>, headerTitleAlign: 'center' as const, headerStyle: { - backgroundColor: '#ffffff', + backgroundColor: mockTheme.colors.background.default, shadowColor: 'transparent', elevation: 0, }, diff --git a/app/components/Views/confirmations/utils/transaction-pay.test.ts b/app/components/Views/confirmations/utils/transaction-pay.test.ts index 25daff43719c..a1582753cd00 100644 --- a/app/components/Views/confirmations/utils/transaction-pay.test.ts +++ b/app/components/Views/confirmations/utils/transaction-pay.test.ts @@ -353,6 +353,36 @@ describe('Transaction Pay Utils', () => { }); }); + describe('fiatPayment', () => { + it('clears isSelected on all tokens when fiat payment is active', () => { + const result = getAvailableTokens({ + tokens: [TOKEN_MOCK], + payToken: { + address: TOKEN_MOCK.address as Hex, + chainId: TOKEN_MOCK.chainId as Hex, + } as TransactionPaymentToken, + fiatPayment: { selectedPaymentMethodId: 'pm-card' }, + }); + + expect(result).toHaveLength(1); + expect(result[0].isSelected).toBe(false); + }); + + it('preserves isSelected when fiat payment has no selected method', () => { + const result = getAvailableTokens({ + tokens: [TOKEN_MOCK], + payToken: { + address: TOKEN_MOCK.address as Hex, + chainId: TOKEN_MOCK.chainId as Hex, + } as TransactionPaymentToken, + fiatPayment: {}, + }); + + expect(result).toHaveLength(1); + expect(result[0].isSelected).toBe(true); + }); + }); + describe('blockedTokens', () => { it('marks token as disabled when its chain is in blocklist chainIds', () => { const blockedTokens: BlockedTokensListConfig = { diff --git a/app/components/Views/confirmations/utils/transaction-pay.ts b/app/components/Views/confirmations/utils/transaction-pay.ts index 98677426c27a..7b6438dba186 100644 --- a/app/components/Views/confirmations/utils/transaction-pay.ts +++ b/app/components/Views/confirmations/utils/transaction-pay.ts @@ -8,6 +8,7 @@ import { Hex } from '@metamask/utils'; import { PERPS_MINIMUM_DEPOSIT } from '../constants/perps'; import { AssetType, TokenStandard } from '../types/token'; import { + TransactionFiatPayment, TransactionPayRequiredToken, TransactionPaymentToken, } from '@metamask/transaction-pay-controller'; @@ -92,12 +93,15 @@ export function getAvailableTokens({ requiredTokens, tokens, blockedTokens, + fiatPayment, }: { payToken?: TransactionPaymentToken; requiredTokens?: TransactionPayRequiredToken[]; tokens: AssetType[]; blockedTokens?: BlockedTokensListConfig; + fiatPayment?: TransactionFiatPayment; }): AssetType[] { + const hasFiatPayment = Boolean(fiatPayment?.selectedPaymentMethodId); const supportedGasFeeTokens = getSupportedGasFeeTokens(); return tokens @@ -158,9 +162,10 @@ export function getAvailableTokens({ ? strings('pay_with_modal.no_gas') : undefined; - const isSelected = - payToken?.address.toLowerCase() === token.address.toLowerCase() && - payToken?.chainId === token.chainId; + const isSelected = hasFiatPayment + ? false + : payToken?.address.toLowerCase() === token.address.toLowerCase() && + payToken?.chainId === token.chainId; return { ...token, diff --git a/docs/perps/perps-feature-flags.md b/docs/perps/perps-feature-flags.md index d2e59b1a4799..5d72833f339c 100644 --- a/docs/perps/perps-feature-flags.md +++ b/docs/perps/perps-feature-flags.md @@ -159,13 +159,14 @@ Follow existing test patterns covering: ### Version-Gated Boolean Flags -| Redux Property | LaunchDarkly Key | Env Variable | Default | Purpose | -| -------------------------------------------------- | -------------------------------------------------------- | ---------------------------------------------- | ------- | ------------------------- | -| `perpsPerpTradingEnabled` | `perps-perp-trading-enabled` | `MM_PERPS_ENABLED` | false | Main Perps feature toggle | -| `perpsPerpTradingServiceInterruptionBannerEnabled` | `perps-perp-trading-service-interruption-banner-enabled` | `MM_PERPS_SERVICE_INTERRUPTION_BANNER_ENABLED` | false | Service disruption banner | -| `perpsPerpGtmOnboardingModalEnabled` | `perps-perp-gtm-onboarding-modal-enabled` | `MM_PERPS_GTM_MODAL_ENABLED` | false | GTM onboarding modal | -| `perpsOrderBookEnabled` | `perps-order-book-enabled` | `MM_PERPS_ORDER_BOOK_ENABLED` | false | Order Book feature | -| `perpsFeedbackEnabled` | `perps-feedback-enabled` | `MM_PERPS_FEEDBACK_ENABLED` | false | Feedback button on home | +| Redux Property | LaunchDarkly Key | Env Variable | Default | Purpose | +| -------------------------------------------------- | -------------------------------------------------------- | ---------------------------------------------- | ------- | --------------------------------------------------------------------------------------- | +| `perpsPerpTradingEnabled` | `perps-perp-trading-enabled` | `MM_PERPS_ENABLED` | false | Main Perps feature toggle | +| `perpsPerpTradingServiceInterruptionBannerEnabled` | `perps-perp-trading-service-interruption-banner-enabled` | `MM_PERPS_SERVICE_INTERRUPTION_BANNER_ENABLED` | false | Service disruption banner | +| `perpsPerpGtmOnboardingModalEnabled` | `perps-perp-gtm-onboarding-modal-enabled` | `MM_PERPS_GTM_MODAL_ENABLED` | false | GTM onboarding modal | +| `perpsOrderBookEnabled` | `perps-order-book-enabled` | `MM_PERPS_ORDER_BOOK_ENABLED` | false | Order Book feature | +| `perpsFeedbackEnabled` | `perps-feedback-enabled` | `MM_PERPS_FEEDBACK_ENABLED` | false | Feedback button on home | +| `perpsDefaultPayTokenWhenNoBalanceEnabled` | `perps-default-pay-token-when-no-balance-enabled` | — | true | Default pay token when no perps balance + Add funds CTA on market details (remote only) | ### A/B Test Flags diff --git a/locales/languages/de.json b/locales/languages/de.json index d28cf3922629..d3c201a77e78 100644 --- a/locales/languages/de.json +++ b/locales/languages/de.json @@ -104,8 +104,8 @@ "title": "Unzureichende Gelder" }, "insufficient_pay_token_native_post_quote": { - "message": "Not enough {{ticker}} to cover fees. Add {{ticker}} to continue.", - "title": "Insufficient funds for post quote" + "message": "Nicht genug {{ticker}}, um die Gebühren zu decken. Fügen Sie {{ticker}} hinzu, um fortzufahren.", + "title": "Unzureichende Mittel für nachträgliche Angebote" }, "no_pay_token_quotes": { "message": "Diese Zahlungsroute ist derzeit nicht verfügbar. Versuchen Sie, den Betrag, das Netzwerk oder das Token zu ändern, und wir finden die beste Option.", @@ -2077,12 +2077,12 @@ "title": "Markteinblicke", "a_closer_look": "Ein genauerer Blick", "whats_being_said": "Was gesagt wird", - "footer_disclaimer": "AI summary for information only", + "footer_disclaimer": "KI-Zusammenfassung nur zu Informationszwecken", "trade_button": "Trade", "sources_count": "+{{count}} Quellen", - "sources_title": "News sources", + "sources_title": "Nachrichtenquellen", "feedback_submitted": "Feedback eingereicht", - "helpful_prompt": "Was this helpful?", + "helpful_prompt": "War dies hilfreich?", "feedback": { "title": "Feedback", "description": "Helfen Sie uns, unsere KI-generierten Markteinblicke zu erweitern.", @@ -2197,6 +2197,7 @@ "available_balance": "Verfügbares Guthaben", "claim_amount_text": "{{amount}} $ einfordern", "claim_winnings_text": "Gewinne einfordern", + "claiming_text": "Claiming...", "unrealized_pnl_label": "Nicht realisierte GuV", "unrealized_pnl_value": "{{amount}} ({{percent}})", "unrealized_pnl_error": "Laden nicht möglich", @@ -2275,6 +2276,9 @@ "title": "Hoppla! Etwas ist schiefgelaufen ...", "description": "Fortfahren mit Einforderung fehlgeschlagen", "try_again": "Erneut versuchen" + }, + "in_progress": { + "title": "Claim already in progress" } } }, @@ -2333,7 +2337,8 @@ "exchange_fee": "Umrechnungsgebühr", "exchange_fee_description": "An die Börse oder den Markt entrichtete Gebühr", "total_incl_fees": "inkl. Gebühren", - "close": "Schließen" + "close": "Schließen", + "fak_partial_fill_note": "Prices shown assume your order is fully filled. Actual amounts may vary if the order is only partially filled." }, "error": { "title": "Verbindung zu Prognosen nicht möglich", @@ -3701,10 +3706,10 @@ "speedup_tx_title": "Versuchen, zu beschleunigen?", "speedup_tx_message": "Das Absenden dieses Versuches garantiert nicht, dass die Transaktion beschleunigt wird. Wenn der Beschleunigungsversuch erfolgreich ist, wird Ihnen die obige Transaktionsgebühr in Rechnung gestellt.", "nevermind": "Macht nichts", - "cancel_speedup_speedup_title": "Speed up Transaction", - "cancel_speedup_cancel_title": "Cancel Transaction", - "cancel_speedup_speedup_message": "This network fee will replace the original.", - "cancel_speedup_cancel_message": "This transaction will be canceled and this network fee will replace the original.", + "cancel_speedup_speedup_title": "Transaktion beschleunigen", + "cancel_speedup_cancel_title": "Transaktion storniert", + "cancel_speedup_speedup_message": "Diese Netzwerkgebühr ersetzt die ursprüngliche Gebühr.", + "cancel_speedup_cancel_message": "Diese Transaktion wird storniert und diese Netzwerkgebühr ersetzt die ursprüngliche Gebühr.", "edit_network_fee": "Gas-Gebühr bearbeiten", "edit_priority": "Priorität bearbeiten", "gas_cancel_fee": "Gas-Stornogebühr", @@ -4837,7 +4842,7 @@ "quote_unavailable": "Angebot nicht verfügbar.", "providers": "Anbieter", "quotes_displayed_for": "Angebote angezeigt für {{paymentMethodName}}.", - "other_options": "Other options", + "other_options": "Weitere Optionen", "previously_used": "Zuvor verwendet", "best_rate": "Bester Wechselkurs", "most_reliable": "Am zuverlässigsten", @@ -4948,10 +4953,10 @@ "provider_picker_modal": { "title": "Anbieter auswählen" }, - "contact_provider_support": "Contact {{provider}} support", + "contact_provider_support": "Wenden Sie sich an den {{provider}}-Support", "got_it": "Verstanden", - "encountered_error": "We've encountered an error", - "no_quotes_error": "We encountered a problem fetching quotes from {{provider}}. Try a different amount or changing provider.", + "encountered_error": "Ein Fehler ist aufgetreten", + "no_quotes_error": "Beim Abrufen der Angebote von {{provider}} ist ein Problem aufgetreten. Versuchen Sie einen anderen Betrag oder wechseln Sie den Anbieter.", "change_provider_button": "Anbieter wechseln" }, "fiat_on_ramp_aggregator": { @@ -5914,7 +5919,7 @@ "error_description": "Installation von {{snap}} fehlgeschlagen." }, "earn": { - "claimable_bonus_tooltip": "The annualized bonus you’ve earned for holding mUSD. Your bonus is claimable daily on Linea.", + "claimable_bonus_tooltip": "Sie haben den jährlichen Bonus für das Halten von mUSD verdient. Ihr Bonus kann täglich auf Linea eingefordert werden.", "earn_a_percentage_bonus": "Verdienen Sie einen Bonus von {{percentage}} %", "claimable_bonus": "Anspruchsberechtigter Bonus", "claim_bonus": "Bonus einfordern", @@ -6022,21 +6027,21 @@ "toasts": { "converting": "Konvertierung von {{token}} → mUSD", "eta": "~{{time}}", - "delivered": "mUSD conversion successful", - "delivered_description": "Bonus will be claimable within a day.", + "delivered": "mUSD-Konvertierung erfolgreich", + "delivered_description": "Der Bonus kann innerhalb eines Tages eingefordert werden.", "failed": "mUSD-Konvertierung fehlgeschlagen" }, "education": { "heading": "ERHALTEN SIE {{percentage}} % AUF\nSTABILECOINS", - "description": "Convert your stablecoins to mUSD and earn up to a {{percentage}}% annualized bonus that you can claim daily.", + "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.", "terms_apply": "Es gelten die Nutzungsbedingungen.", "primary_button": "Erste Schritte", "secondary_button": "Nicht jetzt" }, "buy_musd": "mUSD kaufen", "get_musd": "mUSD erhalten", - "bonus_title": "Get {{percentage}}% on your stablecoins", - "bonus_description": "Convert your stablecoins to mUSD and get a {{percentage}}% annualized bonus.", + "bonus_title": "Erhalten Sie {{percentage}} % auf Ihre Stablecoins", + "bonus_description": "Konvertieren Sie Ihre Stablecoins in mUSD und erhalten Sie einen jährlichen Bonus von {{percentage}} %.", "powered_by_relay": "Unterstützt von Relay", "max": "Max.", "quick_convert_button": "Konvertieren", @@ -6044,14 +6049,14 @@ "tooltip_title": "Verdienen Sie Rendite mit mUSD", "tooltip_content": "Konvertieren Sie Ihre USDC, USDT oder DAI gegen mUSD, den an den US-Dollar gekoppelten Stablecoin von MetaMask. Verdienen Sie {{apy}} Rendite für jeden von Ihnen gehaltenen US-Dollar.", "quick_convert": { - "title": "Convert and get {{percentage}}%", - "subtitle": "Convert your stablecoins to mUSD and receive up to a {{percentage}}% annualized bonus that you can claim daily.", + "title": "Konvertieren und {{percentage}} % erhalten", + "subtitle": "Konvertieren Sie Ihre Stablecoins in mUSD und erhalten Sie einen Bonus von bis zu {{percentage}} % auf jährlicher Basis, den Sie täglich einfordern können.", "inline_failed_message": "Konvertierung fehlgeschlagen. Versuchen Sie es erneut.", "confirmation": { "title": "Konvertieren max" } }, - "percentage_bonus": "{{percentage}}% bonus", + "percentage_bonus": "Bonus von {{percentage}} %", "rate": "Rate" }, "bonus_claim": { @@ -6092,7 +6097,9 @@ "fee": "Gebühr", "errors": { "insufficient_balance": "Sie haben nicht genügend Ressourcen, um diese Aktion durchzuführen." - } + }, + "trx_unstaking_in_progress": "Unstaken {{amount}} TRX in Bearbeitung. Das Unstaken erfordert 14 Tage.", + "has_claimable_trx": "You can claim {{amount}} TRX. Once claimed you'll get TRX back in your wallet." }, "stake_eth": "ETH staken", "unstake_eth": "ETH unstaken", @@ -6343,7 +6350,8 @@ "metamask_fee": "MetaMask-Gebühr", "network_fee": "Netzwerk-Gebühr", "bridge_fee": "Gebühr für Bridge-Anbieter", - "provider_fee": "Anbietergebühr" + "provider_fee": "Anbietergebühr", + "sending": "Senden" }, "title": { "signature": "Signaturanfrage", @@ -6381,10 +6389,10 @@ "transaction_fee": "Wir swappen Ihre Token gegen USDC.e auf Polygon, dem von Predictions verwendeten Netzwerk. Swap-Anbieter erheben möglicherweise eine Gebühr, MetaMask jedoch nicht." }, "predict_withdraw": { - "transaction_fee": "MetaMask will swap to your desired token for you. No MetaMask fee applies when you swap to mUSD." + "transaction_fee": "MetaMask swappt den Token für Sie in den gewünschten Token um. Beim Swap in mUSD fallen keine MetaMask-Gebühren an." }, "musd_conversion": { - "transaction_fee": "mUSD conversion fees include network costs and may include provider fees. No MetaMask fee applies when you convert to mUSD." + "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." }, "title": { "transaction_fee": "Gebühren" @@ -6570,12 +6578,12 @@ "hardware_wallet_not_supported": "Hardware-Wallets werden noch nicht unterstützt. Verwenden Sie eine Hot Wallet, um fortzufahren.", "hardware_wallet_not_supported_solana": "Hardware-Wallets werden für Solana noch nicht unterstützt. Verwenden Sie ein Hot Wallet, um fortzufahren.", "price_impact_info_title": "Preiseinfluss", - "price_impact_info_description": "Der Preiseinfluss spiegelt wider, wie Ihre Swap-Order den Marktpreis des Assets beeinflusst. Er hängt von der Trade-Größe und der verfügbaren Liquidität im Pool ab. MetaMask hat keinerlei Kontrolle über den Preiseinfluss.", + "price_impact_info_description": "This is how your trade changes the market price of a token. It depends on the trade size, available liquidity, and provider fees. MetaMask doesn't control price impact.", "price_impact_info_gasless_description": "Die Preisauswirkung spiegelt wider, wie Ihre Swap-Order den Marktpreis des Assets beeinflusst. Falls Sie nicht über genügend Gelder für Gas halten, wird ein Teil Ihres Quelltokens automatisch zur Deckung der Gebühren verwendet, was die Preisauswirkung erhöht. MetaMask hat keinerlei Kontrolle über die Preisauswirkung.", - "price_impact_warning_description": "This trade has an estimated {{priceImpact}} price impact, which reflects how much your trade changes the market price. The quote already reflects this.", - "price_impact_high": "High price impact", - "price_impact_execution_description": "You'll lose approximately {{priceImpact}} of your token's value on this swap. Try lowering the amount or choosing a more liquid route.", - "proceed": "Proceed", + "price_impact_warning_description": "Because of your trade size and available liquidity, you'll get about {{priceImpact}} less than the market price. This is already factored into your quote.", + "price_impact_high": "Hohe Preisauswirkungen", + "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", "slippage_info_title": "Slippage", "slippage_info_description": "Die prozentuale Preisänderung, die Sie zuzulassen bereit sind, bevor Ihre Transaktion storniert wird.", @@ -6603,7 +6611,14 @@ "exceeding_upper_slippage_error": "Sie können keinen Wert eingeben, der größer als {{value}} % ist.", "custom": "Benutzerdefiniert", "invalid_recipient_address": "Ungültige Adresse", - "got_it": "Got it" + "select_quote": "Angebot auswählen", + "select_quote_info": "Die Angebote sind nach den geschätzten Gesamtkosten einschließlich des Wechselkurses und der Netzwerkgebühr sortiert.", + "lowest_cost": "Niedrigste Kosten", + "total_cost": "Gesamtkosten", + "got_it": "Verstanden", + "price_impact_warning_title": "Hohe Preisauswirkungen", + "price_impact_error_title": "Very high price impact", + "price_impact_error_description": "You'll lose approximately {{priceImpact}} of your token's market price on this swap. Try a smaller trade or a more liquid route to improve your rate." }, "quote_expired_modal": { "title": "Neue Angebote sind verfügbar", @@ -6900,7 +6915,7 @@ "title": "Passwort eingeben", "description": "Geben Sie Ihr Wallet-Passwort ein, um die Kartendetails anzuzeigen.", "description_unfreeze": "Geben Sie Ihr Wallet-Passwort ein, um mit Ihrer Karte weiter bezahlen zu können.", - "description_view_pin": "Enter your wallet password to view your card PIN.", + "description_view_pin": "Geben Sie Ihr Wallet-Passwort ein, um Ihre Karten-PIN einzusehen.", "placeholder": "Passwort", "confirm": "Bestätigen", "cancel": "Stornieren", @@ -6908,7 +6923,7 @@ "error_incorrect": "Falsches Passwort. Bitte versuchen Sie es erneut." }, "view_pin_bottomsheet": { - "title": "Your Card PIN" + "title": "Ihre Karten-PIN" }, "choose_your_card": { "title": "Wählen Sie Ihre Karte", @@ -7225,9 +7240,9 @@ "view_card_details": "Kartendetails anzeigen", "hide_card_details": "Kartendetails verbergen", "view_card_details_description": "Kartennummer, Ablaufdatum und Karteprüfwert", - "view_pin": "View PIN", - "view_pin_description": "View your card PIN securely", - "view_pin_error": "Failed to load PIN. Please try again.", + "view_pin": "PIN anzeigen", + "view_pin_description": "Sehen Sie Ihre Karten-PIN sicher ein", + "view_pin_error": "PIN konnte nicht geladen werden. Bitte versuchen Sie es erneut.", "manage_spending_limit": "Limit verwalten", "manage_spending_limit_description_restricted": "Begrenzte Ausgaben sind an", "manage_spending_limit_description_full": "Vollzugriff ist an", @@ -7240,7 +7255,7 @@ "order_metal_card_description": "Bestellen Sie jetzt Ihre physische Metallkarte", "cashback": "Cashback", "cashback_description": "Verdienen Sie 1 % Rabatt auf alle Ausgaben", - "cashback_description_metal": "Earn 3% back on all spending", + "cashback_description_metal": "Verdienen Sie 3 % Rabatt auf alle Ausgaben", "freeze_card": "Karte sperren", "unfreeze_card": "Karte entsperren", "freeze_card_description": "Alle Ausgaben mit Ihrer Karte pausieren", @@ -7394,7 +7409,8 @@ "pay_with_modal": { "title": "Zahlungsmethode auswählen", "title_receive": "Token empfangen auswählen", - "no_gas": "Kein nativer Saldo für Gas" + "no_gas": "Kein nativer Saldo für Gas", + "not_supported": "Nicht unterstützt" }, "connection_removed_modal": { "title": "Verbindungen entfernt", @@ -7632,12 +7648,12 @@ "environment_selector": "Umgebung", "environment_cancel": "Stornieren", "environment_default": "Standard", - "off_device_accounts_banner_title": "Missing Enrolled Accounts", - "off_device_accounts_banner_description": "There are accounts that were enrolled into the rewards program but are not found on this device.", - "off_device_accounts_banner_cta": "View", - "off_device_accounts_sheet_title": "Missing Enrolled Accounts", - "off_device_accounts_sheet_description": "These might belong to a wallet that has not yet been added after reinstalling MetaMask. Don't recognize any of these addresses?", - "off_device_accounts_sheet_let_us_know": "Let us know" + "off_device_accounts_banner_title": "Angemeldete Konten fehlen", + "off_device_accounts_banner_description": "Es gibt Konten, die für das Belohnungsprogramm angemeldet wurden, aber nicht auf diesem Gerät zu finden sind.", + "off_device_accounts_banner_cta": "Ansehen", + "off_device_accounts_sheet_title": "Angemeldete Konten fehlen", + "off_device_accounts_sheet_description": "Diese gehören möglicherweise zu einer Wallet, die nach der Neuinstallation von MetaMask noch nicht hinzugefügt wurde. Erkennen Sie eine dieser Adressen nicht?", + "off_device_accounts_sheet_let_us_know": "Sagen Sie uns Bescheid" }, "referred_by_code": { "title": "Empfehlungscode", @@ -7835,12 +7851,12 @@ "description": "Bitte stellen Sie über die App eine neue Verbindung her, um fortzufahren." }, "show_internal_error": { - "title": "Something went wrong", - "description": "An unexpected error occurred. Please try again." + "title": "Hoppla! Etwas ist schiefgelaufen ...", + "description": "Ein unerwarteter Fehler ist aufgetreten. Bitte versuchen Sie es erneut." }, "show_method_error": { - "title": "Request failed", - "description": "The request could not be completed. Please try again." + "title": "Anfrage fehlgeschlagen", + "description": "Die Anfrage konnte nicht abgeschlossen werden. Bitte versuchen Sie es erneut." } }, "network_connection_banner": { @@ -7981,7 +7997,7 @@ "scanning": "Scannen nach Geräten ...", "no_devices_found": "Es wurden keine Geräte gefunden", "no_devices_hint": "Vergewissern Sie sich, dass Ihr {{device}} entsperrt und Bluetooth aktiviert ist", - "tips": "Unlock your {{device}}, enable Bluetooth, and ensure Do Not Disturb is turned off", + "tips": "Entsperren Sie Ihr {{device}}, aktivieren Sie Bluetooth und stellen Sie sicher, dass „Nicht stören“ deaktiviert ist", "connect": "Verbinden", "rescan": "Erneut scannen", "unknown_device": "Unbekanntes Gerät", @@ -7997,7 +8013,7 @@ "nfts": "NFTs", "import_nfts": "NFTs importieren", "import_nfts_description": "Fügen Sie ganz einfach Ihre Sammlerstücke hinzu", - "view_more": "View more", + "view_more": "Mehr anzeigen", "positions": { "no_tp_sl": "Kein TP/SL" } diff --git a/locales/languages/el.json b/locales/languages/el.json index 92fda1f70484..e96d7529c909 100644 --- a/locales/languages/el.json +++ b/locales/languages/el.json @@ -104,8 +104,8 @@ "title": "Ανεπαρκές ποσό" }, "insufficient_pay_token_native_post_quote": { - "message": "Not enough {{ticker}} to cover fees. Add {{ticker}} to continue.", - "title": "Insufficient funds for post quote" + "message": "Μη επαρκές υπόλοιπο σε {{ticker}} για την κάλυψη των χρεώσεων. Προσθέστε {{ticker}} για να συνεχίσετε.", + "title": "Ανεπαρκές υπόλοιπο για την υποβολή της προσφοράς" }, "no_pay_token_quotes": { "message": "Αυτή η διαδρομή πληρωμής δεν είναι διαθέσιμη αυτή τη στιγμή. Δοκιμάστε να αλλάξετε το ποσό, το δίκτυο ή το token και θα βρούμε την καλύτερη επιλογή.", @@ -2077,12 +2077,12 @@ "title": "Πληροφορίες αγοράς", "a_closer_look": "Μια πιο προσεκτική ματιά", "whats_being_said": "Τι συζητιέται", - "footer_disclaimer": "AI summary for information only", + "footer_disclaimer": "Περίληψη από ΤΝ, μόνο για ενημερωτικούς σκοπούς", "trade_button": "Συναλλαγές", "sources_count": "+{{count}} πηγές", - "sources_title": "News sources", + "sources_title": "Πηγές ειδήσεων", "feedback_submitted": "Το σχόλιό σας υποβλήθηκε", - "helpful_prompt": "Was this helpful?", + "helpful_prompt": "Ήταν χρήσιμο;", "feedback": { "title": "Ανατροφοδότηση", "description": "Βοηθήστε μας να βελτιώσουμε τις αναλύσεις αγοράς που δημιουργεί η τεχνητή νοημοσύνη.", @@ -2197,6 +2197,7 @@ "available_balance": "Διαθέσιμο υπόλοιπο", "claim_amount_text": "Εξαργυρώστε ${{amount}}", "claim_winnings_text": "Εξαργύρωση κερδών", + "claiming_text": "Claiming...", "unrealized_pnl_label": "Μη οριστικοποιημένα κέρδη & ζημίες", "unrealized_pnl_value": "{{amount}} ({{percent}})", "unrealized_pnl_error": "Δεν ήταν δυνατή η φόρτωση", @@ -2275,6 +2276,9 @@ "title": "Κάτι πήγε στραβά", "description": "Αποτυχία συνέχισης της αξίωσης", "try_again": "Προσπαθήστε ξανά" + }, + "in_progress": { + "title": "Claim already in progress" } } }, @@ -2333,7 +2337,8 @@ "exchange_fee": "Τέλη ανταλλαγής", "exchange_fee_description": "Τέλη που καταβάλλονται στην πλατφόρμα συναλλαγών ή στην αγορά", "total_incl_fees": "συμπερ. τέλη", - "close": "Κλείσιμο" + "close": "Κλείσιμο", + "fak_partial_fill_note": "Prices shown assume your order is fully filled. Actual amounts may vary if the order is only partially filled." }, "error": { "title": "Δεν ήταν δυνατή η σύνδεση με την πλατφόρμα προβλέψεων", @@ -3701,10 +3706,10 @@ "speedup_tx_title": "Προσπάθεια για επιτάχυνση;", "speedup_tx_message": "Η υποβολή αυτής της προσπάθειας δεν εγγυάται ότι η αρχική σας συναλλαγή θα επιταχυνθεί. Εάν η προσπάθεια επιτάχυνσης είναι επιτυχής, θα χρεωθείτε με το παραπάνω τέλος συναλλαγής.", "nevermind": "Άκυρο", - "cancel_speedup_speedup_title": "Speed up Transaction", - "cancel_speedup_cancel_title": "Cancel Transaction", - "cancel_speedup_speedup_message": "This network fee will replace the original.", - "cancel_speedup_cancel_message": "This transaction will be canceled and this network fee will replace the original.", + "cancel_speedup_speedup_title": "Επιτάχυνση συναλλαγής", + "cancel_speedup_cancel_title": "Ακύρωση συναλλαγής", + "cancel_speedup_speedup_message": "Αυτά τα τέλη δικτύου θα αντικαταστήσουν τα αρχικά.", + "cancel_speedup_cancel_message": "Αυτή η συναλλαγή θα ακυρωθεί και αυτά τα τέλη δικτύου θα αντικαταστήσουν τα αρχικά.", "edit_network_fee": "Επεξεργασία τέλους συναλλαγής", "edit_priority": "Επεξεργασία προτεραιότητας", "gas_cancel_fee": "Τέλος ακύρωσης συναλλαγής", @@ -4837,7 +4842,7 @@ "quote_unavailable": "Δεν υπάρχει διαθέσιμη προσφορά.", "providers": "Πάροχοι", "quotes_displayed_for": "Οι προσφορές που εμφανίζονται για το {{paymentMethodName}}.", - "other_options": "Other options", + "other_options": "Άλλες επιλογές", "previously_used": "Χρησιμοποιήθηκε στο παρελθόν", "best_rate": "Καλύτερη τιμή", "most_reliable": "Πιο αξιόπιστο", @@ -4948,10 +4953,10 @@ "provider_picker_modal": { "title": "Επιλέξτε πάροχο" }, - "contact_provider_support": "Contact {{provider}} support", + "contact_provider_support": "Επικοινωνήστε με την υποστήριξη του {{provider}}", "got_it": "Κατανοητό", - "encountered_error": "We've encountered an error", - "no_quotes_error": "We encountered a problem fetching quotes from {{provider}}. Try a different amount or changing provider.", + "encountered_error": "Παρουσιάστηκε σφάλμα", + "no_quotes_error": "Παρουσιάστηκε πρόβλημα κατά την ανάκτηση προσφορών από {{provider}}. Προσπαθήστε με διαφορετικό ποσό ή αλλάξτε πάροχο.", "change_provider_button": "Αλλαγή παρόχου" }, "fiat_on_ramp_aggregator": { @@ -5914,7 +5919,7 @@ "error_description": "Η εγκατάσταση του {{snap}} απέτυχε." }, "earn": { - "claimable_bonus_tooltip": "The annualized bonus you’ve earned for holding mUSD. Your bonus is claimable daily on Linea.", + "claimable_bonus_tooltip": "Το ετήσιο μπόνους που έχετε κερδίσει επειδή διατηρήσατε τα mUSD. Το μπόνους σας μπορείτε να το εξαργυρώσετε καθημερινά στο δίκτυο Linea.", "earn_a_percentage_bonus": "Κερδίστε ένα μπόνους {{percentage}}%", "claimable_bonus": "Μπόνους προς εξαργύρωση", "claim_bonus": "Εξαργύρωση του μπόνους", @@ -6022,21 +6027,21 @@ "toasts": { "converting": "Μετατροπή {{token}} → mUSD", "eta": "~{{time}}", - "delivered": "mUSD conversion successful", - "delivered_description": "Bonus will be claimable within a day.", + "delivered": "Η μετατροπή σε mUSD ολοκληρώθηκε με επιτυχία", + "delivered_description": "Το μπόνους θα είναι διαθέσιμο για εξαργύρωση μέσα σε μία ημέρα.", "failed": "Η μετατροπή σε mUSD απέτυχε" }, "education": { "heading": "ΚΕΡΔΙΣΤΕ {{percentage}}% ΣΤΑ\nSTABLECOINS", - "description": "Convert your stablecoins to mUSD and earn up to a {{percentage}}% annualized bonus that you can claim daily.", + "description": "Μετατρέψτε τα stablecoins σε mUSD και θα κερδίσετε έως και {{percentage}}% μπόνους ετησίως που μπορείτε να εξαργυρώσετε καθημερινά.", "terms_apply": "Ισχύουν όροι.", "primary_button": "Ξεκινήστε", "secondary_button": "Όχι τώρα" }, "buy_musd": "Αγοράστε mUSD", "get_musd": "Αποκτήστε mUSD", - "bonus_title": "Get {{percentage}}% on your stablecoins", - "bonus_description": "Convert your stablecoins to mUSD and get a {{percentage}}% annualized bonus.", + "bonus_title": "Λάβετε {{percentage}}% σε stablecoins", + "bonus_description": "Μετατρέψτε τα stablecoins σε mUSD και θα έχετε {{percentage}}% μπόνους ετησίως.", "powered_by_relay": "Υποστηρίζεται από το Relay", "max": "Μεγ", "quick_convert_button": "Μετατροπή", @@ -6044,14 +6049,14 @@ "tooltip_title": "Κερδίστε απόδοση με τα mUSD", "tooltip_content": "Μετατρέψτε USDC, USDT ή DAI σε mUSD, το stablecoin του MetaMask που υποστηρίζεται από το δολάριο. Κερδίστε απόδοση {{apy}} για κάθε δολάριο που διατηρείτε.", "quick_convert": { - "title": "Convert and get {{percentage}}%", - "subtitle": "Convert your stablecoins to mUSD and receive up to a {{percentage}}% annualized bonus that you can claim daily.", + "title": "Μετατρέψτε και κερδίστε {{percentage}}%", + "subtitle": "Μετατρέψτε τα stablecoins σε mUSD και θα λάβετε έως και {{percentage}}% μπόνους ετησίως που μπορείτε να εξαργυρώσετε καθημερινά.", "inline_failed_message": "Η μετατροπή απέτυχε. Προσπαθήστε ξανά.", "confirmation": { "title": "Μετατροπή μέγιστου ποσού" } }, - "percentage_bonus": "{{percentage}}% bonus", + "percentage_bonus": "{{percentage}}% μπόνους", "rate": "Χρέωση" }, "bonus_claim": { @@ -6092,7 +6097,9 @@ "fee": "Τέλη", "errors": { "insufficient_balance": "Δεν έχετε αρκετό υπόλοιπο πόρων για να εκτελέσετε αυτή την ενέργεια." - } + }, + "trx_unstaking_in_progress": "Η αποδέσμευση {{amount}} TRX βρίσκεται σε εξέλιξη. Η διαδικασία διαρκεί 14 ημέρες.", + "has_claimable_trx": "You can claim {{amount}} TRX. Once claimed you'll get TRX back in your wallet." }, "stake_eth": "Ποντάρισμα σε ETH", "unstake_eth": "Ακύρωση πονταρίσματος σε ETH", @@ -6343,7 +6350,8 @@ "metamask_fee": "Χρεώσεις στο MetaMask", "network_fee": "Τέλη δικτύου", "bridge_fee": "Τέλος παρόχου για την μεταφορά", - "provider_fee": "Τέλη παρόχου" + "provider_fee": "Τέλη παρόχου", + "sending": "Αποστολή" }, "title": { "signature": "Αίτημα υπογραφής", @@ -6381,10 +6389,10 @@ "transaction_fee": "Θα ανταλλάξουμε τα tokens σας με USDC.e στο δίκτυο Polygon, που χρησιμοποιείται για τις Προβλέψεις. Οι πάροχοι ανταλλαγών ενδέχεται να χρεώσουν προμήθεια, αλλά το MetaMask δεν χρεώνει." }, "predict_withdraw": { - "transaction_fee": "MetaMask will swap to your desired token for you. No MetaMask fee applies when you swap to mUSD." + "transaction_fee": "Το MetaMask θα κάνει ανταλλαγή στο token που θέλετε. Δεν υπάρχει χρέωση στο MetaMask όταν κάνετε ανταλλαγή σε mUSD." }, "musd_conversion": { - "transaction_fee": "mUSD conversion fees include network costs and may include provider fees. No MetaMask fee applies when you convert to mUSD." + "transaction_fee": "Τα τέλη μετατροπής σε mUSD περιλαμβάνουν τα έξοδα δικτύου και ενδέχεται να περιλαμβάνουν τα τέλη παρόχου. Δεν υπάρχει χρέωση στο MetaMask όταν μετατρέπετε σε mUSD." }, "title": { "transaction_fee": "Τέλη" @@ -6570,12 +6578,12 @@ "hardware_wallet_not_supported": "Τα πορτοφόλια υλικού δεν υποστηρίζονται ακόμη. Χρησιμοποιήστε ένα θερμό πορτοφόλι για να συνεχίσετε.", "hardware_wallet_not_supported_solana": "Τα πορτοφόλια υλικού δεν υποστηρίζουν ακόμα την Solana. Χρησιμοποιήστε ένα θερμό πορτοφόλι για να συνεχίσετε.", "price_impact_info_title": "Αντίκτυπος στην τιμή", - "price_impact_info_description": "Η επίδραση στη τιμή (price impact) δείχνει πόσο επηρεάζει η εντολή ανταλλαγής σας την τιμή του περιουσιακού στοιχείου στην αγορά. Εξαρτάται από το μέγεθος της συναλλαγής και τη διαθέσιμη ρευστότητα στη δεξαμενή (pool). Το MetaMask δεν επηρεάζει ούτε ελέγχει την επίδραση στη τιμή.", + "price_impact_info_description": "This is how your trade changes the market price of a token. It depends on the trade size, available liquidity, and provider fees. MetaMask doesn't control price impact.", "price_impact_info_gasless_description": "Η επίδραση στην τιμή αντικατοπτρίζει το πώς η εντολή ανταλλαγής σας επηρεάζει την τιμή αγοράς του περιουσιακού στοιχείου. Αν δεν διαθέτετε αρκετά κεφάλαια για τα τέλη συναλλαγής, μέρος του αρχικού σας token κατανέμεται αυτόματα για την κάλυψη των χρεώσεων, γεγονός που αυξάνει την επίδραση στην τιμή. Το MetaMask δεν επηρεάζει ούτε ελέγχει την επίδραση στην τιμή.", - "price_impact_warning_description": "This trade has an estimated {{priceImpact}} price impact, which reflects how much your trade changes the market price. The quote already reflects this.", - "price_impact_high": "High price impact", - "price_impact_execution_description": "You'll lose approximately {{priceImpact}} of your token's value on this swap. Try lowering the amount or choosing a more liquid route.", - "proceed": "Proceed", + "price_impact_warning_description": "Because of your trade size and available liquidity, you'll get about {{priceImpact}} less than the market price. This is already factored into your quote.", + "price_impact_high": "Υψηλή επίδραση στην τιμή", + "price_impact_execution_description": "Θα χάσετε περίπου {{priceImpact}} από την αξία του token σας σε αυτή την ανταλλαγή. Προσπαθήστε να μειώσετε το ποσό ή να επιλέξετε ένα κανάλι με μεγαλύτερη ρευστότητα.", + "proceed": "Συνεχίστε", "cancel": "Άκυρο", "slippage_info_title": "Απόκλιση", "slippage_info_description": "Το ποσοστό μεταβολής στην τιμή που είστε διατεθειμένοι να αποδεχθείτε πριν ακυρωθεί η συναλλαγή.", @@ -6603,7 +6611,14 @@ "exceeding_upper_slippage_error": "Δεν μπορείτε να εισαγάγετε τιμή μεγαλύτερη από {{value}}%", "custom": "Προσαρμογή", "invalid_recipient_address": "Μη έγκυρη διεύθυνση", - "got_it": "Got it" + "select_quote": "Επιλέξτε προσφορά", + "select_quote_info": "Οι προσφορές ταξινομούνται βάσει του εκτιμώμενου συνολικού κόστους, το οποίο περιλαμβάνει την ισοτιμία και τα τέλη δικτύου.", + "lowest_cost": "Χαμηλότερο κόστος", + "total_cost": "Συνολικό κόστος", + "got_it": "Κατανοητό", + "price_impact_warning_title": "Υψηλή επίδραση στην τιμή", + "price_impact_error_title": "Very high price impact", + "price_impact_error_description": "You'll lose approximately {{priceImpact}} of your token's market price on this swap. Try a smaller trade or a more liquid route to improve your rate." }, "quote_expired_modal": { "title": "Υπάρχουν διαθέσιμες νέες προσφορές", @@ -6900,7 +6915,7 @@ "title": "Πληκτρολογήστε τον κωδικό πρόσβασης", "description": "Πληκτρολογήστε τον κωδικό του πορτοφολιού σας για να δείτε τα στοιχεία της κάρτας.", "description_unfreeze": "Εισαγάγετε τον κωδικό πρόσβασης του πορτοφολιού σας για να συνεχίσετε τις δαπάνες με την κάρτα σας.", - "description_view_pin": "Enter your wallet password to view your card PIN.", + "description_view_pin": "Πληκτρολογήστε τον κωδικό πρόσβασης του πορτοφολιού σας για να δείτε το PIN.", "placeholder": "Κωδικός πρόσβασης", "confirm": "Επιβεβαίωση", "cancel": "Ακύρωση", @@ -6908,7 +6923,7 @@ "error_incorrect": "Λανθασμένος κωδικός. Παρακαλούμε δοκιμάστε ξανά." }, "view_pin_bottomsheet": { - "title": "Your Card PIN" + "title": "Το PIN της κάρτας σας" }, "choose_your_card": { "title": "Επιλέξτε την κάρτα σας", @@ -7225,9 +7240,9 @@ "view_card_details": "Προβολή στοιχείων κάρτας", "hide_card_details": "Απόκρυψη στοιχείων κάρτας", "view_card_details_description": "Αριθμός κάρτας, ημερομηνία λήξης και CVV", - "view_pin": "View PIN", - "view_pin_description": "View your card PIN securely", - "view_pin_error": "Failed to load PIN. Please try again.", + "view_pin": "Δείτε το PIN", + "view_pin_description": "Δείτε με ασφάλεια το PIN της κάρτας σας", + "view_pin_error": "Αποτυχία φόρτωσης του PIN. Παρακαλούμε προσπαθήστε ξανά.", "manage_spending_limit": "Διαχείριση ορίου", "manage_spending_limit_description_restricted": "Ο περιορισμός συναλλαγών είναι ενεργός", "manage_spending_limit_description_full": "Η πλήρης πρόσβαση είναι ενεργή", @@ -7240,7 +7255,7 @@ "order_metal_card_description": "Παραγγείλετε τώρα τη φυσική Metal Card σας", "cashback": "Επιστροφή χρημάτων", "cashback_description": "Κερδίστε 1% επιστροφή σε κάθε συναλλαγή", - "cashback_description_metal": "Earn 3% back on all spending", + "cashback_description_metal": "Κερδίστε 3% επιστροφή σε κάθε συναλλαγή", "freeze_card": "Πάγωμα κάρτας", "unfreeze_card": "Ξεπάγωμα κάρτας", "freeze_card_description": "Παύση όλων των δαπανών στην κάρτα σας", @@ -7394,7 +7409,8 @@ "pay_with_modal": { "title": "Επιλέξτε μέθοδο πληρωμής", "title_receive": "Επιλέξτε το token που θα λάβετε", - "no_gas": "Δεν υπάρχει διαθέσιμο υπόλοιπο για τα τέλη συναλλαγών" + "no_gas": "Δεν υπάρχει διαθέσιμο υπόλοιπο για τα τέλη συναλλαγών", + "not_supported": "Δεν υποστηρίζεται" }, "connection_removed_modal": { "title": "Οι συνδέσεις αφαιρέθηκαν", @@ -7632,12 +7648,12 @@ "environment_selector": "Περιβάλλον", "environment_cancel": "Άκυρο", "environment_default": "Προεπιλογή", - "off_device_accounts_banner_title": "Missing Enrolled Accounts", - "off_device_accounts_banner_description": "There are accounts that were enrolled into the rewards program but are not found on this device.", - "off_device_accounts_banner_cta": "View", - "off_device_accounts_sheet_title": "Missing Enrolled Accounts", - "off_device_accounts_sheet_description": "These might belong to a wallet that has not yet been added after reinstalling MetaMask. Don't recognize any of these addresses?", - "off_device_accounts_sheet_let_us_know": "Let us know" + "off_device_accounts_banner_title": "Δεν υπάρχουν καταχωρημένοι λογαριασμοί", + "off_device_accounts_banner_description": "Υπάρχουν λογαριασμοί που είχαν εγγραφεί στο πρόγραμμα ανταμοιβών, αλλά δεν εντοπίζονται σε αυτήν τη συσκευή.", + "off_device_accounts_banner_cta": "Προβολή", + "off_device_accounts_sheet_title": "Δεν υπάρχουν καταχωρημένοι λογαριασμοί", + "off_device_accounts_sheet_description": "Αυτοί οι λογαριασμοί μπορεί να ανήκουν σε πορτοφόλι που δεν έχει προστεθεί ακόμη μετά την επανεγκατάσταση του MetaMask. Δεν αναγνωρίζετε καμία από αυτές τις διευθύνσεις;", + "off_device_accounts_sheet_let_us_know": "Ενημερώστε μας" }, "referred_by_code": { "title": "Κωδικός παραπομπής", @@ -7835,12 +7851,12 @@ "description": "Παρακαλούμε δημιουργήστε μια νέα σύνδεση από την εφαρμογή για να συνεχίσετε." }, "show_internal_error": { - "title": "Something went wrong", - "description": "An unexpected error occurred. Please try again." + "title": "Κάτι πήγε στραβά", + "description": "Παρουσιάστηκε ένα απρόβλεπτο σφάλμα. Προσπαθήστε ξανά." }, "show_method_error": { - "title": "Request failed", - "description": "The request could not be completed. Please try again." + "title": "Αποτυχία αιτήματος", + "description": "Το αίτημα δεν μπόρεσε να ολοκληρωθεί. Παρακαλούμε προσπαθήστε ξανά." } }, "network_connection_banner": { @@ -7981,7 +7997,7 @@ "scanning": "Σάρωση για συσκευές...", "no_devices_found": "Δεν βρέθηκαν συσκευές", "no_devices_hint": "Βεβαιωθείτε ότι το {{device}} είναι ξεκλείδωτο και ότι το Bluetooth είναι ενεργοποιημένο", - "tips": "Unlock your {{device}}, enable Bluetooth, and ensure Do Not Disturb is turned off", + "tips": "Ξεκλειδώστε το {{device}}, ενεργοποιήστε το Bluetooth και βεβαιωθείτε ότι η λειτουργία Μην Ενοχλείτε είναι απενεργοποιημένη", "connect": "Σύνδεση", "rescan": "Σάρωση ξανά", "unknown_device": "Άγνωστη συσκευή", @@ -7997,7 +8013,7 @@ "nfts": "NFT", "import_nfts": "Εισαγωγή NFT", "import_nfts_description": "Προσθέστε εύκολα τα συλλεκτικά σας αντικείμενα", - "view_more": "View more", + "view_more": "Δείτε περισσότερα", "positions": { "no_tp_sl": "Δεν έχουν οριστεί ΛΚ/ΠΖ" } diff --git a/locales/languages/es.json b/locales/languages/es.json index 98a8601b1cfd..0f466a52b69c 100644 --- a/locales/languages/es.json +++ b/locales/languages/es.json @@ -104,8 +104,8 @@ "title": "Fondos insuficientes" }, "insufficient_pay_token_native_post_quote": { - "message": "Not enough {{ticker}} to cover fees. Add {{ticker}} to continue.", - "title": "Insufficient funds for post quote" + "message": "No hay suficiente {{ticker}} para cubrir las tarifas. Añade {{ticker}} para continuar.", + "title": "Fondos insuficientes para la cotización enviada" }, "no_pay_token_quotes": { "message": "Esta ruta de pago no está disponible en este momento. Intenta cambiar el monto, la red o el token y encontraremos la mejor opción.", @@ -2077,12 +2077,12 @@ "title": "Perspectivas del mercado", "a_closer_look": "Un vistazo más de cerca", "whats_being_said": "Qué se dice", - "footer_disclaimer": "AI summary for information only", + "footer_disclaimer": "Resumen generado por IA solo con fines informativos", "trade_button": "Operar", "sources_count": "+{{count}} fuentes", - "sources_title": "News sources", + "sources_title": "Fuentes de noticias", "feedback_submitted": "Comentarios enviados", - "helpful_prompt": "Was this helpful?", + "helpful_prompt": "¿Te resultó útil?", "feedback": { "title": "Comentarios", "description": "Ayuda a mejorar nuestra información de mercado generada por IA.", @@ -2197,6 +2197,7 @@ "available_balance": "Saldo disponible", "claim_amount_text": "Reclamar ${{amount}}", "claim_winnings_text": "Reclama tus ganancias", + "claiming_text": "Claiming...", "unrealized_pnl_label": "P&L no realizado", "unrealized_pnl_value": "{{amount}} ({{percent}})", "unrealized_pnl_error": "No se puede cargar", @@ -2275,6 +2276,9 @@ "title": "Algo salió mal", "description": "No se pudo proceder con la reclamación", "try_again": "Inténtalo de nuevo" + }, + "in_progress": { + "title": "Claim already in progress" } } }, @@ -2333,7 +2337,8 @@ "exchange_fee": "Tarifa de cambio", "exchange_fee_description": "Tarifa pagada al cambio o al mercado", "total_incl_fees": "tarifas incl.", - "close": "Cerrar" + "close": "Cerrar", + "fak_partial_fill_note": "Prices shown assume your order is fully filled. Actual amounts may vary if the order is only partially filled." }, "error": { "title": "No se puede conectar a las predicciones", @@ -3701,10 +3706,10 @@ "speedup_tx_title": "¿Intentar acelerar?", "speedup_tx_message": "Enviar este intento no garantiza que se acelerará la transacción original. Si el intento de aceleración se completa correctamente, se le cobrará la tarifa de transacción anterior.", "nevermind": "No importa", - "cancel_speedup_speedup_title": "Speed up Transaction", - "cancel_speedup_cancel_title": "Cancel Transaction", - "cancel_speedup_speedup_message": "This network fee will replace the original.", - "cancel_speedup_cancel_message": "This transaction will be canceled and this network fee will replace the original.", + "cancel_speedup_speedup_title": "Acelerar transacción", + "cancel_speedup_cancel_title": "Cancelar transacción", + "cancel_speedup_speedup_message": "Esta tarifa de red sustituirá a la original.", + "cancel_speedup_cancel_message": "Esta transacción se cancelará y esta tarifa de red sustituirá a la original.", "edit_network_fee": "Editar tarifa de gas", "edit_priority": "Editar prioridad", "gas_cancel_fee": "Tarifa de cancelación de gas", @@ -4837,7 +4842,7 @@ "quote_unavailable": "Cotización no disponible.", "providers": "Proveedores", "quotes_displayed_for": "Cotizaciones mostradas para {{paymentMethodName}}.", - "other_options": "Other options", + "other_options": "Otras opciones", "previously_used": "Usado anteriormente", "best_rate": "Mejor tarifa", "most_reliable": "Más confiable", @@ -4948,10 +4953,10 @@ "provider_picker_modal": { "title": "Elegir un proveedor" }, - "contact_provider_support": "Contact {{provider}} support", + "contact_provider_support": "Comunícate con el soporte de {{provider}}", "got_it": "Entendido", - "encountered_error": "We've encountered an error", - "no_quotes_error": "We encountered a problem fetching quotes from {{provider}}. Try a different amount or changing provider.", + "encountered_error": "Se produjo un error", + "no_quotes_error": "Se produjo un problema al obtener las cotizaciones de {{provider}}. Intenta con otro monto o cambia de proveedor.", "change_provider_button": "Cambiar de proveedor" }, "fiat_on_ramp_aggregator": { @@ -5914,7 +5919,7 @@ "error_description": "Instalación fallida de {{snap}}." }, "earn": { - "claimable_bonus_tooltip": "The annualized bonus you’ve earned for holding mUSD. Your bonus is claimable daily on Linea.", + "claimable_bonus_tooltip": "El bono anualizado que has ganado por mantener mUSD. Puedes reclamar tu bono diariamente en Linea.", "earn_a_percentage_bonus": "Gana un bono del {{percentage}} %", "claimable_bonus": "Bonificación reclamable", "claim_bonus": "Reclamar bono", @@ -6022,21 +6027,21 @@ "toasts": { "converting": "Convirtiendo {{token}} → mUSD", "eta": "~{{time}}", - "delivered": "mUSD conversion successful", - "delivered_description": "Bonus will be claimable within a day.", + "delivered": "Conversión de mUSD realizada correctamente", + "delivered_description": "El bono se podrá reclamar en un plazo de un día.", "failed": "Conversión de mUSD fallida" }, "education": { "heading": "OBTÉN {{percentage}} % EN\nMONEDAS ESTABLES", - "description": "Convert your stablecoins to mUSD and earn up to a {{percentage}}% annualized bonus that you can claim daily.", + "description": "Convierte tus monedas estables a mUSD y gana hasta un {{percentage}} % de bono anualizado que puedes reclamar diariamente.", "terms_apply": "Se aplican términos y condiciones.", "primary_button": "Comenzar", "secondary_button": "Ahora no" }, "buy_musd": "Comprar mUSD", "get_musd": "Obtener USDC", - "bonus_title": "Get {{percentage}}% on your stablecoins", - "bonus_description": "Convert your stablecoins to mUSD and get a {{percentage}}% annualized bonus.", + "bonus_title": "Obtén un {{percentage}} % en tus monedas estables", + "bonus_description": "Convierte tus stablecoins a mUSD y obtén un {{percentage}} % de bono anualizado.", "powered_by_relay": "Desarrollado por Relay", "max": "Máx.", "quick_convert_button": "Convertir", @@ -6044,14 +6049,14 @@ "tooltip_title": "Gana rendimiento con mUSD", "tooltip_content": "Convierte tus USDC, USDT o DAI en mUSD, la moneda estable de MetaMask respaldada por dólares. Gana un rendimiento del {{apy}} por cada dólar que mantengas.", "quick_convert": { - "title": "Convert and get {{percentage}}%", - "subtitle": "Convert your stablecoins to mUSD and receive up to a {{percentage}}% annualized bonus that you can claim daily.", + "title": "Convierte y obtén un {{percentage}} %", + "subtitle": "Convierte tus monedas estables a mUSD y recibe hasta un {{percentage}} % de bono anualizado que puedes reclamar diariamente.", "inline_failed_message": "Conversión fallida. Inténtalo de nuevo.", "confirmation": { "title": "Convertir máx." } }, - "percentage_bonus": "{{percentage}}% bonus", + "percentage_bonus": "Bonificación del {{percentage}} %", "rate": "Tasa" }, "bonus_claim": { @@ -6092,7 +6097,9 @@ "fee": "Tarifa", "errors": { "insufficient_balance": "No tienes suficiente saldo de recursos para realizar esta acción." - } + }, + "trx_unstaking_in_progress": "Unstaking de {{amount}} n curso. El unstaking tarda 14 días.", + "has_claimable_trx": "You can claim {{amount}} TRX. Once claimed you'll get TRX back in your wallet." }, "stake_eth": "Hacer staking de ETH", "unstake_eth": "Dejar de hacer staking de ETH", @@ -6343,7 +6350,8 @@ "metamask_fee": "Tarifa de MetaMask", "network_fee": "Tarifa de red", "bridge_fee": "Tarifa del proveedor del puente", - "provider_fee": "Tarifa del proveedor" + "provider_fee": "Tarifa del proveedor", + "sending": "Enviando" }, "title": { "signature": "Solicitud de firma", @@ -6381,10 +6389,10 @@ "transaction_fee": "Canjearemos tus tokens por USDC en Polygon, la red que usa Predicciones. Los proveedores de canje pueden cobrar una comisión, pero MetaMask no." }, "predict_withdraw": { - "transaction_fee": "MetaMask will swap to your desired token for you. No MetaMask fee applies when you swap to mUSD." + "transaction_fee": "MetaMask realizará el canje por el token que desees. No se aplica ninguna tarifa de MetaMask al canjear a mUSD." }, "musd_conversion": { - "transaction_fee": "mUSD conversion fees include network costs and may include provider fees. No MetaMask fee applies when you convert to mUSD." + "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." }, "title": { "transaction_fee": "Tarifas" @@ -6570,12 +6578,12 @@ "hardware_wallet_not_supported": "Las billeteras físicas aún no son compatibles. Usa una billetera en caliente para continuar.", "hardware_wallet_not_supported_solana": "Las billeteras físicas aún no son compatibles con Solana. Usa una billetera en caliente para continuar.", "price_impact_info_title": "Impacto sobre el precio", - "price_impact_info_description": "El impacto en el precio refleja cómo tu orden de canje afecta el precio de mercado del activo. Depende del tamaño de la operación y de la liquidez disponible en el fondo. MetaMask no influye ni controla el impacto en el precio.", + "price_impact_info_description": "This is how your trade changes the market price of a token. It depends on the trade size, available liquidity, and provider fees. MetaMask doesn't control price impact.", "price_impact_info_gasless_description": "El impacto en el precio refleja cómo tu orden de canje afecta el precio de mercado del activo. Si no tienes suficientes fondos para gas, parte de tu token de origen se asigna automáticamente para cubrir las tarifas, lo que aumenta el impacto en el precio. MetaMask no influye ni controla el impacto en el precio.", - "price_impact_warning_description": "This trade has an estimated {{priceImpact}} price impact, which reflects how much your trade changes the market price. The quote already reflects this.", - "price_impact_high": "High price impact", - "price_impact_execution_description": "You'll lose approximately {{priceImpact}} of your token's value on this swap. Try lowering the amount or choosing a more liquid route.", - "proceed": "Proceed", + "price_impact_warning_description": "Because of your trade size and available liquidity, you'll get about {{priceImpact}} less than the market price. This is already factored into your quote.", + "price_impact_high": "Alto impacto en el precio", + "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", "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.", @@ -6603,7 +6611,14 @@ "exceeding_upper_slippage_error": "No puedes introducir un valor mayor al {{value}} %", "custom": "Personalizar", "invalid_recipient_address": "Dirección no válida", - "got_it": "Got it" + "select_quote": "Seleccionar cotización", + "select_quote_info": "Las cotizaciones se ordenan según el costo total estimado, que incluye el tipo de cambio y la tarifa de red.", + "lowest_cost": "Menor costo", + "total_cost": "Costo total", + "got_it": "Entendido", + "price_impact_warning_title": "Alto impacto en el precio", + "price_impact_error_title": "Very high price impact", + "price_impact_error_description": "You'll lose approximately {{priceImpact}} of your token's market price on this swap. Try a smaller trade or a more liquid route to improve your rate." }, "quote_expired_modal": { "title": "Hay nuevas cotizaciones disponibles", @@ -6900,7 +6915,7 @@ "title": "Ingresar contraseña", "description": "Ingresa la contraseña de tu billetera para ver los detalles de la tarjeta.", "description_unfreeze": "Ingresa la contraseña de tu billetera para reanudar el gasto con tu tarjeta.", - "description_view_pin": "Enter your wallet password to view your card PIN.", + "description_view_pin": "Ingresa la contraseña de tu billetera para ver el PIN de tu tarjeta.", "placeholder": "Contraseña", "confirm": "Confirmar", "cancel": "Cancelar", @@ -6908,7 +6923,7 @@ "error_incorrect": "Contraseña incorrecta. Inténtalo de nuevo." }, "view_pin_bottomsheet": { - "title": "Your Card PIN" + "title": "El PIN de tu tarjeta" }, "choose_your_card": { "title": "Elige tu tarjeta", @@ -7225,9 +7240,9 @@ "view_card_details": "Ver detalles de la tarjeta", "hide_card_details": "Ocultar detalles de la tarjeta", "view_card_details_description": "Número de tarjeta, fecha de vencimiento y CVV", - "view_pin": "View PIN", - "view_pin_description": "View your card PIN securely", - "view_pin_error": "Failed to load PIN. Please try again.", + "view_pin": "Ver PIN", + "view_pin_description": "Ver el PIN de tu tarjeta de forma segura", + "view_pin_error": "Error al cargar el PIN. Inténtalo de nuevo.", "manage_spending_limit": "Administrar límite", "manage_spending_limit_description_restricted": "Hay un gasto limitado", "manage_spending_limit_description_full": "El acceso completo está activado", @@ -7240,7 +7255,7 @@ "order_metal_card_description": "Solicita ya tu tarjeta Metal física", "cashback": "Cashback", "cashback_description": "Obtén 1 % de cashback en todas tus compras", - "cashback_description_metal": "Earn 3% back on all spending", + "cashback_description_metal": "Obtén 3 % de cashback en todas tus compras", "freeze_card": "Tarjeta suspendida", "unfreeze_card": "Reactivar la tarjeta", "freeze_card_description": "Pausa todos los gastos de tu tarjeta", @@ -7394,7 +7409,8 @@ "pay_with_modal": { "title": "Seleccionar método de pago", "title_receive": "Seleccionar el token a recibir", - "no_gas": "No hay saldo nativo para gas" + "no_gas": "No hay saldo nativo para gas", + "not_supported": "No compatible" }, "connection_removed_modal": { "title": "Conexiones eliminadas", @@ -7632,12 +7648,12 @@ "environment_selector": "Entorno", "environment_cancel": "Cancelar", "environment_default": "Por defecto", - "off_device_accounts_banner_title": "Missing Enrolled Accounts", - "off_device_accounts_banner_description": "There are accounts that were enrolled into the rewards program but are not found on this device.", - "off_device_accounts_banner_cta": "View", - "off_device_accounts_sheet_title": "Missing Enrolled Accounts", - "off_device_accounts_sheet_description": "These might belong to a wallet that has not yet been added after reinstalling MetaMask. Don't recognize any of these addresses?", - "off_device_accounts_sheet_let_us_know": "Let us know" + "off_device_accounts_banner_title": "Cuentas inscritas faltantes", + "off_device_accounts_banner_description": "Hay cuentas que se inscribieron en el programa de recompensas, pero no se encuentran en este dispositivo.", + "off_device_accounts_banner_cta": "Ver", + "off_device_accounts_sheet_title": "Cuentas inscritas faltantes", + "off_device_accounts_sheet_description": "Es posible que pertenezcan a una billetera que aún no se ha añadido después de reinstalar MetaMask. ¿No reconoces alguna de estas direcciones?", + "off_device_accounts_sheet_let_us_know": "Infórmanos" }, "referred_by_code": { "title": "Código de recomendación", @@ -7835,12 +7851,12 @@ "description": "Establece una nueva conexión desde la aplicación para continuar." }, "show_internal_error": { - "title": "Something went wrong", - "description": "An unexpected error occurred. Please try again." + "title": "Algo salió mal", + "description": "Ocurrió un error inesperado. Inténtalo de nuevo." }, "show_method_error": { - "title": "Request failed", - "description": "The request could not be completed. Please try again." + "title": "Solicitud fallida", + "description": "No se pudo completar la solicitud. Inténtalo de nuevo." } }, "network_connection_banner": { @@ -7981,7 +7997,7 @@ "scanning": "Buscando dispositivos...", "no_devices_found": "No se encontraron dispositivos", "no_devices_hint": "Asegúrate de que tu {{device}} esté desbloqueado y el Bluetooth esté activado", - "tips": "Unlock your {{device}}, enable Bluetooth, and ensure Do Not Disturb is turned off", + "tips": "Desbloquea tu {{device}}, activa el Bluetooth y asegúrate de que la función \"No molestar\" esté desactivada", "connect": "Conectar", "rescan": "Volver a buscar", "unknown_device": "Dispositivo desconocido", @@ -7997,7 +8013,7 @@ "nfts": "NFT", "import_nfts": "Importar NFT", "import_nfts_description": "Agrega fácilmente tus coleccionables", - "view_more": "View more", + "view_more": "Ver más", "positions": { "no_tp_sl": "Sin TG/LP" } diff --git a/locales/languages/fr.json b/locales/languages/fr.json index d805b5f683f5..976eb3eeebb6 100644 --- a/locales/languages/fr.json +++ b/locales/languages/fr.json @@ -104,8 +104,8 @@ "title": "Fonds insuffisants" }, "insufficient_pay_token_native_post_quote": { - "message": "Not enough {{ticker}} to cover fees. Add {{ticker}} to continue.", - "title": "Insufficient funds for post quote" + "message": "Pas assez de {{ticker}} pour couvrir les frais. Ajoutez des {{ticker}} pour continuer.", + "title": "Fonds insuffisants pour l’étape post-cotation" }, "no_pay_token_quotes": { "message": "Cette voie de paiement n’est pas disponible pour le moment. Essayez de modifier le montant, le réseau ou le jeton, et nous trouverons la meilleure option.", @@ -2077,12 +2077,12 @@ "title": "Aperçu du marché", "a_closer_look": "Regarder de plus près", "whats_being_said": "Ce qu’on en dit", - "footer_disclaimer": "AI summary for information only", + "footer_disclaimer": "Résumé généré par l’IA fourni à titre informatif uniquement", "trade_button": "Trader", "sources_count": "+{{count}} sources", - "sources_title": "News sources", + "sources_title": "Sources d’information", "feedback_submitted": "Commentaire soumis", - "helpful_prompt": "Was this helpful?", + "helpful_prompt": "Cela vous a-t-il été utile ?", "feedback": { "title": "Commentaires", "description": "Aidez-nous à améliorer nos analyses de marché générées par l’IA.", @@ -2197,6 +2197,7 @@ "available_balance": "Solde disponible", "claim_amount_text": "Réclamer {{amount}} $", "claim_winnings_text": "Réclamer vos gains", + "claiming_text": "Claiming...", "unrealized_pnl_label": "Profits et pertes non réalisés", "unrealized_pnl_value": "{{amount}} ({{percent}})", "unrealized_pnl_error": "Impossible de charger", @@ -2275,6 +2276,9 @@ "title": "Quelque chose a mal tourné", "description": "Échec de la réclamation", "try_again": "Réessayez" + }, + "in_progress": { + "title": "Claim already in progress" } } }, @@ -2333,7 +2337,8 @@ "exchange_fee": "Frais de change", "exchange_fee_description": "Frais payés à la bourse ou au marché", "total_incl_fees": "frais inclus", - "close": "Fermer" + "close": "Fermer", + "fak_partial_fill_note": "Prices shown assume your order is fully filled. Actual amounts may vary if the order is only partially filled." }, "error": { "title": "Impossible de se connecter aux marchés de prédiction", @@ -3701,10 +3706,10 @@ "speedup_tx_title": "Essayer d’accélérer ?", "speedup_tx_message": "Cette tentative ne garantit aucunement l’accélération de votre transaction initiale. Si la tentative d’accélération réussit, les frais de transaction ci-dessus vous seront facturés.", "nevermind": "Peu importe", - "cancel_speedup_speedup_title": "Speed up Transaction", - "cancel_speedup_cancel_title": "Cancel Transaction", - "cancel_speedup_speedup_message": "This network fee will replace the original.", - "cancel_speedup_cancel_message": "This transaction will be canceled and this network fee will replace the original.", + "cancel_speedup_speedup_title": "Accélérer la transaction", + "cancel_speedup_cancel_title": "Annuler la transaction", + "cancel_speedup_speedup_message": "Ces frais de réseau remplaceront les frais initiaux.", + "cancel_speedup_cancel_message": "Cette transaction sera annulée et ces frais de réseau remplaceront les frais initiaux.", "edit_network_fee": "Modifier les frais de gaz", "edit_priority": "Modifier la priorité", "gas_cancel_fee": "Frais de gaz d’annulation", @@ -4837,7 +4842,7 @@ "quote_unavailable": "Cotation non disponible.", "providers": "Fournisseurs", "quotes_displayed_for": "Cotations affichées pour {{paymentMethodName}}.", - "other_options": "Other options", + "other_options": "Autres options", "previously_used": "Utilisé précédemment", "best_rate": "Meilleur taux", "most_reliable": "Le plus fiable", @@ -4948,10 +4953,10 @@ "provider_picker_modal": { "title": "Choisir un fournisseur" }, - "contact_provider_support": "Contact {{provider}} support", + "contact_provider_support": "Contacter le service d’assistance de {{provider}}", "got_it": "J’ai compris", - "encountered_error": "We've encountered an error", - "no_quotes_error": "We encountered a problem fetching quotes from {{provider}}. Try a different amount or changing provider.", + "encountered_error": "Une erreur s’est produite", + "no_quotes_error": "Nous avons rencontré un problème lors de la récupération des cotations de {{provider}}. Essayez un autre montant ou changez de fournisseur.", "change_provider_button": "Changer de fournisseur" }, "fiat_on_ramp_aggregator": { @@ -5914,7 +5919,7 @@ "error_description": "L’installation de {{snap}} a échoué." }, "earn": { - "claimable_bonus_tooltip": "The annualized bonus you’ve earned for holding mUSD. Your bonus is claimable daily on Linea.", + "claimable_bonus_tooltip": "Le bonus annualisé que vous avez gagné pour avoir détenu des mUSD. Vous pouvez réclamer votre bonus quotidiennement sur Linea.", "earn_a_percentage_bonus": "Obtenez un bonus de {{percentage}} %", "claimable_bonus": "Bonus réclamable", "claim_bonus": "Réclamer le bonus", @@ -6022,21 +6027,21 @@ "toasts": { "converting": "Conversion de {{token}} → mUSD", "eta": "Environ {{time}}", - "delivered": "mUSD conversion successful", - "delivered_description": "Bonus will be claimable within a day.", + "delivered": "Conversion en mUSD effectuée avec succès", + "delivered_description": "Le bonus pourra être réclamé dans un délai d’un jour.", "failed": "Échec de la conversion en mUSD" }, "education": { "heading": "OBTENEZ {{percentage}} % SUR LES\nSTABLECOINS", - "description": "Convert your stablecoins to mUSD and earn up to a {{percentage}}% annualized bonus that you can claim daily.", + "description": "Convertissez vos stablecoins en mUSD et gagnez jusqu’à {{percentage}} % de bonus annualisé que vous pouvez réclamer quotidiennement.", "terms_apply": "Des conditions s’appliquent.", "primary_button": "Commencer", "secondary_button": "Pas maintenant" }, "buy_musd": "Acheter des mUSD", "get_musd": "Obtenir des mUSD", - "bonus_title": "Get {{percentage}}% on your stablecoins", - "bonus_description": "Convert your stablecoins to mUSD and get a {{percentage}}% annualized bonus.", + "bonus_title": "Obtenez {{percentage}} % sur vos stablecoins", + "bonus_description": "Convertissez vos stablecoins en mUSD et obtenez un bonus annualisé de {{percentage}} %.", "powered_by_relay": "Propulsé par Relay", "max": "Maximum", "quick_convert_button": "Convertir", @@ -6044,14 +6049,14 @@ "tooltip_title": "Obtenez un rendement en détenant des mUSD", "tooltip_content": "Convertissez vos USDC, USDT ou DAI en mUSD, la stablecoin adossée au dollar de MetaMask. Obtenez un rendement de {{apy}} sur chaque mUSD que vous détenez.", "quick_convert": { - "title": "Convert and get {{percentage}}%", - "subtitle": "Convert your stablecoins to mUSD and receive up to a {{percentage}}% annualized bonus that you can claim daily.", + "title": "Convertissez et obtenez {{percentage}} %", + "subtitle": "Convertissez vos stablecoins en mUSD et obtenez jusqu’à {{percentage}} % de bonus annualisé que vous pouvez réclamer quotidiennement.", "inline_failed_message": "La conversion a échoué. Veuillez réessayer.", "confirmation": { "title": "Convertir le maximum" } }, - "percentage_bonus": "{{percentage}}% bonus", + "percentage_bonus": "Bonus de {{percentage}} %", "rate": "Taux" }, "bonus_claim": { @@ -6092,7 +6097,9 @@ "fee": "Frais", "errors": { "insufficient_balance": "Vous ne disposez pas d’un solde suffisant pour effectuer cette action." - } + }, + "trx_unstaking_in_progress": "Déstaking de {{amount}} TRX en cours. Le déstaking prend 14 jours.", + "has_claimable_trx": "You can claim {{amount}} TRX. Once claimed you'll get TRX back in your wallet." }, "stake_eth": "Staker des ETH", "unstake_eth": "Déstaker des ETH", @@ -6343,7 +6350,8 @@ "metamask_fee": "Commission MetaMask", "network_fee": "Frais de réseau", "bridge_fee": "Frais du fournisseur de passerelles", - "provider_fee": "Commission du fournisseur" + "provider_fee": "Commission du fournisseur", + "sending": "Envoi" }, "title": { "signature": "Demande de signature", @@ -6381,10 +6389,10 @@ "transaction_fee": "Nous échangerons vos jetons contre des USDC.e sur Polygon, le réseau utilisé par « Prédictions ». Les fournisseurs de services d’échange peuvent facturer des frais, mais MetaMask ne le fera pas." }, "predict_withdraw": { - "transaction_fee": "MetaMask will swap to your desired token for you. No MetaMask fee applies when you swap to mUSD." + "transaction_fee": "MetaMask échangera vos jetons pour vous. Aucuns frais MetaMask ne s’appliquent lorsque vous effectuez un échange contre des mUSD." }, "musd_conversion": { - "transaction_fee": "mUSD conversion fees include network costs and may include provider fees. No MetaMask fee applies when you convert to mUSD." + "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." }, "title": { "transaction_fee": "Frais" @@ -6570,12 +6578,12 @@ "hardware_wallet_not_supported": "Les portefeuilles matériels ne sont pas encore pris en charge. Utilisez un portefeuille connecté pour continuer.", "hardware_wallet_not_supported_solana": "Les portefeuilles matériels ne sont pas encore pris en charge pour Solana. Utilisez un portefeuille connecté pour continuer.", "price_impact_info_title": "Impact sur les prix", - "price_impact_info_description": "L’impact sur le prix reflète la manière dont votre ordre de swap affecte le prix du marché de l’actif. Il dépend du volume de la transaction et de la liquidité disponible dans le pool. MetaMask n’influence ni ne contrôle l’impact sur le prix.", + "price_impact_info_description": "This is how your trade changes the market price of a token. It depends on the trade size, available liquidity, and provider fees. MetaMask doesn't control price impact.", "price_impact_info_gasless_description": "L’impact sur le prix reflète la manière dont votre ordre de swap affecte le prix de l’actif sur le marché. Si vous ne disposez pas de fonds suffisants pour payer les frais de gaz, une partie de votre jeton source est automatiquement allouée pour couvrir ces frais, ce qui augmente l’impact sur le prix. MetaMask n’influence ni ne contrôle l’impact sur le prix.", - "price_impact_warning_description": "This trade has an estimated {{priceImpact}} price impact, which reflects how much your trade changes the market price. The quote already reflects this.", - "price_impact_high": "High price impact", - "price_impact_execution_description": "You'll lose approximately {{priceImpact}} of your token's value on this swap. Try lowering the amount or choosing a more liquid route.", - "proceed": "Proceed", + "price_impact_warning_description": "Because of your trade size and available liquidity, you'll get about {{priceImpact}} less than the market price. This is already factored into your quote.", + "price_impact_high": "Impact élevé sur le prix", + "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", "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.", @@ -6603,7 +6611,14 @@ "exceeding_upper_slippage_error": "Vous ne pouvez pas saisir une valeur supérieure à {{value}} %", "custom": "Personnalisé", "invalid_recipient_address": "Adresse non valide", - "got_it": "Got it" + "select_quote": "Sélectionner la cotation", + "select_quote_info": "Les cotations sont triées par coût total estimé, qui comprend le taux de change et les frais de réseau.", + "lowest_cost": "Coût le moins élevé", + "total_cost": "Coût total", + "got_it": "J’ai compris", + "price_impact_warning_title": "Impact élevé sur le prix", + "price_impact_error_title": "Very high price impact", + "price_impact_error_description": "You'll lose approximately {{priceImpact}} of your token's market price on this swap. Try a smaller trade or a more liquid route to improve your rate." }, "quote_expired_modal": { "title": "De nouvelles cotations sont disponibles", @@ -6900,7 +6915,7 @@ "title": "Saisissez votre mot de passe", "description": "Saisissez le mot de passe de votre portefeuille pour afficher les détails de la carte.", "description_unfreeze": "Saisissez le mot de passe de votre portefeuille pour réactiver les paiements avec votre carte.", - "description_view_pin": "Enter your wallet password to view your card PIN.", + "description_view_pin": "Saisissez le mot de passe de votre portefeuille pour afficher le code PIN de votre carte.", "placeholder": "Mot de passe", "confirm": "Confirmer", "cancel": "Annuler", @@ -6908,7 +6923,7 @@ "error_incorrect": "Mot de passe incorrect. Veuillez réessayer." }, "view_pin_bottomsheet": { - "title": "Your Card PIN" + "title": "Le code PIN de votre carte" }, "choose_your_card": { "title": "Choisissez votre carte", @@ -7225,9 +7240,9 @@ "view_card_details": "Afficher les détails de la carte", "hide_card_details": "Masquer les détails de la carte", "view_card_details_description": "Numéro, date d’expiration et CVV de la carte", - "view_pin": "View PIN", - "view_pin_description": "View your card PIN securely", - "view_pin_error": "Failed to load PIN. Please try again.", + "view_pin": "Afficher le code PIN", + "view_pin_description": "Consultez le code PIN de votre carte en toute sécurité", + "view_pin_error": "Échec du chargement du code PIN. Veuillez réessayer.", "manage_spending_limit": "Gérer la limite", "manage_spending_limit_description_restricted": "La limite de dépenses est activée", "manage_spending_limit_description_full": "L’accès complet est activé", @@ -7240,7 +7255,7 @@ "order_metal_card_description": "Commandez votre Carte Metal physique dès maintenant", "cashback": "Cashback", "cashback_description": "Gagner 1 % sur toutes vos dépenses", - "cashback_description_metal": "Earn 3% back on all spending", + "cashback_description_metal": "Gagner 3 % sur toutes vos dépenses", "freeze_card": "Bloquer la carte", "unfreeze_card": "Débloquer la carte", "freeze_card_description": "Suspendre tous les paiements avec votre carte", @@ -7394,7 +7409,8 @@ "pay_with_modal": { "title": "Sélectionnez le mode de paiement", "title_receive": "Sélectionner le jeton à recevoir", - "no_gas": "Pas de solde natif pour le gaz" + "no_gas": "Pas de solde natif pour le gaz", + "not_supported": "Non pris en charge" }, "connection_removed_modal": { "title": "Connexions supprimées", @@ -7632,12 +7648,12 @@ "environment_selector": "Environnement", "environment_cancel": "Annuler", "environment_default": "Par défaut", - "off_device_accounts_banner_title": "Missing Enrolled Accounts", - "off_device_accounts_banner_description": "There are accounts that were enrolled into the rewards program but are not found on this device.", - "off_device_accounts_banner_cta": "View", - "off_device_accounts_sheet_title": "Missing Enrolled Accounts", - "off_device_accounts_sheet_description": "These might belong to a wallet that has not yet been added after reinstalling MetaMask. Don't recognize any of these addresses?", - "off_device_accounts_sheet_let_us_know": "Let us know" + "off_device_accounts_banner_title": "Comptes inscrits manquants", + "off_device_accounts_banner_description": "Certains comptes inscrits au programme de récompenses n’ont pas été détectés sur cet appareil.", + "off_device_accounts_banner_cta": "Afficher", + "off_device_accounts_sheet_title": "Comptes inscrits manquants", + "off_device_accounts_sheet_description": "Ils peuvent appartenir à un portefeuille qui n’a pas encore été ajouté après la réinstallation de MetaMask. Ne reconnaissez-vous aucune de ces adresses ?", + "off_device_accounts_sheet_let_us_know": "Faites-le nous savoir" }, "referred_by_code": { "title": "Code de parrainage", @@ -7835,12 +7851,12 @@ "description": "Veuillez établir une nouvelle connexion depuis l’application pour continuer." }, "show_internal_error": { - "title": "Something went wrong", - "description": "An unexpected error occurred. Please try again." + "title": "Quelque chose a mal tourné", + "description": "Une erreur inattendue est survenue, veuillez réessayer." }, "show_method_error": { - "title": "Request failed", - "description": "The request could not be completed. Please try again." + "title": "Échec de la demande", + "description": "La demande n’a pas pu être traitée. Veuillez réessayer." } }, "network_connection_banner": { @@ -7981,7 +7997,7 @@ "scanning": "Recherche d’appareils…", "no_devices_found": "Aucun appareil trouvé", "no_devices_hint": "Assurez-vous que votre {{device}} est déverrouillé et que le Bluetooth est activé", - "tips": "Unlock your {{device}}, enable Bluetooth, and ensure Do Not Disturb is turned off", + "tips": "Déverrouillez votre {{device}}, activez le Bluetooth et assurez-vous que le mode « Ne pas déranger » est désactivé", "connect": "Connecter", "rescan": "Rechercher à nouveau", "unknown_device": "Appareil inconnu", @@ -7997,7 +8013,7 @@ "nfts": "NFT", "import_nfts": "Importer des NFT", "import_nfts_description": "Ajoutez facilement vos objets de collection", - "view_more": "View more", + "view_more": "Afficher plus", "positions": { "no_tp_sl": "Aucun TP/SL" } diff --git a/locales/languages/hi.json b/locales/languages/hi.json index f5b3c5c71a15..cf29c49855ff 100644 --- a/locales/languages/hi.json +++ b/locales/languages/hi.json @@ -104,8 +104,8 @@ "title": "अपर्याप्त फंड" }, "insufficient_pay_token_native_post_quote": { - "message": "Not enough {{ticker}} to cover fees. Add {{ticker}} to continue.", - "title": "Insufficient funds for post quote" + "message": "शुल्क कवर करने के लिए पर्याप्त {{ticker}} नहीं है। जारी रखने के लिए {{ticker}} जोड़ें।", + "title": "पोस्ट कोटेशन के लिए पर्याप्त फंड नहीं है" }, "no_pay_token_quotes": { "message": "यह भुगतान रूट अभी उपलब्ध नहीं है। राशि, नेटवर्क या टोकन बदलने का प्रयास करें और हम सबसे अच्छा विकल्प ढूँढ लेंगे।", @@ -2077,12 +2077,12 @@ "title": "मार्केट इनसाइट्स", "a_closer_look": "एक करीबी निगाह", "whats_being_said": "क्या कहा जा रहा है", - "footer_disclaimer": "AI summary for information only", + "footer_disclaimer": "AI सारांश केवल जानकारी के लिए है", "trade_button": "ट्रेड करें", "sources_count": "+{{count}} सोर्स", - "sources_title": "News sources", + "sources_title": "समाचार सूत्र", "feedback_submitted": "फीडबैक सबमिट किया गया", - "helpful_prompt": "Was this helpful?", + "helpful_prompt": "क्या यह सहायक था?", "feedback": { "title": "फीडबैक", "description": "हमारे AI-जनित मार्केट इनसाइट्स को बेहतर बनाने में सहायता करें।", @@ -2197,6 +2197,7 @@ "available_balance": "उपलब्ध बैलेंस", "claim_amount_text": "${{amount}} क्लेम करें", "claim_winnings_text": "जीत का ईनाम क्लेम करें", + "claiming_text": "Claiming...", "unrealized_pnl_label": "अनरियलाइज्ड P&L", "unrealized_pnl_value": "{{amount}} ({{percent}})", "unrealized_pnl_error": "लोड करने में असमर्थ", @@ -2275,6 +2276,9 @@ "title": "कुछ गलत हो गया", "description": "क्लेम नहीं हो पाया", "try_again": "फिर से प्रयास करें" + }, + "in_progress": { + "title": "Claim already in progress" } } }, @@ -2333,7 +2337,8 @@ "exchange_fee": "एक्सचेंज शुल्क", "exchange_fee_description": "एक्सचेंज या मार्केट को दिया गया शुल्क", "total_incl_fees": "शुल्क सहित", - "close": "बंद करें" + "close": "बंद करें", + "fak_partial_fill_note": "Prices shown assume your order is fully filled. Actual amounts may vary if the order is only partially filled." }, "error": { "title": "प्रीडिक्शंस से कनेक्ट नहीं हो पाया", @@ -3701,10 +3706,10 @@ "speedup_tx_title": "गति बढ़ाने का प्रयास?", "speedup_tx_message": "इस प्रयास को सबमिट करने से इस बात की गारंटी नहीं मिलती कि आपका मूल लेन-देन तेजी से होगा। यदि गति बढ़ाने का प्रयास सफल रहा, तो आपसे उपरोक्त लेन-देन शुल्क लिया जाएगा।", "nevermind": "कोई बात नहीं", - "cancel_speedup_speedup_title": "Speed up Transaction", - "cancel_speedup_cancel_title": "Cancel Transaction", - "cancel_speedup_speedup_message": "This network fee will replace the original.", - "cancel_speedup_cancel_message": "This transaction will be canceled and this network fee will replace the original.", + "cancel_speedup_speedup_title": "ट्रांसेक्शन की गति बढ़ाएं", + "cancel_speedup_cancel_title": "ट्रांसेक्शन कैंसिल करें", + "cancel_speedup_speedup_message": "यह नेटवर्क शुल्क मूल शुल्क की जगह लेगा।", + "cancel_speedup_cancel_message": "यह ट्रांसेक्शन कैंसिल कर दिया जाएगा और यह नेटवर्क शुल्क मूल शुल्क की जगह लेगा।", "edit_network_fee": "गैस शुल्क संपादित करें", "edit_priority": "प्राथमिकता को संपादित करें", "gas_cancel_fee": "गैस कैंसिल करने का शुल्क", @@ -4837,7 +4842,7 @@ "quote_unavailable": "कोटेशन उपलब्ध नहीं है।", "providers": "प्रोवाइडर्स", "quotes_displayed_for": "{{paymentMethodName}} के लिए कोटेशन दिखाए गए हैं।", - "other_options": "Other options", + "other_options": "अन्य विकल्प", "previously_used": "पहले इस्तेमाल किया गया", "best_rate": "सबसे अच्छी रेट", "most_reliable": "सबसे विश्वसनीय", @@ -4948,10 +4953,10 @@ "provider_picker_modal": { "title": "एक प्रदाता चुनें" }, - "contact_provider_support": "Contact {{provider}} support", + "contact_provider_support": "{{provider}} सपोर्ट से कॉन्टेक्ट करें", "got_it": "समझ गए", - "encountered_error": "We've encountered an error", - "no_quotes_error": "We encountered a problem fetching quotes from {{provider}}. Try a different amount or changing provider.", + "encountered_error": "हमें एक गड़बड़ी का सामना करना पड़ा है", + "no_quotes_error": "हमें {{provider}} से कोटेशन प्राप्त करने में समस्या हुई है। कोई अलग राशि आज़माएं या प्रदाता बदलें।", "change_provider_button": "प्रदाता बदलें" }, "fiat_on_ramp_aggregator": { @@ -5914,7 +5919,7 @@ "error_description": "{{snap}} का इंस्टॉलेशन नहीं हो पाया।" }, "earn": { - "claimable_bonus_tooltip": "The annualized bonus you’ve earned for holding mUSD. Your bonus is claimable daily on Linea.", + "claimable_bonus_tooltip": "mUSD रखने पर आपको मिलने वाला वार्षिक बोनस। आपका बोनस Linea पर रोज़ाना क्लेम किया जा सकता है।", "earn_a_percentage_bonus": "{{percentage}}% बोनस कमाएं", "claimable_bonus": "क्लेम करने योग्य बोनस", "claim_bonus": "बोनस क्लेम करें", @@ -6022,21 +6027,21 @@ "toasts": { "converting": "{{token}} → mUSD में कन्वर्ट किया जा रहा है", "eta": "~{{time}}", - "delivered": "mUSD conversion successful", - "delivered_description": "Bonus will be claimable within a day.", + "delivered": "mUSD कन्वर्शन सफल रहा", + "delivered_description": "बोनस एक दिन के भीतर क्लेम किया जा सकेगा।", "failed": "mUSD कन्वर्शन नहीं हो पाया" }, "education": { "heading": "स्टेबलकॉइन्स पर {{percentage}}% पाएं", - "description": "Convert your stablecoins to mUSD and earn up to a {{percentage}}% annualized bonus that you can claim daily.", + "description": "अपने स्टेबलकॉइन्स को mUSD में बदलें और {{percentage}}% तक वार्षिक बोनस कमाएं, जिसे आप रोज़ाना क्लेम कर सकते हैं।", "terms_apply": "नियम लागू।", "primary_button": "शुरू करें", "secondary_button": "अभी नहीं" }, "buy_musd": "mUSD खरीदें", "get_musd": "mUSD प्राप्त करें", - "bonus_title": "Get {{percentage}}% on your stablecoins", - "bonus_description": "Convert your stablecoins to mUSD and get a {{percentage}}% annualized bonus.", + "bonus_title": "अपने स्टेबलकॉइंस पर {{percentage}}% पाएं", + "bonus_description": "अपने स्टेबलकॉइन्स को mUSD में बदलें और {{percentage}}% वार्षिक बोनस प्राप्त करें।", "powered_by_relay": "Relay द्वारा संचालित", "max": "मैक्स", "quick_convert_button": "कन्वर्ट करें", @@ -6044,14 +6049,14 @@ "tooltip_title": "mUSD के साथ यील्ड कमाएं", "tooltip_content": "अपने USDC, USDT, या DAI को mUSD में बदलें, MetaMask का डॉलर-समर्थित स्टेबलकॉइन। आपके द्वारा रखे गए हर डॉलर पर {{apy}} यील्ड कमाएं।", "quick_convert": { - "title": "Convert and get {{percentage}}%", - "subtitle": "Convert your stablecoins to mUSD and receive up to a {{percentage}}% annualized bonus that you can claim daily.", + "title": "कन्वर्ट करें और {{percentage}}% पाएं", + "subtitle": "अपने स्टेबलकॉइन्स को mUSD में बदलें और {{percentage}}% तक वार्षिक बोनस प्राप्त करें, जिसे आप रोज़ाना क्लेम कर सकते हैं।", "inline_failed_message": "बदलाव नहीं हो पाया। कृपया दोबारा प्रयास करें।", "confirmation": { "title": "अधिकतम बदलें" } }, - "percentage_bonus": "{{percentage}}% bonus", + "percentage_bonus": "{{percentage}}% बोनस", "rate": "रेट" }, "bonus_claim": { @@ -6092,7 +6097,9 @@ "fee": "फीस", "errors": { "insufficient_balance": "आपके पास यह काम करने के लिए पर्याप्त रिसोर्स बैलेंस नहीं है।" - } + }, + "trx_unstaking_in_progress": "{{amount}} TRX का अनस्टेकिंग जारी है। अनस्टेकिंग में 14 दिन लगते हैं।", + "has_claimable_trx": "You can claim {{amount}} TRX. Once claimed you'll get TRX back in your wallet." }, "stake_eth": "ETH स्टेक करें", "unstake_eth": "ETH अनस्टेक करें", @@ -6343,7 +6350,8 @@ "metamask_fee": "MetaMask फीस", "network_fee": "नेटवर्क फीस", "bridge_fee": "प्रदाता फीस ब्रिज करें", - "provider_fee": "प्रदाता फीस" + "provider_fee": "प्रदाता फीस", + "sending": "भेजा जा रहा है" }, "title": { "signature": "हस्ताक्षर का अनुरोध", @@ -6381,10 +6389,10 @@ "transaction_fee": "हम आपके टोकन को Polygon पर USDC.e में स्वैप करेंगे, जो प्रिडिक्शन्स द्वारा इस्तेमाल होने वाला नेटवर्क है। स्वैप प्रदाता फीस ले सकते हैं, लेकिन MetaMask कोई फीस नहीं लेगा।" }, "predict_withdraw": { - "transaction_fee": "MetaMask will swap to your desired token for you. No MetaMask fee applies when you swap to mUSD." + "transaction_fee": "MetaMask आपके लिए आपके पसंदीदा टोकन में स्वैप करेगा। जब आप mUSD में स्वैप करते हैं तो कोई MetaMask शुल्क लागू नहीं होता है।" }, "musd_conversion": { - "transaction_fee": "mUSD conversion fees include network costs and may include provider fees. No MetaMask fee applies when you convert to mUSD." + "transaction_fee": "mUSD कन्वर्शन शुल्क में नेटवर्क लागत शामिल होती है और इसमें प्रदाता शुल्क भी शामिल हो सकता है। जब आप mUSD में कन्वर्ट करते हैं, तो कोई MetaMask शुल्क लागू नहीं होता।" }, "title": { "transaction_fee": "फीस" @@ -6570,12 +6578,12 @@ "hardware_wallet_not_supported": "हार्डवेयर वॉलेट अभी तक सपोर्टेड नहीं हैं। जारी रखने के लिए हॉट वॉलेट का उपयोग करें।", "hardware_wallet_not_supported_solana": "Solana के लिए हार्डवेयर वॉलेट अभी तक सपोर्टेड नहीं हैं। जारी रखने के लिए हॉट वॉलेट का उपयोग करें।", "price_impact_info_title": "कीमत का प्रभाव", - "price_impact_info_description": "प्राइस इम्पैक्ट यह दर्शाता है कि आपका स्वैप ऑर्डर एसेट की मार्केट प्राइस को कैसे प्रभावित करता है। यह ट्रेड के आकार और पूल में उपलब्ध लिक्विडिटी पर निर्भर करता है। MetaMask प्राइस इम्पैक्ट को प्रभावित या नियंत्रित नहीं करता। ", + "price_impact_info_description": "This is how your trade changes the market price of a token. It depends on the trade size, available liquidity, and provider fees. MetaMask doesn't control price impact.", "price_impact_info_gasless_description": "प्राइस इम्पैक्ट यह दर्शाता है कि आपका स्वैप ऑर्डर एसेट की मार्केट प्राइस को कैसे प्रभावित करता है। अगर आपके पास गैस के लिए पर्याप्त फंड नहीं हैं, तो आपके स्रोत टोकन का एक हिस्सा ऑटोमैटिकली फीस को कवर करने के लिए इस्तेमाल किया जाएगा, जिससे प्राइस इम्पैक्ट बढ़ जाता है। MetaMask प्राइस इम्पैक्ट को प्रभावित या नियंत्रित नहीं करता।", - "price_impact_warning_description": "This trade has an estimated {{priceImpact}} price impact, which reflects how much your trade changes the market price. The quote already reflects this.", - "price_impact_high": "High price impact", - "price_impact_execution_description": "You'll lose approximately {{priceImpact}} of your token's value on this swap. Try lowering the amount or choosing a more liquid route.", - "proceed": "Proceed", + "price_impact_warning_description": "Because of your trade size and available liquidity, you'll get about {{priceImpact}} less than the market price. This is already factored into your quote.", + "price_impact_high": "हाई प्राइस इम्पैक्ट", + "price_impact_execution_description": "इस स्वैप में आप अपने टोकन के मूल्य का लगभग {{priceImpact}} खो देंगे। राशि कम करने की कोशिश करें या अधिक लिक्विड रूट चुनें।", + "proceed": "आगे बढ़ें", "cancel": "कैंसिल करें", "slippage_info_title": "स्लिपेज (slippage)", "slippage_info_description": "ट्रांसेक्शन कैंसिल होने से पहले आप जो प्राइस में % परिवर्तन स्वीकार करने के लिए तैयार हैं।", @@ -6603,7 +6611,14 @@ "exceeding_upper_slippage_error": "आप {{value}}% से ज़्यादा वैल्यू नहीं डाल सकते", "custom": "कस्टम", "invalid_recipient_address": "एड्रेस ग़लत है", - "got_it": "Got it" + "select_quote": "कोटेशन चुनें", + "select_quote_info": "कोटेशन को अनुमानित कुल लागत के आधार पर क्रमबद्ध किया जाता है, जिसमें एक्सचेंज रेट और नेटवर्क शुल्क शामिल होते हैं।", + "lowest_cost": "सबसे कम लागत", + "total_cost": "कुल लागत", + "got_it": "समझ गए", + "price_impact_warning_title": "हाई प्राइस इम्पैक्ट", + "price_impact_error_title": "Very high price impact", + "price_impact_error_description": "You'll lose approximately {{priceImpact}} of your token's market price on this swap. Try a smaller trade or a more liquid route to improve your rate." }, "quote_expired_modal": { "title": "नये कोटेशन उपलब्ध हैं", @@ -6900,7 +6915,7 @@ "title": "पासवर्ड दर्ज करें", "description": "कार्ड विवरण देखने के लिए अपना वॉलेट पासवर्ड दर्ज करें।", "description_unfreeze": "अपने कार्ड पर खर्च फिर से शुरू करने के लिए अपना वॉलेट पासवर्ड डालें।", - "description_view_pin": "Enter your wallet password to view your card PIN.", + "description_view_pin": "अपने कार्ड का पिन (PIN) देखने के लिए अपना वॉलेट पासवर्ड दर्ज करें।", "placeholder": "पासवर्ड", "confirm": "कन्फर्म करें", "cancel": "कैंसिल करें", @@ -6908,7 +6923,7 @@ "error_incorrect": "गलत पासवर्ड। कृपया फिर से प्रयास करें।" }, "view_pin_bottomsheet": { - "title": "Your Card PIN" + "title": "आपके कार्ड का पिन" }, "choose_your_card": { "title": "अपना कार्ड चुनें", @@ -7225,9 +7240,9 @@ "view_card_details": "कार्ड विवरण देखें", "hide_card_details": "कार्ड विवरण छिपाएँ", "view_card_details_description": "कार्ड नंबर, समाप्ति तिथि और CVV", - "view_pin": "View PIN", - "view_pin_description": "View your card PIN securely", - "view_pin_error": "Failed to load PIN. Please try again.", + "view_pin": "पिन देखें", + "view_pin_description": "अपने कार्ड का पिन सुरक्षित रूप से देखें", + "view_pin_error": "पिन लोड करना नहीं हो पाया। कृपया फिर से प्रयास करें।", "manage_spending_limit": "लिमिट प्रबंधित करें", "manage_spending_limit_description_restricted": "सीमित खर्च की सेटिंग चालू है", "manage_spending_limit_description_full": "फुल एक्सेस चालू है", @@ -7240,7 +7255,7 @@ "order_metal_card_description": "अपना भौतिक मेटल कार्ड अभी ऑर्डर करें", "cashback": "कैशबैक", "cashback_description": "सारी खर्च पर 1% वापस कमाएं", - "cashback_description_metal": "Earn 3% back on all spending", + "cashback_description_metal": "सारी खर्च पर 3% वापस कमाएं", "freeze_card": "कार्ड फ़्रीज़ करें", "unfreeze_card": "कार्ड अनफ़्रीज़ करें", "freeze_card_description": "अपने कार्ड पर सभी खर्च रोकें", @@ -7394,7 +7409,8 @@ "pay_with_modal": { "title": "भुगतान विधि चुनें", "title_receive": "प्राप्त करने के लिए टोकन चुनें", - "no_gas": "गैस के लिए कोई नेटिव बैलेंस नहीं है" + "no_gas": "गैस के लिए कोई नेटिव बैलेंस नहीं है", + "not_supported": "सपोर्ट नहीं किया गया" }, "connection_removed_modal": { "title": "कनेक्शन हटा दिए गए", @@ -7632,12 +7648,12 @@ "environment_selector": "वातावरण", "environment_cancel": "कैंसिल करें", "environment_default": "डिफॉल्ट", - "off_device_accounts_banner_title": "Missing Enrolled Accounts", - "off_device_accounts_banner_description": "There are accounts that were enrolled into the rewards program but are not found on this device.", - "off_device_accounts_banner_cta": "View", - "off_device_accounts_sheet_title": "Missing Enrolled Accounts", - "off_device_accounts_sheet_description": "These might belong to a wallet that has not yet been added after reinstalling MetaMask. Don't recognize any of these addresses?", - "off_device_accounts_sheet_let_us_know": "Let us know" + "off_device_accounts_banner_title": "गायब पंजीकृत एकाउंट्स", + "off_device_accounts_banner_description": "कुछ एकाउंट्स रिवॉर्ड्स प्रोग्राम में पंजीकृत किए गए थे, लेकिन वे इस डिवाइस पर नहीं मिले।", + "off_device_accounts_banner_cta": "देखें", + "off_device_accounts_sheet_title": "गायब पंजीकृत एकाउंट्स", + "off_device_accounts_sheet_description": "ये शायद उस वॉलेट से संबंधित हो सकते हैं जिसे MetaMask को दोबारा इंस्टॉल करने के बाद अभी तक जोड़ा नहीं गया है। क्या आप इन एड्रेस में से किसी को नहीं पहचानते हैं?", + "off_device_accounts_sheet_let_us_know": "हमें बताएं" }, "referred_by_code": { "title": "रेफरल कोड", @@ -7835,12 +7851,12 @@ "description": "जारी रखने के लिए कृपया ऐप से नया कनेक्शन बनाएं।" }, "show_internal_error": { - "title": "Something went wrong", - "description": "An unexpected error occurred. Please try again." + "title": "कुछ गलत हो गया", + "description": "एक अनपेक्षित गड़बड़ी हुई। कृपया फिर से कोशिश करें।" }, "show_method_error": { - "title": "Request failed", - "description": "The request could not be completed. Please try again." + "title": "अनुरोध सफल नहीं हो पाया", + "description": "अनुरोध पूरा नहीं हो सका। कृपया फिर से कोशिश करें।" } }, "network_connection_banner": { @@ -7981,7 +7997,7 @@ "scanning": "डिवाइस के लिए स्कैन किया जा रहा है...", "no_devices_found": "कोई डिवाइस नहीं पाया गया", "no_devices_hint": "सुनिश्चित करें कि आपका {{device}} अनलॉक है और ब्लूटूथ चालू है", - "tips": "Unlock your {{device}}, enable Bluetooth, and ensure Do Not Disturb is turned off", + "tips": "अपने {{device}} को अनलॉक करें, ब्लूटूथ चालू करें और सुनिश्चित करें कि डू नॉट डिस्टर्ब बंद है", "connect": "कनेक्ट करें", "rescan": "फिर से स्कैन करें", "unknown_device": "अज्ञात डिवाइस", @@ -7997,7 +8013,7 @@ "nfts": "NFTs", "import_nfts": "NFTs इंपोर्ट करें", "import_nfts_description": "अपने कलेक्टिबल्स आसानी से जोड़ें", - "view_more": "View more", + "view_more": "अधिक देखें", "positions": { "no_tp_sl": "कोई TP/SL नहीं" } diff --git a/locales/languages/id.json b/locales/languages/id.json index e561569176c5..fd8e7d2060d1 100644 --- a/locales/languages/id.json +++ b/locales/languages/id.json @@ -104,8 +104,8 @@ "title": "Dana tidak cukup" }, "insufficient_pay_token_native_post_quote": { - "message": "Not enough {{ticker}} to cover fees. Add {{ticker}} to continue.", - "title": "Insufficient funds for post quote" + "message": "{{ticker}} tidak cukup untuk menutupi biaya. Tambahkan {{ticker}} untuk melanjutkan.", + "title": "Dana tidak cukup untuk memposting kuotasi" }, "no_pay_token_quotes": { "message": "Rute pembayaran ini tidak tersedia untuk saat ini. Coba ubah jumlah, jaringan, atau token, dan kami akan mencari opsi terbaik.", @@ -2077,12 +2077,12 @@ "title": "Wawasan pasar", "a_closer_look": "Melihat lebih dekat", "whats_being_said": "Yang sedang dibicarakan", - "footer_disclaimer": "AI summary for information only", + "footer_disclaimer": "Ringkasan AI hanya untuk informasi", "trade_button": "Berdagang", "sources_count": "+{{count}} sumber", - "sources_title": "News sources", + "sources_title": "Sumber berita", "feedback_submitted": "Umpan balik telah dikirim", - "helpful_prompt": "Was this helpful?", + "helpful_prompt": "Apakah ini membantu?", "feedback": { "title": "Umpan balik", "description": "Bantu tingkatkan wawasan pasar yang dihasilkan AI.", @@ -2197,6 +2197,7 @@ "available_balance": "Saldo tersedia", "claim_amount_text": "Klaim ${{amount}}", "claim_winnings_text": "Klaim kemenangan", + "claiming_text": "Claiming...", "unrealized_pnl_label": "P&L Belum Terealisasi", "unrealized_pnl_value": "{{amount}} ({{percent}})", "unrealized_pnl_error": "Tidak dapat memuat", @@ -2275,6 +2276,9 @@ "title": "Terjadi kesalahan", "description": "Gagal memproses klaim", "try_again": "Coba lagi" + }, + "in_progress": { + "title": "Claim already in progress" } } }, @@ -2333,7 +2337,8 @@ "exchange_fee": "Biaya penukaran", "exchange_fee_description": "Biaya yang dibayarkan ke bursa atau pasar", "total_incl_fees": "termasuk biaya", - "close": "Tutup" + "close": "Tutup", + "fak_partial_fill_note": "Prices shown assume your order is fully filled. Actual amounts may vary if the order is only partially filled." }, "error": { "title": "Tidak dapat terhubung ke prediksi", @@ -3701,10 +3706,10 @@ "speedup_tx_title": "Mencoba mempercepat?", "speedup_tx_message": "Mengirimkan upaya ini tidak menjamin percepatan transaksi awal Anda. Jika upaya percepatan berhasil, Anda akan dikenakan biaya transaksi di atas.", "nevermind": "Abaikan", - "cancel_speedup_speedup_title": "Speed up Transaction", - "cancel_speedup_cancel_title": "Cancel Transaction", - "cancel_speedup_speedup_message": "This network fee will replace the original.", - "cancel_speedup_cancel_message": "This transaction will be canceled and this network fee will replace the original.", + "cancel_speedup_speedup_title": "Percepat Transaksi", + "cancel_speedup_cancel_title": "Batalkan Transaksi", + "cancel_speedup_speedup_message": "Biaya jaringan ini akan menggantikan biaya awal.", + "cancel_speedup_cancel_message": "Transaksi ini akan dibatalkan dan biaya jaringan ini akan menggantikan biaya awal.", "edit_network_fee": "Edit biaya gas", "edit_priority": "Edit prioritas", "gas_cancel_fee": "Biaya pembatalan gas", @@ -4837,7 +4842,7 @@ "quote_unavailable": "Kuotasi tidak tersedia.", "providers": "Penyedia", "quotes_displayed_for": "Kuotasi yang ditampilkan untuk {{paymentMethodName}}.", - "other_options": "Other options", + "other_options": "Opsi lainnya", "previously_used": "Digunakan sebelumnya", "best_rate": "Tarif terbaik", "most_reliable": "Paling dapat diandalkan", @@ -4948,10 +4953,10 @@ "provider_picker_modal": { "title": "Pilih penyedia" }, - "contact_provider_support": "Contact {{provider}} support", + "contact_provider_support": "Hubungi dukungan {{provider}}", "got_it": "Mengerti", - "encountered_error": "We've encountered an error", - "no_quotes_error": "We encountered a problem fetching quotes from {{provider}}. Try a different amount or changing provider.", + "encountered_error": "Terjadi kesalahan", + "no_quotes_error": "Terjadi masalah saat mengambil kuotasi dari {{provider}}. Coba jumlah yang berbeda atau ganti penyedia.", "change_provider_button": "Ubah penyedia" }, "fiat_on_ramp_aggregator": { @@ -5914,7 +5919,7 @@ "error_description": "Instalasi {{snap}} gagal." }, "earn": { - "claimable_bonus_tooltip": "The annualized bonus you’ve earned for holding mUSD. Your bonus is claimable daily on Linea.", + "claimable_bonus_tooltip": "Bonus tahunan yang Anda peroleh karena memiliki mUSD. Bonus dapat diklaim setiap hari di Linea.", "earn_a_percentage_bonus": "Dapatkan bonus sebesar {{percentage}}%", "claimable_bonus": "Bonus yang dapat diklaim", "claim_bonus": "Klaim bonus", @@ -6022,21 +6027,21 @@ "toasts": { "converting": "Mengonversi {{token}} → mUSD", "eta": "~{{time}}", - "delivered": "mUSD conversion successful", - "delivered_description": "Bonus will be claimable within a day.", + "delivered": "Konversi mUSD berhasil", + "delivered_description": "Bonus dapat diklaim dalam waktu satu hari.", "failed": "Konversi mUSD gagal" }, "education": { "heading": "DAPATKAN {{percentage}}% PADA\nSTABLECOIN", - "description": "Convert your stablecoins to mUSD and earn up to a {{percentage}}% annualized bonus that you can claim daily.", + "description": "Konversikan stablecoin Anda ke mUSD dan dapatkan bonus tahunan hingga {{percentage}}% yang dapat diklaim setiap hari.", "terms_apply": "Syarat berlaku.", "primary_button": "Mulai", "secondary_button": "Tidak sekarang" }, "buy_musd": "Beli mUSD", "get_musd": "Dapatkan mUSD", - "bonus_title": "Get {{percentage}}% on your stablecoins", - "bonus_description": "Convert your stablecoins to mUSD and get a {{percentage}}% annualized bonus.", + "bonus_title": "Dapatkan {{percentage}}% pada stablecoin", + "bonus_description": "Konversikan stablecoin Anda ke mUSD dan dapatkan bonus tahunan sebesar {{percentage}}%.", "powered_by_relay": "Didukung oleh Relay", "max": "Maks", "quick_convert_button": "Konversikan", @@ -6044,14 +6049,14 @@ "tooltip_title": "Dapatkan keuntungan dengan mUSD", "tooltip_content": "Konversikan USDC, USDT, atau DAI dengan mUSD, stablecoin berbasis dolar milik MetaMask. Dapatkan keuntungan {{apy}} untuk setiap dolar yang Anda miliki.", "quick_convert": { - "title": "Convert and get {{percentage}}%", - "subtitle": "Convert your stablecoins to mUSD and receive up to a {{percentage}}% annualized bonus that you can claim daily.", + "title": "Konversi dan dapatkan {{percentage}}%", + "subtitle": "Konversikan stablecoin Anda ke mUSD dan terima bonus tahunan hingga {{percentage}}% yang dapat diklaim setiap hari.", "inline_failed_message": "Konversi gagal. Coba lagi.", "confirmation": { "title": "Konversi maksimal" } }, - "percentage_bonus": "{{percentage}}% bonus", + "percentage_bonus": "Bonus {{percentage}}%", "rate": "Tingkat" }, "bonus_claim": { @@ -6092,7 +6097,9 @@ "fee": "Biaya", "errors": { "insufficient_balance": "Anda tidak memiliki cukup saldo sumber daya untuk melakukan tindakan ini." - } + }, + "trx_unstaking_in_progress": "Proses pembatalan stake {{amount}} TRX sedang berlangsung. Proses ini membutuhkan waktu 14 hari.", + "has_claimable_trx": "You can claim {{amount}} TRX. Once claimed you'll get TRX back in your wallet." }, "stake_eth": "Stake ETH", "unstake_eth": "Batalkan stake ETH", @@ -6343,7 +6350,8 @@ "metamask_fee": "Biaya MetaMask", "network_fee": "Biaya jaringan", "bridge_fee": "Biaya penyedia bridge", - "provider_fee": "Biaya penyedia" + "provider_fee": "Biaya penyedia", + "sending": "Mengirim" }, "title": { "signature": "Permintaan tanda tangan", @@ -6381,10 +6389,10 @@ "transaction_fee": "Kami akan menukar token Anda dengan USDC.e di Polygon, jaringan yang digunakan oleh Predictions. Penyedia swap mungkin akan mengenakan biaya, tetapi MetaMask tidak." }, "predict_withdraw": { - "transaction_fee": "MetaMask will swap to your desired token for you. No MetaMask fee applies when you swap to mUSD." + "transaction_fee": "MetaMask akan menukar token Anda ke token yang diinginkan. MetaMask tidak mengenakan biaya saat Anda menukar ke mUSD." }, "musd_conversion": { - "transaction_fee": "mUSD conversion fees include network costs and may include provider fees. No MetaMask fee applies when you convert to mUSD." + "transaction_fee": "Biaya konversi mUSD mencakup biaya jaringan dan mungkin termasuk biaya penyedia. MetaMask tidak mengenakan biaya saat Anda mengonversi ke mUSD." }, "title": { "transaction_fee": "Biaya" @@ -6570,12 +6578,12 @@ "hardware_wallet_not_supported": "Dompet perangkat keras belum didukung. Gunakan hot wallet untuk melanjutkan.", "hardware_wallet_not_supported_solana": "Dompet perangkat keras belum didukung untuk Solana. Gunakan hot wallet untuk melanjutkan.", "price_impact_info_title": "Dampak harga", - "price_impact_info_description": "Dampak harga mencerminkan bagaimana order swap Anda memengaruhi harga pasar aset. Hal ini bergantung pada ukuran perdagangan dan likuiditas yang tersedia di pool. MetaMask tidak memengaruhi atau mengontrol dampak harga.", + "price_impact_info_description": "This is how your trade changes the market price of a token. It depends on the trade size, available liquidity, and provider fees. MetaMask doesn't control price impact.", "price_impact_info_gasless_description": "Dampak harga mencerminkan bagaimana perintah swap Anda memengaruhi harga pasar aset. Jika Anda tidak memiliki cukup dana untuk gas, sebagian token sumber akan dialokasikan secara otomatis untuk menutupi biaya, yang meningkatkan dampak harga. MetaMask tidak memengaruhi atau mengendalikan dampak harga.", - "price_impact_warning_description": "This trade has an estimated {{priceImpact}} price impact, which reflects how much your trade changes the market price. The quote already reflects this.", - "price_impact_high": "High price impact", - "price_impact_execution_description": "You'll lose approximately {{priceImpact}} of your token's value on this swap. Try lowering the amount or choosing a more liquid route.", - "proceed": "Proceed", + "price_impact_warning_description": "Because of your trade size and available liquidity, you'll get about {{priceImpact}} less than the market price. This is already factored into your quote.", + "price_impact_high": "Dampak harga tinggi", + "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", "slippage_info_title": "Selip", "slippage_info_description": "% perubahan harga yang Anda bersedia izinkan sebelum transaksi dibatalkan.", @@ -6603,7 +6611,14 @@ "exceeding_upper_slippage_error": "Anda tidak dapat memasukkan nilai yang lebih besar dari {{value}}%", "custom": "Kustom", "invalid_recipient_address": "Alamat tidak valid", - "got_it": "Got it" + "select_quote": "Pilih Kuotasi", + "select_quote_info": "Kuotasi diurutkan berdasarkan estimasi biaya total, yang mencakup nilai tukar dan biaya jaringan.", + "lowest_cost": "Biaya terendah", + "total_cost": "Biaya Total", + "got_it": "Mengerti", + "price_impact_warning_title": "Dampak harga tinggi", + "price_impact_error_title": "Very high price impact", + "price_impact_error_description": "You'll lose approximately {{priceImpact}} of your token's market price on this swap. Try a smaller trade or a more liquid route to improve your rate." }, "quote_expired_modal": { "title": "Kuotasi baru tersedia", @@ -6900,7 +6915,7 @@ "title": "Masukkan kata sandi", "description": "Masukkan kata sandi dompet untuk melihat detail kartu.", "description_unfreeze": "Masukkan kata sandi dompet Anda untuk melanjutkan penggunaan kartu.", - "description_view_pin": "Enter your wallet password to view your card PIN.", + "description_view_pin": "Masukkan kata sandi dompet Anda untuk melihat PIN kartu.", "placeholder": "Kata sandi", "confirm": "Konfirmasikan", "cancel": "Batalkan", @@ -6908,7 +6923,7 @@ "error_incorrect": "Kata sandi salah. Coba lagi." }, "view_pin_bottomsheet": { - "title": "Your Card PIN" + "title": "PIN Kartu Anda" }, "choose_your_card": { "title": "Pilih kartu", @@ -7225,9 +7240,9 @@ "view_card_details": "Lihat detail kartu", "hide_card_details": "Sembunyikan detail kartu", "view_card_details_description": "Nomor kartu, tanggal kedaluwarsa, dan CVV", - "view_pin": "View PIN", - "view_pin_description": "View your card PIN securely", - "view_pin_error": "Failed to load PIN. Please try again.", + "view_pin": "Lihat PIN", + "view_pin_description": "Lihat PIN kartu dengan aman", + "view_pin_error": "Gagal memuat PIN. Coba lagi.", "manage_spending_limit": "Kelola batasan", "manage_spending_limit_description_restricted": "Penggunaan terbatas aktif", "manage_spending_limit_description_full": "Akses penuh aktif", @@ -7240,7 +7255,7 @@ "order_metal_card_description": "Pesan Kartu Logam fisik sekarang", "cashback": "Cashback", "cashback_description": "Dapatkan pengembalian 1% untuk semua penggunaan", - "cashback_description_metal": "Earn 3% back on all spending", + "cashback_description_metal": "Dapatkan pengembalian 3% untuk semua penggunaan", "freeze_card": "Blokir kartu", "unfreeze_card": "Buka blokir kartu", "freeze_card_description": "Jeda semua penggunaan kartu", @@ -7394,7 +7409,8 @@ "pay_with_modal": { "title": "Pilih metode pembayaran", "title_receive": "Pilih terima token", - "no_gas": "Tidak ada saldo asli untuk gas" + "no_gas": "Tidak ada saldo asli untuk gas", + "not_supported": "Tidak didukung" }, "connection_removed_modal": { "title": "Koneksi dihapus", @@ -7632,12 +7648,12 @@ "environment_selector": "Lingkungan", "environment_cancel": "Batal", "environment_default": "Default", - "off_device_accounts_banner_title": "Missing Enrolled Accounts", - "off_device_accounts_banner_description": "There are accounts that were enrolled into the rewards program but are not found on this device.", - "off_device_accounts_banner_cta": "View", - "off_device_accounts_sheet_title": "Missing Enrolled Accounts", - "off_device_accounts_sheet_description": "These might belong to a wallet that has not yet been added after reinstalling MetaMask. Don't recognize any of these addresses?", - "off_device_accounts_sheet_let_us_know": "Let us know" + "off_device_accounts_banner_title": "Akun Terdaftar yang Hilang", + "off_device_accounts_banner_description": "Terdapat akun yang terdaftar dalam program reward tetapi tidak ditemukan pada perangkat ini.", + "off_device_accounts_banner_cta": "Lihat", + "off_device_accounts_sheet_title": "Akun Terdaftar yang Hilang", + "off_device_accounts_sheet_description": "Ini mungkin milik dompet yang belum ditambahkan setelah menginstal ulang MetaMask. Tidak mengenali alamat ini?", + "off_device_accounts_sheet_let_us_know": "Beri tahu kami" }, "referred_by_code": { "title": "Kode Referensi", @@ -7835,12 +7851,12 @@ "description": "Buat koneksi baru dari aplikasi untuk melanjutkan." }, "show_internal_error": { - "title": "Something went wrong", - "description": "An unexpected error occurred. Please try again." + "title": "Terjadi kesalahan", + "description": "Terjadi kesalahan tidak terduga. Coba lagi." }, "show_method_error": { - "title": "Request failed", - "description": "The request could not be completed. Please try again." + "title": "Permintaan gagal", + "description": "Permintaan tidak dapat diselesaikan. Coba lagi." } }, "network_connection_banner": { @@ -7981,7 +7997,7 @@ "scanning": "Memindai perangkat...", "no_devices_found": "Perangkat tidak ditemukan", "no_devices_hint": "Pastikan {{device}} Anda tidak terkunci dan Bluetooth diaktifkan", - "tips": "Unlock your {{device}}, enable Bluetooth, and ensure Do Not Disturb is turned off", + "tips": "Buka {{device}}, aktifkan Bluetooth, dan pastikan mode Jangan Ganggu dinonaktifkan", "connect": "Hubungkan", "rescan": "Pindai Lagi", "unknown_device": "Perangkat Tidak Dikenal", @@ -7997,7 +8013,7 @@ "nfts": "NFT", "import_nfts": "Impor NFT", "import_nfts_description": "Tambahkan koleksi Anda dengan mudah", - "view_more": "View more", + "view_more": "Lihat selengkapnya", "positions": { "no_tp_sl": "Tidak ada TP/SL" } diff --git a/locales/languages/ja.json b/locales/languages/ja.json index 646b257d9512..9de73a0d602e 100644 --- a/locales/languages/ja.json +++ b/locales/languages/ja.json @@ -104,8 +104,8 @@ "title": "資金不足" }, "insufficient_pay_token_native_post_quote": { - "message": "Not enough {{ticker}} to cover fees. Add {{ticker}} to continue.", - "title": "Insufficient funds for post quote" + "message": "手数料をカバーするのに十分な{{ticker}}がありません。続行するには{{ticker}}を追加してください。", + "title": "クォート後に必要な資金が不足しています" }, "no_pay_token_quotes": { "message": "この決済ルートは現在使用できません。金額、ネットワーク、またはトークンを変更してみてください。最善のオプションを探します。", @@ -2077,12 +2077,12 @@ "title": "市場分析情報", "a_closer_look": "詳細", "whats_being_said": "市場の声", - "footer_disclaimer": "AI summary for information only", + "footer_disclaimer": "AIによる要約は参考用です", "trade_button": "取引", "sources_count": "他{{count}}件のソース", - "sources_title": "News sources", + "sources_title": "ニュースソース", "feedback_submitted": "フィードバックが送信されました", - "helpful_prompt": "Was this helpful?", + "helpful_prompt": "この情報は役に立ちましたか?", "feedback": { "title": "フィードバック", "description": "AIが生成した市場分析情報の改善にご協力ください。", @@ -2197,6 +2197,7 @@ "available_balance": "利用可能残高", "claim_amount_text": "請求額 ${{amount}}", "claim_winnings_text": "報酬を請求", + "claiming_text": "Claiming...", "unrealized_pnl_label": "含み損益", "unrealized_pnl_value": "{{amount}} ({{percent}})", "unrealized_pnl_error": "読み込めません", @@ -2275,6 +2276,9 @@ "title": "問題が発生しました", "description": "請求に失敗しました", "try_again": "再試行してください" + }, + "in_progress": { + "title": "Claim already in progress" } } }, @@ -2333,7 +2337,8 @@ "exchange_fee": "取引所手数料", "exchange_fee_description": "取引所または市場に支払われる手数料", "total_incl_fees": "手数料込", - "close": "閉じる" + "close": "閉じる", + "fak_partial_fill_note": "Prices shown assume your order is fully filled. Actual amounts may vary if the order is only partially filled." }, "error": { "title": "予想に接続できません", @@ -3701,10 +3706,10 @@ "speedup_tx_title": "スピードアップを試みますか?", "speedup_tx_message": "このリクエストを実行しても、元のトランザクションが速くなる保証はありません。スピードアップできた場合、上記のトランザクション手数料が発生します。", "nevermind": "キャンセル", - "cancel_speedup_speedup_title": "Speed up Transaction", - "cancel_speedup_cancel_title": "Cancel Transaction", - "cancel_speedup_speedup_message": "This network fee will replace the original.", - "cancel_speedup_cancel_message": "This transaction will be canceled and this network fee will replace the original.", + "cancel_speedup_speedup_title": "トランザクションを高速化", + "cancel_speedup_cancel_title": "トランザクションをキャンセル", + "cancel_speedup_speedup_message": "このネットワーク手数料は元の手数料に置き換えられます。", + "cancel_speedup_cancel_message": "このトランザクションはキャンセルされ、このネットワーク手数料は元の手数料に置き換えられます。", "edit_network_fee": "ガス代を編集", "edit_priority": "優先度を編集", "gas_cancel_fee": "キャンセルのガス代", @@ -4837,7 +4842,7 @@ "quote_unavailable": "クォートが利用できません。", "providers": "プロバイダー", "quotes_displayed_for": "{{paymentMethodName}}用のクォートが表示されています。", - "other_options": "Other options", + "other_options": "その他のオプション", "previously_used": "以前使用", "best_rate": "最も有利なレート", "most_reliable": "信頼性が最も高い", @@ -4948,10 +4953,10 @@ "provider_picker_modal": { "title": "プロバイダーの選択" }, - "contact_provider_support": "Contact {{provider}} support", + "contact_provider_support": "{{provider}}サポートにお問い合わせください", "got_it": "了解", - "encountered_error": "We've encountered an error", - "no_quotes_error": "We encountered a problem fetching quotes from {{provider}}. Try a different amount or changing provider.", + "encountered_error": "エラーが発生しました", + "no_quotes_error": "{{provider}}からのクォート取得中に問題が発生しました。別の金額を試すか、プロバイダーを変更してください。", "change_provider_button": "プロバイダーを変更" }, "fiat_on_ramp_aggregator": { @@ -5914,7 +5919,7 @@ "error_description": "{{snap}}のインストールに失敗しました。" }, "earn": { - "claimable_bonus_tooltip": "The annualized bonus you’ve earned for holding mUSD. Your bonus is claimable daily on Linea.", + "claimable_bonus_tooltip": "mUSDを保有することで獲得した年換算ボーナスです。ボーナスはLineaで毎日請求できます。", "earn_a_percentage_bonus": "{{percentage}}%のボーナスを獲得", "claimable_bonus": "獲得できるボーナス", "claim_bonus": "ボーナスを請求する", @@ -6022,21 +6027,21 @@ "toasts": { "converting": "{{token}} → mUSDに変換中", "eta": "~{{time}}", - "delivered": "mUSD conversion successful", - "delivered_description": "Bonus will be claimable within a day.", + "delivered": "mUSDへの換算が完了しました", + "delivered_description": "ボーナスは1日以内に請求できます。", "failed": "mUSDへの変換に失敗しました" }, "education": { "heading": "ステーブルコインで\n{{percentage}}%をゲット", - "description": "Convert your stablecoins to mUSD and earn up to a {{percentage}}% annualized bonus that you can claim daily.", + "description": "お持ちのステーブルコインをmUSDに換えて、最大{{percentage}}%の年換算ボーナスを獲得しましょう。このボーナスは毎日請求できます。", "terms_apply": "諸条件が適用されます。", "primary_button": "開始", "secondary_button": "後で" }, "buy_musd": "mUSDを購入", "get_musd": "mUSDを入手", - "bonus_title": "Get {{percentage}}% on your stablecoins", - "bonus_description": "Convert your stablecoins to mUSD and get a {{percentage}}% annualized bonus.", + "bonus_title": "ステーブルコインで{{percentage}}%をゲット", + "bonus_description": "お持ちのステーブルコインをmUSDに換えて、{{percentage}}%の年換算ボーナスを獲得しましょう。", "powered_by_relay": "Powered by Relay", "max": "最大額", "quick_convert_button": "変換", @@ -6044,14 +6049,14 @@ "tooltip_title": "mUSDで収益を得ましょう", "tooltip_content": "USDC、USDT、またはDAIを、MetaMaskのドルを裏付けとするステーブルコイン、mUSDに変換しましょう。保有額1ドルあたり{{apy}}の利回りが得られます。", "quick_convert": { - "title": "Convert and get {{percentage}}%", - "subtitle": "Convert your stablecoins to mUSD and receive up to a {{percentage}}% annualized bonus that you can claim daily.", + "title": "変換して{{percentage}}%をゲット", + "subtitle": "お持ちのステーブルコインをmUSDに換えて、最大{{percentage}}%の年換算ボーナスを受け取りましょう。このボーナスは毎日請求できます。", "inline_failed_message": "変換に失敗しました。もう一度お試しください。", "confirmation": { "title": "最大額を変換" } }, - "percentage_bonus": "{{percentage}}% bonus", + "percentage_bonus": "{{percentage}}%のボーナス", "rate": "レート" }, "bonus_claim": { @@ -6092,7 +6097,9 @@ "fee": "手数料", "errors": { "insufficient_balance": "この操作を行うのに十分なリソース残高がありません。" - } + }, + "trx_unstaking_in_progress": "{{amount}}TRXのステーキング解除を実行中です。ステーキング解除には14日かかります。", + "has_claimable_trx": "You can claim {{amount}} TRX. Once claimed you'll get TRX back in your wallet." }, "stake_eth": "ETHをステーキング", "unstake_eth": "ETHのステーキングを解除", @@ -6343,7 +6350,8 @@ "metamask_fee": "MetaMaskの手数料", "network_fee": "ネットワーク手数料", "bridge_fee": "ブリッジプロバイダー手数料", - "provider_fee": "プロバイダーの手数料" + "provider_fee": "プロバイダーの手数料", + "sending": "送信中" }, "title": { "signature": "署名要求", @@ -6381,10 +6389,10 @@ "transaction_fee": "Polygon (予測で使用されるネットワーク) 上でトークンをUSDCにスワップします。スワッププロバイダーは手数料を請求する場合がありますが、MetaMaskは無料です。" }, "predict_withdraw": { - "transaction_fee": "MetaMask will swap to your desired token for you. No MetaMask fee applies when you swap to mUSD." + "transaction_fee": "MetaMaskがユーザーに代わって希望のトークンをスワップします。mUSDへのスワップ時にMetaMaskの手数料は発生しません。" }, "musd_conversion": { - "transaction_fee": "mUSD conversion fees include network costs and may include provider fees. No MetaMask fee applies when you convert to mUSD." + "transaction_fee": "mUSD換算手数料にはネットワークコストが含まれるほか、プロバイダー手数料も含まれる場合があります。なお、mUSDへの換算時にMetaMaskの手数料は発生しません。" }, "title": { "transaction_fee": "手数料" @@ -6570,12 +6578,12 @@ "hardware_wallet_not_supported": "まだハードウェアウォレットに対応していません。続行するにはホットウォレットをご使用ください。", "hardware_wallet_not_supported_solana": "Solanaはまだハードウェアウォレットに対応していません。続行するにはホットウォレットをご使用ください。", "price_impact_info_title": "プライスインパクト", - "price_impact_info_description": "プライスインパクトは、スワップ注文がその資産の市場価格にどのように影響するかを反映します。取引のサイズとプールの利用可能な流動性によって異なります。MetaMaskがプライスインパクトに影響を与えたりコントロールしたりすることはありません。", + "price_impact_info_description": "This is how your trade changes the market price of a token. It depends on the trade size, available liquidity, and provider fees. MetaMask doesn't control price impact.", "price_impact_info_gasless_description": "プライスインパクトは、スワップ注文がその資産の市場価格にどのように影響するかを反映します。ガス代の支払いに十分な資金を保有していない場合、交換前のトークンの一部が自動的に手数料の支払いに充当され、プライスインパクトが増大します。MetaMaskがプライスインパクトに影響を与えたりコントロールしたりすることはありません。", - "price_impact_warning_description": "This trade has an estimated {{priceImpact}} price impact, which reflects how much your trade changes the market price. The quote already reflects this.", - "price_impact_high": "High price impact", - "price_impact_execution_description": "You'll lose approximately {{priceImpact}} of your token's value on this swap. Try lowering the amount or choosing a more liquid route.", - "proceed": "Proceed", + "price_impact_warning_description": "Because of your trade size and available liquidity, you'll get about {{priceImpact}} less than the market price. This is already factored into your quote.", + "price_impact_high": "高プライスインパクト", + "price_impact_execution_description": "このスワップにより、トークンの価値の約{{priceImpact}}が失われます。金額を下げるか、より流動性の高いルートを選択してください。", + "proceed": "先に進む", "cancel": "キャンセル", "slippage_info_title": "スリッページ", "slippage_info_description": "トランザクションが取り消される前に許容する価格の変動率(%)。", @@ -6603,7 +6611,14 @@ "exceeding_upper_slippage_error": "{{value}}%より大きい値を入力することはできません", "custom": "カスタム", "invalid_recipient_address": "無効なアドレス", - "got_it": "Got it" + "select_quote": "クォートを選択", + "select_quote_info": "クォートは、為替レートとネットワーク手数料を含む推定総コストで並べ替えられています。", + "lowest_cost": "最低コスト", + "total_cost": "総コスト", + "got_it": "了解", + "price_impact_warning_title": "高プライスインパクト", + "price_impact_error_title": "Very high price impact", + "price_impact_error_description": "You'll lose approximately {{priceImpact}} of your token's market price on this swap. Try a smaller trade or a more liquid route to improve your rate." }, "quote_expired_modal": { "title": "新しい価格が利用可能です", @@ -6900,7 +6915,7 @@ "title": "パスワードを入力してください", "description": "カード情報を表示するには、ウォレットのパスワードを入力してください。", "description_unfreeze": "カードでの支払いを再開するには、ウォレットのパスワードを入力してください。", - "description_view_pin": "Enter your wallet password to view your card PIN.", + "description_view_pin": "カードの暗証番号を表示するには、ウォレットのパスワードを入力してください。", "placeholder": "パスワード", "confirm": "確定", "cancel": "キャンセル", @@ -6908,7 +6923,7 @@ "error_incorrect": "パスワードが正しくありません。もう一度お試しください。" }, "view_pin_bottomsheet": { - "title": "Your Card PIN" + "title": "カードの暗証番号" }, "choose_your_card": { "title": "カードの選択", @@ -7225,9 +7240,9 @@ "view_card_details": "カード情報を表示", "hide_card_details": "カード情報を非表示", "view_card_details_description": "カード番号、有効期限、CVV", - "view_pin": "View PIN", - "view_pin_description": "View your card PIN securely", - "view_pin_error": "Failed to load PIN. Please try again.", + "view_pin": "暗証番号を表示", + "view_pin_description": "カードの暗証番号を安全に表示", + "view_pin_error": "暗証番号を読み込めませんでした。もう一度お試しください。", "manage_spending_limit": "利用限度額の管理", "manage_spending_limit_description_restricted": "利用制限がオンになっています", "manage_spending_limit_description_full": "フルアクセスがオンになっています", @@ -7240,7 +7255,7 @@ "order_metal_card_description": "実物のメタルカードを今すぐ注文", "cashback": "キャッシュバック", "cashback_description": "常に支出額の1%をキャッシュバック", - "cashback_description_metal": "Earn 3% back on all spending", + "cashback_description_metal": "常に支出額の3%をキャッシュバック", "freeze_card": "カードを凍結する", "unfreeze_card": "カードの凍結を解除する", "freeze_card_description": "カードでのすべての支払いを一時停止する", @@ -7394,7 +7409,8 @@ "pay_with_modal": { "title": "支払方法を選択", "title_receive": "トークンの受取を選択してください", - "no_gas": "ガスの支払いに使えるネイティブ残高がありません" + "no_gas": "ガスの支払いに使えるネイティブ残高がありません", + "not_supported": "未対応" }, "connection_removed_modal": { "title": "接続が削除されました", @@ -7632,12 +7648,12 @@ "environment_selector": "環境", "environment_cancel": "キャンセル", "environment_default": "デフォルト", - "off_device_accounts_banner_title": "Missing Enrolled Accounts", - "off_device_accounts_banner_description": "There are accounts that were enrolled into the rewards program but are not found on this device.", - "off_device_accounts_banner_cta": "View", - "off_device_accounts_sheet_title": "Missing Enrolled Accounts", - "off_device_accounts_sheet_description": "These might belong to a wallet that has not yet been added after reinstalling MetaMask. Don't recognize any of these addresses?", - "off_device_accounts_sheet_let_us_know": "Let us know" + "off_device_accounts_banner_title": "登録済みアカウントが見つかりません", + "off_device_accounts_banner_description": "報酬プログラムに登録されているアカウントがありますが、このデバイスでは見つかりません。", + "off_device_accounts_banner_cta": "表示", + "off_device_accounts_sheet_title": "登録済みアカウントが見つかりません", + "off_device_accounts_sheet_description": "これらのアカウントは、MetaMaskの再インストール後にまだ追加されていないウォレットに属している可能性があります。これらのアドレスに心当たりがありませんか?", + "off_device_accounts_sheet_let_us_know": "お知らせください" }, "referred_by_code": { "title": "紹介コード", @@ -7835,12 +7851,12 @@ "description": "続行するには、アプリから新しい接続を確立させてください。" }, "show_internal_error": { - "title": "Something went wrong", - "description": "An unexpected error occurred. Please try again." + "title": "問題が発生しました", + "description": "予期せぬエラーが発生しました。もう一度お試しください。" }, "show_method_error": { - "title": "Request failed", - "description": "The request could not be completed. Please try again." + "title": "リクエストに失敗しました", + "description": "リクエストを完了できませんでした。もう一度お試しください。" } }, "network_connection_banner": { @@ -7981,7 +7997,7 @@ "scanning": "デバイスを検索中...", "no_devices_found": "デバイスが見つかりませんでした", "no_devices_hint": "{{device}}のロックが解除され、Bluetoothが有効になっていることを確認してください", - "tips": "Unlock your {{device}}, enable Bluetooth, and ensure Do Not Disturb is turned off", + "tips": "{{device}}のロックを解除し、Bluetoothを有効にして、サイレントモードがオフになっていることを確認してください", "connect": "接続", "rescan": "もう一度検索", "unknown_device": "不明なデバイス", @@ -7997,7 +8013,7 @@ "nfts": "NFT", "import_nfts": "NFTをインポート", "import_nfts_description": "コレクティブルを簡単に追加できます", - "view_more": "View more", + "view_more": "さらに表示", "positions": { "no_tp_sl": "TP/SLはありません" } diff --git a/locales/languages/ko.json b/locales/languages/ko.json index 6e7082bc8990..64fd07b2246d 100644 --- a/locales/languages/ko.json +++ b/locales/languages/ko.json @@ -104,8 +104,8 @@ "title": "자금 부족" }, "insufficient_pay_token_native_post_quote": { - "message": "Not enough {{ticker}} to cover fees. Add {{ticker}} to continue.", - "title": "Insufficient funds for post quote" + "message": "{{ticker}} 잔액이 부족하여 수수료를 지불할 수 없습니다. 계속하려면 {{ticker}}을(를) 추가하세요.", + "title": "견적 적용을 위한 잔액이 부족합니다" }, "no_pay_token_quotes": { "message": "현재, 이 결제 경로를 이용할 수 없습니다. 금액이나 네트워크, 토큰을 변경해 보세요. 최적의 옵션을 찾아드리겠습니다.", @@ -2077,12 +2077,12 @@ "title": "시장 인사이트", "a_closer_look": "자세히 보기", "whats_being_said": "시장 반응", - "footer_disclaimer": "AI summary for information only", + "footer_disclaimer": "참고용 AI 요약", "trade_button": "거래하기", "sources_count": "출처 {{count}}개 이상", - "sources_title": "News sources", + "sources_title": "뉴스 출처", "feedback_submitted": "피드백 제출됨", - "helpful_prompt": "Was this helpful?", + "helpful_prompt": "도움이 되셨나요?", "feedback": { "title": "피드백", "description": "AI 기반 시장 인사이트를 개선할 수 있도록 도와주세요.", @@ -2197,6 +2197,7 @@ "available_balance": "사용 가능한 잔액", "claim_amount_text": "${{amount}} 수령", "claim_winnings_text": "수익금 수령", + "claiming_text": "Claiming...", "unrealized_pnl_label": "미실현 손익", "unrealized_pnl_value": "{{amount}}({{percent}})", "unrealized_pnl_error": "불러올 수 없습니다", @@ -2275,6 +2276,9 @@ "title": "문제가 발생했습니다", "description": "수익금 수령을 진행할 수 없음", "try_again": "다시 시도" + }, + "in_progress": { + "title": "Claim already in progress" } } }, @@ -2333,7 +2337,8 @@ "exchange_fee": "거래소 수수료", "exchange_fee_description": "거래소 또는 시장에 지불한 수수료", "total_incl_fees": "수수료 포함", - "close": "닫기" + "close": "닫기", + "fak_partial_fill_note": "Prices shown assume your order is fully filled. Actual amounts may vary if the order is only partially filled." }, "error": { "title": "예측에 연결할 수 없습니다", @@ -3701,10 +3706,10 @@ "speedup_tx_title": "속도 향상을 원하시나요?", "speedup_tx_message": "이 시도를 제출한다고 해서 기존의 거래의 속도가 향상될 것이라는 보장은 없습니다. 속도 향상 시도가 성공적으로 진행되면 위에 공지된 거래 수수료가 부과됩니다.", "nevermind": "취소", - "cancel_speedup_speedup_title": "Speed up Transaction", - "cancel_speedup_cancel_title": "Cancel Transaction", - "cancel_speedup_speedup_message": "This network fee will replace the original.", - "cancel_speedup_cancel_message": "This transaction will be canceled and this network fee will replace the original.", + "cancel_speedup_speedup_title": "트랜잭션 속도 높이기", + "cancel_speedup_cancel_title": "트랜잭션 취소", + "cancel_speedup_speedup_message": "이 네트워크 수수료가 기존 수수료를 대체합니다.", + "cancel_speedup_cancel_message": "이 트랜잭션은 취소되며 이 네트워크 수수료가 기존 수수료를 대체합니다.", "edit_network_fee": "가스요금 수정", "edit_priority": "우선 순위 편집", "gas_cancel_fee": "가스 취소 수수료", @@ -4837,7 +4842,7 @@ "quote_unavailable": "견적을 확인할 수 없습니다.", "providers": "공급자", "quotes_displayed_for": "{{paymentMethodName}}에 대한 견적이 표시됨", - "other_options": "Other options", + "other_options": "기타 옵션", "previously_used": "사용한 적 있음", "best_rate": "최적 환율", "most_reliable": "가장 신뢰할 수 있음", @@ -4948,10 +4953,10 @@ "provider_picker_modal": { "title": "공급업체 변경" }, - "contact_provider_support": "Contact {{provider}} support", + "contact_provider_support": "{{provider}} 지원팀에 문의", "got_it": "컨펌", - "encountered_error": "We've encountered an error", - "no_quotes_error": "We encountered a problem fetching quotes from {{provider}}. Try a different amount or changing provider.", + "encountered_error": "오류가 발생했습니다", + "no_quotes_error": "{{provider}}에서 견적을 가져오는 중 문제가 발생했습니다. 다른 금액을 입력하거나 제공업체를 변경해 보세요.", "change_provider_button": "공급자를 변경하세요" }, "fiat_on_ramp_aggregator": { @@ -5914,7 +5919,7 @@ "error_description": "{{snap}} 설치에 실패했습니다." }, "earn": { - "claimable_bonus_tooltip": "The annualized bonus you’ve earned for holding mUSD. Your bonus is claimable daily on Linea.", + "claimable_bonus_tooltip": "mUSD 보유로 얻은 연간 보너스입니다. 보너스는 Linea에서 매일 청구할 수 있습니다.", "earn_a_percentage_bonus": "{{percentage}}% 보너스 받기", "claimable_bonus": "청구 가능한 보너스", "claim_bonus": "보너스 수령", @@ -6022,21 +6027,21 @@ "toasts": { "converting": "{{token}} → mUSD로 전환 중", "eta": "~{{time}}", - "delivered": "mUSD conversion successful", - "delivered_description": "Bonus will be claimable within a day.", + "delivered": "mUSD 환전 성공", + "delivered_description": "보너스는 하루 이내에 청구할 수 있습니다.", "failed": "mUSD 전환 실패" }, "education": { "heading": "스테이블 코인\n{{percentage}}% 혜택", - "description": "Convert your stablecoins to mUSD and earn up to a {{percentage}}% annualized bonus that you can claim daily.", + "description": "스테이블코인을 mUSD로 환전하고 매일 청구 가능한 최대 {{percentage}}%의 연간 보너스를 받으세요.", "terms_apply": "약관이 적용됩니다.", "primary_button": "시작하기", "secondary_button": "나중에" }, "buy_musd": "mUSD 구매", "get_musd": "mUSD 받기", - "bonus_title": "Get {{percentage}}% on your stablecoins", - "bonus_description": "Convert your stablecoins to mUSD and get a {{percentage}}% annualized bonus.", + "bonus_title": "스테이블코인으로 {{percentage}}% 받기", + "bonus_description": "스테이블코인을 mUSD로 환전하고 {{percentage}}%의 연간 보너스를 받으세요.", "powered_by_relay": "제공자: Relay", "max": "최대", "quick_convert_button": "전환", @@ -6044,14 +6049,14 @@ "tooltip_title": "mUSD로 수익 얻기", "tooltip_content": "USDC, USDT, DAI를 MetaMask의 달러 연동 스테이블코인인 mUSD로 전환하세요. 보유 금액 전체에 대해 {{apy}} 수익을 얻을 수 있습니다.", "quick_convert": { - "title": "Convert and get {{percentage}}%", - "subtitle": "Convert your stablecoins to mUSD and receive up to a {{percentage}}% annualized bonus that you can claim daily.", + "title": "전환 후 {{percentage}}% 받기", + "subtitle": "스테이블코인을 mUSD로 환전하고 매일 청구 가능한 최대 {{percentage}}%의 연간 보너스를 받으세요.", "inline_failed_message": "전환에 실패했습니다. 다시 시도하세요.", "confirmation": { "title": "최대 금액 전환" } }, - "percentage_bonus": "{{percentage}}% bonus", + "percentage_bonus": "{{percentage}}% 보너스", "rate": "비율" }, "bonus_claim": { @@ -6092,7 +6097,9 @@ "fee": "수수료", "errors": { "insufficient_balance": "이 작업을 수행하기에 리소스 잔액이 부족합니다." - } + }, + "trx_unstaking_in_progress": "{{amount}} TRX 언스테이킹이 진행 중입니다. 언스테이킹에는 14일이 소요됩니다.", + "has_claimable_trx": "You can claim {{amount}} TRX. Once claimed you'll get TRX back in your wallet." }, "stake_eth": "ETH 스테이크", "unstake_eth": "ETH 언스테이크", @@ -6343,7 +6350,8 @@ "metamask_fee": "MetaMask 수수료", "network_fee": "네트워크 수수료", "bridge_fee": "브릿지 제공자 수수료", - "provider_fee": "공급자 수수료" + "provider_fee": "공급자 수수료", + "sending": "전송 중" }, "title": { "signature": "서명 요청", @@ -6381,10 +6389,10 @@ "transaction_fee": "예측에서 사용하는 네트워크인 Polygon에서 토큰을 USDC.e로 스왑합니다. 스왑 제공업체가 수수료를 부과할 수 있지만 MetaMask에서 부과하는 수수료는 없습니다." }, "predict_withdraw": { - "transaction_fee": "MetaMask will swap to your desired token for you. No MetaMask fee applies when you swap to mUSD." + "transaction_fee": "MetaMask가 원하는 토큰으로 스왑해 드립니다. mUSD로 스왑할 때 MetaMask 수수료는 적용되지 않습니다." }, "musd_conversion": { - "transaction_fee": "mUSD conversion fees include network costs and may include provider fees. No MetaMask fee applies when you convert to mUSD." + "transaction_fee": "mUSD 환전 수수료에는 네트워크 비용이 포함되며 제공업체 수수료가 포함될 수 있습니다. mUSD로 환전할 때 MetaMask 수수료는 적용되지 않습니다." }, "title": { "transaction_fee": "수수료" @@ -6570,12 +6578,12 @@ "hardware_wallet_not_supported": "하드웨어 지갑은 아직 지원되지 않습니다. 핫월렛을 사용하여 계속하세요.", "hardware_wallet_not_supported_solana": "솔라나는 아직 하드웨어 지갑이 지원하지 않습니다. 계속하려면 핫월렛을 사용하세요.", "price_impact_info_title": "가격 영향", - "price_impact_info_description": "가격 영향은 회원님의 스왑 주문이 자산의 시장 가격에 미치는 영향을 나타냅니다. 이는 거래 규모와 풀의 가용 유동성에 따라 달라집니다. MetaMask는 가격 영향에 관여하지 않으며 이를 통제하지도 않습니다.", + "price_impact_info_description": "This is how your trade changes the market price of a token. It depends on the trade size, available liquidity, and provider fees. MetaMask doesn't control price impact.", "price_impact_info_gasless_description": "가격 영향은 사용자의 스왑 주문이 자산의 시장 가격에 미치는 영향을 의미합니다. 가스비를 지불할 충분한 자금이 없는 경우, 스왑할 토큰 일부가 자동으로 수수료로 사용되므로 가격 영향이 커질 수 있습니다. MetaMask는 가격 영향에 관여하지 않으며 이를 통제하지도 않습니다.", - "price_impact_warning_description": "This trade has an estimated {{priceImpact}} price impact, which reflects how much your trade changes the market price. The quote already reflects this.", - "price_impact_high": "High price impact", - "price_impact_execution_description": "You'll lose approximately {{priceImpact}} of your token's value on this swap. Try lowering the amount or choosing a more liquid route.", - "proceed": "Proceed", + "price_impact_warning_description": "Because of your trade size and available liquidity, you'll get about {{priceImpact}} less than the market price. This is already factored into your quote.", + "price_impact_high": "높은 가격 영향", + "price_impact_execution_description": "이 스왑으로 토큰 가치의 약 {{priceImpact}}을(를) 잃게 됩니다. 금액을 낮추거나 유동성이 더 많은 경로를 선택해 보세요.", + "proceed": "진행", "cancel": "취소", "slippage_info_title": "슬리피지", "slippage_info_description": "사용자가 허용하는 가격 변동률(%)로, 가격이 이보다 크게 변동하면 트랜잭션이 취소됩니다.", @@ -6603,7 +6611,14 @@ "exceeding_upper_slippage_error": "{{value}}%를 초과하는 값은 입력할 수 없습니다", "custom": "맞춤형", "invalid_recipient_address": "잘못된 주소", - "got_it": "Got it" + "select_quote": "견적 선택", + "select_quote_info": "견적은 환율과 네트워크 수수료가 포함된 예상 총비용 순으로 정렬됩니다.", + "lowest_cost": "최저 비용", + "total_cost": "총비용", + "got_it": "컨펌", + "price_impact_warning_title": "높은 가격 영향", + "price_impact_error_title": "Very high price impact", + "price_impact_error_description": "You'll lose approximately {{priceImpact}} of your token's market price on this swap. Try a smaller trade or a more liquid route to improve your rate." }, "quote_expired_modal": { "title": "새로운 견적이 있습니다", @@ -6900,7 +6915,7 @@ "title": "비밀번호 입력", "description": "카드 상세 정보를 보려면 지갑 비밀번호를 입력하세요.", "description_unfreeze": "카드 사용을 재개하려면 지갑 비밀번호를 입력하세요.", - "description_view_pin": "Enter your wallet password to view your card PIN.", + "description_view_pin": "카드 PIN을 확인하려면 지갑 비밀번호를 입력하세요.", "placeholder": "비밀번호", "confirm": "컨펌", "cancel": "취소", @@ -6908,7 +6923,7 @@ "error_incorrect": "잘못된 비밀번호입니다. 다시 시도해 주세요." }, "view_pin_bottomsheet": { - "title": "Your Card PIN" + "title": "내 카드 PIN" }, "choose_your_card": { "title": "카드 선택", @@ -7225,9 +7240,9 @@ "view_card_details": "카드 상세 정보 보기", "hide_card_details": "카드 상세 정보 숨기기", "view_card_details_description": "카드 번호, 만료일 및 CVV", - "view_pin": "View PIN", - "view_pin_description": "View your card PIN securely", - "view_pin_error": "Failed to load PIN. Please try again.", + "view_pin": "PIN 보기", + "view_pin_description": "카드 PIN을 안전하게 확인하세요", + "view_pin_error": "PIN을 불러오지 못했습니다. 다시 시도해 주세요.", "manage_spending_limit": "한도 관리", "manage_spending_limit_description_restricted": "사용 한도가 설정되어 있습니다", "manage_spending_limit_description_full": "제한 없이 사용할 수 있습니다", @@ -7240,7 +7255,7 @@ "order_metal_card_description": "실물 메탈 카드를 지금 주문하세요", "cashback": "캐시백", "cashback_description": "모든 결제 금액의 1% 돌려받기", - "cashback_description_metal": "Earn 3% back on all spending", + "cashback_description_metal": "모든 결제 금액의 3% 돌려받기", "freeze_card": "카드 정지", "unfreeze_card": "카드 정지 해제", "freeze_card_description": "카드의 모든 사용 일시 중지", @@ -7394,7 +7409,8 @@ "pay_with_modal": { "title": "결제 방법 선택", "title_receive": "토큰 받기 선택", - "no_gas": "가스비로 사용할 네이티브 토큰 잔액 없음" + "no_gas": "가스비로 사용할 네이티브 토큰 잔액 없음", + "not_supported": "지원되지 않음" }, "connection_removed_modal": { "title": "연결 제거 완료", @@ -7632,12 +7648,12 @@ "environment_selector": "환경", "environment_cancel": "취소", "environment_default": "기본", - "off_device_accounts_banner_title": "Missing Enrolled Accounts", - "off_device_accounts_banner_description": "There are accounts that were enrolled into the rewards program but are not found on this device.", - "off_device_accounts_banner_cta": "View", - "off_device_accounts_sheet_title": "Missing Enrolled Accounts", - "off_device_accounts_sheet_description": "These might belong to a wallet that has not yet been added after reinstalling MetaMask. Don't recognize any of these addresses?", - "off_device_accounts_sheet_let_us_know": "Let us know" + "off_device_accounts_banner_title": "등록된 계정 누락", + "off_device_accounts_banner_description": "리워드 프로그램에 등록된 계정이 있으나 이 기기에서 찾을 수 없습니다.", + "off_device_accounts_banner_cta": "보기", + "off_device_accounts_sheet_title": "등록된 계정 누락", + "off_device_accounts_sheet_description": "MetaMask를 다시 설치한 후 아직 추가하지 않은 지갑의 계정일 수 있습니다. 본인의 주소가 아닌 것이 있습니까?", + "off_device_accounts_sheet_let_us_know": "알려주세요" }, "referred_by_code": { "title": "추천 코드", @@ -7835,12 +7851,12 @@ "description": "계속하려면 앱에서 새로 연결해 주세요." }, "show_internal_error": { - "title": "Something went wrong", - "description": "An unexpected error occurred. Please try again." + "title": "문제가 발생했습니다", + "description": "예기치 못한 오류가 발생했습니다. 다시 시도하세요." }, "show_method_error": { - "title": "Request failed", - "description": "The request could not be completed. Please try again." + "title": "요청 실패", + "description": "요청을 완료할 수 없습니다. 다시 시도해 주세요." } }, "network_connection_banner": { @@ -7981,7 +7997,7 @@ "scanning": "장치 스캔 중...", "no_devices_found": "장치를 찾을 수 없음", "no_devices_hint": "{{device}}의 잠금이 해제되어 있고 블루투스가 활성화되어 있는지 확인하세요", - "tips": "Unlock your {{device}}, enable Bluetooth, and ensure Do Not Disturb is turned off", + "tips": "{{device}}의 잠금을 해제하고 블루투스를 켠 다음, 방해 금지 모드가 꺼져 있는지 확인하세요", "connect": "연결", "rescan": "다시 스캔", "unknown_device": "알 수 없는 장치", @@ -7997,7 +8013,7 @@ "nfts": "NFT", "import_nfts": "NFT 가져오기", "import_nfts_description": "컬렉터블을 간편하게 추가하세요", - "view_more": "View more", + "view_more": "더 보기", "positions": { "no_tp_sl": "익절/손절 미설정" } diff --git a/locales/languages/pt.json b/locales/languages/pt.json index f1a87ed1ab39..06a3bbf56fca 100644 --- a/locales/languages/pt.json +++ b/locales/languages/pt.json @@ -104,8 +104,8 @@ "title": "Fundos insuficientes" }, "insufficient_pay_token_native_post_quote": { - "message": "Not enough {{ticker}} to cover fees. Add {{ticker}} to continue.", - "title": "Insufficient funds for post quote" + "message": "Não há {{ticker}} suficiente para cobrir as taxas. Adicione {{ticker}} para continuar.", + "title": "Fundos insuficientes para colocar cotação" }, "no_pay_token_quotes": { "message": "Esta rota de pagamento não está disponível no momento. Experimente mudar o valor, a rede ou o token, e encontraremos a melhor opção.", @@ -2077,12 +2077,12 @@ "title": "Análises de mercado", "a_closer_look": "Uma análise mais detalhada", "whats_being_said": "O que as pessoas dizem", - "footer_disclaimer": "AI summary for information only", + "footer_disclaimer": "Resumo de IA apenas para fins informativos", "trade_button": "Negociar", "sources_count": "+{{count}} fontes", - "sources_title": "News sources", + "sources_title": "Fontes de notícias", "feedback_submitted": "Feedback enviado", - "helpful_prompt": "Was this helpful?", + "helpful_prompt": "Isso foi útil?", "feedback": { "title": "Comentário", "description": "Ajude a aprimorar nossas análises de mercado geradas por IA.", @@ -2197,6 +2197,7 @@ "available_balance": "Saldo disponível", "claim_amount_text": "Resgatar $ {{amount}}", "claim_winnings_text": "Resgatar ganhos", + "claiming_text": "Claiming...", "unrealized_pnl_label": "P&L não realizados", "unrealized_pnl_value": "{{amount}} ({{percent}})", "unrealized_pnl_error": "Não foi possível carregar", @@ -2275,6 +2276,9 @@ "title": "Ocorreu algum erro", "description": "Falha ao continuar com o resgate", "try_again": "Tentar novamente" + }, + "in_progress": { + "title": "Claim already in progress" } } }, @@ -2333,7 +2337,8 @@ "exchange_fee": "Taxa de câmbio", "exchange_fee_description": "Taxa paga à bolsa ou ao mercado", "total_incl_fees": "incluindo taxas", - "close": "Fechar" + "close": "Fechar", + "fak_partial_fill_note": "Prices shown assume your order is fully filled. Actual amounts may vary if the order is only partially filled." }, "error": { "title": "Não foi possível conectar-se às previsões", @@ -3701,10 +3706,10 @@ "speedup_tx_title": "Tentar acelerar?", "speedup_tx_message": "Enviar essa tentativa não garante que sua transação original será acelerada. Caso a tentativa de acelerar seja bem-sucedida, será cobrada a taxa de transação acima.", "nevermind": "Deixa para lá", - "cancel_speedup_speedup_title": "Speed up Transaction", - "cancel_speedup_cancel_title": "Cancel Transaction", - "cancel_speedup_speedup_message": "This network fee will replace the original.", - "cancel_speedup_cancel_message": "This transaction will be canceled and this network fee will replace the original.", + "cancel_speedup_speedup_title": "Acelerar transação", + "cancel_speedup_cancel_title": "Cancelar transação", + "cancel_speedup_speedup_message": "Esta taxa de rede substituirá a original.", + "cancel_speedup_cancel_message": "Esta transação será cancelada e esta taxa de rede substituirá a original.", "edit_network_fee": "Editar taxa de gás", "edit_priority": "Editar prioridade", "gas_cancel_fee": "Taxa de cancelamento de gas", @@ -4837,7 +4842,7 @@ "quote_unavailable": "Cotação não disponível.", "providers": "Fornecedores", "quotes_displayed_for": "Cotações exibidas para {{paymentMethodName}}.", - "other_options": "Other options", + "other_options": "Outras opções", "previously_used": "Usado anteriormente", "best_rate": "Melhor taxa", "most_reliable": "Mais confiável", @@ -4948,10 +4953,10 @@ "provider_picker_modal": { "title": "Escolher um provedor" }, - "contact_provider_support": "Contact {{provider}} support", + "contact_provider_support": "Contate o suporte do {{provider}}", "got_it": "Entendi", - "encountered_error": "We've encountered an error", - "no_quotes_error": "We encountered a problem fetching quotes from {{provider}}. Try a different amount or changing provider.", + "encountered_error": "Encontramos um erro", + "no_quotes_error": "Encontramos um problema ao buscar cotações de {{provider}}. Tente com um valor diferente ou mude de provedor.", "change_provider_button": "Alterar fornecedor" }, "fiat_on_ramp_aggregator": { @@ -5914,7 +5919,7 @@ "error_description": "Ocorreu uma falha na instalação de {{snap}}." }, "earn": { - "claimable_bonus_tooltip": "The annualized bonus you’ve earned for holding mUSD. Your bonus is claimable daily on Linea.", + "claimable_bonus_tooltip": "O bônus anualizado que você ganhou por manter mUSD. Seu bônus pode ser resgatado diariamente na Linea.", "earn_a_percentage_bonus": "Ganhe um bônus de {{percentage}}%", "claimable_bonus": "Bônus resgatável", "claim_bonus": "Resgatar bônus", @@ -6022,21 +6027,21 @@ "toasts": { "converting": "Convertendo {{token}} → mUSD", "eta": "~{{time}}", - "delivered": "mUSD conversion successful", - "delivered_description": "Bonus will be claimable within a day.", + "delivered": "Conversão de mUSD bem-sucedida", + "delivered_description": "O bônus poderá ser resgatado em até um dia.", "failed": "Falha ao converter mUSD" }, "education": { "heading": "RECEBA {{percentage}}% EM \nSTABLECOINS", - "description": "Convert your stablecoins to mUSD and earn up to a {{percentage}}% annualized bonus that you can claim daily.", + "description": "Converta suas moedas estáveis em mUSD e ganhe um bônus anualizado de até {{percentage}}% que você pode resgatar diariamente.", "terms_apply": "Sujeito a termos e condições.", "primary_button": "Comece já", "secondary_button": "Agora não" }, "buy_musd": "Comprar mUSD", "get_musd": "Obter mUSD", - "bonus_title": "Get {{percentage}}% on your stablecoins", - "bonus_description": "Convert your stablecoins to mUSD and get a {{percentage}}% annualized bonus.", + "bonus_title": "Obtenha {{percentage}}% sobre suas stablecoins", + "bonus_description": "Converta suas moedas estáveis em mUSD e ganhe um bônus anualizado de {{percentage}}%.", "powered_by_relay": "Desenvolvido por Relay", "max": "Máx.", "quick_convert_button": "Converter", @@ -6044,14 +6049,14 @@ "tooltip_title": "Obtenha rendimentos com mUSD", "tooltip_content": "Converta seus USDC, USDT ou DAI para mUSD, a stablecoin com lastro em dólar da MetaMask. Obtenha {{apy}} de rendimento para cada dólar que você possui.", "quick_convert": { - "title": "Convert and get {{percentage}}%", - "subtitle": "Convert your stablecoins to mUSD and receive up to a {{percentage}}% annualized bonus that you can claim daily.", + "title": "Converta e ganhe {{percentage}}%", + "subtitle": "Converta suas moedas estáveis em mUSD e receba um bônus anualizado de até {{percentage}}% que você pode resgatar diariamente.", "inline_failed_message": "Falha na conversão. Tente novamente.", "confirmation": { "title": "Converter máximo" } }, - "percentage_bonus": "{{percentage}}% bonus", + "percentage_bonus": "{{percentage}}% de bônus", "rate": "Avaliar" }, "bonus_claim": { @@ -6092,7 +6097,9 @@ "fee": "Taxa", "errors": { "insufficient_balance": "Você não possui saldo de recursos suficiente para realizar esta ação." - } + }, + "trx_unstaking_in_progress": "Desfazer staking de {{amount}} TRX em andamento. O processo de desfazer staking leva 14 dias.", + "has_claimable_trx": "You can claim {{amount}} TRX. Once claimed you'll get TRX back in your wallet." }, "stake_eth": "Fazer staking de ETH", "unstake_eth": "Retirar ETH do staking", @@ -6343,7 +6350,8 @@ "metamask_fee": "Taxa da MetaMask", "network_fee": "Taxa de rede", "bridge_fee": "Taxa do provedor de ponte", - "provider_fee": "Taxa do provedor" + "provider_fee": "Taxa do provedor", + "sending": "Enviando" }, "title": { "signature": "Solicitação de assinatura", @@ -6381,10 +6389,10 @@ "transaction_fee": "Trocaremos seus tokens por USDC.e na Polygon, a rede usada pela Predictions. Provedores de swaps talvez cobrem taxas, mas a MetaMask não cobra." }, "predict_withdraw": { - "transaction_fee": "MetaMask will swap to your desired token for you. No MetaMask fee applies when you swap to mUSD." + "transaction_fee": "A MetaMask fará a conversão para o token desejado para você. A MetaMask não aplica taxas quando você converte para mUSD." }, "musd_conversion": { - "transaction_fee": "mUSD conversion fees include network costs and may include provider fees. No MetaMask fee applies when you convert to mUSD." + "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." }, "title": { "transaction_fee": "Taxas" @@ -6570,12 +6578,12 @@ "hardware_wallet_not_supported": "Ainda não oferecemos suporte a carteiras de hardware. Use uma hot wallet para continuar.", "hardware_wallet_not_supported_solana": "Carteiras de hardware ainda não são compatíveis com Solana. Use uma hot wallet para continuar.", "price_impact_info_title": "Impacto do preço", - "price_impact_info_description": "O impacto no preço reflete como sua ordem de troca afeta o preço de mercado do ativo. Ele depende do tamanho da negociação e da liquidez disponível no pool. A MetaMask não influencia nem controla o impacto no preço.", + "price_impact_info_description": "This is how your trade changes the market price of a token. It depends on the trade size, available liquidity, and provider fees. MetaMask doesn't control price impact.", "price_impact_info_gasless_description": "O impacto no preço reflete como sua ordem de troca afeta o preço de mercado do ativo. Se você não tiver fundos suficientes para o gás, parte do seu token de origem será automaticamente alocada para cobrir taxas, o que aumenta o impacto no preço. A MetaMask não influencia nem controla o impacto no preço.", - "price_impact_warning_description": "This trade has an estimated {{priceImpact}} price impact, which reflects how much your trade changes the market price. The quote already reflects this.", - "price_impact_high": "High price impact", - "price_impact_execution_description": "You'll lose approximately {{priceImpact}} of your token's value on this swap. Try lowering the amount or choosing a more liquid route.", - "proceed": "Proceed", + "price_impact_warning_description": "Because of your trade size and available liquidity, you'll get about {{priceImpact}} less than the market price. This is already factored into your quote.", + "price_impact_high": "Alto impacto no preço", + "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", "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.", @@ -6603,7 +6611,14 @@ "exceeding_upper_slippage_error": "Não é possível inserir um valor maior que {{value}}%", "custom": "Personalizado", "invalid_recipient_address": "Endereço inválido", - "got_it": "Got it" + "select_quote": "Selecione uma cotação", + "select_quote_info": "Cotações são classificadas pelo custo total estimado, que inclui a taxa de câmbio e a taxa de rede.", + "lowest_cost": "Custo mais baixo", + "total_cost": "Custo total", + "got_it": "Entendi", + "price_impact_warning_title": "Alto impacto no preço", + "price_impact_error_title": "Very high price impact", + "price_impact_error_description": "You'll lose approximately {{priceImpact}} of your token's market price on this swap. Try a smaller trade or a more liquid route to improve your rate." }, "quote_expired_modal": { "title": "Novas cotações estão disponíveis", @@ -6900,7 +6915,7 @@ "title": "Insira a senha", "description": "Digite a senha da sua carteira para visualizar detalhes do cartão.", "description_unfreeze": "Digite a senha da sua carteira para retomar os gastos com o seu cartão.", - "description_view_pin": "Enter your wallet password to view your card PIN.", + "description_view_pin": "Digite a senha da sua carteira para visualizar o PIN do seu cartão.", "placeholder": "Senha", "confirm": "Confirmar", "cancel": "Cancelar", @@ -6908,7 +6923,7 @@ "error_incorrect": "Senha incorreta. Tente novamente." }, "view_pin_bottomsheet": { - "title": "Your Card PIN" + "title": "PIN do seu cartão" }, "choose_your_card": { "title": "Escolha seu cartão", @@ -7225,9 +7240,9 @@ "view_card_details": "Ver detalhes do cartão", "hide_card_details": "Ocultar detalhes do cartão", "view_card_details_description": "Número do cartão, data de validade e CVV", - "view_pin": "View PIN", - "view_pin_description": "View your card PIN securely", - "view_pin_error": "Failed to load PIN. Please try again.", + "view_pin": "Visualizar PIN", + "view_pin_description": "Veja o PIN do seu cartão com segurança", + "view_pin_error": "Falha ao carregar o PIN. Tente novamente.", "manage_spending_limit": "Gerenciar limite", "manage_spending_limit_description_restricted": "Limitação de gastos ativada", "manage_spending_limit_description_full": "Acesso total está ativado", @@ -7240,7 +7255,7 @@ "order_metal_card_description": "Peça já o seu Cartão Metal físico", "cashback": "Cashback", "cashback_description": "Receba 1% de volta em todos os seus gastos", - "cashback_description_metal": "Earn 3% back on all spending", + "cashback_description_metal": "Receba 3% de volta em todos os seus gastos", "freeze_card": "Congelar cartão", "unfreeze_card": "Descongelar cartão", "freeze_card_description": "Pausar todos os gastos com seu cartão", @@ -7394,7 +7409,8 @@ "pay_with_modal": { "title": "Selecione o método de pagamento", "title_receive": "Selecionar token de recebimento", - "no_gas": "Sem saldo nativo para gas" + "no_gas": "Sem saldo nativo para gas", + "not_supported": "Sem suporte" }, "connection_removed_modal": { "title": "Conexões removidas", @@ -7632,12 +7648,12 @@ "environment_selector": "Ambiente", "environment_cancel": "Cancelar", "environment_default": "Padrão", - "off_device_accounts_banner_title": "Missing Enrolled Accounts", - "off_device_accounts_banner_description": "There are accounts that were enrolled into the rewards program but are not found on this device.", - "off_device_accounts_banner_cta": "View", - "off_device_accounts_sheet_title": "Missing Enrolled Accounts", - "off_device_accounts_sheet_description": "These might belong to a wallet that has not yet been added after reinstalling MetaMask. Don't recognize any of these addresses?", - "off_device_accounts_sheet_let_us_know": "Let us know" + "off_device_accounts_banner_title": "Contas inscritas ausentes", + "off_device_accounts_banner_description": "Existem contas que foram inscritas no programa de recompensas, mas que não constam incluídas neste dispositivo.", + "off_device_accounts_banner_cta": "Ver", + "off_device_accounts_sheet_title": "Contas inscritas ausentes", + "off_device_accounts_sheet_description": "Elas podem pertencer a uma carteira que ainda não foi adicionada após a reinstalação do MetaMask. Não reconhece nenhum desses endereços?", + "off_device_accounts_sheet_let_us_know": "Informe-nos" }, "referred_by_code": { "title": "Código de indicação", @@ -7835,12 +7851,12 @@ "description": "Para continuar, estabeleça uma nova conexão a partir do aplicativo." }, "show_internal_error": { - "title": "Something went wrong", - "description": "An unexpected error occurred. Please try again." + "title": "Ocorreu algum erro", + "description": "Ocorreu um erro inesperado. Tente novamente." }, "show_method_error": { - "title": "Request failed", - "description": "The request could not be completed. Please try again." + "title": "A solicitação falhou", + "description": "Não foi possível concluir a solicitação. Tente novamente." } }, "network_connection_banner": { @@ -7981,7 +7997,7 @@ "scanning": "Procurando dispositivos...", "no_devices_found": "Nenhum dispositivo encontrado", "no_devices_hint": "Certifique-se de que seu {{device}} esteja desbloqueado e o Bluetooth esteja ativado", - "tips": "Unlock your {{device}}, enable Bluetooth, and ensure Do Not Disturb is turned off", + "tips": "Desbloqueie seu {{device}}, ative o Bluetooth e certifique-se de que o modo Não perturbe esteja desativado", "connect": "Conectar", "rescan": "Verificar novamente", "unknown_device": "Dispositivo desconhecido", @@ -7997,7 +8013,7 @@ "nfts": "NFTs", "import_nfts": "Importar NFTs", "import_nfts_description": "Adicione facilmente seus itens colecionáveis", - "view_more": "View more", + "view_more": "Ver mais", "positions": { "no_tp_sl": "Sem TP/SL" } diff --git a/locales/languages/ru.json b/locales/languages/ru.json index 6f44ffcf7d6f..38b8f2a81645 100644 --- a/locales/languages/ru.json +++ b/locales/languages/ru.json @@ -104,8 +104,8 @@ "title": "Недостаточно средств" }, "insufficient_pay_token_native_post_quote": { - "message": "Not enough {{ticker}} to cover fees. Add {{ticker}} to continue.", - "title": "Insufficient funds for post quote" + "message": "Недостаточно {{ticker}} для покрытия комиссий. Добавьте {{ticker}}, чтобы продолжить.", + "title": "Недостаточно средств для публикации котировки" }, "no_pay_token_quotes": { "message": "Этот путь оплаты сейчас недоступен. Попробуйте изменить сумму, сеть или токен, и мы подберём оптимальный вариант.", @@ -2077,12 +2077,12 @@ "title": "Аналитика рынка", "a_closer_look": "Подробный обзор", "whats_being_said": "Что говорят", - "footer_disclaimer": "AI summary for information only", + "footer_disclaimer": "ИИ-сводка только для информации", "trade_button": "Торговать", "sources_count": "+{{count}} источника(-ов)", - "sources_title": "News sources", + "sources_title": "Источники новостей", "feedback_submitted": "Отзыв отправлен", - "helpful_prompt": "Was this helpful?", + "helpful_prompt": "Это было полезно?", "feedback": { "title": "Отзыв", "description": "Помогите улучшить наши обзоры рынка, созданные с помощью ИИ.", @@ -2197,6 +2197,7 @@ "available_balance": "Доступный баланс", "claim_amount_text": "Получить {{amount}} $", "claim_winnings_text": "Получить выигрыши", + "claiming_text": "Claiming...", "unrealized_pnl_label": "Нереализованные П/У", "unrealized_pnl_value": "{{amount}} ({{percent}})", "unrealized_pnl_error": "Не удалось загрузить", @@ -2275,6 +2276,9 @@ "title": "Что-то пошло не так", "description": "Не удалось востребовать", "try_again": "Повторить попытку" + }, + "in_progress": { + "title": "Claim already in progress" } } }, @@ -2333,7 +2337,8 @@ "exchange_fee": "Комиссия биржи", "exchange_fee_description": "Комиссия, уплачиваемая бирже или рынку", "total_incl_fees": "вкл. комиссии", - "close": "Закрыть" + "close": "Закрыть", + "fak_partial_fill_note": "Prices shown assume your order is fully filled. Actual amounts may vary if the order is only partially filled." }, "error": { "title": "Невозможно подключиться к прогнозам", @@ -3701,10 +3706,10 @@ "speedup_tx_title": "Попытаться ускорить?", "speedup_tx_message": "Эта попытка не гарантирует, что ваша первоначальная транзакция будет ускорена. Если попытка ускорения окажется успешной, с вас будет удержана вышеуказанная комиссия за транзакцию.", "nevermind": "Неважно", - "cancel_speedup_speedup_title": "Speed up Transaction", - "cancel_speedup_cancel_title": "Cancel Transaction", - "cancel_speedup_speedup_message": "This network fee will replace the original.", - "cancel_speedup_cancel_message": "This transaction will be canceled and this network fee will replace the original.", + "cancel_speedup_speedup_title": "Ускорить транзакцию", + "cancel_speedup_cancel_title": "Отменить транзакцию", + "cancel_speedup_speedup_message": "Эта комиссия сети заменит исходную.", + "cancel_speedup_cancel_message": "Эта транзакция будет отменена, а эта комиссия сети заменит исходную.", "edit_network_fee": "Изменить плату за газ", "edit_priority": "Изменить приоритет", "gas_cancel_fee": "Плата за газ при отмене", @@ -4837,7 +4842,7 @@ "quote_unavailable": "Котировка недоступна.", "providers": "Поставщики", "quotes_displayed_for": "Котировки отображаются для {{paymentMethodName}}.", - "other_options": "Other options", + "other_options": "Другие варианты", "previously_used": "Ранее использовались", "best_rate": "Лучший курс", "most_reliable": "Самый надежный", @@ -4948,10 +4953,10 @@ "provider_picker_modal": { "title": "Выберите поставщика" }, - "contact_provider_support": "Contact {{provider}} support", + "contact_provider_support": "Связаться с поддержкой {{provider}}", "got_it": "Понятно", - "encountered_error": "We've encountered an error", - "no_quotes_error": "We encountered a problem fetching quotes from {{provider}}. Try a different amount or changing provider.", + "encountered_error": "Произошла ошибка", + "no_quotes_error": "У нас возникла проблема с получением котировок от {{provider}}. Попробуйте другую сумму или смените поставщика.", "change_provider_button": "Изменить поставщика" }, "fiat_on_ramp_aggregator": { @@ -5914,7 +5919,7 @@ "error_description": "Не удалось установить {{snap}}." }, "earn": { - "claimable_bonus_tooltip": "The annualized bonus you’ve earned for holding mUSD. Your bonus is claimable daily on Linea.", + "claimable_bonus_tooltip": "Годовой бонус, который вы заработали за хранение mUSD. Ваш бонус можно получить ежедневно на Linea.", "earn_a_percentage_bonus": "Заработайте бонус в размере {{percentage}}%", "claimable_bonus": "Встребуемый бонус", "claim_bonus": "Получить бонус", @@ -6022,21 +6027,21 @@ "toasts": { "converting": "Конвертация {{token}} → mUSD", "eta": "~{{time}}", - "delivered": "mUSD conversion successful", - "delivered_description": "Bonus will be claimable within a day.", + "delivered": "Конвертация в mUSD прошла успешно", + "delivered_description": "Бонус можно будет получить в течение дня.", "failed": "Конвертация mUSD не удалась." }, "education": { "heading": "ПОЛУЧИТЕ {{percentage}}% НА\nСТЕЙБЛКОИНЫ", - "description": "Convert your stablecoins to mUSD and earn up to a {{percentage}}% annualized bonus that you can claim daily.", + "description": "Конвертируйте свои стейблкоины в mUSD и получайте до {{percentage}}% годовых в виде бонуса, который можно забирать ежедневно.", "terms_apply": "Применяются условия.", "primary_button": "Начало работы", "secondary_button": "Не сейчас" }, "buy_musd": "Купить mUSD", "get_musd": "Получить mUSD", - "bonus_title": "Get {{percentage}}% on your stablecoins", - "bonus_description": "Convert your stablecoins to mUSD and get a {{percentage}}% annualized bonus.", + "bonus_title": "Получите {{percentage}}% на ваши стейблкоины", + "bonus_description": "Конвертируйте свои стейблкоины в mUSD и получайте бонус {{percentage}}% годовых.", "powered_by_relay": "При поддержке Relay", "max": "Максимум", "quick_convert_button": "Конвертировать", @@ -6044,14 +6049,14 @@ "tooltip_title": "Получайте доходность с mUSD", "tooltip_content": "Конвертируйте свои USDC, USDT или DAI в mUSD, стейблкоин MetaMask, обеспеченный долларом. Получайте доходность в размере {{apy}} с каждого имеющегося у вас доллара.", "quick_convert": { - "title": "Convert and get {{percentage}}%", - "subtitle": "Convert your stablecoins to mUSD and receive up to a {{percentage}}% annualized bonus that you can claim daily.", + "title": "Конвертируйте и получите {{percentage}}%", + "subtitle": "Конвертируйте свои стейблкоины в mUSD и получайте бонус до {{percentage}}% годовых, который можно забирать ежедневно.", "inline_failed_message": "Ошибка конвертации. Попробуйте еще раз.", "confirmation": { "title": "Конвертировать максимум" } }, - "percentage_bonus": "{{percentage}}% bonus", + "percentage_bonus": "Бонус {{percentage}}%", "rate": "Курс" }, "bonus_claim": { @@ -6092,7 +6097,9 @@ "fee": "Комиссия", "errors": { "insufficient_balance": "У вас недостаточно ресурсов для выполнения этого действия." - } + }, + "trx_unstaking_in_progress": "Выполняется вывод {{amount}} TRX из стейкинга. Он займет 14 дней.", + "has_claimable_trx": "You can claim {{amount}} TRX. Once claimed you'll get TRX back in your wallet." }, "stake_eth": "Выполнить стейкинг ETH", "unstake_eth": "Отменить стейкинг ETH", @@ -6343,7 +6350,8 @@ "metamask_fee": "Комиссия MetaMask", "network_fee": "Комиссия сети", "bridge_fee": "Комиссия поставщика моста", - "provider_fee": "Комиссия поставщика" + "provider_fee": "Комиссия поставщика", + "sending": "Отправка" }, "title": { "signature": "Запрос подписи", @@ -6381,10 +6389,10 @@ "transaction_fee": "Мы обменяем ваши токены на USDC.e в Polygon, сети, используемой функцией «Прогнозы». Поставщики услуг свопов могут взимать комиссию, но MetaMask не взимает ее." }, "predict_withdraw": { - "transaction_fee": "MetaMask will swap to your desired token for you. No MetaMask fee applies when you swap to mUSD." + "transaction_fee": "MetaMask автоматически обменяет ваш токен на желаемый. При обмене на mUSD комиссия MetaMask не взимается." }, "musd_conversion": { - "transaction_fee": "mUSD conversion fees include network costs and may include provider fees. No MetaMask fee applies when you convert to mUSD." + "transaction_fee": "В стоимость конвертации mUSD входят расходы сети, а также могут входить комиссии поставщика. При обмене на mUSD комиссия MetaMask не взимается." }, "title": { "transaction_fee": "Комиссии" @@ -6570,12 +6578,12 @@ "hardware_wallet_not_supported": "Аппаратные кошельки пока не поддерживаются. Используйте горячий кошелек, чтобы продолжить.", "hardware_wallet_not_supported_solana": "Аппаратные кошельки пока не поддерживаются для Solana. Используйте горячий кошелек, чтобы продолжить.", "price_impact_info_title": "Влияние на цену", - "price_impact_info_description": "Влияние на цену отражает, как ваш своп-ордер влияет на рыночную цену актива. Оно зависит от объёма сделки и доступной ликвидности в пуле. MetaMask не имеет отношения к влиянию на цену и не контролирует его.", + "price_impact_info_description": "This is how your trade changes the market price of a token. It depends on the trade size, available liquidity, and provider fees. MetaMask doesn't control price impact.", "price_impact_info_gasless_description": "Влияние на цену отражает, как ваш ордер на своп влияет на рыночную цену актива. Если у вас недостаточно средств для оплаты газа, часть вашего исходного токена автоматически выделяется на покрытие комиссий, что увеличивает влияние на цену. MetaMask не влияет на воздействие цену и не контролирует его.", - "price_impact_warning_description": "This trade has an estimated {{priceImpact}} price impact, which reflects how much your trade changes the market price. The quote already reflects this.", - "price_impact_high": "High price impact", - "price_impact_execution_description": "You'll lose approximately {{priceImpact}} of your token's value on this swap. Try lowering the amount or choosing a more liquid route.", - "proceed": "Proceed", + "price_impact_warning_description": "Because of your trade size and available liquidity, you'll get about {{priceImpact}} less than the market price. This is already factored into your quote.", + "price_impact_high": "Сильное влияние на цену", + "price_impact_execution_description": "В результате этого обмена вы потеряете примерно {{priceImpact}} от стоимости вашего токена. Попробуйте уменьшить сумму или выбрать более ликвидный вариант.", + "proceed": "Продолжить", "cancel": "Отмена", "slippage_info_title": "Проскальзывание", "slippage_info_description": "Процент изменения цены, который вы готовы допустить, прежде чем транзакция будет отменена.", @@ -6603,7 +6611,14 @@ "exceeding_upper_slippage_error": "Вы не можете ввести значение более {{value}}%", "custom": "Пользовательские", "invalid_recipient_address": "Недействительный адрес", - "got_it": "Got it" + "select_quote": "Выбрать котировку", + "select_quote_info": "Котировки отсортированы по расчетной общей стоимости, которая включает обменный курс и комиссию сети.", + "lowest_cost": "Самая низкая стоимость", + "total_cost": "Общая стоимость", + "got_it": "Понятно", + "price_impact_warning_title": "Сильное влияние на цену", + "price_impact_error_title": "Very high price impact", + "price_impact_error_description": "You'll lose approximately {{priceImpact}} of your token's market price on this swap. Try a smaller trade or a more liquid route to improve your rate." }, "quote_expired_modal": { "title": "Доступны новые котировки", @@ -6900,7 +6915,7 @@ "title": "Введите пароль", "description": "Введите пароль от своего кошелька, чтобы просмотреть реквизиты карты.", "description_unfreeze": "Введите пароль от своего кошелька, чтобы возобновить расходы по карте.", - "description_view_pin": "Enter your wallet password to view your card PIN.", + "description_view_pin": "Введите пароль от кошелька, чтобы посмотреть PIN-код карты.", "placeholder": "Пароль", "confirm": "Подтвердить", "cancel": "Отмена", @@ -6908,7 +6923,7 @@ "error_incorrect": "Неверный пароль. Повторите попытку." }, "view_pin_bottomsheet": { - "title": "Your Card PIN" + "title": "PIN-код вашей карты" }, "choose_your_card": { "title": "Выберите свою карту", @@ -7225,9 +7240,9 @@ "view_card_details": "Смотреть реквизиты карты", "hide_card_details": "Скрыть реквизиты карты", "view_card_details_description": "Номер карты, срок действия и CVV-код", - "view_pin": "View PIN", - "view_pin_description": "View your card PIN securely", - "view_pin_error": "Failed to load PIN. Please try again.", + "view_pin": "Посмотреть PIN-код", + "view_pin_description": "Безопасный просмотр PIN-кода вашей карты", + "view_pin_error": "Не удалось загрузить PIN-код. Повторите попытку.", "manage_spending_limit": "Управление лимитом", "manage_spending_limit_description_restricted": "Активирован лимит расходов", "manage_spending_limit_description_full": "Активирован полный доступ", @@ -7240,7 +7255,7 @@ "order_metal_card_description": "Закажите свою физическую металлическую карту прямо сейчас", "cashback": "Кешбэк", "cashback_description": "Получайте 1% всех трат обратно", - "cashback_description_metal": "Earn 3% back on all spending", + "cashback_description_metal": "Получайте 3% всех трат обратно", "freeze_card": "Заблокировать карту", "unfreeze_card": "Разблокировать карту", "freeze_card_description": "Приостановить все расходы по вашей карте", @@ -7394,7 +7409,8 @@ "pay_with_modal": { "title": "Выбрать способ оплаты", "title_receive": "Выберите токен для получения", - "no_gas": "Нет нативного баланса для оплаты газа" + "no_gas": "Нет нативного баланса для оплаты газа", + "not_supported": "Не поддерживается" }, "connection_removed_modal": { "title": "Соединения удалены", @@ -7632,12 +7648,12 @@ "environment_selector": "Среда", "environment_cancel": "Отмена", "environment_default": "По умолчанию", - "off_device_accounts_banner_title": "Missing Enrolled Accounts", - "off_device_accounts_banner_description": "There are accounts that were enrolled into the rewards program but are not found on this device.", - "off_device_accounts_banner_cta": "View", - "off_device_accounts_sheet_title": "Missing Enrolled Accounts", - "off_device_accounts_sheet_description": "These might belong to a wallet that has not yet been added after reinstalling MetaMask. Don't recognize any of these addresses?", - "off_device_accounts_sheet_let_us_know": "Let us know" + "off_device_accounts_banner_title": "Отсутствуют зарегистрированные счета", + "off_device_accounts_banner_description": "Есть счета, зарегистрированные в программе вознаграждений, но не найденные на этом устройстве.", + "off_device_accounts_banner_cta": "Просмотр", + "off_device_accounts_sheet_title": "Отсутствуют зарегистрированные счета", + "off_device_accounts_sheet_description": "Возможно, эти адреса принадлежат кошельку, который еще не был добавлен после переустановки MetaMask. Не узнаете ни один из этих адресов?", + "off_device_accounts_sheet_let_us_know": "Сообщите нам" }, "referred_by_code": { "title": "Реферальный код", @@ -7835,12 +7851,12 @@ "description": "Для продолжения установите новое соединение через приложение." }, "show_internal_error": { - "title": "Something went wrong", - "description": "An unexpected error occurred. Please try again." + "title": "Что-то пошло не так", + "description": "Произошла непредвиденная ошибка. Повторите попытку." }, "show_method_error": { - "title": "Request failed", - "description": "The request could not be completed. Please try again." + "title": "Не удалось выполнить запрос", + "description": "Не удалось выполнить запрос. Повторите попытку." } }, "network_connection_banner": { @@ -7981,7 +7997,7 @@ "scanning": "Поиск устройств...", "no_devices_found": "Устройства не найдены", "no_devices_hint": "Убедитесь, что ваше {{device}} разблокировано и Bluetooth включен", - "tips": "Unlock your {{device}}, enable Bluetooth, and ensure Do Not Disturb is turned off", + "tips": "Разблокируйте свой {{device}}, включите Bluetooth и убедитесь, что режим «Не беспокоить» выключен", "connect": "Подключиться", "rescan": "Повторить поиск", "unknown_device": "Неизвестное устройство", @@ -7997,7 +8013,7 @@ "nfts": "NFT", "import_nfts": "Импорт NFT", "import_nfts_description": "Легко добавляйте свои предметы коллекционирования", - "view_more": "View more", + "view_more": "Показать еще", "positions": { "no_tp_sl": "Нет TP/SL" } diff --git a/locales/languages/tl.json b/locales/languages/tl.json index a58d4e9991ff..d9e00bb31c2b 100644 --- a/locales/languages/tl.json +++ b/locales/languages/tl.json @@ -104,8 +104,8 @@ "title": "Hindi sapat ang mga pondo" }, "insufficient_pay_token_native_post_quote": { - "message": "Not enough {{ticker}} to cover fees. Add {{ticker}} to continue.", - "title": "Insufficient funds for post quote" + "message": "Hindi sapat ang {{ticker}} para masagot ang mga bayarin. Magdagdag ng {{ticker}} para magpatuloy.", + "title": "Hindi sapat ang mga pondo para sa post quote" }, "no_pay_token_quotes": { "message": "Hindi available ang ruta ng pagbabayad na ito sa ngayon. Subukang baguhin ang halaga, network, o token at hahanapin namin ang pinakamainam na opsyon.", @@ -2077,12 +2077,12 @@ "title": "Mga market insight", "a_closer_look": "Mas malalim na pagtingin", "whats_being_said": "Ano ang sinasabi", - "footer_disclaimer": "AI summary for information only", + "footer_disclaimer": "Para sa impormasyon lang ang buod ng AI", "trade_button": "Mag-trade", "sources_count": "+{{count}} (na) pinagmulan", - "sources_title": "News sources", + "sources_title": "Mga mapagkukunan ng balita", "feedback_submitted": "Isinumite ang feedback", - "helpful_prompt": "Was this helpful?", + "helpful_prompt": "Nakatulong ba ito?", "feedback": { "title": "Feedback", "description": "Tumulong na mapahusay ang mga pananaw sa market na gawa ng AI.", @@ -2197,6 +2197,7 @@ "available_balance": "Available na balanse", "claim_amount_text": "I-claim ang ${{amount}}", "claim_winnings_text": "I-claim ang mga panalo", + "claiming_text": "Claiming...", "unrealized_pnl_label": "Unrealized P&L", "unrealized_pnl_value": "{{amount}} ({{percent}})", "unrealized_pnl_error": "Hindi mai-load", @@ -2275,6 +2276,9 @@ "title": "Mayroong nang mali", "description": "Nabigong magpatuloy sa pag-claim", "try_again": "Subukang muli" + }, + "in_progress": { + "title": "Claim already in progress" } } }, @@ -2333,7 +2337,8 @@ "exchange_fee": "Bayad sa palitan", "exchange_fee_description": "Bayad sa palitan o market", "total_incl_fees": "kasama ang mga bayarin", - "close": "Isara" + "close": "Isara", + "fak_partial_fill_note": "Prices shown assume your order is fully filled. Actual amounts may vary if the order is only partially filled." }, "error": { "title": "Hindi maikonekta sa mga prediksyon", @@ -3701,10 +3706,10 @@ "speedup_tx_title": "Subukang pabilisin?", "speedup_tx_message": "Kapag isinumite ang pagsubok na ito, hindi magagarantiya na maa-accelerate ang iyong orihinal na transaksyon. Kung matagumpay ang pagpapabilis, sisingilin ka para sa bayad sa transaksyon sa itaas.", "nevermind": "Huwag na lang", - "cancel_speedup_speedup_title": "Speed up Transaction", - "cancel_speedup_cancel_title": "Cancel Transaction", - "cancel_speedup_speedup_message": "This network fee will replace the original.", - "cancel_speedup_cancel_message": "This transaction will be canceled and this network fee will replace the original.", + "cancel_speedup_speedup_title": "Pabilisin ang Transaksyon", + "cancel_speedup_cancel_title": "Kanselahin ang Transaksyon", + "cancel_speedup_speedup_message": "Papalitan ng bayad sa network na ito ang orihinal.", + "cancel_speedup_cancel_message": "Makakansela ang transaksyong ito at papalitan ng bayad sa network na ito ang orihinal.", "edit_network_fee": "I-edit ang bayad sa gas", "edit_priority": "I-edit ang priyoridad", "gas_cancel_fee": "Bayad sa pagkansela ng gas", @@ -4837,7 +4842,7 @@ "quote_unavailable": "Hindi available ang quote.", "providers": "Mga Provider", "quotes_displayed_for": "Mga quote na ipinapakita para sa {{paymentMethodName}}.", - "other_options": "Other options", + "other_options": "Iba pang opsyon", "previously_used": "Dating ginamit", "best_rate": "Pinakasulit na rate", "most_reliable": "Pinakamaasahan", @@ -4948,10 +4953,10 @@ "provider_picker_modal": { "title": "Pumili ng provider" }, - "contact_provider_support": "Contact {{provider}} support", + "contact_provider_support": "Makipag-ugnayan sa suporta ng {{provider}}", "got_it": "Nakuha ko", - "encountered_error": "We've encountered an error", - "no_quotes_error": "We encountered a problem fetching quotes from {{provider}}. Try a different amount or changing provider.", + "encountered_error": "Nagkaroon ng error", + "no_quotes_error": "Nagkaproblema sa pag-fetch ng mga quote mula sa {{provider}}. Sumubok ng ibang halaga o magpalit ng provider.", "change_provider_button": "Magpalit ng provider" }, "fiat_on_ramp_aggregator": { @@ -5914,7 +5919,7 @@ "error_description": "Nabigo ang pag-install ng {{snap}}." }, "earn": { - "claimable_bonus_tooltip": "The annualized bonus you’ve earned for holding mUSD. Your bonus is claimable daily on Linea.", + "claimable_bonus_tooltip": "Ang kinita mong taunang bonus para sa pag-hold ng mUSD. Puwedeng ma-claim ang bonus mo sa Linea araw-araw.", "earn_a_percentage_bonus": "Kumita ng {{percentage}}% bonus", "claimable_bonus": "Naki-claim na bonus", "claim_bonus": "I-claim ang bonus", @@ -6022,21 +6027,21 @@ "toasts": { "converting": "Ikino-convert ang {{token}} → mUSD", "eta": "~{{time}}", - "delivered": "mUSD conversion successful", - "delivered_description": "Bonus will be claimable within a day.", + "delivered": "Matagumpay ang pag-convert ng mUSD", + "delivered_description": "Puwedeng ma-claim ang bonus sa loob ng isang araw.", "failed": "Nabigong palitan ang mUSD" }, "education": { "heading": "MAKAKUHA NG {{percentage}}% SA\nMGA STABLECOIN", - "description": "Convert your stablecoins to mUSD and earn up to a {{percentage}}% annualized bonus that you can claim daily.", + "description": "I-convert ang mga stablecoin mo sa mUSD at kumita ng hanggang {{percentage}}% taunang bonus na puwede mong ma-claim araw-araw.", "terms_apply": "Nalalapat ang mga tuntunin.", "primary_button": "Magsimula", "secondary_button": "Hindi sa ngayon" }, "buy_musd": "Bumili ng mUSD", "get_musd": "Kumuha ng mUSD", - "bonus_title": "Get {{percentage}}% on your stablecoins", - "bonus_description": "Convert your stablecoins to mUSD and get a {{percentage}}% annualized bonus.", + "bonus_title": "Makakakuha ng {{percentage}}% sa mga stablecoin mo", + "bonus_description": "I-convert ang mga stablecoin mo sa mUSD at makakuha ng {{percentage}}% taunang bonus.", "powered_by_relay": "Pinapagana ng Relay", "max": "Pinakamataas", "quick_convert_button": "I-convert", @@ -6044,8 +6049,8 @@ "tooltip_title": "Kumita ng yield sa mUSD", "tooltip_content": "I-convert ang USDC, USDT, o DAI mo sa mUSD, ang stablecoin ng MetaMask na sinusuportahan ng dolyar Kumita ng {{apy}} yield sa bawat dolyar na hino-hold mo.", "quick_convert": { - "title": "Convert and get {{percentage}}%", - "subtitle": "Convert your stablecoins to mUSD and receive up to a {{percentage}}% annualized bonus that you can claim daily.", + "title": "I-convert at makakuha ng {{percentage}}%", + "subtitle": "I-convert ang mga stablecoin mo sa mUSD at makatanggap ng hanggang {{percentage}}% taunang bonus na puwede mong ma-claim araw-araw.", "inline_failed_message": "Pumalya ang pag-convert. Subukan ulit.", "confirmation": { "title": "Max ng pag-convert" @@ -6092,7 +6097,9 @@ "fee": "Bayarin", "errors": { "insufficient_balance": "Wala kang sapat na balanse ng mapagkukunan para gawin ang aksyong ito." - } + }, + "trx_unstaking_in_progress": "Kasalukuyang ina-unstake ang {{amount}} TRX. Umaabot nang 14 na araw ang pag-unstake.", + "has_claimable_trx": "You can claim {{amount}} TRX. Once claimed you'll get TRX back in your wallet." }, "stake_eth": "Mag-stake ng ETH", "unstake_eth": "Mag-unstake ng ETH", @@ -6343,7 +6350,8 @@ "metamask_fee": "Bayad sa MetaMask", "network_fee": "Bayad sa network", "bridge_fee": "Bayarin sa provider ng bridge", - "provider_fee": "Bayad sa provider" + "provider_fee": "Bayad sa provider", + "sending": "Ipinapadala" }, "title": { "signature": "Kahilingan sa paglagda", @@ -6381,10 +6389,10 @@ "transaction_fee": "Isu-swap namin ang mga token mo para sa USDE.e sa Polygon, ang network na ginamit ng mga Prediksyon. Maaaring maningil ang mga swap provider, ngunit hindi ang MetaMask." }, "predict_withdraw": { - "transaction_fee": "MetaMask will swap to your desired token for you. No MetaMask fee applies when you swap to mUSD." + "transaction_fee": "Magsu-swap ang MetaMask ng token na gusto mo para sa iyo. Walang hihinging bayad sa MetaMask kapag nag-swap ka sa mUSD." }, "musd_conversion": { - "transaction_fee": "mUSD conversion fees include network costs and may include provider fees. No MetaMask fee applies when you convert to mUSD." + "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." }, "title": { "transaction_fee": "Mga Bayarin" @@ -6570,12 +6578,12 @@ "hardware_wallet_not_supported": "Hindi pa sinusuportahan ang mga wallet na hardware. Gumamit ng hot wallet para magpatuloy.", "hardware_wallet_not_supported_solana": "Hindi pa sinusuportahan ang mga wallet na hardware sa Solana. Gumamit ng hot wallet para magpatuloy.", "price_impact_info_title": "Epekto ng presyo", - "price_impact_info_description": "Ipinapakita ng epekto sa presyo kung paano naaapektuhan ng iyong swap order ang market price ng asset. Nakadepende ito sa laki ng trade at sa available na liquidity sa pool. Walang kontrol o impluwensya ang MetaMask sa epekto sa presyo.", + "price_impact_info_description": "This is how your trade changes the market price of a token. It depends on the trade size, available liquidity, and provider fees. MetaMask doesn't control price impact.", "price_impact_info_gasless_description": "Ipinapakita ng epekto sa presyo kung paano naaapektuhan ng iyong swap order ang market price ng asset. Kung wala kang sapat na pondo para sa gas, awtomatikong ilalaan ang isang bahagi ng source token mo para sa mga bayarin, na magdaragdag sa epekto ng presyo. Walang impluwensya o kontrol ang MetaMask sa epekto sa presyo.", - "price_impact_warning_description": "This trade has an estimated {{priceImpact}} price impact, which reflects how much your trade changes the market price. The quote already reflects this.", - "price_impact_high": "High price impact", - "price_impact_execution_description": "You'll lose approximately {{priceImpact}} of your token's value on this swap. Try lowering the amount or choosing a more liquid route.", - "proceed": "Proceed", + "price_impact_warning_description": "Because of your trade size and available liquidity, you'll get about {{priceImpact}} less than the market price. This is already factored into your quote.", + "price_impact_high": "Matinding epekto sa presyo", + "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", "slippage_info_title": "Slippage", "slippage_info_description": "Ang % ng pagbabago sa presyo na handa mong payagan bago makansela ang iyong transaksyon.", @@ -6603,7 +6611,14 @@ "exceeding_upper_slippage_error": "Hindi mo maaaring ilagay ang value na mas malaki sa {{value}}%", "custom": "Custom", "invalid_recipient_address": "Di-wastong address", - "got_it": "Got it" + "select_quote": "Piliin ang Quote", + "select_quote_info": "Nakaayos ang mga quote ayon sa tinatayang kabuuang halaga, kasama ang rate ng palitan at bayad sa network.", + "lowest_cost": "Pinakamababang halaga", + "total_cost": "Kabuuang Halaga", + "got_it": "Nakuha ko", + "price_impact_warning_title": "Matinding epekto sa presyo", + "price_impact_error_title": "Very high price impact", + "price_impact_error_description": "You'll lose approximately {{priceImpact}} of your token's market price on this swap. Try a smaller trade or a more liquid route to improve your rate." }, "quote_expired_modal": { "title": "Available ang mga bagong quote", @@ -6900,7 +6915,7 @@ "title": "Ilagay ang password", "description": "Ilagay ang password ng wallet mo para tingnan ang mga detalye ng card.", "description_unfreeze": "Ilagay ang password ng wallet mo para ipagpatuloy ang paggastos sa iyong card.", - "description_view_pin": "Enter your wallet password to view your card PIN.", + "description_view_pin": "Ilagay ang password ng wallet mo para tingnan ang mga PIN ng card mo.", "placeholder": "Password", "confirm": "Kumpirmahin", "cancel": "Kanselahin", @@ -6908,7 +6923,7 @@ "error_incorrect": "Mali ang password. Pakisubukan muli." }, "view_pin_bottomsheet": { - "title": "Your Card PIN" + "title": "Ang PIN ng Card mo" }, "choose_your_card": { "title": "Piliin ang card mo", @@ -7225,9 +7240,9 @@ "view_card_details": "Tingnan ang mga detalye ng card", "hide_card_details": "Itago ang mga detalye ng card", "view_card_details_description": "Numero ng card, kailan mag-e-expire at CVV", - "view_pin": "View PIN", - "view_pin_description": "View your card PIN securely", - "view_pin_error": "Failed to load PIN. Please try again.", + "view_pin": "Tingnan ang PIN", + "view_pin_description": "Ligtas na tingnan ang PIN ng card mo", + "view_pin_error": "Hindi nag-load ang PIN. Subukan ulit.", "manage_spending_limit": "Pamahalaan ang limit", "manage_spending_limit_description_restricted": "Naka-on ang limitadong paggastos", "manage_spending_limit_description_full": "Naka-on ang buong pag-access", @@ -7240,7 +7255,7 @@ "order_metal_card_description": "I-order ngayon ang pisikal na Metal Card mo", "cashback": "Cashback", "cashback_description": "Makakuha 1% na balik sa lahat ng nagastos mo", - "cashback_description_metal": "Earn 3% back on all spending", + "cashback_description_metal": "Makakuha 3% na balik sa lahat ng nagastos mo", "freeze_card": "I-freeze ang card", "unfreeze_card": "I-unfreeze ang card", "freeze_card_description": "Ihinto ang lahat ng paggastos sa iyong card", @@ -7394,7 +7409,8 @@ "pay_with_modal": { "title": "Pumili ng paraan ng pagbabayad", "title_receive": "Piliin ang tatanggaping token", - "no_gas": "Walang native na balanse para sa gas" + "no_gas": "Walang native na balanse para sa gas", + "not_supported": "Hindi suportado" }, "connection_removed_modal": { "title": "Naalis na ang mga koneksyon", @@ -7632,12 +7648,12 @@ "environment_selector": "Environment", "environment_cancel": "Kanselahin", "environment_default": "Default", - "off_device_accounts_banner_title": "Missing Enrolled Accounts", - "off_device_accounts_banner_description": "There are accounts that were enrolled into the rewards program but are not found on this device.", - "off_device_accounts_banner_cta": "View", - "off_device_accounts_sheet_title": "Missing Enrolled Accounts", - "off_device_accounts_sheet_description": "These might belong to a wallet that has not yet been added after reinstalling MetaMask. Don't recognize any of these addresses?", - "off_device_accounts_sheet_let_us_know": "Let us know" + "off_device_accounts_banner_title": "Mga Nawawalang Naka-enroll na Account", + "off_device_accounts_banner_description": "May mga account na naka-enroll sa programa ng mga reward pero hindi mahahanap sa device na ito.", + "off_device_accounts_banner_cta": "Tingnan", + "off_device_accounts_sheet_title": "Mga Nawawalang Naka-enroll na Account", + "off_device_accounts_sheet_description": "Baka bahagi ito ng wallet na hindi pa naidaragdag pagkatapos ma-reinstall ang MetaMask. Hindi mo ba kilala ang alinman sa mga address na ito?", + "off_device_accounts_sheet_let_us_know": "Ipaalam sa amin" }, "referred_by_code": { "title": "Referral Code", @@ -7835,12 +7851,12 @@ "description": "Magtatag ng bagong koneksyon mula sa app para magpatuloy." }, "show_internal_error": { - "title": "Something went wrong", - "description": "An unexpected error occurred. Please try again." + "title": "Mayroong nang mali", + "description": "Nagkaroon ng hindi inaasahang error. Subukang muli." }, "show_method_error": { - "title": "Request failed", - "description": "The request could not be completed. Please try again." + "title": "Pumalya ang kahilingan", + "description": "Hindi makumpleto ang kahilingan. Subukan ulit." } }, "network_connection_banner": { @@ -7981,7 +7997,7 @@ "scanning": "Nagsa-scan ng mga device...", "no_devices_found": "Walang nahanap sa device", "no_devices_hint": "Siguraduhing naka-unlock ang {{device}} mo at naka-enable ang Bluetooth mo", - "tips": "Unlock your {{device}}, enable Bluetooth, and ensure Do Not Disturb is turned off", + "tips": "I-unlock ang {{device}} mo. i-enable ang Bluetooh, at tiyaking naka-off ang Do Not Disturb", "connect": "Kumonekta", "rescan": "I-scan Ulit", "unknown_device": "Hindi Kilalang Device", @@ -7997,7 +8013,7 @@ "nfts": "Mga NFT", "import_nfts": "Mag-import ng mga NFT", "import_nfts_description": "Madaling idagdag ang mga collectible mo", - "view_more": "View more", + "view_more": "Tumingin ng higit pa", "positions": { "no_tp_sl": "Walang TP/SL" } diff --git a/locales/languages/tr.json b/locales/languages/tr.json index 69ea5ebcc36c..0e93c96c4b29 100644 --- a/locales/languages/tr.json +++ b/locales/languages/tr.json @@ -104,8 +104,8 @@ "title": "Yetersiz bakiye" }, "insufficient_pay_token_native_post_quote": { - "message": "Not enough {{ticker}} to cover fees. Add {{ticker}} to continue.", - "title": "Insufficient funds for post quote" + "message": "Ücretleri karşılamak için yeterli {{ticker}} yok. Devam etmek için {{ticker}} ekleyin.", + "title": "Teklifi yayınlamak için fon yetersiz" }, "no_pay_token_quotes": { "message": "Bu ödeme rotası şu anda kullanılamıyor. Tutarı, ağı veya token'ı değiştirmeyi deneyin ve sizin için en iyi seçeneği bulalım.", @@ -2077,12 +2077,12 @@ "title": "Piyasa içgörüleri", "a_closer_look": "Daha yakın bir görünüm", "whats_being_said": "Neler söyleniyor", - "footer_disclaimer": "AI summary for information only", + "footer_disclaimer": "Yapay zeka özeti yalnızca bilgi amaçlıdır", "trade_button": "İşlem Yap", "sources_count": "+{{count}} kaynak", - "sources_title": "News sources", + "sources_title": "Haber kaynakları", "feedback_submitted": "Geri bildirim gönderildi", - "helpful_prompt": "Was this helpful?", + "helpful_prompt": "Bu faydalı oldu mu?", "feedback": { "title": "Geri Bildirim", "description": "Yapay zeka ile oluşturulmuş piyasa içgörülerimizi iyileştirmemize yardımcı olun.", @@ -2197,6 +2197,7 @@ "available_balance": "Kullanılabilir bakiye", "claim_amount_text": "{{amount}}$ al", "claim_winnings_text": "Kazançları al", + "claiming_text": "Claiming...", "unrealized_pnl_label": "Gerçekleşmemiş K&Z", "unrealized_pnl_value": "({{percent}}) {{amount}}", "unrealized_pnl_error": "Yüklenemiyor", @@ -2275,6 +2276,9 @@ "title": "Bir şeyler ters gitti", "description": "Alım ile ilerleme başarısız oldu", "try_again": "Tekrar dene" + }, + "in_progress": { + "title": "Claim already in progress" } } }, @@ -2333,7 +2337,8 @@ "exchange_fee": "Borsa ücreti", "exchange_fee_description": "Borsaya veya piyasaya ödenen ücret", "total_incl_fees": "ücretler dahil", - "close": "Kapat" + "close": "Kapat", + "fak_partial_fill_note": "Prices shown assume your order is fully filled. Actual amounts may vary if the order is only partially filled." }, "error": { "title": "Tahminlere bağlanılamıyor", @@ -3701,10 +3706,10 @@ "speedup_tx_title": "Hızlandırmayı dene?", "speedup_tx_message": "Bu denemeyi göndermek ilk işlemin hızlandırılmasını garanti etmez. Hızlandırma denemesi başarılı olursa sizden yukarıdaki işlem ücreti alınır.", "nevermind": "Vazgeç", - "cancel_speedup_speedup_title": "Speed up Transaction", - "cancel_speedup_cancel_title": "Cancel Transaction", - "cancel_speedup_speedup_message": "This network fee will replace the original.", - "cancel_speedup_cancel_message": "This transaction will be canceled and this network fee will replace the original.", + "cancel_speedup_speedup_title": "İşlemi Hızlandır", + "cancel_speedup_cancel_title": "İşlemi İptal Et", + "cancel_speedup_speedup_message": "Bu ağ ücreti orijinalinin yerine geçecektir.", + "cancel_speedup_cancel_message": "Bu işlem iptal edilecek ve bu ağ ücreti orijinalinin yerine geçecektir.", "edit_network_fee": "Gaz ücretini düzenle", "edit_priority": "Önceliği düzenle", "gas_cancel_fee": "Gaz iptal ücreti", @@ -4837,7 +4842,7 @@ "quote_unavailable": "Teklif kullanılamıyor.", "providers": "Sağlayıcılar", "quotes_displayed_for": "{{paymentMethodName}} için teklifler görüntüleniyor.", - "other_options": "Other options", + "other_options": "Diğer seçenekler", "previously_used": "Daha önce kullanılan", "best_rate": "En iyi oran", "most_reliable": "En güvenilir", @@ -4948,10 +4953,10 @@ "provider_picker_modal": { "title": "Bir sağlayıcı seç" }, - "contact_provider_support": "Contact {{provider}} support", + "contact_provider_support": "{{provider}} destek ekibi ile iletişime geçin", "got_it": "Anladım", - "encountered_error": "We've encountered an error", - "no_quotes_error": "We encountered a problem fetching quotes from {{provider}}. Try a different amount or changing provider.", + "encountered_error": "Bir hata ile karşılaştık", + "no_quotes_error": "{{provider}} adlı sağlayıcıdan teklifleri getirirken bir sorunla karşılaştık. Farklı bir miktar deneyin veya sağlayıcı değiştirin.", "change_provider_button": "Sağlayıcı değiştirin" }, "fiat_on_ramp_aggregator": { @@ -5914,7 +5919,7 @@ "error_description": "{{snap}} yüklemesi başarısız oldu." }, "earn": { - "claimable_bonus_tooltip": "The annualized bonus you’ve earned for holding mUSD. Your bonus is claimable daily on Linea.", + "claimable_bonus_tooltip": "mUSD tuttuğunuz için kazandığınız yıllıklandırılmış bonus. Bonusunuzu Linea üzerinde günlük olarak alabilirsiniz.", "earn_a_percentage_bonus": "%{{percentage}} bonus kazanın", "claimable_bonus": "Alınabilir bonus", "claim_bonus": "Bonusu al", @@ -6022,21 +6027,21 @@ "toasts": { "converting": "{{token}} → mUSD dönüştürülüyor", "eta": "~{{time}}", - "delivered": "mUSD conversion successful", - "delivered_description": "Bonus will be claimable within a day.", + "delivered": "mUSD dönüştürme işlemi başarılı", + "delivered_description": "Bonus bir gün içinde alınabilir olacaktır.", "failed": "mUSD dönüştürme işlemi başarısız oldu" }, "education": { "heading": "STABİL KRİPTO PARALARDA\n%{{percentage}} AL", - "description": "Convert your stablecoins to mUSD and earn up to a {{percentage}}% annualized bonus that you can claim daily.", + "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.", "terms_apply": "Şartlar uygulanır.", "primary_button": "Başlarken", "secondary_button": "Şimdi değil" }, "buy_musd": "mUSD al", "get_musd": "mUSD kazan", - "bonus_title": "Get {{percentage}}% on your stablecoins", - "bonus_description": "Convert your stablecoins to mUSD and get a {{percentage}}% annualized bonus.", + "bonus_title": "Stabil kripto paranızda %{{percentage}} bonus kazanın", + "bonus_description": "Stabil kripto paranızı mUSD'ye dönüştürün ve %{{percentage}} oranında yıllıklandırılmış bonus alın.", "powered_by_relay": "Destekleyen Relay", "max": "Maksimum", "quick_convert_button": "Dönüştür", @@ -6044,14 +6049,14 @@ "tooltip_title": "mUSD ile getiri elde et", "tooltip_content": "USDC, USDT veya DAI'nizi MetaMask'in dolar destekli stabil kripto parası olan mUSD'ye dönüştürün. Tuttuğunuz her dolar için {{apy}} getiri elde edin.", "quick_convert": { - "title": "Convert and get {{percentage}}%", - "subtitle": "Convert your stablecoins to mUSD and receive up to a {{percentage}}% annualized bonus that you can claim daily.", + "title": "Dönüştür ve %{{percentage}} al", + "subtitle": "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 alın.", "inline_failed_message": "Dönüştürme işlemi başarısız oldu. Tekrar deneyin.", "confirmation": { "title": "Maksimumu dönüştür" } }, - "percentage_bonus": "{{percentage}}% bonus", + "percentage_bonus": "%{{percentage}} bonus", "rate": "Oran" }, "bonus_claim": { @@ -6092,7 +6097,9 @@ "fee": "Ücret", "errors": { "insufficient_balance": "Bu eylemi gerçekleştirmek için yeterli kaynak bakiyeniz yok." - } + }, + "trx_unstaking_in_progress": "{{amount}} TRX unstake işlemi devam ediyor. Unstake işlemi 14 gün sürer.", + "has_claimable_trx": "You can claim {{amount}} TRX. Once claimed you'll get TRX back in your wallet." }, "stake_eth": "ETH Stake Et", "unstake_eth": "ETH Unstake Et", @@ -6343,7 +6350,8 @@ "metamask_fee": "MetaMask ücreti", "network_fee": "Ağ ücreti", "bridge_fee": "Köprü sağlayıcı ücreti", - "provider_fee": "Sağlayıcı ücreti" + "provider_fee": "Sağlayıcı ücreti", + "sending": "Gönderiliyor" }, "title": { "signature": "İmza talebi", @@ -6381,10 +6389,10 @@ "transaction_fee": "Tokenlerinizi Tahminler tarafından kullanılan Polygon ağı üzerinden USDC ile takas edeceğiz. Takas sağlayıcıları ücret alabilir ancak MetaMask ücret talep etmez." }, "predict_withdraw": { - "transaction_fee": "MetaMask will swap to your desired token for you. No MetaMask fee applies when you swap to mUSD." + "transaction_fee": "MetaMask, sizin için istediğiniz tokena takas gerçekleştirecek. mUSD'ye takas gerçekleştirirken MetaMask ücreti uygulanmaz." }, "musd_conversion": { - "transaction_fee": "mUSD conversion fees include network costs and may include provider fees. No MetaMask fee applies when you convert to mUSD." + "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." }, "title": { "transaction_fee": "Ücretler" @@ -6570,12 +6578,12 @@ "hardware_wallet_not_supported": "Donanım cüzdanları henüz desteklenmiyor. Devam etmek için sıcak cüzdan kullanın.", "hardware_wallet_not_supported_solana": "Donanım cüzdanları henüz Solana için desteklenmiyor. Devam etmek için sıcak cüzdan kullanın.", "price_impact_info_title": "Piyasa etkisi", - "price_impact_info_description": "Fiyat etkisi, takas emrinizin varlığın piyasa fiyatını nasıl etkilediğini yansıtır. İşlem boyutuna ve havuzdaki mevcut likiditeye bağlıdır. MetaMask'in fiyat etkisi üzerinde bir etkisi veya kontrolü bulunmamaktadır.", + "price_impact_info_description": "This is how your trade changes the market price of a token. It depends on the trade size, available liquidity, and provider fees. MetaMask doesn't control price impact.", "price_impact_info_gasless_description": "Fiyat etkisi, takas emrinizin varlığın piyasa fiyatını nasıl etkilediğini yansıtır. Gaz için yeterli fon tutmazsanız kaynak token'inizin bir kısmı otomatik olarak ücretleri karşılamak üzere ayrılır, bu nedenle fiyat etkisi artar. MetaMask fiyat etkisini etkilemez veya kontrol etmez.", - "price_impact_warning_description": "This trade has an estimated {{priceImpact}} price impact, which reflects how much your trade changes the market price. The quote already reflects this.", - "price_impact_high": "High price impact", - "price_impact_execution_description": "You'll lose approximately {{priceImpact}} of your token's value on this swap. Try lowering the amount or choosing a more liquid route.", - "proceed": "Proceed", + "price_impact_warning_description": "Because of your trade size and available liquidity, you'll get about {{priceImpact}} less than the market price. This is already factored into your quote.", + "price_impact_high": "Yüksek fiyat etkisi", + "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", "slippage_info_title": "Kayma", "slippage_info_description": "İşleminiz iptal edilmeden önce izin vermek istediğiniz fiyat değişim % oranı.", @@ -6603,7 +6611,14 @@ "exceeding_upper_slippage_error": "%{{value}} değerin üzerinde olan bir değer giremezsiniz", "custom": "Özel", "invalid_recipient_address": "Geçersiz adres", - "got_it": "Got it" + "select_quote": "Teklif Seç", + "select_quote_info": "Teklifler, döviz kurunu ve ağ ücretini içeren tahmini toplam maliyete göre sıralanır.", + "lowest_cost": "En düşük maliyet", + "total_cost": "Toplam Maliyet", + "got_it": "Anladım", + "price_impact_warning_title": "Yüksek fiyat etkisi", + "price_impact_error_title": "Very high price impact", + "price_impact_error_description": "You'll lose approximately {{priceImpact}} of your token's market price on this swap. Try a smaller trade or a more liquid route to improve your rate." }, "quote_expired_modal": { "title": "Yeni teklifler mevcut", @@ -6900,7 +6915,7 @@ "title": "Şifre girin", "description": "Kart bilgilerini görüntülemek için cüzdan şifrenizi girin.", "description_unfreeze": "Kartınızda harcama yapmaya devam edebilmek için cüzdan şifrenizi girin.", - "description_view_pin": "Enter your wallet password to view your card PIN.", + "description_view_pin": "Kartınızın PIN kodunu görüntülemek için cüzdan şifrenizi girin.", "placeholder": "Şifre", "confirm": "Onayla", "cancel": "İptal et", @@ -6908,7 +6923,7 @@ "error_incorrect": "Şifre yanlış. Lütfen tekrar deneyin." }, "view_pin_bottomsheet": { - "title": "Your Card PIN" + "title": "Kartınızın PIN kodu" }, "choose_your_card": { "title": "Kartınızı seçin", @@ -7225,9 +7240,9 @@ "view_card_details": "Kart bilgilerini görüntüle", "hide_card_details": "Kart bilgilerini gizle", "view_card_details_description": "Kart numarası, son geçerlilik tarihi ve CVV", - "view_pin": "View PIN", - "view_pin_description": "View your card PIN securely", - "view_pin_error": "Failed to load PIN. Please try again.", + "view_pin": "PIN kodunu görüntüle", + "view_pin_description": "Kartınızın PIN kodunu gizli bir şekilde görüntüleyin", + "view_pin_error": "PIN kodu yüklenemedi. Lütfen tekrar deneyin.", "manage_spending_limit": "Limiti yönet", "manage_spending_limit_description_restricted": "Sınırlı harcama açık", "manage_spending_limit_description_full": "Tam erişim açık", @@ -7240,7 +7255,7 @@ "order_metal_card_description": "Hemen Fiziksel Metal Kart siparişinizi verin", "cashback": "Para iadesi", "cashback_description": "Tüm harcamalarda %1 iade al", - "cashback_description_metal": "Earn 3% back on all spending", + "cashback_description_metal": "Tüm harcamalarda %3 iade al", "freeze_card": "Kartı dondur", "unfreeze_card": "Kartı dondurma işlemini iptal et", "freeze_card_description": "Kartındaki tüm harcamaları duraklat", @@ -7394,7 +7409,8 @@ "pay_with_modal": { "title": "Ödeme yöntemi seç", "title_receive": "Token al seçeneğini seç", - "no_gas": "Gaz için yerel bakiye yok" + "no_gas": "Gaz için yerel bakiye yok", + "not_supported": "Desteklenmiyor" }, "connection_removed_modal": { "title": "Bağlantılar kaldırıldı", @@ -7632,12 +7648,12 @@ "environment_selector": "Ortam", "environment_cancel": "İptal", "environment_default": "Varsayılan", - "off_device_accounts_banner_title": "Missing Enrolled Accounts", - "off_device_accounts_banner_description": "There are accounts that were enrolled into the rewards program but are not found on this device.", - "off_device_accounts_banner_cta": "View", - "off_device_accounts_sheet_title": "Missing Enrolled Accounts", - "off_device_accounts_sheet_description": "These might belong to a wallet that has not yet been added after reinstalling MetaMask. Don't recognize any of these addresses?", - "off_device_accounts_sheet_let_us_know": "Let us know" + "off_device_accounts_banner_title": "Eksik Kayıtlı Hesaplar", + "off_device_accounts_banner_description": "Ödül programına kaydolmuş olan ancak bu cihazda bulunmayan hesaplar var.", + "off_device_accounts_banner_cta": "Görüntüle", + "off_device_accounts_sheet_title": "Eksik Kayıtlı Hesaplar", + "off_device_accounts_sheet_description": "Bunlar, MetaMask’i yeniden yükledikten sonra henüz eklenmemiş bir cüzdana ait olabilir. Bu adreslerden hiçbirini tanımıyor musunuz?", + "off_device_accounts_sheet_let_us_know": "Bize bildirin" }, "referred_by_code": { "title": "Referans Kodu", @@ -7835,12 +7851,12 @@ "description": "Devam etmek için lütfen uygulamadan yeni bir bağlantı kurun." }, "show_internal_error": { - "title": "Something went wrong", - "description": "An unexpected error occurred. Please try again." + "title": "Bir şeyler ters gitti", + "description": "Beklenmedik bir hata oluştu. Lütfen tekrar deneyin." }, "show_method_error": { - "title": "Request failed", - "description": "The request could not be completed. Please try again." + "title": "Talep başarısız oldu", + "description": "Talep tamamlanamadı. Lütfen tekrar deneyin." } }, "network_connection_banner": { @@ -7981,7 +7997,7 @@ "scanning": "Cihazlar taranıyor...", "no_devices_found": "Cihaz bulunamadı", "no_devices_hint": "{{device}} cihazınızın kilidinin açık olduğundan ve Bluetooth özelliğinin etkin olduğundan emin olun", - "tips": "Unlock your {{device}}, enable Bluetooth, and ensure Do Not Disturb is turned off", + "tips": "{{device}} cihazınızın kilidini açın, Bluetooth'u etkinleştirin ve Rahatsız Etme modunun kapalı olduğunda emin olun", "connect": "Bağla", "rescan": "Tekrar Tara", "unknown_device": "Bilinmeyen Cihaz", @@ -7997,7 +8013,7 @@ "nfts": "NFT'ler", "import_nfts": "NFT'leri içe aktar", "import_nfts_description": "Koleksiyon ögelerinizi kolayca ekleyin", - "view_more": "View more", + "view_more": "Daha fazlasını görüntüle", "positions": { "no_tp_sl": "KA/ZD yok" } diff --git a/locales/languages/vi.json b/locales/languages/vi.json index d0587d29252d..fcdc4fe6c500 100644 --- a/locales/languages/vi.json +++ b/locales/languages/vi.json @@ -104,8 +104,8 @@ "title": "Không đủ tiền" }, "insufficient_pay_token_native_post_quote": { - "message": "Not enough {{ticker}} to cover fees. Add {{ticker}} to continue.", - "title": "Insufficient funds for post quote" + "message": "Không đủ {{ticker}} để chi trả phí. Nạp thêm {{ticker}} để tiếp tục.", + "title": "Không đủ tiền cho báo giá sau" }, "no_pay_token_quotes": { "message": "Lộ trình thanh toán này hiện không khả dụng. Hãy thử thay đổi số lượng, mạng hoặc token và chúng tôi sẽ tìm phương án tốt nhất.", @@ -2077,12 +2077,12 @@ "title": "Thông tin thị trường", "a_closer_look": "Xem chi tiết hơn", "whats_being_said": "Những gì đang được nói", - "footer_disclaimer": "AI summary for information only", + "footer_disclaimer": "Tóm tắt AI chỉ mang tính chất cung cấp thông tin", "trade_button": "Giao dịch", "sources_count": "+{{count}} nguồn", - "sources_title": "News sources", + "sources_title": "Nguồn tin tức", "feedback_submitted": "Đã gửi phản hồi", - "helpful_prompt": "Was this helpful?", + "helpful_prompt": "Thông tin này có hữu ích không?", "feedback": { "title": "Phản hồi", "description": "Giúp cải thiện thông tin thị trường do AI tạo ra.", @@ -2197,6 +2197,7 @@ "available_balance": "Số dư khả dụng", "claim_amount_text": "Nhận ${{amount}}", "claim_winnings_text": "Nhận tiền thắng", + "claiming_text": "Claiming...", "unrealized_pnl_label": "Lãi/Lỗ chưa thực hiện", "unrealized_pnl_value": "{{amount}} ({{percent}})", "unrealized_pnl_error": "Không thể tải", @@ -2275,6 +2276,9 @@ "title": "Đã xảy ra sự cố", "description": "Không thể thực hiện yêu cầu nhận tiền", "try_again": "Thử lại" + }, + "in_progress": { + "title": "Claim already in progress" } } }, @@ -2333,7 +2337,8 @@ "exchange_fee": "Phí sàn giao dịch", "exchange_fee_description": "Phí trả cho sàn giao dịch hoặc thị trường", "total_incl_fees": "bao gồm phí", - "close": "Đóng" + "close": "Đóng", + "fak_partial_fill_note": "Prices shown assume your order is fully filled. Actual amounts may vary if the order is only partially filled." }, "error": { "title": "Không thể kết nối với thị trường dự đoán", @@ -3701,10 +3706,10 @@ "speedup_tx_title": "Cố tăng tốc?", "speedup_tx_message": "Việc cố tăng tốc này không đảm bảo giao dịch ban đầu của bạn sẽ được tăng tốc. Nếu tăng tốc thành công, bạn sẽ bị tính phí giao dịch ở trên.", "nevermind": "Đừng bận tâm", - "cancel_speedup_speedup_title": "Speed up Transaction", - "cancel_speedup_cancel_title": "Cancel Transaction", - "cancel_speedup_speedup_message": "This network fee will replace the original.", - "cancel_speedup_cancel_message": "This transaction will be canceled and this network fee will replace the original.", + "cancel_speedup_speedup_title": "Tăng tốc giao dịch", + "cancel_speedup_cancel_title": "Hủy giao dịch", + "cancel_speedup_speedup_message": "Phí mạng này sẽ thay thế phí ban đầu.", + "cancel_speedup_cancel_message": "Giao dịch này sẽ bị hủy và phí mạng này sẽ thay thế phí ban đầu.", "edit_network_fee": "Sửa phí gas", "edit_priority": "Sửa mức ưu tiên", "gas_cancel_fee": "Phí hủy gas", @@ -4837,7 +4842,7 @@ "quote_unavailable": "Không có báo giá.", "providers": "Nhà cung cấp", "quotes_displayed_for": "Báo giá được hiển thị cho {{paymentMethodName}}.", - "other_options": "Other options", + "other_options": "Tùy chọn khác", "previously_used": "Đã sử dụng trước đây", "best_rate": "Tỷ giá tốt nhất", "most_reliable": "Đáng tin cậy nhất", @@ -4948,10 +4953,10 @@ "provider_picker_modal": { "title": "Chọn nhà cung cấp" }, - "contact_provider_support": "Contact {{provider}} support", + "contact_provider_support": "Liên hệ bộ phận hỗ trợ của {{provider}}", "got_it": "Tôi đã hiểu", - "encountered_error": "We've encountered an error", - "no_quotes_error": "We encountered a problem fetching quotes from {{provider}}. Try a different amount or changing provider.", + "encountered_error": "Chúng tôi đã gặp lỗi", + "no_quotes_error": "Chúng tôi đã gặp sự cố khi tìm nạp báo giá từ {{provider}}. Hãy thử số tiền khác hoặc thay đổi nhà cung cấp.", "change_provider_button": "Thay đổi nhà cung cấp" }, "fiat_on_ramp_aggregator": { @@ -5914,7 +5919,7 @@ "error_description": "Cài đặt {{snap}} thất bại." }, "earn": { - "claimable_bonus_tooltip": "The annualized bonus you’ve earned for holding mUSD. Your bonus is claimable daily on Linea.", + "claimable_bonus_tooltip": "Phần thưởng quy đổi theo năm bạn đã nhận được khi nắm giữ mUSD. Bạn có thể nhận thưởng hằng ngày trên Linea.", "earn_a_percentage_bonus": "Nhận thưởng {{percentage}}%", "claimable_bonus": "Thưởng có thể nhận", "claim_bonus": "Nhận thưởng", @@ -6022,21 +6027,21 @@ "toasts": { "converting": "Đang chuyển đổi {{token}} → mUSD", "eta": "~{{time}}", - "delivered": "mUSD conversion successful", - "delivered_description": "Bonus will be claimable within a day.", + "delivered": "Chuyển đổi mUSD thành công", + "delivered_description": "Bạn sẽ có thể nhận thưởng trong vòng một ngày.", "failed": "Chuyển đổi mUSD thất bại" }, "education": { "heading": "NHẬN {{percentage}}%\nĐỒNG ỔN ĐỊNH", - "description": "Convert your stablecoins to mUSD and earn up to a {{percentage}}% annualized bonus that you can claim daily.", + "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.", "terms_apply": "Áp dụng điều khoản.", "primary_button": "Bắt đầu", "secondary_button": "Không phải bây giờ" }, "buy_musd": "Mua mUSD", "get_musd": "Nhận mUSD", - "bonus_title": "Get {{percentage}}% on your stablecoins", - "bonus_description": "Convert your stablecoins to mUSD and get a {{percentage}}% annualized bonus.", + "bonus_title": "Nhận {{percentage}}% cho đồng ổn định của bạn", + "bonus_description": "Chuyển đổi đồng ổn định của bạn sang mUSD và nhận thưởng quy đổi theo năm {{percentage}}%.", "powered_by_relay": "Cung cấp bởi Relay", "max": "Tối đa", "quick_convert_button": "Chuyển đổi", @@ -6044,14 +6049,14 @@ "tooltip_title": "Nhận lợi suất với mUSD", "tooltip_content": "Chuyển đổi USDC, USDT hoặc DAI sang mUSD, đồng ổn định được hỗ trợ bằng đô-la của MetaMask. Nhận lợi suất {{apy}} trên mỗi đô-la bạn nắm giữ.", "quick_convert": { - "title": "Convert and get {{percentage}}%", - "subtitle": "Convert your stablecoins to mUSD and receive up to a {{percentage}}% annualized bonus that you can claim daily.", + "title": "Chuyển đổi và nhận {{percentage}}%", + "subtitle": "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.", "inline_failed_message": "Chuyển đổi thất bại. Hãy thử lại.", "confirmation": { "title": "Chuyển đổi tối đa" } }, - "percentage_bonus": "{{percentage}}% bonus", + "percentage_bonus": "Thưởng {{percentage}}%", "rate": "Tỷ lệ" }, "bonus_claim": { @@ -6092,7 +6097,9 @@ "fee": "Phí", "errors": { "insufficient_balance": "Bạn không có đủ số dư tài nguyên để thực hiện hành động này." - } + }, + "trx_unstaking_in_progress": "Đang tiến hành hủy ký gửi {{amount}} TRX. Quá trình hủy ký gửi sẽ mất 14 ngày.", + "has_claimable_trx": "You can claim {{amount}} TRX. Once claimed you'll get TRX back in your wallet." }, "stake_eth": "Ký gửi ETH", "unstake_eth": "Hủy ký gửi ETH", @@ -6343,7 +6350,8 @@ "metamask_fee": "Phí MetaMask", "network_fee": "Phí mạng", "bridge_fee": "Phí nhà cung cấp cầu nối", - "provider_fee": "Phí nhà cung cấp" + "provider_fee": "Phí nhà cung cấp", + "sending": "Đang gửi" }, "title": { "signature": "Yêu cầu chữ ký", @@ -6381,10 +6389,10 @@ "transaction_fee": "Chúng tôi sẽ hoán đổi token của bạn sang USDC.e trên Polygon, mạng được thị trường Dự đoán sử dụng. Các nhà cung cấp dịch vụ hoán đổi có thể tính phí, nhưng MetaMask thì không." }, "predict_withdraw": { - "transaction_fee": "MetaMask will swap to your desired token for you. No MetaMask fee applies when you swap to mUSD." + "transaction_fee": "MetaMask sẽ hoán đổi sang token mà bạn mong muốn. Không áp dụng phí MetaMask khi bạn hoán đổi sang mUSD." }, "musd_conversion": { - "transaction_fee": "mUSD conversion fees include network costs and may include provider fees. No MetaMask fee applies when you convert to mUSD." + "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." }, "title": { "transaction_fee": "Phí" @@ -6570,12 +6578,12 @@ "hardware_wallet_not_supported": "Ví cứng hiện chưa được hỗ trợ. Hãy sử dụng ví nóng để tiếp tục.", "hardware_wallet_not_supported_solana": "Ví cứng hiện chưa được hỗ trợ cho Solana. Hãy sử dụng ví nóng để tiếp tục.", "price_impact_info_title": "Mức tác động giá", - "price_impact_info_description": "Tác động giá phản ánh cách lệnh hoán đổi của bạn ảnh hưởng đến giá thị trường của tài sản. Nó phụ thuộc vào kích thước giao dịch và thanh khoản có sẵn trong bể. MetaMask không ảnh hưởng hoặc kiểm soát tác động giá.", + "price_impact_info_description": "This is how your trade changes the market price of a token. It depends on the trade size, available liquidity, and provider fees. MetaMask doesn't control price impact.", "price_impact_info_gasless_description": "Tác động giá phản ánh cách lệnh hoán đổi của bạn ảnh hưởng đến giá thị trường của tài sản. Nếu bạn không có đủ tiền để trả phí gas, một phần token gốc của bạn sẽ tự động được phân bổ để trả phí, làm tăng tác động giá. MetaMask không can thiệp hoặc kiểm soát tác động giá.", - "price_impact_warning_description": "This trade has an estimated {{priceImpact}} price impact, which reflects how much your trade changes the market price. The quote already reflects this.", - "price_impact_high": "High price impact", - "price_impact_execution_description": "You'll lose approximately {{priceImpact}} of your token's value on this swap. Try lowering the amount or choosing a more liquid route.", - "proceed": "Proceed", + "price_impact_warning_description": "Because of your trade size and available liquidity, you'll get about {{priceImpact}} less than the market price. This is already factored into your quote.", + "price_impact_high": "Tác động giá cao", + "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", "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.", @@ -6603,7 +6611,14 @@ "exceeding_upper_slippage_error": "Bạn không thể nhập giá trị lớn hơn {{value}}%", "custom": "Tùy chỉnh", "invalid_recipient_address": "Địa chỉ không hợp lệ", - "got_it": "Got it" + "select_quote": "Chọn báo giá", + "select_quote_info": "Các báo giá được sắp xếp theo tổng chi phí ước tính, bao gồm tỷ giá và phí mạng.", + "lowest_cost": "Chi phí thấp nhất", + "total_cost": "Tổng chi phí", + "got_it": "Tôi đã hiểu", + "price_impact_warning_title": "Tác động giá cao", + "price_impact_error_title": "Very high price impact", + "price_impact_error_description": "You'll lose approximately {{priceImpact}} of your token's market price on this swap. Try a smaller trade or a more liquid route to improve your rate." }, "quote_expired_modal": { "title": "Đã có báo giá mới", @@ -6900,7 +6915,7 @@ "title": "Nhập mật khẩu", "description": "Nhập mật khẩu ví của bạn để xem thông tin thẻ.", "description_unfreeze": "Nhập mật khẩu ví của bạn để tiếp tục chi tiêu bằng thẻ.", - "description_view_pin": "Enter your wallet password to view your card PIN.", + "description_view_pin": "Nhập mật khẩu ví của bạn để xem mã PIN thẻ.", "placeholder": "Mật khẩu", "confirm": "Xác nhận", "cancel": "Hủy", @@ -6908,7 +6923,7 @@ "error_incorrect": "Mật khẩu không chính xác. Vui lòng thử lại." }, "view_pin_bottomsheet": { - "title": "Your Card PIN" + "title": "Mã PIN thẻ của bạn" }, "choose_your_card": { "title": "Chọn thẻ của bạn", @@ -7225,9 +7240,9 @@ "view_card_details": "Xem thông tin thẻ", "hide_card_details": "Ẩn thông tin thẻ", "view_card_details_description": "Số thẻ, ngày hết hạn và số CVV", - "view_pin": "View PIN", - "view_pin_description": "View your card PIN securely", - "view_pin_error": "Failed to load PIN. Please try again.", + "view_pin": "Xem mã PIN", + "view_pin_description": "Xem mã PIN thẻ của bạn một cách an toàn", + "view_pin_error": "Không tải được mã PIN. Vui lòng thử lại.", "manage_spending_limit": "Quản lý hạn mức", "manage_spending_limit_description_restricted": "Giới hạn chi tiêu đang bật", "manage_spending_limit_description_full": "Quyền truy cập đầy đủ đang bật", @@ -7240,7 +7255,7 @@ "order_metal_card_description": "Đặt hàng Thẻ Metal vật lý ngay", "cashback": "Hoàn tiền", "cashback_description": "Nhận lại 1% cho mọi chi tiêu", - "cashback_description_metal": "Earn 3% back on all spending", + "cashback_description_metal": "Nhận lại 3% cho mọi chi tiêu", "freeze_card": "Khóa thẻ", "unfreeze_card": "Mở khóa thẻ", "freeze_card_description": "Tạm dừng mọi chi tiêu trên thẻ của bạn", @@ -7394,7 +7409,8 @@ "pay_with_modal": { "title": "Chọn phương thức thanh toán", "title_receive": "Chọn token nhận được", - "no_gas": "Không có số dư token gốc để trả phí gas" + "no_gas": "Không có số dư token gốc để trả phí gas", + "not_supported": "Không được hỗ trợ" }, "connection_removed_modal": { "title": "Kết nối đã bị xóa", @@ -7632,12 +7648,12 @@ "environment_selector": "Môi trường", "environment_cancel": "Hủy", "environment_default": "Mặc định", - "off_device_accounts_banner_title": "Missing Enrolled Accounts", - "off_device_accounts_banner_description": "There are accounts that were enrolled into the rewards program but are not found on this device.", - "off_device_accounts_banner_cta": "View", - "off_device_accounts_sheet_title": "Missing Enrolled Accounts", - "off_device_accounts_sheet_description": "These might belong to a wallet that has not yet been added after reinstalling MetaMask. Don't recognize any of these addresses?", - "off_device_accounts_sheet_let_us_know": "Let us know" + "off_device_accounts_banner_title": "Thiếu tài khoản đã đăng ký", + "off_device_accounts_banner_description": "Có các tài khoản đã được đăng ký vào chương trình phần thưởng nhưng không tìm thấy trên thiết bị này.", + "off_device_accounts_banner_cta": "Xem", + "off_device_accounts_sheet_title": "Thiếu tài khoản đã đăng ký", + "off_device_accounts_sheet_description": "Những tài khoản này có thể thuộc về một ví chưa được thêm vào sau khi cài đặt lại MetaMask. Bạn không nhận ra bất kỳ địa chỉ nào trong số này?", + "off_device_accounts_sheet_let_us_know": "Hãy cho chúng tôi biết" }, "referred_by_code": { "title": "Mã giới thiệu", @@ -7835,12 +7851,12 @@ "description": "Vui lòng thiết lập kết nối mới từ ứng dụng để tiếp tục." }, "show_internal_error": { - "title": "Something went wrong", - "description": "An unexpected error occurred. Please try again." + "title": "Đã xảy ra sự cố", + "description": "Đã xảy ra lỗi không mong muốn. Vui lòng thử lại." }, "show_method_error": { - "title": "Request failed", - "description": "The request could not be completed. Please try again." + "title": "Yêu cầu thất bại", + "description": "Không thể hoàn tất yêu cầu. Vui lòng thử lại." } }, "network_connection_banner": { @@ -7981,7 +7997,7 @@ "scanning": "Đang quét thiết bị...", "no_devices_found": "Không tìm thấy thiết bị nào", "no_devices_hint": "Đảm bảo {{device}} đã được mở khóa và Bluetooth đã được bật", - "tips": "Unlock your {{device}}, enable Bluetooth, and ensure Do Not Disturb is turned off", + "tips": "Mở khóa {{device}} của bạn, bật Bluetooth và đảm bảo đã tắt chế độ Không làm phiền", "connect": "Kết nối", "rescan": "Quét lại", "unknown_device": "Thiết bị không xác định", @@ -7997,7 +8013,7 @@ "nfts": "NFT", "import_nfts": "Nhập NFT", "import_nfts_description": "Dễ dàng thêm các bộ sưu tập của bạn", - "view_more": "View more", + "view_more": "Xem thêm", "positions": { "no_tp_sl": "Không có Chốt lời/Cắt lỗ" } diff --git a/locales/languages/zh.json b/locales/languages/zh.json index dcb32b95f506..89bfa35f2970 100644 --- a/locales/languages/zh.json +++ b/locales/languages/zh.json @@ -104,8 +104,8 @@ "title": "资金不足" }, "insufficient_pay_token_native_post_quote": { - "message": "Not enough {{ticker}} to cover fees. Add {{ticker}} to continue.", - "title": "Insufficient funds for post quote" + "message": "{{ticker}} 余额不足,无法支付费用。请添加 {{ticker}} 以继续。", + "title": "资金不足,无法发布报价" }, "no_pay_token_quotes": { "message": "目前该支付路径不可用。请调整金额、网络或代币类型,系统将为您匹配最优选项。", @@ -2077,12 +2077,12 @@ "title": "市场洞察", "a_closer_look": "深度观察", "whats_being_said": "市场声音", - "footer_disclaimer": "AI summary for information only", + "footer_disclaimer": "AI 摘要仅供参考", "trade_button": "交易", "sources_count": "+{{count}} 个来源", - "sources_title": "News sources", + "sources_title": "新闻来源", "feedback_submitted": "反馈已提交", - "helpful_prompt": "Was this helpful?", + "helpful_prompt": "这对您有帮助吗?", "feedback": { "title": "反馈", "description": "帮助我们改进人工智能生成的市场洞察。", @@ -2197,6 +2197,7 @@ "available_balance": "可用余额", "claim_amount_text": "领取 ${{amount}}", "claim_winnings_text": "领取收益", + "claiming_text": "Claiming...", "unrealized_pnl_label": "未实现盈亏", "unrealized_pnl_value": "{{amount}}({{percent}})", "unrealized_pnl_error": "无法加载", @@ -2275,6 +2276,9 @@ "title": "出错了......", "description": "继续领取失败", "try_again": "请重试" + }, + "in_progress": { + "title": "Claim already in progress" } } }, @@ -2333,7 +2337,8 @@ "exchange_fee": "交易所费用", "exchange_fee_description": "支付给交易所或市场的费用", "total_incl_fees": "包含费用", - "close": "关闭" + "close": "关闭", + "fak_partial_fill_note": "Prices shown assume your order is fully filled. Actual amounts may vary if the order is only partially filled." }, "error": { "title": "无法连接预测市场", @@ -3701,10 +3706,10 @@ "speedup_tx_title": "尝试加速?", "speedup_tx_message": "提交此尝试不能保证将会加速您的初始交易。如果加速尝试成功,将向您收取以上交易费。", "nevermind": "没关系", - "cancel_speedup_speedup_title": "Speed up Transaction", - "cancel_speedup_cancel_title": "Cancel Transaction", - "cancel_speedup_speedup_message": "This network fee will replace the original.", - "cancel_speedup_cancel_message": "This transaction will be canceled and this network fee will replace the original.", + "cancel_speedup_speedup_title": "加快交易速度", + "cancel_speedup_cancel_title": "取消交易", + "cancel_speedup_speedup_message": "此网络费用将取代原有费用。", + "cancel_speedup_cancel_message": "这笔交易将被取消,且此网络费用将取代原有费用。", "edit_network_fee": "编辑网络费", "edit_priority": "编辑优先级", "gas_cancel_fee": "燃料取消费", @@ -4837,7 +4842,7 @@ "quote_unavailable": "报价不可用。", "providers": "提供商", "quotes_displayed_for": "为 {{paymentMethodName}} 显示的报价。", - "other_options": "Other options", + "other_options": "其他选项", "previously_used": "先前使用的", "best_rate": "最优价格", "most_reliable": "最可靠", @@ -4948,10 +4953,10 @@ "provider_picker_modal": { "title": "选择提供商" }, - "contact_provider_support": "Contact {{provider}} support", + "contact_provider_support": "联系 {{provider}} 支持团队", "got_it": "知道了", - "encountered_error": "We've encountered an error", - "no_quotes_error": "We encountered a problem fetching quotes from {{provider}}. Try a different amount or changing provider.", + "encountered_error": "我们遇到了错误", + "no_quotes_error": "我们从 {{provider}} 获取报价时遇到问题。请尝试使用不同金额或更换提供商。", "change_provider_button": "更换提供商" }, "fiat_on_ramp_aggregator": { @@ -5914,7 +5919,7 @@ "error_description": "{{snap}}安装失败。" }, "earn": { - "claimable_bonus_tooltip": "The annualized bonus you’ve earned for holding mUSD. Your bonus is claimable daily on Linea.", + "claimable_bonus_tooltip": "您因持有 mUSD 而获得的年化奖励。您可以在 Linea 上每日领取奖励。", "earn_a_percentage_bonus": "获得 {{percentage}}% 的奖励", "claimable_bonus": "可领取奖励", "claim_bonus": "领取奖励", @@ -6022,21 +6027,21 @@ "toasts": { "converting": "正在将 {{token}} 兑换为 mUSD", "eta": "大约 {{time}}", - "delivered": "mUSD conversion successful", - "delivered_description": "Bonus will be claimable within a day.", + "delivered": "mUSD 兑换成功", + "delivered_description": "奖励将在一天内可领取。", "failed": "mUSD 兑换失败" }, "education": { "heading": "获取 {{percentage}}% 稳定币收益", - "description": "Convert your stablecoins to mUSD and earn up to a {{percentage}}% annualized bonus that you can claim daily.", + "description": "将您的稳定币兑换为 mUSD,即可赚取高达 {{percentage}}% 的年化奖励,该奖励每日可领取。", "terms_apply": "具体条款适用。", "primary_button": "开始", "secondary_button": "暂时不" }, "buy_musd": "购买 mUSD", "get_musd": "获取 mUSD", - "bonus_title": "Get {{percentage}}% on your stablecoins", - "bonus_description": "Convert your stablecoins to mUSD and get a {{percentage}}% annualized bonus.", + "bonus_title": "获得稳定币的 {{percentage}}% 奖励", + "bonus_description": "将您的稳定币兑换为 mUSD,即可获得 {{percentage}}% 的年化奖励。", "powered_by_relay": "由 Relay 提供技术支持", "max": "最大值", "quick_convert_button": "兑换", @@ -6044,14 +6049,14 @@ "tooltip_title": "通过 mUSD 赚取收益", "tooltip_content": "将您的 USDC、USDT 或 DAI 兑换为 mUSD——MetaMask 推出的美元稳定币。您持有的每一美元,即可赚取 {{apy}} 收益。", "quick_convert": { - "title": "Convert and get {{percentage}}%", - "subtitle": "Convert your stablecoins to mUSD and receive up to a {{percentage}}% annualized bonus that you can claim daily.", + "title": "转换并获得 {{percentage}}%", + "subtitle": "将您的稳定币兑换为 mUSD,即可获得高达 {{percentage}}% 的年化奖励,该奖励每日可领取。", "inline_failed_message": "兑换失败。请重试。", "confirmation": { "title": "兑换全部" } }, - "percentage_bonus": "{{percentage}}% bonus", + "percentage_bonus": "{{percentage}}% 奖励", "rate": "费率" }, "bonus_claim": { @@ -6092,7 +6097,9 @@ "fee": "费用", "errors": { "insufficient_balance": "您的资源余额不足以执行此操作。" - } + }, + "trx_unstaking_in_progress": "{{amount}} TRX 解除质押正在进行中。解除质押需 14 天。", + "has_claimable_trx": "You can claim {{amount}} TRX. Once claimed you'll get TRX back in your wallet." }, "stake_eth": "质押 ETH", "unstake_eth": "解除质押 ETH", @@ -6343,7 +6350,8 @@ "metamask_fee": "MetaMask 费用", "network_fee": "网络费", "bridge_fee": "桥接服务商费用", - "provider_fee": "服务商费用" + "provider_fee": "服务商费用", + "sending": "发送中" }, "title": { "signature": "签名请求", @@ -6381,10 +6389,10 @@ "transaction_fee": "我们将在预测所使用的 Polygon 网络上将您的代币兑换为 USDC.e。兑换提供商可能收取费用,但 MetaMask 不收取费用。" }, "predict_withdraw": { - "transaction_fee": "MetaMask will swap to your desired token for you. No MetaMask fee applies when you swap to mUSD." + "transaction_fee": "MetaMask 将为您兑换为您想要的代币。兑换至 mUSD 时,MetaMask 不收取任何费用。" }, "musd_conversion": { - "transaction_fee": "mUSD conversion fees include network costs and may include provider fees. No MetaMask fee applies when you convert to mUSD." + "transaction_fee": "mUSD 兑换费用包含网络费用,并可能包含提供商费用。兑换为 mUSD 时,MetaMask 不收取任何费用。" }, "title": { "transaction_fee": "费用" @@ -6570,12 +6578,12 @@ "hardware_wallet_not_supported": "目前暂不支持硬件钱包。请改用热钱包继续操作。", "hardware_wallet_not_supported_solana": "Solana 目前暂不支持硬件钱包。请改用热钱包继续操作。", "price_impact_info_title": "价格影响", - "price_impact_info_description": "价格影响反映您的兑换订单对资产市场价格的影响程度。它取决于交易规模及资金池的可用流动性状况。MetaMask 不参与亦不控制价格影响。", + "price_impact_info_description": "This is how your trade changes the market price of a token. It depends on the trade size, available liquidity, and provider fees. MetaMask doesn't control price impact.", "price_impact_info_gasless_description": "价格影响反映您的兑换订单对资产市场价格的影响程度。如果您没有足够的资金支付燃料费,系统将自动分配部分源代币用于支付费用,这会扩大价格影响。MetaMask 不参与亦不控制价格影响。", - "price_impact_warning_description": "This trade has an estimated {{priceImpact}} price impact, which reflects how much your trade changes the market price. The quote already reflects this.", - "price_impact_high": "High price impact", - "price_impact_execution_description": "You'll lose approximately {{priceImpact}} of your token's value on this swap. Try lowering the amount or choosing a more liquid route.", - "proceed": "Proceed", + "price_impact_warning_description": "Because of your trade size and available liquidity, you'll get about {{priceImpact}} less than the market price. This is already factored into your quote.", + "price_impact_high": "高价格影响", + "price_impact_execution_description": "在此兑换中,您将损失约 {{priceImpact}} 的代币价值。请尝试降低金额或选择流动性更高的路径。", + "proceed": "继续", "cancel": "取消", "slippage_info_title": "滑点", "slippage_info_description": "在交易取消前,您愿意接受的价格波动百分比。", @@ -6603,7 +6611,14 @@ "exceeding_upper_slippage_error": "您输入的数值不能大于 {{value}}%", "custom": "自定义", "invalid_recipient_address": "地址无效", - "got_it": "Got it" + "select_quote": "选择报价", + "select_quote_info": "报价按预估总成本排序,该成本包括汇率及网络费用。", + "lowest_cost": "最低成本", + "total_cost": "总成本", + "got_it": "知道了", + "price_impact_warning_title": "高价格影响", + "price_impact_error_title": "Very high price impact", + "price_impact_error_description": "You'll lose approximately {{priceImpact}} of your token's market price on this swap. Try a smaller trade or a more liquid route to improve your rate." }, "quote_expired_modal": { "title": "有新的报价", @@ -6900,7 +6915,7 @@ "title": "输入密码", "description": "输入您的钱包密码以查看卡详情。", "description_unfreeze": "请输入您的钱包密码以恢复卡消费。", - "description_view_pin": "Enter your wallet password to view your card PIN.", + "description_view_pin": "输入您的钱包密码以查看您的卡 PIN 码。", "placeholder": "密码", "confirm": "确认", "cancel": "取消", @@ -6908,7 +6923,7 @@ "error_incorrect": "密码错误。请重试。" }, "view_pin_bottomsheet": { - "title": "Your Card PIN" + "title": "您的卡 PIN 码" }, "choose_your_card": { "title": "选择您的卡", @@ -7225,9 +7240,9 @@ "view_card_details": "查看卡详情", "hide_card_details": "隐藏卡详情", "view_card_details_description": "卡号、有效期和 CVV 码", - "view_pin": "View PIN", - "view_pin_description": "View your card PIN securely", - "view_pin_error": "Failed to load PIN. Please try again.", + "view_pin": "查看 PIN 码", + "view_pin_description": "安全地查看您的卡 PIN 码", + "view_pin_error": "加载 PIN 码失败。请重试。", "manage_spending_limit": "管理限额", "manage_spending_limit_description_restricted": "限额消费已开启", "manage_spending_limit_description_full": "全部权限已开启", @@ -7240,7 +7255,7 @@ "order_metal_card_description": "立即订购您的实体金属卡", "cashback": "返现", "cashback_description": "所有消费享 1% 返现", - "cashback_description_metal": "Earn 3% back on all spending", + "cashback_description_metal": "所有消费享 3% 返现", "freeze_card": "冻结卡", "unfreeze_card": "解冻卡", "freeze_card_description": "暂停卡所有消费", @@ -7394,7 +7409,8 @@ "pay_with_modal": { "title": "选择付款方式", "title_receive": "选择收款代币", - "no_gas": "无支付燃料所需的原生代币余额" + "no_gas": "无支付燃料所需的原生代币余额", + "not_supported": "不支持" }, "connection_removed_modal": { "title": "连接已删除", @@ -7632,12 +7648,12 @@ "environment_selector": "环境", "environment_cancel": "取消", "environment_default": "默认", - "off_device_accounts_banner_title": "Missing Enrolled Accounts", - "off_device_accounts_banner_description": "There are accounts that were enrolled into the rewards program but are not found on this device.", - "off_device_accounts_banner_cta": "View", - "off_device_accounts_sheet_title": "Missing Enrolled Accounts", - "off_device_accounts_sheet_description": "These might belong to a wallet that has not yet been added after reinstalling MetaMask. Don't recognize any of these addresses?", - "off_device_accounts_sheet_let_us_know": "Let us know" + "off_device_accounts_banner_title": "缺少已注册账户", + "off_device_accounts_banner_description": "部分账户已注册加入奖励计划,但在本设备上找不到。", + "off_device_accounts_banner_cta": "查看", + "off_device_accounts_sheet_title": "缺少已注册账户", + "off_device_accounts_sheet_description": "这些地址可能属于重新安装 MetaMask 后尚未添加的钱包。这些地址您都不认识吗?", + "off_device_accounts_sheet_let_us_know": "请告知我们" }, "referred_by_code": { "title": "推荐码", @@ -7835,12 +7851,12 @@ "description": "请从应用中重新建立连接以继续。" }, "show_internal_error": { - "title": "Something went wrong", - "description": "An unexpected error occurred. Please try again." + "title": "出错了......", + "description": "发生意外错误。请重试。" }, "show_method_error": { - "title": "Request failed", - "description": "The request could not be completed. Please try again." + "title": "请求失败", + "description": "请求无法完成。请重试。" } }, "network_connection_banner": { @@ -7981,7 +7997,7 @@ "scanning": "正在扫描设备……", "no_devices_found": "未找到设备", "no_devices_hint": "请确保您的 {{device}} 已解锁,并且蓝牙已启用", - "tips": "Unlock your {{device}}, enable Bluetooth, and ensure Do Not Disturb is turned off", + "tips": "解锁您的 {{device}},启用蓝牙,并确保勿扰模式已关闭", "connect": "连接", "rescan": "重新扫描", "unknown_device": "未知设备", @@ -7997,7 +8013,7 @@ "nfts": "NFT", "import_nfts": "导入 NFT", "import_nfts_description": "轻松添加您的收藏品", - "view_more": "View more", + "view_more": "查看更多", "positions": { "no_tp_sl": "无止盈/止损" } diff --git a/tests/api-mocking/MockServerE2E.ts b/tests/api-mocking/MockServerE2E.ts index 24c668bc3531..d933f24c29b9 100644 --- a/tests/api-mocking/MockServerE2E.ts +++ b/tests/api-mocking/MockServerE2E.ts @@ -27,6 +27,31 @@ const logger = createLogger({ name: 'MockServer', level: LogLevel.INFO, }); + +/** + * Safely reads request body text, catching abort errors. + * When a client drops a connection mid-request (e.g., app navigation, AbortController), + * mockttp's streamToBuffer rejects with Error('Aborted'). This wrapper catches those + * errors and returns undefined instead of letting them bubble up as unhandled rejections. + * + * @param request - The mockttp request object + * @returns The body text or undefined if reading failed or was aborted + */ +export const safeGetBodyText = async (request: { + body: { getText: () => Promise }; +}): Promise => { + try { + return await request.body.getText(); + } catch (error) { + if (error instanceof Error && error.message === 'Aborted') { + logger.debug('Request body read aborted (client disconnected)'); + return undefined; + } + logger.warn('Failed to read request body:', error); + return undefined; + } +}; + interface LiveRequest { url: string; method: string; @@ -461,11 +486,17 @@ export default class MockServerE2E implements Resource { } try { + // Read body safely before passing to handleDirectFetch to catch abort errors + const bodyText = await safeGetBodyText(request); + // If body read was aborted, return 499 (client closed request) + if (request.method === 'POST' && bodyText === undefined) { + return { statusCode: 499, body: '' }; + } return await handleDirectFetch( translatedUrl, request.method, request.headers, - await request.body.getText(), + bodyText, ); } catch (error) { // Client dropped the connection before we could respond (e.g. bridge diff --git a/tests/api-mocking/helpers/mockHelpers.ts b/tests/api-mocking/helpers/mockHelpers.ts index 5c65e5cc1d21..7228c403a4f3 100644 --- a/tests/api-mocking/helpers/mockHelpers.ts +++ b/tests/api-mocking/helpers/mockHelpers.ts @@ -7,6 +7,7 @@ import { MockEventsObject, } from '../../framework'; import { getDecodedProxiedURL } from '../../smoke/notifications/utils/helpers.ts'; +import { safeGetBodyText } from '../MockServerE2E.ts'; // Creates a logger with INFO level as the mockServer produces too much noise // Change this to DEBUG as needed @@ -252,30 +253,27 @@ export const setupMockPostRequest = async ( } // If URL matches, also check if request body matches (ignoring specified fields) - try { - const requestBodyText = await request.body.getText(); - const result = processPostRequestBody(requestBodyText, requestBody, { - ignoreFields, - }); - - if (!result.matches) { - logger.warn('❌ Request body validation failed for', decodedUrl); - logger.debug('Expected:', requestBody); - logger.debug('Received:', result.requestBodyJson); - logger.debug('Ignored fields:', ignoreFields); - logger.debug('Error:', result.error); - } + // Use safeGetBodyText to handle abort errors gracefully + const requestBodyText = await safeGetBodyText(request); - return result.matches; - } catch (error) { - // If we can't read the body, log the error and don't match - // This prevents incorrect mock selection when body processing fails - logger.error( - 'Failed to read request body during mock matching:', - error, - ); + // If body read failed/aborted, don't match this mock + if (requestBodyText === undefined) { return false; } + + const result = processPostRequestBody(requestBodyText, requestBody, { + ignoreFields, + }); + + if (!result.matches) { + logger.warn('❌ Request body validation failed for', decodedUrl); + logger.debug('Expected:', requestBody); + logger.debug('Received:', result.requestBodyJson); + logger.debug('Ignored fields:', ignoreFields); + logger.debug('Error:', result.error); + } + + return result.matches; }) .asPriority(priority) // Adding priority to this mock request helper as we want TestSpecificMocks to always take precedence .thenCallback(async (request) => { @@ -324,17 +322,35 @@ export const interceptProxyUrl = async ( } } - const response = await fetch(transformedUrl, { - method: request.method, - headers, - body: - request.method === 'POST' ? await request.body.getText() : undefined, - }); + // Use safeGetBodyText to handle abort errors gracefully + let bodyText: string | undefined; + if (request.method === 'POST') { + bodyText = await safeGetBodyText(request); + // If body read was aborted, return 499 (client closed request) + if (bodyText === undefined) { + return { statusCode: 499, body: '' }; + } + } - return { - statusCode: response.status, - body: await response.text(), - }; + try { + const response = await fetch(transformedUrl, { + method: request.method, + headers, + body: bodyText, + }); + + return { + statusCode: response.status, + body: await response.text(), + }; + } catch (error) { + // Handle fetch errors (e.g., network issues) + logger.error('Error forwarding request:', error); + return { + statusCode: 502, + body: JSON.stringify({ error: 'Failed to forward request' }), + }; + } }); }; diff --git a/tests/api-mocking/mock-responses/polymarket/polymarket-mocks.ts b/tests/api-mocking/mock-responses/polymarket/polymarket-mocks.ts index 9479af555f31..b5712bb60e21 100644 --- a/tests/api-mocking/mock-responses/polymarket/polymarket-mocks.ts +++ b/tests/api-mocking/mock-responses/polymarket/polymarket-mocks.ts @@ -4,6 +4,7 @@ import { Mockttp } from 'mockttp'; import { setupMockRequest } from '../../helpers/mockHelpers.ts'; +import { safeGetBodyText } from '../../MockServerE2E.ts'; import { POLYMARKET_CURRENT_POSITIONS_RESPONSE, POLYMARKET_RESOLVED_LOST_POSITIONS_RESPONSE, @@ -437,7 +438,10 @@ export const POLYMARKET_PRICES_MOCKS = async (mockServer: Mockttp) => { }) .asPriority(PRIORITY.BASE) .thenCallback(async (request) => { - const bodyText = await request.body.getText(); + const bodyText = await safeGetBodyText(request); + if (bodyText === undefined) { + return { statusCode: 499, body: '' }; + } const body = bodyText ? JSON.parse(bodyText) : []; // Extract unique token IDs from the request @@ -787,7 +791,10 @@ export const POLYMARKET_USDC_BALANCE_MOCKS = async ( }) .asPriority(PRIORITY.BASE) .thenCallback(async (request) => { - const bodyText = await request.body.getText(); + const bodyText = await safeGetBodyText(request); + if (bodyText === undefined) { + return { statusCode: 499, body: '' }; + } const body = bodyText ? JSON.parse(bodyText) : undefined; // Return appropriate mock response based on the call @@ -1248,7 +1255,10 @@ export const POLYMARKET_UPDATE_USDC_BALANCE_MOCKS = async ( }) .asPriority(PRIORITY.BALANCE_REFRESH_PROXY) // Higher priority (1005) to catch balance refresh calls before base mocks .thenCallback(async (request) => { - const bodyText = await request.body.getText(); + const bodyText = await safeGetBodyText(request); + if (bodyText === undefined) { + return { statusCode: 499, body: '' }; + } const body = bodyText ? JSON.parse(bodyText) : undefined; // Return the current global balance (not a captured value) diff --git a/tests/framework/index.ts b/tests/framework/index.ts index a70108f209dd..3ca2bfe3d24e 100644 --- a/tests/framework/index.ts +++ b/tests/framework/index.ts @@ -13,6 +13,9 @@ export { Logger, createLogger, LogLevel, logger } from './logger.ts'; export { default as PortManager, ResourceType } from './PortManager.ts'; export * from './types.ts'; +// Mock server utilities +export { safeGetBodyText } from '../api-mocking/MockServerE2E.ts'; + // Dapp server exports for standalone usage (e.g., Appwright tests) export { default as DappServer } from './DappServer.ts'; export { DappVariants, TestDapps } from './Constants.ts'; diff --git a/tests/reporters/providers/sentry/PerformanceSentryPublisher.test.ts b/tests/reporters/providers/sentry/PerformanceSentryPublisher.test.ts index 909572936b6a..e25d10517f96 100644 --- a/tests/reporters/providers/sentry/PerformanceSentryPublisher.test.ts +++ b/tests/reporters/providers/sentry/PerformanceSentryPublisher.test.ts @@ -65,12 +65,14 @@ describe('PerformanceSentryPublisher', () => { const originalSentrySampleRate = process.env.E2E_PERFORMANCE_SENTRY_SAMPLE_RATE; const originalSentryEnabled = process.env.E2E_PERFORMANCE_SENTRY_ENABLED; + const originalBuildVariant = process.env.E2E_PERFORMANCE_BUILD_VARIANT; beforeEach(() => { jest.clearAllMocks(); delete process.env.E2E_PERFORMANCE_SENTRY_DSN; delete process.env.E2E_PERFORMANCE_SENTRY_SAMPLE_RATE; delete process.env.E2E_PERFORMANCE_SENTRY_ENABLED; + delete process.env.E2E_PERFORMANCE_BUILD_VARIANT; fetchMock = jest.spyOn(global, 'fetch'); }); @@ -93,6 +95,12 @@ describe('PerformanceSentryPublisher', () => { process.env.E2E_PERFORMANCE_SENTRY_ENABLED = originalSentryEnabled; } + if (originalBuildVariant === undefined) { + delete process.env.E2E_PERFORMANCE_BUILD_VARIANT; + } else { + process.env.E2E_PERFORMANCE_BUILD_VARIANT = originalBuildVariant; + } + fetchMock.mockRestore(); }); @@ -115,6 +123,7 @@ describe('PerformanceSentryPublisher', () => { it('sends performance timers as sentry measurements', async () => { process.env.E2E_PERFORMANCE_SENTRY_DSN = 'https://publicKey@o123.ingest.sentry.io/4567'; + process.env.E2E_PERFORMANCE_BUILD_VARIANT = 'exp'; fetchMock.mockResolvedValue({ ok: true, status: 200, @@ -158,6 +167,7 @@ describe('PerformanceSentryPublisher', () => { expect(payload.measurements.step_1_load_2.value).toBe(700); expect(payload.measurements.scenario_total_time_ms.value).toBe(1300); expect(payload.tags.project_name).toBe('browserstack-android'); + expect(payload.tags.build_variant).toBe('exp'); expect(payload.extra.timer_steps).toHaveLength(2); }); diff --git a/tests/reporters/providers/sentry/PerformanceSentryPublisher.ts b/tests/reporters/providers/sentry/PerformanceSentryPublisher.ts index 221096c614c2..debd6f926d3b 100644 --- a/tests/reporters/providers/sentry/PerformanceSentryPublisher.ts +++ b/tests/reporters/providers/sentry/PerformanceSentryPublisher.ts @@ -12,6 +12,7 @@ const ENV_SENTRY_ENABLED = 'E2E_PERFORMANCE_SENTRY_ENABLED'; const ENV_SENTRY_SAMPLE_RATE = 'E2E_PERFORMANCE_SENTRY_SAMPLE_RATE'; const ENV_SENTRY_ENVIRONMENT = 'E2E_PERFORMANCE_SENTRY_ENVIRONMENT'; const ENV_SENTRY_RELEASE = 'E2E_PERFORMANCE_SENTRY_RELEASE'; +const ENV_SENTRY_BUILD_VARIANT = 'E2E_PERFORMANCE_BUILD_VARIANT'; const MAX_MEASUREMENT_KEY_LENGTH = 64; const RESERVED_MEASUREMENT_KEYS = [ 'scenario_total_time_ms', @@ -75,6 +76,14 @@ function normalizeSpanStatus(status?: string): string { } } +function normalizeBuildVariant(variant?: string): 'rc' | 'exp' | 'unknown' { + if (variant === 'rc' || variant === 'exp') { + return variant; + } + + return 'unknown'; +} + function sanitizeMeasurementKey(name: string): string { const baseKey = name .toLowerCase() @@ -308,6 +317,9 @@ export async function publishPerformanceScenarioToSentry( test_status: options.status || 'unknown', retry: String(options.retry ?? 0), worker_index: String(options.workerIndex ?? 0), + build_variant: normalizeBuildVariant( + getEnvValue(ENV_SENTRY_BUILD_VARIANT), + ), }, measurements, spans,