diff --git a/.eslintrc b/.eslintrc index 20a2a7a00..4fa7c2d7f 100644 --- a/.eslintrc +++ b/.eslintrc @@ -148,7 +148,7 @@ "space-in-parens": [1, "never"], "space-infix-ops": 2, "space-unary-ops": [2, { "words": true, "nonwords": false }], - "spaced-comment": [2, "always", { "markers": ["global", "globals", "eslint", "eslint-disable", "*package", "!", ","] }], + "spaced-comment": [2, "always", { "markers": ["global", "globals", "eslint", "eslint-disable", "*package", "!", ","], "exceptions": ["=", "-"] } ], "strict": 0, "template-curly-spacing": [2, "never"], "use-isnan": 2, diff --git a/.gitignore b/.gitignore index 2bf38cad4..f2a678777 100644 --- a/.gitignore +++ b/.gitignore @@ -6,7 +6,9 @@ app/bower_components test/bower_components package +# IDEs .idea +.vscode temp .tmp diff --git a/CHANGELOG.md b/CHANGELOG.md index 75ba7670f..40d77bc9e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,11 +2,15 @@ ## Current Master -- MetaMask will no longer allow nonces to be specified by the dapp -- Add ability for internationalization. +## 4.3.0 Wed Mar 21 2018 + +- (beta) Add internationalization support! Includes translations for 13 (!!) new languages: French, Spanish, Italian, German, Dutch, Portuguese, Japanese, Korean, Vietnamese, Mandarin, Hindi, Tagalog, and Russian! Select "Try Beta" in the menu to take them for a spin. Read more about the community effort [here](https://medium.com/gitcoin/metamask-internationalizes-via-gitcoin-bf1390c0301c) +- No longer uses nonces specified by the dapp - Will now throw an error if the `to` field in txParams is not valid. - Will strip null values from the `to` field. -- Fix flashing to Log in screen after logging in or restoring from seed phrase. +- (beta) No longer shows token confirmation screen when performing a non-send +- (beta) Fixes bug where tx data was nullified when repricing a tx +- Fix flashing Login screen after logging in or restoring from seed phrase. - Increase tap areas for menu buttons on mobile - Change all fonts in new-ui onboarding to Roboto, size 400 - Add a welcome screen to new-ui onboarding flow diff --git a/README.md b/README.md index 278357c23..a3bf27709 100644 --- a/README.md +++ b/README.md @@ -76,5 +76,3 @@ To write tests that will be run in the browser using QUnit, add your test files - [How to generate a visualization of this repository's development](./docs/development-visualization.md) [1]: http://www.nomnoml.com/#view/%5B%3Cactor%3Euser%5D%0A%0A%5Bmetamask-ui%7C%0A%20%20%20%5Btools%7C%0A%20%20%20%20%20react%0A%20%20%20%20%20redux%0A%20%20%20%20%20thunk%0A%20%20%20%20%20ethUtils%0A%20%20%20%20%20jazzicon%0A%20%20%20%5D%0A%20%20%20%5Bcomponents%7C%0A%20%20%20%20%20app%0A%20%20%20%20%20account-detail%0A%20%20%20%20%20accounts%0A%20%20%20%20%20locked-screen%0A%20%20%20%20%20restore-vault%0A%20%20%20%20%20identicon%0A%20%20%20%20%20config%0A%20%20%20%20%20info%0A%20%20%20%5D%0A%20%20%20%5Breducers%7C%0A%20%20%20%20%20app%0A%20%20%20%20%20metamask%0A%20%20%20%20%20identities%0A%20%20%20%5D%0A%20%20%20%5Bactions%7C%0A%20%20%20%20%20%5BaccountManager%5D%0A%20%20%20%5D%0A%20%20%20%5Bcomponents%5D%3A-%3E%5Bactions%5D%0A%20%20%20%5Bactions%5D%3A-%3E%5Breducers%5D%0A%20%20%20%5Breducers%5D%3A-%3E%5Bcomponents%5D%0A%5D%0A%0A%5Bweb%20dapp%7C%0A%20%20%5Bui%20code%5D%0A%20%20%5Bweb3%5D%0A%20%20%5Bmetamask-inpage%5D%0A%20%20%0A%20%20%5B%3Cactor%3Eui%20developer%5D%0A%20%20%5Bui%20developer%5D-%3E%5Bui%20code%5D%0A%20%20%5Bui%20code%5D%3C-%3E%5Bweb3%5D%0A%20%20%5Bweb3%5D%3C-%3E%5Bmetamask-inpage%5D%0A%5D%0A%0A%5Bmetamask-background%7C%0A%20%20%5Bprovider-engine%5D%0A%20%20%5Bhooked%20wallet%20subprovider%5D%0A%20%20%5Bid%20store%5D%0A%20%20%0A%20%20%5Bprovider-engine%5D%3C-%3E%5Bhooked%20wallet%20subprovider%5D%0A%20%20%5Bhooked%20wallet%20subprovider%5D%3C-%3E%5Bid%20store%5D%0A%20%20%5Bconfig%20manager%7C%0A%20%20%20%20%5Brpc%20configuration%5D%0A%20%20%20%20%5Bencrypted%20keys%5D%0A%20%20%20%20%5Bwallet%20nicknames%5D%0A%20%20%5D%0A%20%20%0A%20%20%5Bprovider-engine%5D%3C-%5Bconfig%20manager%5D%0A%20%20%5Bid%20store%5D%3C-%3E%5Bconfig%20manager%5D%0A%5D%0A%0A%5Buser%5D%3C-%3E%5Bmetamask-ui%5D%0A%0A%5Buser%5D%3C%3A--%3A%3E%5Bweb%20dapp%5D%0A%0A%5Bmetamask-contentscript%7C%0A%20%20%5Bplugin%20restart%20detector%5D%0A%20%20%5Brpc%20passthrough%5D%0A%5D%0A%0A%5Brpc%20%7C%0A%20%20%5Bethereum%20blockchain%20%7C%0A%20%20%20%20%5Bcontracts%5D%0A%20%20%20%20%5Baccounts%5D%0A%20%20%5D%0A%5D%0A%0A%5Bweb%20dapp%5D%3C%3A--%3A%3E%5Bmetamask-contentscript%5D%0A%5Bmetamask-contentscript%5D%3C-%3E%5Bmetamask-background%5D%0A%5Bmetamask-background%5D%3C-%3E%5Bmetamask-ui%5D%0A%5Bmetamask-background%5D%3C-%3E%5Brpc%5D%0A - - diff --git a/app/_locales/de/messages.json b/app/_locales/de/messages.json new file mode 100644 index 000000000..0bdce516c --- /dev/null +++ b/app/_locales/de/messages.json @@ -0,0 +1,873 @@ +{ + "accept": { + "message": "Annehmen" + }, + "account": { + "message": "Account" + }, + "accountDetails": { + "message": "Accountdetails" + }, + "accountName": { + "message": "Accountname" + }, + "address": { + "message": "Adresse" + }, + "addToken": { + "message": "Token hinzufügen" + }, + "amount": { + "message": "Betrag" + }, + "amountPlusGas": { + "message": "Betrag + Gas" + }, + "appDescription": { + "message": "Ethereum Browsererweiterung", + "description": "Die Beschreibung der Erweiterung" + }, + "appName": { + "message": "MetaMask", + "description": "Der Name der Erweiterung" + }, + "attemptingConnect": { + "message": "Versuch mit der Blockchain zu verbinden." + }, + "available": { + "message": "Verfügbar" + }, + "back": { + "message": "Zurück" + }, + "balance": { + "message": "Guthaben:" + }, + "balanceIsInsufficientGas": { + "message": "Guthaben unzureichend für den aktuellen gesamten Gasbetrag" + }, + "beta": { + "message": "BETA" + }, + "betweenMinAndMax": { + "message": "Muss größer oder gleich $1 und kleiner oder gleich $2 sein.", + "description": "Helfer für die Eingabe von hex als dezimal" + }, + "blockiesIdenticon": { + "message": "Blockies Identicon verwenden" + }, + "borrowDharma": { + "message": "Mit Dharma ausleihen (Beta)" + }, + "builtInCalifornia": { + "message": "MetaMask wurde in Kalifornien entwickelt und gebaut." + }, + "buy": { + "message": "Kaufen" + }, + "buyCoinbase": { + "message": "Auf Coinbase kaufen" + }, + "buyCoinbaseExplainer": { + "message": "Coinbase ist die weltweit bekannteste Möglichkeit bitcoin, ethereum und litecoin zu kaufen und verkaufen." + }, + "ok": { + "message": "Ok" + }, + "cancel": { + "message": "Abbrechen" + }, + "classicInterface": { + "message": "Klassische Oberfläche verwenden" + }, + "clickCopy": { + "message": "Klicken um zu kopieren" + }, + "confirm": { + "message": "Bestätigen" + }, + "confirmed": { + "message": "Bestätigt" + }, + "confirmContract": { + "message": "Smart Contract bestätigen" + }, + "confirmPassword": { + "message": "Passwort bestätigen" + }, + "confirmTransaction": { + "message": "Transaktion bestätigen" + }, + "continue": { + "message": "Weiter" + }, + "continueToCoinbase": { + "message": "Zu Coinbase fortfahren" + }, + "contractDeployment": { + "message": "Smart Contract ausführen" + }, + "conversionProgress": { + "message": "Umtausch in Arbeit" + }, + "copiedButton": { + "message": "Kopiert" + }, + "copiedClipboard": { + "message": "In die Zwischenablage kopiert" + }, + "copiedExclamation": { + "message": "Kopiert!" + }, + "copiedSafe": { + "message": "Ich habe es an einen sicheren Ort kopiert" + }, + "copy": { + "message": "Kopieren" + }, + "copyToClipboard": { + "message": "In die Zwischenablage kopieren" + }, + "copyButton": { + "message": " Kopieren " + }, + "copyPrivateKey": { + "message": "Das ist Ihr Private Key (klicken um zu kopieren)" + }, + "create": { + "message": "Erstellen" + }, + "createAccount": { + "message": "Account erstellen" + }, + "createDen": { + "message": "Erstellen" + }, + "crypto": { + "message": "Krypto", + "description": "Börsentyp (Kryptowährungen)" + }, + "currentConversion": { + "message": "Aktueller Umtausch" + }, + "currentNetwork": { + "message": "Aktuelles Netzwerk" + }, + "customGas": { + "message": "Gas anpassen" + }, + "customize": { + "message": "Anpassen" + }, + "customRPC": { + "message": "Spezieller RPC" + }, + "decimalsMustZerotoTen": { + "message": "Die Dezimalangabe muss mindestens 0 und nicht höher als 36 sein." + }, + "decimal": { + "message": "Dezimalangabe der Präzision" + }, + "defaultNetwork": { + "message": "Das Standardnetzwerk für Ether Transaktionen ist das Main Net." + }, + "denExplainer": { + "message": "Dein DEN ist dein passwortverschlüsselter Speicher innerhalb von MetaMask." + }, + "deposit": { + "message": "Einzahlen" + }, + "depositBTC": { + "message": "Zahle dein BTC in die unten stehende Adresse ein:" + }, + "depositCoin": { + "message": "Zahle deine $1 in die unten stehende Adresse ein", + "description": "Teilt dem Benutzer mit welchen Token er beim Einzahlen mit Shapeshift ausgewählt hat" + }, + "depositEth": { + "message": "Eth einzahlen" + }, + "depositEther": { + "message": "Ether einzahlen" + }, + "depositFiat": { + "message": "Fiat einzahlen" + }, + "depositFromAccount": { + "message": "Von einem anderen Account einzahlen" + }, + "depositShapeShift": { + "message": "Mit ShapeShift einzahlen" + }, + "depositShapeShiftExplainer": { + "message": "Wenn du andere Kryptowährungen besitzt, kannst du diese direkt mit Hilfe deiner MetaMask Wallet handeln und einzahlen. Du benötigst keinen Account." + }, + "details": { + "message": "Details" + }, + "directDeposit": { + "message": "Sofortige Einzahlung" + }, + "directDepositEther": { + "message": "Sofort Ether einzahlen" + }, + "directDepositEtherExplainer": { + "message": "Wenn du bereits Ether besitzt, ist die sofortige Einzahlung die schnellste Methode Ether in deine neue Wallet zu bekommen." + }, + "done": { + "message": "Fertig" + }, + "downloadStatelogs": { + "message": "Statelogs herunterladen" + }, + "dropped": { + "message": "Abgewählt" + }, + "edit": { + "message": "Editieren" + }, + "editAccountName": { + "message": "Namen des Accounts editieren" + }, + "emailUs": { + "message": "Schreib uns eine Mail!" + }, + "encryptNewDen": { + "message": "Verschlüssele deine neue DEN" + }, + "enterPassword": { + "message": "Passwort eingeben" + }, + "enterPasswordConfirm": { + "message": "Gib dein neues Passwort zur Bestätigung ein" + }, + "passwordNotLongEnough": { + "message": "Passwort ist nicht lang genug" + }, + "passwordsDontMatch": { + "message": "Passwörter stimmen nicht überein" + }, + "etherscanView": { + "message": "Account auf Etherscan anschauen" + }, + "exchangeRate": { + "message": "Wechselrate" + }, + "exportPrivateKey": { + "message": "Private Key exportieren" + }, + "exportPrivateKeyWarning": { + "message": "Der Export von Private Keys verläuft auf eigene Verantwortung." + }, + "failed": { + "message": "Fehlgeschlagen" + }, + "fiat": { + "message": "FIAT", + "description": "Börsentyp" + }, + "fileImportFail": { + "message": "Dateiimport fehlgeschlagen? Bitte hier klicken!", + "description": "Hilft dem Benutzer sein Benutzerkonto durch eine JSON Datei zu importieren" + }, + "followTwitter": { + "message": "Folge uns auf Twitter" + }, + "from": { + "message": "von" + }, + "fromToSame": { + "message": "Ziel- und Ursprungsadresse dürfen nicht identisch sein" + }, + "fromShapeShift": { + "message": "Von ShapeShift" + }, + "gas": { + "message": "Gas", + "description": "Kleiner Hinweis bzgl. der Gaskosten" + }, + "gasFee": { + "message": "Gasgebühren" + }, + "gasLimit": { + "message": "Gaslimit" + }, + "gasLimitCalculation": { + "message": "Wir berechnen das empfohlene Gaslimit basierend auf der Erfolgsrate des Netzwerks." + }, + "gasLimitRequired": { + "message": "Gaslimit benötigt" + }, + "gasLimitTooLow": { + "message": "Gaslimit muss mindestens 21000 betragen" + }, + "generatingSeed": { + "message": "Seed generieren..." + }, + "gasPrice": { + "message": "Gaspreis (GWEI)" + }, + "gasPriceCalculation": { + "message": "Wir berechnen den empfohlenen Gaspreis basierend auf der Erfolgsrate des Netzwerks." + }, + "gasPriceRequired": { + "message": "Gaspreis benötigt" + }, + "getEther": { + "message": "Ether holen" + }, + "getEtherFromFaucet": { + "message": "Ether für $1 vom Faucet holen", + "description": "Zeigt den Netzwerknamen für den Ether Faucet an" + }, + "greaterThanMin": { + "message": "Muss größer oder gleich $1 sein.", + "description": "Helfer für die Eingabe von hex als dezimal" + }, + "here": { + "message": "hier", + "description": "z.B. für klick hier für mehr Informationen (in Zusammenhang mit troubleTokenBalances)" + }, + "hereList": { + "message": "Hier ist eine Liste!!!!" + }, + "hide": { + "message": "Ausblenden" + }, + "hideToken": { + "message": "Token ausblenden" + }, + "hideTokenPrompt": { + "message": "Token ausblenden?" + }, + "howToDeposit": { + "message": "Wie möchtest du Ether einzahlen?" + }, + "holdEther": { + "message": "Es erlaubt dir ether & Token zu halten und dient dir als Verbindung zu dezentralisierten Applikationen." + }, + "import": { + "message": "Import", + "description": "Button um den Account aus einer ausgewählten Datei zu importieren" + }, + "importAccount": { + "message": "Account importieren" + }, + "importAccountMsg": { + "message":" Importierte Accounts werden nicht mit der Seed Wörterfolge deines ursprünglichen MetaMask Accounts verknüpft. Erfahre mehr über importierte Accounts." + }, + "importAnAccount": { + "message": "Einen Account importieren" + }, + "importDen": { + "message": "Vorhandenes DEN importieren" + }, + "imported": { + "message": "Importiert", + "description": "Status der angezeigt wird wenn ein Benutzerkonto vollständig in das Schlüsselbund geladen wurde." + }, + "infoHelp": { + "message": "Info & Hilfe" + }, + "insufficientFunds": { + "message": "Nicht genügend Guthaben." + }, + "insufficientTokens": { + "message": "Nicht genügend Token." + }, + "invalidAddress": { + "message": "Ungültige Adresse" + }, + "invalidAddressRecipient": { + "message": "Empfängeradresse ist unzulässig" + }, + "invalidGasParams": { + "message": "Ungültige Gasparameter" + }, + "invalidInput": { + "message": "Ungültige Eingabe." + }, + "invalidRequest": { + "message": "Ungültige Abfrage" + }, + "invalidRPC": { + "message": "Ungültige RPC URI" + }, + "jsonFail": { + "message": "Irgendetwas ist schief gelaufen. Bitte überprüfe ob deine JSON Datei korrekt formatiert ist." + }, + "jsonFile": { + "message": "JSON Datei", + "description": "Dateiformat für das Importieren eines Accounts" + }, + "kovan": { + "message": "Kovan Testnetzwerk" + }, + "knowledgeDataBase": { + "message": "Schau in unsere Wissensdatenbank" + }, + "max": { + "message": "Max" + }, + "lessThanMax": { + "message": "Muss kleiner oder gleich $1 sein.", + "description": "Helfer für die Eingabe von hex als dezimal" + }, + "likeToAddTokens": { + "message": "Möchtest du diese Token hinzufügen?" + }, + "links": { + "message": "Links" + }, + "limit": { + "message": "Limit" + }, + "loading": { + "message": "Laden..." + }, + "loadingTokens": { + "message": "Token laden..." + }, + "localhost": { + "message": "Localhost 8545" + }, + "login": { + "message": "Login" + }, + "logout": { + "message": "Ausloggen" + }, + "loose": { + "message": "Frei" + }, + "loweCaseWords": { + "message": "Die Wörter der Seed Wörterfolgen sind alle kleingeschrieben" + }, + "mainnet": { + "message": "Ethereum Hauptnetzwerk (Main Net)" + }, + "message": { + "message": "Nachricht" + }, + "metamaskDescription": { + "message": "MetaMask ist ein sicherer Identitätssafe für Ethereum." + }, + "min": { + "message": "Minimum" + }, + "myAccounts": { + "message": "Meine Accounts" + }, + "mustSelectOne": { + "message": "Du musst mindestens 1 Token auswählen." + }, + "needEtherInWallet": { + "message": "Um dezentralisierte Applikationen mit MetaMask verwenden zu können, benötigst du Ether in deiner Wallet." + }, + "needImportFile": { + "message": "Für den Import musst du eine Datei auswählen.", + "description": "Benutzer importiert ein Benutzerkonto und muss eine Datei hinzufügen um fortzufahren" + }, + "needImportPassword": { + "message": "Für die ausgewählte Datei muss ein Passwort eingegeben werden.", + "description": "Passwort und Datei sind notwendig um einen Account zu importieren" + }, + "negativeETH": { + "message": "Negative ETH Beträge können nicht versendet werden." + }, + "networks": { + "message": "Netzwerke" + }, + "newAccount": { + "message": "Neuer Account" + }, + "newAccountNumberName": { + "message": "Account $1", + "description": "Standardname für einen weiteren Account der angelegt wird, wenn create account screen geklickt wird" + }, + "newContract": { + "message": "Neuer Smart Contract" + }, + "newPassword": { + "message": "Neues Passwort (min. 8 Zeichen)" + }, + "newRecipient": { + "message": "Neuer Empfänger" + }, + "newRPC": { + "message": "Neue RPC URL" + }, + "next": { + "message": "Weiter" + }, + "noAddressForName": { + "message": "Für den angegebene Namen wurde keine Adresse eingegeben." + }, + "noDeposits": { + "message": "Keine Einzahlung erhalten" + }, + "noTransactionHistory": { + "message": "Keine Transaktionshistorie." + }, + "noTransactions": { + "message": "Keine Transaktionen" + }, + "notStarted": { + "message": "Nicht gestartet" + }, + "oldUI": { + "message": "Alte Oberfläche" + }, + "oldUIMessage": { + "message": "Du bist zur alten Oberfläche zurückgewechselt. Du kannst mit Hilfe der Option im oberen rechten Dropdown Menü zur neuen Oberfläche zurückwechseln." + }, + "or": { + "message": "oder", + "description": "Wahl zwischen erstellen oder importieren eines Accounts." + }, + "passwordCorrect": { + "message": "Bitte überzeuge dich davon, dass dein Passwort korrekt ist." + }, + "passwordMismatch": { + "message": "Passwörter stimmen nicht überein", + "description": "Im Passwort erstellen Prozess stimmen beide Passwörter nicht miteinander überein" + }, + "passwordShort": { + "message": "Passwort ist nicht lang genug", + "description": "Im Passwort erstellen Prozess ist das eingegebene Passwort nicht lang genug um sicher zu sein" + }, + "pastePrivateKey": { + "message": "Füge deine Private Key Zeichenfolge hier ein:", + "description": "Für den Import eine Accounts mit Hilfe eines Private Keys" + }, + "pasteSeed": { + "message": "Füge deine Seed Wörterfolge hier ein!" + }, + "personalAddressDetected": { + "message": "Personalisierte Adresse identifiziert. Bitte füge die Token Contract Adresse ein." + }, + "pleaseReviewTransaction": { + "message": "Bitte überprüfe deine Transaktion." + }, + "privacyMsg": { + "message": "Datenschutzrichtlinie" + }, + "privateKey": { + "message": "Private Key", + "description": "Wähle diesen Dateityp um damit einen Account zu importieren" + }, + "privateKeyWarning": { + "message": "Warnung: Niemals jemanden deinen Private Key mitteilen. Jeder der im Besitz deines Private Keys ist, kann jegliches Guthaben deines Accounts stehlen." + }, + "privateNetwork": { + "message": "Privates Netzwerk" + }, + "qrCode": { + "message": "QR Code anzeigen" + }, + "readdToken": { + "message": "Du kannst diesen Token zukünftig wieder hinzufügen indem du in den Menüpunkt \"Token hinzufügen\" in den Einstellungen deines Accounts gehst." + }, + "readMore": { + "message": "Hier mehr erfahren." + }, + "readMore2": { + "message": "Mehr erfahren." + }, + "receive": { + "message": "Erhalten" + }, + "recipientAddress": { + "message": "Empfängeradresse" + }, + "refundAddress": { + "message": "Rückerstattungsadresse" + }, + "rejected": { + "message": "Abgelehnt" + }, + "resetAccount": { + "message": "Account zurücksetzten" + }, + "restoreFromSeed": { + "message": "Mit Hilfe der Seed Wörterfolge wiederherstellen." + }, + "restoreVault": { + "message": "Vault wiederherstellen" + }, + "required": { + "message": "Benötigt" + }, + "retryWithMoreGas": { + "message": "Versuche es hier mit einem höheren Gaspreis noch einmal" + }, + "walletSeed": { + "message": "Wallet Seed" + }, + "revealSeedWords": { + "message": "Seed Wörterfolge anzeigen" + }, + "revealSeedWordsWarning": { + "message": "Bitte niemals deine Seed Wörterfolge an einem öffentlichen Ort kenntlich machen. Mit diesen Wörtern können alle deine Accounts gestohlen werden." + }, + "revert": { + "message": "Zurück gehen" + }, + "rinkeby": { + "message": "Rinkeby Testnetzwerk" + }, + "ropsten": { + "message": "Ropsten Testnetzwerk" + }, + "currentRpc": { + "message": "Aktueller RPC" + }, + "connectingToMainnet": { + "message": "Verbinde zum Ethereum Hauptnetzwerk (Main Net)" + }, + "connectingToRopsten": { + "message": " Verbinde zum Ropsten Testnetzwerk" + }, + "connectingToKovan": { + "message": " Verbinde zum Kovan Testnetzwerk" + }, + "connectingToRinkeby": { + "message": " Verbinde zum Rinkeby Testnetzwerk" + }, + "connectingToUnknown": { + "message": "Verbinde zu einem unbekanntem Netzwerk" + }, + "sampleAccountName": { + "message": "Z.B. mein neuer Account", + "description": "Dem Benutzer helfen das Konzept des Hinzufügens eines menschlich lesbaren Namen für den Account hinzuzufügen" + }, + "save": { + "message": "Speichern" + }, + "saveAsFile": { + "message": "Als Datei speichern", + "description": "Prozess des Exportieren eines Accounts" + }, + "saveSeedAsFile": { + "message": "Seed Wörterfolge als Datei speichern" + }, + "search": { + "message": "Suche" + }, + "secretPhrase": { + "message": "Gib die 12 Wörter deiner geheimem Wörterfolge ein um deinen Vault wiederherzustellen." + }, + "newPassword8Chars": { + "message": "Neues Passwort (min. 8 Zeichen)" + }, + "seedPhraseReq": { + "message": "Seed Wörterfolgen bestehen aus 12 Wörtern" + }, + "select": { + "message": "Auswählen" + }, + "selectCurrency": { + "message": "Währung auswählen" + }, + "selectService": { + "message": "Service auswählen" + }, + "selectType": { + "message": "Typ auswählen" + }, + "send": { + "message": "Senden" + }, + "sendETH": { + "message": "ETH senden" + }, + "sendTokens": { + "message": "Token senden" + }, + "onlySendToEtherAddress": { + "message": "ETH nur zu einer Ethereum Adresse senden." + }, + "sendTokensAnywhere": { + "message": "Token zu einer beliebigen Person mit einem Ethereumaccount senden" + }, + "settings": { + "message": "Einstellungen" + }, + "info": { + "message": "Info" + }, + "shapeshiftBuy": { + "message": "Mit Shapeshift kaufen" + }, + "showPrivateKeys": { + "message": "Private Keys anzeigen" + }, + "showQRCode": { + "message": "QR Code anzeigen" + }, + "sign": { + "message": "Unterschreiben" + }, + "signed": { + "message": "Unterschrieben" + }, + "signMessage": { + "message": "Nachricht unterschreiben" + }, + "signNotice": { + "message": "Das Unterschreiben dieser Nachricht kann gefährliche Nebeneffekte haben. Bitte nur Nachrichten von Webseiten unterschreiben denen du deinen vollständigen Account anvertrauen würdest. Diese gefährliche Variante wird in zukünftigen Versionen entfernt werden." + }, + "sigRequest": { + "message": "Unterschriftsanfrage" + }, + "sigRequested": { + "message": "Unterschrift angefragt" + }, + "spaceBetween": { + "message": "Es darf nur ein Leerzeichen zwischen den Wörtern sein" + }, + "status": { + "message": "Status" + }, + "stateLogs": { + "message": "Statelogs" + }, + "stateLogsDescription": { + "message": "Statelogs zeigen die Public Adresse und die gesendeten Transaktionen deines Accounts." + }, + "stateLogError": { + "message": "Fehler beim Abfragen der Statelogs." + }, + "submit": { + "message": "Einreichen" + }, + "submitted": { + "message": "Eingereicht" + }, + "supportCenter": { + "message": "Gehe zu unserem Support Center" + }, + "symbolBetweenZeroTen": { + "message": "Das Symbol muss zwischen 0 und 10 Zeichen haben." + }, + "takesTooLong": { + "message": "Dauert es zu lang?" + }, + "terms": { + "message": "Nutzungsbedingungen" + }, + "testFaucet": { + "message": "Testfaucet" + }, + "to": { + "message": "An:" + }, + "toETHviaShapeShift": { + "message": "$1 an ETH via ShapeShift", + "description": "Das System wird den Einzahlungstyp im Beginn der Nachricht eintragen" + }, + "tokenAddress": { + "message": "Tokenadresse" + }, + "tokenAlreadyAdded": { + "message": "Der Token wurde bereits hinzugefügt." + }, + "tokenBalance": { + "message": "Dein Tokenguthaben beträgt:" + }, + "tokenSelection": { + "message": "Suche nach Token oder wähle aus einer Liste der beliebtesten Token aus." + }, + "tokenSymbol": { + "message": "Tokensymbol" + }, + "tokenWarning1": { + "message": "Behalte die Token die du mit deinem MetaMask Account gekauft hast im Auge. Wenn du Token mit einem anderen Account gekauft hast, werden diese hier nicht angezeigt." + }, + "total": { + "message": "Gesamt" + }, + "transactions": { + "message": "Transaktionen" + }, + "transactionMemo": { + "message": "Transaktionsmemo (optional)" + }, + "transactionNumber": { + "message": "Transaktionsnummer" + }, + "transfers": { + "message": "Transfers" + }, + "troubleTokenBalances": { + "message": "Wir haben Schwierigkeiten dein Tokenguthaben zu laden. Du kannst es hier anzeigen lassen", + "description": "Gefolgt von einem Link (hier) um die Tokenguthaben anzuzeigen" + }, + "twelveWords": { + "message": "Diese 12 Wörter stellen die einzige Möglichkeit dar deinen MetaMask Account wiederherzustellen. Speichere sie daher an einem sicheren und geheimen Ort." + }, + "typePassword": { + "message": "Passwort eingeben" + }, + "uiWelcome": { + "message": "Willkommen zur neuen Oberfläche (Beta)" + }, + "uiWelcomeMessage": { + "message": "Du verwendest nun die neue Metamask Oberfläche. Schau dich um, teste die neuen Features wie z.B. das Senden von Token und lass es uns wissen falls du irgendwelche Probleme hast." + }, + "unapproved": { + "message": "Nicht genehmigt" + }, + "unavailable": { + "message": "Nicht verfügbar" + }, + "unknown": { + "message": "Unbekannt" + }, + "unknownNetwork": { + "message": "Unbekanntes privates Netzwerk" + }, + "uriErrorMsg": { + "message": "URIs benötigen die korrekten HTTP/HTTPS Präfixe." + }, + "unknownNetworkId": { + "message": "Unbekannte Netzwerk ID" + }, + "usaOnly": { + "message": "Nur USA ", + "description": "Diese Börse ist nur für Einwohner der USA verfügbar" + }, + "usedByClients": { + "message": "Verwendet von einer Reihe verschiedenen Kunden" + }, + "useOldUI": { + "message": "Alte Oberfläche verwenden" + }, + "validFileImport": { + "message": "Du musst eine gültige Datei für den Import auswählen." + }, + "vaultCreated": { + "message": "Vault erstellt" + }, + "viewAccount": { + "message": " Account einsehen" + }, + "visitWebSite": { + "message": "Gehe zu unsere Webseite" + }, + "warning": { + "message": "Warnung" + }, + "welcomeBeta": { + "message": "Willkommen zu MetaMask Beta" + }, + "whatsThis": { + "message": "Was ist das?" + }, + "yourSigRequested": { + "message": "Deine Unterschrift wird angefordert" + }, + "youSign": { + "message": "Du unterschreibst" + } +} diff --git a/app/_locales/es/messages.json b/app/_locales/es/messages.json index 0bef6bebf..fa28b09da 100644 --- a/app/_locales/es/messages.json +++ b/app/_locales/es/messages.json @@ -11,11 +11,17 @@ "accountName": { "message": "Nombre de la cuenta" }, - "address": { - "message": "Dirección" + "addCustomToken": { + "message": "Agregar token personalizados" }, "addToken": { - "message": "Agregar Token" + "message": "Agregar token" + }, + "addTokens": { + "message": "Agregar tokens" + }, + "address": { + "message": "Dirección" }, "amount": { "message": "Cantidad" @@ -24,16 +30,22 @@ "message": "Cantidad + Gas" }, "appDescription": { - "message": "Extensión del explorador usar Ethereum", + "message": "Extensión del navegador para Ethereum", "description": "La descripción de la aplicación" }, "appName": { "message": "MetaMask", "description": "El nombre de la aplicación" }, + "approved": { + "message": "Aprobado" + }, "attemptingConnect": { "message": "Intentando conectar a la Blockchain" }, + "attributions": { + "message": "Atribuciones" + }, "available": { "message": "Disponible" }, @@ -43,12 +55,12 @@ "balance": { "message": "Saldo" }, - "balances": { - "message": "Tus saldos" - }, "balanceIsInsufficientGas": { "message": "Saldo de gas insuficiente" }, + "balances": { + "message": "Tus saldos" + }, "beta": { "message": "BETA" }, @@ -56,9 +68,15 @@ "message": "Debe ser mayor o igual a $1 y menor o igual a $2", "description": "helper para ingresar hex como un ingreso decimal" }, + "blockiesIdenticon": { + "message": "Usar Blockies Identicon (Iconos)" + }, "borrowDharma": { "message": "Pedir prestado con Dharma (Beta)" }, + "builtInCalifornia": { + "message": "Metamask fue diseñado y construido en California" + }, "buy": { "message": "Comprar" }, @@ -66,40 +84,55 @@ "message": "Comprar en Coinbase" }, "buyCoinbaseExplainer": { - "message": "Coinbase es la manera más popular en el mundo para comprar y vender bitcoin, ethereum y litecoin" + "message": "Coinbase es la plataforma global más popular para comprar y vender Bitcoin, Ethereum y Litecoin" }, "cancel": { "message": "Cancelar" }, + "classicInterface": { + "message": "Usar interfaz clásica" + }, "clickCopy": { "message": "Click para copiar" }, "confirm": { "message": "Confirmar" }, - "continue": { - "message": "Continuar" - }, "confirmContract": { "message": "Confirmar contrato" }, + "confirmed": { + "message": "Confirmado" + }, "confirmPassword": { "message": "Confirmar contraseña" }, - "enterPasswordConfirm": { - "message": "Ingresa tu contraseña para confirmar" - }, "confirmTransaction": { - "message": "Confirmar transacción " + "message": "Confirmar transacción" + }, + "connectingToMainnet": { + "message": "Conectando a la red principal de Ethereum (Main Net)" + }, + "connectingToRopsten": { + "message": "Conectando a la red de test Ropsten" + }, + "connectingToKovan": { + "message": "Conectando a la red de test Kovan" + }, + "connectingToRinkeby": { + "message": "Conectando a la red de test Rinkeby" + }, + "connectingToUnknown": { + "message": "Conectando a una red desconocida" + }, + "continue": { + "message": "Continuar" }, "continueToCoinbase": { "message": "Continuar a Coinbase" }, "contractDeployment": { - "message": "Deployar contrato" - }, - "currentConversion": { - "message": "Conversión Actual" + "message": "Desplegar (Deploy) contrato" }, "conversionProgress": { "message": "Conversión en progreso" @@ -111,53 +144,65 @@ "message": "Copiado al portapapeles" }, "copiedExclamation": { - "message": "Copiado!" + "message": "¡Copiado!" + }, + "copiedSafe": { + "message": "Ya lo guardé en un lugar seguro" }, "copy": { "message": "Copiar" }, - "copyToClipboard": { - "message": "Copiar al portapapeles" - }, "copyButton": { "message": " Copiar " }, "copyPrivateKey": { - "message": "Esta es tu llave privada (Click para copiar)" + "message": "Ésta es tu llave privada (haz click para copiar)" + }, + "copyToClipboard": { + "message": "Copiar al portapapeles" }, "create": { "message": "Crear" }, "createAccount": { - "message": "Crear Cuenta" + "message": "Crear cuenta" }, "createDen": { "message": "Crear" }, "crypto": { "message": "Crypto", - "description": "Tipo de Cambio (criptomonedas)" + "description": "Tipo de cambio (criptomonedas)" }, - "customGas": { - "message": "Personalizar Gas" + "currentConversion": { + "message": "Conversión actual" }, - "customize": { - "message": "Personalizar" + "currentNetwork": { + "message": "Red actual" }, - "currentRPC": { + "currentRpc": { "message": "RPC actual" }, + "customGas": { + "message": "Personalizar gas" + }, "customRPC": { - "message": "RPC Personalizado" + "message": "RPC personalizado" }, - "newRPC": { - "message": "Nueva URL del RPC" + "customize": { + "message": "Personalizar" + }, + "decimal": { + "message": "Decimales de precisión" + }, + "decimalsMustZerotoTen": { + "message": "Los decimales deben ser al menos 0 y no más de 36" }, "defaultNetwork": { "message": "La red por defecto para las transacciones de Ether es MainNet (red principal)" }, "denExplainer": { - "message": "Tu DEN es tu contraseña encriptada guardada dentro de MetaMask" + "message": "El DEN es tu contraseña encriptada almacenada dentro de MetaMask" }, "deposit": { "message": "Depositar" @@ -170,13 +215,13 @@ "description": "Informa al usuario que moneda ha elegido para depositar en shapeshift" }, "depositEth": { - "message": "Depositar Eth" + "message": "Depositar Ether" }, "depositEther": { "message": "Depositar Ether" }, "depositFiat": { - "message": "Depositar con Fiat (divisa nacional)" + "message": "Depositar con fiat (divisa nacional)" }, "depositFromAccount": { "message": "Depositar con otra cuenta" @@ -185,37 +230,46 @@ "message": "Depositar con ShapeShift" }, "depositShapeShiftExplainer": { - "message": "Si tu tienes otras criptomonedas, puedes intercambiar y depositar Ether directamente en tu billetera de MetaMask. No necesitas tener una cuenta." + "message": "Si posees otras criptomonedas, puedes intercambiar y depositar Ether directamente en tu billetera de MetaMask. No necesitas tener una cuenta." }, "details": { "message": "Detalles" }, "directDeposit": { - "message": "Deposito directo" + "message": "Depósito directo" }, "directDepositEther": { "message": "Depositar Ether directamente" }, "directDepositEtherExplainer": { - "message": "Si tu tienes algo de Ether, la forma rapida para tener Ether en tu nueva billetera es depositando directamente" + "message": "Si posees Ether, la forma más rápida de transferirlo a tu nueva billetera es depositándolo directamente" }, "done": { "message": "Completo" }, + "downloadStatelogs": { + "message": "Descargar logs de estado" + }, + "dropped": { + "message": "Caído" + }, "edit": { "message": "Editar" }, "editAccountName": { "message": "Editar el nombre de la cuenta" }, + "emailUs": { + "message": "¡Envíanos un correo!" + }, "encryptNewDen": { "message": "Encriptar tu nuevo DEN" }, "enterPassword": { "message": "Ingresa contraseña" }, - "passwordCorrect": { - "message": "Asegurate que tu contraseña es correcta" + "enterPasswordConfirm": { + "message": "Ingresa tu contraseña para confirmar" }, "etherscanView": { "message": "Ver la cuenta en Etherscan" @@ -234,18 +288,24 @@ }, "fiat": { "message": "FIAT", - "description": "Exchange type" + "description": "Tipo de cambio" }, "fileImportFail": { - "message": "No funciona importar el archivo? Haz Click Aquí!", + "message": "¿La importación no funcionó? ¡Haz click aquí!", "description": "Ayuda al usuario a importar su cuenta desde un archivo JSON" }, + "followTwitter": { + "message": "Síguenos en Twitter" + }, "from": { "message": "De:" }, "fromShapeShift": { "message": "De ShapeShift" }, + "fromToSame": { + "message": "La dirección de origen y destino no pueden ser la misma" + }, "gas": { "message": "Gas", "description": "Indicación pequeña del costo de gas" @@ -260,7 +320,7 @@ "message": "Calculamos el límite de gas sugerido en función de las tasas de éxito de la red" }, "gasLimitRequired": { - "message": "Límite de Gas requerido" + "message": "Límite de gas requerido" }, "gasLimitTooLow": { "message": "El límite de gas debe ser de al menos 21000" @@ -274,6 +334,9 @@ "gasPriceRequired": { "message": "Precio del gas requerido" }, + "generatingSeed": { + "message": "Generando semilla..." + }, "getEther": { "message": "Conseguir Ether" }, @@ -286,27 +349,33 @@ "description": "helper para ingresar hex como entrada decimal" }, "here": { - "message": "Aqui", + "message": "Aquí", "description": "como en -haz click aquí- para más información" }, + "hereList": { + "message": "¡¡¡Aquí está una lista!!!" + }, "hide": { "message": "Ocultar" }, "hideToken": { - "message": "Ocultar Token" + "message": "Ocultar token" }, "hideTokenPrompt": { - "message": "Ocultar Token?" + "message": "¿Ocultar token?" + }, + "holdEther": { + "message": "Te permite mantener tus ether y tokens, así como puente para aplicaciones descentralizadas" }, "howToDeposit": { - "message": "Cómo te gustaria depositar Ether?" + "message": "¿Cómo te gustaria depositar Ether?" }, "import": { "message": "Importar", "description": "Botón para importar una cuenta desde un archivo seleccionado" }, "importAccount": { - "message": "Importar Cuenta" + "message": "Importar cuenta" }, "importAnAccount": { "message": "Importar una cuenta" @@ -316,51 +385,72 @@ }, "imported": { "message": "Importado", - "description": "estado que muestra que una cuenta ha sido completamente cargada en el llavero" + "description": "Estado que muestra que una cuenta ha sido completamente cargada en el llavero" + }, + "importAccountMsg": { + "message": "Las cuentas importadas no serán asociadas con tu cuenta original creada con tu MetaMask. Aprende más acerca de importar cuentas." + }, + "info": { + "message": "Información" }, "infoHelp": { - "message": "Informacion y Ayuda" + "message": "Informacion y ayuda" + }, + "insufficientFunds": { + "message": "Fondos insuficientes" + }, + "insufficientTokens": { + "message": "Tokens insuficientes" }, "invalidAddress": { - "message": "Dirección Inválida" + "message": "Dirección inválida" + }, + "invalidAddressRecipient": { + "message": "Dirección del destinatario invalida" }, "invalidGasParams": { - "message": "Parametros de Gas Inválidos" + "message": "Parametros de gas inválidos" }, "invalidInput": { "message": "Entrada inválida" }, - "invalidRequest": { - "message": "Peticion inválida" + "invalidRPC": { + "message": "Invalida URL del RPC" }, - "invalidAddressRecipient": { - "message": "Dirección del recipiente invalida" + "invalidRequest": { + "message": "Petición inválida" }, - "fromToSame": { - "message": "La dirección de origen y destino no pueden ser la misma" + "jsonFail": { + "message": "Algo falló. Asegúrate que tu JSON tiene el formato correcto" }, "jsonFile": { "message": "Archivo JSON", - "description": "formato para importar una cuenta" + "description": "Formato para importar una cuenta" }, - "jsonFail": { - "message": "Algo malo pasó. Asegurate que tu JSON tiene el formato correcto" + "knowledgeDataBase": { + "message": "Visita nuestra base de conocimiento" }, "kovan": { "message": "Red de pruebas Kovan" }, "lessThanMax": { "message": "Debe ser menor o igual a $1", - "description": "helper para ingresar hex como decimal" + "description": "Helper para ingresar hex como decimal" + }, + "likeToAddTokens": { + "message": "¿Te gustaría agregar estos tokens?" }, "limit": { "message": "Límite" }, + "links": { + "message": "Enlaces" + }, "loading": { "message": "Cargando..." }, "loadingTokens": { - "message": "Cargando Tokens..." + "message": "Cargando tokens..." }, "localhost": { "message": "Localhost 8545" @@ -369,25 +459,37 @@ "message": "Ingresar" }, "logout": { - "message": "Cerrar sesion" + "message": "Cerrar sesión" }, "loose": { - "message": "Loose" + "message": "Suelto" + }, + "loweCaseWords": { + "message": "las frases semilla sólo pueden tener minúsculas" }, "mainnet": { - "message": "Red principal de Ethereum (MainNet)" + "message": "Red principal de Ethereum (Main Net)" + }, + "max": { + "message": "Max" }, "message": { "message": "Mensaje" }, + "metamaskDescription": { + "message": "MetaMask es una identidad segura en Ethereum" + }, "min": { - "message": "Minimo" + "message": "Mínimo" + }, + "mustSelectOne": { + "message": "Debe seleccionar al menos un (1) token" }, "myAccounts": { "message": "Mis cuentas" }, "needEtherInWallet": { - "message": "Para interactuar con una aplicación descentralizada usando MetaMask, vas a necesitar tener Ether en tu billetera" + "message": "Para interactuar con una aplicación descentralizada usando MetaMask, necesitas tener Ether en tu billetera" }, "needImportFile": { "message": "Debes seleccionar un archivo para importar", @@ -397,8 +499,8 @@ "message": "Debes ingresar una contraseña para el archivo seleccionado", "description": "Contraseña y archivo necesarios para importar una cuenta" }, - "validFileImport": { - "message": "Debes selecionar un archivo valido para importar" + "negativeETH": { + "message": "No se pueden mandar cantidades negativas de ETH" }, "networks": { "message": "Redes" @@ -416,6 +518,12 @@ "newPassword": { "message": "Nueva contraseña (mínimo [8] caracteres)" }, + "newPassword8Chars": { + "message": "Nueva contraseña (mínimo [8] caracteres)" + }, + "newRPC": { + "message": "Nueva URL del RPC" + }, "newRecipient": { "message": "Nuevo destinatario" }, @@ -431,68 +539,83 @@ "noTransactionHistory": { "message": "Sin historial de transacciones" }, - "transactions": { - "message": "Transacciones" - }, "noTransactions": { "message": "Sin transacciones" }, "notStarted": { "message": "Sin iniciar" }, - "oldUI": { - "message": "Antigua UI" + "ok": { + "message": "Ok" }, - "useOldUI": { - "message": "Usar UI antigua" + "oldUI": { + "message": "Antigua UI (Interfaz de Usuario)" }, "oldUIMessage": { - "message": "Regresaste a la antigua UI. Puedes regresar a la nueva UI mediante la opcion en la barra desplegable del menu de arriba a la derecha." + "message": "Regresaste a la antigua UI (Interfaz de Usuario). Puedes regresar a la nueva UI mediante la opcion en la barra desplegable del menu de arriba a la derecha." + }, + "onlySendToEtherAddress": { + "message": "Sólo envía a una dirección de Ethereum" }, "or": { "message": "o", "description": "opción entre crear o importar una cuenta" }, + "passwordCorrect": { + "message": "Asegurate que tu contraseña es correcta" + }, "passwordMismatch": { - "message": "Contraseña no concide", - "description": "en el proceso de creación de contraseña, los dos campos de contraseña no coincidieron" + "message": "La contraseña no coincide", + "description": "En el proceso de creación de contraseña, los dos campos de contraseña no coincidieron" + }, + "passwordNotLongEnough": { + "message": "La contraseña no es lo suficientemente larga" + }, + "passwordsDontMatch": { + "message": "Las contraseñas no coinciden" }, "passwordShort": { - "message": "Contraseña no es lo suficientemente larga", - "description": "in password creation process, the password is not long enough to be secure" + "message": "La contraseña no es lo suficientemente larga", + "description": "En el proceso de creación de contraseña, esta no es lo suficientemente larga para ser segura" }, "pastePrivateKey": { "message": "Pega tu llave privada aqui", "description": "Para importar una cuenta desde una llave privada" }, "pasteSeed": { - "message": "Pegue su frase semilla aquí!" + "message": "¡Pega tu frase semilla aquí!" }, - "generatingSeed": { - "message": "Generando semilla..." + "personalAddressDetected": { + "message": "Dirección personal detectada. Ingresa la dirección del contrato del token" }, "pleaseReviewTransaction": { - "message": "Por favor revisa tu transaccion" + "message": "Por favor, revisa tu transaccion" + }, + "privacyMsg": { + "message": "Política de privacidad" }, "privateKey": { "message": "Llave privada", - "description": "select this type of file to use to import an account" + "description": "Selecciona este tupo de archivo para importar una cuenta" }, "privateKeyWarning": { - "message": "Advertencia: Nunca revele esta clave. Cualquier persona con sus claves privadas puede robar cualquier activo retenido en su cuenta." + "message": "Advertencia: NUNCA reveles esta clave. Cualquier persona con tus claves privadas puede robar los activos retenidos en tu cuenta" }, "privateNetwork": { - "message": "Red Privada" + "message": "Red privada" }, "qrCode": { "message": "Mostrar codigo QR" }, - "readdToken": { - "message": "Puede volver a agregar este token en el futuro yendo a 'Agregar token' en el menú de opciones de su cuenta.." - }, "readMore": { "message": "Leer más aquí" }, + "readMore2": { + "message": "Leer más" + }, + "readdToken": { + "message": "Puedes volver a agregar este token en el futuro pinchando sobre 'Agregar token' en el menú de opciones de tu cuenta" + }, "receive": { "message": "Recibir" }, @@ -500,7 +623,7 @@ "message": "Dirección del receptor" }, "refundAddress": { - "message": "Su dirección de reembolso" + "message": "Tu dirección de reembolso" }, "rejected": { "message": "Rechazado" @@ -508,8 +631,23 @@ "required": { "message": "Requerido" }, + "resetAccount": { + "message": "Reiniciar cuenta" + }, + "restoreFromSeed": { + "message": "Restaurar desde semilla" + }, + "restoreVault": { + "message": "Restaurar Bóveda" + }, "retryWithMoreGas": { - "message": "Vuelva a intentar con un precio de Gas más alto aquí" + "message": "Vuelva a intentar con un precio de gas más alto aquí" + }, + "revealSeedWords": { + "message": "Revelar palabras de semilla" + }, + "revealSeedWordsWarning": { + "message": "¡No recuperes tu semilla en un lugar pública! Esas palabras pueden ser usadas para robarte todas tus cuentas" }, "revert": { "message": "Revertir" @@ -521,7 +659,7 @@ "message": "Red privada Ropsten" }, "sampleAccountName": { - "message": "Ej. Mi nueva cuenta", + "message": "P.ej. Mi nueva cuenta", "description": "Ayuda al usuario a entender el concepto de agregar un nombre, leíble por humanos, a su cuenta" }, "save": { @@ -531,27 +669,45 @@ "message": "Guardar como archivo", "description": "Proceso de exportación de cuenta" }, + "saveSeedAsFile": { + "message": "Guardar la semilla como archivo" + }, + "search": { + "message": "Buscar" + }, + "secretPhrase": { + "message": "Ingresa tu frase de doce (12) palabras para restaurar tu bóveda" + }, + "seedPhraseReq": { + "message": "las frases semilla tienen doce (12) palabras de largo" + }, + "select": { + "message": "Seleccionar" + }, + "selectCurrency": { + "message": "Seleccionar moneda" + }, "selectService": { "message": "Seleccionar servicio" }, + "selectType": { + "message": "Seleccionar tipo" + }, "send": { "message": "Enviar" }, - "sendTokens": { - "message": "Enviar Tokens" - }, "sendETH": { - "message": "Enviar ETH" + "message": "Enviar Ether" + }, + "sendTokens": { + "message": "Enviar tokens" }, "sendTokensAnywhere": { - "message": "Enviar Tokens a cualquiera con una cuenta de Ethereum" + "message": "Enviar tokens a cualquiera con una cuenta de Ethereum" }, "settings": { "message": "Configuración" }, - "info": { - "message": "Información" - }, "shapeshiftBuy": { "message": "Comprar con ShapeShift" }, @@ -561,20 +717,35 @@ "showQRCode": { "message": "Mostrar codigo QR" }, + "sigRequest": { + "message": "Solicitud de firma" + }, + "sigRequested": { + "message": "Firma solicitada" + }, "sign": { "message": "Firmar" }, + "signed": { + "message": "Firmado" + }, "signMessage": { - "message": "Firmar Mensaje" + "message": "Firmar mensaje" }, "signNotice": { - "message": "Firmar este mensaje puede tener\n efectos secundarios peligrosos. Firma sólo\nmensajes desde sitios a los cuales tú estés dispuesto a confiar completamente tu cuenta.\nEste método peligroso va a ser \nremovido en una version futura." + "message": "Firmar este mensaje puede tener\n efectos secundarios peligrosos. Firma sólo\nmensajes desde sitios a los que estés plenamente dispuesto a confiar tu cuenta.\nEste método peligroso va a ser \neliminado en una version futura." }, - "sigRequest": { - "message": "Solicitud de firma" + "spaceBetween": { + "message": "Sólo puede haber un espacio entre las palabras" }, - "sigRequested": { - "message": "Firma solicitada" + "stateLogs": { + "message": "Logs de estado" + }, + "stateLogsDescription": { + "message": "Los logs de estado contienen tus direcciones de cuentas públicas y transacciones envíadas" + }, + "stateLogError": { + "message": "Error en la recogida de logs de estado" }, "status": { "message": "Estado" @@ -582,11 +753,23 @@ "submit": { "message": "Enviar" }, + "submitted": { + "message": "Enviado" + }, + "supportCenter": { + "message": "Visita nuestro centro de atención" + }, + "symbolBetweenZeroTen": { + "message": "Símbolo debe ser entre 0 y 10 caracteres" + }, "takesTooLong": { - "message": "¿Está tomando demasiado?" + "message": "¿Está tardando demasiado?" + }, + "terms": { + "message": "Términos de uso" }, "testFaucet": { - "message": "Testear Faucet" + "message": "Probar Faucet" }, "to": { "message": "Para:" @@ -595,24 +778,45 @@ "message": "$1 a ETH via ShapeShift", "description": "el sistema llenará el tipo de depósito al principio del mensaje" }, + "tokenAddress": { + "message": "Dirección del token" + }, + "tokenAlreadyAdded": { + "message": "El token está actualmente agregado" + }, "tokenBalance": { - "message": "Tu balance de Tokens es:" + "message": "Tu balance de tokens es:" + }, + "tokenSelection": { + "message": "Busca tokens o selecciónalo de nuestra lista de tokens populares" + }, + "tokenSymbol": { + "message": "Símbolo del token" + }, + "tokenWarning1": { + "message": "Mantén un registro de los tokens que has comprado con tu cuenta de MetaMask. Si compraste tokens usando una cuenta diferente, esos tokens no aparecerán aquí." }, "total": { "message": "Total" }, "transactionMemo": { - "message": "Memo de transaccion (opcional)" + "message": "Memo de transacción (opcional)" }, "transactionNumber": { "message": "Número de transacción" }, + "transactions": { + "message": "Transacciones" + }, "transfers": { "message": "Transferencias" }, "troubleTokenBalances": { - "message": "Tuvimos problemas para cargar sus balances de tokens. Puedes verlos ", - "description": "Followed by a link (here) to view token balances" + "message": "Tuvimos problemas para cargar tus saldos de tokens. Puedes verlos ", + "description": "Seguidos por un enlace (aquí) para ver los saldos de token" + }, + "twelveWords": { + "message": "Estas 12 palabras son la única forma de restablecer tus cuentas de MetaMask. \nGuárdalas en un lugar seguro y secreto." }, "typePassword": { "message": "Escribe tu contraseña" @@ -621,11 +825,14 @@ "message": "Bienvenido a la nueva UI (Beta)" }, "uiWelcomeMessage": { - "message": "Estás usando la nueva UI de MetaMask. Echa un vistazo alrededor, prueba las nuevas características, tales como mandar tokens, y déjanos saber si tienes algún problema" + "message": "Estás usando la nueva UI de MetaMask. Echa un vistazo alrededor, prueba las nuevas características, tales como mandar tokens, y háznos saber si tienes algún problema" }, "unavailable": { "message": "No disponible" }, + "unapproved": { + "message": "No aprobado" + }, "unknown": { "message": "Desconocido (a)" }, @@ -633,208 +840,49 @@ "message": "Red privada desconocida" }, "unknownNetworkId": { - "message": "ID (identidad) de Red desconocida" + "message": "ID (identidad) de red desconocida" }, - "currentNetwork": { - "message": "Red actual" + "uriErrorMsg": { + "message": "URI necesita el prefijo HTTP/HTTPS apropiado" }, "usaOnly": { "message": "Sólo USA (Estados Unidos)", - "description": "El uso de este exchange (casa de cambio) estaá limitado a las personas dentro de los Estados Unidos de America" + "description": "El uso de este exchange (casa de cambio) está limitado a las personas dentro de los Estados Unidos de América" + }, + "useOldUI": { + "message": "Usar UI antigua" }, "usedByClients": { "message": "Utilizado por una variedad de clientes diferentes" }, - "viewAccount": { - "message": "Mirar cuenta" - }, - "warning": { - "message": "Advertencia" - }, - "whatsThis": { - "message": "Qué es esto?" - }, - "yourSigRequested": { - "message": "Tu firma ya fue solicidada" - }, - "youSign": { - "message": "Usted está firmando" - }, - "importedAccountMsg": { - "message": "Cuentas importadas no serán asociadas con tu cuenta original creada con tu MetaMask. Aprende más acerca de importar cuentas. " - }, - "selectType": { - "message": "Seleccionar tipo" - }, - "selectCurrency": { - "message": "Seleccionar moneda" - }, - "password": { - "message": "Contraseña" - }, - "select": { - "message": "Seleccionar" - }, - "readMore2": { - "message": "Leer más." - }, - "secretPhrase": { - "message": "Ingresa tu frase de 12 palabras para restaurar tu bóveda" - }, - "spaceBetween": { - "message": "Sólo puede haber un espacio entre las palabras" - }, - "loweCaseWords": { - "message": "las frases semilla sólo pueden tener minúsculas" - }, - "seedPhraseReq": { - "message": "las frases semilla tienen doce (12) palabras de largo" - }, - "addTokens": { - "message": "Agregar tokens" - }, - "addCustomTokens": { - "message": "Agregar token personalizados" - }, - "up": { - "message": "arriba" - }, - "down": { - "message": "abajo" - }, - "tokenWarning1": { - "message": "Mantenga un registro de los tokens que ha comprado con su cuenta de MetaMask. Si compraste tokens usando una cuenta diferente, esos tokens no aparecerán aquí." - }, - "tokenSelection": { - "message": "Busca tokens o selecciónalo de nuestra lista de tokens populares" - }, - "search": { - "message": "Buscar" - }, - "privacyMsg": { - "message": "Política de privacidad" - }, - "terms": { - "message": "Terminos de Uso" - }, - "attributions": { - "message": "Atribuciones" + "validFileImport": { + "message": "Debes selecionar un archivo valido para importar" }, - "supportCenter": { - "message": "Visita nuestro centro de atención" + "vaultCreated": { + "message": "Bóveda creada" }, - "knowledgeDataBase": { - "message": "Visita nuestra base de conocimiento" + "viewAccount": { + "message": "Mirar cuenta" }, "visitWebSite": { "message": "Visita nuestro sitio web" }, - "followTwitter": { - "message": "Síguenos en Twitter" - }, - "emailUs": { - "message": "Envíanos un correo!" - }, - "hereList": { - "message": "Aquí está una lista!!!" - }, - "insufficientFounds": { - "message": "Fondos insuficientes" - }, - "insufficientTokens": { - "message": "Tokens insuficientes" + "walletSeed": { + "message": "Semilla de la billetera" }, - "negativeETH": { - "message": "No se pueden mandar cantidades negativas de ETH" - }, - "urlErrorMsg": { - "message": "URI necesita el prefijo HTTP/HTTPS apropiado" - }, - "invalidRPC": { - "message": "Invalida URL del RPC" - }, - "saveLogs": { - "message": "Logs de estado contienen tus direcciones publicas y transacciones enviadas" - }, - "stateLogs": { - "message": "Logs de estado" - }, - "downloadStateLogs": { - "message": "Descargar logs de estados" - }, - "revealSeedWords": { - "message": "Revelar palabras de semilla" - }, - "revealSeedWordsWarning": { - "message": "No recuperes tu semilla en un lugar publico! Esas palabras pueden ser usadas para robarte todas tus cuentas" - }, - "resetAccount": { - "message": "Reiniciar cuenta" - }, - "builtInCalifornia": { - "message": "Metamask fue diseñado y construido en California " - }, - "classicInterface": { - "message": "Usar interfaz clasica " + "warning": { + "message": "Advertencia" }, "welcomeBeta": { "message": "Bienvenido a Metamask Beta" }, - "metamaskDescription": { - "message": "Metamask es una identidad segura en Ethereum" - }, - "holdEther": { - "message": "Te permite mantener tus ether y tokens, así como puente para aplicaciones descentralizadas" - }, - "decimalsMustZerotoTen": { - "message": "Los decimales deben ser al menos 0 y no más de 36" - }, - "symbolBetweenZeroTen": { - "message": "Símbolo debe ser entre 0 y 10 caracteres" - }, - "personalAddressDetected": { - "message": "Dirección personal detectada. Ingresa la dirección del contrato del token" - }, - "tokenAlreadyAdded": { - "message": "El token esta actualmente agregado" - }, - "mustSelectOne": { - "message": "Debe seleccionar al menos un (1) token" - }, - "tokenAddress": { - "message": "Dirección del token" - }, - "tokenSymbol": { - "message": "Símbolo del token" - }, - "decimalsPrecision": { - "message": "Decimales de precisión" - }, - "likeToAddTokens": { - "message": "¿Te gustaría agregar estos tokens?" - }, - "msgCompose1": { - "message": "Solo manda " - }, - "msgCompose2": { - "message": " a una dirección de Ethereum" - }, - "blockiesIdenticon": { - "message": "Usar Blockies Identicon (Iconos)" - }, - "vaultCreated": { - "message": "Bóveda creada" - }, - "twelveWords": { - "message": "Estas 12 palabras son la única forma de restablecer sus cuentas de MetaMask. \nGuardalas en un lugar seguro y secreto." - }, - "copiedSafe": { - "message": "Ya lo guardé en un lugar seguro" + "whatsThis": { + "message": "¿Qué es esto?" }, - "saveSeedAsFile": { - "message": "Guardar la semilla como archivo" + "youSign": { + "message": "Usted está firmando" }, - "restoreFromSeed": { - "message": "Restaurar desde semilla" + "yourSigRequested": { + "message": "Tu firma ya fue solicitada" } -} \ No newline at end of file +} diff --git a/app/_locales/es_419/messages.json b/app/_locales/es_419/messages.json deleted file mode 100644 index 78fc64dbf..000000000 --- a/app/_locales/es_419/messages.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "appName": { - "message": "MetaMask", - "description": "The name of the application" - }, - "appDescription": { - "message": "Administración de identidad en Ethereum", - "description": "The description of the application" - } -} diff --git a/app/_locales/hn/messages.json b/app/_locales/hn/messages.json new file mode 100644 index 000000000..3703faa13 --- /dev/null +++ b/app/_locales/hn/messages.json @@ -0,0 +1,819 @@ +{ + "accept": { + "message": "स्वीकार करें" + }, + "account": { + "message": "खाता" + }, + "accountDetails": { + "message": "खाता विवरण" + }, + "accountName": { + "message": "खाता का नाम" + }, + "address": { + "message": "खाते का पता" + }, + "addCustomToken": { + "message": "कस्टम टोकन जोड़ें" + }, + "addToken": { + "message": "टोकन जोड़ें" + }, + "addTokens": { + "message": "टोकनो को जोड़ें" + }, + "amount": { + "message": "राशि" + }, + "amountPlusGas": { + "message": "राशि + गैस" + }, + "appDescription": { + "message": "एथरेम ब्राउज़र एक्सटेंशन", + "description": "आवेदन का विवरण" + }, + "appName": { + "message": "मेटामास्क/MetaMask", + "description": "एप्लिकेशन का नाम" + }, + "attemptingConnect": { + "message": "ब्लॉकचैन से कनेक्ट करने का प्रयास करना होगा।सब्र करे।" + }, + "attributions": { + "message": "एट्रिब्यूशन" + }, + "available": { + "message": "एट्रिब्यूशन उपलब्ध ह्ने" + }, + "back": { + "message": "वापस" + }, + "balance": { + "message": "उपलब्ध बैलेंस।" + }, + "balances": { + "message": "ापके उपलब्ध बैलेंस" + }, + "balanceIsInsufficientGas": { + "message": "वर्तमान गैस कुल के लिए अपर्याप्त शेष" + }, + "beta": { + "message": "BETA/बीटा" + }, + "betweenMinAndMax": { + "message": "$1 के बराबर या ज्यदा या, $2 के बराबर या कम होना चाहिए।", + "description": "हेक्स इनपुट के लिए दशमलव इनपुट के रूप में सहायक" + }, + "blockiesIdenticon": { + "message": "ब्लॉकीज पहचान का उपयोग करें" + }, + "borrowDharma": { + "message": "धर्मा (बीटा) से / के साथ उधार लें" + }, + "builtInCalifornia": { + "message": "मेटामास्क कैलिफ़ोर्निया में डिज़ाइन और बनाया गया है।" + }, + "buy": { + "message": "खरीदें" + }, + "buyCoinbase": { + "message": "कॉनबेस पर खरीदें" + }, + "buyCoinbaseExplainer": { + "message": "बिल्टकोइन, एथरेम और लाइटकोइन खरीदने और बेचने के लिए दुनिया का सबसे लोकप्रिय तरीका Coinbase है।" + }, + "cancel": { + "message": "रद्द करें" + }, + "classicInterface": { + "message": "क्लासिक इंटरफ़ेस का उपयोग क" + }, + "clickCopy": { + "message": "कॉपी करने के लिए क्लिक करें" + }, + "confirm": { + "message": "पुष्टि करें" + }, + "confirmContract": { + "message": "अनुबंध की पुष्टि करें" + }, + "confirmPassword": { + "message": "पासवर्ड की पुष्टि करें" + }, + "confirmTransaction": { + "message": "लेनदेन की पुष्टि करें" + }, + "continue": { + "message": "जारी रखें" + }, + "continueToCoinbase": { + "message": "कॉ्ोनबेस को ब्हेजना जारी रखें" + }, + "contractDeployment": { + "message": "अनुबंध परिनियोजन व तैनाती" + }, + "conversionProgress": { + "message": "रूपांतरण प्रगति में हे।" + }, + "copiedButton": { + "message": "कॉपी किया गया" + }, + "copiedClipboard": { + "message": "क्लिपबोर्ड पर कॉपी किया गया" + }, + "copiedExclamation": { + "message": "कॉपी कर दिया गया!" + }, + "copiedSafe": { + "message": "मैंने इसे कहीं सुरक्षित कॉपी कर दिया है" + }, + "copy": { + "message": "कॉपी / प्रतिलिपि कर्रे" + }, + "copyToClipboard": { + "message": "क्लिपबोर्ड पर कॉपी करें" + }, + "copyButton": { + "message": " कॉपी / प्रतिलिपि कर्रे [बत्तन] " + }, + "copyPrivateKey": { + "message": "यह आपकी निजी कुंजी है (कॉपी करने के लिए क्लिक करें)।" + }, + "create": { + "message": "बनाएं" + }, + "createAccount": { + "message": "खाता बनाएं" + }, + "createDen": { + "message": "डेन बनाएं" + }, + "crypto": { + "message": "क्रिप्टो", + "description": "एक्सचेंज टाइप (क्रिप्टोक्यूचरस)" + }, + "currentConversion": { + "message": "वर्तमान रूपांतरण" + }, + "currentNetwork": { + "message": "वर्तमान नेटवर्क" + }, + "customGas": { + "message": "अनुकूलित करें गैस" + }, + "customize": { + "message": "अनुकूलित करें" + }, + "customRPC": { + "message": "कस्टम RPC" + }, + "decimalsMustZerotoTen": { + "message": "दशमलव कम से कम 0 होनी चाहिए, और 36 से अधिक नहीं होनी चाहिए।" + }, + "decimal": { + "message": "दशमलव परिशुद्धता" + }, + "defaultNetwork": { + "message": "ईथर लेनदेन के लिए डिफ़ॉल्ट नेटवर्क मुख्य नेट है।" + }, + "denExplainer": { + "message": "आपका डेन मेटामास्क के भीतर आपका पासवर्ड-एन्क्रिप्टेड स्टोरेज है।" + }, + "deposit": { + "message": "जमा" + }, + "depositBTC": { + "message": "नीचे दिए गए पते पर अपना बीटीसी जमा करें:" + }, + "depositCoin": { + "message": "नीचे दिए गए पते पर अपना $1 जमा करें", + "description": "उपयोगकर्ता को बताता है कि उन्होंने सिक्का के साथ जमा करने के लिए किस सिक्का का चयन किया है" + }, + "depositEth": { + "message": "Eth जमाआर्थ" + }, + "depositEther": { + "message": "जमा - Ether" + }, + "depositFiat": { + "message": "फिएट के साथ जमा हो" + }, + "depositFromAccount": { + "message": "दूसरे खाते से जमा करें" + }, + "depositShapeShift": { + "message": "शेपशिप के साथ जमा करें" + }, + "depositShapeShiftExplainer": { + "message": "यदि आप अन्य क्रिप्टोकाउंटरज रखते हैं, तो आप सीधे मेटामास्क वॉलेट में ईथर को व्यापार और जमा कर सकते हैं। कोई खाता आवश्यक नहीं है।" + }, + "details": { + "message": "संदेश विवरण" + }, + "directDeposit": { + "message": "प्रत्यक्ष जमा" + }, + "directDepositEther": { + "message": "सीधे ईथर जमा करें" + }, + "directDepositEtherExplainer": { + "message": "यदि आपके पास पहले से कुछ ईथर है, तो सीधे जमा द्वारा अपने नए बटुए में ईथर प्राप्त करने का तेज़ तरीका है।" + }, + "done": { + "message": "संपन्न" + }, + "downloadStatelogs": { + "message": "राज्य लॉग डाउनलोड करें" + }, + "edit": { + "message": "संपादित करें" + }, + "editAccountName": { + "message": "खाता नाम संपादित करें" + }, + "emailUs": { + "message": "हमें ईमेल करें!" + }, + "encryptNewDen": { + "message": "अपना नया डेन एन्क्रिप्ट करें" + }, + "enterPassword": { + "message": "पासवर्ड दर्ज करें" + }, + "enterPasswordConfirm": { + "message": "पुष्टि करने के लिए अपना पासवर्ड दर्ज करें" + }, + "etherscanView": { + "message": "ईथरस्कैन पर खाता देखें" + }, + "exchangeRate": { + "message": "विनिमय दरै" + }, + "exportPrivateKey": { + "message": "निजी कुंजी निर्यात करें" + }, + "exportPrivateKeyWarning": { + "message": "अपने जोखिम पर निजी कुंजी निर्यात करें।" + }, + "failed": { + "message": "विफल" + }, + "fiat": { + "message": "FIAT एक्सचेंज टाइप", + "description": "एक्सचेंज FIAT टाइप" + }, + "fileImportFail": { + "message": "फ़ाइल आयात काम नहीं कर रहा है? यहां क्लिक करें!", + "description": "यूजर को अपने खाते को जे.एस.ौ.एन फ़ाइल से आयात करने में मदद करता है" + }, + "followTwitter": { + "message": "हमें ट्विटर पर अनुसरण करें" + }, + "from": { + "message": "की तरफ से - संदेश" + }, + "fromToSame": { + "message": "से और पता करने के लिए समान नहीं हो सकता" + }, + "fromShapeShift": { + "message": "सेशशशफ्ट का" + }, + "gas": { + "message": "गैस की लागत", + "description": "गैस की लागत का संक्षिप्त संकेत" + }, + "gasFee": { + "message": "गैस शुल्क" + }, + "gasLimit": { + "message": "गैस सीमा" + }, + "gasLimitCalculation": { + "message": "हम नेटवर्क की सफलता दर के आधार पर सुझाई गई गैस सीमा की गणना करते हैं।" + }, + "gasLimitRequired": { + "message": "गैस सीमा आवश्यक" + }, + "gasLimitTooLow": { + "message": "२१००० - गैस की सीमा कम से कम 21000 होनी चाहिए" + }, + "generatingSeed": { + "message": "सृजन बीज उत्पन्न ... उत्पन्न ...उत्पन्न..." + }, + "gasPrice": { + "message": "गैस मूल्य (जीडब्ल्यूईआई),(GWEI)" + }, + "gasPriceCalculation": { + "message": "हम नेटवर्क की सफलता दर के आधार पर सुझाए गए गैस की कीमतों की गणना करते हैं।" + }, + "gasPriceRequired": { + "message": "गैस की कीमत आवश्यक है" + }, + "getEther": { + "message": "ईथर प्राप्त करें" + }, + "getEtherFromFaucet": { + "message": "$1 के लिए एक नल से ईथर प्राप्त करें", + "description": "ईथर नल के लिए नेटवर्क नाम प्रदर्शित करता है" + }, + "greaterThanMin": { + "message": "$1 के बराबर या बराबर होना चाहिए।", + "description": "हेक्स इनपुट के लिए दशमलव इनपुट के रूप में सहायक" + }, + "here": { + "message": "यहां", + "description": "अधिक जानकारी के लिए यहां क्लिक करें- (परेशानी के साथ जाता है टोकनबैलेंस) (troubleTokenBalances)" + }, + "hereList": { + "message": "यहां एक सूची है !!!!" + }, + "hide": { + "message": "छुपाएं" + }, + "hideToken": { + "message": "टोकन छिपाएं" + }, + "hideTokenPrompt": { + "message": "टोकन छिपाएंn?" + }, + "howToDeposit": { + "message": "आप ईथर जमा कैसे करना चाहेंगे?" + }, + "holdEther": { + "message": "यह आपको आकाश और टोकन रखने की अनुमति देता है, और विकेंद्रीकृत अनुप्रयोगों के लिए आपके पुल के रूप में कार्य करता है।" + }, + "import": { + "message": "आयात", + "description": "एक चयनित फ़ाइल से एक खाता आयात करने के लिए बटन " + }, + "importAccount": { + "message": "खाता आयात" + }, + "importAccountMsg": { + "message": "आयात किए गए खाते आपके मूल रूप से बनाए गए मेटामास्क अकाउंट सीडफ्रेज से संबद्ध नहीं होंगे। आयात किए गए खातों के बारे में और जानें" + }, + "importAnAccount": { + "message": "खाता आयात करैॉ" + }, + "importDen": { + "message": "मौजूदा डेन आयात करें - DEN" + }, + "imported": { + "message": "आयातित", + "description": "यह स्थिति दिखाती है कि कोई खाता पूरी तरह से कीरिंग में लोड हो चुका है" + }, + "infoHelp": { + "message": "जानकारी और सहायता" + }, + "insufficientFunds": { + "message": "अपर्याप्त धन" + }, + "insufficientTokens": { + "message": "अपर्याप्त टोकन।" + }, + "invalidAddress": { + "message": "अमान्य पता" + }, + "invalidAddressRecipient": { + "message": "प्राप्तकर्ता का पता अमान्य है" + }, + "invalidGasParams": { + "message": "अमान्य गैस पैरामीटर" + }, + "invalidInput": { + "message": "अमान्य इनपुट।" + }, + "invalidRequest": { + "message": "अमान्य अनुरोध" + }, + "invalidRPC": { + "message": "अमान्य RPC कै URI" + }, + "jsonFail": { + "message": "कुछ गलत हो गया। कृपया सुनिश्चित करें कि आपकी JSON फ़ाइल ठीक से फ़ॉर्मेट की गई है।" + }, + "jsonFile": { + "message": "JSON फ़ाइल", + "description": "एक खाता आयात करने के लिए प्रारूप" + }, + "kovan": { + "message": "कोवान टेस्ट नेटवर्क" + }, + "knowledgeDataBase": { + "message": "हमारे नॉलेज बेस पर जाएं" + }, + "lessThanMax": { + "message": "$1 से कम या बराबर होना चाहिए।", + "description": "हेक्स इनपुट के लिए दशमलव इनपुट के रूप में सहायक" + }, + "likeToAddTokens": { + "message": "क्या आप इन टोकनों को जोड़ना चाहते हैं?" + }, + "limit": { + "message": "सीमा" + }, + "loading": { + "message": "लोड हो रहा है ....." + }, + "loadingTokens": { + "message": "टोकन लोड हो रहा है ....." + }, + "localhost": { + "message": "स्थानीयहोस्ट 8545" + }, + "login": { + "message": "लॉग इन करें" + }, + "logout": { + "message": "लॉग आउट करें" + }, + "loose": { + "message": "ढीला" + }, + "loweCaseWords": { + "message": "बीज शब्द में केवल लोअरकेस वर्ण होते हैं" + }, + "mainnet": { + "message": "मुख्य ईथरम नेटवर्क" + }, + "message": { + "message": "संदेश" + }, + "metamaskDescription": { + "message": "मेटामास्क एथर्मम के लिए एक सुरक्षित पहचान वॉल्ट है।" + }, + "min": { + "message": "न्यूनतम" + }, + "myAccounts": { + "message": "मेरे खाते" + }, + "mustSelectOne": { + "message": "कम से कम 1 टोकन का चयन करना आवश्यक है।" + }, + "needEtherInWallet": { + "message": "मेटामास्क का उपयोग करने वाले विकेन्द्रीकृत अनुप्रयोगों के साथ बातचीत करने के लिए, आपको अपने वॉलेट में ईथर की आवश्यकता होगी।" + }, + "needImportFile": { + "message": "आयात करने के लिए आपको एक फ़ाइल का चयन करना होगा।", + "description": "प्रयोक्ता महत्वपूर्ण खाता है और उसे जारी रखने के लिए एक फ़ाइल जोड़ने की आवश्यकता है" + }, + "needImportPassword": { + "message": "चयनित फ़ाइल के लिए आपको एक पासवर्ड दर्ज करना होगा।", + "description": "पासवर्ड और फाइल को एक खाते आयात करने के लिए आवश्यक है" + }, + "negativeETH": { + "message": "ईटीएच की नकारात्मक मात्रा नहीं भेज सकते हैं।." + }, + "networks": { + "message": "नेटवर्क" + }, + "newAccount": { + "message": "नया खाता" + }, + "newAccountNumberName": { + "message": "नया खाता $1", + "description": "खाते का खाता बनाने पर अगले खाते का डिफ़ॉल्ट नाम" + }, + "newContract": { + "message": "नया अनुबंध" + }, + "newPassword": { + "message": "नया पासवर्ड (न्यूनतम 8 वर्ण)" + }, + "newRecipient": { + "message": "नया प्राप्तकर्ता" + }, + "newRPC": { + "message": "नया RPC URL" + }, + "next": { + "message": "अगला" + }, + "noAddressForName": { + "message": "इस नाम के लिए कोई पता सेट नहीं किया गया है।" + }, + "noDeposits": { + "message": "कोई जमा प्राप्त नहीं हुई" + }, + "noTransactionHistory": { + "message": "कोई लेनदेन इतिहास नहीं ..." + }, + "noTransactions": { + "message": "कोई लेन-देन नहीं" + }, + "notStarted": { + "message": "प्रारंभ नहीं किया गया" + }, + "oldUI": { + "message": "पुराना UI" + }, + "oldUIMessage": { + "message": "आप पुराने UI पर वापस आ गए हैं। आप ऊपर दाईं ओर ड्रॉपडाउन मेनू में विकल्प के माध्यम से नए UI पर वापस स्विच कर सकते हैं।" + }, + "or": { + "message": "या", + "description": "एक नया खाता बनाने या आयात करने के बीच की पसंद" + }, + "passwordCorrect": { + "message": "कृपया सुनिश्चित करें कि आपका पासवर्ड सही है।" + }, + "passwordMismatch": { + "message": "पासवर्ड मेल नहीं खाते", + "description": "पासवर्ड निर्माण प्रक्रिया में, दो नए पासवर्ड फ़ील्ड मेल नहीं खाते" + }, + "passwordShort": { + "message": "पासवर्ड पर्याप्त लंबा नहीं", + "description": "पासवर्ड बनाने की प्रक्रिया में, पासवर्ड सुरक्षित होने के लिए पर्याप्त नहीं है" + }, + "pastePrivateKey": { + "message": "यहां अपनी निजी कुंजी स्ट्रिंग चिपकाएं:", + "description": "किसी निजी कुंजी से किसी खाते को आयात करने के लिए" + }, + "pasteSeed": { + "message": "यहां अपने बीज वाक्यांश पेस्ट करें!" + }, + "personalAddressDetected": { + "message": "व्यक्तिगत पता मिला। टोकन अनुबंध का पता इनपुट।" + }, + "pleaseReviewTransaction": { + "message": "कृपया अपने लेनदेन की समीक्षा करें।" + }, + "privacyMsg": { + "message": "गोपनीयता नीति" + }, + "privateKey": { + "message": "निजी कुंजी", + "description": "खाता आयात करने के लिए उपयोग करने के लिए इस प्रकार की फ़ाइल का चयन करें" + }, + "privateKeyWarning": { + "message": "चेतावनी: कभी भी इस कुंजी का खुलासा न करें। आपकी निजी कुंजी वाले कोई भी आपके खाते में रखी किसी भी संपत्ति को चुरा सकता है।" + }, + "privateNetwork": { + "message": "निजी नेटवर्क" + }, + "qrCode": { + "message": "QR कोड दिखाएं" + }, + "readdToken": { + "message": "आप अपने खाता विकल्प मेनू में .टोकन जोड़ें. पर जाकर भविष्य में इस टोकन को वापस जोड़ सकते हैं।" + }, + "readMore": { + "message": "यहां और पढ़ें।" + }, + "readMore2": { + "message": "हां - और पढ़ें।" + }, + "receive": { + "message": "प्राप्त करें" + }, + "recipientAddress": { + "message": "प्राप्तकर्ता पता" + }, + "refundAddress": { + "message": "आपका रिफंड पता" + }, + "rejected": { + "message": "अस्वीकृत" + }, + "resetAccount": { + "message": "खाता रीसेट करें" + }, + "restoreFromSeed": { + "message": "बीज वाक्यांश से पुनर्स्थापित करें" + }, + "required": { + "message": "आवश्यक" + }, + "retryWithMoreGas": { + "message": "यहां एक उच्च गैस कीमत के साथ पुन: प्रयास करें" + }, + "revealSeedWords": { + "message": "बीज शब्द प्रकट करें" + }, + "revealSeedWordsWarning": { + "message": "किसी सार्वजनिक स्थान पर अपने बीज के शब्द ठीक नहीं करें! ये शब्द आपके सभी खातों को चोरी करने के लिए उपयोग किए जा सकते हैं।" + }, + "revert": { + "message": "वापस" + }, + "rinkeby": { + "message": "रिचीव टेस्ट नेटवर्क" + }, + "ropsten": { + "message": "रॉप्स्टेन टेस्ट नेटवर्क" + }, + "sampleAccountName": { + "message": "उदाहरण के लिए मेरा नया खाता", + "description": "उपयोगकर्ता को अपने खाते में मानव-पठनीय नाम जोड़ने की अवधारणा को समझें." + }, + "save": { + "message": "सहेजें" + }, + "saveAsFile": { + "message": "फ़ाइल के रूप में सहेजें", + "description": "खाता निर्यात प्रक्रिया" + }, + "saveSeedAsFile": { + "message": "सेड वर्ड्स - फाईल्स सेव करें" + }, + "search": { + "message": "खोज करें" + }, + "secretPhrase": { + "message": "अपनी गुप्त बारह शब्द वाक्यांश यहाँ अपनी तिजोरी को पुनर्स्थापित करने के लिए दर्ज करें।" + }, + "seedPhraseReq": { + "message": "बीज वाक्यांश 12 शब्द लंबा हैं" + }, + "select": { + "message": "चुनें" + }, + "selectCurrency": { + "message": "मुद्रा चुनें" + }, + "selectService": { + "message": "सेवा चुनें" + }, + "selectType": { + "message": "प्रकार चुनें" + }, + "send": { + "message": "भेजें" + }, + "sendETH": { + "message": "भेजें ETH" + }, + "sendTokens": { + "message": "भेजें टोकन" + }, + "sendTokensAnywhere": { + "message": "इटोरम खाते वाले किसी को भी टोकन भेजें" + }, + "settings": { + "message": "सेटिंग्स" + }, + "shapeshiftBuy": { + "message": "शेपेशिस्ट के साथ खरीदें" + }, + "showPrivateKeys": { + "message": "निजी कुंजी दिखाएँ" + }, + "showQRCode": { + "message": "QR कोड दिखाएं" + }, + "sign": { + "message": "हस्ताक्षर" + }, + "signMessage": { + "message": "हस्ताक्षर संदेश" + }, + "signNotice": { + "message": "इस संदेश पर हस्ताक्षर करने से \n साइड इफेक्ट हो सकते हैं। \n केवल अपने पूरे खाते के साथ पूरी तरह से भरोसेमंद \n साइटों से संदेश पर हस्ताक्षर करें। \n यह खतरनाक विधि भविष्य के संस्करण में निकाल दी जाएगी।" + }, + "sigRequest": { + "message": "हस्ताक्षर अनुरोध" + }, + "sigRequested": { + "message": "हस्ताक्षर अनुरोधित" + }, + "spaceBetween": { + "message": "केवल शब्दों के बीच एक स्थान हो सकता है" + }, + "status": { + "message": "स्थिति" + }, + "stateLogs": { + "message": "स्थिति संदेश" + }, + "stateLogsDescription": { + "message": "स्थिति संदेश में आपका सार्वजनिक खाता, पतों और भेजे गए लेनदेन, होते हैं।" + }, + "submit": { + "message": "सबमिट करें" + }, + "supportCenter": { + "message": "हमारे सहायता केंद्र पर जाएं" + }, + "symbolBetweenZeroTen": { + "message": "प्रतीक 0 और 10 अक्षरों के बीच होना चाहिए" + }, + "takesTooLong": { + "message": "बहुत समय ले रहा है?" + }, + "terms": { + "message": "उपयोग की शर्तें" + }, + "testFaucet": { + "message": "टेस्ट नलि" + }, + "to": { + "message": "के लिए" + }, + "toETHviaShapeShift": { + "message": "शैपशैफ्ट द्वारा $1 से ETH में जमा", + "description": "संदेश की शुरुआत में जमा प्रकार भर जाएगा" + }, + "tokenAddress": { + "message": "टोकन पता" + }, + "tokenAlreadyAdded": { + "message": "टोकन पहले ही जोड़ा जा चुका है।" + }, + "tokenBalance": { + "message": "आपका टोकन बैलेंस है:" + }, + "tokenSelection": { + "message": "टोकन के लिए खोजें या हमारी लोकप्रिय टॉकेन्स की सूची से चुनें।" + }, + "tokenSymbol": { + "message": "टोकन प्रतीक" + }, + "tokenWarning1": { + "message": "अपने मेटामास्क अकाउंट से खरीदे गए टोकनों का नज़र रखें। अगर आप किसी अलग खाते का उपयोग कर टोकन खरीदे हैं, तो ये टोकन यहां दिखाई नहीं देंगे।" + }, + "total": { + "message": "कुल" + }, + "transactions": { + "message": "लेनदेन" + }, + "transactionMemo": { + "message": "लेनदेन मेमो (वैकल्पिक)" + }, + "transactionNumber": { + "message": "लेनदेन संख्या" + }, + "transfers": { + "message": "स्थानांतरण" + }, + "troubleTokenBalances": { + "message": "मुसीबत... आपके टोकन शेष राशि को लोड करने में हमें परेशानी हुई थी। आप उन्हें देख सकते हैं", + "description": "टोकन शेष देखने के लिए एक लिंक ... (यहां)" + }, + "twelveWords": { + "message": "ये 12 शब्द आपके मेटामास्क खातों को पुनर्स्थापित करने का एकमात्र तरीका है। \n उन्हें कहीं सुरक्षित और गुप्त रूप से सहेजें।" + }, + "typePassword": { + "message": "अपना पासवर्ड टाइप करें" + }, + "uiWelcome": { + "message": "नया यूआई (बीटा) में आपका स्वागत है" + }, + "uiWelcomeMessage": { + "message": "आप अब नए मेटामास्क UI का उपयोग कर रहे हैं। चारों ओर एक नज़र डालें, टोकन भेजने की तरह नई सुविधाएं देखें, और हमें बताएं कि आपके पास कोई समस्या है।" + }, + "unavailable": { + "message": "अनुपलब्ध" + }, + "unknown": { + "message": "अज्ञात नेटवर्क" + }, + "unknownNetwork": { + "message": "अज्ञात निजी नेटवर्क" + }, + "unknownNetworkId": { + "message": "अज्ञात नेटवर्क आईडी.य़" + }, + "uriErrorMsg": { + "message": "URI-यूआरआई को उपयुक्त HTTP / HTTPS उपसर्ग की आवश्यकता होती है।" + }, + "usaOnly": { + "message": "केवल यूएसए - USA", + "description": "इस एक्सचेंज का उपयोग करना संयुक्त राज्य अमेरिका के अंदर ही सीमित है" + }, + "usedByClients": { + "message": "विभिन्न क्लाइंट्स द्वारा उपयोग किया जाता है" + }, + "useOldUI": { + "message": "पुराने UI का उपयोग करें" + }, + "validFileImport": { + "message": "आयात करने के लिए आपको एक वैध फ़ाइल चुननी होगी।" + }, + "vaultCreated": { + "message": "वॉल्ट बनाया गया" + }, + "viewAccount": { + "message": "खाता देखें" + }, + "visitWebSite": { + "message": "हमारी वेब साइट पर जाएं" + }, + "warning": { + "message": "चेतावनी" + }, + "welcomeBeta": { + "message": "मेटामास्क बीटा में आपका स्वागत है" + }, + "whatsThis": { + "message": "यह क्या है?" + }, + "yourSigRequested": { + "message": "आपका हस्ताक्षर अनुरोध किया जा रहा है" + }, + "youSign": { + "message": "आप हस्ताक्षर कर रहे हैं" + } +} diff --git a/app/_locales/nl/messages.json b/app/_locales/nl/messages.json new file mode 100644 index 000000000..aacb81fee --- /dev/null +++ b/app/_locales/nl/messages.json @@ -0,0 +1,819 @@ +{ + "accept": { + "message": "Aanvaarden" + }, + "account": { + "message": "Account" + }, + "accountDetails": { + "message": "Accountgegevens" + }, + "accountName": { + "message": "Accountnaam" + }, + "address": { + "message": "Adres" + }, + "addCustomToken": { + "message": "Aangepaste token toevoegen" + }, + "addToken": { + "message": "Voeg token toe" + }, + "addTokens": { + "message": "Tokens toevoegen" + }, + "amount": { + "message": "Bedrag" + }, + "amountPlusGas": { + "message": "Bedrag + gas" + }, + "appDescription": { + "message": "Ethereum Browser-extensie", + "description": "De beschrijving van de applicatie" + }, + "appName": { + "message": "MetaMask", + "description": "De naam van de applicatie" + }, + "attemptingConnect": { + "message": "Poging om verbinding te maken met blockchain." + }, + "attributions": { + "message": "Bevoegdheden" + }, + "available": { + "message": "Beschikbaar" + }, + "back": { + "message": "Terug" + }, + "balance": { + "message": "Balans:" + }, + "balances": { + "message": "Je saldo" + }, + "balanceIsInsufficientGas": { + "message": "Onvoldoende saldo voor huidig ​​gastotaal" + }, + "beta": { + "message": "BETA" + }, + "betweenMinAndMax": { + "message": "moet groter zijn dan of gelijk zijn aan $1 en kleiner dan of gelijk aan $2.", + "description": "helper voor het invoeren van hex als decimale invoer" + }, + "blockiesIdenticon": { + "message": "Gebruik Blockies Identicon" + }, + "borrowDharma": { + "message": "Lenen met Dharma (Beta)" + }, + "builtInCalifornia": { + "message": "MetaMask is ontworpen en gebouwd in Californië." + }, + "buy": { + "message": "Kopen" + }, + "buyCoinbase": { + "message": "Koop op Coinbase" + }, + "buyCoinbaseExplainer": { + "message": "Coinbase is 's werelds populairste manier om bitcoin, ethereum en litecoin te kopen en verkopen." + }, + "cancel": { + "message": "Annuleer" + }, + "classicInterface": { + "message": "Gebruik de klassieke interface" + }, + "clickCopy": { + "message": "Klik om te kopiëren" + }, + "confirm": { + "message": "Bevestigen" + }, + "confirmContract": { + "message": "Contract bevestigen" + }, + "confirmPassword": { + "message": "bevestig wachtwoord" + }, + "confirmTransaction": { + "message": "Bevestig transactie" + }, + "continue": { + "message": "Doorgaan met" + }, + "continueToCoinbase": { + "message": "Ga verder naar Coinbase" + }, + "contractDeployment": { + "message": "Contractimplementatie" + }, + "conversionProgress": { + "message": "Bezig met conversie" + }, + "copiedButton": { + "message": "gekopieerde" + }, + "copiedClipboard": { + "message": "Gekopieerd naar het klembord" + }, + "copiedExclamation": { + "message": "Gekopieerde!" + }, + "copiedSafe": { + "message": "Ik heb het ergens veilig gekopieerd" + }, + "copy": { + "message": "Kopiëren" + }, + "copyToClipboard": { + "message": "Kopieer naar klembord" + }, + "copyButton": { + "message": " Kopiëren " + }, + "copyPrivateKey": { + "message": "Dit is uw privésleutel (klik om te kopiëren)" + }, + "create": { + "message": "creëren" + }, + "createAccount": { + "message": "Account aanmaken" + }, + "createDen": { + "message": "creëren" + }, + "crypto": { + "message": "crypto", + "description": "Ruiltype (cryptocurrencies)" + }, + "currentConversion": { + "message": "Huidige conversie" + }, + "currentNetwork": { + "message": "Huidig ​​netwerk" + }, + "customGas": { + "message": "Pas Gas aan" + }, + "customize": { + "message": "Aanpassen" + }, + "customRPC": { + "message": "Aangepaste RPC" + }, + "decimalsMustZerotoTen": { + "message": "Decimalen moeten minimaal 0 en niet meer dan 36 zijn." + }, + "decimal": { + "message": "Decimalen van precisie" + }, + "defaultNetwork": { + "message": "Het standaardnetwerk voor Ether-transacties is Main Net." + }, + "denExplainer": { + "message": "Uw DEN is uw wachtwoord-gecodeerde opslag binnen MetaMask." + }, + "deposit": { + "message": "Storting" + }, + "depositBTC": { + "message": "Stort uw BTC op het onderstaande adres:" + }, + "depositCoin": { + "message": "Stort uw $1 op het onderstaande adres", + "description": "Laat de gebruiker weten welk muntje ze hebben geselecteerd om te deponeren met shapeshift" + }, + "depositEth": { + "message": "Aanbetaling Eth" + }, + "depositEther": { + "message": "Stort Ether" + }, + "depositFiat": { + "message": "Stort met Fiat" + }, + "depositFromAccount": { + "message": "Storten van een ander account" + }, + "depositShapeShift": { + "message": "Stort met ShapeShift" + }, + "depositShapeShiftExplainer": { + "message": "Als u andere cryptocurrencies bezit, kunt u Ether direct in uw MetaMask-portemonnee ruilen en storten. Geen account nodig." + }, + "details": { + "message": "Details" + }, + "directDeposit": { + "message": "Directe storting" + }, + "directDepositEther": { + "message": "Directe Ether storten" + }, + "directDepositEtherExplainer": { + "message": "Als je al wat Ether hebt, de snelste manier om Ether in je nieuwe portemonnee te krijgen door een directe storting." + }, + "done": { + "message": "Gedaan" + }, + "downloadStatelogs": { + "message": "Staatslogboeken downloaden" + }, + "edit": { + "message": "Bewerk" + }, + "editAccountName": { + "message": "Bewerk accountnaam" + }, + "emailUs": { + "message": "Email ons!" + }, + "encryptNewDen": { + "message": "Versleutel je nieuwe DEN" + }, + "enterPassword": { + "message": "Voer wachtwoord in" + }, + "enterPasswordConfirm": { + "message": "Voer uw wachtwoord in om te bevestigen" + }, + "etherscanView": { + "message": "Bekijk account op Etherscan" + }, + "exchangeRate": { + "message": "Wisselkoers" + }, + "exportPrivateKey": { + "message": "Exporteer privésleutel" + }, + "exportPrivateKeyWarning": { + "message": "Exporteer privésleutels op eigen risico." + }, + "failed": { + "message": "mislukt" + }, + "fiat": { + "message": "FIAT", + "description": "Ruiltype" + }, + "fileImportFail": { + "message": "Bestandsimport werkt niet? Klik hier!", + "description": "Helpt de gebruiker om zijn account vanuit een JSON-bestand te importeren" + }, + "followTwitter": { + "message": "Volg ons op Twitter" + }, + "from": { + "message": "Van" + }, + "fromToSame": { + "message": "Van en naar adres kan niet hetzelfde zijn" + }, + "fromShapeShift": { + "message": "Van ShapeShift" + }, + "gas": { + "message": "Gas", + "description": "Korte indicatie van gaskosten" + }, + "gasFee": { + "message": "Gas vergoeding" + }, + "gasLimit": { + "message": "Gaslimiet" + }, + "gasLimitCalculation": { + "message": "We berekenen de voorgestelde gaslimiet op basis van succespercentages van het netwerk." + }, + "gasLimitRequired": { + "message": "Gaslimiet vereist" + }, + "gasLimitTooLow": { + "message": "De gaslimiet moet minstens 21000 zijn" + }, + "generatingSeed": { + "message": "Zaad produceren ..." + }, + "gasPrice": { + "message": "Gasprijs (GWEI)" + }, + "gasPriceCalculation": { + "message": "We berekenen de voorgestelde gasprijzen op basis van succespercentages van het netwerk." + }, + "gasPriceRequired": { + "message": "Gasprijs vereist" + }, + "getEther": { + "message": "Krijg Ether" + }, + "getEtherFromFaucet": { + "message": "Haal Ether uit een kraan voor de $1", + "description": "Geeft de netwerknaam voor Ether-kraan weer" + }, + "greaterThanMin": { + "message": "moet groter zijn dan of gelijk zijn aan $1.", + "description": "helper voor het invoeren van hex als decimale invoer" + }, + "here": { + "message": "hier", + "description": "zoals in -klik hier- voor meer informatie (gaat met troubleTokenBalances)" + }, + "hereList": { + "message": "Hier is een lijst !!!!" + }, + "hide": { + "message": "Verbergen" + }, + "hideToken": { + "message": "Token verbergen" + }, + "hideTokenPrompt": { + "message": "Token verbergen?" + }, + "howToDeposit": { + "message": "Hoe zou je Ether willen deponeren?" + }, + "holdEther": { + "message": "Hiermee kunt u ether & tokens bewaren en dient u als brug naar gedecentraliseerde applicaties." + }, + "import": { + "message": "Importeren", + "description": "Knop om een ​​account uit een geselecteerd bestand te importeren" + }, + "importAccount": { + "message": "Account importeren" + }, + "importAccountMsg": { + "message":" Geïmporteerde accounts worden niet gekoppeld aan de seedphrase van uw oorspronkelijk gemaakte MetaMask-account. Meer informatie over geïmporteerde accounts" + }, + "importAnAccount": { + "message": "Importeer een account" + }, + "importDen": { + "message": "Bestaande DEN importeren" + }, + "imported": { + "message": "geïmporteerde", + "description": "status die aantoont dat een account volledig in de sleutelring is geladen" + }, + "infoHelp": { + "message": "Info en hulp" + }, + "insufficientFunds": { + "message": "Onvoldoende fondsen." + }, + "insufficientTokens": { + "message": "Onvoldoende tokens." + }, + "invalidAddress": { + "message": "Ongeldig adres" + }, + "invalidAddressRecipient": { + "message": "Het adres van de ontvanger is ongeldig" + }, + "invalidGasParams": { + "message": "Ongeldige gasparameters" + }, + "invalidInput": { + "message": "Ongeldige invoer." + }, + "invalidRequest": { + "message": "ongeldig verzoek" + }, + "invalidRPC": { + "message": "Ongeldige RPC-URI" + }, + "jsonFail": { + "message": "Er is iets fout gegaan. Zorg ervoor dat uw JSON-bestand correct is opgemaakt." + }, + "jsonFile": { + "message": "JSON-bestand", + "description": "formaat voor het importeren van een account" + }, + "kovan": { + "message": "Kovan-testnetwerk" + }, + "knowledgeDataBase": { + "message": "Bezoek onze Knowledge Base" + }, + "lessThanMax": { + "message": "moet kleiner zijn dan of gelijk zijn aan $1.", + "description": "helper voor het invoeren van hex als decimale invoer" + }, + "likeToAddTokens": { + "message": "Wil je deze tokens toevoegen?" + }, + "limit": { + "message": "Begrenzing" + }, + "loading": { + "message": "Bezig met laden..." + }, + "loadingTokens": { + "message": "Tokens laden ..." + }, + "localhost": { + "message": "Localhost 8545" + }, + "login": { + "message": "Log in" + }, + "logout": { + "message": "Uitloggen" + }, + "loose": { + "message": "Los" + }, + "loweCaseWords": { + "message": "zaadwoorden hebben alleen kleine letters" + }, + "mainnet": { + "message": "belangrijkste ethereum-netwerk" + }, + "message": { + "message": "Bericht" + }, + "metamaskDescription": { + "message": "MetaMask is een veilige identiteitskluis voor Ethereum." + }, + "min": { + "message": "Minimum" + }, + "myAccounts": { + "message": "Mijn accounts" + }, + "mustSelectOne": { + "message": "Moet ten minste één token selecteren." + }, + "needEtherInWallet": { + "message": "Om te communiceren met gedecentraliseerde applicaties met MetaMask, heb je Ether nodig in je portemonnee." + }, + "needImportFile": { + "message": "U moet een bestand selecteren om te importeren.", + "description": "Gebruiker is belangrijk een account en moet een bestand toevoegen om door te gaan" + }, + "needImportPassword": { + "message": "U moet een wachtwoord invoeren voor het geselecteerde bestand.", + "description": "Wachtwoord en bestand nodig om een ​​account te importeren" + }, + "negativeETH": { + "message": "Kan geen negatieve hoeveelheden ETH verzenden." + }, + "networks": { + "message": "netwerken" + }, + "newAccount": { + "message": "Nieuw account" + }, + "newAccountNumberName": { + "message": "Account $1", + "description": "Standaardnaam van de volgende account die moet worden aangemaakt op het scherm voor het maken van een account" + }, + "newContract": { + "message": "Nieuw contract" + }, + "newPassword": { + "message": "Nieuw wachtwoord (min 8 tekens)" + }, + "newRecipient": { + "message": "Nieuwe ontvanger" + }, + "newRPC": { + "message": "Nieuwe RPC-URL" + }, + "next": { + "message": "volgende" + }, + "noAddressForName": { + "message": "Er is geen adres ingesteld voor deze naam." + }, + "noDeposits": { + "message": "Geen aanbetalingen ontvangen" + }, + "noTransactionHistory": { + "message": "Geen transactiegeschiedenis." + }, + "noTransactions": { + "message": "Geen transacties" + }, + "notStarted": { + "message": "Niet begonnen" + }, + "oldUI": { + "message": "Oude gebruikersinterface" + }, + "oldUIMessage": { + "message": "U bent teruggekeerd naar de oude gebruikersinterface. U kunt terugschakelen naar de nieuwe gebruikersinterface via de optie in het vervolgkeuzemenu in de rechterbovenhoek." + }, + "or": { + "message": "of", + "description": "keuze tussen het maken of importeren van een nieuw account" + }, + "passwordCorrect": { + "message": "Zorg ervoor dat uw wachtwoord correct is." + }, + "passwordMismatch": { + "message": "wachtwoorden komen niet overeen", + "description": "bij het maken van het wachtwoord kwamen de twee nieuwe wachtwoordvelden niet overeen" + }, + "passwordShort": { + "message": "wachtwoord niet lang genoeg", + "description": "bij het maken van het wachtwoord is het wachtwoord niet lang genoeg om veilig te zijn" + }, + "pastePrivateKey": { + "message": "Plak hier uw privésleutelstring:", + "description": "Voor het importeren van een account vanaf een privésleutel" + }, + "pasteSeed": { + "message": "Plak je zaadzin hier!" + }, + "personalAddressDetected": { + "message": "Persoonlijk adres gedetecteerd. Voer het tokencontractadres in." + }, + "pleaseReviewTransaction": { + "message": "Controleer uw transactie." + }, + "privacyMsg": { + "message": "Privacybeleid" + }, + "privateKey": { + "message": "Prive sleutel", + "description": "selecteer dit type bestand om te gebruiken om een ​​account te importeren" + }, + "privateKeyWarning": { + "message": "Waarschuwing: open deze sleutel nooit. Iedereen met uw privésleutels kan stelen van alle items in uw account." + }, + "privateNetwork": { + "message": "Prive netwerk" + }, + "qrCode": { + "message": "QR-code weergeven" + }, + "readdToken": { + "message": "U kunt dit token in de toekomst weer toevoegen door naar \"Token toevoegen\" te gaan in het menu met accountopties." + }, + "readMore": { + "message": "Lees hier meer." + }, + "readMore2": { + "message": "Lees verder." + }, + "receive": { + "message": "Te ontvangen" + }, + "recipientAddress": { + "message": "Geadresseerde adres" + }, + "refundAddress": { + "message": "Uw teruggave adres" + }, + "rejected": { + "message": "Verworpen" + }, + "resetAccount": { + "message": "Account opnieuw instellen" + }, + "restoreFromSeed": { + "message": "Herstel van zaaduitdrukking" + }, + "required": { + "message": "Verplicht" + }, + "retryWithMoreGas": { + "message": "Probeer hier opnieuw met een hogere gasprijs" + }, + "revealSeedWords": { + "message": "Onthul zaadwoorden" + }, + "revealSeedWordsWarning": { + "message": "Herstel je zaadwoorden niet op een openbare plaats! Deze woorden kunnen worden gebruikt om al uw accounts te stelen." + }, + "revert": { + "message": "terugkeren" + }, + "rinkeby": { + "message": "Rinkeby testnetwerk" + }, + "ropsten": { + "message": "Ropsten testnetwerk" + }, + "sampleAccountName": { + "message": "Bijv. Mijn nieuwe account", + "description": "Help de gebruiker begrip te ontwikkelen van het toevoegen van een door mensen leesbare naam aan zijn of haar account" + }, + "save": { + "message": "Opslaan" + }, + "saveAsFile": { + "message": "Sla op als bestand", + "description": "Account export proces" + }, + "saveSeedAsFile": { + "message": "Bewaar zaadwoorden als bestand" + }, + "search": { + "message": "Zoeken" + }, + "secretPhrase": { + "message": "Voer hier je geheime twaalfwoordfrase in om je kluis te herstellen." + }, + "seedPhraseReq": { + "message": "zaadzinnen zijn 12 woorden lang" + }, + "select": { + "message": "kiezen" + }, + "selectCurrency": { + "message": "selecteer valuta" + }, + "selectService": { + "message": "Selecteer Service" + }, + "selectType": { + "message": "Selecteer type" + }, + "send": { + "message": "Sturen" + }, + "sendETH": { + "message": "Verzend ETH" + }, + "sendTokens": { + "message": "Stuur tokens" + }, + "sendTokensAnywhere": { + "message": "Stuur tokens naar iedereen met een Ethereum-account" + }, + "settings": { + "message": "instellingen" + }, + "shapeshiftBuy": { + "message": "Koop met Shapeshift" + }, + "showPrivateKeys": { + "message": "Privésleutels weergeven" + }, + "showQRCode": { + "message": "QR-code weergeven" + }, + "sign": { + "message": "Teken" + }, + "signMessage": { + "message": "Teken bericht" + }, + "signNotice": { + "message": "Het ondertekenen van dit bericht kan hebben \ngevaarlijke bijwerkingen. Meld alleen berichten van \nsites die u volledig vertrouwt met uw volledige account.\n Deze gevaarlijke methode wordt in een toekomstige versie verwijderd." + }, + "sigRequest": { + "message": "Ondertekeningsverzoek" + }, + "sigRequested": { + "message": "Handtekening aangevraagd" + }, + "spaceBetween": { + "message": "er kan alleen een spatie tussen woorden zijn" + }, + "status": { + "message": "staat" + }, + "stateLogs": { + "message": "Staatslogboeken" + }, + "stateLogsDescription": { + "message": "Staatslogboeken bevatten uw openbare accountadressen en verzonden transacties." + }, + "submit": { + "message": "voorleggen" + }, + "supportCenter": { + "message": "Bezoek ons ​​ondersteuningscentrum" + }, + "symbolBetweenZeroTen": { + "message": "Het symbool moet tussen 0 en 10 tekens lang zijn." + }, + "takesTooLong": { + "message": "Duurt te lang?" + }, + "terms": { + "message": "Gebruiksvoorwaarden" + }, + "testFaucet": { + "message": "Test de kraan" + }, + "to": { + "message": "Naar" + }, + "toETHviaShapeShift": { + "message": "$1 tot ETH via ShapeShift", + "description": "systeem zal het aanbetalingstype invullen bij het begin van het bericht" + }, + "tokenAddress": { + "message": "Token-adres" + }, + "tokenAlreadyAdded": { + "message": "Token is al toegevoegd." + }, + "tokenBalance": { + "message": "Uw tokensaldo is:" + }, + "tokenSelection": { + "message": "Zoek naar tokens of selecteer uit onze lijst met populaire tokens." + }, + "tokenSymbol": { + "message": "Token Symbol" + }, + "tokenWarning1": { + "message": "Houd de tokens bij die je hebt gekocht met je MetaMask-account. Als je tokens met een ander account hebt gekocht, worden die tokens hier niet weergegeven." + }, + "total": { + "message": "Totaal" + }, + "transactions": { + "message": "transacties" + }, + "transactionMemo": { + "message": "Transactiememo (optioneel)" + }, + "transactionNumber": { + "message": "Transactie nummer" + }, + "transfers": { + "message": "transfers" + }, + "troubleTokenBalances": { + "message": "We hadden problemen bij het laden van uw tokenbalansen. Je kunt ze bekijken", + "description": "Gevolgd door een link (hier) om tegensaldi te bekijken" + }, + "twelveWords": { + "message": "Deze 12 woorden zijn de enige manier om uw MetaMask-accounts te herstellen.\nBewaar ze ergens veilig en geheim." + }, + "typePassword": { + "message": "Typ uw wachtwoord" + }, + "uiWelcome": { + "message": "Welkom bij de nieuwe gebruikersinterface (bèta)" + }, + "uiWelcomeMessage": { + "message": "U gebruikt nu de nieuwe gebruikersinterface van Metamask. Kijk rond, probeer nieuwe functies uit zoals het verzenden van tokens en laat ons weten of u problemen ondervindt." + }, + "unavailable": { + "message": "Niet beschikbaar" + }, + "unknown": { + "message": "Onbekend" + }, + "unknownNetwork": { + "message": "Onbekend privénetwerk" + }, + "unknownNetworkId": { + "message": "Onbekende netwerk-ID" + }, + "uriErrorMsg": { + "message": "Voor URI's is het juiste HTTP / HTTPS-voorvoegsel vereist." + }, + "usaOnly": { + "message": "Alleen in de VS.", + "description": "Het gebruik van deze uitwisseling is beperkt tot mensen in de VS." + }, + "usedByClients": { + "message": "Gebruikt door verschillende klanten" + }, + "useOldUI": { + "message": "Gebruik de oude gebruikersinterface" + }, + "validFileImport": { + "message": "U moet een geldig bestand selecteren om te importeren." + }, + "vaultCreated": { + "message": "Vault gemaakt" + }, + "viewAccount": { + "message": "Bekijk account" + }, + "visitWebSite": { + "message": "Bezoek onze website" + }, + "warning": { + "message": "Waarschuwing" + }, + "welcomeBeta": { + "message": "Welkom bij MetaMask Beta" + }, + "whatsThis": { + "message": "Wat is dit?" + }, + "yourSigRequested": { + "message": "Uw handtekening wordt aangevraagd" + }, + "youSign": { + "message": "U ondertekent" + } +} diff --git a/app/_locales/ru/messages.json b/app/_locales/ru/messages.json new file mode 100644 index 000000000..e3a1935f5 --- /dev/null +++ b/app/_locales/ru/messages.json @@ -0,0 +1,819 @@ +{ + "accept": { + "message": "Принять" + }, + "account": { + "message": "Аккаунт" + }, + "accountDetails": { + "message": "Детали Аккаунта" + }, + "accountName": { + "message": "Имя Пользователя" + }, + "address": { + "message": "Адрес" + }, + "addCustomToken": { + "message": "Добавить пользовательский токен" + }, + "addToken": { + "message": "Добавить токен" + }, + "addTokens": { + "message": "Добавить Токены" + }, + "amount": { + "message": "Количество" + }, + "amountPlusGas": { + "message": "Количество + газ" + }, + "appDescription": { + "message": "Расширение браузера для Ethereum", + "description": "The description of the application" + }, + "appName": { + "message": "MetaMask", + "description": "The name of the application" + }, + "attemptingConnect": { + "message": "Попытка подключиться к блокчейн сети." + }, + "attributions": { + "message": "Опознания" + }, + "available": { + "message": "Доступный" + }, + "back": { + "message": "Назад" + }, + "balance": { + "message": "Баланс:" + }, + "balances": { + "message": "Ваши балансы" + }, + "balanceIsInsufficientGas": { + "message": "Недостаточный баланс для текущего объема газа" + }, + "beta": { + "message": "БЕТА" + }, + "betweenMinAndMax": { + "message": "должно быть больше или равно $1 и меньше или равно $2.", + "description": "helper for inputting hex as decimal input" + }, + "blockiesIdenticon": { + "message": "Использовать Blockies Identicon" + }, + "borrowDharma": { + "message": "Заимствовать с Dharma (бета)" + }, + "builtInCalifornia": { + "message": "MetaMask спроектирован и построен в Калифорнии." + }, + "buy": { + "message": "Купить" + }, + "buyCoinbase": { + "message": "Купить на Coinbase" + }, + "buyCoinbaseExplainer": { + "message": "Coinbase - самый популярный в мире способ купить и продать биткойн, ethereum и litecoin." + }, + "cancel": { + "message": "Отмена" + }, + "classicInterface": { + "message": "Использовать классический интерфейс" + }, + "clickCopy": { + "message": "Нажмите, чтобы скопировать" + }, + "confirm": { + "message": "Подтвердить" + }, + "confirmContract": { + "message": "Подтвердить Контракт" + }, + "confirmPassword": { + "message": "Подтвердите Пароль" + }, + "confirmTransaction": { + "message": "Подтвердить Транзакцию" + }, + "continue": { + "message": "Продолжить" + }, + "continueToCoinbase": { + "message": "Продолжить в Coinbase" + }, + "contractDeployment": { + "message": "Развертывание контракта" + }, + "conversionProgress": { + "message": "Выполняется конверсия" + }, + "copiedButton": { + "message": "Скопировано" + }, + "copiedClipboard": { + "message": "Скопировано в буфер обмена" + }, + "copiedExclamation": { + "message": "Скопировано!" + }, + "copiedSafe": { + "message": "Я скопировал его где-то в безопасности" + }, + "copy": { + "message": "Скопировать" + }, + "copyToClipboard": { + "message": "Скопировать в буфер обмена" + }, + "copyButton": { + "message": " Скопировать " + }, + "copyPrivateKey": { + "message": "Это ваш личный ключ (нажмите, чтобы скопировать)" + }, + "create": { + "message": "Создать" + }, + "createAccount": { + "message": "Регистрация" + }, + "createDen": { + "message": "Создать" + }, + "crypto": { + "message": "Крипто", + "description": "Exchange type (cryptocurrencies)" + }, + "currentConversion": { + "message": "Текущая конверсия" + }, + "currentNetwork": { + "message": "Текущая сеть" + }, + "customGas": { + "message": "Настроить Газ" + }, + "customize": { + "message": "Настроить" + }, + "customRPC": { + "message": "Пользовательский RPC" + }, + "decimalsMustZerotoTen": { + "message": "Десятичные числа должны быть не менее 0, и не более 36." + }, + "decimal": { + "message": "Десятичные значения точности" + }, + "defaultNetwork": { + "message": "Сеть по умолчанию для транзакций Ether - это Main Net." + }, + "denExplainer": { + "message": "Ваш DEN - это ваше зашифрованное паролем хранилище в MetaMask." + }, + "deposit": { + "message": "Депозит" + }, + "depositBTC": { + "message": "Депозит BTC по адресу:" + }, + "depositCoin": { + "message": "Депозит $1 по указанному ниже адресу", + "description": "Tells the user what coin they have selected to deposit with shapeshift" + }, + "depositEth": { + "message": "Депозит Eth" + }, + "depositEther": { + "message": "Депозит Эфир" + }, + "depositFiat": { + "message": "Депозит с деньгами" + }, + "depositFromAccount": { + "message": "Депозит с другого счета" + }, + "depositShapeShift": { + "message": "Депозит с ShapeShift" + }, + "depositShapeShiftExplainer": { + "message": "Если у вас есть другие крипторесурсы, вы можете торговать и вносить Эфир непосредственно в кошелек MetaMask. Нет необходимости в аккаунте." + }, + "details": { + "message": "Детали" + }, + "directDeposit": { + "message": "Прямой Депозит" + }, + "directDepositEther": { + "message": "Прямой Депозит Эфира" + }, + "directDepositEtherExplainer": { + "message": "Если у вас уже есть Эфир, самый быстрый способ получить Эфир в вашем новом кошельке это прямым депозитом." + }, + "done": { + "message": "Готово" + }, + "downloadStatelogs": { + "message": "Загрузить логи статус" + }, + "edit": { + "message": "Редактировать" + }, + "editAccountName": { + "message": "Изменить Имя Аккаунта" + }, + "emailUs": { + "message": "Свяжитесь с нами по электронной почте!" + }, + "encryptNewDen": { + "message": "Шифруйте новый DEN" + }, + "enterPassword": { + "message": "Введите пароль" + }, + "enterPasswordConfirm": { + "message": "Введите свой пароль для подтверждения" + }, + "etherscanView": { + "message": "Просмотреть аккаунт на Etherscan" + }, + "exchangeRate": { + "message": "Обменный Курс" + }, + "exportPrivateKey": { + "message": "Экспорт закрытого ключа" + }, + "exportPrivateKeyWarning": { + "message": "Экспорт секретных ключей на свой страх и риск." + }, + "failed": { + "message": "Не смогли" + }, + "fiat": { + "message": "Бумажные деньги", + "description": "Exchange type" + }, + "fileImportFail": { + "message": "Ошибка импорта файлов? Кликните сюда!", + "description": "Helps user import their account from a JSON file" + }, + "followTwitter": { + "message": "Следуйте за нами на Twitter" + }, + "from": { + "message": "Из" + }, + "fromToSame": { + "message": "От и до адреса не могут быть одинаковым" + }, + "fromShapeShift": { + "message": "Из ShapeShift" + }, + "gas": { + "message": "Газ", + "description": "Short indication of gas cost" + }, + "gasFee": { + "message": "Плата за Газ" + }, + "gasLimit": { + "message": "Газовый Предел" + }, + "gasLimitCalculation": { + "message": "Мы рассчитываем предполагаемый предел газа на основе коэффициентов успешности сети." + }, + "gasLimitRequired": { + "message": "Требуется ограничение на Газ" + }, + "gasLimitTooLow": { + "message": "Предел газа должен быть не менее 21000" + }, + "generatingSeed": { + "message": "Создание Семян ..." + }, + "gasPrice": { + "message": "Цена на Газ (GWEI)" + }, + "gasPriceCalculation": { + "message": "Мы вычисляем предлагаемые цены на газ на основе коэффициентов успеха сети." + }, + "gasPriceRequired": { + "message": "Требуется цена на Газ" + }, + "getEther": { + "message": "Получить Эфир" + }, + "getEtherFromFaucet": { + "message": "Получите Эфир из крана $1", + "description": "Displays network name for Ether faucet" + }, + "greaterThanMin": { + "message": "должно быть больше или равно $1.", + "description": "helper for inputting hex as decimal input" + }, + "here": { + "message": "здесь", + "description": "as in -click here- for more information (goes with troubleTokenBalances)" + }, + "hereList": { + "message": "Вот список !!!!" + }, + "hide": { + "message": "Спрятать" + }, + "hideToken": { + "message": "Скрыть токен" + }, + "hideTokenPrompt": { + "message": "Скрыть токен?" + }, + "howToDeposit": { + "message": "Как бы вы хотели поместить Эфир?" + }, + "holdEther": { + "message": "Это позволяет вам использовать эфир и токены и служит мостом для децентрализованных приложений." + }, + "import": { + "message": "Импортировать", + "description": "Button to import an account from a selected file" + }, + "importAccount": { + "message": "Импорт Аккаунта" + }, + "importAccountMsg": { + "message": " Импортированные аккаунты не будут связаны с вашей первоначально созданным аккаунтом MetaMask. Подробнее о импортированных аккаунтах " + }, + "importAnAccount": { + "message": "Импортировать аккаунт" + }, + "importDen": { + "message": "Импорт существующих DEN" + }, + "imported": { + "message": "Импортирован", + "description": "status showing that an account has been fully loaded into the keyring" + }, + "infoHelp": { + "message": "Информация и Помощь" + }, + "insufficientFunds": { + "message": "Недостаточно средств." + }, + "insufficientTokens": { + "message": "Недостаточно токенов." + }, + "invalidAddress": { + "message": "Недействительный адрес" + }, + "invalidAddressRecipient": { + "message": "Недопустимый адрес получателя." + }, + "invalidGasParams": { + "message": "Недопустимые параметры Газа" + }, + "invalidInput": { + "message": "Неправильный ввод." + }, + "invalidRequest": { + "message": "Неверный Запрос" + }, + "invalidRPC": { + "message": "Недопустимый URI RPC" + }, + "jsonFail": { + "message": "Что-то пошло не так. Убедитесь, что ваш файл JSON правильно отформатирован." + }, + "jsonFile": { + "message": "Файл JSON", + "description": "format for importing an account" + }, + "kovan": { + "message": "Kovan тестовая сеть" + }, + "knowledgeDataBase": { + "message": "Посетите нашу базу знаний" + }, + "lessThanMax": { + "message": "должно быть меньше или равно $1.", + "description": "helper for inputting hex as decimal input" + }, + "likeToAddTokens": { + "message": "Вы хотите добавить эти токены?" + }, + "limit": { + "message": "Предел" + }, + "loading": { + "message": "Загрузка..." + }, + "loadingTokens": { + "message": "Загрузка токенов ..." + }, + "localhost": { + "message": "Локальный адрес 8545" + }, + "login": { + "message": "Авторизоваться" + }, + "logout": { + "message": "Выйти" + }, + "loose": { + "message": "Рыхлый" + }, + "loweCaseWords": { + "message": "семенные слова имеют только символы нижнего регистра" + }, + "mainnet": { + "message": "Основная сеть Ethereum" + }, + "message": { + "message": "Сообщение" + }, + "metamaskDescription": { + "message": "MetaMask - это безопасное хранилище для Ethereum." + }, + "min": { + "message": "Минимум" + }, + "myAccounts": { + "message": "Мои Аккаунты" + }, + "mustSelectOne": { + "message": "Необходимо выбрать не менее 1 токена." + }, + "needEtherInWallet": { + "message": "Чтобы взаимодействовать с децентрализованными приложениями с помощью MetaMask, вам понадобится Эфир в вашем кошельке." + }, + "needImportFile": { + "message": "Вы должны выбрать файл для импорта.", + "description": "User is important an account and needs to add a file to continue" + }, + "needImportPassword": { + "message": "Вы должны ввести пароль для выбранного файла.", + "description": "Password and file needed to import an account" + }, + "negativeETH": { + "message": "Невозможно отправить отрицательные количества ETH." + }, + "networks": { + "message": "Сети" + }, + "newAccount": { + "message": "Новый Аккаунт" + }, + "newAccountNumberName": { + "message": "Аккаунт $1", + "description": "Default name of next account to be created on create account screen" + }, + "newContract": { + "message": "Новый Контракт" + }, + "newPassword": { + "message": "Новый пароль (мин. 8 символов)" + }, + "newRecipient": { + "message": "Новый Получатель" + }, + "newRPC": { + "message": "Новый URL-адрес RPC" + }, + "next": { + "message": "Далее" + }, + "noAddressForName": { + "message": "Для этого имени не задан адрес." + }, + "noDeposits": { + "message": "Не было получено никаких депозитов" + }, + "noTransactionHistory": { + "message": "Нет истории транзакций." + }, + "noTransactions": { + "message": "Нет Транзакций" + }, + "notStarted": { + "message": "Не Начался" + }, + "oldUI": { + "message": "Старый Интерфейс" + }, + "oldUIMessage": { + "message": "Вы вернулись к старому интерфейсу. Вы можете вернуться к новому с помощью опции в раскрывающемся меню в правом верхнем углу." + }, + "or": { + "message": "или", + "description": "choice between creating or importing a new account" + }, + "passwordCorrect": { + "message": "Убедитесь, что ваш пароль правильный." + }, + "passwordMismatch": { + "message": "пароли не совпадают", + "description": "in password creation process, the two new password fields did not match" + }, + "passwordShort": { + "message": "пароль недостаточно длинный", + "description": "in password creation process, the password is not long enough to be secure" + }, + "pastePrivateKey": { + "message": "Вставьте свою личную строку:", + "description": "For importing an account from a private key" + }, + "pasteSeed": { + "message": "Вставьте здесь свою семенную фразу!" + }, + "personalAddressDetected": { + "message": "Персональный адрес обнаружен. Введите адрес контракта токена." + }, + "pleaseReviewTransaction": { + "message": "Проверьте транзакцию." + }, + "privacyMsg": { + "message": "Политика Конфиденциальности" + }, + "privateKey": { + "message": "Закрытый ключ", + "description": "select this type of file to use to import an account" + }, + "privateKeyWarning": { + "message": "Предупреждение: никогда не раскрывайте этот ключ. Любой, у кого есть ваши личные ключи, может украсть любые активы, хранящиеся в вашем аккаунте." + }, + "privateNetwork": { + "message": "Частная сеть" + }, + "qrCode": { + "message": "Показать QR-код" + }, + "readdToken": { + "message": "Вы можете добавить этот токен в будущем, перейдя в “Добавить токен” в меню параметров вашего аккаунта." + }, + "readMore": { + "message": "Подробнее читайте здесь." + }, + "readMore2": { + "message": "Прочитайте больше." + }, + "receive": { + "message": "Получить" + }, + "recipientAddress": { + "message": "Адрес Получателя" + }, + "refundAddress": { + "message": "Ваш Адрес Возврата" + }, + "rejected": { + "message": "Отклонено" + }, + "resetAccount": { + "message": "Сбросить аккаунт" + }, + "restoreFromSeed": { + "message": "Восстановить от семенной фразы" + }, + "required": { + "message": "Необходимо" + }, + "retryWithMoreGas": { + "message": "Повторите попытку с более высокой ценой на газ здесь" + }, + "revealSeedWords": { + "message": "Раскрыть семенные слова" + }, + "revealSeedWordsWarning": { + "message": "Не восстанавливайте семенные слова в общественном месте! Эти слова могут использоваться для кражи всех ваших аккаунтах." + }, + "revert": { + "message": "Откат" + }, + "rinkeby": { + "message": "Rinkeby тестовая сеть" + }, + "ropsten": { + "message": "Ropsten тестовая сеть" + }, + "sampleAccountName": { + "message": "Например, Мой новый аккаунт", + "description": "Help user understand concept of adding a human-readable name to their account" + }, + "save": { + "message": "Сохранить" + }, + "saveAsFile": { + "message": "Сохранить как Файл", + "description": "Account export process" + }, + "saveSeedAsFile": { + "message": "Сохранить Семенные Слова Как Файл" + }, + "search": { + "message": "Поиск" + }, + "secretPhrase": { + "message": "Введите свою секретную двенадцатисловную фразу здесь, чтобы восстановить хранилище." + }, + "seedPhraseReq": { + "message": "семенные фразы длиной 12 слов" + }, + "select": { + "message": "Выбрать" + }, + "selectCurrency": { + "message": "Выберите Валюту" + }, + "selectService": { + "message": "Выберите Сервис" + }, + "selectType": { + "message": "Выберите Тип" + }, + "send": { + "message": "Послать" + }, + "sendETH": { + "message": "Отправить ETH" + }, + "sendTokens": { + "message": "Отправить Токены" + }, + "sendTokensAnywhere": { + "message": "Отправить Токены кому-либо с аккаунтом Ethereum" + }, + "settings": { + "message": "Настройки" + }, + "shapeshiftBuy": { + "message": "Купить с помощью Shapeshift" + }, + "showPrivateKeys": { + "message": "Показать приватные ключи" + }, + "showQRCode": { + "message": "Показать QR-код" + }, + "sign": { + "message": "Знак" + }, + "signMessage": { + "message": "Нодписать сообщение" + }, + "signNotice": { + "message": "Подписание этого сообщения может иметь \nопасные побочные эффекты. Только подписывайте сообщения \nс сайтов, которым вы полностью доверяете своим аккаунтом. Этот опасный метод будет удален в будущей версии." + }, + "sigRequest": { + "message": "Запрос на подпись" + }, + "sigRequested": { + "message": "Подпись Запрошена" + }, + "spaceBetween": { + "message": "между словами может быть только пробел" + }, + "status": { + "message": "Статус" + }, + "stateLogs": { + "message": "Логи Статуса" + }, + "stateLogsDescription": { + "message": "Логи статуса содержат ваши общедоступные адреса и отправленные транзакции." + }, + "submit": { + "message": "Отправить" + }, + "supportCenter": { + "message": "Посетите наш Центр поддержки" + }, + "symbolBetweenZeroTen": { + "message": "Символ должен быть от 0 до 10 символов." + }, + "takesTooLong": { + "message": "Занимает слишком долго?" + }, + "terms": { + "message": "Условия Эксплуатации" + }, + "testFaucet": { + "message": "Тестовый Кран" + }, + "to": { + "message": "К" + }, + "toETHviaShapeShift": { + "message": "$1 в ETH через ShapeShift", + "description": "system will fill in deposit type in start of message" + }, + "tokenAddress": { + "message": "Адрес Токена" + }, + "tokenAlreadyAdded": { + "message": "Токен уже добавлен." + }, + "tokenBalance": { + "message": "Баланс Вашых Tокенов:" + }, + "tokenSelection": { + "message": "Поиск токенов или выбор из нашего списка популярных токенов." + }, + "tokenSymbol": { + "message": "Символ Токена" + }, + "tokenWarning1": { + "message": "Следите за токенами, которые вы купили с помощью аккаунта MetaMask. Если вы купили токены, используя другой аккаунт, эти токены здесь не появятся." + }, + "total": { + "message": "Всего" + }, + "transactions": { + "message": "транзакции" + }, + "transactionMemo": { + "message": "Транзакционная записка (необязательно)" + }, + "transactionNumber": { + "message": "Номер Транзакции" + }, + "transfers": { + "message": "Переводы" + }, + "troubleTokenBalances": { + "message": "У нас были проблемы с загрузкой ваших токенов. Вы можете просмотреть их ", + "description": "Followed by a link (here) to view token balances" + }, + "twelveWords": { + "message": "Эти 12 слов - единственный способ восстановить ваши учетные записи MetaMask.\nСохраните их где-нибудь в безопасности и в тайне." + }, + "typePassword": { + "message": "Введите Пароль" + }, + "uiWelcome": { + "message": "Добро пожаловать в новый интерфейс (бета-версия)" + }, + "uiWelcomeMessage": { + "message": "Теперь вы используете новый интерфейс Metamask. Осмотритесь, попробуйте новые функции, такие как отправку токенов, и сообщите нам, есть ли у вас какие-либо проблемы." + }, + "unavailable": { + "message": "Недоступен" + }, + "unknown": { + "message": "Неизвестный" + }, + "unknownNetwork": { + "message": "Неизвестная частная сеть" + }, + "unknownNetworkId": { + "message": "Неизвестный идентификатор сети" + }, + "uriErrorMsg": { + "message": "Для URI требуется соответствующий префикс HTTP / HTTPS." + }, + "usaOnly": { + "message": "Только США", + "description": "Using this exchange is limited to people inside the USA" + }, + "usedByClients": { + "message": "Используется различными клиентами" + }, + "useOldUI": { + "message": "Использовать старый интерфейс" + }, + "validFileImport": { + "message": "Вы должны выбрать действительный файл для импорта." + }, + "vaultCreated": { + "message": "Создано хранилище" + }, + "viewAccount": { + "message": "Посмотреть аккаунт" + }, + "visitWebSite": { + "message": "Посетите наш сайт" + }, + "warning": { + "message": "Предупреждение" + }, + "welcomeBeta": { + "message": "Добро пожаловать в MetaMask Beta" + }, + "whatsThis": { + "message": "Что это?" + }, + "yourSigRequested": { + "message": "Ваша подпись запрашивается" + }, + "youSign": { + "message": "Вы подписываете" + } +} diff --git a/app/manifest.json b/app/manifest.json index 6fcf6cd7c..0aac1c8df 100644 --- a/app/manifest.json +++ b/app/manifest.json @@ -1,7 +1,7 @@ { "name": "__MSG_appName__", "short_name": "__MSG_appName__", - "version": "4.2.0", + "version": "4.3.0", "manifest_version": 2, "author": "https://metamask.io", "description": "__MSG_appDescription__", diff --git a/app/scripts/README.md b/app/scripts/README.md new file mode 100644 index 000000000..f5a907244 --- /dev/null +++ b/app/scripts/README.md @@ -0,0 +1,14 @@ +# Main MetaMask Code + +This folder contains the core-code. + +Currently, it is organized mostly based on file category, like: + +controllers, migrations, lib + +## Ongoing Task + +Refactor code-structure, thus the subsystems are reflected on the filesystem. + +### Examples + diff --git a/app/scripts/background.js b/app/scripts/background.js index ef5513ec7..8bd7766ad 100644 --- a/app/scripts/background.js +++ b/app/scripts/background.js @@ -42,6 +42,7 @@ const isIE = !!document.documentMode const isEdge = !isIE && !!window.StyleMedia let popupIsOpen = false +let notificationIsOpen = false let openMetamaskTabsIDs = {} // state persistence @@ -165,6 +166,11 @@ function setupController (initState) { } }) } + if (remotePort.name === 'notification') { + endOfStream(portStream, () => { + notificationIsOpen = false + }) + } } else { // communication with page const originDomain = urlUtil.parse(remotePort.sender.url).hostname @@ -207,7 +213,8 @@ function setupController (initState) { function triggerUi () { extension.tabs.query({ active: true }, (tabs) => { const currentlyActiveMetamaskTab = tabs.find(tab => openMetamaskTabsIDs[tab.id]) - if (!popupIsOpen && !currentlyActiveMetamaskTab) notificationManager.showPopup() + if (!popupIsOpen && !currentlyActiveMetamaskTab && !notificationIsOpen) notificationManager.showPopup() + notificationIsOpen = true }) } diff --git a/app/scripts/controllers/README.md b/app/scripts/controllers/README.md new file mode 100644 index 000000000..392c0457d --- /dev/null +++ b/app/scripts/controllers/README.md @@ -0,0 +1,4 @@ +# Controllers + +Different controllers (in the sense of *VC *View-Controller). + diff --git a/app/scripts/lib/notification-manager.js b/app/scripts/lib/notification-manager.js index adaf60c65..1fcb7cf69 100644 --- a/app/scripts/lib/notification-manager.js +++ b/app/scripts/lib/notification-manager.js @@ -13,11 +13,12 @@ class NotificationManager { this._getPopup((err, popup) => { if (err) throw err + // Bring focus to chrome popup if (popup) { - // bring focus to existing popup + // bring focus to existing chrome popup extension.windows.update(popup.id, { focused: true }) } else { - // create new popup + // create new notification popup extension.windows.create({ url: 'notification.html', type: 'popup', @@ -29,6 +30,7 @@ class NotificationManager { } closePopup () { + // closes notification popup this._getPopup((err, popup) => { if (err) throw err if (!popup) return @@ -60,9 +62,8 @@ class NotificationManager { _getPopupIn (windows) { return windows ? windows.find((win) => { - return (win && win.type === 'popup' && - win.height === height && - win.width === width) + // Returns notification popup + return (win && win.type === 'popup') }) : null } diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index 4ff08e029..bd092cea0 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -1,3 +1,9 @@ +/** + * @file The central metamask controller. Aggregates other controllers and exports an api. + * @copyright Copyright (c) 2018 MetaMask + * @license MIT + */ + const EventEmitter = require('events') const extend = require('xtend') const pump = require('pump') @@ -41,7 +47,11 @@ const seedPhraseVerifier = require('./lib/seed-phrase-verifier') module.exports = class MetamaskController extends EventEmitter { - constructor (opts) { + /** + * @constructor + * @param {Object} opts + */ + constructor (opts) { super() this.defaultMaxListeners = 20 @@ -223,10 +233,9 @@ module.exports = class MetamaskController extends EventEmitter { this.infuraController.store.subscribe(sendUpdate) } - // - // Constructor helpers - // - + /** + * Constructor helper: initialize a provider. + */ initializeProvider () { const providerOpts = { static: { @@ -257,6 +266,9 @@ module.exports = class MetamaskController extends EventEmitter { return providerProxy } + /** + * Constructor helper: initialize a public config store. + */ initPublicConfigStore () { // get init state const publicConfigStore = new ObservableStore() @@ -278,10 +290,15 @@ module.exports = class MetamaskController extends EventEmitter { return publicConfigStore } - // - // State Management - // +//============================================================================= +// EXPOSED TO THE UI SUBSYSTEM +//============================================================================= + /** + * The metamask-state of the various controllers, made available to the UI + * + * @returns {Object} status + */ getState () { const wallet = this.configManager.getWallet() const vault = this.keyringController.store.getState().vault @@ -316,10 +333,11 @@ module.exports = class MetamaskController extends EventEmitter { ) } - // - // Remote Features - // - + /** + * Returns an api-object which is consumed by the UI + * + * @returns {Object} + */ getApi () { const keyringController = this.keyringController const preferencesController = this.preferencesController @@ -401,127 +419,24 @@ module.exports = class MetamaskController extends EventEmitter { } } - setupUntrustedCommunication (connectionStream, originDomain) { - // Check if new connection is blacklisted - if (this.blacklistController.checkForPhishing(originDomain)) { - log.debug('MetaMask - sending phishing warning for', originDomain) - this.sendPhishingWarning(connectionStream, originDomain) - return - } - - // setup multiplexing - const mux = setupMultiplex(connectionStream) - // connect features - this.setupProviderConnection(mux.createStream('provider'), originDomain) - this.setupPublicConfig(mux.createStream('publicConfig')) - } - - setupTrustedCommunication (connectionStream, originDomain) { - // setup multiplexing - const mux = setupMultiplex(connectionStream) - // connect features - this.setupControllerConnection(mux.createStream('controller')) - this.setupProviderConnection(mux.createStream('provider'), originDomain) - } - - sendPhishingWarning (connectionStream, hostname) { - const mux = setupMultiplex(connectionStream) - const phishingStream = mux.createStream('phishing') - phishingStream.write({ hostname }) - } - - setupControllerConnection (outStream) { - const api = this.getApi() - const dnode = Dnode(api) - pump( - outStream, - dnode, - outStream, - (err) => { - if (err) log.error(err) - } - ) - dnode.on('remote', (remote) => { - // push updates to popup - const sendUpdate = remote.sendUpdate.bind(remote) - this.on('update', sendUpdate) - }) - } - - setupProviderConnection (outStream, origin) { - // setup json rpc engine stack - const engine = new RpcEngine() - - // create filter polyfill middleware - const filterMiddleware = createFilterMiddleware({ - provider: this.provider, - blockTracker: this.provider._blockTracker, - }) - - engine.push(createOriginMiddleware({ origin })) - engine.push(createLoggerMiddleware({ origin })) - engine.push(filterMiddleware) - engine.push(createProviderMiddleware({ provider: this.provider })) - - // setup connection - const providerStream = createEngineStream({ engine }) - pump( - outStream, - providerStream, - outStream, - (err) => { - // cleanup filter polyfill middleware - filterMiddleware.destroy() - if (err) log.error(err) - } - ) - } - - setupPublicConfig (outStream) { - pump( - asStream(this.publicConfigStore), - outStream, - (err) => { - if (err) log.error(err) - } - ) - } - privateSendUpdate () { - this.emit('update', this.getState()) - } - getGasPrice () { - const { recentBlocksController } = this - const { recentBlocks } = recentBlocksController.store.getState() - - // Return 1 gwei if no blocks have been observed: - if (recentBlocks.length === 0) { - return '0x' + GWEI_BN.toString(16) - } - - const lowestPrices = recentBlocks.map((block) => { - if (!block.gasPrices || block.gasPrices.length < 1) { - return GWEI_BN - } - return block.gasPrices - .map(hexPrefix => hexPrefix.substr(2)) - .map(hex => new BN(hex, 16)) - .sort((a, b) => { - return a.gt(b) ? 1 : -1 - })[0] - }) - .map(number => number.div(GWEI_BN).toNumber()) - - const percentileNum = percentile(50, lowestPrices) - const percentileNumBn = new BN(percentileNum) - return '0x' + percentileNumBn.mul(GWEI_BN).toString(16) - } - - // - // Vault Management - // +//============================================================================= +// VAULT / KEYRING RELATED METHODS +//============================================================================= + /** + * Creates a new Vault(?) and create a new keychain(?) + * + * A vault is ... + * + * A keychain is ... + * + * + * @param {} password + * + * @returns {} vault + */ async createNewVaultAndKeychain (password) { const release = await this.createVaultMutex.acquire() let vault @@ -545,6 +460,11 @@ module.exports = class MetamaskController extends EventEmitter { return vault } + /** + * Create a new Vault and restore an existent keychain + * @param {} password + * @param {} seed + */ async createNewVaultAndRestore (password, seed) { const release = await this.createVaultMutex.acquire() try { @@ -558,16 +478,28 @@ module.exports = class MetamaskController extends EventEmitter { } } + /** + * Retrieves the first Identiy from the passed Vault and selects the related address + * + * An Identity is ... + * + * @param {} vault + */ selectFirstIdentity (vault) { const { identities } = vault const address = Object.keys(identities)[0] this.preferencesController.setSelectedAddress(address) } - // + // ? // Opinionated Keyring Management // + /** + * Adds a new account to ... + * + * @returns {} keyState + */ async addNewAccount () { const primaryKeyring = this.keyringController.getKeyringsByType('HD Key Tree')[0] if (!primaryKeyring) { @@ -589,10 +521,12 @@ module.exports = class MetamaskController extends EventEmitter { return keyState } - // Adds the current vault's seed words to the UI's state tree. - // - // Used when creating a first vault, to allow confirmation. - // Also used when revealing the seed words in the confirmation view. + /** + * Adds the current vault's seed words to the UI's state tree. + * + * Used when creating a first vault, to allow confirmation. + * Also used when revealing the seed words in the confirmation view. + */ placeSeedWords (cb) { this.verifySeedPhrase() @@ -605,10 +539,13 @@ module.exports = class MetamaskController extends EventEmitter { }) } - // Verifies the current vault's seed words if they can restore the - // accounts belonging to the current vault. - // - // Called when the first account is created and on unlocking the vault. + /** + * Verifies the validity of the current vault's seed phrase. + * + * Validity: seed phrase restores the accounts belonging to the current vault. + * + * Called when the first account is created and on unlocking the vault. + */ async verifySeedPhrase () { const primaryKeyring = this.keyringController.getKeyringsByType('HD Key Tree')[0] @@ -633,22 +570,33 @@ module.exports = class MetamaskController extends EventEmitter { } } - // ClearSeedWordCache - // - // Removes the primary account's seed words from the UI's state tree, - // ensuring they are only ever available in the background process. + /** + * Remove the primary account seed phrase from the UI's state tree. + * + * The seed phrase remains available in the background process. + * + */ clearSeedWordCache (cb) { this.configManager.setSeedWords(null) cb(null, this.preferencesController.getSelectedAddress()) } - + + /** + * ? + */ resetAccount (cb) { const selectedAddress = this.preferencesController.getSelectedAddress() this.txController.wipeTransactions(selectedAddress) cb(null, selectedAddress) } - + /** + * Imports an account ... ? + * + * @param {} strategy + * @param {} args + * @param {} cb + */ importAccountWithStrategy (strategy, args, cb) { accountImporter.importAccount(strategy, args) .then((privateKey) => { @@ -660,11 +608,150 @@ module.exports = class MetamaskController extends EventEmitter { .catch((reason) => { cb(reason) }) } + // --------------------------------------------------------------------------- + // Identity Management (sign) - // - // Identity Management - // - // + /** + * @param {} msgParams + * @param {} cb + */ + signMessage (msgParams, cb) { + log.info('MetaMaskController - signMessage') + const msgId = msgParams.metamaskId + + // sets the status op the message to 'approved' + // and removes the metamaskId for signing + return this.messageManager.approveMessage(msgParams) + .then((cleanMsgParams) => { + // signs the message + return this.keyringController.signMessage(cleanMsgParams) + }) + .then((rawSig) => { + // tells the listener that the message has been signed + // and can be returned to the dapp + this.messageManager.setMsgStatusSigned(msgId, rawSig) + return this.getState() + }) + } + + // Prefixed Style Message Signing Methods: + + /** + * + * @param {} msgParams + * @param {} cb + */ + approvePersonalMessage (msgParams, cb) { + const msgId = this.personalMessageManager.addUnapprovedMessage(msgParams) + this.sendUpdate() + this.opts.showUnconfirmedMessage() + this.personalMessageManager.once(`${msgId}:finished`, (data) => { + switch (data.status) { + case 'signed': + return cb(null, data.rawSig) + case 'rejected': + return cb(new Error('MetaMask Message Signature: User denied transaction signature.')) + default: + return cb(new Error(`MetaMask Message Signature: Unknown problem: ${JSON.stringify(msgParams)}`)) + } + }) + } + + /** + * @param {} msgParams + */ + signPersonalMessage (msgParams) { + log.info('MetaMaskController - signPersonalMessage') + const msgId = msgParams.metamaskId + // sets the status op the message to 'approved' + // and removes the metamaskId for signing + return this.personalMessageManager.approveMessage(msgParams) + .then((cleanMsgParams) => { + // signs the message + return this.keyringController.signPersonalMessage(cleanMsgParams) + }) + .then((rawSig) => { + // tells the listener that the message has been signed + // and can be returned to the dapp + this.personalMessageManager.setMsgStatusSigned(msgId, rawSig) + return this.getState() + }) + } + + /** + * @param {} msgParams + */ + signTypedMessage (msgParams) { + log.info('MetaMaskController - signTypedMessage') + const msgId = msgParams.metamaskId + // sets the status op the message to 'approved' + // and removes the metamaskId for signing + return this.typedMessageManager.approveMessage(msgParams) + .then((cleanMsgParams) => { + // signs the message + return this.keyringController.signTypedMessage(cleanMsgParams) + }) + .then((rawSig) => { + // tells the listener that the message has been signed + // and can be returned to the dapp + this.typedMessageManager.setMsgStatusSigned(msgId, rawSig) + return this.getState() + }) + } + + // --------------------------------------------------------------------------- + // Account Restauration + + /** + * ? + * + * @param {} migratorOutput + */ + restoreOldVaultAccounts (migratorOutput) { + const { serialized } = migratorOutput + return this.keyringController.restoreKeyring(serialized) + .then(() => migratorOutput) + } + + /** + * ? + * + * @param {} migratorOutput + */ + restoreOldLostAccounts (migratorOutput) { + const { lostAccounts } = migratorOutput + if (lostAccounts) { + this.configManager.setLostAccounts(lostAccounts.map(acct => acct.address)) + return this.importLostAccounts(migratorOutput) + } + return Promise.resolve(migratorOutput) + } + + /** + * Import (lost) Accounts + * + * @param {Object} {lostAccounts} @Array accounts <{ address, privateKey }> + * + * Uses the array's private keys to create a new Simple Key Pair keychain + * and add it to the keyring controller. + */ + importLostAccounts ({ lostAccounts }) { + const privKeys = lostAccounts.map(acct => acct.privateKey) + return this.keyringController.restoreKeyring({ + type: 'Simple Key Pair', + data: privKeys, + }) + } + +//============================================================================= +// END (VAULT / KEYRING RELATED METHODS) +//============================================================================= + +// + +//============================================================================= +// MESSAGES +//============================================================================= async retryTransaction (txId, cb) { await this.txController.retryTransaction(txId) @@ -731,85 +818,13 @@ module.exports = class MetamaskController extends EventEmitter { }) } - signMessage (msgParams, cb) { - log.info('MetaMaskController - signMessage') - const msgId = msgParams.metamaskId - - // sets the status op the message to 'approved' - // and removes the metamaskId for signing - return this.messageManager.approveMessage(msgParams) - .then((cleanMsgParams) => { - // signs the message - return this.keyringController.signMessage(cleanMsgParams) - }) - .then((rawSig) => { - // tells the listener that the message has been signed - // and can be returned to the dapp - this.messageManager.setMsgStatusSigned(msgId, rawSig) - return this.getState() - }) - } - cancelMessage (msgId, cb) { const messageManager = this.messageManager messageManager.rejectMsg(msgId) if (cb && typeof cb === 'function') { cb(null, this.getState()) } - } - - // Prefixed Style Message Signing Methods: - approvePersonalMessage (msgParams, cb) { - const msgId = this.personalMessageManager.addUnapprovedMessage(msgParams) - this.sendUpdate() - this.opts.showUnconfirmedMessage() - this.personalMessageManager.once(`${msgId}:finished`, (data) => { - switch (data.status) { - case 'signed': - return cb(null, data.rawSig) - case 'rejected': - return cb(new Error('MetaMask Message Signature: User denied transaction signature.')) - default: - return cb(new Error(`MetaMask Message Signature: Unknown problem: ${JSON.stringify(msgParams)}`)) - } - }) - } - - signPersonalMessage (msgParams) { - log.info('MetaMaskController - signPersonalMessage') - const msgId = msgParams.metamaskId - // sets the status op the message to 'approved' - // and removes the metamaskId for signing - return this.personalMessageManager.approveMessage(msgParams) - .then((cleanMsgParams) => { - // signs the message - return this.keyringController.signPersonalMessage(cleanMsgParams) - }) - .then((rawSig) => { - // tells the listener that the message has been signed - // and can be returned to the dapp - this.personalMessageManager.setMsgStatusSigned(msgId, rawSig) - return this.getState() - }) - } - - signTypedMessage (msgParams) { - log.info('MetaMaskController - signTypedMessage') - const msgId = msgParams.metamaskId - // sets the status op the message to 'approved' - // and removes the metamaskId for signing - return this.typedMessageManager.approveMessage(msgParams) - .then((cleanMsgParams) => { - // signs the message - return this.keyringController.signTypedMessage(cleanMsgParams) - }) - .then((rawSig) => { - // tells the listener that the message has been signed - // and can be returned to the dapp - this.typedMessageManager.setMsgStatusSigned(msgId, rawSig) - return this.getState() - }) - } + } cancelPersonalMessage (msgId, cb) { const messageManager = this.personalMessageManager @@ -845,36 +860,130 @@ module.exports = class MetamaskController extends EventEmitter { cb() } - restoreOldVaultAccounts (migratorOutput) { - const { serialized } = migratorOutput - return this.keyringController.restoreKeyring(serialized) - .then(() => migratorOutput) - } +//============================================================================= +// SETUP +//============================================================================= - restoreOldLostAccounts (migratorOutput) { - const { lostAccounts } = migratorOutput - if (lostAccounts) { - this.configManager.setLostAccounts(lostAccounts.map(acct => acct.address)) - return this.importLostAccounts(migratorOutput) + setupUntrustedCommunication (connectionStream, originDomain) { + // Check if new connection is blacklisted + if (this.blacklistController.checkForPhishing(originDomain)) { + log.debug('MetaMask - sending phishing warning for', originDomain) + this.sendPhishingWarning(connectionStream, originDomain) + return } - return Promise.resolve(migratorOutput) + + // setup multiplexing + const mux = setupMultiplex(connectionStream) + // connect features + this.setupProviderConnection(mux.createStream('provider'), originDomain) + this.setupPublicConfig(mux.createStream('publicConfig')) } - // IMPORT LOST ACCOUNTS - // @Object with key lostAccounts: @Array accounts <{ address, privateKey }> - // Uses the array's private keys to create a new Simple Key Pair keychain - // and add it to the keyring controller. - importLostAccounts ({ lostAccounts }) { - const privKeys = lostAccounts.map(acct => acct.privateKey) - return this.keyringController.restoreKeyring({ - type: 'Simple Key Pair', - data: privKeys, + setupTrustedCommunication (connectionStream, originDomain) { + // setup multiplexing + const mux = setupMultiplex(connectionStream) + // connect features + this.setupControllerConnection(mux.createStream('controller')) + this.setupProviderConnection(mux.createStream('provider'), originDomain) + } + + sendPhishingWarning (connectionStream, hostname) { + const mux = setupMultiplex(connectionStream) + const phishingStream = mux.createStream('phishing') + phishingStream.write({ hostname }) + } + + setupControllerConnection (outStream) { + const api = this.getApi() + const dnode = Dnode(api) + pump( + outStream, + dnode, + outStream, + (err) => { + if (err) log.error(err) + } + ) + dnode.on('remote', (remote) => { + // push updates to popup + const sendUpdate = remote.sendUpdate.bind(remote) + this.on('update', sendUpdate) }) } - // - // config - // + setupProviderConnection (outStream, origin) { + // setup json rpc engine stack + const engine = new RpcEngine() + + // create filter polyfill middleware + const filterMiddleware = createFilterMiddleware({ + provider: this.provider, + blockTracker: this.provider._blockTracker, + }) + + engine.push(createOriginMiddleware({ origin })) + engine.push(createLoggerMiddleware({ origin })) + engine.push(filterMiddleware) + engine.push(createProviderMiddleware({ provider: this.provider })) + + // setup connection + const providerStream = createEngineStream({ engine }) + pump( + outStream, + providerStream, + outStream, + (err) => { + // cleanup filter polyfill middleware + filterMiddleware.destroy() + if (err) log.error(err) + } + ) + } + + setupPublicConfig (outStream) { + pump( + asStream(this.publicConfigStore), + outStream, + (err) => { + if (err) log.error(err) + } + ) + } + + privateSendUpdate () { + this.emit('update', this.getState()) + } + + getGasPrice () { + const { recentBlocksController } = this + const { recentBlocks } = recentBlocksController.store.getState() + + // Return 1 gwei if no blocks have been observed: + if (recentBlocks.length === 0) { + return '0x' + GWEI_BN.toString(16) + } + + const lowestPrices = recentBlocks.map((block) => { + if (!block.gasPrices || block.gasPrices.length < 1) { + return GWEI_BN + } + return block.gasPrices + .map(hexPrefix => hexPrefix.substr(2)) + .map(hex => new BN(hex, 16)) + .sort((a, b) => { + return a.gt(b) ? 1 : -1 + })[0] + }) + .map(number => number.div(GWEI_BN).toNumber()) + + const percentileNum = percentile(50, lowestPrices) + const percentileNumBn = new BN(percentileNum) + return '0x' + percentileNumBn.mul(GWEI_BN).toString(16) + } + +//============================================================================= +// CONFIG +//============================================================================= // Log blocks diff --git a/app/scripts/migrations/README.md b/app/scripts/migrations/README.md new file mode 100644 index 000000000..3a67b08e1 --- /dev/null +++ b/app/scripts/migrations/README.md @@ -0,0 +1,5 @@ +# Migrations + +Data (user data, config files etc.) is migrated from one version to another. + +Migrations are called by {} from {} during {}. \ No newline at end of file diff --git a/app/scripts/popup.js b/app/scripts/popup.js index 6ef0be1ff..13c7ac5ec 100644 --- a/app/scripts/popup.js +++ b/app/scripts/popup.js @@ -69,6 +69,7 @@ async function start() { function closePopupIfOpen (windowType) { if (windowType !== 'notification') { + // should close only chrome popup notificationManager.closePopup() } } diff --git a/development/README.md b/development/README.md new file mode 100644 index 000000000..1e18d4f16 --- /dev/null +++ b/development/README.md @@ -0,0 +1,5 @@ +# Development + +Several files which are needed for developing on(!) MetaMask. + +Usually each files contains information about its scope / usage. \ No newline at end of file diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 000000000..0739cfa46 --- /dev/null +++ b/docs/README.md @@ -0,0 +1,13 @@ +# Documentation + + +- [How to add custom build to Chrome](./add-to-chrome.md) +- [How to add custom build to Firefox](./add-to-firefox.md) +- [How to develop a live-reloading UI](./ui-dev-mode.md) +- [Publishing Guide](./publishing.md) +- [How to develop an in-browser mocked UI](./ui-mock-mode.md) +- [How to live reload on local dependency changes](./developing-on-deps.md) +- [How to add new networks to the Provider Menu](./adding-new-networks.md) +- [How to manage notices that appear when the app starts up](./notices.md) +- [How to port MetaMask to a new platform](./porting_to_new_environment.md) +- [How to generate a visualization of this repository's development](./development-visualization.md) \ No newline at end of file diff --git a/gulpfile.js b/gulpfile.js index dbbb1e4ff..adfb148a9 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -408,11 +408,7 @@ function bundleTask(opts) { .pipe(gulpif(debug, sourcemaps.init({ loadMaps: true }))) // Minification .pipe(gulpif(opts.isBuild, uglify({ - mangle: { reserved: [ 'MetamaskInpageProvider' ] }, - }))) - // Transpile to ES5 - .pipe(gulpif(opts.isBuild, babel({ - presets: ['env'] + mangle: { reserved: [ 'MetamaskInpageProvider' ] }, }))) // writes .map file .pipe(gulpif(debug, sourcemaps.write('./'))) diff --git a/notices/README.md b/notices/README.md new file mode 100644 index 000000000..9362769c2 --- /dev/null +++ b/notices/README.md @@ -0,0 +1,5 @@ +# Notices + +Those notices are of legal nature. They are displayed to the users of MetaMask. + +Any changes or additions must be reviewed by the product management. \ No newline at end of file diff --git a/package.json b/package.json index 8f05bc7f1..1aae1092e 100644 --- a/package.json +++ b/package.json @@ -10,10 +10,9 @@ "mock": "beefy development/mock-dev.js:bundle.js --live --open --index=./development/index.html --cwd ./", "watch": "mocha watch --recursive \"test/unit/**/*.js\"", "mascara": "gulp build && cross-env METAMASK_DEBUG=true node ./mascara/example/server", - "dist": "npm run dist:clear && npm install && gulp dist && npm run test:es5", + "dist": "npm run dist:clear && npm install && gulp dist", "dist:clear": "rm -rf node_modules/eth-contract-metadata && rm -rf node_modules/eth-phishing-detect", "test": "npm run lint && npm run test:coverage && npm run test:integration", - "test:es5": "es-check es5 ./dist/**/*.js", "test:unit": "cross-env METAMASK_ENV=test mocha --exit --require babel-core/register --require test/helper.js --recursive \"test/unit/**/*.js\"", "test:single": "cross-env METAMASK_ENV=test mocha --require test/helper.js", "test:integration": "npm run test:integration:build && npm run test:flat && npm run test:mascara", @@ -201,7 +200,6 @@ "envify": "^4.0.0", "enzyme": "^3.3.0", "enzyme-adapter-react-15": "^1.0.5", - "es-check": "^2.0.2", "eslint-plugin-chai": "0.0.1", "eslint-plugin-mocha": "^4.9.0", "eslint-plugin-react": "^7.4.0", diff --git a/test/integration/lib/send-new-ui.js b/test/integration/lib/send-new-ui.js index 573faaee3..46e0ef0e4 100644 --- a/test/integration/lib/send-new-ui.js +++ b/test/integration/lib/send-new-ui.js @@ -127,11 +127,12 @@ async function runSendFlowTest(assert, done) { selectState.val('send edit') reactTriggerChange(selectState[0]) + await timeout(10000) - const confirmFromName = (await queryAsync($, '.confirm-screen-account-name')).first() + const confirmFromName = (await queryAsync($, '.sender-to-recipient__sender-name')).first() assert.equal(confirmFromName[0].textContent, 'Send Account 2', 'confirm screen should show correct from name') - const confirmToName = (await queryAsync($, '.confirm-screen-account-name')).last() + const confirmToName = (await queryAsync($, '.sender-to-recipient__recipient-name')).last() assert.equal(confirmToName[0].textContent, 'Send Account 3', 'confirm screen should show correct to name') const confirmScreenRows = await queryAsync($, '.confirm-screen-rows') @@ -140,7 +141,7 @@ async function runSendFlowTest(assert, done) { const confirmScreenTotal = confirmScreenRows.find('.confirm-screen-row-info')[2] assert.equal(confirmScreenTotal.textContent, '2405.36 USD', 'confirm screen should show correct total') - const confirmScreenBackButton = await queryAsync($, '.confirm-screen-back-button') + const confirmScreenBackButton = await queryAsync($, '.page-container__back-button') confirmScreenBackButton[0].click() const sendFromFieldItemInEdit = await queryAsync($, '.account-list-item') diff --git a/ui/app/components/currency-input.js b/ui/app/components/currency-input.js index 940238fa5..ece3eb43d 100644 --- a/ui/app/components/currency-input.js +++ b/ui/app/components/currency-input.js @@ -91,6 +91,7 @@ CurrencyInput.prototype.render = function () { placeholder, readOnly, inputRef, + type, } = this.props const { emptyState, focused } = this.state @@ -99,6 +100,7 @@ CurrencyInput.prototype.render = function () { const valueToRender = this.getValueToRender() return h('input', { className, + type, value: emptyState ? '' : valueToRender, placeholder: focused ? '' : placeholder, size: valueToRender.length * inputSizeMultiplier, diff --git a/ui/app/components/input-number.js b/ui/app/components/input-number.js index fd8c5c309..5600e35ee 100644 --- a/ui/app/components/input-number.js +++ b/ui/app/components/input-number.js @@ -55,6 +55,7 @@ InputNumber.prototype.render = function () { className: 'customize-gas-input', value, placeholder, + type: 'number', onInputChange: newValue => { this.setValue(newValue) }, diff --git a/ui/app/components/network-display.js b/ui/app/components/network-display.js new file mode 100644 index 000000000..9dc31b5c7 --- /dev/null +++ b/ui/app/components/network-display.js @@ -0,0 +1,51 @@ +const { Component } = require('react') +const h = require('react-hyperscript') +const PropTypes = require('prop-types') +const { connect } = require('react-redux') +const NetworkDropdownIcon = require('./dropdowns/components/network-dropdown-icon') +const t = require('../../i18n') + +const networkToColorHash = { + 1: '#038789', + 3: '#e91550', + 42: '#690496', + 4: '#ebb33f', +} + +class NetworkDisplay extends Component { + renderNetworkIcon () { + const { network } = this.props + const networkColor = networkToColorHash[network] + + return networkColor + ? h(NetworkDropdownIcon, { backgroundColor: networkColor }) + : h('i.fa.fa-question-circle.fa-med', { + style: { + margin: '0 4px', + color: 'rgb(125, 128, 130)', + }, + }) + } + + render () { + const { provider: { type } } = this.props + return h('.network-display__container', [ + this.renderNetworkIcon(), + h('.network-name', t(type)), + ]) + } +} + +NetworkDisplay.propTypes = { + network: PropTypes.string, + provider: PropTypes.object, +} + +const mapStateToProps = ({ metamask: { network, provider } }) => { + return { + network, + provider, + } +} + +module.exports = connect(mapStateToProps)(NetworkDisplay) diff --git a/ui/app/components/pending-tx/confirm-deploy-contract.js b/ui/app/components/pending-tx/confirm-deploy-contract.js index 6b912af7f..512aa793d 100644 --- a/ui/app/components/pending-tx/confirm-deploy-contract.js +++ b/ui/app/components/pending-tx/confirm-deploy-contract.js @@ -1,5 +1,5 @@ const { Component } = require('react') -const connect = require('../../metamask-connect') +const { connect } = require('react-redux') const h = require('react-hyperscript') const PropTypes = require('prop-types') const actions = require('../../actions') @@ -8,7 +8,9 @@ const ethUtil = require('ethereumjs-util') const BN = ethUtil.BN const hexToBn = require('../../../../app/scripts/lib/hex-to-bn') const { conversionUtil } = require('../../conversion-util') +const t = require('../../../i18n') const SenderToRecipient = require('../sender-to-recipient') +const NetworkDisplay = require('../network-display') const { MIN_GAS_PRICE_HEX } = require('../send/send-constants') @@ -243,9 +245,12 @@ class ConfirmDeployContract extends Component { return ( h('.page-container', [ h('.page-container__header', [ - h('.page-container__back-button', { - onClick: () => backToAccountDetail(selectedAddress), - }, this.props.t('back')), + h('.page-container__header-row', [ + h('span.page-container__back-button', { + onClick: () => backToAccountDetail(selectedAddress), + }, this.props.t('back')), + window.METAMASK_UI_TYPE === 'notification' && h(NetworkDisplay), + ]), h('.page-container__title', this.props.t('confirmContract')), h('.page-container__subtitle', this.props.t('pleaseReviewTransaction')), ]), @@ -320,7 +325,6 @@ ConfirmDeployContract.propTypes = { conversionRate: PropTypes.number, currentCurrency: PropTypes.string, selectedAddress: PropTypes.string, - localeMessages: PropTypes.object, } const mapStateToProps = state => { @@ -343,8 +347,8 @@ const mapDispatchToProps = dispatch => { return { backToAccountDetail: address => dispatch(actions.backToAccountDetail(address)), cancelTransaction: ({ id }) => dispatch(actions.cancelTx({ id })), - displayWarning: warning => actions.displayWarning(this.props.t(warning)), + displayWarning: warning => actions.displayWarning(t(warning)), } } -module.exports = connect(mapStateToProps, mapDispatchToProps)(ConfirmDeployContract) +module.exports = connect(mapStateToProps, mapDispatchToProps)(ConfirmDeployContract) \ No newline at end of file diff --git a/ui/app/components/pending-tx/confirm-send-ether.js b/ui/app/components/pending-tx/confirm-send-ether.js index 02394b0c5..68c6f14d2 100644 --- a/ui/app/components/pending-tx/confirm-send-ether.js +++ b/ui/app/components/pending-tx/confirm-send-ether.js @@ -1,10 +1,9 @@ const Component = require('react').Component -const connect = require('../../metamask-connect') +const { connect } = require('react-redux') const h = require('react-hyperscript') const inherits = require('util').inherits const actions = require('../../actions') const clone = require('clone') -const Identicon = require('../identicon') const ethUtil = require('ethereumjs-util') const BN = ethUtil.BN const hexToBn = require('../../../../app/scripts/lib/hex-to-bn') @@ -14,6 +13,9 @@ const { multiplyCurrencies, } = require('../../conversion-util') const GasFeeDisplay = require('../send/gas-fee-display-v2') +const t = require('../../../i18n') +const SenderToRecipient = require('../sender-to-recipient') +const NetworkDisplay = require('../network-display') const { MIN_GAS_PRICE_HEX } = require('../send/send-constants') @@ -256,196 +258,181 @@ ConfirmSendEther.prototype.render = function () { this.inputs = [] return ( - h('div.confirm-screen-container.confirm-send-ether', [ - // Main Send token Card - h('div.page-container', [ - h('div.page-container__header', [ - !txMeta.lastGasPrice && h('button.confirm-screen-back-button', { + // Main Send token Card + h('.page-container', [ + h('.page-container__header', [ + h('.page-container__header-row', [ + h('span.page-container__back-button', { onClick: () => editTransaction(txMeta), + style: { + visibility: !txMeta.lastGasPrice ? 'initial' : 'hidden', + }, }, 'Edit'), - h('div.page-container__title', title), - h('div.page-container__subtitle', subtitle), + window.METAMASK_UI_TYPE === 'notification' && h(NetworkDisplay), + ]), + h('.page-container__title', title), + h('.page-container__subtitle', subtitle), + ]), + h('.page-container__content', [ + h(SenderToRecipient, { + senderName: fromName, + senderAddress: fromAddress, + recipientName: toName, + recipientAddress: txParams.to, + }), + + // h('h3.flex-center.confirm-screen-sending-to-message', { + // style: { + // textAlign: 'center', + // fontSize: '16px', + // }, + // }, [ + // `You're sending to Recipient ...${toAddress.slice(toAddress.length - 4)}`, + // ]), + + h('h3.flex-center.confirm-screen-send-amount', [`${amountInFIAT}`]), + h('h3.flex-center.confirm-screen-send-amount-currency', [ currentCurrency.toUpperCase() ]), + h('div.flex-center.confirm-memo-wrapper', [ + h('h3.confirm-screen-send-memo', [ memo ? `"${memo}"` : '' ]), ]), - h('.page-container__content', [ - h('div.flex-row.flex-center.confirm-screen-identicons', [ - h('div.confirm-screen-account-wrapper', [ - h( - Identicon, - { - address: fromAddress, - diameter: 60, - }, - ), - h('span.confirm-screen-account-name', fromName), - // h('span.confirm-screen-account-number', fromAddress.slice(fromAddress.length - 4)), - ]), - h('i.fa.fa-arrow-right.fa-lg'), - h('div.confirm-screen-account-wrapper', [ - h( - Identicon, - { - address: txParams.to, - diameter: 60, - }, - ), - h('span.confirm-screen-account-name', toName), - // h('span.confirm-screen-account-number', toAddress.slice(toAddress.length - 4)), - ]), - ]), - // h('h3.flex-center.confirm-screen-sending-to-message', { - // style: { - // textAlign: 'center', - // fontSize: '16px', - // }, - // }, [ - // `You're sending to Recipient ...${toAddress.slice(toAddress.length - 4)}`, - // ]), - - h('h3.flex-center.confirm-screen-send-amount', [`${amountInFIAT}`]), - h('h3.flex-center.confirm-screen-send-amount-currency', [ currentCurrency.toUpperCase() ]), - h('div.flex-center.confirm-memo-wrapper', [ - h('h3.confirm-screen-send-memo', [ memo ? `"${memo}"` : '' ]), + h('div.confirm-screen-rows', [ + h('section.flex-row.flex-center.confirm-screen-row', [ + h('span.confirm-screen-label.confirm-screen-section-column', [ this.props.t('from') ]), + h('div.confirm-screen-section-column', [ + h('div.confirm-screen-row-info', fromName), + h('div.confirm-screen-row-detail', `...${fromAddress.slice(fromAddress.length - 4)}`), + ]), ]), - h('div.confirm-screen-rows', [ - h('section.flex-row.flex-center.confirm-screen-row', [ - h('span.confirm-screen-label.confirm-screen-section-column', [ this.props.t('from') ]), - h('div.confirm-screen-section-column', [ - h('div.confirm-screen-row-info', fromName), - h('div.confirm-screen-row-detail', `...${fromAddress.slice(fromAddress.length - 4)}`), - ]), + h('section.flex-row.flex-center.confirm-screen-row', [ + h('span.confirm-screen-label.confirm-screen-section-column', [ this.props.t('to') ]), + h('div.confirm-screen-section-column', [ + h('div.confirm-screen-row-info', toName), + h('div.confirm-screen-row-detail', `...${toAddress.slice(toAddress.length - 4)}`), ]), + ]), - h('section.flex-row.flex-center.confirm-screen-row', [ - h('span.confirm-screen-label.confirm-screen-section-column', [ this.props.t('to') ]), - h('div.confirm-screen-section-column', [ - h('div.confirm-screen-row-info', toName), - h('div.confirm-screen-row-detail', `...${toAddress.slice(toAddress.length - 4)}`), - ]), + h('section.flex-row.flex-center.confirm-screen-row', [ + h('span.confirm-screen-label.confirm-screen-section-column', [ this.props.t('gasFee') ]), + h('div.confirm-screen-section-column', [ + h(GasFeeDisplay, { + gasTotal: gasTotal || gasFeeInHex, + conversionRate, + convertedCurrency, + onClick: () => showCustomizeGasModal(txMeta, sendGasLimit, sendGasPrice, gasTotal), + }), ]), + ]), - h('section.flex-row.flex-center.confirm-screen-row', [ - h('span.confirm-screen-label.confirm-screen-section-column', [ this.props.t('gasFee') ]), - h('div.confirm-screen-section-column', [ - h(GasFeeDisplay, { - gasTotal: gasTotal || gasFeeInHex, - conversionRate, - convertedCurrency, - onClick: () => showCustomizeGasModal(txMeta, sendGasLimit, sendGasPrice, gasTotal), - }), - ]), + h('section.flex-row.flex-center.confirm-screen-row.confirm-screen-total-box ', [ + h('div.confirm-screen-section-column', [ + h('span.confirm-screen-label', [ this.props.t('total') + ' ' ]), + h('div.confirm-screen-total-box__subtitle', [ this.props.t('amountPlusGas') ]), ]), - h('section.flex-row.flex-center.confirm-screen-row.confirm-screen-total-box ', [ - h('div.confirm-screen-section-column', [ - h('span.confirm-screen-label', [ this.props.t('total') + ' ' ]), - h('div.confirm-screen-total-box__subtitle', [ this.props.t('amountPlusGas') ]), - ]), - - h('div.confirm-screen-section-column', [ - h('div.confirm-screen-row-info', `${totalInFIAT} ${currentCurrency.toUpperCase()}`), - h('div.confirm-screen-row-detail', `${totalInETH} ETH`), - ]), + h('div.confirm-screen-section-column', [ + h('div.confirm-screen-row-info', `${totalInFIAT} ${currentCurrency.toUpperCase()}`), + h('div.confirm-screen-row-detail', `${totalInETH} ETH`), ]), ]), - - // These are latest errors handling from master - // Leaving as comments as reference when we start implementing error handling - // h('style', ` - // .conf-buttons button { - // margin-left: 10px; - // text-transform: uppercase; - // } - // `), - - // txMeta.simulationFails ? - // h('.error', { - // style: { - // marginLeft: 50, - // fontSize: '0.9em', - // }, - // }, 'Transaction Error. Exception thrown in contract code.') - // : null, - - // !isValidAddress ? - // h('.error', { - // style: { - // marginLeft: 50, - // fontSize: '0.9em', - // }, - // }, 'Recipient address is invalid. Sending this transaction will result in a loss of ETH.') - // : null, - - // insufficientBalance ? - // h('span.error', { - // style: { - // marginLeft: 50, - // fontSize: '0.9em', - // }, - // }, 'Insufficient balance for transaction') - // : null, - - // // send + cancel - // h('.flex-row.flex-space-around.conf-buttons', { - // style: { - // display: 'flex', - // justifyContent: 'flex-end', - // margin: '14px 25px', - // }, - // }, [ - // h('button', { - // onClick: (event) => { - // this.resetGasFields() - // event.preventDefault() - // }, - // }, 'Reset'), - - // // Accept Button or Buy Button - // insufficientBalance ? h('button.btn-green', { onClick: props.buyEth }, 'Buy Ether') : - // h('input.confirm.btn-green', { - // type: 'submit', - // value: 'SUBMIT', - // style: { marginLeft: '10px' }, - // disabled: buyDisabled, - // }), - - // h('button.cancel.btn-red', { - // onClick: props.cancelTransaction, - // }, 'Reject'), - // ]), - // showRejectAll ? h('.flex-row.flex-space-around.conf-buttons', { - // style: { - // display: 'flex', - // justifyContent: 'flex-end', - // margin: '14px 25px', - // }, - // }, [ - // h('button.cancel.btn-red', { - // onClick: props.cancelAllTransactions, - // }, 'Reject All'), - // ]) : null, - // ]), - // ]) - // ) - // } ]), - h('form#pending-tx-form', { - onSubmit: this.onSubmit, - }, [ - h('.page-container__footer', [ - // Cancel Button - h('button.btn-cancel.page-container__footer-button.allcaps', { - onClick: (event) => { - clearSend() - this.cancel(event, txMeta) - }, - }, this.props.t('cancel')), - - // Accept Button - h('button.btn-confirm.page-container__footer-button.allcaps', [this.props.t('confirm')]), - ]), +// These are latest errors handling from master +// Leaving as comments as reference when we start implementing error handling +// h('style', ` +// .conf-buttons button { +// margin-left: 10px; +// text-transform: uppercase; +// } +// `), + +// txMeta.simulationFails ? +// h('.error', { +// style: { +// marginLeft: 50, +// fontSize: '0.9em', +// }, +// }, 'Transaction Error. Exception thrown in contract code.') +// : null, + +// !isValidAddress ? +// h('.error', { +// style: { +// marginLeft: 50, +// fontSize: '0.9em', +// }, +// }, 'Recipient address is invalid. Sending this transaction will result in a loss of ETH.') +// : null, + +// insufficientBalance ? +// h('span.error', { +// style: { +// marginLeft: 50, +// fontSize: '0.9em', +// }, +// }, 'Insufficient balance for transaction') +// : null, + +// // send + cancel +// h('.flex-row.flex-space-around.conf-buttons', { +// style: { +// display: 'flex', +// justifyContent: 'flex-end', +// margin: '14px 25px', +// }, +// }, [ +// h('button', { +// onClick: (event) => { +// this.resetGasFields() +// event.preventDefault() +// }, +// }, 'Reset'), + +// // Accept Button or Buy Button +// insufficientBalance ? h('button.btn-green', { onClick: props.buyEth }, 'Buy Ether') : +// h('input.confirm.btn-green', { +// type: 'submit', +// value: 'SUBMIT', +// style: { marginLeft: '10px' }, +// disabled: buyDisabled, +// }), + +// h('button.cancel.btn-red', { +// onClick: props.cancelTransaction, +// }, 'Reject'), +// ]), +// showRejectAll ? h('.flex-row.flex-space-around.conf-buttons', { +// style: { +// display: 'flex', +// justifyContent: 'flex-end', +// margin: '14px 25px', +// }, +// }, [ +// h('button.cancel.btn-red', { +// onClick: props.cancelAllTransactions, +// }, 'Reject All'), +// ]) : null, +// ]), +// ]) +// ) +// } + ]), + + h('form#pending-tx-form', { + onSubmit: this.onSubmit, + }, [ + h('.page-container__footer', [ + // Cancel Button + h('button.btn-cancel.page-container__footer-button.allcaps', { + onClick: (event) => { + clearSend() + this.cancel(event, txMeta) + }, + }, this.props.t('cancel')), + + // Accept Button + h('button.btn-confirm.page-container__footer-button.allcaps', [this.props.t('confirm')]), ]), ]), ]) @@ -536,4 +523,4 @@ ConfirmSendEther.prototype.bnMultiplyByFraction = function (targetBN, numerator, const numBN = new BN(numerator) const denomBN = new BN(denominator) return targetBN.mul(numBN).div(denomBN) -} +} \ No newline at end of file diff --git a/ui/app/components/pending-tx/confirm-send-token.js b/ui/app/components/pending-tx/confirm-send-token.js index d53f8b32f..50d803fc4 100644 --- a/ui/app/components/pending-tx/confirm-send-token.js +++ b/ui/app/components/pending-tx/confirm-send-token.js @@ -86,6 +86,7 @@ function mapDispatchToProps (dispatch, ownProps) { amount: tokenAmountInHex, errors: { to: null, amount: null }, editingTransactionId: id, + token: ownProps.token, })) dispatch(actions.showSendTokenPage()) }, diff --git a/ui/app/components/pending-tx/index.js b/ui/app/components/pending-tx/index.js index e490a45f4..0a8813b03 100644 --- a/ui/app/components/pending-tx/index.js +++ b/ui/app/components/pending-tx/index.js @@ -64,13 +64,20 @@ PendingTx.prototype.componentWillMount = async function () { }) } - try { + // inspect tx data for supported special confirmation screens + let isTokenTransaction = false + if (txParams.data) { + const tokenData = abiDecoder.decodeMethod(txParams.data) + const { name: tokenMethodName } = tokenData || {} + isTokenTransaction = (tokenMethodName === 'transfer') + } + + if (isTokenTransaction) { const token = util.getContractAtAddress(txParams.to) const results = await Promise.all([ token.symbol(), token.decimals(), ]) - const [ symbol, decimals ] = results if (symbol[0] && decimals[0]) { @@ -83,11 +90,14 @@ PendingTx.prototype.componentWillMount = async function () { }) } else { this.setState({ - transactionType: TX_TYPES.SEND_ETHER, + transactionType: TX_TYPES.SEND_TOKEN, + tokenAddress: txParams.to, + tokenSymbol: null, + tokenDecimals: null, isFetching: false, }) } - } catch (e) { + } else { this.setState({ transactionType: TX_TYPES.SEND_ETHER, isFetching: false, diff --git a/ui/app/components/sender-to-recipient.js b/ui/app/components/sender-to-recipient.js index dc72dc303..420d50e42 100644 --- a/ui/app/components/sender-to-recipient.js +++ b/ui/app/components/sender-to-recipient.js @@ -5,6 +5,28 @@ const PropTypes = require('prop-types') const Identicon = require('./identicon') class SenderToRecipient extends Component { + renderRecipientIcon () { + const { recipientAddress } = this.props + return ( + recipientAddress + ? h(Identicon, { address: recipientAddress, diameter: 20 }) + : h('i.fa.fa-file-text-o') + ) + } + + renderRecipient () { + const { recipientName } = this.props + return ( + h('.sender-to-recipient__recipient', [ + this.renderRecipientIcon(), + h( + '.sender-to-recipient__name.sender-to-recipient__recipient-name', + recipientName || this.props.t('newContract') + ), + ]) + ) + } + render () { const { senderName, senderAddress } = this.props @@ -28,10 +50,7 @@ class SenderToRecipient extends Component { }), ]), ]), - h('.sender-to-recipient__recipient', [ - h('i.fa.fa-file-text-o'), - h('.sender-to-recipient__name.sender-to-recipient__recipient-name', this.props.t('newContract')), - ]), + this.renderRecipient(), ]) ) } @@ -41,6 +60,8 @@ SenderToRecipient.propTypes = { senderName: PropTypes.string, senderAddress: PropTypes.string, localeMessages: PropTypes.object, + recipientName: PropTypes.string, + recipientAddress: PropTypes.string, } module.exports = { diff --git a/ui/app/css/itcss/components/network.scss b/ui/app/css/itcss/components/network.scss index 374cb71b6..c34b5cd06 100644 --- a/ui/app/css/itcss/components/network.scss +++ b/ui/app/css/itcss/components/network.scss @@ -159,3 +159,15 @@ .network-caret { margin: 0 8px 2px; } + +.network-display { + &__container { + display: flex; + align-items: center; + justify-content: flex-start; + + @media screen and (min-width: 576px) { + display: none; + } + } +} diff --git a/ui/app/css/itcss/components/send.scss b/ui/app/css/itcss/components/send.scss index bdea1b008..263b362ca 100644 --- a/ui/app/css/itcss/components/send.scss +++ b/ui/app/css/itcss/components/send.scss @@ -526,14 +526,10 @@ } &__form { - padding: 13px 0; - width: 100%; - overflow-y: auto; + padding: 10px 0 25px; @media screen and (max-width: $break-small) { - padding: 13px 0; margin: 0; - overflow-y: auto; flex: 1 1 auto; } } diff --git a/ui/app/css/itcss/generic/index.scss b/ui/app/css/itcss/generic/index.scss index 1e226b93e..08e639d74 100644 --- a/ui/app/css/itcss/generic/index.scss +++ b/ui/app/css/itcss/generic/index.scss @@ -106,6 +106,12 @@ input.large-input { } } + &__header-row { + padding-bottom: 10px; + display: flex; + justify-content: space-between; + } + &__footer { display: flex; flex-flow: row; @@ -138,7 +144,6 @@ input.large-input { color: #2f9ae0; font-size: 1rem; cursor: pointer; - padding-bottom: 10px; font-weight: 400; } diff --git a/ui/app/selectors.js b/ui/app/selectors.js index d37c26f7e..2bdc39004 100644 --- a/ui/app/selectors.js +++ b/ui/app/selectors.js @@ -56,8 +56,9 @@ function getSelectedToken (state) { const tokens = state.metamask.tokens || [] const selectedTokenAddress = state.metamask.selectedTokenAddress const selectedToken = tokens.filter(({ address }) => address === selectedTokenAddress)[0] + const sendToken = state.metamask.send.token - return selectedToken || null + return selectedToken || sendToken || null } function getSelectedTokenExchangeRate (state) { diff --git a/ui/app/send-v2.js b/ui/app/send-v2.js index 49947a11c..8a20ffe66 100644 --- a/ui/app/send-v2.js +++ b/ui/app/send-v2.js @@ -479,18 +479,19 @@ SendTransactionScreen.prototype.renderMemoRow = function () { } SendTransactionScreen.prototype.renderForm = function () { - return h('div.send-v2__form', {}, [ + return h('.page-container__content', {}, [ + h('.send-v2__form', [ + this.renderFromRow(), - this.renderFromRow(), + this.renderToRow(), - this.renderToRow(), + this.renderAmountRow(), - this.renderAmountRow(), + this.renderGasRow(), - this.renderGasRow(), - - // this.renderMemoRow(), + // this.renderMemoRow(), + ]), ]) }