diff --git a/.github/scripts/fitness-functions/common/constants.ts b/.github/scripts/fitness-functions/common/constants.ts index 78c5ac66dfc..686ec3aef94 100644 --- a/.github/scripts/fitness-functions/common/constants.ts +++ b/.github/scripts/fitness-functions/common/constants.ts @@ -7,4 +7,7 @@ enum AUTOMATION_TYPE { PRE_PUSH_HOOK = 'pre-push-hook', } -export { EXCLUDE_REGEX, AUTOMATION_TYPE }; +// only allow TS and TSX files in the app directory only +const APP_FOLDER_JS_REGEX = /^(app).*\.(js|jsx)$/; + +export { EXCLUDE_REGEX, APP_FOLDER_JS_REGEX, AUTOMATION_TYPE }; diff --git a/.github/scripts/fitness-functions/common/shared.ts b/.github/scripts/fitness-functions/common/shared.ts index 004b26711c0..9b05fc94c20 100644 --- a/.github/scripts/fitness-functions/common/shared.ts +++ b/.github/scripts/fitness-functions/common/shared.ts @@ -33,6 +33,34 @@ function filterDiffByFilePath(diff: string, regex: RegExp): string { return filteredDiff; } +function restrictedFilePresent(diff: string, regex: RegExp): boolean { + // split by `diff --git` and remove the first element which is empty + const diffBlocks = diff.split(`diff --git`).slice(1); + let jsOrJsxFilePresent = false; + diffBlocks + .map((block) => block.trim()) + .filter((block) => { + block + // get the first line of the block which has the paths + .split('\n')[0] + .trim() + // split the two paths + .split(' ') + // remove `a/` and `b/` from the paths + .map((path) => path.substring(2)) + // if at least one of the two paths matches the regex, filter the + // corresponding diff block in + .forEach((path) => { + if (regex.test(path)) { + // Not excluded, include in check + jsOrJsxFilePresent = true; + } + }); + return jsOrJsxFilePresent; + }) + return jsOrJsxFilePresent; +} + // This function returns all lines that are additions to files that are being // modified but that previously already existed. Example: // diff --git a/test.js b/test.js @@ -111,6 +139,7 @@ function hasNumberOfCodeBlocksIncreased( export { filterDiffByFilePath, + restrictedFilePresent, filterDiffFileCreations, filterDiffLineAdditions, hasNumberOfCodeBlocksIncreased, diff --git a/.github/scripts/fitness-functions/rules/index.ts b/.github/scripts/fitness-functions/rules/index.ts index d0fa4d57588..b5d30de0ee8 100644 --- a/.github/scripts/fitness-functions/rules/index.ts +++ b/.github/scripts/fitness-functions/rules/index.ts @@ -1,3 +1,4 @@ +import { preventJavaScriptFileAdditions } from './javascript-additions'; import { preventCodeBlocksRule } from './prevent-code-blocks'; const RULES: IRule[] = [ @@ -6,6 +7,11 @@ const RULES: IRule[] = [ fn: preventCodeBlocksRule, docURL: '[WIP] No documentation exists for this rule yet.', }, + { + name: 'Check for js or jsx file being added', + fn: preventJavaScriptFileAdditions, + docURL: '[WIP] No documentation exists for this rule yet.', + }, ]; interface IRule { @@ -32,5 +38,5 @@ function runFitnessFunctionRule(rule: IRule, diff: string): void { } } -export { RULES, runFitnessFunctionRule }; +export { RULES, runFitnessFunctionRule, preventJavaScriptFileAdditions }; export type { IRule }; diff --git a/.github/scripts/fitness-functions/rules/javascript-additions.test.ts b/.github/scripts/fitness-functions/rules/javascript-additions.test.ts new file mode 100644 index 00000000000..b997ffe1521 --- /dev/null +++ b/.github/scripts/fitness-functions/rules/javascript-additions.test.ts @@ -0,0 +1,51 @@ +import { + generateModifyFilesDiff, + generateCreateFileDiff, +} from '../common/test-data'; +import { preventJavaScriptFileAdditions } from './javascript-additions'; + +describe('preventJavaScriptFileAdditions()', (): void => { + it('should pass when receiving an empty diff', (): void => { + const testDiff = ''; + + const hasRulePassed = preventJavaScriptFileAdditions(testDiff); + + expect(hasRulePassed).toBe(true); + }); + + it('should pass when receiving a diff with a new TS file on the shared folder', (): void => { + const testDiff = [ + generateModifyFilesDiff('new-file.ts', 'foo', 'bar'), + generateModifyFilesDiff('old-file.js', undefined, 'pong'), + generateCreateFileDiff('app/test.ts', 'yada yada yada yada'), + ].join(''); + + const hasRulePassed = preventJavaScriptFileAdditions(testDiff); + + expect(hasRulePassed).toBe(true); + }); + + it('should not pass when receiving a diff with a new JS file on the shared folder', (): void => { + const testDiff = [ + generateModifyFilesDiff('new-file.ts', 'foo', 'bar'), + generateModifyFilesDiff('old-file.js', undefined, 'pong'), + generateCreateFileDiff('app/test.js', 'yada yada yada yada'), + ].join(''); + + const hasRulePassed = preventJavaScriptFileAdditions(testDiff); + + expect(hasRulePassed).toBe(false); + }); + + it('should not pass when receiving a diff with a new JSX file on the shared folder', (): void => { + const testDiff = [ + generateModifyFilesDiff('new-file.ts', 'foo', 'bar'), + generateModifyFilesDiff('old-file.js', undefined, 'pong'), + generateCreateFileDiff('app/test.jsx', 'yada yada yada yada'), + ].join(''); + + const hasRulePassed = preventJavaScriptFileAdditions(testDiff); + + expect(hasRulePassed).toBe(false); + }); +}); diff --git a/.github/scripts/fitness-functions/rules/javascript-additions.ts b/.github/scripts/fitness-functions/rules/javascript-additions.ts new file mode 100644 index 00000000000..591787ee8bc --- /dev/null +++ b/.github/scripts/fitness-functions/rules/javascript-additions.ts @@ -0,0 +1,12 @@ +import { APP_FOLDER_JS_REGEX } from '../common/constants'; +import { filterDiffFileCreations, restrictedFilePresent } from '../common/shared'; + +function preventJavaScriptFileAdditions(diff: string): boolean { + const diffAdditions = filterDiffFileCreations(diff); + if (restrictedFilePresent(diffAdditions, APP_FOLDER_JS_REGEX)) { + return false; + } + return true; +} + +export { preventJavaScriptFileAdditions }; diff --git a/CHANGELOG.md b/CHANGELOG.md index 7a30a43dd6d..f1d8e7e518e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ ## Current Main Branch +## 7.24.3 - Jun 19, 2024 +### Fixed +- [#10045](https://github.com/MetaMask/metamask-mobile/pull/10045): fix: Update ppom package to 1.4.8 (#10041) + ## 7.24.2 - Jun 13, 2024 ### Added - [#9687](https://github.com/MetaMask/metamask-mobile/pull/9687): feat: adds "data collection for marketing" toggles diff --git a/android/app/build.gradle b/android/app/build.gradle index b7c7b5d720e..59ab639b631 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -181,8 +181,8 @@ android { applicationId "io.metamask" minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion - versionCode 1348 - versionName "7.24.2" + versionCode 1351 + versionName "7.24.3" testBuildType System.getProperty('testBuildType', 'debug') missingDimensionStrategy 'react-native-camera', 'general' testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" diff --git a/app/components/Nav/App/index.js b/app/components/Nav/App/index.js index 4c87c167b15..6021355e2ac 100644 --- a/app/components/Nav/App/index.js +++ b/app/components/Nav/App/index.js @@ -344,15 +344,9 @@ const App = ({ userLoggedIn }) => { animationNameRef?.current?.play(); } }; - appTriggeredAuth() - .then(() => { - queueOfHandleDeeplinkFunctions.current.forEach((func) => func()); - - queueOfHandleDeeplinkFunctions.current = []; - }) - .catch((error) => { - Logger.error(error, 'App: Error in appTriggeredAuth'); - }); + appTriggeredAuth().catch((error) => { + Logger.error(error, 'App: Error in appTriggeredAuth'); + }); }, [navigator, queueOfHandleDeeplinkFunctions]); const handleDeeplink = useCallback(({ error, params, uri }) => { @@ -415,9 +409,11 @@ const App = ({ userLoggedIn }) => { handleDeeplink(opts); } else { queueOfHandleDeeplinkFunctions.current = - queueOfHandleDeeplinkFunctions.current.concat(() => { - handleDeeplink(opts); - }); + queueOfHandleDeeplinkFunctions.current.concat([ + () => { + handleDeeplink(opts); + }, + ]); } }); } @@ -456,7 +452,11 @@ const App = ({ userLoggedIn }) => { try { const sdkConnect = SDKConnect.getInstance(); await sdkConnect.init({ navigation: navigator, context: 'Nav/App' }); - await SDKConnect.getInstance().postInit(); + await SDKConnect.getInstance().postInit(() => { + setTimeout(() => { + queueOfHandleDeeplinkFunctions.current = []; + }, 1000); + }); sdkInit.current = true; } catch (err) { sdkInit.current = undefined; @@ -464,9 +464,13 @@ const App = ({ userLoggedIn }) => { } } } - initSDKConnect().catch((err) => { - Logger.error(err, 'Error initializing SDKConnect'); - }); + initSDKConnect() + .then(() => { + queueOfHandleDeeplinkFunctions.current.forEach((func) => func()); + }) + .catch((err) => { + Logger.error(err, 'Error initializing SDKConnect'); + }); }, [navigator, onboarded, userLoggedIn]); useEffect(() => { diff --git a/app/components/UI/AssetOverview/AssetOverview.tsx b/app/components/UI/AssetOverview/AssetOverview.tsx index 0103d9f67fa..9757bb06110 100644 --- a/app/components/UI/AssetOverview/AssetOverview.tsx +++ b/app/components/UI/AssetOverview/AssetOverview.tsx @@ -169,7 +169,7 @@ const AssetOverview: React.FC = ({ const itemAddress = safeToChecksumAddress(asset.address); const exchangeRate = itemAddress && itemAddress in tokenExchangeRates - ? tokenExchangeRates[itemAddress] + ? tokenExchangeRates?.[itemAddress]?.price : undefined; let balance, balanceFiat; diff --git a/app/components/UI/NetworkInfo/index.tsx b/app/components/UI/NetworkInfo/index.tsx index dfca807590c..c4a55151b23 100644 --- a/app/components/UI/NetworkInfo/index.tsx +++ b/app/components/UI/NetworkInfo/index.tsx @@ -8,7 +8,7 @@ import { connect, useSelector } from 'react-redux'; import Description from './InfoDescription'; import { useTheme } from '../../../util/theme'; import { fontStyles } from '../../../styles/common'; -import { isTokenDetectionSupportedForNetwork } from '@metamask/assets-controllers/dist/assetsUtil'; +import { isTokenDetectionSupportedForNetwork } from '@metamask/assets-controllers'; import { NETWORK_EDUCATION_MODAL_CLOSE_BUTTON } from '../../../../wdio/screen-objects/testIDs/Screens/NetworksScreen.testids.js'; import { selectProviderConfig } from '../../../selectors/networkController'; import { diff --git a/app/components/UI/Notification/BaseNotification/index.js b/app/components/UI/Notification/BaseNotification/index.js index 94810c6210f..96a11304d75 100644 --- a/app/components/UI/Notification/BaseNotification/index.js +++ b/app/components/UI/Notification/BaseNotification/index.js @@ -9,7 +9,7 @@ import IonicIcon from 'react-native-vector-icons/Ionicons'; import AntIcon from 'react-native-vector-icons/AntDesign'; import Text from '../../../Base/Text'; import { useTheme } from '../../../../util/theme'; -import { CommonSelectorsIDs } from '../../../../../e2e/selectors/Common.selectors'; +import { ToastSelectorsIDs } from '../../../../../e2e/selectors/Modals/ToastModal.selectors'; const createStyles = (colors) => StyleSheet.create({ @@ -185,7 +185,7 @@ const BaseNotification = ({ {!title ? getTitle(status, data) : title} diff --git a/app/components/UI/PaymentRequest/index.js b/app/components/UI/PaymentRequest/index.js index 35cb474d41c..ac632e49634 100644 --- a/app/components/UI/PaymentRequest/index.js +++ b/app/components/UI/PaymentRequest/index.js @@ -46,7 +46,7 @@ import { toLowerCaseEquals } from '../../../util/general'; import { utils as ethersUtils } from 'ethers'; import { ThemeContext, mockTheme } from '../../../util/theme'; import { isTestNet } from '../../../util/networks'; -import { isTokenDetectionSupportedForNetwork } from '@metamask/assets-controllers/dist/assetsUtil'; +import { isTokenDetectionSupportedForNetwork } from '@metamask/assets-controllers'; import { selectChainId, selectTicker, @@ -553,7 +553,7 @@ class PaymentRequest extends PureComponent { const exchangeRate = selectedAsset && selectedAsset.address && - contractExchangeRates[selectedAsset.address]; + contractExchangeRates?.[selectedAsset.address]?.price; if (selectedAsset.symbol !== 'ETH') { secondaryAmount = exchangeRate ? balanceToFiat( @@ -587,7 +587,8 @@ class PaymentRequest extends PureComponent { const exchangeRate = selectedAsset && selectedAsset.address && - contractExchangeRates[selectedAsset.address]; + contractExchangeRates && + contractExchangeRates[selectedAsset.address]?.price; const undefAmount = (isDecimal(amount) && amount) || 0; let secondaryAmount, cryptoAmount; if (selectedAsset.symbol !== 'ETH' && exchangeRate && exchangeRate !== 0) { @@ -631,7 +632,8 @@ class PaymentRequest extends PureComponent { const exchangeRate = selectedAsset && selectedAsset.address && - contractExchangeRates[selectedAsset.address]; + contractExchangeRates && + contractExchangeRates[selectedAsset.address]?.price; let res; // If primary currency is not crypo we need to know if there are conversion and exchange rates to handle0, // fiat conversion for the payment request @@ -745,7 +747,8 @@ class PaymentRequest extends PureComponent { const exchangeRate = selectedAsset && selectedAsset.address && - contractExchangeRates[selectedAsset.address]; + contractExchangeRates && + contractExchangeRates[selectedAsset.address]?.price; let switchable = true; const colors = this.context.colors || mockTheme.colors; const themeAppearance = this.context.themeAppearance || 'light'; diff --git a/app/components/UI/Ramp/hooks/useBalance.ts b/app/components/UI/Ramp/hooks/useBalance.ts index f7d2dbca9c9..f0e49c63e3a 100644 --- a/app/components/UI/Ramp/hooks/useBalance.ts +++ b/app/components/UI/Ramp/hooks/useBalance.ts @@ -51,10 +51,7 @@ export default function useBalance(asset?: Asset) { ); balanceFiat = weiToFiat(balanceBN, conversionRate, currentCurrency); } else { - const exchangeRate = - assetAddress && assetAddress in tokenExchangeRates - ? tokenExchangeRates[assetAddress] - : undefined; + const exchangeRate = tokenExchangeRates?.[assetAddress]?.price; balance = assetAddress && assetAddress in balances ? renderFromTokenMinimalUnit( diff --git a/app/components/UI/Swaps/components/TokenSelectModal.js b/app/components/UI/Swaps/components/TokenSelectModal.js index 8dbe18c247b..0b4a61778a3 100644 --- a/app/components/UI/Swaps/components/TokenSelectModal.js +++ b/app/components/UI/Swaps/components/TokenSelectModal.js @@ -242,8 +242,8 @@ function TokenSelectModal({ ); } else { const exchangeRate = - itemAddress in tokenExchangeRates - ? tokenExchangeRates[itemAddress] + tokenExchangeRates && itemAddress in tokenExchangeRates + ? tokenExchangeRates[itemAddress]?.price : undefined; balance = itemAddress in balances diff --git a/app/components/UI/Swaps/index.js b/app/components/UI/Swaps/index.js index e7a2ef448fa..69ee6d47ee2 100644 --- a/app/components/UI/Swaps/index.js +++ b/app/components/UI/Swaps/index.js @@ -32,10 +32,8 @@ import { MetaMetricsEvents } from '../../../core/Analytics'; import { getFeatureFlagChainId, - setSwapsHasOnboarded, setSwapsLiveness, swapsControllerTokens, - swapsHasOnboardedSelector, swapsTokensSelector, swapsTokensWithBalanceSelector, swapsTopAssetsSelector, @@ -198,8 +196,6 @@ function SwapsAmountView({ conversionRate, tokenExchangeRates, currentCurrency, - userHasOnboarded, - setHasOnboarded, setLiveness, }) { const navigation = useNavigation(); @@ -502,8 +498,8 @@ function SwapsAmountView({ } else { const sourceAddress = safeToChecksumAddress(sourceToken.address); const exchangeRate = - sourceAddress in tokenExchangeRates - ? tokenExchangeRates[sourceAddress] + tokenExchangeRates && sourceAddress in tokenExchangeRates + ? tokenExchangeRates[sourceAddress]?.price : undefined; balanceFiat = balanceToFiat( amount, @@ -978,14 +974,6 @@ SwapsAmountView.propTypes = { * An object containing token exchange rates in the format address => exchangeRate */ tokenExchangeRates: PropTypes.object, - /** - * Wether the user has been onboarded or not - */ - userHasOnboarded: PropTypes.bool, - /** - * Function to set hasOnboarded - */ - setHasOnboarded: PropTypes.func, /** * Current network provider configuration */ @@ -1018,12 +1006,9 @@ const mapStateToProps = (state) => ({ chainId: selectChainId(state), tokensWithBalance: swapsTokensWithBalanceSelector(state), tokensTopAssets: swapsTopAssetsSelector(state), - userHasOnboarded: swapsHasOnboardedSelector(state), }); const mapDispatchToProps = (dispatch) => ({ - setHasOnboarded: (hasOnboarded) => - dispatch(setSwapsHasOnboarded(hasOnboarded)), setLiveness: (chainId, featureFlags) => dispatch(setSwapsLiveness(chainId, featureFlags)), }); diff --git a/app/components/UI/Tokens/index.test.tsx b/app/components/UI/Tokens/index.test.tsx index 53dfd08cc04..4a7e22aaabf 100644 --- a/app/components/UI/Tokens/index.test.tsx +++ b/app/components/UI/Tokens/index.test.tsx @@ -68,10 +68,12 @@ const initialState = { ], }, TokenRatesController: { - contractExchangeRates: { - '0x0': 0.005, - '0x01': 0.005, - '0x02': 0.005, + marketData: { + '0x1': { + '0x0': { price: 0.005 }, + '0x01': { price: 0.005 }, + '0x02': { price: 0.005 }, + }, }, }, CurrencyRateController: { @@ -225,8 +227,10 @@ describe('Tokens', () => { ], }, TokenRatesController: { - contractExchangeRates: { - '0x02': undefined, + marketData: { + 0x1: { + '0x02': undefined, + }, }, }, CurrencyRateController: { diff --git a/app/components/UI/Tokens/index.tsx b/app/components/UI/Tokens/index.tsx index ecdcf614ee3..5e81b74159e 100644 --- a/app/components/UI/Tokens/index.tsx +++ b/app/components/UI/Tokens/index.tsx @@ -316,10 +316,11 @@ const Tokens: React.FC = ({ tokens }) => { // When the exchange rate of a token is not found, the return is undefined // We fallback to the TOKEN_RATE_UNDEFINED to handle it properly - const exchangeRate = - itemAddress in tokenExchangeRates + const tokenMarketData = tokenExchangeRates + ? itemAddress in tokenExchangeRates ? tokenExchangeRates[itemAddress] || TOKEN_RATE_UNDEFINED - : undefined; + : undefined + : undefined; const balance = asset.balance || @@ -336,13 +337,13 @@ const Tokens: React.FC = ({ tokens }) => { const balanceValueFormatted = `${balance} ${asset.symbol}`; - if (!conversionRate || !exchangeRate) + if (!conversionRate) return { balanceFiat: asset.isETH ? asset.balanceFiat : TOKEN_BALANCE_LOADING, balanceValueFormatted, }; - if (exchangeRate === TOKEN_RATE_UNDEFINED) + if (!tokenMarketData || tokenMarketData === TOKEN_RATE_UNDEFINED) return { balanceFiat: asset.isETH ? asset.balanceFiat : TOKEN_RATE_UNDEFINED, balanceValueFormatted, @@ -350,7 +351,7 @@ const Tokens: React.FC = ({ tokens }) => { const balanceFiatCalculation = Number( asset.balanceFiat || - balanceToFiatNumber(balance, conversionRate, exchangeRate), + balanceToFiatNumber(balance, conversionRate, tokenMarketData.price), ); const balanceFiat = diff --git a/app/components/UI/TransactionElement/utils.js b/app/components/UI/TransactionElement/utils.js index 1f6f7ef9a45..22b0e562005 100644 --- a/app/components/UI/TransactionElement/utils.js +++ b/app/components/UI/TransactionElement/utils.js @@ -120,7 +120,10 @@ function getTokenTransfer(args) { const renderTokenAmount = token ? `${renderFromTokenMinimalUnit(amount, token.decimals)} ${token.symbol}` : undefined; - const exchangeRate = token ? contractExchangeRates[token.address] : undefined; + const exchangeRate = + token && contractExchangeRates + ? contractExchangeRates[token.address]?.price + : undefined; let renderTokenFiatAmount, renderTokenFiatNumber; if (exchangeRate) { renderTokenFiatAmount = balanceToFiat( @@ -286,9 +289,10 @@ export function decodeIncomingTransfer(args) { const renderTokenAmount = token ? `${renderFromTokenMinimalUnit(amount, token.decimals)} ${token.symbol}` : undefined; - const exchangeRate = token - ? contractExchangeRates[toChecksumAddress(token.address)] - : undefined; + const exchangeRate = + token && contractExchangeRates + ? contractExchangeRates[toChecksumAddress(token.address)]?.price + : undefined; let renderTokenFiatAmount, renderTokenFiatNumber; if (exchangeRate) { @@ -769,7 +773,8 @@ function decodeSwapsTx(args) { const sourceExchangeRate = isSwapsNativeAsset(sourceToken) ? 1 - : contractExchangeRates[safeToChecksumAddress(sourceToken.address)]; + : contractExchangeRates?.[safeToChecksumAddress(sourceToken.address)] + ?.price; const renderSourceTokenFiatNumber = balanceToFiatNumber( decimalSourceAmount, conversionRate, @@ -778,7 +783,8 @@ function decodeSwapsTx(args) { const destinationExchangeRate = isSwapsNativeAsset(destinationToken) ? 1 - : contractExchangeRates[safeToChecksumAddress(destinationToken.address)]; + : contractExchangeRates?.[safeToChecksumAddress(destinationToken.address)] + ?.price; const renderDestinationTokenFiatNumber = balanceToFiatNumber( decimalDestinationAmount, conversionRate, diff --git a/app/components/Views/AddAsset/AddAsset.tsx b/app/components/Views/AddAsset/AddAsset.tsx index 871926468bb..69fa8020663 100644 --- a/app/components/Views/AddAsset/AddAsset.tsx +++ b/app/components/Views/AddAsset/AddAsset.tsx @@ -11,7 +11,7 @@ import { getImportTokenNavbarOptions, getNetworkNavbarOptions, } from '../../UI/Navbar'; -import { isTokenDetectionSupportedForNetwork } from '@metamask/assets-controllers/dist/assetsUtil'; +import { isTokenDetectionSupportedForNetwork } from '@metamask/assets-controllers'; import { selectChainId, selectProviderConfig, diff --git a/app/components/Views/AssetDetails/index.tsx b/app/components/Views/AssetDetails/index.tsx index 6b0e411298a..13c30c6683b 100644 --- a/app/components/Views/AssetDetails/index.tsx +++ b/app/components/Views/AssetDetails/index.tsx @@ -269,7 +269,9 @@ const AssetDetails = (props: Props) => { const renderTokenBalance = () => { let balanceDisplay = ''; const exchangeRate = - address in tokenExchangeRates ? tokenExchangeRates[address] : undefined; + tokenExchangeRates && address in tokenExchangeRates + ? tokenExchangeRates[address]?.price + : undefined; const balance = address in tokenBalances ? renderFromTokenMinimalUnit(tokenBalances[address], decimals) diff --git a/app/components/Views/DetectedTokens/components/Token.tsx b/app/components/Views/DetectedTokens/components/Token.tsx index 2b719d70554..6f85170ddb8 100644 --- a/app/components/Views/DetectedTokens/components/Token.tsx +++ b/app/components/Views/DetectedTokens/components/Token.tsx @@ -111,7 +111,7 @@ const Token = ({ token, selected, toggleSelected }: Props) => { const tokenBalances = useSelector(selectContractBalances); const conversionRate = useSelector(selectConversionRate); const currentCurrency = useSelector(selectCurrentCurrency); - const exchangeRate = tokenExchangeRates[address]; + const tokenMarketData = tokenExchangeRates?.[address] ?? null; const tokenBalance = renderFromTokenMinimalUnit( tokenBalances[address], decimals, @@ -122,7 +122,7 @@ const Token = ({ token, selected, toggleSelected }: Props) => { const fiatBalance = balanceToFiat( tokenBalance, conversionRate, - exchangeRate, + tokenMarketData?.price || undefined, currentCurrency, ); diff --git a/app/components/Views/DetectedTokens/index.tsx b/app/components/Views/DetectedTokens/index.tsx index 72692507ddc..4df619a584f 100644 --- a/app/components/Views/DetectedTokens/index.tsx +++ b/app/components/Views/DetectedTokens/index.tsx @@ -20,7 +20,10 @@ import { getDecimalChainId } from '../../../util/networks'; import { createNavigationDetails } from '../../../util/navigation/navUtils'; import Routes from '../../../constants/navigation/Routes'; import { selectDetectedTokens } from '../../../selectors/tokensController'; -import { selectChainId } from '../../../selectors/networkController'; +import { + selectChainId, + selectNetworkClientId, +} from '../../../selectors/networkController'; import BottomSheet, { BottomSheetRef, } from '../../../component-library/components/BottomSheets/BottomSheet'; @@ -77,6 +80,7 @@ const DetectedTokens = () => { const sheetRef = useRef(null); const detectedTokens = useSelector(selectDetectedTokens); const chainId = useSelector(selectChainId); + const networkClientId = useSelector(selectNetworkClientId); const [ignoredTokens, setIgnoredTokens] = useState( {}, ); @@ -130,7 +134,7 @@ const DetectedTokens = () => { tokensToIgnore.length > 0 && (await TokensController.ignoreTokens(tokensToIgnore)); if (tokensToImport.length > 0) { - await TokensController.addTokens(tokensToImport); + await TokensController.addTokens(tokensToImport, networkClientId); InteractionManager.runAfterInteractions(() => tokensToImport.forEach(({ address, symbol }) => trackEvent(MetaMetricsEvents.TOKEN_ADDED, { @@ -153,7 +157,7 @@ const DetectedTokens = () => { } }); }, - [chainId, detectedTokens, ignoredTokens, trackEvent], + [chainId, detectedTokens, ignoredTokens, trackEvent, networkClientId], ); const triggerIgnoreAllTokens = () => { diff --git a/app/components/Views/Notifications/Details/hooks/useDetails.tsx b/app/components/Views/Notifications/Details/hooks/useDetails.tsx index 8b3d6ae926a..95d8825b9e5 100644 --- a/app/components/Views/Notifications/Details/hooks/useDetails.tsx +++ b/app/components/Views/Notifications/Details/hooks/useDetails.tsx @@ -239,7 +239,7 @@ const useDetails = ({ const renderAsset = useCallback( (type, title, token, network) => { const exchangeRate = - token.address && contractExchangeRates[token.address]; + token.address && contractExchangeRates?.[token.address]?.price; const balanceFiat = token ? balanceToFiat( token.amount || '0', diff --git a/app/components/Views/Settings/AdvancedSettings/index.js b/app/components/Views/Settings/AdvancedSettings/index.js index 6b2aa997bd1..53d0cc62734 100644 --- a/app/components/Views/Settings/AdvancedSettings/index.js +++ b/app/components/Views/Settings/AdvancedSettings/index.js @@ -4,7 +4,7 @@ import React, { PureComponent } from 'react'; import { Linking, SafeAreaView, StyleSheet, Switch, View } from 'react-native'; import { connect } from 'react-redux'; import { KeyboardAwareScrollView } from 'react-native-keyboard-aware-scroll-view'; -import { isTokenDetectionSupportedForNetwork } from '@metamask/assets-controllers/dist/assetsUtil'; +import { isTokenDetectionSupportedForNetwork } from '@metamask/assets-controllers'; import { getApplicationName, getBuildNumber, diff --git a/app/components/Views/confirmations/Send/index.test.tsx b/app/components/Views/confirmations/Send/index.test.tsx index a11f2bb49d6..6432727b813 100644 --- a/app/components/Views/confirmations/Send/index.test.tsx +++ b/app/components/Views/confirmations/Send/index.test.tsx @@ -132,7 +132,7 @@ const initialState = { allNftContracts: {}, }, TokenRatesController: { - contractExchangeRates: {}, + marketData: {}, }, TransactionController: { methodData: {}, diff --git a/app/components/Views/confirmations/SendFlow/Amount/index.js b/app/components/Views/confirmations/SendFlow/Amount/index.js index eb25757372a..60ef28bd8e1 100644 --- a/app/components/Views/confirmations/SendFlow/Amount/index.js +++ b/app/components/Views/confirmations/SendFlow/Amount/index.js @@ -599,7 +599,8 @@ class Amount extends PureComponent { if (selectedAsset.isETH) { return !!conversionRate; } - const exchangeRate = contractExchangeRates[selectedAsset.address]; + const exchangeRate = + contractExchangeRates?.[selectedAsset.address]?.price ?? null; return !!exchangeRate; }; @@ -900,7 +901,9 @@ class Amount extends PureComponent { }); } } else { - const exchangeRate = contractExchangeRates[selectedAsset.address]; + const exchangeRate = contractExchangeRates + ? contractExchangeRates[selectedAsset.address]?.price + : undefined; if (internalPrimaryCurrencyIsCrypto || !exchangeRate) { input = fromTokenMinimalUnitString( contractBalances[selectedAsset.address]?.toString(10), @@ -965,7 +968,9 @@ class Amount extends PureComponent { renderableInputValueConversion = `${inputValueConversion} ${processedTicker}`; } } else { - const exchangeRate = contractExchangeRates[selectedAsset.address]; + const exchangeRate = contractExchangeRates + ? contractExchangeRates[selectedAsset.address]?.price + : null; hasExchangeRate = !!exchangeRate; if (internalPrimaryCurrencyIsCrypto) { inputValueConversion = `${balanceToFiatNumber( @@ -1078,7 +1083,9 @@ class Amount extends PureComponent { ); } else { balance = renderFromTokenMinimalUnit(contractBalances[address], decimals); - const exchangeRate = contractExchangeRates[address]; + const exchangeRate = contractExchangeRates + ? contractExchangeRates[address]?.price + : undefined; balanceFiat = balanceToFiat( balance, conversionRate, diff --git a/app/components/Views/confirmations/SendFlow/Amount/index.test.tsx b/app/components/Views/confirmations/SendFlow/Amount/index.test.tsx index 68f4cd935e4..4ecbb9893e5 100644 --- a/app/components/Views/confirmations/SendFlow/Amount/index.test.tsx +++ b/app/components/Views/confirmations/SendFlow/Amount/index.test.tsx @@ -85,7 +85,6 @@ const initialState = { backgroundState: { ...initialBackgroundState, NetworkController: { - network: '1', providerConfig: { ticker: 'ETH', type: 'mainnet', @@ -371,8 +370,10 @@ describe('Amount', () => { backgroundState: { ...initialState.engine.backgroundState, TokenRatesController: { - contractExchangeRates: { - '0x514910771AF9Ca656af840dff83E8264EcF986CA': 0.005, + marketData: { + '0x1': { + '0x514910771AF9Ca656af840dff83E8264EcF986CA': { price: 0.005 }, + }, }, }, CurrencyRateController: { @@ -475,8 +476,10 @@ describe('Amount', () => { backgroundState: { ...initialState.engine.backgroundState, TokenRatesController: { - contractExchangeRates: { - '0x514910771AF9Ca656af840dff83E8264EcF986CA': 0.005, + marketData: { + '0x1': { + '0x514910771AF9Ca656af840dff83E8264EcF986CA': { price: 0.005 }, + }, }, }, CurrencyRateController: { @@ -530,7 +533,7 @@ describe('Amount', () => { backgroundState: { ...initialState.engine.backgroundState, TokenRatesController: { - contractExchangeRates: {}, + marketData: {}, }, CurrencyRateController: {}, }, @@ -571,8 +574,10 @@ describe('Amount', () => { backgroundState: { ...initialState.engine.backgroundState, TokenRatesController: { - contractExchangeRates: { - '0x514910771AF9Ca656af840dff83E8264EcF986CA': 0.005, + marketData: { + '0x1': { + '0x514910771AF9Ca656af840dff83E8264EcF986CA': { price: 0.005 }, + }, }, }, CurrencyRateController: {}, @@ -617,7 +622,11 @@ describe('Amount', () => { backgroundState: { ...initialState.engine.backgroundState, TokenRatesController: { - contractExchangeRates: {}, + marketData: { + '0x1': { + '0x514910771AF9Ca656af840dff83E8264EcF986CA': { price: 0.005 }, + }, + }, }, CurrencyRateController: {}, }, diff --git a/app/components/Views/confirmations/SendFlow/Confirm/index.js b/app/components/Views/confirmations/SendFlow/Confirm/index.js index fb17097e85a..295e1abe2b9 100644 --- a/app/components/Views/confirmations/SendFlow/Confirm/index.js +++ b/app/components/Views/confirmations/SendFlow/Confirm/index.js @@ -673,7 +673,9 @@ class Confirm extends PureComponent { decimals, ); transactionValue = `${transferValue} ${symbol}`; - const exchangeRate = contractExchangeRates[address]; + const exchangeRate = contractExchangeRates + ? contractExchangeRates[address]?.price + : undefined; transactionValueFiat = balanceToFiat( transferValue, diff --git a/app/components/Views/confirmations/components/PersonalSign/PersonalSign.tsx b/app/components/Views/confirmations/components/PersonalSign/PersonalSign.tsx index b51d4e56909..6cefc97575f 100644 --- a/app/components/Views/confirmations/components/PersonalSign/PersonalSign.tsx +++ b/app/components/Views/confirmations/components/PersonalSign/PersonalSign.tsx @@ -13,7 +13,7 @@ import { isExternalHardwareAccount, stripHexPrefix, } from '../../../../../util/address'; -import sanitizeString from '../../../../../util/string'; +import { sanitizeString } from '../../../../../util/string'; import { KEYSTONE_TX_CANCELED } from '../../../../../constants/error'; import { useTheme } from '../../../../../util/theme'; import { PersonalSignProps } from './types'; diff --git a/app/components/Views/confirmations/components/TransactionReview/TransactionReviewData/index.js b/app/components/Views/confirmations/components/TransactionReview/TransactionReviewData/index.js index 3abf121f4c8..fc22f2973f8 100644 --- a/app/components/Views/confirmations/components/TransactionReview/TransactionReviewData/index.js +++ b/app/components/Views/confirmations/components/TransactionReview/TransactionReviewData/index.js @@ -15,7 +15,6 @@ import { selectConversionRate, selectCurrentCurrency, } from '../../../../../../selectors/currencyRateController'; -import { selectContractExchangeRates } from '../../../../../../selectors/tokenRatesController'; const createStyles = (colors) => StyleSheet.create({ @@ -186,7 +185,6 @@ class TransactionReviewData extends PureComponent { const mapStateToProps = (state) => ({ conversionRate: selectConversionRate(state), currentCurrency: selectCurrentCurrency(state), - contractExchangeRates: selectContractExchangeRates(state), transaction: state.transaction, }); diff --git a/app/components/Views/confirmations/components/TransactionReview/TransactionReviewEIP1559Update/index.test.tsx b/app/components/Views/confirmations/components/TransactionReview/TransactionReviewEIP1559Update/index.test.tsx index 0e6a2c4bd92..b065a8fbc70 100644 --- a/app/components/Views/confirmations/components/TransactionReview/TransactionReviewEIP1559Update/index.test.tsx +++ b/app/components/Views/confirmations/components/TransactionReview/TransactionReviewEIP1559Update/index.test.tsx @@ -27,8 +27,10 @@ const initialState = { gasEstimateType: 'low', }, TokenRatesController: { - contractExchangeRates: { - '0x326836cc6cd09B5aa59B81A7F72F25FcC0136b95': 1, + marketData: { + 0x1: { + '0x326836cc6cd09B5aa59B81A7F72F25FcC0136b95': 1, + }, }, }, TokenBalancesController: { diff --git a/app/components/Views/confirmations/components/TransactionReview/index.js b/app/components/Views/confirmations/components/TransactionReview/index.js index 38655aa09c8..de924772852 100644 --- a/app/components/Views/confirmations/components/TransactionReview/index.js +++ b/app/components/Views/confirmations/components/TransactionReview/index.js @@ -393,7 +393,9 @@ class TransactionReview extends PureComponent { value, selectedAsset.decimals, )} ${selectedAsset.symbol}`; - const conversionRate = contractExchangeRates[selectedAsset.address]; + const conversionRate = contractExchangeRates + ? contractExchangeRates[selectedAsset.address]?.price + : undefined; const fiatValue = balanceToFiat( (value && fromTokenMinimalUnit(value, selectedAsset.decimals)) || 0, this.props.conversionRate, diff --git a/app/components/Views/confirmations/components/TypedSign/index.js b/app/components/Views/confirmations/components/TypedSign/index.js index ab992817d54..bd2838cb114 100644 --- a/app/components/Views/confirmations/components/TypedSign/index.js +++ b/app/components/Views/confirmations/components/TypedSign/index.js @@ -9,7 +9,10 @@ import Device from '../../../../../util/device'; import { MetaMetricsEvents } from '../../../../../core/Analytics'; import { KEYSTONE_TX_CANCELED } from '../../../../../constants/error'; import { ThemeContext, mockTheme } from '../../../../../util/theme'; -import sanitizeString from '../../../../../util/string'; +import { + parseTypedSignDataMessage, + sanitizeString, +} from '../../../../../util/string'; import { addSignatureErrorListener, @@ -180,7 +183,6 @@ class TypedSign extends PureComponent { renderTypedMessageV3 = (obj) => { const styles = this.getStyles(); - return Object.keys(obj).map((key) => ( {obj[key] && typeof obj[key] === 'object' ? ( @@ -221,7 +223,7 @@ class TypedSign extends PureComponent { ); } if (messageParams.version === 'V3' || messageParams.version === 'V4') { - const { message } = JSON.parse(messageParams.data); + const message = parseTypedSignDataMessage(messageParams.data); return this.renderTypedMessageV3(message); } }; diff --git a/app/constants/eth-methods.ts b/app/constants/eth-methods.ts new file mode 100644 index 00000000000..5df93ee0954 --- /dev/null +++ b/app/constants/eth-methods.ts @@ -0,0 +1,11 @@ +import { EthMethod } from '@metamask/keyring-api'; + +// eslint-disable-next-line import/prefer-default-export +export const ETH_EOA_METHODS = [ + EthMethod.PersonalSign, + EthMethod.Sign, + EthMethod.SignTransaction, + EthMethod.SignTypedDataV1, + EthMethod.SignTypedDataV3, + EthMethod.SignTypedDataV4, +]; diff --git a/app/core/Engine.ts b/app/core/Engine.ts index 8965cb45b92..26228259228 100644 --- a/app/core/Engine.ts +++ b/app/core/Engine.ts @@ -178,7 +178,7 @@ import { SignatureControllerActions, SignatureControllerEvents, } from '@metamask/signature-controller'; -import { hasProperty, Json } from '@metamask/utils'; +import { hasProperty, Hex, Json } from '@metamask/utils'; // TODO: Export this type from the package directly import { SwapsState } from '@metamask/swaps-controller/dist/SwapsController'; import { providerErrors } from '@metamask/rpc-errors'; @@ -481,7 +481,6 @@ class Engine { networkController.initializeProvider(); const assetsContractController = new AssetsContractController({ - //@ts-expect-error mismatch version, will disappear when bump assets-controllers to >=29 onPreferencesStateChange, onNetworkDidChange: (listener) => this.controllerMessenger.subscribe( @@ -489,23 +488,19 @@ class Engine { listener, ), chainId: networkController.state.providerConfig.chainId, - //@ts-expect-error - Network Controller mismatch version getNetworkClientById: networkController.getNetworkClientById.bind(networkController), }); const nftController = new NftController( { - //@ts-expect-error mismatch version, will disappear when bump assets-controllers to >=29 onPreferencesStateChange, onNetworkStateChange: (listener) => this.controllerMessenger.subscribe( AppConstants.NETWORK_STATE_CHANGE_EVENT, listener, ), - //@ts-expect-error - Network Controller mismatch version getNetworkClientById: networkController.getNetworkClientById.bind(networkController), - //@ts-expect-error Misalign types because of Base Controller version messenger: this.controllerMessenger.getRestricted({ name: 'NftController', allowedActions: [ @@ -555,7 +550,6 @@ class Engine { state: initialState.LoggingController, }); - //@ts-expect-error Misalign types because of Base Controller version const accountsControllerMessenger: AccountsControllerMessenger = this.controllerMessenger.getRestricted({ name: 'AccountsController', @@ -585,15 +579,17 @@ class Engine { const tokensController = new TokensController({ chainId: networkController.state.providerConfig.chainId, config: { - //@ts-expect-error - Network Controller mismatch version provider: networkController.getProviderAndBlockTracker().provider, chainId: networkController.state.providerConfig.chainId, selectedAddress: preferencesController.state.selectedAddress, }, - //@ts-expect-error Misalign types because of Base Controller version + state: initialState.TokensController, messenger: this.controllerMessenger.getRestricted({ name: 'TokensController', - allowedActions: [`${approvalController.name}:addRequest`], + allowedActions: [ + `${approvalController.name}:addRequest`, + 'NetworkController:getNetworkClientById', + ], allowedEvents: [ 'PreferencesController:stateChange', 'NetworkController:networkDidChange', @@ -608,7 +604,6 @@ class Engine { AppConstants.NETWORK_STATE_CHANGE_EVENT, listener, ), - //@ts-expect-error Misalign types because of Base Controller version messenger: this.controllerMessenger.getRestricted({ name: 'TokenListController', allowedActions: [], @@ -616,7 +611,6 @@ class Engine { }), }); const currencyRateController = new CurrencyRateController({ - //@ts-expect-error Misalign types because of Base Controller version messenger: this.controllerMessenger.getRestricted({ name: 'CurrencyRateController', allowedActions: [`${networkController.name}:getNetworkClientById`], @@ -792,7 +786,6 @@ class Engine { }); ///: END:ONLY_INCLUDE_IF const accountTrackerController = new AccountTrackerController({ - //@ts-expect-error mismatch version, will disappear when bump assets-controllers to >=29 onPreferencesStateChange, getIdentities: () => preferencesController.state.identities, getSelectedAddress: () => accountsController.getSelectedAccount().address, @@ -800,7 +793,6 @@ class Engine { preferencesController.state.isMultiAccountBalancesEnabled, getCurrentChainId: () => toHexadecimal(networkController.state.providerConfig.chainId), - //@ts-expect-error - Network Controller mismatch version getNetworkClientById: networkController.getNetworkClientById.bind(networkController), }); @@ -1051,8 +1043,6 @@ class Engine { onNetworkStateChange: (listener) => this.controllerMessenger.subscribe( AppConstants.NETWORK_STATE_CHANGE_EVENT, - //@ts-expect-error This is because the network type is still missing linea-sepolia - // When transaction controller be updated to v^25 listener, ), // @ts-expect-error at this point in time the provider will be defined by the `networkController.initializeProvider` @@ -1152,7 +1142,6 @@ class Engine { tokensController, tokenListController, new TokenDetectionController({ - //@ts-expect-error Misalign types because of Base Controller version messenger: this.controllerMessenger.getRestricted({ name: 'TokenDetectionController', allowedActions: [ @@ -1196,7 +1185,6 @@ class Engine { }), new NftDetectionController({ onNftsStateChange: (listener) => nftController.subscribe(listener), - //@ts-expect-error mismatch version, will disappear when bump assets-controllers to >=29 onPreferencesStateChange, onNetworkStateChange: (listener) => this.controllerMessenger.subscribe( @@ -1208,22 +1196,22 @@ class Engine { addNft: nftController.addNft.bind(nftController), getNftApi: nftController.getNftApi.bind(nftController), getNftState: () => nftController.state, - //@ts-expect-error - Network Controller mismatch version getNetworkClientById: networkController.getNetworkClientById.bind(networkController), + disabled: false, + selectedAddress: preferencesController.state.selectedAddress, }), currencyRateController, networkController, phishingController, preferencesController, new TokenBalancesController({ - //@ts-expect-error Misalign types because of Base Controller version messenger: this.controllerMessenger.getRestricted({ name: 'TokenBalancesController', allowedActions: ['PreferencesController:getState'], allowedEvents: ['TokensController:stateChange'], }), - // onTokensStateChange will be removed when Tokens Controller extends Base Controller v2 + //@ts-expect-error onTokensStateChange will be removed when Tokens Controller extends Base Controller v2 onTokensStateChange: (listener) => tokensController.subscribe(listener), getERC20BalanceOf: assetsContractController.getERC20BalanceOf.bind( assetsContractController, @@ -1237,14 +1225,12 @@ class Engine { AppConstants.NETWORK_STATE_CHANGE_EVENT, listener, ), - //@ts-expect-error mismatch version, will disappear when bump assets-controllers to >=29 onPreferencesStateChange, chainId: networkController.state.providerConfig.chainId, ticker: networkController.state.providerConfig.ticker, selectedAddress: preferencesController.state.selectedAddress, tokenPricesService: codefiTokenApiV2, interval: 30 * 60 * 1000, - //@ts-expect-error - Network Controller mismatch version getNetworkClientById: networkController.getNetworkClientById.bind(networkController), }), @@ -1492,9 +1478,6 @@ class Engine { } provider.sendAsync = provider.sendAsync.bind(provider); AccountTrackerController.configure({ provider }); - //@ts-expect-error This seems to be incosistency on the core repo between the provider type - // AssetsContractController provider type = Provider | undefined - // NetworkController provider type = SafeEventEmitterProvider AssetsContractController.configure({ provider }); SwapsController.configure({ @@ -1551,13 +1534,13 @@ class Engine { } if (tokens.length > 0) { const { contractBalances: tokenBalances } = TokenBalancesController.state; - const { contractExchangeRates: tokenExchangeRates } = - TokenRatesController.state; + const { marketData } = TokenRatesController.state; + const tokenExchangeRates = marketData[chainId]; tokens.forEach( (item: { address: string; balance?: string; decimals: number }) => { const exchangeRate = - item.address in tokenExchangeRates - ? tokenExchangeRates[item.address] + tokenExchangeRates && item.address in tokenExchangeRates + ? tokenExchangeRates[item.address as Hex] : undefined; const tokenBalance = item.balance || @@ -1651,7 +1634,7 @@ class Engine { }); TokenBalancesController.reset(); - TokenRatesController.update({ contractExchangeRates: {} }); + TokenRatesController.update({ marketData: {} }); TransactionController.update({ methodData: {}, diff --git a/app/core/SDKConnect/InitializationManagement/postInit.ts b/app/core/SDKConnect/InitializationManagement/postInit.ts index b6ea823f7a2..e0539b6988c 100644 --- a/app/core/SDKConnect/InitializationManagement/postInit.ts +++ b/app/core/SDKConnect/InitializationManagement/postInit.ts @@ -9,7 +9,7 @@ import { waitForKeychainUnlocked, } from '../utils/wait.util'; -async function postInit(instance: SDKConnect) { +async function postInit(instance: SDKConnect, callback?: () => void) { if (!instance.state._initialized) { throw new Error(`SDKConnect::postInit() - not initialized`); } @@ -53,6 +53,8 @@ async function postInit(instance: SDKConnect) { instance.state._postInitialized = true; DevLogger.log(`SDKConnect::postInit() - done`); + + callback?.(); } export default postInit; diff --git a/app/core/SDKConnect/SDKConnect.test.ts b/app/core/SDKConnect/SDKConnect.test.ts index f3f82e0d073..920d62f1cec 100644 --- a/app/core/SDKConnect/SDKConnect.test.ts +++ b/app/core/SDKConnect/SDKConnect.test.ts @@ -150,7 +150,6 @@ describe('SDKConnect', () => { await sdkConnect.postInit(); expect(mockPostInit).toHaveBeenCalledTimes(1); - expect(mockPostInit).toHaveBeenCalledWith(sdkConnect); }); }); }); diff --git a/app/core/SDKConnect/SDKConnect.ts b/app/core/SDKConnect/SDKConnect.ts index 8708a9b1767..f4975e34b62 100644 --- a/app/core/SDKConnect/SDKConnect.ts +++ b/app/core/SDKConnect/SDKConnect.ts @@ -361,8 +361,8 @@ export class SDKConnect { return init({ navigation, context, instance: this }); } - async postInit() { - return postInit(this); + async postInit(callback?: () => void) { + return postInit(this, callback); } hasInitialized() { diff --git a/app/selectors/accountsController.test.ts b/app/selectors/accountsController.test.ts index 25dcf1db960..abb7dbaa089 100644 --- a/app/selectors/accountsController.test.ts +++ b/app/selectors/accountsController.test.ts @@ -83,6 +83,7 @@ describe('Accounts Controller Selectors', () => { options: {}, metadata: { name: 'Account 2', + importTime: 1684232000456, keyring: { type: 'HD Key Tree', }, diff --git a/app/selectors/tokenRatesController.ts b/app/selectors/tokenRatesController.ts index 79874e2b1e6..aad37a30ebb 100644 --- a/app/selectors/tokenRatesController.ts +++ b/app/selectors/tokenRatesController.ts @@ -2,12 +2,15 @@ import { createSelector } from 'reselect'; import { TokenRatesState } from '@metamask/assets-controllers'; import { RootState } from '../reducers'; +import { selectChainId } from './networkController'; +import { Hex } from '@metamask/utils'; const selectTokenRatesControllerState = (state: RootState) => state.engine.backgroundState.TokenRatesController; export const selectContractExchangeRates = createSelector( + selectChainId, selectTokenRatesControllerState, - (tokenRatesControllerState: TokenRatesState) => - tokenRatesControllerState.contractExchangeRates, + (chainId: Hex, tokenRatesControllerState: TokenRatesState) => + tokenRatesControllerState.marketData[chainId], ); diff --git a/app/store/migrations/029.ts b/app/store/migrations/029.ts index e0b8041a8c1..0431c101b0d 100644 --- a/app/store/migrations/029.ts +++ b/app/store/migrations/029.ts @@ -536,6 +536,7 @@ export default async function migrate(stateAsync: unknown) { ).forEach((chainId) => { if (!isHexString(chainId)) { const hexChainId = toHex(chainId); + //@ts-expect-error At the time of that migrations assets controllers version had those properties, so those users will have that property on their phone storage, the migration was casted and that where it's wrong, we shouldn't cast migrations because the structure and property names change over time. newTokenRatesControllerState.contractExchangeRatesByChainId[ hexChainId ] = diff --git a/app/store/migrations/031.ts b/app/store/migrations/031.ts index 33b05b90e88..1424b95b3b1 100644 --- a/app/store/migrations/031.ts +++ b/app/store/migrations/031.ts @@ -130,10 +130,12 @@ export default async function migrate(stateAsync: unknown) { if ( !Object.prototype.hasOwnProperty.call( + //@ts-expect-error At the time of that migrations assets controllers version had those properties, so those users will have that property on their phone storage, the migration was casted and that where it's wrong, we shouldn't cast migrations because the structure and property names change over time. newTokenRatesControllerState.contractExchangeRatesByChainId, hexChainId, ) ) { + //@ts-expect-error At the time of that migrations assets controllers version had those properties, so those users will have that property on their phone storage, the migration was casted and that where it's wrong, we shouldn't cast migrations because the structure and property names change over time. newTokenRatesControllerState.contractExchangeRatesByChainId[ hexChainId ] = diff --git a/app/store/migrations/036.test.ts b/app/store/migrations/036.test.ts index 0a3ff51760a..71f29f1222e 100644 --- a/app/store/migrations/036.test.ts +++ b/app/store/migrations/036.test.ts @@ -51,6 +51,7 @@ function expectedInternalAccount( id: getUUIDFromAddressOfNormalAccount(address), metadata: { name: nickname, + importTime: Date.now(), keyring: { type: 'HD Key Tree', }, diff --git a/app/store/migrations/036.ts b/app/store/migrations/036.ts index d0c48b0ccef..84d5b6a521b 100644 --- a/app/store/migrations/036.ts +++ b/app/store/migrations/036.ts @@ -1,17 +1,15 @@ -import { - EthAccountType, - InternalAccount, - EthMethod, -} from '@metamask/keyring-api'; +import { EthAccountType, InternalAccount } from '@metamask/keyring-api'; import { isObject, hasProperty } from '@metamask/utils'; import { captureException } from '@sentry/react-native'; import { getUUIDFromAddressOfNormalAccount } from '@metamask/accounts-controller'; import { KeyringTypes } from '@metamask/keyring-controller'; +import { ETH_EOA_METHODS } from '../../constants/eth-methods'; export interface Identity { name: string; address: string; lastSelected?: number; + importTime?: number; } export default function migrate(state: unknown) { @@ -118,6 +116,7 @@ function createInternalAccountsForAccountsController( options: {}, metadata: { name: identity.name, + importTime: identity.importTime ?? Date.now(), lastSelected: identity.lastSelected ?? undefined, keyring: { // This is default HD Key Tree type because the keyring is encrypted @@ -126,14 +125,7 @@ function createInternalAccountsForAccountsController( type: KeyringTypes.hd, }, }, - methods: [ - EthMethod.PersonalSign, - EthMethod.Sign, - EthMethod.SignTransaction, - EthMethod.SignTypedDataV1, - EthMethod.SignTypedDataV3, - EthMethod.SignTypedDataV4, - ], + methods: ETH_EOA_METHODS, type: EthAccountType.Eoa, }; diff --git a/app/store/migrations/042.test.ts b/app/store/migrations/042.test.ts index 8b9cb8f196a..62b72f370de 100644 --- a/app/store/migrations/042.test.ts +++ b/app/store/migrations/042.test.ts @@ -1,9 +1,6 @@ import migrate from './042'; import { captureException } from '@sentry/react-native'; -import { - AccountsControllerState, - getUUIDFromAddressOfNormalAccount, -} from '@metamask/accounts-controller'; +import { getUUIDFromAddressOfNormalAccount } from '@metamask/accounts-controller'; import { toChecksumHexAddress } from '@metamask/controller-utils'; import { EthMethod } from '@metamask/keyring-api'; @@ -24,9 +21,7 @@ const expectedId3 = getUUIDFromAddressOfNormalAccount(MOCK_LOWERCASE_ADDRESS_3); const expectedId4 = getUUIDFromAddressOfNormalAccount(MOCK_LOWERCASE_ADDRESS_4); const expectedId5 = getUUIDFromAddressOfNormalAccount(MOCK_LOWERCASE_ADDRESS_5); -function createMockAccountsControllerState( - selectedAccount = 'id1', -): AccountsControllerState { +function createMockAccountsControllerState(selectedAccount = 'id1') { return { internalAccounts: { accounts: { @@ -427,7 +422,7 @@ describe('Migration #042', () => { }); it('should handle cases with no duplicates correctly', () => { - const uniqueState: AccountsControllerState = { + const uniqueState = { internalAccounts: { accounts: { unique1: { diff --git a/app/store/migrations/042.ts b/app/store/migrations/042.ts index 080bcd498fd..86491ef8050 100644 --- a/app/store/migrations/042.ts +++ b/app/store/migrations/042.ts @@ -7,6 +7,7 @@ import { } from '@metamask/accounts-controller'; import { InternalAccount } from '@metamask/keyring-api'; import { isDefaultAccountName } from '../../util/ENSUtils'; +import { ETH_EOA_METHODS } from '../../constants/eth-methods'; export default function migrate(state: unknown) { if (!ensureValidState(state, 42)) { @@ -75,9 +76,7 @@ function mergeInternalAccounts(state: ValidState) { account.metadata.name, ), }; - existingAccount.methods = Array.from( - new Set([...existingAccount.methods, ...account.methods]), - ); + existingAccount.methods = ETH_EOA_METHODS; } else { const newId = getUUIDFromAddressOfNormalAccount(lowerCaseAddress); addressMap[lowerCaseAddress] = newId; diff --git a/app/store/migrations/047.test.ts b/app/store/migrations/047.test.ts new file mode 100644 index 00000000000..026c9feecfc --- /dev/null +++ b/app/store/migrations/047.test.ts @@ -0,0 +1,255 @@ +import migration from './047'; +import { merge } from 'lodash'; +import initialRootState from '../../util/test/initial-root-state'; +import { captureException } from '@sentry/react-native'; +import { + expectedUuid, + expectedUuid2, + internalAccount1, + internalAccount2, +} from '../../util/test/accountsControllerTestUtils'; +import { RootState } from '../../reducers'; +import { toChecksumHexAddress } from '@metamask/controller-utils'; +import { Identity } from './036'; + +const mockChecksummedInternalAcc1 = toChecksumHexAddress( + internalAccount1.address, +); +const mockChecksummedInternalAcc2 = toChecksumHexAddress( + internalAccount2.address, +); + +const oldState = { + engine: { + backgroundState: { + PreferencesController: { + identities: { + [mockChecksummedInternalAcc1]: { + address: mockChecksummedInternalAcc1, + name: 'Internal Account 1', + //Fake time for testing + importTime: 123, + }, + [mockChecksummedInternalAcc2]: { + address: mockChecksummedInternalAcc2, + name: 'Internal Account 2', + //No importTime set for the test the default Date.now + }, + }, + }, + AccountsController: { + internalAccounts: { + accounts: { + //importTime variable didn't exist on the old state + [expectedUuid]: { + ...internalAccount1, + metadata: { ...internalAccount1.metadata, importTime: undefined }, + }, + [expectedUuid2]: { + ...internalAccount2, + metadata: { ...internalAccount2.metadata, importTime: undefined }, + }, + }, + selectedAccount: {}, + }, + }, + }, + }, +}; + +jest.mock('@sentry/react-native', () => ({ + captureException: jest.fn(), +})); +const mockedCaptureException = jest.mocked(captureException); + +describe('Migration #47', () => { + beforeEach(() => { + jest.restoreAllMocks(); + jest.resetAllMocks(); + }); + + const invalidStates = [ + { + state: merge({}, initialRootState, { + engine: null, + }), + errorMessage: + "FATAL ERROR: Migration 47: Invalid engine state error: 'object'", + scenario: 'engine state is invalid', + }, + { + state: merge({}, initialRootState, { + engine: { + backgroundState: null, + }, + }), + errorMessage: + "FATAL ERROR: Migration 47: Invalid engine backgroundState error: 'object'", + scenario: 'backgroundState is invalid', + }, + { + state: merge({}, initialRootState, { + engine: { + backgroundState: { + AccountsController: null, + }, + }, + }), + errorMessage: + "FATAL ERROR: Migration 47: Invalid AccountsController state error: 'object'", + scenario: 'AccountsController state is invalid', + }, + { + state: merge({}, initialRootState, { + engine: { + backgroundState: { + AccountsController: { internalAccounts: null }, + }, + }, + }), + errorMessage: + "FATAL ERROR: Migration 47: Invalid AccountsController internalAccounts state error: 'object'", + scenario: 'AccountsController internalAccounts state is invalid', + }, + { + state: merge({}, initialRootState, { + engine: { + backgroundState: { + PreferencesController: null, + AccountsController: { internalAccounts: { accounts: {} } }, + }, + }, + }), + errorMessage: + "FATAL ERROR: Migration 47: Invalid PreferencesController state error: 'null'", + scenario: 'PreferencesController state is invalid', + }, + { + state: merge({}, initialRootState, { + engine: { + backgroundState: { + PreferencesController: { identities: null }, + AccountsController: { internalAccounts: { accounts: {} } }, + }, + }, + }), + errorMessage: + "FATAL ERROR: Migration 47: Invalid PreferencesController identities state error: 'null'", + scenario: 'PreferencesController identities state is invalid', + }, + { + state: merge({}, initialRootState, { + engine: { + backgroundState: { + PreferencesController: { identities: null }, + AccountsController: { + internalAccounts: { + accounts: { '92c0e479-6133-4a18-b1bf-fa38f654e293': null }, + }, + }, + }, + }, + }), + errorMessage: + "FATAL ERROR: Migration 47: Invalid AccountsController entry with id: '92c0e479-6133-4a18-b1bf-fa38f654e293', type: 'object'", + scenario: 'AccountsController accounts account state is invalid', + }, + ]; + + for (const { errorMessage, scenario, state } of invalidStates) { + it(`should capture exception if ${scenario}`, () => { + const newState = migration(state); + + expect(newState).toStrictEqual(state); + expect(mockedCaptureException).toHaveBeenCalledWith(expect.any(Error)); + expect(mockedCaptureException.mock.calls[0][0].message).toBe( + errorMessage, + ); + }); + } + + it('should add importTime from identities or default to the current date', () => { + // Mocked Date.now since jest is not aware of date. + jest.spyOn(Date, 'now').mockReturnValue(new Date('2023-01-01').getTime()); + const newState: Pick = migration(oldState) as Pick< + RootState, + 'engine' + >; + + Object.keys( + newState.engine.backgroundState.AccountsController.internalAccounts + .accounts, + ).forEach((accountId) => { + expect( + newState.engine.backgroundState.AccountsController.internalAccounts + .accounts[accountId].metadata.importTime, + ).toEqual(expect.any(Number)); + + Object.values( + newState.engine.backgroundState.PreferencesController.identities, + ).forEach((identity) => { + if ( + (identity as Identity).importTime && + toChecksumHexAddress( + newState.engine.backgroundState.AccountsController.internalAccounts + .accounts[accountId].address, + ) === (identity as Identity).address + ) { + expect( + newState.engine.backgroundState.AccountsController.internalAccounts + .accounts[accountId].metadata.importTime, + ).toStrictEqual((identity as Identity).importTime); + } + }); + }); + }); + it('should default importTime to the current date if identities is not populated and import time is undefined', () => { + // Mocked Date.now since jest is not aware of date. + jest.spyOn(Date, 'now').mockReturnValue(new Date('2023-01-01').getTime()); + + const oldState2 = { + engine: { + backgroundState: { + PreferencesController: { identities: {} }, + AccountsController: { + internalAccounts: { + accounts: { + //importTime variable didn't exist on the old state + [expectedUuid]: { + ...internalAccount1, + metadata: { + ...internalAccount1.metadata, + importTime: undefined, + }, + }, + [expectedUuid2]: { + ...internalAccount2, + metadata: { + ...internalAccount2.metadata, + importTime: undefined, + }, + }, + }, + selectedAccount: {}, + }, + }, + }, + }, + }; + + const newState: Pick = migration(oldState2) as Pick< + RootState, + 'engine' + >; + + Object.keys( + newState.engine.backgroundState.AccountsController.internalAccounts + .accounts, + ).forEach((accountId) => { + expect( + newState.engine.backgroundState.AccountsController.internalAccounts + .accounts[accountId].metadata.importTime, + ).toEqual(expect.any(Number)); + }); + }); +}); diff --git a/app/store/migrations/047.ts b/app/store/migrations/047.ts new file mode 100644 index 00000000000..77f77f1b21d --- /dev/null +++ b/app/store/migrations/047.ts @@ -0,0 +1,135 @@ +import { captureException } from '@sentry/react-native'; +import { isObject, hasProperty } from '@metamask/utils'; +import { ensureValidState } from './util'; +import { AccountsControllerState } from '@metamask/accounts-controller'; +import { PreferencesState } from '@metamask/preferences-controller'; +import { toChecksumHexAddress } from '@metamask/controller-utils'; + +/** + * Migration to add importTime property to accounts metadata of accounts controller + * This migration is needed due to the update of Accounts Controller to version 14 + * @param state Persisted Redux state + * @returns Valid persisted Redux state + */ +export default function migrate(state: unknown) { + if (!ensureValidState(state, 47)) { + return state; + } + + const accountsControllerState = + state.engine.backgroundState.AccountsController; + + if (!isObject(accountsControllerState)) { + captureException( + new Error( + `FATAL ERROR: Migration 47: Invalid AccountsController state error: '${typeof accountsControllerState}'`, + ), + ); + return state; + } + + if ( + !hasProperty(accountsControllerState, 'internalAccounts') || + !isObject(accountsControllerState.internalAccounts) + ) { + captureException( + new Error( + `FATAL ERROR: Migration 47: Invalid AccountsController internalAccounts state error: '${typeof accountsControllerState.internalAccounts}'`, + ), + ); + return state; + } + + if ( + !hasProperty(accountsControllerState.internalAccounts, 'accounts') || + !isObject(accountsControllerState.internalAccounts.accounts) + ) { + captureException( + new Error( + `FATAL ERROR: Migration 47: Invalid AccountsController internalAccounts accounts state error: '${typeof accountsControllerState + .internalAccounts.accounts}'`, + ), + ); + return state; + } + + if ( + Object.values(accountsControllerState.internalAccounts.accounts).some( + (account) => !isObject(account), + ) + ) { + const invalidEntry = Object.entries( + accountsControllerState.internalAccounts.accounts, + ).find(([_, account]) => !isObject(account)); + captureException( + new Error( + `FATAL ERROR: Migration 47: Invalid AccountsController entry with id: '${ + invalidEntry?.[0] + }', type: '${typeof invalidEntry?.[1]}'`, + ), + ); + return state; + } + + const preferencesControllerState = state.engine.backgroundState + .PreferencesController as PreferencesState; + + if (!isObject(preferencesControllerState)) { + captureException( + new Error( + `FATAL ERROR: Migration 47: Invalid PreferencesController state error: '${JSON.stringify( + preferencesControllerState, + )}'`, + ), + ); + return state; + } + + if ( + !hasProperty(preferencesControllerState, 'identities') || + !isObject(preferencesControllerState.identities) + ) { + captureException( + new Error( + `FATAL ERROR: Migration 47: Invalid PreferencesController identities state error: '${preferencesControllerState.identities}'`, + ), + ); + return state; + } + + const accounts = accountsControllerState.internalAccounts.accounts; + Object.keys(accountsControllerState.internalAccounts.accounts).forEach( + (accountId) => { + const account = accounts[accountId]; + if ( + isObject(account) && + isObject(account.metadata) && + !account.metadata.importTime + ) { + if (Object.keys(preferencesControllerState.identities).length) { + Object.keys(preferencesControllerState.identities).forEach( + (identityAddress) => { + if ( + toChecksumHexAddress(identityAddress) === + toChecksumHexAddress(account.address as string) + ) { + ( + accountsControllerState as AccountsControllerState + ).internalAccounts.accounts[accountId].metadata.importTime = + preferencesControllerState.identities[identityAddress] + .importTime ?? Date.now(); + } + }, + ); + } else { + ( + accountsControllerState as AccountsControllerState + ).internalAccounts.accounts[accountId].metadata.importTime = + Date.now(); + } + } + }, + ); + + return state; +} diff --git a/app/store/migrations/048.test.ts b/app/store/migrations/048.test.ts new file mode 100644 index 00000000000..f8ea08170c9 --- /dev/null +++ b/app/store/migrations/048.test.ts @@ -0,0 +1,85 @@ +import migration from './048'; +import { merge } from 'lodash'; +import initialRootState from '../../util/test/initial-root-state'; +import { captureException } from '@sentry/react-native'; + +const oldState = { + engine: { + backgroundState: { + TokenRatesController: { + contractExchangeRates: {}, + contractExchangeRatesByChainId: {}, + }, + }, + }, +}; + +const expectedNewState = { + engine: { + backgroundState: { + TokenRatesController: {}, + }, + }, +}; + +jest.mock('@sentry/react-native', () => ({ + captureException: jest.fn(), +})); +const mockedCaptureException = jest.mocked(captureException); + +describe('Migration #48', () => { + beforeEach(() => { + jest.restoreAllMocks(); + jest.resetAllMocks(); + }); + + const invalidStates = [ + { + state: merge({}, initialRootState, { + engine: null, + }), + errorMessage: + "FATAL ERROR: Migration 48: Invalid engine state error: 'object'", + scenario: 'engine state is invalid', + }, + { + state: merge({}, initialRootState, { + engine: { + backgroundState: null, + }, + }), + errorMessage: + "FATAL ERROR: Migration 48: Invalid engine backgroundState error: 'object'", + scenario: 'backgroundState is invalid', + }, + { + state: merge({}, initialRootState, { + engine: { + backgroundState: { + TokenRatesController: null, + }, + }, + }), + errorMessage: + "FATAL ERROR: Migration 48: Invalid TokenRatesController state error: 'object'", + scenario: 'TokenRatesController state is invalid', + }, + ]; + + for (const { errorMessage, scenario, state } of invalidStates) { + it(`should capture exception if ${scenario}`, async () => { + const newState = await migration(state); + + expect(newState).toStrictEqual(state); + expect(mockedCaptureException).toHaveBeenCalledWith(expect.any(Error)); + expect(mockedCaptureException.mock.calls[0][0].message).toBe( + errorMessage, + ); + }); + } + + it('removes TokenRatesController contractExchangeRates and contractExchangeRatesByChainId properties', async () => { + const newState = await migration(oldState); + expect(newState).toStrictEqual(expectedNewState); + }); +}); diff --git a/app/store/migrations/048.ts b/app/store/migrations/048.ts new file mode 100644 index 00000000000..a2608c190da --- /dev/null +++ b/app/store/migrations/048.ts @@ -0,0 +1,32 @@ +import { captureException } from '@sentry/react-native'; +import { isObject } from '@metamask/utils'; +import { ensureValidState } from './util'; + +/** + * Migration to remove contractExchangeRates and contractExchangeRatesByChainId from the state of TokenRatesController + * + * @param state Persisted Redux state + * @returns + */ +export default function migrate(state: unknown) { + if (!ensureValidState(state, 48)) { + return state; + } + + const tokenRatesControllerState = + state.engine.backgroundState.TokenRatesController; + + if (!isObject(tokenRatesControllerState)) { + captureException( + new Error( + `FATAL ERROR: Migration 48: Invalid TokenRatesController state error: '${typeof tokenRatesControllerState}'`, + ), + ); + return state; + } + + delete tokenRatesControllerState.contractExchangeRates; + delete tokenRatesControllerState.contractExchangeRatesByChainId; + + return state; +} diff --git a/app/store/migrations/index.ts b/app/store/migrations/index.ts index 27a5a71969e..9e1131237fd 100644 --- a/app/store/migrations/index.ts +++ b/app/store/migrations/index.ts @@ -47,6 +47,8 @@ import migration43 from './043'; import migration44 from './044'; import migration45 from './045'; import migration46 from './046'; +import migration47 from './047'; +import migration48 from './048'; type MigrationFunction = (state: unknown) => unknown; type AsyncMigrationFunction = (state: unknown) => Promise; @@ -106,6 +108,8 @@ export const migrationList: MigrationsList = { 44: migration44, 45: migration45, 46: migration46, + 47: migration47, + 48: migration48, }; // Enable both synchronous and asynchronous migrations diff --git a/app/util/string/index.test.ts b/app/util/string/index.test.ts new file mode 100644 index 00000000000..bb3e270f2c1 --- /dev/null +++ b/app/util/string/index.test.ts @@ -0,0 +1,105 @@ +import { + parseTypedSignDataMessage, + sanitizeString, + stripMultipleNewlines, +} from '.'; + +describe('string utils', () => { + describe('sanitizeString', () => { + it('should escape all occurences of \u202E in text', async () => { + const result = sanitizeString('test \u202E test \u202E test'); + expect(result).toEqual('test \\u202E test \\u202E test'); + }); + }); + + describe('stripMultipleNewlines', () => { + it('replace multiple newline characters in string with single newline character', async () => { + const result = stripMultipleNewlines( + 'Secure ✅ \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n', + ); + expect(result).toEqual('Secure ✅ \n'); + }); + }); + + describe('parseTypedSignDataMessage', () => { + const typedDataMsg = + '{"domain":{"chainId":97,"name":"Ether Mail","verifyingContract":"0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC","version":"1"},"message":{"contents":"Hello, Bob!","from":{"name":"Cow","wallets":["0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826","0xDeaDbeefdEAdbeefdEadbEEFdeadbeEFdEaDbeeF","0x06195827297c7A80a443b6894d3BDB8824b43896"]},"to":[{"name":"Bob","wallets":["0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB","0xB0BdaBea57B0BDABeA57b0bdABEA57b0BDabEa57","0xB0B0b0b0b0b0B000000000000000000000000000"]}]},"primaryType":"Mail","types":{"EIP712Domain":[{"name":"name","type":"string"},{"name":"version","type":"string"},{"name":"chainId","type":"uint256"},{"name":"verifyingContract","type":"address"}],"Mail":[{"name":"from","type":"Person"},{"name":"to","type":"Person[]"},{"name":"contents","type":"string"}],"Person":[{"name":"name","type":"string"},{"name":"wallets","type":"address[]"}]}}'; + + it('should throw an error if types is undefined', () => { + const typedDataMsgWithoutTypes = + '{"domain":{"chainId":97,"name":"Ether Mail","verifyingContract":"0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC","version":"1"},"message":{"contents":"Hello, Bob!","from":{"name":"Cow","wallets":["0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826","0xDeaDbeefdEAdbeefdEadbEEFdeadbeEFdEaDbeeF","0x06195827297c7A80a443b6894d3BDB8824b43896"]},"to":[{"name":"Bob","wallets":["0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB","0xB0BdaBea57B0BDABeA57b0bdABEA57b0BDabEa57","0xB0B0b0b0b0b0B000000000000000000000000000"]}]},"primaryType":"Mail"}'; + expect(() => parseTypedSignDataMessage(typedDataMsgWithoutTypes)).toThrow( + 'Invalid types definition', + ); + }); + + it('should throw an error if base type is not defined', () => { + const typedSignDataWithoutBaseType = + '{"domain":{"chainId":97,"name":"Ether Mail","verifyingContract":"0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC","version":"1"},"message":{"contents":"Hello, Bob!","from":{"name":"Cow","wallets":["0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826","0xDeaDbeefdEAdbeefdEadbEEFdeadbeEFdEaDbeeF","0x06195827297c7A80a443b6894d3BDB8824b43896"]},"to":[{"name":"Bob","wallets":["0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB","0xB0BdaBea57B0BDABeA57b0bdABEA57b0BDabEa57","0xB0B0b0b0b0b0B000000000000000000000000000"]}]},"types":{"EIP712Domain":[{"name":"name","type":"string"},{"name":"version","type":"string"},{"name":"chainId","type":"uint256"},{"name":"verifyingContract","type":"address"}],"Mail":[{"name":"from","type":"Person"},{"name":"to","type":"Person[]"},{"name":"contents","type":"string"}],"Person":[{"name":"name","type":"string"},{"name":"wallets","type":"address[]"}]}}'; + expect(() => + parseTypedSignDataMessage(typedSignDataWithoutBaseType), + ).toThrow('Invalid primary type definition'); + }); + + it('should return ignore message data with unknown types and trim new lines', () => { + const result = parseTypedSignDataMessage(typedDataMsg); + expect(result).toStrictEqual({ + value: { + contents: { value: 'Hello, Bob!', type: 'string' }, + from: { + value: { + name: { value: 'Cow', type: 'string' }, + wallets: { + value: [ + { + value: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826', + type: 'address', + }, + { + value: '0xDeaDbeefdEAdbeefdEadbEEFdeadbeEFdEaDbeeF', + type: 'address', + }, + { + value: '0x06195827297c7A80a443b6894d3BDB8824b43896', + type: 'address', + }, + ], + type: 'address[]', + }, + }, + type: 'Person', + }, + to: { + value: [ + { + value: { + name: { value: 'Bob', type: 'string' }, + wallets: { + value: [ + { + value: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', + type: 'address', + }, + { + value: '0xB0BdaBea57B0BDABeA57b0bdABEA57b0BDabEa57', + type: 'address', + }, + { + value: '0xB0B0b0b0b0b0B000000000000000000000000000', + type: 'address', + }, + ], + type: 'address[]', + }, + }, + type: 'Person', + }, + ], + type: 'Person[]', + }, + }, + type: 'Mail', + }); + }); + }); +}); diff --git a/app/util/string/index.text.ts b/app/util/string/index.text.ts deleted file mode 100644 index d17ad79f806..00000000000 --- a/app/util/string/index.text.ts +++ /dev/null @@ -1,12 +0,0 @@ -import sanitizeString from '.'; - -describe('sanitizeString', () => { - it('should escape all occurences of \u202E in text', async () => { - const result = sanitizeString('test \u202E test \u202E test'); - expect(result).toEqual('test \\u202E test \\u202E test'); - }); - it('should return a non-string value as it is', async () => { - const result = sanitizeString({ test: 'test \u202E test \u202E test' }); - expect(result.test).toEqual('test \u202E test \u202E test'); - }); -}); diff --git a/app/util/string/index.ts b/app/util/string/index.ts index 8ab0fc357c6..565a5b1ba41 100644 --- a/app/util/string/index.ts +++ b/app/util/string/index.ts @@ -3,12 +3,10 @@ import { isString } from '../lodash'; /** * The method escape RTL character in string * - * @param {any} str + * @param {string} str * @returns {(string|*)} escaped string or original param value */ -// TODO: Replace "any" with type -// eslint-disable-next-line @typescript-eslint/no-explicit-any -export default (str: any): any => { +export const sanitizeString = (str: string): string => { if (!str) { return str; } @@ -18,3 +16,141 @@ export default (str: any): any => { // Ref: https://stackoverflow.com/questions/69297024/why-is-string-replaceall-not-a-function-on-android-react-native return str.split('\u202E').join('\\u202E'); }; + +export const stripMultipleNewlines = (str: string): string => { + if (!str || typeof str !== 'string') { + return str; + } + return str.replace(/\n+/g, '\n'); +}; + +const solidityTypes = () => { + const types = [ + 'bool', + 'address', + 'string', + 'bytes', + 'int', + 'uint', + 'fixed', + 'ufixed', + ]; + + const ints = Array.from(new Array(32)).map( + (_, index) => `int${(index + 1) * 8}`, + ); + const uints = Array.from(new Array(32)).map( + (_, index) => `uint${(index + 1) * 8}`, + ); + const bytes = Array.from(new Array(32)).map( + (_, index) => `bytes${index + 1}`, + ); + + const fixedM = Array.from(new Array(32)).map( + (_, index) => `fixed${(index + 1) * 8}`, + ); + const ufixedM = Array.from(new Array(32)).map( + (_, index) => `ufixed${(index + 1) * 8}`, + ); + const fixed = Array.from(new Array(80)).map((_, index) => + fixedM.map((aFixedM) => `${aFixedM}x${index + 1}`), + ); + const ufixed = Array.from(new Array(80)).map((_, index) => + ufixedM.map((auFixedM) => `${auFixedM}x${index + 1}`), + ); + + return [ + ...types, + ...ints, + ...uints, + ...bytes, + ...fixed.flat(), + ...ufixed.flat(), + ]; +}; + +const SOLIDITY_TYPES = solidityTypes(); + +const stripArrayType = (potentialArrayType: string) => + potentialArrayType.replace(/\[[[0-9]*\]*/gu, ''); + +const stripOneLayerofNesting = (potentialArrayType: string) => + potentialArrayType.replace(/\[(\d*)\]/u, ''); + +const isArrayType = (potentialArrayType: string) => + potentialArrayType.match(/\[[[0-9]*\]*/u) !== null; + +const isSolidityType = (type: string) => SOLIDITY_TYPES.includes(type); + +interface BaseType { + name: string; + type: string; +} + +type FieldValue = string | string[] | Record; + +interface ValueType { + value: FieldValue | ValueType[]; + type: string; +} + +const sanitizeMessage = ( + message: FieldValue, + primaryType: string, + types: Record, +): ValueType => { + if (!types) { + throw new Error(`Invalid types definition`); + } + + // Primary type can be an array. + const isArray = primaryType && isArrayType(primaryType); + if (isArray) { + return { + value: (message as string[]).map( + (value: string): ValueType => + sanitizeMessage(value, stripOneLayerofNesting(primaryType), types), + ), + type: primaryType, + }; + } else if (isSolidityType(primaryType)) { + return { + value: stripMultipleNewlines(message as string), + type: primaryType, + }; + } + + // If not, assume to be struct + const baseType = isArray ? stripArrayType(primaryType) : primaryType; + + const baseTypeDefinitions = types[baseType]; + if (!baseTypeDefinitions) { + throw new Error(`Invalid primary type definition`); + } + + const sanitizedStruct = {}; + const msgKeys = Object.keys(message); + msgKeys.forEach((msgKey: string) => { + const definedType: BaseType | undefined = Object.values( + baseTypeDefinitions, + ).find( + (baseTypeDefinition: BaseType) => baseTypeDefinition.name === msgKey, + ); + + if (!definedType) { + return; + } + + (sanitizedStruct as Record)[msgKey] = sanitizeMessage( + (message as Record)[msgKey], + definedType.type, + types, + ); + }); + return { value: sanitizedStruct, type: primaryType }; +}; + +export const parseTypedSignDataMessage = (dataToParse: string) => { + const { message, primaryType, types } = JSON.parse(dataToParse); + return sanitizeMessage(message, primaryType, types); +}; diff --git a/app/util/test/accountsControllerTestUtils.ts b/app/util/test/accountsControllerTestUtils.ts index ce95a95c1a9..e044766e275 100644 --- a/app/util/test/accountsControllerTestUtils.ts +++ b/app/util/test/accountsControllerTestUtils.ts @@ -21,6 +21,7 @@ export function createMockInternalAccount( id: createMockUuidFromAddress(address), metadata: { name: nickname, + importTime: 1684232000456, keyring: { type: 'HD Key Tree', }, diff --git a/app/util/test/initial-background-state.json b/app/util/test/initial-background-state.json index 3a7ed6c5c84..d15e9fd0a7d 100644 --- a/app/util/test/initial-background-state.json +++ b/app/util/test/initial-background-state.json @@ -126,8 +126,7 @@ "contractBalances": {} }, "TokenRatesController": { - "contractExchangeRates": {}, - "contractExchangeRatesByChainId": {} + "marketData":{} }, "TransactionController": { "lastFetchedBlockNumbers": {}, diff --git a/app/util/transactions/index.js b/app/util/transactions/index.js index 87eefbe2dcc..670b57c606f 100644 --- a/app/util/transactions/index.js +++ b/app/util/transactions/index.js @@ -1188,7 +1188,7 @@ export const parseTransactionEIP1559 = ( }); const tokenAmount = renderFromTokenMinimalUnit(rawAmountString, decimals); - const exchangeRate = contractExchangeRates[address]; + const exchangeRate = contractExchangeRates[address]?.price; [ renderableTotalMinNative, @@ -1335,7 +1335,7 @@ export const parseTransactionLegacy = ( }); const transferValue = renderFromTokenMinimalUnit(rawAmountString, decimals); const transactionValue = `${transferValue} ${symbol}`; - const exchangeRate = contractExchangeRates[address]; + const exchangeRate = contractExchangeRates?.[address]?.price; const transactionFeeFiatNumber = weiToFiatNumber( weiTransactionFee, conversionRate, diff --git a/bitrise.yml b/bitrise.yml index ef7576640ed..85435877251 100644 --- a/bitrise.yml +++ b/bitrise.yml @@ -117,6 +117,8 @@ stages: workflows: - run_tag_smoke_accounts_ios: {} - run_tag_smoke_accounts_android: {} + - run_tag_smoke_assets_ios: {} + - run_tag_smoke_assets_android: {} - run_tag_smoke_confirmations_ios: {} - run_tag_smoke_confirmations_android: {} - run_tag_smoke_swaps_ios: {} @@ -139,6 +141,8 @@ stages: - run_tag_smoke_confirmations_android: {} - run_tag_smoke_accounts_ios: {} - run_tag_smoke_accounts_android: {} + - run_tag_smoke_assets_ios: {} + - run_tag_smoke_assets_android: {} - run_tag_smoke_swaps_ios: {} - run_tag_smoke_swaps_android: {} - run_tag_smoke_core_ios: {} @@ -445,8 +449,8 @@ workflows: machine_type_id: elite-xl envs: - PRODUCTION_APP_URL: 'bs://ba40e5b7b4210a06c659b5c6818a3efec2624513' # Last production's QA build - - PRODUCTION_BUILD_VERSION_NAME: 7.22.0 - - PRODUCTION_BUILD_VERSION_NUMBER: 1325 + - PRODUCTION_BUILD_VERSION_NAME: 7.24.3 + - PRODUCTION_BUILD_VERSION_NUMBER: 1351 - CUCUMBER_TAG_EXPRESSION: '@upgrade and @androidApp' - PRODUCTION_BUILD_STRING: 'MetaMask-QA v$PRODUCTION_BUILD_VERSION_NAME ($PRODUCTION_BUILD_VERSION_NUMBER)' - NEW_BUILD_STRING: 'MetaMask-QA v$VERSION_NAME ($VERSION_NUMBER)' @@ -470,6 +474,22 @@ workflows: - TEST_SUITE_TAG: '.*SmokeAccounts.*' after_run: - android_e2e_test + run_tag_smoke_assets_ios: + envs: + - TEST_SUITE_FOLDER: './e2e/specs/assets/*' + - TEST_SUITE_TAG: '.*SmokeAssets.*' + after_run: + - ios_e2e_test + run_tag_smoke_assets_android: + meta: + bitrise.io: + stack: linux-docker-android-20.04 + machine_type_id: elite-xl + envs: + - TEST_SUITE_FOLDER: './e2e/specs/assets/*' + - TEST_SUITE_TAG: '.*SmokeAssets.*' + after_run: + - android_e2e_test run_tag_smoke_confirmations_ios: envs: - TEST_SUITE_FOLDER: './e2e/specs/confirmations/*' @@ -1381,16 +1401,16 @@ app: PROJECT_LOCATION_IOS: ios - opts: is_expand: false - VERSION_NAME: 7.24.2 + VERSION_NAME: 7.24.3 - opts: is_expand: false - VERSION_NUMBER: 1348 + VERSION_NUMBER: 1351 - opts: is_expand: false - FLASK_VERSION_NAME: 7.24.2 + FLASK_VERSION_NAME: 7.24.3 - opts: is_expand: false - FLASK_VERSION_NUMBER: 1348 + FLASK_VERSION_NUMBER: 1351 - opts: is_expand: false ANDROID_APK_LINK: '' diff --git a/e2e/fixtures/fixture-builder.js b/e2e/fixtures/fixture-builder.js index 4ed0bc8e979..d71be2dddb8 100644 --- a/e2e/fixtures/fixture-builder.js +++ b/e2e/fixtures/fixture-builder.js @@ -302,7 +302,7 @@ class FixtureBuilder { contractBalances: {}, }, TokenRatesController: { - contractExchangeRates: {}, + marketData: {}, }, TokensController: { tokens: [], @@ -744,6 +744,21 @@ class FixtureBuilder { return this; } + withKeyringController() { + merge(this.fixture.state.engine.backgroundState.KeyringController, { + keyrings: [ + { + type: 'HD Key Tree', + accounts: ['0x37cc5ef6bfe753aeaf81f945efe88134b238face'], + }, + { type: 'QR Hardware Wallet Device', accounts: [] }, + ], + vault: + '{"cipher":"T+MXWPPwXOh8RLxpryUuoFCObwXqNQdwak7FafAoVeXOehhpuuUDbjWiHkeVs9slsy/uzG8z+4Va+qyz4dlRnd/Gvc/2RbHTAb/LG1ECk1rvLZW23JPGkBBVAu36FNGCTtT+xrF4gRzXPfIBVAAgg40YuLJWkcfVty6vGcHr3R3/9gpsqs3etrF5tF4tHYWPEhzhhx6HN6Tr4ts3G9sqgyEhyxTLCboAYWp4lsq2iTEl1vQ6T/UyBRNhfDj8RyQMF6hwkJ0TIq2V+aAYkr5NJguBBSi0YKPFI/SGLrin9/+d66gcOSFhIH0GhUbez3Yf54852mMtvOH8Vj7JZc664ukOvEdJIpvCw1CbtA9TItyVApkjQypLtE+IdV3sT5sy+v0mK7Xc054p6+YGiV8kTiTG5CdlI4HkKvCOlP9axwXP0aRwc4ffsvp5fKbnAVMf9+otqmOmlA5nCKdx4FOefTkr/jjhMlTGV8qUAJ2c6Soi5X02fMcrhAfdUtFxtUqHovOh3KzOe25XhjxZ6KCuix8OZZiGtbNDu3xJezPc3vzkTFwF75ubYozLDvw8HzwI+D5Ifn0S3q4/hiequ6NGiR3Dd0BIhWODSvFzbaD7BKdbgXhbJ9+3FXFF9Xkp74msFp6o7nLsx02ywv/pmUNqQhwtVBfoYhcFwqZZQlOPKcH8otguhSvZ7dPgt7VtUuf8gR23eAV4ffVsYK0Hll+5n0nZztpLX4jyFZiV/kSaBp+D2NZM2dnQbsWULKOkjo/1EpNBIjlzjXRBg5Ui3GgT3JXUDx/2GmJXceacrbMcos3HC2yfxwUTXC+yda4IrBx/81eYb7sIjEVNxDuoBxNdRLKoxwmAJztxoQLF3gRexS45QKoFZZ0kuQ9MqLyY6HDK","iv":"3271713c2b35a7c246a2a9b263365c3d","keyMetadata":{"algorithm":"PBKDF2","params":{"iterations":5000}},"lib":"original","salt":"l4e+sn/jdsaofDWIB/cuGQ=="}', + }); + return this; + } + /** * Build and return the fixture object. * @returns {Object} - The built fixture object. diff --git a/e2e/pages/AccountListView.js b/e2e/pages/AccountListView.js index 7d8068fd9ad..2e35ffd726f 100644 --- a/e2e/pages/AccountListView.js +++ b/e2e/pages/AccountListView.js @@ -49,7 +49,7 @@ export default class AccountListView { static async isAccount2VisibleAtIndex(index) { await expect( element(by.id(CellModalSelectorsIDs.BASE_TITLE)).atIndex(index), - ).toHaveText('Account 2'); + ).not.toHaveText('Account 1'); } static async accountNameNotVisible() { diff --git a/e2e/pages/CommonView.js b/e2e/pages/CommonView.js index 53a48ace4db..bd7a985e859 100644 --- a/e2e/pages/CommonView.js +++ b/e2e/pages/CommonView.js @@ -1,9 +1,6 @@ import Matchers from '../utils/Matchers'; import Gestures from '../utils/Gestures'; -import { - CommonSelectorsIDs, - CommonSelectorsText, -} from '../selectors/Common.selectors'; +import { CommonSelectorsIDs } from '../selectors/Common.selectors'; class CommonView { get okAlertByText() { @@ -14,18 +11,10 @@ class CommonView { return Matchers.getElementByID(CommonSelectorsIDs.BACK_ARROW_BUTTON); } - get toast() { - return Matchers.getElementByID(CommonSelectorsIDs.TOAST_NOTIFICATION_TITLE); - } - get errorMessage() { return Matchers.getElementByID(CommonSelectorsIDs.ERROR_MESSAGE); } - get disconnectedAccountsText() { - return Matchers.getElementByText(CommonSelectorsText.TOAST_REVOKE_ACCOUNTS); - } - async tapBackButton() { await Gestures.waitAndTap(this.backButton); } diff --git a/e2e/pages/modals/ToastModal.js b/e2e/pages/modals/ToastModal.js new file mode 100644 index 00000000000..8d96ec74310 --- /dev/null +++ b/e2e/pages/modals/ToastModal.js @@ -0,0 +1,26 @@ +import { + ToastSelectorsIDs, + ToastSelectorsText, +} from '../../selectors/Modals/ToastModal.selectors'; +import Gestures from '../../utils/Gestures'; +import Matchers from '../../utils/Matchers'; + +class ToastModal { + get container() { + return Matchers.getElementByID(ToastSelectorsIDs.CONTAINER); + } + + get notificationTitle() { + return Matchers.getElementByID(ToastSelectorsIDs.NOTIFICATION_TITLE); + } + + get toastCloseButton() { + return Matchers.getElementByText(ToastSelectorsText.CLOSE_BUTTON); + } + + async tapToastCloseButton() { + await Gestures.waitAndTap(this.toastCloseButton); + } +} + +export default new ToastModal(); diff --git a/e2e/selectors/Common.selectors.js b/e2e/selectors/Common.selectors.js index a340b1a8664..797c8df89f2 100644 --- a/e2e/selectors/Common.selectors.js +++ b/e2e/selectors/Common.selectors.js @@ -5,7 +5,6 @@ export const CommonSelectorsIDs = { BACK_ARROW_BUTTON: 'back-arrow-button', CONNECT_BUTTON: 'connect-button', CANCEL_BUTTON: 'cancel-button', - TOAST_NOTIFICATION_TITLE: 'notification-title', NOTIFICATION_CONFIRM_BUTTON: 'confirm-notification-button', EDIT_CONTACT_BACK_BUTTON: 'edit-contact-back-button', CONFIRM_TXN_EDIT_BUTTON: 'confirm-txn-edit-button', @@ -20,7 +19,5 @@ export const CommonSelectorsIDs = { export const CommonSelectorsText = { OK_ALERT_BUTTON: enContent.template_confirmation.ok, CANCEL_BUTTON: enContent.template_confirmation.cancel, - TOAST_REVOKE_ACCOUNTS: enContent.toast.revoked_all, - TOAST_CONNECTED_ACCOUNTS: enContent.toast.connected_and_active, YES_ALERT_BUTTON: enContent.drawer.lock_ok, }; diff --git a/e2e/selectors/Modals/ToastModal.selectors.js b/e2e/selectors/Modals/ToastModal.selectors.js new file mode 100644 index 00000000000..285f8b0a031 --- /dev/null +++ b/e2e/selectors/Modals/ToastModal.selectors.js @@ -0,0 +1,10 @@ +import enContent from '../../../locales/languages/en.json'; + +export const ToastSelectorsText = { + CLOSE_BUTTON: enContent.privacy_policy.toast_action_button, +}; + +export const ToastSelectorsIDs = { + CONTAINER: 'toast', + NOTIFICATION_TITLE: 'notification-title', +}; diff --git a/e2e/specs/assets/import-tokens.spec.js b/e2e/specs/assets/import-tokens.spec.js index aa87e42f14d..f85b160f879 100644 --- a/e2e/specs/assets/import-tokens.spec.js +++ b/e2e/specs/assets/import-tokens.spec.js @@ -1,5 +1,5 @@ 'use strict'; -import { SmokeCore } from '../../tags'; +import { SmokeAssets } from '../../tags'; import TestHelpers from '../../helpers'; import WalletView from '../../pages/WalletView'; import ImportTokensView from '../../pages/ImportTokensView'; @@ -16,7 +16,7 @@ import ConfirmAddAssetView from '../../pages/ConfirmAddAsset'; const fixtureServer = new FixtureServer(); -describe(SmokeCore('Import Tokens'), () => { +describe(SmokeAssets('Import Tokens'), () => { beforeAll(async () => { await TestHelpers.reverseServerPort(); const fixture = new FixtureBuilder().build(); diff --git a/e2e/specs/assets/token-detection-import-all.spec.js b/e2e/specs/assets/token-detection-import-all.spec.js index 1beb7f71a14..b13a2c42593 100644 --- a/e2e/specs/assets/token-detection-import-all.spec.js +++ b/e2e/specs/assets/token-detection-import-all.spec.js @@ -1,11 +1,11 @@ 'use strict'; import { importWalletWithRecoveryPhrase } from '../../viewHelper'; -import { SmokeCore } from '../../tags'; +import { SmokeAssets } from '../../tags'; import WalletView from '../../pages/WalletView'; import DetectedTokensView from '../../pages/wallet/DetectedTokensView'; import Assertions from '../../utils/Assertions'; -describe(SmokeCore('Import all tokens detected'), () => { +describe(SmokeAssets('Import all tokens detected'), () => { beforeAll(async () => { await device.launchApp(); }); diff --git a/e2e/specs/browser/browser-tests.spec.js b/e2e/specs/browser/browser-tests.spec.js index 8ffdfd76f0c..6e0204ece86 100644 --- a/e2e/specs/browser/browser-tests.spec.js +++ b/e2e/specs/browser/browser-tests.spec.js @@ -60,10 +60,10 @@ describe(SmokeCore('Browser Tests'), () => { await Browser.tapOptionsButton(); await Browser.tapAddToFavoritesButton(); - await Assertions.checkIfVisible(await AddBookmarkView.container); + await Assertions.checkIfVisible(AddBookmarkView.container); await AddBookmarkView.tapAddBookmarksButton(); - await Assertions.checkIfNotVisible(await AddBookmarkView.container); + await Assertions.checkIfNotVisible(AddBookmarkView.container); }); it('should tap on the test dapp in favorites on the home page', async () => { diff --git a/e2e/specs/onboarding/onboarding-wizard-opt-in.spec.js b/e2e/specs/onboarding/onboarding-wizard-opt-in.spec.js index ae981ef578e..4ae17644ef0 100644 --- a/e2e/specs/onboarding/onboarding-wizard-opt-in.spec.js +++ b/e2e/specs/onboarding/onboarding-wizard-opt-in.spec.js @@ -83,7 +83,7 @@ describe( // dealing with flakiness on bitrise. await TestHelpers.delay(2500); try { - await WhatsNewModal.isVisible(); + await Assertions.checkIfVisible(WhatsNewModal.container); await WhatsNewModal.tapCloseButton(); } catch { /* eslint-disable no-console */ @@ -95,15 +95,13 @@ describe( // dealing with flakiness on bitrise. await TestHelpers.delay(1000); try { - await Assertions.checkIfVisible( - await ExperienceEnhancerModal.container, - ); + await Assertions.checkIfVisible(ExperienceEnhancerModal.container); await ExperienceEnhancerModal.tapIagree(); } catch { console.log('The marketing consent sheet is not visible'); } try { - await WhatsNewModal.isVisible(); + await Assertions.checkIfVisible(WhatsNewModal.container); await WhatsNewModal.tapCloseButton(); } catch { /* eslint-disable no-console */ diff --git a/e2e/specs/permission-systems/permission-system-delete-wallet.spec.js b/e2e/specs/permission-systems/permission-system-delete-wallet.spec.js index 8bfafe1f0d0..2ba00efa9a9 100644 --- a/e2e/specs/permission-systems/permission-system-delete-wallet.spec.js +++ b/e2e/specs/permission-systems/permission-system-delete-wallet.spec.js @@ -20,7 +20,7 @@ import MetaMetricsOptIn from '../../pages/Onboarding/MetaMetricsOptInView'; import ProtectYourWalletModal from '../../pages/modals/ProtectYourWalletModal'; import OnboardingSuccessView from '../../pages/Onboarding/OnboardingSuccessView'; import Assertions from '../../utils/Assertions'; -import CommonView from '../../pages/CommonView'; +import ToastModal from '../../pages/modals/ToastModal'; const PASSWORD = '12345678'; @@ -71,9 +71,9 @@ describe( await TestHelpers.delay(2000); await Assertions.checkIfVisible(OnboardingView.container); if (device.getPlatform() === 'ios') { - await Assertions.checkIfVisible(await CommonView.toast); + await Assertions.checkIfVisible(ToastModal.notificationTitle); } - await Assertions.checkIfNotVisible(await CommonView.toast); + await Assertions.checkIfNotVisible(ToastModal.notificationTitle); await OnboardingView.tapCreateWallet(); // Create new wallet diff --git a/e2e/specs/permission-systems/permission-system-revoke-single-account.spec.js b/e2e/specs/permission-systems/permission-system-revoke-single-account.spec.js index afc70094d8f..3051404f787 100644 --- a/e2e/specs/permission-systems/permission-system-revoke-single-account.spec.js +++ b/e2e/specs/permission-systems/permission-system-revoke-single-account.spec.js @@ -9,7 +9,7 @@ import FixtureBuilder from '../../fixtures/fixture-builder'; import { withFixtures } from '../../fixtures/fixture-helper'; import { loginToApp } from '../../viewHelper'; import Assertions from '../../utils/Assertions'; -import CommonView from '../../pages/CommonView'; +import ToastModal from '../../pages/modals/ToastModal'; describe(SmokeCore('Revoke Single Account after connecting to a dapp'), () => { beforeAll(async () => { @@ -37,7 +37,7 @@ describe(SmokeCore('Revoke Single Account after connecting to a dapp'), () => { await TestHelpers.delay(5500); // this is because the toast is delayed. await ConnectedAccountsModal.tapDisconnectAllButton(); - await Assertions.checkIfNotVisible(await CommonView.toast); + await Assertions.checkIfNotVisible(ToastModal.notificationTitle); await Browser.tapNetworkAvatarButtonOnBrowser(); await Assertions.checkIfNotVisible(ConnectedAccountsModal.title); diff --git a/e2e/specs/permission-systems/permission-system-revoking-multiple-accounts.spec.js b/e2e/specs/permission-systems/permission-system-revoking-multiple-accounts.spec.js index 6b67584352a..c92f296ea36 100644 --- a/e2e/specs/permission-systems/permission-system-revoking-multiple-accounts.spec.js +++ b/e2e/specs/permission-systems/permission-system-revoking-multiple-accounts.spec.js @@ -3,12 +3,10 @@ import TestHelpers from '../../helpers'; import Browser from '../../pages/Browser/BrowserView'; import AccountListView from '../../pages/AccountListView'; import TabBarComponent from '../../pages/TabBarComponent'; +import ToastModal from '../../pages/modals/ToastModal'; import ConnectedAccountsModal from '../../pages/modals/ConnectedAccountsModal'; - -import CommonView from '../../pages/CommonView'; - -import { loginToApp } from '../../viewHelper'; import NetworkListModal from '../../pages/modals/NetworkListModal'; +import { loginToApp } from '../../viewHelper'; import FixtureBuilder from '../../fixtures/fixture-builder'; import { withFixtures } from '../../fixtures/fixture-helper'; import Assertions from '../../utils/Assertions'; @@ -41,7 +39,7 @@ describe('Connecting to multiple dapps and revoking permission on one but stayin await Assertions.checkIfVisible(ConnectedAccountsModal.title); await TestHelpers.delay(2000); - await Assertions.checkIfNotVisible(CommonView.toast); + await Assertions.checkIfNotVisible(ToastModal.notificationTitle); await ConnectedAccountsModal.tapConnectMoreAccountsButton(); await AccountListView.tapAddAccountButton(); await AccountListView.tapCreateAccountButton(); @@ -54,7 +52,7 @@ describe('Connecting to multiple dapps and revoking permission on one but stayin await ConnectedAccountsModal.tapPermissionsButton(); await TestHelpers.delay(1500); await ConnectedAccountsModal.tapDisconnectAllButton(); - await Assertions.checkIfNotVisible(await CommonView.toast); + await Assertions.checkIfNotVisible(ToastModal.notificationTitle); await Browser.tapNetworkAvatarButtonOnBrowser(); await Assertions.checkIfNotVisible(ConnectedAccountsModal.title); diff --git a/e2e/specs/quarantine/import-nft.failing.js b/e2e/specs/quarantine/import-nft.failing.js index 6e352a6cd23..68eca90dcf0 100644 --- a/e2e/specs/quarantine/import-nft.failing.js +++ b/e2e/specs/quarantine/import-nft.failing.js @@ -1,5 +1,5 @@ 'use strict'; -import { SmokeCore } from '../../tags'; +import { SmokeAssets } from '../../tags'; import TestHelpers from '../../helpers'; import WalletView from '../../pages/WalletView'; import AddCustomTokenView from '../../pages/AddCustomTokenView'; @@ -11,7 +11,7 @@ import { import { SMART_CONTRACTS } from '../../../app/util/test/smart-contracts'; import FixtureBuilder from '../../fixtures/fixture-builder'; -describe(SmokeCore('Import NFT'), () => { +describe(SmokeAssets('Import NFT'), () => { beforeAll(async () => { jest.setTimeout(150000); }); diff --git a/e2e/specs/swaps/swap-action-regression.spec.js b/e2e/specs/swaps/swap-action-regression.spec.js index 7d9314eddc2..9b088e849f5 100644 --- a/e2e/specs/swaps/swap-action-regression.spec.js +++ b/e2e/specs/swaps/swap-action-regression.spec.js @@ -87,13 +87,20 @@ describe(Regression('Multiple Swaps from Actions'), () => { sourceTokenSymbol, destTokenSymbol, ); - await Assertions.checkIfVisible(DetailsModal.title); - await Assertions.checkIfElementToHaveText( - DetailsModal.title, - DetailsModal.generateExpectedTitle(sourceTokenSymbol, destTokenSymbol), - ); - await Assertions.checkIfVisible(DetailsModal.statusConfirmed); - await DetailsModal.tapOnCloseIcon(); + + if (device.getPlatform() === 'android') { + await Assertions.checkIfVisible(DetailsModal.title); + await Assertions.checkIfElementToHaveText( + DetailsModal.title, + DetailsModal.generateExpectedTitle( + sourceTokenSymbol, + destTokenSymbol, + ), + ); + await Assertions.checkIfVisible(DetailsModal.statusConfirmed); + await DetailsModal.tapOnCloseIcon(); + await Assertions.checkIfNotVisible(DetailsModal.title); + } }, ); }); diff --git a/e2e/specs/wallet/request-token-flow.spec.js b/e2e/specs/wallet/request-token-flow.spec.js index 68a9e6f4089..36e647c59ee 100644 --- a/e2e/specs/wallet/request-token-flow.spec.js +++ b/e2e/specs/wallet/request-token-flow.spec.js @@ -25,7 +25,7 @@ const fixtureServer = new FixtureServer(); describe(SmokeCore('Request Token Flow with Unprotected Wallet'), () => { beforeAll(async () => { await TestHelpers.reverseServerPort(); - const fixture = new FixtureBuilder().build(); + const fixture = new FixtureBuilder().withKeyringController().build(); fixture.state.user.seedphraseBackedUp = false; await startFixtureServer(fixtureServer); await loadFixture(fixtureServer, { fixture }); diff --git a/e2e/tags.js b/e2e/tags.js index 9a441bcc1b8..8e78b934e57 100644 --- a/e2e/tags.js +++ b/e2e/tags.js @@ -5,6 +5,7 @@ const tags = { smokeConfirmations: 'SmokeConfirmations', SmokeSwaps: 'SmokeSwaps', SmokeRest: 'SmokeRest', + smokeAssets: 'smokeAssets', }; const Regression = (testName) => `${tags.regression} ${testName}`; @@ -13,5 +14,13 @@ const SmokeCore = (testName) => `${tags.smokeCore} ${testName}`; const SmokeConfirmations = (testName) => `${tags.smokeConfirmations} ${testName}`; const SmokeSwaps = (testName) => `${tags.SmokeSwaps} ${testName}`; +const SmokeAssets = (testName) => `${tags.smokeAssets} ${testName}`; -export { Regression, SmokeAccounts, SmokeCore, SmokeConfirmations, SmokeSwaps }; +export { + Regression, + SmokeAccounts, + SmokeCore, + SmokeConfirmations, + SmokeSwaps, + SmokeAssets, +}; diff --git a/e2e/viewHelper.js b/e2e/viewHelper.js index cb72e8b0621..eb016bb6ff6 100644 --- a/e2e/viewHelper.js +++ b/e2e/viewHelper.js @@ -28,13 +28,9 @@ import LoginView from './pages/LoginView'; import { getGanachePort } from './fixtures/utils'; import Assertions from './utils/Assertions'; import { CustomNetworks } from './resources/networks.e2e'; -import enContent from '../locales/languages/en.json'; +import ToastModal from './pages/modals/ToastModal'; const LOCALHOST_URL = `http://localhost:${getGanachePort()}/`; - -// detox on ios does not have a clean way of interacting with webview elements. You would need to tap by coordinates -export const testDappConnectButtonCooridinates = { x: 170, y: 280 }; -export const testDappSendEIP1559ButtonCoordinates = { x: 320, y: 500 }; const validAccount = Accounts.getValidAccount(); export const acceptTermOfUse = async () => { @@ -49,36 +45,37 @@ export const acceptTermOfUse = async () => { }; export const closeOnboardingModals = async () => { /* -These onboarding modals are becoming a bit wild. We need less of these so we dont -have to have all these work arounds in the tests +These onboarding modals are becoming a bit wild. We need less of these so we don't +have to have all these workarounds in the tests */ await TestHelpers.delay(1000); try { - await WhatsNewModal.isVisible(); + await Assertions.checkIfVisible(WhatsNewModal.container); await WhatsNewModal.tapCloseButton(); + await Assertions.checkIfNotVisible(WhatsNewModal.container); } catch { - // + /* eslint-disable no-console */ + + console.log('The whats new modal is not visible'); } // Handle Onboarding wizard try { - await Assertions.checkIfVisible( - await OnboardingWizardModal.stepOneContainer, - ); + await Assertions.checkIfVisible(OnboardingWizardModal.stepOneContainer); await OnboardingWizardModal.tapNoThanksButton(); - await Assertions.checkIfNotVisible( - await OnboardingWizardModal.stepOneContainer, - ); + await Assertions.checkIfNotVisible(OnboardingWizardModal.stepOneContainer); } catch { /* eslint-disable no-console */ console.log('The onboarding modal is not visible'); } + // TODO: Define the correct order of onboarding modals to be displayed try { - await WhatsNewModal.isVisible(); + await Assertions.checkIfVisible(WhatsNewModal.container); await WhatsNewModal.tapCloseButton(); + await Assertions.checkIfNotVisible(WhatsNewModal.container); } catch { /* eslint-disable no-console */ @@ -88,15 +85,17 @@ have to have all these work arounds in the tests try { // Handle Marketing consent modal - await Assertions.checkIfVisible(await ExperienceEnhancerModal.container); + await Assertions.checkIfVisible(ExperienceEnhancerModal.container); await ExperienceEnhancerModal.tapNoThanks(); + await Assertions.checkIfNotVisible(ExperienceEnhancerModal.container); } catch { console.log('The marketing consent modal is not visible'); } + try { - await TestHelpers.waitAndTapText( - enContent.privacy_policy.toast_action_button, - ); + await Assertions.checkIfVisible(ToastModal.container); + await ToastModal.tapToastCloseButton(); + await Assertions.checkIfNotVisible(ToastModal.container); } catch { /* eslint-disable no-undef */ @@ -127,22 +126,7 @@ export const importWalletWithRecoveryPhrase = async () => { // should dismiss the onboarding wizard // dealing with flakiness on bitrise. - await TestHelpers.delay(1000); - await closeOnboardingModals(); - - // should tap on the close button to dismiss the whats new modal - try { - await Assertions.checkIfVisible(WhatsNewModal.container); - await WhatsNewModal.tapCloseButton(); - } catch { - /* eslint-disable no-console */ - console.log('The whats new modal is not visible'); - } finally { - // Handle Marketing consent modal - - await Assertions.checkIfVisible(await ExperienceEnhancerModal.container); - await ExperienceEnhancerModal.tapNoThanks(); - } + await this.closeOnboardingModals(); }; export const CreateNewWallet = async () => { @@ -179,25 +163,9 @@ export const CreateNewWallet = async () => { // 'should dismiss the onboarding wizard' // dealing with flakiness on bitrise. - await TestHelpers.delay(1000); - await closeOnboardingModals(); + await this.closeOnboardingModals(); - // should tap on the close button to dismiss the whats new modal - try { - await Assertions.checkIfVisible(WhatsNewModal.container); - await WhatsNewModal.tapCloseButton(); - } catch { - /* eslint-disable no-console */ console.log( - 'The whats new modal is not visible', - ); - } finally { - // Handle Marketing consent modal - - await Assertions.checkIfVisible(await ExperienceEnhancerModal.container); - await ExperienceEnhancerModal.tapNoThanks(); - } - - // Dismissing the protect your wallet modal + // Dismissing to protect your wallet modal await Assertions.checkIfVisible(ProtectYourWalletModal.collapseWalletModal); await ProtectYourWalletModal.tapRemindMeLaterButton(); await SkipAccountSecurityModal.tapIUnderstandCheckBox(); @@ -219,7 +187,7 @@ export const addLocalhostNetwork = async () => { await NetworkView.typeInNetworkSymbol('ETH\n'); if (device.getPlatform() === 'ios') { - await NetworkView.swipeToRPCTitleAndDismissKeyboard(); // Focus outside of text input field + // await NetworkView.swipeToRPCTitleAndDismissKeyboard(); // Focus outside of text input field await NetworkView.tapRpcNetworkAddButton(); } await TestHelpers.delay(3000); @@ -251,26 +219,5 @@ export const loginToApp = async () => { await LoginView.isVisible(); await LoginView.enterPassword(PASSWORD); - await TestHelpers.delay(2500); - try { - await TestHelpers.waitAndTapText( - enContent.privacy_policy.toast_action_button, - ); - await WhatsNewModal.isVisible(); - await WhatsNewModal.tapCloseButton(); - await Assertions.checkIfVisible(ExperienceEnhancerModal.title); - await ExperienceEnhancerModal.tapNoThanks(); - } catch { - /* eslint-disable no-console */ console.log( - 'The onboarding modals is not visible', - ); - } - // this is not ideal. The whats new modal usually pops up last? - try { - await Assertions.checkIfVisible(WhatsNewModal.container); - await WhatsNewModal.tapCloseButton(); - } catch { - /* eslint-disable no-console */ - console.log('The whats new modal is not visible'); - } + await this.closeOnboardingModals(); }; diff --git a/ios/MetaMask.xcodeproj/project.pbxproj b/ios/MetaMask.xcodeproj/project.pbxproj index 22e4612978a..1ba6e8c3555 100644 --- a/ios/MetaMask.xcodeproj/project.pbxproj +++ b/ios/MetaMask.xcodeproj/project.pbxproj @@ -1207,7 +1207,7 @@ CODE_SIGN_ENTITLEMENTS = MetaMask/MetaMaskDebug.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1348; + CURRENT_PROJECT_VERSION = 1351; DEAD_CODE_STRIPPING = YES; DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_TEAM = 48XVW22RCG; @@ -1244,7 +1244,7 @@ "${inherited}", ); LLVM_LTO = YES; - MARKETING_VERSION = 7.24.2; + MARKETING_VERSION = 7.24.3; ONLY_ACTIVE_ARCH = YES; OTHER_CFLAGS = "$(inherited)"; OTHER_LDFLAGS = ( @@ -1272,7 +1272,7 @@ CODE_SIGN_ENTITLEMENTS = MetaMask/MetaMask.entitlements; CODE_SIGN_IDENTITY = "iPhone Distribution"; CODE_SIGN_STYLE = Manual; - CURRENT_PROJECT_VERSION = 1348; + CURRENT_PROJECT_VERSION = 1351; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = 48XVW22RCG; "DEVELOPMENT_TEAM[sdk=iphoneos*]" = 48XVW22RCG; @@ -1307,7 +1307,7 @@ "${inherited}", ); LLVM_LTO = YES; - MARKETING_VERSION = 7.24.2; + MARKETING_VERSION = 7.24.3; ONLY_ACTIVE_ARCH = NO; OTHER_CFLAGS = "$(inherited)"; OTHER_LDFLAGS = ( @@ -1335,7 +1335,7 @@ CODE_SIGN_ENTITLEMENTS = MetaMask/MetaMaskDebug.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1348; + CURRENT_PROJECT_VERSION = 1351; DEAD_CODE_STRIPPING = YES; DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_TEAM = 48XVW22RCG; @@ -1368,7 +1368,7 @@ ); LIBRARY_SEARCH_PATHS = "$(SDKROOT)/usr/lib/swift$(inherited)"; LLVM_LTO = YES; - MARKETING_VERSION = 7.24.2; + MARKETING_VERSION = 7.24.3; ONLY_ACTIVE_ARCH = YES; OTHER_CFLAGS = "$(inherited)"; OTHER_LDFLAGS = ( @@ -1396,7 +1396,7 @@ CODE_SIGN_ENTITLEMENTS = MetaMask/MetaMask.entitlements; CODE_SIGN_IDENTITY = "iPhone Distribution"; CODE_SIGN_STYLE = Manual; - CURRENT_PROJECT_VERSION = 1348; + CURRENT_PROJECT_VERSION = 1351; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = 48XVW22RCG; "DEVELOPMENT_TEAM[sdk=iphoneos*]" = 48XVW22RCG; @@ -1427,7 +1427,7 @@ ); LIBRARY_SEARCH_PATHS = "$(SDKROOT)/usr/lib/swift$(inherited)"; LLVM_LTO = YES; - MARKETING_VERSION = 7.24.2; + MARKETING_VERSION = 7.24.3; ONLY_ACTIVE_ARCH = NO; OTHER_CFLAGS = "$(inherited)"; OTHER_LDFLAGS = ( @@ -1554,7 +1554,7 @@ CODE_SIGN_ENTITLEMENTS = MetaMask/MetaMaskDebug.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1348; + CURRENT_PROJECT_VERSION = 1351; DEAD_CODE_STRIPPING = YES; DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_TEAM = 48XVW22RCG; @@ -1591,7 +1591,7 @@ "\"$(SRCROOT)/MetaMask/System/Library/Frameworks\"", ); LLVM_LTO = YES; - MARKETING_VERSION = 7.24.2; + MARKETING_VERSION = 7.24.3; ONLY_ACTIVE_ARCH = YES; OTHER_CFLAGS = ( "$(inherited)", @@ -1622,7 +1622,7 @@ CODE_SIGN_ENTITLEMENTS = MetaMask/MetaMask.entitlements; CODE_SIGN_IDENTITY = "iPhone Distribution"; CODE_SIGN_STYLE = Manual; - CURRENT_PROJECT_VERSION = 1348; + CURRENT_PROJECT_VERSION = 1351; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = 48XVW22RCG; "DEVELOPMENT_TEAM[sdk=iphoneos*]" = 48XVW22RCG; @@ -1657,7 +1657,7 @@ "\"$(SRCROOT)/MetaMask/System/Library/Frameworks\"", ); LLVM_LTO = YES; - MARKETING_VERSION = 7.24.2; + MARKETING_VERSION = 7.24.3; ONLY_ACTIVE_ARCH = NO; OTHER_CFLAGS = ( "$(inherited)", diff --git a/locales/languages/de.json b/locales/languages/de.json index cfb790551e4..8fdbf4e4760 100644 --- a/locales/languages/de.json +++ b/locales/languages/de.json @@ -365,17 +365,17 @@ "title": "Empfangen" }, "experience_enhancer_modal": { - "title": "Help us enhance your experience", - "paragraph1a": "In addition to ", - "paragraph1b": ", we'd like to use data (like information from cookies) to learn how you interact with our marketing communications.", + "title": "Helfen Sie uns, Ihr Erlebnis zu verbessern", + "paragraph1a": "Zusätzlich zu ", + "paragraph1b": "möchten wir Daten (z. B. Informationen aus Cookies) verwenden, um zu erfahren, wie Sie mit unserer Marketingkommunikation interagieren.", "link": "MetaMetrics", - "paragraph2": "This helps us personalize what we share with you, like:", - "bullet1": "Latest developments", - "bullet2": "Product features", - "bullet3": "Other relevant promotional materials", - "footer": "Remember, we never sell the data you provide and you can opt out any time.", - "accept": "I agree", - "cancel": "No thanks" + "paragraph2": "Dies hilft uns, das, was wir mit Ihnen teilen, zu personalisieren, wie z. B.:", + "bullet1": "Neueste Entwicklungen", + "bullet2": "Produktmerkmale", + "bullet3": "Andere relevante Werbematerialien", + "footer": "Denken Sie daran, dass wir die von Ihnen bereitgestellten Daten niemals verkaufen und Sie sich jederzeit abmelden können.", + "accept": "Ich stimme zu", + "cancel": "Nein, danke" }, "wallet": { "title": "Wallet", @@ -413,7 +413,7 @@ "no_tokens": "Sie haben keine Tokens!", "no_nfts_yet": "Noch keine NFTs", "nfts_autodetection_title": "NFT-Erkennung", - "nfts_autodetection_desc": "Erlauben Sie MetaMask, NFTs automatisch in OpenSea zu erkennen und in Ihrer MetaMask-Wallet anzuzeigen.", + "nfts_autodetection_desc": "Lassen Sie zu, dass MetaMask NFTs automatisch in Ihrer Wallet erkennt und anzeigt.", "network_details_check": "Überprüfung der Netzwerkangaben", "network_with_chain_id": "Das Netzwerk mit Chain-ID", "chain_list_returned_different_ticker_symbol": "Dieses Token-Symbol stimmt nicht mit dem eingegebenen Netzwerknamen oder der eingegebenen Chain-ID überein. Viele beliebte Tokens verwenden ähnliche Symbole, die Betrüger nutzen können, um Sie dazu zu bringen, ihnen im Gegenzug einen wertvolleren Token zu senden. Überprüfen Sie alles, bevor Sie fortfahren.", @@ -454,7 +454,7 @@ "display_nft_media_cta": "„NFT-Medien anzeigen“ aktivieren", "display_media_nft_warning": "Das Anzeigen von NFT-Medien und -Daten könnte Ihre IT-Adresse an zentralisierte Server weitergeben. Importieren Sie nur dann ein NFT, wenn Sie sich über die damit verbundenen Risiken im Klaren sind.", "nfts_autodetect_title": "Automatische NFT-Erkennung", - "nfts_autodetect_cta": "„Automatische Erkennung von NFTs“ in den Einstellungen aktivieren", + "nfts_autodetect_cta": "Automatische NFT-Erkennung aktivieren", "turn_on_network_check_cta": "Überprüfung der Netzwerkdetails einschalten", "display_nft_media_cta_new_1": "Zur Anzeige eines NFT aktivieren Sie „NFT-Medien anzeigen” in", "display_nft_media_cta_new_2": "Einstellungen > Sicherheit und Datenschutz.", @@ -520,7 +520,7 @@ "description_title": "Helfen Sie uns dabei, MetaMask zu verbessern.", "description_content_1": "Wir würden gerne grundlegende Nutzungsdaten sammeln, um MetaMask zu verbessern. Sie sollten wissen, dass wir die Daten, die Sie uns hier zur Verfügung stellen, niemals verkaufen.", "description_content_2": "Wenn wir Metriken sammeln, wird es immer wie folgt sein ...", - "checkbox": "We'll use this data to learn how you interact with our marketing communications. We may share relavent news (like product features).", + "checkbox": "Wir verwenden diese Daten, um zu erfahren, wie Sie mit unserer Marketingkommunikation umgehen. Wir können relevante Neuigkeiten (wie Produktmerkmale) teilen.", "action_description_1_prefix": "Privat:", "action_description_2_prefix": "Allgemein:", "action_description_3_prefix": "Optional:", @@ -650,7 +650,8 @@ "revoked_all": "Alle Konten widerrufen.", "accounts_connected": "Konten verbunden.", "disconnected": "getrennt.", - "disconnected_all": "Alle Konten wurden getrennt." + "disconnected_all": "Alle Konten wurden getrennt.", + "nft_detection_enabled": "Automatische NFT-Erkennung aktiviert" }, "connect_qr_hardware": { "title": "Eine QR-basierte Hardware-Wallet verknüpfen", @@ -672,7 +673,7 @@ }, "data_collection_modal": { "accept": "Okay", - "content": "You turned off data collection for our marketing purposes. This only applies to this device. If you use MetaMask on other devices, make sure to opt out there as well." + "content": "Sie haben die Datenerhebung für unsere Marketingzwecke deaktiviert. Dies gilt nur für dieses Gerät. Wenn Sie MetaMask auf anderen Geräten verwenden, stellen Sie sicher, dass Sie sich auch dort abmelden." }, "account_selector": { "prev": "ZURÜCK", @@ -845,9 +846,9 @@ "clear_history_desc": "Wählen Sie diese Option, um Ihren gesamten Browser-Verlauf zu löschen.", "clear_cookies_desc": "Wählen Sie diese Option, um die Cookies Ihres Browsers zu löschen.", "metametrics_title": "An MetaMetrics teilnehmen", - "metametrics_description": "Allow MetaMetrics to collect basic usage and diagnostics data to improve our product. You can disable MetaMetrics for this device.", - "data_collection_title": "Data collection for marketing", - "data_collection_description": "We’ll use MetaMetrics to learn how you interact with our marketing communications. We may share relevant news (like product features and other materials).", + "metametrics_description": "Erlauben Sie MetaMetrics, grundlegende Nutzungs- und Diagnosedaten zu sammeln, um unser Produkt zu verbessern. Sie können MetaMetrics für dieses Gerät deaktivieren.", + "data_collection_title": "Datenerhebung für das Marketing", + "data_collection_description": "Wir verwenden MetaMetrics, um zu erfahren, wie Sie mit unserer Marketingkommunikation umgehen. Wir können relevante Neuigkeiten (wie Produktmerkmale und andere Materialien) teilen.", "batch_balance_requests_title": "Kontoguthaben-Anfragen sammeln", "batch_balance_requests_description": "Wir sammeln Konten und fragen bei Infura an, um Ihr Guthaben anzuzeigen. Wenn Sie dies deaktivieren, werden nur aktive Konten abgefragt. Einige dApps funktionieren nicht, wenn Sie Ihre Wallet nicht verbinden.", "third_party_title": "Eingehende Transaktionen erhalten", @@ -888,6 +889,13 @@ "delete": "Löschen", "network_exists": "Dieses Netzwerk wurde bereits hinzugefügt.", "delete_metrics_title": "MetaMetrics-Daten löschen", + "delete_metrics_description_part_one": "Dies löscht historische", + "delete_metrics_description_part_two": "MetaMetrics", + "delete_metrics_description_part_three": "Daten im Zusammenhang mit Ihrer Wallet.", + "delete_metrics_description_before_delete": "Ihre Wallet und Ihre Konten bleiben nach der Löschung dieser Daten genau wie sie jetzt sind. Dieser Prozess kann bis zu 30 Tage in Anspruch nehmen. Lesen Sie unsere", + "delete_metrics_description_after_delete_part_one": "Sie haben diese Aktion eingeleitet am", + "delete_metrics_description_after_delete_part_two": ". Dieser Prozess kann bis zu 30 Tage in Anspruch nehmen. Lesen Sie unsere", + "delete_metrics_description_privacy_policy": "Datenschutzerklärung.", "delete_metrics_button": "MetaMetrics-Daten löschen", "check_status_button": "Status überprüfen", "delete_metrics_confirm_modal_title": "MetaMetrics-Daten löschen?", @@ -990,8 +998,27 @@ "security_alerts": "Sicherheitsbenachrichtigungen", "security_alerts_desc": "Diese Funktion warnt Sie vor bösartigen Aktivitäten, indem sie Ihre Transaktions- und Signaturanfragen lokal überprüft. Führen Sie immer Ihre eigene Prüfung durch, bevor Sie Anfragen genehmigen. Es gibt keine Garantie dafür, dass diese Funktion alle bösartigen Aktivitäten erkennt. Mit der Aktivierung dieser Funktion erklären Sie sich mit den Nutzungsbedingungen des Anbieters einverstanden.", "smart_transactions_opt_in_heading": "Smart Transactions", - "smart_transactions_opt_in_desc": "Schalten Sie Smart Transactions für zuverlässigere und sicherere Transaktionen und anpassbare Gebühren im ETH Mainnet ein.", - "smart_transactions_learn_more": "Erfahren Sie mehr." + "smart_transactions_opt_in_desc": "Schalten Sie Smart Transactions für zuverlässigere und sicherere Transaktionen im Ethereum Mainnet ein.", + "smart_transactions_learn_more": "Erfahren Sie mehr.", + "simulation_details": "Geschätzte Kontostandänderungen", + "simulation_details_description": "Schalten Sie dies ein, um die Kontostandänderungen von Transaktionen zu schätzen, bevor Sie sie bestätigen. Dies ist keine Garantie für das endgültige Ergebnis Ihrer Transaktionen. ", + "simulation_details_learn_more": "Erfahren Sie mehr.", + "aes_crypto_test_form_title": "AES Crypto – Testformular", + "aes_crypto_test_form_description": "Abschnitt, der ausschließlich für E2E-Tests entwickelt wurde. Wenn dies in Ihrer App sichtbar ist, melden Sie dies bitte dem MetaMask-Support." + }, + "aes_crypto_test_form": { + "generate_random_salt": "Zufällige Salt generieren", + "salt_bytes_count": "Salt-Bytes-Anzahl", + "generate": "Generieren", + "generate_encryption_key": "Verschlüsselungsschlüssel aus Passwort generieren", + "password": "Passwort", + "salt": "Salt", + "encrypt_with_key": "Mit Schlüssel verschlüsseln", + "encrypt": "Verschlüsseln", + "encryption_key": "Verschlüsselungsschlüssel", + "data": "Daten", + "decrypt_with_key": "Mit Schlüssel entschlüsseln", + "decrypt": "Entschlüsseln" }, "sdk": { "disconnect_title": "Verbindung mit allen Seiten trennen?", @@ -1172,6 +1199,15 @@ "account_copied_to_clipboard": "Öffentliche Adresse in die Zwischenablage kopiert", "share_public_key": "Teilen meines öffentlichen Schlüssels:" }, + "enable_nft-auto-detection": { + "title": "Automatische NFT-Erkennung aktivieren", + "description": "Erlauben Sie MetaMask, Ihre NFTs mit automatischer Erkennung zu entdecken und anzuzeigen. Das können Sie tun:", + "immediateAccess": "Sofortiger Zugriff auf Ihre NFTs", + "navigate": "Mühelose Navigation durch Ihre digitalen Assets", + "dive": "Verwenden Sie Ihre NFTs sofort", + "allow": "Erlauben", + "notRightNow": "Im Moment nicht" + }, "detected_tokens": { "title": "{{tokenCount}} neues Token gefunden", "title_plural": "{{tokenCount}} neue Tokens gefunden", @@ -1370,10 +1406,12 @@ "approve": "Genehmigen", "allow_to_access": "Genehmigung zum Zugriff erteilen auf Ihr", "allow_to_address_access": "Dieser Adresse Zugriff erteilen auf Ihr(e)", + "allow_to_transfer_all": "Erlauben Sie den Zugriff auf und die Übertragung von all Ihren", "spend_cap": "Ausgabenobergrenzeanfrage für Ihr", "token": "Token", "nft": "NFT", "you_trust_this_site": "Durch Genehmigungserteilung gewähren Sie dem folgenden Drittanbieter Zugriff auf Ihre Gelder.", + "you_trust_this_third_party": "Dies gestattet es Dritten, ohne weitere Benachrichtigung auf Ihre NFTs zuzugreifen und diese zu übertragen, bis Sie dieses Zugriffsrecht widerrufen.", "you_trust_this_address": "Vertrauen Sie dieser Adresse? Wenn Sie diese Genehmigung erteilen, gewähren Sie dieser Adresse Zugriff auf Ihre Gelder.", "edit_permission": "Genehmigung bearbeiten", "edit": "Bearbeiten", @@ -1477,6 +1515,8 @@ "tx_review_transfer_from": "Übertragung von", "tx_review_unknown": "Unbekannte Methode", "tx_review_approve": "Genehmigen", + "tx_review_increase_allowance": "Zulage erhöhen", + "tx_review_set_approval_for_all": "Erlaubnis für alle erteilen", "sent_ether": "Ether senden", "self_sent_ether": "Senden Sie sich selbst Ether.", "received_ether": "Ether empfangen", @@ -1498,11 +1538,17 @@ "smart_contract_interaction": "Smart Contract-Interaktion", "swaps_transaction": "Swaps-Transaktion", "approve": "Genehmigen", + "increase_allowance": "Zulage erhöhen", + "set_approval_for_all": "Erlaubnis für alle erteilen", "hash": "Hash", "from": "Von", "to": "Bis", "details": "Details", "amount": "Betrag", + "fee": { + "transaction_fee_in_ether": "Transaktionsgebühr", + "transaction_fee_in_usd": "Transaktionsgebühr (USD)" + }, "gas_used": "Verbrauchtes Gas (Einheiten)", "gas_limit": "Gas-Limit (Einheiten)", "gas_price": "Gas-Preis (GWEI)", @@ -1630,6 +1676,8 @@ "you_can": "Sie können aber auch", "add_network": "weitere Netzwerke manuell hinzufügen.", "select_network": "Netzwerk wählen", + "enabled_networks": "Aktivierte Netzwerke", + "additional_networks": "Zusätzliche Netzwerke", "show_test_networks": "Testnetzwerke anzeigen", "deprecated_goerli": "Aufgrund der Protokolländerungen von Ethereum: Das Goerli-Testnetzwerk funktioniert möglicherweise nicht mehr so zuverlässig und wird demnächst abgeschaltet.", "network_deprecated_title": "Dieses Netzwerk ist veraltet", @@ -1898,19 +1946,26 @@ "back_to_safety": "Zurück zu Sicherheit" }, "notifications": { + "staked": "Staked", + "received": "Empfangen", + "unstaked": "Unstaked", + "to": "An", + "rate": "Preis (einschließlich Gebühren)", + "unstaking_requested": "Unstaking angefordert", "stake_completed": "Stake vervollständigt", "withdrawal_completed": "Abhebung abgeschlossen", "unstake_completed": "Unstake abgeschlossen", "withdrawal_requested": "Auszahlungsanfrage", "stake_ready_to_be_withdrawn": "Stake bereit für die Auszahlung", "swap_completed": "Getauscht {{from}} für {{to}}", + "swap": "Geswappt", "sent": "An {{address}} gesendet", - "received": "Erhalten von {{address}}", - "nft_sent": "Sent NFT to {{address}}", - "erc721_sent": "Sent NFT to {{address}}", - "erc1155_sent": "Sent NFT to {{address}}", - "erc721_received": "Received NFT from {{address}}", - "erc1155_received": "Received NFT from {{address}}", + "received_from": "Erhalten von {{address}}", + "nft_sent": "NFT an {{address}} gesendet", + "erc721_sent": "NFT an {{address}} gesendet", + "erc1155_sent": "NFT an {{address}} gesendet", + "erc721_received": "NFT von {{address}} erhalten", + "erc1155_received": "NFT von {{address}} erhalten", "received_nft": "NFT von {{address}} erhalten", "pending_title": "Transaktion abgesendet", "pending_deposit_title": "Einzahlung im Gange!", @@ -1952,6 +2007,7 @@ "wc_description": "Bitte überprüfen Sie die App.", "wallet": "Wallet", "web3": "Web3", + "staking_provider": "Staking-Anbieter", "empty": { "title": "Hier gibt es nichts zu sehen", "message": "Hier finden Sie Benachrichtigungen, sobald eine Aktivität in Ihrer Wallet stattfindet. " @@ -2561,11 +2617,18 @@ "submit_ticket_5": "Ein Ticket absenden", "submit_ticket_6": "absenden.", "submit_ticket_7": "Bitte senden Sie uns die Fehlermeldung und den Screenshot.", + "submit_ticket_8": "Senden Sie uns einen Fehlerbericht", + "submit_ticket_9": "Geben Sie bitte Einzelheiten zu dem Vorfall an.", + "bug_report_prompt_title": "Erzählen Sie uns, was passiert ist", + "bug_report_prompt_description": "Fügen Sie Details hinzu, damit wir herausfinden können, was schiefgelaufen ist.", + "bug_report_thanks": "Danke! Wir werden bald einen Blick darauf werfen.", "save_seedphrase_1": "Sollte der Fehler anhalten,", "save_seedphrase_2": "speichern Sie Ihre geheime Wiederherstellungsphrase", "save_seedphrase_3": "und installieren Sie die App neu. Achtung: Sie können Ihre Wallet ohne ihre geheime Wiederherstellungsphrase NICHT wiederherstellen.", "copied_clipboard": "In die Zwischenablage kopiert", - "ok": "OK" + "ok": "OK", + "cancel": "Stornieren", + "send": "Senden" }, "whats_new": { "title": "Was neu ist", @@ -2585,7 +2648,7 @@ "header": "Verbesserter Transaktionsschutz", "description_1": "Erzielen Sie mit Smart Transactions höhere Erfolgsraten, einen Frontrunning-Schutz und eine bessere Transparenz.", "description_2": "Nur auf Ethereum verfügbar. Sie können diese Funktion jederzeit in den Einstellungen aktivieren oder deaktivieren.", - "secondary_button": "Erhöhten Schutz nicht aktivieren", + "secondary_button": "In Einstellungen verwalten", "primary_button": "Aktivieren", "learn_more": "Erfahren Sie mehr.", "benefit_1_1": "Erfolgsrate:", @@ -2594,6 +2657,11 @@ "benefit_2_2": "Geld", "benefit_3_1": "Echtzeit", "benefit_3_2": "Updates" + }, + "transaction_simulation": { + "title": "Geschätzte Kontostandänderungen", + "description_1": "Jetzt können Sie das mögliche Ergebnis Ihrer Transaktionen sehen, bevor Sie sie tätigen!", + "description_2": "Dies ist nur eine Simulation, wir können also nicht für das Endergebnis garantieren. Sie können dies jederzeit unter Einstellungen > Sicherheit und Datenschutz ausschalten." } }, "invalid_network": { @@ -3025,7 +3093,8 @@ "manage_networks": "Netzwerke verwalten", "manage_networks_body": "Wir verwenden Infura als RPC-Anbieter (Remote Procedure Call), um einen möglichst zuverlässigen und privaten Zugriff auf Ethereum-Daten zu ermöglichen. Sie können Ihren eigenen RPC auswählen, bedenken Sie aber, dass RPC Ihre IP-Adresse und Ihre Ethereum-Wallet erhalten wird, um Transaktionen durchzuführen. Lesen Sie unsere ", "manage_networks_body2": " um mehr darüber zu erfahren, wie Infura mit Daten umgeht.", - "functionality_body": "Enthält Token-Daten und -Werte, optimale Gas-Einstellungen, Sicherheitsupdates und vieles mehr. Bei der Nutzung dieser Dienstleistungen wird Ihre IP-Adresse wie beim Besuch einer Website an MetaMask weitergegeben.", + "functionality_body": "MetaMask bietet grundlegende Funktionen wie Token-Details und Gas-Einstellungen über Internetdienste. Wenn Sie Internetdienste nutzen, wird Ihre IP-Adresse weitergegeben, in diesem Fall an MetaMask. Das ist genau so, wie wenn Sie eine beliebige Website besuchen. MetaMask verwendet diese Daten vorübergehend und verkauft Ihre Daten niemals. Sie können ein VPN verwenden oder diese Dienste abschalten, aber das kann Ihr MetaMask-Erlebnis beeinträchtigen. Lesen Sie unsere ", + "functionality_body2": " um mehr zu erfahren.", "sheet": { "title_off": "Grundfunktionalität ausschalten", "description_off": "Dies bedeutet, dass Sie Ihre Zeit auf MetaMask nicht vollständig optimieren können. Grundlegende Funktionen (wie Token-Details, optimale Gas-Einstellungen und andere) stehen Ihnen nicht zur Verfügung.", @@ -3038,5 +3107,16 @@ "turn_off": "Ausschalten" } } + }, + "simulation_details": { + "failed": "Es ist ein Fehler beim Laden Ihrer Schätzung aufgetreten.", + "fiat_not_available": "Nicht verfügbar", + "incoming_heading": "Sie erhalten", + "no_balance_changes": "Keine Änderungen für Ihre Wallet prognostiziert", + "outgoing_heading": "Sie senden", + "reverted": "Diese Transaktion wird wahrscheinlich scheitern", + "title": "Geschätzte Änderungen", + "tooltip_description": "Die geschätzten Änderungen sind das, was passieren könnte, wenn Sie diese Transaktion durchführen. Dies ist nur eine Prognostizierung, keine Garantie.", + "total_fiat": "Gesamt = {{currency}}" } -} \ No newline at end of file +} diff --git a/locales/languages/el.json b/locales/languages/el.json index ce458f3cd51..bbf8287883f 100644 --- a/locales/languages/el.json +++ b/locales/languages/el.json @@ -365,17 +365,17 @@ "title": "Λήψη" }, "experience_enhancer_modal": { - "title": "Help us enhance your experience", - "paragraph1a": "In addition to ", - "paragraph1b": ", we'd like to use data (like information from cookies) to learn how you interact with our marketing communications.", + "title": "Βοηθήστε μας να βελτιώσουμε την εμπειρία σας", + "paragraph1a": "Εκτός από τo ", + "paragraph1b": ", θέλουμε να χρησιμοποιήσουμε δεδομένα (όπως πληροφορίες από τα cookies) για να μάθουμε πώς αλληλεπιδράτε με τις επικοινωνίες μάρκετινγκ.", "link": "MetaMetrics", - "paragraph2": "This helps us personalize what we share with you, like:", - "bullet1": "Latest developments", - "bullet2": "Product features", - "bullet3": "Other relevant promotional materials", - "footer": "Remember, we never sell the data you provide and you can opt out any time.", - "accept": "I agree", - "cancel": "No thanks" + "paragraph2": "Αυτό μας βοηθά να εξατομικεύσουμε αυτά που κοινοποιούμε σε εσάς, όπως:", + "bullet1": "Τελευταίες εξελίξεις", + "bullet2": "Χαρακτηριστικά προϊόντων", + "bullet3": "Άλλο σχετικό προωθητικό υλικό", + "footer": "Να θυμάστε, δεν πουλάμε ποτέ τα δεδομένα που μας παρέχετε και μπορείτε να εξαιρεθείτε ανά πάσα στιγμή.", + "accept": "Συμφωνώ", + "cancel": "Όχι, ευχαριστώ" }, "wallet": { "title": "Πορτοφόλι", @@ -413,7 +413,7 @@ "no_tokens": "Δεν έχετε καθόλου tokens!", "no_nfts_yet": "Δεν έχετε ακόμη NFT", "nfts_autodetection_title": "Εντοπισμός NFT", - "nfts_autodetection_desc": "Επιτρέψτε στο MetaMask να εντοπίζει αυτόματα NFT από το OpenSea και να τα εμφανίζει στο πορτοφόλι σας στο MetaMask.", + "nfts_autodetection_desc": "Επιτρέψτε στο MetaMask να ανιχνεύσει και να εμφανίσει αυτόματα τα NFT στο πορτοφόλι σας.", "network_details_check": "Ο έλεγχος λεπτομερειών δικτύου", "network_with_chain_id": "Το δίκτυο με αναγνωριστικό αλυσίδας", "chain_list_returned_different_ticker_symbol": "Αυτό το σύμβολο token δεν ταιριάζει με το όνομα δικτύου ή το αναγνωριστικό αλυσίδας που καταχωρίσατε. Πολλά δημοφιλή tokens χρησιμοποιούν παρόμοια σύμβολα, τα οποία οι απατεώνες μπορούν να χρησιμοποιήσουν για να σας εξαπατήσουν ώστε να τους στείλετε ένα πιο πολύτιμο token ως αντάλλαγμα. Επαληθεύετέ τα πάντοτε προτού συνεχίσετε.", @@ -454,7 +454,7 @@ "display_nft_media_cta": "Ενεργοποιήστε την «Προβολή μέσων των NFT»", "display_media_nft_warning": "Η εμφάνιση μέσων και δεδομένων των NFT ενδέχεται να εκθέσει τη διεύθυνση IP σας σε κεντρικούς διακομιστές. Εισαγάγετε ένα NFT μόνο αν κατανοείτε τους κινδύνους που συνεπάγονται.", "nfts_autodetect_title": "Αυτόματος εντοπισμός των NFT", - "nfts_autodetect_cta": "Ενεργοποιήστε τον «Αυτόματο εντοπισμό των NFT» στις Ρυθμίσεις", + "nfts_autodetect_cta": "Ενεργοποίηση της αυτόματης ανίχνευσης NFT", "turn_on_network_check_cta": "Ενεργοποίηση του ελέγχου λεπτομερειών δικτύου", "display_nft_media_cta_new_1": "Για να δείτε ένα NFT, ενεργοποιήστε την επιλογή «Προβολή μέσων NFT» στο", "display_nft_media_cta_new_2": "Ρυθμίσεις > Ασφάλεια και απόρρητο.", @@ -520,7 +520,7 @@ "description_title": "Βοηθήστε μας να βελτιώσουμε το MetaMask", "description_content_1": "Θέλουμε να συλλέξουμε βασικά δεδομένα χρήσης για να βελτιώσουμε το MetaMask. Λάβετε υπόψη ότι δεν πουλάμε ποτέ τα δεδομένα που μας παρέχετε εδώ.", "description_content_2": "Όταν συγκεντρώνουμε μετρήσεις, θα είναι πάντα...", - "checkbox": "We'll use this data to learn how you interact with our marketing communications. We may share relavent news (like product features).", + "checkbox": "Θα χρησιμοποιήσουμε αυτά τα δεδομένα για να μάθουμε πώς αλληλεπιδράτε με τις επικοινωνίες μάρκετινγκ. Ενδέχεται να κοινοποιήσουμε σχετικές ειδήσεις (όπως χαρακτηριστικά προϊόντων).", "action_description_1_prefix": "Ιδιωτικές:", "action_description_2_prefix": "Γενικές:", "action_description_3_prefix": "Προαιρετικές:", @@ -650,7 +650,8 @@ "revoked_all": "Όλοι οι λογαριασμοί ανακλήθηκαν.", "accounts_connected": "λογαριασμοί συνδεδεμένοι.", "disconnected": "αποσυνδέθηκε.", - "disconnected_all": "Όλοι οι λογαριασμοί αποσυνδέθηκαν." + "disconnected_all": "Όλοι οι λογαριασμοί αποσυνδέθηκαν.", + "nft_detection_enabled": "Ενεργοποιήθηκε η αυτόματη ανίχνευση NFT" }, "connect_qr_hardware": { "title": "Συνδέστε ένα πορτοφόλι υλικού με βάση το QR", @@ -671,8 +672,8 @@ "please_wait": "Παρακαλούμε περιμένετε" }, "data_collection_modal": { - "accept": "Okay", - "content": "You turned off data collection for our marketing purposes. This only applies to this device. If you use MetaMask on other devices, make sure to opt out there as well." + "accept": "Εντάξει", + "content": "Έχετε απενεργοποιήσει τη συλλογή δεδομένων για σκοπούς μάρκετινγκ. Αυτό ισχύει μόνο για αυτή τη συσκευή. Εάν χρησιμοποιείτε το MetaMask και σε άλλες συσκευές, βεβαιωθείτε ότι έχετε επιλέξει την απενεργοποίηση." }, "account_selector": { "prev": "ΠΡΟΗΓΟΥΜΕΝΟ", @@ -845,9 +846,9 @@ "clear_history_desc": "Επιλέξτε αυτή την επιλογή για να διαγράψετε ολόκληρο το ιστορικό περιήγησής σας.", "clear_cookies_desc": "Επιλέξτε αυτή την επιλογή για να διαγράψετε τα cookies από το πρόγραμμα περιήγησής σας.", "metametrics_title": "Πάρτε μέρος στα MetaMetrics", - "metametrics_description": "Allow MetaMetrics to collect basic usage and diagnostics data to improve our product. You can disable MetaMetrics for this device.", - "data_collection_title": "Data collection for marketing", - "data_collection_description": "We’ll use MetaMetrics to learn how you interact with our marketing communications. We may share relevant news (like product features and other materials).", + "metametrics_description": "Επιτρέψτε στο MetaMetrics να συλλέγει βασικά δεδομένα χρήσης και διάγνωσης για τη βελτίωση των προϊόντων μας. Μπορείτε να απενεργοποιήσετε το MetaMetrics για αυτή τη συσκευή.", + "data_collection_title": "Συγκέντρωση δεδομένων για μάρκετινγκ", + "data_collection_description": "Θα χρησιμοποιήσουμε το MetaMetrics για να μάθουμε πώς αλληλεπιδράτε με τις επικοινωνίες μάρκετινγκ. Ενδέχεται να κοινοποιήσουμε σχετικές ειδήσεις (όπως χαρακτηριστικά προϊόντων και άλλο υλικό).", "batch_balance_requests_title": "Αιτήματα υπολοίπου μαζικών λογαριασμών", "batch_balance_requests_description": "Συγκεντρώνουμε τους λογαριασμούς και ζητάμε από την Infura να εμφανίσει τα υπόλοιπά σας. Αν το απενεργοποιήσετε αυτό, θα ερωτηθούν μόνο οι ενεργοί λογαριασμοί. Ορισμένες αποκεντρωμένες εφαρμογές δεν θα λειτουργούν, αν δεν συνδέσετε το πορτοφόλι σας.", "third_party_title": "Λήψη εισερχόμενων συναλλαγών", @@ -888,6 +889,13 @@ "delete": "Διαγραφή", "network_exists": "Αυτό το δίκτυο έχει ήδη προστεθεί.", "delete_metrics_title": "Διαγραφή δεδομένων MetaMetrics", + "delete_metrics_description_part_one": "Αυτό θα διαγράψει τα ιστορικά δεδομένα", + "delete_metrics_description_part_two": "από το MetaMetrics", + "delete_metrics_description_part_three": "που σχετίζονται με το πορτοφόλι σας.", + "delete_metrics_description_before_delete": "Το πορτοφόλι και οι λογαριασμοί σας θα παραμείνουν ακριβώς όπως είναι τώρα μετά τη διαγραφή αυτών των δεδομένων. Αυτή η διαδικασία μπορεί να διαρκέσει έως και 30 ημέρες. Δείτε την", + "delete_metrics_description_after_delete_part_one": "Ξεκινήσατε την ενέργεια αυτή στις", + "delete_metrics_description_after_delete_part_two": ". Η διαδικασία αυτή μπορεί να διαρκέσει έως και 30 ημέρες. Δείτε την", + "delete_metrics_description_privacy_policy": "Πολιτική Απορρήτου.", "delete_metrics_button": "Διαγραφή δεδομένων MetaMetrics", "check_status_button": "Έλεγχος Κατάστασης", "delete_metrics_confirm_modal_title": "Διαγραφή δεδομένων MetaMetrics;", @@ -990,8 +998,27 @@ "security_alerts": "Ειδοποιήσεις ασφαλείας", "security_alerts_desc": "Αυτή η λειτουργία σας προειδοποιεί για κακόβουλη δραστηριότητα, καθώς ελέγχει τοπικά τα αιτήματα συναλλαγών και υπογραφών σας. Πάντα να κάνετε τη δική σας επιμελή έρευνα προτού εγκρίνετε οποιαδήποτε αιτήματα. Δεν υπάρχει καμία εγγύηση ότι αυτή η λειτουργία θα εντοπίσει όλες τις κακόβουλες δραστηριότητες. Ενεργοποιώντας αυτή τη λειτουργία, συμφωνείτε με τους όρους χρήσης του παρόχου.", "smart_transactions_opt_in_heading": "Έξυπνες Συναλλαγές", - "smart_transactions_opt_in_desc": "Ενεργοποιήστε τις έξυπνες συναλλαγές για πιο αξιόπιστες και ασφαλείς συναλλαγές και ρυθμιζόμενες χρεώσεις στο ETH Mainnet.", - "smart_transactions_learn_more": "Μάθετε περισσότερα." + "smart_transactions_opt_in_desc": "Ενεργοποιήστε τις Έξυπνες Συναλλαγές για πιο αξιόπιστες και ασφαλείς συναλλαγές στο Ethereum Mainnet.", + "smart_transactions_learn_more": "Μάθετε περισσότερα.", + "simulation_details": "Εκτίμηση μεταβολών υπολοίπου", + "simulation_details_description": "Ενεργοποιήστε το για να εκτιμήσετε τις αλλαγές στο υπόλοιπο των συναλλαγών πριν τις επιβεβαιώσετε. Αυτό δεν εγγυάται την τελική αποτίμηση των συναλλαγών σας. ", + "simulation_details_learn_more": "Μάθετε περισσότερα.", + "aes_crypto_test_form_title": "AES Crypto - Φόρμα δοκιμών", + "aes_crypto_test_form_description": "Το τμήμα αναπτύχθηκε αποκλειστικά για δοκιμές E2E. Εάν αυτό είναι ορατό στην εφαρμογή σας, αναφέρετέ το στην υποστήριξη του MetaMask." + }, + "aes_crypto_test_form": { + "generate_random_salt": "Δημιουργία τυχαίων δεδομένων", + "salt_bytes_count": "Καταμέτρηση bytes δεδομένων", + "generate": "Δημιουργία", + "generate_encryption_key": "Δημιουργία κλειδιού κρυπτογράφησης από τον κωδικό πρόσβασης", + "password": "Κωδικός πρόσβασης", + "salt": "Δεδομένα", + "encrypt_with_key": "Κρυπτογράφηση με κλειδί", + "encrypt": "Κρυπτογράφηση", + "encryption_key": "Κλειδί κρυπτογράφησης", + "data": "Δεδομένα", + "decrypt_with_key": "Αποκρυπτογράφηση με κλειδί", + "decrypt": "Αποκρυπτογράφηση" }, "sdk": { "disconnect_title": "Αποσύνδεση όλων των ιστότοπων;", @@ -1172,6 +1199,15 @@ "account_copied_to_clipboard": "Η δημόσια διεύθυνση αντιγράφηκε στο πρόχειρο", "share_public_key": "Κοινοποίηση του δημόσιου κλειδιού μου:" }, + "enable_nft-auto-detection": { + "title": "Ενεργοποίηση της αυτόματης ανίχνευσης NFT", + "description": "Επιτρέψτε στο MetaMask να ανιχνεύει και να εμφανίζει τα NFT σας με αυτόματο εντοπισμό. Θα μπορείτε να έχετε:", + "immediateAccess": "Άμεση πρόσβαση στα NFT σας", + "navigate": "Εύκολη πλοήγηση στα ψηφιακά σας περιουσιακά στοιχεία", + "dive": "Άμεση χρήση των NFT σας", + "allow": "Να επιτρέπεται", + "notRightNow": "Όχι τώρα" + }, "detected_tokens": { "title": "Βρέθηκε {{tokenCount}} νέο token", "title_plural": "Βρέθηκαν {{tokenCount}} νέα tokens", @@ -1370,10 +1406,12 @@ "approve": "Έγκριση", "allow_to_access": "Δώστε άδεια πρόσβασης στο", "allow_to_address_access": "Δώστε σε αυτή τη διεύθυνση πρόσβαση στο", + "allow_to_transfer_all": "Επιτρέψτε την πρόσβαση και τη μεταφορά όλων των", "spend_cap": "Αίτημα ανώτατου ορίου δαπανών για το", "token": "token", "nft": "NFT", "you_trust_this_site": "Χορηγώντας την άδεια, επιτρέπετε στο ακόλουθο τρίτο μέρος να έχει πρόσβαση στα κεφάλαιά σας.", + "you_trust_this_third_party": "Αυτό επιτρέπει σε τρίτα μέρη να έχουν πρόσβαση και να μεταφέρουν τα NFT σας χωρίς περαιτέρω ειδοποίηση μέχρι να ανακαλέσετε την πρόσβασή τους.", "you_trust_this_address": "Εμπιστεύεστε αυτή τη διεύθυνση; Χορηγώντας αυτή την άδεια, επιτρέπετε σε αυτή τη διεύθυνση να έχει πρόσβαση στα κεφάλαιά σας.", "edit_permission": "Επεξεργασία άδειας", "edit": "Επεξεργασία", @@ -1477,6 +1515,8 @@ "tx_review_transfer_from": "Μεταφορά Από", "tx_review_unknown": "Άγνωστη Μέθοδος", "tx_review_approve": "Έγκριση", + "tx_review_increase_allowance": "Αύξηση των αποδοχών", + "tx_review_set_approval_for_all": "Ορίστε την έγκριση για όλους", "sent_ether": "Αποστολή Ether", "self_sent_ether": "Στείλτε Ether στον εαυτό σας", "received_ether": "Ληφθέντα Ether", @@ -1498,11 +1538,17 @@ "smart_contract_interaction": "Αλληλεπίδραση έξυπνου συμβολαίου", "swaps_transaction": "Συναλλαγή ανταλλαγής", "approve": "Έγκριση", + "increase_allowance": "Αύξηση των αποδοχών", + "set_approval_for_all": "Ορίστε την έγκριση για όλους", "hash": "Κατακερματισμός", "from": "Από", "to": "Προς", "details": "Λεπτομέρειες", "amount": "Ποσό", + "fee": { + "transaction_fee_in_ether": "Τέλη συναλλαγών", + "transaction_fee_in_usd": "Τέλη συναλλαγών (USD)" + }, "gas_used": "Τέλη συναλλαγών που χρησιμοποιήθηκαν (μονάδες)", "gas_limit": "Όριο τελών συναλλαγής (Μονάδες)", "gas_price": "Τιμή τελών συναλλαγής (GWEI)", @@ -1630,6 +1676,8 @@ "you_can": "Ή μπορείτε", "add_network": "να προσθέσετε περισσότερα δίκτυα χειροκίνητα.", "select_network": "Επιλέξτε ένα δίκτυο", + "enabled_networks": "Ενεργοποιημένα δίκτυα", + "additional_networks": "Πρόσθετα δίκτυα", "show_test_networks": "Εμφάνιση δοκιμαστικών δικτύων", "deprecated_goerli": "Λόγω των αλλαγών στο πρωτόκολλο του δοκιμαστικού δίκτυου Ethereum: Goerli μπορεί να μην λειτουργεί τόσο αξιόπιστα και θα καταργηθεί σύντομα.", "network_deprecated_title": "Αυτό το δίκτυο έχει καταργηθεί", @@ -1898,19 +1946,26 @@ "back_to_safety": "Πίσω στην ασφάλεια" }, "notifications": { + "staked": "Ποντάρισμα", + "received": "Ελήφθη", + "unstaked": "Ακύρωση πονταρίσματος", + "to": "Προς", + "rate": "Ποσό (περιλαμβάνονται οι χρεώσεις)", + "unstaking_requested": "Αίτημα ακύρωσης πονταρίσματος", "stake_completed": "Ολοκλήρωση του πονταρίσματος", "withdrawal_completed": "Η ανάληψη ολοκληρώθηκε", "unstake_completed": "Μη ολοκλήρωση του πονταρίσματος", "withdrawal_requested": "Αίτημα ανάληψης", "stake_ready_to_be_withdrawn": "Το ποντάρισμα είναι έτοιμο για ανάληψη", "swap_completed": "Ανταλλαγή {{from}} για {{to}}", + "swap": "Ανταλλαγή", "sent": "Στάλθηκε σε {{address}}", - "received": "Ελήφθη από {{address}}", - "nft_sent": "Sent NFT to {{address}}", - "erc721_sent": "Sent NFT to {{address}}", - "erc1155_sent": "Sent NFT to {{address}}", - "erc721_received": "Received NFT from {{address}}", - "erc1155_received": "Received NFT from {{address}}", + "received_from": "Ελήφθη από {{address}}", + "nft_sent": "Αποστολή NFT σε {{address}}", + "erc721_sent": "Αποστολή NFT σε {{address}}", + "erc1155_sent": "Αποστολή NFT σε {{address}}", + "erc721_received": "Ελήφθησαν NFT από {{address}}", + "erc1155_received": "Ελήφθησαν NFT από {{address}}", "received_nft": "Ελήφθη NFT από {{address}}", "pending_title": "Η συναλλαγή υποβλήθηκε", "pending_deposit_title": "Κατάθεση σε εξέλιξη!", @@ -1952,6 +2007,7 @@ "wc_description": "Παρακαλούμε ελέγξτε την εφαρμογή", "wallet": "Πορτοφόλι", "web3": "Web3", + "staking_provider": "Πάροχος πονταρίσματος", "empty": { "title": "Τίποτα το ιδιαίτερο εδώ", "message": "Εδώ μπορείτε να βρείτε ειδοποιήσεις μόλις παρατηρηθεί δραστηριότητα στο πορτοφόλι σας. " @@ -2561,11 +2617,18 @@ "submit_ticket_5": "Υποβάλετε ένα αίτημα υποστήριξης", "submit_ticket_6": "εδώ.", "submit_ticket_7": "Συμπεριλάβετε το μήνυμα σφάλματος και το στιγμιότυπο οθόνης.", + "submit_ticket_8": "Στείλτε μας μια αναφορά σφαλμάτων", + "submit_ticket_9": "Παρακαλούμε να αναφέρετε λεπτομέρειες σχετικά με το τι συνέβη.", + "bug_report_prompt_title": "Πείτε μας τι συνέβη", + "bug_report_prompt_description": "Προσθέστε λεπτομέρειες ώστε να καταλάβουμε τι πήγε στραβά.", + "bug_report_thanks": "Ευχαριστούμε! Θα το εξετάσουμε σύντομα.", "save_seedphrase_1": "Εάν αυτό το σφάλμα παραμένει,", "save_seedphrase_2": "αποθηκεύστε τη Μυστική Φράση Ανάκτησης", "save_seedphrase_3": "και εγκαταστήστε ξανά την εφαρμογή. Σημείωση: ΔΕΝ μπορείτε να επαναφέρετε το πορτοφόλι σας χωρίς τη Μυστική Φράση Ανάκτησης.", "copied_clipboard": "Αντιγράφηκε στο πρόχειρο", - "ok": "Εντάξει" + "ok": "Εντάξει", + "cancel": "Άκυρο", + "send": "Αποστολή" }, "whats_new": { "title": "Τι νέο υπάρχει", @@ -2585,7 +2648,7 @@ "header": "Ενισχυμένη Προστασία Συναλλαγών", "description_1": "Ξεκλειδώστε υψηλότερα ποσοστά επιτυχίας, προστασία εκ των προτέρων και καλύτερη ορατότητα με τις Έξυπνες Συναλλαγές.", "description_2": "Διατίθεται μόνο στο Ethereum. Ενεργοποίηση ή απενεργοποίηση ανά πάσα στιγμή στις ρυθμίσεις.", - "secondary_button": "Μην ενεργοποιήσετε την ενισχυμένη προστασία", + "secondary_button": "Διαχείριση στις ρυθμίσεις", "primary_button": "Ενεργοποίηση", "learn_more": "Μάθετε περισσότερα.", "benefit_1_1": "99,5% ποσοστό", @@ -2594,6 +2657,11 @@ "benefit_2_2": "χρήματα", "benefit_3_1": "Ενημερώσεις", "benefit_3_2": "σε πραγματικό χρόνο" + }, + "transaction_simulation": { + "title": "Εκτιμώμενες μεταβολές υπολοίπου", + "description_1": "Τώρα μπορείτε να βλέπετε την πιθανή απόδοση των συναλλαγών σας πριν τις πραγματοποιήσετε!", + "description_2": "Πρόκειται απλώς για μια προσομοίωση, οπότε δεν μπορούμε να εγγυηθούμε την τελική απόδοση. Μπορείτε να το απενεργοποιήσετε ανά πάσα στιγμή στις Ρυθμίσεις > Ασφάλεια και Απόρρητο." } }, "invalid_network": { @@ -3025,7 +3093,8 @@ "manage_networks": "Διαχείριση δικτύων", "manage_networks_body": "Χρησιμοποιούμε το Infura ως πάροχο κλήσεων απομακρυσμένης διαδικασίας (RPC) για να προσφέρουμε την πιο αξιόπιστη και ιδιωτική πρόσβαση στα δεδομένα του Ethereum που διαθέτουμε. Μπορείτε να επιλέξετε το δικό σας RPC, αλλά να θυμάστε ότι οποιοδήποτε RPC θα λαμβάνει τη διεύθυνση IP και το πορτοφόλι σας στο Ethereum για να πραγματοποιεί συναλλαγές. Διαβάστε το ", "manage_networks_body2": " για να μάθετε περισσότερα σχετικά με τον τρόπο με τον οποίο η Infura χειρίζεται τα δεδομένα.", - "functionality_body": "Περιλαμβάνει δεδομένα και αξίες των tokens, βέλτιστες ρυθμίσεις τελών συναλλαγών, ενημερώσεις ασφαλείας και πολλά άλλα. Χρησιμοποιώντας αυτές τις υπηρεσίες, κοινοποιείτε τη διεύθυνση IP σας στο MetaMask, όπως ακριβώς όταν επισκέπτεστε έναν ιστότοπο.", + "functionality_body": "Το MetaMask παρέχει βασικές λειτουργίες, όπως λεπτομέρειες για τα tokens και ρυθμίσεις τελών συναλλαγών μέσω υπηρεσιών διαδικτύου. Όταν χρησιμοποιείτε υπηρεσίες διαδικτύου, η διεύθυνση IP σας κοινοποιείται, σε αυτή την περίπτωση με το MetaMask. Αυτό συμβαίνει ακριβώς όπως όταν επισκέπτεστε οποιονδήποτε ιστότοπο. Το MetaMask χρησιμοποιεί αυτά τα δεδομένα προσωρινά και δεν πωλεί ποτέ τα δεδομένα σας. Μπορείτε να χρησιμοποιήσετε ένα VPN ή να απενεργοποιήσετε αυτές τις υπηρεσίες, αλλά αυτό μπορεί να επηρεάσει την εμπειρία σας στο MetaMask. Διαβάστε την ", + "functionality_body2": " για να μάθετε περισσότερα.", "sheet": { "title_off": "Απενεργοποίηση βασικών λειτουργιών", "description_off": "Αυτό σημαίνει ότι δεν θα βελτιστοποιήσετε πλήρως το χρόνο σας στο MetaMask. Βασικές λειτουργίες (όπως λεπτομέρειες των tokens, βέλτιστες ρυθμίσεις τελών συναλλαγών και άλλα) δεν θα είναι διαθέσιμες σε εσάς.", @@ -3038,5 +3107,16 @@ "turn_off": "Απενεργοποίηση" } } + }, + "simulation_details": { + "failed": "Προέκυψε ένα σφάλμα κατά τη φόρτωση της εκτίμησής σας.", + "fiat_not_available": "Μη διαθέσιμο", + "incoming_heading": "Λαμβάνετε", + "no_balance_changes": "Δεν προβλέπονται αλλαγές για το πορτοφόλι σας", + "outgoing_heading": "Στέλνετε", + "reverted": "Αυτή η συναλλαγή είναι πιθανό να αποτύχει", + "title": "Εκτιμώμενες αλλαγές", + "tooltip_description": "Οι εκτιμώμενες αλλαγές είναι αυτές που μπορεί να συμβούν αν προχωρήσετε σε αυτή τη συναλλαγή. Πρόκειται απλώς για μια πρόβλεψη, δεν αποτελεί εγγύηση.", + "total_fiat": "Σύνολο = {{currency}}" } -} \ No newline at end of file +} diff --git a/locales/languages/es.json b/locales/languages/es.json index 946c8162158..ae339b025fb 100644 --- a/locales/languages/es.json +++ b/locales/languages/es.json @@ -365,17 +365,17 @@ "title": "Recibir" }, "experience_enhancer_modal": { - "title": "Help us enhance your experience", - "paragraph1a": "In addition to ", - "paragraph1b": ", we'd like to use data (like information from cookies) to learn how you interact with our marketing communications.", + "title": "Ayúdenos a mejorar su experiencia", + "paragraph1a": "Además de ", + "paragraph1b": ", nos gustaría utilizar datos (como la información de las cookies) para saber cómo interactúa con nuestras comunicaciones de marketing.", "link": "MetaMetrics", - "paragraph2": "This helps us personalize what we share with you, like:", - "bullet1": "Latest developments", - "bullet2": "Product features", - "bullet3": "Other relevant promotional materials", - "footer": "Remember, we never sell the data you provide and you can opt out any time.", - "accept": "I agree", - "cancel": "No thanks" + "paragraph2": "Esto nos ayuda a personalizar lo que compartimos con usted, como:", + "bullet1": "Últimas novedades", + "bullet2": "Características de productos", + "bullet3": "Otros materiales promocionales relevantes", + "footer": "Recuerde que nunca vendemos los datos que nos proporciona y que puede cancelar su suscripción en cualquier momento.", + "accept": "Acepto", + "cancel": "No, gracias" }, "wallet": { "title": "Monedero", @@ -413,7 +413,7 @@ "no_tokens": "No tiene ningún token.", "no_nfts_yet": "No hay ningún NFT aún", "nfts_autodetection_title": "Detección de NFT", - "nfts_autodetection_desc": "Permita que MetaMask detecte automáticamente los NFT de OpenSea y los muestre en su monedero MetaMask.", + "nfts_autodetection_desc": "Deje que MetaMask detecte y muestre automáticamente los NFT en su monedero.", "network_details_check": "Verificación de detalles de la red", "network_with_chain_id": "La red con ID de cadena", "chain_list_returned_different_ticker_symbol": "Este símbolo de token no coincide con el nombre de la red o el ID de cadena ingresados. Muchos tokens populares usan símbolos similares, lo que los estafadores pueden aprovechar para engañarlo y hacer que les envíe un token más valioso. Verifique todo antes de continuar.", @@ -454,7 +454,7 @@ "display_nft_media_cta": "Activar Mostrar medios NFT", "display_media_nft_warning": "Mostrar medios y datos NFT puede exponer su dirección IP a servidores centralizados. Importe un NFT solo si comprende los riesgos que esto implica.", "nfts_autodetect_title": "Detección automática de NFT", - "nfts_autodetect_cta": "Activar la detección automática de NFT en Configuración", + "nfts_autodetect_cta": "Habilite la autodetección de NFT", "turn_on_network_check_cta": "Activar la verificación de detalles de la red", "display_nft_media_cta_new_1": "Para ver un NFT, active Mostrar medios NFT en", "display_nft_media_cta_new_2": "Configuración > Seguridad y privacidad.", @@ -520,7 +520,7 @@ "description_title": "Ayúdenos a mejorar MetaMask", "description_content_1": "Nos gustaría recopilar datos básicos de uso para mejorar MetaMask. Tenga en cuenta que nunca venderemos los datos que nos proporcione aquí.", "description_content_2": "Al recopilar métricas, siempre serán...", - "checkbox": "We'll use this data to learn how you interact with our marketing communications. We may share relavent news (like product features).", + "checkbox": "Utilizaremos estos datos para saber cómo interactúa con nuestras comunicaciones de marketing. Podemos compartir noticias relevantes (como características de productos).", "action_description_1_prefix": "Privadas:", "action_description_2_prefix": "Generales:", "action_description_3_prefix": "Opcionales:", @@ -650,7 +650,8 @@ "revoked_all": "Todas las cuentas revocadas.", "accounts_connected": "cuentas conectadas.", "disconnected": "desconectadas.", - "disconnected_all": "Todas las cuentas desconectadas." + "disconnected_all": "Todas las cuentas desconectadas.", + "nft_detection_enabled": "Autodetección de NFT habilitada" }, "connect_qr_hardware": { "title": "Conectar un monedero físico basado en QR", @@ -671,8 +672,8 @@ "please_wait": "Espere, por favor" }, "data_collection_modal": { - "accept": "Okay", - "content": "You turned off data collection for our marketing purposes. This only applies to this device. If you use MetaMask on other devices, make sure to opt out there as well." + "accept": "De acuerdo", + "content": "Desactivó la recopilación de datos para nuestros fines de marketing. Esto solo se aplica a este dispositivo. Si utiliza MetaMask en otros dispositivos, asegúrese de desactivarlo allí también." }, "account_selector": { "prev": "ANT.", @@ -845,9 +846,9 @@ "clear_history_desc": "Elija esta opción para borrar todo el historial de exploración.", "clear_cookies_desc": "Elija esta opción para borrar las cookies del explorador.", "metametrics_title": "Participar en MetaMetrics", - "metametrics_description": "Allow MetaMetrics to collect basic usage and diagnostics data to improve our product. You can disable MetaMetrics for this device.", - "data_collection_title": "Data collection for marketing", - "data_collection_description": "We’ll use MetaMetrics to learn how you interact with our marketing communications. We may share relevant news (like product features and other materials).", + "metametrics_description": "Permitir que MetaMetrics recopile datos básicos de uso y diagnóstico para mejorar nuestro producto. Puede desactivar MetaMetrics para este dispositivo.", + "data_collection_title": "Recopilación de datos para marketing", + "data_collection_description": "Utilizaremos MetaMetrics para saber cómo interactúa con nuestras comunicaciones de marketing. Podemos compartir noticias relevantes (como características de productos y otros materiales).", "batch_balance_requests_title": "Solicitudes de saldo de cuenta por lotes", "batch_balance_requests_description": "Procesamos cuentas por lotes y consultamos a Infura para mostrar sus saldos de manera receptiva. Si desactiva esta opción, solo se consultarán las cuentas activas. Algunas dApps no funcionarán a menos que conecte su monedero.", "third_party_title": "Obtener transacciones entrantes", @@ -888,6 +889,13 @@ "delete": "Eliminar", "network_exists": "La red ya ha sido instalada", "delete_metrics_title": "Eliminar datos de MetaMetrics", + "delete_metrics_description_part_one": "Esto eliminará los datos históricos de", + "delete_metrics_description_part_two": "MetaMetrics", + "delete_metrics_description_part_three": "asociados a su monedero.", + "delete_metrics_description_before_delete": "Su monedero y cuentas permanecerán exactamente como están ahora después de que se hayan eliminado estos datos. Este proceso puede tardar hasta 30 días. Consulte nuestra", + "delete_metrics_description_after_delete_part_one": "Inició esta acción el", + "delete_metrics_description_after_delete_part_two": ". Este proceso puede tardar hasta 30 días. Consulte nuestra", + "delete_metrics_description_privacy_policy": "Política de privacidad.", "delete_metrics_button": "Eliminar datos de MetaMetrics", "check_status_button": "Comprobar estado", "delete_metrics_confirm_modal_title": "¿Eliminar datos de MetaMetrics?", @@ -990,8 +998,27 @@ "security_alerts": "Alertas de seguridad", "security_alerts_desc": "Esta función le alerta sobre actividad maliciosa al revisar localmente sus solicitudes de transacción y firma. Haga siempre su propia diligencia debida antes de aprobar cualquier solicitud. No hay garantía de que esta función detecte toda la actividad maliciosa. Al habilitar esta función, acepta los términos de uso del proveedor.", "smart_transactions_opt_in_heading": "Transacciones inteligentes", - "smart_transactions_opt_in_desc": "Active las transacciones inteligentes para realizar transacciones más confiables y seguras, y tarifas ajustables en la red principal de ETH.", - "smart_transactions_learn_more": "Más información." + "smart_transactions_opt_in_desc": "Active las transacciones inteligentes para realizar transacciones más confiables y seguras en la red principal de Ethereum.", + "smart_transactions_learn_more": "Más información.", + "simulation_details": "Estimar cambios de saldo", + "simulation_details_description": "Active esta opción para estimar los cambios de saldo de las transacciones antes de confirmarlas. Esto no garantiza el resultado final de sus transacciones. ", + "simulation_details_learn_more": "Obtenga más información.", + "aes_crypto_test_form_title": "AES Crypto: formulario de prueba", + "aes_crypto_test_form_description": "Sección desarrollada exclusivamente para pruebas E2E. Si esto es visible en su aplicación, infórmelo al soporte de MetaMask." + }, + "aes_crypto_test_form": { + "generate_random_salt": "Generar sal aleatoria", + "salt_bytes_count": "Recuento de bytes de sal", + "generate": "Generar", + "generate_encryption_key": "Generar clave de cifrado a partir de contraseña", + "password": "Contraseña", + "salt": "Sal", + "encrypt_with_key": "Cifrar con clave", + "encrypt": "Cifrar", + "encryption_key": "Clave de cifrado", + "data": "Datos", + "decrypt_with_key": "Descifrar con clave", + "decrypt": "Descifrar" }, "sdk": { "disconnect_title": "¿Desconectar de todos los sitios?", @@ -1172,6 +1199,15 @@ "account_copied_to_clipboard": "Dirección pública copiada en el Portapapeles", "share_public_key": "Uso compartido de mi clave pública: " }, + "enable_nft-auto-detection": { + "title": "Habilite la autodetección de NFT", + "description": "Permita que MetaMask detecte y muestre sus NFT con autodetección. Podrá:", + "immediateAccess": "Acceda inmediatamente a sus NFT", + "navigate": "Navegue por sus activos digitales sin esfuerzo", + "dive": "Comience a utilizar sus NFT", + "allow": "Permitir", + "notRightNow": "Ahora no" + }, "detected_tokens": { "title": "{{tokenCount}} nuevos tokens encontrados", "title_plural": "{{tokenCount}} nuevos tokens encontrados", @@ -1370,10 +1406,12 @@ "approve": "Aprobar", "allow_to_access": "Dar permiso para acceder a su", "allow_to_address_access": "Dar a esta dirección acceso a su", + "allow_to_transfer_all": "Permitir el acceso y la transferencia de todos sus", "spend_cap": "Solicitud de límite de gasto para su", "token": "token", "nft": "NFT", "you_trust_this_site": "Al otorgar permiso, permite que el siguiente tercero acceda a sus fondos.", + "you_trust_this_third_party": "Esto permite que un tercero acceda y transfiera sus NFT sin previo aviso hasta que usted revoque su acceso.", "you_trust_this_address": "¿Esta dirección es de confianza? Al conceder este permiso, autoriza que esta dirección acceda a sus fondos.", "edit_permission": "Editar permiso", "edit": "Editar", @@ -1477,6 +1515,8 @@ "tx_review_transfer_from": "Transferir desde", "tx_review_unknown": "Método desconocido", "tx_review_approve": "Aprobar", + "tx_review_increase_allowance": "Aumentar la asignación", + "tx_review_set_approval_for_all": "Establecer aprobación para todos", "sent_ether": "Ether enviado", "self_sent_ether": "Ether enviado a usted mismo", "received_ether": "Ether recibido", @@ -1498,11 +1538,17 @@ "smart_contract_interaction": "Interacción con el contrato inteligente", "swaps_transaction": "Transacción de intercambios", "approve": "Aprobar", + "increase_allowance": "Aumentar la asignación", + "set_approval_for_all": "Establecer aprobación para todos", "hash": "Hash", "from": "De", "to": "Para", "details": "Detalles", "amount": "Importe", + "fee": { + "transaction_fee_in_ether": "Tarifa de transacción", + "transaction_fee_in_usd": "Tarifa de transacción (USD)" + }, "gas_used": "Gas usado (unidades)", "gas_limit": "Límite de gas (unidades)", "gas_price": "Precio de gas (GWEI)", @@ -1630,6 +1676,8 @@ "you_can": "O puede", "add_network": "agregar más redes manualmente.", "select_network": "Seleccionar una red", + "enabled_networks": "Redes habilitadas", + "additional_networks": "Redes adicionales", "show_test_networks": "Mostrar redes de prueba", "deprecated_goerli": "Debido a los cambios de protocolo de Ethereum: es posible que la red de prueba de Goerli no funcione de manera tan confiable y pronto quedará obsoleta.", "network_deprecated_title": "Esta red está en desuso", @@ -1898,19 +1946,26 @@ "back_to_safety": "Volver a Seguridad" }, "notifications": { + "staked": "Con staking", + "received": "Recibido", + "unstaked": "Sin staking", + "to": "Para", + "rate": "Tasa (tarifa incluida)", + "unstaking_requested": "Unstaking solicitado", "stake_completed": "Staking finalizado", "withdrawal_completed": "Retiro finalizado", "unstake_completed": "Unstaking finalizado", "withdrawal_requested": "Retiro solicitado", "stake_ready_to_be_withdrawn": "Staking listo para ser retirado", "swap_completed": "Canjeado {{from}} por {{to}}", + "swap": "Canjeado", "sent": "Enviado a {{address}}", - "received": "Recibido desde {{address}}", - "nft_sent": "Sent NFT to {{address}}", - "erc721_sent": "Sent NFT to {{address}}", - "erc1155_sent": "Sent NFT to {{address}}", - "erc721_received": "Received NFT from {{address}}", - "erc1155_received": "Received NFT from {{address}}", + "received_from": "Recibido desde {{address}}", + "nft_sent": "NFT enviado a {{address}}", + "erc721_sent": "NFT enviado a {{address}}", + "erc1155_sent": "NFT enviado a {{address}}", + "erc721_received": "NFT recibido de {{address}}", + "erc1155_received": "NFT recibido de {{address}}", "received_nft": "NFT recibido desde {{address}}", "pending_title": "Transacción enviada", "pending_deposit_title": "¡Depósito en curso!", @@ -1952,6 +2007,7 @@ "wc_description": "Revise su aplicación", "wallet": "Monedero", "web3": "Web3", + "staking_provider": "Proveedor de staking", "empty": { "title": "Nada que ver aquí", "message": "Aquí es donde puede encontrar notificaciones una vez que haya actividad en su monedero. " @@ -2561,11 +2617,18 @@ "submit_ticket_5": "Envíe una incidencia", "submit_ticket_6": "aquí.", "submit_ticket_7": "Incluya el mensaje de error y la captura de pantalla.", + "submit_ticket_8": "Envíenos un informe de error", + "submit_ticket_9": "Incluya detalles acerca de lo que sucedió.", + "bug_report_prompt_title": "Cuéntenos que pasó", + "bug_report_prompt_description": "Agregue detalles para que podamos descubrir qué salió mal.", + "bug_report_thanks": "¡Gracias! Echaremos un vistazo pronto.", "save_seedphrase_1": "Si este error persiste,", "save_seedphrase_2": "guarde la frase secreta de recuperación", "save_seedphrase_3": "y vuelva a instalar la aplicación. Nota: NO puede restaurar su monedero si no tiene la frase secreta de recuperación.", "copied_clipboard": "Copiado en el Portapapeles", - "ok": "Aceptar" + "ok": "Aceptar", + "cancel": "Cancelar", + "send": "Enviar" }, "whats_new": { "title": "Novedades", @@ -2585,7 +2648,7 @@ "header": "Protección mejorada de transacciones", "description_1": "Desbloquee índices de éxito más altos, protección contra frontrunning y mejor visibilidad con transacciones inteligentes.", "description_2": "Solo disponible en Ethereum. Active o desactive en cualquier momento en la configuración.", - "secondary_button": "No activar la protección mejorada", + "secondary_button": "Administrar en configuración", "primary_button": "Activar", "learn_more": "Más información.", "benefit_1_1": "99,5 % de índice", @@ -2594,6 +2657,11 @@ "benefit_2_2": "dinero", "benefit_3_1": "Tiempo real", "benefit_3_2": "actualizaciones" + }, + "transaction_simulation": { + "title": "Cambios de saldo estimados", + "description_1": "¡Ahora puede ver el resultado potencial de sus transacciones antes de realizarlas!", + "description_2": "Esto es solo una simulación, por lo que no podemos garantizar el resultado final. Puede desactivar esta opción en cualquier momento en Configuración > Seguridad y privacidad." } }, "invalid_network": { @@ -3025,7 +3093,8 @@ "manage_networks": "Gestionar redes", "manage_networks_body": "Usamos Infura como nuestro proveedor de llamadas a procedimientos remotos (RPC) para ofrecer el acceso más confiable y privado posible a los datos de Ethereum. Puede elegir su propio RPC, pero recuerde que cualquier RPC recibirá su dirección IP y su monedero de Ethereum para realizar transacciones. Lea nuestra ", "manage_networks_body2": " para saber más sobre cómo Infura maneja los datos.", - "functionality_body": "Incluye datos y valor de los tokenes, configuración óptima de gas, actualizaciones de seguridad y mucho más. Al usar estos servicios comparte su dirección IP con MetaMask, al igual que cuando visita un sitio web.", + "functionality_body": "MetaMask ofrece funciones básicas como los detalles del token y la configuración de gas mediante servicios de Internet. Al utilizar los servicios de Internet, su dirección IP es compartida, en este caso con MetaMask. Es lo mismo que cuando visita cualquier página web. MetaMask utiliza estos datos temporalmente y nunca los vende. Puede utilizar una VPN o desactivar estos servicios, pero esto podría afectar su experiencia con MetaMask. Consulte nuestros ", + "functionality_body2": " para saber más.", "sheet": { "title_off": "Desactivar la funcionalidad básica", "description_off": "Esto significa que no optimizará completamente su tiempo en MetaMask. Las funciones básicas (como los detalles de los tokenes, la configuración óptima de gas y otras) no estarán disponibles para usted.", @@ -3038,5 +3107,16 @@ "turn_off": "Desactivar" } } + }, + "simulation_details": { + "failed": "Se produjo un error al cargar su estimación.", + "fiat_not_available": "No disponible", + "incoming_heading": "Usted recibe", + "no_balance_changes": "No se prevén cambios para su monedero", + "outgoing_heading": "Envía", + "reverted": "Es probable que esta transacción falle", + "title": "Cambios estimados", + "tooltip_description": "Los cambios estimados son los que podrían producirse si sigue adelante con esta transacción. Esto es solo una predicción, no una garantía.", + "total_fiat": "Total = {{currency}}" } -} \ No newline at end of file +} diff --git a/locales/languages/fr.json b/locales/languages/fr.json index 5d2b698ed6b..d6ce53cf281 100644 --- a/locales/languages/fr.json +++ b/locales/languages/fr.json @@ -365,17 +365,17 @@ "title": "Recevoir" }, "experience_enhancer_modal": { - "title": "Help us enhance your experience", - "paragraph1a": "In addition to ", - "paragraph1b": ", we'd like to use data (like information from cookies) to learn how you interact with our marketing communications.", + "title": "Aidez-nous à améliorer votre expérience", + "paragraph1a": "En plus de ", + "paragraph1b": ", nous aimerions utiliser des données (comme des informations provenant de cookies) pour savoir comment vous interagissez avec nos communications commerciales.", "link": "MetaMetrics", - "paragraph2": "This helps us personalize what we share with you, like:", - "bullet1": "Latest developments", - "bullet2": "Product features", - "bullet3": "Other relevant promotional materials", - "footer": "Remember, we never sell the data you provide and you can opt out any time.", - "accept": "I agree", - "cancel": "No thanks" + "paragraph2": "Cela nous aide à personnaliser les informations que nous partageons avec vous, comme :", + "bullet1": "Dernières avancées", + "bullet2": "Caractéristiques du produit", + "bullet3": "Autres matériels promotionnels pertinents", + "footer": "N’oubliez pas que nous ne vendons jamais les données que vous nous fournissez et que vous pouvez vous désinscrire à tout moment.", + "accept": "J’accepte", + "cancel": "Non, merci" }, "wallet": { "title": "Portefeuille", @@ -413,7 +413,7 @@ "no_tokens": "Vous n’avez aucun jeton !", "no_nfts_yet": "Aucun NFT pour le moment", "nfts_autodetection_title": "Détection de NFT", - "nfts_autodetection_desc": "Cela permet à MetaMask de détecter automatiquement les NFT d’OpenSea et de les afficher dans votre portefeuille MetaMask.", + "nfts_autodetection_desc": "Laissez MetaMask détecter et afficher automatiquement les NFT dans votre portefeuille.", "network_details_check": "Vérification des détails du réseau", "network_with_chain_id": "Le réseau qui a un ID de chaîne", "chain_list_returned_different_ticker_symbol": "Le symbole de ce jeton ne correspond pas au nom du réseau ou à l’ID de chaîne saisi. De nombreux jetons populaires utilisent des symboles similaires dont les escrocs peuvent se servir pour vous amener à leur envoyer un jeton de plus grande valeur en retour. Vérifiez toutes les informations avant de continuer.", @@ -454,7 +454,7 @@ "display_nft_media_cta": "Activez l’option « Afficher les supports NFT »", "display_media_nft_warning": "L’affichage des supports et des données NFT peut exposer votre adresse IP à des serveurs centralisés. N’importez un NFT que si vous comprenez les risques encourus.", "nfts_autodetect_title": "Détection automatique des NFT", - "nfts_autodetect_cta": "Activez la détection automatique des NFT dans les Paramètres", + "nfts_autodetect_cta": "Activer la détection automatique des NFT", "turn_on_network_check_cta": "Activer la vérification des détails du réseau", "display_nft_media_cta_new_1": "Pour voir un NFT, activez l’option « Afficher les supports NFT » dans", "display_nft_media_cta_new_2": "Paramètres > Sécurité et confidentialité.", @@ -520,7 +520,7 @@ "description_title": "Aidez-nous à améliorer MetaMask", "description_content_1": "Nous aimerions recueillir des données d’utilisation de base pour améliorer MetaMask. Sachez que nous ne vendrons jamais les informations que vous nous fournissez ici.", "description_content_2": "Lorsque nous recueillons des données, elles sont toujours…", - "checkbox": "We'll use this data to learn how you interact with our marketing communications. We may share relavent news (like product features).", + "checkbox": "Nous utiliserons ces données pour savoir comment vous interagissez avec nos communications commerciales et pour partager avec vous des informations pertinentes (comme les caractéristiques des produits).", "action_description_1_prefix": "Privé :", "action_description_2_prefix": "Général :", "action_description_3_prefix": "Facultatif :", @@ -650,7 +650,8 @@ "revoked_all": "Tous les comptes ont été révoqués.", "accounts_connected": "comptes connectés.", "disconnected": "déconnecté.", - "disconnected_all": "Tous les comptes ont été déconnectés." + "disconnected_all": "Tous les comptes ont été déconnectés.", + "nft_detection_enabled": "Détection automatique des NFT activée" }, "connect_qr_hardware": { "title": "Connecter un hardware wallet (portefeuille matériel) basé sur code QR", @@ -671,8 +672,8 @@ "please_wait": "Veuillez patienter" }, "data_collection_modal": { - "accept": "Okay", - "content": "You turned off data collection for our marketing purposes. This only applies to this device. If you use MetaMask on other devices, make sure to opt out there as well." + "accept": "OK", + "content": "Vous avez désactivé la collecte de données à des fins de marketing. Cela ne s’applique qu’à cet appareil. Si vous utilisez MetaMask sur d’autres appareils, n’oubliez pas de désactiver cette fonctionnalité sur ces appareils aussi." }, "account_selector": { "prev": "PRÉCÉDENT", @@ -845,9 +846,9 @@ "clear_history_desc": "Choisissez cette option pour effacer l’ensemble de votre historique de navigation.", "clear_cookies_desc": "Choisissez cette option pour effacer l’ensemble des cookies de votre navigateur.", "metametrics_title": "Participer à MetaMetrics", - "metametrics_description": "Allow MetaMetrics to collect basic usage and diagnostics data to improve our product. You can disable MetaMetrics for this device.", - "data_collection_title": "Data collection for marketing", - "data_collection_description": "We’ll use MetaMetrics to learn how you interact with our marketing communications. We may share relevant news (like product features and other materials).", + "metametrics_description": "Autorisez MetaMetrics à collecter des données d’utilisation et de diagnostic de base afin d’améliorer notre produit. Vous pouvez désactiver MetaMetrics pour cet appareil.", + "data_collection_title": "Collecte de données à des fins de marketing", + "data_collection_description": "Nous utiliserons MetaMetrics pour savoir comment vous interagissez avec nos communications commerciales et pour partager avec vous des informations pertinentes (comme les caractéristiques des produits et d’autres contenus).", "batch_balance_requests_title": "Demandes d’informations concernant le solde de plusieurs comptes", "batch_balance_requests_description": "Nous regroupons vos comptes et demandons à Infura de fournir des informations sur le solde de chacun de vos comptes. Si vous désactivez cette fonction, Infura ne fournira que des informations sur le solde des comptes actifs. Certaines applications décentralisées (dApps) ne fonctionneront pas si vous ne connectez pas votre portefeuille.", "third_party_title": "Obtenir les transactions entrantes", @@ -888,6 +889,13 @@ "delete": "Supprimer", "network_exists": "Ce réseau a déjà été ajouté.", "delete_metrics_title": "Supprimer les données MetaMetrics", + "delete_metrics_description_part_one": "Cela supprimera l’historique des données", + "delete_metrics_description_part_two": "MetaMetrics", + "delete_metrics_description_part_three": "associées à votre portefeuille.", + "delete_metrics_description_before_delete": "Votre portefeuille et vos comptes resteront exactement tels qu’ils sont maintenant après la suppression de ces données. Ce processus peut prendre jusqu’à 30 jours. Veuillez consulter notre", + "delete_metrics_description_after_delete_part_one": "Vous avez entrepris cette action le", + "delete_metrics_description_after_delete_part_two": ". Ce processus peut prendre jusqu’à 30 jours. Veuillez consulter notre", + "delete_metrics_description_privacy_policy": "Politique de confidentialité.", "delete_metrics_button": "Supprimer les données MetaMetrics", "check_status_button": "Vérifier l’état", "delete_metrics_confirm_modal_title": "Voulez-vous supprimer les données MetaMetrics ?", @@ -990,8 +998,27 @@ "security_alerts": "Alertes de sécurité", "security_alerts_desc": "Cette fonctionnalité vous avertit de toute activité malveillante en examinant localement vos demandes de transaction et de signature. Vous devez faire preuve de diligence raisonnable avant d’approuver toute demande. Rien ne garantit que toutes les activités malveillantes seront détectées par cette fonctionnalité. En l’activant, vous acceptez les conditions d’utilisation du fournisseur.", "smart_transactions_opt_in_heading": "Transactions intelligentes", - "smart_transactions_opt_in_desc": "Activez les transactions intelligentes pour profiter de transactions plus fiables et plus sûres, et de frais ajustables sur le réseau principal Ethereum.", - "smart_transactions_learn_more": "En savoir plus." + "smart_transactions_opt_in_desc": "Activez les transactions intelligentes pour profiter de transactions plus fiables et plus sûres sur le réseau principal Ethereum.", + "smart_transactions_learn_more": "En savoir plus.", + "simulation_details": "Estimer les changements de solde", + "simulation_details_description": "Activez cette option pour estimer les changements de solde des transactions avant de les confirmer. Cela ne garantit pas le résultat final de vos transactions. ", + "simulation_details_learn_more": "En savoir plus.", + "aes_crypto_test_form_title": "AES Crypto - Formulaire de test", + "aes_crypto_test_form_description": "Section exclusivement développée pour les tests de bout en bout. Si vous la voyez dans votre application, veuillez le signaler au service d’assistance de MetaMask." + }, + "aes_crypto_test_form": { + "generate_random_salt": "Générer du sel aléatoire", + "salt_bytes_count": "Nombre d’octets du sel", + "generate": "Générer", + "generate_encryption_key": "Générer une clé de chiffrement à partir du mot de passe", + "password": "Mot de passe", + "salt": "Sel", + "encrypt_with_key": "Chiffrer à l’aide d’une clé", + "encrypt": "Chiffrer", + "encryption_key": "Clé de chiffrement", + "data": "Données", + "decrypt_with_key": "Décrypter en utilisant la clé", + "decrypt": "Décrypter" }, "sdk": { "disconnect_title": "Déconnecter tous les sites ?", @@ -1172,6 +1199,15 @@ "account_copied_to_clipboard": "Adresse publique copiée dans le presse-papiers", "share_public_key": "Partager ma clé publique :" }, + "enable_nft-auto-detection": { + "title": "Activer la détection automatique des NFT", + "description": "Autorisez MetaMask à détecter et à afficher vos NFT grâce à la détection automatique des NFT. Vous pourrez ainsi :", + "immediateAccess": "Accéder immédiatement à vos NFT", + "navigate": "Gérer facilement vos actifs numériques", + "dive": "Commencer à utiliser vos NFT", + "allow": "Autoriser", + "notRightNow": "Pas maintenant" + }, "detected_tokens": { "title": "{{tokenCount}} nouveau jeton trouvé", "title_plural": "{{tokenCount}} nouveaux tokens trouvés", @@ -1370,10 +1406,12 @@ "approve": "Approuver", "allow_to_access": "Donner l’autorisation d’accéder à votre", "allow_to_address_access": "Donner à cette adresse l’autorisation d’accéder à votre", + "allow_to_transfer_all": "Autoriser l’accès et le transfert de tous vos", "spend_cap": "Demande de fixer un plafond de dépenses pour votre", "token": "jeton", "nft": "NFT", "you_trust_this_site": "En accordant la permission, vous autorisez le contrat suivant à accéder à vos fonds.", + "you_trust_this_third_party": "Tant que vous n’aurez pas révoqué cette autorisation, l’autre partie pourra accéder à votre portefeuille et transférer sans préavis vos NFT.", "you_trust_this_address": "Faites-vous confiance à cette adresse ? En accordant cette permission, vous autorisez cette adresse à accéder à vos fonds.", "edit_permission": "Modifier l’autorisation", "edit": "Modifier", @@ -1477,6 +1515,8 @@ "tx_review_transfer_from": "Transfert de", "tx_review_unknown": "Méthode inconnue", "tx_review_approve": "Approuver", + "tx_review_increase_allowance": "Augmenter la provision", + "tx_review_set_approval_for_all": "Définir l’approbation pour tous", "sent_ether": "Ether envoyé(s)", "self_sent_ether": "Ether envoyé(s) à vous-même", "received_ether": "Ether reçu(s)", @@ -1498,11 +1538,17 @@ "smart_contract_interaction": "Interaction de contrats intelligents", "swaps_transaction": "Transaction de swap", "approve": "Approuver", + "increase_allowance": "Augmenter la provision", + "set_approval_for_all": "Définir l’approbation pour tous", "hash": "Hachage", "from": "De", "to": "À", "details": "Détails", "amount": "Montant", + "fee": { + "transaction_fee_in_ether": "Frais de transaction", + "transaction_fee_in_usd": "Frais de transaction (USD)" + }, "gas_used": "Gaz utilisé (unités)", "gas_limit": "Limite de gaz (unités)", "gas_price": "Prix du gaz (GWEI)", @@ -1630,6 +1676,8 @@ "you_can": "Ou vous pouvez", "add_network": "ajouter manuellement d’autres réseaux.", "select_network": "Sélectionner un réseau", + "enabled_networks": "Réseaux activés", + "additional_networks": "Réseaux supplémentaires", "show_test_networks": "Afficher les réseaux de test", "deprecated_goerli": "En raison des changements apportés au protocole d’Ethereum, le réseau de test Goerli pourra ne pas fonctionner d’une manière aussi fiable qu’auparavant et deviendra bientôt obsolète.", "network_deprecated_title": "Ce réseau est obsolète", @@ -1898,19 +1946,26 @@ "back_to_safety": "Retour à la sécurité" }, "notifications": { + "staked": "Staké", + "received": "Reçu", + "unstaked": "Déstaké", + "to": "À", + "rate": "Taux (frais inclus)", + "unstaking_requested": "Demande d’annulation du staking", "stake_completed": "Stake terminé", "withdrawal_completed": "Retrait effectué", "unstake_completed": "Annulation du staking terminée", "withdrawal_requested": "La demande de retrait a été envoyée", "stake_ready_to_be_withdrawn": "Stake prêt à être retiré", "swap_completed": "A échangé {{from}} contre {{to}}", + "swap": "Échangé", "sent": "Envoyée à {{address}}", - "received": "Reçue de {{address}}", - "nft_sent": "Sent NFT to {{address}}", - "erc721_sent": "Sent NFT to {{address}}", - "erc1155_sent": "Sent NFT to {{address}}", - "erc721_received": "Received NFT from {{address}}", - "erc1155_received": "Received NFT from {{address}}", + "received_from": "Reçue de {{address}}", + "nft_sent": "A envoyé un NFT à {{address}}", + "erc721_sent": "A envoyé un NFT à {{address}}", + "erc1155_sent": "A envoyé un NFT à {{address}}", + "erc721_received": "A reçu un NFT de {{address}}", + "erc1155_received": "A reçu un NFT de {{address}}", "received_nft": "A reçu un NFT de {{address}}", "pending_title": "Transaction soumise", "pending_deposit_title": "Dépôt en cours !", @@ -1952,6 +2007,7 @@ "wc_description": "Veuillez vérifier l’application", "wallet": "Portefeuille", "web3": "Web3", + "staking_provider": "Fournisseur de services de staking", "empty": { "title": "Rien à voir ici", "message": "C’est ici qu’apparaitront les notifications vous informant qu’une activité a été détectée dans votre portefeuille. " @@ -2561,11 +2617,18 @@ "submit_ticket_5": "Envoyez une demande d’assistance", "submit_ticket_6": "ici.", "submit_ticket_7": "Veuillez inclure le message d’erreur et la capture d’écran.", + "submit_ticket_8": "Envoyez-nous un rapport de bogue", + "submit_ticket_9": "Veuillez donner des détails sur ce qui s’est passé.", + "bug_report_prompt_title": "Dites-nous ce qui s’est passé", + "bug_report_prompt_description": "Ajoutez des détails pour que nous puissions identifier le problème.", + "bug_report_thanks": "Merci. Nous y jetterons un coup d’œil très prochainement.", "save_seedphrase_1": "Si cette erreur persiste,", "save_seedphrase_2": "conservez votre phrase secrète de récupération en lieu sûr", "save_seedphrase_3": "et réinstallez l’application. Remarque : vous ne pouvez PAS restaurer votre portefeuille sans votre phrase secrète de récupération.", "copied_clipboard": "Copié dans le presse-papiers", - "ok": "OK" + "ok": "OK", + "cancel": "Annuler", + "send": "Envoyer" }, "whats_new": { "title": "Nouveautés", @@ -2585,7 +2648,7 @@ "header": "Protection renforcée des transactions", "description_1": "Bénéficiez de taux de réussite plus élevés, d’une protection contre le « front running » et d’une meilleure visibilité grâce aux transactions intelligentes.", "description_2": "Disponible uniquement sur Ethereum. Vous pouvez activer ou désactiver cette option à tout moment dans les paramètres.", - "secondary_button": "Ne pas activer la protection renforcée", + "secondary_button": "Gérer dans les paramètres", "primary_button": "Activer", "learn_more": "En savoir plus.", "benefit_1_1": "Taux de réussite de", @@ -2594,6 +2657,11 @@ "benefit_2_2": "de l’argent", "benefit_3_1": "Mises à jour", "benefit_3_2": "en temps réel" + }, + "transaction_simulation": { + "title": "Estimation des changements de solde", + "description_1": "Vous pouvez désormais connaître le résultat potentiel de vos transactions avant de les effectuer !", + "description_2": "Il s’agit d’une simple simulation, nous ne pouvons donc pas garantir le résultat final. Vous pouvez désactiver cette option à tout moment dans Paramètres > Sécurité et confidentialité." } }, "invalid_network": { @@ -3025,7 +3093,8 @@ "manage_networks": "Gérer les réseaux", "manage_networks_body": "Nous utilisons Infura comme fournisseur d’appel de procédure à distance (APD) pour offrir l’accès le plus fiable et le plus privé possible aux données Ethereum. Vous pouvez choisir votre propre fournisseur d’APD, mais rappelez-vous qu’il aura besoin d’accéder à votre adresse IP et à l’adresse de votre portefeuille Ethereum pour effectuer des transactions. Lisez notre ", "manage_networks_body2": " pour en savoir plus sur la façon dont Infura traite les données.", - "functionality_body": "Comprend les données et la valeur des jetons, les réglages optimaux du gaz, les mises à jour de sécurité et plus encore. Si vous utilisez ces services, votre adresse IP sera partagée avec MetaMask, tout comme lorsque vous visitez un site web.", + "functionality_body": "MetaMask offre des fonctionnalités de base telles que l’affichage des détails des jetons et des paramètres de gaz par le biais de services Internet. Lorsque vous utilisez des services Internet, votre adresse IP est partagée avec le fournisseur de ces services, dans ce cas MetaMask. C’est la même chose que lorsque vous visitez un site web. MetaMask conserve ces données temporairement et ne les vend jamais. Vous pouvez utiliser un VPN ou désactiver ces services, mais cela peut affecter votre expérience avec MetaMask. Lisez notre ", + "functionality_body2": " pour en savoir plus.", "sheet": { "title_off": "Désactiver la fonctionnalité de base", "description_off": "Cela signifie que vous n’optimiserez pas complètement votre temps sur MetaMask. Vous n’aurez pas accès aux fonctions de base (comme les détails des jetons, les réglages optimaux du gaz, etc.).", @@ -3038,5 +3107,16 @@ "turn_off": "Désactiver" } } + }, + "simulation_details": { + "failed": "Une erreur s’est produite lors du chargement de l’estimation.", + "fiat_not_available": "Non disponible", + "incoming_heading": "Vous recevez", + "no_balance_changes": "Aucun changement prévu pour votre portefeuille", + "outgoing_heading": "Vous envoyez", + "reverted": "Cette transaction va probablement échouer", + "title": "Changements estimés", + "tooltip_description": "Les changements estimés représentent ce qui pourrait se produire si vous effectuez cette transaction. Il s’agit juste d’une estimation fournie à des fins d’information.", + "total_fiat": "Total = {{currency}}" } -} \ No newline at end of file +} diff --git a/locales/languages/hi.json b/locales/languages/hi.json index 12711887571..ffe90ef975e 100644 --- a/locales/languages/hi.json +++ b/locales/languages/hi.json @@ -365,17 +365,17 @@ "title": "प्राप्त करें" }, "experience_enhancer_modal": { - "title": "Help us enhance your experience", - "paragraph1a": "In addition to ", - "paragraph1b": ", we'd like to use data (like information from cookies) to learn how you interact with our marketing communications.", + "title": "आपके अनुभव को बेहतर करने में हमारी सहायता करें", + "paragraph1a": "के अलावा ", + "paragraph1b": ", हम यह जानने के लिए डेटा (जैसे कुकीज़ से जानकारी) का उपयोग करना चाहेंगे कि आप हमारे मार्केटिंग कम्यूनिकेशन्स के साथ कैसे इंटरैक्ट करते हैं।", "link": "MetaMetrics", - "paragraph2": "This helps us personalize what we share with you, like:", - "bullet1": "Latest developments", - "bullet2": "Product features", - "bullet3": "Other relevant promotional materials", - "footer": "Remember, we never sell the data you provide and you can opt out any time.", - "accept": "I agree", - "cancel": "No thanks" + "paragraph2": "इससे हमें आपके साथ साझा की जाने वाली चीज़ों को निजीकृत करने में मदद मिलती है, जैसे:", + "bullet1": "लेटेस्ट डेवलप्मेंट्स", + "bullet2": "प्रॉडक्ट फीचर्स", + "bullet3": "अन्य प्रासंगिक प्रमोशनल सामग्री", + "footer": "याद रखें, हम आपके द्वारा प्रदान किया गया डेटा कभी नहीं बेचते हैं और आप किसी भी समय इससे बाहर निकल सकते हैं।", + "accept": "मैं सहमत हूं", + "cancel": "जी नहीं, धन्यवाद" }, "wallet": { "title": "वॉलेट", @@ -413,7 +413,7 @@ "no_tokens": "आपके पास कोई टोकन नहीं है!", "no_nfts_yet": "अभी तक कोई NFT नहीं है", "nfts_autodetection_title": "NFT का पता लगाना", - "nfts_autodetection_desc": "MetaMask को अनुमति दें ताकि OpenSea से NFT का अपनेआप पता लगा ले और आपके MetaMask वॉलेट में दिखे।", + "nfts_autodetection_desc": "MetaMask को ऑटोमेटिक तरीके से NFTs का पता लगाने और आपके वॉलेट में दिखाने के लिए अनुमति दें।", "network_details_check": "नेटवर्क डिटेल्स की जांच", "network_with_chain_id": "चेन ID के साथ वाला नेटवर्क", "chain_list_returned_different_ticker_symbol": "यह टोकन सिंबल आपके द्वारा डाले गए नेटवर्क नाम या चेन ID से मैच नहीं कर रहा है। कई लोकप्रिय टोकन इसी तरह के सिंबल का उपयोग करते हैं, जिनका उपयोग स्कैमर्स आपको बदले में ज़्यादा कीमती टोकन भेजने का झांसा देने के लिए कर सकते हैं। आगे बढ़ने से पहले हर चीज़ अच्छे से वेरीफाई कर लें।", @@ -454,7 +454,7 @@ "display_nft_media_cta": "'NFT मीडिया दिखाएं' को चालू करें", "display_media_nft_warning": "NFT मीडिया और डेटा को दिखाने से आपका आईपी ​​एड्रेस सेंट्रलाइज़्ड सर्वरों के सामने आ सकता है। NFT को सिर्फ तभी इम्पोर्ट करें जब आप इससे जुड़े खतरों को समझते हों।", "nfts_autodetect_title": "NFT ऑटोडिटेक्शन", - "nfts_autodetect_cta": "सेटिंग्स में जाकर 'NFTs को ऑटोडिटेक्ट करें' को चालू करें", + "nfts_autodetect_cta": "NFT ऑटोडिटेक्शन चालू करें", "turn_on_network_check_cta": "नेटवर्क डिटेल्स की जांच को चालू करें", "display_nft_media_cta_new_1": "NFT देखने के लिए, इसमें 'NFT मीडिया दिखाएं' को चालू करें", "display_nft_media_cta_new_2": "सेटिंग्स > सुरक्षा और गोपनीयता।", @@ -520,7 +520,7 @@ "description_title": "MetaMask को बेहतर बनाने में हमारी मदद करें", "description_content_1": "हम MetaMask को बेहतर बनाने के लिए बुनियादी यूसेज डेटा एकत्र करना चाहेंगे। जान लें कि हम आपके द्वारा यहां उपलब्ध कराया गया डेटा कभी नहीं बेचते हैं।", "description_content_2": "जब हम मेट्रिक्स इकट्ठा करते हैं, तो यह हमेशा... रहेगा", - "checkbox": "We'll use this data to learn how you interact with our marketing communications. We may share relavent news (like product features).", + "checkbox": "हम इस डेटा का उपयोग यह जानने के लिए करेंगे कि आप हमारे मार्केटिंग कम्यूनिकेशन्स के साथ कैसे इंटरैक्ट करते हैं। हम प्रासंगिक समाचार (जैसे प्रॉडक्ट फीचर्स) साझा कर सकते हैं।", "action_description_1_prefix": "निजी:", "action_description_2_prefix": "सामान्य:", "action_description_3_prefix": "वैकल्पिक:", @@ -650,7 +650,8 @@ "revoked_all": "सभी खाते निरस्त कर दिए गए।", "accounts_connected": "खाते कनेक्ट किए गए।", "disconnected": "डिसकनेक्ट किया गया।", - "disconnected_all": "सभी अकाउंट्स डिसकनेक्ट किए गए।" + "disconnected_all": "सभी अकाउंट्स डिसकनेक्ट किए गए।", + "nft_detection_enabled": "NFT ऑटोडिटेक्शन चालू किया गया" }, "connect_qr_hardware": { "title": "क्यूआर-आधारित हार्डवेयर वॉलेट के साथ कनेक्ट करें", @@ -671,8 +672,8 @@ "please_wait": "कृपया प्रतीक्षा करें" }, "data_collection_modal": { - "accept": "Okay", - "content": "You turned off data collection for our marketing purposes. This only applies to this device. If you use MetaMask on other devices, make sure to opt out there as well." + "accept": "ठीक है", + "content": "आपने हमारे मार्केटिंग उद्देश्यों के लिए डेटा संग्रहण बंद कर दिया है।  यह केवल इस डिवाइस पर लागू होता है। यदि आप अन्य डिवाइसों पर MetaMask का उपयोग करते हैं, तो वहां भी ऑप्ट आउट करना सुनिश्चित करें।" }, "account_selector": { "prev": "पिछला", @@ -845,9 +846,9 @@ "clear_history_desc": "ब्राउज किए गए अपने पूरे इतिहास को साफ करने के लिए इस विकल्प को चुनें।", "clear_cookies_desc": "अपने ब्राउजर की कुकीज को साफ करने के लिए इस विकल्प को चुनें।", "metametrics_title": "MetaMetrics में हिस्सा लें", - "metametrics_description": "Allow MetaMetrics to collect basic usage and diagnostics data to improve our product. You can disable MetaMetrics for this device.", - "data_collection_title": "Data collection for marketing", - "data_collection_description": "We’ll use MetaMetrics to learn how you interact with our marketing communications. We may share relevant news (like product features and other materials).", + "metametrics_description": "MetaMetrics को हमारे उत्पाद को बेहतर बनाने के लिए बुनियादी यूसेज और डाएगोनोस्टिक्स डेटा एकत्र करने की अनुमति दें। आप इस डिवाइस के लिए MetaMetrics को बंद कर सकते हैं।", + "data_collection_title": "मार्केटिंग के लिए डेटा संग्रह", + "data_collection_description": "आप हमारे मार्केटिंग कम्यूनिकेशन्स के साथ कैसे इंटरैक्ट करते हैं, यह जानने के लिए हम MetaMetrics का उपयोग करेंगे। हम प्रासंगिक समाचार (जैसे प्रॉडक्ट फीचर्स और अन्य सामग्री) साझा कर सकते हैं।", "batch_balance_requests_title": "बैच खाता बैलेन्स रिक्वेस्ट", "batch_balance_requests_description": "हम खातों को बैच करते हैं और तुरंत शेष राशि देखने के लिए Infura से पूछताछ करते हैं। यदि आप इसे बंद कर देते हैं, तो केवल सक्रिय खातों के बारे में पूछताछ की जाएगी। कुछ डीऐप्स वॉलेट कनेक्शन के बिना काम नहीं करेंगे।", "third_party_title": "आवक लेन-देन पाएं", @@ -888,6 +889,13 @@ "delete": "हटाएँ", "network_exists": "यह नेटवर्क पहले से ही जोड़ा जा चुका है।", "delete_metrics_title": "मेटामेट्रिक्स डेटा हटाएं", + "delete_metrics_description_part_one": "यह आपके वॉलेट से जुड़ा ऐतिहासिक", + "delete_metrics_description_part_two": "MetaMetrics", + "delete_metrics_description_part_three": "डेटा हटा देगा", + "delete_metrics_description_before_delete": "इस डेटा को हटा दिए जाने के बाद आपके वॉलेट और अकाउंट ठीक वैसे ही रहेंगे जैसे वे अभी हैं। इस प्रक्रिया में 30 दिन तक लग सकते हैं। हमारी देखें", + "delete_metrics_description_after_delete_part_one": "आपने यह कार्रवाई इस तिथि को शुरू की", + "delete_metrics_description_after_delete_part_two": "। इस प्रक्रिया में 30 दिन तक लग सकते हैं। हमारी", + "delete_metrics_description_privacy_policy": "गोपनीयता नीति देखें।", "delete_metrics_button": "मेटामेट्रिक्स डेटा हटाएं", "check_status_button": "स्थिति जांचें", "delete_metrics_confirm_modal_title": "मेटामेट्रिक्स डेटा हटाएं?", @@ -990,8 +998,27 @@ "security_alerts": "सुरक्षा एलर्ट", "security_alerts_desc": "यह सुविधा स्थानीय रूप से आपके ट्रांसेक्शन और हस्ताक्षर अनुरोधों की समीक्षा करके आपको बुरी नीयत वाली गतिविधि के प्रति एलर्ट करती है। किसी भी अनुरोध को मंजूरी देने से पहले हमेशा पूरी जांच-पड़ताल ज़रूर करें। इस बात की कोई गारंटी नहीं है कि यह सुविधा सभी बुरी नीयत वाली गतिविधि का पता लगा लेगी। इस सुविधा को सक्षम करके आप प्रदाता की उपयोग की शर्तों से सहमत होते हैं।", "smart_transactions_opt_in_heading": "स्मार्ट ट्रांसेक्शन", - "smart_transactions_opt_in_desc": "अधिक विश्वसनीय और सुरक्षित ट्रांसेक्शन के लिए स्मार्ट ट्रांसेक्शन और ETH मेननेट (mainnet) पर एडजस्टेबल फ़ीस चालू करें।", - "smart_transactions_learn_more": "अधिक जानें।" + "smart_transactions_opt_in_desc": "Ethereum Mainnet पर अधिक विश्वसनीय और सुरक्षित ट्रांसेक्शन के लिए स्मार्ट ट्रांसेक्शन चालू करें। $", + "smart_transactions_learn_more": "अधिक जानें।", + "simulation_details": "बैलेंस अमाउंट में बदलावों का अनुमान लगाएं", + "simulation_details_description": "ट्रांसेक्शन को कन्फर्म करने से पहले बैलेंस अमाउंट में बदलाव का अनुमान लगाने के लिए इसे चालू करें। यह आपके ट्रांसेक्शन के फाइनल आउटकम की गारंटी नहीं देता है। ", + "simulation_details_learn_more": "अधिक जानें।", + "aes_crypto_test_form_title": "एईएस क्रिप्टो - टेस्ट फॉर्म", + "aes_crypto_test_form_description": "अनुभाग विशेष रूप से E2E परीक्षण के लिए विकसित किया गया है। यदि यह आपके ऐप में दिखाई दे रहा है, तो कृपया MetaMask सपोर्ट को इसकी रिपोर्ट करें।" + }, + "aes_crypto_test_form": { + "generate_random_salt": "रैंडम सॉल्ट उत्पन्न करें", + "salt_bytes_count": "सॉल्ट बाइट्स की संख्या", + "generate": "उत्पन्न करें", + "generate_encryption_key": "पासवर्ड से एन्क्रिप्शन की उत्पन्न करें", + "password": "पासवर्ड", + "salt": "सॉल्ट", + "encrypt_with_key": "की के साथ एन्क्रिप्ट करें", + "encrypt": "एन्क्रिप्ट करें", + "encryption_key": "एन्क्रिप्शन की", + "data": "डेटा", + "decrypt_with_key": "की के साथ डिक्रिप्ट करें", + "decrypt": "डिक्रिप्ट करें" }, "sdk": { "disconnect_title": "सभी साइटों को डिसकनेक्ट करें?", @@ -1172,6 +1199,15 @@ "account_copied_to_clipboard": "पब्लिक एड्रेस क्लिपबोर्ड पर कॉपी किया गया", "share_public_key": "मेरी सार्वजनिक की साझा करना:" }, + "enable_nft-auto-detection": { + "title": "NFT ऑटोडिटेक्शन चालू करें", + "description": "MetaMask को ऑटोडिटेक्शन के साथ आपके NFT का पता लगाने और प्रदर्शित करने की अनुमति दें। आप यह कर सकेंगे:", + "immediateAccess": "तुरंत अपने NFT तक पहुंचें पा लेंगे", + "navigate": "अपनी डिजिटल एसेट को आसानी से नेविगेट कर लेंगे", + "dive": "अपने NFT का उपयोग करने के लिए सीधे प्रवेश कर लेंगे", + "allow": "अनुमति दें", + "notRightNow": "अभी नहीं" + }, "detected_tokens": { "title": "{{tokenCount}} नया टोकन मिला", "title_plural": "{{tokenCount}} नए टोकन मिले", @@ -1370,10 +1406,12 @@ "approve": "स्वीकृति दें", "allow_to_access": "आपकी एक्सेस करने के लिए अनुमति दें", "allow_to_address_access": "इस पते को आपकी एक्सेस प्रदान करें", + "allow_to_transfer_all": "आपके सभी को एक्सेस और ट्रांसफर करने के लिए अनुमति दें", "spend_cap": "आपके लिए खर्च की सीमा का रिक्वेस्ट", "token": "टोकन", "nft": "NFT", "you_trust_this_site": "अनुमति देकर, आप निम्न थर्ड पार्टी को अपनी धनराशि तक पहुंचने की अनुमति दे रहे हैं।", + "you_trust_this_third_party": "यह किसी थर्ड पार्टी को बिना किसी नोटिस के आपके NFTs को ऐक्सेस करने और ट्रांसफ़र करने की अनुमति देता है जब तक कि आप इसकी ऐक्सेस को हटा नहीं देते।", "you_trust_this_address": "क्या आप इस पता पर भरोसा करते हैं? यह अनुमति प्रदान कर, आप इस पता को अपने फंड तक पहुंचने की अनुमति दे रहे हैं।", "edit_permission": "मंजूरी संपादित करें", "edit": "संपादित करें", @@ -1477,6 +1515,8 @@ "tx_review_transfer_from": "यहां से स्थानांतरित करें", "tx_review_unknown": "अज्ञात विधि", "tx_review_approve": "स्वीकृति दें", + "tx_review_increase_allowance": "भत्ता बढ़ाएं", + "tx_review_set_approval_for_all": "सभी के लिए एप्रूवल सेट करें", "sent_ether": "Ether भेजे गए", "self_sent_ether": "खुद को Ether भेजें", "received_ether": "Ether प्राप्त किया", @@ -1498,11 +1538,17 @@ "smart_contract_interaction": "स्मार्ट अनुबंध संपर्क", "swaps_transaction": "स्वैप का लेन-देन", "approve": "स्वीकृति दें", + "increase_allowance": "भत्ता बढ़ाएं", + "set_approval_for_all": "सभी के लिए एप्रूवल सेट करें", "hash": "हैश", "from": "से", "to": "को", "details": "विवरण", "amount": "रकम", + "fee": { + "transaction_fee_in_ether": "ट्रांसेक्शन फीस", + "transaction_fee_in_usd": "ट्रांसेक्शन फीस (USD)" + }, "gas_used": "इस्तेमाल की गई गैस (यूनिट्स)", "gas_limit": "गैस की सीमा (इकाई)", "gas_price": "गैस की कीमत (GWEI)", @@ -1630,6 +1676,8 @@ "you_can": "या आप", "add_network": "मैन्युअल रूप से अधिक नेटवर्क जोड़ें।", "select_network": "एक नेटवर्क चुनें", + "enabled_networks": "चालू किए गए नेटवर्क", + "additional_networks": "अतिरिक्त नेटवर्क", "show_test_networks": "परीक्षण नेटवर्क दिखाएं", "deprecated_goerli": "Ethereum के प्रोटोकॉल परिवर्तनों के कारण: Goerli परीक्षण नेटवर्क विश्वसनीय रूप से काम नहीं कर सकता है और जल्द ही बंद हो जाएगा।", "network_deprecated_title": "इस नेटवर्क को हटा दिया गया है", @@ -1898,19 +1946,26 @@ "back_to_safety": "सुरक्षा पर वापस जाएं" }, "notifications": { + "staked": "स्टेक किया गया", + "received": "प्राप्त किया गया", + "unstaked": "अनस्टेक किया गया", + "to": "प्रति", + "rate": "दर (शुल्क शामिल है)", + "unstaking_requested": "अनस्टेकिंग का अनुरोध किया गया", "stake_completed": "स्टेक पूरा हुआ", "withdrawal_completed": "विदड्रॉवल पूरा हुआ", "unstake_completed": "अनस्टेक पूरा हुआ", "withdrawal_requested": "विदड्रॉवल का अनुरोध किया गया", "stake_ready_to_be_withdrawn": "स्टेक विदड्रॉ करने के लिए तैयार है", "swap_completed": "{{from}} को {{to}} के लिए स्वैप किया गया", + "swap": "स्वैप किया गया", "sent": "{{address}} पर भेजा गया", - "received": "{{address}} से प्राप्त हुआ", - "nft_sent": "Sent NFT to {{address}}", - "erc721_sent": "Sent NFT to {{address}}", - "erc1155_sent": "Sent NFT to {{address}}", - "erc721_received": "Received NFT from {{address}}", - "erc1155_received": "Received NFT from {{address}}", + "received_from": "{{address}} से प्राप्त हुआ", + "nft_sent": "NFT को {{address}} पर भेजा गया", + "erc721_sent": "NFT को {{address}} पर भेजा गया", + "erc1155_sent": "NFT को {{address}} पर भेजा गया", + "erc721_received": "NFT को {{address}} से प्राप्त किया गया", + "erc1155_received": "NFT को {{address}} से प्राप्त किया गया", "received_nft": "NFT को {{address}} से प्राप्त किया गया", "pending_title": "लेन-देन सबमिट किया गया", "pending_deposit_title": "प्रगति में जमा करें!", @@ -1952,6 +2007,7 @@ "wc_description": "कृपया एप्लिकेशन को जांचें", "wallet": "वॉलेट", "web3": "Web3", + "staking_provider": "स्टेकिंग प्रदाता", "empty": { "title": "यहाँ देखने के लिए कुछ नहीं है।", "message": "यहाँ पर आप अपने वॉलेट में गतिविधि होने पर नोटिफिकेशंस पा सकते हैं। " @@ -2561,11 +2617,18 @@ "submit_ticket_5": "एक टिकट सबमिट करें", "submit_ticket_6": "यहां।", "submit_ticket_7": "कृपया त्रुटि संदेश और स्क्रीनशॉट को शामिल करें।", + "submit_ticket_8": "हमें एक बग रिपोर्ट भेजें।", + "submit_ticket_9": "कृपया जो हुआ उसके बारे में विवरण शामिल करें।", + "bug_report_prompt_title": "हमें बताएं कि क्या हुआ", + "bug_report_prompt_description": "विवरण जोड़ें ताकि हम पता लगा सकें कि क्या गलत हुआ।", + "bug_report_thanks": "धन्यवाद! हम जल्द ही नज़र डालेंगे।", "save_seedphrase_1": "यदि यह त्रुटि कायम रहती है,", "save_seedphrase_2": "अपने सीक्रेट रिकवरी फ्रेज को सहेजें", "save_seedphrase_3": "और ऐप को फिर से स्थापित करें। नोट: अपने सीक्रेट रिकवरी फ्रेज के बिना आप अपने वॉलेट को बहाल नहीं कर सकते हैं।", "copied_clipboard": "क्लिपबोर्ड पर नकल ", - "ok": "ठीक है" + "ok": "ठीक है", + "cancel": "कैंसिल करें", + "send": "भेजें" }, "whats_new": { "title": "नया क्या है", @@ -2585,7 +2648,7 @@ "header": "उन्नत ट्रांसेक्शन सुरक्षा", "description_1": "स्मार्ट ट्रांसेक्शन के साथ उच्च सफलता दर, फ्रंटरनिंग सुरक्षा और बेहतर दृश्यता अनलॉक करें।", "description_2": "केवल Ethereum पर उपलब्ध है। सेटिंग्स में किसी भी समय चालू करें या बंद करें।", - "secondary_button": "उन्नत सुरक्षा चालू न करें", + "secondary_button": "सेटिंग्स में मैनेज करें", "primary_button": "चालू करें", "learn_more": "अधिक जानें।", "benefit_1_1": "99.5% सफलता", @@ -2594,6 +2657,11 @@ "benefit_2_2": "बचाता है", "benefit_3_1": "रियल टाइम", "benefit_3_2": "अपडेट" + }, + "transaction_simulation": { + "title": "अनुमानित बैलेंस अमाउंट में बदलाव", + "description_1": "अब आप अपने ट्रांसेक्शन करने से पहले उनका पोटेंशियल आउटकम देख सकते हैं!", + "description_2": "यह केवल एक सिमुलेशन है, इसलिए हम फाइनल आउटकम की गारंटी नहीं दे सकते। आप इसे Settings > Security & Privacy में जाकर किसी भी समय बंद कर सकते हैं।" } }, "invalid_network": { @@ -3025,7 +3093,8 @@ "manage_networks": "नेटवर्क मैनेज करें", "manage_networks_body": "हम अपने रिमोट प्रोसीजर कॉल (RPC) प्रोवाइडर के रूप में Infura का इस्तेमाल करते हैं ताकि हम Ethereum डेटा तक सबसे विश्वसनीय और निजी ऐक्सेस प्रदान कर सकें। आप अपना स्वयं का RPC चुन सकते हैं, लेकिन याद रखें कि ट्रांसेक्शन करने के लिए कोई भी RPC आपका IP एड्रेस और Ethereum वॉलेट प्राप्त करेगा। ", "manage_networks_body2": " Infura डेटा को कैसे मैनेज करता है, इस बारे में अधिक जानने के लिए हमारी पढ़ें।", - "functionality_body": "इसमें टोकन डेटा और मूल्य, ऑप्टीमल गैस सेटिंग्स, सिक्योरिटी अपडेट और बहुत कुछ शामिल है। इन सेवाओं का उपयोग करने से आपका आईपी ​​एड्रेस MetaMask के साथ शेयर हो जाता है, ठीक उसी तरह जब आप किसी वेबसाइट पर जाते हैं।", + "functionality_body": "MetaMask इंटरनेट सेवाओं के माध्यम से टोकन विवरण और गैस सेटिंग्स जैसी बुनियादी सुविधाएं प्रदान करता है। जब आप इंटरनेट सेवाओं का उपयोग करते हैं, तो आपका आईपी ​​एड्रेस साझा किया जाता है, इस मामले में MetaMask के साथ। यह बिल्कुल वैसा ही है जैसे आप किसी वेबसाइट पर जाते हैं। MetaMask इस डेटा का अस्थायी रूप से उपयोग करता है और कभी भी आपका डेटा नहीं बेचता है। आप वीपीएन का उपयोग कर सकते हैं या इन सेवाओं को बंद कर सकते हैं, लेकिन यह आपके MetaMask अनुभव को प्रभावित कर सकता है। हमारी पढ़ें।", + "functionality_body2": " अधिक जानने के लिए।", "sheet": { "title_off": "बेसिक फंक्शनलिटी को बंद करें", "description_off": "इसका मतलब यह है कि आप MetaMask पर अपना समय सबसे अच्छे तरीके से इस्तेमाल नहीं कर पाएंगे। बेसिक फीचर्स (जैसे, टोकन विवरण, ऑप्टीमल गैस सेटिंग्स और अन्य) आपके लिए उपलब्ध नहीं होंगे।", @@ -3038,5 +3107,16 @@ "turn_off": "बंद करें" } } + }, + "simulation_details": { + "failed": "आपका एस्टीमेशन लोड करने में गड़बड़ी हुई।", + "fiat_not_available": "उपलब्ध नहीं है", + "incoming_heading": "आप प्राप्त करते हैं", + "no_balance_changes": "आपके वॉलेट के लिए किसी बदलाव का प्रेडिक्शन नहीं किया गया है", + "outgoing_heading": "आप भेजते हैं", + "reverted": "यह ट्रांसेक्शन विफल हो सकता है", + "title": "अनुमानित बदलाव", + "tooltip_description": "अगर आप यह ट्रांसेक्शन करते हैं तो अनुमानित परिवर्तन हो सकते हैं। यह सिर्फ एक प्रेडिक्शन है, कोई गारंटी नहीं।", + "total_fiat": "कुल = {{currency}}" } -} \ No newline at end of file +} diff --git a/locales/languages/id.json b/locales/languages/id.json index 7078414b319..835cb3453c3 100644 --- a/locales/languages/id.json +++ b/locales/languages/id.json @@ -365,17 +365,17 @@ "title": "Terima" }, "experience_enhancer_modal": { - "title": "Help us enhance your experience", - "paragraph1a": "In addition to ", - "paragraph1b": ", we'd like to use data (like information from cookies) to learn how you interact with our marketing communications.", + "title": "Bantu kami meningkatkan pengalaman Anda", + "paragraph1a": "Sebagai tambahan ", + "paragraph1b": ", kami ingin menggunakan data (seperti informasi dari cookie) untuk mempelajari cara Anda berinteraksi dengan komunikasi pemasaran kami.", "link": "MetaMetrics", - "paragraph2": "This helps us personalize what we share with you, like:", - "bullet1": "Latest developments", - "bullet2": "Product features", - "bullet3": "Other relevant promotional materials", - "footer": "Remember, we never sell the data you provide and you can opt out any time.", - "accept": "I agree", - "cancel": "No thanks" + "paragraph2": "Ini membantu kami mempersonalisasi hal yang kami bagikan kepada Anda, seperti:", + "bullet1": "Perkembangan terkini", + "bullet2": "Fitur produk", + "bullet3": "Materi promosi lain yang relevan", + "footer": "Ingat, kami tidak pernah menjual data yang Anda berikan dan Anda dapat memilih untuk keluar setiap saat.", + "accept": "Saya setuju", + "cancel": "Tidak, terima kasih" }, "wallet": { "title": "Dompet", @@ -413,7 +413,7 @@ "no_tokens": "Anda tidak memiliki token!", "no_nfts_yet": "Belum ada NFT", "nfts_autodetection_title": "Deteksi NFT", - "nfts_autodetection_desc": "Izinkan MetaMask untuk mendeteksi NFT dari OpenSea secara otomatis dan ditampilkan di dompet MetaMask Anda.", + "nfts_autodetection_desc": "Izinkan MetaMask mendeteksi dan menampilkan NFT di dompet Anda secara otomatis.", "network_details_check": "Pemeriksaan detail jaringan", "network_with_chain_id": "Jaringan dengan ID chain", "chain_list_returned_different_ticker_symbol": "Simbol token ini tidak cocok dengan nama jaringan atau ID chain yang dimasukkan. Banyak token populer menggunakan simbol serupa, yang dapat digunakan penipu untuk mengelabui Anda agar mengirimkan token yang lebih berharga sebagai gantinya. Pastikan untuk memverifikasi semuanya sebelum melanjutkan.", @@ -454,7 +454,7 @@ "display_nft_media_cta": "Aktifkan Tampilkan media NFT", "display_media_nft_warning": "Menampilkan media dan data NFT dapat mengekspos alamat IP ke server terpusat. Impor NFT hanya jika Anda memahami risiko yang terlibat.", "nfts_autodetect_title": "Autodeteksi NFT", - "nfts_autodetect_cta": "Aktifkan Autodeteksi NFT di Pengaturan", + "nfts_autodetect_cta": "Aktifkan autodeteksi NFT", "turn_on_network_check_cta": "Aktifkan pemeriksaan detail jaringan", "display_nft_media_cta_new_1": "Untuk melihat NFT, aktifkan Tampilkan media NFT di", "display_nft_media_cta_new_2": "Pengaturan > Keamanan dan Privasi.", @@ -520,7 +520,7 @@ "description_title": "Bantu kami meningkatkan MetaMask", "description_content_1": "Kami ingin mengumpulkan data penggunaan dasar untuk meningkatkan MetaMask. Pahami bahwa kami tidak pernah menjual data yang Anda berikan di sini.", "description_content_2": "Saat kami mengumpulkan metrik, maka akan selalu...", - "checkbox": "We'll use this data to learn how you interact with our marketing communications. We may share relavent news (like product features).", + "checkbox": "Kami akan menggunakan data ini untuk mempelajari cara Anda berinteraksi dengan komunikasi pemasaran kami. Kami mungkin akan membagikan berita terkait (seperti fitur produk).", "action_description_1_prefix": "Pribadi:", "action_description_2_prefix": "Umum:", "action_description_3_prefix": "Opsional:", @@ -650,7 +650,8 @@ "revoked_all": "Semua akun dicabut.", "accounts_connected": "akun terhubung.", "disconnected": "koneksi terputus.", - "disconnected_all": "Semua akun terputus koneksinya." + "disconnected_all": "Semua akun terputus koneksinya.", + "nft_detection_enabled": "Autodeteksi NFT diaktifkan" }, "connect_qr_hardware": { "title": "Hubungkan dompet perangkat keras berbasis QR", @@ -671,8 +672,8 @@ "please_wait": "Harap tunggu" }, "data_collection_modal": { - "accept": "Okay", - "content": "You turned off data collection for our marketing purposes. This only applies to this device. If you use MetaMask on other devices, make sure to opt out there as well." + "accept": "Oke", + "content": "Anda menonaktifkan pengumpulan data untuk tujuan pemasaran kami. Ini hanya berlaku untuk perangkat ini. Jika Anda menggunakan MetaMask di perangkat lain, pastikan untuk keluar terlebih dahulu." }, "account_selector": { "prev": "SEBELUMNYA", @@ -845,9 +846,9 @@ "clear_history_desc": "Pilih opsi ini untuk menghapus seluruh riwayat penelusuran Anda.", "clear_cookies_desc": "Pilih opsi ini untuk menghapus cookie browser Anda.", "metametrics_title": "Berpartisipasi dalam MetaMetrics", - "metametrics_description": "Allow MetaMetrics to collect basic usage and diagnostics data to improve our product. You can disable MetaMetrics for this device.", - "data_collection_title": "Data collection for marketing", - "data_collection_description": "We’ll use MetaMetrics to learn how you interact with our marketing communications. We may share relevant news (like product features and other materials).", + "metametrics_description": "Izinkan MetaMetrics mengumpulkan data penggunaan dasar dan diagnostik untuk meningkatkan produk kami. Anda dapat menonaktifkan MetaMetrics untuk perangkat ini.", + "data_collection_title": "Pengumpulan data untuk pemasaran", + "data_collection_description": "Kami akan menggunakan MetaMetrics untuk mempelajari cara Anda berinteraksi dengan komunikasi pemasaran kami. Kami mungkin akan membagikan berita yang relevan (seperti fitur produk dan materi lainnya).", "batch_balance_requests_title": "Kelompokkan permintaan saldo akun", "batch_balance_requests_description": "Kami mengelompokkan akun dan meminta Infura untuk menunjukkan saldo Anda secara responsif. Jika Anda menonaktifkannya, hanya akun aktif yang akan diminta. Beberapa aplikasi terdesentralisasi (dApp) tidak akan berfungsi kecuali dompet Anda terhubung.", "third_party_title": "Dapatkan transaksi masuk", @@ -888,6 +889,13 @@ "delete": "Hapus", "network_exists": "Jaringan ini telah ditambahkan.", "delete_metrics_title": "Hapus data MetaMetrics", + "delete_metrics_description_part_one": "Ini akan menghapus riwayat", + "delete_metrics_description_part_two": "MetaMetrics", + "delete_metrics_description_part_three": "data yang terhubung dengan dompet Anda.", + "delete_metrics_description_before_delete": "Dompet dan akun Anda akan tetap sama seperti sekarang setelah data ini dihapus. Proses ini dapat memerlukan waktu hingga 30 hari. Lihat", + "delete_metrics_description_after_delete_part_one": "Anda memulai tindakan ini pada", + "delete_metrics_description_after_delete_part_two": ". Proses ini bisa memerlukan waktu hingga 30 hari. Lihat", + "delete_metrics_description_privacy_policy": "Kebijakan Privasi.", "delete_metrics_button": "Hapus data MetaMetrics", "check_status_button": "Periksa Status", "delete_metrics_confirm_modal_title": "Hapus data MetaMetrics?", @@ -990,8 +998,27 @@ "security_alerts": "Peringatan keamanan", "security_alerts_desc": "Fitur ini memperingatkan Anda tentang aktivitas berbahaya dengan meninjau permintaan transaksi dan tanda tangan secara lokal. Selalu lakukan uji tuntas sendiri sebelum menyetujui permintaan. Tidak ada jaminan bahwa fitur ini akan mendeteksi semua aktivitas berbahaya. Dengan mengaktifkan fitur ini, Anda menyetujui persyaratan penggunaan penyedia.", "smart_transactions_opt_in_heading": "Transaksi Pintar", - "smart_transactions_opt_in_desc": "Aktifkan Transaksi Pintar untuk transaksi yang lebih andal dan aman, serta biaya yang dapat disesuaikan di ETH Mainnet.", - "smart_transactions_learn_more": "Selengkapnya." + "smart_transactions_opt_in_desc": "Aktifkan Transaksi Pintar untuk transaksi yang lebih andal dan aman di Mainnet Ethereum.", + "smart_transactions_learn_more": "Selengkapnya.", + "simulation_details": "Estimasikan perubahan saldo", + "simulation_details_description": "Aktifkan ini untuk mengestimasikan perubahan saldo transaksi sebelum Anda mengonfirmasikannya. Ini tidak menjamin hasil akhir transaksi Anda. ", + "simulation_details_learn_more": "Selengkapnya.", + "aes_crypto_test_form_title": "Kripto AES - Formulir Uji", + "aes_crypto_test_form_description": "Bagian khusus dikembangkan untuk pengujian E2E. Apabila terlihat di aplikasi, laporkan ke dukungan MetaMask." + }, + "aes_crypto_test_form": { + "generate_random_salt": "Buat Salt Acak", + "salt_bytes_count": "Jumlah byte salt yang dihitung", + "generate": "Buat", + "generate_encryption_key": "Buat kunci enkripsi dari kata sandi", + "password": "Kata sandi", + "salt": "Salt", + "encrypt_with_key": "Enkripsikan dengan kunci", + "encrypt": "Enkripsikan", + "encryption_key": "Kunci Enkripsi", + "data": "Data", + "decrypt_with_key": "Dekripsikan dengan kunci", + "decrypt": "Dekripsikan" }, "sdk": { "disconnect_title": "Putuskan koneksi semua situs?", @@ -1172,6 +1199,15 @@ "account_copied_to_clipboard": "Alamat publik disalin ke papan klip", "share_public_key": "Bagikan kunci publik saya:" }, + "enable_nft-auto-detection": { + "title": "Aktifkan autodeteksi NFT", + "description": "Izinkan MetaMask mendeteksi dan menampilkan NFT dengan autodeteksi. Anda akan dapat:", + "immediateAccess": "Mengakses NFT secara cepat", + "navigate": "Menavigasikan aset digital dengan mudah", + "dive": "Menggunakan NFT secara langsung", + "allow": "Izinkan", + "notRightNow": "Tidak sekarang" + }, "detected_tokens": { "title": "{{tokenCount}} token baru ditemukan", "title_plural": "{{tokenCount}} token baru ditemukan", @@ -1370,10 +1406,12 @@ "approve": "Setujui", "allow_to_access": "Berikan izin untuk mengakses", "allow_to_address_access": "Berikan alamat ini untuk mengakses", + "allow_to_transfer_all": "Berikan izin untuk mengakses dan mentransfer seluruh", "spend_cap": "Permintaan batas penggunaan untuk", "token": "token", "nft": "NFT", "you_trust_this_site": "Dengan memberikan izin, Anda mengizinkan pihak ketiga berikut untuk mengakses dana Anda.", + "you_trust_this_third_party": "Hal ini memungkinkan pihak ketiga untuk mengakses dan mentransfer NFT tanpa pemberitahuan lebih lanjut sampai Anda mencabut aksesnya.", "you_trust_this_address": "Apakah Anda memercayai alamat ini? Dengan memberikan izin, Anda mengizinkan alamat ini untuk mengakses dana Anda.", "edit_permission": "Edit izin", "edit": "Edit", @@ -1477,6 +1515,8 @@ "tx_review_transfer_from": "Transfer Dari", "tx_review_unknown": "Metode Tidak Dikenal", "tx_review_approve": "Setujui", + "tx_review_increase_allowance": "Tingkatkan Persetujuan", + "tx_review_set_approval_for_all": "Atur Persetujuan Untuk Semua", "sent_ether": "Mengirim Ether", "self_sent_ether": "Mengirim Ether ke Diri Sendiri", "received_ether": "Menerima Ether", @@ -1498,11 +1538,17 @@ "smart_contract_interaction": "Interaksi kontrak cerdas", "swaps_transaction": "Transaksi swap", "approve": "Setujui", + "increase_allowance": "Tingkatkan Persetujuan", + "set_approval_for_all": "Atur Persetujuan Untuk Semua", "hash": "Hash", "from": "Dari", "to": "Ke", "details": "Detail", "amount": "Jumlah", + "fee": { + "transaction_fee_in_ether": "Biaya Transaksi", + "transaction_fee_in_usd": "Biaya Transaksi (USD)" + }, "gas_used": "Gas yang Digunakan (Unit)", "gas_limit": "Batas Gas (Unit)", "gas_price": "Harga Gas (GWEI)", @@ -1630,6 +1676,8 @@ "you_can": "Atau Anda dapat", "add_network": "menambahkan lebih banyak jaringan secara manual.", "select_network": "Pilih jaringan", + "enabled_networks": "Jaringan yang diaktifkan", + "additional_networks": "Jaringan tambahan", "show_test_networks": "Tampilkan jaringan pengujian", "deprecated_goerli": "Sehubungan dengan perubahan protokol Ethereum: Jaringan uji Goerli mungkin tidak dapat beroperasi dengan baik dan akan segera dihentikan.", "network_deprecated_title": "Jaringan ini tidak digunakan lagi", @@ -1898,19 +1946,26 @@ "back_to_safety": "Kembali ke keamanan" }, "notifications": { + "staked": "Di-stake", + "received": "Diterima", + "unstaked": "Stake dibatalkan", + "to": "Ke", + "rate": "Tarif (termasuk biaya)", + "unstaking_requested": "Permintaan pembatalan stake", "stake_completed": "Stake selesai", "withdrawal_completed": "Penarikan selesai", "unstake_completed": "Pembatalan stake selesai", "withdrawal_requested": "Penarikan diminta", "stake_ready_to_be_withdrawn": "Stake siap untuk ditarik", "swap_completed": "Swap {{from}} dengan {{to}}", + "swap": "Ditukar", "sent": "Dikirim ke {{address}}", - "received": "Diterima dari {{address}}", - "nft_sent": "Sent NFT to {{address}}", - "erc721_sent": "Sent NFT to {{address}}", - "erc1155_sent": "Sent NFT to {{address}}", - "erc721_received": "Received NFT from {{address}}", - "erc1155_received": "Received NFT from {{address}}", + "received_from": "Diterima dari {{address}}", + "nft_sent": "Mengirim NFT ke {{address}}", + "erc721_sent": "Mengirim NFT ke {{address}}", + "erc1155_sent": "Mengirim NFT ke {{address}}", + "erc721_received": "Menerima NFT dari {{address}}", + "erc1155_received": "Menerima NFT dari {{address}}", "received_nft": "Menerima NFT dari {{address}}", "pending_title": "Transaksi dikirim", "pending_deposit_title": "Deposit sedang diproses!", @@ -1952,6 +2007,7 @@ "wc_description": "Harap periksa permohonan ini", "wallet": "Dompet", "web3": "Web3", + "staking_provider": "Penyedia Stake", "empty": { "title": "Tak ada apa pun di sini", "message": "Di sinilah Anda dapat menemukan notifikasi saat terjadi aktivitas di dompet. " @@ -2561,11 +2617,18 @@ "submit_ticket_5": "Kirimkan tiket", "submit_ticket_6": "di sini.", "submit_ticket_7": "Harap sertakan pesan kesalahan dan tangkapan layar.", + "submit_ticket_8": "Kirimkan laporan masalah", + "submit_ticket_9": "Harap sertakan detail tentang hal yang terjadi.", + "bug_report_prompt_title": "Beri tahu kami hal yang terjadi", + "bug_report_prompt_description": "Tambahkan detail sehingga kami dapat mengetahui apa yang salah.", + "bug_report_thanks": "Terima kasih! Kami akan segera memeriksanya.", "save_seedphrase_1": "Jika kesalahan masih berlanjut,", "save_seedphrase_2": "simpan Frasa Pemulihan Rahasia", "save_seedphrase_3": "dan instal ulang aplikasi. Catatan: Anda TIDAK dapat memulihkan dompet Anda tanpa Frasa Pemulihan Rahasia.", "copied_clipboard": "Disalin ke papan klip", - "ok": "Oke" + "ok": "Oke", + "cancel": "Batalkan", + "send": "Kirim" }, "whats_new": { "title": "Yang baru", @@ -2585,7 +2648,7 @@ "header": "Peningkatan Perlindungan Transaksi", "description_1": "Raih tingkat keberhasilan yang lebih tinggi, perlindungan frontrunning, dan visibilitas yang lebih baik dengan Transaksi Pintar.", "description_2": "Hanya tersedia di Ethereum. Aktifkan atau nonaktifkan setiap saat di pengaturan.", - "secondary_button": "Jangan aktifkan peningkatan perlindungan", + "secondary_button": "Kelola di pengaturan", "primary_button": "Aktifkan", "learn_more": "Selengkapnya.", "benefit_1_1": "Keberhasilan 99,5%", @@ -2594,6 +2657,11 @@ "benefit_2_2": "uang", "benefit_3_1": "Waktu nyata", "benefit_3_2": "pembaruan" + }, + "transaction_simulation": { + "title": "Estimasi perubahan saldo", + "description_1": "Kini Anda dapat melihat potensi hasil transaksi sebelum melakukannya!", + "description_2": "Ini hanyalah simulasi, jadi kami tidak bisa menjamin hasil akhirnya. Anda dapat menonaktifkannya kapan saja di Pengaturan > Keamanan & Privasi." } }, "invalid_network": { @@ -3025,7 +3093,8 @@ "manage_networks": "Kelola jaringan", "manage_networks_body": "Kami menggunakan Infura sebagai penyedia panggilan prosedur jarak jauh (RPC) untuk menawarkan akses paling andal dan pribadi ke data Ethereum sebisa mungkin. Anda dapat memilih RPC sendiri, akan tetapi ingatlah bahwa RPC apa pun akan menerima alamat IP dan dompet Ethereum Anda untuk melakukan transaksi. Baca ", "manage_networks_body2": " untuk selengkapnya seputar cara Infura menangani data.", - "functionality_body": "Meliputi nilai dan data token, pengaturan gas optimal, pembaruan keamanan, dan lainnya. MetaMask akan mengetahui alamat IP Anda saat menggunakan layanan ini, seperti halnya saat mengunjungi situs web.", + "functionality_body": "MetaMask menawarkan fitur dasar seperti detail token dan pengaturan gas melalui layanan internet. Alamat IP dibagikan saat menggunakan layanan internet, dalam hal ini kepada MetaMask. Ini sama seperti saat Anda mengunjungi situs web mana pun. MetaMask menggunakan data ini untuk sementara dan tidak akan pernah menjual data Anda. Anda dapat menggunakan VPN atau menonaktifkan layanan ini, akan tetapi hal ini dapat memengaruhi pengalaman dalam menggunakan MetaMask. Baca ", + "functionality_body2": " kami untuk selengkapnya.", "sheet": { "title_off": "Nonaktifkan fungsionalitas dasar", "description_off": "Artinya, Anda tidak akan benar-benar mengoptimalkan waktu di MetaMask. Fitur dasar (seperti detail token, pengaturan gas optimal, dan lainnya) tidak akan tersedia untuk Anda.", @@ -3038,5 +3107,16 @@ "turn_off": "Nonaktifkan" } } + }, + "simulation_details": { + "failed": "Terjadi kesalahan saat memuat estimasi Anda.", + "fiat_not_available": "Tidak Tersedia", + "incoming_heading": "Anda menerima", + "no_balance_changes": "Tidak ada perubahan yang terprediksi untuk dompet Anda", + "outgoing_heading": "Anda mengirim", + "reverted": "Transaksi ini kemungkinan besar akan gagal", + "title": "Estimasi perubahan", + "tooltip_description": "Estimasi perubahan merupakan hal yang mungkin terjadi jika Anda melakukan transaksi ini. Ini hanyalah prediksi, bukan jaminan.", + "total_fiat": "Total = {{currency}}" } -} \ No newline at end of file +} diff --git a/locales/languages/ja.json b/locales/languages/ja.json index 85fa977f6b6..631dcfc7ebf 100644 --- a/locales/languages/ja.json +++ b/locales/languages/ja.json @@ -365,17 +365,17 @@ "title": "受取" }, "experience_enhancer_modal": { - "title": "Help us enhance your experience", - "paragraph1a": "In addition to ", - "paragraph1b": ", we'd like to use data (like information from cookies) to learn how you interact with our marketing communications.", + "title": "エクスペリエンスの改善にご協力ください", + "paragraph1a": "さらに、", + "paragraph1b": "ユーザーによる当社のマーケティングコミュニケーションとのインタラクションについて把握するために、データ (Cookieからの情報など) を使用できればと思います。", "link": "MetaMetrics", - "paragraph2": "This helps us personalize what we share with you, like:", - "bullet1": "Latest developments", - "bullet2": "Product features", - "bullet3": "Other relevant promotional materials", - "footer": "Remember, we never sell the data you provide and you can opt out any time.", - "accept": "I agree", - "cancel": "No thanks" + "paragraph2": "これは、次のようなお伝えする情報のカスタマイズに役立ちます:", + "bullet1": "最新情報", + "bullet2": "製品の機能", + "bullet3": "その他関連プロモーション資料", + "footer": "ユーザーから提供されたデータが販売されることは一切なく、いつでもオプトアウトできます。", + "accept": "同意する", + "cancel": "いいえ、結構です" }, "wallet": { "title": "ウォレット", @@ -413,7 +413,7 @@ "no_tokens": "トークンがありません!", "no_nfts_yet": "まだNFTがありません", "nfts_autodetection_title": "NFTの検出", - "nfts_autodetection_desc": "MetaMaskがOpenSeaからNFTを自動検出し、MetaMaskウォレットに表示できるように許可してください。", + "nfts_autodetection_desc": "MetaMaskによるウォレット内のNFTの自動検出と表示を許可します。", "network_details_check": "ネットワーク情報の確認", "network_with_chain_id": "チェーンIDを持つネットワーク", "chain_list_returned_different_ticker_symbol": "このトークンシンボルは、入力されたネットワーク名またはチェーンIDと一致しません。人気のトークンの多くはシンボルが似ているため、詐欺師がそれを利用してより価値の高いトークンを送り返すように仕向ける可能性があります。続行する前にすべてを確認してください。", @@ -454,7 +454,7 @@ "display_nft_media_cta": "NFTメディアの表示をオンにする", "display_media_nft_warning": "NFTのメディアとデータを表示した場合、IPアドレスが集中型のサーバーに公開される可能性があります。関連するリスクを理解できている場合のみ、NFTをインポートしてください。", "nfts_autodetect_title": "NFTの自動検出", - "nfts_autodetect_cta": "設定でNFTの検出をオンにする", + "nfts_autodetect_cta": "NFTの自動検出を有効にする", "turn_on_network_check_cta": "ネットワーク情報の確認をオンにする", "display_nft_media_cta_new_1": "NFTを表示するには、次の場所で「NFTメディアを表示」を有効にしてください", "display_nft_media_cta_new_2": "「設定」>「セキュリティとプライバシー」。", @@ -520,7 +520,7 @@ "description_title": "MetaMaskの改善にご協力ください", "description_content_1": "MetaMaskの改善を目的に、基本的な使用状況データを収集したいと思います。ここで提供されるデータが販売されることはありません。", "description_content_2": "指標を収集する際、常に次の条件が適用されます...", - "checkbox": "We'll use this data to learn how you interact with our marketing communications. We may share relavent news (like product features).", + "checkbox": "このデータは、ユーザーによる当社のマーケティングコミュニケーションとのインタラクションを把握するために使用されます。また、関連ニュースをお伝えする場合もあります (製品の機能など)。", "action_description_1_prefix": "非公開:", "action_description_2_prefix": "一般:", "action_description_3_prefix": "任意:", @@ -650,7 +650,8 @@ "revoked_all": "すべてのアカウントが取り消されました。", "accounts_connected": "アカウントが接続されました。", "disconnected": "接続が解除されました。", - "disconnected_all": "すべてのアカウントの接続が解除されました。" + "disconnected_all": "すべてのアカウントの接続が解除されました。", + "nft_detection_enabled": "NFTの自動検出が有効になりました" }, "connect_qr_hardware": { "title": "QRベースのハードウェアウォレットを接続", @@ -671,8 +672,8 @@ "please_wait": "お待ちください" }, "data_collection_modal": { - "accept": "Okay", - "content": "You turned off data collection for our marketing purposes. This only applies to this device. If you use MetaMask on other devices, make sure to opt out there as well." + "accept": "OK", + "content": "マーケティング目的のデータ収集をオフにしました。これはこのデバイスにのみ適用されます。MetaMaskを他のデバイスで使用する場合は、そのデバイスでもオプトアウトしてください。" }, "account_selector": { "prev": "前へ", @@ -845,9 +846,9 @@ "clear_history_desc": "ブラウザの履歴をすべて消去するにはこのオプションを選択します。", "clear_cookies_desc": "ブラウザのCookieを消去するにはこのオプションを選択します。", "metametrics_title": "MetaMetricsに参加", - "metametrics_description": "Allow MetaMetrics to collect basic usage and diagnostics data to improve our product. You can disable MetaMetrics for this device.", - "data_collection_title": "Data collection for marketing", - "data_collection_description": "We’ll use MetaMetrics to learn how you interact with our marketing communications. We may share relevant news (like product features and other materials).", + "metametrics_description": "製品の改善を目的とするMetaMetricsによる基本的な使用状況および診断データの収集を許可してください。このデバイスのMetaMetricsを無効にすることができます。", + "data_collection_title": "マーケティング目的のデータ収集", + "data_collection_description": "当社はMetaMetricsを使用して、ユーザーによる当社のマーケティングコミュニケーションとのインタラクションを把握します。また、関連ニュースをお伝えする場合もあります (製品の機能、その他資料など)。", "batch_balance_requests_title": "アカウント残高の一括リクエスト", "batch_balance_requests_description": "当社は残高を素早く表示できるよう、アカウントをまとめてInfuraにクエリを送ります。この機能をオフにすると、アクティブなアカウントのみクエリの対象となります。DAppによっては、ウォレットを接続しないと機能しないものもあります。", "third_party_title": "受信トランザクションを取得", @@ -888,6 +889,13 @@ "delete": "削除", "network_exists": "このネットワークはすでに追加されています。", "delete_metrics_title": "MetaMetricsデータを削除", + "delete_metrics_description_part_one": "これにより、ウォレットに関連付けられている過去の", + "delete_metrics_description_part_two": "MetaMetrics", + "delete_metrics_description_part_three": "データが削除されます。", + "delete_metrics_description_before_delete": "このデータが削除されてもウォレットとアカウントに変化はありません。このプロセスには最長30日かかる場合があります。", + "delete_metrics_description_after_delete_part_one": "このアクションは次の日に開始されました:", + "delete_metrics_description_after_delete_part_two": "。このプロセスには最長30日かかる場合があります。", + "delete_metrics_description_privacy_policy": "プライバシー ポリシーをご覧ください。", "delete_metrics_button": "MetaMetricsデータを削除", "check_status_button": "ステータスを確認", "delete_metrics_confirm_modal_title": "MetaMetricsデータを削除しますか?", @@ -990,8 +998,27 @@ "security_alerts": "セキュリティアラート", "security_alerts_desc": "この機能は、トランザクションと署名要求をローカルで確認することで、悪質な行為に関するアラートを発します。要求を承認する前に、必ず独自のデューデリジェンスを行ってください。この機能がすべての悪質な行為を検出するという保証はありません。この機能を有効にすることで、プロバイダーの利用規約に同意したものとみなされます。", "smart_transactions_opt_in_heading": "スマートトランザクション", - "smart_transactions_opt_in_desc": "スマートトランザクションをオンにして、ETHメインネットでより信頼性が高く安全なトランザクションと、調整可能な手数料をご利用ください。", - "smart_transactions_learn_more": "詳細。" + "smart_transactions_opt_in_desc": "スマートトランザクションをオンにして、イーサリアムメインネット上でのトランザクションの信頼性と安全性を高めましょう。", + "smart_transactions_learn_more": "詳細。", + "simulation_details": "予測される残高の増減", + "simulation_details_description": "トランザクションを確定する前に残高の増減を予測するには、この機能をオンにします。これはトランザクションの最終的な結果を保証するものではありません。", + "simulation_details_learn_more": "詳細。", + "aes_crypto_test_form_title": "AES暗号化 - テストフォーム", + "aes_crypto_test_form_description": "E2Eテスト専用に開発されたセクションです。このセクションがアプリに表示される場合は、MetaMaskサポートに報告してください。" + }, + "aes_crypto_test_form": { + "generate_random_salt": "ランダムなソルトを生成", + "salt_bytes_count": "ソルトのバイト数", + "generate": "生成", + "generate_encryption_key": "パスワードから暗号化キーを生成", + "password": "パスワード", + "salt": "ソルト", + "encrypt_with_key": "キーで暗号化", + "encrypt": "暗号化", + "encryption_key": "暗号化キー", + "data": "データ", + "decrypt_with_key": "キーで復号化", + "decrypt": "復号化" }, "sdk": { "disconnect_title": "すべてのサイトとの接続を解除しますか?", @@ -1172,6 +1199,15 @@ "account_copied_to_clipboard": "パブリックアドレスがクリップボードにコピーされました", "share_public_key": "公開鍵を共有中:" }, + "enable_nft-auto-detection": { + "title": "NFTの自動検出を有効にする", + "description": "MetaMaskによる自動検出でのNFTの検出と表示を許可してください。これにより、次のことが可能になります:", + "immediateAccess": "NFTにすぐにアクセス", + "navigate": "デジタル資産を簡単に運用", + "dive": "NFTをすぐに使用開始", + "allow": "許可する", + "notRightNow": "また後で" + }, "detected_tokens": { "title": "{{tokenCount}}個の新しいトークンが見つかりました", "title_plural": "{{tokenCount}}個の新しいトークンが見つかりました", @@ -1370,10 +1406,12 @@ "approve": "承認", "allow_to_access": "次へのアクセス許可を与えますか?", "allow_to_address_access": "このアドレスに次へのアクセス許可を与えますか?", + "allow_to_transfer_all": "次のすべてへのアクセスと転送を許可する:", "spend_cap": "使用上限のリクエスト:", "token": "トークン", "nft": "NFT", "you_trust_this_site": "許可を与えることで、次の第三者が資金にアクセスできるようになります。", + "you_trust_this_third_party": "これにより、アクセス許可を取り消すまで、第三者が今後通知なしにNFTにアクセスし、転送できるようになります。", "you_trust_this_address": "このアドレスは信用できますか?この許可を与えることで、このアドレスによる資金へのアクセスを許可することになります。", "edit_permission": "許可の編集", "edit": "編集", @@ -1477,6 +1515,8 @@ "tx_review_transfer_from": "送金元:", "tx_review_unknown": "不明な方法", "tx_review_approve": "承認", + "tx_review_increase_allowance": "許容額を増やす", + "tx_review_set_approval_for_all": "すべてを承認に設定", "sent_ether": "送信されたイーサ", "self_sent_ether": "自分に送信されたイーサ", "received_ether": "受け取ったイーサ", @@ -1498,11 +1538,17 @@ "smart_contract_interaction": "スマートコントラクトのインタラクション", "swaps_transaction": "スワップトランザクション", "approve": "承認", + "increase_allowance": "許容額を増やす", + "set_approval_for_all": "すべてを承認に設定", "hash": "ハッシュ", "from": "送信元", "to": "送信先", "details": "詳細", "amount": "金額", + "fee": { + "transaction_fee_in_ether": "トランザクション手数料", + "transaction_fee_in_usd": "トランザクション手数料 (USD)" + }, "gas_used": "使用ガス (単位)", "gas_limit": "ガスリミット (単位)", "gas_price": "ガス価格 (gwei)", @@ -1630,6 +1676,8 @@ "you_can": "または", "add_network": "他のネットワークを手動で追加できます。", "select_network": "ネットワークを選択", + "enabled_networks": "ネットワークが有効になりました", + "additional_networks": "他のネットワーク", "show_test_networks": "テストネットワークを表示", "deprecated_goerli": "イーサリアムのプロトコルの変更により、Goerliテストネットワークは安定して動作しない可能性があり、近日中に非推奨になります。", "network_deprecated_title": "このネットワークはサポートされなくなりました", @@ -1898,19 +1946,26 @@ "back_to_safety": "安全な場所に戻る" }, "notifications": { + "staked": "ステーキングしました", + "received": "受け取りました", + "unstaked": "ステーキングが解除されました", + "to": "送り先", + "rate": "レート (手数料込み)", + "unstaking_requested": "ステーキングの解除がリクエストされました", "stake_completed": "ステーキングが完了しました", "withdrawal_completed": "出金が完了しました", "unstake_completed": "ステーキングの解除が完了しました", "withdrawal_requested": "出金がリクエストされました", "stake_ready_to_be_withdrawn": "ステークの出金準備が完了しました", "swap_completed": "{{from}}を{{to}}にスワップしました", + "swap": "スワップしました", "sent": "{{address}}に送りました", - "received": "{{address}}から受け取りました", - "nft_sent": "Sent NFT to {{address}}", - "erc721_sent": "Sent NFT to {{address}}", - "erc1155_sent": "Sent NFT to {{address}}", - "erc721_received": "Received NFT from {{address}}", - "erc1155_received": "Received NFT from {{address}}", + "received_from": "{{address}}から受け取りました", + "nft_sent": "{{address}}にNFTを送りました", + "erc721_sent": "{{address}}にNFTを送りました", + "erc1155_sent": "{{address}}にNFTを送りました", + "erc721_received": "{{address}}からNFTを受け取りました", + "erc1155_received": "{{address}}からNFTを受け取りました", "received_nft": "{{address}}からNFTを受け取りました", "pending_title": "トランザクションが送信されました", "pending_deposit_title": "入金が進行中です。", @@ -1952,6 +2007,7 @@ "wc_description": "アプリケーションを確認してください", "wallet": "ウォレット", "web3": "Web3", + "staking_provider": "ステーキングプロバイダー", "empty": { "title": "ここに表示する内容はありません", "message": "ウォレットにアクティビティがあると、ここに通知が表示されます。" @@ -2561,11 +2617,18 @@ "submit_ticket_5": "チケットの送信は", "submit_ticket_6": "こちら。", "submit_ticket_7": "エラーメッセージとスクリーンショットを含めてください。", + "submit_ticket_8": "バグの報告をお送りください", + "submit_ticket_9": "何が起きたのか、詳細に説明してください。", + "bug_report_prompt_title": "何が起きたのか教えてください", + "bug_report_prompt_description": "何が問題だったか調査できるよう、詳細を追加してください。", + "bug_report_thanks": "ありがとうございます!すぐに調査いたします。", "save_seedphrase_1": "このエラーが解決されない場合は、", "save_seedphrase_2": "シークレットリカバリーフレーズを保存", "save_seedphrase_3": "して、アプリを再インストールしてください。注: シークレットリカバリーフレーズがないとウォレットを復元できません。", "copied_clipboard": "クリップボードにコピーされました", - "ok": "OK" + "ok": "OK", + "cancel": "キャンセル", + "send": "送金" }, "whats_new": { "title": "新機能", @@ -2585,7 +2648,7 @@ "header": "強化されたトランザクション保護", "description_1": "スマートトランザクションで、成功率を上げ、フロントランニングを防ぎ、可視性を高めましょう。", "description_2": "イーサリアムでのみご利用いただけ、いつでも設定で有効・無効を切り替えられます。", - "secondary_button": "強化された保護を有効にしない", + "secondary_button": "設定で管理", "primary_button": "有効にする", "learn_more": "詳細。", "benefit_1_1": "99.5%の", @@ -2594,6 +2657,11 @@ "benefit_2_2": "節約できます", "benefit_3_1": "リアルタイム", "benefit_3_2": "最新情報" + }, + "transaction_simulation": { + "title": "予測される残高の増減", + "description_1": "トランザクションを実行する前に、予測される結果を確認できるようになりました!", + "description_2": "これは単なるシミュレーションに過ぎないため、最終的な結果は保証できません。この機能は「設定」>「セキュリティとプライバシー」でいつでもオフにできます。" } }, "invalid_network": { @@ -3025,7 +3093,8 @@ "manage_networks": "ネットワークの管理", "manage_networks_body": "当社では、遠隔手続き呼び出し (RPC) プロバイダーにInfuraを使用して、イーサリアムデータにできるだけ信頼性の高いプライベートな形でアクセスできるようにしています。独自のRPCをお選びいただくこともできますが、どのRPCもトランザクションを実行するために、ユーザーのIPアドレスとイーサリアムウォレットを取得する点にご注意ください。", "manage_networks_body2": "で、Infuraによるデータの取扱いに関する詳細をご覧ください。", - "functionality_body": "トークンのデータと値、最適なガス設定、セキュリティアップデートなどを含みます。これらのサービスを使用すると、Webサイトにアクセスした場合と同様に、MetaMaskにIPアドレスが共有されます。", + "functionality_body": "MetaMaskは、インターネットサービスを通じてトークンの詳細やガス設定などの基本的な機能を提供します。インターネットサービスを使用すると、この場合はMetaMaskに、ユーザーのIPアドレスが共有されます。これは他のどのWebサイトにアクセスした場合も同様で、MetaMaskはこのデータを一時的に使用し、ユーザーのデータを販売することは一切ありません。VPNを使用したりこのようなサービスをオフにできますが、MetaMaskでのエクスペリエンスに影響を与える可能性があります。詳細は", + "functionality_body2": "をお読みください。", "sheet": { "title_off": "基本機能をオフにする", "description_off": "これは、MetaMaskでの時間が完全に最適化されないことを意味します。基本機能 (トークンの詳細、最適なガス設定など) は利用できません。", @@ -3038,5 +3107,16 @@ "turn_off": "オフにする" } } + }, + "simulation_details": { + "failed": "予測結果の読み込み中にエラーが発生しました。", + "fiat_not_available": "利用できません", + "incoming_heading": "受取額", + "no_balance_changes": "ウォレット残高の増減は予測されていません", + "outgoing_heading": "送金額", + "reverted": "このトランザクションはおそらく失敗します", + "title": "予測される増減額", + "tooltip_description": "予測される増減額は、このトランザクションを実行すると発生する可能性がある増減額です。これは単に予測に過ぎず、保証されたものではありません。", + "total_fiat": "合計 = {{currency}}" } -} \ No newline at end of file +} diff --git a/locales/languages/ko.json b/locales/languages/ko.json index a1323174ad0..ab9cefebaab 100644 --- a/locales/languages/ko.json +++ b/locales/languages/ko.json @@ -365,17 +365,17 @@ "title": "받기" }, "experience_enhancer_modal": { - "title": "Help us enhance your experience", - "paragraph1a": "In addition to ", - "paragraph1b": ", we'd like to use data (like information from cookies) to learn how you interact with our marketing communications.", + "title": "사용자 경험을 개선할 수 있도록 도와주세요", + "paragraph1a": "또한 ", + "paragraph1b": ", MetaMask는 쿠키 정보 같은 데이터를 사용하여 사용자가 마케팅 커뮤니케이션과 어떻게 상호작용하는지 파악하고자 합니다.", "link": "MetaMetrics", - "paragraph2": "This helps us personalize what we share with you, like:", - "bullet1": "Latest developments", - "bullet2": "Product features", - "bullet3": "Other relevant promotional materials", - "footer": "Remember, we never sell the data you provide and you can opt out any time.", - "accept": "I agree", - "cancel": "No thanks" + "paragraph2": "이를 통해 회원님과 공유하는 다음과 같은 콘텐츠를 개인화할 수 있습니다.", + "bullet1": "최신 개발", + "bullet2": "제품 특징", + "bullet3": "기타 관련 프로모션 자료", + "footer": "당사는 회원님이 제공한 데이터를 절대 판매하지 않으며, 언제든지 데이터 수집을 거부할 수 있습니다.", + "accept": "동의합니다", + "cancel": "아니요, 괜찮습니다" }, "wallet": { "title": "지갑", @@ -413,7 +413,7 @@ "no_tokens": "토큰이 없습니다!", "no_nfts_yet": "아직 NFT가 없습니다", "nfts_autodetection_title": "NFT 감지", - "nfts_autodetection_desc": "MetaMask가 OpenSea에서 NFT를 자동으로 탐지하여 MetaMask 지갑에 표시할 수 있도록 하세요.", + "nfts_autodetection_desc": "MetaMask를 통해 자동으로 NFT를 감지하여 지갑에 표시할 수 있습니다.", "network_details_check": "네트워크 세부 정보 확인", "network_with_chain_id": "체인 ID 포함 네트워크", "chain_list_returned_different_ticker_symbol": "이 토큰 심볼이 입력한 네트워크 이름 또는 체인 ID와 일치하지 않습니다. 여러 인기 토큰이 비슷한 심볼을 사용합니다. 사기꾼은 이를 이용해 더 가격이 높은 토큰을 보내도록 속일 수 있습니다. 계속하기 전에 모든 사항을 확인하세요.", @@ -454,7 +454,7 @@ "display_nft_media_cta": "NFT 미디어 표시 켜기", "display_media_nft_warning": "NFT 미디어와 데이터를 표시하면 IP 주소가 중앙 서버에 노출될 수 있습니다. 관련 위험을 이해하고 있는 경우에만 NFT를 가져오세요.", "nfts_autodetect_title": "NFT 자동 감지", - "nfts_autodetect_cta": "설정에서 NFT 자동 감지 켜기", + "nfts_autodetect_cta": "NFT 자동 감지 활성화", "turn_on_network_check_cta": "네트워크 세부 정보 확인 켜기", "display_nft_media_cta_new_1": "NFT를 보려면, 다음에서 NFT 미디어 표시를 켜세요", "display_nft_media_cta_new_2": "설정 > 보안 및 개인정보.", @@ -520,7 +520,7 @@ "description_title": "MetaMask 개선에 도움을 주세요", "description_content_1": "MetaMask를 개선하기 위해 기본적인 데이터 사용 데이터를 수집하고자 합니다. MetaMask는 제공받은 데이터를 절대 판매하지 않습니다.", "description_content_2": "메트릭을 수집할 때는 항상...", - "checkbox": "We'll use this data to learn how you interact with our marketing communications. We may share relavent news (like product features).", + "checkbox": "당사는 이 데이터를 사용하여 사용자가 마케팅 커뮤니케이션과 어떻게 상호 작용하는지 파악합니다. 관련 뉴스(예: 제품 기능)를 공유할 수 있습니다.", "action_description_1_prefix": "개인 정보:", "action_description_2_prefix": "일반:", "action_description_3_prefix": "선택 사항:", @@ -650,7 +650,8 @@ "revoked_all": "모든 계정이 취소되었습니다.", "accounts_connected": "계정이 연결되었습니다.", "disconnected": "연결 해제됨", - "disconnected_all": "모든 계정 연결 해제됨" + "disconnected_all": "모든 계정 연결 해제됨", + "nft_detection_enabled": "NFT 자동 감지 켜짐" }, "connect_qr_hardware": { "title": "QR 코드 기반 하드웨어 지갑 연결", @@ -671,8 +672,8 @@ "please_wait": "잠시 기다리세요" }, "data_collection_modal": { - "accept": "Okay", - "content": "You turned off data collection for our marketing purposes. This only applies to this device. If you use MetaMask on other devices, make sure to opt out there as well." + "accept": "확인", + "content": "마케팅 목적의 데이터 수집을 비활성화했습니다. 이는 이 기기에만 적용됩니다. 다른 기기에서도 MetaMask를 사용하는 경우 해당 기기에서도 데이터 수집을 비활성화해야 합니다." }, "account_selector": { "prev": "이전", @@ -845,9 +846,9 @@ "clear_history_desc": "전체 검색 기록을 지우려면 이 옵션을 선택하세요.", "clear_cookies_desc": "브라우저의 쿠키를 지우려면 이 옵션을 선택하세요.", "metametrics_title": "MetaMetrics 참여", - "metametrics_description": "Allow MetaMetrics to collect basic usage and diagnostics data to improve our product. You can disable MetaMetrics for this device.", - "data_collection_title": "Data collection for marketing", - "data_collection_description": "We’ll use MetaMetrics to learn how you interact with our marketing communications. We may share relevant news (like product features and other materials).", + "metametrics_description": "MetaMetrics가 제품 개선을 위해 기본 사용 및 진단 데이터를 수집하도록 허용합니다. 이 기기에서 MetaMetrics를 비활성화할 수 있습니다.", + "data_collection_title": "마케팅 목적의 데이터 수집", + "data_collection_description": "당사는 MetaMetrics를 사용하여 사용자가 마케팅 커뮤니케이션과 어떻게 상호 작용하는지 파악합니다. 관련 뉴스(예: 제품 기능 및 기타 자료)를 공유할 수 있습니다.", "batch_balance_requests_title": "일괄 계정 잔액 요청", "batch_balance_requests_description": "모든 계정을 일괄 처리하여 잔액을 신속하게 표시하도록 Infura에 요청합니다. 이 기능을 끄면 활성 계정에 대한 잔액만 요청합니다. 일부 디앱은 지갑을 연결하지 않으면 작동하지 않습니다.", "third_party_title": "들어오는 트랜잭션 가져오기", @@ -888,6 +889,13 @@ "delete": "삭제", "network_exists": "이 네트워크는 이미 추가되었습니다.", "delete_metrics_title": "MetaMetrics 데이터 삭제", + "delete_metrics_description_part_one": "이렇게 하면 기록이 삭제됩니다", + "delete_metrics_description_part_two": "MetaMetrics", + "delete_metrics_description_part_three": "데이터가 삭제됩니다.", + "delete_metrics_description_before_delete": "이 데이터를 삭제해도 지갑과 계정에는 아무런 영향이 없습니다. 삭제에는 약 30일 정도 소요됩니다. 다음을 참고하세요:", + "delete_metrics_description_after_delete_part_one": "이 조치는 다음에 시작되었습니다:", + "delete_metrics_description_after_delete_part_two": ". 이 과정에는 약 30일 정도 소요됩니다. 다음을 참고하세요:", + "delete_metrics_description_privacy_policy": "개인정보 처리방침.", "delete_metrics_button": "MetaMetrics 데이터 삭제", "check_status_button": "상태 확인", "delete_metrics_confirm_modal_title": "MetaMetrics 데이터를 삭제할까요?", @@ -990,8 +998,27 @@ "security_alerts": "보안 경고", "security_alerts_desc": "이 기능은 트랜잭션 및 서명 요청을 로컬에서 검토하여 악의적인 활동이 있는 경우 경고합니다. 요청을 승인하기 전에 항상 직접 검토하세요. 이 기능이 모든 악성 활동을 탐지하는 것은 아닙니다. 이 기능을 활성화하면 제공 업체의 이용 약관에 동의하는 것이 됩니다.", "smart_transactions_opt_in_heading": "스마트 트랜잭션", - "smart_transactions_opt_in_desc": "ETH 메인넷에서 더욱 안전하고 안정적으로 트랜잭션하고 수수료를 조정하려면 스마트 트랜잭션을 켜세요.", - "smart_transactions_learn_more": "자세히 알아보세요." + "smart_transactions_opt_in_desc": "이더리움 메인넷에서 더욱 안정적이고 안전하게 트랜잭션을 진행하려면 스마트 트랜잭션을 활성화하세요.", + "smart_transactions_learn_more": "자세히 알아보세요.", + "simulation_details": "예상 잔액 변동", + "simulation_details_description": "이 기능을 켜면 트랜잭션을 확정하기 전에 트랜잭션의 잔액 변동을 추정할 수 있습니다. 이 기능이 트랜잭션의 최종 결과를 보장하지는 않습니다. ", + "simulation_details_learn_more": "더 알아보기.", + "aes_crypto_test_form_title": "AES 암호화 - 테스트 양식", + "aes_crypto_test_form_description": "E2E 테스트 전용으로 개발된 섹션입니다. 앱에서 이 섹션이 표시되면 MetaMask 지원팀에 보고하세요." + }, + "aes_crypto_test_form": { + "generate_random_salt": "무작위 솔트 생성", + "salt_bytes_count": "솔트 바이트 카운트", + "generate": "생성", + "generate_encryption_key": "비밀번호에서 암호화 키 생성", + "password": "비밀번호", + "salt": "솔트", + "encrypt_with_key": "키로 암호화", + "encrypt": "암호화", + "encryption_key": "암호화 키", + "data": "데이터", + "decrypt_with_key": "키로 복호화", + "decrypt": "복호화" }, "sdk": { "disconnect_title": "모든 사이트를 연결 해제할까요?", @@ -1172,6 +1199,15 @@ "account_copied_to_clipboard": "공개 주소가 클립보드에 복사되었습니다", "share_public_key": "내 개인 키 공유:" }, + "enable_nft-auto-detection": { + "title": "NFT 자동 감지 활성화", + "description": "자동 감지를 통해 MetaMask가 NFT를 감지하고 표시하도록 허용합니다. 다음과 같은 작업을 할 수 있습니다.", + "immediateAccess": "NFT에 즉시 액세스", + "navigate": "디지털 자산을 손쉽게 탐색", + "dive": "NFT 바로 사용", + "allow": "허용", + "notRightNow": "나중에" + }, "detected_tokens": { "title": "{{tokenCount}}개의 신규 토큰 발견됨", "title_plural": "{{tokenCount}}개의 신규 토큰 발견됨", @@ -1370,10 +1406,12 @@ "approve": "승인", "allow_to_access": "다음에 액세스할 수 있도록 권한을 부여하세요:", "allow_to_address_access": "이 주소가 다음에 액세스할 수 있도록 권한을 부여하세요:", + "allow_to_transfer_all": "다음 모든 항목에 대한 액세스 및 전송 허용:", "spend_cap": "다음에 대한 지출 한도 요청:", "token": "토큰", "nft": "NFT", "you_trust_this_site": "이를 허용하면 다음과 같은 타사가 회원님의 자금에 접근할 수 있게 됩니다.", + "you_trust_this_third_party": "이렇게 하면 회원님이 해당 액세스 권한을 취소할 때까지 제삼자가 별도의 통보 없이 회원님의 NFT에 액세스하고 전송할 수 있습니다.", "you_trust_this_address": "이 주소를 신뢰하시나요? 이 권한을 승인함으로서 회원님는 해당 주소에 회원님의 자금에 접속할 수 있는 권한을 제공하는 것입니다.", "edit_permission": "권한 편집", "edit": "편집", @@ -1477,6 +1515,8 @@ "tx_review_transfer_from": "송금 출처:", "tx_review_unknown": "확인되지 않은 방법", "tx_review_approve": "승인", + "tx_review_increase_allowance": "한도 증가", + "tx_review_set_approval_for_all": "모두 승인 설정", "sent_ether": "보낸 에테르", "self_sent_ether": "나에게 보낸 에테르", "received_ether": "받은 에테르", @@ -1498,11 +1538,17 @@ "smart_contract_interaction": "스마트 계약 인터렉션", "swaps_transaction": "스와프 트랜잭션", "approve": "승인", + "increase_allowance": "한도 증가", + "set_approval_for_all": "모두 승인 설정", "hash": "해시", "from": "보내는 사람", "to": "수신:", "details": "세부 사항", "amount": "금액", + "fee": { + "transaction_fee_in_ether": "트랜잭션 수수료", + "transaction_fee_in_usd": "트랜잭션 수수료(USD)" + }, "gas_used": "사용한 가스(단위)", "gas_limit": "가스 한도 (Units)", "gas_price": "가스 가격 (GWEI)", @@ -1630,6 +1676,8 @@ "you_can": "또는 다음을 확인하세요:", "add_network": "네트워크를 직접 추가할 수도 있습니다.", "select_network": "네트워크 선택", + "enabled_networks": "활성화된 네트워크", + "additional_networks": "추가 네트워크", "show_test_networks": "테스트 네트워크 표시", "deprecated_goerli": "이더리움의 프로토콜 변경으로 인해 Goerli 테스트 네트워크가 안정적으로 작동하지 않을 수 있으며, 곧 사용 중지될 예정입니다.", "network_deprecated_title": "이 네트워크는 더 이상 지원되지 않습니다", @@ -1898,19 +1946,26 @@ "back_to_safety": "안전성으로 돌아가기" }, "notifications": { + "staked": "스테이킹됨", + "received": "받음", + "unstaked": "언스테이킹됨", + "to": "수신:", + "rate": "환율(수수료 포함)", + "unstaking_requested": "언스테이킹 요청 완료", "stake_completed": "스테이킹 완료", "withdrawal_completed": "인출 완료", "unstake_completed": "언스테이킹 완료", "withdrawal_requested": "인출 요청됨", "stake_ready_to_be_withdrawn": "스테이킹이 인출 준비됨", "swap_completed": "{{from}}에서 {{to}}(으)로 스왑됨", + "swap": "스왑됨", "sent": "{{address}}(으)로 보냄", - "received": "{{address}}에서 받음", - "nft_sent": "Sent NFT to {{address}}", - "erc721_sent": "Sent NFT to {{address}}", - "erc1155_sent": "Sent NFT to {{address}}", - "erc721_received": "Received NFT from {{address}}", - "erc1155_received": "Received NFT from {{address}}", + "received_from": "{{address}}에서 받음", + "nft_sent": "{{address}}(으)로 NFT 전송함", + "erc721_sent": "{{address}}(으)로 NFT 전송함", + "erc1155_sent": "{{address}}(으)로 NFT 전송함", + "erc721_received": "{{address}}에서 NFT 받음", + "erc1155_received": "{{address}}에서 NFT 받음", "received_nft": "{{address}}에서 NFT 받음", "pending_title": "제출된 트랜잭션", "pending_deposit_title": "입금이 진행 중입니다!", @@ -1952,6 +2007,7 @@ "wc_description": "애플리케이션을 확인하세요", "wallet": "지갑", "web3": "웹3", + "staking_provider": "스테이킹 공급자", "empty": { "title": "표시할 항목이 없습니다", "message": "지갑에 활동이 있으면 여기서 알림을 확인할 수 있습니다. " @@ -2561,11 +2617,18 @@ "submit_ticket_5": "여기에 티켓을", "submit_ticket_6": "제출하세요.", "submit_ticket_7": "오류 메시지와 스크린샷을 포함해 주세요.", + "submit_ticket_8": "버그 리포트 전송", + "submit_ticket_9": "오류에 대해 자세히 설명해 주세요.", + "bug_report_prompt_title": "어떤 오류인지 알려주세요", + "bug_report_prompt_description": "무엇이 잘못되었는지 파악할 수 있도록 세부 정보를 추가하세요.", + "bug_report_thanks": "감사합니다! 곧 확인하겠습니다.", "save_seedphrase_1": "오류가 지속되면,", "save_seedphrase_2": "비밀복구구문을 저장하고", "save_seedphrase_3": "앱을 다시 설치하세요. 참고: 비밀복구구문 없이는 지갑을 복구할 수 없습니다.", "copied_clipboard": "클립보드에 복사되었습니다", - "ok": "확인" + "ok": "확인", + "cancel": "취소", + "send": "전송" }, "whats_new": { "title": "새로운 소식", @@ -2585,7 +2648,7 @@ "header": "트랜잭션 보호 강화", "description_1": "스마트 트랜잭션으로 선행거래를 방지하고 더 높은 성공률과 가시성을 확보하세요.", "description_2": "이더리움에서만 사용할 수 있습니다. 설정에서 언제든지 활성화하거나 비활성화할 수 있습니다.", - "secondary_button": "강화된 보호 기능 사용하지 않음", + "secondary_button": "설정에서 관리", "primary_button": "활성화", "learn_more": "자세히 알아보세요.", "benefit_1_1": "99.5% 성공", @@ -2594,6 +2657,11 @@ "benefit_2_2": "절감", "benefit_3_1": "실시간", "benefit_3_2": "업데이트" + }, + "transaction_simulation": { + "title": "예상 잔액 변동", + "description_1": "이제 트랜잭션 전에 예상 결과를 확인할 수 있습니다!", + "description_2": "이는 시뮬레이션일 뿐 최종 결과를 보장하지는 않습니다. 언제든 '설정 > 보호 및 보안'에서 이 기능을 끌 수 있습니다." } }, "invalid_network": { @@ -3025,7 +3093,8 @@ "manage_networks": "네트워크 관리", "manage_networks_body": "가능한 가장 안정적인 비공개 이더리움 액세스를 위해 Infura를 원격 프로시저 호출(RPC) 공급업체로 선정하였습니다. 회원님은 개인적으로 원하는 RPC를 선택할 수 있습니다. 하지만, 모든 RPC는 트랜잭션을 위해 회원님의 이더리움 지갑과 IP 주소를 수령한다는 점에 유의해야 합니다. 다음을 확인하세요: ", "manage_networks_body2": " infura의 데이터 처리 방법 확인.", - "functionality_body": "토큰 데이터 및 가격, 최적의 가스 설정, 보안 업데이트 등을 포함합니다. 이 서비스를 사용하면 웹사이트를 방문할 때와 마찬가지로 사용자의 IP 주소를 MetaMask와 공유하게 됩니다.", + "functionality_body": "MetaMask는 인터넷 서비스를 통해 토큰 세부 정보 및 가스 설정과 같은 기본 기능을 제공합니다. 인터넷 서비스를 이용할 때 IP 주소가 공유되며, 이 경우 MetaMask와 공유됩니다. 이는 다른 웹사이트를 방문할 때와 마찬가지입니다. MetaMask는 이 데이터를 일시적으로 사용하며 데이터를 절대 판매하지 않습니다. VPN을 사용하거나 이러한 서비스를 비활성화할 수 있지만 MetaMask 사용 환경에 영향을 미칠 수 있습니다. 자세한 내용은 ", + "functionality_body2": " 을(를) 참고하세요.", "sheet": { "title_off": "기본 기능 끄기", "description_off": "이렇게 하면 MetaMask에서 시간을 완전히 최적화할 수 없습니다. 기본 기능(토큰 세부 정보, 최적의 가스 설정 등)을 사용할 수 없게 됩니다.", @@ -3038,5 +3107,16 @@ "turn_off": "끄기" } } + }, + "simulation_details": { + "failed": "추정치를 불러오는 동안 오류가 발생했습니다.", + "fiat_not_available": "이용할 수 없음", + "incoming_heading": "받음:", + "no_balance_changes": "지갑에 예상 변동 사항 없음", + "outgoing_heading": "보냄:", + "reverted": "이 트랜잭션은 실패할 가능성이 높습니다", + "title": "예상 변동 사항", + "tooltip_description": "예상 변동 사항은 이 트랜잭션을 진행할 경우 발생하는 결과를 예측한 것입니다. 이는 예측일 뿐 결과를 보장하지는 않습니다.", + "total_fiat": "합계 = {{currency}}" } -} \ No newline at end of file +} diff --git a/locales/languages/pt.json b/locales/languages/pt.json index 2dca4d583c9..d552edbd391 100644 --- a/locales/languages/pt.json +++ b/locales/languages/pt.json @@ -365,17 +365,17 @@ "title": "Receber" }, "experience_enhancer_modal": { - "title": "Help us enhance your experience", - "paragraph1a": "In addition to ", - "paragraph1b": ", we'd like to use data (like information from cookies) to learn how you interact with our marketing communications.", + "title": "Ajude-nos a melhorar sua experiência", + "paragraph1a": "Além do ", + "paragraph1b": ", gostaríamos de usar dados (como informações de cookies) para saber como você interage com nossas comunicações de marketing.", "link": "MetaMetrics", - "paragraph2": "This helps us personalize what we share with you, like:", - "bullet1": "Latest developments", - "bullet2": "Product features", - "bullet3": "Other relevant promotional materials", - "footer": "Remember, we never sell the data you provide and you can opt out any time.", - "accept": "I agree", - "cancel": "No thanks" + "paragraph2": "Isso nos ajuda a personalizar o que compartilhamos com você, como:", + "bullet1": "Últimos desenvolvimentos", + "bullet2": "Recursos de produtos", + "bullet3": "Outros materiais promocionais relevantes", + "footer": "Lembre-se, nunca vendemos os dados que você fornece e você pode desativar quando quiser.", + "accept": "Concordo", + "cancel": "Não, obrigado" }, "wallet": { "title": "Carteira", @@ -413,7 +413,7 @@ "no_tokens": "Você não tem nenhum token!", "no_nfts_yet": "Nenhum NFT até agora", "nfts_autodetection_title": "Detecção de NFTs", - "nfts_autodetection_desc": "Permita que a MetaMask detecte NFTs automaticamente da OpenSea e os exiba na sua carteira MetaMask.", + "nfts_autodetection_desc": "Permite à MetaMask detectar e exibir automaticamente os NFTs em sua carteira.", "network_details_check": "A verificação dos dados da rede", "network_with_chain_id": "A rede com a ID de cadeia", "chain_list_returned_different_ticker_symbol": "O símbolo deste token não corresponde ao nome ou ID da cadeia inseridos para a rede. Muitos tokens populares apresentam símbolos semelhantes, que podem ser usados por golpistas para induzir você ao erro de enviar um token mais valioso em troca. Verifique todos os detalhes antes de continuar.", @@ -454,7 +454,7 @@ "display_nft_media_cta": "Ativar Exibir mídias de NFTs", "display_media_nft_warning": "Exibir mídias e dados de NFTs pode expor seu endereço IP a servidores centralizados. Importe NFTs somente se você entende os riscos envolvidos.", "nfts_autodetect_title": "Detecção automática de NFTs", - "nfts_autodetect_cta": "Ative a Detecção automática de NFTs nas Configurações", + "nfts_autodetect_cta": "Ativar detecção automática de NFTs", "turn_on_network_check_cta": "Ativar verificação de dados da rede", "display_nft_media_cta_new_1": "Para ver um NFT, ative Exibir mídias de NFTs em", "display_nft_media_cta_new_2": "Configurações > Segurança e Privacidade.", @@ -520,7 +520,7 @@ "description_title": "Ajude a melhorar a MetaMask", "description_content_1": "Gostaríamos de coletar dados básicos de uso para melhorar a MetaMask. Saiba que nunca vendemos os dados que você fornece aqui.", "description_content_2": "Quando coletamos as métricas, elas sempre são...", - "checkbox": "We'll use this data to learn how you interact with our marketing communications. We may share relavent news (like product features).", + "checkbox": "Usaremos esses dados para saber como você interage com nossas comunicações de marketing. Podemos compartilhar novidades relevantes (como recursos de produtos).", "action_description_1_prefix": "Privadas:", "action_description_2_prefix": "Gerais:", "action_description_3_prefix": "Opcionais:", @@ -650,7 +650,8 @@ "revoked_all": "Todas as contas revogadas.", "accounts_connected": "contas conectadas.", "disconnected": "desconectada.", - "disconnected_all": "Todas as contas estão desconectadas." + "disconnected_all": "Todas as contas estão desconectadas.", + "nft_detection_enabled": "Detecção automática de NFT ativada" }, "connect_qr_hardware": { "title": "Conecte uma carteira de hardware baseada em QR", @@ -671,8 +672,8 @@ "please_wait": "Aguarde" }, "data_collection_modal": { - "accept": "Okay", - "content": "You turned off data collection for our marketing purposes. This only applies to this device. If you use MetaMask on other devices, make sure to opt out there as well." + "accept": "OK", + "content": "Você desativou a coleta de dados para fins de marketing. Isso é aplicável apenas a este dispositivo. Se você usa a MetaMask em outros dispositivos, desative-a neles também." }, "account_selector": { "prev": "ANT", @@ -845,9 +846,9 @@ "clear_history_desc": "Selecione essa opção para limpar todo seu histórico de navegação.", "clear_cookies_desc": "Selecione essa opção para limpar os cookies do seu navegador.", "metametrics_title": "Participar da MetaMetrics", - "metametrics_description": "Allow MetaMetrics to collect basic usage and diagnostics data to improve our product. You can disable MetaMetrics for this device.", - "data_collection_title": "Data collection for marketing", - "data_collection_description": "We’ll use MetaMetrics to learn how you interact with our marketing communications. We may share relevant news (like product features and other materials).", + "metametrics_description": "Permita que o MetaMetrics colete dados básicos de uso e diagnóstico para melhorar nosso produto. Você pode desativar o MetaMetrics neste dispositivo.", + "data_collection_title": "Coleta de dados para marketing", + "data_collection_description": "Usaremos o MetaMetrics para saber como você interage com nossas comunicações de marketing. Poderemos compartilhar novidades relevantes (como recursos de produtos e outros materiais).", "batch_balance_requests_title": "Agrupar solicitações de saldo de contas", "batch_balance_requests_description": "Agrupamos as contas e consultamos a Infura para exibir seus saldos de forma responsiva. Se isso for desativado, somente contas ativas serão consultadas. Alguns dapps só funcionam se você conecta a sua carteira.", "third_party_title": "Receba transações de entrada", @@ -888,6 +889,13 @@ "delete": "Excluir", "network_exists": "Essa rede já foi adicionada.", "delete_metrics_title": "Excluir dados do MetaMetrics", + "delete_metrics_description_part_one": "Isso excluirá os dados históricos de", + "delete_metrics_description_part_two": "MetaMetrics", + "delete_metrics_description_part_three": "associados à sua carteira.", + "delete_metrics_description_before_delete": "Sua carteira e suas contas permanecerão exatamente como estão agora após a exclusão desses dados. Este processo pode levar até 30 dias. Veja nossa", + "delete_metrics_description_after_delete_part_one": "Você iniciou esta ação em", + "delete_metrics_description_after_delete_part_two": ". Este processo pode levar até 30 dias. Veja nossa", + "delete_metrics_description_privacy_policy": "Política de Privacidade.", "delete_metrics_button": "Excluir dados do MetaMetrics", "check_status_button": "Verificar status", "delete_metrics_confirm_modal_title": "Excluir dados do MetaMetrics?", @@ -990,8 +998,27 @@ "security_alerts": "Alertas de segurança", "security_alerts_desc": "Esse recurso alerta sobre atividades mal-intencionadas por meio da análise local de solicitações de transações e assinaturas. Sempre realize sua própria devida diligência antes de aprovar solicitações. Não há garantia de que esse recurso detectará toda e qualquer atividade mal-intencionada. Ao ativar esse recurso, você concorda com os termos de uso do provedor.", "smart_transactions_opt_in_heading": "Transações inteligentes", - "smart_transactions_opt_in_desc": "Ative as transações inteligentes para ter transações mais seguras e confiáveis, além de taxas ajustáveis na Mainnet da Ethereum.", - "smart_transactions_learn_more": "Saiba mais." + "smart_transactions_opt_in_desc": "Ative as transações inteligentes para fazer transações mais confiáveis ​​e seguras na Mainnet da Ethereum.", + "smart_transactions_learn_more": "Saiba mais.", + "simulation_details": "Estimar alterações de saldo", + "simulation_details_description": "Ative esta opção para estimar as alterações de saldo pelas transações antes de confirmá-las. Isso não garante o resultado de suas transações. ", + "simulation_details_learn_more": "Saiba mais.", + "aes_crypto_test_form_title": "AES Crypto - Formulário de teste", + "aes_crypto_test_form_description": "Seção desenvolvida exclusivamente para testes E2E. Se isso for exibido em seu aplicativo, informe ao suporte da MetaMask." + }, + "aes_crypto_test_form": { + "generate_random_salt": "Gerar sal aleatório", + "salt_bytes_count": "Contagem de bytes de sal", + "generate": "Gerar", + "generate_encryption_key": "Gerar chave de criptografia baseada na senha", + "password": "Senha", + "salt": "Sal", + "encrypt_with_key": "Criptografar com chave", + "encrypt": "Criptografar", + "encryption_key": "Chave de criptografia", + "data": "Dados", + "decrypt_with_key": "Descriptografar com chave", + "decrypt": "Descriptografar" }, "sdk": { "disconnect_title": "Desconectar todos os sites?", @@ -1172,6 +1199,15 @@ "account_copied_to_clipboard": "Endereço público copiado para a área de transferência", "share_public_key": "Compartilhando minha chave pública: " }, + "enable_nft-auto-detection": { + "title": "Ativar detecção automática de NFTs", + "description": "Permita que a MetaMask detecte e exiba seus NFTs com detecção automática. Você será capaz de:", + "immediateAccess": "Acessar suas NFTs imediatamente", + "navigate": "Navegar tranquilo por seus ativos digitais", + "dive": "Acessar e começar a usar diretamente seus NFTs", + "allow": "Permitir", + "notRightNow": "Agora não" + }, "detected_tokens": { "title": "{{tokenCount}} novo token encontrado", "title_plural": "{{tokenCount}} novos tokens encontrados", @@ -1370,10 +1406,12 @@ "approve": "Aprovar", "allow_to_access": "Dê permissão para acessar seu", "allow_to_address_access": "Dar a esse endereço acesso ao seu", + "allow_to_transfer_all": "Permitir acesso e transferência de todos os seus", "spend_cap": "Solicitação de limite de gasto para seu", "token": "token", "nft": "NFT", "you_trust_this_site": "Ao conceder permissão, você permite que os terceiros a seguir acessem seus fundos.", + "you_trust_this_third_party": "Isso permite que terceiros acessem e transfiram seus NFTs sem avisar, até que você revogue esse acesso.", "you_trust_this_address": "Você confia neste endereço? Ao conceder esta permissão, você permitirá que este endereço acesse seus fundos.", "edit_permission": "Editar permissão", "edit": "Editar", @@ -1477,6 +1515,8 @@ "tx_review_transfer_from": "Transferir de", "tx_review_unknown": "Método desconhecido", "tx_review_approve": "Aprovar", + "tx_review_increase_allowance": "Aumentar permissão", + "tx_review_set_approval_for_all": "Definir aprovação para todos", "sent_ether": "Ethers enviados", "self_sent_ether": "Ethers enviados a si mesmo", "received_ether": "Ethers recebidos", @@ -1498,11 +1538,17 @@ "smart_contract_interaction": "Interação com contrato inteligente", "swaps_transaction": "Transação de trocas", "approve": "Aprovar", + "increase_allowance": "Aumentar permissão", + "set_approval_for_all": "Definir aprovação para todos", "hash": "Hash", "from": "De", "to": "Para", "details": "Detalhes", "amount": "Valor", + "fee": { + "transaction_fee_in_ether": "Taxa de transação", + "transaction_fee_in_usd": "Taxa de transação (USD)" + }, "gas_used": "Gás usado (unidades)", "gas_limit": "Limite de gás (unidades)", "gas_price": "Preço do gás (GWEI)", @@ -1630,6 +1676,8 @@ "you_can": "Ou você pode", "add_network": "adicionar mais redes manualmente.", "select_network": "Selecione uma rede", + "enabled_networks": "Redes habilitadas", + "additional_networks": "Redes adicionais", "show_test_networks": "Exibir redes de teste", "deprecated_goerli": "Devido às alterações no protocolo Ethereum, a rede de teste Goerli pode não funcionar com a mesma confiabilidade e será descontinuada.", "network_deprecated_title": "Essa rede foi descontinuada", @@ -1898,19 +1946,26 @@ "back_to_safety": "Voltar para a segurança" }, "notifications": { + "staked": "Em staking", + "received": "Recebido", + "unstaked": "Retirado de staking", + "to": "Para", + "rate": "Cotação (taxas incluídas)", + "unstaking_requested": "Retirada de staking solicitada", "stake_completed": "Staking concluído", "withdrawal_completed": "Saque concluído", "unstake_completed": "Retirada de staking concluída", "withdrawal_requested": "Saque solicitado", "stake_ready_to_be_withdrawn": "Staking pronto para ser sacado", "swap_completed": "{{from}} trocado por {{to}}", + "swap": "Trocado", "sent": "Enviou para {{address}}", - "received": "Recebeu de {{address}}", - "nft_sent": "Sent NFT to {{address}}", - "erc721_sent": "Sent NFT to {{address}}", - "erc1155_sent": "Sent NFT to {{address}}", - "erc721_received": "Received NFT from {{address}}", - "erc1155_received": "Received NFT from {{address}}", + "received_from": "Recebido de {{address}}", + "nft_sent": "Enviou NFT para {{address}}", + "erc721_sent": "Enviou NFT para {{address}}", + "erc1155_sent": "Enviou NFT para {{address}}", + "erc721_received": "Recebeu NFT de {{address}}", + "erc1155_received": "Recebeu NFT de {{address}}", "received_nft": "Recebeu NFT de {{address}}", "pending_title": "Transação enviada", "pending_deposit_title": "Depósito em andamento!", @@ -1952,6 +2007,7 @@ "wc_description": "Verifique o aplicativo", "wallet": "Carteira", "web3": "Web3", + "staking_provider": "Provedor de staking", "empty": { "title": "Não há nada aqui", "message": "Aqui você encontra as notificações quando há atividade em sua carteira. " @@ -2561,11 +2617,18 @@ "submit_ticket_5": "Envie um chamado", "submit_ticket_6": "aqui.", "submit_ticket_7": "Inclua a mensagem de erro e a captura de tela.", + "submit_ticket_8": "Envie-nos um relatório de erros", + "submit_ticket_9": "Inclua detalhes sobre a ocorrência.", + "bug_report_prompt_title": "Conte-nos o que aconteceu", + "bug_report_prompt_description": "Adicione detalhes para que possamos descobrir o que deu errado.", + "bug_report_thanks": "Obrigado! Daremos uma olhada em breve.", "save_seedphrase_1": "Se o erro persistir,", "save_seedphrase_2": "salve sua Frase de Recuperação Secreta", "save_seedphrase_3": "e reinstale o app. Observação: você NÃO poderá restaurar sua carteira sem a Frase de Recuperação Secreta.", "copied_clipboard": "Copiada para a área de transferência", - "ok": "OK" + "ok": "OK", + "cancel": "Cancelar", + "send": "Enviar" }, "whats_new": { "title": "Novidades", @@ -2585,7 +2648,7 @@ "header": "Proteção de transações aprimorada", "description_1": "Desbloqueie taxas de sucesso maiores, proteção contra front running e melhor visibilidade com as transações inteligentes.", "description_2": "Disponível somente na Ethereum. Ative ou desative a qualquer momento nas configurações.", - "secondary_button": "Não ativar a proteção aprimorada", + "secondary_button": "Gerenciar nas configurações", "primary_button": "Ativar", "learn_more": "Saiba mais.", "benefit_1_1": "99,5% de taxa de", @@ -2594,6 +2657,11 @@ "benefit_2_2": "dinheiro", "benefit_3_1": "em tempo real", "benefit_3_2": "Atualizações" + }, + "transaction_simulation": { + "title": "Alterações de saldo estimadas", + "description_1": "Agora você pode ver os possíveis resultados de suas transações antes de realizá-las!", + "description_2": "Isto é apenas uma simulação, portanto não podemos garantir o resultado. Você pode desativar isso quando quiser em Configurações > Segurança e privacidade." } }, "invalid_network": { @@ -3025,7 +3093,8 @@ "manage_networks": "Gerenciar redes", "manage_networks_body": "Usamos a Infura como nosso provedor de chamada de procedimento remoto (RPC) para oferecermos o acesso mais confiável e privado possível aos dados do Ethereum. Você pode escolher sua própria RPC, mas lembre-se de que qualquer RPC receberá seu endereço IP e da carteira de Ethereum para realizar transações. Leia nosso ", "manage_networks_body2": " para saber mais sobre como a Infura trata os dados.", - "functionality_body": "Inclui os dados e o valor dos tokens, as configurações ideais de gás, atualizações de segurança e mais. Ao usar esses serviços, seu endereço IP será compartilhado com a MetaMask, assim como ocorre quando você visita um site.", + "functionality_body": "A MetaMask oferece recursos básicos como detalhes de token e configurações de gás por meio de serviços de internet. Quando você usa serviços de internet, seu endereço IP é compartilhado, neste caso com o MetaMask. É exatamente igual a quando você visita qualquer site. A MetaMask usa esses dados temporariamente e nunca os vende. Você pode usar uma VPN ou desligar esses serviços, mas isso poderá afetar sua experiência com a MetaMask. Leia nossos ", + "functionality_body2": " para saber mais.", "sheet": { "title_off": "Desativar funcionalidade básica", "description_off": "Isso significa que você não otimizará totalmente seu tempo na MetaMask. Os recursos básicos (como detalhes de tokens, configurações ideais de gás e outros) não estarão disponíveis.", @@ -3038,5 +3107,16 @@ "turn_off": "Desativar" } } + }, + "simulation_details": { + "failed": "Houve um erro ao carregar sua estimativa.", + "fiat_not_available": "Não disponível", + "incoming_heading": "Você recebe", + "no_balance_changes": "Nenhuma alteração prevista para sua carteira", + "outgoing_heading": "Você envia", + "reverted": "Essa transação provavelmente falhará", + "title": "Alterações estimadas", + "tooltip_description": "As alterações estimadas podem acontecer se você prosseguir com essa transação. Isso é apenas uma previsão, não uma garantia.", + "total_fiat": "Total = {{currency}}" } -} \ No newline at end of file +} diff --git a/locales/languages/ru.json b/locales/languages/ru.json index f1ed4a3c24f..22e0e680ebf 100644 --- a/locales/languages/ru.json +++ b/locales/languages/ru.json @@ -365,17 +365,17 @@ "title": "Получить" }, "experience_enhancer_modal": { - "title": "Help us enhance your experience", - "paragraph1a": "In addition to ", - "paragraph1b": ", we'd like to use data (like information from cookies) to learn how you interact with our marketing communications.", - "link": "MetaMetrics", - "paragraph2": "This helps us personalize what we share with you, like:", - "bullet1": "Latest developments", - "bullet2": "Product features", - "bullet3": "Other relevant promotional materials", - "footer": "Remember, we never sell the data you provide and you can opt out any time.", - "accept": "I agree", - "cancel": "No thanks" + "title": "Помогите нам улучшить ваш опыт", + "paragraph1a": "В дополнение к ", + "paragraph1b": ", мы хотели бы использовать данные (например, информацию из файлов cookie), чтобы узнать, как вы взаимодействуете с нашими маркетинговыми сообщениями.", + "link": "MetaMetrics,", + "paragraph2": "Это помогает нам персонализировать то, чем мы делимся с вами, например:", + "bullet1": "Последние разработки", + "bullet2": "Функции продукта", + "bullet3": "Другие соответствующие промоматериалы", + "footer": "Помните, что мы никогда не продаем предоставленные вами данные и вы можете отказаться от их предоставления в любое время.", + "accept": "Я согласен(-на)", + "cancel": "Нет, спасибо" }, "wallet": { "title": "Кошелек", @@ -413,7 +413,7 @@ "no_tokens": "У вас нет токенов!", "no_nfts_yet": "Пока нет NFT", "nfts_autodetection_title": "Определение NFT", - "nfts_autodetection_desc": "Разрешите MetaMask автоопределять NFT из OpenSea и отображать их в кошельке MetaMask.", + "nfts_autodetection_desc": "Разрешите MetaMask автоматически определять и отображать NFT в вашем кошельке.", "network_details_check": "Проверка сведений о сети", "network_with_chain_id": "Сеть с ID блокчейна", "chain_list_returned_different_ticker_symbol": "Этот символ токена не соответствует введенному имени сети или идентификатору блокчейна. Многие популярные токены обозначаются похожими символами, которые мошенники могут использовать, чтобы обманом заставить вас отправить им взамен более ценный токен. Проверьте все, прежде чем продолжить.", @@ -454,7 +454,7 @@ "display_nft_media_cta": "Включите отображение носителя NFT", "display_media_nft_warning": "Отображение носителей и данных NFT может раскрыть ваш IP-адрес централизованным серверам. Импортируйте NFT только в том случае, если вы понимаете связанные с этим риски.", "nfts_autodetect_title": "Автоопределение NFT", - "nfts_autodetect_cta": "Включите автоопределение NFT в Настройках", + "nfts_autodetect_cta": "Включить автоопределение NFT", "turn_on_network_check_cta": "Включить проверку сведений о сети", "display_nft_media_cta_new_1": "Чтобы увидеть NFT, включите \"Показать носитель NFT\"", "display_nft_media_cta_new_2": "Настройки > Безопасность и конфиденциальность.", @@ -520,7 +520,7 @@ "description_title": "Помогите нам улучшить Metamask", "description_content_1": "Мы хотели бы собрать базовые данные об использовании для улучшения MetaMask. Помните, что мы никогда не продаем данные, которые вы здесь предоставляете.", "description_content_2": "Когда мы собираем показатели, они всегда будут...", - "checkbox": "We'll use this data to learn how you interact with our marketing communications. We may share relavent news (like product features).", + "checkbox": "Мы будем использовать эти данные, чтобы узнать, как вы взаимодействуете с нашими маркетинговыми сообщениями. Мы можем отправлять соответствующие новости (например, о функциях продукта).", "action_description_1_prefix": "Приватными:", "action_description_2_prefix": "Общедоступными:", "action_description_3_prefix": "Необязательными:", @@ -650,7 +650,8 @@ "revoked_all": "Все счета отозваны.", "accounts_connected": "счета подключены.", "disconnected": "отключен.", - "disconnected_all": "Все счета отключены." + "disconnected_all": "Все счета отключены.", + "nft_detection_enabled": "Автоопределение NFT включено" }, "connect_qr_hardware": { "title": "Подключите аппаратный кошелек на основе QR-кодов", @@ -671,8 +672,8 @@ "please_wait": "Пожалуйста, подождите..." }, "data_collection_modal": { - "accept": "Okay", - "content": "You turned off data collection for our marketing purposes. This only applies to this device. If you use MetaMask on other devices, make sure to opt out there as well." + "accept": "Хорошо", + "content": "Вы отключили сбор данных для наших маркетинговых целей. Это касается только этого устройства. Если вы используете MetaMask на других устройствах, обязательно отключите его и там." }, "account_selector": { "prev": "ПРЕДЫД.", @@ -845,9 +846,9 @@ "clear_history_desc": "Выберите этот вариант, чтобы очистить всю историю просмотра.", "clear_cookies_desc": "Выберите этот вариант, чтобы очистить файлы cookie вашего браузера.", "metametrics_title": "Участвуйте в MetaMetrics", - "metametrics_description": "Allow MetaMetrics to collect basic usage and diagnostics data to improve our product. You can disable MetaMetrics for this device.", - "data_collection_title": "Data collection for marketing", - "data_collection_description": "We’ll use MetaMetrics to learn how you interact with our marketing communications. We may share relevant news (like product features and other materials).", + "metametrics_description": "Разрешите MetaMetrics собирать основные данные об использовании и диагностические данные для улучшения нашего продукта. Вы можете отключить MetaMetrics для этого устройства.", + "data_collection_title": "Сбор данных для маркетинга", + "data_collection_description": "Мы будем использовать MetaMetrics, чтобы узнать, как вы взаимодействуете с нашими маркетинговыми сообщениями. Мы можем делиться соответствующими новостями (например, новостями о функциях продукта и другими материалами).", "batch_balance_requests_title": "Пакетные запросы баланса счета", "batch_balance_requests_description": "Мы создаем пакет счетов и запрашиваем Infura, чтобы оперативно отображать ваши балансы. Если вы отключите это, запрос будет отправляться только в отношении активных счетов. Некоторые dApps не будут работать, пока вы не подключите свой кошелек.", "third_party_title": "Получить входящие транзакции", @@ -888,6 +889,13 @@ "delete": "Удалить", "network_exists": "Сеть уже добавлена.", "delete_metrics_title": "Удалить данные MetaMetrics", + "delete_metrics_description_part_one": "Это удалит исторические данные", + "delete_metrics_description_part_two": "MetaMetrics,", + "delete_metrics_description_part_three": "связанные с вашим кошельком.", + "delete_metrics_description_before_delete": "Ваш кошелек и счета останутся точно такими, какие они есть сейчас, после того, как эти данные будут удалены. Этот процесс может занять до 30 дней. Ознакомьтесь с нашей", + "delete_metrics_description_after_delete_part_one": "Вы инициировали это действие", + "delete_metrics_description_after_delete_part_two": ". Этот процесс может занять до 30 дней. Ознакомьтесь с нашей", + "delete_metrics_description_privacy_policy": "Политикой конфиденциальности.", "delete_metrics_button": "Удалить данные MetaMetrics", "check_status_button": "Проверить статус", "delete_metrics_confirm_modal_title": "Удалить данные MetaMetrics?", @@ -990,8 +998,27 @@ "security_alerts": "Оповещения безопасности", "security_alerts_desc": "Эта функция предупреждает вас о вредоносной активности, проверяя запросы транзакций и подписей локально. Всегда проводите комплексную проверку перед утверждением каких-либо запросов. Нет никакой гарантии, что эта функция обнаружит всю вредоносную активность. Включая эту функцию, вы соглашаетесь с условиями использования поставщика.", "smart_transactions_opt_in_heading": "Умные транзакции", - "smart_transactions_opt_in_desc": "Включите умные транзакции для более надежных и безопасных транзакций, а также настраиваемых комиссий в Мейн-нете ETH.", - "smart_transactions_learn_more": "Узнайте подробнее." + "smart_transactions_opt_in_desc": "Включите функцию «Умные транзакции» для более надежного и безопасного выполнения транзакций в Мейн-нете Ethereum.", + "smart_transactions_learn_more": "Узнайте подробнее.", + "simulation_details": "Спрогнозировать изменения баланса", + "simulation_details_description": "Включите эту опцию, чтобы спрогнозировать изменения баланса транзакций перед их подтверждением. Это не гарантирует окончательный результат ваших транзакций. ", + "simulation_details_learn_more": "Узнайте подробнее.", + "aes_crypto_test_form_title": "Криптовалюта AES — тестовая форма", + "aes_crypto_test_form_description": "Раздел разработан исключительно для тестирования E2E. Если его видно в вашем приложении, сообщите об этом в службу поддержки MetaMask." + }, + "aes_crypto_test_form": { + "generate_random_salt": "Генерировать случайный солт", + "salt_bytes_count": "Количество байтов в солт", + "generate": "Генерировать", + "generate_encryption_key": "Создать ключ шифрования из пароля", + "password": "Пароль", + "salt": "Солт", + "encrypt_with_key": "Зашифровать ключом", + "encrypt": "Зашифровать", + "encryption_key": "Ключ шифрования", + "data": "Данные", + "decrypt_with_key": "Рассшифровать ключом", + "decrypt": "Расшифровать" }, "sdk": { "disconnect_title": "Отключить все сайты?", @@ -1172,6 +1199,15 @@ "account_copied_to_clipboard": "Публичный адрес скопирован в буфер обмена", "share_public_key": "Отправка моего открытого ключа:" }, + "enable_nft-auto-detection": { + "title": "Включить автоопределение NFT", + "description": "Разрешите MetaMask обнаруживать и отображать ваши ТАЕ-токены с помощью автоопределения. Вы сможете:", + "immediateAccess": "Немедленно получать доступ к своим NFT-токенам", + "navigate": "Легко перемещаться по своим цифровым активам", + "dive": "Переходить прямо к использованию своих NFT-токенов", + "allow": "Разрешить", + "notRightNow": "Не сейчас" + }, "detected_tokens": { "title": "Найден {{tokenCount}} новый токен", "title_plural": "Найден {{tokenCount}} новых токена(-ов)", @@ -1370,10 +1406,12 @@ "approve": "Одобрить", "allow_to_access": "Разрешить доступ к вашему", "allow_to_address_access": "Предоставить этому адресу доступ к вашему", + "allow_to_transfer_all": "Разрешить доступ и перевести все ваши", "spend_cap": "Запрос лимита расходов для", "token": "токену", "nft": "NFT", "you_trust_this_site": "Предоставляя разрешение, вы предоставляете следующей третьей стороне доступ к вашим средствам.", + "you_trust_this_third_party": "Эта функция позволяет третьей стороне получать доступ к Вашим NFT и переводить их без дополнительного уведомления, пока вы не отзовете ее доступ.", "you_trust_this_address": "Вы доверяете этому адресу? После предоставления этого разрешения данный адрес получит доступ к вашим средствам.", "edit_permission": "Изменить разрешение", "edit": "Изменить", @@ -1477,6 +1515,8 @@ "tx_review_transfer_from": "Перевести из", "tx_review_unknown": "Неизвестный способ", "tx_review_approve": "Одобрить", + "tx_review_increase_allowance": "Увеличить допуск", + "tx_review_set_approval_for_all": "Одобрить все", "sent_ether": "Отправлен эфир", "self_sent_ether": "Отправил(-а) себе эфир", "received_ether": "Получен эфир", @@ -1498,11 +1538,17 @@ "smart_contract_interaction": "Взаимодействие со смарт-контрактом", "swaps_transaction": "Транзакция свопа", "approve": "Одобрить", + "increase_allowance": "Увеличить квоту", + "set_approval_for_all": "Одобрить все", "hash": "Хэш", "from": "От", "to": "В адрес", "details": "Подробные сведения", "amount": "Сумма", + "fee": { + "transaction_fee_in_ether": "Комиссия за транзакцию", + "transaction_fee_in_usd": "Комиссия за транзакцию (USD)" + }, "gas_used": "Использовано газа (единицы)", "gas_limit": "Лимит газа (единицы)", "gas_price": "Цена газа (Гвей)", @@ -1630,6 +1676,8 @@ "you_can": "Или вы можете", "add_network": "добавить другие сети вручную.", "select_network": "Выбрать сеть", + "enabled_networks": "Включенные сети", + "additional_networks": "Дополнительные сети", "show_test_networks": "Показать тестнеты", "deprecated_goerli": "Из-за изменений протокола Ethereum: тестовая сеть Goerli может работать ненадежно и скоро будет выведена из эксплуатации.", "network_deprecated_title": "Эта сеть устарела", @@ -1898,19 +1946,26 @@ "back_to_safety": "Назад в безопасное место" }, "notifications": { + "staked": "В стейкинге", + "received": "Получено", + "unstaked": "Стейкинг отменен", + "to": "В", + "rate": "Курс (включая комиссии)", + "unstaking_requested": "Запрошена отмена стейкинга", "stake_completed": "Стейкинг завершен", "withdrawal_completed": "Вывод завершен", "unstake_completed": "Отмена стейкинга завершена", "withdrawal_requested": "Запрошен вывод", "stake_ready_to_be_withdrawn": "Доля готова к выводу", "swap_completed": "{{from}} обменянные на {{to}}", + "swap": "Выполнен обмен", "sent": "Отправленные на {{address}}", - "received": "Полученные от {{address}}", - "nft_sent": "Sent NFT to {{address}}", - "erc721_sent": "Sent NFT to {{address}}", - "erc1155_sent": "Sent NFT to {{address}}", - "erc721_received": "Received NFT from {{address}}", - "erc1155_received": "Received NFT from {{address}}", + "received_from": "Получено от {{address}}", + "nft_sent": "Отправил(-а) NFT на {{address}}", + "erc721_sent": "Отправил(-а) NFT на {{address}}", + "erc1155_sent": "Отправил(-а) NFT на {{address}}", + "erc721_received": "Получил(-а) NFT от {{address}}", + "erc1155_received": "Получил(-а) NFT от {{address}}", "received_nft": "NFT, полученные от {{address}}", "pending_title": "Транзакция отправлена", "pending_deposit_title": "Выполняется внесение депозита!", @@ -1952,6 +2007,7 @@ "wc_description": "Проверьте приложение", "wallet": "Кошелек", "web3": "Web3", + "staking_provider": "Поставщик услуг стейкинга", "empty": { "title": "Здесь не на что смотреть", "message": "Здесь вы можете найти уведомления, когда в вашем кошельке выполняются действия. " @@ -2561,11 +2617,18 @@ "submit_ticket_5": "Отправьте запрос о поддержке", "submit_ticket_6": "здесь.", "submit_ticket_7": "Приложите сообщение об ошибке и скриншот.", + "submit_ticket_8": "Отправьте нам отчет об ошибке", + "submit_ticket_9": "Опишите подробности произошедшего.", + "bug_report_prompt_title": "Расскажите нам, что случилось", + "bug_report_prompt_description": "Добавьте детали, чтобы мы могли понять, что пошло не так.", + "bug_report_thanks": "Спасибо! Мы скоро рассмотрим этот вопрос.", "save_seedphrase_1": "Если эта ошибка сохраняется,", "save_seedphrase_2": "сохраните свою секретную фразу для восстановления", "save_seedphrase_3": "и переустановите приложение. Примечание: вы НЕ сможете восстановить свой кошелек без секретной фразы для восстановления.", "copied_clipboard": "Скопирована в буфер обмена", - "ok": "ОК" + "ok": "ОК", + "cancel": "Отмена", + "send": "Отправить" }, "whats_new": { "title": "Что нового", @@ -2585,7 +2648,7 @@ "header": "Улучшенная защита транзакций", "description_1": "Откройте для себя более высокие коэффициенты успеха, передовую защиту и лучшую прозрачность с помощью смарт-транзакций.", "description_2": "Доступно только на Ethereum. Включайте или отключайте в любое время в настройках.", - "secondary_button": "Не включать усиленную защиту", + "secondary_button": "Управляйте в настройках", "primary_button": "Включить", "learn_more": "Подробнее.", "benefit_1_1": "Показатель успеха:", @@ -2594,6 +2657,11 @@ "benefit_2_2": "деньги", "benefit_3_1": "Статус", "benefit_3_2": "в реальном времени" + }, + "transaction_simulation": { + "title": "Предполагаемые изменения баланса", + "description_1": "Теперь вы можете увидеть потенциальный результат ваших транзакций еще до их совершения!", + "description_2": "Это всего лишь симуляция, поэтому мы не можем гарантировать конечный результат. Вы можете отключить ее в любое время вразделе «Настройки» > «Безопасность и конфиденциальность»." } }, "invalid_network": { @@ -3025,7 +3093,8 @@ "manage_networks": "Управление сетями", "manage_networks_body": "Мы используем Infura в качестве нашего поставщика удаленного вызова процедур (RPC), чтобы предложить наиболее надежный и конфиденциальный доступ к данным Ethereum из возможных. Вы можете выбрать свой собственного RPC, но помните, что любой RPC получит ваш IP-адрес и номер кошелька Ethereum для совершения транзакций. См. наши ", "manage_networks_body2": " чтобы узнать больше о том, как Infura обрабатывает данные.", - "functionality_body": "Включает данные и стоимость токена, оптимальные настройки газа, обновления безопаности и многое другое. При использовании этих сервисов ваш IP-адрес передается MetaMask, как при посещении веб-сайта.", + "functionality_body": "MetaMask предлагает базовые функции, такие как сведения о токенах и настройки газа, через интернет-службы. Когда вы пользуетесь интернет-службами, ваш IP-адрес передается, в данном случае MetaMask. Это похоже на посещение любого веб-сайта. MetaMask временно использует ваши данные и никогда не продает их. Вы можете использовать VPN или отключить эти службы, но это может негативно повлиять на вашу работу с MetaMask. Прочитайте нашу ", + "functionality_body2": " для получения дополнительной информации.", "sheet": { "title_off": "Выключить базовый функционал", "description_off": "Это означает, что вы не сможете полностью оптимизировать свое время в MetaMask. Вам будут недоступны базовые функции (например, сведения о токенах, оптимальные настройки газа и т. д.).", @@ -3038,5 +3107,16 @@ "turn_off": "Выключить" } } + }, + "simulation_details": { + "failed": "Не удалось загрузить прогноз.", + "fiat_not_available": "Недоступен", + "incoming_heading": "Вы получаете", + "no_balance_changes": "Никаких изменений в вашем кошельке не прогнозируется", + "outgoing_heading": "Вы отправляете", + "reverted": "Эта транзакция, скорее всего, не удастся", + "title": "Прогнозируемые изменения", + "tooltip_description": "Прогнозируемые изменения — это то, что может произойти, если вы завершите эту транзакцию. Это всего лишь прогноз, а не гарантия.", + "total_fiat": "Итого = {{currency}}" } -} \ No newline at end of file +} diff --git a/locales/languages/tl.json b/locales/languages/tl.json index f43bf67b883..42bf7fc95ec 100644 --- a/locales/languages/tl.json +++ b/locales/languages/tl.json @@ -365,17 +365,17 @@ "title": "Tumanggap" }, "experience_enhancer_modal": { - "title": "Help us enhance your experience", - "paragraph1a": "In addition to ", - "paragraph1b": ", we'd like to use data (like information from cookies) to learn how you interact with our marketing communications.", + "title": "Tulungan kami na paghusayin ang iyong karanasan", + "paragraph1a": "Dagdag pa sa ", + "paragraph1b": ", nais naming gamitin ang data (tulad ng impormasyon mula sa mga cookie) upang matutunan kung paano ka nakikipag-ugnayan sa aming mga komunikasyon sa marketing.", "link": "MetaMetrics", - "paragraph2": "This helps us personalize what we share with you, like:", - "bullet1": "Latest developments", - "bullet2": "Product features", - "bullet3": "Other relevant promotional materials", - "footer": "Remember, we never sell the data you provide and you can opt out any time.", - "accept": "I agree", - "cancel": "No thanks" + "paragraph2": "Nakakatulong itong iangkop ang aming ibinabahagi sa iyo, tulad ng:", + "bullet1": "Pinakabagong mga pagpapaunlad", + "bullet2": "Mga tampok ng produkto", + "bullet3": "Iba pang kaugnay na mga materyal sa promosyon", + "footer": "Tandaan, hindi namin ibebenta ang data na iyong ibibigay at maaari kang mag-opt out anumang oras.", + "accept": "Sumasang-ayon ako", + "cancel": "Huwag na lang" }, "wallet": { "title": "Wallet", @@ -413,7 +413,7 @@ "no_tokens": "Wala kang anumang token!", "no_nfts_yet": "Wala pang mga NFT", "nfts_autodetection_title": "Pagtuklas ng NFT", - "nfts_autodetection_desc": "Payagan ang MetaMask na awtomatikong matuklasan ang mga NFT mula sa OpenSea at ipakita sa iyong wallet sa MetaMask.", + "nfts_autodetection_desc": "Hayaan ang MetaMask na awtomatikong i-detect at ipakita ang mga NFT sa iyong wallet.", "network_details_check": "Pagsusuri ng detalye ng network", "network_with_chain_id": "Ang network na may ID ng chain", "chain_list_returned_different_ticker_symbol": "Ang simbolo ng token na ito ay hindi tugma sa pangalan ng network o chain ID na inilagay. Maraming popular na token ang gumagamit ng magkakatulad ng simbolo, na maaaring gamitin ng mga scammer para lokohin ka na magpadala ka ng mas mahalagang token bilang kapalit. Beripikahin ang lahat bago ka magpatuloy.", @@ -454,7 +454,7 @@ "display_nft_media_cta": "I-on ang I-display ng NFT media", "display_media_nft_warning": "Ang pagpapakita ng media at data ng NFT ay maaaring maglantad sa iyong IP address sa mga sentralisadong server. Mag-import lang ng NFT kung nauunawaan mo ang mga kaugnay na panganib.", "nfts_autodetect_title": "Awtomatikong pagtuklas ng NFT", - "nfts_autodetect_cta": "I-on ang awtomatikong pagtuklas ng ng NFT sa Mga Setting", + "nfts_autodetect_cta": "Paganahin ang autodetection ng NFT", "turn_on_network_check_cta": "I-on ang pagsusuri ng ng detalye ng network", "display_nft_media_cta_new_1": "Para makita ang NFT, i-on ang Display NFT media sa", "display_nft_media_cta_new_2": "Mga Setting > Seguridad at Pagkapribado.", @@ -520,7 +520,7 @@ "description_title": "Tulungan kaming mapahusay ang MetaMask", "description_content_1": "Nais naming mangalap ng data para sa batayang paggamit upang mapahusay ang MetaMask. Dapat mong malaman na hindi namin ibebenta ang data na iyong ibibigay rito.", "description_content_2": "Kapag kami ay nangangalap ng metrics, ito ay palaging...", - "checkbox": "We'll use this data to learn how you interact with our marketing communications. We may share relavent news (like product features).", + "checkbox": "Gagamitin namin ang data na ito upang matutunan paano ka nakikipag-ugnayan sa aming mga komunikasyon sa marketing. Maaari kaming magbahagi ng kaugnay na balita (tulad ng mga tampok ng produkto).", "action_description_1_prefix": "Pribado:", "action_description_2_prefix": "Pangkalahatan:", "action_description_3_prefix": "Opsyonal:", @@ -650,7 +650,8 @@ "revoked_all": "Ang lahat ng account ay binawi.", "accounts_connected": "mga account na konektado.", "disconnected": "nadiskonekta.", - "disconnected_all": "Nadiskonekta ang lahat ng account." + "disconnected_all": "Nadiskonekta ang lahat ng account.", + "nft_detection_enabled": "Pinagana ang autodetection ng NFT" }, "connect_qr_hardware": { "title": "Ikonekta ang QR-based na wallet na hardware", @@ -672,7 +673,7 @@ }, "data_collection_modal": { "accept": "Okay", - "content": "You turned off data collection for our marketing purposes. This only applies to this device. If you use MetaMask on other devices, make sure to opt out there as well." + "content": "In-off mo ang koleksyon ng data para sa layunin sa marketing. Ito ay inilalapat lamang sa device na ito. Kung gumagamit ka ng MetaMask sa ibang mga device, siguraduhing mag-opt out din doon." }, "account_selector": { "prev": "NAKARAAN", @@ -845,9 +846,9 @@ "clear_history_desc": "Piliin ang opsyong ito para i-clear ang iyong buong history ng pag-browse.", "clear_cookies_desc": "Piliin ang opsyong ito para i-clear ang cookies ng iyong browser.", "metametrics_title": "Sumali sa MetaMetrics", - "metametrics_description": "Allow MetaMetrics to collect basic usage and diagnostics data to improve our product. You can disable MetaMetrics for this device.", - "data_collection_title": "Data collection for marketing", - "data_collection_description": "We’ll use MetaMetrics to learn how you interact with our marketing communications. We may share relevant news (like product features and other materials).", + "metametrics_description": "Payagan ang MetaMetrics upang kolektahin ang batayang paggamit at data sa diagnostics upang mapahusay ang aming produkto. Maaari mong i-disable ang MetaMetrics para sa device na ito.", + "data_collection_title": "Koleksyon ng data para sa marketing", + "data_collection_description": "Gagamitin namin ang MetaMetrics upang matutunan paano ka nakikipag-ugnayan sa aming mga komunikasyon sa marketing. Maaari kaming magbahagi ng kaugnay na balita (tulad ng mga tampok ng produkto).", "batch_balance_requests_title": "Maramihang kahilingan sa balanse ng account", "batch_balance_requests_description": "Bina-batch namin ang mga account at nagtatanong sa Infura para maipakita nang mabilis ang iyong mga balanse. Kung io-off mo ito, mga aktibong account lang ang itatanong. Hindi gagana ang ilang dApp maliban kung ikokonekta mo ang iyong wallet.", "third_party_title": "Makuha ang mga papasok na transaksyon", @@ -888,6 +889,13 @@ "delete": "Tanggalin", "network_exists": "Naidagdag na ang network na ito.", "delete_metrics_title": "Tanggalin ang data ng MetaMetrics", + "delete_metrics_description_part_one": "Buburahin nito ang historikal na", + "delete_metrics_description_part_two": "MetaMetrics", + "delete_metrics_description_part_three": "data na kaugnay sa iyong wallet.", + "delete_metrics_description_before_delete": "Ang iyong wallet at mga account ay mananatiling eksaktong katulad ng kung ano ang mga ito sa ngayon pagkatapos matanggal ang data na ito. Maaaring tumagal nang hanggang 30 araw ang prosesong ito. Tingnan ang aming", + "delete_metrics_description_after_delete_part_one": "Sinimulan mo ang aksyon na ito noong", + "delete_metrics_description_after_delete_part_two": ". Maaaring tumagal nang hanggang 30 araw ang prosesong ito. Tingnan ang aming", + "delete_metrics_description_privacy_policy": "Patakaran sa Pagkapribado.", "delete_metrics_button": "Tanggalin ang data ng MetaMetrics", "check_status_button": "Tingnan ang Katayuan", "delete_metrics_confirm_modal_title": "Tanggalin ang data ng MetaMetrics?", @@ -990,8 +998,27 @@ "security_alerts": "Mga alerto sa seguridad", "security_alerts_desc": "Inaalertuhan ka ng tampok na ito sa mga aktibidad na may masamang hangarin sa pamamagitan ng lokal na pagsusuri sa iyong mga transaksyon at kahilingan sa paglagda. Palaging gumawa ng sarili mong pag-iingat bago aprubahan ang anumang mga kahilingan. Walang garantiya na made-detect ng tampok na ito ang lahat ng aktibidad na may masamang hangarin. Sa pagpapagana sa tampok na ito, sumasang-ayon ka sa mga tuntunin ng paggamit ng provider.", "smart_transactions_opt_in_heading": "Mga Smart Transaction", - "smart_transactions_opt_in_desc": "I-on ang mga Smart Transaction para sa mas maaasahan at ligtas na mga transaksyon, at naaayong singil sa ETH Mainnet.", - "smart_transactions_learn_more": "Matuto pa." + "smart_transactions_opt_in_desc": "I-on ang mga Smart Transaction para sa mas maaasahan at ligtas na mga transaksyon sa Ethereum Mainnet.", + "smart_transactions_learn_more": "Matuto pa.", + "simulation_details": "Tinatayang mga pagbabago sa balanse", + "simulation_details_description": "I-on ito para gumawa ng pagtataya sa mga pagbabago sa balanse ng mga transaksyon bago mo kumpirmahin ang mga ito. Hindi nito iginagarantiya ang panghuling resulta ng iyong mga transaksyon. ", + "simulation_details_learn_more": "Matuto pa.", + "aes_crypto_test_form_title": "AES Crypto - Test Form", + "aes_crypto_test_form_description": "Bahagi na ekslusibong binuo para sa E2E testing. Kung ito ay nakikita sa iyong app, mangyaring i-ulat ito sa MetaMask support." + }, + "aes_crypto_test_form": { + "generate_random_salt": "Gumawa ng Random Salt", + "salt_bytes_count": "Bilang ng salt bytes", + "generate": "Bumuo", + "generate_encryption_key": "Bumuo ng encryption key mula sa password", + "password": "Password", + "salt": "Salt", + "encrypt_with_key": "I-encrypt gamit ang key", + "encrypt": "I-encrypt", + "encryption_key": "Encryption Key", + "data": "Data", + "decrypt_with_key": "I-decrypt gamit ang key", + "decrypt": "I-decrypt" }, "sdk": { "disconnect_title": "Idiskonekta ang lahat ng site?", @@ -1172,6 +1199,15 @@ "account_copied_to_clipboard": "Nakopya ang pampublikong address sa clipboard", "share_public_key": "Ibahagi ang aking pampublikong key: " }, + "enable_nft-auto-detection": { + "title": "Paganahin ang autodetection ng NFT", + "description": "Pahintulutan ang MetaMask na i-detect at ipakita ang iyong mga NFT gamit ang autodetection. Maaari mong:", + "immediateAccess": "Agad na i-access ang mga NFT mo", + "navigate": "Walang hirap na pamahalaan ang iyong mga digital na asset", + "dive": "Dumiretso sa paggamit ng iyong mga NFT", + "allow": "Payagan", + "notRightNow": "Hindi ngayon" + }, "detected_tokens": { "title": "{{tokenCount}} bagong token ang natagpuan", "title_plural": "{{tokenCount}} (na) bagong token ang natagpuan", @@ -1370,10 +1406,12 @@ "approve": "Aprubahan", "allow_to_access": "Magbigay ng pahintulot para ma-access ang iyong", "allow_to_address_access": "Bigyan ang address na ito ng access sa iyong", + "allow_to_transfer_all": "Payagan ang pag-access sa at paglilipat ng lahat ng iyong", "spend_cap": "Kahilingan sa limitasyon sa paggastos para sa iyong", "token": "token", "nft": "NFT", "you_trust_this_site": "Sa pamamagitan ng pagbibigay ng pahintulot, pinapayagan mo ang sumusunod na third party na i-access ang iyong mga pondo.", + "you_trust_this_third_party": "Pinapayagan nito ang third party na i-access at ilipat ang iyong mga NFT nang walang karagdagang abiso hanggang sa bawiin mo ang pag-access nito.", "you_trust_this_address": "Pinagkakatiwalaan mo ba ang address na ito? Sa pamamagitan ng pagbibigay ng pahintulot, pinapayagan mo ang address na ito na i-access ang iyong mga pondo.", "edit_permission": "Pahintulot sa pag-edit", "edit": "I-edit", @@ -1477,6 +1515,8 @@ "tx_review_transfer_from": "Maglipat Mula Kay/Sa", "tx_review_unknown": "Hindi Alam na Paraan", "tx_review_approve": "Aprubahan", + "tx_review_increase_allowance": "Dagdag na Allowance", + "tx_review_set_approval_for_all": "Itakda ang Pag-apruba Para sa Lahat", "sent_ether": "Nagpadala ng Ether", "self_sent_ether": "Nagpadala ka sa sarili mo ng Ether", "received_ether": "Nakatanggap ng Ether", @@ -1498,11 +1538,17 @@ "smart_contract_interaction": "Interaksyon sa smart na kontrata", "swaps_transaction": "Transaksyon sa mga swap", "approve": "Aprubahan", + "increase_allowance": "Dagdag na Allowance", + "set_approval_for_all": "Itakda ang Pag-apruba Para sa Lahat", "hash": "Hash", "from": "Mula kay/sa", "to": "Para kay/sa", "details": "Mga Detalye", "amount": "Halaga", + "fee": { + "transaction_fee_in_ether": "Bayarin sa Transaksyon", + "transaction_fee_in_usd": "Bayarin sa Transaksyon (USD)" + }, "gas_used": "Ginamit na Gas (Mga Unit)", "gas_limit": "Limitasyon ng Gas (Mga Unit)", "gas_price": "Presyo ng Gas (GWEI)", @@ -1630,6 +1676,8 @@ "you_can": "O maaari kang", "add_network": "magdagdag pa ng mga network nang manu-mano.", "select_network": "Pumili ng network", + "enabled_networks": "Naka-enable na mga network", + "additional_networks": "Mga karagdagang network", "show_test_networks": "Ipakita ang mga test network", "deprecated_goerli": "Dahil sa mga pagbabago sa protocol ng Ethereum: Ang Goerli test network ay maaaring hindi gumana tulad ng inaasahan at malapit nang ihinto ang paggamit.", "network_deprecated_title": "Ang network na ito ay hindi na suportado", @@ -1898,19 +1946,26 @@ "back_to_safety": "Bumalik sa ligtas" }, "notifications": { + "staked": "Nai-stake", + "received": "Natanggap", + "unstaked": "Na-unstake", + "to": "Sa/Kay", + "rate": "Halaga (kasama ang bayarin)", + "unstaking_requested": "Hiniling ang pag-unstake", "stake_completed": "Nakumpleto ang pag-stake", "withdrawal_completed": "Nakumpleto ang pag-withdraw", "unstake_completed": "Nakumpleto ang pag-unstake", "withdrawal_requested": "Hiniling ang pag-withdraw", "stake_ready_to_be_withdrawn": "Handa ng i-withdraw ang stake", "swap_completed": "I-swap ang {{from}} sa {{to}}", + "swap": "Nai-swap", "sent": "Ipinadala sa {{address}}", - "received": "Natanggap mula sa {{address}}", - "nft_sent": "Sent NFT to {{address}}", - "erc721_sent": "Sent NFT to {{address}}", - "erc1155_sent": "Sent NFT to {{address}}", - "erc721_received": "Received NFT from {{address}}", - "erc1155_received": "Received NFT from {{address}}", + "received_from": "Natanggap mula sa {{address}}", + "nft_sent": "Ipinadala ang NFT sa {{address}}", + "erc721_sent": "Ipinadala ang NFT sa {{address}}", + "erc1155_sent": "Ipinadala ang NFT sa {{address}}", + "erc721_received": "Natanggap ang NFT mula sa {{address}}", + "erc1155_received": "Natanggap ang NFT mula sa {{address}}", "received_nft": "Natanggap ang NFT mula sa {{address}}", "pending_title": "Naisumite ang transaksyon", "pending_deposit_title": "Kasalukuyang nagdedeposito!", @@ -1952,6 +2007,7 @@ "wc_description": "Mangyaring suriin ang aplikasyon", "wallet": "Wallet", "web3": "Web3", + "staking_provider": "Tagapagbigay ng Staking", "empty": { "title": "Walang makikita rito", "message": "Dito mo mahahanap ang mga notipikasyon kapag may aktibidad sa wallet mo. " @@ -2561,11 +2617,18 @@ "submit_ticket_5": "Magsumite ng ticket", "submit_ticket_6": "dito.", "submit_ticket_7": "Pakisama ang mensahe ng error at ang screenshot.", + "submit_ticket_8": "Padalhan kami ng ulat ng bug", + "submit_ticket_9": "Mangyaring isama ang mga detalye tungkol sa kung ano ang nangyari.", + "bug_report_prompt_title": "Sabihin mo sa amin kung anong nangyari", + "bug_report_prompt_description": "Magdagdag ng mga detalye upang malaman namin ano ang nangyari.", + "bug_report_thanks": "Salamat! Titingnan namin ito sa lalong madaling panahon.", "save_seedphrase_1": "Kung magpapatuloy ang error na ito,", "save_seedphrase_2": "i-save ang iyong Lihim na Parirala sa Pagbawi", "save_seedphrase_3": "at i-install ulit ang app. Paalala: HINDI mo maibabalik ang iyong wallet nang wala ang iyong Lihim na Parirala sa Pagbawi.", "copied_clipboard": "Nakopya sa clipboard", - "ok": "OK" + "ok": "OK", + "cancel": "Kanselahin", + "send": "Ipadala" }, "whats_new": { "title": "Ano'ng bago", @@ -2585,7 +2648,7 @@ "header": "Pinahusay na Proteksyon sa Transaksyon", "description_1": "I-unlock ang mas mataas na tiyansa ng tagumpay, proteksyon sa frontrunning, at mas mahusay na visibility sa mga Smart Transaction.", "description_2": "Available lamang sa Ethereum. I-enable o i-disable anumang oras sa mga setting.", - "secondary_button": "Huwag i-enable ang pinahusay na proteksyon", + "secondary_button": "Pamahalaan sa mga setting", "primary_button": "I-enable", "learn_more": "Matuto pa.", "benefit_1_1": "99.5% tagumpay", @@ -2594,6 +2657,11 @@ "benefit_2_2": "pera", "benefit_3_1": "Real-time", "benefit_3_2": "mga update" + }, + "transaction_simulation": { + "title": "Tinatayang mga pagbabago sa balanse", + "description_1": "Maaari mo na ngayong makita ang potensyal na resulta ng iyong mga transaksyon bago mo gawin ang mga iyon!", + "description_2": "Ito ay isang simulasyon lamang, kaya hindi namin matitiyak ang panghuling resulta. Maaari mo itong i-off anumang oras sa Mga Setting > Seguridad at Pagkapribado." } }, "invalid_network": { @@ -3025,7 +3093,8 @@ "manage_networks": "Pamahalaan ang mga network", "manage_networks_body": "Gumagamit kami ng Infura bilang aming provider ng remote procedure call (RPC) para mag-alok ng pinakamaaasahan at pribadong access sa Ethereum data na aming makakaya. Maaari kang pumili ng iyong sariling RPC, ngunit tandaan na ang anumang RPC ay makakatanggap ng iyong IP address at Ethereum wallet upang gumawa ng mga transaksyon. Basahin ang aming ", "manage_networks_body2": " para matuto pa tungkol sa kung paano pinangangasiwaan ng Infura ang data.", - "functionality_body": "Kasama ang data at halaga ng token, optimal na settings sa gas, at marami pang iba. Ang paggamit ng mga serbisyong ito ay nagbabahagi ng iyong IP address sa MetaMask, tulad kapag bumisita ka sa isang website.", + "functionality_body": "Nag-aalok ang MetaMask ng mga batayang tampok tulad ng mga detalye ng token at mga setting ng gas sa pamamagitan ng serbisyo sa internet. Kapag gumamit ka ng serbisyo sa internet, ibabahagi ang iyong IP address, sa kasong ito sa MetaMask. Tulad ito ng pagbisita mo sa anumang website. Ang MetaMask ay pansamantalang ginagamit ang datos na ito at hindi ibebenta ang iyong datos. Maaari kang gumamit ng VPN o i-off ang mga serbisyon ito, ngunit maaari itong makaapekto sa iyong karanasan sa MetaMask. Basahin ang aming ", + "functionality_body2": " upang matuto pa.", "sheet": { "title_off": "I-off ang batayang kapakinabangan", "description_off": "Ibig sabihin nito hindi mo lubos na mao-optimize ang iyong oras sa MetaMask. Ang mga batayang tampok (tulad ng mga detalye ng token, optimal na settings ng gas, at iba pa) ay hindi magiging available para sa iyo.", @@ -3038,5 +3107,16 @@ "turn_off": "I-off" } } + }, + "simulation_details": { + "failed": "Mayroong error sa pag-load ng iyong pagtataya.", + "fiat_not_available": "Hindi Available", + "incoming_heading": "Nakatanggap ka ng", + "no_balance_changes": "Walang pagbabagong nahulaan para sa iyong wallet", + "outgoing_heading": "Nagpadala ka ng", + "reverted": "Ang transaksyon na ito ay malamang na mabigo", + "title": "Tinatayang mga pagbabago", + "tooltip_description": "Ang tinatayang mga pagbabago ay ang maaaring mangyari kung magpapatuloy ka sa transaksyon ito. Ito ay isang hula lamang, hindi isang garantiya.", + "total_fiat": "Kabuuan = {{currency}}" } -} \ No newline at end of file +} diff --git a/locales/languages/tr.json b/locales/languages/tr.json index 03b901e2c62..03f6f8e8234 100644 --- a/locales/languages/tr.json +++ b/locales/languages/tr.json @@ -365,17 +365,17 @@ "title": "Al" }, "experience_enhancer_modal": { - "title": "Help us enhance your experience", - "paragraph1a": "In addition to ", - "paragraph1b": ", we'd like to use data (like information from cookies) to learn how you interact with our marketing communications.", + "title": "Deneyiminizi iyileştirmemize yardımcı olun", + "paragraph1a": "Biz ", + "paragraph1b": "dışında verileri (çerezlerden alınan bilgiler gibi) pazarlama iletişimlerimizle nasıl etkileşimde bulunduğunuzu öğrenmek amacıyla kullanırız.", "link": "MetaMetrics", - "paragraph2": "This helps us personalize what we share with you, like:", - "bullet1": "Latest developments", - "bullet2": "Product features", - "bullet3": "Other relevant promotional materials", - "footer": "Remember, we never sell the data you provide and you can opt out any time.", - "accept": "I agree", - "cancel": "No thanks" + "paragraph2": "Sizinle örneğin şunlar gibi neleri paylaşacağımızı kişiselleştirebilmemize yardımcı olur:", + "bullet1": "En yeni gelişmeler", + "bullet2": "Ürün özellikleri", + "bullet3": "İlgili diğer promosyon materyalleri", + "footer": "Unutmayın, sunduğunuz verileri hiçbir zaman satmayız ve dilediğiniz zaman tercihinizi değiştirebilirsiniz.", + "accept": "Kabul ediyorum", + "cancel": "Hayır, istemiyorum" }, "wallet": { "title": "Cüzdan", @@ -413,7 +413,7 @@ "no_tokens": "Tokeniniz yok!", "no_nfts_yet": "Henüz NFT yok", "nfts_autodetection_title": "NFT algılama", - "nfts_autodetection_desc": "MetaMask'ın OpenSea'den NFT'leri otomatik olarak algılayıp MetaMask cüzdanınızda göstermesine izin verin.", + "nfts_autodetection_desc": "MetaMask'in otomatik olarak cüzdanınızdaki NFT'leri algılayıp göstermesine izin verin.", "network_details_check": "Ağ bilgileri kontrolü", "network_with_chain_id": "Zincir kimliği olan ağ", "chain_list_returned_different_ticker_symbol": "Bu token sembolü, girilen ağ adı veya zincir kimliği ile eşleşmiyor. Pek çok popüler token benzer sembolleri kullanır ve dolandırıcılar, karşılığında daha değerli bir token gönderecekleri yönünde sizi kandırmak için bunları kullanabilirler. Devam etmeden önce her şeyi doğrulayın.", @@ -454,7 +454,7 @@ "display_nft_media_cta": "NFT medyasını göster seçeneğini açın", "display_media_nft_warning": "NFT medyasını ve verilerini göstermek IP adresinizi merkezi sunuculara ifşa edebilir. Sadece mevcut riskleri anlıyorsanız NFT'yi içe aktarın.", "nfts_autodetect_title": "NFT otomatik algılama", - "nfts_autodetect_cta": "Ayarlar kısmında NFT'leri Otomatik Algıla seçeneğini açın", + "nfts_autodetect_cta": "NFT otomatik algılamayı etkinleştir", "turn_on_network_check_cta": "Ağ bilgileri kontrolünü aç", "display_nft_media_cta_new_1": "Bir NFT'yi görmek için NFT medyasını göster seçeneğini açın", "display_nft_media_cta_new_2": "Ayarlar > Güvenlik ve Gizlilik.", @@ -520,7 +520,7 @@ "description_title": "MetaMask'ı iyileştirmemize yardımcı olun", "description_content_1": "MetaMask'i iyileştirmek için temel kullanım verilerini toplamak istiyoruz. Burada sunduğunuz verileri asla satmadığımızı bilmenizi isteriz.", "description_content_2": "Topladığımız ölçümler her zaman şu şekilde olacaktır...", - "checkbox": "We'll use this data to learn how you interact with our marketing communications. We may share relavent news (like product features).", + "checkbox": "Bu verileri, pazarlama iletişimlerimizle nasıl etkileşimde bulunduğunuzu öğrenmek için kullanacağız. İlgili haberleri (ürün özellikleri gibi) paylaşabiliriz.", "action_description_1_prefix": "Özel:", "action_description_2_prefix": "Genel:", "action_description_3_prefix": "İsteğe bağlı:", @@ -650,7 +650,8 @@ "revoked_all": "Tüm hesaplar iptal edildi.", "accounts_connected": "hesap bağlandı.", "disconnected": "bağlantısı kesildi.", - "disconnected_all": "Tüm hesapların bağlantısı kesildi." + "disconnected_all": "Tüm hesapların bağlantısı kesildi.", + "nft_detection_enabled": "NFT otomatik algılama etkinleştirildi" }, "connect_qr_hardware": { "title": "QR tabanlı bir donanım cüzdanı bağlayın", @@ -671,8 +672,8 @@ "please_wait": "Lütfen bekleyin" }, "data_collection_modal": { - "accept": "Okay", - "content": "You turned off data collection for our marketing purposes. This only applies to this device. If you use MetaMask on other devices, make sure to opt out there as well." + "accept": "Tamam", + "content": "Pazarlama amacıyla veri toplama seçeneğini kapattınız. Bu, sadece bu cihaz için geçerlidir. MetaMask'i başka cihazlarda kullanırsanız orada da vazgeçtiğinizden emin olun." }, "account_selector": { "prev": "ÖNCEKİ", @@ -845,9 +846,9 @@ "clear_history_desc": "Tüm tarayıcı geçmişini temizlemek için bu seçeneği seçin.", "clear_cookies_desc": "Tarayıcının çerezlerini temizlemek için bu seçeneği seçin.", "metametrics_title": "MetaMetrics'e katıl", - "metametrics_description": "Allow MetaMetrics to collect basic usage and diagnostics data to improve our product. You can disable MetaMetrics for this device.", - "data_collection_title": "Data collection for marketing", - "data_collection_description": "We’ll use MetaMetrics to learn how you interact with our marketing communications. We may share relevant news (like product features and other materials).", + "metametrics_description": "MetaMetrics'in ürünümüzü iyileştirmek için temel kullanım ve tanılama verilerini toplamasına izin verin. Bu cihaz için MetaMetrics'i devre dışı bırakabilirsiniz.", + "data_collection_title": "Pazarlama amacıyla veri toplama", + "data_collection_description": "MetaMetrics'i, pazarlama iletişimlerimizle nasıl etkileşimde bulunduğunuzu öğrenmek için kullanacağız. İlgili haberleri (ürün özellikleri ve diğer materyaller gibi) paylaşabiliriz.", "batch_balance_requests_title": "Toplu hesap bakiyesi talepleri", "batch_balance_requests_description": "Hesapları toplarız ve bakiyelerinizi göstermek için Infura'yı sorgularız. Bunu kapattığınız takdirde sadece aktif hesaplar sorgulanır. Bazı merkeziyetsiz uygulamalar siz cüzdanınızı bağlamadığınız sürece çalışmaz.", "third_party_title": "Gelen işlemleri al", @@ -888,6 +889,13 @@ "delete": "Sil", "network_exists": "Bu ağ zaten eklenmiş.", "delete_metrics_title": "MetaMetrics verilerini sil", + "delete_metrics_description_part_one": "Bu işlem cüzdanınızla ilişkili geçmiş", + "delete_metrics_description_part_two": "MetaMetrics", + "delete_metrics_description_part_three": "verilerini silecektir.", + "delete_metrics_description_before_delete": "Bu veriler silindikten sonra cüzdanınız ve hesaplarınız tam olarak şimdi olduğu gibi kalacaktır. Bu işlem 30 güne kadar sürebilir. Şunu görüntüleyin:", + "delete_metrics_description_after_delete_part_one": "Bu eylemi şurada başlattınız:", + "delete_metrics_description_after_delete_part_two": ". Bu işlem 30 gün kadar sürebilir. Şunu görüntüleyin:", + "delete_metrics_description_privacy_policy": "Gizlilik Politikası.", "delete_metrics_button": "MetaMetrics verilerini sil", "check_status_button": "Durumu Kontrol Et", "delete_metrics_confirm_modal_title": "MetaMetrics verilerini sil?", @@ -990,8 +998,27 @@ "security_alerts": "Güvenlik uyarıları", "security_alerts_desc": "Bu özellik, işlem ve imza taleplerinizi yerel olarak incelerken gizliliğinizi koruyarak Ethereum Ana Ağındaki kötü amaçlı aktivitelere karşı sizi uyarır. Talepleri onaylamadan önce her zaman gereken özeni kendiniz gösterin. Bu özelliğin tüm kötü amaçlı faaliyetleri algılayacağına dair herhangi bir garanti bulunmamaktadır. Bu özelliği etkinleştirerek sağlayıcının kullanım koşullarını kabul etmiş olursunuz.", "smart_transactions_opt_in_heading": "Akıllı İşlemler", - "smart_transactions_opt_in_desc": "Daha güvenilir ve güvenli işlemler ile ETH Ana Ağı üzerinde ayarlanabilir ücretler için Akıllı İşlemleri açın.", - "smart_transactions_learn_more": "Daha fazla bilgi edinin." + "smart_transactions_opt_in_desc": "Daha güvenilir ve emniyetli işlemler için Ethereum Ana Ağı üzerinde Akıllı İşlemleri açın.", + "smart_transactions_learn_more": "Daha fazla bilgi edinin.", + "simulation_details": "Bakiye değişikliklerini tahmin edin", + "simulation_details_description": "İşlemleri onaylamadan önce işlemlerin neden olacağı bakiye değişikliklerini tahmin etmek için bunu açın. İşlemlerinizin nihai sonucunu garanti etmez. ", + "simulation_details_learn_more": "Daha fazla bilgi edinin.", + "aes_crypto_test_form_title": "AES Crypto - Test Biçimi", + "aes_crypto_test_form_description": "Kısım özel olarak E2E testi için geliştirilmiştir. Bu sizin uygulamanızda görünür ise lütfen MetaMask destek bölümüne bildirin." + }, + "aes_crypto_test_form": { + "generate_random_salt": "Rastgele Tuz Oluştur", + "salt_bytes_count": "Tuz bayt sayımı", + "generate": "Oluştur", + "generate_encryption_key": "Şifreden şifreleme anahtarı oluştur", + "password": "Şifre", + "salt": "Tuz", + "encrypt_with_key": "Anahtar ile şifrele", + "encrypt": "Şifrele", + "encryption_key": "Şifreleme Anahtarı", + "data": "Veri", + "decrypt_with_key": "Anahtar ile şifre çöz", + "decrypt": "Şifre çöz" }, "sdk": { "disconnect_title": "Tüm sitelerin bağlantısı kesilsin mi?", @@ -1172,6 +1199,15 @@ "account_copied_to_clipboard": "Genel adres panoya kopyalandı", "share_public_key": "Halka açık anahtarım paylaşılıyor: " }, + "enable_nft-auto-detection": { + "title": "NFT otomatik algılamayı etkinleştir", + "description": "MetaMask'in otomatik algılama ile NFT'lerinizi algılamasına ve göstermesine izin verin. Şunları yapabileceksiniz:", + "immediateAccess": "NFT'lerinize anında erişim sağlayın", + "navigate": "Dijital varlıklarınızda zahmetsizce gezinin", + "dive": "Doğrudan NFT'lerinizi kullanmaya başlayın", + "allow": "İzin Ver", + "notRightNow": "Şimdi değil" + }, "detected_tokens": { "title": "{{tokenCount}} yeni token bulundu", "title_plural": "{{tokenCount}} yeni token bulundu", @@ -1370,10 +1406,12 @@ "approve": "Onayla", "allow_to_access": "Erişim izni verin:", "allow_to_address_access": "Bu adrese erişim izni verin:", + "allow_to_transfer_all": "Erişim ve transfer izni verilsin mi", "spend_cap": "Şunun için harcama üst limiti:", "token": "token", "nft": "NFT", "you_trust_this_site": "İzin vererek aşağıdaki üçüncü tarafın bakiyenize erişim sağlamasına izin verirsiniz.", + "you_trust_this_third_party": "Üçüncü bir tarafın, siz bu erişimi iptal edene kadar başka bildirim yapılmaksızın NFT'lerinize erişim sağlamasına ve onları transfer edebilmesine izin verir.", "you_trust_this_address": "Bu adrese güveniyor musunuz? Bu izni vererek bu adresin paranıza erişim sağlamasına izin veriyorsunuz.", "edit_permission": "İzni düzenle", "edit": "Düzenle", @@ -1477,6 +1515,8 @@ "tx_review_transfer_from": "Şuradan Transfer Et", "tx_review_unknown": "Bilinmeyen Yöntem", "tx_review_approve": "Onayla", + "tx_review_increase_allowance": "Ödeneği Artır", + "tx_review_set_approval_for_all": "Tümüne Onay Ver", "sent_ether": "Ether Gönderdi", "self_sent_ether": "Sana Ether Gönderdi", "received_ether": "Ether Aldı", @@ -1498,11 +1538,17 @@ "smart_contract_interaction": "Akıllı sözleşme etkileşimi", "swaps_transaction": "Swap işlemi", "approve": "Onayla", + "increase_allowance": "Ödeneği Artır", + "set_approval_for_all": "Tümüne Onay Ver", "hash": "Hash", "from": "Kimden", "to": "Kime", "details": "Ayrıntılar", "amount": "Tutar", + "fee": { + "transaction_fee_in_ether": "İşlem Ücreti", + "transaction_fee_in_usd": "İşlem Ücreti (USD)" + }, "gas_used": "Kullanılan Gaz (Birim)", "gas_limit": "Gaz Limiti (Birimler)", "gas_price": "Gaz Fiyatı (GWEI)", @@ -1630,6 +1676,8 @@ "you_can": "Veya", "add_network": "manuel olarak daha fazla ekleyebilirsiniz.", "select_network": "Bir ağ seçin", + "enabled_networks": "Etkinleştirilen ağlar", + "additional_networks": "İlave ağlar", "show_test_networks": "Test ağlarını göster", "deprecated_goerli": "Ethereum'da yaşanan protokol değişikliklerinden dolayı: Goerli test ağı güvenilir bir şekilde çalışmayabilir ve yakında kullanım dışı olacak.", "network_deprecated_title": "Bu ağ artık kullanılmıyor", @@ -1898,19 +1946,26 @@ "back_to_safety": "Güvenliğe geri dön" }, "notifications": { + "staked": "Stake edildi", + "received": "Alınan", + "unstaked": "Unstake edildi", + "to": "Alıcı", + "rate": "Oran (ücretler dahil)", + "unstaking_requested": "Unstake talep edildi", "stake_completed": "Stake tamamlandı", "withdrawal_completed": "Para çekme işlemi tamamlandı", "unstake_completed": "Unstake tamamlandı", "withdrawal_requested": "Para çekme talep edildi", "stake_ready_to_be_withdrawn": "Stake çekilmeye hazır", "swap_completed": "{{from}} - {{to}} swap işlemi gerçekleştirildi", + "swap": "Swap yapılan", "sent": "Alıcı: {{address}}", - "received": "Gönderen: {{address}}", - "nft_sent": "Sent NFT to {{address}}", - "erc721_sent": "Sent NFT to {{address}}", - "erc1155_sent": "Sent NFT to {{address}}", - "erc721_received": "Received NFT from {{address}}", - "erc1155_received": "Received NFT from {{address}}", + "received_from": "Gönderen: {{address}}", + "nft_sent": "NFT alıcısı: {{address}}", + "erc721_sent": "NFT alıcısı: {{address}}", + "erc1155_sent": "NFT alıcısı: {{address}}", + "erc721_received": "NFT gönderen: {{address}}", + "erc1155_received": "NFT gönderen: {{address}}", "received_nft": "NFT gönderen: {{address}}", "pending_title": "İşlem gönderildi", "pending_deposit_title": "Para yatırma işlemi sürüyor!", @@ -1952,6 +2007,7 @@ "wc_description": "Lütfen uygulamayı kontrol edin", "wallet": "Cüzdan", "web3": "Web3", + "staking_provider": "Stake Sağlayıcısı", "empty": { "title": "Burada gösterilecek bir şey yok", "message": "Burası cüzdanınızda aktivite olduğunda bildirimleri bulabileceğiniz yerdir. " @@ -2561,11 +2617,18 @@ "submit_ticket_5": "Buradan", "submit_ticket_6": "bir sorgu gönderin.", "submit_ticket_7": "Lütfen hata mesajını ve ekran görüntüsünü dahil edin.", + "submit_ticket_8": "Bize bir hata raporu gönder", + "submit_ticket_9": "Lütfen ne olduğuyla ilgili ayrıntıları ekleyin.", + "bug_report_prompt_title": "Ne olduğunu bize söyleyin", + "bug_report_prompt_description": "Neyin ters gittiğini anlayabilmemiz için ayrıntıları ekleyin.", + "bug_report_thanks": "Teşekkürler! Kısa bir süre sonra inceleyeceğiz.", "save_seedphrase_1": "Bu hata devam ederse", "save_seedphrase_2": "Gizli Kurtarma İfadenizi kaydedin", "save_seedphrase_3": "ve uygulamayı tekrar yükleyin. Not: Gizli Kurtarma İfadeniz olmadan cüzdanınızı geri YÜKLEYEMEZSİNİZ.", "copied_clipboard": "Panoya kopyalandı", - "ok": "Tamam" + "ok": "Tamam", + "cancel": "İptal", + "send": "Gönder" }, "whats_new": { "title": "Yenilikler", @@ -2585,7 +2648,7 @@ "header": "İyileştirilmiş İşlem Koruması", "description_1": "Akıllı İşlemler ile daha yüksek başarı oranlarının, arkadan çalıştırma korumasının ve daha iyi görünürlüğün kilidini açın.", "description_2": "Sadece Ethereum'da mevcuttur. Dilediğiniz zaman ayarlar kısmında etkinleştirin veya devre dışı bırakın.", - "secondary_button": "İyileştirilmiş korumayı etkinleştirme", + "secondary_button": "Ayarlar kısmında yönet", "primary_button": "Etkinleştir", "learn_more": "Daha fazla bilgi edinin.", "benefit_1_1": "%99,5 başarı oranı", @@ -2594,6 +2657,11 @@ "benefit_2_2": "tasarruf sağlar", "benefit_3_1": "Gerçek zamanlı", "benefit_3_2": "güncellemeler" + }, + "transaction_simulation": { + "title": "Tahmini bakiye değişiklikleri", + "description_1": "Artık gerçekleştirmeden önce işlemlerinizin potansiyel sonuçlarını görebilirsiniz!", + "description_2": "Bu sadece bir simülasyondur, bu nedenle nihai sonucu garanti edemeyiz. Bunu dilediğiniz zaman şurada kapatabilirsiniz: Ayarlar > Güvenlik ve Gizlilik." } }, "invalid_network": { @@ -3025,7 +3093,8 @@ "manage_networks": "Ağları yönet", "manage_networks_body": "Ethereum verilerine mümkün olan en güvenilir ve gizli erişimi sunmak amacıyla uzak yordam çağrısı (RPC) sağlayıcısı olarak Infura kullanırız. Kendi RPC'nizi seçebilirsiniz ancak tüm RPC'lerin işlemleri gerçekleştirmek için IP adresinizi ve Ethereum cüzdanınızı alacağını unutmayın. Infura'nın verileri nasıl kullandığı hakkında daha fazla bilgi edinmek için ", "manage_networks_body2": " $1 bölümümüzü okuyun.", - "functionality_body": "Token verileri ve değeri, en iyi gaz ayarları, güvenlik güncellemeleri ve daha fazlasını içerir. Bu hizmetleri kullanırken tıpkı bir web sitesini ziyaret ederken olduğu gibi IP adresiniz MetaMask ile paylaşılır.", + "functionality_body": "MetaMask, internet hizmetleri üzerinden token bilgileri ve gaz ayarları gibi temel özellikler sunar. İnternet hizmetlerini kullandığınızda IP adresiniz, bu durumda MetaMask ile, paylaşılır. Bu tıpkı herhangi bir web sitesini ziyaret ettiğinizde olduğu gibidir. MetaMask bu verileri geçici olarak kullanır ve verilerinizi hiçbir zaman satmaz. Bir VPN kullanabilir veya bu hizmetleri kapatabilirsiniz ancak bu durum MetaMask deneyiminizi etkileyebilir. Daha fazla bilgi için ", + "functionality_body2": " bölümümüzü okuyun.", "sheet": { "title_off": "Temel işlevselliği kapat", "description_off": "Bu, MetaMask'te zamanınızı tamamen optimize edemeyeceğiniz anlamına gelir. Temel özellikler (token bilgileri, en iyi gaz ayarları vb. gibi) sizin için sunulmayacaktır.", @@ -3038,5 +3107,16 @@ "turn_off": "Kapat" } } + }, + "simulation_details": { + "failed": "Tahmininiz yüklenirken bir hata oldu.", + "fiat_not_available": "Mevcut Değil", + "incoming_heading": "Aldığınız", + "no_balance_changes": "Cüzdanınız için herhangi bir değişiklik öngörülmüyor", + "outgoing_heading": "Gönderdiğiniz", + "reverted": "Bu işlemin başarısız olması muhtemel", + "title": "Tahmini değişiklikler", + "tooltip_description": "Tahmini değişiklikler bu işlemi gerçekleştirirseniz meydana gelebilecek değişikliklerdir. Bu bir garanti değil, sadece bir tahmindir.", + "total_fiat": "Toplam = {{currency}}" } -} \ No newline at end of file +} diff --git a/locales/languages/vi.json b/locales/languages/vi.json index 648848f94ca..6d0afb42500 100644 --- a/locales/languages/vi.json +++ b/locales/languages/vi.json @@ -365,17 +365,17 @@ "title": "Nhận" }, "experience_enhancer_modal": { - "title": "Help us enhance your experience", - "paragraph1a": "In addition to ", - "paragraph1b": ", we'd like to use data (like information from cookies) to learn how you interact with our marketing communications.", + "title": "Hãy giúp chúng tôi nâng cao trải nghiệm của bạn", + "paragraph1a": "Ngoài ", + "paragraph1b": ", chúng tôi muốn sử dụng dữ liệu (chẳng hạn như thông tin từ cookie) để tìm hiểu cách bạn tương tác với các thông tin tiếp thị của chúng tôi.", "link": "MetaMetrics", - "paragraph2": "This helps us personalize what we share with you, like:", - "bullet1": "Latest developments", - "bullet2": "Product features", - "bullet3": "Other relevant promotional materials", - "footer": "Remember, we never sell the data you provide and you can opt out any time.", - "accept": "I agree", - "cancel": "No thanks" + "paragraph2": "Điều này sẽ giúp chúng tôi cá nhân hóa nội dung mà chúng tôi chia sẻ với bạn, chẳng hạn như:", + "bullet1": "Bước tiến mới nhất", + "bullet2": "Tính năng sản phẩm", + "bullet3": "Các tài liệu khuyến mại liên quan khác", + "footer": "Hãy nhớ rằng chúng tôi không bán dữ liệu mà bạn cung cấp và bạn có thể chọn không tham gia bất kỳ lúc nào.", + "accept": "Tôi đồng ý", + "cancel": "Không, cảm ơn" }, "wallet": { "title": "Ví", @@ -413,7 +413,7 @@ "no_tokens": "Bạn không có token nào!", "no_nfts_yet": "Chưa có NFT", "nfts_autodetection_title": "Phát hiện NFT", - "nfts_autodetection_desc": "Cho phép MetaMask tự động phát hiện NFT từ OpenSea và hiển thị trên ví MetaMask của bạn.", + "nfts_autodetection_desc": "Cho phép MetaMask tự động phát hiện và hiển thị NFT trong ví của bạn.", "network_details_check": "Kiểm tra thông tin mạng", "network_with_chain_id": "Mạng có ID chuỗi", "chain_list_returned_different_ticker_symbol": "Biểu tượng token này không trùng khớp với tên mạng hoặc ID chuỗi đã nhập. Nhiều token phổ biến sử dụng các biểu tượng tương tự, do đó những kẻ lừa đảo có thể lợi dụng điều này để lừa bạn gửi cho chúng một token có giá trị hơn. Nhớ xác minh mọi thông tin trước khi tiếp tục.", @@ -454,7 +454,7 @@ "display_nft_media_cta": "Bật Hiển thị phương tiện NFT", "display_media_nft_warning": "Việc hiển thị dữ liệu và phương tiện NFT có thể làm lộ địa chỉ IP của bạn với các máy chủ tập trung. Chỉ nhập NFT nếu bạn hiểu rõ những rủi ro đi kèm.", "nfts_autodetect_title": "Tự động phát hiện NFT", - "nfts_autodetect_cta": "Bật Tự động phát hiện NFT trong phần Cài đặt", + "nfts_autodetect_cta": "Bật tính năng tự động phát hiện NFT", "turn_on_network_check_cta": "Bật kiểm tra thông tin mạng", "display_nft_media_cta_new_1": "Để xem một NFT, hãy bật Hiển thị phương tiện NFT trong", "display_nft_media_cta_new_2": "Cài đặt > Bảo mật và quyền riêng tư.", @@ -520,7 +520,7 @@ "description_title": "Giúp chúng tôi cải thiện MetaMask", "description_content_1": "Chúng tôi muốn thu thập dữ liệu sử dụng cơ bản để cải tiến MetaMask. Xin lưu ý, chúng tôi không bao giờ bán dữ liệu mà bạn cung cấp ở đây.", "description_content_2": "Khi thu thập số liệu, chúng tôi sẽ luôn cam kết điều này...", - "checkbox": "We'll use this data to learn how you interact with our marketing communications. We may share relavent news (like product features).", + "checkbox": "Chúng tôi sẽ sử dụng dữ liệu này để tìm hiểu cách bạn tương tác với các thông tin tiếp thị. Chúng tôi có thể chia sẻ tin tức liên quan (chẳng hạn như tính năng sản phẩm).", "action_description_1_prefix": "Riêng tư:", "action_description_2_prefix": "Chung:", "action_description_3_prefix": "Không bắt buộc:", @@ -650,7 +650,8 @@ "revoked_all": "Tất cả tài khoản đã bị thu hồi.", "accounts_connected": "tài khoản đã được kết nối.", "disconnected": "đã ngắt kết nối.", - "disconnected_all": "Đã ngắt kết nối tất cả các tài khoản." + "disconnected_all": "Đã ngắt kết nối tất cả các tài khoản.", + "nft_detection_enabled": "Tính năng tự động phát hiện NFT đã được bật" }, "connect_qr_hardware": { "title": "Kết nối với một ví cứng dựa trên mã QR", @@ -671,8 +672,8 @@ "please_wait": "Vui lòng chờ" }, "data_collection_modal": { - "accept": "Okay", - "content": "You turned off data collection for our marketing purposes. This only applies to this device. If you use MetaMask on other devices, make sure to opt out there as well." + "accept": "Đồng ý", + "content": "Bạn đã tắt tính năng thu thập dữ liệu cho mục đích tiếp thị của chúng tôi. Thao tác này chỉ áp dụng cho thiết bị này. Nếu bạn sử dụng MetaMask trên các thiết bị khác, nhớ chọn không tham gia trên các thiết bị đó." }, "account_selector": { "prev": "TRƯỚC", @@ -845,9 +846,9 @@ "clear_history_desc": "Chọn tùy chọn này để xóa toàn bộ lịch sử duyệt web của bạn.", "clear_cookies_desc": "Chọn tùy chọn này để xóa cookie trình duyệt của bạn.", "metametrics_title": "Tham gia vào MetaMetrics", - "metametrics_description": "Allow MetaMetrics to collect basic usage and diagnostics data to improve our product. You can disable MetaMetrics for this device.", - "data_collection_title": "Data collection for marketing", - "data_collection_description": "We’ll use MetaMetrics to learn how you interact with our marketing communications. We may share relevant news (like product features and other materials).", + "metametrics_description": "Cho phép MetaMetrics thu thập dữ liệu sử dụng và chẩn đoán cơ bản để cải thiện sản phẩm của chúng tôi. Bạn có thể tắt MetaMetrics cho thiết bị này.", + "data_collection_title": "Thu thập dữ liệu cho mục đích tiếp thị", + "data_collection_description": "Chúng tôi sẽ sử dụng MetaMetrics để tìm hiểu cách bạn tương tác với các thông tin tiếp thị. Chúng tôi có thể chia sẻ tin tức liên quan (chẳng hạn như tính năng sản phẩm và các tài liệu khác).", "batch_balance_requests_title": "Xử lý hàng loạt yêu cầu số dư tài khoản", "batch_balance_requests_description": "Chúng tôi xử lý hàng loạt tài khoản và truy vấn Infura để hiển thị các số dư của bạn một cách nhanh chóng. Nếu bạn tắt tính năng này, chỉ những tài khoản đang hoạt động mới được truy vấn. Một số dApp sẽ không hoạt động trừ khi bạn kết nối với ví của mình.", "third_party_title": "Nhận các giao dịch chuyển đến", @@ -888,6 +889,13 @@ "delete": "Xóa", "network_exists": "Mạng này đã được thêm.", "delete_metrics_title": "Xóa dữ liệu MetaMetrics", + "delete_metrics_description_part_one": "Thao tác này sẽ xóa dữ liệu", + "delete_metrics_description_part_two": "MetaMetrics", + "delete_metrics_description_part_three": "lịch sử được liên kết với ví của bạn.", + "delete_metrics_description_before_delete": "Ví và tài khoản của bạn sẽ vẫn giữ nguyên như hiện tại sau khi dữ liệu này đã bị xóa. Quá trình này có thể mất đến 30 ngày. Xem", + "delete_metrics_description_after_delete_part_one": "Bạn đã thực hiện hành động này vào", + "delete_metrics_description_after_delete_part_two": ". Quá trình này có thể mất đến 30 ngày. Xem", + "delete_metrics_description_privacy_policy": "Chính sách quyền riêng tư.", "delete_metrics_button": "Xóa dữ liệu MetaMetrics", "check_status_button": "Kiểm tra trạng thái", "delete_metrics_confirm_modal_title": "Xóa dữ liệu MetaMetrics?", @@ -990,8 +998,27 @@ "security_alerts": "Cảnh báo bảo mật", "security_alerts_desc": "Tính năng này sẽ cảnh báo bạn về hoạt động độc hại bằng cách xem xét cục bộ các yêu cầu giao dịch và chữ ký của bạn. Hãy luôn tự mình thực hiện quy trình thẩm định trước khi chấp thuận bất kỳ yêu cầu nào. Không có gì đảm bảo rằng tính năng này sẽ phát hiện được tất cả các hoạt động độc hại. Bằng cách bật tính năng này, bạn đồng ý với các điều khoản sử dụng của nhà cung cấp.", "smart_transactions_opt_in_heading": "Giao dịch thông minh", - "smart_transactions_opt_in_desc": "Bật Giao dịch thông minh để có các giao dịch đáng tin cậy và an toàn hơn, cùng phí có thể điều chỉnh trên Mạng chính của ETH.", - "smart_transactions_learn_more": "Tìm hiểu thêm." + "smart_transactions_opt_in_desc": "Bật Giao dịch thông minh để có các giao dịch đáng tin cậy và an toàn hơn trên Ethereum Mainnet.", + "smart_transactions_learn_more": "Tìm hiểu thêm.", + "simulation_details": "Ước tính thay đổi số dư", + "simulation_details_description": "Bật tính năng này để ước tính thay đổi số dư của các giao dịch trước khi bạn xác nhận. Điều này không đảm bảo cho kết quả cuối cùng của giao dịch. ", + "simulation_details_learn_more": "Tìm hiểu thêm.", + "aes_crypto_test_form_title": "Tiền mã hóa AES - Mẫu thử nghiệm", + "aes_crypto_test_form_description": "Phần được phát triển dành riêng cho thử nghiệm E2E. Nếu bạn thấy phần này trong ứng dụng, vui lòng báo cáo với bộ phận hỗ trợ của MetaMask." + }, + "aes_crypto_test_form": { + "generate_random_salt": "Tạo Salt ngẫu nhiên", + "salt_bytes_count": "Số byte Salt", + "generate": "Tạo", + "generate_encryption_key": "Tạo khóa mã hóa từ mật khẩu", + "password": "Mật khẩu", + "salt": "Salt", + "encrypt_with_key": "Mã hóa bằng khóa", + "encrypt": "Mã hóa", + "encryption_key": "Khóa mã hóa", + "data": "Dữ liệu", + "decrypt_with_key": "Giải mã bằng khóa", + "decrypt": "Giải mã" }, "sdk": { "disconnect_title": "Ngắt kết nối tất cả các trang web?", @@ -1172,6 +1199,15 @@ "account_copied_to_clipboard": "Đã sao chép địa chỉ công khai vào bộ nhớ đệm", "share_public_key": "Chia sẻ khóa công khai của tôi: " }, + "enable_nft-auto-detection": { + "title": "Bật tính năng tự động phát hiện NFT", + "description": "Cho phép MetaMask phát hiện và hiển thị NFT của bạn bằng tính năng tự động phát hiện. Bạn sẽ có thể:", + "immediateAccess": "Truy cập ngay lập tức vào NFT của bạn", + "navigate": "Dễ dàng quản lý tài sản kỹ thuật số của bạn", + "dive": "Bắt đầu sử dụng NFT của bạn ngay lập tức", + "allow": "Cho phép", + "notRightNow": "Không phải bây giờ" + }, "detected_tokens": { "title": "Đã tìm thấy {{tokenCount}} token mới", "title_plural": "Đã tìm thấy {{tokenCount}} token mới", @@ -1370,10 +1406,12 @@ "approve": "Chấp thuận", "allow_to_access": "Cấp quyền truy cập", "allow_to_address_access": "Cho phép địa chỉ này truy cập", + "allow_to_transfer_all": "Cho phép truy cập và chuyển tất cả", "spend_cap": "Yêu cầu hạn mức chi tiêu cho", "token": "token", "nft": "NFT", "you_trust_this_site": "Bằng cách cấp quyền, bạn đang cho phép bên thứ ba sau đây truy cập vào số tiền của bạn.", + "you_trust_this_third_party": "Điều này cho phép bên thứ ba được quyền truy cập và chuyển các NFT của bạn mà không cần thông báo thêm cho đến khi bạn thu hồi quyền truy cập của họ.", "you_trust_this_address": "Bạn tin tưởng địa chỉ này? Bằng cách cấp quyền, bạn đang cho phép địa chỉ này truy cập tiền của bạn.", "edit_permission": "Sửa quyền", "edit": "Sửa", @@ -1477,6 +1515,8 @@ "tx_review_transfer_from": "Chuyển từ", "tx_review_unknown": "Phương thức không xác định", "tx_review_approve": "Chấp thuận", + "tx_review_increase_allowance": "Tăng hạn mức", + "tx_review_set_approval_for_all": "Thiết lập phê duyệt tất cả", "sent_ether": "Đã gửi Ether", "self_sent_ether": "Đã gửi Ether cho chính bạn", "received_ether": "Đã nhận Ether", @@ -1498,11 +1538,17 @@ "smart_contract_interaction": "Tương tác hợp đồng thông minh", "swaps_transaction": "Giao dịch hoán đổi", "approve": "Chấp thuận", + "increase_allowance": "Tăng hạn mức", + "set_approval_for_all": "Thiết lập phê duyệt tất cả", "hash": "Mã băm", "from": "Từ", "to": "Đến", "details": "Chi tiết", "amount": "Số tiền", + "fee": { + "transaction_fee_in_ether": "Phí giao dịch", + "transaction_fee_in_usd": "Phí giao dịch (USD)" + }, "gas_used": "Gas đã sử dụng (Đơn vị)", "gas_limit": "Giới hạn gas (Đơn vị)", "gas_price": "Giá gas (GWEI)", @@ -1630,6 +1676,8 @@ "you_can": "Hoặc bạn có thể", "add_network": "thêm thủ công các mạng khác.", "select_network": "Chọn mạng", + "enabled_networks": "Mạng được bật", + "additional_networks": "Mạng bổ sung", "show_test_networks": "Hiển thị các mạng thử nghiệm", "deprecated_goerli": "Do những thay đổi trong giao thức của Ethereum: Mạng thử nghiệm Goerli có thể không hoạt động đáng tin cậy và sẽ sớm bị ngừng sử dụng.", "network_deprecated_title": "Mạng này đã ngừng sử dụng", @@ -1898,19 +1946,26 @@ "back_to_safety": "Quay lại mục an toàn" }, "notifications": { + "staked": "Đã ký gửi", + "received": "Đã nhận", + "unstaked": "Đã hủy ký gửi", + "to": "Đến", + "rate": "Tỷ giá (đã bao gồm phí)", + "unstaking_requested": "Đã yêu cầu hủy ký gửi", "stake_completed": "Ký gửi đã hoàn tất", "withdrawal_completed": "Rút tiền đã hoàn tất", "unstake_completed": "Hủy ký gửi đã hoàn tất", "withdrawal_requested": "Đã yêu cầu rút tiền", "stake_ready_to_be_withdrawn": "Tài sản ký gửi đã sẵn sàng để rút", "swap_completed": "Đã hoán đổi {{from}} thành {{to}}", + "swap": "Đã hoán đổi", "sent": "Đã gửi đến {{address}}", - "received": "Đã nhận được từ {{address}}", - "nft_sent": "Sent NFT to {{address}}", - "erc721_sent": "Sent NFT to {{address}}", - "erc1155_sent": "Sent NFT to {{address}}", - "erc721_received": "Received NFT from {{address}}", - "erc1155_received": "Received NFT from {{address}}", + "received_from": "Đã nhận được từ {{address}}", + "nft_sent": "Đã gửi NFT đến {{address}}", + "erc721_sent": "Đã gửi NFT đến {{address}}", + "erc1155_sent": "Đã gửi NFT đến {{address}}", + "erc721_received": "Đã nhận được NFT từ {{address}}", + "erc1155_received": "Đã nhận được NFT từ {{address}}", "received_nft": "Đã nhận được NFT từ {{address}}", "pending_title": "Đã gửi giao dịch", "pending_deposit_title": "Đang nạp tiền!", @@ -1952,6 +2007,7 @@ "wc_description": "Vui lòng kiểm tra ứng dụng", "wallet": "Ví", "web3": "Web3", + "staking_provider": "Nhà cung cấp dịch vụ ký gửi", "empty": { "title": "Không có gì ở đây", "message": "Đây là nơi bạn có thể tìm thấy thông báo khi có hoạt động trong ví của bạn. " @@ -2561,11 +2617,18 @@ "submit_ticket_5": "Nộp phiếu hỏi đáp", "submit_ticket_6": "tại đây.", "submit_ticket_7": "Vui lòng cung cấp cả tin nhắn báo lỗi và ảnh chụp màn hình.", + "submit_ticket_8": "Gửi báo cáo lỗi", + "submit_ticket_9": "Vui lòng đính kèm thông tin về vấn đề đã xảy ra.", + "bug_report_prompt_title": "Ghi rõ vấn đề gì đã xảy ra", + "bug_report_prompt_description": "Thêm thông tin để chúng tôi biết vấn đề gì đã xảy ra.", + "bug_report_thanks": "Xin cảm ơn! Chúng tôi sẽ sớm xem xét.", "save_seedphrase_1": "Nếu lỗi này vẫn tiếp diễn,", "save_seedphrase_2": "hãy lưu Cụm từ khôi phục bí mật của bạn", "save_seedphrase_3": "& cài đặt lại ứng dụng. Lưu ý: bạn KHÔNG thể khôi phục ví nếu không có Cụm từ khôi phục bí mật.", "copied_clipboard": "Đã sao chép vào bộ nhớ đệm", - "ok": "OK" + "ok": "OK", + "cancel": "Hủy", + "send": "Gửi" }, "whats_new": { "title": "Xem tính năng mới", @@ -2585,7 +2648,7 @@ "header": "Tăng cường bảo vệ giao dịch", "description_1": "Đạt tỷ lệ thành công cao hơn, bảo vệ chống hành vi lợi dụng thông tin biết trước và khả năng hiển thị tốt hơn với Giao dịch thông minh.", "description_2": "Chỉ có sẵn trên Ethereum. Có thể bật/tắt bất cứ lúc nào trong phần Cài đặt.", - "secondary_button": "Không bật bảo vệ nâng cao", + "secondary_button": "Quản lý trong phần cài đặt", "primary_button": "Bật", "learn_more": "Tìm hiểu thêm.", "benefit_1_1": "Tỷ lệ thành công", @@ -2594,6 +2657,11 @@ "benefit_2_2": "của bạn", "benefit_3_1": "Cập nhật", "benefit_3_2": "theo thời gian thực" + }, + "transaction_simulation": { + "title": "Thay đổi số dư ước tính", + "description_1": "Bây giờ bạn có thể xem kết quả tiềm năng của các giao dịch trước khi thực hiện!", + "description_2": "Đây chỉ là mô phỏng, vì vậy chúng tôi không thể đảm bảo kết quả cuối cùng. Bạn có thể tắt tính năng này bất cứ lúc nào trong phần Cài đặt > Bảo mật & Quyền riêng tư." } }, "invalid_network": { @@ -3025,7 +3093,8 @@ "manage_networks": "Quản lý mạng", "manage_networks_body": "Chúng tôi sử dụng Infura làm nhà cung cấp dịch vụ gọi hàm từ xa (RPC) để cung cấp quyền truy cập riêng tư và đáng tin cậy nhất có thể vào dữ liệu Ethereum. Bạn có thể chọn RPC của riêng mình, nhưng hãy nhớ rằng bất kỳ RPC nào cũng sẽ thu thập địa chỉ IP và ví Ethereum của bạn để thực hiện giao dịch. Đọc ", "manage_networks_body2": " để tìm hiểu thêm về cách Infura xử lý dữ liệu.", - "functionality_body": "Bao gồm dữ liệu và giá trị của token, cài đặt gas tối ưu, cập nhật bảo mật, v.v. Sử dụng các dịch vụ này sẽ chia sẻ địa chỉ IP của bạn với MetaMask, giống như khi bạn truy cập một trang web.", + "functionality_body": "MetaMask cung cấp các tính năng cơ bản như chi tiết token và cài đặt gas thông qua các dịch vụ Internet. Khi bạn sử dụng các dịch vụ Internet, địa chỉ IP của bạn sẽ được chia sẻ, trong trường hợp này là với MetaMask. Điều này giống như khi bạn truy cập bất kỳ trang web nào. MetaMask sử dụng dữ liệu này tạm thời và không bao giờ bán dữ liệu của bạn. Bạn có thể sử dụng VPN hoặc tắt các dịch vụ này, nhưng nó có thể ảnh hưởng đến trải nghiệm sử dụng MetaMask của bạn. Đọc ", + "functionality_body2": " để tìm hiểu thêm.", "sheet": { "title_off": "Tắt chức năng cơ bản", "description_off": "Điều này có nghĩa là bạn sẽ không thể tối ưu hoàn toàn thời gian sử dụng MetaMask. Các tính năng cơ bản (chẳng hạn như chi tiết token, cài đặt gas tối ưu và các tính năng khác) sẽ không khả dụng.", @@ -3038,5 +3107,16 @@ "turn_off": "Tắt" } } + }, + "simulation_details": { + "failed": "Đã xảy ra lỗi khi tải kết quả ước tính.", + "fiat_not_available": "Không có sẵn", + "incoming_heading": "Bạn nhận được", + "no_balance_changes": "Ví của bạn dự kiến không có thay đổi nào", + "outgoing_heading": "Bạn gửi", + "reverted": "Giao dịch này có khả năng thất bại", + "title": "Thay đổi ước tính", + "tooltip_description": "Thay đổi ước tính là những gì có thể xảy ra nếu bạn thực hiện giao dịch này. Đây chỉ là dự đoán, không phải là đảm bảo.", + "total_fiat": "Tổng cộng = {{currency}}" } -} \ No newline at end of file +} diff --git a/locales/languages/zh.json b/locales/languages/zh.json index f88023c73d6..008e1ec3bdd 100644 --- a/locales/languages/zh.json +++ b/locales/languages/zh.json @@ -365,17 +365,17 @@ "title": "接收" }, "experience_enhancer_modal": { - "title": "Help us enhance your experience", - "paragraph1a": "In addition to ", - "paragraph1b": ", we'd like to use data (like information from cookies) to learn how you interact with our marketing communications.", + "title": "帮助我们改善您的体验", + "paragraph1a": "除了 ", + "paragraph1b": ",我们还想使用数据(例如来自 cookies 的信息)来了解您如何与我们的营销通信交互。", "link": "MetaMetrics", - "paragraph2": "This helps us personalize what we share with you, like:", - "bullet1": "Latest developments", - "bullet2": "Product features", - "bullet3": "Other relevant promotional materials", - "footer": "Remember, we never sell the data you provide and you can opt out any time.", - "accept": "I agree", - "cancel": "No thanks" + "paragraph2": "这可以帮助我们个性化与您分享的内容,例如:", + "bullet1": "最新发展动态", + "bullet2": "产品特点", + "bullet3": "其他相关宣传材料", + "footer": "请记住,我们绝不会出卖您提供的数据,并且您可以随时选择退出。", + "accept": "我同意", + "cancel": "不,谢谢" }, "wallet": { "title": "钱包", @@ -413,7 +413,7 @@ "no_tokens": "您没有任何代币!", "no_nfts_yet": "尚无 NFT", "nfts_autodetection_title": "NFT 检测", - "nfts_autodetection_desc": "允许 MetaMask 自动检测 OpenSea 的 NFT,并显示在您的 MetaMask 钱包里。", + "nfts_autodetection_desc": "让 MetaMask 自动检测并显示您钱包中的 NFT。", "network_details_check": "网络详情检查", "network_with_chain_id": "网络及其链 ID", "chain_list_returned_different_ticker_symbol": "此代币符号与输入的网络名称或链 ID 不匹配。许多热门代币使用类似的符号,骗子可能会使用这些符号来欺骗您,让您向他们发送更有价值的代币作为回报。在您继续之前请先验证所有信息。", @@ -454,7 +454,7 @@ "display_nft_media_cta": "打开“显示NFT媒体”", "display_media_nft_warning": "显示NFT媒体和数据可能会导致您的IP地址被中心化服务器获悉。仅当您了解相关风险时才可导入NFT。", "nfts_autodetect_title": "NFT自动检测", - "nfts_autodetect_cta": "在设置中打开“自动检测NFT”", + "nfts_autodetect_cta": "启用 NFT 自动检测", "turn_on_network_check_cta": "开启网络详情检查", "display_nft_media_cta_new_1": "要查看NFT,请在此打开“显示NFT媒体”", "display_nft_media_cta_new_2": "设置>安全和隐私。", @@ -520,7 +520,7 @@ "description_title": "帮助我们改进 MetaMask", "description_content_1": "我们希望收集基本的使用数据,以改进 MetaMask。请注意,我们绝不会出卖您在此处提供的数据。", "description_content_2": "当我们收集指标时,总是...", - "checkbox": "We'll use this data to learn how you interact with our marketing communications. We may share relavent news (like product features).", + "checkbox": "我们将使用此数据来了解您如何与我们的营销通信交互。我们可能会分享相关资讯(例如产品特点)。", "action_description_1_prefix": "私密:", "action_description_2_prefix": "通用:", "action_description_3_prefix": "可选:", @@ -650,7 +650,8 @@ "revoked_all": "已撤销所有账户。", "accounts_connected": "账户已连接。", "disconnected": "已断开连接。", - "disconnected_all": "所有账户都已断开连接。" + "disconnected_all": "所有账户都已断开连接。", + "nft_detection_enabled": "已启用 NFT 自动检测" }, "connect_qr_hardware": { "title": "连接基于二维码的硬件钱包", @@ -671,8 +672,8 @@ "please_wait": "请稍候" }, "data_collection_modal": { - "accept": "Okay", - "content": "You turned off data collection for our marketing purposes. This only applies to this device. If you use MetaMask on other devices, make sure to opt out there as well." + "accept": "好的", + "content": "您关闭了我们用于营销目的的数据收集。 这仅适用于此设备。如果您在其他设备上使用 MetaMask,请务必也在其他设备上选择退出。" }, "account_selector": { "prev": "上一步", @@ -845,9 +846,9 @@ "clear_history_desc": "选择此选项可清除您的整个浏览历史记录。", "clear_cookies_desc": "选择此选项可清除您的浏览器的 Cookie。", "metametrics_title": "参加 MetaMetrics", - "metametrics_description": "Allow MetaMetrics to collect basic usage and diagnostics data to improve our product. You can disable MetaMetrics for this device.", - "data_collection_title": "Data collection for marketing", - "data_collection_description": "We’ll use MetaMetrics to learn how you interact with our marketing communications. We may share relevant news (like product features and other materials).", + "metametrics_description": "允许 MetaMetrics 收集基本使用和诊断数据,以改进我们的产品。您可以为此设备禁用 MetaMetrics。", + "data_collection_title": "用于营销目的的数据收集", + "data_collection_description": "我们将使用 MetaMetrics 来了解您如何与我们的营销通信交互。我们可能会分享相关资讯(例如产品特点和其他内容)。", "batch_balance_requests_title": "批量账户余额请求", "batch_balance_requests_description": "我们对账户进行批量处理并查询 Infura ,以便对应地显示您的余额。如果关闭此选项,则仅限查询活跃账户。除非连接钱包,否则某些去中心化应用(dApp)将无法工作。", "third_party_title": "获取传入交易", @@ -888,6 +889,13 @@ "delete": "删除", "network_exists": "这个网络已经被添加。", "delete_metrics_title": "删除MetaMetrics数据", + "delete_metrics_description_part_one": "此操作将删除历史记录", + "delete_metrics_description_part_two": "MetaMetrics", + "delete_metrics_description_part_three": "与钱包相关的数据。", + "delete_metrics_description_before_delete": "删除此数据后,您的钱包和账户将保持原样。此过程可能需要长达 30 天的时间。查看我们的", + "delete_metrics_description_after_delete_part_one": "您在此处启动了此操作:", + "delete_metrics_description_after_delete_part_two": "。此过程可能需要长达 30 天的时间。查看我们的", + "delete_metrics_description_privacy_policy": "隐私政策。", "delete_metrics_button": "删除MetaMetrics数据", "check_status_button": "检查状态", "delete_metrics_confirm_modal_title": "要删除MetaMetrics数据吗?", @@ -990,8 +998,27 @@ "security_alerts": "安全提醒", "security_alerts_desc": "此功能通过本地审查您的交易和签名请求来提醒您注意恶意活动。在批准任何请求之前,请务必自行进行审慎调查。无法保证此功能能够检测到所有恶意活动。启用此功能即表示您同意提供商的使用条款。", "smart_transactions_opt_in_heading": "智能交易", - "smart_transactions_opt_in_desc": "开启智能交易,以实现更加安全可靠的交易,并在 ETH 主网上调整费用。", - "smart_transactions_learn_more": "了解更多。" + "smart_transactions_opt_in_desc": "开启智能交易,以便在以太坊主网上实现更加安全可靠的交易。", + "smart_transactions_learn_more": "了解更多。", + "simulation_details": "预计余额变化", + "simulation_details_description": "开启此选项,以便在确认交易之前估计交易余额的变化。这并不能保证交易的最终结果。 ", + "simulation_details_learn_more": "了解更多。", + "aes_crypto_test_form_title": "AES 加密 - 测试表", + "aes_crypto_test_form_description": "专为 E2E 测试开发的部分。如果这在您的应用程序中可见,请向 MetaMask 支持团队报告。" + }, + "aes_crypto_test_form": { + "generate_random_salt": "生成随机盐", + "salt_bytes_count": "盐字节数", + "generate": "生成", + "generate_encryption_key": "从密码生成加密密钥", + "password": "密码", + "salt": "盐", + "encrypt_with_key": "使用密钥加密", + "encrypt": "加密", + "encryption_key": "加密密钥", + "data": "数据", + "decrypt_with_key": "使用密钥解密", + "decrypt": "解密" }, "sdk": { "disconnect_title": "要断开所有网站的连接吗?", @@ -1110,7 +1137,7 @@ }, "asset_overview": { "send_button": "发送", - "buy_button": "购买", + "buy_button": "买入", "sell_button": "卖出", "receive_button": "接收", "portfolio_button": "投资组合", @@ -1172,6 +1199,15 @@ "account_copied_to_clipboard": "公钥已复制到剪贴板", "share_public_key": "共享我的公钥:" }, + "enable_nft-auto-detection": { + "title": "启用 NFT 自动检测", + "description": "允许 MetaMask 使用自动检测功能检测并显示您的 NFT。您将能够:", + "immediateAccess": "立即访问您的 NFT", + "navigate": "轻松浏览您的数字资产", + "dive": "直接开始使用您的 NFT", + "allow": "允许", + "notRightNow": "暂时不" + }, "detected_tokens": { "title": "找到{{tokenCount}}个新代币", "title_plural": "找到{{tokenCount}}个新代币", @@ -1370,10 +1406,12 @@ "approve": "批准", "allow_to_access": "授予权限以访问您的", "allow_to_address_access": "准许此地址访问您的", + "allow_to_transfer_all": "允许访问并转移您所有的", "spend_cap": "下列项目的支出上限请求", "token": "代币", "nft": "NFT", "you_trust_this_site": "授予此权限,即表示您允许以下第三方存取您的资金。", + "you_trust_this_third_party": "这允许第三方访问并转移您的 NFT,而无需另行通知,直到您撤销其访问权限。", "you_trust_this_address": "您是否信任此地址?授予此权限,即表示您允许此地址访问您的资金。", "edit_permission": "编辑权限", "edit": "编辑", @@ -1477,6 +1515,8 @@ "tx_review_transfer_from": "转移自", "tx_review_unknown": "未知方法", "tx_review_approve": "批准", + "tx_review_increase_allowance": "增加限额", + "tx_review_set_approval_for_all": "设置批准所有", "sent_ether": "已发送以太币", "self_sent_ether": "已向自己发送以太币", "received_ether": "已接收以太币", @@ -1498,11 +1538,17 @@ "smart_contract_interaction": "智能合约交互", "swaps_transaction": "兑换交易", "approve": "批准", + "increase_allowance": "增加限额", + "set_approval_for_all": "设置批准所有", "hash": "哈希", "from": "自", "to": "至", "details": "详细信息", "amount": "数额", + "fee": { + "transaction_fee_in_ether": "交易费用", + "transaction_fee_in_usd": "交易费用 (USD)" + }, "gas_used": "已使用燃料(单位)", "gas_limit": "燃料限额(单位)", "gas_price": "燃料价格 (GWEI)", @@ -1630,6 +1676,8 @@ "you_can": "或者您可以", "add_network": "手动添加更多网络。", "select_network": "选择网络", + "enabled_networks": "启用的网络", + "additional_networks": "其他网络", "show_test_networks": "显示测试网络", "deprecated_goerli": "由于以太坊协议的变化:Goerli 测试网络可能无法可靠工作,很快就会弃用。", "network_deprecated_title": "该网络已弃用", @@ -1898,19 +1946,26 @@ "back_to_safety": "返回以确保安全" }, "notifications": { + "staked": "已质押", + "received": "已收到", + "unstaked": "已解除质押", + "to": "至", + "rate": "价格(包括费用)", + "unstaking_requested": "已请求解除质押", "stake_completed": "质押已完成", "withdrawal_completed": "提取已完成", "unstake_completed": "取消质押已完成", "withdrawal_requested": "已请求提取", "stake_ready_to_be_withdrawn": "已准备好提取质押", "swap_completed": "已用 {{from}} 兑换 {{to}}", + "swap": "已兑换", "sent": "已发送至 {{address}}", - "received": "已从 {{address}} 收到", - "nft_sent": "Sent NFT to {{address}}", - "erc721_sent": "Sent NFT to {{address}}", - "erc1155_sent": "Sent NFT to {{address}}", - "erc721_received": "Received NFT from {{address}}", - "erc1155_received": "Received NFT from {{address}}", + "received_from": "已从 {{address}} 收到", + "nft_sent": "已发送 NFT 至 {{address}}", + "erc721_sent": "已发送 NFT 至 {{address}}", + "erc1155_sent": "已发送 NFT 至 {{address}}", + "erc721_received": "已从 {{address}} 收到 NFT", + "erc1155_received": "已从 {{address}} 收到 NFT", "received_nft": "已从 {{address}} 收到 NFT", "pending_title": "已提交交易", "pending_deposit_title": "保证经进行中!", @@ -1952,6 +2007,7 @@ "wc_description": "请检查应用程序", "wallet": "钱包", "web3": "Web3", + "staking_provider": "质押提供商", "empty": { "title": "此处无内容", "message": "当您的钱包有活动时,您可以在此处找到通知。" @@ -2017,7 +2073,7 @@ "qr_code_description": "能够读取您的地址的可扫描图像", "request_title": "请求", "request_description": "向朋友请求资产", - "buy_title": "购买", + "buy_title": "买入", "buy_description": "使用借记卡或银行转账购买加密币", "public_address": "公钥", "public_address_qr_code": "公钥", @@ -2561,11 +2617,18 @@ "submit_ticket_5": "在此处提交", "submit_ticket_6": "工单。", "submit_ticket_7": "请包含错误消息和屏幕截图。", + "submit_ticket_8": "向我们发送错误报告", + "submit_ticket_9": "请包含所发生情况的详细说明。", + "bug_report_prompt_title": "告诉我们发生了什么", + "bug_report_prompt_description": "添加详细信息,以便我们能够找出问题所在。", + "bug_report_thanks": "谢谢!我们很快会查看。", "save_seedphrase_1": "如果此错误持续存在,", "save_seedphrase_2": "请保存您的助记词", "save_seedphrase_3": "并重新安装应用。注:没有私钥助记词将无法恢复钱包。", "copied_clipboard": "已复制到剪贴板", - "ok": "确定" + "ok": "确定", + "cancel": "取消", + "send": "发送" }, "whats_new": { "title": "最新动态", @@ -2585,7 +2648,7 @@ "header": "增强型交易保护", "description_1": "通过智能交易解锁更高的成功率、抢先交易保护和更高的透明度。", "description_2": "仅适用于以太坊。可随时在设置中启用或禁用。", - "secondary_button": "不启用增强型保护", + "secondary_button": "在设置中管理", "primary_button": "启用", "learn_more": "了解更多。", "benefit_1_1": "99.5% 的成功", @@ -2594,6 +2657,11 @@ "benefit_2_2": "钱", "benefit_3_1": "实时", "benefit_3_2": "更新" + }, + "transaction_simulation": { + "title": "预计余额变化", + "description_1": "现在,您可以在进行交易之前看到交易的潜在结果!", + "description_2": "这只是一次模拟,所以我们不能保证最终的结果。您可以随时在“设置 >安全与隐私”中关闭。" } }, "invalid_network": { @@ -3025,7 +3093,8 @@ "manage_networks": "管理网络", "manage_networks_body": "我们使用 Infura 作为我们的远程过程调用(RPC)提供商,以提供最可靠和最私密的以太坊数据访问。您可以选择自己的 RPC,但请谨记,任何 RPC 都可以接收您的 IP 地址和以太坊钱包以进行交易。请阅读我们的 ", "manage_networks_body2": " 以进一步了解 Infura 如何处理数据。", - "functionality_body": "包括代币数据和值、最优燃料设置、安全更新等。使用这些服务会与 MetaMask 共享您的 IP 地址,就像您访问网站一样。", + "functionality_body": "MetaMask 通过互联网服务提供代币详情和燃料设置等基本功能。当您使用互联网服务时,您的 IP 地址会共享,在本例中与 MetaMask 共享。这就像您访问任何网站一样。MetaMask 暂时使用这些数据,并且绝不会出卖您的数据。您可以使用 VPN 或关闭这些服务,但这可能会影响您的 MetaMask 体验。阅读我们的 ", + "functionality_body2": " 了解详情。", "sheet": { "title_off": "关闭基本功能", "description_off": "这意味着您不能充分优化您在 MetaMask 上的时间。您将无法使用基本功能(例如代币详情、最优燃料设置等)。", @@ -3038,5 +3107,16 @@ "turn_off": "关闭" } } + }, + "simulation_details": { + "failed": "加载估算时出错。", + "fiat_not_available": "不可用", + "incoming_heading": "您收到", + "no_balance_changes": "预计您的钱包不会发生变化", + "outgoing_heading": "您发送", + "reverted": "这笔交易可能会失败", + "title": "预计变化", + "tooltip_description": "预计变化是指您完成该交易可能发生的变化。这只是一个预测,而不是保证。", + "total_fiat": "总计 = {{currency}}" } -} \ No newline at end of file +} diff --git a/package.json b/package.json index 616bb1df29d..2d0d6627410 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "metamask", - "version": "7.24.2", + "version": "7.24.3", "private": true, "scripts": { "audit:ci": "./scripts/yarn-audit.sh", @@ -142,21 +142,21 @@ "@keystonehq/metamask-airgapped-keyring": "^0.13.1", "@keystonehq/ur-decoder": "^0.12.2", "@ledgerhq/react-native-hw-transport-ble": "^6.32.3", - "@metamask/accounts-controller": "^11.0.0", + "@metamask/accounts-controller": "^14.0.0", "@metamask/address-book-controller": "^4.0.1", "@metamask/approval-controller": "^3.5.2", - "@metamask/assets-controllers": "^26.0.0", + "@metamask/assets-controllers": "^30.0.0", "@metamask/base-controller": "^5.0.0", "@metamask/composable-controller": "^3.0.0", "@metamask/contract-metadata": "^2.1.0", - "@metamask/controller-utils": "^8.0.4", + "@metamask/controller-utils": "^10.0.0", "@metamask/eth-json-rpc-middleware": "^12.0.0", "@metamask/design-tokens": "^4.0.0", "@metamask/eth-sig-util": "^7.0.2", "@metamask/etherscan-link": "^2.0.0", "@metamask/gas-fee-controller": "^15.1.2", "@metamask/key-tree": "^9.0.0", - "@metamask/keyring-api": "^4.0.0", + "@metamask/keyring-api": "^6.0.0", "@metamask/keyring-controller": "^16.0.0", "@metamask/network-controller": "^18.1.0", "@metamask/logging-controller": "^3.0.0", diff --git a/patches/@metamask+accounts-controller+11.0.0.patch b/patches/@metamask+accounts-controller+11.0.0.patch deleted file mode 100644 index 3d403f0e4f5..00000000000 --- a/patches/@metamask+accounts-controller+11.0.0.patch +++ /dev/null @@ -1,13 +0,0 @@ -diff --git a/node_modules/@metamask/accounts-controller/dist/AccountsController.js b/node_modules/@metamask/accounts-controller/dist/AccountsController.js -index 22b1565..82306fd 100644 ---- a/node_modules/@metamask/accounts-controller/dist/AccountsController.js -+++ b/node_modules/@metamask/accounts-controller/dist/AccountsController.js -@@ -433,7 +433,7 @@ _AccountsController_instances = new WeakSet(), _AccountsController_generateInter - this.update((currentState) => { - currentState.internalAccounts.accounts[newAccount.id] = Object.assign(Object.assign({}, newAccount), { metadata: Object.assign(Object.assign({}, newAccount.metadata), { name: accountName, lastSelected: Date.now() }) }); - }); -- this.setSelectedAccount(newAccount.id); -+ // this.setSelectedAccount(newAccount.id); - }, _AccountsController_handleAccountRemoved = function _AccountsController_handleAccountRemoved(accountId) { - this.update((currentState) => { - delete currentState.internalAccounts.accounts[accountId]; diff --git a/patches/@metamask+accounts-controller+14.0.0.patch b/patches/@metamask+accounts-controller+14.0.0.patch new file mode 100644 index 00000000000..136a64fb714 --- /dev/null +++ b/patches/@metamask+accounts-controller+14.0.0.patch @@ -0,0 +1,13 @@ +diff --git a/node_modules/@metamask/accounts-controller/dist/chunk-YSAAOUCM.js b/node_modules/@metamask/accounts-controller/dist/chunk-YSAAOUCM.js +index cb3fb28..4b55f04 100644 +--- a/node_modules/@metamask/accounts-controller/dist/chunk-YSAAOUCM.js ++++ b/node_modules/@metamask/accounts-controller/dist/chunk-YSAAOUCM.js +@@ -535,7 +535,7 @@ handleNewAccountAdded_fn = function(account) { + } + }; + }); +- this.setSelectedAccount(newAccount.id); ++ // this.setSelectedAccount(newAccount.id); + }; + _handleAccountRemoved = new WeakSet(); + handleAccountRemoved_fn = function(accountId) { diff --git a/patches/@metamask+assets-controllers+26.0.0.patch b/patches/@metamask+assets-controllers+26.0.0.patch deleted file mode 100644 index 199b25b6678..00000000000 --- a/patches/@metamask+assets-controllers+26.0.0.patch +++ /dev/null @@ -1,1395 +0,0 @@ -diff --git a/node_modules/@metamask/assets-controllers/dist/.patch.txt b/node_modules/@metamask/assets-controllers/dist/.patch.txt -new file mode 100644 -index 0000000..b867ea9 ---- /dev/null -+++ b/node_modules/@metamask/assets-controllers/dist/.patch.txt -@@ -0,0 +1,14 @@ -+PATCH GENERATED FROM MetaMask/core branch: patch/mobile-assets-controllers-26 -+This patch backports various assets controllers features from the main branch of MetaMask/core -+Steps to update patch: -+* Create a new core branch from: patch/mobile-assets-controllers-26 -+* Run "yarn build" in the core monorepo -+* Run "yarn patch:assets " in the mobile repo -+* If you have changes also add them to the branch: patch/mobile-assets-controllers-26 -+* Steps to update the assets-controllers version -+* Create a new core branch from the next assets-controllers version -+* Merge the branch patch/mobile-assets-controllers-26 -+* Solve the conflicts and review changes accordingly the changelog -+* Run "yarn build" in the core monorepo -+* Run "yarn patch:assets " in the mobile repo -+* If you have changes also add them to the branch: patch/mobile-assets-controllers-26 -diff --git a/node_modules/@metamask/assets-controllers/dist/AccountTrackerController.js b/node_modules/@metamask/assets-controllers/dist/AccountTrackerController.js -index ee99eb2..c786b6c 100644 ---- a/node_modules/@metamask/assets-controllers/dist/AccountTrackerController.js -+++ b/node_modules/@metamask/assets-controllers/dist/AccountTrackerController.js -@@ -69,17 +69,28 @@ class AccountTrackerController extends polling_controller_1.StaticIntervalPollin - : [this.getSelectedAddress()]; - const accountsForChain = Object.assign({}, accountsByChainId[chainId]); - for (const address of accountsToUpdate) { -- accountsForChain[address] = { -- balance: (0, controller_utils_1.BNToHex)(yield this.getBalanceFromChain(address, ethQuery)), -- }; -+ /** -+ * IMPORTANT NOTE ABOUT THIS PATCH -+ * This patch can be removed once Assets Controller is updated to v^27 -+ */ -+ const balance = yield this.getBalanceFromChain(address, ethQuery); -+ if(balance){ -+ accountsForChain[address] = { -+ balance, -+ }; -+ } - } - this.update(Object.assign(Object.assign({}, (chainId === this.getCurrentChainId() && { - accounts: accountsForChain, - })), { accountsByChainId: Object.assign(Object.assign({}, this.state.accountsByChainId), { [chainId]: accountsForChain }) })); - } - catch (err) { -- releaseLock(); - throw err; -+ } finally { -+ /** -+ * This change is not present on the core repo -+ */ -+ releaseLock(); - } - }); - this.defaultConfig = { -diff --git a/node_modules/@metamask/assets-controllers/dist/NftController.d.ts b/node_modules/@metamask/assets-controllers/dist/NftController.d.ts -index 45e07b8..096baf1 100644 ---- a/node_modules/@metamask/assets-controllers/dist/NftController.d.ts -+++ b/node_modules/@metamask/assets-controllers/dist/NftController.d.ts -@@ -8,7 +8,7 @@ import type { Hex } from '@metamask/utils'; - import { EventEmitter } from 'events'; - import type { AssetsContractController } from './AssetsContractController'; - import { Source } from './constants'; --import type { ApiNftCreator, ApiNftLastSale } from './NftDetectionController'; -+import type { Collection, Attributes, LastSale } from './NftDetectionController'; - declare type NFTStandardType = 'ERC721' | 'ERC1155'; - declare type SuggestedNftMeta = { - asset: { -@@ -21,75 +21,6 @@ declare type SuggestedNftMeta = { - interactingAddress: string; - origin: string; - }; --export declare enum OpenSeaV2ChainIds { -- ethereum = "ethereum" --} --export declare type OpenSeaV2GetNftResponse = { -- nft: OpenSeaV2DetailedNft; --}; --export declare type OpenSeaV2Nft = { -- identifier: string; -- collection: string; -- contract: string; -- token_standard: string; -- name: string; -- description: string; -- image_url?: string; -- metadata_url?: string; -- updated_at: string; -- is_disabled: boolean; -- is_nsfw: boolean; --}; --export declare type OpenSeaV2DetailedNft = OpenSeaV2Nft & { -- animation_url?: string; -- is_suspicious: boolean; -- creator: string; -- traits: { -- trait_type: string; -- display_type?: string; -- max_value: string; -- trait_count?: number; -- value: number | string; -- }[]; -- owners: { -- address: string; -- quantity: number; -- }[]; -- rarity: { -- rank: number; -- }; --}; --export declare type OpenSeaV2ListNftsResponse = { -- nfts: OpenSeaV2Nft[]; -- next?: string; --}; --export declare type OpenSeaV2Contract = { -- address: string; -- chain: string; -- collection: string; -- contract_standard: string; -- name: string; -- total_supply?: number; --}; --export declare type OpenSeaV2Collection = { -- collection: string; -- name: string; -- description?: string; -- image_url?: string; -- owner: string; -- category: string; -- is_disabled: boolean; -- is_nsfw: boolean; -- trait_offers_enabled: boolean; -- opensea_url: string; -- project_url?: string; -- wiki_url?: string; -- discord_url?: string; -- telegram_url?: string; -- twitter_username?: string; -- instagram_username?: string; -- total_supply?: number; --}; - /** - * @type Nft - * -@@ -116,6 +47,10 @@ export interface Nft extends NftMetadata { - address: string; - isCurrentlyOwned?: boolean; - } -+export declare type NftUpdate = { -+ nft: Nft; -+ newMetadata: NftMetadata; -+}; - /** - * @type NftContract - * -@@ -175,10 +110,15 @@ export interface NftMetadata { - animation?: string; - animationOriginal?: string; - externalLink?: string; -- creator?: ApiNftCreator; -- lastSale?: ApiNftLastSale; -+ creator?: string; - transactionId?: string; - tokenURI?: string | null; -+ error?: string; -+ collection?: Collection; -+ address?: string; -+ attributes?: Attributes; -+ lastSale?: LastSale; -+ rarityRank?: string; - } - /** - * @type NftConfig -@@ -190,7 +130,7 @@ export interface NftConfig extends BaseConfig { - selectedAddress: string; - chainId: Hex; - ipfsGateway: string; -- openSeaEnabled: boolean; -+ displayNftMedia: boolean; - useIPFSSubdomains: boolean; - isIpfsGatewayEnabled: boolean; - } -@@ -232,18 +172,17 @@ declare type AllowedActions = AddApprovalRequest; - */ - export declare type NftControllerMessenger = RestrictedControllerMessenger; - export declare const getDefaultNftState: () => NftState; -+/** -+ * Changes regarding displayNftMedia, TokenURI and error nft metadata property are not on the core repo and needed to be refactor to be removed from the patch -+ * updateNftMetadata changes will be introduced on latest versions of changes of assets controllers, v^30 or next -+ */ - /** - * Controller that stores assets and exposes convenience methods - */ - export declare class NftController extends BaseControllerV1 { - private readonly mutex; - private readonly messagingSystem; -- getNftApi({ contractAddress, tokenId, }: { -- contractAddress: string; -- tokenId: string; -- }): string; -- private getNftContractInformationApi; -- private getNftCollectionInformationApi; -+ getNftApi(): string; - /** - * Helper method to update nested state for allNfts and allNftContracts. - * -@@ -255,7 +194,7 @@ export declare class NftController extends BaseControllerV1 - */ - private updateNestedNftState; - /** -- * Request individual NFT information from OpenSea API. -+ * Request individual NFT information from NFT API. - * - * @param contractAddress - Hex address of the NFT contract. - * @param tokenId - The NFT identifier. -@@ -289,13 +228,6 @@ export declare class NftController extends BaseControllerV1 - * @returns Promise resolving to the current NFT name and image. - */ - private getNftInformation; -- /** -- * Request NFT contract information from OpenSea API. -- * -- * @param contractAddress - Hex address of the NFT contract. -- * @returns Promise resolving to the current NFT name and image. -- */ -- private getNftContractInformationFromApi; - /** - * Request NFT contract information from the contract itself. - * -@@ -305,9 +237,10 @@ export declare class NftController extends BaseControllerV1 - */ - private getNftContractInformationFromContract; - /** -- * Request NFT contract information from OpenSea API. -+ * Request NFT contract information from Blockchain and aggregate with received data from NFTMetadata. - * - * @param contractAddress - Hex address of the NFT contract. -+ * @param nftMetadataFromApi - Received NFT information to be aggregated with blockchain contract information. - * @param networkClientId - The networkClientId that can be used to identify the network client to use for this request. - * @returns Promise resolving to the NFT contract name, image and description. - */ -@@ -331,6 +264,7 @@ export declare class NftController extends BaseControllerV1 - * @param options - options. - * @param options.tokenAddress - Hex address of the NFT contract. - * @param options.userAddress - The address of the account where the NFT is being added. -+ * @param options.nftMetadata - The retrieved NFTMetadata from API. - * @param options.networkClientId - The networkClientId that can be used to identify the network client to use for this request. - * @param options.source - Whether the NFT was detected, added manually or suggested by a dapp. - * @returns Promise resolving to the current NFT contracts list. -@@ -356,6 +290,19 @@ export declare class NftController extends BaseControllerV1 - * @param options.userAddress - The address of the account where the NFT is being removed. - */ - private removeIndividualNft; -+ /** -+ * Refetches NFT metadata and updates the state -+ * -+ * @param options - Options for refetching NFT metadata -+ * @param options.nfts - nfts to update metadata for. -+ * @param options.userAddress - The current user address -+ * @param options.networkClientId - The networkClientId that can be used to identify the network client to use for this request. -+ */ -+ updateNftMetadata({ nfts, userAddress, networkClientId, }: { -+ nfts: Nft[]; -+ userAddress?: string; -+ networkClientId?: NetworkClientId; -+ }): Promise; - /** - * Removes an NFT contract to the stored NFT contracts list. - * -@@ -423,9 +370,10 @@ export declare class NftController extends BaseControllerV1 - tokenId: string; - standard: string | null; - source: string; -+ tokenURI?: string | null; - }) => void; - messenger: NftControllerMessenger; -- }, config?: Partial, state?: Partial); -+ }, config?: Partial, state?: Partial); - private validateWatchNft; - private getCorrectChainId; - /** -diff --git a/node_modules/@metamask/assets-controllers/dist/NftController.js b/node_modules/@metamask/assets-controllers/dist/NftController.js -index 0873ccd..9359c9a 100644 ---- a/node_modules/@metamask/assets-controllers/dist/NftController.js -+++ b/node_modules/@metamask/assets-controllers/dist/NftController.js -@@ -12,7 +12,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; - }; - Object.defineProperty(exports, "__esModule", { value: true }); --exports.NftController = exports.getDefaultNftState = exports.OpenSeaV2ChainIds = void 0; -+exports.NftController = exports.getDefaultNftState = void 0; - const address_1 = require("@ethersproject/address"); - const base_controller_1 = require("@metamask/base-controller"); - const controller_utils_1 = require("@metamask/controller-utils"); -@@ -24,10 +24,6 @@ const events_1 = require("events"); - const uuid_1 = require("uuid"); - const assetsUtil_1 = require("./assetsUtil"); - const constants_1 = require("./constants"); --var OpenSeaV2ChainIds; --(function (OpenSeaV2ChainIds) { -- OpenSeaV2ChainIds["ethereum"] = "ethereum"; --})(OpenSeaV2ChainIds = exports.OpenSeaV2ChainIds || (exports.OpenSeaV2ChainIds = {})); - const ALL_NFTS_STATE_KEY = 'allNfts'; - const ALL_NFTS_CONTRACTS_STATE_KEY = 'allNftContracts'; - /** -@@ -42,6 +38,10 @@ const getDefaultNftState = () => { - }; - }; - exports.getDefaultNftState = getDefaultNftState; -+/** -+ * Changes regarding displayNftMedia, TokenURI and error nft metadata property are not on the core repo and needed to be refactor to be removed from the patch -+ * updateNftMetadata changes will be introduced on latest versions of changes of assets controllers, v^30 or next -+ */ - /** - * Controller that stores assets and exposes convenience methods - */ -@@ -81,7 +81,7 @@ class NftController extends base_controller_1.BaseControllerV1 { - selectedAddress: '', - chainId: initialChainId, - ipfsGateway: controller_utils_1.IPFS_DEFAULT_GATEWAY_URL, -- openSeaEnabled: false, -+ displayNftMedia: false, - useIPFSSubdomains: true, - isIpfsGatewayEnabled: true, - }; -@@ -96,11 +96,11 @@ class NftController extends base_controller_1.BaseControllerV1 { - this.getNetworkClientById = getNetworkClientById; - this.onNftAdded = onNftAdded; - this.messagingSystem = messenger; -- onPreferencesStateChange(({ selectedAddress, ipfsGateway, openSeaEnabled, isIpfsGatewayEnabled, }) => { -+ onPreferencesStateChange(({ selectedAddress, ipfsGateway, displayNftMedia, isIpfsGatewayEnabled, }) => { - this.configure({ - selectedAddress, - ipfsGateway, -- openSeaEnabled, -+ displayNftMedia, - isIpfsGatewayEnabled, - }); - }); -@@ -109,14 +109,8 @@ class NftController extends base_controller_1.BaseControllerV1 { - this.configure({ chainId }); - }); - } -- getNftApi({ contractAddress, tokenId, }) { -- return `${controller_utils_1.OPENSEA_PROXY_URL}/chain/${OpenSeaV2ChainIds.ethereum}/contract/${contractAddress}/nfts/${tokenId}`; -- } -- getNftContractInformationApi({ contractAddress, }) { -- return `${controller_utils_1.OPENSEA_PROXY_URL}/chain/${OpenSeaV2ChainIds.ethereum}/contract/${contractAddress}`; -- } -- getNftCollectionInformationApi({ collectionSlug, }) { -- return `${controller_utils_1.OPENSEA_PROXY_URL}/collections/${collectionSlug}`; -+ getNftApi() { -+ return `${controller_utils_1.NFT_API_BASE_URL}/tokens`; - } - /** - * Helper method to update nested state for allNfts and allNftContracts. -@@ -137,38 +131,49 @@ class NftController extends base_controller_1.BaseControllerV1 { - }); - } - /** -- * Request individual NFT information from OpenSea API. -+ * Request individual NFT information from NFT API. - * - * @param contractAddress - Hex address of the NFT contract. - * @param tokenId - The NFT identifier. - * @returns Promise resolving to the current NFT name and image. - */ - getNftInformationFromApi(contractAddress, tokenId) { -+ var _a, _b, _c, _d; - return __awaiter(this, void 0, void 0, function* () { - // TODO Parameterize this by chainId for non-mainnet token detection -- // Attempt to fetch the data with the proxy -+ // Attempt to fetch the data with the nft-api -+ const urlParams = new URLSearchParams({ -+ chainIds: '1', -+ tokens: `${contractAddress}:${tokenId}`, -+ includeTopBid: 'true', -+ includeAttributes: 'true', -+ includeLastSale: 'true', -+ }).toString(); - const nftInformation = yield (0, controller_utils_1.fetchWithErrorHandling)({ -- url: this.getNftApi({ -- contractAddress, -- tokenId, -- }), -+ url: `${this.getNftApi()}?${urlParams}`, -+ options: { -+ headers: { -+ Version: '1', -+ }, -+ }, - }); - // if we were still unable to fetch the data we return out the default/null of `NftMetadata` -- if (!(nftInformation === null || nftInformation === void 0 ? void 0 : nftInformation.nft)) { -+ if (!((_b = (_a = nftInformation === null || nftInformation === void 0 ? void 0 : nftInformation.tokens) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.token)) { - return { - name: null, - description: null, - image: null, - standard: null, -+ error: 'Opensea import error', - }; - } - // if we've reached this point, we have successfully fetched some data for nftInformation - // now we reconfigure the data to conform to the `NftMetadata` type for storage. -- const { num_sales, background_color, image_url, image_preview_url, image_thumbnail_url, image_original_url, animation_url, animation_original_url, name, description, external_link, creator, last_sale, asset_contract: { schema_name }, } = (0, assetsUtil_1.mapOpenSeaDetailedNftV2ToV1)(nftInformation.nft); -+ const { image, metadata: { imageOriginal } = {}, name, description, collection, kind, rarityRank, rarity, attributes, lastSale, imageSmall, } = nftInformation.tokens[0].token; - /* istanbul ignore next */ -- const nftMetadata = Object.assign({}, { name: name || null }, { description: description || null }, { image: image_url || null }, creator && { creator }, num_sales && { numberOfSales: num_sales }, background_color && { backgroundColor: background_color }, image_preview_url && { imagePreview: image_preview_url }, image_thumbnail_url && { imageThumbnail: image_thumbnail_url }, image_original_url && { imageOriginal: image_original_url }, animation_url && { animation: animation_url }, animation_original_url && { -- animationOriginal: animation_original_url, -- }, external_link && { externalLink: external_link }, last_sale && { lastSale: last_sale }, schema_name && { standard: schema_name }); -+ const nftMetadata = Object.assign({}, { name: name || null }, { description: description || null }, { image: image || null }, (collection === null || collection === void 0 ? void 0 : collection.creator) && { creator: collection.creator }, imageOriginal && { imageOriginal }, imageSmall && { imageThumbnail: imageSmall }, kind && { standard: kind.toUpperCase() }, lastSale && { lastSale }, attributes && { attributes }, ((_c = nftInformation.tokens[0].market) === null || _c === void 0 ? void 0 : _c.topBid) && { -+ topBid: (_d = nftInformation.tokens[0].market) === null || _d === void 0 ? void 0 : _d.topBid, -+ }, rarityRank && { rarityRank }, rarity && { rarity }, collection && { collection }); - return nftMetadata; - }); - } -@@ -182,10 +187,20 @@ class NftController extends base_controller_1.BaseControllerV1 { - */ - getNftInformationFromTokenURI(contractAddress, tokenId, networkClientId) { - return __awaiter(this, void 0, void 0, function* () { -- const { ipfsGateway, useIPFSSubdomains, isIpfsGatewayEnabled } = this.config; -+ const { ipfsGateway, useIPFSSubdomains, isIpfsGatewayEnabled, displayNftMedia, } = this.config; - const result = yield this.getNftURIAndStandard(contractAddress, tokenId, networkClientId); - let tokenURI = result[0]; - const standard = result[1]; -+ if (!displayNftMedia && !isIpfsGatewayEnabled) { -+ return { -+ image: null, -+ name: null, -+ description: null, -+ standard: standard || null, -+ favorite: false, -+ tokenURI, -+ }; -+ } - const hasIpfsTokenURI = tokenURI.startsWith('ipfs://'); - if (hasIpfsTokenURI && !isIpfsGatewayEnabled) { - return { -@@ -197,8 +212,7 @@ class NftController extends base_controller_1.BaseControllerV1 { - tokenURI: tokenURI !== null && tokenURI !== void 0 ? tokenURI : null, - }; - } -- const isDisplayNFTMediaToggleEnabled = this.config.openSeaEnabled; -- if (!hasIpfsTokenURI && !isDisplayNFTMediaToggleEnabled) { -+ if (!hasIpfsTokenURI && !displayNftMedia) { - return { - image: null, - name: null, -@@ -234,6 +248,7 @@ class NftController extends base_controller_1.BaseControllerV1 { - standard: standard || null, - favorite: false, - tokenURI: tokenURI !== null && tokenURI !== void 0 ? tokenURI : null, -+ error: 'URI import error', - }; - } - }); -@@ -287,60 +302,29 @@ class NftController extends base_controller_1.BaseControllerV1 { - * @returns Promise resolving to the current NFT name and image. - */ - getNftInformation(contractAddress, tokenId, networkClientId) { -- var _a, _b, _c, _d, _e, _f, _g, _h, _j; -+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l; - return __awaiter(this, void 0, void 0, function* () { - const chainId = this.getCorrectChainId({ - networkClientId, - }); -- const [blockchainMetadata, openSeaMetadata] = yield Promise.all([ -+ const [blockchainMetadata, nftApiMetadata] = yield Promise.all([ - (0, controller_utils_1.safelyExecute)(() => this.getNftInformationFromTokenURI(contractAddress, tokenId, networkClientId)), -- this.config.openSeaEnabled && chainId === '0x1' -+ this.config.displayNftMedia && chainId === '0x1' - ? (0, controller_utils_1.safelyExecute)(() => this.getNftInformationFromApi(contractAddress, tokenId)) - : undefined, - ]); -- return Object.assign(Object.assign({}, openSeaMetadata), { name: (_b = (_a = blockchainMetadata === null || blockchainMetadata === void 0 ? void 0 : blockchainMetadata.name) !== null && _a !== void 0 ? _a : openSeaMetadata === null || openSeaMetadata === void 0 ? void 0 : openSeaMetadata.name) !== null && _b !== void 0 ? _b : null, description: (_d = (_c = blockchainMetadata === null || blockchainMetadata === void 0 ? void 0 : blockchainMetadata.description) !== null && _c !== void 0 ? _c : openSeaMetadata === null || openSeaMetadata === void 0 ? void 0 : openSeaMetadata.description) !== null && _d !== void 0 ? _d : null, image: (_f = (_e = blockchainMetadata === null || blockchainMetadata === void 0 ? void 0 : blockchainMetadata.image) !== null && _e !== void 0 ? _e : openSeaMetadata === null || openSeaMetadata === void 0 ? void 0 : openSeaMetadata.image) !== null && _f !== void 0 ? _f : null, standard: (_h = (_g = blockchainMetadata === null || blockchainMetadata === void 0 ? void 0 : blockchainMetadata.standard) !== null && _g !== void 0 ? _g : openSeaMetadata === null || openSeaMetadata === void 0 ? void 0 : openSeaMetadata.standard) !== null && _h !== void 0 ? _h : null, tokenURI: (_j = blockchainMetadata === null || blockchainMetadata === void 0 ? void 0 : blockchainMetadata.tokenURI) !== null && _j !== void 0 ? _j : null }); -- }); -- } -- /** -- * Request NFT contract information from OpenSea API. -- * -- * @param contractAddress - Hex address of the NFT contract. -- * @returns Promise resolving to the current NFT name and image. -- */ -- getNftContractInformationFromApi(contractAddress) { -- return __awaiter(this, void 0, void 0, function* () { -- /* istanbul ignore if */ -- const apiNftContractObject = yield (0, controller_utils_1.fetchWithErrorHandling)({ -- url: this.getNftContractInformationApi({ -- contractAddress, -- }), -- }); -- // If we successfully fetched the contract -- if (apiNftContractObject) { -- // Then fetch some additional details from the collection -- const collection = yield (0, controller_utils_1.fetchWithErrorHandling)({ -- url: this.getNftCollectionInformationApi({ -- collectionSlug: apiNftContractObject.collection, -- }), -- }); -- return (0, assetsUtil_1.mapOpenSeaContractV2ToV1)(apiNftContractObject, collection); -- } -- // If we've reached this point we were unable to fetch data from either the proxy or opensea so we return -- // the default/null of ApiNftContract -- return { -- address: contractAddress, -- asset_contract_type: null, -- created_date: null, -- schema_name: null, -- symbol: null, -- total_supply: null, -- description: null, -- external_link: null, -- collection: { -+ if ((blockchainMetadata === null || blockchainMetadata === void 0 ? void 0 : blockchainMetadata.error) && (nftApiMetadata === null || nftApiMetadata === void 0 ? void 0 : nftApiMetadata.error)) { -+ return { -+ image: null, - name: null, -- image_url: null, -- }, -- }; -+ description: null, -+ standard: (_a = blockchainMetadata.standard) !== null && _a !== void 0 ? _a : null, -+ favorite: false, -+ tokenURI: (_b = blockchainMetadata.tokenURI) !== null && _b !== void 0 ? _b : null, -+ error: 'Both import failed', -+ }; -+ } -+ return Object.assign(Object.assign({}, nftApiMetadata), { name: (_d = (_c = blockchainMetadata === null || blockchainMetadata === void 0 ? void 0 : blockchainMetadata.name) !== null && _c !== void 0 ? _c : nftApiMetadata === null || nftApiMetadata === void 0 ? void 0 : nftApiMetadata.name) !== null && _d !== void 0 ? _d : null, description: (_f = (_e = blockchainMetadata === null || blockchainMetadata === void 0 ? void 0 : blockchainMetadata.description) !== null && _e !== void 0 ? _e : nftApiMetadata === null || nftApiMetadata === void 0 ? void 0 : nftApiMetadata.description) !== null && _f !== void 0 ? _f : null, image: (_h = (_g = nftApiMetadata === null || nftApiMetadata === void 0 ? void 0 : nftApiMetadata.image) !== null && _g !== void 0 ? _g : blockchainMetadata === null || blockchainMetadata === void 0 ? void 0 : blockchainMetadata.image) !== null && _h !== void 0 ? _h : null, standard: (_k = (_j = blockchainMetadata === null || blockchainMetadata === void 0 ? void 0 : blockchainMetadata.standard) !== null && _j !== void 0 ? _j : nftApiMetadata === null || nftApiMetadata === void 0 ? void 0 : nftApiMetadata.standard) !== null && _k !== void 0 ? _k : null, tokenURI: (_l = blockchainMetadata === null || blockchainMetadata === void 0 ? void 0 : blockchainMetadata.tokenURI) !== null && _l !== void 0 ? _l : null }); - }); - } - /** -@@ -364,25 +348,20 @@ class NftController extends base_controller_1.BaseControllerV1 { - }); - } - /** -- * Request NFT contract information from OpenSea API. -+ * Request NFT contract information from Blockchain and aggregate with received data from NFTMetadata. - * - * @param contractAddress - Hex address of the NFT contract. -+ * @param nftMetadataFromApi - Received NFT information to be aggregated with blockchain contract information. - * @param networkClientId - The networkClientId that can be used to identify the network client to use for this request. - * @returns Promise resolving to the NFT contract name, image and description. - */ -- getNftContractInformation(contractAddress, networkClientId) { -+ getNftContractInformation(contractAddress, nftMetadataFromApi, networkClientId) { -+ var _a, _b, _c, _d, _e, _f, _g; - return __awaiter(this, void 0, void 0, function* () { -- const chainId = this.getCorrectChainId({ -- networkClientId, -- }); -- const [blockchainContractData, openSeaContractData] = yield Promise.all([ -- (0, controller_utils_1.safelyExecute)(() => this.getNftContractInformationFromContract(contractAddress, networkClientId)), -- this.config.openSeaEnabled && chainId === '0x1' -- ? (0, controller_utils_1.safelyExecute)(() => this.getNftContractInformationFromApi(contractAddress)) -- : undefined, -- ]); -- if (blockchainContractData || openSeaContractData) { -- return Object.assign(Object.assign(Object.assign({ address: contractAddress }, openSeaContractData), blockchainContractData), { collection: Object.assign(Object.assign({ name: null, image_url: null }, openSeaContractData === null || openSeaContractData === void 0 ? void 0 : openSeaContractData.collection), blockchainContractData === null || blockchainContractData === void 0 ? void 0 : blockchainContractData.collection) }); -+ const blockchainContractData = yield (0, controller_utils_1.safelyExecute)(() => this.getNftContractInformationFromContract(contractAddress, networkClientId)); -+ if (blockchainContractData || -+ !Object.values(nftMetadataFromApi).every((value) => value === null)) { -+ return Object.assign(Object.assign({ address: contractAddress }, blockchainContractData), { schema_name: (_a = nftMetadataFromApi === null || nftMetadataFromApi === void 0 ? void 0 : nftMetadataFromApi.standard) !== null && _a !== void 0 ? _a : null, collection: Object.assign(Object.assign({ name: null, image_url: (_e = (_c = (_b = nftMetadataFromApi === null || nftMetadataFromApi === void 0 ? void 0 : nftMetadataFromApi.collection) === null || _b === void 0 ? void 0 : _b.image) !== null && _c !== void 0 ? _c : (_d = nftMetadataFromApi === null || nftMetadataFromApi === void 0 ? void 0 : nftMetadataFromApi.collection) === null || _d === void 0 ? void 0 : _d.imageUrl) !== null && _e !== void 0 ? _e : null, tokenCount: (_g = (_f = nftMetadataFromApi === null || nftMetadataFromApi === void 0 ? void 0 : nftMetadataFromApi.collection) === null || _f === void 0 ? void 0 : _f.tokenCount) !== null && _g !== void 0 ? _g : null }, nftMetadataFromApi === null || nftMetadataFromApi === void 0 ? void 0 : nftMetadataFromApi.collection), blockchainContractData === null || blockchainContractData === void 0 ? void 0 : blockchainContractData.collection) }); - } - /* istanbul ignore next */ - return { -@@ -449,6 +428,7 @@ class NftController extends base_controller_1.BaseControllerV1 { - tokenId: tokenId.toString(), - standard: nftMetadata.standard, - source, -+ tokenURI: nftMetadata.tokenURI, - }); - } - return newNfts; -@@ -464,11 +444,12 @@ class NftController extends base_controller_1.BaseControllerV1 { - * @param options - options. - * @param options.tokenAddress - Hex address of the NFT contract. - * @param options.userAddress - The address of the account where the NFT is being added. -+ * @param options.nftMetadata - The retrieved NFTMetadata from API. - * @param options.networkClientId - The networkClientId that can be used to identify the network client to use for this request. - * @param options.source - Whether the NFT was detected, added manually or suggested by a dapp. - * @returns Promise resolving to the current NFT contracts list. - */ -- addNftContract({ tokenAddress, userAddress, networkClientId, source, }) { -+ addNftContract({ tokenAddress, userAddress, networkClientId, source, nftMetadata, }) { - var _a; - return __awaiter(this, void 0, void 0, function* () { - const releaseLock = yield this.mutex.acquire(); -@@ -485,8 +466,9 @@ class NftController extends base_controller_1.BaseControllerV1 { - } - // this doesn't work currently for detection if the user switches networks while the detection is processing - // will be fixed once detection uses networkClientIds -- const contractInformation = yield this.getNftContractInformation(tokenAddress, networkClientId); -- const { asset_contract_type, created_date, schema_name, symbol, total_supply, description, external_link, collection: { name, image_url }, } = contractInformation; -+ // get name and symbol if ERC721 then put together the metadata -+ const contractInformation = yield this.getNftContractInformation(tokenAddress, nftMetadata, networkClientId); -+ const { asset_contract_type, created_date, symbol, description, external_link, schema_name, collection: { name, image_url, tokenCount }, } = contractInformation; - // If the nft is auto-detected we want some valid metadata to be present - if (source === constants_1.Source.Detected && - 'address' in contractInformation && -@@ -501,8 +483,8 @@ class NftController extends base_controller_1.BaseControllerV1 { - return nftContracts; - } - /* istanbul ignore next */ -- const newEntry = Object.assign({}, { address: tokenAddress }, description && { description }, name && { name }, image_url && { logo: image_url }, symbol && { symbol }, total_supply !== null && -- typeof total_supply !== 'undefined' && { totalSupply: total_supply }, asset_contract_type && { assetContractType: asset_contract_type }, created_date && { createdDate: created_date }, schema_name && { schemaName: schema_name }, external_link && { externalLink: external_link }); -+ const newEntry = Object.assign({}, { address: tokenAddress }, description && { description }, name && { name }, image_url && { logo: image_url }, symbol && { symbol }, tokenCount !== null && -+ typeof tokenCount !== 'undefined' && { totalSupply: tokenCount }, asset_contract_type && { assetContractType: asset_contract_type }, created_date && { createdDate: created_date }, schema_name && { schemaName: schema_name }, external_link && { externalLink: external_link }); - const newNftContracts = [...nftContracts, newEntry]; - this.updateNestedNftState(newNftContracts, ALL_NFTS_CONTRACTS_STATE_KEY, { - chainId, -@@ -568,6 +550,55 @@ class NftController extends base_controller_1.BaseControllerV1 { - chainId, - }); - } -+ /** -+ * Refetches NFT metadata and updates the state -+ * -+ * @param options - Options for refetching NFT metadata -+ * @param options.nfts - nfts to update metadata for. -+ * @param options.userAddress - The current user address -+ * @param options.networkClientId - The networkClientId that can be used to identify the network client to use for this request. -+ */ -+ updateNftMetadata({ nfts, userAddress = this.config.selectedAddress, networkClientId, }) { -+ var _a; -+ return __awaiter(this, void 0, void 0, function* () { -+ const releaseLock = yield this.mutex.acquire(); -+ try { -+ const chainId = this.getCorrectChainId({ networkClientId }); -+ const nftsWithChecksumAdr = nfts.map((nft) => { -+ return Object.assign(Object.assign({}, nft), { address: (0, controller_utils_1.toChecksumHexAddress)(nft.address) }); -+ }); -+ const nftMetadataResults = yield Promise.allSettled(nftsWithChecksumAdr.map((nft) => __awaiter(this, void 0, void 0, function* () { -+ const resMetadata = yield this.getNftInformation(nft.address, nft.tokenId, networkClientId); -+ return { -+ nft, -+ newMetadata: resMetadata, -+ }; -+ }))); -+ const successfulNewFetchedNfts = nftMetadataResults.filter((result) => result.status === 'fulfilled'); -+ // We want to avoid updating the state if the state and fetched nft info are the same -+ const nftsWithDifferentMetadata = []; -+ const { allNfts } = this.state; -+ const stateNfts = ((_a = allNfts[userAddress]) === null || _a === void 0 ? void 0 : _a[chainId]) || []; -+ successfulNewFetchedNfts.forEach((singleNft) => { -+ const existingEntry = stateNfts.find((nft) => nft.address.toLowerCase() === -+ singleNft.value.nft.address.toLowerCase() && -+ nft.tokenId === singleNft.value.nft.tokenId); -+ if (existingEntry) { -+ const differentMetadata = (0, assetsUtil_1.compareNftMetadata)(singleNft.value.newMetadata, existingEntry); -+ if (differentMetadata) { -+ nftsWithDifferentMetadata.push(singleNft); -+ } -+ } -+ }); -+ if (nftsWithDifferentMetadata.length !== 0) { -+ nftsWithDifferentMetadata.forEach((elm) => this.updateNft(elm.value.nft, elm.value.newMetadata, userAddress, chainId)); -+ } -+ } -+ finally { -+ releaseLock(); -+ } -+ }); -+ } - /** - * Removes an NFT contract to the stored NFT contracts list. - * -@@ -763,15 +794,16 @@ class NftController extends base_controller_1.BaseControllerV1 { - return __awaiter(this, void 0, void 0, function* () { - tokenAddress = (0, controller_utils_1.toChecksumHexAddress)(tokenAddress); - const chainId = this.getCorrectChainId({ networkClientId }); -+ nftMetadata = -+ nftMetadata || -+ (yield this.getNftInformation(tokenAddress, tokenId, networkClientId)); - const newNftContracts = yield this.addNftContract({ - tokenAddress, - userAddress, - networkClientId, - source, -+ nftMetadata, - }); -- nftMetadata = -- nftMetadata || -- (yield this.getNftInformation(tokenAddress, tokenId, networkClientId)); - // If NFT contract was not added, do not add individual NFT - const nftContract = newNftContracts.find((contract) => contract.address.toLowerCase() === tokenAddress.toLowerCase()); - // If NFT contract information, add individual NFT -diff --git a/node_modules/@metamask/assets-controllers/dist/NftDetectionController.d.ts b/node_modules/@metamask/assets-controllers/dist/NftDetectionController.d.ts -index d5c60db..adef299 100644 ---- a/node_modules/@metamask/assets-controllers/dist/NftDetectionController.d.ts -+++ b/node_modules/@metamask/assets-controllers/dist/NftDetectionController.d.ts -@@ -3,6 +3,7 @@ import type { NetworkClientId, NetworkController, NetworkState, NetworkClient } - import { StaticIntervalPollingControllerV1 } from '@metamask/polling-controller'; - import type { PreferencesState } from '@metamask/preferences-controller'; - import type { Hex } from '@metamask/utils'; -+import { Source } from './constants'; - import { type NftController, type NftState } from './NftController'; - /** - * @type ApiNft -@@ -67,6 +68,7 @@ export interface ApiNftContract { - collection: { - name: string | null; - image_url?: string | null; -+ tokenCount?: string | null; - }; - } - /** -@@ -113,6 +115,188 @@ export interface NftDetectionConfig extends BaseConfig { - chainId: Hex; - selectedAddress: string; - } -+export declare type ReservoirResponse = { -+ tokens: TokensResponse[]; -+ continuation?: string; -+}; -+export declare type TokensResponse = { -+ token: TokenResponse; -+ ownership: Ownership; -+ market?: Market; -+ blockaidResult?: Blockaid; -+}; -+export declare enum BlockaidResultType { -+ Benign = "Benign", -+ Spam = "Spam", -+ Warning = "Warning", -+ Malicious = "Malicious" -+} -+export declare type Blockaid = { -+ contract: string; -+ chainId: number; -+ result_type: BlockaidResultType; -+ malicious_score: string; -+ attack_types: object; -+}; -+export declare type Market = { -+ floorAsk?: FloorAsk; -+ topBid?: TopBid; -+}; -+export declare type TokenResponse = { -+ chainId: number; -+ contract: string; -+ tokenId: string; -+ kind?: string; -+ name?: string; -+ image?: string; -+ imageSmall?: string; -+ imageLarge?: string; -+ metadata?: Metadata; -+ description?: string; -+ supply?: number; -+ remainingSupply?: number; -+ rarityScore?: number; -+ rarity?: number; -+ rarityRank?: number; -+ media?: string; -+ isFlagged?: boolean; -+ isSpam?: boolean; -+ isNsfw?: boolean; -+ metadataDisabled?: boolean; -+ lastFlagUpdate?: string; -+ lastFlagChange?: string; -+ collection?: Collection; -+ lastSale?: LastSale; -+ topBid?: TopBid; -+ lastAppraisalValue?: number; -+ attributes?: Attributes[]; -+}; -+export declare type TopBid = { -+ id?: string; -+ price?: Price; -+ source?: { -+ id?: string; -+ domain?: string; -+ name?: string; -+ icon?: string; -+ url?: string; -+ }; -+}; -+export declare type LastSale = { -+ saleId?: string; -+ token?: { -+ contract?: string; -+ tokenId?: string; -+ name?: string; -+ image?: string; -+ collection?: { -+ id?: string; -+ name?: string; -+ }; -+ }; -+ orderSource?: string; -+ orderSide?: 'ask' | 'bid'; -+ orderKind?: string; -+ orderId?: string; -+ from?: string; -+ to?: string; -+ amount?: string; -+ fillSource?: string; -+ block?: number; -+ txHash?: string; -+ logIndex?: number; -+ batchIndex?: number; -+ timestamp?: number; -+ price?: Price; -+ washTradingScore?: number; -+ royaltyFeeBps?: number; -+ marketplaceFeeBps?: number; -+ paidFullRoyalty?: boolean; -+ feeBreakdown?: FeeBreakdown[]; -+ isDeleted?: boolean; -+ createdAt?: string; -+ updatedAt?: string; -+}; -+export declare type FeeBreakdown = { -+ kind?: string; -+ bps?: number; -+ recipient?: string; -+ source?: string; -+ rawAmount?: string; -+}; -+export declare type Attributes = { -+ key?: string; -+ kind?: string; -+ value: string; -+ tokenCount?: number; -+ onSaleCount?: number; -+ floorAskPrice?: Price | null; -+ topBidValue?: number | null; -+ createdAt?: string; -+}; -+export declare type Collection = { -+ id?: string; -+ name?: string; -+ slug?: string; -+ symbol?: string; -+ imageUrl?: string; -+ image?: string; -+ isSpam?: boolean; -+ isNsfw?: boolean; -+ creator?: string; -+ tokenCount?: string; -+ metadataDisabled?: boolean; -+ openseaVerificationStatus?: string; -+ floorAskPrice?: Price; -+ royaltiesBps?: number; -+ royalties?: Royalties[]; -+}; -+export declare type Royalties = { -+ bps?: number; -+ recipient?: string; -+}; -+export declare type Ownership = { -+ tokenCount?: string; -+ onSaleCount?: string; -+ floorAsk?: FloorAsk; -+ acquiredAt?: string; -+}; -+export declare type FloorAsk = { -+ id?: string; -+ price?: Price; -+ maker?: string; -+ kind?: string; -+ validFrom?: number; -+ validUntil?: number; -+ source?: Source; -+ rawData?: Metadata; -+ isNativeOffChainCancellable?: boolean; -+}; -+export declare type Price = { -+ currency?: { -+ contract?: string; -+ name?: string; -+ symbol?: string; -+ decimals?: number; -+ chainId?: number; -+ }; -+ amount?: { -+ raw?: string; -+ decimal?: number; -+ usd?: number; -+ native?: number; -+ }; -+ netAmount?: { -+ raw?: string; -+ decimal?: number; -+ usd?: number; -+ native?: number; -+ }; -+}; -+export declare type Metadata = { -+ imageOriginal?: string; -+ tokenURI?: string; -+}; - /** - * Controller that passively polls on a set interval for NFT auto detection - */ -diff --git a/node_modules/@metamask/assets-controllers/dist/NftDetectionController.js b/node_modules/@metamask/assets-controllers/dist/NftDetectionController.js -index 24373e3..2eb0892 100644 ---- a/node_modules/@metamask/assets-controllers/dist/NftDetectionController.js -+++ b/node_modules/@metamask/assets-controllers/dist/NftDetectionController.js -@@ -9,13 +9,18 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge - }); - }; - Object.defineProperty(exports, "__esModule", { value: true }); --exports.NftDetectionController = void 0; -+exports.NftDetectionController = exports.BlockaidResultType = void 0; - const controller_utils_1 = require("@metamask/controller-utils"); - const polling_controller_1 = require("@metamask/polling-controller"); --const assetsUtil_1 = require("./assetsUtil"); - const constants_1 = require("./constants"); --const NftController_1 = require("./NftController"); - const DEFAULT_INTERVAL = 180000; -+var BlockaidResultType; -+(function (BlockaidResultType) { -+ BlockaidResultType["Benign"] = "Benign"; -+ BlockaidResultType["Spam"] = "Spam"; -+ BlockaidResultType["Warning"] = "Warning"; -+ BlockaidResultType["Malicious"] = "Malicious"; -+})(BlockaidResultType = exports.BlockaidResultType || (exports.BlockaidResultType = {})); - /** - * Controller that passively polls on a set interval for NFT auto detection - */ -@@ -84,7 +89,7 @@ class NftDetectionController extends polling_controller_1.StaticIntervalPollingC - this.setIntervalLength(this.config.interval); - } - getOwnerNftApi({ address, next, }) { -- return `${controller_utils_1.OPENSEA_PROXY_URL}/chain/${NftController_1.OpenSeaV2ChainIds.ethereum}/account/${address}/nfts?limit=200&next=${next !== null && next !== void 0 ? next : ''}`; -+ return `${controller_utils_1.NFT_API_BASE_URL}/users/${address}/tokens?chainIds=1&limit=200&includeTopBid=true&continuation=${next !== null && next !== void 0 ? next : ''}`; - } - getOwnerNfts(address) { - return __awaiter(this, void 0, void 0, function* () { -@@ -94,27 +99,25 @@ class NftDetectionController extends polling_controller_1.StaticIntervalPollingC - do { - nftApiResponse = yield (0, controller_utils_1.fetchWithErrorHandling)({ - url: this.getOwnerNftApi({ address, next }), -+ options: { -+ headers: { -+ Version: '1', -+ }, -+ }, - timeout: 15000, - }); - if (!nftApiResponse) { - return nfts; - } -- const newNfts = yield Promise.all(nftApiResponse.nfts.map((nftV2) => __awaiter(this, void 0, void 0, function* () { -+ const newNfts = nftApiResponse.tokens.filter((elm) => { - var _a, _b; -- const nftV1 = (0, assetsUtil_1.mapOpenSeaNftV2ToV1)(nftV2); -- // If the image hasn't been processed into OpenSea's CDN, the image_url will be null. -- // Try fetching the NFT individually, which returns the original image url from metadata if available. -- if (!nftV1.image_url && nftV2.metadata_url) { -- const nftDetails = yield (0, controller_utils_1.safelyExecute)(() => (0, controller_utils_1.timeoutFetch)(this.getNftApi({ -- contractAddress: nftV2.contract, -- tokenId: nftV2.identifier, -- }), undefined, 1000).then((r) => r.json())); -- nftV1.image_original_url = (_b = (_a = nftDetails === null || nftDetails === void 0 ? void 0 : nftDetails.nft) === null || _a === void 0 ? void 0 : _a.image_url) !== null && _b !== void 0 ? _b : null; -- } -- return nftV1; -- }))); -+ return elm.token.isSpam === false && -+ (((_a = elm.blockaidResult) === null || _a === void 0 ? void 0 : _a.result_type) -+ ? ((_b = elm.blockaidResult) === null || _b === void 0 ? void 0 : _b.result_type) === BlockaidResultType.Benign -+ : true); -+ }); - nfts = [...nfts, ...newNfts]; -- } while ((next = nftApiResponse.next)); -+ } while ((next = nftApiResponse.continuation)); - return nfts; - }); - } -@@ -180,24 +183,22 @@ class NftDetectionController extends polling_controller_1.StaticIntervalPollingC - } - const apiNfts = yield this.getOwnerNfts(userAddress); - const addNftPromises = apiNfts.map((nft) => __awaiter(this, void 0, void 0, function* () { -- const { token_id, num_sales, background_color, image_url, image_preview_url, image_thumbnail_url, image_original_url, animation_url, animation_original_url, name, description, external_link, creator, asset_contract: { address, schema_name }, last_sale, } = nft; -+ const { tokenId: token_id, contract, kind, image: image_url, imageSmall: image_thumbnail_url, metadata: { imageOriginal: image_original_url } = {}, name, description, attributes, topBid, lastSale, rarityRank, rarityScore, collection, } = nft.token; - let ignored; - /* istanbul ignore else */ - const { ignoredNfts } = this.getNftState(); - if (ignoredNfts.length) { - ignored = ignoredNfts.find((c) => { - /* istanbul ignore next */ -- return (c.address === (0, controller_utils_1.toChecksumHexAddress)(address) && -+ return (c.address === (0, controller_utils_1.toChecksumHexAddress)(contract) && - c.tokenId === token_id); - }); - } - /* istanbul ignore else */ - if (!ignored) { - /* istanbul ignore next */ -- const nftMetadata = Object.assign({}, { name }, creator && { creator }, description && { description }, image_url && { image: image_url }, num_sales && { numberOfSales: num_sales }, background_color && { backgroundColor: background_color }, image_preview_url && { imagePreview: image_preview_url }, image_thumbnail_url && { imageThumbnail: image_thumbnail_url }, image_original_url && { imageOriginal: image_original_url }, animation_url && { animation: animation_url }, animation_original_url && { -- animationOriginal: animation_original_url, -- }, schema_name && { standard: schema_name }, external_link && { externalLink: external_link }, last_sale && { lastSale: last_sale }); -- yield this.addNft(address, token_id, { -+ const nftMetadata = Object.assign({}, { name }, description && { description }, image_url && { image: image_url }, image_thumbnail_url && { imageThumbnail: image_thumbnail_url }, image_original_url && { imageOriginal: image_original_url }, kind && { standard: kind.toUpperCase() }, lastSale && { lastSale }, attributes && { attributes }, topBid && { topBid }, rarityRank && { rarityRank }, rarityScore && { rarityScore }, collection && { collection }); -+ yield this.addNft(contract, token_id, { - nftMetadata, - userAddress, - source: constants_1.Source.Detected, -diff --git a/node_modules/@metamask/assets-controllers/dist/TokenBalancesController.d.ts b/node_modules/@metamask/assets-controllers/dist/TokenBalancesController.d.ts -index 796f2be..86d635f 100644 ---- a/node_modules/@metamask/assets-controllers/dist/TokenBalancesController.d.ts -+++ b/node_modules/@metamask/assets-controllers/dist/TokenBalancesController.d.ts -@@ -2,7 +2,7 @@ import { type RestrictedControllerMessenger, type ControllerGetStateAction, type - import type { PreferencesControllerGetStateAction } from '@metamask/preferences-controller'; - import type { AssetsContractController } from './AssetsContractController'; - import type { Token } from './TokenRatesController'; --import type { TokensControllerStateChangeEvent } from './TokensController'; -+import type { TokensControllerStateChangeEvent, TokensState } from './TokensController'; - declare const controllerName = "TokenBalancesController"; - /** - * Token balances controller options -@@ -15,6 +15,7 @@ declare type TokenBalancesControllerOptions = { - interval?: number; - tokens?: Token[]; - disabled?: boolean; -+ onTokensStateChange: (listener: (tokensState: TokensState) => void) => void; - getERC20BalanceOf: AssetsContractController['getERC20BalanceOf']; - messenger: TokenBalancesControllerMessenger; - state?: Partial; -@@ -56,11 +57,12 @@ export declare class TokenBalancesController extends BaseController; -+ /** -+ * THIS FUNCTIONS IS CURRENTLY PATCHED AND STILL NEEDS TO BE IMPLEMENTED ON THE CORE REPO -+ * Resets to the default state -+ */ -+ reset(): void; - } - export default TokenBalancesController; - //# sourceMappingURL=TokenBalancesController.d.ts.map -\ No newline at end of file -diff --git a/node_modules/@metamask/assets-controllers/dist/TokenBalancesController.js b/node_modules/@metamask/assets-controllers/dist/TokenBalancesController.js -index 7d09db2..92d57ce 100644 ---- a/node_modules/@metamask/assets-controllers/dist/TokenBalancesController.js -+++ b/node_modules/@metamask/assets-controllers/dist/TokenBalancesController.js -@@ -19,7 +19,7 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function ( - if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); - return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); - }; --var _TokenBalancesController_handle, _TokenBalancesController_getERC20BalanceOf, _TokenBalancesController_interval, _TokenBalancesController_tokens, _TokenBalancesController_disabled; -+var _TokenBalancesController_handle, _TokenBalancesController_getERC20BalanceOf, _TokenBalancesController_interval, _TokenBalancesController_tokens, _TokenBalancesController_disabled, _TokenBalancesController_updateInProgress; - Object.defineProperty(exports, "__esModule", { value: true }); - exports.TokenBalancesController = exports.getDefaultTokenBalancesState = void 0; - const base_controller_1 = require("@metamask/base-controller"); -@@ -52,11 +52,12 @@ class TokenBalancesController extends base_controller_1.BaseController { - * @param options.interval - Polling interval used to fetch new token balances. - * @param options.tokens - List of tokens to track balances for. - * @param options.disabled - If set to true, all tracked tokens contract balances updates are blocked. -+ * @param options.onTokensStateChange - Allows subscribing to token controller state changes. - * @param options.getERC20BalanceOf - Gets the balance of the given account at the given contract address. - * @param options.state - Initial state to set on this controller. - * @param options.messenger - The controller restricted messenger. - */ -- constructor({ interval = DEFAULT_INTERVAL, tokens = [], disabled = false, getERC20BalanceOf, messenger, state = {}, }) { -+ constructor({ interval = DEFAULT_INTERVAL, tokens = [], disabled = false, onTokensStateChange, getERC20BalanceOf, messenger, state = {}, }) { - super({ - name: controllerName, - metadata, -@@ -68,13 +69,14 @@ class TokenBalancesController extends base_controller_1.BaseController { - _TokenBalancesController_interval.set(this, void 0); - _TokenBalancesController_tokens.set(this, void 0); - _TokenBalancesController_disabled.set(this, void 0); -+ _TokenBalancesController_updateInProgress.set(this, false); - __classPrivateFieldSet(this, _TokenBalancesController_disabled, disabled, "f"); - __classPrivateFieldSet(this, _TokenBalancesController_interval, interval, "f"); - __classPrivateFieldSet(this, _TokenBalancesController_tokens, tokens, "f"); -- this.messagingSystem.subscribe('TokensController:stateChange', ({ tokens: newTokens, detectedTokens }) => { -+ onTokensStateChange(({ tokens: newTokens, detectedTokens }) => __awaiter(this, void 0, void 0, function* () { - __classPrivateFieldSet(this, _TokenBalancesController_tokens, [...newTokens, ...detectedTokens], "f"); -- this.updateBalances(); -- }); -+ yield this.updateBalances(); -+ })); - __classPrivateFieldSet(this, _TokenBalancesController_getERC20BalanceOf, getERC20BalanceOf, "f"); - this.poll(); - } -@@ -114,29 +116,42 @@ class TokenBalancesController extends base_controller_1.BaseController { - */ - updateBalances() { - return __awaiter(this, void 0, void 0, function* () { -- if (__classPrivateFieldGet(this, _TokenBalancesController_disabled, "f")) { -+ if (__classPrivateFieldGet(this, _TokenBalancesController_disabled, "f") || __classPrivateFieldGet(this, _TokenBalancesController_updateInProgress, "f")) { - return; - } -+ __classPrivateFieldSet(this, _TokenBalancesController_updateInProgress, true, "f"); - const newContractBalances = {}; -- for (const token of __classPrivateFieldGet(this, _TokenBalancesController_tokens, "f")) { -+ const balancePromises = __classPrivateFieldGet(this, _TokenBalancesController_tokens, "f").map((token) => { - const { address } = token; - const { selectedAddress } = this.messagingSystem.call('PreferencesController:getState'); -- try { -- newContractBalances[address] = (0, controller_utils_1.toHex)(yield __classPrivateFieldGet(this, _TokenBalancesController_getERC20BalanceOf, "f").call(this, address, selectedAddress)); -+ return __classPrivateFieldGet(this, _TokenBalancesController_getERC20BalanceOf, "f").call(this, address, selectedAddress) -+ .then((balance) => { -+ newContractBalances[address] = (0, controller_utils_1.toHex)(balance); - token.balanceError = null; -- } -- catch (error) { -+ }) -+ .catch((error) => { - newContractBalances[address] = (0, controller_utils_1.toHex)(0); - token.balanceError = error; -- } -- } -+ }); -+ }); -+ yield Promise.all(balancePromises); - this.update((state) => { - state.contractBalances = newContractBalances; - }); -+ __classPrivateFieldSet(this, _TokenBalancesController_updateInProgress, false, "f"); -+ }); -+ } -+ /** -+ * THIS FUNCTIONS IS CURRENTLY PATCHED AND STILL NEEDS TO BE IMPLEMENTED ON THE CORE REPO -+ * Resets to the default state -+ */ -+ reset() { -+ this.update((state) => { -+ state.contractBalances = {}; - }); - } - } - exports.TokenBalancesController = TokenBalancesController; --_TokenBalancesController_handle = new WeakMap(), _TokenBalancesController_getERC20BalanceOf = new WeakMap(), _TokenBalancesController_interval = new WeakMap(), _TokenBalancesController_tokens = new WeakMap(), _TokenBalancesController_disabled = new WeakMap(); -+_TokenBalancesController_handle = new WeakMap(), _TokenBalancesController_getERC20BalanceOf = new WeakMap(), _TokenBalancesController_interval = new WeakMap(), _TokenBalancesController_tokens = new WeakMap(), _TokenBalancesController_disabled = new WeakMap(), _TokenBalancesController_updateInProgress = new WeakMap(); - exports.default = TokenBalancesController; - //# sourceMappingURL=TokenBalancesController.js.map -\ No newline at end of file -diff --git a/node_modules/@metamask/assets-controllers/dist/TokenDetectionController.d.ts b/node_modules/@metamask/assets-controllers/dist/TokenDetectionController.d.ts -index 528f665..87859b7 100644 ---- a/node_modules/@metamask/assets-controllers/dist/TokenDetectionController.d.ts -+++ b/node_modules/@metamask/assets-controllers/dist/TokenDetectionController.d.ts -@@ -6,7 +6,7 @@ import { StaticIntervalPollingController } from '@metamask/polling-controller'; - import type { PreferencesControllerGetStateAction, PreferencesControllerStateChangeEvent } from '@metamask/preferences-controller'; - import type { AssetsContractController } from './AssetsContractController'; - import type { GetTokenListState, TokenListMap, TokenListStateChange } from './TokenListController'; --import type { TokensControllerAddDetectedTokensAction, TokensControllerGetStateAction } from './TokensController'; -+import type { TokensControllerAddDetectedTokensAction, TokensControllerGetStateAction, TokensState } from './TokensController'; - /** - * Compare 2 given strings and return boolean - * eg: "foo" and "FOO" => true -@@ -54,11 +54,12 @@ export declare class TokenDetectionController extends StaticIntervalPollingContr - * @param options.getBalancesInSingleCall - Gets the balances of a list of tokens for the given address. - * @param options.trackMetaMetricsEvent - Sets options for MetaMetrics event tracking. - */ -- constructor({ selectedAddress, interval, disabled, getBalancesInSingleCall, trackMetaMetricsEvent, messenger, }: { -+ constructor({ selectedAddress, interval, disabled, getBalancesInSingleCall, getTokensState, trackMetaMetricsEvent, messenger, }: { - selectedAddress?: string; - interval?: number; - disabled?: boolean; - getBalancesInSingleCall: AssetsContractController['getBalancesInSingleCall']; -+ getTokensState: () => TokensState; - trackMetaMetricsEvent: (options: { - event: string; - category: string; -diff --git a/node_modules/@metamask/assets-controllers/dist/TokenDetectionController.js b/node_modules/@metamask/assets-controllers/dist/TokenDetectionController.js -index 9aa0914..d91cd80 100644 ---- a/node_modules/@metamask/assets-controllers/dist/TokenDetectionController.js -+++ b/node_modules/@metamask/assets-controllers/dist/TokenDetectionController.js -@@ -33,7 +33,7 @@ var __rest = (this && this.__rest) || function (s, e) { - var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; - }; --var _TokenDetectionController_instances, _TokenDetectionController_intervalId, _TokenDetectionController_selectedAddress, _TokenDetectionController_networkClientId, _TokenDetectionController_tokenList, _TokenDetectionController_disabled, _TokenDetectionController_isUnlocked, _TokenDetectionController_isDetectionEnabledFromPreferences, _TokenDetectionController_isDetectionEnabledForNetwork, _TokenDetectionController_getBalancesInSingleCall, _TokenDetectionController_trackMetaMetricsEvent, _TokenDetectionController_registerEventListeners, _TokenDetectionController_stopPolling, _TokenDetectionController_startPolling, _TokenDetectionController_getCorrectChainIdAndNetworkClientId, _TokenDetectionController_restartTokenDetection, _TokenDetectionController_getSlicesOfTokensToDetect, _TokenDetectionController_addDetectedTokens; -+var _TokenDetectionController_instances, _TokenDetectionController_intervalId, _TokenDetectionController_selectedAddress, _TokenDetectionController_networkClientId, _TokenDetectionController_tokenList, _TokenDetectionController_disabled, _TokenDetectionController_isUnlocked, _TokenDetectionController_isDetectionEnabledFromPreferences, _TokenDetectionController_isDetectionEnabledForNetwork, _TokenDetectionController_getBalancesInSingleCall, _TokenDetectionController_getTokensState, _TokenDetectionController_trackMetaMetricsEvent, _TokenDetectionController_registerEventListeners, _TokenDetectionController_stopPolling, _TokenDetectionController_startPolling, _TokenDetectionController_getCorrectChainIdAndNetworkClientId, _TokenDetectionController_restartTokenDetection, _TokenDetectionController_getSlicesOfTokensToDetect, _TokenDetectionController_addDetectedTokens; - Object.defineProperty(exports, "__esModule", { value: true }); - exports.TokenDetectionController = exports.controllerName = exports.STATIC_MAINNET_TOKEN_LIST = exports.isEqualCaseInsensitive = void 0; - const contract_metadata_1 = __importDefault(require("@metamask/contract-metadata")); -@@ -63,6 +63,12 @@ exports.STATIC_MAINNET_TOKEN_LIST = Object.entries(contract_metadata_1.default). - return Object.assign(Object.assign({}, acc), { [base.toLowerCase()]: Object.assign(Object.assign({}, tokenMetadata), { address: base.toLowerCase(), iconUrl: `images/contract/${logo}`, aggregators: [] }) }); - }, {}); - exports.controllerName = 'TokenDetectionController'; -+ -+/** -+ * **IMPORTANT NOTE ABOUT THIS PATCH** -+ * TokenDetectionController patch can be removed once Tokens Controller extends Base Controller v2 -+ */ -+ - /** - * Controller that passively polls on a set interval for Tokens auto detection - * @property intervalId - Polling interval used to fetch new token rates -@@ -85,7 +91,7 @@ class TokenDetectionController extends polling_controller_1.StaticIntervalPollin - * @param options.getBalancesInSingleCall - Gets the balances of a list of tokens for the given address. - * @param options.trackMetaMetricsEvent - Sets options for MetaMetrics event tracking. - */ -- constructor({ selectedAddress, interval = DEFAULT_INTERVAL, disabled = true, getBalancesInSingleCall, trackMetaMetricsEvent, messenger, }) { -+ constructor({ selectedAddress, interval = DEFAULT_INTERVAL, disabled = true, getBalancesInSingleCall, getTokensState, trackMetaMetricsEvent, messenger, }) { - super({ - name: exports.controllerName, - messenger, -@@ -102,6 +108,7 @@ class TokenDetectionController extends polling_controller_1.StaticIntervalPollin - _TokenDetectionController_isDetectionEnabledFromPreferences.set(this, void 0); - _TokenDetectionController_isDetectionEnabledForNetwork.set(this, void 0); - _TokenDetectionController_getBalancesInSingleCall.set(this, void 0); -+ _TokenDetectionController_getTokensState.set(this, void 0); - _TokenDetectionController_trackMetaMetricsEvent.set(this, void 0); - __classPrivateFieldSet(this, _TokenDetectionController_disabled, disabled, "f"); - this.setIntervalLength(interval); -@@ -113,6 +120,7 @@ class TokenDetectionController extends polling_controller_1.StaticIntervalPollin - __classPrivateFieldSet(this, _TokenDetectionController_isDetectionEnabledFromPreferences, defaultUseTokenDetection, "f"); - __classPrivateFieldSet(this, _TokenDetectionController_isDetectionEnabledForNetwork, (0, assetsUtil_1.isTokenDetectionSupportedForNetwork)(chainId), "f"); - __classPrivateFieldSet(this, _TokenDetectionController_getBalancesInSingleCall, getBalancesInSingleCall, "f"); -+ __classPrivateFieldSet(this, _TokenDetectionController_getTokensState, getTokensState, "f"); - __classPrivateFieldSet(this, _TokenDetectionController_trackMetaMetricsEvent, trackMetaMetricsEvent, "f"); - const { isUnlocked } = this.messagingSystem.call('KeyringController:getState'); - __classPrivateFieldSet(this, _TokenDetectionController_isUnlocked, isUnlocked, "f"); -@@ -210,7 +218,7 @@ class TokenDetectionController extends polling_controller_1.StaticIntervalPollin - } - } - exports.TokenDetectionController = TokenDetectionController; --_TokenDetectionController_intervalId = new WeakMap(), _TokenDetectionController_selectedAddress = new WeakMap(), _TokenDetectionController_networkClientId = new WeakMap(), _TokenDetectionController_tokenList = new WeakMap(), _TokenDetectionController_disabled = new WeakMap(), _TokenDetectionController_isUnlocked = new WeakMap(), _TokenDetectionController_isDetectionEnabledFromPreferences = new WeakMap(), _TokenDetectionController_isDetectionEnabledForNetwork = new WeakMap(), _TokenDetectionController_getBalancesInSingleCall = new WeakMap(), _TokenDetectionController_trackMetaMetricsEvent = new WeakMap(), _TokenDetectionController_instances = new WeakSet(), _TokenDetectionController_registerEventListeners = function _TokenDetectionController_registerEventListeners() { -+_TokenDetectionController_intervalId = new WeakMap(), _TokenDetectionController_selectedAddress = new WeakMap(), _TokenDetectionController_networkClientId = new WeakMap(), _TokenDetectionController_tokenList = new WeakMap(), _TokenDetectionController_disabled = new WeakMap(), _TokenDetectionController_isUnlocked = new WeakMap(), _TokenDetectionController_isDetectionEnabledFromPreferences = new WeakMap(), _TokenDetectionController_isDetectionEnabledForNetwork = new WeakMap(), _TokenDetectionController_getBalancesInSingleCall = new WeakMap(), _TokenDetectionController_getTokensState = new WeakMap(), _TokenDetectionController_trackMetaMetricsEvent = new WeakMap(), _TokenDetectionController_instances = new WeakSet(), _TokenDetectionController_registerEventListeners = function _TokenDetectionController_registerEventListeners() { - this.messagingSystem.subscribe('KeyringController:unlock', () => __awaiter(this, void 0, void 0, function* () { - __classPrivateFieldSet(this, _TokenDetectionController_isUnlocked, true, "f"); - yield __classPrivateFieldGet(this, _TokenDetectionController_instances, "m", _TokenDetectionController_restartTokenDetection).call(this); -@@ -298,7 +306,7 @@ _TokenDetectionController_intervalId = new WeakMap(), _TokenDetectionController_ - this.setIntervalLength(DEFAULT_INTERVAL); - }); - }, _TokenDetectionController_getSlicesOfTokensToDetect = function _TokenDetectionController_getSlicesOfTokensToDetect({ chainId, selectedAddress, }) { -- const { allTokens, allDetectedTokens, allIgnoredTokens } = this.messagingSystem.call('TokensController:getState'); -+ const { allTokens, allDetectedTokens, allIgnoredTokens } = __classPrivateFieldGet(this, _TokenDetectionController_getTokensState, "f").call(this); - const [tokensAddresses, detectedTokensAddresses, ignoredTokensAddresses] = [ - allTokens, - allDetectedTokens, -diff --git a/node_modules/@metamask/assets-controllers/dist/assetsUtil.d.ts b/node_modules/@metamask/assets-controllers/dist/assetsUtil.d.ts -index 85c8569..aa14bc1 100644 ---- a/node_modules/@metamask/assets-controllers/dist/assetsUtil.d.ts -+++ b/node_modules/@metamask/assets-controllers/dist/assetsUtil.d.ts -@@ -1,8 +1,7 @@ - import type { BigNumber } from '@ethersproject/bignumber'; - import type { Hex } from '@metamask/utils'; - import BN from 'bn.js'; --import type { Nft, NftMetadata, OpenSeaV2Collection, OpenSeaV2Contract, OpenSeaV2DetailedNft, OpenSeaV2Nft } from './NftController'; --import type { ApiNft, ApiNftContract } from './NftDetectionController'; -+import type { Nft, NftMetadata } from './NftController'; - import type { AbstractTokenPricesService } from './token-prices-service'; - import { type ContractExchangeRates } from './TokenRatesController'; - /** -@@ -145,25 +144,6 @@ export declare function reduceInBatchesSerially, batch: Value[], index: number) => Partial | Promise>; - initialResult: Partial; - }): Promise; --/** -- * Maps an OpenSea V2 NFT to the V1 schema. -- * @param nft - The V2 NFT to map. -- * @returns The NFT in the V1 schema. -- */ --export declare function mapOpenSeaNftV2ToV1(nft: OpenSeaV2Nft): ApiNft; --/** -- * Maps an OpenSea V2 detailed NFT to the V1 schema. -- * @param nft - The V2 detailed NFT to map. -- * @returns The NFT in the V1 schema. -- */ --export declare function mapOpenSeaDetailedNftV2ToV1(nft: OpenSeaV2DetailedNft): ApiNft; --/** -- * Maps an OpenSea V2 contract to the V1 schema. -- * @param contract - The v2 contract data. -- * @param collection - The v2 collection data. -- * @returns The contract in the v1 schema. -- */ --export declare function mapOpenSeaContractV2ToV1(contract: OpenSeaV2Contract, collection?: OpenSeaV2Collection): ApiNftContract; - /** - * Retrieves token prices for a set of contract addresses in a specific currency and chainId. - * -diff --git a/node_modules/@metamask/assets-controllers/dist/assetsUtil.js b/node_modules/@metamask/assets-controllers/dist/assetsUtil.js -index 2768926..1e81cde 100644 ---- a/node_modules/@metamask/assets-controllers/dist/assetsUtil.js -+++ b/node_modules/@metamask/assets-controllers/dist/assetsUtil.js -@@ -12,7 +12,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; - }; - Object.defineProperty(exports, "__esModule", { value: true }); --exports.fetchTokenContractExchangeRates = exports.mapOpenSeaContractV2ToV1 = exports.mapOpenSeaDetailedNftV2ToV1 = exports.mapOpenSeaNftV2ToV1 = exports.reduceInBatchesSerially = exports.divideIntoBatches = exports.ethersBigNumberToBN = exports.addUrlProtocolPrefix = exports.getFormattedIpfsUrl = exports.getIpfsCIDv1AndPath = exports.removeIpfsProtocolPrefix = exports.isTokenListSupportedForNetwork = exports.isTokenDetectionSupportedForNetwork = exports.SupportedTokenDetectionNetworks = exports.formatIconUrlWithProxy = exports.formatAggregatorNames = exports.compareNftMetadata = exports.TOKEN_PRICES_BATCH_SIZE = void 0; -+exports.fetchTokenContractExchangeRates = exports.reduceInBatchesSerially = exports.divideIntoBatches = exports.ethersBigNumberToBN = exports.addUrlProtocolPrefix = exports.getFormattedIpfsUrl = exports.getIpfsCIDv1AndPath = exports.removeIpfsProtocolPrefix = exports.isTokenListSupportedForNetwork = exports.isTokenDetectionSupportedForNetwork = exports.SupportedTokenDetectionNetworks = exports.formatIconUrlWithProxy = exports.formatAggregatorNames = exports.compareNftMetadata = exports.TOKEN_PRICES_BATCH_SIZE = void 0; - const controller_utils_1 = require("@metamask/controller-utils"); - const utils_1 = require("@metamask/utils"); - const bn_js_1 = __importDefault(require("bn.js")); -@@ -268,84 +268,6 @@ function reduceInBatchesSerially({ values, batchSize, eachBatch, initialResult, - }); - } - exports.reduceInBatchesSerially = reduceInBatchesSerially; --/** -- * Maps an OpenSea V2 NFT to the V1 schema. -- * @param nft - The V2 NFT to map. -- * @returns The NFT in the V1 schema. -- */ --function mapOpenSeaNftV2ToV1(nft) { -- var _a; -- return { -- token_id: nft.identifier, -- num_sales: null, -- background_color: null, -- image_url: (_a = nft.image_url) !== null && _a !== void 0 ? _a : null, -- image_preview_url: null, -- image_thumbnail_url: null, -- image_original_url: null, -- animation_url: null, -- animation_original_url: null, -- name: nft.name, -- description: nft.description, -- external_link: null, -- asset_contract: { -- address: nft.contract, -- asset_contract_type: null, -- created_date: null, -- schema_name: nft.token_standard.toUpperCase(), -- symbol: null, -- total_supply: null, -- description: nft.description, -- external_link: null, -- collection: { -- name: nft.collection, -- image_url: null, -- }, -- }, -- creator: { -- user: { username: '' }, -- profile_img_url: '', -- address: '', -- }, -- last_sale: null, -- }; --} --exports.mapOpenSeaNftV2ToV1 = mapOpenSeaNftV2ToV1; --/** -- * Maps an OpenSea V2 detailed NFT to the V1 schema. -- * @param nft - The V2 detailed NFT to map. -- * @returns The NFT in the V1 schema. -- */ --function mapOpenSeaDetailedNftV2ToV1(nft) { -- var _a; -- const mapped = mapOpenSeaNftV2ToV1(nft); -- return Object.assign(Object.assign({}, mapped), { animation_url: (_a = nft.animation_url) !== null && _a !== void 0 ? _a : null, creator: Object.assign(Object.assign({}, mapped.creator), { address: nft.creator }) }); --} --exports.mapOpenSeaDetailedNftV2ToV1 = mapOpenSeaDetailedNftV2ToV1; --/** -- * Maps an OpenSea V2 contract to the V1 schema. -- * @param contract - The v2 contract data. -- * @param collection - The v2 collection data. -- * @returns The contract in the v1 schema. -- */ --function mapOpenSeaContractV2ToV1(contract, collection) { -- var _a, _b, _c, _d, _e, _f, _g; -- return { -- address: contract.address, -- asset_contract_type: null, -- created_date: null, -- schema_name: contract.contract_standard.toUpperCase(), -- symbol: null, -- total_supply: (_d = (_b = (_a = collection === null || collection === void 0 ? void 0 : collection.total_supply) === null || _a === void 0 ? void 0 : _a.toString()) !== null && _b !== void 0 ? _b : (_c = contract.total_supply) === null || _c === void 0 ? void 0 : _c.toString()) !== null && _d !== void 0 ? _d : null, -- description: (_e = collection === null || collection === void 0 ? void 0 : collection.description) !== null && _e !== void 0 ? _e : null, -- external_link: (_f = collection === null || collection === void 0 ? void 0 : collection.project_url) !== null && _f !== void 0 ? _f : null, -- collection: { -- name: (_g = collection === null || collection === void 0 ? void 0 : collection.name) !== null && _g !== void 0 ? _g : contract.name, -- image_url: collection === null || collection === void 0 ? void 0 : collection.image_url, -- }, -- }; --} --exports.mapOpenSeaContractV2ToV1 = mapOpenSeaContractV2ToV1; - /** - * Retrieves token prices for a set of contract addresses in a specific currency and chainId. - * -diff --git a/node_modules/@metamask/assets-controllers/dist/index.d.ts b/node_modules/@metamask/assets-controllers/dist/index.d.ts -index 9c19787..489b198 100644 ---- a/node_modules/@metamask/assets-controllers/dist/index.d.ts -+++ b/node_modules/@metamask/assets-controllers/dist/index.d.ts -@@ -3,7 +3,7 @@ export * from './AssetsContractController'; - export * from './CurrencyRateController'; - export * from './NftController'; - export * from './NftDetectionController'; --export type { TokenBalancesControllerMessenger, TokenBalancesControllerActions, TokenBalancesControllerGetStateAction, TokenBalancesControllerEvents, TokenBalancesControllerStateChangeEvent, } from './TokenBalancesController'; -+export type { TokenBalancesControllerMessenger, TokenBalancesControllerActions, TokenBalancesControllerGetStateAction, TokenBalancesControllerEvents, TokenBalancesControllerStateChangeEvent, TokenBalancesControllerState, } from './TokenBalancesController'; - export { TokenBalancesController } from './TokenBalancesController'; - export type { TokenDetectionControllerMessenger, TokenDetectionControllerActions, TokenDetectionControllerGetStateAction, TokenDetectionControllerEvents, TokenDetectionControllerStateChangeEvent, } from './TokenDetectionController'; - export { TokenDetectionController } from './TokenDetectionController'; diff --git a/patches/@metamask+assets-controllers+30.0.0.patch b/patches/@metamask+assets-controllers+30.0.0.patch new file mode 100644 index 00000000000..f2bd7884c39 --- /dev/null +++ b/patches/@metamask+assets-controllers+30.0.0.patch @@ -0,0 +1,577 @@ +diff --git a/node_modules/@metamask/assets-controllers/dist/chunk-6W5EQ3JQ.js b/node_modules/@metamask/assets-controllers/dist/chunk-6W5EQ3JQ.js +index 0dc70ec..461a210 100644 +--- a/node_modules/@metamask/assets-controllers/dist/chunk-6W5EQ3JQ.js ++++ b/node_modules/@metamask/assets-controllers/dist/chunk-6W5EQ3JQ.js +@@ -378,9 +378,10 @@ fetchAndMapExchangeRatesForSupportedNativeCurrency_fn = async function({ + } + return Object.entries(contractNativeInformations).reduce( + (obj, [tokenAddress, token]) => { ++ // This is fixed on v31 of assets controllers + obj = { + ...obj, +- [tokenAddress.toLowerCase()]: { ...token } ++ [tokenAddress]: { ...token } + }; + return obj; + }, +@@ -416,7 +417,7 @@ fetchAndMapExchangeRatesForUnsupportedNativeCurrency_fn = async function({ + ...acc, + [tokenAddress]: { + ...token, +- value: token.value ? token.value * fallbackCurrencyToNativeCurrencyConversionRate : void 0 ++ price: token.price ? token.price * fallbackCurrencyToNativeCurrencyConversionRate : void 0 + } + }; + return acc; +diff --git a/node_modules/@metamask/assets-controllers/dist/chunk-HDI4L2DD.js b/node_modules/@metamask/assets-controllers/dist/chunk-HDI4L2DD.js +index 76e3362..5ab79a4 100644 +--- a/node_modules/@metamask/assets-controllers/dist/chunk-HDI4L2DD.js ++++ b/node_modules/@metamask/assets-controllers/dist/chunk-HDI4L2DD.js +@@ -34,7 +34,7 @@ var STATIC_MAINNET_TOKEN_LIST = Object.entries( + }; + }, {}); + var controllerName = "TokenDetectionController"; +-var _intervalId, _selectedAddress, _networkClientId, _tokenList, _disabled, _isUnlocked, _isDetectionEnabledFromPreferences, _isDetectionEnabledForNetwork, _getBalancesInSingleCall, _trackMetaMetricsEvent, _registerEventListeners, registerEventListeners_fn, _stopPolling, stopPolling_fn, _startPolling, startPolling_fn, _getCorrectChainIdAndNetworkClientId, getCorrectChainIdAndNetworkClientId_fn, _restartTokenDetection, restartTokenDetection_fn, _getSlicesOfTokensToDetect, getSlicesOfTokensToDetect_fn, _addDetectedTokens, addDetectedTokens_fn; ++var _intervalId, _selectedAddress, _networkClientId, _tokenList, _disabled, _isUnlocked, _isDetectionEnabledFromPreferences, _isDetectionEnabledForNetwork, _getBalancesInSingleCall, _getTokensState, _trackMetaMetricsEvent, _registerEventListeners, registerEventListeners_fn, _stopPolling, stopPolling_fn, _startPolling, startPolling_fn, _getCorrectChainIdAndNetworkClientId, getCorrectChainIdAndNetworkClientId_fn, _restartTokenDetection, restartTokenDetection_fn, _getSlicesOfTokensToDetect, getSlicesOfTokensToDetect_fn, _addDetectedTokens, addDetectedTokens_fn; + var TokenDetectionController = class extends _pollingcontroller.StaticIntervalPollingController { + /** + * Creates a TokenDetectionController instance. +@@ -52,6 +52,7 @@ var TokenDetectionController = class extends _pollingcontroller.StaticIntervalPo + interval = DEFAULT_INTERVAL, + disabled = true, + getBalancesInSingleCall, ++ getTokensState, + trackMetaMetricsEvent, + messenger + }) { +@@ -91,6 +92,7 @@ var TokenDetectionController = class extends _pollingcontroller.StaticIntervalPo + _chunkZ4BLTVTBjs.__privateAdd.call(void 0, this, _isDetectionEnabledFromPreferences, void 0); + _chunkZ4BLTVTBjs.__privateAdd.call(void 0, this, _isDetectionEnabledForNetwork, void 0); + _chunkZ4BLTVTBjs.__privateAdd.call(void 0, this, _getBalancesInSingleCall, void 0); ++ _chunkZ4BLTVTBjs.__privateAdd.call(void 0, this, _getTokensState, void 0); + _chunkZ4BLTVTBjs.__privateAdd.call(void 0, this, _trackMetaMetricsEvent, void 0); + _chunkZ4BLTVTBjs.__privateSet.call(void 0, this, _disabled, disabled); + this.setIntervalLength(interval); +@@ -101,6 +103,7 @@ var TokenDetectionController = class extends _pollingcontroller.StaticIntervalPo + _chunkZ4BLTVTBjs.__privateSet.call(void 0, this, _isDetectionEnabledFromPreferences, defaultUseTokenDetection); + _chunkZ4BLTVTBjs.__privateSet.call(void 0, this, _isDetectionEnabledForNetwork, _chunkNEXY7SE2js.isTokenDetectionSupportedForNetwork.call(void 0, chainId)); + _chunkZ4BLTVTBjs.__privateSet.call(void 0, this, _getBalancesInSingleCall, getBalancesInSingleCall); ++ _chunkZ4BLTVTBjs.__privateSet.call(void 0, this, _getTokensState, getTokensState); + _chunkZ4BLTVTBjs.__privateSet.call(void 0, this, _trackMetaMetricsEvent, trackMetaMetricsEvent); + const { isUnlocked } = this.messagingSystem.call( + "KeyringController:getState" +@@ -203,6 +206,7 @@ _isDetectionEnabledFromPreferences = new WeakMap(); + _isDetectionEnabledForNetwork = new WeakMap(); + _getBalancesInSingleCall = new WeakMap(); + _trackMetaMetricsEvent = new WeakMap(); ++_getTokensState = new WeakMap(); + _registerEventListeners = new WeakSet(); + registerEventListeners_fn = function() { + this.messagingSystem.subscribe("KeyringController:unlock", async () => { +@@ -324,7 +328,7 @@ getSlicesOfTokensToDetect_fn = function({ + chainId, + selectedAddress + }) { +- const { allTokens, allDetectedTokens, allIgnoredTokens } = this.messagingSystem.call("TokensController:getState"); ++ const { allTokens, allDetectedTokens, allIgnoredTokens } = _chunkZ4BLTVTBjs.__privateGet.call(void 0, this, _getTokensState).call(this); + const [tokensAddresses, detectedTokensAddresses, ignoredTokensAddresses] = [ + allTokens, + allDetectedTokens, +diff --git a/node_modules/@metamask/assets-controllers/dist/chunk-LAU6ZDZR.js b/node_modules/@metamask/assets-controllers/dist/chunk-LAU6ZDZR.js +index d429be1..f5c1e2e 100644 +--- a/node_modules/@metamask/assets-controllers/dist/chunk-LAU6ZDZR.js ++++ b/node_modules/@metamask/assets-controllers/dist/chunk-LAU6ZDZR.js +@@ -33,6 +33,11 @@ var getDefaultNftState = () => { + ignoredNfts: [] + }; + }; ++ ++/** ++ * Changes regarding displayNftMedia, TokenURI and error nft metadata property are not on the core repo and needed to be refactor to be removed from the patch ++ * updateNftMetadata changes will be introduced on latest versions of changes of assets controllers, v^30 or next ++ */ + var NftController = class extends _basecontroller.BaseControllerV1 { + /** + * Creates an NftController instance. +@@ -82,7 +87,7 @@ var NftController = class extends _basecontroller.BaseControllerV1 { + selectedAddress: "", + chainId: initialChainId, + ipfsGateway: _controllerutils.IPFS_DEFAULT_GATEWAY_URL, +- openSeaEnabled: false, ++ displayNftMedia: false, + useIPFSSubdomains: true, + isIpfsGatewayEnabled: true + }; +@@ -101,16 +106,16 @@ var NftController = class extends _basecontroller.BaseControllerV1 { + async ({ + selectedAddress, + ipfsGateway, +- openSeaEnabled, ++ displayNftMedia, + isIpfsGatewayEnabled + }) => { + this.configure({ + selectedAddress, + ipfsGateway, +- openSeaEnabled, ++ displayNftMedia, + isIpfsGatewayEnabled + }); +- const needsUpdateNftMetadata = isIpfsGatewayEnabled && ipfsGateway !== "" || openSeaEnabled; ++ const needsUpdateNftMetadata = isIpfsGatewayEnabled && ipfsGateway !== "" || displayNftMedia; + if (needsUpdateNftMetadata) { + const { chainId } = this.config; + const nfts = this.state.allNfts[selectedAddress]?.[chainId] ?? []; +@@ -189,7 +194,8 @@ var NftController = class extends _basecontroller.BaseControllerV1 { + name: null, + description: null, + image: null, +- standard: null ++ standard: null, ++ error: 'Opensea import error', + }; + } + const { +@@ -234,7 +240,7 @@ var NftController = class extends _basecontroller.BaseControllerV1 { + * @returns Promise resolving to the current NFT name and image. + */ + async getNftInformationFromTokenURI(contractAddress, tokenId, networkClientId) { +- const { ipfsGateway, useIPFSSubdomains, isIpfsGatewayEnabled } = this.config; ++ const { ipfsGateway, useIPFSSubdomains, isIpfsGatewayEnabled, displayNftMedia, } = this.config; + const result = await this.getNftURIAndStandard( + contractAddress, + tokenId, +@@ -242,6 +248,18 @@ var NftController = class extends _basecontroller.BaseControllerV1 { + ); + let tokenURI = result[0]; + const standard = result[1]; ++ ++ if (!displayNftMedia && !isIpfsGatewayEnabled) { ++ return { ++ image: null, ++ name: null, ++ description: null, ++ standard: standard || null, ++ favorite: false, ++ tokenURI, ++ }; ++ } ++ + const hasIpfsTokenURI = tokenURI.startsWith("ipfs://"); + if (hasIpfsTokenURI && !isIpfsGatewayEnabled) { + return { +@@ -253,15 +271,15 @@ var NftController = class extends _basecontroller.BaseControllerV1 { + tokenURI: tokenURI ?? null + }; + } +- const isDisplayNFTMediaToggleEnabled = this.config.openSeaEnabled; +- if (!hasIpfsTokenURI && !isDisplayNFTMediaToggleEnabled) { ++ if (!hasIpfsTokenURI && !displayNftMedia) { + return { + image: null, + name: null, + description: null, + standard: standard || null, + favorite: false, +- tokenURI: tokenURI ?? null ++ tokenURI: tokenURI ?? null, ++ error: 'URI import error', + }; + } + if (hasIpfsTokenURI) { +@@ -288,7 +306,8 @@ var NftController = class extends _basecontroller.BaseControllerV1 { + description: null, + standard: standard || null, + favorite: false, +- tokenURI: tokenURI ?? null ++ tokenURI: tokenURI ?? null, ++ error: 'URI import error', + }; + } + } +@@ -345,15 +364,28 @@ var NftController = class extends _basecontroller.BaseControllerV1 { + networkClientId + ) + ), +- this.config.openSeaEnabled && chainId === "0x1" ? _controllerutils.safelyExecute.call(void 0, ++ this.config.displayNftMedia && chainId === "0x1" ? _controllerutils.safelyExecute.call(void 0, + () => this.getNftInformationFromApi(contractAddress, tokenId) + ) : void 0 + ]); ++ ++ if (blockchainMetadata?.error && nftApiMetadata?.error) { ++ return { ++ image: null, ++ name: null, ++ description: null, ++ standard: blockchainMetadata.standard ?? null, ++ favorite: false, ++ tokenURI: blockchainMetadata.tokenURI ?? null, ++ error: 'Both import failed', ++ }; ++ } ++ + return { + ...nftApiMetadata, + name: blockchainMetadata?.name ?? nftApiMetadata?.name ?? null, + description: blockchainMetadata?.description ?? nftApiMetadata?.description ?? null, +- image: blockchainMetadata?.image ?? nftApiMetadata?.image ?? null, ++ image: nftApiMetadata?.image ?? blockchainMetadata?.image ?? null, + standard: blockchainMetadata?.standard ?? nftApiMetadata?.standard ?? null, + tokenURI: blockchainMetadata?.tokenURI ?? null + }; +@@ -472,7 +504,8 @@ var NftController = class extends _basecontroller.BaseControllerV1 { + symbol: nftContract.symbol, + tokenId: tokenId.toString(), + standard: nftMetadata.standard, +- source ++ source, ++ tokenURI: nftMetadata.tokenURI, + }); + } + return newNfts; +@@ -850,7 +883,7 @@ var NftController = class extends _basecontroller.BaseControllerV1 { + ); + } + } +- /** ++ /** + * Refetches NFT metadata and updates the state + * + * @param options - Options for refetching NFT metadata +@@ -858,11 +891,13 @@ var NftController = class extends _basecontroller.BaseControllerV1 { + * @param options.userAddress - The current user address + * @param options.networkClientId - The networkClientId that can be used to identify the network client to use for this request. + */ +- async updateNftMetadata({ +- nfts, +- userAddress = this.config.selectedAddress, +- networkClientId +- }) { ++ async updateNftMetadata({ ++ nfts, ++ userAddress = this.config.selectedAddress, ++ networkClientId ++}) { ++ const releaseLock = await this.mutex.acquire(); ++ try { + const chainId = this.getCorrectChainId({ networkClientId }); + const nftsWithChecksumAdr = nfts.map((nft) => { + return { +@@ -870,7 +905,7 @@ var NftController = class extends _basecontroller.BaseControllerV1 { + address: _controllerutils.toChecksumHexAddress.call(void 0, nft.address) + }; + }); +- const nftMetadataResults = await Promise.allSettled( ++ const nftMetadataResults = await Promise.all( + nftsWithChecksumAdr.map(async (nft) => { + const resMetadata = await this.getNftInformation( + nft.address, +@@ -883,19 +918,16 @@ var NftController = class extends _basecontroller.BaseControllerV1 { + }; + }) + ); +- const successfulNewFetchedNfts = nftMetadataResults.filter( +- (result) => result.status === "fulfilled" +- ); + const nftsWithDifferentMetadata = []; + const { allNfts } = this.state; + const stateNfts = allNfts[userAddress]?.[chainId] || []; +- successfulNewFetchedNfts.forEach((singleNft) => { ++ nftMetadataResults.forEach((singleNft) => { + const existingEntry = stateNfts.find( +- (nft) => nft.address.toLowerCase() === singleNft.value.nft.address.toLowerCase() && nft.tokenId === singleNft.value.nft.tokenId ++ (nft) => nft.address.toLowerCase() === singleNft.nft.address.toLowerCase() && nft.tokenId === singleNft.nft.tokenId + ); + if (existingEntry) { + const differentMetadata = _chunkNEXY7SE2js.compareNftMetadata.call(void 0, +- singleNft.value.newMetadata, ++ singleNft.newMetadata, + existingEntry + ); + if (differentMetadata) { +@@ -905,15 +937,13 @@ var NftController = class extends _basecontroller.BaseControllerV1 { + }); + if (nftsWithDifferentMetadata.length !== 0) { + nftsWithDifferentMetadata.forEach( +- (elm) => this.updateNft( +- elm.value.nft, +- elm.value.newMetadata, +- userAddress, +- chainId +- ) ++ (elm) => this.updateNft(elm.nft, elm.newMetadata, userAddress, chainId) + ); + } ++ } finally { ++ releaseLock(); + } ++} + /** + * Removes an NFT from the stored token list. + * +diff --git a/node_modules/@metamask/assets-controllers/dist/chunk-LD4GC7OR.js b/node_modules/@metamask/assets-controllers/dist/chunk-LD4GC7OR.js +index cd8f792..b20db8a 100644 +--- a/node_modules/@metamask/assets-controllers/dist/chunk-LD4GC7OR.js ++++ b/node_modules/@metamask/assets-controllers/dist/chunk-LD4GC7OR.js +@@ -19,7 +19,7 @@ function getDefaultTokenBalancesState() { + contractBalances: {} + }; + } +-var _handle, _getERC20BalanceOf, _interval, _tokens, _disabled; ++var _handle, _getERC20BalanceOf, _interval, _tokens, _disabled, _updateInProgress; + var TokenBalancesController = class extends _basecontroller.BaseController { + /** + * Construct a Token Balances Controller. +@@ -28,6 +28,7 @@ var TokenBalancesController = class extends _basecontroller.BaseController { + * @param options.interval - Polling interval used to fetch new token balances. + * @param options.tokens - List of tokens to track balances for. + * @param options.disabled - If set to true, all tracked tokens contract balances updates are blocked. ++ * @param options.onTokensStateChange - Allows subscribing to token controller state changes. + * @param options.getERC20BalanceOf - Gets the balance of the given account at the given contract address. + * @param options.state - Initial state to set on this controller. + * @param options.messenger - The controller restricted messenger. +@@ -36,6 +37,7 @@ var TokenBalancesController = class extends _basecontroller.BaseController { + interval = DEFAULT_INTERVAL, + tokens = [], + disabled = false, ++ onTokensStateChange, + getERC20BalanceOf, + messenger, + state = {} +@@ -54,16 +56,14 @@ var TokenBalancesController = class extends _basecontroller.BaseController { + _chunkZ4BLTVTBjs.__privateAdd.call(void 0, this, _interval, void 0); + _chunkZ4BLTVTBjs.__privateAdd.call(void 0, this, _tokens, void 0); + _chunkZ4BLTVTBjs.__privateAdd.call(void 0, this, _disabled, void 0); ++ _chunkZ4BLTVTBjs.__privateAdd.call(void 0, this, _updateInProgress, false); + _chunkZ4BLTVTBjs.__privateSet.call(void 0, this, _disabled, disabled); + _chunkZ4BLTVTBjs.__privateSet.call(void 0, this, _interval, interval); + _chunkZ4BLTVTBjs.__privateSet.call(void 0, this, _tokens, tokens); +- this.messagingSystem.subscribe( +- "TokensController:stateChange", +- ({ tokens: newTokens, detectedTokens }) => { +- _chunkZ4BLTVTBjs.__privateSet.call(void 0, this, _tokens, [...newTokens, ...detectedTokens]); +- this.updateBalances(); +- } +- ); ++ onTokensStateChange(async ({ tokens: newTokens, detectedTokens }) => { ++ _chunkZ4BLTVTBjs.__privateSet.call(void 0, this, _tokens, [...newTokens, ...detectedTokens]); ++ await this.updateBalances(); ++ }); + _chunkZ4BLTVTBjs.__privateSet.call(void 0, this, _getERC20BalanceOf, getERC20BalanceOf); + this.poll(); + } +@@ -96,39 +96,50 @@ var TokenBalancesController = class extends _basecontroller.BaseController { + this.poll(_chunkZ4BLTVTBjs.__privateGet.call(void 0, this, _interval)); + }, _chunkZ4BLTVTBjs.__privateGet.call(void 0, this, _interval))); + } +- /** ++ /** + * Updates balances for all tokens. + */ +- async updateBalances() { +- if (_chunkZ4BLTVTBjs.__privateGet.call(void 0, this, _disabled)) { ++ async updateBalances() { ++ if (_chunkZ4BLTVTBjs.__privateGet.call(void 0, this, _disabled) || _chunkZ4BLTVTBjs.__privateGet.call(void 0, this, _updateInProgress)) { + return; + } ++ _chunkZ4BLTVTBjs.__privateSet.call(void 0, this, _updateInProgress, true); + const newContractBalances = {}; +- for (const token of _chunkZ4BLTVTBjs.__privateGet.call(void 0, this, _tokens)) { ++ const balancePromises = _chunkZ4BLTVTBjs.__privateGet.call(void 0, this, _tokens).map((token) => { + const { address } = token; + const { selectedAddress } = this.messagingSystem.call( + "PreferencesController:getState" + ); +- try { +- newContractBalances[address] = _controllerutils.toHex.call(void 0, +- await _chunkZ4BLTVTBjs.__privateGet.call(void 0, this, _getERC20BalanceOf).call(this, address, selectedAddress) +- ); ++ return _chunkZ4BLTVTBjs.__privateGet.call(void 0, this, _getERC20BalanceOf).call(this, address, selectedAddress).then((balance) => { ++ newContractBalances[address] = _controllerutils.toHex.call(void 0, balance); + token.balanceError = null; +- } catch (error) { ++ }).catch((error) => { + newContractBalances[address] = _controllerutils.toHex.call(void 0, 0); + token.balanceError = error; +- } +- } ++ }); ++ }); ++ await Promise.all(balancePromises); + this.update((state) => { + state.contractBalances = newContractBalances; + }); ++ _chunkZ4BLTVTBjs.__privateSet.call(void 0, this, _updateInProgress, false); + } ++ /** ++ * THIS FUNCTIONS IS CURRENTLY PATCHED AND STILL NEEDS TO BE IMPLEMENTED ON THE CORE REPO ++ * Resets to the default state ++ */ ++ reset() { ++ this.update((state) => { ++ state.contractBalances = {}; ++ }); ++ } + }; + _handle = new WeakMap(); + _getERC20BalanceOf = new WeakMap(); + _interval = new WeakMap(); + _tokens = new WeakMap(); + _disabled = new WeakMap(); ++_updateInProgress = new WeakMap(); + var TokenBalancesController_default = TokenBalancesController; + + +diff --git a/node_modules/@metamask/assets-controllers/dist/chunk-NEXY7SE2.js b/node_modules/@metamask/assets-controllers/dist/chunk-NEXY7SE2.js +index 8c506d9..d1ec2d2 100644 +--- a/node_modules/@metamask/assets-controllers/dist/chunk-NEXY7SE2.js ++++ b/node_modules/@metamask/assets-controllers/dist/chunk-NEXY7SE2.js +@@ -182,7 +182,7 @@ async function fetchTokenContractExchangeRates({ + (obj, [tokenAddress, tokenPrice]) => { + return { + ...obj, +- [_controllerutils.toChecksumHexAddress.call(void 0, tokenAddress)]: tokenPrice?.value ++ [_controllerutils.toChecksumHexAddress.call(void 0, tokenAddress)]: tokenPrice?.price + }; + }, + {} +diff --git a/node_modules/@metamask/assets-controllers/dist/chunk-V4ZO3F2S.js b/node_modules/@metamask/assets-controllers/dist/chunk-V4ZO3F2S.js +index 0430e5c..dee32be 100644 +--- a/node_modules/@metamask/assets-controllers/dist/chunk-V4ZO3F2S.js ++++ b/node_modules/@metamask/assets-controllers/dist/chunk-V4ZO3F2S.js +@@ -80,9 +80,11 @@ var AccountTrackerController = class extends _pollingcontroller.StaticIntervalPo + [chainId]: accountsForChain + } + }); +- } catch (err) { ++ } finally { ++ /** ++ * This change is not present on the core repo ++ */ + releaseLock(); +- throw err; + } + }; + this.defaultConfig = { +diff --git a/node_modules/@metamask/assets-controllers/dist/chunk-Z6TBQQE5.js b/node_modules/@metamask/assets-controllers/dist/chunk-Z6TBQQE5.js +index 2f1b66f..60cbc0f 100644 +--- a/node_modules/@metamask/assets-controllers/dist/chunk-Z6TBQQE5.js ++++ b/node_modules/@metamask/assets-controllers/dist/chunk-Z6TBQQE5.js +@@ -295,13 +295,12 @@ var CodefiTokenPricesServiceV2 = class { + (obj, tokenAddress) => { + const lowercasedTokenAddress = tokenAddress.toLowerCase(); + const marketData = addressCryptoDataMap[lowercasedTokenAddress]; +- if (marketData === void 0) { ++ // This is fixed on v31 of assets controllers ++ if (!marketData) { + return obj; + } +- const { price } = marketData; + const token = { + tokenAddress, +- value: price, + currency, + ...marketData + }; +diff --git a/node_modules/@metamask/assets-controllers/dist/types/NftController.d.ts b/node_modules/@metamask/assets-controllers/dist/types/NftController.d.ts +index 42a321a..1393ca3 100644 +--- a/node_modules/@metamask/assets-controllers/dist/types/NftController.d.ts ++++ b/node_modules/@metamask/assets-controllers/dist/types/NftController.d.ts +@@ -109,6 +109,7 @@ export interface NftMetadata { + creator?: string; + transactionId?: string; + tokenURI?: string | null; ++ error?: string; + collection?: Collection; + address?: string; + attributes?: Attributes; +@@ -125,7 +126,7 @@ export interface NftConfig extends BaseConfig { + selectedAddress: string; + chainId: Hex; + ipfsGateway: string; +- openSeaEnabled: boolean; ++ displayNftMedia: boolean; + useIPFSSubdomains: boolean; + isIpfsGatewayEnabled: boolean; + } +@@ -350,7 +351,7 @@ export declare class NftController extends BaseControllerV1 + source: string; + }) => void; + messenger: NftControllerMessenger; +- }, config?: Partial, state?: Partial); ++ }, config?: Partial, state?: Partial); + private validateWatchNft; + private getCorrectChainId; + /** +diff --git a/node_modules/@metamask/assets-controllers/dist/types/TokenBalancesController.d.ts b/node_modules/@metamask/assets-controllers/dist/types/TokenBalancesController.d.ts +index 52bb3ac..1f4d15d 100644 +--- a/node_modules/@metamask/assets-controllers/dist/types/TokenBalancesController.d.ts ++++ b/node_modules/@metamask/assets-controllers/dist/types/TokenBalancesController.d.ts +@@ -56,11 +56,12 @@ export declare class TokenBalancesController extends BaseController; ++ /** ++ * THIS FUNCTIONS IS CURRENTLY PATCHED AND STILL NEEDS TO BE IMPLEMENTED ON THE CORE REPO ++ * Resets to the default state ++ */ ++ reset(): void; + } + export default TokenBalancesController; + //# sourceMappingURL=TokenBalancesController.d.ts.map +\ No newline at end of file +diff --git a/node_modules/@metamask/assets-controllers/dist/types/TokenDetectionController.d.ts b/node_modules/@metamask/assets-controllers/dist/types/TokenDetectionController.d.ts +index 220d78d..795b96e 100644 +--- a/node_modules/@metamask/assets-controllers/dist/types/TokenDetectionController.d.ts ++++ b/node_modules/@metamask/assets-controllers/dist/types/TokenDetectionController.d.ts +@@ -6,7 +6,7 @@ import { StaticIntervalPollingController } from '@metamask/polling-controller'; + import type { PreferencesControllerGetStateAction, PreferencesControllerStateChangeEvent } from '@metamask/preferences-controller'; + import type { AssetsContractController } from './AssetsContractController'; + import type { GetTokenListState, TokenListMap, TokenListStateChange } from './TokenListController'; +-import type { TokensControllerAddDetectedTokensAction, TokensControllerGetStateAction } from './TokensController'; ++import type { TokensControllerAddDetectedTokensAction, TokensControllerGetStateAction, TokensState } from './TokensController'; + /** + * Compare 2 given strings and return boolean + * eg: "foo" and "FOO" => true +@@ -54,11 +54,12 @@ export declare class TokenDetectionController extends StaticIntervalPollingContr + * @param options.getBalancesInSingleCall - Gets the balances of a list of tokens for the given address. + * @param options.trackMetaMetricsEvent - Sets options for MetaMetrics event tracking. + */ +- constructor({ selectedAddress, interval, disabled, getBalancesInSingleCall, trackMetaMetricsEvent, messenger, }: { ++ constructor({ selectedAddress, interval, disabled, getBalancesInSingleCall, getTokensState, trackMetaMetricsEvent, messenger, }: { + selectedAddress?: string; + interval?: number; + disabled?: boolean; + getBalancesInSingleCall: AssetsContractController['getBalancesInSingleCall']; ++ getTokensState: () => TokensState; + trackMetaMetricsEvent: (options: { + event: string; + category: string; +diff --git a/node_modules/@metamask/assets-controllers/dist/types/index.d.ts b/node_modules/@metamask/assets-controllers/dist/types/index.d.ts +index a71f4a7..df1ddc9 100644 +--- a/node_modules/@metamask/assets-controllers/dist/types/index.d.ts ++++ b/node_modules/@metamask/assets-controllers/dist/types/index.d.ts +@@ -3,7 +3,7 @@ export * from './AssetsContractController'; + export * from './CurrencyRateController'; + export * from './NftController'; + export * from './NftDetectionController'; +-export type { TokenBalancesControllerMessenger, TokenBalancesControllerActions, TokenBalancesControllerGetStateAction, TokenBalancesControllerEvents, TokenBalancesControllerStateChangeEvent, } from './TokenBalancesController'; ++export type { TokenBalancesControllerMessenger, TokenBalancesControllerActions, TokenBalancesControllerGetStateAction, TokenBalancesControllerEvents, TokenBalancesControllerStateChangeEvent, TokenBalancesControllerState } from './TokenBalancesController'; + export { TokenBalancesController } from './TokenBalancesController'; + export type { TokenDetectionControllerMessenger, TokenDetectionControllerActions, TokenDetectionControllerGetStateAction, TokenDetectionControllerEvents, TokenDetectionControllerStateChangeEvent, } from './TokenDetectionController'; + export { TokenDetectionController } from './TokenDetectionController'; diff --git a/patches/@metamask+controller-utils+8.0.4.patch b/patches/@metamask+controller-utils+8.0.4.patch deleted file mode 100644 index f934736eaa5..00000000000 --- a/patches/@metamask+controller-utils+8.0.4.patch +++ /dev/null @@ -1,158 +0,0 @@ -diff --git a/node_modules/@metamask/controller-utils/dist/constants.d.ts b/node_modules/@metamask/controller-utils/dist/constants.d.ts -index ac69412..b7fb5d5 100644 ---- a/node_modules/@metamask/controller-utils/dist/constants.d.ts -+++ b/node_modules/@metamask/controller-utils/dist/constants.d.ts -@@ -28,6 +28,7 @@ export declare const TESTNET_TICKER_SYMBOLS: { - GOERLI: string; - SEPOLIA: string; - LINEA_GOERLI: string; -+ LINEA_SEPOLIA: string; - }; - /** - * Map of all build-in Infura networks to their network, ticker and chain IDs. -@@ -61,6 +62,13 @@ export declare const BUILT_IN_NETWORKS: { - readonly blockExplorerUrl: "https://goerli.lineascan.build"; - }; - }; -+ readonly "linea-sepolia": { -+ readonly chainId: "0xe705"; -+ readonly ticker: typeof NetworksTicker["linea-sepolia"]; -+ readonly rpcPrefs: { -+ readonly blockExplorerUrl: "https://sepolia.lineascan.build"; -+ }; -+ }; - readonly "linea-mainnet": { - readonly chainId: "0xe708"; - readonly ticker: NetworksTicker.mainnet; -@@ -76,6 +84,7 @@ export declare const BUILT_IN_NETWORKS: { - }; - }; - export declare const OPENSEA_PROXY_URL = "https://proxy.metafi.codefi.network/opensea/v1/api/v2"; -+export declare const NFT_API_BASE_URL = "https://nft.api.cx.metamask.io"; - export declare const ORIGIN_METAMASK = "metamask"; - /** - * Approval request types for various operations. -diff --git a/node_modules/@metamask/controller-utils/dist/constants.js b/node_modules/@metamask/controller-utils/dist/constants.js -index 70c2076..39526e8 100644 ---- a/node_modules/@metamask/controller-utils/dist/constants.js -+++ b/node_modules/@metamask/controller-utils/dist/constants.js -@@ -38,6 +38,7 @@ exports.TESTNET_TICKER_SYMBOLS = { - GOERLI: 'GoerliETH', - SEPOLIA: 'SepoliaETH', - LINEA_GOERLI: 'LineaETH', -+ LINEA_SEPOLIA: 'LineaETH', - }; - /** - * Map of all build-in Infura networks to their network, ticker and chain IDs. -@@ -71,6 +72,13 @@ exports.BUILT_IN_NETWORKS = { - blockExplorerUrl: 'https://goerli.lineascan.build', - }, - }, -+ [types_1.NetworkType['linea-sepolia']]: { -+ chainId: types_1.ChainId['linea-sepolia'], -+ ticker: types_1.NetworksTicker['linea-sepolia'], -+ rpcPrefs: { -+ blockExplorerUrl: 'https://sepolia.lineascan.build', -+ }, -+ }, - [types_1.NetworkType['linea-mainnet']]: { - chainId: types_1.ChainId['linea-mainnet'], - ticker: types_1.NetworksTicker['linea-mainnet'], -@@ -87,6 +95,9 @@ exports.BUILT_IN_NETWORKS = { - }; - // APIs - exports.OPENSEA_PROXY_URL = 'https://proxy.metafi.codefi.network/opensea/v1/api/v2'; -+ -+exports.NFT_API_BASE_URL = 'https://nft.api.cx.metamask.io'; -+ - // Default origin for controllers - exports.ORIGIN_METAMASK = 'metamask'; - /** -@@ -120,6 +131,7 @@ exports.CHAIN_ID_TO_ETHERS_NETWORK_NAME_MAP = { - [types_1.ChainId.sepolia]: types_1.BuiltInNetworkName.Sepolia, - [types_1.ChainId.mainnet]: types_1.BuiltInNetworkName.Mainnet, - [types_1.ChainId['linea-goerli']]: types_1.BuiltInNetworkName.LineaGoerli, -+ [types_1.ChainId['linea-sepolia']]: types_1.BuiltInNetworkName.LineaSepolia, - [types_1.ChainId['linea-mainnet']]: types_1.BuiltInNetworkName.LineaMainnet, - [types_1.ChainId.aurora]: types_1.BuiltInNetworkName.Aurora, - }; -diff --git a/node_modules/@metamask/controller-utils/dist/types.d.ts b/node_modules/@metamask/controller-utils/dist/types.d.ts -index 35c711f..b53f0ac 100644 ---- a/node_modules/@metamask/controller-utils/dist/types.d.ts -+++ b/node_modules/@metamask/controller-utils/dist/types.d.ts -@@ -6,6 +6,7 @@ export declare const InfuraNetworkType: { - readonly goerli: "goerli"; - readonly sepolia: "sepolia"; - readonly 'linea-goerli': "linea-goerli"; -+ readonly 'linea-sepolia': "linea-sepolia"; - readonly 'linea-mainnet': "linea-mainnet"; - }; - export declare type InfuraNetworkType = (typeof InfuraNetworkType)[keyof typeof InfuraNetworkType]; -@@ -18,6 +19,7 @@ export declare const NetworkType: { - readonly goerli: "goerli"; - readonly sepolia: "sepolia"; - readonly 'linea-goerli': "linea-goerli"; -+ readonly 'linea-sepolia': "linea-sepolia"; - readonly 'linea-mainnet': "linea-mainnet"; - }; - export declare type NetworkType = (typeof NetworkType)[keyof typeof NetworkType]; -@@ -46,6 +48,7 @@ export declare enum BuiltInNetworkName { - Goerli = "goerli", - Sepolia = "sepolia", - LineaGoerli = "linea-goerli", -+ LineaSepolia = "linea-sepolia", - LineaMainnet = "linea-mainnet", - Aurora = "aurora" - } -@@ -60,6 +63,7 @@ export declare const ChainId: { - readonly sepolia: "0xaa36a7"; - readonly aurora: "0x4e454152"; - readonly "linea-goerli": "0xe704"; -+ readonly "linea-sepolia": "0xe705"; - readonly "linea-mainnet": "0xe708"; - }; - export declare type ChainId = (typeof ChainId)[keyof typeof ChainId]; -@@ -68,6 +72,7 @@ export declare enum NetworksTicker { - goerli = "GoerliETH", - sepolia = "SepoliaETH", - 'linea-goerli' = "LineaETH", -+ 'linea-sepolia' = "LineaETH", - 'linea-mainnet' = "ETH", - rpc = "" - } -diff --git a/node_modules/@metamask/controller-utils/dist/types.js b/node_modules/@metamask/controller-utils/dist/types.js -index c59368a..e49129e 100644 ---- a/node_modules/@metamask/controller-utils/dist/types.js -+++ b/node_modules/@metamask/controller-utils/dist/types.js -@@ -9,6 +9,7 @@ exports.InfuraNetworkType = { - goerli: 'goerli', - sepolia: 'sepolia', - 'linea-goerli': 'linea-goerli', -+ 'linea-sepolia': 'linea-sepolia', - 'linea-mainnet': 'linea-mainnet', - }; - /** -@@ -50,6 +51,7 @@ var BuiltInNetworkName; - BuiltInNetworkName["Goerli"] = "goerli"; - BuiltInNetworkName["Sepolia"] = "sepolia"; - BuiltInNetworkName["LineaGoerli"] = "linea-goerli"; -+ BuiltInNetworkName["LineaSepolia"] = "linea-sepolia"; - BuiltInNetworkName["LineaMainnet"] = "linea-mainnet"; - BuiltInNetworkName["Aurora"] = "aurora"; - })(BuiltInNetworkName = exports.BuiltInNetworkName || (exports.BuiltInNetworkName = {})); -@@ -64,6 +66,7 @@ exports.ChainId = { - [BuiltInNetworkName.Sepolia]: '0xaa36a7', - [BuiltInNetworkName.Aurora]: '0x4e454152', - [BuiltInNetworkName.LineaGoerli]: '0xe704', -+ [BuiltInNetworkName.LineaSepolia]: '0xe705', - [BuiltInNetworkName.LineaMainnet]: '0xe708', // toHex(59144) - }; - var NetworksTicker; -@@ -72,6 +75,7 @@ var NetworksTicker; - NetworksTicker["goerli"] = "GoerliETH"; - NetworksTicker["sepolia"] = "SepoliaETH"; - NetworksTicker["linea-goerli"] = "LineaETH"; -+ NetworksTicker["linea-sepolia"] = "LineaETH"; - NetworksTicker["linea-mainnet"] = "ETH"; - NetworksTicker["rpc"] = ""; - })(NetworksTicker = exports.NetworksTicker || (exports.NetworksTicker = {})); diff --git a/scripts/patch-assets-controllers.sh b/scripts/patch-assets-controllers.sh deleted file mode 100755 index 78036fab558..00000000000 --- a/scripts/patch-assets-controllers.sh +++ /dev/null @@ -1,80 +0,0 @@ -#!/bin/bash - -# ! IMPORTANT ! - Do not forget to give permission to this script: `chmod +x ./scripts/patch-assets-controllers.sh`` - -# Generates the patch for the @metamask/assets-controllers package -# given only the path to a local core repository. - -# Applies standardisation including: -# - Adding a comment to the top of the patch which is added to a `.patch.txt` file. -# - Removing all sourcemaps. -# - Removing the mocks directory. - -# Requires the assets-controllers package to have already been built -# in the core repository. - -set -e -set -o pipefail - -PACKAGE="@metamask/assets-controllers" -PACKAGE_DIR_MOBILE="node_modules/$PACKAGE" -DIST_DIR_MOBILE="$PACKAGE_DIR_MOBILE/dist" -PATCH_FILE="patches/@metamask+assets-controllers+*.patch" - - -COMMENT='+PATCH GENERATED FROM MetaMask/core branch: patch/mobile-assets-controllers-26\ -+This patch backports various assets controllers features from the main branch of MetaMask/core\ -+Steps to update patch:\ -+* Create a new core branch from: patch/mobile-assets-controllers-26\ -+* Run "yarn build" in the core monorepo\ -+* Run "yarn patch:assets " in the mobile repo\ -+* If you have changes also add them to the branch: patch/mobile-assets-controllers-26\ -+* Steps to update the assets-controllers version\ -+* Create a new core branch from the next assets-controllers version\ -+* Merge the branch patch/mobile-assets-controllers-26\ -+* Solve the conflicts and review changes accordingly the changelog\ -+* Run "yarn build" in the core monorepo\ -+* Run "yarn patch:assets " in the mobile repo\ -+* If you have changes also add them to the branch: patch/mobile-assets-controllers-26' - -# The number of lines of the `COMMENT` variable -COMMENT_LINE_COUNT=14 - -COMMENT_DIFF='diff --git a/node_modules/@metamask/assets-controllers/dist/.patch.txt b/node_modules/@metamask/assets-controllers/dist/.patch.txt\ -new file mode 100644\ -index 0000000..550de56\ ---- /dev/null\ -+++ b/node_modules/@metamask/assets-controllers/dist/.patch.txt\ -@@ -0,0 +1,'"$COMMENT_LINE_COUNT"' @@\ -'"$COMMENT" - -CORE_DIR="$1" - -if [ -z "$CORE_DIR" ] ; then - echo "Usage: yarn patch:assets " - echo "" - echo "Example: yarn patch:assets ../core" - exit 1 -fi - -DIST_DIR_CORE="$CORE_DIR/packages/assets-controllers/dist" - -rm -rf "$DIST_DIR_MOBILE" -cp -r "$DIST_DIR_CORE" "$PACKAGE_DIR_MOBILE" - -rm -rf "$DIST_DIR_MOBILE/mocks" - -yarn patch-package "$PACKAGE" - - -NEW_LINE=$'\n' - -# ShellCheck disabled as intentionally not using quotes as PATCH_FILE relies on globbing - -#shellcheck disable=SC2086 -sed -i.bak "1i\\$NEW_LINE$COMMENT_DIFF$NEW_LINE" $PATCH_FILE - -#shellcheck disable=SC2086 -rm $PATCH_FILE.bak - - diff --git a/yarn.lock b/yarn.lock index 9a8944599a0..e93a7db9e4b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3556,17 +3556,17 @@ "@metamask/utils" "^8.0.0" superstruct "^1.0.3" -"@metamask/accounts-controller@^11.0.0": - version "11.0.0" - resolved "https://registry.yarnpkg.com/@metamask/accounts-controller/-/accounts-controller-11.0.0.tgz#898cba99e0df0f7632af98a61d6d524ef7d75885" - integrity sha512-8/KGdLdxu7G90a+4w30RJaC6W4GqEg7O8LG9S6ZfzeofrlUe/uJl+PkqjU8W1KclXyPlK0XdnSW+2DQjw1jpLQ== +"@metamask/accounts-controller@^14.0.0": + version "14.0.0" + resolved "https://registry.yarnpkg.com/@metamask/accounts-controller/-/accounts-controller-14.0.0.tgz#aea6004b66ff02f30eea2d1ed77a9820c1f0a6d2" + integrity sha512-vI79c/Va8ziso7LQnF2du411AQUXAfO2JwhNxGVBo3EHSKPAX0v0WTz+GF/1sTUIIuCuDaOsemH1kBj5nA+rwg== dependencies: "@ethereumjs/util" "^8.1.0" - "@metamask/base-controller" "^4.1.1" - "@metamask/eth-snap-keyring" "^2.1.1" - "@metamask/keyring-api" "^3.0.0" - "@metamask/snaps-sdk" "^1.3.2" - "@metamask/snaps-utils" "^5.1.2" + "@metamask/base-controller" "^5.0.2" + "@metamask/eth-snap-keyring" "^4.0.0" + "@metamask/keyring-api" "^6.0.0" + "@metamask/snaps-sdk" "^4.0.1" + "@metamask/snaps-utils" "^7.1.0" "@metamask/utils" "^8.3.0" deepmerge "^4.2.2" ethereum-cryptography "^2.1.2" @@ -3593,16 +3593,6 @@ immer "^9.0.6" nanoid "^3.1.31" -"@metamask/approval-controller@^5.1.2", "@metamask/approval-controller@^5.1.3": - version "5.1.3" - resolved "https://registry.yarnpkg.com/@metamask/approval-controller/-/approval-controller-5.1.3.tgz#19e04b559df12cb078dcafabdb2f0aa8a5e73a45" - integrity sha512-RebVeTCrNePzXKTe+YcLlqWeKP5ADpWdIINOoP+IP8+AAWwzBJiHXXJ/4AxSBrIC4la+a0Xnohd+ou27bzfDDg== - dependencies: - "@metamask/base-controller" "^4.1.1" - "@metamask/rpc-errors" "^6.2.1" - "@metamask/utils" "^8.3.0" - nanoid "^3.1.31" - "@metamask/approval-controller@^6.0.2": version "6.0.2" resolved "https://registry.yarnpkg.com/@metamask/approval-controller/-/approval-controller-6.0.2.tgz#2bae3c293b73e8ecaf8cbba11fbc99c61adb4367" @@ -3613,10 +3603,10 @@ "@metamask/utils" "^8.3.0" nanoid "^3.1.31" -"@metamask/assets-controllers@^26.0.0": - version "26.0.0" - resolved "https://registry.yarnpkg.com/@metamask/assets-controllers/-/assets-controllers-26.0.0.tgz#09cf1ed9d42415c2674e45b17c64e0f1b685b8d7" - integrity sha512-ylb0PV2jkde7KZlOcSpNp2yY3K3ne+kaZva3pyZQoJgy5JtllCEJLx+x/kUCa8jerk6IOO4MYUBK/KWJIRdfog== +"@metamask/assets-controllers@^30.0.0": + version "30.0.0" + resolved "https://registry.yarnpkg.com/@metamask/assets-controllers/-/assets-controllers-30.0.0.tgz#f8c4094692f184a57f2587e0e71e06c349583e74" + integrity sha512-tHG/1UowHznr2vU6QzvSGGoPvlDi3OLFYSUXiMO789yFr57UoFkuoq/Joq2SNShYQzKFCrlqGxlqXJ90hWrOsA== dependencies: "@ethereumjs/util" "^8.1.0" "@ethersproject/address" "^5.7.0" @@ -3624,17 +3614,17 @@ "@ethersproject/contracts" "^5.7.0" "@ethersproject/providers" "^5.7.0" "@metamask/abi-utils" "^2.0.2" - "@metamask/accounts-controller" "^11.0.0" - "@metamask/approval-controller" "^5.1.3" - "@metamask/base-controller" "^4.1.1" + "@metamask/accounts-controller" "^14.0.0" + "@metamask/approval-controller" "^6.0.2" + "@metamask/base-controller" "^5.0.2" "@metamask/contract-metadata" "^2.4.0" - "@metamask/controller-utils" "^8.0.4" + "@metamask/controller-utils" "^10.0.0" "@metamask/eth-query" "^4.0.0" - "@metamask/keyring-controller" "^13.0.0" - "@metamask/metamask-eth-abis" "3.0.0" - "@metamask/network-controller" "^17.2.1" - "@metamask/polling-controller" "^5.0.1" - "@metamask/preferences-controller" "^8.0.0" + "@metamask/keyring-controller" "^16.0.0" + "@metamask/metamask-eth-abis" "^3.1.1" + "@metamask/network-controller" "^18.1.2" + "@metamask/polling-controller" "^6.0.2" + "@metamask/preferences-controller" "^11.0.0" "@metamask/rpc-errors" "^6.2.1" "@metamask/utils" "^8.3.0" "@types/bn.js" "^5.1.5" @@ -3655,7 +3645,7 @@ "@metamask/utils" "^8.1.0" immer "^9.0.6" -"@metamask/base-controller@^4.0.1", "@metamask/base-controller@^4.1.0", "@metamask/base-controller@^4.1.1": +"@metamask/base-controller@^4.0.1", "@metamask/base-controller@^4.1.1": version "4.1.1" resolved "https://registry.yarnpkg.com/@metamask/base-controller/-/base-controller-4.1.1.tgz#9b411adf4822de7382fe69d07bb6b3fc3e738923" integrity sha512-sJdsd/XlyOa0kRJ16qbM+xeQ8peV1yZcYumJmHCClPK09MkAlxq7EzsrahVZXUCFwcxtSucf244pbttnVqNthw== @@ -3934,18 +3924,18 @@ ethereum-cryptography "^2.1.2" randombytes "^2.1.0" -"@metamask/eth-snap-keyring@^2.1.1": - version "2.2.0" - resolved "https://registry.yarnpkg.com/@metamask/eth-snap-keyring/-/eth-snap-keyring-2.2.0.tgz#c1564df4af3d2ecfd9138ae8e765c0838d440f5f" - integrity sha512-L0WVgg5mh7D9nBp2NLru/qDv90wwwuig33SdTj817k3nJefVuCzxhSzvJe74CcQqS/nyt6cCNBbUcMJNIYOJgQ== +"@metamask/eth-snap-keyring@^4.0.0": + version "4.2.0" + resolved "https://registry.yarnpkg.com/@metamask/eth-snap-keyring/-/eth-snap-keyring-4.2.0.tgz#39864df9696b72978ab99ef4347f7dd5d1c057c4" + integrity sha512-FkkswrPX49GY9YfDhDVyG9yJ0OxtZE7EMTvHZ1Oey05JV5yCfdvngqrtFlngLSFfqNP9/3f8of2PAsw6sxfGXg== dependencies: "@ethereumjs/tx" "^4.2.0" "@metamask/eth-sig-util" "^7.0.1" - "@metamask/keyring-api" "^4.0.0" - "@metamask/snaps-controllers" "^5.0.1" - "@metamask/snaps-sdk" "^2.1.0" - "@metamask/snaps-utils" "^6.1.0" - "@metamask/utils" "^8.3.0" + "@metamask/keyring-api" "^6.2.1" + "@metamask/snaps-controllers" "^8.1.1" + "@metamask/snaps-sdk" "^4.2.0" + "@metamask/snaps-utils" "^7.4.0" + "@metamask/utils" "^8.4.0" "@types/uuid" "^9.0.1" superstruct "^1.0.3" uuid "^9.0.0" @@ -4056,7 +4046,7 @@ bn.js "^5.2.1" uuid "^8.3.2" -"@metamask/json-rpc-engine@^7.0.0", "@metamask/json-rpc-engine@^7.1.1", "@metamask/json-rpc-engine@^7.3.1", "@metamask/json-rpc-engine@^7.3.2", "@metamask/json-rpc-engine@^7.3.3": +"@metamask/json-rpc-engine@^7.0.0", "@metamask/json-rpc-engine@^7.1.1", "@metamask/json-rpc-engine@^7.3.2", "@metamask/json-rpc-engine@^7.3.3": version "7.3.3" resolved "https://registry.yarnpkg.com/@metamask/json-rpc-engine/-/json-rpc-engine-7.3.3.tgz#f2b30a2164558014bfcca45db10f5af291d989af" integrity sha512-dwZPq8wx9yV3IX2caLi9q9xZBw2XeIoYqdyihDDDpuHVCEiqadJLwqM3zy+uwf6F1QYQ65A8aOMQg1Uw7LMLNg== @@ -4095,59 +4085,17 @@ "@noble/hashes" "^1.3.2" "@scure/base" "^1.0.0" -"@metamask/keyring-api@^3.0.0": - version "3.0.0" - resolved "https://registry.yarnpkg.com/@metamask/keyring-api/-/keyring-api-3.0.0.tgz#66e6d9de01ba652f0f7959d04d8d4d0c6a3dd040" - integrity sha512-hvBH55P0ajhHOU8lkUFLCs/HdXJORDHzBT6BSVh7nxUmxf8gdDIYX9iG/+2PYWHo1qvUlnojzfROMS1/E6MQgQ== - dependencies: - "@metamask/providers" "^14.0.1" - "@metamask/snaps-sdk" "^1.3.2" - "@metamask/utils" "^8.1.0" - "@types/uuid" "^9.0.1" - superstruct "^1.0.3" - uuid "^9.0.0" - -"@metamask/keyring-api@^4.0.0": - version "4.0.0" - resolved "https://registry.yarnpkg.com/@metamask/keyring-api/-/keyring-api-4.0.0.tgz#5e9eba65d6db56c2a64d4eaae2ba26d0ded036e2" - integrity sha512-wkApdp5UOwmPW4SuX+bj9vu73hxNzzrFBnwvDA0HN7oIiCDSH/97o8C5LsZ7Hmn6YplMEwOl28AhuQgFjOR2+w== +"@metamask/keyring-api@^6.0.0", "@metamask/keyring-api@^6.2.1": + version "6.2.1" + resolved "https://registry.yarnpkg.com/@metamask/keyring-api/-/keyring-api-6.2.1.tgz#10e91b07c6afbf8c18d29169b4ec907adcdc8ccc" + integrity sha512-RT2P6RU48/CjZ8pmh8XDZN31APwByzC7l0GeZjuHVO9WKyYhvELYEBcvaID9R8BZ2HZCvHbn/hzj5IxTgDouVQ== dependencies: - "@metamask/providers" "^14.0.1" - "@metamask/snaps-sdk" "^1.3.2" - "@metamask/utils" "^8.1.0" - "@types/uuid" "^9.0.1" + "@metamask/snaps-sdk" "^4.2.0" + "@metamask/utils" "^8.4.0" + "@types/uuid" "^9.0.8" + bech32 "^2.0.0" superstruct "^1.0.3" - uuid "^9.0.0" - -"@metamask/keyring-api@^6.0.0": - version "6.0.0" - resolved "https://registry.yarnpkg.com/@metamask/keyring-api/-/keyring-api-6.0.0.tgz#c8f876ddc256106458a8041910038f9dbdb3b13b" - integrity sha512-yba04Q/l3RHK6xlYrcNQoH8482qsf4j/MDzb+3ti8nkmaDrYnFbgJ+hYO2DLhoBLLrJWcdSwYJ8WATzC7YL4bg== - dependencies: - "@metamask/snaps-sdk" "^4.0.0" - "@metamask/utils" "^8.3.0" - "@types/uuid" "^9.0.1" - superstruct "^1.0.3" - uuid "^9.0.0" - -"@metamask/keyring-controller@^13.0.0": - version "13.0.0" - resolved "https://registry.yarnpkg.com/@metamask/keyring-controller/-/keyring-controller-13.0.0.tgz#6552f95dc2c19003f1c5f4e8f48ac221d8a1c063" - integrity sha512-b8vvTqnsWi7xVpzGf7XDUVgX3xthQ1pUYWhoDlNhq6JLuocNgq9H1Rr3F5Vz0RtC2Caz2VnSYxecGHvGUlvlhQ== - dependencies: - "@ethereumjs/util" "^8.1.0" - "@keystonehq/metamask-airgapped-keyring" "^0.13.1" - "@metamask/base-controller" "^4.1.1" - "@metamask/browser-passworder" "^4.3.0" - "@metamask/eth-hd-keyring" "^7.0.1" - "@metamask/eth-sig-util" "^7.0.1" - "@metamask/eth-simple-keyring" "^6.0.1" - "@metamask/keyring-api" "^3.0.0" - "@metamask/message-manager" "^7.3.9" - "@metamask/utils" "^8.3.0" - async-mutex "^0.2.6" - ethereumjs-wallet "^1.0.1" - immer "^9.0.6" + uuid "^9.0.1" "@metamask/keyring-controller@^16.0.0": version "16.0.0" @@ -4177,19 +4125,6 @@ "@metamask/controller-utils" "^9.0.1" uuid "^8.3.2" -"@metamask/message-manager@^7.3.9": - version "7.3.9" - resolved "https://registry.yarnpkg.com/@metamask/message-manager/-/message-manager-7.3.9.tgz#4d416998bbdda30d80ebbb50b5efc7475b816ec9" - integrity sha512-B0+Qa1bPGMuVdBDaq8zcAKkRXWAt1CYAXW2NXzfO85a2ePFCUIrIhF9W8LflatXDXqesE5Y8Dij0sHGmsUfF8w== - dependencies: - "@metamask/base-controller" "^4.1.1" - "@metamask/controller-utils" "^8.0.4" - "@metamask/eth-sig-util" "^7.0.1" - "@metamask/utils" "^8.3.0" - "@types/uuid" "^8.3.0" - jsonschema "^1.2.4" - uuid "^8.3.2" - "@metamask/message-manager@^8.0.2": version "8.0.2" resolved "https://registry.yarnpkg.com/@metamask/message-manager/-/message-manager-8.0.2.tgz#84720f0fe9e0c02cc97b76f0bc8f3d5b0a25f731" @@ -4216,7 +4151,7 @@ "@noble/hashes" "^1.4.0" zod "^3.22.4" -"@metamask/metamask-eth-abis@3.0.0", "@metamask/metamask-eth-abis@3.1.1", "@metamask/metamask-eth-abis@^3.0.0", "@metamask/metamask-eth-abis@^3.1.1": +"@metamask/metamask-eth-abis@3.1.1", "@metamask/metamask-eth-abis@^3.0.0", "@metamask/metamask-eth-abis@^3.1.1": version "3.1.1" resolved "https://registry.yarnpkg.com/@metamask/metamask-eth-abis/-/metamask-eth-abis-3.1.1.tgz#3de904511115c488809ddee25c470332c03db531" integrity sha512-lRUyWN/GrIFQlT0wq/9gB+4wIV2i0N6yAQlJhfLCT6bVfK5GI5IUDxvCyLTDvxQxaLpNgtBFFzbuY1iVj3UWLA== @@ -4246,7 +4181,7 @@ json-rpc-engine "^6.1.0" uuid "^8.3.2" -"@metamask/network-controller@^17.0.0", "@metamask/network-controller@^17.1.0", "@metamask/network-controller@^17.2.1": +"@metamask/network-controller@^17.0.0", "@metamask/network-controller@^17.1.0": version "17.2.1" resolved "https://registry.yarnpkg.com/@metamask/network-controller/-/network-controller-17.2.1.tgz#55d846e9e6000f3264e9ac1cc9c5b1493bac335a" integrity sha512-+cWbnqJyuLO+a3c9Rmdr10onNXv03J2Knl+IAR8QztAczqegtXB0pwTYlclU+j73Rsi9XWrUxS6fMGK1Vb3r9g== @@ -4327,44 +4262,14 @@ "@metamask/safe-event-emitter" "^2.0.0" through2 "^2.0.3" -"@metamask/permission-controller@^7.1.0": - version "7.1.0" - resolved "https://registry.yarnpkg.com/@metamask/permission-controller/-/permission-controller-7.1.0.tgz#e6a2e6c66e8b1c4a46a59eac6fdbdc20d0d7d19d" - integrity sha512-CrE+TU1MQSMgQJ3PDV3KsDD+mhRr+KQ40/XNL/Vk3ShKHqOkCpZLskIm5cawcqgwkTSoRgRY4DYgipIr1ISgpw== - dependencies: - "@metamask/base-controller" "^4.0.1" - "@metamask/controller-utils" "^8.0.1" - "@metamask/json-rpc-engine" "^7.3.1" - "@metamask/rpc-errors" "^6.1.0" - "@metamask/utils" "^8.2.0" - "@types/deep-freeze-strict" "^1.1.0" - deep-freeze-strict "^1.1.1" - immer "^9.0.6" - nanoid "^3.1.31" - -"@metamask/permission-controller@^8.0.0": - version "8.0.0" - resolved "https://registry.yarnpkg.com/@metamask/permission-controller/-/permission-controller-8.0.0.tgz#2f358e9793cab5f047cb536906b6b0a71c93d107" - integrity sha512-VwrkxKnvUSrpQeqljC/okrJG47tuLKkNrfmaj1SJ9S6/TUQjeRpsE0abKRt6pprTCbDpzJdyspexZq2aWykGLQ== - dependencies: - "@metamask/base-controller" "^4.1.1" - "@metamask/controller-utils" "^8.0.2" - "@metamask/json-rpc-engine" "^7.3.2" - "@metamask/rpc-errors" "^6.1.0" - "@metamask/utils" "^8.3.0" - "@types/deep-freeze-strict" "^1.1.0" - deep-freeze-strict "^1.1.1" - immer "^9.0.6" - nanoid "^3.1.31" - "@metamask/permission-controller@^9.0.0", "@metamask/permission-controller@^9.0.2": - version "9.0.2" - resolved "https://registry.yarnpkg.com/@metamask/permission-controller/-/permission-controller-9.0.2.tgz#93505974d037a7227da3efff5cac4ec2d1d068a2" - integrity sha512-4EV39Y8Sg88kQiMZ5eAYW5rOkPFb23FzhAVSv0bwOdOEFBJc/tDel8SmX68XQCrTwOgkUmatiUpNDj22r0ujrA== + version "9.1.1" + resolved "https://registry.yarnpkg.com/@metamask/permission-controller/-/permission-controller-9.1.1.tgz#de8c15438afa4ef65e419c20f358799924fc3f2c" + integrity sha512-h4EakReO5JFDZBIAjXXOiwaMGqrQvNp6/6kQfDYREvT+tIpjGD5JUaqgwBblLkPCLeip57hIqxeobPlgmCfATA== dependencies: - "@metamask/base-controller" "^5.0.1" - "@metamask/controller-utils" "^9.0.1" - "@metamask/json-rpc-engine" "^8.0.1" + "@metamask/base-controller" "^5.0.2" + "@metamask/controller-utils" "^10.0.0" + "@metamask/json-rpc-engine" "^8.0.2" "@metamask/rpc-errors" "^6.2.1" "@metamask/utils" "^8.3.0" "@types/deep-freeze-strict" "^1.1.0" @@ -4372,17 +4277,6 @@ immer "^9.0.6" nanoid "^3.1.31" -"@metamask/phishing-controller@^8.0.2": - version "8.0.2" - resolved "https://registry.yarnpkg.com/@metamask/phishing-controller/-/phishing-controller-8.0.2.tgz#612d2d2d0d5e8746289fda036b0382a63ea82ffb" - integrity sha512-aRnpv+AtjqffT7hnwF1XZahWs8K99dOd8DcAAaVJyWsdt0cT3o6ryZXHMcFTUGP8Fl88LmkLm1970zfUO8AxFg== - dependencies: - "@metamask/base-controller" "^4.1.1" - "@metamask/controller-utils" "^8.0.2" - "@types/punycode" "^2.1.0" - eth-phishing-detect "^1.2.0" - punycode "^2.1.1" - "@metamask/phishing-controller@^9.0.0", "@metamask/phishing-controller@^9.0.1": version "9.0.2" resolved "https://registry.yarnpkg.com/@metamask/phishing-controller/-/phishing-controller-9.0.2.tgz#d140b6a8a05947c59b04bf161a0d9055e6b711b2" @@ -4407,19 +4301,6 @@ fast-json-stable-stringify "^2.1.0" uuid "^8.3.2" -"@metamask/polling-controller@^5.0.1": - version "5.0.1" - resolved "https://registry.yarnpkg.com/@metamask/polling-controller/-/polling-controller-5.0.1.tgz#e0468ce9b7aaf0223099004ae869e77431b7f585" - integrity sha512-7mxco9i7SOW3gdXSAC9ZkhylIhCPpr4srdLd2Vpe/XKqYlJxX5g/qWmVuSDueNCwa7qQ+2uAT8D4Cf7KJdqANA== - dependencies: - "@metamask/base-controller" "^4.1.1" - "@metamask/controller-utils" "^8.0.4" - "@metamask/network-controller" "^17.2.1" - "@metamask/utils" "^8.3.0" - "@types/uuid" "^8.3.0" - fast-json-stable-stringify "^2.1.0" - uuid "^8.3.2" - "@metamask/polling-controller@^6.0.1", "@metamask/polling-controller@^6.0.2": version "6.0.2" resolved "https://registry.yarnpkg.com/@metamask/polling-controller/-/polling-controller-6.0.2.tgz#dbe3c7d6610729db0749d37ce0eebf846894bd0e" @@ -4464,14 +4345,6 @@ "@metamask/base-controller" "^5.0.2" "@metamask/controller-utils" "^9.1.0" -"@metamask/preferences-controller@^8.0.0": - version "8.0.0" - resolved "https://registry.yarnpkg.com/@metamask/preferences-controller/-/preferences-controller-8.0.0.tgz#097b1f83c17b56d06a3aee6ceeb55bbb8e93f04f" - integrity sha512-N3SuZ9DwHGnN6Xx58j7vkPLPPIIgEYoPm2RgMzSPS5fnJ1Pyrv7Qql/PBc86Ncz0AZUTJLhewGF1rCQJluZXnQ== - dependencies: - "@metamask/base-controller" "^4.1.1" - "@metamask/controller-utils" "^8.0.4" - "@metamask/providers@^13.1.0": version "13.1.0" resolved "https://registry.yarnpkg.com/@metamask/providers/-/providers-13.1.0.tgz#c5aef8e7073e097e6693cffc5f463b0632e1f1fd" @@ -4489,24 +4362,6 @@ json-rpc-middleware-stream "^4.2.1" webextension-polyfill "^0.10.0" -"@metamask/providers@^14.0.1", "@metamask/providers@^14.0.2": - version "14.0.2" - resolved "https://registry.yarnpkg.com/@metamask/providers/-/providers-14.0.2.tgz#683c43ed1f58075b8238b85e7c585ecefe484f0b" - integrity sha512-6KuCLQVzE/8IA1r8LkTo0FbG4fgm7ryjzleda0lMsz5XMxinNGuXAoh7Y08bX5OHVpDEjkHREPhuLw4dFK9wIQ== - dependencies: - "@metamask/json-rpc-engine" "^7.1.1" - "@metamask/object-multiplex" "^2.0.0" - "@metamask/rpc-errors" "^6.0.0" - "@metamask/safe-event-emitter" "^3.0.0" - "@metamask/utils" "^8.1.0" - detect-browser "^5.2.0" - extension-port-stream "^3.0.0" - fast-deep-equal "^3.1.3" - is-stream "^2.0.0" - json-rpc-middleware-stream "^5.0.1" - readable-stream "^3.6.2" - webextension-polyfill "^0.10.0" - "@metamask/providers@^16.0.0": version "16.1.0" resolved "https://registry.yarnpkg.com/@metamask/providers/-/providers-16.1.0.tgz#7da593d17c541580fa3beab8d9d8a9b9ce19ea07" @@ -4580,7 +4435,7 @@ resolved "https://registry.yarnpkg.com/@metamask/react-native-splash-screen/-/react-native-splash-screen-3.2.0.tgz#06a6547c143b088e47af40eacea9ac6657ac937f" integrity sha512-V8Cn0MXe9jdaUli/DK3PoJ71tx7k3IW2v2slqflvNstvHiO3MpCtdylsYIyu+tiPwI2JiyLRzLK8s02/3jxk6g== -"@metamask/rpc-errors@^6.0.0", "@metamask/rpc-errors@^6.1.0", "@metamask/rpc-errors@^6.2.1": +"@metamask/rpc-errors@^6.0.0", "@metamask/rpc-errors@^6.2.1": version "6.2.1" resolved "https://registry.yarnpkg.com/@metamask/rpc-errors/-/rpc-errors-6.2.1.tgz#f5daf429ededa7cb83069dc621bd5738fe2a1d80" integrity sha512-VTgWkjWLzb0nupkFl1duQi9Mk8TGT9rsdnQg6DeRrYEFxtFOh0IF8nAwxM/4GWqDl6uIB06lqUBgUrAVWl62Bw== @@ -4657,36 +4512,7 @@ fast-json-patch "^3.1.0" lodash "^4.17.21" -"@metamask/snaps-controllers@^5.0.1": - version "5.0.1" - resolved "https://registry.yarnpkg.com/@metamask/snaps-controllers/-/snaps-controllers-5.0.1.tgz#89d60011dbd5f2686918796c6cbcc73307cf40a5" - integrity sha512-Ian2Ky6YSoFHFdSUZ3TqZIHXvW09bV2OhgrQlGRslxnNQDSYhwsQ0O5kOzcuVQ1EvaLwZu3zvaPHpxJGLt20pA== - dependencies: - "@metamask/approval-controller" "^5.1.2" - "@metamask/base-controller" "^4.1.0" - "@metamask/json-rpc-engine" "^7.3.2" - "@metamask/object-multiplex" "^2.0.0" - "@metamask/permission-controller" "^8.0.0" - "@metamask/phishing-controller" "^8.0.2" - "@metamask/post-message-stream" "^8.0.0" - "@metamask/rpc-errors" "^6.1.0" - "@metamask/snaps-registry" "^3.0.0" - "@metamask/snaps-rpc-methods" "^6.0.0" - "@metamask/snaps-sdk" "^2.1.0" - "@metamask/snaps-utils" "^6.1.0" - "@metamask/utils" "^8.3.0" - "@xstate/fsm" "^2.0.0" - browserify-zlib "^0.2.0" - concat-stream "^2.0.0" - get-npm-tarball-url "^2.0.3" - immer "^9.0.6" - json-rpc-middleware-stream "^5.0.0" - nanoid "^3.1.31" - readable-stream "^3.6.2" - readable-web-to-node-stream "^3.0.2" - tar-stream "^3.1.7" - -"@metamask/snaps-controllers@^8.3.1": +"@metamask/snaps-controllers@^8.1.1", "@metamask/snaps-controllers@^8.3.1": version "8.3.1" resolved "https://registry.yarnpkg.com/@metamask/snaps-controllers/-/snaps-controllers-8.3.1.tgz#a509a020aa4a2eac88ecc6ec84c6bc488282f143" integrity sha512-kGyywksj7VyEuQXRKdFZBSAcTYPjr22J21FLhIBiiSlBI3lbHEqb/hr/q8b+m27iA1JGtTrvJL1JMpRFGQAOEA== @@ -4716,7 +4542,7 @@ readable-web-to-node-stream "^3.0.2" tar-stream "^3.1.7" -"@metamask/snaps-registry@^3.0.0", "@metamask/snaps-registry@^3.1.0": +"@metamask/snaps-registry@^3.1.0": version "3.1.0" resolved "https://registry.yarnpkg.com/@metamask/snaps-registry/-/snaps-registry-3.1.0.tgz#05635a09971f1e106deef73ef3181f17005b1750" integrity sha512-72fQIAxCFSQ/25c0VgPj/XIL8K6Xm8nRuHYayhLmsSgRbHlNXzwVhMieK3yztBqMFD5Hi+9gKsl0HkMMORoqzg== @@ -4726,20 +4552,6 @@ "@noble/hashes" "^1.3.2" superstruct "^1.0.3" -"@metamask/snaps-rpc-methods@^6.0.0": - version "6.0.0" - resolved "https://registry.yarnpkg.com/@metamask/snaps-rpc-methods/-/snaps-rpc-methods-6.0.0.tgz#ba51260f5755ee0b2afa73bdb70f2dd4ced820bb" - integrity sha512-jwr8Uordq2FsRzglwWg4H0qsGu5BQdnSY3iCZbiQzR87fUkLyJrWDIw+ATb7xO+0Xk8eIsxsvrlYLFEUI+UouQ== - dependencies: - "@metamask/key-tree" "^9.0.0" - "@metamask/permission-controller" "^8.0.0" - "@metamask/rpc-errors" "^6.1.0" - "@metamask/snaps-sdk" "^2.0.0" - "@metamask/snaps-utils" "^6.0.0" - "@metamask/utils" "^8.3.0" - "@noble/hashes" "^1.3.1" - superstruct "^1.0.3" - "@metamask/snaps-rpc-methods@^9.0.0", "@metamask/snaps-rpc-methods@^9.1.2": version "9.1.2" resolved "https://registry.yarnpkg.com/@metamask/snaps-rpc-methods/-/snaps-rpc-methods-9.1.2.tgz#fda8a6f8fcc4fca50b1ed71fb8c9dc88a9f9c3d8" @@ -4754,30 +4566,6 @@ "@noble/hashes" "^1.3.1" superstruct "^1.0.3" -"@metamask/snaps-sdk@^1.3.2", "@metamask/snaps-sdk@^1.4.0": - version "1.4.0" - resolved "https://registry.yarnpkg.com/@metamask/snaps-sdk/-/snaps-sdk-1.4.0.tgz#a433593e540811291daf6419bdac46f1f8b72e47" - integrity sha512-wiuFn1i51nvYMu80xTqUMHBome9yY9V5N5vGRvuhA+VB5EOp7cWGTjJx4XB7H4RZt5Iwczd/lcGiMvLRBrLx2g== - dependencies: - "@metamask/key-tree" "^9.0.0" - "@metamask/providers" "^14.0.2" - "@metamask/rpc-errors" "^6.1.0" - "@metamask/utils" "^8.3.0" - is-svg "^4.4.0" - superstruct "^1.0.3" - -"@metamask/snaps-sdk@^2.0.0", "@metamask/snaps-sdk@^2.1.0": - version "2.1.0" - resolved "https://registry.yarnpkg.com/@metamask/snaps-sdk/-/snaps-sdk-2.1.0.tgz#0a8a621731841e9d641ca687ab0f8e75ef94d261" - integrity sha512-np65mEcck5Ald9Phf65ItmIz1CExi1a/wZc/6H+WLyyPwkh9R+b22CQJjpr3pFeF+JY/etulM/vCECw5Wwux3Q== - dependencies: - "@metamask/key-tree" "^9.0.0" - "@metamask/providers" "^14.0.2" - "@metamask/rpc-errors" "^6.1.0" - "@metamask/utils" "^8.3.0" - fast-xml-parser "^4.3.4" - superstruct "^1.0.3" - "@metamask/snaps-sdk@^3.1.1": version "3.2.0" resolved "https://registry.yarnpkg.com/@metamask/snaps-sdk/-/snaps-sdk-3.2.0.tgz#66d60869697a479a3484adc9532d82c3b568fc19" @@ -4790,7 +4578,7 @@ fast-xml-parser "^4.3.4" superstruct "^1.0.3" -"@metamask/snaps-sdk@^4.0.0", "@metamask/snaps-sdk@^4.2.0", "@metamask/snaps-sdk@^4.4.1": +"@metamask/snaps-sdk@^4.0.1", "@metamask/snaps-sdk@^4.2.0", "@metamask/snaps-sdk@^4.4.1": version "4.4.1" resolved "https://registry.yarnpkg.com/@metamask/snaps-sdk/-/snaps-sdk-4.4.1.tgz#90603a6c83eeb27334e7192a77e7abd6a01d1f53" integrity sha512-SNtkyIOYdaadFKPSpnGfNu7dXHiTXogHusQdmIHkqidWQaFTIEnKuViePTPgBCdx17/nwu/ZBEhq0AlugRsZ6w== @@ -4802,62 +4590,7 @@ fast-xml-parser "^4.3.4" superstruct "^1.0.3" -"@metamask/snaps-utils@^5.1.2": - version "5.2.0" - resolved "https://registry.yarnpkg.com/@metamask/snaps-utils/-/snaps-utils-5.2.0.tgz#ff43b97ff176846230d8bdedb1769b269effc4d8" - integrity sha512-jUtt62bMWmTUg2s3pWe6+rG110s8nSM2VQIV05fAbhITfSU8Quz3N7ch/rQulAgpP24D9pn+2vTzTXTeaEZXgQ== - dependencies: - "@babel/core" "^7.23.2" - "@babel/types" "^7.23.0" - "@metamask/base-controller" "^4.1.0" - "@metamask/key-tree" "^9.0.0" - "@metamask/permission-controller" "^7.1.0" - "@metamask/rpc-errors" "^6.1.0" - "@metamask/slip44" "^3.1.0" - "@metamask/snaps-registry" "^3.0.0" - "@metamask/snaps-sdk" "^1.4.0" - "@metamask/utils" "^8.3.0" - "@noble/hashes" "^1.3.1" - "@scure/base" "^1.1.1" - chalk "^4.1.2" - cron-parser "^4.5.0" - fast-deep-equal "^3.1.3" - fast-json-stable-stringify "^2.1.0" - is-svg "^4.4.0" - rfdc "^1.3.0" - semver "^7.5.4" - ses "^1.1.0" - superstruct "^1.0.3" - validate-npm-package-name "^5.0.0" - -"@metamask/snaps-utils@^6.0.0", "@metamask/snaps-utils@^6.1.0": - version "6.1.0" - resolved "https://registry.yarnpkg.com/@metamask/snaps-utils/-/snaps-utils-6.1.0.tgz#8350e4d69c57902f9ca5caa175421994e25af79a" - integrity sha512-N8aeqN2DGcqEdb90q1ps3gHLOG7X5M9/1m6Fi/F7CBrRxQGXXL2aAZotRXg3CJzu5bChFimHwiDe8dLrjcidtw== - dependencies: - "@babel/core" "^7.23.2" - "@babel/types" "^7.23.0" - "@metamask/base-controller" "^4.1.0" - "@metamask/key-tree" "^9.0.0" - "@metamask/permission-controller" "^8.0.0" - "@metamask/rpc-errors" "^6.1.0" - "@metamask/slip44" "^3.1.0" - "@metamask/snaps-registry" "^3.0.0" - "@metamask/snaps-sdk" "^2.1.0" - "@metamask/utils" "^8.3.0" - "@noble/hashes" "^1.3.1" - "@scure/base" "^1.1.1" - chalk "^4.1.2" - cron-parser "^4.5.0" - fast-deep-equal "^3.1.3" - fast-json-stable-stringify "^2.1.0" - rfdc "^1.3.0" - semver "^7.5.4" - ses "^1.1.0" - superstruct "^1.0.3" - validate-npm-package-name "^5.0.0" - -"@metamask/snaps-utils@^7.4.0", "@metamask/snaps-utils@^7.4.1": +"@metamask/snaps-utils@^7.1.0", "@metamask/snaps-utils@^7.4.0", "@metamask/snaps-utils@^7.4.1": version "7.4.1" resolved "https://registry.yarnpkg.com/@metamask/snaps-utils/-/snaps-utils-7.4.1.tgz#54a2b40ba30cc05a0862f4662e5cd6ef5beba42e" integrity sha512-IPoZTh90Bg4LJJCmkRig1QIyXOgdziuZqdx3c521gHaKpMlcOFl1fvII17X9yVF9SUtTSDoj1R4//4e5rnLZnw== @@ -5007,10 +4740,10 @@ semver "^7.3.8" superstruct "^1.0.3" -"@metamask/utils@^8.0.0", "@metamask/utils@^8.1.0", "@metamask/utils@^8.2.0", "@metamask/utils@^8.3.0": - version "8.3.0" - resolved "https://registry.yarnpkg.com/@metamask/utils/-/utils-8.3.0.tgz#a20de447aeb9ffb75924d822a186a597033984b6" - integrity sha512-WFVcMPEkKKRCJ8DDkZUTVbLlpwgRn98F4VM/WzN89HM8PmHMnCyk/oG0AmK/seOxtik7uC7Bbi2YBC5Z5XB2zw== +"@metamask/utils@^8.0.0", "@metamask/utils@^8.1.0", "@metamask/utils@^8.2.0", "@metamask/utils@^8.3.0", "@metamask/utils@^8.4.0": + version "8.4.0" + resolved "https://registry.yarnpkg.com/@metamask/utils/-/utils-8.4.0.tgz#f44812c96467a4e1b70b2edff6ee89a9caa4e354" + integrity sha512-dbIc3C7alOe0agCuBHM1h71UaEaEqOk2W8rAtEn8QGz4haH2Qq7MoK6i7v2guzvkJVVh79c+QCzIqphC3KvrJg== dependencies: "@ethereumjs/tx" "^4.2.0" "@noble/hashes" "^1.3.1" @@ -5020,6 +4753,7 @@ pony-cause "^2.1.10" semver "^7.5.4" superstruct "^1.0.3" + uuid "^9.0.1" "@ngraveio/bc-ur@^1.1.5", "@ngraveio/bc-ur@^1.1.6": version "1.1.6" @@ -9306,7 +9040,7 @@ resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-9.0.2.tgz#ede1d1b1e451548d44919dc226253e32a6952c4b" integrity sha512-kNnC1GFBLuhImSnV7w4njQkUiJi0ZXUycu1rUaouPqiKlXkh77JKgdRnTAp1x5eBwcIwbtI+3otwzuIDEuDoxQ== -"@types/uuid@^9.0.1": +"@types/uuid@^9.0.1", "@types/uuid@^9.0.8": version "9.0.8" resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-9.0.8.tgz#7545ba4fc3c003d6c756f651f3bf163d8f0f29ba" integrity sha512-jg+97EGIcY9AGHJJRaaPVgetKDsrTgbRjQ5Msgjh/DQKEFl0DtyRr/VCOyD1T2R1MNeWPK/u7JoGhlDZnKBAfA== @@ -12270,6 +12004,11 @@ bech32@1.1.4: resolved "https://registry.yarnpkg.com/bech32/-/bech32-1.1.4.tgz#e38c9f37bf179b8eb16ae3a772b40c356d4832e9" integrity sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ== +bech32@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/bech32/-/bech32-2.0.0.tgz#078d3686535075c8c79709f054b1b226a133b355" + integrity sha512-LcknSilhIGatDAsY1ak2I8VtGaHNhgMSYVxFrGLXv+xLHytaKZKcaUJJUE7qmBr7h33o5YQwP55pMI0xmkpJwg== + before-after-hook@^2.2.0: version "2.2.3" resolved "https://registry.yarnpkg.com/before-after-hook/-/before-after-hook-2.2.3.tgz#c51e809c81a4e354084422b9b26bad88249c517c" @@ -16689,7 +16428,7 @@ fast-url-parser@1.1.3: dependencies: punycode "^1.3.2" -fast-xml-parser@^4.0.12, fast-xml-parser@^4.1.3, fast-xml-parser@^4.3.4: +fast-xml-parser@^4.0.12, fast-xml-parser@^4.3.4: version "4.3.5" resolved "https://registry.yarnpkg.com/fast-xml-parser/-/fast-xml-parser-4.3.5.tgz#e2f2a2ae8377e9c3dc321b151e58f420ca7e5ccc" integrity sha512-sWvP1Pl8H03B8oFJpFR3HE31HUfwtX7Rlf9BNsvdpujD4n7WMhfmu8h9wOV2u+c1k0ZilTADhPqypzx2J690ZQ== @@ -18771,13 +18510,6 @@ is-subset@^0.1.1: resolved "https://registry.yarnpkg.com/is-subset/-/is-subset-0.1.1.tgz#8a59117d932de1de00f245fcdd39ce43f1e939a6" integrity sha1-ilkRfZMt4d4A8kX83TnOQ/HpOaY= -is-svg@^4.4.0: - version "4.4.0" - resolved "https://registry.yarnpkg.com/is-svg/-/is-svg-4.4.0.tgz#34db20a38146be5f2b3060154da33d11e6f74b7c" - integrity sha512-v+AgVwiK5DsGtT9ng+m4mClp6zDAmwrW8nZi6Gg15qzvBnRWWdfWA1TGaXyCDnWq5g5asofIgMVl3PjKxvk1ug== - dependencies: - fast-xml-parser "^4.1.3" - is-symbol@^1.0.2, is-symbol@^1.0.3: version "1.0.4" resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.4.tgz#a6dac93b635b063ca6872236de88910a57af139c" @@ -19762,16 +19494,6 @@ json-rpc-middleware-stream@^4.2.1: json-rpc-engine "^6.1.0" readable-stream "^2.3.3" -json-rpc-middleware-stream@^5.0.0, json-rpc-middleware-stream@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/json-rpc-middleware-stream/-/json-rpc-middleware-stream-5.0.1.tgz#9a5984b4dfe6ccf4f51c648e9327dbe3abf88860" - integrity sha512-PMrzifccjdilqU0xftUkusJq0J9O73q66YdVduEmu6vkiTh3V1akliYJGWBAbhg+vhFPC8btUSANa5FNo7a6bg== - dependencies: - "@metamask/json-rpc-engine" "^7.1.1" - "@metamask/safe-event-emitter" "^3.0.0" - "@metamask/utils" "^8.1.0" - readable-stream "^3.6.2" - json-rpc-random-id@^1.0.0, json-rpc-random-id@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/json-rpc-random-id/-/json-rpc-random-id-1.0.1.tgz#ba49d96aded1444dbb8da3d203748acbbcdec8c8"