aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.circleci/config.yml17
-rw-r--r--README.md2
-rw-r--r--app/_locales/sl/messages.json819
-rw-r--r--app/_locales/th/messages.json819
-rw-r--r--app/_locales/zh_TW/messages.json864
-rw-r--r--app/scripts/lib/setupRaven.js32
-rw-r--r--app/scripts/vendor/raven.min.js3
-rw-r--r--gulpfile.js6
-rw-r--r--package-lock.json68
-rw-r--r--package.json11
-rw-r--r--test/integration/lib/add-token.js22
-rw-r--r--test/integration/lib/confirm-sig-requests.js6
-rw-r--r--test/integration/lib/send-new-ui.js8
-rw-r--r--ui/app/accounts/import/json.js4
-rw-r--r--ui/app/accounts/import/private-key.js4
-rw-r--r--ui/app/accounts/new-account/create-form.js6
-rw-r--r--ui/app/actions.js4
-rw-r--r--ui/app/add-token.js8
-rw-r--r--ui/app/components/customize-gas-modal/index.js8
-rw-r--r--ui/app/components/ens-input.js41
-rw-r--r--ui/app/components/modals/account-details-modal.js4
-rw-r--r--ui/app/components/modals/deposit-ether-modal.js2
-rw-r--r--ui/app/components/modals/export-private-key-modal.js6
-rw-r--r--ui/app/components/send/send-v2-container.js4
-rw-r--r--ui/app/components/shapeshift-form.js2
-rw-r--r--ui/app/components/signature-request.js4
-rw-r--r--ui/app/components/tx-view.js6
-rw-r--r--ui/app/components/wallet-view.js2
-rw-r--r--ui/app/css/itcss/components/add-token.scss9
-rw-r--r--ui/app/css/itcss/components/buttons.scss84
-rw-r--r--ui/app/css/itcss/components/hero-balance.scss3
-rw-r--r--ui/app/css/itcss/components/modal.scss13
-rw-r--r--ui/app/css/itcss/components/new-account.scss27
-rw-r--r--ui/app/css/itcss/components/request-signature.scss34
-rw-r--r--ui/app/css/itcss/components/send.scss8
-rw-r--r--ui/app/css/itcss/components/settings.scss38
-rw-r--r--ui/app/css/itcss/generic/index.scss2
-rw-r--r--ui/app/css/itcss/settings/variables.scss2
-rw-r--r--ui/app/reducers/metamask.js4
-rw-r--r--ui/app/send-v2.js24
-rw-r--r--ui/app/settings.js8
41 files changed, 2828 insertions, 210 deletions
diff --git a/.circleci/config.yml b/.circleci/config.yml
index c14909783..bcc9a299f 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -6,6 +6,9 @@ workflows:
jobs:
- prep-deps-npm
- prep-deps-firefox
+ - build:
+ requires:
+ - prep-deps-npm
- prep-scss:
requires:
- prep-deps-npm
@@ -200,3 +203,17 @@ jobs:
- run:
name: test:integration:mascara
command: npm run test:mascara
+
+ build:
+ docker:
+ - image: circleci/node:8-browsers
+ steps:
+ - checkout
+ - restore_cache:
+ key: dependency-cache-{{ checksum "package-lock.json" }}
+ - run:
+ name: build:dist
+ command: npm run dist
+ - run:
+ name: build:debug
+ command: find dist/ -type f -exec md5sum {} \; | sort -k 2
diff --git a/README.md b/README.md
index a3bf27709..2e68991b5 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,5 @@
# MetaMask Browser Extension
-[![Build Status](https://circleci.com/gh/MetaMask/metamask-extension.svg?style=shield&circle-token=a1ddcf3cd38e29267f254c9c59d556d513e3a1fd)](https://circleci.com/gh/MetaMask/metamask-extension) [![Coverage Status](https://coveralls.io/repos/github/MetaMask/metamask-extension/badge.svg?branch=master)](https://coveralls.io/github/MetaMask/metamask-extension?branch=master) [![Greenkeeper badge](https://badges.greenkeeper.io/MetaMask/metamask-extension.svg)](https://greenkeeper.io/) [![Stories in Ready](https://badge.waffle.io/MetaMask/metamask-extension.png?label=in%20progress&title=waffle.io)](http://waffle.io/MetaMask/metamask-extension)
+[![Build Status](https://circleci.com/gh/MetaMask/metamask-extension.svg?style=shield&circle-token=a1ddcf3cd38e29267f254c9c59d556d513e3a1fd)](https://circleci.com/gh/MetaMask/metamask-extension) [![Coverage Status](https://coveralls.io/repos/github/MetaMask/metamask-extension/badge.svg?branch=master)](https://coveralls.io/github/MetaMask/metamask-extension?branch=master) [![Greenkeeper badge](https://badges.greenkeeper.io/MetaMask/metamask-extension.svg)](https://greenkeeper.io/) [![Stories in Ready](https://badge.waffle.io/MetaMask/metamask-extension.png?label=in%20progress&title=waffle.io)](https://waffle.io/MetaMask/metamask-extension)
## Support
diff --git a/app/_locales/sl/messages.json b/app/_locales/sl/messages.json
new file mode 100644
index 000000000..0532f11b2
--- /dev/null
+++ b/app/_locales/sl/messages.json
@@ -0,0 +1,819 @@
+{
+ "accept": {
+ "message": "Sprejmi"
+ },
+ "account": {
+ "message": "Račun"
+ },
+ "accountDetails": {
+ "message": "Podrobnosti računa"
+ },
+ "accountName": {
+ "message": "Ime računa"
+ },
+ "address": {
+ "message": "Naslov"
+ },
+ "addCustomToken": {
+ "message": "Dodaj žeton po meri"
+ },
+ "addToken": {
+ "message": "Dodaj žeton"
+ },
+ "addTokens": {
+ "message": "Dodaj žetone"
+ },
+ "amount": {
+ "message": "Znesek"
+ },
+ "amountPlusGas": {
+ "message": "Znesek + Gas"
+ },
+ "appDescription": {
+ "message": "Denarnica za Ethereum v brskalniku",
+ "description": "The description of the application"
+ },
+ "appName": {
+ "message": "MetaMask",
+ "description": "The name of the application"
+ },
+ "attemptingConnect": {
+ "message": "Povezovanje z verigo blokov ..."
+ },
+ "attributions": {
+ "message": "Dodelitve"
+ },
+ "available": {
+ "message": "Na voljo"
+ },
+ "back": {
+ "message": "Nazaj"
+ },
+ "balance": {
+ "message": "Znesek:"
+ },
+ "balances": {
+ "message": "Vaš znesek"
+ },
+ "balanceIsInsufficientGas": {
+ "message": "Napačen znesek za skupno gas vrednost"
+ },
+ "beta": {
+ "message": "BETA"
+ },
+ "betweenMinAndMax": {
+ "message": "mora biti večji ali enak $1 in manjši ali enak $1.",
+ "description": "helper for inputting hex as decimal input"
+ },
+ "blockiesIdenticon": {
+ "message": "Uporabite Blockies Identicon"
+ },
+ "borrowDharma": {
+ "message": "Izposoja z Dharma (Beta)"
+ },
+ "builtInCalifornia": {
+ "message": "MetaMask je ustvarjen v Kaliforniji."
+ },
+ "buy": {
+ "message": "Kupi"
+ },
+ "buyCoinbase": {
+ "message": "Kupi na Coinbase"
+ },
+ "buyCoinbaseExplainer": {
+ "message": "Coinbase je najpopularnejši načun za kupovanje in prodajo bitcoinov, ethereuma, in litecoina."
+ },
+ "cancel": {
+ "message": "Prekliči"
+ },
+ "classicInterface": {
+ "message": "Uporabi navaden način"
+ },
+ "clickCopy": {
+ "message": "Kliknite za kopiranje"
+ },
+ "confirm": {
+ "message": "Potrdi"
+ },
+ "confirmContract": {
+ "message": "Potrdi pogodbo"
+ },
+ "confirmPassword": {
+ "message": "Potrdi geslo"
+ },
+ "confirmTransaction": {
+ "message": "Potrdi transakcijo"
+ },
+ "continue": {
+ "message": "Nadaljuj"
+ },
+ "continueToCoinbase": {
+ "message": "Nadaljuj na Coinbase"
+ },
+ "contractDeployment": {
+ "message": "Ustvarjanje pogodbe"
+ },
+ "conversionProgress": {
+ "message": "Poteka pretvorba"
+ },
+ "copiedButton": {
+ "message": "Kopirano"
+ },
+ "copiedClipboard": {
+ "message": "Kopirano v odložišče"
+ },
+ "copiedExclamation": {
+ "message": "Kopirano!"
+ },
+ "copiedSafe": {
+ "message": "Prilepil sem ga na varno!"
+ },
+ "copy": {
+ "message": "Kopiraj"
+ },
+ "copyToClipboard": {
+ "message": "Kopiraj v odložišče"
+ },
+ "copyButton": {
+ "message": " Kopiraj "
+ },
+ "copyPrivateKey": {
+ "message": "To je vaš zesebni ključ (kliknite za kopiranje)"
+ },
+ "create": {
+ "message": "Ustvari"
+ },
+ "createAccount": {
+ "message": "Ustvari račun"
+ },
+ "createDen": {
+ "message": "Ustvari"
+ },
+ "crypto": {
+ "message": "Kripto",
+ "description": "Exchange type (cryptocurrencies)"
+ },
+ "currentConversion": {
+ "message": "Trenutna cena"
+ },
+ "currentNetwork": {
+ "message": "Trenutno omrežje"
+ },
+ "customGas": {
+ "message": "Prilagodi gas"
+ },
+ "customize": {
+ "message": "Prilagodi"
+ },
+ "customRPC": {
+ "message": "Poljuben RPC"
+ },
+ "decimalsMustZerotoTen": {
+ "message": "Decimalk mora biti vsaj 0, in ne več kot 36."
+ },
+ "decimal": {
+ "message": "Decimalke natančnosti"
+ },
+ "defaultNetwork": {
+ "message": "Privzeto omrežje za transakcije je Main Net."
+ },
+ "denExplainer": {
+ "message": "DEN je vaša šifrirana shramba v MetaMasku."
+ },
+ "deposit": {
+ "message": "Vplačilo"
+ },
+ "depositBTC": {
+ "message": "Vplačajte vaš BTC na spodnji naslov:"
+ },
+ "depositCoin": {
+ "message": "Vplačajte $1 na spodnji naslov",
+ "description": "Tells the user what coin they have selected to deposit with shapeshift"
+ },
+ "depositEth": {
+ "message": "Vplačilo ETH"
+ },
+ "depositEther": {
+ "message": "Vplačilo ethera"
+ },
+ "depositFiat": {
+ "message": "Vplačilo s klasičnimi valutami"
+ },
+ "depositFromAccount": {
+ "message": "Vplačilo iz drugega računa"
+ },
+ "depositShapeShift": {
+ "message": "Vplačilo z ShapeShift"
+ },
+ "depositShapeShiftExplainer": {
+ "message": "Če imate druge kriptovalute, lahko vpačate ether neposredno v MetaMask. Brez računov."
+ },
+ "details": {
+ "message": "Podrobnosti"
+ },
+ "directDeposit": {
+ "message": "Direktno vplačilo"
+ },
+ "directDepositEther": {
+ "message": "Direktno vplačilo ehera"
+ },
+ "directDepositEtherExplainer": {
+ "message": "Če že imate ether, ga lahko najhitreje dobite v MetaMask z direktnim vplačilom."
+ },
+ "done": {
+ "message": "Končano"
+ },
+ "downloadStatelogs": {
+ "message": "Prenesi state dnevnike"
+ },
+ "edit": {
+ "message": "Uredi"
+ },
+ "editAccountName": {
+ "message": "Uredi ime računa"
+ },
+ "emailUs": {
+ "message": "Pišite nam!"
+ },
+ "encryptNewDen": {
+ "message": "Šifrirajte DEN"
+ },
+ "enterPassword": {
+ "message": "Vpišite geslo"
+ },
+ "enterPasswordConfirm": {
+ "message": "Potrdite geslo"
+ },
+ "etherscanView": {
+ "message": "Poglejte račun na Etherscan"
+ },
+ "exchangeRate": {
+ "message": "Menjalni tečaj"
+ },
+ "exportPrivateKey": {
+ "message": "Izvozi zasebni ključ"
+ },
+ "exportPrivateKeyWarning": {
+ "message": "Izvažanje zasebnih ključev je na lastno odgovornost."
+ },
+ "failed": {
+ "message": "Ni uspelo"
+ },
+ "fiat": {
+ "message": "FIAT",
+ "description": "Exchange type"
+ },
+ "fileImportFail": {
+ "message": "Uvoz z datoteko ni uspel? Kliknite tukaj!",
+ "description": "Helps user import their account from a JSON file"
+ },
+ "followTwitter": {
+ "message": "Sledite nam na Twitterju"
+ },
+ "from": {
+ "message": "Od"
+ },
+ "fromToSame": {
+ "message": "From and To address cannot be the same"
+ },
+ "fromShapeShift": {
+ "message": "Od ShapeShift"
+ },
+ "gas": {
+ "message": "Gas",
+ "description": "Short indication of gas cost"
+ },
+ "gasFee": {
+ "message": "Gas fee"
+ },
+ "gasLimit": {
+ "message": "Gas limit"
+ },
+ "gasLimitCalculation": {
+ "message": "Priporočen gas limit je izračunan glede na omrežje."
+ },
+ "gasLimitRequired": {
+ "message": "Gas limit je zahtevan"
+ },
+ "gasLimitTooLow": {
+ "message": "Gas limit mora biti najmanj 21000"
+ },
+ "generatingSeed": {
+ "message": "Ustvarjenje seed ..."
+ },
+ "gasPrice": {
+ "message": "Gas price (GWEI)"
+ },
+ "gasPriceCalculation": {
+ "message": "Priporočen gas price je izračunan glede na omrežje"
+ },
+ "gasPriceRequired": {
+ "message": "Gas price je zahtevan"
+ },
+ "getEther": {
+ "message": "Pridobite ether"
+ },
+ "getEtherFromFaucet": {
+ "message": "Pridobite ether iz fauceta za $1",
+ "description": "Displays network name for Ether faucet"
+ },
+ "greaterThanMin": {
+ "message": "mora biti višji ali enak $1.",
+ "description": "helper for inputting hex as decimal input"
+ },
+ "here": {
+ "message": "tukaj",
+ "description": "as in -click here- for more information (goes with troubleTokenBalances)"
+ },
+ "hereList": {
+ "message": "Tukaj je seznam!!!"
+ },
+ "hide": {
+ "message": "Skrij"
+ },
+ "hideToken": {
+ "message": "Skrij žeton"
+ },
+ "hideTokenPrompt": {
+ "message": "Skrijem žeton?"
+ },
+ "howToDeposit": {
+ "message": "Kako želite vplačati ether?"
+ },
+ "holdEther": {
+ "message": "Omogoča vam, da imate eter in žetone in služi kot most za decentralizirane aplikacije."
+ },
+ "import": {
+ "message": "Uvozi",
+ "description": "Button to import an account from a selected file"
+ },
+ "importAccount": {
+ "message": "Uvozi račun"
+ },
+ "importAccountMsg": {
+ "message":" Uvoženi računi ne bodo povezani s prvotnim seedphaseom. Preberite več o uvoženih računih "
+ },
+ "importAnAccount": {
+ "message": "Uvozi račun"
+ },
+ "importDen": {
+ "message": "Uvozi DEN"
+ },
+ "imported": {
+ "message": "Uvoženo",
+ "description": "status showing that an account has been fully loaded into the keyring"
+ },
+ "infoHelp": {
+ "message": "Info & Pomoč"
+ },
+ "insufficientFunds": {
+ "message": "Nezadostna sredstva."
+ },
+ "insufficientTokens": {
+ "message": "Nezadostni žetoni."
+ },
+ "invalidAddress": {
+ "message": "Nepravilen naslov"
+ },
+ "invalidAddressRecipient": {
+ "message": "Prejemnikov naslov je neveljaven"
+ },
+ "invalidGasParams": {
+ "message": "Nepravilno nastavljen gas"
+ },
+ "invalidInput": {
+ "message": "Napačen vnos."
+ },
+ "invalidRequest": {
+ "message": "Napačna zahteva"
+ },
+ "invalidRPC": {
+ "message": "Napačen RPC URI"
+ },
+ "jsonFail": {
+ "message": "Nekaj je bilo narobe. Prepričajte se, da je JSON datoteka pravilno oblikovana."
+ },
+ "jsonFile": {
+ "message": "JSON datoteka",
+ "description": "format for importing an account"
+ },
+ "kovan": {
+ "message": "Testno omrežje Kovan"
+ },
+ "knowledgeDataBase": {
+ "message": "Obiščite našo pomoč"
+ },
+ "lessThanMax": {
+ "message": "mora biti večji ali enak $1.",
+ "description": "helper for inputting hex as decimal input"
+ },
+ "likeToAddTokens": {
+ "message": "Želite dodati te žetone?"
+ },
+ "limit": {
+ "message": "Omejitev"
+ },
+ "loading": {
+ "message": "Nalaganje ..."
+ },
+ "loadingTokens": {
+ "message": "Nalaganje žetonov ..."
+ },
+ "localhost": {
+ "message": "Localhost 8545"
+ },
+ "login": {
+ "message": "Prijava"
+ },
+ "logout": {
+ "message": "Odjava"
+ },
+ "loose": {
+ "message": "Loose"
+ },
+ "loweCaseWords": {
+ "message": "seed words imajo lahko le male črke"
+ },
+ "mainnet": {
+ "message": "Glavno omrežje"
+ },
+ "message": {
+ "message": "Sporočilo"
+ },
+ "metamaskDescription": {
+ "message": "MetaMask je varen identitetni sklad za Ethereum."
+ },
+ "min": {
+ "message": "Najmanj"
+ },
+ "myAccounts": {
+ "message": "Moji računi"
+ },
+ "mustSelectOne": {
+ "message": "Izbran mora biti vsaj 1 žeton."
+ },
+ "needEtherInWallet": {
+ "message": "Za interakcijo z decentraliziranimi aplikacijami, ki uporabljajo MetaMask, boste v svoji denarnici potrebovali eter."
+ },
+ "needImportFile": {
+ "message": "Za uvoz morate izbrati datoteko.",
+ "description": "User is important an account and needs to add a file to continue"
+ },
+ "needImportPassword": {
+ "message": "Za izbrano datoteko morate vnesti geslo.",
+ "description": "Password and file needed to import an account"
+ },
+ "negativeETH": {
+ "message": "Ni mogoče poslati negativne vsote ETH."
+ },
+ "networks": {
+ "message": "Omrežja"
+ },
+ "newAccount": {
+ "message": "Nov račun"
+ },
+ "newAccountNumberName": {
+ "message": "Račun $1",
+ "description": "Default name of next account to be created on create account screen"
+ },
+ "newContract": {
+ "message": "Nova pogodba"
+ },
+ "newPassword": {
+ "message": "Novo geslo (min. 8. črk)"
+ },
+ "newRecipient": {
+ "message": "Nov prejemnik"
+ },
+ "newRPC": {
+ "message": "Nov RPC URL"
+ },
+ "next": {
+ "message": "Naprej"
+ },
+ "noAddressForName": {
+ "message": "Za to ime ni bil nastavljen noben naslov."
+ },
+ "noDeposits": {
+ "message": "Ni prejetih vplačil"
+ },
+ "noTransactionHistory": {
+ "message": "Ni zgodovine transakcij."
+ },
+ "noTransactions": {
+ "message": "Ni transakcij"
+ },
+ "notStarted": {
+ "message": "Ni se začelo"
+ },
+ "oldUI": {
+ "message": "Starejši uporabniški vmesnik"
+ },
+ "oldUIMessage": {
+ "message": "Vrnili ste se v starejši uporabniški vmesnik. V novega se lahko vrnete z možnostjo v spustnem meniju v zgornjem desnem kotu."
+ },
+ "or": {
+ "message": "ali",
+ "description": "choice between creating or importing a new account"
+ },
+ "passwordCorrect": {
+ "message": "Prepričajte se, da je geslo pravilno."
+ },
+ "passwordMismatch": {
+ "message": "gesli se ne ujemata",
+ "description": "in password creation process, the two new password fields did not match"
+ },
+ "passwordShort": {
+ "message": "geslo ni dovolj dolgo",
+ "description": "in password creation process, the password is not long enough to be secure"
+ },
+ "pastePrivateKey": {
+ "message": "Tukaj prilepite zasebni ključ:",
+ "description": "For importing an account from a private key"
+ },
+ "pasteSeed": {
+ "message": "Tukaj prilepite seed phrase!"
+ },
+ "personalAddressDetected": {
+ "message": "Osebni naslov je zaznan. Vnesite naslov žetona."
+ },
+ "pleaseReviewTransaction": {
+ "message": "Preglejte transakcijo."
+ },
+ "privacyMsg": {
+ "message": "Politika zasebnosti"
+ },
+ "privateKey": {
+ "message": "Zasebni ključ",
+ "description": "select this type of file to use to import an account"
+ },
+ "privateKeyWarning": {
+ "message": "Opozorilo: Nikoli ne razkrijte tega ključa. Vsakdo s svojimi zasebnimi ključi lahko ukrade vse premoženje v računu."
+ },
+ "privateNetwork": {
+ "message": "Zasebno omrežje"
+ },
+ "qrCode": {
+ "message": "Prikaži QR kodo"
+ },
+ "readdToken": {
+ "message": "Ta žeton lahko dodate tudi v prihodnosti, tako da odprete možnost »Dodaj žeton« v meniju z računi."
+ },
+ "readMore": {
+ "message": "Preberite več."
+ },
+ "readMore2": {
+ "message": "Preberite več."
+ },
+ "receive": {
+ "message": "Prejmite"
+ },
+ "recipientAddress": {
+ "message": "Prejemnikov naslov"
+ },
+ "refundAddress": {
+ "message": "Vaš naslov za vračilo"
+ },
+ "rejected": {
+ "message": "Zavrnjeno"
+ },
+ "resetAccount": {
+ "message": "Ponastavi račun"
+ },
+ "restoreFromSeed": {
+ "message": "Obnovi iz seed phrase"
+ },
+ "required": {
+ "message": "Zahtevano"
+ },
+ "retryWithMoreGas": {
+ "message": "Poskusi z višjim gas price"
+ },
+ "revealSeedWords": {
+ "message": "Prikaži seed words"
+ },
+ "revealSeedWordsWarning": {
+ "message": "Ne obnovite seed words na javnem mestu! Te besede se lahko uporabijo za krajo vseh vaših računov."
+ },
+ "revert": {
+ "message": "Povrni"
+ },
+ "rinkeby": {
+ "message": "Testno omrežje Rinkeby"
+ },
+ "ropsten": {
+ "message": "Testno omrežje Ropsten"
+ },
+ "sampleAccountName": {
+ "message": "npr. Moj nov račun",
+ "description": "Help user understand concept of adding a human-readable name to their account"
+ },
+ "save": {
+ "message": "Shrani"
+ },
+ "saveAsFile": {
+ "message": "Shrani kot datoteko",
+ "description": "Account export process"
+ },
+ "saveSeedAsFile": {
+ "message": "Shrani seed words kot datoteko"
+ },
+ "search": {
+ "message": "Iskanje"
+ },
+ "secretPhrase": {
+ "message": "Tukaj vnesite svoje seed words, da obnovite svoje račune."
+ },
+ "seedPhraseReq": {
+ "message": "seed phrases so dolgi 12 besed"
+ },
+ "select": {
+ "message": "Izberi"
+ },
+ "selectCurrency": {
+ "message": "Izberi valuto"
+ },
+ "selectService": {
+ "message": "Izberi storitev"
+ },
+ "selectType": {
+ "message": "Izberi vrsto"
+ },
+ "send": {
+ "message": "Pošlji"
+ },
+ "sendETH": {
+ "message": "Pošlji ETH"
+ },
+ "sendTokens": {
+ "message": "Pošlji žetone"
+ },
+ "sendTokensAnywhere": {
+ "message": "Pošljite žetone vsem, ki imajo Ethereum račun"
+ },
+ "settings": {
+ "message": "Nastavitve"
+ },
+ "shapeshiftBuy": {
+ "message": "Kupite z Shapeshift"
+ },
+ "showPrivateKeys": {
+ "message": "Prikaži zasebne ključe"
+ },
+ "showQRCode": {
+ "message": "Prikaži QR kodo"
+ },
+ "sign": {
+ "message": "Podpiši"
+ },
+ "signMessage": {
+ "message": "Podpiši sporočilo"
+ },
+ "signNotice": {
+ "message": "To podpisovanje lahko povzroči \nnevarne stranske učinke. Podpisujte samo sporočila \nstrani, ki jim zaupate s svojim celotnim računom.\n Ta nevarna funkcija bo odstranjena v prihodnji različici. "
+ },
+ "sigRequest": {
+ "message": "Zahteva za podpis"
+ },
+ "sigRequested": {
+ "message": "Podpis je zahtevan"
+ },
+ "spaceBetween": {
+ "message": "med besedami je lahko samo presledek"
+ },
+ "status": {
+ "message": "Status"
+ },
+ "stateLogs": {
+ "message": "State dnevniki"
+ },
+ "stateLogsDescription": {
+ "message": "State dnevniki vsebujejo naslove vašega računa in poslane transakcije.."
+ },
+ "submit": {
+ "message": "Potrdi"
+ },
+ "supportCenter": {
+ "message": "Obiščite našo podporo"
+ },
+ "symbolBetweenZeroTen": {
+ "message": "Simbol mora biti dolg od 0 do 10 znakov."
+ },
+ "takesTooLong": {
+ "message": "Traja predolgo?"
+ },
+ "terms": {
+ "message": "Pogoji uporabe"
+ },
+ "testFaucet": {
+ "message": "Testni faucet"
+ },
+ "to": {
+ "message": "Za"
+ },
+ "toETHviaShapeShift": {
+ "message": "$1 v ETH prek ShapeShift",
+ "description": "system will fill in deposit type in start of message"
+ },
+ "tokenAddress": {
+ "message": "Naslov žetona"
+ },
+ "tokenAlreadyAdded": {
+ "message": "Žeton je že bil dodan."
+ },
+ "tokenBalance": {
+ "message": "Vaš znesek žetona:"
+ },
+ "tokenSelection": {
+ "message": "Poiščite žetone ali jih izberite z našega seznama priljubljenih žetonov."
+ },
+ "tokenSymbol": {
+ "message": "Simbol žetona"
+ },
+ "tokenWarning1": {
+ "message": "Spremljajte žetone, ki ste jih kupili s svojim MetaMask računom. Če ste kupili žetone z drugačnim računom, ti žetoni ne bodo prikazani tukaj."
+ },
+ "total": {
+ "message": "Skupno"
+ },
+ "transactions": {
+ "message": "transakcije"
+ },
+ "transactionMemo": {
+ "message": "Opis transakcije (ni zahtevano)"
+ },
+ "transactionNumber": {
+ "message": "Številka transakcije"
+ },
+ "transfers": {
+ "message": "Prenosi"
+ },
+ "troubleTokenBalances": {
+ "message": "Imeli smo težave pri nalaganju vaših žetonov. Ogledate si jih lahko ",
+ "description": "Followed by a link (here) to view token balances"
+ },
+ "twelveWords": {
+ "message": "Edini način za obnovitev MetaMask računa, je teh 12 besed.\nShranite jih na varno in skrivno mesto."
+ },
+ "typePassword": {
+ "message": "Vpišite vaše geslo"
+ },
+ "uiWelcome": {
+ "message": "Dobrodošli v novem uporabniškem vmesniku (Beta)"
+ },
+ "uiWelcomeMessage": {
+ "message": "Zdaj uporabljate novi MetaMask uporabniški vmesnik. Razglejte se, preizkusite nove funkcije, kot so pošiljanje žetonov, in nas obvestite, če imate kakšne težave."
+ },
+ "unavailable": {
+ "message": "Ni na voljo"
+ },
+ "unknown": {
+ "message": "Neznano"
+ },
+ "unknownNetwork": {
+ "message": "Neznano zasebno omrežje"
+ },
+ "unknownNetworkId": {
+ "message": "Neznan ID omrežja"
+ },
+ "uriErrorMsg": {
+ "message": "URI-ji zahtevajo ustrezno HTTP/HTTPS predpono."
+ },
+ "usaOnly": {
+ "message": "Samo za ZDA",
+ "description": "Using this exchange is limited to people inside the USA"
+ },
+ "usedByClients": {
+ "message": "Uporablja jih več različnih odjemalcev"
+ },
+ "useOldUI": {
+ "message": "Uporabi star uporabniški vmesnik"
+ },
+ "validFileImport": {
+ "message": "Za uvoz morate izbrati pravilno datoteko."
+ },
+ "vaultCreated": {
+ "message": "Račun je ustvarjen"
+ },
+ "viewAccount": {
+ "message": "Poglej račun"
+ },
+ "visitWebSite": {
+ "message": "Obiščite našo spletno stran"
+ },
+ "warning": {
+ "message": "Opozorilo"
+ },
+ "welcomeBeta": {
+ "message": "Dobrodošli v MetaMask Beta"
+ },
+ "whatsThis": {
+ "message": "Kaj je to?"
+ },
+ "yourSigRequested": {
+ "message": "Vaš podpis je bil zahtevan"
+ },
+ "youSign": {
+ "message": "Podpisani ste"
+ }
+}
diff --git a/app/_locales/th/messages.json b/app/_locales/th/messages.json
new file mode 100644
index 000000000..887714f3f
--- /dev/null
+++ b/app/_locales/th/messages.json
@@ -0,0 +1,819 @@
+{
+ "accept": {
+ "message": "ยอมรับ"
+ },
+ "account": {
+ "message": "บัญชี"
+ },
+ "accountDetails": {
+ "message": "รายละเอียดบัญชี"
+ },
+ "accountName": {
+ "message": "ชื่อบัญชี"
+ },
+ "address": {
+ "message": "แอดเดรส"
+ },
+ "addCustomToken": {
+ "message": "เพิ่มโทเค็นด้วยตัวเอง"
+ },
+ "addToken": {
+ "message": "เพิ่มโทเค็น"
+ },
+ "addTokens": {
+ "message": "เพิ่มหลายโทเค็น"
+ },
+ "amount": {
+ "message": "จำนวน"
+ },
+ "amountPlusGas": {
+ "message": "จำนวน + แก๊ส"
+ },
+ "appDescription": {
+ "message": "ส่วนขยายเบราว์เซอร์สำหรับอีเธอเรียม",
+ "description": "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 เป็นแหล่งซื้อขายบิตคอยน์ไลท์คอยน์และอีเธอเรียมที่ได้รับความนิยมสูงสุดในโลก"
+ },
+ "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": "ค่าเริ่มต้นของเครือข่ายสำหรับทำรายการธุรกรรมอีเธอร์คือ Main Net"
+ },
+ "denExplainer": {
+ "message": "DEN ของคุณคือตัวเก็บข้อมูลที่เข้ารหัสไว้ด้วยรหัสผ่านของคุณภายใน MetaMask "
+ },
+ "deposit": {
+ "message": "ฝาก"
+ },
+ "depositBTC": {
+ "message": "ฝากบิตคอยน์ของคุณไปที่แอดเดรสด้านล่างนี้:"
+ },
+ "depositCoin": {
+ "message": "ฝาก $1 ของคุณไปที่แอดเดรสด้านล่างนี้:",
+ "description": "Tells the user what coin they have selected to deposit with shapeshift"
+ },
+ "depositEth": {
+ "message": "การฝากอีเธอร์"
+ },
+ "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": "ติดตามเราบนทวิตเตอร์"
+ },
+ "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":"บัญชีที่นำเข้าจะไม่ถูกรวมกับบัญชีที่สร้างด้วยคำเเริ่มต้นบนเมต้ามาร์สในตอนแรก เรียนรู้เพิ่มเติมเกี่ยวกับบัญชีที่นำเข้า"
+ },
+ "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": "RPC URI ไม่ถูกต้อง"
+ },
+ "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": "Localhost 8545"
+ },
+ "login": {
+ "message": "เข้าสู่ระบบ"
+ },
+ "logout": {
+ "message": "ออกจากระบบ"
+ },
+ "loose": {
+ "message": "อิสระ"
+ },
+ "loweCaseWords": {
+ "message": "กลุ่มคำชีดมีเพียงตัวพิมพ์เล็กเท่านั้น"
+ },
+ "mainnet": {
+ "message": "เครือข่าย Main Net"
+ },
+ "message": {
+ "message": "ข้อความ"
+ },
+ "metamaskDescription": {
+ "message": "MetaMask คือที่เก็บตัวตนนิรภัยสำหรับอีเธอเรียม"
+ },
+ "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": "ไม่สามารถส่งอีเธอร์เป็นจำนวนติดลบได้"
+ },
+ "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": "RPC URL ใหม่"
+ },
+ "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 Code"
+ },
+ "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": "ส่งอีเธอร์"
+ },
+ "sendTokens": {
+ "message": "ส่งโทเค็น"
+ },
+ "sendTokensAnywhere": {
+ "message": "ส่งโทเค็นไปให้ทุกคนที่มีบัญชีอีเธอเรียม"
+ },
+ "settings": {
+ "message": "การตั้งค่า"
+ },
+ "shapeshiftBuy": {
+ "message": "ซื้อด้วย Shapeshift"
+ },
+ "showPrivateKeys": {
+ "message": "แสดงคีย์ส่วนตัว"
+ },
+ "showQRCode": {
+ "message": "แสดง QR Code"
+ },
+ "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 เป็นอีเธอร์โดย ShapeShift",
+ "description": "system will fill in deposit type in start of message"
+ },
+ "tokenAddress": {
+ "message": "แอดแดรสโทเค็น"
+ },
+ "tokenAlreadyAdded": {
+ "message": "โทเคนได้ถูกเพิ่มไปแล้ว"
+ },
+ "tokenBalance": {
+ "message": "ยอดโทเค็นคงเหลือของคุณคือ:"
+ },
+ "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 เบต้า"
+ },
+ "whatsThis": {
+ "message": "นี่คืออะไร?"
+ },
+ "yourSigRequested": {
+ "message": "ลายเซ็นของคุณกำลังได้รับการร้องขอ"
+ },
+ "youSign": {
+ "message": "คุณกำลังเซ็นชื่อ"
+ }
+}
diff --git a/app/_locales/zh_TW/messages.json b/app/_locales/zh_TW/messages.json
new file mode 100644
index 000000000..90f63c6a6
--- /dev/null
+++ b/app/_locales/zh_TW/messages.json
@@ -0,0 +1,864 @@
+{
+ "accept": {
+ "message": "接受"
+ },
+ "account": {
+ "message": "帳戶"
+ },
+ "accountDetails": {
+ "message": "帳戶詳情"
+ },
+ "accountName": {
+ "message": "帳戶名稱"
+ },
+ "address": {
+ "message": "帳戶地址"
+ },
+ "addCustomToken": {
+ "message": "加入自訂代幣"
+ },
+ "addToken": {
+ "message": "加入代幣"
+ },
+ "addTokens": {
+ "message": "加入多筆代幣"
+ },
+ "amount": {
+ "message": "數額"
+ },
+ "amountPlusGas": {
+ "message": "數額 + Gas"
+ },
+ "appDescription": {
+ "message": "乙太坊瀏覽器擴充插件",
+ "description": "The description of the application"
+ },
+ "appName": {
+ "message": "MetaMask",
+ "description": "The name of the application"
+ },
+ "approved": {
+ "message": "已同意"
+ },
+ "attemptingConnect": {
+ "message": "正在嘗試連接區塊鏈。"
+ },
+ "attributions": {
+ "message": "來源"
+ },
+ "available": {
+ "message": "可使用"
+ },
+ "back": {
+ "message": "上一頁"
+ },
+ "balance": {
+ "message": "餘額:"
+ },
+ "balances": {
+ "message": "你的餘額:"
+ },
+ "balanceIsInsufficientGas": {
+ "message": "當前餘額不足以支付 Gas"
+ },
+ "beta": {
+ "message": "BETA"
+ },
+ "betweenMinAndMax": {
+ "message": "必須大於等於 $1 並且小於等於 $2 。",
+ "description": "helper for inputting hex as decimal input"
+ },
+ "blockiesIdenticon": {
+ "message": "使用 Blockies Identicon"
+ },
+ "borrowDharma": {
+ "message": "透過 Dharma (Beta) 借用"
+ },
+ "builtInCalifornia": {
+ "message": "MetaMask 是在加州設計製造."
+ },
+ "buy": {
+ "message": "購買"
+ },
+ "buyCoinbase": {
+ "message": "在 Coinbase 上購買"
+ },
+ "buyCoinbaseExplainer": {
+ "message": "Coinbase 是世界上最流行的買賣比特幣,以太幣和萊特幣的交易所。"
+ },
+ "ok": {
+ "message": "Ok"
+ },
+ "cancel": {
+ "message": "取消"
+ },
+ "classicInterface": {
+ "message": "使用舊版界面"
+ },
+ "clickCopy": {
+ "message": "點擊複製"
+ },
+ "confirm": {
+ "message": "確認"
+ },
+ "confirmed": {
+ "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": "自訂 Gas"
+ },
+ "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": "存入 Ether"
+ },
+ "depositFiat": {
+ "message": "從法定貨幣存入"
+ },
+ "depositFromAccount": {
+ "message": "從其他帳戶存入"
+ },
+ "depositShapeShift": {
+ "message": "從 ShapeShift 存入"
+ },
+ "depositShapeShiftExplainer": {
+ "message": "如果你擁有其他加密貨幣,你可以直接交易並存入 Ether 到你的MetaMask錢包。不需要開帳戶。"
+ },
+ "details": {
+ "message": "詳情"
+ },
+ "directDeposit": {
+ "message": "直接存入"
+ },
+ "directDepositEther": {
+ "message": "直接存入 Ether"
+ },
+ "directDepositEtherExplainer": {
+ "message": "如果你已經擁有了一些Ether,使用直接存入功能是讓你的新錢包最快取得Ether的方式。"
+ },
+ "done": {
+ "message": "完成"
+ },
+ "downloadStatelogs": {
+ "message": "下載狀態紀錄"
+ },
+ "dropped": {
+ "message": "丟棄"
+ },
+ "edit": {
+ "message": "編輯"
+ },
+ "editAccountName": {
+ "message": "編輯帳戶名稱"
+ },
+ "emailUs": {
+ "message": "寄 Email 給我們!"
+ },
+ "encryptNewDen": {
+ "message": "加密你的新 DEN"
+ },
+ "enterPassword": {
+ "message": "請輸入密碼"
+ },
+ "enterPasswordConfirm": {
+ "message": "請再次輸入密碼確認"
+ },
+ "passwordNotLongEnough": {
+ "message": "您所輸入的密碼長度不足"
+ },
+ "passwordsDontMatch": {
+ "message": "您所輸入的密碼不一致"
+ },
+ "etherscanView": {
+ "message": "在 Etherscan 上查看帳戶"
+ },
+ "exchangeRate": {
+ "message": "匯率"
+ },
+ "exportPrivateKey": {
+ "message": "導出私鑰"
+ },
+ "exportPrivateKeyWarning": {
+ "message": "您需要自行負擔導出私鑰產生的風險"
+ },
+ "failed": {
+ "message": "失败"
+ },
+ "fiat": {
+ "message": "FIAT",
+ "description": "Exchange type"
+ },
+ "fileImportFail": {
+ "message": "檔案導入失敗?點擊這裡!",
+ "description": "Helps user import their account from a JSON file"
+ },
+ "from": {
+ "message": "來源地址"
+ },
+ "fromToSame": {
+ "message": "來源和目的地址不能一樣"
+ },
+ "fromShapeShift": {
+ "message": "來自 ShapeShift"
+ },
+ "gas": {
+ "message": "Gas",
+ "description": "Short indication of gas cost"
+ },
+ "gasFee": {
+ "message": "Gas 費用"
+ },
+ "gasLimit": {
+ "message": "Gas 上限"
+ },
+ "gasLimitCalculation": {
+ "message": "我們根據網路成功率算出建議的 Gas 上限。"
+ },
+ "gasLimitRequired": {
+ "message": "必需填寫 Gas 上限"
+ },
+ "gasLimitTooLow": {
+ "message": "Gas 上限至少為 21000"
+ },
+ "gasPrice": {
+ "message": "Gas 價格 (GWEI)"
+ },
+ "gasPriceCalculation": {
+ "message": "我們根據網路成功率算出建議的 Gas 價格"
+ },
+ "gasPriceRequired": {
+ "message": "必需填寫 Gas 價格"
+ },
+ "getEther": {
+ "message": "取得 Ether"
+ },
+ "getEtherFromFaucet": {
+ "message": "從水管取得$1 Ether",
+ "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": "Here's a list!!!!"
+ },
+ "hide": {
+ "message": "隱藏"
+ },
+ "hideToken": {
+ "message": "隱藏代幣"
+ },
+ "hideTokenPrompt": {
+ "message": "隱藏代幣?"
+ },
+ "howToDeposit": {
+ "message": "你想怎麼存入 Ether?"
+ },
+ "holdEther": {
+ "message": "Metamask 讓您能保存 ether 和代幣, 並成為您接觸分散式應用程式的途徑."
+ },
+ "import": {
+ "message": "導入",
+ "description": "Button to import an account from a selected file"
+ },
+ "importAccount": {
+ "message": "導入帳戶"
+ },
+ "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": "Gas 參數錯誤"
+ },
+ "invalidInput": {
+ "message": "輸入錯誤。"
+ },
+ "invalidRequest": {
+ "message": "無效的請求"
+ },
+ "invalidRPC": {
+ "message": "無效的 RPC URI"
+ },
+ "jsonFail": {
+ "message": "有東西出錯了. 請確認你的 JSON 檔案格式正確."
+ },
+ "jsonFile": {
+ "message": "JSON 檔案",
+ "description": "format for importing an account"
+ },
+ "kovan": {
+ "message": "Kovan 測試網路"
+ },
+ "knowledgeDataBase": {
+ "message": "查看我們的知識庫"
+ },
+ "max": {
+ "message": "最大值"
+ },
+ "lessThanMax": {
+ "message": "必須小於等於 $1.",
+ "description": "helper for inputting hex as decimal input"
+ },
+ "likeToAddTokens": {
+ "message": "您確定要加入這些代幣嗎?"
+ },
+ "links": {
+ "message": "連結"
+ },
+ "limit": {
+ "message": "上限"
+ },
+ "loading": {
+ "message": "載入..."
+ },
+ "loadingTokens": {
+ "message": "載入代幣..."
+ },
+ "localhost": {
+ "message": "Localhost 8545"
+ },
+ "logout": {
+ "message": "登出"
+ },
+ "loose": {
+ "message": "非Metamask帳號"
+ },
+ "loweCaseWords": {
+ "message": "助憶詞僅包含小寫字元"
+ },
+ "mainnet": {
+ "message": "主乙太坊網路"
+ },
+ "message": {
+ "message": "訊息"
+ },
+ "metamaskDescription": {
+ "message": "MetaMask 是Ethereum的安全身份識別金庫."
+ },
+ "min": {
+ "message": "最小"
+ },
+ "myAccounts": {
+ "message": "我的帳戶"
+ },
+ "mustSelectOne": {
+ "message": "必須選擇至少 1 代幣."
+ },
+ "needEtherInWallet": {
+ "message": "要使用 MetaMask 存取 DAPP時,您的錢包中需要有 Ether。"
+ },
+ "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"
+ },
+ "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": "New RPC URL"
+ },
+ "next": {
+ "message": "下一頁"
+ },
+ "noAddressForName": {
+ "message": "此 ENS 尚未指定地址。"
+ },
+ "noDeposits": {
+ "message": "尚未有存款"
+ },
+ "noTransactionHistory": {
+ "message": "尚未有交易紀錄。"
+ },
+ "noTransactions": {
+ "message": "尚未有交易"
+ },
+ "notStarted": {
+ "message": "尚未開始"
+ },
+ "oldUI": {
+ "message": "舊版界面"
+ },
+ "oldUIMessage": {
+ "message": "你已經切換到舊版界面。可以通過右上方下拉選單中的選項切換回新的使用者界面。"
+ },
+ "or": {
+ "message": "或",
+ "description": "choice between creating or importing a new account"
+ },
+ "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": "請檢查你的交易。"
+ },
+ "privateKey": {
+ "message": "私鑰",
+ "description": "select this type of file to use to import an account"
+ },
+ "privateKeyWarning": {
+ "message": "注意:永遠不要公開這個私鑰。任何取得這把私鑰的人都可以竊取這個帳號中的任何資產。"
+ },
+ "privateNetwork": {
+ "message": "私有網路"
+ },
+ "qrCode": {
+ "message": "顯示 QR Code"
+ },
+ "readdToken": {
+ "message": "之後還可以透過帳戶選單中的“加入代幣”來加入此代幣。"
+ },
+ "readMore": {
+ "message": "了解更多。"
+ },
+ "readMore2": {
+ "message": "了解更多。"
+ },
+ "receive": {
+ "message": "接收"
+ },
+ "recipientAddress": {
+ "message": "接收地址"
+ },
+ "refundAddress": {
+ "message": "你的退款地址"
+ },
+ "rejected": {
+ "message": "拒絕"
+ },
+ "resetAccount": {
+ "message": "重置帳戶"
+ },
+ "restoreFromSeed": {
+ "message": "透過助憶詞重置"
+ },
+ "restoreVault": {
+ "message": "重置金庫"
+ },
+ "required": {
+ "message": "必填"
+ },
+ "retryWithMoreGas": {
+ "message": "改用更高的 Gas 價格重試"
+ },
+ "walletSeed": {
+ "message": "錢包助憶詞"
+ },
+ "revealSeedWords": {
+ "message": "顯示助憶詞"
+ },
+ "revealSeedWordsWarning": {
+ "message": "別在公共場合回復你的助憶詞!這些詞可被用來竊取你的帳戶."
+ },
+ "revert": {
+ "message": "還原"
+ },
+ "rinkeby": {
+ "message": "Rinkeby 測試網路"
+ },
+ "ropsten": {
+ "message": "Ropsten 測試網路"
+ },
+ "currentRpc": {
+ "message": "當前的 RPC"
+ },
+ "connectingToMainnet": {
+ "message": "連線到主 Ethereum 網路"
+ },
+ "connectingToRopsten": {
+ "message": "連線到 Ropsten 測試網路"
+ },
+ "connectingToKovan": {
+ "message": "連線到 Kovan 測試網路"
+ },
+ "connectingToRinkeby": {
+ "message": "連線到 Rinkeby 測試網路"
+ },
+ "connectingToUnknown": {
+ "message": "連線到未知網路"
+ },
+ "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": "在此輸入你的12個祕密助憶詞以回復金庫."
+ },
+ "newPassword8Chars": {
+ "message": "新密碼 (至少 8 個字元)"
+ },
+ "seedPhraseReq": {
+ "message": "助憶詞為 12 個詞語"
+ },
+ "select": {
+ "message": "選擇"
+ },
+ "selectCurrency": {
+ "message": "選擇幣別"
+ },
+ "selectService": {
+ "message": "選擇服務"
+ },
+ "selectType": {
+ "message": "選擇類型"
+ },
+ "send": {
+ "message": "發送"
+ },
+ "sendETH": {
+ "message": "發送 ETH"
+ },
+ "sendTokens": {
+ "message": "發送代幣"
+ },
+ "onlySendToEtherAddress": {
+ "message": "只發送 ETH 到乙太坊地址."
+ },
+ "sendTokensAnywhere": {
+ "message": "發送代幣給擁有乙太坊帳戶的任何人"
+ },
+ "settings": {
+ "message": "設定"
+ },
+ "info": {
+ "message": "資訊"
+ },
+ "shapeshiftBuy": {
+ "message": "從 Shapeshift 購買"
+ },
+ "showPrivateKeys": {
+ "message": "顯示私鑰"
+ },
+ "showQRCode": {
+ "message": "顯示 QR Code"
+ },
+ "sign": {
+ "message": "簽名"
+ },
+ "signMessage": {
+ "message": "簽署訊息"
+ },
+ "signNotice": {
+ "message": "簽署此訊息可能會產生危險的副作用。 \n只從你完全信任的網站上簽名。這種危險的方法;將在未來的版本中被移除。"
+ },
+ "sigRequest": {
+ "message": "請求簽署"
+ },
+ "sigRequested": {
+ "message": "已請求簽署"
+ },
+ "spaceBetween": {
+ "message": "there can only be a space between words"
+ },
+ "status": {
+ "message": "狀態"
+ },
+ "stateLogs": {
+ "message": "狀態紀錄"
+ },
+ "stateLogsDescription": {
+ "message": "狀態紀錄包含你的公開帳戶地址和已傳送的交易資訊."
+ },
+ "stateLogError": {
+ "message": "在取得狀態紀錄時發生錯誤."
+ },
+ "submit": {
+ "message": "送出"
+ },
+ "submitted": {
+ "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": "代幣餘額:"
+ },
+ "tokenSelection": {
+ "message": "搜尋代幣或是從熱門代幣列表中選擇。"
+ },
+ "tokenSymbol": {
+ "message": "代幣代號"
+ },
+ "tokenWarning1": {
+ "message": "使用 MetaMask 帳戶追蹤你已購得的代幣。如果你使用不同的帳戶保存購得的代幣,那些代幣就不會出現在這裡。"
+ },
+ "total": {
+ "message": "總量"
+ },
+ "transactions": {
+ "message": "交易紀錄"
+ },
+ "transactionMemo": {
+ "message": "交易備註(選填)"
+ },
+ "transactionNumber": {
+ "message": "交易號碼"
+ },
+ "transfers": {
+ "message": "交易"
+ },
+ "troubleTokenBalances": {
+ "message": "無法取得代幣餘額。您k可以到這裡查看 ",
+ "description": "Followed by a link (here) to view token balances"
+ },
+ "twelveWords": {
+ "message": "這 12 個單詞是唯一回復你的 MetaMask 帳號的方法。\n將它們儲存到那些安全且隱密的地方吧。"
+ },
+ "typePassword": {
+ "message": "請輸入密碼"
+ },
+ "uiWelcome": {
+ "message": "歡迎使用新版界面 (Beta)"
+ },
+ "uiWelcomeMessage": {
+ "message": "你現在正在使用新的 Metamask 界面。試試諸如發送代幣等新功能,有任何問題請告知我們。"
+ },
+ "unapproved": {
+ "message": "未同意"
+ },
+ "unavailable": {
+ "message": "不可用"
+ },
+ "unknown": {
+ "message": "未知"
+ },
+ "unknownNetwork": {
+ "message": "未知私有網路"
+ },
+ "unknownNetworkId": {
+ "message": "未知網路 ID"
+ },
+ "uriErrorMsg": {
+ "message": "URIs 需要加入適當的 HTTP/HTTPS 前綴."
+ },
+ "usaOnly": {
+ "message": "僅限美國",
+ "description": "Using this exchange is limited to people inside the USA"
+ },
+ "usedByClients": {
+ "message": "可用於各種不同的客戶端"
+ },
+ "useOldUI": {
+ "message": "使用舊版界面"
+ },
+ "validFileImport": {
+ "message": "您必須選擇一個合法的檔案來導入."
+ },
+ "vaultCreated": {
+ "message": "已建立金庫"
+ },
+ "viewAccount": {
+ "message": "查看帳戶"
+ },
+ "visitWebSite": {
+ "message": "造訪我們的網站"
+ },
+ "warning": {
+ "message": "警告"
+ },
+ "welcomeBeta": {
+ "message": "歡迎到 MetaMask Beta"
+ },
+ "whatsThis": {
+ "message": "這是什麼?"
+ },
+ "yourSigRequested": {
+ "message": "正在請求你的簽署"
+ },
+ "youSign": {
+ "message": "正在簽署"
+ }
+}
diff --git a/app/scripts/lib/setupRaven.js b/app/scripts/lib/setupRaven.js
index 42e48cb90..02c01b755 100644
--- a/app/scripts/lib/setupRaven.js
+++ b/app/scripts/lib/setupRaven.js
@@ -1,4 +1,4 @@
-const Raven = require('../vendor/raven.min.js')
+const Raven = require('raven-js')
const METAMASK_DEBUG = 'GULP_METAMASK_DEBUG'
const PROD = 'https://3567c198f8a8412082d32655da2961d0@sentry.io/273505'
const DEV = 'https://f59f3dd640d2429d9d0e2445a87ea8e1@sentry.io/273496'
@@ -18,9 +18,35 @@ function setupRaven(opts) {
ravenTarget = PROD
}
- Raven.config(ravenTarget, {
+ const client = Raven.config(ravenTarget, {
release,
- }).install()
+ transport: function(opts) {
+ // modify report urls
+ const report = opts.data
+ rewriteReportUrls(report)
+ // make request normally
+ client._makeRequest(opts)
+ },
+ })
+ client.install()
return Raven
}
+
+function rewriteReportUrls(report) {
+ // update request url
+ report.request.url = toMetamaskUrl(report.request.url)
+ // update exception stack trace
+ report.exception.values.forEach(item => {
+ item.stacktrace.frames.forEach(frame => {
+ frame.filename = toMetamaskUrl(frame.filename)
+ })
+ })
+}
+
+function toMetamaskUrl(origUrl) {
+ const filePath = origUrl.split(location.origin)[1]
+ if (!filePath) return origUrl
+ const metamaskUrl = `metamask${filePath}`
+ return metamaskUrl
+}
diff --git a/app/scripts/vendor/raven.min.js b/app/scripts/vendor/raven.min.js
deleted file mode 100644
index b439aeae6..000000000
--- a/app/scripts/vendor/raven.min.js
+++ /dev/null
@@ -1,3 +0,0 @@
-/*! Raven.js 3.22.1 (7584197) | github.com/getsentry/raven-js */
-!function(a){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=a();else if("function"==typeof define&&define.amd)define([],a);else{var b;b="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,b.Raven=a()}}(function(){return function a(b,c,d){function e(g,h){if(!c[g]){if(!b[g]){var i="function"==typeof require&&require;if(!h&&i)return i(g,!0);if(f)return f(g,!0);var j=new Error("Cannot find module '"+g+"'");throw j.code="MODULE_NOT_FOUND",j}var k=c[g]={exports:{}};b[g][0].call(k.exports,function(a){var c=b[g][1][a];return e(c?c:a)},k,k.exports,a,b,c,d)}return c[g].exports}for(var f="function"==typeof require&&require,g=0;g<d.length;g++)e(d[g]);return e}({1:[function(a,b,c){function d(a){this.name="RavenConfigError",this.message=a}d.prototype=new Error,d.prototype.constructor=d,b.exports=d},{}],2:[function(a,b,c){var d=function(a,b,c){var d=a[b],e=a;if(b in a){var f="warn"===b?"warning":b;a[b]=function(){var a=[].slice.call(arguments),g=""+a.join(" "),h={level:f,logger:"console",extra:{arguments:a}};"assert"===b?a[0]===!1&&(g="Assertion failed: "+(a.slice(1).join(" ")||"console.assert"),h.extra.arguments=a.slice(1),c&&c(g,h)):c&&c(g,h),d&&Function.prototype.apply.call(d,e,a)}}};b.exports={wrapMethod:d}},{}],3:[function(a,b,c){(function(c){function d(){return+new Date}function e(a,b){return o(b)?function(c){return b(c,a)}:b}function f(){this.a=!("object"!=typeof JSON||!JSON.stringify),this.b=!n(K),this.c=!n(L),this.d=null,this.e=null,this.f=null,this.g=null,this.h=null,this.i=null,this.j={},this.k={release:J.SENTRY_RELEASE&&J.SENTRY_RELEASE.id,logger:"javascript",ignoreErrors:[],ignoreUrls:[],whitelistUrls:[],includePaths:[],headers:null,collectWindowErrors:!0,maxMessageLength:0,maxUrlLength:250,stackTraceLimit:50,autoBreadcrumbs:!0,instrument:!0,sampleRate:1},this.l={method:"POST",keepalive:!0,referrerPolicy:"origin"},this.m=0,this.n=!1,this.o=Error.stackTraceLimit,this.p=J.console||{},this.q={},this.r=[],this.s=d(),this.t=[],this.u=[],this.v=null,this.w=J.location,this.x=this.w&&this.w.href,this.y();for(var a in this.p)this.q[a]=this.p[a]}var g=a(6),h=a(7),i=a(1),j=a(5),k=j.isError,l=j.isObject,m=j.isErrorEvent,n=j.isUndefined,o=j.isFunction,p=j.isString,q=j.isArray,r=j.isEmptyObject,s=j.each,t=j.objectMerge,u=j.truncate,v=j.objectFrozen,w=j.hasKey,x=j.joinRegExp,y=j.urlencode,z=j.uuid4,A=j.htmlTreeAsString,B=j.isSameException,C=j.isSameStacktrace,D=j.parseUrl,E=j.fill,F=j.supportsFetch,G=a(2).wrapMethod,H="source protocol user pass host port path".split(" "),I=/^(?:(\w+):)?\/\/(?:(\w+)(:\w+)?@)?([\w\.-]+)(?::(\d+))?(\/.*)/,J="undefined"!=typeof window?window:"undefined"!=typeof c?c:"undefined"!=typeof self?self:{},K=J.document,L=J.navigator;f.prototype={VERSION:"3.22.1",debug:!1,TraceKit:g,config:function(a,b){var c=this;if(c.g)return this.z("error","Error: Raven has already been configured"),c;if(!a)return c;var d=c.k;b&&s(b,function(a,b){"tags"===a||"extra"===a||"user"===a?c.j[a]=b:d[a]=b}),c.setDSN(a),d.ignoreErrors.push(/^Script error\.?$/),d.ignoreErrors.push(/^Javascript error: Script error\.? on line 0$/),d.ignoreErrors=x(d.ignoreErrors),d.ignoreUrls=!!d.ignoreUrls.length&&x(d.ignoreUrls),d.whitelistUrls=!!d.whitelistUrls.length&&x(d.whitelistUrls),d.includePaths=x(d.includePaths),d.maxBreadcrumbs=Math.max(0,Math.min(d.maxBreadcrumbs||100,100));var e={xhr:!0,console:!0,dom:!0,location:!0,sentry:!0},f=d.autoBreadcrumbs;"[object Object]"==={}.toString.call(f)?f=t(e,f):f!==!1&&(f=e),d.autoBreadcrumbs=f;var h={tryCatch:!0},i=d.instrument;return"[object Object]"==={}.toString.call(i)?i=t(h,i):i!==!1&&(i=h),d.instrument=i,g.collectWindowErrors=!!d.collectWindowErrors,c},install:function(){var a=this;return a.isSetup()&&!a.n&&(g.report.subscribe(function(){a.A.apply(a,arguments)}),a.B(),a.k.instrument&&a.k.instrument.tryCatch&&a.C(),a.k.autoBreadcrumbs&&a.D(),a.E(),a.n=!0),Error.stackTraceLimit=a.k.stackTraceLimit,this},setDSN:function(a){var b=this,c=b.F(a),d=c.path.lastIndexOf("/"),e=c.path.substr(1,d);b.G=a,b.h=c.user,b.H=c.pass&&c.pass.substr(1),b.i=c.path.substr(d+1),b.g=b.I(c),b.J=b.g+"/"+e+"api/"+b.i+"/store/",this.y()},context:function(a,b,c){return o(a)&&(c=b||[],b=a,a=void 0),this.wrap(a,b).apply(this,c)},wrap:function(a,b,c){function d(){var d=[],f=arguments.length,g=!a||a&&a.deep!==!1;for(c&&o(c)&&c.apply(this,arguments);f--;)d[f]=g?e.wrap(a,arguments[f]):arguments[f];try{return b.apply(this,d)}catch(h){throw e.K(),e.captureException(h,a),h}}var e=this;if(n(b)&&!o(a))return a;if(o(a)&&(b=a,a=void 0),!o(b))return b;try{if(b.L)return b;if(b.M)return b.M}catch(f){return b}for(var g in b)w(b,g)&&(d[g]=b[g]);return d.prototype=b.prototype,b.M=d,d.L=!0,d.N=b,d},uninstall:function(){return g.report.uninstall(),this.O(),this.P(),Error.stackTraceLimit=this.o,this.n=!1,this},captureException:function(a,b){var c=!k(a),d=!m(a),e=m(a)&&!a.error;if(c&&d||e)return this.captureMessage(a,t({trimHeadFrames:1,stacktrace:!0},b));m(a)&&(a=a.error),this.d=a;try{var f=g.computeStackTrace(a);this.Q(f,b)}catch(h){if(a!==h)throw h}return this},captureMessage:function(a,b){if(!this.k.ignoreErrors.test||!this.k.ignoreErrors.test(a)){b=b||{};var c,d=t({message:a+""},b);try{throw new Error(a)}catch(e){c=e}c.name=null;var f=g.computeStackTrace(c),h=q(f.stack)&&f.stack[1],i=h&&h.url||"";if((!this.k.ignoreUrls.test||!this.k.ignoreUrls.test(i))&&(!this.k.whitelistUrls.test||this.k.whitelistUrls.test(i))){if(this.k.stacktrace||b&&b.stacktrace){b=t({fingerprint:a,trimHeadFrames:(b.trimHeadFrames||0)+1},b);var j=this.R(f,b);d.stacktrace={frames:j.reverse()}}return this.S(d),this}}},captureBreadcrumb:function(a){var b=t({timestamp:d()/1e3},a);if(o(this.k.breadcrumbCallback)){var c=this.k.breadcrumbCallback(b);if(l(c)&&!r(c))b=c;else if(c===!1)return this}return this.u.push(b),this.u.length>this.k.maxBreadcrumbs&&this.u.shift(),this},addPlugin:function(a){var b=[].slice.call(arguments,1);return this.r.push([a,b]),this.n&&this.E(),this},setUserContext:function(a){return this.j.user=a,this},setExtraContext:function(a){return this.T("extra",a),this},setTagsContext:function(a){return this.T("tags",a),this},clearContext:function(){return this.j={},this},getContext:function(){return JSON.parse(h(this.j))},setEnvironment:function(a){return this.k.environment=a,this},setRelease:function(a){return this.k.release=a,this},setDataCallback:function(a){var b=this.k.dataCallback;return this.k.dataCallback=e(b,a),this},setBreadcrumbCallback:function(a){var b=this.k.breadcrumbCallback;return this.k.breadcrumbCallback=e(b,a),this},setShouldSendCallback:function(a){var b=this.k.shouldSendCallback;return this.k.shouldSendCallback=e(b,a),this},setTransport:function(a){return this.k.transport=a,this},lastException:function(){return this.d},lastEventId:function(){return this.f},isSetup:function(){return!!this.a&&(!!this.g||(this.ravenNotConfiguredError||(this.ravenNotConfiguredError=!0,this.z("error","Error: Raven has not been configured.")),!1))},afterLoad:function(){var a=J.RavenConfig;a&&this.config(a.dsn,a.config).install()},showReportDialog:function(a){if(K){a=a||{};var b=a.eventId||this.lastEventId();if(!b)throw new i("Missing eventId");var c=a.dsn||this.G;if(!c)throw new i("Missing DSN");var d=encodeURIComponent,e="";e+="?eventId="+d(b),e+="&dsn="+d(c);var f=a.user||this.j.user;f&&(f.name&&(e+="&name="+d(f.name)),f.email&&(e+="&email="+d(f.email)));var g=this.I(this.F(c)),h=K.createElement("script");h.async=!0,h.src=g+"/api/embed/error-page/"+e,(K.head||K.body).appendChild(h)}},K:function(){var a=this;this.m+=1,setTimeout(function(){a.m-=1})},U:function(a,b){var c,d;if(this.b){b=b||{},a="raven"+a.substr(0,1).toUpperCase()+a.substr(1),K.createEvent?(c=K.createEvent("HTMLEvents"),c.initEvent(a,!0,!0)):(c=K.createEventObject(),c.eventType=a);for(d in b)w(b,d)&&(c[d]=b[d]);if(K.createEvent)K.dispatchEvent(c);else try{K.fireEvent("on"+c.eventType.toLowerCase(),c)}catch(e){}}},V:function(a){var b=this;return function(c){if(b.W=null,b.v!==c){b.v=c;var d;try{d=A(c.target)}catch(e){d="<unknown>"}b.captureBreadcrumb({category:"ui."+a,message:d})}}},X:function(){var a=this,b=1e3;return function(c){var d;try{d=c.target}catch(e){return}var f=d&&d.tagName;if(f&&("INPUT"===f||"TEXTAREA"===f||d.isContentEditable)){var g=a.W;g||a.V("input")(c),clearTimeout(g),a.W=setTimeout(function(){a.W=null},b)}}},Y:function(a,b){var c=D(this.w.href),d=D(b),e=D(a);this.x=b,c.protocol===d.protocol&&c.host===d.host&&(b=d.relative),c.protocol===e.protocol&&c.host===e.host&&(a=e.relative),this.captureBreadcrumb({category:"navigation",data:{to:b,from:a}})},B:function(){var a=this;a.Z=Function.prototype.toString,Function.prototype.toString=function(){return"function"==typeof this&&this.L?a.Z.apply(this.N,arguments):a.Z.apply(this,arguments)}},O:function(){this.Z&&(Function.prototype.toString=this.Z)},C:function(){function a(a){return function(b,d){for(var e=new Array(arguments.length),f=0;f<e.length;++f)e[f]=arguments[f];var g=e[0];return o(g)&&(e[0]=c.wrap(g)),a.apply?a.apply(this,e):a(e[0],e[1])}}function b(a){var b=J[a]&&J[a].prototype;b&&b.hasOwnProperty&&b.hasOwnProperty("addEventListener")&&(E(b,"addEventListener",function(b){return function(d,f,g,h){try{f&&f.handleEvent&&(f.handleEvent=c.wrap(f.handleEvent))}catch(i){}var j,k,l;return e&&e.dom&&("EventTarget"===a||"Node"===a)&&(k=c.V("click"),l=c.X(),j=function(a){if(a){var b;try{b=a.type}catch(c){return}return"click"===b?k(a):"keypress"===b?l(a):void 0}}),b.call(this,d,c.wrap(f,void 0,j),g,h)}},d),E(b,"removeEventListener",function(a){return function(b,c,d,e){try{c=c&&(c.M?c.M:c)}catch(f){}return a.call(this,b,c,d,e)}},d))}var c=this,d=c.t,e=this.k.autoBreadcrumbs;E(J,"setTimeout",a,d),E(J,"setInterval",a,d),J.requestAnimationFrame&&E(J,"requestAnimationFrame",function(a){return function(b){return a(c.wrap(b))}},d);for(var f=["EventTarget","Window","Node","ApplicationCache","AudioTrackList","ChannelMergerNode","CryptoOperation","EventSource","FileReader","HTMLUnknownElement","IDBDatabase","IDBRequest","IDBTransaction","KeyOperation","MediaController","MessagePort","ModalWindow","Notification","SVGElementInstance","Screen","TextTrack","TextTrackCue","TextTrackList","WebSocket","WebSocketWorker","Worker","XMLHttpRequest","XMLHttpRequestEventTarget","XMLHttpRequestUpload"],g=0;g<f.length;g++)b(f[g])},D:function(){function a(a,c){a in c&&o(c[a])&&E(c,a,function(a){return b.wrap(a)})}var b=this,c=this.k.autoBreadcrumbs,d=b.t;if(c.xhr&&"XMLHttpRequest"in J){var e=XMLHttpRequest.prototype;E(e,"open",function(a){return function(c,d){return p(d)&&d.indexOf(b.h)===-1&&(this.$={method:c,url:d,status_code:null}),a.apply(this,arguments)}},d),E(e,"send",function(c){return function(){function d(){if(e.$&&4===e.readyState){try{e.$.status_code=e.status}catch(a){}b.captureBreadcrumb({type:"http",category:"xhr",data:e.$})}}for(var e=this,f=["onload","onerror","onprogress"],g=0;g<f.length;g++)a(f[g],e);return"onreadystatechange"in e&&o(e.onreadystatechange)?E(e,"onreadystatechange",function(a){return b.wrap(a,void 0,d)}):e.onreadystatechange=d,c.apply(this,arguments)}},d)}c.xhr&&F()&&E(J,"fetch",function(a){return function(){for(var c=new Array(arguments.length),d=0;d<c.length;++d)c[d]=arguments[d];var e,f=c[0],g="GET";if("string"==typeof f?e=f:"Request"in J&&f instanceof J.Request?(e=f.url,f.method&&(g=f.method)):e=""+f,e.indexOf(b.h)!==-1)return a.apply(this,c);c[1]&&c[1].method&&(g=c[1].method);var h={method:g,url:e,status_code:null};return a.apply(this,c).then(function(a){return h.status_code=a.status,b.captureBreadcrumb({type:"http",category:"fetch",data:h}),a})}},d),c.dom&&this.b&&(K.addEventListener?(K.addEventListener("click",b.V("click"),!1),K.addEventListener("keypress",b.X(),!1)):(K.attachEvent("onclick",b.V("click")),K.attachEvent("onkeypress",b.X())));var f=J.chrome,g=f&&f.app&&f.app.runtime,h=!g&&J.history&&history.pushState&&history.replaceState;if(c.location&&h){var i=J.onpopstate;J.onpopstate=function(){var a=b.w.href;if(b.Y(b.x,a),i)return i.apply(this,arguments)};var j=function(a){return function(){var c=arguments.length>2?arguments[2]:void 0;return c&&b.Y(b.x,c+""),a.apply(this,arguments)}};E(history,"pushState",j,d),E(history,"replaceState",j,d)}if(c.console&&"console"in J&&console.log){var k=function(a,c){b.captureBreadcrumb({message:a,level:c.level,category:"console"})};s(["debug","info","warn","error","log"],function(a,b){G(console,b,k)})}},P:function(){for(var a;this.t.length;){a=this.t.shift();var b=a[0],c=a[1],d=a[2];b[c]=d}},E:function(){var a=this;s(this.r,function(b,c){var d=c[0],e=c[1];d.apply(a,[a].concat(e))})},F:function(a){var b=I.exec(a),c={},d=7;try{for(;d--;)c[H[d]]=b[d]||""}catch(e){throw new i("Invalid DSN: "+a)}if(c.pass&&!this.k.allowSecretKey)throw new i("Do not specify your secret key in the DSN. See: http://bit.ly/raven-secret-key");return c},I:function(a){var b="//"+a.host+(a.port?":"+a.port:"");return a.protocol&&(b=a.protocol+":"+b),b},A:function(){this.m||this.Q.apply(this,arguments)},Q:function(a,b){var c=this.R(a,b);this.U("handle",{stackInfo:a,options:b}),this._(a.name,a.message,a.url,a.lineno,c,b)},R:function(a,b){var c=this,d=[];if(a.stack&&a.stack.length&&(s(a.stack,function(b,e){var f=c.aa(e,a.url);f&&d.push(f)}),b&&b.trimHeadFrames))for(var e=0;e<b.trimHeadFrames&&e<d.length;e++)d[e].in_app=!1;return d=d.slice(0,this.k.stackTraceLimit)},aa:function(a,b){var c={filename:a.url,lineno:a.line,colno:a.column,"function":a.func||"?"};return a.url||(c.filename=b),c.in_app=!(this.k.includePaths.test&&!this.k.includePaths.test(c.filename)||/(Raven|TraceKit)\./.test(c["function"])||/raven\.(min\.)?js$/.test(c.filename)),c},_:function(a,b,c,d,e,f){var g=(a?a+": ":"")+(b||"");if(!this.k.ignoreErrors.test||!this.k.ignoreErrors.test(b)&&!this.k.ignoreErrors.test(g)){var h;if(e&&e.length?(c=e[0].filename||c,e.reverse(),h={frames:e}):c&&(h={frames:[{filename:c,lineno:d,in_app:!0}]}),(!this.k.ignoreUrls.test||!this.k.ignoreUrls.test(c))&&(!this.k.whitelistUrls.test||this.k.whitelistUrls.test(c))){var i=t({exception:{values:[{type:a,value:b,stacktrace:h}]},culprit:c},f);this.S(i)}}},ba:function(a){var b=this.k.maxMessageLength;if(a.message&&(a.message=u(a.message,b)),a.exception){var c=a.exception.values[0];c.value=u(c.value,b)}var d=a.request;return d&&(d.url&&(d.url=u(d.url,this.k.maxUrlLength)),d.Referer&&(d.Referer=u(d.Referer,this.k.maxUrlLength))),a.breadcrumbs&&a.breadcrumbs.values&&this.ca(a.breadcrumbs),a},ca:function(a){for(var b,c,d,e=["to","from","url"],f=0;f<a.values.length;++f)if(c=a.values[f],c.hasOwnProperty("data")&&l(c.data)&&!v(c.data)){d=t({},c.data);for(var g=0;g<e.length;++g)b=e[g],d.hasOwnProperty(b)&&d[b]&&(d[b]=u(d[b],this.k.maxUrlLength));a.values[f].data=d}},da:function(){if(this.c||this.b){var a={};return this.c&&L.userAgent&&(a.headers={"User-Agent":navigator.userAgent}),J.location&&J.location.href&&(a.url=J.location.href),this.b&&K.referrer&&(a.headers||(a.headers={}),a.headers.Referer=K.referrer),a}},y:function(){this.ea=0,this.fa=null},ga:function(){return this.ea&&d()-this.fa<this.ea},ha:function(a){var b=this.e;return!(!b||a.message!==b.message||a.culprit!==b.culprit)&&(a.stacktrace||b.stacktrace?C(a.stacktrace,b.stacktrace):!a.exception&&!b.exception||B(a.exception,b.exception))},ia:function(a){if(!this.ga()){var b=a.status;if(400===b||401===b||429===b){var c;try{c=F()?a.headers.get("Retry-After"):a.getResponseHeader("Retry-After"),c=1e3*parseInt(c,10)}catch(e){}this.ea=c?c:2*this.ea||1e3,this.fa=d()}}},S:function(a){var b=this.k,c={project:this.i,logger:b.logger,platform:"javascript"},e=this.da();if(e&&(c.request=e),a.trimHeadFrames&&delete a.trimHeadFrames,a=t(c,a),a.tags=t(t({},this.j.tags),a.tags),a.extra=t(t({},this.j.extra),a.extra),a.extra["session:duration"]=d()-this.s,this.u&&this.u.length>0&&(a.breadcrumbs={values:[].slice.call(this.u,0)}),this.j.user&&(a.user=this.j.user),b.environment&&(a.environment=b.environment),b.release&&(a.release=b.release),b.serverName&&(a.server_name=b.serverName),Object.keys(a).forEach(function(b){(null==a[b]||""===a[b]||r(a[b]))&&delete a[b]}),o(b.dataCallback)&&(a=b.dataCallback(a)||a),a&&!r(a)&&(!o(b.shouldSendCallback)||b.shouldSendCallback(a)))return this.ga()?void this.z("warn","Raven dropped error due to backoff: ",a):void("number"==typeof b.sampleRate?Math.random()<b.sampleRate&&this.ja(a):this.ja(a))},ka:function(){return z()},ja:function(a,b){var c=this,d=this.k;if(this.isSetup()){if(a=this.ba(a),!this.k.allowDuplicates&&this.ha(a))return void this.z("warn","Raven dropped repeat event: ",a);this.f=a.event_id||(a.event_id=this.ka()),this.e=a,this.z("debug","Raven about to send:",a);var e={sentry_version:"7",sentry_client:"raven-js/"+this.VERSION,sentry_key:this.h};this.H&&(e.sentry_secret=this.H);var f=a.exception&&a.exception.values[0];this.k.autoBreadcrumbs&&this.k.autoBreadcrumbs.sentry&&this.captureBreadcrumb({category:"sentry",message:f?(f.type?f.type+": ":"")+f.value:a.message,event_id:a.event_id,level:a.level||"error"});var g=this.J;(d.transport||this.la).call(this,{url:g,auth:e,data:a,options:d,onSuccess:function(){c.y(),c.U("success",{data:a,src:g}),b&&b()},onError:function(d){c.z("error","Raven transport failed to send: ",d),d.request&&c.ia(d.request),c.U("failure",{data:a,src:g}),d=d||new Error("Raven send failed (no additional details provided)"),b&&b(d)}})}},la:function(a){var b=a.url+"?"+y(a.auth),c=null,d={};if(a.options.headers&&(c=this.ma(a.options.headers)),a.options.fetchParameters&&(d=this.ma(a.options.fetchParameters)),F()){d.body=h(a.data);var e=t({},this.l),f=t(e,d);return c&&(f.headers=c),J.fetch(b,f).then(function(b){if(b.ok)a.onSuccess&&a.onSuccess();else{var c=new Error("Sentry error code: "+b.status);c.request=b,a.onError&&a.onError(c)}})["catch"](function(){a.onError&&a.onError(new Error("Sentry error code: network unavailable"))})}var g=J.XMLHttpRequest&&new J.XMLHttpRequest;if(g){var i="withCredentials"in g||"undefined"!=typeof XDomainRequest;i&&("withCredentials"in g?g.onreadystatechange=function(){if(4===g.readyState)if(200===g.status)a.onSuccess&&a.onSuccess();else if(a.onError){var b=new Error("Sentry error code: "+g.status);b.request=g,a.onError(b)}}:(g=new XDomainRequest,b=b.replace(/^https?:/,""),a.onSuccess&&(g.onload=a.onSuccess),a.onError&&(g.onerror=function(){var b=new Error("Sentry error code: XDomainRequest");b.request=g,a.onError(b)})),g.open("POST",b),c&&s(c,function(a,b){g.setRequestHeader(a,b)}),g.send(h(a.data)))}},ma:function(a){var b={};for(var c in a)if(a.hasOwnProperty(c)){var d=a[c];b[c]="function"==typeof d?d():d}return b},z:function(a){this.q[a]&&this.debug&&Function.prototype.apply.call(this.q[a],this.p,[].slice.call(arguments,1))},T:function(a,b){n(b)?delete this.j[a]:this.j[a]=t(this.j[a]||{},b)}},f.prototype.setUser=f.prototype.setUserContext,f.prototype.setReleaseContext=f.prototype.setRelease,b.exports=f}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{1:1,2:2,5:5,6:6,7:7}],4:[function(a,b,c){(function(c){var d=a(3),e="undefined"!=typeof window?window:"undefined"!=typeof c?c:"undefined"!=typeof self?self:{},f=e.Raven,g=new d;g.noConflict=function(){return e.Raven=f,g},g.afterLoad(),b.exports=g}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{3:3}],5:[function(a,b,c){(function(a){function c(a){return"object"==typeof a&&null!==a}function d(a){switch({}.toString.call(a)){case"[object Error]":return!0;case"[object Exception]":return!0;case"[object DOMException]":return!0;default:return a instanceof Error}}function e(a){return l()&&"[object ErrorEvent]"==={}.toString.call(a)}function f(a){return void 0===a}function g(a){return"function"==typeof a}function h(a){return"[object Object]"===Object.prototype.toString.call(a)}function i(a){return"[object String]"===Object.prototype.toString.call(a)}function j(a){return"[object Array]"===Object.prototype.toString.call(a)}function k(a){if(!h(a))return!1;for(var b in a)if(a.hasOwnProperty(b))return!1;return!0}function l(){try{return new ErrorEvent(""),!0}catch(a){return!1}}function m(){if(!("fetch"in E))return!1;try{return new Headers,new Request(""),new Response,!0}catch(a){return!1}}function n(a){function b(b,c){var d=a(b)||b;return c?c(d)||d:d}return b}function o(a,b){var c,d;if(f(a.length))for(c in a)s(a,c)&&b.call(null,c,a[c]);else if(d=a.length)for(c=0;c<d;c++)b.call(null,c,a[c])}function p(a,b){return b?(o(b,function(b,c){a[b]=c}),a):a}function q(a){return!!Object.isFrozen&&Object.isFrozen(a)}function r(a,b){return!b||a.length<=b?a:a.substr(0,b)+"…"}function s(a,b){return Object.prototype.hasOwnProperty.call(a,b)}function t(a){for(var b,c=[],d=0,e=a.length;d<e;d++)b=a[d],i(b)?c.push(b.replace(/([.*+?^=!:${}()|\[\]\/\\])/g,"\\$1")):b&&b.source&&c.push(b.source);return new RegExp(c.join("|"),"i")}function u(a){var b=[];return o(a,function(a,c){b.push(encodeURIComponent(a)+"="+encodeURIComponent(c))}),b.join("&")}function v(a){if("string"!=typeof a)return{};var b=a.match(/^(([^:\/?#]+):)?(\/\/([^\/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?$/),c=b[6]||"",d=b[8]||"";return{protocol:b[2],host:b[4],path:b[5],relative:b[5]+c+d}}function w(){var a=E.crypto||E.msCrypto;if(!f(a)&&a.getRandomValues){var b=new Uint16Array(8);a.getRandomValues(b),b[3]=4095&b[3]|16384,b[4]=16383&b[4]|32768;var c=function(a){for(var b=a.toString(16);b.length<4;)b="0"+b;return b};return c(b[0])+c(b[1])+c(b[2])+c(b[3])+c(b[4])+c(b[5])+c(b[6])+c(b[7])}return"xxxxxxxxxxxx4xxxyxxxxxxxxxxxxxxx".replace(/[xy]/g,function(a){var b=16*Math.random()|0,c="x"===a?b:3&b|8;return c.toString(16)})}function x(a){for(var b,c=5,d=80,e=[],f=0,g=0,h=" > ",i=h.length;a&&f++<c&&(b=y(a),!("html"===b||f>1&&g+e.length*i+b.length>=d));)e.push(b),g+=b.length,a=a.parentNode;return e.reverse().join(h)}function y(a){var b,c,d,e,f,g=[];if(!a||!a.tagName)return"";if(g.push(a.tagName.toLowerCase()),a.id&&g.push("#"+a.id),b=a.className,b&&i(b))for(c=b.split(/\s+/),f=0;f<c.length;f++)g.push("."+c[f]);var h=["type","name","title","alt"];for(f=0;f<h.length;f++)d=h[f],e=a.getAttribute(d),e&&g.push("["+d+'="'+e+'"]');return g.join("")}function z(a,b){return!!(!!a^!!b)}function A(a,b){return f(a)&&f(b)}function B(a,b){return!z(a,b)&&(a=a.values[0],b=b.values[0],a.type===b.type&&a.value===b.value&&(!A(a.stacktrace,b.stacktrace)&&C(a.stacktrace,b.stacktrace)))}function C(a,b){if(z(a,b))return!1;var c=a.frames,d=b.frames;if(c.length!==d.length)return!1;for(var e,f,g=0;g<c.length;g++)if(e=c[g],f=d[g],e.filename!==f.filename||e.lineno!==f.lineno||e.colno!==f.colno||e["function"]!==f["function"])return!1;return!0}function D(a,b,c,d){var e=a[b];a[b]=c(e),a[b].L=!0,a[b].N=e,d&&d.push([a,b,e])}var E="undefined"!=typeof window?window:"undefined"!=typeof a?a:"undefined"!=typeof self?self:{};b.exports={isObject:c,isError:d,isErrorEvent:e,isUndefined:f,isFunction:g,isPlainObject:h,isString:i,isArray:j,isEmptyObject:k,supportsErrorEvent:l,supportsFetch:m,wrappedCallback:n,each:o,objectMerge:p,truncate:r,objectFrozen:q,hasKey:s,joinRegExp:t,urlencode:u,uuid4:w,htmlTreeAsString:x,htmlElementAsString:y,isSameException:B,isSameStacktrace:C,parseUrl:v,fill:D}}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{}],6:[function(a,b,c){(function(c){function d(){return"undefined"==typeof document||null==document.location?"":document.location.href}var e=a(5),f={collectWindowErrors:!0,debug:!1},g="undefined"!=typeof window?window:"undefined"!=typeof c?c:"undefined"!=typeof self?self:{},h=[].slice,i="?",j=/^(?:[Uu]ncaught (?:exception: )?)?(?:((?:Eval|Internal|Range|Reference|Syntax|Type|URI|)Error): )?(.*)$/;f.report=function(){function a(a){m(),s.push(a)}function b(a){for(var b=s.length-1;b>=0;--b)s[b]===a&&s.splice(b,1)}function c(){n(),s=[]}function k(a,b){var c=null;if(!b||f.collectWindowErrors){for(var d in s)if(s.hasOwnProperty(d))try{s[d].apply(null,[a].concat(h.call(arguments,2)))}catch(e){c=e}if(c)throw c}}function l(a,b,c,g,h){var l=null,m=e.isErrorEvent(h)?h.error:h,n=e.isErrorEvent(a)?a.message:a;if(v)f.computeStackTrace.augmentStackTraceWithInitialElement(v,b,c,n),o();else if(m&&e.isError(m))l=f.computeStackTrace(m),k(l,!0);else{var p,r={url:b,line:c,column:g},s=void 0;if("[object String]"==={}.toString.call(n)){var p=n.match(j);p&&(s=p[1],n=p[2])}r.func=i,l={name:s,message:n,url:d(),stack:[r]},k(l,!0)}return!!q&&q.apply(this,arguments)}function m(){r||(q=g.onerror,g.onerror=l,r=!0)}function n(){r&&(g.onerror=q,r=!1,q=void 0)}function o(){var a=v,b=t;t=null,v=null,u=null,k.apply(null,[a,!1].concat(b))}function p(a,b){var c=h.call(arguments,1);if(v){if(u===a)return;o()}var d=f.computeStackTrace(a);if(v=d,u=a,t=c,setTimeout(function(){u===a&&o()},d.incomplete?2e3:0),b!==!1)throw a}var q,r,s=[],t=null,u=null,v=null;return p.subscribe=a,p.unsubscribe=b,p.uninstall=c,p}(),f.computeStackTrace=function(){function a(a){if("undefined"!=typeof a.stack&&a.stack){for(var b,c,e,f=/^\s*at (.*?) ?\(((?:file|https?|blob|chrome-extension|native|eval|webpack|<anonymous>|[a-z]:|\/).*?)(?::(\d+))?(?::(\d+))?\)?\s*$/i,g=/^\s*(.*?)(?:\((.*?)\))?(?:^|@)((?:file|https?|blob|chrome|webpack|resource|\[native).*?|[^@]*bundle)(?::(\d+))?(?::(\d+))?\s*$/i,h=/^\s*at (?:((?:\[object object\])?.+) )?\(?((?:file|ms-appx(?:-web)|https?|webpack|blob):.*?):(\d+)(?::(\d+))?\)?\s*$/i,j=/(\S+) line (\d+)(?: > eval line \d+)* > eval/i,k=/\((\S*)(?::(\d+))(?::(\d+))\)/,l=a.stack.split("\n"),m=[],n=(/^(.*) is undefined$/.exec(a.message),0),o=l.length;n<o;++n){if(c=f.exec(l[n])){var p=c[2]&&0===c[2].indexOf("native"),q=c[2]&&0===c[2].indexOf("eval");q&&(b=k.exec(c[2]))&&(c[2]=b[1],c[3]=b[2],c[4]=b[3]),e={url:p?null:c[2],func:c[1]||i,args:p?[c[2]]:[],line:c[3]?+c[3]:null,column:c[4]?+c[4]:null}}else if(c=h.exec(l[n]))e={url:c[2],func:c[1]||i,args:[],line:+c[3],column:c[4]?+c[4]:null};else{if(!(c=g.exec(l[n])))continue;var q=c[3]&&c[3].indexOf(" > eval")>-1;q&&(b=j.exec(c[3]))?(c[3]=b[1],c[4]=b[2],c[5]=null):0!==n||c[5]||"undefined"==typeof a.columnNumber||(m[0].column=a.columnNumber+1),e={url:c[3],func:c[1]||i,args:c[2]?c[2].split(","):[],line:c[4]?+c[4]:null,column:c[5]?+c[5]:null}}!e.func&&e.line&&(e.func=i),m.push(e)}return m.length?{name:a.name,message:a.message,url:d(),stack:m}:null}}function b(a,b,c,d){var e={url:b,line:c};if(e.url&&e.line){if(a.incomplete=!1,e.func||(e.func=i),a.stack.length>0&&a.stack[0].url===e.url){if(a.stack[0].line===e.line)return!1;if(!a.stack[0].line&&a.stack[0].func===e.func)return a.stack[0].line=e.line,!1}return a.stack.unshift(e),a.partial=!0,!0}return a.incomplete=!0,!1}function c(a,g){for(var h,j,k=/function\s+([_$a-zA-Z\xA0-\uFFFF][_$a-zA-Z0-9\xA0-\uFFFF]*)?\s*\(/i,l=[],m={},n=!1,o=c.caller;o&&!n;o=o.caller)if(o!==e&&o!==f.report){if(j={url:null,func:i,line:null,column:null},o.name?j.func=o.name:(h=k.exec(o.toString()))&&(j.func=h[1]),"undefined"==typeof j.func)try{j.func=h.input.substring(0,h.input.indexOf("{"))}catch(p){}m[""+o]?n=!0:m[""+o]=!0,l.push(j)}g&&l.splice(0,g);var q={name:a.name,message:a.message,url:d(),stack:l};return b(q,a.sourceURL||a.fileName,a.line||a.lineNumber,a.message||a.description),q}function e(b,e){var g=null;e=null==e?0:+e;try{if(g=a(b))return g}catch(h){if(f.debug)throw h}try{if(g=c(b,e+1))return g}catch(h){if(f.debug)throw h}return{name:b.name,message:b.message,url:d()}}return e.augmentStackTraceWithInitialElement=b,e.computeStackTraceFromStackProp=a,e}(),b.exports=f}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{5:5}],7:[function(a,b,c){function d(a,b){for(var c=0;c<a.length;++c)if(a[c]===b)return c;return-1}function e(a,b,c,d){return JSON.stringify(a,g(b,d),c)}function f(a){var b={stack:a.stack,message:a.message,name:a.name};for(var c in a)Object.prototype.hasOwnProperty.call(a,c)&&(b[c]=a[c]);return b}function g(a,b){var c=[],e=[];return null==b&&(b=function(a,b){return c[0]===b?"[Circular ~]":"[Circular ~."+e.slice(0,d(c,b)).join(".")+"]"}),function(g,h){if(c.length>0){var i=d(c,this);~i?c.splice(i+1):c.push(this),~i?e.splice(i,1/0,g):e.push(g),~d(c,h)&&(h=b.call(this,g,h))}else c.push(h);return null==a?h instanceof Error?f(h):h:a.call(this,g,h)}}c=b.exports=e,c.getSerialize=g},{}]},{},[4])(4)});
-//# sourceMappingURL=raven.min.js.map \ No newline at end of file
diff --git a/gulpfile.js b/gulpfile.js
index adfb148a9..f57ea6206 100644
--- a/gulpfile.js
+++ b/gulpfile.js
@@ -339,7 +339,7 @@ function generateBundler(opts, performBundle) {
const browserifyOpts = assign({}, watchify.args, {
entries: ['./app/scripts/'+opts.filename],
plugin: 'browserify-derequire',
- debug: debug,
+ debug: true,
fullPaths: debug,
})
@@ -405,13 +405,13 @@ function bundleTask(opts) {
.pipe(buffer())
// sourcemaps
// loads map from browserify file
- .pipe(gulpif(debug, sourcemaps.init({ loadMaps: true })))
+ .pipe(sourcemaps.init({ loadMaps: true }))
// Minification
.pipe(gulpif(opts.isBuild, uglify({
mangle: { reserved: [ 'MetamaskInpageProvider' ] },
})))
// writes .map file
- .pipe(gulpif(debug, sourcemaps.write('./')))
+ .pipe(sourcemaps.write(debug ? './' : '../../sourcemaps'))
// write completed bundles
.pipe(gulp.dest('./dist/firefox/scripts'))
.pipe(gulp.dest('./dist/chrome/scripts'))
diff --git a/package-lock.json b/package-lock.json
index d1c488b09..5d1c46c26 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -182,6 +182,48 @@
"through2": "2.0.3"
}
},
+ "@sentry/cli": {
+ "version": "1.30.3",
+ "resolved": "https://registry.npmjs.org/@sentry/cli/-/cli-1.30.3.tgz",
+ "integrity": "sha1-AtD3eBwe5eG+WkMSoyX76LGzcjE=",
+ "dev": true,
+ "requires": {
+ "https-proxy-agent": "2.2.0",
+ "node-fetch": "1.7.3",
+ "progress": "2.0.0",
+ "proxy-from-env": "1.0.0"
+ },
+ "dependencies": {
+ "agent-base": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.2.0.tgz",
+ "integrity": "sha512-c+R/U5X+2zz2+UCrCFv6odQzJdoqI+YecuhnAJLa1zYaMc13zPfwMwZrr91Pd1DYNo/yPRbiM4WVf9whgwFsIg==",
+ "dev": true,
+ "requires": {
+ "es6-promisify": "5.0.0"
+ }
+ },
+ "debug": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
+ "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
+ "dev": true,
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "https-proxy-agent": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.0.tgz",
+ "integrity": "sha512-uUWcfXHvy/dwfM9bqa6AozvAjS32dZSTUYd/4SEpYKRg6LEcPLshksnQYRudM9AyNvUARMfAg5TLjUDyX/K4vA==",
+ "dev": true,
+ "requires": {
+ "agent-base": "4.2.0",
+ "debug": "3.1.0"
+ }
+ }
+ }
+ },
"@types/node": {
"version": "8.5.5",
"resolved": "https://registry.npmjs.org/@types/node/-/node-8.5.5.tgz",
@@ -4932,6 +4974,21 @@
"event-emitter": "0.3.5"
}
},
+ "es6-promise": {
+ "version": "4.2.4",
+ "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.4.tgz",
+ "integrity": "sha512-/NdNZVJg+uZgtm9eS3O6lrOLYmQag2DjdEXuPaHlZ6RuVqgqaVZfgYCepEIKsLqwdQArOPtC3XzRLqGGfT8KQQ==",
+ "dev": true
+ },
+ "es6-promisify": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz",
+ "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=",
+ "dev": true,
+ "requires": {
+ "es6-promise": "4.2.4"
+ }
+ },
"es6-set": {
"version": "0.1.5",
"resolved": "https://registry.npmjs.org/es6-set/-/es6-set-0.1.5.tgz",
@@ -16914,6 +16971,12 @@
}
}
},
+ "proxy-from-env": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.0.0.tgz",
+ "integrity": "sha1-M8UDmPcOp+uW0h97gXYwpVeRx+4=",
+ "dev": true
+ },
"prr": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz",
@@ -17237,6 +17300,11 @@
"eve-raphael": "0.5.0"
}
},
+ "raven-js": {
+ "version": "3.24.0",
+ "resolved": "https://registry.npmjs.org/raven-js/-/raven-js-3.24.0.tgz",
+ "integrity": "sha512-+/ygcWib8PXAE7Xq53j1tYxCgkzFyp9z05LYAKp2PA9KwO4Ek74q1tkGwZyPWI/FoXOgas6jNtQ7O3tdPif6uA=="
+ },
"raw-body": {
"version": "2.3.2",
"resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.2.tgz",
diff --git a/package.json b/package.json
index 1aae1092e..ac4758f57 100644
--- a/package.json
+++ b/package.json
@@ -12,7 +12,7 @@
"mascara": "gulp build && cross-env METAMASK_DEBUG=true node ./mascara/example/server",
"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": "npm run test:unit && npm run test:integration && npm run lint",
"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",
@@ -29,6 +29,13 @@
"test:mascara:build:ui": "browserify mascara/test/test-ui.js -o dist/mascara/ui.js",
"test:mascara:build:background": "browserify mascara/src/background.js -o dist/mascara/background.js",
"test:mascara:build:tests": "browserify test/integration/lib/first-time.js -o dist/mascara/tests.js",
+ "sentry": "export RELEASE=`cat app/manifest.json| jq -r .version` && npm run sentry:release && npm run sentry:upload",
+ "sentry:release": "npm run sentry:release:new && npm run sentry:release:clean",
+ "sentry:release:new": "sentry-cli releases --org 'metamask' --project 'metamask' new $RELEASE",
+ "sentry:release:clean": "sentry-cli releases --org 'metamask' --project 'metamask' files $RELEASE delete --all",
+ "sentry:upload": "npm run sentry:upload:source && npm run sentry:upload:maps",
+ "sentry:upload:source": "for FILEPATH in ./dist/chrome/scripts/*.js; do [ -e $FILEPATH ] || continue; export FILE=`basename $FILEPATH` && echo uploading $FILE && sentry-cli releases --org 'metamask' --project 'metamask' files $RELEASE upload $FILEPATH metamask/scripts/$FILE; done;",
+ "sentry:upload:maps": "sentry-cli releases --org 'metamask' --project 'metamask' files $RELEASE upload-sourcemaps ./dist/sourcemaps/ --url-prefix 'sourcemaps' --rewrite",
"lint": "gulp lint",
"lint:fix": "gulp lint:fix",
"disc": "gulp disc --debug",
@@ -144,6 +151,7 @@
"pumpify": "^1.3.4",
"qrcode-npm": "0.0.3",
"ramda": "^0.24.1",
+ "raven-js": "^3.24.0",
"react": "^15.6.2",
"react-addons-css-transition-group": "^15.6.0",
"react-dom": "^15.6.2",
@@ -179,6 +187,7 @@
"xtend": "^4.0.1"
},
"devDependencies": {
+ "@sentry/cli": "^1.30.3",
"babel-core": "^6.24.1",
"babel-eslint": "^8.0.0",
"babel-plugin-transform-async-to-generator": "^6.24.1",
diff --git a/test/integration/lib/add-token.js b/test/integration/lib/add-token.js
index 42ed28dca..228192e7b 100644
--- a/test/integration/lib/add-token.js
+++ b/test/integration/lib/add-token.js
@@ -26,7 +26,7 @@ async function runAddTokenFlowTest (assert, done) {
assert.ok($('.token-list-item').length === 0, 'no tokens added')
// Go to Add Token screen
- let addTokenButton = await queryAsync($, 'button.btn-clear.wallet-view__add-token-button')
+ let addTokenButton = await queryAsync($, 'button.btn-primary.wallet-view__add-token-button')
assert.ok(addTokenButton[0], 'add token button present')
addTokenButton[0].click()
@@ -38,14 +38,14 @@ async function runAddTokenFlowTest (assert, done) {
assert.equal(addTokenTitle[0].textContent, 'Add Token', 'add token title is correct')
// Cancel Add Token
- const cancelAddTokenButton = await queryAsync($, 'button.btn-cancel.add-token__button')
+ const cancelAddTokenButton = await queryAsync($, 'button.btn-secondary--lg.add-token__cancel-button')
assert.ok(cancelAddTokenButton[0], 'cancel add token button present')
cancelAddTokenButton.click()
assert.ok($('.wallet-view')[0], 'cancelled and returned to account detail wallet view')
// Return to Add Token Screen
- addTokenButton = await queryAsync($, 'button.btn-clear.wallet-view__add-token-button')
+ addTokenButton = await queryAsync($, 'button.btn-primary.wallet-view__add-token-button')
assert.ok(addTokenButton[0], 'add token button present')
addTokenButton[0].click()
@@ -68,7 +68,7 @@ async function runAddTokenFlowTest (assert, done) {
tokenWrapper[0].click()
// Click Next button
- let nextButton = await queryAsync($, 'button.btn-clear.add-token__button')
+ let nextButton = await queryAsync($, 'button.btn-primary--lg')
assert.equal(nextButton[0].textContent, 'Next', 'next button rendered')
nextButton[0].click()
@@ -78,8 +78,8 @@ async function runAddTokenFlowTest (assert, done) {
'Would you like to add these tokens?',
'confirm add token rendered'
)
- assert.ok($('button.btn-clear.add-token__button')[0], 'confirm add token button found')
- $('button.btn-clear.add-token__button')[0].click()
+ assert.ok($('button.btn-primary--lg')[0], 'confirm add token button found')
+ $('button.btn-primary--lg')[0].click()
// Verify added token image
let heroBalance = await queryAsync($, '.hero-balance')
@@ -87,7 +87,7 @@ async function runAddTokenFlowTest (assert, done) {
assert.ok(tokenImageUrl.indexOf(heroBalance.find('img').attr('src')) > -1, 'token added')
// Return to Add Token Screen
- addTokenButton = await queryAsync($, 'button.btn-clear.wallet-view__add-token-button')
+ addTokenButton = await queryAsync($, 'button.btn-primary.wallet-view__add-token-button')
assert.ok(addTokenButton[0], 'add token button present')
addTokenButton[0].click()
@@ -101,14 +101,14 @@ async function runAddTokenFlowTest (assert, done) {
reactTriggerChange(customInput[0])
// Click Next button
- nextButton = await queryAsync($, 'button.btn-clear.add-token__button')
+ nextButton = await queryAsync($, 'button.btn-primary--lg')
assert.equal(nextButton[0].textContent, 'Next', 'next button rendered')
nextButton[0].click()
// Verify symbol length error since contract address won't return symbol
const errorMessage = await queryAsync($, '.add-token__add-custom-error-message')
assert.ok(errorMessage[0], 'error rendered')
- $('button.btn-cancel.add-token__button')[0].click()
+ $('button.btn-secondary--lg')[0].click()
// // Confirm Add token
// assert.equal(
@@ -116,8 +116,8 @@ async function runAddTokenFlowTest (assert, done) {
// 'Would you like to add these tokens?',
// 'confirm add token rendered'
// )
- // assert.ok($('button.btn-clear.add-token__button')[0], 'confirm add token button found')
- // $('button.btn-clear.add-token__button')[0].click()
+ // assert.ok($('button.btn-primary--lg')[0], 'confirm add token button found')
+ // $('button.btn-primary--lg')[0].click()
// // Verify added token image
// heroBalance = await queryAsync($, '.hero-balance')
diff --git a/test/integration/lib/confirm-sig-requests.js b/test/integration/lib/confirm-sig-requests.js
index 9737a2283..f1116d1a6 100644
--- a/test/integration/lib/confirm-sig-requests.js
+++ b/test/integration/lib/confirm-sig-requests.js
@@ -27,7 +27,7 @@ async function runConfirmSigRequestsTest(assert, done) {
let confirmSigRowValue = await queryAsync($, '.request-signature__row-value')
assert.ok(confirmSigRowValue[0].textContent.match(/^\#\sTerms\sof\sUse/))
- let confirmSigSignButton = await queryAsync($, '.request-signature__footer__sign-button')
+ let confirmSigSignButton = await queryAsync($, 'button.btn-primary--lg')
confirmSigSignButton[0].click()
confirmSigHeadline = await queryAsync($, '.request-signature__headline')
@@ -39,7 +39,7 @@ async function runConfirmSigRequestsTest(assert, done) {
confirmSigRowValue = await queryAsync($, '.request-signature__row-value')
assert.equal(confirmSigRowValue[0].textContent, '0x879a053d4800c6354e76c7985a865d2922c82fb5b3f4577b2fe08b998954f2e0')
- confirmSigSignButton = await queryAsync($, '.request-signature__footer__sign-button')
+ confirmSigSignButton = await queryAsync($, 'button.btn-primary--lg')
confirmSigSignButton[0].click()
confirmSigHeadline = await queryAsync($, '.request-signature__headline')
@@ -49,7 +49,7 @@ async function runConfirmSigRequestsTest(assert, done) {
assert.equal(confirmSigRowValue[0].textContent, 'Hi, Alice!')
assert.equal(confirmSigRowValue[1].textContent, '1337')
- confirmSigSignButton = await queryAsync($, '.request-signature__footer__sign-button')
+ confirmSigSignButton = await queryAsync($, 'button.btn-primary--lg')
confirmSigSignButton[0].click()
const txView = await queryAsync($, '.tx-view')
diff --git a/test/integration/lib/send-new-ui.js b/test/integration/lib/send-new-ui.js
index 46e0ef0e4..7bd9a7a65 100644
--- a/test/integration/lib/send-new-ui.js
+++ b/test/integration/lib/send-new-ui.js
@@ -21,13 +21,15 @@ global.ethQuery = {
sendTransaction: () => {},
}
+global.ethereumProvider = {}
+
async function runSendFlowTest(assert, done) {
console.log('*** start runSendFlowTest')
const selectState = await queryAsync($, 'select')
selectState.val('send new ui')
reactTriggerChange(selectState[0])
- const sendScreenButton = await queryAsync($, 'button.btn-clear.hero-balance-button')
+ const sendScreenButton = await queryAsync($, 'button.btn-primary.hero-balance-button')
assert.ok(sendScreenButton[1], 'send screen button present')
sendScreenButton[1].click()
@@ -120,7 +122,7 @@ async function runSendFlowTest(assert, done) {
'send gas field should show customized gas total converted to USD'
)
- const sendButton = await queryAsync($, 'button.btn-clear.page-container__footer-button')
+ const sendButton = await queryAsync($, 'button.btn-primary--lg.page-container__footer-button')
assert.equal(sendButton[0].textContent, 'Next', 'next button rendered')
sendButton[0].click()
await timeout()
@@ -161,7 +163,7 @@ async function runSendFlowTest(assert, done) {
sendAmountFieldInputInEdit.val('1.0')
reactTriggerChange(sendAmountFieldInputInEdit[0])
- const sendButtonInEdit = await queryAsync($, '.btn-clear.page-container__footer-button')
+ const sendButtonInEdit = await queryAsync($, '.btn-primary--lg.page-container__footer-button')
assert.equal(sendButtonInEdit[0].textContent, 'Next', 'next button in edit rendered')
sendButtonInEdit[0].click()
diff --git a/ui/app/accounts/import/json.js b/ui/app/accounts/import/json.js
index fa25168f1..eeba73e77 100644
--- a/ui/app/accounts/import/json.js
+++ b/ui/app/accounts/import/json.js
@@ -50,13 +50,13 @@ class JsonImportSubview extends Component {
h('div.new-account-create-form__buttons', {}, [
- h('button.new-account-create-form__button-cancel', {
+ h('button.btn-secondary.new-account-create-form__button', {
onClick: () => this.props.goHome(),
}, [
t('cancel'),
]),
- h('button.new-account-create-form__button-create', {
+ h('button.btn-primary.new-account-create-form__button', {
onClick: () => this.createNewKeychain(),
}, [
t('import'),
diff --git a/ui/app/accounts/import/private-key.js b/ui/app/accounts/import/private-key.js
index bc9e9384e..13c8da722 100644
--- a/ui/app/accounts/import/private-key.js
+++ b/ui/app/accounts/import/private-key.js
@@ -48,13 +48,13 @@ PrivateKeyImportView.prototype.render = function () {
h('div.new-account-import-form__buttons', {}, [
- h('button.new-account-create-form__button-cancel.allcaps', {
+ h('button.btn-secondary--lg.new-account-create-form__button', {
onClick: () => goHome(),
}, [
t('cancel'),
]),
- h('button.new-account-create-form__button-create.allcaps', {
+ h('button.btn-primary--lg.new-account-create-form__button', {
onClick: () => this.createNewKeychain(),
}, [
t('import'),
diff --git a/ui/app/accounts/new-account/create-form.js b/ui/app/accounts/new-account/create-form.js
index 8ef842a2a..c820cdf6d 100644
--- a/ui/app/accounts/new-account/create-form.js
+++ b/ui/app/accounts/new-account/create-form.js
@@ -20,7 +20,7 @@ class NewAccountCreateForm extends Component {
render () {
const { newAccountName, defaultAccountName } = this.state
-
+
return h('div.new-account-create-form', [
@@ -38,13 +38,13 @@ class NewAccountCreateForm extends Component {
h('div.new-account-create-form__buttons', {}, [
- h('button.new-account-create-form__button-cancel.allcaps', {
+ h('button.btn-secondary--lg.new-account-create-form__button', {
onClick: () => this.props.goHome(),
}, [
t('cancel'),
]),
- h('button.new-account-create-form__button-create.allcaps', {
+ h('button.btn-primary--lg.new-account-create-form__button', {
onClick: () => this.props.createAccount(newAccountName || defaultAccountName),
}, [
t('create'),
diff --git a/ui/app/actions.js b/ui/app/actions.js
index bc7ee3d07..4a5962610 100644
--- a/ui/app/actions.js
+++ b/ui/app/actions.js
@@ -694,10 +694,10 @@ function updateSendFrom (from) {
}
}
-function updateSendTo (to) {
+function updateSendTo (to, nickname = '') {
return {
type: actions.UPDATE_SEND_TO,
- value: to,
+ value: { to, nickname },
}
}
diff --git a/ui/app/add-token.js b/ui/app/add-token.js
index b3a5bdc20..edeea11d8 100644
--- a/ui/app/add-token.js
+++ b/ui/app/add-token.js
@@ -321,10 +321,10 @@ AddTokenScreen.prototype.renderConfirmation = function () {
]),
]),
h('div.add-token__buttons', [
- h('button.btn-cancel.add-token__button', {
+ h('button.btn-secondary--lg.add-token__cancel-button', {
onClick: () => this.setState({ isShowingConfirmation: false }),
}, t('back')),
- h('button.btn-clear.add-token__button', {
+ h('button.btn-primary--lg', {
onClick: () => addTokens(tokens).then(goHome),
}, t('addTokens')),
]),
@@ -371,10 +371,10 @@ AddTokenScreen.prototype.render = function () {
]),
]),
h('div.add-token__buttons', [
- h('button.btn-cancel.add-token__button', {
+ h('button.btn-secondary--lg.add-token__cancel-button', {
onClick: goHome,
}, t('cancel')),
- h('button.btn-clear.add-token__button', {
+ h('button.btn-primary--lg', {
onClick: this.onNext,
}, t('next')),
]),
diff --git a/ui/app/components/customize-gas-modal/index.js b/ui/app/components/customize-gas-modal/index.js
index d8384c19d..22ad98ce4 100644
--- a/ui/app/components/customize-gas-modal/index.js
+++ b/ui/app/components/customize-gas-modal/index.js
@@ -302,12 +302,16 @@ CustomizeGasModal.prototype.render = function () {
}, [t('revert')]),
h('div.send-v2__customize-gas__buttons', [
- h('div.send-v2__customize-gas__cancel.allcaps', {
+ h('button.btn-secondary.send-v2__customize-gas__cancel', {
onClick: this.props.hideModal,
+ style: {
+ marginRight: '10px',
+ },
}, [t('cancel')]),
- h(`div.send-v2__customize-gas__save${error ? '__error' : ''}.allcaps`, {
+ h('button.btn-primary.send-v2__customize-gas__save', {
onClick: () => !error && this.save(newGasPrice, gasLimit, gasTotal),
+ className: error && 'btn-primary--disabled',
}, [t('save')]),
]),
diff --git a/ui/app/components/ens-input.js b/ui/app/components/ens-input.js
index add67ea35..1b2d4009d 100644
--- a/ui/app/components/ens-input.js
+++ b/ui/app/components/ens-input.js
@@ -9,6 +9,7 @@ const networkMap = require('ethjs-ens/lib/network-map.json')
const ensRE = /.+\..+$/
const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000'
const t = require('../../i18n')
+const ToAutoComplete = require('./send/to-autocomplete')
module.exports = EnsInput
@@ -22,12 +23,14 @@ EnsInput.prototype.render = function () {
const props = this.props
const opts = extend(props, {
list: 'addresses',
- onChange: () => {
+ onChange: (recipient) => {
const network = this.props.network
const networkHasEnsSupport = getNetworkEnsSupport(network)
+
if (!networkHasEnsSupport) return
- const recipient = document.querySelector('input[name="address"]').value
+ props.onChange(recipient)
+
if (recipient.match(ensRE) === null) {
return this.setState({
loadingEns: false,
@@ -39,34 +42,13 @@ EnsInput.prototype.render = function () {
this.setState({
loadingEns: true,
})
- this.checkName()
+ this.checkName(recipient)
},
})
return h('div', {
- style: { width: '100%' },
+ style: { width: '100%', position: 'relative' },
}, [
- h('input.large-input.send-screen-input', opts),
- // The address book functionality.
- h('datalist#addresses',
- [
- // Corresponds to the addresses owned.
- Object.keys(props.identities).map((key) => {
- const identity = props.identities[key]
- return h('option', {
- value: identity.address,
- label: identity.name,
- key: identity.address,
- })
- }),
- // Corresponds to previously sent-to addresses.
- props.addressBook.map((identity) => {
- return h('option', {
- value: identity.address,
- label: identity.name,
- key: identity.address,
- })
- }),
- ]),
+ h(ToAutoComplete, { ...opts }),
this.ensIcon(),
])
}
@@ -83,8 +65,7 @@ EnsInput.prototype.componentDidMount = function () {
}
}
-EnsInput.prototype.lookupEnsName = function () {
- const recipient = document.querySelector('input[name="address"]').value
+EnsInput.prototype.lookupEnsName = function (recipient) {
const { ensResolution } = this.state
log.info(`ENS attempting to resolve name: ${recipient}`)
@@ -130,8 +111,8 @@ EnsInput.prototype.ensIcon = function (recipient) {
title: hoverText,
style: {
position: 'absolute',
- padding: '9px',
- transform: 'translatex(-40px)',
+ top: '16px',
+ left: '-25px',
},
}, this.ensIconContents(recipient))
}
diff --git a/ui/app/components/modals/account-details-modal.js b/ui/app/components/modals/account-details-modal.js
index 75f989e86..927d73482 100644
--- a/ui/app/components/modals/account-details-modal.js
+++ b/ui/app/components/modals/account-details-modal.js
@@ -63,12 +63,12 @@ AccountDetailsModal.prototype.render = function () {
h('div.account-modal-divider'),
- h('button.btn-clear.account-modal__button', {
+ h('button.btn-primary.account-modal__button', {
onClick: () => global.platform.openWindow({ url: genAccountLink(address, network) }),
}, t('etherscanView')),
// Holding on redesign for Export Private Key functionality
- h('button.btn-clear.account-modal__button', {
+ h('button.btn-primary.account-modal__button', {
onClick: () => showExportPrivateKeyModal(),
}, t('exportPrivateKey')),
diff --git a/ui/app/components/modals/deposit-ether-modal.js b/ui/app/components/modals/deposit-ether-modal.js
index b642513d7..2de1240fc 100644
--- a/ui/app/components/modals/deposit-ether-modal.js
+++ b/ui/app/components/modals/deposit-ether-modal.js
@@ -94,7 +94,7 @@ DepositEtherModal.prototype.renderRow = function ({
]),
!hideButton && h('div.deposit-ether-modal__buy-row__button', [
- h('button.deposit-ether-modal__deposit-button', {
+ h('button.btn-primary--lg.deposit-ether-modal__deposit-button', {
onClick: onButtonClick,
}, [buttonLabel]),
]),
diff --git a/ui/app/components/modals/export-private-key-modal.js b/ui/app/components/modals/export-private-key-modal.js
index 017177cfd..cf42e4fa2 100644
--- a/ui/app/components/modals/export-private-key-modal.js
+++ b/ui/app/components/modals/export-private-key-modal.js
@@ -81,14 +81,14 @@ ExportPrivateKeyModal.prototype.renderButton = function (className, onClick, lab
ExportPrivateKeyModal.prototype.renderButtons = function (privateKey, password, address, hideModal) {
return h('div.export-private-key-buttons', {}, [
!privateKey && this.renderButton(
- 'btn-cancel export-private-key__button export-private-key__button--cancel',
+ 'btn-secondary--lg export-private-key__button export-private-key__button--cancel',
() => hideModal(),
'Cancel'
),
(privateKey
- ? this.renderButton('btn-clear export-private-key__button', () => hideModal(), t('done'))
- : this.renderButton('btn-clear export-private-key__button', () => this.exportAccountAndGetPrivateKey(this.state.password, address), t('confirm'))
+ ? this.renderButton('btn-primary--lg export-private-key__button', () => hideModal(), t('done'))
+ : this.renderButton('btn-primary--lg export-private-key__button', () => this.exportAccountAndGetPrivateKey(this.state.password, address), t('confirm'))
),
])
diff --git a/ui/app/components/send/send-v2-container.js b/ui/app/components/send/send-v2-container.js
index d1319b6dc..08c26a91f 100644
--- a/ui/app/components/send/send-v2-container.js
+++ b/ui/app/components/send/send-v2-container.js
@@ -69,13 +69,13 @@ function mapDispatchToProps (dispatch) {
updateAndApproveTx: txParams => dispatch(actions.updateAndApproveTx(txParams)),
updateTx: txData => dispatch(actions.updateTransaction(txData)),
setSelectedAddress: address => dispatch(actions.setSelectedAddress(address)),
- addToAddressBook: address => dispatch(actions.addToAddressBook(address)),
+ addToAddressBook: (address, nickname) => dispatch(actions.addToAddressBook(address, nickname)),
updateGasTotal: newTotal => dispatch(actions.updateGasTotal(newTotal)),
updateGasPrice: newGasPrice => dispatch(actions.updateGasPrice(newGasPrice)),
updateGasLimit: newGasLimit => dispatch(actions.updateGasLimit(newGasLimit)),
updateSendTokenBalance: tokenBalance => dispatch(actions.updateSendTokenBalance(tokenBalance)),
updateSendFrom: newFrom => dispatch(actions.updateSendFrom(newFrom)),
- updateSendTo: newTo => dispatch(actions.updateSendTo(newTo)),
+ updateSendTo: (newTo, nickname) => dispatch(actions.updateSendTo(newTo, nickname)),
updateSendAmount: newAmount => dispatch(actions.updateSendAmount(newAmount)),
updateSendMemo: newMemo => dispatch(actions.updateSendMemo(newMemo)),
updateSendErrors: newError => dispatch(actions.updateSendErrors(newError)),
diff --git a/ui/app/components/shapeshift-form.js b/ui/app/components/shapeshift-form.js
index 3f8c17932..5729f893c 100644
--- a/ui/app/components/shapeshift-form.js
+++ b/ui/app/components/shapeshift-form.js
@@ -236,7 +236,7 @@ ShapeshiftForm.prototype.render = function () {
]),
- !depositAddress && h('button.shapeshift-form__shapeshift-buy-btn', {
+ !depositAddress && h('button.btn-primary--lg.shapeshift-form__shapeshift-buy-btn', {
className: btnClass,
disabled: !token,
onClick: () => this.onBuyWithShapeShift(),
diff --git a/ui/app/components/signature-request.js b/ui/app/components/signature-request.js
index 7bf34e7b6..810a52e55 100644
--- a/ui/app/components/signature-request.js
+++ b/ui/app/components/signature-request.js
@@ -223,10 +223,10 @@ SignatureRequest.prototype.renderFooter = function () {
}
return h('div.request-signature__footer', [
- h('button.request-signature__footer__cancel-button', {
+ h('button.btn-secondary--lg.request-signature__footer__cancel-button', {
onClick: cancel,
}, t('cancel')),
- h('button.request-signature__footer__sign-button', {
+ h('button.btn-primary--lg', {
onClick: sign,
}, t('sign')),
])
diff --git a/ui/app/components/tx-view.js b/ui/app/components/tx-view.js
index 96d776270..bf2065106 100644
--- a/ui/app/components/tx-view.js
+++ b/ui/app/components/tx-view.js
@@ -69,13 +69,13 @@ TxView.prototype.renderButtons = function () {
return !selectedToken
? (
h('div.flex-row.flex-center.hero-balance-buttons', [
- h('button.btn-clear.hero-balance-button.allcaps', {
+ h('button.btn-primary.hero-balance-button', {
onClick: () => showModal({
name: 'DEPOSIT_ETHER',
}),
}, t('deposit')),
- h('button.btn-clear.hero-balance-button.allcaps', {
+ h('button.btn-primary.hero-balance-button', {
style: {
marginLeft: '0.8em',
},
@@ -85,7 +85,7 @@ TxView.prototype.renderButtons = function () {
)
: (
h('div.flex-row.flex-center.hero-balance-buttons', [
- h('button.btn-clear.hero-balance-button', {
+ h('button.btn-primary.hero-balance-button', {
onClick: showSendTokenPage,
}, t('send')),
])
diff --git a/ui/app/components/wallet-view.js b/ui/app/components/wallet-view.js
index 18452205c..2c6d7f784 100644
--- a/ui/app/components/wallet-view.js
+++ b/ui/app/components/wallet-view.js
@@ -168,7 +168,7 @@ WalletView.prototype.render = function () {
h(TokenList),
- h('button.btn-clear.wallet-view__add-token-button', {
+ h('button.btn-primary.wallet-view__add-token-button', {
onClick: () => {
showAddTokenPage()
hideSidebar()
diff --git a/ui/app/css/itcss/components/add-token.scss b/ui/app/css/itcss/components/add-token.scss
index 13020f62f..bdf9da385 100644
--- a/ui/app/css/itcss/components/add-token.scss
+++ b/ui/app/css/itcss/components/add-token.scss
@@ -172,11 +172,8 @@
justify-content: center;
}
- &__button {
- flex: 1 0 141px;
- margin: 0 12px;
- padding: 10px 22px;
- height: 54px;
+ &__cancel-button {
+ margin-right: 1.2rem;
}
&__token-icons-container {
@@ -334,7 +331,7 @@
}
&__buttons {
- padding: 12px 0;
+ padding: 1rem;
margin: 0;
border-top: 1px solid $gallery;
width: 100%;
diff --git a/ui/app/css/itcss/components/buttons.scss b/ui/app/css/itcss/components/buttons.scss
index 8df8829f2..04e1ed96e 100644
--- a/ui/app/css/itcss/components/buttons.scss
+++ b/ui/app/css/itcss/components/buttons.scss
@@ -2,6 +2,76 @@
Buttons
*/
+.btn-primary,
+.btn-primary--lg,
+.btn-secondary,
+.btn-secondary--lg {
+ background: $white;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ box-sizing: border-box;
+ border-radius: 4px;
+ font-size: 14px;
+ font-weight: 500;
+ transition: border-color .3s ease;
+ padding: 0 20px;
+ min-width: 140px;
+ text-transform: uppercase;
+}
+
+.btn-primary,
+.btn-primary--lg {
+ color: $curious-blue;
+ border: 2px solid $spindle;
+
+ &:active {
+ background: $zumthor;
+ border-color: $curious-blue;
+ }
+
+ &:hover {
+ border-color: $curious-blue;
+ }
+
+ &--disabled,
+ &[disabled] {
+ cursor: auto;
+ opacity: .5;
+ pointer-events: none;
+ }
+}
+
+.btn-secondary,
+.btn-secondary--lg {
+ color: $scorpion;
+ border: 2px solid $dusty-gray;
+
+ &:active {
+ background: $gallery;
+ border-color: $dusty-gray;
+ }
+
+ &:hover {
+ border-color: $scorpion;
+ }
+
+ &--disabled,
+ &[disabled] {
+ cursor: auto;
+ opacity: .5;
+ pointer-events: none;
+ }
+}
+
+.btn-primary, .btn-secondary {
+ height: 44px;
+}
+
+.btn-primary--lg, .btn-secondary--lg {
+ height: 54px;
+}
+
.btn-green {
background-color: #02c9b1; // TODO: reusable color in colors.css
}
@@ -130,20 +200,6 @@ button.btn-thin {
font-size: 13px;
}
-.btn-secondary {
- border: 1px solid #979797;
- border-radius: 2px;
- background-color: $white;
- font-size: 16px;
- line-height: 24px;
- padding: 16px 42px;
-
- &[disabled] {
- background-color: $white !important;
- opacity: .5;
- }
-}
-
.btn-tertiary {
border: 1px solid transparent;
border-radius: 2px;
diff --git a/ui/app/css/itcss/components/hero-balance.scss b/ui/app/css/itcss/components/hero-balance.scss
index a3f051361..69cde8a0f 100644
--- a/ui/app/css/itcss/components/hero-balance.scss
+++ b/ui/app/css/itcss/components/hero-balance.scss
@@ -103,10 +103,11 @@
}
.hero-balance-button {
+ min-width: initial;
width: 6rem;
@media #{$sub-mid-size-breakpoint-range} {
- padding: 0.4rem;
+ padding: .4rem;
width: 4rem;
display: flex;
flex: 1;
diff --git a/ui/app/css/itcss/components/modal.scss b/ui/app/css/itcss/components/modal.scss
index a8d5e8dc2..9ae3ea7fa 100644
--- a/ui/app/css/itcss/components/modal.scss
+++ b/ui/app/css/itcss/components/modal.scss
@@ -261,7 +261,7 @@
.account-modal__button {
margin-top: 17px;
padding: 10px 22px;
- width: 235px;
+ width: 286px;
}
}
@@ -341,9 +341,8 @@
.export-private-key__button {
margin-top: 17px;
- padding: 10px 22px;
width: 141px;
- height: 54px;
+ min-width: initial;
}
.export-private-key__button--cancel {
@@ -765,15 +764,7 @@
}
&__deposit-button, .shapeshift-form__shapeshift-buy-btn {
- height: 54px;
width: 257px;
- border: 1px solid $curious-blue;
- border-radius: 4px;
- display: flex;
- justify-content: center;
- font-size: 16px;
- color: $curious-blue;
- background-color: $white;
}
.shapeshift-form-wrapper {
diff --git a/ui/app/css/itcss/components/new-account.scss b/ui/app/css/itcss/components/new-account.scss
index c2cefe4ad..aa7fed956 100644
--- a/ui/app/css/itcss/components/new-account.scss
+++ b/ui/app/css/itcss/components/new-account.scss
@@ -192,29 +192,8 @@
justify-content: space-between;
}
- &__button-cancel,
- &__button-create {
- height: 55px;
+ &__button {
width: 150px;
- border-radius: 2px;
- background-color: #FFFFFF;
- }
-
- &__button-cancel {
- border: 1px solid $dusty-gray;
- color: $dusty-gray;
- font-family: Roboto;
- font-size: 16px;
- line-height: 21px;
- text-align: center;
+ min-width: initial;
}
-
- &__button-create {
- border: 1px solid $curious-blue;
- color: $curious-blue;
- font-family: Roboto;
- font-size: 16px;
- line-height: 21px;
- text-align: center;
- }
-} \ No newline at end of file
+}
diff --git a/ui/app/css/itcss/components/request-signature.scss b/ui/app/css/itcss/components/request-signature.scss
index 9ad69dfc0..083481b8f 100644
--- a/ui/app/css/itcss/components/request-signature.scss
+++ b/ui/app/css/itcss/components/request-signature.scss
@@ -191,41 +191,19 @@
width: 100%;
display: flex;
align-items: center;
- justify-content: space-evenly;
+ justify-content: center;
font-size: 22px;
position: relative;
flex: 0 0 auto;
border-top: 1px solid $geyser;
+ padding: 1.6rem;
- &__cancel-button,
- &__sign-button {
- display: flex;
- align-items: center;
- justify-content: center;
- flex: 1 0 auto;
- font-family: Roboto;
- font-size: 16px;
- font-weight: 300;
- height: 55px;
- line-height: 32px;
- cursor: pointer;
- border-radius: 2px;
- box-shadow: none;
- max-width: 162px;
- margin: 12px;
+ button {
+ width: 165px;
}
&__cancel-button {
- background: none;
- border: 1px solid $dusty-gray;
- margin-right: 6px;
- }
-
- &__sign-button {
- background-color: $caribbean-green;
- border-width: 0;
- color: $white;
- margin-left: 6px;
+ margin-right: 1.2rem;
}
}
-} \ No newline at end of file
+}
diff --git a/ui/app/css/itcss/components/send.scss b/ui/app/css/itcss/components/send.scss
index 263b362ca..89d2be891 100644
--- a/ui/app/css/itcss/components/send.scss
+++ b/ui/app/css/itcss/components/send.scss
@@ -782,7 +782,6 @@
&__buttons {
display: flex;
justify-content: space-between;
- width: 181.75px;
margin-right: 21.25px;
}
@@ -800,13 +799,8 @@
}
&__cancel, &__save, &__save__error {
- height: 34.64px;
width: 85.74px;
- border: 1px solid $dusty-gray;
- border-radius: 2px;
- font-family: 'DIN OT';
- font-size: 12px;
- color: $dusty-gray;
+ min-width: initial;
}
&__save__error {
diff --git a/ui/app/css/itcss/components/settings.scss b/ui/app/css/itcss/components/settings.scss
index d60ebd934..dcc9b98d5 100644
--- a/ui/app/css/itcss/components/settings.scss
+++ b/ui/app/css/itcss/components/settings.scss
@@ -130,24 +130,32 @@
cursor: pointer;
}
-.settings__clear-button {
- font-size: 16px;
- border: 1px solid $curious-blue;
- color: $curious-blue;
- border-radius: 2px;
- padding: 18px;
- background-color: $white;
- text-transform: uppercase;
-}
-
-.settings__clear-button--red {
- border: 1px solid $monzo;
+.settings__button--red {
+ border-color: lighten($monzo, 10%);
color: $monzo;
+
+ &:active {
+ background: lighten($monzo, 55%);
+ border-color: $monzo;
+ }
+
+ &:hover {
+ border-color: $monzo;
+ }
}
-.settings__clear-button--orange {
- border: 1px solid rgba(247, 134, 28, 1);
- color: rgba(247, 134, 28, 1);
+.settings__button--orange {
+ border-color: lighten($ecstasy, 20%);
+ color: $ecstasy;
+
+ &:active {
+ background: lighten($ecstasy, 40%);
+ border-color: $ecstasy;
+ }
+
+ &:hover {
+ border-color: $ecstasy;
+ }
}
.settings__info-logo-wrapper {
diff --git a/ui/app/css/itcss/generic/index.scss b/ui/app/css/itcss/generic/index.scss
index 08e639d74..92321394b 100644
--- a/ui/app/css/itcss/generic/index.scss
+++ b/ui/app/css/itcss/generic/index.scss
@@ -132,7 +132,7 @@ input.large-input {
height: 55px;
font-size: 1rem;
text-transform: uppercase;
- margin-right: 1rem;
+ margin-right: 1.2rem;
border-radius: 2px;
&:last-of-type {
diff --git a/ui/app/css/itcss/settings/variables.scss b/ui/app/css/itcss/settings/variables.scss
index 640fd95b8..0031238a8 100644
--- a/ui/app/css/itcss/settings/variables.scss
+++ b/ui/app/css/itcss/settings/variables.scss
@@ -51,6 +51,8 @@ $java: #29b6af;
$wild-strawberry: #ff4a8d;
$cornflower-blue: #7057ff;
$saffron: #f6c343;
+$zumthor: #edf7ff;
+$ecstasy: #f7861c;
/*
Z-Indicies
diff --git a/ui/app/reducers/metamask.js b/ui/app/reducers/metamask.js
index e6e02d057..9cba5e83b 100644
--- a/ui/app/reducers/metamask.js
+++ b/ui/app/reducers/metamask.js
@@ -39,6 +39,7 @@ function reduceMetamask (state, action) {
maxModeOn: false,
editingTransactionId: null,
forceGasMin: null,
+ toNickname: '',
},
coinOptions: {},
useBlockie: false,
@@ -238,7 +239,8 @@ function reduceMetamask (state, action) {
return extend(metamaskState, {
send: {
...metamaskState.send,
- to: action.value,
+ to: action.value.to,
+ toNickname: action.value.nickname,
},
})
diff --git a/ui/app/send-v2.js b/ui/app/send-v2.js
index de71ce94c..620da73f8 100644
--- a/ui/app/send-v2.js
+++ b/ui/app/send-v2.js
@@ -7,7 +7,7 @@ const ethAbi = require('ethereumjs-abi')
const ethUtil = require('ethereumjs-util')
const FromDropdown = require('./components/send/from-dropdown')
-const ToAutoComplete = require('./components/send/to-autocomplete')
+const EnsInput = require('./components/ens-input')
const CurrencyDisplay = require('./components/send/currency-display')
const MemoTextArea = require('./components/send/memo-textarea')
const GasFeeDisplay = require('./components/send/gas-fee-display-v2')
@@ -253,7 +253,7 @@ SendTransactionScreen.prototype.renderFromRow = function () {
])
}
-SendTransactionScreen.prototype.handleToChange = function (to) {
+SendTransactionScreen.prototype.handleToChange = function (to, nickname = '') {
const {
updateSendTo,
updateSendErrors,
@@ -269,12 +269,12 @@ SendTransactionScreen.prototype.handleToChange = function (to) {
toError = t('fromToSame')
}
- updateSendTo(to)
+ updateSendTo(to, nickname)
updateSendErrors({ to: toError })
}
SendTransactionScreen.prototype.renderToRow = function () {
- const { toAccounts, errors, to } = this.props
+ const { toAccounts, errors, to, network } = this.props
const { toDropdownOpen } = this.state
@@ -289,7 +289,10 @@ SendTransactionScreen.prototype.renderToRow = function () {
]),
h('div.send-v2__form-field', [
- h(ToAutoComplete, {
+ h(EnsInput, {
+ name: 'address',
+ placeholder: 'Recipient Address',
+ network,
to,
accounts: Object.entries(toAccounts).map(([key, account]) => account),
dropdownOpen: toDropdownOpen,
@@ -510,13 +513,13 @@ SendTransactionScreen.prototype.renderFooter = function () {
const noErrors = !amountError && toError === null
return h('div.page-container__footer', [
- h('button.btn-cancel.page-container__footer-button', {
+ h('button.btn-secondary--lg.page-container__footer-button', {
onClick: () => {
clearSend()
goHome()
},
}, t('cancel')),
- h('button.btn-clear.page-container__footer-button', {
+ h('button.btn-primary--lg.page-container__footer-button', {
disabled: !noErrors || !gasTotal || missingTokenBalance,
onClick: event => this.onSubmit(event),
}, t('next')),
@@ -538,11 +541,11 @@ SendTransactionScreen.prototype.render = function () {
)
}
-SendTransactionScreen.prototype.addToAddressBookIfNew = function (newAddress) {
+SendTransactionScreen.prototype.addToAddressBookIfNew = function (newAddress, nickname = '') {
const { toAccounts, addToAddressBook } = this.props
if (!toAccounts.find(({ address }) => newAddress === address)) {
// TODO: nickname, i.e. addToAddressBook(recipient, nickname)
- addToAddressBook(newAddress)
+ addToAddressBook(newAddress, nickname)
}
}
@@ -603,6 +606,7 @@ SendTransactionScreen.prototype.onSubmit = function (event) {
updateTx,
selectedToken,
editingTransactionId,
+ toNickname,
errors: { amount: amountError, to: toError },
} = this.props
@@ -612,7 +616,7 @@ SendTransactionScreen.prototype.onSubmit = function (event) {
return
}
- this.addToAddressBookIfNew(to)
+ this.addToAddressBookIfNew(to, toNickname)
if (editingTransactionId) {
const editedTx = this.getEditedTx()
diff --git a/ui/app/settings.js b/ui/app/settings.js
index 105cbb40b..78ca6c94b 100644
--- a/ui/app/settings.js
+++ b/ui/app/settings.js
@@ -200,7 +200,7 @@ class Settings extends Component {
]),
h('div.settings__content-item', [
h('div.settings__content-item-col', [
- h('button.settings__clear-button', {
+ h('button.btn-primary--lg.settings__button', {
onClick (event) {
window.logStateString((err, result) => {
if (err) {
@@ -225,7 +225,7 @@ class Settings extends Component {
h('div.settings__content-item', t('revealSeedWords')),
h('div.settings__content-item', [
h('div.settings__content-item-col', [
- h('button.settings__clear-button.settings__clear-button--red', {
+ h('button.btn-primary--lg.settings__button--red', {
onClick (event) {
event.preventDefault()
revealSeedConfirmation()
@@ -245,7 +245,7 @@ class Settings extends Component {
h('div.settings__content-item', t('useOldUI')),
h('div.settings__content-item', [
h('div.settings__content-item-col', [
- h('button.settings__clear-button.settings__clear-button--orange', {
+ h('button.btn-primary--lg.settings__button--orange', {
onClick (event) {
event.preventDefault()
setFeatureFlagToBeta()
@@ -264,7 +264,7 @@ class Settings extends Component {
h('div.settings__content-item', t('resetAccount')),
h('div.settings__content-item', [
h('div.settings__content-item-col', [
- h('button.settings__clear-button.settings__clear-button--orange', {
+ h('button.btn-primary--lg.settings__button--orange', {
onClick (event) {
event.preventDefault()
showResetAccountConfirmationModal()