aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDan <danjm.com@gmail.com>2018-03-20 02:00:47 +0800
committerDan <danjm.com@gmail.com>2018-03-20 02:00:47 +0800
commitd8788af9b867cebcc702384b780cc06a06f9d33b (patch)
tree126ae3e4bfd478b75bf6a550caa40d1629db0761
parente51ba2e75c517d88f0e526eed613ef656af47293 (diff)
parent424e98f6a896df6a848a92ef318464abc505d83d (diff)
downloadtangerine-wallet-browser-d8788af9b867cebcc702384b780cc06a06f9d33b.tar
tangerine-wallet-browser-d8788af9b867cebcc702384b780cc06a06f9d33b.tar.gz
tangerine-wallet-browser-d8788af9b867cebcc702384b780cc06a06f9d33b.tar.bz2
tangerine-wallet-browser-d8788af9b867cebcc702384b780cc06a06f9d33b.tar.lz
tangerine-wallet-browser-d8788af9b867cebcc702384b780cc06a06f9d33b.tar.xz
tangerine-wallet-browser-d8788af9b867cebcc702384b780cc06a06f9d33b.tar.zst
tangerine-wallet-browser-d8788af9b867cebcc702384b780cc06a06f9d33b.zip
Merge branch 'master' into retry-tx-refractor
-rw-r--r--app/_locales/en/messages.json210
-rw-r--r--app/_locales/fr/messages.json2
-rw-r--r--app/_locales/ja/messages.json605
-rw-r--r--app/_locales/ko/messages.json609
-rw-r--r--app/_locales/vi/messages.json609
-rw-r--r--app/_locales/zh_CN/messages.json605
-rw-r--r--app/images/arrow-right.svg16
-rw-r--r--app/scripts/contentscript.js17
-rw-r--r--docs/add-to-chrome.md18
-rw-r--r--mascara/src/app/first-time/backup-phrase-screen.js52
-rw-r--r--mascara/src/app/first-time/import-seed-phrase-screen.js129
-rw-r--r--mascara/src/app/first-time/index.css99
-rw-r--r--mascara/src/app/first-time/notice-screen.js46
-rw-r--r--mascara/src/app/first-time/unique-image-screen.js34
-rw-r--r--package-lock.json10
-rw-r--r--test/integration/lib/send-new-ui.js4
-rw-r--r--test/lib/react-trigger-change.js161
-rw-r--r--test/unit/components/binary-renderer-test.js2
-rw-r--r--test/unit/components/bn-as-decimal-input-test.js2
-rw-r--r--test/unit/nameForAccount_test.js2
-rw-r--r--ui/app/account-detail.js117
-rw-r--r--ui/app/app.js14
-rw-r--r--ui/app/components/balance.js89
-rw-r--r--ui/app/components/binary-renderer.js46
-rw-r--r--ui/app/components/currency-input.js20
-rw-r--r--ui/app/components/dropdowns/account-options-dropdown.js29
-rw-r--r--ui/app/components/dropdowns/account-selection-dropdown.js29
-rw-r--r--ui/app/components/dropdowns/index.js6
-rw-r--r--ui/app/components/mini-account-panel.js74
-rw-r--r--ui/app/components/modals/deposit-ether-modal.js2
-rw-r--r--ui/app/components/pending-personal-msg-details.js60
-rw-r--r--ui/app/components/pending-tx/confirm-deploy-contract.js587
-rw-r--r--ui/app/components/pending-tx/confirm-send-ether.js329
-rw-r--r--ui/app/components/pending-tx/confirm-send-token.js134
-rw-r--r--ui/app/components/pending-typed-msg-details.js60
-rw-r--r--ui/app/components/pending-typed-msg.js47
-rw-r--r--ui/app/components/range-slider.js58
-rw-r--r--ui/app/components/send-token/index.js440
-rw-r--r--ui/app/components/send/currency-toggle.js44
-rw-r--r--ui/app/components/send/eth-fee-display.js37
-rw-r--r--ui/app/components/send/gas-fee-display.js62
-rw-r--r--ui/app/components/send/usd-fee-display.js35
-rw-r--r--ui/app/components/sender-to-recipient.js45
-rw-r--r--ui/app/components/template.js18
-rw-r--r--ui/app/components/transaction-list-item-icon.js68
-rw-r--r--ui/app/components/transaction-list-item.js239
-rw-r--r--ui/app/components/transaction-list.js87
-rw-r--r--ui/app/components/typed-message-renderer.js42
-rw-r--r--ui/app/components/wallet-content-display.js56
-rw-r--r--ui/app/css/itcss/components/buttons.scss12
-rw-r--r--ui/app/css/itcss/components/confirm.scss32
-rw-r--r--ui/app/css/itcss/components/index.scss1
-rw-r--r--ui/app/css/itcss/components/sender-to-recipient.scss58
-rw-r--r--ui/app/css/itcss/generic/index.scss17
-rw-r--r--ui/app/info.js154
-rw-r--r--ui/app/send.js547
-rw-r--r--ui/app/template.js30
-rw-r--r--ui/app/token-tracker.js0
-rw-r--r--ui/lib/contract-namer.js33
59 files changed, 3744 insertions, 3246 deletions
diff --git a/app/_locales/en/messages.json b/app/_locales/en/messages.json
index 1ca31427d..35a360c84 100644
--- a/app/_locales/en/messages.json
+++ b/app/_locales/en/messages.json
@@ -14,9 +14,15 @@
"address": {
"message": "Address"
},
+ "addCustomToken": {
+ "message": "Add custom token"
+ },
"addToken": {
"message": "Add Token"
},
+ "addTokens": {
+ "message": "Add Tokens"
+ },
"amount": {
"message": "Amount"
},
@@ -34,6 +40,9 @@
"attemptingConnect": {
"message": "Attempting to connect to blockchain."
},
+ "attributions": {
+ "message": "Attributions"
+ },
"available": {
"message": "Available"
},
@@ -43,6 +52,9 @@
"balance": {
"message": "Balance:"
},
+ "balances": {
+ "message": "Your balances"
+ },
"balanceIsInsufficientGas": {
"message": "Insufficient balance for current gas total"
},
@@ -53,9 +65,15 @@
"message": "must be greater than or equal to $1 and less than or equal to $2.",
"description": "helper for inputting hex as decimal input"
},
+ "blockiesIdenticon": {
+ "message": "Use Blockies Identicon"
+ },
"borrowDharma": {
"message": "Borrow With Dharma (Beta)"
},
+ "builtInCalifornia": {
+ "message": "MetaMask is designed and built in California."
+ },
"buy": {
"message": "Buy"
},
@@ -68,6 +86,9 @@
"cancel": {
"message": "Cancel"
},
+ "classicInterface": {
+ "message": "Use classic interface"
+ },
"clickCopy": {
"message": "Click to Copy"
},
@@ -83,6 +104,9 @@
"confirmTransaction": {
"message": "Confirm Transaction"
},
+ "continue": {
+ "message": "Continue"
+ },
"continueToCoinbase": {
"message": "Continue to Coinbase"
},
@@ -101,6 +125,9 @@
"copiedExclamation": {
"message": "Copied!"
},
+ "copiedSafe": {
+ "message": "I've copied it somewhere safe"
+ },
"copy": {
"message": "Copy"
},
@@ -126,6 +153,12 @@
"message": "Crypto",
"description": "Exchange type (cryptocurrencies)"
},
+ "currentConversion": {
+ "message": "Current Conversion"
+ },
+ "currentNetwork": {
+ "message": "Current Network"
+ },
"customGas": {
"message": "Customize Gas"
},
@@ -135,6 +168,12 @@
"customRPC": {
"message": "Custom RPC"
},
+ "decimalsMustZerotoTen": {
+ "message": "Decimals must be at least 0, and not over 36."
+ },
+ "decimal": {
+ "message": "Decimals of Precision"
+ },
"defaultNetwork": {
"message": "The default network for Ether transactions is Main Net."
},
@@ -184,18 +223,27 @@
"done": {
"message": "Done"
},
+ "downloadStatelogs": {
+ "message": "Download State Logs"
+ },
"edit": {
"message": "Edit"
},
"editAccountName": {
"message": "Edit Account Name"
},
+ "emailUs": {
+ "message": "Email us!"
+ },
"encryptNewDen": {
"message": "Encrypt your new DEN"
},
"enterPassword": {
"message": "Enter password"
},
+ "enterPasswordConfirm": {
+ "message": "Enter your password to confirm"
+ },
"etherscanView": {
"message": "View account on Etherscan"
},
@@ -219,9 +267,15 @@
"message": "File import not working? Click here!",
"description": "Helps user import their account from a JSON file"
},
+ "followTwitter": {
+ "message": "Follow us on Twitter"
+ },
"from": {
"message": "From"
},
+ "fromToSame": {
+ "message": "From and To address cannot be the same"
+ },
"fromShapeShift": {
"message": "From ShapeShift"
},
@@ -244,6 +298,9 @@
"gasLimitTooLow": {
"message": "Gas limit must be at least 21000"
},
+ "generatingSeed": {
+ "message": "Generating Seed..."
+ },
"gasPrice": {
"message": "Gas Price (GWEI)"
},
@@ -268,6 +325,9 @@
"message": "here",
"description": "as in -click here- for more information (goes with troubleTokenBalances)"
},
+ "hereList": {
+ "message": "Here's a list!!!!"
+ },
"hide": {
"message": "Hide"
},
@@ -280,6 +340,9 @@
"howToDeposit": {
"message": "How would you like to deposit Ether?"
},
+ "holdEther": {
+ "message": "It allows you to hold ether & tokens, and serves as your bridge to decentralized applications."
+ },
"import": {
"message": "Import",
"description": "Button to import an account from a selected file"
@@ -287,6 +350,9 @@
"importAccount": {
"message": "Import Account"
},
+ "importAccountMsg": {
+ "message":" Imported accounts will not be associated with your originally created MetaMask account seedphrase. Learn more about imported accounts "
+ },
"importAnAccount": {
"message": "Import an account"
},
@@ -300,9 +366,18 @@
"infoHelp": {
"message": "Info & Help"
},
+ "insufficientFunds": {
+ "message": "Insufficient funds."
+ },
+ "insufficientTokens": {
+ "message": "Insufficient tokens."
+ },
"invalidAddress": {
"message": "Invalid address"
},
+ "invalidAddressRecipient": {
+ "message": "Recipient address is invalid"
+ },
"invalidGasParams": {
"message": "Invalid Gas Parameters"
},
@@ -312,6 +387,12 @@
"invalidRequest": {
"message": "Invalid Request"
},
+ "invalidRPC": {
+ "message": "Invalid RPC URI"
+ },
+ "jsonFail": {
+ "message": "Something went wrong. Please make sure your JSON file is properly formatted."
+ },
"jsonFile": {
"message": "JSON File",
"description": "format for importing an account"
@@ -319,10 +400,16 @@
"kovan": {
"message": "Kovan Test Network"
},
+ "knowledgeDataBase": {
+ "message": "Visit our Knowledge Base"
+ },
"lessThanMax": {
"message": "must be less than or equal to $1.",
"description": "helper for inputting hex as decimal input"
},
+ "likeToAddTokens": {
+ "message": "Would you like to add these tokens?"
+ },
"limit": {
"message": "Limit"
},
@@ -335,24 +422,36 @@
"localhost": {
"message": "Localhost 8545"
},
+ "login": {
+ "message": "Log In"
+ },
"logout": {
"message": "Log out"
},
"loose": {
"message": "Loose"
},
+ "loweCaseWords": {
+ "message": "seed words only have lowercase characters"
+ },
"mainnet": {
"message": "Main Ethereum Network"
},
"message": {
"message": "Message"
},
+ "metamaskDescription": {
+ "message": "MetaMask is a secure identity vault for Ethereum."
+ },
"min": {
"message": "Minimum"
},
"myAccounts": {
"message": "My Accounts"
},
+ "mustSelectOne": {
+ "message": "Must select at least 1 token."
+ },
"needEtherInWallet": {
"message": "To interact with decentralized applications using MetaMask, you’ll need Ether in your wallet."
},
@@ -364,6 +463,9 @@
"message": "You must enter a password for the selected file.",
"description": "Password and file needed to import an account"
},
+ "negativeETH": {
+ "message": "Can not send negative amounts of ETH."
+ },
"networks": {
"message": "Networks"
},
@@ -383,6 +485,9 @@
"newRecipient": {
"message": "New Recipient"
},
+ "newRPC": {
+ "message": "New RPC URL"
+ },
"next": {
"message": "Next"
},
@@ -411,6 +516,9 @@
"message": "or",
"description": "choice between creating or importing a new account"
},
+ "passwordCorrect": {
+ "message": "Please make sure your password is correct."
+ },
"passwordMismatch": {
"message": "passwords don't match",
"description": "in password creation process, the two new password fields did not match"
@@ -426,9 +534,15 @@
"pasteSeed": {
"message": "Paste your seed phrase here!"
},
+ "personalAddressDetected": {
+ "message": "Personal address detected. Input the token contract address."
+ },
"pleaseReviewTransaction": {
"message": "Please review your transaction."
},
+ "privacyMsg": {
+ "message": "Privacy Policy"
+ },
"privateKey": {
"message": "Private Key",
"description": "select this type of file to use to import an account"
@@ -448,6 +562,9 @@
"readMore": {
"message": "Read more here."
},
+ "readMore2": {
+ "message": "Read more."
+ },
"receive": {
"message": "Receive"
},
@@ -460,12 +577,24 @@
"rejected": {
"message": "Rejected"
},
+ "resetAccount": {
+ "message": "Reset Account"
+ },
+ "restoreFromSeed": {
+ "message": "Restore from seed phrase"
+ },
"required": {
"message": "Required"
},
"retryWithMoreGas": {
"message": "Retry with a higher gas price here"
},
+ "revealSeedWords": {
+ "message": "Reveal Seed Words"
+ },
+ "revealSeedWordsWarning": {
+ "message": "Do not recover your seed words in a public place! These words can be used to steal all your accounts."
+ },
"revert": {
"message": "Revert"
},
@@ -486,12 +615,36 @@
"message": "Save as File",
"description": "Account export process"
},
+ "saveSeedAsFile": {
+ "message": "Save Seed Words As File"
+ },
+ "search": {
+ "message": "Search"
+ },
+ "secretPhrase": {
+ "message": "Enter your secret twelve word phrase here to restore your vault."
+ },
+ "seedPhraseReq": {
+ "message": "seed phrases are 12 words long"
+ },
+ "select": {
+ "message": "Select"
+ },
+ "selectCurrency": {
+ "message": "Select Currency"
+ },
"selectService": {
"message": "Select Service"
},
+ "selectType": {
+ "message": "Select Type"
+ },
"send": {
"message": "Send"
},
+ "sendETH": {
+ "message": "Send ETH"
+ },
"sendTokens": {
"message": "Send Tokens"
},
@@ -525,15 +678,33 @@
"sigRequested": {
"message": "Signature Requested"
},
+ "spaceBetween": {
+ "message": "there can only be a space between words"
+ },
"status": {
"message": "Status"
},
+ "stateLogs": {
+ "message": "State Logs"
+ },
+ "stateLogsDescription": {
+ "message": "State logs contain your public account addresses and sent transactions."
+ },
"submit": {
"message": "Submit"
},
+ "supportCenter": {
+ "message": "Visit our Support Center"
+ },
+ "symbolBetweenZeroTen": {
+ "message": "Symbol must be between 0 and 10 characters."
+ },
"takesTooLong": {
"message": "Taking too long?"
},
+ "terms": {
+ "message": "Terms of Use"
+ },
"testFaucet": {
"message": "Test Faucet"
},
@@ -544,12 +715,30 @@
"message": "$1 to ETH via ShapeShift",
"description": "system will fill in deposit type in start of message"
},
+ "tokenAddress": {
+ "message": "Token Address"
+ },
+ "tokenAlreadyAdded": {
+ "message": "Token has already been added."
+ },
"tokenBalance": {
"message": "Your Token Balance is:"
},
+ "tokenSelection": {
+ "message": "Search for tokens or select from our list of popular tokens."
+ },
+ "tokenSymbol": {
+ "message": "Token Symbol"
+ },
+ "tokenWarning1": {
+ "message": "Keep track of the tokens you’ve bought with your MetaMask account. If you bought tokens using a different account, those tokens will not appear here."
+ },
"total": {
"message": "Total"
},
+ "transactions": {
+ "message": "transactions"
+ },
"transactionMemo": {
"message": "Transaction memo (optional)"
},
@@ -563,6 +752,9 @@
"message": "We had trouble loading your token balances. You can view them ",
"description": "Followed by a link (here) to view token balances"
},
+ "twelveWords": {
+ "message": "These 12 words are the only way to restore your MetaMask accounts.\nSave them somewhere safe and secret."
+ },
"typePassword": {
"message": "Type Your Password"
},
@@ -584,6 +776,9 @@
"unknownNetworkId": {
"message": "Unknown network ID"
},
+ "uriErrorMsg": {
+ "message": "URIs require the appropriate HTTP/HTTPS prefix."
+ },
"usaOnly": {
"message": "USA only",
"description": "Using this exchange is limited to people inside the USA"
@@ -591,12 +786,27 @@
"usedByClients": {
"message": "Used by a variety of different clients"
},
+ "useOldUI": {
+ "message": "Use old UI"
+ },
+ "validFileImport": {
+ "message": "You must select a valid file to import."
+ },
+ "vaultCreated": {
+ "message": "Vault Created"
+ },
"viewAccount": {
"message": "View Account"
},
+ "visitWebSite": {
+ "message": "Visit our web site"
+ },
"warning": {
"message": "Warning"
},
+ "welcomeBeta": {
+ "message": "Welcome to MetaMask Beta"
+ },
"whatsThis": {
"message": "What's this?"
},
diff --git a/app/_locales/fr/messages.json b/app/_locales/fr/messages.json
index 7edbd41ab..da2cfe4f8 100644
--- a/app/_locales/fr/messages.json
+++ b/app/_locales/fr/messages.json
@@ -149,7 +149,7 @@
},
"depositCoin": {
"message": "Déposez votre $1 à l'adresse ci-dessous",
- "description": "Indique à l'utilisateur quelle monnaie ils a choisi de déposer avec shapeshift"
+ "description": "Indique à l'utilisateur quelle monnaie il a choisi de déposer avec shapeshift"
},
"depositEth": {
"message": "Dépôt Eth"
diff --git a/app/_locales/ja/messages.json b/app/_locales/ja/messages.json
index f15d06ff4..bab8d3b95 100644
--- a/app/_locales/ja/messages.json
+++ b/app/_locales/ja/messages.json
@@ -1,10 +1,609 @@
{
+ "accept": {
+ "message": "承認"
+ },
+ "account": {
+ "message": "アカウント"
+ },
+ "accountDetails": {
+ "message": "アカウント詳細"
+ },
+ "accountName": {
+ "message": "アカウント名"
+ },
+ "address": {
+ "message": "アドレス"
+ },
+ "addToken": {
+ "message": "トークンを追加"
+ },
+ "amount": {
+ "message": "金額"
+ },
+ "amountPlusGas": {
+ "message": "金額 + ガス"
+ },
+ "appDescription": {
+ "message": "Ethereumのブラウザ・エクステンション",
+ "description": "The description of the application"
+ },
"appName": {
"message": "MetaMask",
"description": "The name of the application"
},
- "appDescription": {
- "message": "EthereumのID管理",
- "description": "The description of the application"
+ "attemptingConnect": {
+ "message": "ブロックチェーンに接続中"
+ },
+ "available": {
+ "message": "有効"
+ },
+ "back": {
+ "message": "戻る"
+ },
+ "balance": {
+ "message": "残高:"
+ },
+ "balanceIsInsufficientGas": {
+ "message": "現在のガス総量に対して残高が不足しています"
+ },
+ "beta": {
+ "message": "ベータ版"
+ },
+ "betweenMinAndMax": {
+ "message": " $1以上 $2以下にして下さい。",
+ "description": "helper for inputting hex as decimal input"
+ },
+ "borrowDharma": {
+ "message": "Dharmaで借りる(ベータ版)"
+ },
+ "buy": {
+ "message": "購入"
+ },
+ "buyCoinbase": {
+ "message": "Coinbaseで購入"
+ },
+ "buyCoinbaseExplainer": {
+ "message": "Coinbaseは、世界で最もポピュラーなBitcoin、Ethereum、そしてLitecoinの取引所です。"
+ },
+ "cancel": {
+ "message": "キャンセル"
+ },
+ "clickCopy": {
+ "message": "クリックしてコピー"
+ },
+ "confirm": {
+ "message": "確認"
+ },
+ "confirmContract": {
+ "message": "コントラクトの確認"
+ },
+ "confirmPassword": {
+ "message": "パスワードの確認"
+ },
+ "confirmTransaction": {
+ "message": "トランザクションの確認"
+ },
+ "continueToCoinbase": {
+ "message": "Coinbaseで続行"
+ },
+ "contractDeployment": {
+ "message": "コントラクトのデプロイ"
+ },
+ "conversionProgress": {
+ "message": "変換中"
+ },
+ "copiedButton": {
+ "message": "コピー完了"
+ },
+ "copiedClipboard": {
+ "message": "クリップボードへコピー済み"
+ },
+ "copiedExclamation": {
+ "message": "コピー完了!"
+ },
+ "copy": {
+ "message": "コピー"
+ },
+ "copyToClipboard": {
+ "message": "クリップボードへコピー"
+ },
+ "copyButton": {
+ "message": " コピー "
+ },
+ "copyPrivateKey": {
+ "message": "これはあなたの秘密鍵です(クリックでコピー)"
+ },
+ "create": {
+ "message": "作成"
+ },
+ "createAccount": {
+ "message": "アカウント作成"
+ },
+ "createDen": {
+ "message": "作成"
+ },
+ "crypto": {
+ "message": "暗号通貨",
+ "description": "Exchange type (cryptocurrencies)"
+ },
+ "customGas": {
+ "message": "ガスのカスタマイズ"
+ },
+ "customize": {
+ "message": "カスタマイズ"
+ },
+ "customRPC": {
+ "message": "カスタムRPC"
+ },
+ "defaultNetwork": {
+ "message": "Etherトランザクションのデフォルトのネットワークはメインネットです。"
+ },
+ "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にトレードしてダイレクトにメタマスクウォレットへのデポジットが可能です。アカウント作成は不要。"
+ },
+ "details": {
+ "message": "詳細"
+ },
+ "directDeposit": {
+ "message": "ダイレクトデポジット"
+ },
+ "directDepositEther": {
+ "message": "Etherをダイレクトデポジット"
+ },
+ "directDepositEtherExplainer": {
+ "message": "あなたがEtherをすでにお持ちなら、ダイレクトデポジットは新しいウォレットにEtherを入手する最も迅速な方法です。"
+ },
+ "done": {
+ "message": "完了"
+ },
+ "edit": {
+ "message": "編集"
+ },
+ "editAccountName": {
+ "message": "アカウント名を編集"
+ },
+ "encryptNewDen": {
+ "message": "新しいDENを暗号化する"
+ },
+ "enterPassword": {
+ "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"
+ },
+ "from": {
+ "message": "送信元"
+ },
+ "fromShapeShift": {
+ "message": "ShapeShiftから"
+ },
+ "gas": {
+ "message": "ガス",
+ "description": "Short indication of gas cost"
+ },
+ "gasFee": {
+ "message": "ガス料金"
+ },
+ "gasLimit": {
+ "message": "ガスリミット"
+ },
+ "gasLimitCalculation": {
+ "message": "ネットワークの成功率を基にして、ガスリミットを提案しています。"
+ },
+ "gasLimitRequired": {
+ "message": "必要ガスリミット"
+ },
+ "gasLimitTooLow": {
+ "message": "ガスリミットは最低21000です。"
+ },
+ "gasPrice": {
+ "message": "ガスプライス (GWEI)"
+ },
+ "gasPriceCalculation": {
+ "message": "ネットワークの成功率を基にして、ガスプライスを提案しています。"
+ },
+ "gasPriceRequired": {
+ "message": "必要ガスプライス"
+ },
+ "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)"
+ },
+ "hide": {
+ "message": "隠す"
+ },
+ "hideToken": {
+ "message": "トークンを隠す"
+ },
+ "hideTokenPrompt": {
+ "message": "トークンを隠しますか??"
+ },
+ "howToDeposit": {
+ "message": "どのように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": "インフォメーションとヘルプ"
+ },
+ "invalidAddress": {
+ "message": "アドレスが無効です。"
+ },
+ "invalidGasParams": {
+ "message": "ガスのパラメーターが無効です。"
+ },
+ "invalidInput": {
+ "message": "インプットが無効です。"
+ },
+ "invalidRequest": {
+ "message": "リクエストが無効です。"
+ },
+ "jsonFile": {
+ "message": "JSONファイル",
+ "description": "format for importing an account"
+ },
+ "kovan": {
+ "message": "Kovanテストネットワーク"
+ },
+ "lessThanMax": {
+ "message": " $1以下にして下さい。",
+ "description": "helper for inputting hex as decimal input"
+ },
+ "limit": {
+ "message": "リミット"
+ },
+ "loading": {
+ "message": "ロード中..."
+ },
+ "loadingTokens": {
+ "message": "トークンをロード中..."
+ },
+ "localhost": {
+ "message": "Localhost 8545"
+ },
+ "logout": {
+ "message": "ログアウト"
+ },
+ "loose": {
+ "message": "外部秘密鍵"
+ },
+ "mainnet": {
+ "message": "Ethereumメインネットワーク"
+ },
+ "message": {
+ "message": "メッセージ"
+ },
+ "min": {
+ "message": "ミニマム"
+ },
+ "myAccounts": {
+ "message": "マイアカウント"
+ },
+ "needEtherInWallet": {
+ "message": "MetaMaskを使って分散型アプリケーションと対話するためには、あなたのウォレットに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": "新規受取人"
+ },
+ "next": {
+ "message": "次へ"
+ },
+ "noAddressForName": {
+ "message": "この名前にはアドレスが設定されていません。"
+ },
+ "noDeposits": {
+ "message": "デポジットがありません。"
+ },
+ "noTransactionHistory": {
+ "message": "トランザクション履歴がありません。"
+ },
+ "noTransactions": {
+ "message": "トランザクションがありません。"
+ },
+ "notStarted": {
+ "message": "スタートしていません。"
+ },
+ "oldUI": {
+ "message": "旧UI"
+ },
+ "oldUIMessage": {
+ "message": "旧UIを表示しています。右上のドロップダウンメニューのオプションより、新UIへ切り替えが可能です。"
+ },
+ "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": "シードをここにペーストして下さい!"
+ },
+ "pleaseReviewTransaction": {
+ "message": "トランザクションをレビューして下さい。"
+ },
+ "privateKey": {
+ "message": "秘密鍵",
+ "description": "select this type of file to use to import an account"
+ },
+ "privateKeyWarning": {
+ "message": "警告: この鍵は絶対に公開しないで下さい。公開すると、誰でもあなたのアカウント内の資産を盗むことができてしまいます。"
+ },
+ "privateNetwork": {
+ "message": "プライベート・ネットワーク"
+ },
+ "qrCode": {
+ "message": "QRコードを表示"
+ },
+ "readdToken": {
+ "message": "アカウントのオプションメニューから「トークンを追加」すれば、将来このトークンを追加し直すことができます。"
+ },
+ "readMore": {
+ "message": "もっと読む"
+ },
+ "receive": {
+ "message": "受け取る"
+ },
+ "recipientAddress": {
+ "message": "受取人アドレス"
+ },
+ "refundAddress": {
+ "message": "あなたの返金先アドレス"
+ },
+ "rejected": {
+ "message": "拒否されました"
+ },
+ "required": {
+ "message": "必要です。"
+ },
+ "retryWithMoreGas": {
+ "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"
+ },
+ "selectService": {
+ "message": "サービスを選択"
+ },
+ "send": {
+ "message": "送信"
+ },
+ "sendTokens": {
+ "message": "トークンを送る"
+ },
+ "sendTokensAnywhere": {
+ "message": "イーサリアムのアカウントを持っている人にトークンを送る"
+ },
+ "settings": {
+ "message": "設定"
+ },
+ "shapeshiftBuy": {
+ "message": "Shapeshiftで買う"
+ },
+ "showPrivateKeys": {
+ "message": "秘密鍵を表示"
+ },
+ "showQRCode": {
+ "message": "QRコードを表示"
+ },
+ "sign": {
+ "message": "署名"
+ },
+ "signMessage": {
+ "message": "メッセージに署名"
+ },
+ "signNotice": {
+ "message": "このメッセージへの署名は危険となる可能性があります。\n完全に信頼するサイトからのメッセージのみ、\nあなたのアカウントで署名して下さい。今後のバージョンでは、\nこの危険なメソッドは削除される予定です。"
+ },
+ "sigRequest": {
+ "message": "署名リクエスト"
+ },
+ "sigRequested": {
+ "message": "署名がリクエストされました"
+ },
+ "status": {
+ "message": "ステータス"
+ },
+ "submit": {
+ "message": "送信"
+ },
+ "takesTooLong": {
+ "message": "長くかかりすぎていますか?"
+ },
+ "testFaucet": {
+ "message": "Faucetをテスト"
+ },
+ "to": {
+ "message": "宛先"
+ },
+ "toETHviaShapeShift": {
+ "message": "ShapeShiftで $1をETHにする",
+ "description": "system will fill in deposit type in start of message"
+ },
+ "tokenBalance": {
+ "message": "あなたのトークン残高:"
+ },
+ "total": {
+ "message": "合計"
+ },
+ "transactionMemo": {
+ "message": "トランザクションメモ (オプション)"
+ },
+ "transactionNumber": {
+ "message": "トランザクション番号"
+ },
+ "transfers": {
+ "message": "トランスファー"
+ },
+ "troubleTokenBalances": {
+ "message": "トークン残高を取得できません。こちらでご確認ください。",
+ "description": "Followed by a link (here) to view token balances"
+ },
+ "typePassword": {
+ "message": "パスワードタイプ"
+ },
+ "uiWelcome": {
+ "message": "新UIへようこそ!(ベータ版)"
+ },
+ "uiWelcomeMessage": {
+ "message": "現在Metamaskの新しいUIをお使いになっています。トークン送信など、新たな機能を試してみましょう!何か問題があればご報告ください。"
+ },
+ "unavailable": {
+ "message": "有効ではありません。"
+ },
+ "unknown": {
+ "message": "不明"
+ },
+ "unknownNetwork": {
+ "message": "不明なプライベートネットワーク"
+ },
+ "unknownNetworkId": {
+ "message": "不明なネットワークID"
+ },
+ "usaOnly": {
+ "message": "米国居住者のみ",
+ "description": "Using this exchange is limited to people inside the USA"
+ },
+ "usedByClients": {
+ "message": "様々なクライアントによって使用されています。"
+ },
+ "viewAccount": {
+ "message": "アカウントを見る"
+ },
+ "warning": {
+ "message": "警告"
+ },
+ "whatsThis": {
+ "message": "これは何でしょう?"
+ },
+ "yourSigRequested": {
+ "message": "あなたの署名がリクエストされています。"
+ },
+ "youSign": {
+ "message": "署名しています。"
}
}
diff --git a/app/_locales/ko/messages.json b/app/_locales/ko/messages.json
index c58af4b80..d3801c4f5 100644
--- a/app/_locales/ko/messages.json
+++ b/app/_locales/ko/messages.json
@@ -1,10 +1,609 @@
{
- "appName": {
- "message": "MetaMask",
- "description": "The name of the application"
+ "accept": {
+ "message": "수락"
+ },
+ "account": {
+ "message": "계좌"
+ },
+ "accountDetails": {
+ "message": "계좌 상세보기"
+ },
+ "accountName": {
+ "message": "계좌 이름"
+ },
+ "address": {
+ "message": "주소"
+ },
+ "addToken": {
+ "message": "토큰 추가"
+ },
+ "amount": {
+ "message": "금액"
+ },
+ "amountPlusGas": {
+ "message": "금액 + 가스"
},
"appDescription": {
- "message": "이더리움 계좌 관리",
- "description": "The description of the application"
+ "message": "이더리움 브라우저 확장 프로그램",
+ "description": "어플리케이션 내용"
+ },
+ "appName": {
+ "message": "메타마스크",
+ "description": "어플리케이션 이름"
+ },
+ "attemptingConnect": {
+ "message": "블록체인에 접속 시도 중입니다."
+ },
+ "available": {
+ "message": "사용 가능한"
+ },
+ "back": {
+ "message": "뒤로"
+ },
+ "balance": {
+ "message": "잔액:"
+ },
+ "balanceIsInsufficientGas": {
+ "message": "가스가 충분하지 않습니다."
+ },
+ "beta": {
+ "message": "베타"
+ },
+ "betweenMinAndMax": {
+ "message": "$1 이상 $2 이하여야 합니다.",
+ "description": "helper for inputting hex as decimal input"
+ },
+ "borrowDharma": {
+ "message": "Dharma에서 빌리기(베타)"
+ },
+ "buy": {
+ "message": "구매"
+ },
+ "buyCoinbase": {
+ "message": "코인베이스에서 구매"
+ },
+ "buyCoinbaseExplainer": {
+ "message": "코인베이스에서 비트코인, 이더리움, 라이트코인을 구매하실 수 있습니다."
+ },
+ "cancel": {
+ "message": "취소"
+ },
+ "clickCopy": {
+ "message": "클릭하여 복사"
+ },
+ "confirm": {
+ "message": "승인"
+ },
+ "confirmContract": {
+ "message": "컨트랙트 승인"
+ },
+ "confirmPassword": {
+ "message": "패스워드 승인"
+ },
+ "confirmTransaction": {
+ "message": "트랜잭션 승인"
+ },
+ "continueToCoinbase": {
+ "message": "코인베이스로 계속하기"
+ },
+ "contractDeployment": {
+ "message": "컨트랙트 배포"
+ },
+ "conversionProgress": {
+ "message": "변환중.."
+ },
+ "copiedButton": {
+ "message": "복사되었습니다."
+ },
+ "copiedClipboard": {
+ "message": "클립보드에 복사되었습니다."
+ },
+ "copiedExclamation": {
+ "message": "복사되었습니다."
+ },
+ "copy": {
+ "message": "복사하기"
+ },
+ "copyToClipboard": {
+ "message": "클립보드에 복사"
+ },
+ "copyButton": {
+ "message": " 복사 "
+ },
+ "copyPrivateKey": {
+ "message": "비밀 키 (클릭하여 복사)"
+ },
+ "create": {
+ "message": "생성"
+ },
+ "createAccount": {
+ "message": "계좌 생성"
+ },
+ "createDen": {
+ "message": "생성"
+ },
+ "crypto": {
+ "message": "암호화폐",
+ "description": "Exchange type (cryptocurrencies)"
+ },
+ "customGas": {
+ "message": "가스 설정"
+ },
+ "customize": {
+ "message": "커스터마이즈"
+ },
+ "customRPC": {
+ "message": "커스텀 RPC"
+ },
+ "defaultNetwork": {
+ "message": "이더리움 트랜잭션의 기본 네트워크는 메인넷입니다."
+ },
+ "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": "이더 입금"
+ },
+ "depositEther": {
+ "message": "이더 입금"
+ },
+ "depositFiat": {
+ "message": "현금으로 입금하기"
+ },
+ "depositFromAccount": {
+ "message": "다른 주소에서 입금하기"
+ },
+ "depositShapeShift": {
+ "message": "ShapeShift를 통해 입금하기"
+ },
+ "depositShapeShiftExplainer": {
+ "message": "다른 암호화폐를 가지고 있으면, 계좌 생성 필요없이, 거래를 하거나 메타마스크 지갑을 통해 이더를 입금할 수 있습니다."
+ },
+ "details": {
+ "message": "상세"
+ },
+ "directDeposit": {
+ "message": "즉시 입금"
+ },
+ "directDepositEther": {
+ "message": "이더 즉시 입금"
+ },
+ "directDepositEtherExplainer": {
+ "message": "이더를 이미 보유하고 있다면, 직접 입금을 통해 이더를 즉시 입금하실 수 있습니다."
+ },
+ "done": {
+ "message": "완료"
+ },
+ "edit": {
+ "message": "수정"
+ },
+ "editAccountName": {
+ "message": "계좌명 수정"
+ },
+ "encryptNewDen": {
+ "message": "새 DEN 암호화"
+ },
+ "enterPassword": {
+ "message": "패스워드를 입력해주세요."
+ },
+ "etherscanView": {
+ "message": "이더스캔에서 계좌보기"
+ },
+ "exchangeRate": {
+ "message": "환율"
+ },
+ "exportPrivateKey": {
+ "message": "비밀키 내보내기"
+ },
+ "exportPrivateKeyWarning": {
+ "message": "Export private keys at your own risk."
+ },
+ "failed": {
+ "message": "실패"
+ },
+ "fiat": {
+ "message": "FIAT",
+ "description": "Exchange type"
+ },
+ "fileImportFail": {
+ "message": "파일을 가져올 수 없나요? 여기를 클릭해주세요!",
+ "description": "Helps user import their account from a JSON file"
+ },
+ "from": {
+ "message": "보내는 사람"
+ },
+ "fromShapeShift": {
+ "message": "ShapeShift로 부터"
+ },
+ "gas": {
+ "message": "가스",
+ "description": "Short indication of gas cost"
+ },
+ "gasFee": {
+ "message": "가스 수수료"
+ },
+ "gasLimit": {
+ "message": "가스 리밋"
+ },
+ "gasLimitCalculation": {
+ "message": "네트워크 성공률을 기반으로 적합한 가스 리밋을 계산합니다."
+ },
+ "gasLimitRequired": {
+ "message": "가스 리밋이 필요합니다."
+ },
+ "gasLimitTooLow": {
+ "message": "가스 리밋은 21000 이상이여야 합니다."
+ },
+ "gasPrice": {
+ "message": "가스 가격 (GWEI)"
+ },
+ "gasPriceCalculation": {
+ "message": "네트워크 성공률을 기반으로 적합한 가스 가격을 계산합니다."
+ },
+ "gasPriceRequired": {
+ "message": "가스 가격이 필요합니다."
+ },
+ "getEther": {
+ "message": "이더 얻기"
+ },
+ "getEtherFromFaucet": {
+ "message": "faucet에서 $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)"
+ },
+ "hide": {
+ "message": "숨기기"
+ },
+ "hideToken": {
+ "message": "토큰 숨기기"
+ },
+ "hideTokenPrompt": {
+ "message": "토큰 숨기기?"
+ },
+ "howToDeposit": {
+ "message": "어떤 방법으로 이더를 입금하시겠습니까?"
+ },
+ "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": "정보 및 도움말"
+ },
+ "invalidAddress": {
+ "message": "유효하지 않은 주소"
+ },
+ "invalidGasParams": {
+ "message": "유효하지 않은 가스 입력값"
+ },
+ "invalidInput": {
+ "message": "유효하지 않은 입력값"
+ },
+ "invalidRequest": {
+ "message": "유효하지 않은 요청"
+ },
+ "jsonFile": {
+ "message": "JSON 파일",
+ "description": "format for importing an account"
+ },
+ "kovan": {
+ "message": "Kovan 테스트넷"
+ },
+ "lessThanMax": {
+ "message": "$1 이하여야합니다.",
+ "description": "helper for inputting hex as decimal input"
+ },
+ "limit": {
+ "message": "리밋"
+ },
+ "loading": {
+ "message": "로딩중..."
+ },
+ "loadingTokens": {
+ "message": "토큰 로딩중..."
+ },
+ "localhost": {
+ "message": "로컬호스트 8545"
+ },
+ "logout": {
+ "message": "로그아웃"
+ },
+ "loose": {
+ "message": "외부 비밀키"
+ },
+ "mainnet": {
+ "message": "이더리움 메인넷"
+ },
+ "message": {
+ "message": "메시지"
+ },
+ "min": {
+ "message": "최소"
+ },
+ "myAccounts": {
+ "message": "내 계좌"
+ },
+ "needEtherInWallet": {
+ "message": "dApp을 이용하기 위해서는 지갑에 이더가 있어야 합니다."
+ },
+ "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": "받는 사람"
+ },
+ "next": {
+ "message": "다음"
+ },
+ "noAddressForName": {
+ "message": "이 이름에는 주소가 설정되어 있지 않습니다."
+ },
+ "noDeposits": {
+ "message": "입금이 없습니다."
+ },
+ "noTransactionHistory": {
+ "message": "트랜잭션 기록이 없습니다."
+ },
+ "noTransactions": {
+ "message": "트랜잭션이 없습니다."
+ },
+ "notStarted": {
+ "message": "시작되지 않음."
+ },
+ "oldUI": {
+ "message": "구버전의 UI"
+ },
+ "oldUIMessage": {
+ "message": "구버전 UI로 변경하셨습니다. 우 상단 드랍다운 메뉴에서 새 UI로 변경하실 수 있습니다."
+ },
+ "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": "시드 문장들을 붙여넣어주세요."
+ },
+ "pleaseReviewTransaction": {
+ "message": "트랜잭션을 검토해주세요."
+ },
+ "privateKey": {
+ "message": "비밀키",
+ "description": "select this type of file to use to import an account"
+ },
+ "privateKeyWarning": {
+ "message": " 절대 이 키를 노출하지 마십시오. 비밀키가 노출되면 누구나 당신의 계좌에서 자산을 빼갈 수 있습니다."
+ },
+ "privateNetwork": {
+ "message": "프라이빗 네트워크"
+ },
+ "qrCode": {
+ "message": "QR 코드 보기"
+ },
+ "readdToken": {
+ "message": "옵션 메뉴에서 “토큰 추가”를 눌러서 추후에 다시 이 토큰을 추가하실 수 있습니다."
+ },
+ "readMore": {
+ "message": "더 읽기."
+ },
+ "receive": {
+ "message": "받기"
+ },
+ "recipientAddress": {
+ "message": "받는 사람 주소"
+ },
+ "refundAddress": {
+ "message": "환불받을 주소"
+ },
+ "rejected": {
+ "message": "거부되었음."
+ },
+ "required": {
+ "message": "필요함."
+ },
+ "retryWithMoreGas": {
+ "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"
+ },
+ "selectService": {
+ "message": "서비스 선택"
+ },
+ "send": {
+ "message": "전송"
+ },
+ "sendTokens": {
+ "message": "토큰 전송"
+ },
+ "sendTokensAnywhere": {
+ "message": "이더 계좌로 토큰 전송"
+ },
+ "settings": {
+ "message": "설정"
+ },
+ "shapeshiftBuy": {
+ "message": "Shapeshift를 통해서 구매하기"
+ },
+ "showPrivateKeys": {
+ "message": "비밀키 보기"
+ },
+ "showQRCode": {
+ "message": "QR코드 보기"
+ },
+ "sign": {
+ "message": "서명"
+ },
+ "signMessage": {
+ "message": "서명 메시지"
+ },
+ "signNotice": {
+ "message": "이 메시지에 대한 서명은 위험할 수 있습니다.\n 완전히 신뢰할 수 있는 사이트에서만 서명해주세요.\n 안전을 위해 추후의 버전에서는 삭제될 기능입니다. "
+ },
+ "sigRequest": {
+ "message": "서명 요청"
+ },
+ "sigRequested": {
+ "message": "서명이 요청되었습니다."
+ },
+ "status": {
+ "message": "상태"
+ },
+ "submit": {
+ "message": "제출"
+ },
+ "takesTooLong": {
+ "message": "너무 오래걸리나요?"
+ },
+ "testFaucet": {
+ "message": "Faucet 테스트"
+ },
+ "to": {
+ "message": "대상"
+ },
+ "toETHviaShapeShift": {
+ "message": "ShapeShift를 통해 $1를 ETH로 바꾸기",
+ "description": "system will fill in deposit type in start of message"
+ },
+ "tokenBalance": {
+ "message": "현재 토큰 잔액: "
+ },
+ "total": {
+ "message": "합계"
+ },
+ "transactionMemo": {
+ "message": "트랜잭션 메모 (선택사항)"
+ },
+ "transactionNumber": {
+ "message": "트랜잭션 번호"
+ },
+ "transfers": {
+ "message": "전송"
+ },
+ "troubleTokenBalances": {
+ "message": "토큰 잔액을 가져오는데에 문제가 생겼습니다. (여기)서 상세내용을 볼 수 있습니다.",
+ "description": "Followed by a link (here) to view token balances"
+ },
+ "typePassword": {
+ "message": "패스워드를 입력하세요."
+ },
+ "uiWelcome": {
+ "message": "새 UI에 오신 것을 환영합니다. (베타)"
+ },
+ "uiWelcomeMessage": {
+ "message": "새 메타마스크 UI를 사용하고 계십니다. 토큰 전송과 같은 새 기능들을 사용해보시면서 문제가 있다면 알려주세요."
+ },
+ "unavailable": {
+ "message": "유효하지 않은"
+ },
+ "unknown": {
+ "message": "알려지지 않은"
+ },
+ "unknownNetwork": {
+ "message": "알려지지 않은 프라이빗 네트워크"
+ },
+ "unknownNetworkId": {
+ "message": "알려지지 않은 네트워크 ID"
+ },
+ "usaOnly": {
+ "message": "USA 거주자 한정",
+ "description": "Using this exchange is limited to people inside the USA"
+ },
+ "usedByClients": {
+ "message": "다양한 클라이언트에서 사용되고 있습니다."
+ },
+ "viewAccount": {
+ "message": "계좌 보기"
+ },
+ "warning": {
+ "message": "경고"
+ },
+ "whatsThis": {
+ "message": "이것은 무엇인가요?"
+ },
+ "yourSigRequested": {
+ "message": "서명이 요청되고 있습니다."
+ },
+ "youSign": {
+ "message": "서명 중입니다."
}
}
diff --git a/app/_locales/vi/messages.json b/app/_locales/vi/messages.json
new file mode 100644
index 000000000..cd30de4de
--- /dev/null
+++ b/app/_locales/vi/messages.json
@@ -0,0 +1,609 @@
+{
+ "accept": {
+ "message": "Chấp nhận"
+ },
+ "account": {
+ "message": "Tài khoản"
+ },
+ "accountDetails": {
+ "message": "Chi tiết tài khoản"
+ },
+ "accountName": {
+ "message": "Tên tài khoản"
+ },
+ "addToken": {
+ "message": "Thêm mã Token"
+ },
+ "address": {
+ "message": "Địa chỉ"
+ },
+ "amount": {
+ "message": "Số lượng"
+ },
+ "amountPlusGas": {
+ "message": "Số lượng + Gas"
+ },
+ "appDescription": {
+ "description": "Mô tả phần mềm",
+ "message": "Tính năng Ethereum cho trình duyệt"
+ },
+ "appName": {
+ "description": "Tên phần mềm",
+ "message": "MetaMask"
+ },
+ "attemptingConnect": {
+ "message": "Đang kết nối đến blockchain."
+ },
+ "available": {
+ "message": "Có sẵn"
+ },
+ "back": {
+ "message": "Quay lại"
+ },
+ "balance": {
+ "message": "Số dư:"
+ },
+ "balanceIsInsufficientGas": {
+ "message": "Số dư không đủ để thanh toán tổng tiền gas hiện tại"
+ },
+ "beta": {
+ "message": "Bản thử nghiệm Beta"
+ },
+ "betweenMinAndMax": {
+ "description": "trợ giúp để nhập hex dưới dạng số thập phân",
+ "message": "phải nhiều hơn hoặc bằng $1 và ít hơn hoặc bằng $2."
+ },
+ "borrowDharma": {
+ "message": "Vay Dharma (thử nghiệm)"
+ },
+ "buy": {
+ "message": "Mua"
+ },
+ "buyCoinbase": {
+ "message": "Mua trên Coinbase"
+ },
+ "buyCoinbaseExplainer": {
+ "message": "Coinbase là dịch vụ ví điện tử thông dụng nhất thế giới để mua bán Bitcoin, Ethereum, và Litecoin"
+ },
+ "cancel": {
+ "message": "Hủy"
+ },
+ "clickCopy": {
+ "message": "Nhấp vào để sao chép"
+ },
+ "confirm": {
+ "message": "Xác nhận"
+ },
+ "confirmContract": {
+ "message": "Xác nhận hợp đồng"
+ },
+ "confirmPassword": {
+ "message": "Xác nhận mật khẩu"
+ },
+ "confirmTransaction": {
+ "message": "Xác nhận giao dịch"
+ },
+ "continueToCoinbase": {
+ "message": "Tiếp tục đến Coinbase"
+ },
+ "contractDeployment": {
+ "message": "Triển khai hợp đồng"
+ },
+ "conversionProgress": {
+ "message": "Đang chuyển đổi"
+ },
+ "copiedButton": {
+ "message": "Đã sao chép"
+ },
+ "copiedClipboard": {
+ "message": "Đã sao chép vào bộ nhớ Clipboard"
+ },
+ "copiedExclamation": {
+ "message": "Đã sao chép!"
+ },
+ "copy": {
+ "message": "Sao chép"
+ },
+ "copyButton": {
+ "message": "Sao chép"
+ },
+ "copyPrivateKey": {
+ "message": "Đây là Khoá Bí Mật của bạn (nhấp vào để sao chép)"
+ },
+ "copyToClipboard": {
+ "message": "Đã sao chép vào clipboard"
+ },
+ "create": {
+ "message": "Tạo"
+ },
+ "createAccount": {
+ "message": "Tạo tài khoản"
+ },
+ "createDen": {
+ "message": "Tạo"
+ },
+ "crypto": {
+ "description": "Hình thức giao dịch (tiền điện tử)",
+ "message": "Tiền điện tử"
+ },
+ "customGas": {
+ "message": "Tùy chỉnh gas"
+ },
+ "customRPC": {
+ "message": "Tùy chỉnh RPC"
+ },
+ "customize": {
+ "message": "Tùy chỉnh"
+ },
+ "defaultNetwork": {
+ "message": "Mạng lưới mặc định dùng cho các giao dịch Ether là Main Net (tiền ETH thật)."
+ },
+ "denExplainer": {
+ "message": "Số DEN của bạn là mật khẩu đã được mã hóa và lưu trữ trong MetaMask"
+ },
+ "deposit": {
+ "message": "Ký gửi/nạp tiền"
+ },
+ "depositBTC": {
+ "message": "Ký gửi BTC đến địa chỉ sau:"
+ },
+ "depositCoin": {
+ "description": "Báo cho người dùng biết đồng tiền nào họ đã chọn để ký gửi với ShapeShift",
+ "message": "Ký gửi $1 đến địa chỉ sau:"
+ },
+ "depositEth": {
+ "message": "Ký gửi Eth"
+ },
+ "depositEther": {
+ "message": "Ký gửi Ether"
+ },
+ "depositFiat": {
+ "message": "Ký gửi bằng tiền Fiat (USD, GBP, ...)"
+ },
+ "depositFromAccount": {
+ "message": "Ký gửi từ một tài khoản khác"
+ },
+ "depositShapeShift": {
+ "message": "Ký gửi với ShapeShift"
+ },
+ "depositShapeShiftExplainer": {
+ "message": "Nếu bạn sở hữu các đồng tiền điện tử khác, bạn có thể giao dịch và ký gửi Ether trực tiếp vào ví MetaMask của bạn. Không cần tạo thêm tài khoản."
+ },
+ "details": {
+ "message": "Chi tiết"
+ },
+ "directDeposit": {
+ "message": "Ký gửi trực tiếp"
+ },
+ "directDepositEther": {
+ "message": "Ký gửi Ether trực tiếp"
+ },
+ "directDepositEtherExplainer": {
+ "message": "Nếu bạn đã có sẵn vài Ether, cách nhanh nhất để thêm Ether vào ví tiền mới của bạn là bằng ký gửi trực tiếp."
+ },
+ "done": {
+ "message": "Hoàn tất"
+ },
+ "edit": {
+ "message": "Chỉnh sửa"
+ },
+ "editAccountName": {
+ "message": "Chỉnh sửa tên tài khoản"
+ },
+ "encryptNewDen": {
+ "message": "Mã hóa số DEN mới của bạn"
+ },
+ "enterPassword": {
+ "message": "Nhập mật khẩu"
+ },
+ "etherscanView": {
+ "message": "Xem tài khoản trên Etherscan"
+ },
+ "exchangeRate": {
+ "message": "Tỷ giá"
+ },
+ "exportPrivateKey": {
+ "message": "Xuất mã khóa cá nhân"
+ },
+ "exportPrivateKeyWarning": {
+ "message": "Xuất mã khóa cá nhân theo rủi ro tự chịu"
+ },
+ "failed": {
+ "message": "Không thành công"
+ },
+ "fiat": {
+ "description": "Hình thức giao dịch",
+ "message": "FIAT"
+ },
+ "fileImportFail": {
+ "description": "Giúp người dùng nhập tài khoản từ tập tin JSON",
+ "message": "Tập tin đã nhập không hoạt động? Nhấp vào đây!"
+ },
+ "from": {
+ "message": "Từ"
+ },
+ "fromShapeShift": {
+ "message": "Từ ShapeShift"
+ },
+ "gas": {
+ "description": "Viết tắt của giá ga",
+ "message": "Ga"
+ },
+ "gasFee": {
+ "message": "Tiền ga"
+ },
+ "gasLimit": {
+ "message": "Hạn mức ga"
+ },
+ "gasLimitCalculation": {
+ "message": "Chúng tôi tính toán và gợi ý một hạn mức ga cụ thể dựa trên tỷ lệ thành công của hệ thống."
+ },
+ "gasLimitRequired": {
+ "message": "Hạn mức ga được yêu cầu"
+ },
+ "gasLimitTooLow": {
+ "message": "Hạn mức ga phải đạt tối thiểu 21000"
+ },
+ "gasPrice": {
+ "message": "Giá ga (GWEI)"
+ },
+ "gasPriceCalculation": {
+ "message": "Chúng tôi tính toán và gợi ý một giá ga cụ thể dựa trên tỷ lệ thành công của hệ thống."
+ },
+ "gasPriceRequired": {
+ "message": "Giá ga được yêu cầu"
+ },
+ "getEther": {
+ "message": "Lấy Ether"
+ },
+ "getEtherFromFaucet": {
+ "description": "Hiển thị tên mạng cho vòi Ether",
+ "message": "Lấy Ether từ vòi với giá $1"
+ },
+ "greaterThanMin": {
+ "description": "trợ giúp để nhập hex dưới dạng số thập phân",
+ "message": "phải nhiều hơn hoặc bằng $1"
+ },
+ "here": {
+ "description": "như trong -Nhấp vào đây để xem thêm thông tin- (dùng với các số dư token có vấn đề)",
+ "message": "tại đây"
+ },
+ "hide": {
+ "message": "Ẩn"
+ },
+ "hideToken": {
+ "message": "Ẩn mã token"
+ },
+ "hideTokenPrompt": {
+ "message": "Ẩn mã token?"
+ },
+ "howToDeposit": {
+ "message": "Bạn muốn ký gửi Ether bằng cách nào?"
+ },
+ "import": {
+ "description": "Nút để nhập tài khoản từ một tập tin đã chọn",
+ "message": "Nhập"
+ },
+ "importAccount": {
+ "message": "Nhập tài khoản"
+ },
+ "importAnAccount": {
+ "message": "Nhập một tài khoản"
+ },
+ "importDen": {
+ "message": "Nhập mã DEN hiện hành"
+ },
+ "imported": {
+ "description": "Trạng thái hiển thị cho một tài khoản đã được tải toàn bộ vào chùm chìa khóa",
+ "message": "Đã nhập"
+ },
+ "infoHelp": {
+ "message": "Thông tin & Trợ giúp"
+ },
+ "invalidAddress": {
+ "message": "Địa chỉ không hợp lệ"
+ },
+ "invalidGasParams": {
+ "message": "Thông số ga không hợp lệ"
+ },
+ "invalidInput": {
+ "message": "Thông tin nhập vào không hợp lệ"
+ },
+ "invalidRequest": {
+ "message": "Yêu cầu không hợp lệ"
+ },
+ "jsonFile": {
+ "description": "định dạng để nhập tài khoản",
+ "message": "Tập tin JSON"
+ },
+ "kovan": {
+ "message": "Mạng thử nghiệm Kovan"
+ },
+ "lessThanMax": {
+ "description": "trợ giúp để nhập hex dưới dạng số thập phân",
+ "message": "phải ít hơn hoặc bằng $1."
+ },
+ "limit": {
+ "message": "Giới hạn"
+ },
+ "loading": {
+ "message": "Đang tải..."
+ },
+ "loadingTokens": {
+ "message": "Đang tải mã token..."
+ },
+ "localhost": {
+ "message": "Localhost 8545"
+ },
+ "logout": {
+ "message": "Thoát"
+ },
+ "loose": {
+ "message": "Nới lỏng"
+ },
+ "mainnet": {
+ "message": "Mạng Ethereum MainNet (tiền ETH thật)"
+ },
+ "message": {
+ "message": "Tin nhắn"
+ },
+ "min": {
+ "message": "Tối thiểu"
+ },
+ "myAccounts": {
+ "message": "Tài khoản của tôi"
+ },
+ "needEtherInWallet": {
+ "message": "Để tương tác với các ứng dụng phân tán bằng MetaMask, bạn sẽ phải cần có Ether trong ví của bạn."
+ },
+ "needImportFile": {
+ "description": "Người dùng đang nhập một tài khoản và cần thêm tập tin để tiếp tục",
+ "message": "Bạn phải chọn một tập tin để nhập."
+ },
+ "needImportPassword": {
+ "description": "Mật khẩu và tập tin cần thiết để nhập một tài khoản",
+ "message": "Bạn phải điền mật khẩu cho tập tin đã chọn."
+ },
+ "networks": {
+ "message": "Các mạng lưới"
+ },
+ "newAccount": {
+ "message": "Tài khoản mới"
+ },
+ "newAccountNumberName": {
+ "description": "Tên mặc định của tài khoản tiếp theo để tạo trên màn hình tài khoản",
+ "message": "Tài khoản $1"
+ },
+ "newContract": {
+ "message": "Hợp đồng mới"
+ },
+ "newPassword": {
+ "message": "Mật khẩu mới (tối thiểu 8 ký tự)"
+ },
+ "newRecipient": {
+ "message": "Người nhận mới"
+ },
+ "next": {
+ "message": "Kế tiếp"
+ },
+ "noAddressForName": {
+ "message": "Không có địa chỉ nào được ấn định cho tên này."
+ },
+ "noDeposits": {
+ "message": "Không có tiền ký gửi nào được nhận"
+ },
+ "noTransactionHistory": {
+ "message": "Không có lịch sử giao dịch"
+ },
+ "noTransactions": {
+ "message": "Không có giao dịch"
+ },
+ "notStarted": {
+ "message": "Chưa bắt đầu"
+ },
+ "oldUI": {
+ "message": "Giao diện cũ"
+ },
+ "oldUIMessage": {
+ "message": "Bạn vừa quay về giao diện cũ. Bạn có thể chuyển đổi sang giao diện mới bằng tùy chọn trong menu ở góc phải trên cùng."
+ },
+ "or": {
+ "description": "lựa chọn giữa tạo hay nhập một tài khoản mới",
+ "message": "hoặc"
+ },
+ "passwordMismatch": {
+ "description": "trong quá trình tạo mật khẩu, hai trường mật khẩu mới không khớp",
+ "message": "mật khẩu không khớp"
+ },
+ "passwordShort": {
+ "description": "trong quá trình tạo mật khẩu, mật khẩu không đủ dài để đảm bảo an toàn",
+ "message": "mật khẩu không đủ dài"
+ },
+ "pastePrivateKey": {
+ "description": "Dùng cho việc nhập tài khoản từ một khóa cá nhân",
+ "message": "Dán dãy khóa cá nhân của bạn tại đây:"
+ },
+ "pasteSeed": {
+ "message": "Dán Mật Khẩu Sinh Khoá (seed phrase) của bạn tại đây!"
+ },
+ "pleaseReviewTransaction": {
+ "message": "Vui lòng xem lại giao dịch của bạn."
+ },
+ "privateKey": {
+ "description": "chọn định dạng tập tin này để nhập một tài khoản",
+ "message": "Khóa Bí Mật"
+ },
+ "privateKeyWarning": {
+ "message": "Cảnh báo: Không bao giờ được tiết lộ khóa này. Bất kỳ ai có Khóa Bí Mật của bạn đều có thể đánh cắp tài sản được giữ trong tài khoản của bạn."
+ },
+ "privateNetwork": {
+ "message": "Mạng lưới riêng"
+ },
+ "qrCode": {
+ "message": "Hiển thị mã QR"
+ },
+ "readMore": {
+ "message": "Đọc thêm tại đây."
+ },
+ "readdToken": {
+ "message": "Bạn có thể thêm trở lại mã token này bằng cách nhấn \"Thêm mã token\" trong menu tùy chọn trong tài khoản của bạn."
+ },
+ "receive": {
+ "message": "Nhận"
+ },
+ "recipientAddress": {
+ "message": "Địa chỉ người nhận"
+ },
+ "refundAddress": {
+ "message": "Địa chỉ hoàn trả lại của bạn"
+ },
+ "rejected": {
+ "message": "Không chấp thuận/Bị từ chối"
+ },
+ "required": {
+ "message": "Yêu cầu"
+ },
+ "retryWithMoreGas": {
+ "message": "Thử lại với một giá ga cao hơn tại đây"
+ },
+ "revert": {
+ "message": "Chuyển lại"
+ },
+ "rinkeby": {
+ "message": "Mạng thử nghiệm Rinkeby"
+ },
+ "ropsten": {
+ "message": "Mạng thử nghiệm Ropsten"
+ },
+ "sampleAccountName": {
+ "description": "Giúp người dùng hiểu khái niệm thêm một cái tên có thể đọc được vào tài khoản của họ",
+ "message": "Ví dụ, Tài khoản mới của tôi"
+ },
+ "save": {
+ "message": "Lưu"
+ },
+ "saveAsFile": {
+ "description": "Quá trình xuất tài khoản",
+ "message": "Lưu lại dưới dạng tập tin"
+ },
+ "selectService": {
+ "message": "Chọn dịch vụ"
+ },
+ "send": {
+ "message": "Gửi"
+ },
+ "sendTokens": {
+ "message": "Gửi mã token"
+ },
+ "sendTokensAnywhere": {
+ "message": "Gửi mã token đến bất kỳ ai có tài khoản Ethereum"
+ },
+ "settings": {
+ "message": "Cài đặt"
+ },
+ "shapeshiftBuy": {
+ "message": "Mua với ShapeShift"
+ },
+ "showPrivateKeys": {
+ "message": "Hiển thị khóa cá nhân"
+ },
+ "showQRCode": {
+ "message": "Hiển thị mã QR"
+ },
+ "sigRequest": {
+ "message": "Yêu cầu chữ ký"
+ },
+ "sigRequested": {
+ "message": "Đã yêu cầu chữ ký"
+ },
+ "sign": {
+ "message": "Ký nhận"
+ },
+ "signMessage": {
+ "message": "Ký nhận tin nhắn"
+ },
+ "signNotice": {
+ "message": "Ký nhận vào tin nhắn này có thể gây nguy hiểm. Chỉ nên ký nhận tin nhắn từ những nguồn bạn hoàn toàn tin tưởng có thể dùng với tài khoản của bạn. Cách thức nguy hiểm này sẽ bị xóa trong phiên bản sắp tới."
+ },
+ "status": {
+ "message": "Trạng thái"
+ },
+ "submit": {
+ "message": "Gửi đi"
+ },
+ "takesTooLong": {
+ "message": "Chờ quá lâu?"
+ },
+ "testFaucet": {
+ "message": "Vòi nhận tiền ETH ảo để thử nghiệm"
+ },
+ "to": {
+ "message": "Đến"
+ },
+ "toETHviaShapeShift": {
+ "description": "hệ thống sẽ điền vào loại tiền gửi khi bắt đầu tin nhắn",
+ "message": "$1 thành ETH qua ShapeShift"
+ },
+ "tokenBalance": {
+ "message": "Số dư token của bạn là:"
+ },
+ "total": {
+ "message": "Tổng cộng"
+ },
+ "transactionMemo": {
+ "message": "Ghi nhớ giao dịch (tùy chọn)"
+ },
+ "transactionNumber": {
+ "message": "Số thứ tự giao dịch"
+ },
+ "transfers": {
+ "message": "Các giao dịch"
+ },
+ "troubleTokenBalances": {
+ "description": "Kèm theo một đường link (tại đây) để xem số dư token.",
+ "message": "Chúng tôi gặp sự cố khi tải số dư token của bạn. Xin vui lòng xem lại"
+ },
+ "typePassword": {
+ "message": "Điền mật khẩu của bạn"
+ },
+ "uiWelcome": {
+ "message": "Chào mừng bạn đến với giao diện mới (Beta)"
+ },
+ "uiWelcomeMessage": {
+ "message": "Bạn đang sử dụng giao diện mới của Metamask. Chúng tôi khuyến khích bạn thử nghiệm và khám phá các tính năng mới như gửi token, và nếu bạn có gặp phải vấn đề gì khó khăn, xin hãy liên hệ ngay để chúng tôi có thể giúp đỡ bạn."
+ },
+ "unavailable": {
+ "message": "Không có sẵn"
+ },
+ "unknown": {
+ "message": "Không xác định"
+ },
+ "unknownNetwork": {
+ "message": "Mạng lưới riêng không xác định"
+ },
+ "unknownNetworkId": {
+ "message": "ID không xác định"
+ },
+ "usaOnly": {
+ "description": "Việc sử dụng hệ thống giao dịch này chỉ giới hạn cho người dùng ở Mỹ",
+ "message": "Chỉ áp dụng cho người dùng ở Mỹ"
+ },
+ "usedByClients": {
+ "message": "Được sử dụng bởi nhiều khách hàng khác nhau"
+ },
+ "viewAccount": {
+ "message": "Xem tài khoản"
+ },
+ "warning": {
+ "message": "Cảnh báo"
+ },
+ "whatsThis": {
+ "message": "Đây là gì?"
+ },
+ "youSign": {
+ "message": "Bạn đang ký nhận"
+ },
+ "yourSigRequested": {
+ "message": "Chữ ký của bạn đang được yêu cầu"
+ }
+}
diff --git a/app/_locales/zh_CN/messages.json b/app/_locales/zh_CN/messages.json
index fc87384e5..203ab1923 100644
--- a/app/_locales/zh_CN/messages.json
+++ b/app/_locales/zh_CN/messages.json
@@ -1,10 +1,609 @@
{
+ "accept": {
+ "message": "接受"
+ },
+ "account": {
+ "message": "账户"
+ },
+ "accountDetails": {
+ "message": "账户详情"
+ },
+ "accountName": {
+ "message": "账户名称"
+ },
+ "address": {
+ "message": "地址"
+ },
+ "addToken": {
+ "message": "添加代币"
+ },
+ "amount": {
+ "message": "数量"
+ },
+ "amountPlusGas": {
+ "message": "数量 + Gas"
+ },
+ "appDescription": {
+ "message": "以太坊浏览器插件",
+ "description": "The description of the application"
+ },
"appName": {
"message": "MetaMask",
"description": "The name of the application"
},
- "appDescription": {
- "message": "以太坊身份管理",
- "description": "The description of the application"
+ "attemptingConnect": {
+ "message": "正在尝试连接区块链。"
+ },
+ "available": {
+ "message": "可用"
+ },
+ "back": {
+ "message": "返回"
+ },
+ "balance": {
+ "message": "余额:"
+ },
+ "balanceIsInsufficientGas": {
+ "message": "当前余额不足以支付 Gas"
+ },
+ "beta": {
+ "message": "BETA"
+ },
+ "betweenMinAndMax": {
+ "message": "必须大于等于 $1 并且小于等于 $2 。",
+ "description": "helper for inputting hex as decimal input"
+ },
+ "borrowDharma": {
+ "message": "Borrow With Dharma (Beta)"
+ },
+ "buy": {
+ "message": "购买"
+ },
+ "buyCoinbase": {
+ "message": "在 Coinbase 上购买"
+ },
+ "buyCoinbaseExplainer": {
+ "message": "Coinbase 是世界上最流行的买卖比特币,以太币和莱特币的交易所。"
+ },
+ "cancel": {
+ "message": "取消"
+ },
+ "clickCopy": {
+ "message": "点击复制"
+ },
+ "confirm": {
+ "message": "确认"
+ },
+ "confirmContract": {
+ "message": "确认合约"
+ },
+ "confirmPassword": {
+ "message": "确认密码"
+ },
+ "confirmTransaction": {
+ "message": "确认交易"
+ },
+ "continueToCoinbase": {
+ "message": "继续访问 Coinbase"
+ },
+ "contractDeployment": {
+ "message": "合约部署"
+ },
+ "conversionProgress": {
+ "message": "正在进行转换"
+ },
+ "copiedButton": {
+ "message": "已复制"
+ },
+ "copiedClipboard": {
+ "message": "已复制到剪贴板"
+ },
+ "copiedExclamation": {
+ "message": "已复制!"
+ },
+ "copy": {
+ "message": "复制"
+ },
+ "copyToClipboard": {
+ "message": "复制到剪贴板"
+ },
+ "copyButton": {
+ "message": " 复制 "
+ },
+ "copyPrivateKey": {
+ "message": "这是你的私钥(点击复制)"
+ },
+ "create": {
+ "message": "创建"
+ },
+ "createAccount": {
+ "message": "创建账户"
+ },
+ "createDen": {
+ "message": "创建"
+ },
+ "crypto": {
+ "message": "加密",
+ "description": "Exchange type (cryptocurrencies)"
+ },
+ "customGas": {
+ "message": "自定义 Gas"
+ },
+ "customize": {
+ "message": "自定义"
+ },
+ "customRPC": {
+ "message": "自定义 RPC"
+ },
+ "defaultNetwork": {
+ "message": "默认以太坊交易网络为主网。"
+ },
+ "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": "从 Fiat 存入"
+ },
+ "depositFromAccount": {
+ "message": "从其他账户存入"
+ },
+ "depositShapeShift": {
+ "message": "从 ShapeShift 存入"
+ },
+ "depositShapeShiftExplainer": {
+ "message": "如果你拥有其他加密货币,你可以直接交易并存入 Ether 到你的 MetaMask 钱包。 不需要帐户。"
+ },
+ "details": {
+ "message": "详情"
+ },
+ "directDeposit": {
+ "message": "直接存入"
+ },
+ "directDepositEther": {
+ "message": "直接存入 Ether"
+ },
+ "directDepositEtherExplainer": {
+ "message": "如果你已经有了一些 Ether,通过直接转入是你的新钱包获取 Ether 的最快捷方式。"
+ },
+ "done": {
+ "message": "完成"
+ },
+ "edit": {
+ "message": "编辑"
+ },
+ "editAccountName": {
+ "message": "编辑账户名称"
+ },
+ "encryptNewDen": {
+ "message": "加密你的新 DEN"
+ },
+ "enterPassword": {
+ "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": "来自"
+ },
+ "fromShapeShift": {
+ "message": "来自 ShapeShift"
+ },
+ "gas": {
+ "message": "Gas",
+ "description": "Short indication of gas cost"
+ },
+ "gasFee": {
+ "message": "Gas 费用"
+ },
+ "gasLimit": {
+ "message": "Gas Limit"
+ },
+ "gasLimitCalculation": {
+ "message": "我们根据网络成功率计算建议的 Gas Limit。"
+ },
+ "gasLimitRequired": {
+ "message": "Gas Limit 必填"
+ },
+ "gasLimitTooLow": {
+ "message": "Gas Limit 至少要 21000"
+ },
+ "gasPrice": {
+ "message": "Gas Price (GWEI)"
+ },
+ "gasPriceCalculation": {
+ "message": "我们根据网络成功率计算建议的 Gas Price"
+ },
+ "gasPriceRequired": {
+ "message": "Gas Price 必填"
+ },
+ "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)"
+ },
+ "hide": {
+ "message": "隐藏"
+ },
+ "hideToken": {
+ "message": "隐藏代币"
+ },
+ "hideTokenPrompt": {
+ "message": "隐藏代币?"
+ },
+ "howToDeposit": {
+ "message": "你想怎样转入 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": "信息 & 帮助"
+ },
+ "invalidAddress": {
+ "message": "错误的地址"
+ },
+ "invalidGasParams": {
+ "message": "错误的 Gas 参数"
+ },
+ "invalidInput": {
+ "message": "错误的输入。"
+ },
+ "invalidRequest": {
+ "message": "无效请求"
+ },
+ "jsonFile": {
+ "message": "JSON 文件",
+ "description": "format for importing an account"
+ },
+ "kovan": {
+ "message": "Kovan 测试网络"
+ },
+ "lessThanMax": {
+ "message": "必须小于等于 $1.",
+ "description": "helper for inputting hex as decimal input"
+ },
+ "limit": {
+ "message": "限定"
+ },
+ "loading": {
+ "message": "加载..."
+ },
+ "loadingTokens": {
+ "message": "加载代币..."
+ },
+ "localhost": {
+ "message": "本地主机 8545"
+ },
+ "logout": {
+ "message": "登出"
+ },
+ "loose": {
+ "message": "疏松"
+ },
+ "mainnet": {
+ "message": "以太坊主网络"
+ },
+ "message": {
+ "message": "消息"
+ },
+ "min": {
+ "message": "最小"
+ },
+ "myAccounts": {
+ "message": "我的账户"
+ },
+ "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": "新收款人"
+ },
+ "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": "请粘贴你的助记词!"
+ },
+ "pleaseReviewTransaction": {
+ "message": "请检查你的交易。"
+ },
+ "privateKey": {
+ "message": "私钥",
+ "description": "select this type of file to use to import an account"
+ },
+ "privateKeyWarning": {
+ "message": "注意:永远不要公开这个私钥。任何拥有你的私钥的人都可以窃取你帐户中的任何资产。"
+ },
+ "privateNetwork": {
+ "message": "私有网络"
+ },
+ "qrCode": {
+ "message": "显示二维码"
+ },
+ "readdToken": {
+ "message": "之后你还可以通过帐户选项菜单中的“添加代币”来添加此代币。"
+ },
+ "readMore": {
+ "message": "了解更多。"
+ },
+ "receive": {
+ "message": "接收"
+ },
+ "recipientAddress": {
+ "message": "接收地址"
+ },
+ "refundAddress": {
+ "message": "你的退款地址"
+ },
+ "rejected": {
+ "message": "拒绝"
+ },
+ "required": {
+ "message": "必填"
+ },
+ "retryWithMoreGas": {
+ "message": "使用更高的 Gas Price 重试"
+ },
+ "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"
+ },
+ "selectService": {
+ "message": "选择服务"
+ },
+ "send": {
+ "message": "发送"
+ },
+ "sendTokens": {
+ "message": "发送代币"
+ },
+ "sendTokensAnywhere": {
+ "message": "发送代币给拥有以太坊账户的任何人"
+ },
+ "settings": {
+ "message": "设置"
+ },
+ "shapeshiftBuy": {
+ "message": "使用 Shapeshift 购买"
+ },
+ "showPrivateKeys": {
+ "message": "显示私钥"
+ },
+ "showQRCode": {
+ "message": "显示二维码"
+ },
+ "sign": {
+ "message": "签名"
+ },
+ "signMessage": {
+ "message": "签署消息"
+ },
+ "signNotice": {
+ "message": "签署此消息可能会产生危险的副作用。 \n只从你完全信任的网站上签名。 这种危险的方法将在未来的版本中被移除。"
+ },
+ "sigRequest": {
+ "message": "请求签名"
+ },
+ "sigRequested": {
+ "message": "签名已请求"
+ },
+ "status": {
+ "message": "状态"
+ },
+ "submit": {
+ "message": "提交"
+ },
+ "takesTooLong": {
+ "message": "花费太长时间?"
+ },
+ "testFaucet": {
+ "message": "测试水管"
+ },
+ "to": {
+ "message": "至"
+ },
+ "toETHviaShapeShift": {
+ "message": "$1 ETH 通过 ShapeShift",
+ "description": "system will fill in deposit type in start of message"
+ },
+ "tokenBalance": {
+ "message": "代币余额:"
+ },
+ "total": {
+ "message": "总量"
+ },
+ "transactionMemo": {
+ "message": "交易备注 (可选)"
+ },
+ "transactionNumber": {
+ "message": "交易号"
+ },
+ "transfers": {
+ "message": "Transfers"
+ },
+ "troubleTokenBalances": {
+ "message": "无法加载代币余额。你可以再这里查看 ",
+ "description": "Followed by a link (here) to view token balances"
+ },
+ "typePassword": {
+ "message": "请输入密码"
+ },
+ "uiWelcome": {
+ "message": "欢迎使用新版界面 (Beta)"
+ },
+ "uiWelcomeMessage": {
+ "message": "你现在正在使用新的 Metamask 界面。 尝试发送代币等新功能,有任何问题请告知我们。"
+ },
+ "unavailable": {
+ "message": "不可用"
+ },
+ "unknown": {
+ "message": "未知"
+ },
+ "unknownNetwork": {
+ "message": "未知私有网络"
+ },
+ "unknownNetworkId": {
+ "message": "未知网络 ID"
+ },
+ "usaOnly": {
+ "message": "只限于美国",
+ "description": "Using this exchange is limited to people inside the USA"
+ },
+ "usedByClients": {
+ "message": "可用于各种不同的客户端"
+ },
+ "viewAccount": {
+ "message": "查看账户"
+ },
+ "warning": {
+ "message": "警告"
+ },
+ "whatsThis": {
+ "message": "这是什么?"
+ },
+ "yourSigRequested": {
+ "message": "正在请求你的签名"
+ },
+ "youSign": {
+ "message": "正在签名"
}
}
diff --git a/app/images/arrow-right.svg b/app/images/arrow-right.svg
new file mode 100644
index 000000000..ea5cd0609
--- /dev/null
+++ b/app/images/arrow-right.svg
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="25px" height="21px" viewBox="0 0 25 21" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+ <!-- Generator: Sketch 48.2 (47327) - http://www.bohemiancoding.com/sketch -->
+ <title>arrow-right</title>
+ <desc>Created with Sketch.</desc>
+ <defs></defs>
+ <g id="Confirm-Send-ETH---V3" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" transform="translate(-500.000000, -235.000000)">
+ <g id="Group-4" transform="translate(312.000000, 99.000000)" fill="#5B5B5B">
+ <g id="Group-18" transform="translate(109.000000, 119.000000)">
+ <g id="arrow-right" transform="translate(78.000000, 17.000000)">
+ <path d="M13.2809946,0.467462271 L13.2809946,0.467462271 C12.6477116,1.09191648 12.6477116,2.10286154 13.2809946,2.72571868 L19.1052554,8.46878095 L2.61883998,8.46878095 C1.72479329,8.46878095 0.999190175,9.18426813 0.999190175,10.0658505 L0.999190175,10.0674476 C0.999190175,10.94903 1.72479329,11.6629201 2.61883998,11.6629201 L19.1052554,11.6629201 L13.2809946,17.4075795 C12.6477116,18.0304366 12.6477116,19.0413817 13.2809946,19.6658359 C13.9126581,20.288693 14.9378964,20.288693 15.5711795,19.6658359 L25.3052748,10.0658505 L15.5711795,0.467462271 C14.9378964,-0.155394872 13.9126581,-0.155394872 13.2809946,0.467462271" id="Fill-1"></path>
+ </g>
+ </g>
+ </g>
+ </g>
+</svg> \ No newline at end of file
diff --git a/app/scripts/contentscript.js b/app/scripts/contentscript.js
index 2ed7c87b6..7abbc60e7 100644
--- a/app/scripts/contentscript.js
+++ b/app/scripts/contentscript.js
@@ -96,7 +96,8 @@ function logStreamDisconnectWarning (remoteLabel, err) {
}
function shouldInjectWeb3 () {
- return doctypeCheck() && suffixCheck() && documentElementCheck()
+ return doctypeCheck() && suffixCheck()
+ && documentElementCheck() && !blacklistedDomainCheck()
}
function doctypeCheck () {
@@ -129,6 +130,20 @@ function documentElementCheck () {
return true
}
+function blacklistedDomainCheck () {
+ var blacklistedDomains = ['uscourts.gov', 'dropbox.com']
+ var currentUrl = window.location.href
+ var currentRegex
+ for (let i = 0; i < blacklistedDomains.length; i++) {
+ const blacklistedDomain = blacklistedDomains[i].replace('.', '\\.')
+ currentRegex = new RegExp(`(?:https?:\\/\\/)(?:(?!${blacklistedDomain}).)*$`)
+ if (!currentRegex.test(currentUrl)) {
+ return true
+ }
+ }
+ return false
+}
+
function redirectToPhishingWarning () {
console.log('MetaMask - redirecting to phishing warning')
window.location.href = 'https://metamask.io/phishing.html'
diff --git a/docs/add-to-chrome.md b/docs/add-to-chrome.md
index ea5213182..9c321a1a6 100644
--- a/docs/add-to-chrome.md
+++ b/docs/add-to-chrome.md
@@ -1,14 +1,12 @@
## Add Custom Build to Chrome
-Open `Settings` > `Extensions`.
-
-Check "Developer mode".
-
-At the top, click `Load Unpacked Extension`.
-
-Navigate to your `metamask-plugin/dist/chrome` folder.
-
-Click `Select`.
+* Open `Settings` > `Extensions`.
+* Check "Developer mode".
+* Alternatively, use the URL `chrome://extensions/` in your address bar
+* At the top, click `Load Unpacked Extension`.
+* Navigate to your `metamask-plugin/dist/chrome` folder.
+* Click `Select`.
+* Change to your locale via `chrome://settings/languages`
+* Restart the browser and test the plugin in your locale
You now have the plugin, and can click 'inspect views: background plugin' to view its dev console.
-
diff --git a/mascara/src/app/first-time/backup-phrase-screen.js b/mascara/src/app/first-time/backup-phrase-screen.js
index 9db61f3ab..6819abcf3 100644
--- a/mascara/src/app/first-time/backup-phrase-screen.js
+++ b/mascara/src/app/first-time/backup-phrase-screen.js
@@ -78,26 +78,28 @@ class BackupPhraseScreen extends Component {
{this.props.seedWords}
</div>
{!isShowingSecret && (
- <div className="backup-phrase__secret-blocker">
+ <div
+ className="backup-phrase__secret-blocker"
+ onClick={() => this.setState({ isShowingSecret: true })}
+ >
<LockIcon width="28px" height="35px" fill="#FFFFFF" />
- <button
+ <div
className="backup-phrase__reveal-button"
- onClick={() => this.setState({ isShowingSecret: true })}
>
Click here to reveal secret words
- </button>
+ </div>
</div>
)}
</div>
- );
+ )
}
- renderSecretScreen() {
+ renderSecretScreen () {
const { isShowingSecret } = this.state
return (
<div className="backup-phrase__content-wrapper">
- <div>
+ <div className="backup-phrase__phrase">
<div className="backup-phrase__title">Secret Backup Phrase</div>
<div className="backup-phrase__body-text">
Your secret backup phrase makes it easy to back up and restore your account.
@@ -106,17 +108,6 @@ class BackupPhraseScreen extends Component {
WARNING: Never disclose your backup phrase. Anyone with this phrase can take your Ether forever.
</div>
{this.renderSecretWordsContainer()}
- <button
- className="first-time-flow__button"
- onClick={() => isShowingSecret && this.setState({
- isShowingSecret: false,
- page: BackupPhraseScreen.PAGE.CONFIRM
- })}
- disabled={!isShowingSecret}
- >
- Next
- </button>
- <Breadcrumbs total={3} currentIndex={1} />
</div>
<div className="backup-phrase__tips">
<div className="backup-phrase__tips-text">Tips:</div>
@@ -130,6 +121,19 @@ class BackupPhraseScreen extends Component {
Memorize this phrase.
</div>
</div>
+ <div className="backup-phrase__next-button">
+ <button
+ className="first-time-flow__button"
+ onClick={() => isShowingSecret && this.setState({
+ isShowingSecret: false,
+ page: BackupPhraseScreen.PAGE.CONFIRM,
+ })}
+ disabled={!isShowingSecret}
+ >
+ Next
+ </button>
+ <Breadcrumbs total={3} currentIndex={1} />
+ </div>
</div>
)
}
@@ -231,10 +235,14 @@ class BackupPhraseScreen extends Component {
return this.props.isLoading
? <LoadingScreen loadingMessage="Creating your new account" />
: (
- <div className="backup-phrase">
- {this.renderBack()}
- <Identicon address={this.props.address} diameter={70} />
- {this.renderContent()}
+ <div className="first-view-main-wrapper">
+ <div className="first-view-main">
+ <div className="backup-phrase">
+ {this.renderBack()}
+ <Identicon address={this.props.address} diameter={70} />
+ {this.renderContent()}
+ </div>
+ </div>
</div>
)
}
diff --git a/mascara/src/app/first-time/import-seed-phrase-screen.js b/mascara/src/app/first-time/import-seed-phrase-screen.js
index de8d675e1..86f02ceac 100644
--- a/mascara/src/app/first-time/import-seed-phrase-screen.js
+++ b/mascara/src/app/first-time/import-seed-phrase-screen.js
@@ -79,70 +79,73 @@ class ImportSeedPhraseScreen extends Component {
const { warning } = this.props
const importDisabled = warning || !seedPhrase || !password || !confirmPassword
return (
- <div className="import-account">
- <a
- className="import-account__back-button"
- onClick={e => {
- e.preventDefault()
- this.props.back()
- }}
- href="#"
- >
- {`< Back`}
- </a>
- <div className="import-account__title">
- Import an Account with Seed Phrase
+ <div className="first-view-main-wrapper">
+ <div className="first-view-main">
+ <div className="import-account">
+ <a
+ className="import-account__back-button"
+ onClick={e => {
+ e.preventDefault()
+ this.props.back()
+ }}
+ href="#"
+ >
+ {`< Back`}
+ </a>
+ <div className="import-account__title">
+ Import an Account with Seed Phrase
+ </div>
+ <div className="import-account__selector-label">
+ Enter your secret twelve word phrase here to restore your vault.
+ </div>
+ <div className="import-account__input-wrapper">
+ <label className="import-account__input-label">Wallet Seed</label>
+ <textarea
+ className="import-account__secret-phrase"
+ onChange={e => this.onChange({seedPhrase: e.target.value})}
+ value={this.state.seedPhrase}
+ placeholder="Separate each word with a single space"
+ />
+ </div>
+ <span
+ className="error"
+ >
+ {this.props.warning}
+ </span>
+ <div className="import-account__input-wrapper">
+ <label className="import-account__input-label">New Password</label>
+ <input
+ className="first-time-flow__input"
+ type="password"
+ placeholder="New Password (min 8 characters)"
+ onChange={e => this.onChange({password: e.target.value})}
+ />
+ </div>
+ <div className="import-account__input-wrapper">
+ <label
+ className={classnames('import-account__input-label', {
+ 'import-account__input-label__disabled': password.length < 8,
+ })}
+ >Confirm Password</label>
+ <input
+ className={classnames('first-time-flow__input', {
+ 'first-time-flow__input__disabled': password.length < 8,
+ })}
+ type="password"
+ placeholder="Confirm Password"
+ onChange={e => this.onChange({confirmPassword: e.target.value})}
+ disabled={password.length < 8}
+ />
+ </div>
+ <button
+ className="first-time-flow__button"
+ onClick={() => !importDisabled && this.onClick()}
+ disabled={importDisabled}
+ >
+ Import
+ </button>
+ </div>
</div>
- <div className="import-account__selector-label">
- Enter your secret twelve word phrase here to restore your vault.
- </div>
- <div className="import-account__input-wrapper">
- <label className="import-account__input-label">Wallet Seed</label>
- <textarea
- className="import-account__secret-phrase"
- onChange={e => this.onChange({seedPhrase: e.target.value})}
- value={this.state.seedPhrase}
- placeholder="Separate each word with a single space"
- />
- </div>
- <span
- className="error"
- >
- {this.props.warning}
- </span>
- <div className="import-account__input-wrapper">
- <label className="import-account__input-label">New Password</label>
- <input
- className="first-time-flow__input"
- type="password"
- placeholder="New Password (min 8 characters)"
- onChange={e => this.onChange({password: e.target.value})}
- />
- </div>
- <div className="import-account__input-wrapper">
- <label
- className="import-account__input-label"
- className={classnames('import-account__input-label', {
- 'import-account__input-label__disabled': password.length < 8,
- })}
- >Confirm Password</label>
- <input
- className={classnames('first-time-flow__input', {
- 'first-time-flow__input__disabled': password.length < 8,
- })}
- type="password"
- placeholder="Confirm Password"
- onChange={e => this.onChange({confirmPassword: e.target.value})}
- disabled={password.length < 8}
- />
- </div>
- <button
- className="first-time-flow__button"
- onClick={() => !importDisabled && this.onClick()}
- disabled={importDisabled}
- >
- Import
- </button>
</div>
)
}
diff --git a/mascara/src/app/first-time/index.css b/mascara/src/app/first-time/index.css
index 6c45816bd..d7b146e51 100644
--- a/mascara/src/app/first-time/index.css
+++ b/mascara/src/app/first-time/index.css
@@ -17,12 +17,34 @@
font-family: Roboto;
}
+.alpha-warning__container {
+ display: flex;
+ justify-content: center;
+ background: #f7861c;
+}
+
.alpha-warning,
.alpha-warning-welcome-screen {
- background: #f7861c;
color: #fff;
line-height: 2em;
- padding-left: 10vw;
+}
+
+@media screen and (min-width: 576px) {
+ .alpha-warning {
+ width: 85vw;
+ }
+}
+
+@media screen and (min-width: 769px) {
+ .alpha-warning {
+ width: 80vw;
+ }
+}
+
+@media screen and (min-width: 1281px) {
+ .alpha-warning {
+ width: 62vw;
+ }
}
.alpha-warning-welcome-screen {
@@ -33,26 +55,22 @@
.first-view-main-wrapper {
display: flex;
width: 100%;
- padding-left: 10vw;
+ height: 100%;
+ justify-content: center;
+ padding: 0 10px;
}
.first-view-main,
.first-view-main__mascara {
display: flex;
- flex-direction: row-reverse;
- justify-content: center;
+ flex-direction: row;
+ justify-content: flex-start;
}
.first-view-main__mascara {
justify-content: space-between;
}
-@media screen and (max-width: 575px) {
- .first-view-main-wrapper {
- padding: 0;
- }
-}
-
@media screen and (min-width: 1281px) {
.first-view-main {
width: 62vw;
@@ -83,12 +101,8 @@
.buy-ether {
display: flex;
flex-flow: column nowrap;
- margin: 67px 0 50px;
- max-width: 35rem;
-}
-
-.create-password {
- margin: 67px 0 50px;
+ margin: 60px 0 30px 0;
+ position: relative;
}
.import-account {
@@ -133,10 +147,6 @@
margin-top: 12px;
}
- .first-view-main .create-password {
- margin-top: 0px;
- }
-
.mascara-info {
margin-top: 0px;
width: 100%;
@@ -212,7 +222,7 @@
}
.backup-phrase {
- max-width: 100%;
+ width: 100%;
}
.create-password__title,
@@ -298,7 +308,18 @@
.backup-phrase__content-wrapper {
display: flex;
- flex: row nowrap;
+ flex-flow: row wrap;
+ justify-content: space-between;
+}
+
+.backup-phrase__phrase {
+ flex-grow: .5;
+ min-width: 0;
+}
+
+.backup-phrase__next-button {
+ flex-grow: 1;
+ width: 100%;
}
.backup-phrase__body-text {
@@ -306,8 +327,10 @@
}
.backup-phrase__tips {
- margin: 40px 85px;
+ margin-top: 40px;
width: 285px;
+ flex-grow: .5;
+ min-width: 0;
}
.backup-phrase__tips-text {
@@ -315,6 +338,22 @@
font-size: 16px;
line-height: 23px;
font-family: Roboto;
+ min-width: 0;
+}
+
+@media only screen and (max-width: 768px) {
+ .backup-phrase__content-wrapper {
+ flex-direction: column;
+ }
+
+ .backup-phrase__phrase {
+ flex: 1 0 auto;
+ }
+
+ .backup-phrase__tips {
+ width: 100%;
+ flex: 1 0 auto;
+ }
}
.backup-phrase__secret {
@@ -371,13 +410,17 @@
}
.backup-phrase__back-button,
-.backup-phrase__back-button:hover,
-.import-account__back-button,
-.import-account__back-button:hover {
+.import-account__back-button {
margin-bottom: 18px;
- color: #22232C;
+ color: #22232c;
font-size: 16px;
line-height: 21px;
+ position: absolute;
+ top: -25px;
+}
+
+.backup-phrase__back-button {
+ top: -30px;
}
button.backup-phrase__reveal-button:hover {
diff --git a/mascara/src/app/first-time/notice-screen.js b/mascara/src/app/first-time/notice-screen.js
index 0f0a7e95d..cbd8f9f5b 100644
--- a/mascara/src/app/first-time/notice-screen.js
+++ b/mascara/src/app/first-time/notice-screen.js
@@ -63,26 +63,32 @@ class NoticeScreen extends Component {
return (
isLoading
? <LoadingScreen />
- : <div
- className="tou"
- onScroll={this.onScroll}
- >
- <Identicon address={address} diameter={70} />
- <div className="tou__title">{title}</div>
- <Markdown
- className="tou__body markdown"
- source={body}
- skipHtml
- />
- <button
- className="first-time-flow__button"
- onClick={atBottom && this.acceptTerms}
- disabled={!atBottom}
- >
- Accept
- </button>
- <Breadcrumbs total={3} currentIndex={2} />
- </div>
+ : (
+ <div className="first-view-main-wrapper">
+ <div className="first-view-main">
+ <div
+ className="tou"
+ onScroll={this.onScroll}
+ >
+ <Identicon address={address} diameter={70} />
+ <div className="tou__title">{title}</div>
+ <Markdown
+ className="tou__body markdown"
+ source={body}
+ skipHtml
+ />
+ <button
+ className="first-time-flow__button"
+ onClick={atBottom && this.acceptTerms}
+ disabled={!atBottom}
+ >
+ Accept
+ </button>
+ <Breadcrumbs total={3} currentIndex={2} />
+ </div>
+ </div>
+ </div>
+ )
)
}
}
diff --git a/mascara/src/app/first-time/unique-image-screen.js b/mascara/src/app/first-time/unique-image-screen.js
index 46448aacf..ede17ee3d 100644
--- a/mascara/src/app/first-time/unique-image-screen.js
+++ b/mascara/src/app/first-time/unique-image-screen.js
@@ -12,22 +12,26 @@ class UniqueImageScreen extends Component {
render () {
return (
- <div className="unique-image">
- <Identicon address={this.props.address} diameter={70} />
- <div className="unique-image__title">Your unique account image</div>
- <div className="unique-image__body-text">
- This image was programmatically generated for you by your new account number.
+ <div className="first-view-main-wrapper">
+ <div className="first-view-main">
+ <div className="unique-image">
+ <Identicon address={this.props.address} diameter={70} />
+ <div className="unique-image__title">Your unique account image</div>
+ <div className="unique-image__body-text">
+ This image was programmatically generated for you by your new account number.
+ </div>
+ <div className="unique-image__body-text">
+ You’ll see this image everytime you need to confirm a transaction.
+ </div>
+ <button
+ className="first-time-flow__button"
+ onClick={this.props.next}
+ >
+ Next
+ </button>
+ <Breadcrumbs total={3} currentIndex={1} />
+ </div>
</div>
- <div className="unique-image__body-text">
- You’ll see this image everytime you need to confirm a transaction.
- </div>
- <button
- className="first-time-flow__button"
- onClick={this.props.next}
- >
- Next
- </button>
- <Breadcrumbs total={3} currentIndex={1} />
</div>
)
}
diff --git a/package-lock.json b/package-lock.json
index bd3026816..d1c488b09 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -3929,6 +3929,16 @@
"resolved": "https://registry.npmjs.org/debounce/-/debounce-1.1.0.tgz",
"integrity": "sha512-ZQVKfRVlwRfD150ndzEK8M90ABT+Y/JQKs4Y7U4MXdpuoUkkrr4DwKbVux3YjylA5bUMUj0Nc3pMxPJX6N2QQQ=="
},
+ "debounce-stream": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/debounce-stream/-/debounce-stream-2.0.0.tgz",
+ "integrity": "sha1-HjNADM/wFavY7DMGYaVitoQQsI8=",
+ "requires": {
+ "debounce": "1.1.0",
+ "duplexer": "0.1.1",
+ "through": "2.3.8"
+ }
+ },
"debug": {
"version": "2.6.9",
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
diff --git a/test/integration/lib/send-new-ui.js b/test/integration/lib/send-new-ui.js
index bfd17f3d8..573faaee3 100644
--- a/test/integration/lib/send-new-ui.js
+++ b/test/integration/lib/send-new-ui.js
@@ -1,4 +1,4 @@
-const reactTriggerChange = require('react-trigger-change')
+const reactTriggerChange = require('../../lib/react-trigger-change')
const {
timeout,
queryAsync,
@@ -167,7 +167,7 @@ async function runSendFlowTest(assert, done) {
// TODO: Need a way to mock background so that we can test correct transition from editing to confirm
selectState.val('confirm new ui')
reactTriggerChange(selectState[0])
- const confirmScreenConfirmButton = await queryAsync($, '.confirm-screen-confirm-button')
+ const confirmScreenConfirmButton = await queryAsync($, '.btn-confirm.page-container__footer-button')
console.log(`+++++++++++++++++++++++++++++++= confirmScreenConfirmButton[0]`, confirmScreenConfirmButton[0]);
confirmScreenConfirmButton[0].click()
diff --git a/test/lib/react-trigger-change.js b/test/lib/react-trigger-change.js
new file mode 100644
index 000000000..a25ddff00
--- /dev/null
+++ b/test/lib/react-trigger-change.js
@@ -0,0 +1,161 @@
+// Trigger React's synthetic change events on input, textarea and select elements
+// https://github.com/vitalyq/react-trigger-change
+
+/******************IMPORTANT NOTE******************/
+/* This file is a modification of the */
+/* 'react-trigger-change' library linked above. */
+/* That library breaks when 'onFocus' events are */
+/* added to components under test because it */
+/* dispatches focus events to ensure changes are */
+/* triggered in some versions of IE. */
+/* This modification removes the accomodations */
+/* 'react-trigger-change' makes for IE to ensure */
+/* our tests can pass in chrome and firefox. */
+/**************************************************/
+
+'use strict';
+
+// Constants and functions are declared inside the closure.
+// In this way, reactTriggerChange can be passed directly to executeScript in Selenium.
+module.exports = function reactTriggerChange(node) {
+ var supportedInputTypes = {
+ color: true,
+ date: true,
+ datetime: true,
+ 'datetime-local': true,
+ email: true,
+ month: true,
+ number: true,
+ password: true,
+ range: true,
+ search: true,
+ tel: true,
+ text: true,
+ time: true,
+ url: true,
+ week: true
+ };
+ var nodeName = node.nodeName.toLowerCase();
+ var type = node.type;
+ var event;
+ var descriptor;
+ var initialValue;
+ var initialChecked;
+ var initialCheckedRadio;
+
+ // Do not try to delete non-configurable properties.
+ // Value and checked properties on DOM elements are non-configurable in PhantomJS.
+ function deletePropertySafe(elem, prop) {
+ var desc = Object.getOwnPropertyDescriptor(elem, prop);
+ if (desc && desc.configurable) {
+ delete elem[prop];
+ }
+ }
+
+ function getCheckedRadio(radio) {
+ var name = radio.name;
+ var radios;
+ var i;
+ if (name) {
+ radios = document.querySelectorAll('input[type="radio"][name="' + name + '"]');
+ for (i = 0; i < radios.length; i += 1) {
+ if (radios[i].checked) {
+ return radios[i] !== radio ? radios[i] : null;
+ }
+ }
+ }
+ return null;
+ }
+
+ function preventChecking(e) {
+ e.preventDefault();
+ if (!initialChecked) {
+ e.target.checked = false;
+ }
+ if (initialCheckedRadio) {
+ initialCheckedRadio.checked = true;
+ }
+ }
+
+ if (nodeName === 'select' ||
+ (nodeName === 'input' && type === 'file')) {
+ // IE9-IE11, non-IE
+ // Dispatch change.
+ event = document.createEvent('HTMLEvents');
+ event.initEvent('change', true, false);
+ node.dispatchEvent(event);
+ } else if ((nodeName === 'input' && supportedInputTypes[type]) ||
+ nodeName === 'textarea') {
+ // React 16
+ // Cache artificial value property descriptor.
+ // Property doesn't exist in React <16, descriptor is undefined.
+ descriptor = Object.getOwnPropertyDescriptor(node, 'value');
+
+ // Update inputValueTracking cached value.
+ // Remove artificial value property.
+ // Restore initial value to trigger event with it.
+ initialValue = node.value;
+ node.value = initialValue + '#';
+ deletePropertySafe(node, 'value');
+ node.value = initialValue;
+
+ // React 0.14: IE10-IE11, non-IE
+ // React 15: non-IE
+ // React 16: IE10-IE11, non-IE
+ event = document.createEvent('HTMLEvents');
+ event.initEvent('input', true, false);
+ node.dispatchEvent(event);
+
+ // React 16
+ // Restore artificial value property descriptor.
+ if (descriptor) {
+ Object.defineProperty(node, 'value', descriptor);
+ }
+ } else if (nodeName === 'input' && type === 'checkbox') {
+ // Invert inputValueTracking cached value.
+ node.checked = !node.checked;
+
+ // Dispatch click.
+ // Click event inverts checked value.
+ event = document.createEvent('MouseEvents');
+ event.initEvent('click', true, true);
+ node.dispatchEvent(event);
+ } else if (nodeName === 'input' && type === 'radio') {
+ // Cache initial checked value.
+ initialChecked = node.checked;
+
+ // Find and cache initially checked radio in the group.
+ initialCheckedRadio = getCheckedRadio(node);
+
+ // React 16
+ // Cache property descriptor.
+ // Invert inputValueTracking cached value.
+ // Remove artificial checked property.
+ // Restore initial value, otherwise preventDefault will eventually revert the value.
+ descriptor = Object.getOwnPropertyDescriptor(node, 'checked');
+ node.checked = !initialChecked;
+ deletePropertySafe(node, 'checked');
+ node.checked = initialChecked;
+
+ // Prevent toggling during event capturing phase.
+ // Set checked value to false if initialChecked is false,
+ // otherwise next listeners will see true.
+ // Restore initially checked radio in the group.
+ node.addEventListener('click', preventChecking, true);
+
+ // Dispatch click.
+ // Click event inverts checked value.
+ event = document.createEvent('MouseEvents');
+ event.initEvent('click', true, true);
+ node.dispatchEvent(event);
+
+ // Remove listener to stop further change prevention.
+ node.removeEventListener('click', preventChecking, true);
+
+ // React 16
+ // Restore artificial checked property descriptor.
+ if (descriptor) {
+ Object.defineProperty(node, 'checked', descriptor);
+ }
+ }
+};
diff --git a/test/unit/components/binary-renderer-test.js b/test/unit/components/binary-renderer-test.js
index ee2fa8b60..7bf9250cc 100644
--- a/test/unit/components/binary-renderer-test.js
+++ b/test/unit/components/binary-renderer-test.js
@@ -1,5 +1,5 @@
var assert = require('assert')
-var BinaryRenderer = require('../../../ui/app/components/binary-renderer')
+var BinaryRenderer = require('../../../old-ui/app/components/binary-renderer')
describe('BinaryRenderer', function () {
let binaryRenderer
diff --git a/test/unit/components/bn-as-decimal-input-test.js b/test/unit/components/bn-as-decimal-input-test.js
index 58ecc9c89..7b9d9814f 100644
--- a/test/unit/components/bn-as-decimal-input-test.js
+++ b/test/unit/components/bn-as-decimal-input-test.js
@@ -6,7 +6,7 @@ const ReactTestUtils = require('react-addons-test-utils')
const ethUtil = require('ethereumjs-util')
const BN = ethUtil.BN
-var BnInput = require('../../../ui/app/components/bn-as-decimal-input')
+var BnInput = require('../../../old-ui/app/components/bn-as-decimal-input')
describe('BnInput', function () {
it('can tolerate a gas decimal number at a high precision', function (done) {
diff --git a/test/unit/nameForAccount_test.js b/test/unit/nameForAccount_test.js
index e7c0b18b4..32af49e9d 100644
--- a/test/unit/nameForAccount_test.js
+++ b/test/unit/nameForAccount_test.js
@@ -2,7 +2,7 @@ var assert = require('assert')
var sinon = require('sinon')
var path = require('path')
-var contractNamer = require(path.join(__dirname, '..', '..', 'ui', 'lib', 'contract-namer.js'))
+var contractNamer = require(path.join(__dirname, '..', '..', 'old-ui', 'lib', 'contract-namer.js'))
describe('contractNamer', function () {
beforeEach(function () {
diff --git a/ui/app/account-detail.js b/ui/app/account-detail.js
deleted file mode 100644
index 0da435298..000000000
--- a/ui/app/account-detail.js
+++ /dev/null
@@ -1,117 +0,0 @@
-const inherits = require('util').inherits
-const extend = require('xtend')
-const Component = require('react').Component
-const h = require('react-hyperscript')
-const connect = require('react-redux').connect
-const actions = require('./actions')
-const valuesFor = require('./util').valuesFor
-const TransactionList = require('./components/transaction-list')
-const ExportAccountView = require('./components/account-export')
-const TabBar = require('./components/tab-bar')
-const TokenList = require('./components/token-list')
-
-module.exports = connect(mapStateToProps)(AccountDetailScreen)
-
-function mapStateToProps (state) {
- return {
- metamask: state.metamask,
- identities: state.metamask.identities,
- accounts: state.metamask.accounts,
- address: state.metamask.selectedAddress,
- accountDetail: state.appState.accountDetail,
- network: state.metamask.network,
- unapprovedMsgs: valuesFor(state.metamask.unapprovedMsgs),
- shapeShiftTxList: state.metamask.shapeShiftTxList,
- transactions: state.metamask.selectedAddressTxList || [],
- conversionRate: state.metamask.conversionRate,
- currentCurrency: state.metamask.currentCurrency,
- currentAccountTab: state.metamask.currentAccountTab,
- tokens: state.metamask.tokens,
- computedBalances: state.metamask.computedBalances,
- }
-}
-
-inherits(AccountDetailScreen, Component)
-function AccountDetailScreen () {
- Component.call(this)
-}
-
-// Note: This component is no longer used. Leaving the file for reference:
-// - structuring routing for add token
-// - state required for TxList
-// Delete file when those features are complete
-AccountDetailScreen.prototype.render = function () {}
-
-AccountDetailScreen.prototype.subview = function () {
- var subview
- try {
- subview = this.props.accountDetail.subview
- } catch (e) {
- subview = null
- }
-
- switch (subview) {
- case 'transactions':
- return this.tabSections()
- case 'export':
- var state = extend({key: 'export'}, this.props)
- return h(ExportAccountView, state)
- default:
- return this.tabSections()
- }
-}
-
-AccountDetailScreen.prototype.tabSections = function () {
- const { currentAccountTab } = this.props
-
- return h('section.tabSection.full-flex-height.grow-tenx', [
-
- h(TabBar, {
- tabs: [
- { content: 'Sent', key: 'history' },
- { content: 'Tokens', key: 'tokens' },
- ],
- defaultTab: currentAccountTab || 'history',
- tabSelected: (key) => {
- this.props.dispatch(actions.setCurrentAccountTab(key))
- },
- }),
-
- this.tabSwitchView(),
- ])
-}
-
-AccountDetailScreen.prototype.tabSwitchView = function () {
- const props = this.props
- const { address, network } = props
- const { currentAccountTab, tokens } = this.props
-
- switch (currentAccountTab) {
- case 'tokens':
- return h(TokenList, {
- userAddress: address,
- network,
- tokens,
- addToken: () => this.props.dispatch(actions.showAddTokenPage()),
- })
- default:
- return this.transactionList()
- }
-}
-
-AccountDetailScreen.prototype.transactionList = function () {
- const {transactions, unapprovedMsgs, address,
- network, shapeShiftTxList, conversionRate } = this.props
-
- return h(TransactionList, {
- transactions: transactions.sort((a, b) => b.time - a.time),
- network,
- unapprovedMsgs,
- conversionRate,
- address,
- shapeShiftTxList,
- viewPendingTx: (txId) => {
- this.props.dispatch(actions.viewPendingTx(txId))
- },
- })
-}
diff --git a/ui/app/app.js b/ui/app/app.js
index 9708a2485..954299a6a 100644
--- a/ui/app/app.js
+++ b/ui/app/app.js
@@ -329,12 +329,14 @@ App.prototype.renderAppBar = function () {
]),
]),
- !isInitialized && !isPopup && betaUI && h('h2', {
- className: classnames({
- 'alpha-warning': welcomeScreenSeen,
- 'alpha-warning-welcome-screen': !welcomeScreenSeen,
- }),
- }, 'Please be aware that this version is still under development'),
+ !isInitialized && !isPopup && betaUI && h('.alpha-warning__container', {}, [
+ h('h2', {
+ className: classnames({
+ 'alpha-warning': welcomeScreenSeen,
+ 'alpha-warning-welcome-screen': !welcomeScreenSeen,
+ }),
+ }, 'Please be aware that this version is still under development'),
+ ]),
])
)
diff --git a/ui/app/components/balance.js b/ui/app/components/balance.js
deleted file mode 100644
index 57ca84564..000000000
--- a/ui/app/components/balance.js
+++ /dev/null
@@ -1,89 +0,0 @@
-const Component = require('react').Component
-const h = require('react-hyperscript')
-const inherits = require('util').inherits
-const formatBalance = require('../util').formatBalance
-const generateBalanceObject = require('../util').generateBalanceObject
-const Tooltip = require('./tooltip.js')
-const FiatValue = require('./fiat-value.js')
-
-module.exports = EthBalanceComponent
-
-inherits(EthBalanceComponent, Component)
-function EthBalanceComponent () {
- Component.call(this)
-}
-
-EthBalanceComponent.prototype.render = function () {
- var props = this.props
- let { value } = props
- var style = props.style
- var needsParse = this.props.needsParse !== undefined ? this.props.needsParse : true
- value = value ? formatBalance(value, 6, needsParse) : '...'
- var width = props.width
-
- return (
-
- h('.ether-balance.ether-balance-amount', {
- style: style,
- }, [
- h('div', {
- style: {
- display: 'inline',
- width: width,
- },
- }, this.renderBalance(value)),
- ])
-
- )
-}
-EthBalanceComponent.prototype.renderBalance = function (value) {
- var props = this.props
- if (value === 'None') return value
- if (value === '...') return value
- var balanceObj = generateBalanceObject(value, props.shorten ? 1 : 3)
- var balance
- var splitBalance = value.split(' ')
- var ethNumber = splitBalance[0]
- var ethSuffix = splitBalance[1]
- const showFiat = 'showFiat' in props ? props.showFiat : true
-
- if (props.shorten) {
- balance = balanceObj.shortBalance
- } else {
- balance = balanceObj.balance
- }
-
- var label = balanceObj.label
-
- return (
- h(Tooltip, {
- position: 'bottom',
- title: `${ethNumber} ${ethSuffix}`,
- }, h('div.flex-column', [
- h('.flex-row', {
- style: {
- alignItems: 'flex-end',
- lineHeight: '13px',
- fontFamily: 'Montserrat Light',
- textRendering: 'geometricPrecision',
- },
- }, [
- h('div', {
- style: {
- width: '100%',
- textAlign: 'right',
- },
- }, this.props.incoming ? `+${balance}` : balance),
- h('div', {
- style: {
- color: ' #AEAEAE',
- fontSize: '12px',
- marginLeft: '5px',
- },
- }, label),
- ]),
-
- showFiat ? h(FiatValue, { value: props.value }) : null,
- ]))
- )
-}
diff --git a/ui/app/components/binary-renderer.js b/ui/app/components/binary-renderer.js
deleted file mode 100644
index 0b6a1f5c2..000000000
--- a/ui/app/components/binary-renderer.js
+++ /dev/null
@@ -1,46 +0,0 @@
-const Component = require('react').Component
-const h = require('react-hyperscript')
-const inherits = require('util').inherits
-const ethUtil = require('ethereumjs-util')
-const extend = require('xtend')
-
-module.exports = BinaryRenderer
-
-inherits(BinaryRenderer, Component)
-function BinaryRenderer () {
- Component.call(this)
-}
-
-BinaryRenderer.prototype.render = function () {
- const props = this.props
- const { value, style } = props
- const text = this.hexToText(value)
-
- const defaultStyle = extend({
- width: '315px',
- maxHeight: '210px',
- resize: 'none',
- border: 'none',
- background: 'white',
- padding: '3px',
- }, style)
-
- return (
- h('textarea.font-small', {
- readOnly: true,
- style: defaultStyle,
- defaultValue: text,
- })
- )
-}
-
-BinaryRenderer.prototype.hexToText = function (hex) {
- try {
- const stripped = ethUtil.stripHexPrefix(hex)
- const buff = Buffer.from(stripped, 'hex')
- return buff.toString('utf8')
- } catch (e) {
- return hex
- }
-}
-
diff --git a/ui/app/components/currency-input.js b/ui/app/components/currency-input.js
index 6f7862e51..940238fa5 100644
--- a/ui/app/components/currency-input.js
+++ b/ui/app/components/currency-input.js
@@ -8,8 +8,12 @@ inherits(CurrencyInput, Component)
function CurrencyInput (props) {
Component.call(this)
+ const sanitizedValue = sanitizeValue(props.value)
+
this.state = {
- value: sanitizeValue(props.value),
+ value: sanitizedValue,
+ emptyState: false,
+ focused: false,
}
}
@@ -58,9 +62,11 @@ CurrencyInput.prototype.handleChange = function (newValue) {
if (value === '0' && newValue[newValueLastIndex] === '0') {
parsedValue = parsedValue.slice(0, newValueLastIndex)
}
-
const sanitizedValue = sanitizeValue(parsedValue)
- this.setState({ value: sanitizedValue })
+ this.setState({
+ value: sanitizedValue,
+ emptyState: newValue === '' && sanitizedValue === '0',
+ })
onInputChange(sanitizedValue)
}
@@ -86,17 +92,19 @@ CurrencyInput.prototype.render = function () {
readOnly,
inputRef,
} = this.props
+ const { emptyState, focused } = this.state
const inputSizeMultiplier = readOnly ? 1 : 1.2
const valueToRender = this.getValueToRender()
-
return h('input', {
className,
- value: valueToRender,
- placeholder,
+ value: emptyState ? '' : valueToRender,
+ placeholder: focused ? '' : placeholder,
size: valueToRender.length * inputSizeMultiplier,
readOnly,
+ onFocus: () => this.setState({ focused: true, emptyState: valueToRender === '0' }),
+ onBlur: () => this.setState({ focused: false, emptyState: false }),
onChange: e => this.handleChange(e.target.value),
ref: inputRef,
})
diff --git a/ui/app/components/dropdowns/account-options-dropdown.js b/ui/app/components/dropdowns/account-options-dropdown.js
deleted file mode 100644
index f74c0a2d4..000000000
--- a/ui/app/components/dropdowns/account-options-dropdown.js
+++ /dev/null
@@ -1,29 +0,0 @@
-const Component = require('react').Component
-const h = require('react-hyperscript')
-const inherits = require('util').inherits
-const AccountDropdowns = require('./components/account-dropdowns')
-
-inherits(AccountOptionsDropdown, Component)
-function AccountOptionsDropdown () {
- Component.call(this)
-}
-
-module.exports = AccountOptionsDropdown
-
-// TODO: specify default props and proptypes
-// TODO: hook up to state, connect to redux to clean up API
-// TODO: selectedAddress is not defined... should we use selected?
-AccountOptionsDropdown.prototype.render = function () {
- const { selected, network, identities, style, dropdownWrapperStyle, menuItemStyles } = this.props
-
- return h(AccountDropdowns, {
- enableAccountOptions: true,
- enableAccountsSelector: false,
- selected,
- network,
- identities,
- style: style || {},
- dropdownWrapperStyle: dropdownWrapperStyle || {},
- menuItemStyles: menuItemStyles || {},
- }, [])
-}
diff --git a/ui/app/components/dropdowns/account-selection-dropdown.js b/ui/app/components/dropdowns/account-selection-dropdown.js
deleted file mode 100644
index 2f6452b15..000000000
--- a/ui/app/components/dropdowns/account-selection-dropdown.js
+++ /dev/null
@@ -1,29 +0,0 @@
-const Component = require('react').Component
-const h = require('react-hyperscript')
-const inherits = require('util').inherits
-const AccountDropdowns = require('./components/account-dropdowns')
-
-inherits(AccountSelectionDropdown, Component)
-function AccountSelectionDropdown () {
- Component.call(this)
-}
-
-module.exports = AccountSelectionDropdown
-
-// TODO: specify default props and proptypes
-// TODO: hook up to state, connect to redux to clean up API
-// TODO: selectedAddress is not defined... should we use selected?
-AccountSelectionDropdown.prototype.render = function () {
- const { selected, network, identities, style, dropdownWrapperStyle, menuItemStyles } = this.props
-
- return h(AccountDropdowns, {
- enableAccountOptions: false,
- enableAccountsSelector: true,
- selected,
- network,
- identities,
- style: style || {},
- dropdownWrapperStyle: dropdownWrapperStyle || {},
- menuItemStyles: menuItemStyles || {},
- }, [])
-}
diff --git a/ui/app/components/dropdowns/index.js b/ui/app/components/dropdowns/index.js
index fa66f5000..605507058 100644
--- a/ui/app/components/dropdowns/index.js
+++ b/ui/app/components/dropdowns/index.js
@@ -1,17 +1,11 @@
// Reusable Dropdown Components
// TODO: Refactor into separate components
const Dropdown = require('./components/dropdown').Dropdown
-const AccountDropdowns = require('./components/account-dropdowns')
// App-Specific Instances
-const AccountSelectionDropdown = require('./account-selection-dropdown')
-const AccountOptionsDropdown = require('./account-options-dropdown')
const NetworkDropdown = require('./network-dropdown').default
module.exports = {
- AccountSelectionDropdown,
- AccountOptionsDropdown,
NetworkDropdown,
Dropdown,
- AccountDropdowns,
}
diff --git a/ui/app/components/mini-account-panel.js b/ui/app/components/mini-account-panel.js
deleted file mode 100644
index c09cf5b7a..000000000
--- a/ui/app/components/mini-account-panel.js
+++ /dev/null
@@ -1,74 +0,0 @@
-const inherits = require('util').inherits
-const Component = require('react').Component
-const h = require('react-hyperscript')
-const Identicon = require('./identicon')
-
-module.exports = AccountPanel
-
-
-inherits(AccountPanel, Component)
-function AccountPanel () {
- Component.call(this)
-}
-
-AccountPanel.prototype.render = function () {
- var props = this.props
- var picOrder = props.picOrder || 'left'
- const { imageSeed } = props
-
- return (
-
- h('.identity-panel.flex-row.flex-left', {
- style: {
- cursor: props.onClick ? 'pointer' : undefined,
- },
- onClick: props.onClick,
- }, [
-
- this.genIcon(imageSeed, picOrder),
-
- h('div.flex-column.flex-justify-center', {
- style: {
- lineHeight: '15px',
- order: 2,
- display: 'flex',
- alignItems: picOrder === 'left' ? 'flex-begin' : 'flex-end',
- },
- }, this.props.children),
- ])
- )
-}
-
-AccountPanel.prototype.genIcon = function (seed, picOrder) {
- const props = this.props
-
- // When there is no seed value, this is a contract creation.
- // We then show the contract icon.
- if (!seed) {
- return h('.identicon-wrapper.flex-column.select-none', {
- style: {
- order: picOrder === 'left' ? 1 : 3,
- },
- }, [
- h('i.fa.fa-file-text-o.fa-lg', {
- style: {
- fontSize: '42px',
- transform: 'translate(0px, -16px)',
- },
- }),
- ])
- }
-
- // If there was a seed, we return an identicon for that address.
- return h('.identicon-wrapper.flex-column.select-none', {
- style: {
- order: picOrder === 'left' ? 1 : 3,
- },
- }, [
- h(Identicon, {
- address: seed,
- imageify: props.imageifyIdenticons,
- }),
- ])
-}
-
diff --git a/ui/app/components/modals/deposit-ether-modal.js b/ui/app/components/modals/deposit-ether-modal.js
index 23e8666af..b642513d7 100644
--- a/ui/app/components/modals/deposit-ether-modal.js
+++ b/ui/app/components/modals/deposit-ether-modal.js
@@ -109,7 +109,7 @@ DepositEtherModal.prototype.render = function () {
const isTestNetwork = ['3', '4', '42'].find(n => n === network)
const networkName = networkNames[network]
- return h('div.page-container.page-container--full-width', {}, [
+ return h('div.page-container.page-container--full-width.page-container--full-height', {}, [
h('div.page-container__header', [
diff --git a/ui/app/components/pending-personal-msg-details.js b/ui/app/components/pending-personal-msg-details.js
deleted file mode 100644
index b896e9a7e..000000000
--- a/ui/app/components/pending-personal-msg-details.js
+++ /dev/null
@@ -1,60 +0,0 @@
-const Component = require('react').Component
-const h = require('react-hyperscript')
-const inherits = require('util').inherits
-const t = require('../../i18n')
-
-const AccountPanel = require('./account-panel')
-const BinaryRenderer = require('./binary-renderer')
-
-module.exports = PendingMsgDetails
-
-inherits(PendingMsgDetails, Component)
-function PendingMsgDetails () {
- Component.call(this)
-}
-
-PendingMsgDetails.prototype.render = function () {
- var state = this.props
- var msgData = state.txData
-
- var msgParams = msgData.msgParams || {}
- var address = msgParams.from || state.selectedAddress
- var identity = state.identities[address] || { address: address }
- var account = state.accounts[address] || { address: address }
-
- var { data } = msgParams
-
- return (
- h('div', {
- key: msgData.id,
- style: {
- margin: '10px 20px',
- },
- }, [
-
- // account that will sign
- h(AccountPanel, {
- showFullAddress: true,
- identity: identity,
- account: account,
- imageifyIdenticons: state.imageifyIdenticons,
- }),
-
- // message data
- h('div', {
- style: {
- height: '260px',
- },
- }, [
- h('label.font-small.allcaps', { style: { display: 'block' } }, t('message')),
- h(BinaryRenderer, {
- value: data,
- style: {
- height: '215px',
- },
- }),
- ]),
-
- ])
- )
-}
diff --git a/ui/app/components/pending-tx/confirm-deploy-contract.js b/ui/app/components/pending-tx/confirm-deploy-contract.js
index 49fbe6387..4810bb515 100644
--- a/ui/app/components/pending-tx/confirm-deploy-contract.js
+++ b/ui/app/components/pending-tx/confirm-deploy-contract.js
@@ -1,349 +1,350 @@
-const Component = require('react').Component
+const { Component } = require('react')
const { connect } = require('react-redux')
const h = require('react-hyperscript')
-const inherits = require('util').inherits
+const PropTypes = require('prop-types')
const actions = require('../../actions')
const clone = require('clone')
-const Identicon = require('../identicon')
const ethUtil = require('ethereumjs-util')
const BN = ethUtil.BN
const hexToBn = require('../../../../app/scripts/lib/hex-to-bn')
const { conversionUtil } = require('../../conversion-util')
const t = require('../../../i18n')
+const SenderToRecipient = require('../sender-to-recipient')
const { MIN_GAS_PRICE_HEX } = require('../send/send-constants')
+class ConfirmDeployContract extends Component {
+ constructor (props) {
+ super(props)
-module.exports = connect(mapStateToProps, mapDispatchToProps)(ConfirmDeployContract)
-
-function mapStateToProps (state) {
- const {
- conversionRate,
- identities,
- currentCurrency,
- } = state.metamask
- const accounts = state.metamask.accounts
- const selectedAddress = state.metamask.selectedAddress || Object.keys(accounts)[0]
- return {
- currentCurrency,
- conversionRate,
- identities,
- selectedAddress,
+ this.state = {
+ valid: false,
+ submitting: false,
+ }
}
-}
-function mapDispatchToProps (dispatch) {
- return {
- backToAccountDetail: address => dispatch(actions.backToAccountDetail(address)),
- cancelTransaction: ({ id }) => dispatch(actions.cancelTx({ id })),
+ onSubmit (event) {
+ event.preventDefault()
+ const txMeta = this.gatherTxMeta()
+ const valid = this.checkValidity()
+ this.setState({ valid, submitting: true })
+
+ if (valid && this.verifyGasParams()) {
+ this.props.sendTransaction(txMeta, event)
+ } else {
+ this.props.displayWarning('invalidGasParams')
+ this.setState({ submitting: false })
+ }
}
-}
-
-inherits(ConfirmDeployContract, Component)
-function ConfirmDeployContract () {
- Component.call(this)
- this.state = {}
- this.onSubmit = this.onSubmit.bind(this)
-}
+ cancel (event, txMeta) {
+ event.preventDefault()
+ this.props.cancelTransaction(txMeta)
+ }
-ConfirmDeployContract.prototype.onSubmit = function (event) {
- event.preventDefault()
- const txMeta = this.gatherTxMeta()
- const valid = this.checkValidity()
- this.setState({ valid, submitting: true })
-
- if (valid && this.verifyGasParams()) {
- this.props.sendTransaction(txMeta, event)
- } else {
- this.props.dispatch(actions.displayWarning(t('invalidGasParams')))
- this.setState({ submitting: false })
+ checkValidity () {
+ const form = this.getFormEl()
+ const valid = form.checkValidity()
+ return valid
}
-}
-ConfirmDeployContract.prototype.cancel = function (event, txMeta) {
- event.preventDefault()
- this.props.cancelTransaction(txMeta)
-}
+ getFormEl () {
+ const form = document.querySelector('form#pending-tx-form')
+ // Stub out form for unit tests:
+ if (!form) {
+ return { checkValidity () { return true } }
+ }
+ return form
+ }
-ConfirmDeployContract.prototype.checkValidity = function () {
- const form = this.getFormEl()
- const valid = form.checkValidity()
- return valid
-}
+ // After a customizable state value has been updated,
+ gatherTxMeta () {
+ const props = this.props
+ const state = this.state
+ const txData = clone(state.txData) || clone(props.txData)
-ConfirmDeployContract.prototype.getFormEl = function () {
- const form = document.querySelector('form#pending-tx-form')
- // Stub out form for unit tests:
- if (!form) {
- return { checkValidity () { return true } }
+ // log.debug(`UI has defaulted to tx meta ${JSON.stringify(txData)}`)
+ return txData
}
- return form
-}
-
-// After a customizable state value has been updated,
-ConfirmDeployContract.prototype.gatherTxMeta = function () {
- const props = this.props
- const state = this.state
- const txData = clone(state.txData) || clone(props.txData)
- // log.debug(`UI has defaulted to tx meta ${JSON.stringify(txData)}`)
- return txData
-}
+ verifyGasParams () {
+ // We call this in case the gas has not been modified at all
+ if (!this.state) { return true }
+ return (
+ this._notZeroOrEmptyString(this.state.gas) &&
+ this._notZeroOrEmptyString(this.state.gasPrice)
+ )
+ }
-ConfirmDeployContract.prototype.verifyGasParams = function () {
- // We call this in case the gas has not been modified at all
- if (!this.state) { return true }
- return (
- this._notZeroOrEmptyString(this.state.gas) &&
- this._notZeroOrEmptyString(this.state.gasPrice)
- )
-}
+ _notZeroOrEmptyString (obj) {
+ return obj !== '' && obj !== '0x0'
+ }
-ConfirmDeployContract.prototype._notZeroOrEmptyString = function (obj) {
- return obj !== '' && obj !== '0x0'
-}
+ bnMultiplyByFraction (targetBN, numerator, denominator) {
+ const numBN = new BN(numerator)
+ const denomBN = new BN(denominator)
+ return targetBN.mul(numBN).div(denomBN)
+ }
-ConfirmDeployContract.prototype.bnMultiplyByFraction = function (targetBN, numerator, denominator) {
- const numBN = new BN(numerator)
- const denomBN = new BN(denominator)
- return targetBN.mul(numBN).div(denomBN)
-}
+ getData () {
+ const { identities } = this.props
+ const txMeta = this.gatherTxMeta()
+ const txParams = txMeta.txParams || {}
+
+ return {
+ from: {
+ address: txParams.from,
+ name: identities[txParams.from].name,
+ },
+ memo: txParams.memo || '',
+ }
+ }
-ConfirmDeployContract.prototype.getData = function () {
- const { identities } = this.props
- const txMeta = this.gatherTxMeta()
- const txParams = txMeta.txParams || {}
+ getAmount () {
+ const { conversionRate, currentCurrency } = this.props
+ const txMeta = this.gatherTxMeta()
+ const txParams = txMeta.txParams || {}
+
+ const FIAT = conversionUtil(txParams.value, {
+ fromNumericBase: 'hex',
+ toNumericBase: 'dec',
+ fromCurrency: 'ETH',
+ toCurrency: currentCurrency,
+ numberOfDecimals: 2,
+ fromDenomination: 'WEI',
+ conversionRate,
+ })
+ const ETH = conversionUtil(txParams.value, {
+ fromNumericBase: 'hex',
+ toNumericBase: 'dec',
+ fromCurrency: 'ETH',
+ toCurrency: 'ETH',
+ fromDenomination: 'WEI',
+ conversionRate,
+ numberOfDecimals: 6,
+ })
+
+ return {
+ fiat: Number(FIAT),
+ token: Number(ETH),
+ }
- return {
- from: {
- address: txParams.from,
- name: identities[txParams.from].name,
- },
- memo: txParams.memo || '',
}
-}
-
-ConfirmDeployContract.prototype.getAmount = function () {
- const { conversionRate, currentCurrency } = this.props
- const txMeta = this.gatherTxMeta()
- const txParams = txMeta.txParams || {}
-
- const FIAT = conversionUtil(txParams.value, {
- fromNumericBase: 'hex',
- toNumericBase: 'dec',
- fromCurrency: 'ETH',
- toCurrency: currentCurrency,
- numberOfDecimals: 2,
- fromDenomination: 'WEI',
- conversionRate,
- })
- const ETH = conversionUtil(txParams.value, {
- fromNumericBase: 'hex',
- toNumericBase: 'dec',
- fromCurrency: 'ETH',
- toCurrency: 'ETH',
- fromDenomination: 'WEI',
- conversionRate,
- numberOfDecimals: 6,
- })
- return {
- fiat: Number(FIAT),
- token: Number(ETH),
+ getGasFee () {
+ const { conversionRate, currentCurrency } = this.props
+ const txMeta = this.gatherTxMeta()
+ const txParams = txMeta.txParams || {}
+
+ // Gas
+ const gas = txParams.gas
+ const gasBn = hexToBn(gas)
+
+ // Gas Price
+ const gasPrice = txParams.gasPrice || MIN_GAS_PRICE_HEX
+ const gasPriceBn = hexToBn(gasPrice)
+
+ const txFeeBn = gasBn.mul(gasPriceBn)
+
+ const FIAT = conversionUtil(txFeeBn, {
+ fromNumericBase: 'BN',
+ toNumericBase: 'dec',
+ fromDenomination: 'WEI',
+ fromCurrency: 'ETH',
+ toCurrency: currentCurrency,
+ numberOfDecimals: 2,
+ conversionRate,
+ })
+ const ETH = conversionUtil(txFeeBn, {
+ fromNumericBase: 'BN',
+ toNumericBase: 'dec',
+ fromDenomination: 'WEI',
+ fromCurrency: 'ETH',
+ toCurrency: 'ETH',
+ numberOfDecimals: 6,
+ conversionRate,
+ })
+
+ return {
+ fiat: Number(FIAT),
+ eth: Number(ETH),
+ }
}
-}
+ renderGasFee () {
+ const { currentCurrency } = this.props
+ const { fiat: fiatGas, eth: ethGas } = this.getGasFee()
-ConfirmDeployContract.prototype.getGasFee = function () {
- const { conversionRate, currentCurrency } = this.props
- const txMeta = this.gatherTxMeta()
- const txParams = txMeta.txParams || {}
+ return (
+ h('section.flex-row.flex-center.confirm-screen-row', [
+ h('span.confirm-screen-label.confirm-screen-section-column', [ t('gasFee') ]),
+ h('div.confirm-screen-section-column', [
+ h('div.confirm-screen-row-info', `${fiatGas} ${currentCurrency.toUpperCase()}`),
- // Gas
- const gas = txParams.gas
- const gasBn = hexToBn(gas)
+ h(
+ 'div.confirm-screen-row-detail',
+ `${ethGas} ETH`
+ ),
+ ]),
+ ])
+ )
+ }
- // Gas Price
- const gasPrice = txParams.gasPrice || MIN_GAS_PRICE_HEX
- const gasPriceBn = hexToBn(gasPrice)
+ renderHeroAmount () {
+ const { currentCurrency } = this.props
+ const { fiat: fiatAmount } = this.getAmount()
+ const txMeta = this.gatherTxMeta()
+ const txParams = txMeta.txParams || {}
+ const { memo = '' } = txParams
+
+ return (
+ h('div.confirm-send-token__hero-amount-wrapper', [
+ h('h3.flex-center.confirm-screen-send-amount', `${fiatAmount}`),
+ h('h3.flex-center.confirm-screen-send-amount-currency', currentCurrency.toUpperCase()),
+ h('div.flex-center.confirm-memo-wrapper', [
+ h('h3.confirm-screen-send-memo', memo),
+ ]),
+ ])
+ )
+ }
- const txFeeBn = gasBn.mul(gasPriceBn)
+ renderTotalPlusGas () {
+ const { currentCurrency } = this.props
+ const { fiat: fiatAmount, token: tokenAmount } = this.getAmount()
+ const { fiat: fiatGas, eth: ethGas } = this.getGasFee()
- const FIAT = conversionUtil(txFeeBn, {
- fromNumericBase: 'BN',
- toNumericBase: 'dec',
- fromDenomination: 'WEI',
- fromCurrency: 'ETH',
- toCurrency: currentCurrency,
- numberOfDecimals: 2,
- conversionRate,
- })
- const ETH = conversionUtil(txFeeBn, {
- fromNumericBase: 'BN',
- toNumericBase: 'dec',
- fromDenomination: 'WEI',
- fromCurrency: 'ETH',
- toCurrency: 'ETH',
- numberOfDecimals: 6,
- conversionRate,
- })
+ return (
+ h('section.flex-row.flex-center.confirm-screen-row.confirm-screen-total-box ', [
+ h('div.confirm-screen-section-column', [
+ h('span.confirm-screen-label', [ t('total') + ' ' ]),
+ h('div.confirm-screen-total-box__subtitle', [ t('amountPlusGas') ]),
+ ]),
- return {
- fiat: Number(FIAT),
- eth: Number(ETH),
+ h('div.confirm-screen-section-column', [
+ h('div.confirm-screen-row-info', `${fiatAmount + fiatGas} ${currentCurrency.toUpperCase()}`),
+ h('div.confirm-screen-row-detail', `${tokenAmount + ethGas} ETH`),
+ ]),
+ ])
+ )
}
-}
-
-ConfirmDeployContract.prototype.renderGasFee = function () {
- const { currentCurrency } = this.props
- const { fiat: fiatGas, eth: ethGas } = this.getGasFee()
-
- return (
- h('section.flex-row.flex-center.confirm-screen-row', [
- h('span.confirm-screen-label.confirm-screen-section-column', [ t('gasFee') ]),
- h('div.confirm-screen-section-column', [
- h('div.confirm-screen-row-info', `${fiatGas} ${currentCurrency.toUpperCase()}`),
-
- h(
- 'div.confirm-screen-row-detail',
- `${ethGas} ETH`
- ),
- ]),
- ])
- )
-}
-ConfirmDeployContract.prototype.renderHeroAmount = function () {
- const { currentCurrency } = this.props
- const { fiat: fiatAmount } = this.getAmount()
- const txMeta = this.gatherTxMeta()
- const txParams = txMeta.txParams || {}
- const { memo = '' } = txParams
-
- return (
- h('div.confirm-send-token__hero-amount-wrapper', [
- h('h3.flex-center.confirm-screen-send-amount', `${fiatAmount}`),
- h('h3.flex-center.confirm-screen-send-amount-currency', currentCurrency.toUpperCase()),
- h('div.flex-center.confirm-memo-wrapper', [
- h('h3.confirm-screen-send-memo', memo),
- ]),
- ])
- )
-}
+ render () {
+ const { backToAccountDetail, selectedAddress } = this.props
+ const txMeta = this.gatherTxMeta()
-ConfirmDeployContract.prototype.renderTotalPlusGas = function () {
- const { currentCurrency } = this.props
- const { fiat: fiatAmount, token: tokenAmount } = this.getAmount()
- const { fiat: fiatGas, eth: ethGas } = this.getGasFee()
-
- return (
- h('section.flex-row.flex-center.confirm-screen-total-box ', [
- h('div.confirm-screen-section-column', [
- h('span.confirm-screen-label', [ t('total') + ' ' ]),
- h('div.confirm-screen-total-box__subtitle', [ t('amountPlusGas') ]),
- ]),
-
- h('div.confirm-screen-section-column', [
- h('div.confirm-screen-row-info', `${fiatAmount + fiatGas} ${currentCurrency.toUpperCase()}`),
- h('div.confirm-screen-row-detail', `${tokenAmount + ethGas} ETH`),
- ]),
- ])
- )
-}
+ const {
+ from: {
+ address: fromAddress,
+ name: fromName,
+ },
+ } = this.getData()
-ConfirmDeployContract.prototype.render = function () {
- const { backToAccountDetail, selectedAddress } = this.props
- const txMeta = this.gatherTxMeta()
+ this.inputs = []
- const {
- from: {
- address: fromAddress,
- name: fromName,
- },
- } = this.getData()
-
- this.inputs = []
-
- return (
- h('div.flex-column.flex-grow.confirm-screen-container', {
- style: { minWidth: '355px' },
- }, [
- // Main Send token Card
- h('div.confirm-screen-wrapper.flex-column.flex-grow', [
- h('h3.flex-center.confirm-screen-header', [
- h('button.confirm-screen-back-button.allcaps', {
+ return (
+ h('.page-container', [
+ h('.page-container__header', [
+ h('.page-container__back-button', {
onClick: () => backToAccountDetail(selectedAddress),
}, t('back')),
- h('div.confirm-screen-title', t('confirmContract')),
- h('div.confirm-screen-header-tip'),
- ]),
- h('div.flex-row.flex-center.confirm-screen-identicons', [
- h('div.confirm-screen-account-wrapper', [
- h(
- Identicon,
- {
- address: fromAddress,
- diameter: 60,
- },
- ),
- h('span.confirm-screen-account-name', fromName),
- // h('span.confirm-screen-account-number', fromAddress.slice(fromAddress.length - 4)),
- ]),
- h('i.fa.fa-arrow-right.fa-lg'),
- h('div.confirm-screen-account-wrapper', [
- h('i.fa.fa-file-text-o'),
- h('span.confirm-screen-account-name', t('newContract')),
- h('span.confirm-screen-account-number', ' '),
- ]),
+ h('.page-container__title', t('confirmContract')),
+ h('.page-container__subtitle', t('pleaseReviewTransaction')),
]),
+ // Main Send token Card
+ h('.page-container__content', [
+
+ h(SenderToRecipient, {
+ senderName: fromName,
+ senderAddress: fromAddress,
+ }),
+
+ // h('h3.flex-center.confirm-screen-sending-to-message', {
+ // style: {
+ // textAlign: 'center',
+ // fontSize: '16px',
+ // },
+ // }, [
+ // `You're deploying a new contract.`,
+ // ]),
+
+ this.renderHeroAmount(),
+
+ h('div.confirm-screen-rows', [
+ h('section.flex-row.flex-center.confirm-screen-row', [
+ h('span.confirm-screen-label.confirm-screen-section-column', [ t('from') ]),
+ h('div.confirm-screen-section-column', [
+ h('div.confirm-screen-row-info', fromName),
+ h('div.confirm-screen-row-detail', `...${fromAddress.slice(fromAddress.length - 4)}`),
+ ]),
+ ]),
- // h('h3.flex-center.confirm-screen-sending-to-message', {
- // style: {
- // textAlign: 'center',
- // fontSize: '16px',
- // },
- // }, [
- // `You're deploying a new contract.`,
- // ]),
-
- this.renderHeroAmount(),
-
- h('div.confirm-screen-rows', [
- h('section.flex-row.flex-center.confirm-screen-row', [
- h('span.confirm-screen-label.confirm-screen-section-column', [ t('from') ]),
- h('div.confirm-screen-section-column', [
- h('div.confirm-screen-row-info', fromName),
- h('div.confirm-screen-row-detail', `...${fromAddress.slice(fromAddress.length - 4)}`),
+ h('section.flex-row.flex-center.confirm-screen-row', [
+ h('span.confirm-screen-label.confirm-screen-section-column', [ t('to') ]),
+ h('div.confirm-screen-section-column', [
+ h('div.confirm-screen-row-info', t('newContract')),
+ ]),
]),
+
+ this.renderGasFee(),
+
+ this.renderTotalPlusGas(),
+
]),
+ ]),
- h('section.flex-row.flex-center.confirm-screen-row', [
- h('span.confirm-screen-label.confirm-screen-section-column', [ t('to') ]),
- h('div.confirm-screen-section-column', [
- h('div.confirm-screen-row-info', t('newContract')),
- ]),
+ h('form#pending-tx-form', {
+ onSubmit: event => this.onSubmit(event),
+ }, [
+ h('.page-container__footer', [
+ // Cancel Button
+ h('button.btn-cancel.page-container__footer-button.allcaps', {
+ onClick: event => this.cancel(event, txMeta),
+ }, t('cancel')),
+
+ // Accept Button
+ h('button.btn-confirm.page-container__footer-button.allcaps', {
+ onClick: event => this.onSubmit(event),
+ }, t('confirm')),
]),
+ ]),
+ ])
+ )
+ }
+}
- this.renderGasFee(),
+ConfirmDeployContract.propTypes = {
+ sendTransaction: PropTypes.func,
+ cancelTransaction: PropTypes.func,
+ backToAccountDetail: PropTypes.func,
+ displayWarning: PropTypes.func,
+ identities: PropTypes.object,
+ conversionRate: PropTypes.number,
+ currentCurrency: PropTypes.string,
+ selectedAddress: PropTypes.string,
+}
- this.renderTotalPlusGas(),
+const mapStateToProps = state => {
+ const {
+ conversionRate,
+ identities,
+ currentCurrency,
+ } = state.metamask
+ const accounts = state.metamask.accounts
+ const selectedAddress = state.metamask.selectedAddress || Object.keys(accounts)[0]
+ return {
+ currentCurrency,
+ conversionRate,
+ identities,
+ selectedAddress,
+ }
+}
- ]),
- ]),
-
- h('form#pending-tx-form', {
- onSubmit: this.onSubmit,
- }, [
- // Cancel Button
- h('div.cancel.btn-light.confirm-screen-cancel-button.allcaps', {
- onClick: (event) => this.cancel(event, txMeta),
- }, t('cancel')),
-
- // Accept Button
- h('button.confirm-screen-confirm-button.allcaps', [t('confirm')]),
-
- ]),
- ])
- )
+const mapDispatchToProps = dispatch => {
+ return {
+ backToAccountDetail: address => dispatch(actions.backToAccountDetail(address)),
+ cancelTransaction: ({ id }) => dispatch(actions.cancelTx({ id })),
+ displayWarning: warning => actions.displayWarning(t(warning)),
+ }
}
+
+module.exports = connect(mapStateToProps, mapDispatchToProps)(ConfirmDeployContract)
diff --git a/ui/app/components/pending-tx/confirm-send-ether.js b/ui/app/components/pending-tx/confirm-send-ether.js
index a4763eab7..f36def9d5 100644
--- a/ui/app/components/pending-tx/confirm-send-ether.js
+++ b/ui/app/components/pending-tx/confirm-send-ether.js
@@ -267,184 +267,187 @@ ConfirmSendEther.prototype.render = function () {
h('div.page-container__title', title),
h('div.page-container__subtitle', subtitle),
]),
- h('div.flex-row.flex-center.confirm-screen-identicons', [
- h('div.confirm-screen-account-wrapper', [
- h(
- Identicon,
- {
- address: fromAddress,
- diameter: 60,
- },
- ),
- h('span.confirm-screen-account-name', fromName),
- // h('span.confirm-screen-account-number', fromAddress.slice(fromAddress.length - 4)),
- ]),
- h('i.fa.fa-arrow-right.fa-lg'),
- h('div.confirm-screen-account-wrapper', [
- h(
- Identicon,
- {
- address: txParams.to,
- diameter: 60,
- },
- ),
- h('span.confirm-screen-account-name', toName),
- // h('span.confirm-screen-account-number', toAddress.slice(toAddress.length - 4)),
- ]),
- ]),
-
- // h('h3.flex-center.confirm-screen-sending-to-message', {
- // style: {
- // textAlign: 'center',
- // fontSize: '16px',
- // },
- // }, [
- // `You're sending to Recipient ...${toAddress.slice(toAddress.length - 4)}`,
- // ]),
-
- h('h3.flex-center.confirm-screen-send-amount', [`${amountInFIAT}`]),
- h('h3.flex-center.confirm-screen-send-amount-currency', [ currentCurrency.toUpperCase() ]),
- h('div.flex-center.confirm-memo-wrapper', [
- h('h3.confirm-screen-send-memo', [ memo ? `"${memo}"` : '' ]),
- ]),
-
- h('div.confirm-screen-rows', [
- h('section.flex-row.flex-center.confirm-screen-row', [
- h('span.confirm-screen-label.confirm-screen-section-column', [ t('from') ]),
- h('div.confirm-screen-section-column', [
- h('div.confirm-screen-row-info', fromName),
- h('div.confirm-screen-row-detail', `...${fromAddress.slice(fromAddress.length - 4)}`),
+ h('.page-container__content', [
+ h('div.flex-row.flex-center.confirm-screen-identicons', [
+ h('div.confirm-screen-account-wrapper', [
+ h(
+ Identicon,
+ {
+ address: fromAddress,
+ diameter: 60,
+ },
+ ),
+ h('span.confirm-screen-account-name', fromName),
+ // h('span.confirm-screen-account-number', fromAddress.slice(fromAddress.length - 4)),
+ ]),
+ h('i.fa.fa-arrow-right.fa-lg'),
+ h('div.confirm-screen-account-wrapper', [
+ h(
+ Identicon,
+ {
+ address: txParams.to,
+ diameter: 60,
+ },
+ ),
+ h('span.confirm-screen-account-name', toName),
+ // h('span.confirm-screen-account-number', toAddress.slice(toAddress.length - 4)),
]),
]),
- h('section.flex-row.flex-center.confirm-screen-row', [
- h('span.confirm-screen-label.confirm-screen-section-column', [ t('to') ]),
- h('div.confirm-screen-section-column', [
- h('div.confirm-screen-row-info', toName),
- h('div.confirm-screen-row-detail', `...${toAddress.slice(toAddress.length - 4)}`),
- ]),
+ // h('h3.flex-center.confirm-screen-sending-to-message', {
+ // style: {
+ // textAlign: 'center',
+ // fontSize: '16px',
+ // },
+ // }, [
+ // `You're sending to Recipient ...${toAddress.slice(toAddress.length - 4)}`,
+ // ]),
+
+ h('h3.flex-center.confirm-screen-send-amount', [`${amountInFIAT}`]),
+ h('h3.flex-center.confirm-screen-send-amount-currency', [ currentCurrency.toUpperCase() ]),
+ h('div.flex-center.confirm-memo-wrapper', [
+ h('h3.confirm-screen-send-memo', [ memo ? `"${memo}"` : '' ]),
]),
- h('section.flex-row.flex-center.confirm-screen-row', [
- h('span.confirm-screen-label.confirm-screen-section-column', [ t('gasFee') ]),
- h('div.confirm-screen-section-column', [
- h(GasFeeDisplay, {
- gasTotal: gasTotal || gasFeeInHex,
- conversionRate,
- convertedCurrency,
- onClick: () => showCustomizeGasModal(txMeta, sendGasLimit, sendGasPrice, gasTotal),
- }),
+ h('div.confirm-screen-rows', [
+ h('section.flex-row.flex-center.confirm-screen-row', [
+ h('span.confirm-screen-label.confirm-screen-section-column', [ t('from') ]),
+ h('div.confirm-screen-section-column', [
+ h('div.confirm-screen-row-info', fromName),
+ h('div.confirm-screen-row-detail', `...${fromAddress.slice(fromAddress.length - 4)}`),
+ ]),
]),
- ]),
+ h('section.flex-row.flex-center.confirm-screen-row', [
+ h('span.confirm-screen-label.confirm-screen-section-column', [ t('to') ]),
+ h('div.confirm-screen-section-column', [
+ h('div.confirm-screen-row-info', toName),
+ h('div.confirm-screen-row-detail', `...${toAddress.slice(toAddress.length - 4)}`),
+ ]),
+ ]),
- h('section.flex-row.flex-center.confirm-screen-total-box ', [
- h('div.confirm-screen-section-column', [
- h('span.confirm-screen-label', [ t('total') + ' ' ]),
- h('div.confirm-screen-total-box__subtitle', [ t('amountPlusGas') ]),
+ h('section.flex-row.flex-center.confirm-screen-row', [
+ h('span.confirm-screen-label.confirm-screen-section-column', [ t('gasFee') ]),
+ h('div.confirm-screen-section-column', [
+ h(GasFeeDisplay, {
+ gasTotal: gasTotal || gasFeeInHex,
+ conversionRate,
+ convertedCurrency,
+ onClick: () => showCustomizeGasModal(txMeta, sendGasLimit, sendGasPrice, gasTotal),
+ }),
+ ]),
]),
- h('div.confirm-screen-section-column', [
- h('div.confirm-screen-row-info', `${totalInFIAT} ${currentCurrency.toUpperCase()}`),
- h('div.confirm-screen-row-detail', `${totalInETH} ETH`),
+ h('section.flex-row.flex-center.confirm-screen-row.confirm-screen-total-box ', [
+ h('div.confirm-screen-section-column', [
+ h('span.confirm-screen-label', [ t('total') + ' ' ]),
+ h('div.confirm-screen-total-box__subtitle', [ t('amountPlusGas') ]),
+ ]),
+
+ h('div.confirm-screen-section-column', [
+ h('div.confirm-screen-row-info', `${totalInFIAT} ${currentCurrency.toUpperCase()}`),
+ h('div.confirm-screen-row-detail', `${totalInETH} ETH`),
+ ]),
]),
]),
+
+ // These are latest errors handling from master
+ // Leaving as comments as reference when we start implementing error handling
+ // h('style', `
+ // .conf-buttons button {
+ // margin-left: 10px;
+ // text-transform: uppercase;
+ // }
+ // `),
+
+ // txMeta.simulationFails ?
+ // h('.error', {
+ // style: {
+ // marginLeft: 50,
+ // fontSize: '0.9em',
+ // },
+ // }, 'Transaction Error. Exception thrown in contract code.')
+ // : null,
+
+ // !isValidAddress ?
+ // h('.error', {
+ // style: {
+ // marginLeft: 50,
+ // fontSize: '0.9em',
+ // },
+ // }, 'Recipient address is invalid. Sending this transaction will result in a loss of ETH.')
+ // : null,
+
+ // insufficientBalance ?
+ // h('span.error', {
+ // style: {
+ // marginLeft: 50,
+ // fontSize: '0.9em',
+ // },
+ // }, 'Insufficient balance for transaction')
+ // : null,
+
+ // // send + cancel
+ // h('.flex-row.flex-space-around.conf-buttons', {
+ // style: {
+ // display: 'flex',
+ // justifyContent: 'flex-end',
+ // margin: '14px 25px',
+ // },
+ // }, [
+ // h('button', {
+ // onClick: (event) => {
+ // this.resetGasFields()
+ // event.preventDefault()
+ // },
+ // }, 'Reset'),
+
+ // // Accept Button or Buy Button
+ // insufficientBalance ? h('button.btn-green', { onClick: props.buyEth }, 'Buy Ether') :
+ // h('input.confirm.btn-green', {
+ // type: 'submit',
+ // value: 'SUBMIT',
+ // style: { marginLeft: '10px' },
+ // disabled: buyDisabled,
+ // }),
+
+ // h('button.cancel.btn-red', {
+ // onClick: props.cancelTransaction,
+ // }, 'Reject'),
+ // ]),
+ // showRejectAll ? h('.flex-row.flex-space-around.conf-buttons', {
+ // style: {
+ // display: 'flex',
+ // justifyContent: 'flex-end',
+ // margin: '14px 25px',
+ // },
+ // }, [
+ // h('button.cancel.btn-red', {
+ // onClick: props.cancelAllTransactions,
+ // }, 'Reject All'),
+ // ]) : null,
+ // ]),
+ // ])
+ // )
+ // }
]),
-// These are latest errors handling from master
-// Leaving as comments as reference when we start implementing error handling
-// h('style', `
-// .conf-buttons button {
-// margin-left: 10px;
-// text-transform: uppercase;
-// }
-// `),
-
-// txMeta.simulationFails ?
-// h('.error', {
-// style: {
-// marginLeft: 50,
-// fontSize: '0.9em',
-// },
-// }, 'Transaction Error. Exception thrown in contract code.')
-// : null,
-
-// !isValidAddress ?
-// h('.error', {
-// style: {
-// marginLeft: 50,
-// fontSize: '0.9em',
-// },
-// }, 'Recipient address is invalid. Sending this transaction will result in a loss of ETH.')
-// : null,
-
-// insufficientBalance ?
-// h('span.error', {
-// style: {
-// marginLeft: 50,
-// fontSize: '0.9em',
-// },
-// }, 'Insufficient balance for transaction')
-// : null,
-
-// // send + cancel
-// h('.flex-row.flex-space-around.conf-buttons', {
-// style: {
-// display: 'flex',
-// justifyContent: 'flex-end',
-// margin: '14px 25px',
-// },
-// }, [
-// h('button', {
-// onClick: (event) => {
-// this.resetGasFields()
-// event.preventDefault()
-// },
-// }, 'Reset'),
-
-// // Accept Button or Buy Button
-// insufficientBalance ? h('button.btn-green', { onClick: props.buyEth }, 'Buy Ether') :
-// h('input.confirm.btn-green', {
-// type: 'submit',
-// value: 'SUBMIT',
-// style: { marginLeft: '10px' },
-// disabled: buyDisabled,
-// }),
-
-// h('button.cancel.btn-red', {
-// onClick: props.cancelTransaction,
-// }, 'Reject'),
-// ]),
-// showRejectAll ? h('.flex-row.flex-space-around.conf-buttons', {
-// style: {
-// display: 'flex',
-// justifyContent: 'flex-end',
-// margin: '14px 25px',
-// },
-// }, [
-// h('button.cancel.btn-red', {
-// onClick: props.cancelAllTransactions,
-// }, 'Reject All'),
-// ]) : null,
-// ]),
-// ])
-// )
-// }
- ]),
+ h('form#pending-tx-form', {
+ onSubmit: this.onSubmit,
+ }, [
+ h('.page-container__footer', [
+ // Cancel Button
+ h('button.btn-cancel.page-container__footer-button.allcaps', {
+ onClick: (event) => {
+ clearSend()
+ this.cancel(event, txMeta)
+ },
+ }, t('cancel')),
- h('form#pending-tx-form', {
- onSubmit: this.onSubmit,
- }, [
- // Cancel Button
- h('div.cancel.btn-light.confirm-screen-cancel-button.allcaps', {
- onClick: (event) => {
- clearSend()
- this.cancel(event, txMeta)
- },
- }, t('cancel')),
-
- // Accept Button
- h('button.confirm-screen-confirm-button.allcaps', [t('confirm')]),
+ // Accept Button
+ h('button.btn-confirm.page-container__footer-button.allcaps', [t('confirm')]),
+ ]),
+ ]),
]),
])
)
diff --git a/ui/app/components/pending-tx/confirm-send-token.js b/ui/app/components/pending-tx/confirm-send-token.js
index f1142b142..ccd87c0a4 100644
--- a/ui/app/components/pending-tx/confirm-send-token.js
+++ b/ui/app/components/pending-tx/confirm-send-token.js
@@ -306,7 +306,7 @@ ConfirmSendToken.prototype.renderTotalPlusGas = function () {
return fiatAmount && fiatGas
? (
- h('section.flex-row.flex-center.confirm-screen-total-box ', [
+ h('section.flex-row.flex-center.confirm-screen-row.confirm-screen-total-box ', [
h('div.confirm-screen-section-column', [
h('span.confirm-screen-label', [ t('total') + ' ' ]),
h('div.confirm-screen-total-box__subtitle', [ t('amountPlusGas') ]),
@@ -319,7 +319,7 @@ ConfirmSendToken.prototype.renderTotalPlusGas = function () {
])
)
: (
- h('section.flex-row.flex-center.confirm-screen-total-box ', [
+ h('section.flex-row.flex-center.confirm-screen-row.confirm-screen-total-box ', [
h('div.confirm-screen-section-column', [
h('span.confirm-screen-label', [ t('total') + ' ' ]),
h('div.confirm-screen-total-box__subtitle', [ t('amountPlusGas') ]),
@@ -365,80 +365,82 @@ ConfirmSendToken.prototype.render = function () {
h('div.page-container__title', title),
h('div.page-container__subtitle', subtitle),
]),
- h('div.flex-row.flex-center.confirm-screen-identicons', [
- h('div.confirm-screen-account-wrapper', [
- h(
- Identicon,
- {
- address: fromAddress,
- diameter: 60,
- },
- ),
- h('span.confirm-screen-account-name', fromName),
- // h('span.confirm-screen-account-number', fromAddress.slice(fromAddress.length - 4)),
- ]),
- h('i.fa.fa-arrow-right.fa-lg'),
- h('div.confirm-screen-account-wrapper', [
- h(
- Identicon,
- {
- address: toAddress,
- diameter: 60,
- },
- ),
- h('span.confirm-screen-account-name', toName),
- // h('span.confirm-screen-account-number', toAddress.slice(toAddress.length - 4)),
+ h('.page-container__content', [
+ h('div.flex-row.flex-center.confirm-screen-identicons', [
+ h('div.confirm-screen-account-wrapper', [
+ h(
+ Identicon,
+ {
+ address: fromAddress,
+ diameter: 60,
+ },
+ ),
+ h('span.confirm-screen-account-name', fromName),
+ // h('span.confirm-screen-account-number', fromAddress.slice(fromAddress.length - 4)),
+ ]),
+ h('i.fa.fa-arrow-right.fa-lg'),
+ h('div.confirm-screen-account-wrapper', [
+ h(
+ Identicon,
+ {
+ address: toAddress,
+ diameter: 60,
+ },
+ ),
+ h('span.confirm-screen-account-name', toName),
+ // h('span.confirm-screen-account-number', toAddress.slice(toAddress.length - 4)),
+ ]),
]),
- ]),
- // h('h3.flex-center.confirm-screen-sending-to-message', {
- // style: {
- // textAlign: 'center',
- // fontSize: '16px',
- // },
- // }, [
- // `You're sending to Recipient ...${toAddress.slice(toAddress.length - 4)}`,
- // ]),
-
- this.renderHeroAmount(),
-
- h('div.confirm-screen-rows', [
- h('section.flex-row.flex-center.confirm-screen-row', [
- h('span.confirm-screen-label.confirm-screen-section-column', [ t('from') ]),
- h('div.confirm-screen-section-column', [
- h('div.confirm-screen-row-info', fromName),
- h('div.confirm-screen-row-detail', `...${fromAddress.slice(fromAddress.length - 4)}`),
+ // h('h3.flex-center.confirm-screen-sending-to-message', {
+ // style: {
+ // textAlign: 'center',
+ // fontSize: '16px',
+ // },
+ // }, [
+ // `You're sending to Recipient ...${toAddress.slice(toAddress.length - 4)}`,
+ // ]),
+
+ this.renderHeroAmount(),
+
+ h('div.confirm-screen-rows', [
+ h('section.flex-row.flex-center.confirm-screen-row', [
+ h('span.confirm-screen-label.confirm-screen-section-column', [ t('from') ]),
+ h('div.confirm-screen-section-column', [
+ h('div.confirm-screen-row-info', fromName),
+ h('div.confirm-screen-row-detail', `...${fromAddress.slice(fromAddress.length - 4)}`),
+ ]),
]),
- ]),
- toAddress && h('section.flex-row.flex-center.confirm-screen-row', [
- h('span.confirm-screen-label.confirm-screen-section-column', [ t('to') ]),
- h('div.confirm-screen-section-column', [
- h('div.confirm-screen-row-info', toName),
- h('div.confirm-screen-row-detail', `...${toAddress.slice(toAddress.length - 4)}`),
+ toAddress && h('section.flex-row.flex-center.confirm-screen-row', [
+ h('span.confirm-screen-label.confirm-screen-section-column', [ t('to') ]),
+ h('div.confirm-screen-section-column', [
+ h('div.confirm-screen-row-info', toName),
+ h('div.confirm-screen-row-detail', `...${toAddress.slice(toAddress.length - 4)}`),
+ ]),
]),
- ]),
- this.renderGasFee(),
+ this.renderGasFee(),
- this.renderTotalPlusGas(),
+ this.renderTotalPlusGas(),
- ]),
- ]),
-
- h('form#pending-tx-form', {
- onSubmit: this.onSubmit,
- }, [
- // Cancel Button
- h('div.cancel.btn-light.confirm-screen-cancel-button.allcaps', {
- onClick: (event) => this.cancel(event, txMeta),
- }, t('cancel')),
+ ]),
- // Accept Button
- h('button.confirm-screen-confirm-button.allcaps', [t('confirm')]),
+ ]),
+ h('form#pending-tx-form', {
+ onSubmit: this.onSubmit,
+ }, [
+ h('.page-container__footer', [
+ // Cancel Button
+ h('button.btn-cancel.page-container__footer-button.allcaps', {
+ onClick: (event) => this.cancel(event, txMeta),
+ }, t('cancel')),
+
+ // Accept Button
+ h('button.btn-confirm.page-container__footer-button.allcaps', [t('confirm')]),
+ ]),
+ ]),
]),
-
-
])
)
}
diff --git a/ui/app/components/pending-typed-msg-details.js b/ui/app/components/pending-typed-msg-details.js
deleted file mode 100644
index ae0a1171e..000000000
--- a/ui/app/components/pending-typed-msg-details.js
+++ /dev/null
@@ -1,60 +0,0 @@
-const Component = require('react').Component
-const h = require('react-hyperscript')
-const inherits = require('util').inherits
-
-const AccountPanel = require('./account-panel')
-const TypedMessageRenderer = require('./typed-message-renderer')
-const t = require('../../i18n')
-
-module.exports = PendingMsgDetails
-
-inherits(PendingMsgDetails, Component)
-function PendingMsgDetails () {
- Component.call(this)
-}
-
-PendingMsgDetails.prototype.render = function () {
- var state = this.props
- var msgData = state.txData
-
- var msgParams = msgData.msgParams || {}
- var address = msgParams.from || state.selectedAddress
- var identity = state.identities[address] || { address: address }
- var account = state.accounts[address] || { address: address }
-
- var { data } = msgParams
-
- return (
- h('div', {
- key: msgData.id,
- style: {
- margin: '10px 20px',
- },
- }, [
-
- // account that will sign
- h(AccountPanel, {
- showFullAddress: true,
- identity: identity,
- account: account,
- imageifyIdenticons: state.imageifyIdenticons,
- }),
-
- // message data
- h('div', {
- style: {
- height: '260px',
- },
- }, [
- h('label.font-small.allcaps', { style: { display: 'block' } }, t('youSign')),
- h(TypedMessageRenderer, {
- value: data,
- style: {
- height: '215px',
- },
- }),
- ]),
-
- ])
- )
-}
diff --git a/ui/app/components/pending-typed-msg.js b/ui/app/components/pending-typed-msg.js
deleted file mode 100644
index ccde5e8af..000000000
--- a/ui/app/components/pending-typed-msg.js
+++ /dev/null
@@ -1,47 +0,0 @@
-const Component = require('react').Component
-const h = require('react-hyperscript')
-const inherits = require('util').inherits
-const PendingTxDetails = require('./pending-typed-msg-details')
-const t = require('../../i18n')
-
-module.exports = PendingMsg
-
-inherits(PendingMsg, Component)
-function PendingMsg () {
- Component.call(this)
-}
-
-PendingMsg.prototype.render = function () {
- var state = this.props
- var msgData = state.txData
-
- return (
-
- h('div', {
- key: msgData.id,
- }, [
-
- // header
- h('h3', {
- style: {
- fontWeight: 'bold',
- textAlign: 'center',
- },
- }, t('signMessage')),
-
- // message details
- h(PendingTxDetails, state),
-
- // sign + cancel
- h('.flex-row.flex-space-around', [
- h('button.allcaps', {
- onClick: state.cancelTypedMessage,
- }, t('cancel')),
- h('button.allcaps', {
- onClick: state.signTypedMessage,
- }, t('sign')),
- ]),
- ])
-
- )
-}
diff --git a/ui/app/components/range-slider.js b/ui/app/components/range-slider.js
deleted file mode 100644
index 823f5eb01..000000000
--- a/ui/app/components/range-slider.js
+++ /dev/null
@@ -1,58 +0,0 @@
-const Component = require('react').Component
-const h = require('react-hyperscript')
-const inherits = require('util').inherits
-
-module.exports = RangeSlider
-
-inherits(RangeSlider, Component)
-function RangeSlider () {
- Component.call(this)
-}
-
-RangeSlider.prototype.render = function () {
- const state = this.state || {}
- const props = this.props
- const onInput = props.onInput || function () {}
- const name = props.name
- const {
- min = 0,
- max = 100,
- increment = 1,
- defaultValue = 50,
- mirrorInput = false,
- } = this.props.options
- const {container, input, range} = props.style
-
- return (
- h('.flex-row', {
- style: container,
- }, [
- h('input', {
- type: 'range',
- name: name,
- min: min,
- max: max,
- step: increment,
- style: range,
- value: state.value || defaultValue,
- onChange: mirrorInput ? this.mirrorInputs.bind(this, event) : onInput,
- }),
-
- // Mirrored input for range
- mirrorInput ? h('input.large-input', {
- type: 'number',
- name: `${name}Mirror`,
- min: min,
- max: max,
- value: state.value || defaultValue,
- step: increment,
- style: input,
- onChange: this.mirrorInputs.bind(this, event),
- }) : null,
- ])
- )
-}
-
-RangeSlider.prototype.mirrorInputs = function (event) {
- this.setState({value: event.target.value})
-}
diff --git a/ui/app/components/send-token/index.js b/ui/app/components/send-token/index.js
deleted file mode 100644
index 58743b641..000000000
--- a/ui/app/components/send-token/index.js
+++ /dev/null
@@ -1,440 +0,0 @@
-const Component = require('react').Component
-const connect = require('react-redux').connect
-const h = require('react-hyperscript')
-const classnames = require('classnames')
-const abi = require('ethereumjs-abi')
-const inherits = require('util').inherits
-const actions = require('../../actions')
-const selectors = require('../../selectors')
-const { isValidAddress, allNull } = require('../../util')
-const t = require('../../../i18n')
-
-// const BalanceComponent = require('./balance-component')
-const Identicon = require('../identicon')
-const TokenBalance = require('../token-balance')
-const CurrencyToggle = require('../send/currency-toggle')
-const GasTooltip = require('../send/gas-tooltip')
-const GasFeeDisplay = require('../send/gas-fee-display')
-
-module.exports = connect(mapStateToProps, mapDispatchToProps)(SendTokenScreen)
-
-function mapStateToProps (state) {
- // const sidebarOpen = state.appState.sidebarOpen
-
- const { warning } = state.appState
- const identities = state.metamask.identities
- const addressBook = state.metamask.addressBook
- const conversionRate = state.metamask.conversionRate
- const currentBlockGasLimit = state.metamask.currentBlockGasLimit
- const accounts = state.metamask.accounts
- const selectedTokenAddress = state.metamask.selectedTokenAddress
- const selectedAddress = state.metamask.selectedAddress || Object.keys(accounts)[0]
- const selectedToken = selectors.getSelectedToken(state)
- const tokenExchangeRates = state.metamask.tokenExchangeRates
- const pair = `${selectedToken.symbol.toLowerCase()}_eth`
- const { rate: tokenExchangeRate = 0 } = tokenExchangeRates[pair] || {}
-
- return {
- selectedAddress,
- selectedTokenAddress,
- identities,
- addressBook,
- conversionRate,
- tokenExchangeRate,
- currentBlockGasLimit,
- selectedToken,
- warning,
- }
-}
-
-function mapDispatchToProps (dispatch) {
- return {
- backToAccountDetail: address => dispatch(actions.backToAccountDetail(address)),
- hideWarning: () => dispatch(actions.hideWarning()),
- addToAddressBook: (recipient, nickname) => dispatch(
- actions.addToAddressBook(recipient, nickname)
- ),
- signTx: txParams => dispatch(actions.signTx(txParams)),
- signTokenTx: (tokenAddress, toAddress, amount, txData) => (
- dispatch(actions.signTokenTx(tokenAddress, toAddress, amount, txData))
- ),
- updateTokenExchangeRate: token => dispatch(actions.updateTokenExchangeRate(token)),
- estimateGas: params => dispatch(actions.estimateGas(params)),
- getGasPrice: () => dispatch(actions.getGasPrice()),
- }
-}
-
-inherits(SendTokenScreen, Component)
-function SendTokenScreen () {
- Component.call(this)
- this.state = {
- to: '',
- amount: '0x0',
- amountToSend: '0x0',
- selectedCurrency: 'USD',
- isGasTooltipOpen: false,
- gasPrice: null,
- gasLimit: null,
- errors: {},
- }
-}
-
-SendTokenScreen.prototype.componentWillMount = function () {
- const {
- updateTokenExchangeRate,
- selectedToken: { symbol },
- getGasPrice,
- estimateGas,
- selectedAddress,
- } = this.props
-
- updateTokenExchangeRate(symbol)
-
- const data = Array.prototype.map.call(
- abi.rawEncode(['address', 'uint256'], [selectedAddress, '0x0']),
- x => ('00' + x.toString(16)).slice(-2)
- ).join('')
-
- console.log(data)
- Promise.all([
- getGasPrice(),
- estimateGas({
- from: selectedAddress,
- value: '0x0',
- gas: '746a528800',
- data,
- }),
- ])
- .then(([blockGasPrice, estimatedGas]) => {
- console.log({ blockGasPrice, estimatedGas})
- this.setState({
- gasPrice: blockGasPrice,
- gasLimit: estimatedGas,
- })
- })
-}
-
-SendTokenScreen.prototype.validate = function () {
- const {
- to,
- amount: stringAmount,
- gasPrice: hexGasPrice,
- gasLimit: hexGasLimit,
- } = this.state
-
- const gasPrice = parseInt(hexGasPrice, 16)
- const gasLimit = parseInt(hexGasLimit, 16) / 1000000000
- const amount = Number(stringAmount)
-
- const errors = {
- to: !to ? t('required') : null,
- amount: !amount ? t('required') : null,
- gasPrice: !gasPrice ? t('gasPriceRequired') : null,
- gasLimit: !gasLimit ? t('gasLimitRequired') : null,
- }
-
- if (to && !isValidAddress(to)) {
- errors.to = t('invalidAddress')
- }
-
- const isValid = Object.entries(errors).every(([key, value]) => value === null)
- return {
- isValid,
- errors: isValid ? {} : errors,
- }
-}
-
-SendTokenScreen.prototype.setErrorsFor = function (field) {
- const { errors: previousErrors } = this.state
-
- const {
- isValid,
- errors: newErrors,
- } = this.validate()
-
- const nextErrors = Object.assign({}, previousErrors, {
- [field]: newErrors[field] || null,
- })
-
- if (!isValid) {
- this.setState({
- errors: nextErrors,
- isValid,
- })
- }
-}
-
-SendTokenScreen.prototype.clearErrorsFor = function (field) {
- const { errors: previousErrors } = this.state
- const nextErrors = Object.assign({}, previousErrors, {
- [field]: null,
- })
-
- this.setState({
- errors: nextErrors,
- isValid: allNull(nextErrors),
- })
-}
-
-SendTokenScreen.prototype.getAmountToSend = function (amount, selectedToken) {
- const { decimals } = selectedToken || {}
- const multiplier = Math.pow(10, Number(decimals || 0))
- const sendAmount = '0x' + Number(amount * multiplier).toString(16)
- return sendAmount
-}
-
-SendTokenScreen.prototype.submit = function () {
- const {
- to,
- amount,
- gasPrice,
- gasLimit,
- } = this.state
-
- const {
- identities,
- selectedAddress,
- selectedTokenAddress,
- hideWarning,
- addToAddressBook,
- signTokenTx,
- selectedToken,
- } = this.props
-
- const { nickname = ' ' } = identities[to] || {}
-
- hideWarning()
- addToAddressBook(to, nickname)
-
- const txParams = {
- from: selectedAddress,
- value: '0',
- gas: gasLimit,
- gasPrice: gasPrice,
- }
-
- const sendAmount = this.getAmountToSend(amount, selectedToken)
-
- signTokenTx(selectedTokenAddress, to, sendAmount, txParams)
-}
-
-SendTokenScreen.prototype.renderToAddressInput = function () {
- const {
- identities,
- addressBook,
- } = this.props
-
- const {
- to,
- errors: { to: errorMessage },
- } = this.state
-
- return h('div', {
- className: classnames('send-screen-input-wrapper', {
- 'send-screen-input-wrapper--error': errorMessage,
- }),
- }, [
- h('div', [t('to') + ':']),
- h('input.large-input.send-screen-input', {
- name: 'address',
- list: 'addresses',
- placeholder: t('address'),
- value: to,
- onChange: e => this.setState({
- to: e.target.value,
- errors: {},
- }),
- onBlur: () => {
- this.setErrorsFor('to')
- },
- onFocus: event => {
- if (to) event.target.select()
- this.clearErrorsFor('to')
- },
- }),
- h('datalist#addresses', [
- // Corresponds to the addresses owned.
- Object.entries(identities).map(([key, { address, name }]) => {
- return h('option', {
- value: address,
- label: name,
- key: address,
- })
- }),
- addressBook.map(({ address, name }) => {
- return h('option', {
- value: address,
- label: name,
- key: address,
- })
- }),
- ]),
- h('div.send-screen-input-wrapper__error-message', [ errorMessage ]),
- ])
-}
-
-SendTokenScreen.prototype.renderAmountInput = function () {
- const {
- selectedCurrency,
- amount,
- errors: { amount: errorMessage },
- } = this.state
-
- const {
- tokenExchangeRate,
- selectedToken: {symbol},
- } = this.props
-
- return h('div.send-screen-input-wrapper', {
- className: classnames('send-screen-input-wrapper', {
- 'send-screen-input-wrapper--error': errorMessage,
- }),
- }, [
- h('div.send-screen-amount-labels', [
- h('span', [t('amount')]),
- h(CurrencyToggle, {
- currentCurrency: tokenExchangeRate ? selectedCurrency : 'USD',
- currencies: tokenExchangeRate ? [ symbol, 'USD' ] : [],
- onClick: currency => this.setState({ selectedCurrency: currency }),
- }),
- ]),
- h('input.large-input.send-screen-input', {
- placeholder: `0 ${symbol}`,
- type: 'number',
- value: amount,
- onChange: e => this.setState({
- amount: e.target.value,
- }),
- onBlur: () => {
- this.setErrorsFor('amount')
- },
- onFocus: () => this.clearErrorsFor('amount'),
- }),
- h('div.send-screen-input-wrapper__error-message', [ errorMessage ]),
- ])
-}
-
-SendTokenScreen.prototype.renderGasInput = function () {
- const {
- isGasTooltipOpen,
- gasPrice,
- gasLimit,
- selectedCurrency,
- errors: {
- gasPrice: gasPriceErrorMessage,
- gasLimit: gasLimitErrorMessage,
- },
- } = this.state
-
- const {
- conversionRate,
- tokenExchangeRate,
- currentBlockGasLimit,
- } = this.props
-
- return h('div.send-screen-input-wrapper', {
- className: classnames('send-screen-input-wrapper', {
- 'send-screen-input-wrapper--error': gasPriceErrorMessage || gasLimitErrorMessage,
- }),
- }, [
- isGasTooltipOpen && h(GasTooltip, {
- className: 'send-tooltip',
- gasPrice: gasPrice || '0x0',
- gasLimit: gasLimit || '0x0',
- onClose: () => this.setState({ isGasTooltipOpen: false }),
- onFeeChange: ({ gasLimit, gasPrice }) => {
- this.setState({ gasLimit, gasPrice, errors: {} })
- },
- onBlur: () => {
- this.setErrorsFor('gasLimit')
- this.setErrorsFor('gasPrice')
- },
- onFocus: () => {
- this.clearErrorsFor('gasLimit')
- this.clearErrorsFor('gasPrice')
- },
- }),
-
- h('div.send-screen-gas-labels', {}, [
- h('span', [ h('i.fa.fa-bolt'), t('gasFee') + ':']),
- h('span', [t('whatsThis')]),
- ]),
- h('div.large-input.send-screen-gas-input', [
- h(GasFeeDisplay, {
- conversionRate,
- tokenExchangeRate,
- gasPrice: gasPrice || '0x0',
- activeCurrency: selectedCurrency,
- gas: gasLimit || '0x0',
- blockGasLimit: currentBlockGasLimit,
- }),
- h(
- 'div.send-screen-gas-input-customize',
- { onClick: () => this.setState({ isGasTooltipOpen: !isGasTooltipOpen }) },
- [t('customize')]
- ),
- ]),
- h('div.send-screen-input-wrapper__error-message', [
- gasPriceErrorMessage || gasLimitErrorMessage,
- ]),
- ])
-}
-
-SendTokenScreen.prototype.renderMemoInput = function () {
- return h('div.send-screen-input-wrapper', [
- h('div', {}, [t('transactionMemo')]),
- h(
- 'input.large-input.send-screen-input',
- { onChange: e => this.setState({ memo: e.target.value }) }
- ),
- ])
-}
-
-SendTokenScreen.prototype.renderButtons = function () {
- const { selectedAddress, backToAccountDetail } = this.props
- const { isValid } = this.validate()
-
- return h('div.send-token__button-group', [
- h('button.send-token__button-next.btn-secondary', {
- className: !isValid && 'send-screen__send-button__disabled',
- onClick: () => isValid && this.submit(),
- }, [t('next')]),
- h('button.send-token__button-cancel.btn-tertiary', {
- onClick: () => backToAccountDetail(selectedAddress),
- }, [t('cancel')]),
- ])
-}
-
-SendTokenScreen.prototype.render = function () {
- const {
- selectedTokenAddress,
- selectedToken,
- warning,
- } = this.props
-
- return h('div.send-token', [
- h('div.send-token__content', [
- h(Identicon, {
- diameter: 75,
- address: selectedTokenAddress,
- }),
- h('div.send-token__title', [t('sendTokens')]),
- h('div.send-token__description', [t('sendTokensAnywhere')]),
- h('div.send-token__balance-text', [t('tokenBalance')]),
- h('div.send-token__token-balance', [
- h(TokenBalance, { token: selectedToken, balanceOnly: true }),
- ]),
- h('div.send-token__token-symbol', [selectedToken.symbol]),
- this.renderToAddressInput(),
- this.renderAmountInput(),
- this.renderGasInput(),
- this.renderMemoInput(),
- warning && h('div.send-screen-input-wrapper--error', {},
- h('div.send-screen-input-wrapper__error-message', [
- warning,
- ])
- ),
- ]),
- this.renderButtons(),
- ])
-}
diff --git a/ui/app/components/send/currency-toggle.js b/ui/app/components/send/currency-toggle.js
deleted file mode 100644
index 7aaccd490..000000000
--- a/ui/app/components/send/currency-toggle.js
+++ /dev/null
@@ -1,44 +0,0 @@
-const Component = require('react').Component
-const h = require('react-hyperscript')
-const inherits = require('util').inherits
-const classnames = require('classnames')
-
-module.exports = CurrencyToggle
-
-inherits(CurrencyToggle, Component)
-function CurrencyToggle () {
- Component.call(this)
-}
-
-const defaultCurrencies = [ 'ETH', 'USD' ]
-
-CurrencyToggle.prototype.renderToggles = function () {
- const { onClick, activeCurrency } = this.props
- const [currencyA, currencyB] = this.props.currencies || defaultCurrencies
-
- return [
- h('span', {
- className: classnames('currency-toggle__item', {
- 'currency-toggle__item--selected': currencyA === activeCurrency,
- }),
- onClick: () => onClick(currencyA),
- }, [ currencyA ]),
- '<>',
- h('span', {
- className: classnames('currency-toggle__item', {
- 'currency-toggle__item--selected': currencyB === activeCurrency,
- }),
- onClick: () => onClick(currencyB),
- }, [ currencyB ]),
- ]
-}
-
-CurrencyToggle.prototype.render = function () {
- const currencies = this.props.currencies || defaultCurrencies
-
- return h('span.currency-toggle', currencies.length
- ? this.renderToggles()
- : []
- )
-}
-
diff --git a/ui/app/components/send/eth-fee-display.js b/ui/app/components/send/eth-fee-display.js
deleted file mode 100644
index 9eda5ec62..000000000
--- a/ui/app/components/send/eth-fee-display.js
+++ /dev/null
@@ -1,37 +0,0 @@
-const Component = require('react').Component
-const h = require('react-hyperscript')
-const inherits = require('util').inherits
-const EthBalance = require('../eth-balance')
-const { getTxFeeBn } = require('../../util')
-
-module.exports = EthFeeDisplay
-
-inherits(EthFeeDisplay, Component)
-function EthFeeDisplay () {
- Component.call(this)
-}
-
-EthFeeDisplay.prototype.render = function () {
- const {
- activeCurrency,
- conversionRate,
- gas,
- gasPrice,
- blockGasLimit,
- } = this.props
-
- return h(EthBalance, {
- value: getTxFeeBn(gas, gasPrice, blockGasLimit),
- currentCurrency: activeCurrency,
- conversionRate,
- showFiat: false,
- hideTooltip: true,
- styleOveride: {
- color: '#5d5d5d',
- fontSize: '16px',
- fontFamily: 'DIN OT',
- lineHeight: '22.4px',
- },
- })
-}
-
diff --git a/ui/app/components/send/gas-fee-display.js b/ui/app/components/send/gas-fee-display.js
deleted file mode 100644
index a9a3f3f49..000000000
--- a/ui/app/components/send/gas-fee-display.js
+++ /dev/null
@@ -1,62 +0,0 @@
-const Component = require('react').Component
-const h = require('react-hyperscript')
-const inherits = require('util').inherits
-const USDFeeDisplay = require('./usd-fee-display')
-const EthFeeDisplay = require('./eth-fee-display')
-const { getTxFeeBn, formatBalance, shortenBalance } = require('../../util')
-
-module.exports = GasFeeDisplay
-
-inherits(GasFeeDisplay, Component)
-function GasFeeDisplay () {
- Component.call(this)
-}
-
-GasFeeDisplay.prototype.getTokenValue = function () {
- const {
- tokenExchangeRate,
- gas,
- gasPrice,
- blockGasLimit,
- } = this.props
-
- const value = formatBalance(getTxFeeBn(gas, gasPrice, blockGasLimit), 6, true)
- const [ethNumber] = value.split(' ')
-
- return shortenBalance(Number(ethNumber) / tokenExchangeRate, 6)
-}
-
-GasFeeDisplay.prototype.render = function () {
- const {
- activeCurrency,
- conversionRate,
- gas,
- gasPrice,
- blockGasLimit,
- } = this.props
-
- switch (activeCurrency) {
- case 'USD':
- return h(USDFeeDisplay, {
- activeCurrency,
- conversionRate,
- gas,
- gasPrice,
- blockGasLimit,
- })
- case 'ETH':
- return h(EthFeeDisplay, {
- activeCurrency,
- conversionRate,
- gas,
- gasPrice,
- blockGasLimit,
- })
- default:
- return h('div.token-gas', [
- h('div.token-gas__amount', this.getTokenValue()),
- h('div.token-gas__symbol', activeCurrency),
- ])
- }
-}
-
diff --git a/ui/app/components/send/usd-fee-display.js b/ui/app/components/send/usd-fee-display.js
deleted file mode 100644
index 4cf31a493..000000000
--- a/ui/app/components/send/usd-fee-display.js
+++ /dev/null
@@ -1,35 +0,0 @@
-const Component = require('react').Component
-const h = require('react-hyperscript')
-const inherits = require('util').inherits
-const FiatValue = require('../fiat-value')
-const { getTxFeeBn } = require('../../util')
-
-module.exports = USDFeeDisplay
-
-inherits(USDFeeDisplay, Component)
-function USDFeeDisplay () {
- Component.call(this)
-}
-
-USDFeeDisplay.prototype.render = function () {
- const {
- activeCurrency,
- conversionRate,
- gas,
- gasPrice,
- blockGasLimit,
- } = this.props
-
- return h(FiatValue, {
- value: getTxFeeBn(gas, gasPrice, blockGasLimit),
- conversionRate,
- currentCurrency: activeCurrency,
- style: {
- color: '#5d5d5d',
- fontSize: '16px',
- fontFamily: 'DIN OT',
- lineHeight: '22.4px',
- },
- })
-}
-
diff --git a/ui/app/components/sender-to-recipient.js b/ui/app/components/sender-to-recipient.js
new file mode 100644
index 000000000..25b9c7d6b
--- /dev/null
+++ b/ui/app/components/sender-to-recipient.js
@@ -0,0 +1,45 @@
+const { Component } = require('react')
+const h = require('react-hyperscript')
+const PropTypes = require('prop-types')
+const t = require('../../i18n')
+const Identicon = require('./identicon')
+
+class SenderToRecipient extends Component {
+ render () {
+ const { senderName, senderAddress } = this.props
+
+ return (
+ h('.sender-to-recipient__container', [
+ h('.sender-to-recipient__sender', [
+ h('.sender-to-recipient__sender-icon', [
+ h(Identicon, {
+ address: senderAddress,
+ diameter: 20,
+ }),
+ ]),
+ h('.sender-to-recipient__name.sender-to-recipient__sender-name', senderName),
+ ]),
+ h('.sender-to-recipient__arrow-container', [
+ h('.sender-to-recipient__arrow-circle', [
+ h('img', {
+ height: 15,
+ width: 15,
+ src: '/images/arrow-right.svg',
+ }),
+ ]),
+ ]),
+ h('.sender-to-recipient__recipient', [
+ h('i.fa.fa-file-text-o'),
+ h('.sender-to-recipient__name.sender-to-recipient__recipient-name', t('newContract')),
+ ]),
+ ])
+ )
+ }
+}
+
+SenderToRecipient.propTypes = {
+ senderName: PropTypes.string,
+ senderAddress: PropTypes.string,
+}
+
+module.exports = SenderToRecipient
diff --git a/ui/app/components/template.js b/ui/app/components/template.js
deleted file mode 100644
index b6ed8eaa0..000000000
--- a/ui/app/components/template.js
+++ /dev/null
@@ -1,18 +0,0 @@
-const Component = require('react').Component
-const h = require('react-hyperscript')
-const inherits = require('util').inherits
-
-module.exports = NewComponent
-
-inherits(NewComponent, Component)
-function NewComponent () {
- Component.call(this)
-}
-
-NewComponent.prototype.render = function () {
- const props = this.props
-
- return (
- h('span', props.message)
- )
-}
diff --git a/ui/app/components/transaction-list-item-icon.js b/ui/app/components/transaction-list-item-icon.js
deleted file mode 100644
index f442b05af..000000000
--- a/ui/app/components/transaction-list-item-icon.js
+++ /dev/null
@@ -1,68 +0,0 @@
-const Component = require('react').Component
-const h = require('react-hyperscript')
-const inherits = require('util').inherits
-const Tooltip = require('./tooltip')
-
-const Identicon = require('./identicon')
-
-module.exports = TransactionIcon
-
-inherits(TransactionIcon, Component)
-function TransactionIcon () {
- Component.call(this)
-}
-
-TransactionIcon.prototype.render = function () {
- const { transaction, txParams, isMsg } = this.props
- switch (transaction.status) {
- case 'unapproved':
- return h(!isMsg ? '.unapproved-tx-icon' : 'i.fa.fa-certificate.fa-lg')
-
- case 'rejected':
- return h('i.fa.fa-exclamation-triangle.fa-lg.warning', {
- style: {
- width: '24px',
- },
- })
-
- case 'failed':
- return h('i.fa.fa-exclamation-triangle.fa-lg.error', {
- style: {
- width: '24px',
- },
- })
-
- case 'submitted':
- return h(Tooltip, {
- title: 'Pending',
- position: 'right',
- }, [
- h('i.fa.fa-ellipsis-h', {
- style: {
- fontSize: '27px',
- },
- }),
- ])
- }
-
- if (isMsg) {
- return h('i.fa.fa-certificate.fa-lg', {
- style: {
- width: '24px',
- },
- })
- }
-
- if (txParams.to) {
- return h(Identicon, {
- diameter: 24,
- address: txParams.to || transaction.hash,
- })
- } else {
- return h('i.fa.fa-file-text-o.fa-lg', {
- style: {
- width: '24px',
- },
- })
- }
-}
diff --git a/ui/app/components/transaction-list-item.js b/ui/app/components/transaction-list-item.js
deleted file mode 100644
index 6d6e79bd5..000000000
--- a/ui/app/components/transaction-list-item.js
+++ /dev/null
@@ -1,239 +0,0 @@
-const Component = require('react').Component
-const h = require('react-hyperscript')
-const inherits = require('util').inherits
-const connect = require('react-redux').connect
-
-const EthBalance = require('./eth-balance')
-const addressSummary = require('../util').addressSummary
-const explorerLink = require('etherscan-link').createExplorerLink
-const CopyButton = require('./copyButton')
-const vreme = new (require('vreme'))()
-const Tooltip = require('./tooltip')
-const numberToBN = require('number-to-bn')
-const actions = require('../actions')
-const t = require('../../i18n')
-
-const TransactionIcon = require('./transaction-list-item-icon')
-const ShiftListItem = require('./shift-list-item')
-
-const mapDispatchToProps = dispatch => {
- return {
- retryTransaction: transactionId => dispatch(actions.retryTransaction(transactionId)),
- }
-}
-
-module.exports = connect(null, mapDispatchToProps)(TransactionListItem)
-
-inherits(TransactionListItem, Component)
-function TransactionListItem () {
- Component.call(this)
-}
-
-TransactionListItem.prototype.showRetryButton = function () {
- const { transaction = {} } = this.props
- const { status, time } = transaction
- return status === 'submitted' && Date.now() - time > 30000
-}
-
-TransactionListItem.prototype.render = function () {
- const { transaction, network, conversionRate, currentCurrency } = this.props
- const { status } = transaction
- if (transaction.key === 'shapeshift') {
- if (network === '1') return h(ShiftListItem, transaction)
- }
- var date = formatDate(transaction.time)
-
- let isLinkable = false
- const numericNet = parseInt(network)
- isLinkable = numericNet === 1 || numericNet === 3 || numericNet === 4 || numericNet === 42
-
- var isMsg = ('msgParams' in transaction)
- var isTx = ('txParams' in transaction)
- var isPending = status === 'unapproved'
- let txParams
- if (isTx) {
- txParams = transaction.txParams
- } else if (isMsg) {
- txParams = transaction.msgParams
- }
-
- const nonce = txParams.nonce ? numberToBN(txParams.nonce).toString(10) : ''
-
- const isClickable = ('hash' in transaction && isLinkable) || isPending
- return (
- h('.transaction-list-item.flex-column', {
- onClick: (event) => {
- if (isPending) {
- this.props.showTx(transaction.id)
- }
- event.stopPropagation()
- if (!transaction.hash || !isLinkable) return
- var url = explorerLink(transaction.hash, parseInt(network))
- global.platform.openWindow({ url })
- },
- style: {
- padding: '20px 0',
- alignItems: 'center',
- },
- }, [
- h(`.flex-row.flex-space-between${isClickable ? '.pointer' : ''}`, {
- style: {
- width: '100%',
- },
- }, [
- h('.identicon-wrapper.flex-column.flex-center.select-none', [
- h(TransactionIcon, { txParams, transaction, isTx, isMsg }),
- ]),
-
- h(Tooltip, {
- title: t('transactionNumber'),
- position: 'right',
- }, [
- h('span', {
- style: {
- display: 'flex',
- cursor: 'normal',
- flexDirection: 'column',
- alignItems: 'center',
- justifyContent: 'center',
- padding: '10px',
- },
- }, nonce),
- ]),
-
- h('.flex-column', {style: {width: '200px', overflow: 'hidden'}}, [
- domainField(txParams),
- h('div', date),
- recipientField(txParams, transaction, isTx, isMsg),
- ]),
-
- // Places a copy button if tx is successful, else places a placeholder empty div.
- transaction.hash ? h(CopyButton, { value: transaction.hash }) : h('div', {style: { display: 'flex', alignItems: 'center', width: '26px' }}),
-
- isTx ? h(EthBalance, {
- value: txParams.value,
- conversionRate,
- currentCurrency,
- width: '55px',
- shorten: true,
- showFiat: false,
- style: {fontSize: '15px'},
- }) : h('.flex-column'),
- ]),
-
- this.showRetryButton() && h('.transition-list-item__retry.grow-on-hover', {
- onClick: event => {
- event.stopPropagation()
- this.resubmit()
- },
- style: {
- height: '22px',
- borderRadius: '22px',
- color: '#F9881B',
- padding: '0 20px',
- backgroundColor: '#FFE3C9',
- display: 'flex',
- justifyContent: 'center',
- alignItems: 'center',
- fontSize: '8px',
- cursor: 'pointer',
- },
- }, [
- h('div', {
- style: {
- paddingRight: '2px',
- },
- }, t('takesTooLong')),
- h('div', {
- style: {
- textDecoration: 'underline',
- },
- }, t('retryWithMoreGas')),
- ]),
- ])
- )
-}
-
-TransactionListItem.prototype.resubmit = function () {
- const { transaction } = this.props
- this.props.retryTransaction(transaction.id)
-}
-
-function domainField (txParams) {
- return h('div', {
- style: {
- fontSize: 'x-small',
- color: '#ABA9AA',
- overflow: 'hidden',
- textOverflow: 'ellipsis',
- width: '100%',
- },
- }, [
- txParams.origin,
- ])
-}
-
-function recipientField (txParams, transaction, isTx, isMsg) {
- let message
-
- if (isMsg) {
- message = t('sigRequested')
- } else if (txParams.to) {
- message = addressSummary(txParams.to)
- } else {
- message = t('contractDeployment')
- }
-
- return h('div', {
- style: {
- fontSize: 'x-small',
- color: '#ABA9AA',
- },
- }, [
- message,
- renderErrorOrWarning(transaction),
- ])
-}
-
-function formatDate (date) {
- return vreme.format(new Date(date), 'March 16 2014 14:30')
-}
-
-function renderErrorOrWarning (transaction) {
- const { status } = transaction
-
- // show rejected
- if (status === 'rejected') {
- return h('span.error', ' (' + t('rejected') + ')')
- }
- if (transaction.err || transaction.warning) {
- const { err, warning = {} } = transaction
- const errFirst = !!((err && warning) || err)
-
- errFirst ? err.message : warning.message
-
- // show error
- if (err) {
- const message = err.message || ''
- return (
- h(Tooltip, {
- title: message,
- position: 'bottom',
- }, [
- h(`span.error`, ` (` + t('failed') + `)`),
- ])
- )
- }
-
- // show warning
- if (warning) {
- const message = warning.message
- return h(Tooltip, {
- title: message,
- position: 'bottom',
- }, [
- h(`span.warning`, ` (` + t('warning') + `)`),
- ])
- }
- }
-}
diff --git a/ui/app/components/transaction-list.js b/ui/app/components/transaction-list.js
deleted file mode 100644
index 07f7a06ae..000000000
--- a/ui/app/components/transaction-list.js
+++ /dev/null
@@ -1,87 +0,0 @@
-const Component = require('react').Component
-const h = require('react-hyperscript')
-const inherits = require('util').inherits
-
-const TransactionListItem = require('./transaction-list-item')
-const t = require('../../i18n')
-
-module.exports = TransactionList
-
-
-inherits(TransactionList, Component)
-function TransactionList () {
- Component.call(this)
-}
-
-TransactionList.prototype.render = function () {
- const { transactions, network, unapprovedMsgs, conversionRate } = this.props
-
- var shapeShiftTxList
- if (network === '1') {
- shapeShiftTxList = this.props.shapeShiftTxList
- }
- const txsToRender = !shapeShiftTxList ? transactions.concat(unapprovedMsgs) : transactions.concat(unapprovedMsgs, shapeShiftTxList)
- .sort((a, b) => b.time - a.time)
-
- return (
-
- h('section.transaction-list.full-flex-height', {
- style: {
- justifyContent: 'center',
- },
- }, [
-
- h('style', `
- .transaction-list .transaction-list-item:not(:last-of-type) {
- border-bottom: 1px solid #D4D4D4;
- }
- .transaction-list .transaction-list-item .ether-balance-label {
- display: block !important;
- font-size: small;
- }
- `),
-
- h('.tx-list', {
- style: {
- overflowY: 'auto',
- height: '100%',
- padding: '0 20px',
- textAlign: 'center',
- },
- }, [
-
- txsToRender.length
- ? txsToRender.map((transaction, i) => {
- let key
- switch (transaction.key) {
- case 'shapeshift':
- const { depositAddress, time } = transaction
- key = `shift-tx-${depositAddress}-${time}-${i}`
- break
- default:
- key = `tx-${transaction.id}-${i}`
- }
- return h(TransactionListItem, {
- transaction, i, network, key,
- conversionRate,
- showTx: (txId) => {
- this.props.viewPendingTx(txId)
- },
- })
- })
- : h('.flex-center.full-flex-height', {
- style: {
- flexDirection: 'column',
- justifyContent: 'center',
- },
- }, [
- h('p', {
- style: {
- marginTop: '50px',
- },
- }, t('noTransactionHistory')),
- ]),
- ]),
- ])
- )
-}
diff --git a/ui/app/components/typed-message-renderer.js b/ui/app/components/typed-message-renderer.js
deleted file mode 100644
index d170d63b7..000000000
--- a/ui/app/components/typed-message-renderer.js
+++ /dev/null
@@ -1,42 +0,0 @@
-const Component = require('react').Component
-const h = require('react-hyperscript')
-const inherits = require('util').inherits
-const extend = require('xtend')
-
-module.exports = TypedMessageRenderer
-
-inherits(TypedMessageRenderer, Component)
-function TypedMessageRenderer () {
- Component.call(this)
-}
-
-TypedMessageRenderer.prototype.render = function () {
- const props = this.props
- const { value, style } = props
- const text = renderTypedData(value)
-
- const defaultStyle = extend({
- width: '315px',
- maxHeight: '210px',
- resize: 'none',
- border: 'none',
- background: 'white',
- padding: '3px',
- overflow: 'scroll',
- }, style)
-
- return (
- h('div.font-small', {
- style: defaultStyle,
- }, text)
- )
-}
-
-function renderTypedData (values) {
- return values.map(function (value) {
- return h('div', {}, [
- h('strong', {style: {display: 'block', fontWeight: 'bold'}}, String(value.name) + ':'),
- h('div', {}, value.value),
- ])
- })
-}
diff --git a/ui/app/components/wallet-content-display.js b/ui/app/components/wallet-content-display.js
deleted file mode 100644
index bfa061be4..000000000
--- a/ui/app/components/wallet-content-display.js
+++ /dev/null
@@ -1,56 +0,0 @@
-const Component = require('react').Component
-const h = require('react-hyperscript')
-const inherits = require('util').inherits
-
-module.exports = WalletContentDisplay
-
-inherits(WalletContentDisplay, Component)
-function WalletContentDisplay () {
- Component.call(this)
-}
-
-WalletContentDisplay.prototype.render = function () {
- const { title, amount, fiatValue, active, style } = this.props
-
- // TODO: Separate component: wallet-content-account
- return h('div.flex-column', {
- style: {
- marginLeft: '1.3em',
- alignItems: 'flex-start',
- ...style,
- },
- }, [
-
- h('span', {
- style: {
- fontSize: '1.1em',
- },
- }, title),
-
- h('span', {
- style: {
- fontSize: '1.8em',
- margin: '0.4em 0em',
- },
- }, amount),
-
- h('span', {
- style: {
- fontSize: '1.3em',
- },
- }, fiatValue),
-
- active && h('div', {
- style: {
- position: 'absolute',
- marginLeft: '-1.3em',
- height: '6em',
- width: '0.3em',
- background: '#D8D8D8', // $alto
- },
- }, [
- ]),
- ])
-
-}
-
diff --git a/ui/app/css/itcss/components/buttons.scss b/ui/app/css/itcss/components/buttons.scss
index 1450b71cc..8df8829f2 100644
--- a/ui/app/css/itcss/components/buttons.scss
+++ b/ui/app/css/itcss/components/buttons.scss
@@ -45,6 +45,18 @@
}
}
+.btn-confirm {
+ background-color: $caribbean-green; // TODO: reusable color in colors.css
+ text-align: center;
+ padding: .8rem 1rem;
+ color: $white;
+ border: 2px solid $caribbean-green;
+ border-radius: 4px;
+ font-size: .85rem;
+ font-weight: 400;
+ transition: border-color .3s ease;
+}
+
// No longer used in flat design, remove when modal buttons done
// div.wallet-btn {
// border: 1px solid rgb(91, 93, 103);
diff --git a/ui/app/css/itcss/components/confirm.scss b/ui/app/css/itcss/components/confirm.scss
index 878495290..1977b49ae 100644
--- a/ui/app/css/itcss/components/confirm.scss
+++ b/ui/app/css/itcss/components/confirm.scss
@@ -202,7 +202,7 @@
}
.confirm-screen-label {
- font-size: 18px;
+ font-size: 16px;
line-height: 40px;
color: $scorpion;
text-align: left;
@@ -229,7 +229,6 @@ section .confirm-screen-account-number,
.confirm-screen-row {
display: flex;
flex-flow: row nowrap;
- border-bottom: 1px solid $alto;
width: 100%;
align-items: center;
padding: 12px;
@@ -237,6 +236,10 @@ section .confirm-screen-account-number,
font-size: 16px;
line-height: 22px;
font-weight: 300;
+
+ &:not(:last-of-type) {
+ border-bottom: 1px solid $alto;
+ }
}
.confirm-screen-row-detail {
@@ -247,12 +250,9 @@ section .confirm-screen-account-number,
.confirm-screen-total-box {
background-color: $wild-sand;
- padding: 20px;
- padding-left: 35px;
- border-bottom: 1px solid $alto;
.confirm-screen-label {
- line-height: 18px;
+ line-height: 21px;
}
.confirm-screen-row-detail {
@@ -261,7 +261,7 @@ section .confirm-screen-account-number,
&__subtitle {
font-size: 12px;
- line-height: 22px;
+ line-height: 16px;
}
.confirm-screen-row-info {
@@ -304,21 +304,3 @@ section .confirm-screen-account-number,
font-weight: 300;
margin: 0 5px;
}
-
-#pending-tx-form {
- flex: 1 0 auto;
- position: relative;
- display: flex;
- flex-flow: row nowrap;
- background-color: $white;
- padding: 12px;
- border-bottom-left-radius: 8px;
- border-bottom-right-radius: 8px;
- width: 100%;
-
- @media screen and (max-width: $break-small) {
- border-top: 1px solid $alto;
- border-bottom-left-radius: 0;
- border-bottom-right-radius: 0;
- }
-}
diff --git a/ui/app/css/itcss/components/index.scss b/ui/app/css/itcss/components/index.scss
index f107b7aca..ffd43ecbf 100644
--- a/ui/app/css/itcss/components/index.scss
+++ b/ui/app/css/itcss/components/index.scss
@@ -58,3 +58,4 @@
@import './welcome-screen.scss';
+@import './sender-to-recipient.scss';
diff --git a/ui/app/css/itcss/components/sender-to-recipient.scss b/ui/app/css/itcss/components/sender-to-recipient.scss
new file mode 100644
index 000000000..f16013cdf
--- /dev/null
+++ b/ui/app/css/itcss/components/sender-to-recipient.scss
@@ -0,0 +1,58 @@
+.sender-to-recipient {
+ &__container {
+ width: 100%;
+ display: flex;
+ flex-direction: row;
+ justify-content: center;
+ border-bottom: 1px solid $geyser;
+ position: relative;
+ }
+
+ &__sender,
+ &__recipient {
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ flex: 1;
+ padding: 10px 20px;
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ }
+
+ &__sender {
+ padding-right: 30px;
+ }
+
+ &__recipient {
+ border-left: 1px solid $geyser;
+ padding-left: 30px;
+ }
+
+ &__arrow-container {
+ position: absolute;
+ height: 100%;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ }
+
+ &__arrow-circle {
+ background: $white;
+ padding: 5px;
+ border: 1px solid $geyser;
+ border-radius: 20px;
+ height: 30px;
+ width: 30px;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ }
+
+ &__name {
+ padding-left: 5px;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ }
+}
diff --git a/ui/app/css/itcss/generic/index.scss b/ui/app/css/itcss/generic/index.scss
index 0077cb661..1fbd9896f 100644
--- a/ui/app/css/itcss/generic/index.scss
+++ b/ui/app/css/itcss/generic/index.scss
@@ -82,7 +82,6 @@ input.large-input {
display: flex;
flex-flow: column;
border-radius: 7px;
- height: 100%;
&__header {
display: flex;
@@ -116,7 +115,8 @@ input.large-input {
flex: 0 0 auto;
.btn-clear,
- .btn-cancel {
+ .btn-cancel,
+ .btn-confirm {
font-size: 1rem;
}
}
@@ -134,9 +134,16 @@ input.large-input {
}
}
+ &__back-button {
+ color: #2f9ae0;
+ font-size: 1rem;
+ cursor: pointer;
+ padding-bottom: 10px;
+ font-weight: 400;
+ }
+
&__title {
color: $black;
- font-family: Roboto;
font-size: 2rem;
font-weight: 500;
line-height: 2rem;
@@ -188,6 +195,10 @@ input.large-input {
width: initial;
}
+ &--full-height {
+ height: 100%;
+ }
+
&__content {
height: 100%;
overflow-y: auto;
diff --git a/ui/app/info.js b/ui/app/info.js
deleted file mode 100644
index 49ff9f24a..000000000
--- a/ui/app/info.js
+++ /dev/null
@@ -1,154 +0,0 @@
-const inherits = require('util').inherits
-const Component = require('react').Component
-const h = require('react-hyperscript')
-const connect = require('react-redux').connect
-const actions = require('./actions')
-
-module.exports = connect(mapStateToProps)(InfoScreen)
-
-function mapStateToProps (state) {
- return {}
-}
-
-inherits(InfoScreen, Component)
-function InfoScreen () {
- Component.call(this)
-}
-
-InfoScreen.prototype.render = function () {
- const state = this.props
- const version = global.platform.getVersion()
-
- return (
- h('.flex-column.flex-grow', {
- style: {
- maxWidth: '400px',
- },
- }, [
-
- // subtitle and nav
- h('.section-title.flex-row.flex-center', [
- h('i.fa.fa-arrow-left.fa-lg.cursor-pointer', {
- onClick: (event) => {
- state.dispatch(actions.goHome())
- },
- }),
- h('h2.page-subtitle', 'Info'),
- ]),
-
- // main view
- h('.flex-column.flex-justify-center.flex-grow.select-none', [
- h('.flex-space-around', {
- style: {
- padding: '20px',
- },
- }, [
- // current version number
-
- h('.info.info-gray', [
- h('div', 'Metamask'),
- h('div', {
- style: {
- marginBottom: '10px',
- },
- }, `Version: ${version}`),
- ]),
-
- h('div', {
- style: {
- marginBottom: '5px',
- }},
- [
- h('div', [
- h('a', {
- href: 'https://metamask.io/privacy.html',
- target: '_blank',
- onClick (event) { this.navigateTo(event.target.href) },
- }, [
- h('div.info', 'Privacy Policy'),
- ]),
- ]),
- h('div', [
- h('a', {
- href: 'https://metamask.io/terms.html',
- target: '_blank',
- onClick (event) { this.navigateTo(event.target.href) },
- }, [
- h('div.info', 'Terms of Use'),
- ]),
- ]),
- h('div', [
- h('a', {
- href: 'https://metamask.io/attributions.html',
- target: '_blank',
- onClick (event) { this.navigateTo(event.target.href) },
- }, [
- h('div.info', 'Attributions'),
- ]),
- ]),
- ]
- ),
-
- h('hr', {
- style: {
- margin: '10px 0 ',
- width: '7em',
- },
- }),
-
- h('div', {
- style: {
- paddingLeft: '30px',
- }},
- [
- h('div.fa.fa-support', [
- h('a.info', {
- href: 'https://metamask.helpscoutdocs.com/',
- target: '_blank',
- }, 'Visit our Knowledge Base'),
- ]),
-
- h('div', [
- h('a', {
- href: 'https://metamask.io/',
- target: '_blank',
- }, [
- h('img.icon-size', {
- src: 'images/icon-128.png',
- style: {
- // IE6-9
- filter: 'grayscale(100%)',
- // Microsoft Edge and Firefox 35+
- WebkitFilter: 'grayscale(100%)',
- },
- }),
- h('div.info', 'Visit our web site'),
- ]),
- ]),
-
- h('div', [
- h('.fa.fa-twitter', [
- h('a.info', {
- href: 'https://twitter.com/metamask_io',
- target: '_blank',
- }, 'Follow us on Twitter'),
- ]),
- ]),
-
- h('div.fa.fa-envelope', [
- h('a.info', {
- target: '_blank',
- href: 'mailto:support@metamask.io?subject=MetaMask Support',
- }, 'Email us!'),
- ]),
- ]),
- ]),
- ]),
- ])
- )
-}
-
-InfoScreen.prototype.navigateTo = function (url) {
- global.platform.openWindow({ url })
-}
-
diff --git a/ui/app/send.js b/ui/app/send.js
deleted file mode 100644
index 517b7690d..000000000
--- a/ui/app/send.js
+++ /dev/null
@@ -1,547 +0,0 @@
-// const { inherits } = require('util')
-// const PersistentForm = require('../lib/persistent-form')
-// const h = require('react-hyperscript')
-// const connect = require('react-redux').connect
-// const Identicon = require('./components/identicon')
-// const EnsInput = require('./components/ens-input')
-// const GasTooltip = require('./components/send/gas-tooltip')
-// const CurrencyToggle = require('./components/send/currency-toggle')
-// const GasFeeDisplay = require('./components/send/gas-fee-display')
-// const { getSelectedIdentity } = require('./selectors')
-
-// const {
-// showAccountsPage,
-// backToAccountDetail,
-// displayWarning,
-// hideWarning,
-// addToAddressBook,
-// signTx,
-// estimateGas,
-// getGasPrice,
-// } = require('./actions')
-// const { stripHexPrefix, addHexPrefix } = require('ethereumjs-util')
-// const { isHex, numericBalance, isValidAddress, allNull } = require('./util')
-// const { conversionUtil, conversionGreaterThan } = require('./conversion-util')
-
-// module.exports = connect(mapStateToProps)(SendTransactionScreen)
-
-// function mapStateToProps (state) {
-// const {
-// selectedAddress: address,
-// accounts,
-// identities,
-// network,
-// addressBook,
-// conversionRate,
-// currentBlockGasLimit: blockGasLimit,
-// } = state.metamask
-// const { warning } = state.appState
-// const selectedIdentity = getSelectedIdentity(state)
-// const account = accounts[address]
-
-// return {
-// address,
-// accounts,
-// identities,
-// network,
-// addressBook,
-// conversionRate,
-// blockGasLimit,
-// warning,
-// selectedIdentity,
-// error: warning && warning.split('.')[0],
-// account,
-// identity: identities[address],
-// balance: account ? account.balance : null,
-// }
-// }
-
-// inherits(SendTransactionScreen, PersistentForm)
-// function SendTransactionScreen () {
-// PersistentForm.call(this)
-
-// // [WIP] These are the bare minimum of tx props needed to sign a transaction
-// // We will need a few more for contract-related interactions
-// this.state = {
-// newTx: {
-// from: '',
-// to: '',
-// amountToSend: '0x0',
-// gasPrice: null,
-// gas: null,
-// amount: '0x0',
-// txData: null,
-// memo: '',
-// },
-// activeCurrency: 'USD',
-// tooltipIsOpen: false,
-// errors: {},
-// isValid: false,
-// }
-
-// this.back = this.back.bind(this)
-// this.closeTooltip = this.closeTooltip.bind(this)
-// this.onSubmit = this.onSubmit.bind(this)
-// this.setActiveCurrency = this.setActiveCurrency.bind(this)
-// this.toggleTooltip = this.toggleTooltip.bind(this)
-// this.validate = this.validate.bind(this)
-// this.getAmountToSend = this.getAmountToSend.bind(this)
-// this.setErrorsFor = this.setErrorsFor.bind(this)
-// this.clearErrorsFor = this.clearErrorsFor.bind(this)
-
-// this.renderFromInput = this.renderFromInput.bind(this)
-// this.renderToInput = this.renderToInput.bind(this)
-// this.renderAmountInput = this.renderAmountInput.bind(this)
-// this.renderGasInput = this.renderGasInput.bind(this)
-// this.renderMemoInput = this.renderMemoInput.bind(this)
-// this.renderErrorMessage = this.renderErrorMessage.bind(this)
-// }
-
-// SendTransactionScreen.prototype.componentWillMount = function () {
-// const { newTx } = this.state
-// const { address } = this.props
-
-// Promise.all([
-// this.props.dispatch(getGasPrice()),
-// this.props.dispatch(estimateGas({
-// from: address,
-// gas: '746a528800',
-// })),
-// ])
-// .then(([blockGasPrice, estimatedGas]) => {
-// console.log({ blockGasPrice, estimatedGas})
-// this.setState({
-// newTx: {
-// ...newTx,
-// gasPrice: blockGasPrice,
-// gas: estimatedGas,
-// },
-// })
-// })
-// }
-
-// SendTransactionScreen.prototype.renderErrorMessage = function(errorType, warning) {
-// const { errors } = this.state
-// const errorMessage = errors[errorType];
-
-// return errorMessage || warning
-// ? h('div.send-screen-input-wrapper__error-message', [ errorMessage || warning ])
-// : null
-// }
-
-// SendTransactionScreen.prototype.renderFromInput = function (from, identities) {
-// return h('div.send-screen-input-wrapper', [
-
-// h('div', 'From:'),
-
-// h('input.large-input.send-screen-input', {
-// list: 'accounts',
-// placeholder: 'Account',
-// value: from,
-// onChange: (event) => {
-// this.setState({
-// newTx: {
-// ...this.state.newTx,
-// from: event.target.value,
-// },
-// })
-// },
-// onBlur: () => this.setErrorsFor('from'),
-// onFocus: event => {
-// this.clearErrorsFor('from')
-// this.state.newTx.from && event.target.select()
-// },
-// }),
-
-// h('datalist#accounts', [
-// Object.entries(identities).map(([key, { address, name }]) => {
-// return h('option', {
-// value: address,
-// label: name,
-// key: address,
-// })
-// }),
-// ]),
-
-// this.renderErrorMessage('from'),
-
-// ])
-// }
-
-// SendTransactionScreen.prototype.renderToInput = function (to, identities, addressBook) {
-// return h('div.send-screen-input-wrapper', [
-
-// h('div', 'To:'),
-
-// h('input.large-input.send-screen-input', {
-// name: 'address',
-// list: 'addresses',
-// placeholder: 'Address',
-// value: to,
-// onChange: (event) => {
-// this.setState({
-// newTx: {
-// ...this.state.newTx,
-// to: event.target.value,
-// },
-// })
-// },
-// onBlur: () => {
-// this.setErrorsFor('to')
-// },
-// onFocus: event => {
-// this.clearErrorsFor('to')
-// this.state.newTx.to && event.target.select()
-// },
-// }),
-
-// h('datalist#addresses', [
-// // Corresponds to the addresses owned.
-// ...Object.entries(identities).map(([key, { address, name }]) => {
-// return h('option', {
-// value: address,
-// label: name,
-// key: address,
-// })
-// }),
-// // Corresponds to previously sent-to addresses.
-// ...addressBook.map(({ address, name }) => {
-// return h('option', {
-// value: address,
-// label: name,
-// key: address,
-// })
-// }),
-// ]),
-
-// this.renderErrorMessage('to'),
-
-// ])
-// }
-
-// SendTransactionScreen.prototype.renderAmountInput = function (activeCurrency) {
-// return h('div.send-screen-input-wrapper', [
-
-// h('div.send-screen-amount-labels', [
-// h('span', 'Amount'),
-// h(CurrencyToggle, {
-// activeCurrency,
-// onClick: (newCurrency) => this.setActiveCurrency(newCurrency),
-// }), // holding on icon from design
-// ]),
-
-// h('input.large-input.send-screen-input', {
-// placeholder: `0 ${activeCurrency}`,
-// type: 'number',
-// onChange: (event) => {
-// const amountToSend = event.target.value
-// ? this.getAmountToSend(event.target.value)
-// : '0x0'
-
-// this.setState({
-// newTx: Object.assign(
-// this.state.newTx,
-// {
-// amount: event.target.value,
-// amountToSend: amountToSend,
-// }
-// ),
-// })
-// },
-// onBlur: () => {
-// this.setErrorsFor('amount')
-// },
-// onFocus: () => this.clearErrorsFor('amount'),
-// }),
-
-// this.renderErrorMessage('amount'),
-
-// ])
-// }
-
-// SendTransactionScreen.prototype.renderGasInput = function (gasPrice, gas, activeCurrency, conversionRate, blockGasLimit) {
-// return h('div.send-screen-input-wrapper', [
-// this.state.tooltipIsOpen && h(GasTooltip, {
-// className: 'send-tooltip',
-// gasPrice,
-// gasLimit: gas,
-// onClose: this.closeTooltip,
-// onFeeChange: ({gasLimit, gasPrice}) => {
-// this.setState({
-// newTx: {
-// ...this.state.newTx,
-// gas: gasLimit,
-// gasPrice,
-// },
-// })
-// },
-// }),
-
-// h('div.send-screen-gas-labels', [
-// h('span', [
-// h('i.fa.fa-bolt'),
-// 'Gas fee:',
-// ]),
-// h('span', 'What\'s this?'),
-// ]),
-
-// // TODO: handle loading time when switching to USD
-// h('div.large-input.send-screen-gas-input', {}, [
-// h(GasFeeDisplay, {
-// activeCurrency,
-// conversionRate,
-// gas,
-// gasPrice,
-// blockGasLimit,
-// }),
-// h('div.send-screen-gas-input-customize', {
-// onClick: this.toggleTooltip,
-// }, [
-// 'Customize',
-// ]),
-// ]),
-
-// ])
-// }
-
-// SendTransactionScreen.prototype.renderMemoInput = function () {
-// return h('div.send-screen-input-wrapper', [
-// h('div', 'Transaction memo (optional)'),
-// h('input.large-input.send-screen-input', {
-// onChange: () => {
-// this.setState({
-// newTx: Object.assign(
-// this.state.newTx,
-// {
-// memo: event.target.value,
-// }
-// ),
-// })
-// },
-// }),
-// ])
-// }
-
-// SendTransactionScreen.prototype.render = function () {
-// this.persistentFormParentId = 'send-tx-form'
-
-// const props = this.props
-// const {
-// warning,
-// identities,
-// addressBook,
-// conversionRate,
-// } = props
-
-// const {
-// blockGasLimit,
-// newTx,
-// activeCurrency,
-// isValid,
-// } = this.state
-// const { gas, gasPrice } = newTx
-
-// return (
-
-// h('div.send-screen-wrapper', [
-// // Main Send token Card
-// h('div.send-screen-card', [
-
-// h('img.send-eth-icon', { src: '../images/eth_logo.svg' }),
-
-// h('div.send-screen__title', 'Send'),
-
-// h('div.send-screen__subtitle', 'Send Ethereum to anyone with an Ethereum account'),
-
-// this.renderFromInput(this.state.newTx.from, identities),
-
-// this.renderToInput(this.state.newTx.to, identities, addressBook),
-
-// this.renderAmountInput(activeCurrency),
-
-// this.renderGasInput(
-// gasPrice || '0x0',
-// gas || '0x0',
-// activeCurrency,
-// conversionRate,
-// blockGasLimit
-// ),
-
-// this.renderMemoInput(),
-
-// this.renderErrorMessage(null, warning),
-
-// ]),
-
-// // Buttons underneath card
-// h('section.flex-column.flex-center', [
-// h('button.btn-secondary.send-screen__send-button', {
-// className: !isValid && 'send-screen__send-button__disabled',
-// onClick: (event) => isValid && this.onSubmit(event),
-// }, 'Next'),
-// h('button.btn-tertiary.send-screen__cancel-button', {
-// onClick: this.back,
-// }, 'Cancel'),
-// ]),
-// ])
-
-// )
-// }
-
-// SendTransactionScreen.prototype.toggleTooltip = function () {
-// this.setState({ tooltipIsOpen: !this.state.tooltipIsOpen })
-// }
-
-// SendTransactionScreen.prototype.closeTooltip = function () {
-// this.setState({ tooltipIsOpen: false })
-// }
-
-// SendTransactionScreen.prototype.setActiveCurrency = function (newCurrency) {
-// this.setState({ activeCurrency: newCurrency })
-// }
-
-// SendTransactionScreen.prototype.back = function () {
-// var address = this.props.address
-// this.props.dispatch(backToAccountDetail(address))
-// }
-
-// SendTransactionScreen.prototype.validate = function (balance, amountToSend, { to, from }) {
-// const sufficientBalance = conversionGreaterThan(
-// {
-// value: balance,
-// fromNumericBase: 'hex',
-// },
-// {
-// value: amountToSend,
-// fromNumericBase: 'hex',
-// },
-// )
-
-// const amountLessThanZero = conversionGreaterThan(
-// {
-// value: 0,
-// fromNumericBase: 'dec',
-// },
-// {
-// value: amountToSend,
-// fromNumericBase: 'hex',
-// },
-// )
-
-// const errors = {}
-
-// if (!sufficientBalance) {
-// errors.amount = 'Insufficient funds.'
-// }
-
-// if (amountLessThanZero) {
-// errors.amount = 'Can not send negative amounts of ETH.'
-// }
-
-// if (!from) {
-// errors.from = 'Required'
-// }
-
-// if (from && !isValidAddress(from)) {
-// errors.from = 'Sender address is invalid.'
-// }
-
-// if (!to) {
-// errors.to = 'Required'
-// }
-
-// if (to && !isValidAddress(to)) {
-// errors.to = 'Recipient address is invalid.'
-// }
-
-// // if (txData && !isHex(stripHexPrefix(txData))) {
-// // message = 'Transaction data must be hex string.'
-// // return this.props.dispatch(displayWarning(message))
-// // }
-
-// return {
-// isValid: allNull(errors),
-// errors,
-// }
-// }
-
-// SendTransactionScreen.prototype.getAmountToSend = function (amount) {
-// const { activeCurrency } = this.state
-// const { conversionRate } = this.props
-
-// return conversionUtil(amount, {
-// fromNumericBase: 'dec',
-// toNumericBase: 'hex',
-// fromCurrency: activeCurrency,
-// toCurrency: 'ETH',
-// toDenomination: 'WEI',
-// conversionRate,
-// invertConversionRate: activeCurrency !== 'ETH',
-// })
-// }
-
-// SendTransactionScreen.prototype.setErrorsFor = function (field) {
-// const { balance } = this.props
-// const { newTx, errors: previousErrors } = this.state
-// const { amountToSend } = newTx
-
-// const {
-// isValid,
-// errors: newErrors
-// } = this.validate(balance, amountToSend, newTx)
-
-// const nextErrors = Object.assign({}, previousErrors, {
-// [field]: newErrors[field] || null
-// })
-
-// if (!isValid) {
-// this.setState({
-// errors: nextErrors,
-// isValid,
-// })
-// }
-// }
-
-// SendTransactionScreen.prototype.clearErrorsFor = function (field) {
-// const { errors: previousErrors } = this.state
-// const nextErrors = Object.assign({}, previousErrors, {
-// [field]: null
-// })
-
-// this.setState({
-// errors: nextErrors,
-// isValid: allNull(nextErrors),
-// })
-// }
-
-// SendTransactionScreen.prototype.onSubmit = function (event) {
-// event.preventDefault()
-// const { warning, balance } = this.props
-// const state = this.state || {}
-
-// const recipient = state.newTx.to
-// const sender = state.newTx.from
-// const nickname = state.nickname || ' '
-
-// // TODO: convert this to hex when created and include it in send
-// const txData = state.newTx.memo
-
-// this.props.dispatch(hideWarning())
-
-// this.props.dispatch(addToAddressBook(recipient, nickname))
-
-// var txParams = {
-// from: this.state.newTx.from,
-// to: this.state.newTx.to,
-
-// value: this.state.newTx.amountToSend,
-
-// gas: this.state.newTx.gas,
-// gasPrice: this.state.newTx.gasPrice,
-// }
-
-// if (recipient) txParams.to = addHexPrefix(recipient)
-// if (txData) txParams.data = txData
-
-// this.props.dispatch(signTx(txParams))
-// }
diff --git a/ui/app/template.js b/ui/app/template.js
deleted file mode 100644
index d15b30fd2..000000000
--- a/ui/app/template.js
+++ /dev/null
@@ -1,30 +0,0 @@
-const inherits = require('util').inherits
-const Component = require('react').Component
-const h = require('react-hyperscript')
-const connect = require('react-redux').connect
-
-module.exports = connect(mapStateToProps)(COMPONENTNAME)
-
-function mapStateToProps (state) {
- return {}
-}
-
-inherits(COMPONENTNAME, Component)
-function COMPONENTNAME () {
- Component.call(this)
-}
-
-COMPONENTNAME.prototype.render = function () {
- const props = this.props
-
- return (
- h('div', {
- style: {
- background: 'blue',
- },
- }, [
- `Hello, ${props.sender}`,
- ])
- )
-}
-
diff --git a/ui/app/token-tracker.js b/ui/app/token-tracker.js
deleted file mode 100644
index e69de29bb..000000000
--- a/ui/app/token-tracker.js
+++ /dev/null
diff --git a/ui/lib/contract-namer.js b/ui/lib/contract-namer.js
deleted file mode 100644
index f05e770cc..000000000
--- a/ui/lib/contract-namer.js
+++ /dev/null
@@ -1,33 +0,0 @@
-/* CONTRACT NAMER
- *
- * Takes an address,
- * Returns a nicname if we have one stored,
- * otherwise returns null.
- */
-
-const contractMap = require('eth-contract-metadata')
-const ethUtil = require('ethereumjs-util')
-
-module.exports = function (addr, identities = {}) {
- const checksummed = ethUtil.toChecksumAddress(addr)
- if (contractMap[checksummed] && contractMap[checksummed].name) {
- return contractMap[checksummed].name
- }
-
- const address = addr.toLowerCase()
- const ids = hashFromIdentities(identities)
- return addrFromHash(address, ids)
-}
-
-function hashFromIdentities (identities) {
- const result = {}
- for (const key in identities) {
- result[key] = identities[key].name
- }
- return result
-}
-
-function addrFromHash (addr, hash) {
- const address = addr.toLowerCase()
- return hash[address] || null
-}