Merge branch 'master' into i18n-translator-redux

feature/default_network_editable
Dan 7 years ago
commit be845fd190
  1. 2
      .eslintrc
  2. 2
      .gitignore
  3. 10
      CHANGELOG.md
  4. 2
      README.md
  5. 873
      app/_locales/de/messages.json
  6. 650
      app/_locales/es/messages.json
  7. 10
      app/_locales/es_419/messages.json
  8. 819
      app/_locales/hn/messages.json
  9. 819
      app/_locales/nl/messages.json
  10. 819
      app/_locales/ru/messages.json
  11. 2
      app/manifest.json
  12. 14
      app/scripts/README.md
  13. 9
      app/scripts/background.js
  14. 4
      app/scripts/controllers/README.md
  15. 11
      app/scripts/lib/notification-manager.js
  16. 599
      app/scripts/metamask-controller.js
  17. 5
      app/scripts/migrations/README.md
  18. 1
      app/scripts/popup.js
  19. 5
      development/README.md
  20. 13
      docs/README.md
  21. 6
      gulpfile.js
  22. 5
      notices/README.md
  23. 4
      package.json
  24. 7
      test/integration/lib/send-new-ui.js
  25. 2
      ui/app/components/currency-input.js
  26. 1
      ui/app/components/input-number.js
  27. 51
      ui/app/components/network-display.js
  28. 18
      ui/app/components/pending-tx/confirm-deploy-contract.js
  29. 341
      ui/app/components/pending-tx/confirm-send-ether.js
  30. 1
      ui/app/components/pending-tx/confirm-send-token.js
  31. 18
      ui/app/components/pending-tx/index.js
  32. 29
      ui/app/components/sender-to-recipient.js
  33. 12
      ui/app/css/itcss/components/network.scss
  34. 6
      ui/app/css/itcss/components/send.scss
  35. 7
      ui/app/css/itcss/generic/index.scss
  36. 3
      ui/app/selectors.js
  37. 15
      ui/app/send-v2.js

@ -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,

2
.gitignore vendored

@ -6,7 +6,9 @@ app/bower_components
test/bower_components
package
# IDEs
.idea
.vscode
temp
.tmp

@ -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

@ -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

@ -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"
}
}

File diff suppressed because it is too large Load Diff

@ -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"
}
}

@ -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": "आप हसषर कर रह"
}
}

@ -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"
}
}

@ -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": "Вы подписываете"
}
}

@ -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__",

@ -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

@ -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
})
}

@ -0,0 +1,4 @@
# Controllers
Different controllers (in the sense of *VC *View-Controller).

@ -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
}

@ -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

@ -0,0 +1,5 @@
# Migrations
Data (user data, config files etc.) is migrated from one version to another.
Migrations are called by {} from {} during {}.

@ -69,6 +69,7 @@ async function start() {
function closePopupIfOpen (windowType) {
if (windowType !== 'notification') {
// should close only chrome popup
notificationManager.closePopup()
}
}

@ -0,0 +1,5 @@
# Development
Several files which are needed for developing on(!) MetaMask.
Usually each files contains information about its scope / usage.

@ -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)

@ -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('./')))

@ -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.

@ -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",

@ -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')

@ -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,

@ -55,6 +55,7 @@ InputNumber.prototype.render = function () {
className: 'customize-gas-input',
value,
placeholder,
type: 'number',
onInputChange: newValue => {
this.setValue(newValue)
},

@ -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)

@ -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)

@ -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)
}
}

@ -86,6 +86,7 @@ function mapDispatchToProps (dispatch, ownProps) {
amount: tokenAmountInHex,
errors: { to: null, amount: null },
editingTransactionId: id,
token: ownProps.token,
}))
dispatch(actions.showSendTokenPage())
},

@ -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,

@ -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 = {

@ -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;
}
}
}

@ -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;
}
}

@ -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;
}

@ -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) {

@ -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(),
]),
])
}

Loading…
Cancel
Save