Merge branch 'master' into selenium-e2e

feature/default_network_editable
Thomas Huang 7 years ago committed by GitHub
commit 8648aee907
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 21
      CHANGELOG.md
  2. 2
      README.md
  3. 15
      app/_locales/en/messages.json
  4. 100
      app/_locales/es/messages.json
  5. 76
      app/_locales/ja/messages.json
  6. 819
      app/_locales/sl/messages.json
  7. 819
      app/_locales/th/messages.json
  8. 903
      app/_locales/zh_TW/messages.json
  9. 2
      app/manifest.json
  10. 11
      app/scripts/background.js
  11. 11
      app/scripts/lib/notification-manager.js
  12. 32
      app/scripts/lib/setupRaven.js
  13. 39
      app/scripts/migrations/022.js
  14. 1
      app/scripts/migrations/index.js
  15. 1
      app/scripts/popup.js
  16. 3
      app/scripts/vendor/raven.min.js
  17. 6
      gulpfile.js
  18. 9
      mascara/src/app/first-time/index.css
  19. 7
      mascara/src/app/first-time/index.js
  20. 68
      package-lock.json
  21. 11
      package.json
  22. 39
      test/integration/lib/add-token.js
  23. 6
      test/integration/lib/confirm-sig-requests.js
  24. 6
      test/integration/lib/mascara-first-time.js
  25. 8
      test/integration/lib/send-new-ui.js
  26. 32
      test/unit/migrations/022-test.js
  27. 4
      ui/app/accounts/import/json.js
  28. 4
      ui/app/accounts/import/private-key.js
  29. 4
      ui/app/accounts/new-account/create-form.js
  30. 4
      ui/app/actions.js
  31. 102
      ui/app/add-token.js
  32. 6
      ui/app/app.js
  33. 8
      ui/app/components/customize-gas-modal/index.js
  34. 41
      ui/app/components/ens-input.js
  35. 4
      ui/app/components/modals/account-details-modal.js
  36. 2
      ui/app/components/modals/deposit-ether-modal.js
  37. 6
      ui/app/components/modals/export-private-key-modal.js
  38. 1
      ui/app/components/pending-tx/confirm-send-token.js
  39. 18
      ui/app/components/pending-tx/index.js
  40. 4
      ui/app/components/send/send-v2-container.js
  41. 2
      ui/app/components/shapeshift-form.js
  42. 4
      ui/app/components/signature-request.js
  43. 6
      ui/app/components/tx-view.js
  44. 2
      ui/app/components/wallet-view.js
  45. 185
      ui/app/css/itcss/components/add-token.scss
  46. 84
      ui/app/css/itcss/components/buttons.scss
  47. 3
      ui/app/css/itcss/components/hero-balance.scss
  48. 13
      ui/app/css/itcss/components/modal.scss
  49. 25
      ui/app/css/itcss/components/new-account.scss
  50. 33
      ui/app/css/itcss/components/request-signature.scss
  51. 8
      ui/app/css/itcss/components/send.scss
  52. 36
      ui/app/css/itcss/components/settings.scss
  53. 2
      ui/app/css/itcss/generic/index.scss
  54. 3
      ui/app/css/itcss/settings/variables.scss
  55. 4
      ui/app/reducers/metamask.js
  56. 3
      ui/app/selectors.js
  57. 24
      ui/app/send-v2.js
  58. 8
      ui/app/settings.js
  59. 44
      yarn.lock

@ -2,11 +2,26 @@
## Current Master ## Current Master
- MetaMask will no longer allow nonces to be specified by the dapp ## 4.4.0 Mon Mar 26 2018
- Add ability for internationalization.
- Internationalization: Taiwanese, Thai, Slovenian
- Fixes bug where MetaMask would not open once its storage grew too large.
- Updates design of new-ui Add Token screen
- New-ui can send to ens addresses
- Update new-ui button styles
- Signed-type-data notification handles long messages
- Popup extension in new-ui uses new on-boarding designs
- Buy ether step of new-ui on-boarding uses new buy ether modal designs
## 4.3.0 Wed Mar 21 2018
- (beta) Add internationalization support! Includes translations for 13 (!!) new languages: French, Spanish, Italian, German, Dutch, Portuguese, Japanese, Korean, Vietnamese, Mandarin, Hindi, Tagalog, and Russian! Select "Try Beta" in the menu to take them for a spin. Read more about the community effort [here](https://medium.com/gitcoin/metamask-internationalizes-via-gitcoin-bf1390c0301c)
- No longer uses nonces specified by the dapp
- Will now throw an error if the `to` field in txParams is not valid. - Will now throw an error if the `to` field in txParams is not valid.
- Will strip null values from the `to` field. - Will strip null values from the `to` field.
- Fix flashing to Log in screen after logging in or restoring from seed phrase. - (beta) No longer shows token confirmation screen when performing a non-send
- (beta) Fixes bug where tx data was nullified when repricing a tx
- Fix flashing Login screen after logging in or restoring from seed phrase.
- Increase tap areas for menu buttons on mobile - Increase tap areas for menu buttons on mobile
- Change all fonts in new-ui onboarding to Roboto, size 400 - Change all fonts in new-ui onboarding to Roboto, size 400
- Add a welcome screen to new-ui onboarding flow - Add a welcome screen to new-ui onboarding flow

@ -1,5 +1,5 @@
# MetaMask Browser Extension # MetaMask Browser Extension
[![Build Status](https://circleci.com/gh/MetaMask/metamask-extension.svg?style=shield&circle-token=a1ddcf3cd38e29267f254c9c59d556d513e3a1fd)](https://circleci.com/gh/MetaMask/metamask-extension) [![Coverage Status](https://coveralls.io/repos/github/MetaMask/metamask-extension/badge.svg?branch=master)](https://coveralls.io/github/MetaMask/metamask-extension?branch=master) [![Greenkeeper badge](https://badges.greenkeeper.io/MetaMask/metamask-extension.svg)](https://greenkeeper.io/) [![Stories in Ready](https://badge.waffle.io/MetaMask/metamask-extension.png?label=in%20progress&title=waffle.io)](http://waffle.io/MetaMask/metamask-extension) [![Build Status](https://circleci.com/gh/MetaMask/metamask-extension.svg?style=shield&circle-token=a1ddcf3cd38e29267f254c9c59d556d513e3a1fd)](https://circleci.com/gh/MetaMask/metamask-extension) [![Coverage Status](https://coveralls.io/repos/github/MetaMask/metamask-extension/badge.svg?branch=master)](https://coveralls.io/github/MetaMask/metamask-extension?branch=master) [![Greenkeeper badge](https://badges.greenkeeper.io/MetaMask/metamask-extension.svg)](https://greenkeeper.io/) [![Stories in Ready](https://badge.waffle.io/MetaMask/metamask-extension.png?label=in%20progress&title=waffle.io)](https://waffle.io/MetaMask/metamask-extension)
## Support ## Support

@ -171,6 +171,9 @@
"customGas": { "customGas": {
"message": "Customize Gas" "message": "Customize Gas"
}, },
"customToken": {
"message": "Custom Token"
},
"customize": { "customize": {
"message": "Customize" "message": "Customize"
}, },
@ -415,6 +418,9 @@
"message": "JSON File", "message": "JSON File",
"description": "format for importing an account" "description": "format for importing an account"
}, },
"keepTrackTokens": {
"message": "Keep track of the tokens you’ve bought with your MetaMask account."
},
"kovan": { "kovan": {
"message": "Kovan Test Network" "message": "Kovan Test Network"
}, },
@ -424,6 +430,9 @@
"max": { "max": {
"message": "Max" "message": "Max"
}, },
"learnMore": {
"message": "Learn more."
},
"lessThanMax": { "lessThanMax": {
"message": "must be less than or equal to $1.", "message": "must be less than or equal to $1.",
"description": "helper for inputting hex as decimal input" "description": "helper for inputting hex as decimal input"
@ -564,6 +573,9 @@
"pleaseReviewTransaction": { "pleaseReviewTransaction": {
"message": "Please review your transaction." "message": "Please review your transaction."
}, },
"popularTokens": {
"message": "Popular Tokens"
},
"privacyMsg": { "privacyMsg": {
"message": "Privacy Policy" "message": "Privacy Policy"
}, },
@ -702,6 +714,9 @@
"onlySendToEtherAddress": { "onlySendToEtherAddress": {
"message": "Only send ETH to an Ethereum address." "message": "Only send ETH to an Ethereum address."
}, },
"searchTokens": {
"message": "Search Tokens"
},
"sendTokensAnywhere": { "sendTokensAnywhere": {
"message": "Send Tokens to anyone with an Ethereum account" "message": "Send Tokens to anyone with an Ethereum account"
}, },

@ -84,7 +84,7 @@
"message": "Comprar en Coinbase" "message": "Comprar en Coinbase"
}, },
"buyCoinbaseExplainer": { "buyCoinbaseExplainer": {
"message": "Coinbase es la forma global más popular para comprar y vender bitcoin, ethereum y litecoin" "message": "Coinbase es la plataforma global más popular para comprar y vender Bitcoin, Ethereum y Litecoin"
}, },
"cancel": { "cancel": {
"message": "Cancelar" "message": "Cancelar"
@ -144,7 +144,7 @@
"message": "Copiado al portapapeles" "message": "Copiado al portapapeles"
}, },
"copiedExclamation": { "copiedExclamation": {
"message": "Copiado!" "message": "¡Copiado!"
}, },
"copiedSafe": { "copiedSafe": {
"message": "Ya lo guardé en un lugar seguro" "message": "Ya lo guardé en un lugar seguro"
@ -156,7 +156,7 @@
"message": " Copiar " "message": " Copiar "
}, },
"copyPrivateKey": { "copyPrivateKey": {
"message": "Esta es tu llave privada (Click para copiar)" "message": "Ésta es tu llave privada (haz click para copiar)"
}, },
"copyToClipboard": { "copyToClipboard": {
"message": "Copiar al portapapeles" "message": "Copiar al portapapeles"
@ -165,17 +165,17 @@
"message": "Crear" "message": "Crear"
}, },
"createAccount": { "createAccount": {
"message": "Crear Cuenta" "message": "Crear cuenta"
}, },
"createDen": { "createDen": {
"message": "Crear" "message": "Crear"
}, },
"crypto": { "crypto": {
"message": "Crypto", "message": "Crypto",
"description": "Tipo de Cambio (criptomonedas)" "description": "Tipo de cambio (criptomonedas)"
}, },
"currentConversion": { "currentConversion": {
"message": "Conversión Actual" "message": "Conversión actual"
}, },
"currentNetwork": { "currentNetwork": {
"message": "Red actual" "message": "Red actual"
@ -184,10 +184,10 @@
"message": "RPC actual" "message": "RPC actual"
}, },
"customGas": { "customGas": {
"message": "Personalizar Gas" "message": "Personalizar gas"
}, },
"customRPC": { "customRPC": {
"message": "RPC Personalizado" "message": "RPC personalizado"
}, },
"customize": { "customize": {
"message": "Personalizar" "message": "Personalizar"
@ -202,7 +202,7 @@
"message": "La red por defecto para las transacciones de Ether es MainNet (red principal)" "message": "La red por defecto para las transacciones de Ether es MainNet (red principal)"
}, },
"denExplainer": { "denExplainer": {
"message": "Tu DEN es tu contraseña encriptada guardada dentro de MetaMask" "message": "El DEN es tu contraseña encriptada almacenada dentro de MetaMask"
}, },
"deposit": { "deposit": {
"message": "Depositar" "message": "Depositar"
@ -221,7 +221,7 @@
"message": "Depositar Ether" "message": "Depositar Ether"
}, },
"depositFiat": { "depositFiat": {
"message": "Depositar con Fiat (divisa nacional)" "message": "Depositar con fiat (divisa nacional)"
}, },
"depositFromAccount": { "depositFromAccount": {
"message": "Depositar con otra cuenta" "message": "Depositar con otra cuenta"
@ -230,7 +230,7 @@
"message": "Depositar con ShapeShift" "message": "Depositar con ShapeShift"
}, },
"depositShapeShiftExplainer": { "depositShapeShiftExplainer": {
"message": "Si tu tienes otras criptomonedas, puedes intercambiar y depositar Ether directamente en tu billetera de MetaMask. No necesitas tener una cuenta" "message": "Si posees otras criptomonedas, puedes intercambiar y depositar Ether directamente en tu billetera de MetaMask. No necesitas tener una cuenta."
}, },
"details": { "details": {
"message": "Detalles" "message": "Detalles"
@ -242,7 +242,7 @@
"message": "Depositar Ether directamente" "message": "Depositar Ether directamente"
}, },
"directDepositEtherExplainer": { "directDepositEtherExplainer": {
"message": "Si tu tienes algo de Ether, la forma rápida para tener Ether en tu nueva billetera es depositando directamente" "message": "Si posees Ether, la forma más rápida de transferirlo a tu nueva billetera es depositándolo directamente"
}, },
"done": { "done": {
"message": "Completo" "message": "Completo"
@ -260,7 +260,7 @@
"message": "Editar el nombre de la cuenta" "message": "Editar el nombre de la cuenta"
}, },
"emailUs": { "emailUs": {
"message": "Envíanos un correo!" "message": "¡Envíanos un correo!"
}, },
"encryptNewDen": { "encryptNewDen": {
"message": "Encriptar tu nuevo DEN" "message": "Encriptar tu nuevo DEN"
@ -291,7 +291,7 @@
"description": "Tipo de cambio" "description": "Tipo de cambio"
}, },
"fileImportFail": { "fileImportFail": {
"message": "No funciona importar el archivo? Haz Click Aquí!", "message": "¿La importación no funcionó? ¡Haz click aquí!",
"description": "Ayuda al usuario a importar su cuenta desde un archivo JSON" "description": "Ayuda al usuario a importar su cuenta desde un archivo JSON"
}, },
"followTwitter": { "followTwitter": {
@ -320,7 +320,7 @@
"message": "Calculamos el límite de gas sugerido en función de las tasas de éxito de la red" "message": "Calculamos el límite de gas sugerido en función de las tasas de éxito de la red"
}, },
"gasLimitRequired": { "gasLimitRequired": {
"message": "Límite de Gas requerido" "message": "Límite de gas requerido"
}, },
"gasLimitTooLow": { "gasLimitTooLow": {
"message": "El límite de gas debe ser de al menos 21000" "message": "El límite de gas debe ser de al menos 21000"
@ -353,22 +353,22 @@
"description": "como en -haz click aquí- para más información" "description": "como en -haz click aquí- para más información"
}, },
"hereList": { "hereList": {
"message": "Aquí está una lista!!!" "message": "¡¡¡Aquí está una lista!!!"
}, },
"hide": { "hide": {
"message": "Ocultar" "message": "Ocultar"
}, },
"hideToken": { "hideToken": {
"message": "Ocultar Token" "message": "Ocultar token"
}, },
"hideTokenPrompt": { "hideTokenPrompt": {
"message": "Ocultar Token?" "message": "¿Ocultar token?"
}, },
"holdEther": { "holdEther": {
"message": "Te permite mantener tus ether y tokens, así como puente para aplicaciones descentralizadas" "message": "Te permite mantener tus ether y tokens, así como puente para aplicaciones descentralizadas"
}, },
"howToDeposit": { "howToDeposit": {
"message": "Cómo te gustaria depositar Ether?" "message": "¿Cómo te gustaria depositar Ether?"
}, },
"import": { "import": {
"message": "Importar", "message": "Importar",
@ -388,13 +388,13 @@
"description": "Estado que muestra que una cuenta ha sido completamente cargada en el llavero" "description": "Estado que muestra que una cuenta ha sido completamente cargada en el llavero"
}, },
"importAccountMsg": { "importAccountMsg": {
"message": "Cuentas importadas no serán asociadas con tu cuenta original creada con tu MetaMask. Aprende más acerca de importar cuentas." "message": "Las cuentas importadas no serán asociadas con tu cuenta original creada con tu MetaMask. Aprende más acerca de importar cuentas."
}, },
"info": { "info": {
"message": "Información" "message": "Información"
}, },
"infoHelp": { "infoHelp": {
"message": "Informacion y Ayuda" "message": "Informacion y ayuda"
}, },
"insufficientFunds": { "insufficientFunds": {
"message": "Fondos insuficientes" "message": "Fondos insuficientes"
@ -421,7 +421,7 @@
"message": "Petición inválida" "message": "Petición inválida"
}, },
"jsonFail": { "jsonFail": {
"message": "Algo malo pasó. Asegurate que tu JSON tiene el formato correcto" "message": "Algo falló. Asegúrate que tu JSON tiene el formato correcto"
}, },
"jsonFile": { "jsonFile": {
"message": "Archivo JSON", "message": "Archivo JSON",
@ -477,7 +477,7 @@
"message": "Mensaje" "message": "Mensaje"
}, },
"metamaskDescription": { "metamaskDescription": {
"message": "Metamask es una identidad segura en Ethereum" "message": "MetaMask es una identidad segura en Ethereum"
}, },
"min": { "min": {
"message": "Mínimo" "message": "Mínimo"
@ -489,7 +489,7 @@
"message": "Mis cuentas" "message": "Mis cuentas"
}, },
"needEtherInWallet": { "needEtherInWallet": {
"message": "Para interactuar con una aplicación descentralizada usando MetaMask, vas a necesitar tener Ether en tu billetera" "message": "Para interactuar con una aplicación descentralizada usando MetaMask, necesitas tener Ether en tu billetera"
}, },
"needImportFile": { "needImportFile": {
"message": "Debes seleccionar un archivo para importar", "message": "Debes seleccionar un archivo para importar",
@ -565,17 +565,17 @@
"message": "Asegurate que tu contraseña es correcta" "message": "Asegurate que tu contraseña es correcta"
}, },
"passwordMismatch": { "passwordMismatch": {
"message": "Contraseña no coincide", "message": "La contraseña no coincide",
"description": "En el proceso de creación de contraseña, los dos campos de contraseña no coincidieron" "description": "En el proceso de creación de contraseña, los dos campos de contraseña no coincidieron"
}, },
"passwordNotLongEnough": { "passwordNotLongEnough": {
"message": "La contraseña no es lo suficientemente larga" "message": "La contraseña no es lo suficientemente larga"
}, },
"passwordsDontMatch": { "passwordsDontMatch": {
"message": "Contraseñas no coinciden" "message": "Las contraseñas no coinciden"
}, },
"passwordShort": { "passwordShort": {
"message": "Contraseña no es lo suficientemente larga", "message": "La contraseña no es lo suficientemente larga",
"description": "En el proceso de creación de contraseña, esta no es lo suficientemente larga para ser segura" "description": "En el proceso de creación de contraseña, esta no es lo suficientemente larga para ser segura"
}, },
"pastePrivateKey": { "pastePrivateKey": {
@ -583,13 +583,13 @@
"description": "Para importar una cuenta desde una llave privada" "description": "Para importar una cuenta desde una llave privada"
}, },
"pasteSeed": { "pasteSeed": {
"message": "Pega tu frase semilla aquí!" "message": "¡Pega tu frase semilla aquí!"
}, },
"personalAddressDetected": { "personalAddressDetected": {
"message": "Dirección personal detectada. Ingresa la dirección del contrato del token" "message": "Dirección personal detectada. Ingresa la dirección del contrato del token"
}, },
"pleaseReviewTransaction": { "pleaseReviewTransaction": {
"message": "Por favor revisa tu transaccion" "message": "Por favor, revisa tu transaccion"
}, },
"privacyMsg": { "privacyMsg": {
"message": "Política de privacidad" "message": "Política de privacidad"
@ -602,7 +602,7 @@
"message": "Advertencia: NUNCA reveles esta clave. Cualquier persona con tus claves privadas puede robar los activos retenidos en tu cuenta" "message": "Advertencia: NUNCA reveles esta clave. Cualquier persona con tus claves privadas puede robar los activos retenidos en tu cuenta"
}, },
"privateNetwork": { "privateNetwork": {
"message": "Red Privada" "message": "Red privada"
}, },
"qrCode": { "qrCode": {
"message": "Mostrar codigo QR" "message": "Mostrar codigo QR"
@ -614,7 +614,7 @@
"message": "Leer más" "message": "Leer más"
}, },
"readdToken": { "readdToken": {
"message": "Puede volver a agregar este token en el futuro yendo a 'Agregar token' en el menú de opciones de tu cuenta" "message": "Puedes volver a agregar este token en el futuro pinchando sobre 'Agregar token' en el menú de opciones de tu cuenta"
}, },
"receive": { "receive": {
"message": "Recibir" "message": "Recibir"
@ -641,13 +641,13 @@
"message": "Restaurar Bóveda" "message": "Restaurar Bóveda"
}, },
"retryWithMoreGas": { "retryWithMoreGas": {
"message": "Vuelva a intentar con un precio de Gas más alto aquí" "message": "Vuelva a intentar con un precio de gas más alto aquí"
}, },
"revealSeedWords": { "revealSeedWords": {
"message": "Revelar palabras de semilla" "message": "Revelar palabras de semilla"
}, },
"revealSeedWordsWarning": { "revealSeedWordsWarning": {
"message": "No recuperes tu semilla en un lugar publico! Esas palabras pueden ser usadas para robarte todas tus cuentas" "message": "¡No recuperes tu semilla en un lugar pública! Esas palabras pueden ser usadas para robarte todas tus cuentas"
}, },
"revert": { "revert": {
"message": "Revertir" "message": "Revertir"
@ -659,7 +659,7 @@
"message": "Red privada Ropsten" "message": "Red privada Ropsten"
}, },
"sampleAccountName": { "sampleAccountName": {
"message": "Ej. Mi nueva cuenta", "message": "P.ej. Mi nueva cuenta",
"description": "Ayuda al usuario a entender el concepto de agregar un nombre, leíble por humanos, a su cuenta" "description": "Ayuda al usuario a entender el concepto de agregar un nombre, leíble por humanos, a su cuenta"
}, },
"save": { "save": {
@ -700,10 +700,10 @@
"message": "Enviar Ether" "message": "Enviar Ether"
}, },
"sendTokens": { "sendTokens": {
"message": "Enviar Tokens" "message": "Enviar tokens"
}, },
"sendTokensAnywhere": { "sendTokensAnywhere": {
"message": "Enviar Tokens a cualquiera con una cuenta de Ethereum" "message": "Enviar tokens a cualquiera con una cuenta de Ethereum"
}, },
"settings": { "settings": {
"message": "Configuración" "message": "Configuración"
@ -730,10 +730,10 @@
"message": "Firmado" "message": "Firmado"
}, },
"signMessage": { "signMessage": {
"message": "Firmar Mensaje" "message": "Firmar mensaje"
}, },
"signNotice": { "signNotice": {
"message": "Firmar este mensaje puede tener\n efectos secundarios peligrosos. Firma sólo\nmensajes desde sitios a los cuales tú estés dispuesto a confiar completamente tu cuenta.\nEste método peligroso va a ser \nremovido en una version futura." "message": "Firmar este mensaje puede tener\n efectos secundarios peligrosos. Firma sólo\nmensajes desde sitios a los que estés plenamente dispuesto a confiar tu cuenta.\nEste método peligroso va a ser \neliminado en una version futura."
}, },
"spaceBetween": { "spaceBetween": {
"message": "Sólo puede haber un espacio entre las palabras" "message": "Sólo puede haber un espacio entre las palabras"
@ -742,7 +742,7 @@
"message": "Logs de estado" "message": "Logs de estado"
}, },
"stateLogsDescription": { "stateLogsDescription": {
"message": "Los Logs de estado contienen tus direcciones de cuentas públicas y transacciones envíadas" "message": "Los logs de estado contienen tus direcciones de cuentas públicas y transacciones envíadas"
}, },
"stateLogError": { "stateLogError": {
"message": "Error en la recogida de logs de estado" "message": "Error en la recogida de logs de estado"
@ -763,10 +763,10 @@
"message": "Símbolo debe ser entre 0 y 10 caracteres" "message": "Símbolo debe ser entre 0 y 10 caracteres"
}, },
"takesTooLong": { "takesTooLong": {
"message": "¿Está tomando demasiado?" "message": "¿Está tardando demasiado?"
}, },
"terms": { "terms": {
"message": "Terminos de Uso" "message": "Términos de uso"
}, },
"testFaucet": { "testFaucet": {
"message": "Probar Faucet" "message": "Probar Faucet"
@ -782,7 +782,7 @@
"message": "Dirección del token" "message": "Dirección del token"
}, },
"tokenAlreadyAdded": { "tokenAlreadyAdded": {
"message": "El token esta actualmente agregado" "message": "El token está actualmente agregado"
}, },
"tokenBalance": { "tokenBalance": {
"message": "Tu balance de tokens es:" "message": "Tu balance de tokens es:"
@ -794,13 +794,13 @@
"message": "Símbolo del token" "message": "Símbolo del token"
}, },
"tokenWarning1": { "tokenWarning1": {
"message": "Manten un registro de los tokens que has comprado con tu cuenta de MetaMask. Si compraste tokens usando una cuenta diferente, esos tokens no aparecerán aquí." "message": "Mantén un registro de los tokens que has comprado con tu cuenta de MetaMask. Si compraste tokens usando una cuenta diferente, esos tokens no aparecerán aquí."
}, },
"total": { "total": {
"message": "Total" "message": "Total"
}, },
"transactionMemo": { "transactionMemo": {
"message": "Memo de transaccion (opcional)" "message": "Memo de transacción (opcional)"
}, },
"transactionNumber": { "transactionNumber": {
"message": "Número de transacción" "message": "Número de transacción"
@ -816,7 +816,7 @@
"description": "Seguidos por un enlace (aquí) para ver los saldos de token" "description": "Seguidos por un enlace (aquí) para ver los saldos de token"
}, },
"twelveWords": { "twelveWords": {
"message": "Estas 12 palabras son la única forma de restablecer tus cuentas de MetaMask. \nGuardalas en un lugar seguro y secreto." "message": "Estas 12 palabras son la única forma de restablecer tus cuentas de MetaMask. \nGuárdalas en un lugar seguro y secreto."
}, },
"typePassword": { "typePassword": {
"message": "Escribe tu contraseña" "message": "Escribe tu contraseña"
@ -825,13 +825,13 @@
"message": "Bienvenido a la nueva UI (Beta)" "message": "Bienvenido a la nueva UI (Beta)"
}, },
"uiWelcomeMessage": { "uiWelcomeMessage": {
"message": "Estás usando la nueva UI de MetaMask. Echa un vistazo alrededor, prueba las nuevas características, tales como mandar tokens, y déjanos saber si tienes algún problema" "message": "Estás usando la nueva UI de MetaMask. Echa un vistazo alrededor, prueba las nuevas características, tales como mandar tokens, y háznos saber si tienes algún problema"
}, },
"unavailable": { "unavailable": {
"message": "No disponible" "message": "No disponible"
}, },
"unapproved": { "unapproved": {
"message": "No Aprobado" "message": "No aprobado"
}, },
"unknown": { "unknown": {
"message": "Desconocido (a)" "message": "Desconocido (a)"
@ -840,14 +840,14 @@
"message": "Red privada desconocida" "message": "Red privada desconocida"
}, },
"unknownNetworkId": { "unknownNetworkId": {
"message": "ID (identidad) de Red desconocida" "message": "ID (identidad) de red desconocida"
}, },
"uriErrorMsg": { "uriErrorMsg": {
"message": "URI necesita el prefijo HTTP/HTTPS apropiado" "message": "URI necesita el prefijo HTTP/HTTPS apropiado"
}, },
"usaOnly": { "usaOnly": {
"message": "Sólo USA (Estados Unidos)", "message": "Sólo USA (Estados Unidos)",
"description": "El uso de este exchange (casa de cambio) está limitado a las personas dentro de los Estados Unidos de America" "description": "El uso de este exchange (casa de cambio) está limitado a las personas dentro de los Estados Unidos de América"
}, },
"useOldUI": { "useOldUI": {
"message": "Usar UI antigua" "message": "Usar UI antigua"
@ -877,7 +877,7 @@
"message": "Bienvenido a Metamask Beta" "message": "Bienvenido a Metamask Beta"
}, },
"whatsThis": { "whatsThis": {
"message": "Qué es esto?" "message": "¿Qué es esto?"
}, },
"youSign": { "youSign": {
"message": "Usted está firmando" "message": "Usted está firmando"

@ -14,6 +14,9 @@
"address": { "address": {
"message": "アドレス" "message": "アドレス"
}, },
"addCustomToken": {
"message": "カスタムトークンを追加"
},
"addToken": { "addToken": {
"message": "トークンを追加" "message": "トークンを追加"
}, },
@ -63,11 +66,14 @@
"message": "Coinbaseで購入" "message": "Coinbaseで購入"
}, },
"buyCoinbaseExplainer": { "buyCoinbaseExplainer": {
"message": "Coinbaseは、世界で最もポピュラーなBitcoin、Ethereum、そしてLitecoinの取引所です。" "message": "Coinbaseは、世界なBitcoin、Ethereum、そしてLitecoinの取引所です。"
}, },
"cancel": { "cancel": {
"message": "キャンセル" "message": "キャンセル"
}, },
"classicInterface": {
"message": "旧インタフェイスを使用"
},
"clickCopy": { "clickCopy": {
"message": "クリックしてコピー" "message": "クリックしてコピー"
}, },
@ -126,6 +132,9 @@
"message": "暗号通貨", "message": "暗号通貨",
"description": "Exchange type (cryptocurrencies)" "description": "Exchange type (cryptocurrencies)"
}, },
"currentConversion": {
"message": "基軸通貨"
},
"customGas": { "customGas": {
"message": "ガスのカスタマイズ" "message": "ガスのカスタマイズ"
}, },
@ -135,14 +144,17 @@
"customRPC": { "customRPC": {
"message": "カスタムRPC" "message": "カスタムRPC"
}, },
"decimal": {
"message": "小数点桁数"
},
"defaultNetwork": { "defaultNetwork": {
"message": "Etherトランザクションのデフォルトのネットワークはメインネットです。" "message": "デフォルトのEther送受信ネットワークはメインネットです。"
}, },
"denExplainer": { "denExplainer": {
"message": "DENとは、あなたのパスワードが暗号化されたMetaMask内のストレージです。" "message": "DENとは、あなたのパスワードが暗号化されたMetaMask内のストレージです。"
}, },
"deposit": { "deposit": {
"message": "デポジット" "message": "受取り"
}, },
"depositBTC": { "depositBTC": {
"message": "あなたのBTCを次のアドレスへデポジット:" "message": "あなたのBTCを次のアドレスへデポジット:"
@ -161,13 +173,13 @@
"message": "法定通貨でデポジット" "message": "法定通貨でデポジット"
}, },
"depositFromAccount": { "depositFromAccount": {
"message": "別のアカウントからデポジット" "message": "別のアカウントから入金"
}, },
"depositShapeShift": { "depositShapeShift": {
"message": "ShapeShiftでデポジット" "message": "ShapeShiftで入金"
}, },
"depositShapeShiftExplainer": { "depositShapeShiftExplainer": {
"message": "あなたが他の暗号通貨を持っているなら、Etherにトレードしてダイレクトにメタマスクウォレットへのデポジットが可能です。アカウント作成は不要。" "message": "他の暗号通貨をEtherと交換してMetaMaskのウォレットへ入金できます。アカウント作成は不要です。"
}, },
"details": { "details": {
"message": "詳細" "message": "詳細"
@ -176,10 +188,10 @@
"message": "ダイレクトデポジット" "message": "ダイレクトデポジット"
}, },
"directDepositEther": { "directDepositEther": {
"message": "Etherをダイレクトデポジット" "message": "Etherを直接受け取り"
}, },
"directDepositEtherExplainer": { "directDepositEtherExplainer": {
"message": "あなたがEtherをすでにお持ちなら、ダイレクトデポジットは新しいウォレットにEtherを入手する最も迅速な方法です。" "message": "Etherをすでにお持ちなら、MetaMaskの新しいウォレットにEtherを送信することができます。"
}, },
"done": { "done": {
"message": "完了" "message": "完了"
@ -197,7 +209,7 @@
"message": "パスワードを入力" "message": "パスワードを入力"
}, },
"etherscanView": { "etherscanView": {
"message": "Etherscanでアカウントを見る" "message": "Etherscanでアカウントを参照"
}, },
"exchangeRate": { "exchangeRate": {
"message": "交換レート" "message": "交換レート"
@ -257,7 +269,7 @@
"message": "Etherをゲット" "message": "Etherをゲット"
}, },
"getEtherFromFaucet": { "getEtherFromFaucet": {
"message": "フォーセットで $1のEtherをゲット", "message": "フォーセットで $1のEtherを得ることができます。",
"description": "Displays network name for Ether faucet" "description": "Displays network name for Ether faucet"
}, },
"greaterThanMin": { "greaterThanMin": {
@ -281,12 +293,15 @@
"message": "どのようにEtherをデポジットしますか?" "message": "どのようにEtherをデポジットしますか?"
}, },
"import": { "import": {
"message": "インポート", "message": "追加",
"description": "Button to import an account from a selected file" "description": "Button to import an account from a selected file"
}, },
"importAccount": { "importAccount": {
"message": "アカウントのインポート" "message": "アカウントのインポート"
}, },
"importAccountMsg": {
"message":"追加したアカウントはMetaMaskのアカウントシードフレーズとは関連付けられません。インポートしたアカウントについての詳細は"
},
"importAnAccount": { "importAnAccount": {
"message": "アカウントをインポート" "message": "アカウントをインポート"
}, },
@ -298,7 +313,10 @@
"description": "status showing that an account has been fully loaded into the keyring" "description": "status showing that an account has been fully loaded into the keyring"
}, },
"infoHelp": { "infoHelp": {
"message": "インフォメーションとヘルプ" "message": "情報とヘルプ"
},
"insufficientFunds": {
"message": "残高不足"
}, },
"invalidAddress": { "invalidAddress": {
"message": "アドレスが無効です。" "message": "アドレスが無効です。"
@ -354,7 +372,7 @@
"message": "マイアカウント" "message": "マイアカウント"
}, },
"needEtherInWallet": { "needEtherInWallet": {
"message": "MetaMaskを使って分散型アプリケーションと対話するためには、あなたのウォレットにEtherが必要になります。" "message": "MetaMaskを使って分散型アプリケーションを使用するためには、このウォレットにEtherが必要です。"
}, },
"needImportFile": { "needImportFile": {
"message": "インポートするファイルを選択してください。", "message": "インポートするファイルを選択してください。",
@ -383,6 +401,9 @@
"newRecipient": { "newRecipient": {
"message": "新規受取人" "message": "新規受取人"
}, },
"newRPC": {
"message": "新しいRPCのURLを追加"
},
"next": { "next": {
"message": "次へ" "message": "次へ"
}, },
@ -460,12 +481,21 @@
"rejected": { "rejected": {
"message": "拒否されました" "message": "拒否されました"
}, },
"resetAccount": {
"message": "アカウントをリセット"
},
"restoreFromSeed": {
"message": "パスフレーズから復元する"
},
"required": { "required": {
"message": "必要です。" "message": "必要です。"
}, },
"retryWithMoreGas": { "retryWithMoreGas": {
"message": "より高いガスプライスで再度試して下さい。" "message": "より高いガスプライスで再度試して下さい。"
}, },
"revealSeedWords": {
"message": "パスフレーズを表示"
},
"revert": { "revert": {
"message": "元に戻す" "message": "元に戻す"
}, },
@ -495,8 +525,11 @@
"sendTokens": { "sendTokens": {
"message": "トークンを送る" "message": "トークンを送る"
}, },
"onlySendToEtherAddress": {
"message": "ETHはイーサリウムアカウントのみに送信できます。"
},
"sendTokensAnywhere": { "sendTokensAnywhere": {
"message": "イーサリアムのアカウントを持っている人にトークンを送る" "message": "イーサリアムアカウントを持っている人にトークンを送る"
}, },
"settings": { "settings": {
"message": "設定" "message": "設定"
@ -544,9 +577,21 @@
"message": "ShapeShiftで $1をETHにする", "message": "ShapeShiftで $1をETHにする",
"description": "system will fill in deposit type in start of message" "description": "system will fill in deposit type in start of message"
}, },
"tokenAddress": {
"message": "トークンアドレス"
},
"tokenBalance": { "tokenBalance": {
"message": "あなたのトークン残高:" "message": "あなたのトークン残高:"
}, },
"tokenSelection": {
"message": "トークンを検索、またはリストから選択してください。"
},
"tokenSymbol": {
"message": "トークンシンボル"
},
"tokenWarning1": {
"message": "MetaMaskのアカウントで取得したアカウントのみ追加できます。他のアカウントを使用して取得したトークンは、カスタムトークンを使用してください。"
},
"total": { "total": {
"message": "合計" "message": "合計"
}, },
@ -591,6 +636,9 @@
"usedByClients": { "usedByClients": {
"message": "様々なクライアントによって使用されています。" "message": "様々なクライアントによって使用されています。"
}, },
"useOldUI": {
"message": "旧UIに切り替え"
},
"viewAccount": { "viewAccount": {
"message": "アカウントを見る" "message": "アカウントを見る"
}, },

@ -0,0 +1,819 @@
{
"accept": {
"message": "Sprejmi"
},
"account": {
"message": "Račun"
},
"accountDetails": {
"message": "Podrobnosti računa"
},
"accountName": {
"message": "Ime računa"
},
"address": {
"message": "Naslov"
},
"addCustomToken": {
"message": "Dodaj žeton po meri"
},
"addToken": {
"message": "Dodaj žeton"
},
"addTokens": {
"message": "Dodaj žetone"
},
"amount": {
"message": "Znesek"
},
"amountPlusGas": {
"message": "Znesek + Gas"
},
"appDescription": {
"message": "Denarnica za Ethereum v brskalniku",
"description": "The description of the application"
},
"appName": {
"message": "MetaMask",
"description": "The name of the application"
},
"attemptingConnect": {
"message": "Povezovanje z verigo blokov ..."
},
"attributions": {
"message": "Dodelitve"
},
"available": {
"message": "Na voljo"
},
"back": {
"message": "Nazaj"
},
"balance": {
"message": "Znesek:"
},
"balances": {
"message": "Vaš znesek"
},
"balanceIsInsufficientGas": {
"message": "Napačen znesek za skupno gas vrednost"
},
"beta": {
"message": "BETA"
},
"betweenMinAndMax": {
"message": "mora biti večji ali enak $1 in manjši ali enak $1.",
"description": "helper for inputting hex as decimal input"
},
"blockiesIdenticon": {
"message": "Uporabite Blockies Identicon"
},
"borrowDharma": {
"message": "Izposoja z Dharma (Beta)"
},
"builtInCalifornia": {
"message": "MetaMask je ustvarjen v Kaliforniji."
},
"buy": {
"message": "Kupi"
},
"buyCoinbase": {
"message": "Kupi na Coinbase"
},
"buyCoinbaseExplainer": {
"message": "Coinbase je najpopularnejši načun za kupovanje in prodajo bitcoinov, ethereuma, in litecoina."
},
"cancel": {
"message": "Prekliči"
},
"classicInterface": {
"message": "Uporabi navaden način"
},
"clickCopy": {
"message": "Kliknite za kopiranje"
},
"confirm": {
"message": "Potrdi"
},
"confirmContract": {
"message": "Potrdi pogodbo"
},
"confirmPassword": {
"message": "Potrdi geslo"
},
"confirmTransaction": {
"message": "Potrdi transakcijo"
},
"continue": {
"message": "Nadaljuj"
},
"continueToCoinbase": {
"message": "Nadaljuj na Coinbase"
},
"contractDeployment": {
"message": "Ustvarjanje pogodbe"
},
"conversionProgress": {
"message": "Poteka pretvorba"
},
"copiedButton": {
"message": "Kopirano"
},
"copiedClipboard": {
"message": "Kopirano v odložišče"
},
"copiedExclamation": {
"message": "Kopirano!"
},
"copiedSafe": {
"message": "Prilepil sem ga na varno!"
},
"copy": {
"message": "Kopiraj"
},
"copyToClipboard": {
"message": "Kopiraj v odložišče"
},
"copyButton": {
"message": " Kopiraj "
},
"copyPrivateKey": {
"message": "To je vaš zesebni ključ (kliknite za kopiranje)"
},
"create": {
"message": "Ustvari"
},
"createAccount": {
"message": "Ustvari račun"
},
"createDen": {
"message": "Ustvari"
},
"crypto": {
"message": "Kripto",
"description": "Exchange type (cryptocurrencies)"
},
"currentConversion": {
"message": "Trenutna cena"
},
"currentNetwork": {
"message": "Trenutno omrežje"
},
"customGas": {
"message": "Prilagodi gas"
},
"customize": {
"message": "Prilagodi"
},
"customRPC": {
"message": "Poljuben RPC"
},
"decimalsMustZerotoTen": {
"message": "Decimalk mora biti vsaj 0, in ne več kot 36."
},
"decimal": {
"message": "Decimalke natančnosti"
},
"defaultNetwork": {
"message": "Privzeto omrežje za transakcije je Main Net."
},
"denExplainer": {
"message": "DEN je vaša šifrirana shramba v MetaMasku."
},
"deposit": {
"message": "Vplačilo"
},
"depositBTC": {
"message": "Vplačajte vaš BTC na spodnji naslov:"
},
"depositCoin": {
"message": "Vplačajte $1 na spodnji naslov",
"description": "Tells the user what coin they have selected to deposit with shapeshift"
},
"depositEth": {
"message": "Vplačilo ETH"
},
"depositEther": {
"message": "Vplačilo ethera"
},
"depositFiat": {
"message": "Vplačilo s klasičnimi valutami"
},
"depositFromAccount": {
"message": "Vplačilo iz drugega računa"
},
"depositShapeShift": {
"message": "Vplačilo z ShapeShift"
},
"depositShapeShiftExplainer": {
"message": "Če imate druge kriptovalute, lahko vpačate ether neposredno v MetaMask. Brez računov."
},
"details": {
"message": "Podrobnosti"
},
"directDeposit": {
"message": "Direktno vplačilo"
},
"directDepositEther": {
"message": "Direktno vplačilo ehera"
},
"directDepositEtherExplainer": {
"message": "Če že imate ether, ga lahko najhitreje dobite v MetaMask z direktnim vplačilom."
},
"done": {
"message": "Končano"
},
"downloadStatelogs": {
"message": "Prenesi state dnevnike"
},
"edit": {
"message": "Uredi"
},
"editAccountName": {
"message": "Uredi ime računa"
},
"emailUs": {
"message": "Pišite nam!"
},
"encryptNewDen": {
"message": "Šifrirajte DEN"
},
"enterPassword": {
"message": "Vpišite geslo"
},
"enterPasswordConfirm": {
"message": "Potrdite geslo"
},
"etherscanView": {
"message": "Poglejte račun na Etherscan"
},
"exchangeRate": {
"message": "Menjalni tečaj"
},
"exportPrivateKey": {
"message": "Izvozi zasebni ključ"
},
"exportPrivateKeyWarning": {
"message": "Izvažanje zasebnih ključev je na lastno odgovornost."
},
"failed": {
"message": "Ni uspelo"
},
"fiat": {
"message": "FIAT",
"description": "Exchange type"
},
"fileImportFail": {
"message": "Uvoz z datoteko ni uspel? Kliknite tukaj!",
"description": "Helps user import their account from a JSON file"
},
"followTwitter": {
"message": "Sledite nam na Twitterju"
},
"from": {
"message": "Od"
},
"fromToSame": {
"message": "From and To address cannot be the same"
},
"fromShapeShift": {
"message": "Od ShapeShift"
},
"gas": {
"message": "Gas",
"description": "Short indication of gas cost"
},
"gasFee": {
"message": "Gas fee"
},
"gasLimit": {
"message": "Gas limit"
},
"gasLimitCalculation": {
"message": "Priporočen gas limit je izračunan glede na omrežje."
},
"gasLimitRequired": {
"message": "Gas limit je zahtevan"
},
"gasLimitTooLow": {
"message": "Gas limit mora biti najmanj 21000"
},
"generatingSeed": {
"message": "Ustvarjenje seed ..."
},
"gasPrice": {
"message": "Gas price (GWEI)"
},
"gasPriceCalculation": {
"message": "Priporočen gas price je izračunan glede na omrežje"
},
"gasPriceRequired": {
"message": "Gas price je zahtevan"
},
"getEther": {
"message": "Pridobite ether"
},
"getEtherFromFaucet": {
"message": "Pridobite ether iz fauceta za $1",
"description": "Displays network name for Ether faucet"
},
"greaterThanMin": {
"message": "mora biti višji ali enak $1.",
"description": "helper for inputting hex as decimal input"
},
"here": {
"message": "tukaj",
"description": "as in -click here- for more information (goes with troubleTokenBalances)"
},
"hereList": {
"message": "Tukaj je seznam!!!"
},
"hide": {
"message": "Skrij"
},
"hideToken": {
"message": "Skrij žeton"
},
"hideTokenPrompt": {
"message": "Skrijem žeton?"
},
"howToDeposit": {
"message": "Kako želite vplačati ether?"
},
"holdEther": {
"message": "Omogoča vam, da imate eter in žetone in služi kot most za decentralizirane aplikacije."
},
"import": {
"message": "Uvozi",
"description": "Button to import an account from a selected file"
},
"importAccount": {
"message": "Uvozi račun"
},
"importAccountMsg": {
"message":" Uvoženi računi ne bodo povezani s prvotnim seedphaseom. Preberite več o uvoženih računih "
},
"importAnAccount": {
"message": "Uvozi račun"
},
"importDen": {
"message": "Uvozi DEN"
},
"imported": {
"message": "Uvoženo",
"description": "status showing that an account has been fully loaded into the keyring"
},
"infoHelp": {
"message": "Info & Pomoč"
},
"insufficientFunds": {
"message": "Nezadostna sredstva."
},
"insufficientTokens": {
"message": "Nezadostni žetoni."
},
"invalidAddress": {
"message": "Nepravilen naslov"
},
"invalidAddressRecipient": {
"message": "Prejemnikov naslov je neveljaven"
},
"invalidGasParams": {
"message": "Nepravilno nastavljen gas"
},
"invalidInput": {
"message": "Napačen vnos."
},
"invalidRequest": {
"message": "Napačna zahteva"
},
"invalidRPC": {
"message": "Napačen RPC URI"
},
"jsonFail": {
"message": "Nekaj je bilo narobe. Prepričajte se, da je JSON datoteka pravilno oblikovana."
},
"jsonFile": {
"message": "JSON datoteka",
"description": "format for importing an account"
},
"kovan": {
"message": "Testno omrežje Kovan"
},
"knowledgeDataBase": {
"message": "Obiščite našo pomoč"
},
"lessThanMax": {
"message": "mora biti večji ali enak $1.",
"description": "helper for inputting hex as decimal input"
},
"likeToAddTokens": {
"message": "Želite dodati te žetone?"
},
"limit": {
"message": "Omejitev"
},
"loading": {
"message": "Nalaganje ..."
},
"loadingTokens": {
"message": "Nalaganje žetonov ..."
},
"localhost": {
"message": "Localhost 8545"
},
"login": {
"message": "Prijava"
},
"logout": {
"message": "Odjava"
},
"loose": {
"message": "Loose"
},
"loweCaseWords": {
"message": "seed words imajo lahko le male črke"
},
"mainnet": {
"message": "Glavno omrežje"
},
"message": {
"message": "Sporočilo"
},
"metamaskDescription": {
"message": "MetaMask je varen identitetni sklad za Ethereum."
},
"min": {
"message": "Najmanj"
},
"myAccounts": {
"message": "Moji računi"
},
"mustSelectOne": {
"message": "Izbran mora biti vsaj 1 žeton."
},
"needEtherInWallet": {
"message": "Za interakcijo z decentraliziranimi aplikacijami, ki uporabljajo MetaMask, boste v svoji denarnici potrebovali eter."
},
"needImportFile": {
"message": "Za uvoz morate izbrati datoteko.",
"description": "User is important an account and needs to add a file to continue"
},
"needImportPassword": {
"message": "Za izbrano datoteko morate vnesti geslo.",
"description": "Password and file needed to import an account"
},
"negativeETH": {
"message": "Ni mogoče poslati negativne vsote ETH."
},
"networks": {
"message": "Omrežja"
},
"newAccount": {
"message": "Nov račun"
},
"newAccountNumberName": {
"message": "Račun $1",
"description": "Default name of next account to be created on create account screen"
},
"newContract": {
"message": "Nova pogodba"
},
"newPassword": {
"message": "Novo geslo (min. 8. črk)"
},
"newRecipient": {
"message": "Nov prejemnik"
},
"newRPC": {
"message": "Nov RPC URL"
},
"next": {
"message": "Naprej"
},
"noAddressForName": {
"message": "Za to ime ni bil nastavljen noben naslov."
},
"noDeposits": {
"message": "Ni prejetih vplačil"
},
"noTransactionHistory": {
"message": "Ni zgodovine transakcij."
},
"noTransactions": {
"message": "Ni transakcij"
},
"notStarted": {
"message": "Ni se začelo"
},
"oldUI": {
"message": "Starejši uporabniški vmesnik"
},
"oldUIMessage": {
"message": "Vrnili ste se v starejši uporabniški vmesnik. V novega se lahko vrnete z možnostjo v spustnem meniju v zgornjem desnem kotu."
},
"or": {
"message": "ali",
"description": "choice between creating or importing a new account"
},
"passwordCorrect": {
"message": "Prepričajte se, da je geslo pravilno."
},
"passwordMismatch": {
"message": "gesli se ne ujemata",
"description": "in password creation process, the two new password fields did not match"
},
"passwordShort": {
"message": "geslo ni dovolj dolgo",
"description": "in password creation process, the password is not long enough to be secure"
},
"pastePrivateKey": {
"message": "Tukaj prilepite zasebni ključ:",
"description": "For importing an account from a private key"
},
"pasteSeed": {
"message": "Tukaj prilepite seed phrase!"
},
"personalAddressDetected": {
"message": "Osebni naslov je zaznan. Vnesite naslov žetona."
},
"pleaseReviewTransaction": {
"message": "Preglejte transakcijo."
},
"privacyMsg": {
"message": "Politika zasebnosti"
},
"privateKey": {
"message": "Zasebni ključ",
"description": "select this type of file to use to import an account"
},
"privateKeyWarning": {
"message": "Opozorilo: Nikoli ne razkrijte tega ključa. Vsakdo s svojimi zasebnimi ključi lahko ukrade vse premoženje v računu."
},
"privateNetwork": {
"message": "Zasebno omrežje"
},
"qrCode": {
"message": "Prikaži QR kodo"
},
"readdToken": {
"message": "Ta žeton lahko dodate tudi v prihodnosti, tako da odprete možnost »Dodaj žeton« v meniju z računi."
},
"readMore": {
"message": "Preberite več."
},
"readMore2": {
"message": "Preberite več."
},
"receive": {
"message": "Prejmite"
},
"recipientAddress": {
"message": "Prejemnikov naslov"
},
"refundAddress": {
"message": "Vaš naslov za vračilo"
},
"rejected": {
"message": "Zavrnjeno"
},
"resetAccount": {
"message": "Ponastavi račun"
},
"restoreFromSeed": {
"message": "Obnovi iz seed phrase"
},
"required": {
"message": "Zahtevano"
},
"retryWithMoreGas": {
"message": "Poskusi z višjim gas price"
},
"revealSeedWords": {
"message": "Prikaži seed words"
},
"revealSeedWordsWarning": {
"message": "Ne obnovite seed words na javnem mestu! Te besede se lahko uporabijo za krajo vseh vaših računov."
},
"revert": {
"message": "Povrni"
},
"rinkeby": {
"message": "Testno omrežje Rinkeby"
},
"ropsten": {
"message": "Testno omrežje Ropsten"
},
"sampleAccountName": {
"message": "npr. Moj nov račun",
"description": "Help user understand concept of adding a human-readable name to their account"
},
"save": {
"message": "Shrani"
},
"saveAsFile": {
"message": "Shrani kot datoteko",
"description": "Account export process"
},
"saveSeedAsFile": {
"message": "Shrani seed words kot datoteko"
},
"search": {
"message": "Iskanje"
},
"secretPhrase": {
"message": "Tukaj vnesite svoje seed words, da obnovite svoje račune."
},
"seedPhraseReq": {
"message": "seed phrases so dolgi 12 besed"
},
"select": {
"message": "Izberi"
},
"selectCurrency": {
"message": "Izberi valuto"
},
"selectService": {
"message": "Izberi storitev"
},
"selectType": {
"message": "Izberi vrsto"
},
"send": {
"message": "Pošlji"
},
"sendETH": {
"message": "Pošlji ETH"
},
"sendTokens": {
"message": "Pošlji žetone"
},
"sendTokensAnywhere": {
"message": "Pošljite žetone vsem, ki imajo Ethereum račun"
},
"settings": {
"message": "Nastavitve"
},
"shapeshiftBuy": {
"message": "Kupite z Shapeshift"
},
"showPrivateKeys": {
"message": "Prikaži zasebne ključe"
},
"showQRCode": {
"message": "Prikaži QR kodo"
},
"sign": {
"message": "Podpiši"
},
"signMessage": {
"message": "Podpiši sporočilo"
},
"signNotice": {
"message": "To podpisovanje lahko povzroči \nnevarne stranske učinke. Podpisujte samo sporočila \nstrani, ki jim zaupate s svojim celotnim računom.\n Ta nevarna funkcija bo odstranjena v prihodnji različici. "
},
"sigRequest": {
"message": "Zahteva za podpis"
},
"sigRequested": {
"message": "Podpis je zahtevan"
},
"spaceBetween": {
"message": "med besedami je lahko samo presledek"
},
"status": {
"message": "Status"
},
"stateLogs": {
"message": "State dnevniki"
},
"stateLogsDescription": {
"message": "State dnevniki vsebujejo naslove vašega računa in poslane transakcije.."
},
"submit": {
"message": "Potrdi"
},
"supportCenter": {
"message": "Obiščite našo podporo"
},
"symbolBetweenZeroTen": {
"message": "Simbol mora biti dolg od 0 do 10 znakov."
},
"takesTooLong": {
"message": "Traja predolgo?"
},
"terms": {
"message": "Pogoji uporabe"
},
"testFaucet": {
"message": "Testni faucet"
},
"to": {
"message": "Za"
},
"toETHviaShapeShift": {
"message": "$1 v ETH prek ShapeShift",
"description": "system will fill in deposit type in start of message"
},
"tokenAddress": {
"message": "Naslov žetona"
},
"tokenAlreadyAdded": {
"message": "Žeton je že bil dodan."
},
"tokenBalance": {
"message": "Vaš znesek žetona:"
},
"tokenSelection": {
"message": "Poiščite žetone ali jih izberite z našega seznama priljubljenih žetonov."
},
"tokenSymbol": {
"message": "Simbol žetona"
},
"tokenWarning1": {
"message": "Spremljajte žetone, ki ste jih kupili s svojim MetaMask računom. Če ste kupili žetone z drugačnim računom, ti žetoni ne bodo prikazani tukaj."
},
"total": {
"message": "Skupno"
},
"transactions": {
"message": "transakcije"
},
"transactionMemo": {
"message": "Opis transakcije (ni zahtevano)"
},
"transactionNumber": {
"message": "Številka transakcije"
},
"transfers": {
"message": "Prenosi"
},
"troubleTokenBalances": {
"message": "Imeli smo težave pri nalaganju vaših žetonov. Ogledate si jih lahko ",
"description": "Followed by a link (here) to view token balances"
},
"twelveWords": {
"message": "Edini način za obnovitev MetaMask računa, je teh 12 besed.\nShranite jih na varno in skrivno mesto."
},
"typePassword": {
"message": "Vpišite vaše geslo"
},
"uiWelcome": {
"message": "Dobrodošli v novem uporabniškem vmesniku (Beta)"
},
"uiWelcomeMessage": {
"message": "Zdaj uporabljate novi MetaMask uporabniški vmesnik. Razglejte se, preizkusite nove funkcije, kot so pošiljanje žetonov, in nas obvestite, če imate kakšne težave."
},
"unavailable": {
"message": "Ni na voljo"
},
"unknown": {
"message": "Neznano"
},
"unknownNetwork": {
"message": "Neznano zasebno omrežje"
},
"unknownNetworkId": {
"message": "Neznan ID omrežja"
},
"uriErrorMsg": {
"message": "URI-ji zahtevajo ustrezno HTTP/HTTPS predpono."
},
"usaOnly": {
"message": "Samo za ZDA",
"description": "Using this exchange is limited to people inside the USA"
},
"usedByClients": {
"message": "Uporablja jih več različnih odjemalcev"
},
"useOldUI": {
"message": "Uporabi star uporabniški vmesnik"
},
"validFileImport": {
"message": "Za uvoz morate izbrati pravilno datoteko."
},
"vaultCreated": {
"message": "Račun je ustvarjen"
},
"viewAccount": {
"message": "Poglej račun"
},
"visitWebSite": {
"message": "Obiščite našo spletno stran"
},
"warning": {
"message": "Opozorilo"
},
"welcomeBeta": {
"message": "Dobrodošli v MetaMask Beta"
},
"whatsThis": {
"message": "Kaj je to?"
},
"yourSigRequested": {
"message": "Vaš podpis je bil zahtevan"
},
"youSign": {
"message": "Podpisani ste"
}
}

@ -0,0 +1,819 @@
{
"accept": {
"message": "ยอมรบ"
},
"account": {
"message": "บญช"
},
"accountDetails": {
"message": "รายละเอยดบญช"
},
"accountName": {
"message": "ชอบญช"
},
"address": {
"message": "แอดเดรส"
},
"addCustomToken": {
"message": "เพมโทเคนดวยตวเอง"
},
"addToken": {
"message": "เพมโทเคน"
},
"addTokens": {
"message": "เพมหลายโทเคน"
},
"amount": {
"message": "จำนวน"
},
"amountPlusGas": {
"message": "จำนวน + แกส"
},
"appDescription": {
"message": "สวนขยายเบราวเซอรสำหรบอเธอเรยม",
"description": "The description of the application"
},
"appName": {
"message": "MetaMask",
"description": "The name of the application"
},
"attemptingConnect": {
"message": "กำลงเชอมตอกบบลอกเชน"
},
"attributions": {
"message": "อางถง"
},
"available": {
"message": "วาง"
},
"back": {
"message": "กลบ"
},
"balance": {
"message": "ยอดคงเหลอ:"
},
"balances": {
"message": "ยอดคงเหลอของคณ"
},
"balanceIsInsufficientGas": {
"message": "ยอดคงเหลอไมพอสำหรบจายคาแกสทงหมด"
},
"beta": {
"message": "เบตา"
},
"betweenMinAndMax": {
"message": "ตองมากกวาหรอเทากบ $1 และนอยกวาหรอเทากบ $2",
"description": "helper for inputting hex as decimal input"
},
"blockiesIdenticon": {
"message": "ใชงาน Blockies Identicon"
},
"borrowDharma": {
"message": "ยมดวย Dharma (เบตา)"
},
"builtInCalifornia": {
"message": "MetaMask ออกแบบและพฒนาทแคลฟอรเนย"
},
"buy": {
"message": "ซอ"
},
"buyCoinbase": {
"message": "ซอดวย Coinbase"
},
"buyCoinbaseExplainer": {
"message": "Coinbase เปนแหลงซอขายบตคอยนไลทคอยนและอเธอเรยมทไดบความนยมสงสดในโลก"
},
"cancel": {
"message": "ยกเลก"
},
"classicInterface": {
"message": "ใชหนาตาแบบเกา"
},
"clickCopy": {
"message": "กดเพอคดลอก"
},
"confirm": {
"message": "ยนยน"
},
"confirmContract": {
"message": "ยนยนสญญา"
},
"confirmPassword": {
"message": "ยนยนรหสผาน"
},
"confirmTransaction": {
"message": "ยนยนการทำรายการธรกรรม"
},
"continue": {
"message": "ทำตอไป"
},
"continueToCoinbase": {
"message": "ไปท Coinbase"
},
"contractDeployment": {
"message": "การตดตงสญญา"
},
"conversionProgress": {
"message": "กำลงดำเนนการแปลงหนวย"
},
"copiedButton": {
"message": "คดลอกแลว"
},
"copiedClipboard": {
"message": "คดลอกไปทคลบบอรดแลว"
},
"copiedExclamation": {
"message": "คดลอกแลว!"
},
"copiedSafe": {
"message": "ฉนไดดลอกเกบไวในทปลอดภยเรยบรอยแลว"
},
"copy": {
"message": "คดลอก"
},
"copyToClipboard": {
"message": "คดลอกไปคลปบอรด"
},
"copyButton": {
"message": " คดลอก "
},
"copyPrivateKey": {
"message": "นอควนตวของคณ(กดเพอคดลอก)"
},
"create": {
"message": "สราง"
},
"createAccount": {
"message": "สรางบญช"
},
"createDen": {
"message": "สราง"
},
"crypto": {
"message": "ครปโต",
"description": "Exchange type (cryptocurrencies)"
},
"currentConversion": {
"message": "อตราแลกเปลยนปจจน"
},
"currentNetwork": {
"message": "เครอขายปจจน"
},
"customGas": {
"message": "กำหนดคาแกสเอง"
},
"customize": {
"message": "กำหนดคาเอง"
},
"customRPC": {
"message": "กำหนดคา RPC เอง"
},
"decimalsMustZerotoTen": {
"message": "จำนวนตองมากกวา 0 และไมเกน 36"
},
"decimal": {
"message": "ตำแหนงของทศนยม"
},
"defaultNetwork": {
"message": "คาเรมตนของเครอขายสำหรบทำรายการธรกรรมอเธอรอ Main Net"
},
"denExplainer": {
"message": "DEN ของคณคอตวเกบขอมลทเขารหสไววยรหสผานของคณภายใน MetaMask "
},
"deposit": {
"message": "ฝาก"
},
"depositBTC": {
"message": "ฝากบตคอยนของคณไปทแอดเดรสดานลางน:"
},
"depositCoin": {
"message": "ฝาก $1 ของคณไปทแอดเดรสดานลางน:",
"description": "Tells the user what coin they have selected to deposit with shapeshift"
},
"depositEth": {
"message": "การฝากอเธอร"
},
"depositEther": {
"message": "การฝากอเธอร"
},
"depositFiat": {
"message": "ฝากดวยเงนตรา"
},
"depositFromAccount": {
"message": "ฝากจากบญชน"
},
"depositShapeShift": {
"message": "ฝากดวย ShapeShift"
},
"depositShapeShiftExplainer": {
"message": "ถามเงนสกลอนอยสามารถแลกเงนและฝากเปนอเธอรไดโดยตรงเขากระเปา MetaMask ไดเลยไมองสมครบญช"
},
"details": {
"message": "รายละเอยด"
},
"directDeposit": {
"message": "ฝากตรง"
},
"directDepositEther": {
"message": "ฝากอเธอรโดยตรง"
},
"directDepositEtherExplainer": {
"message": "ถาคณมเธอรอยแลววการทเรวทดในการเอาเงนเขากระเปาใหมอการโอนตรงๆ"
},
"done": {
"message": "เสรจสน"
},
"downloadStatelogs": {
"message": "ดาวนโหลดลอกสถานะ"
},
"edit": {
"message": "แกไข"
},
"editAccountName": {
"message": "แกไขชอบญช"
},
"emailUs": {
"message": "อเมลหาเรา!"
},
"encryptNewDen": {
"message": "เขารหส DEN ของคณ"
},
"enterPassword": {
"message": "ใสรหสผาน"
},
"enterPasswordConfirm": {
"message": "ใสรหสผานอกครงเพอยนยน"
},
"etherscanView": {
"message": "ดญชบน Etherscan"
},
"exchangeRate": {
"message": "อตราแลกเปลยน"
},
"exportPrivateKey": {
"message": "สงออกควนตว"
},
"exportPrivateKeyWarning": {
"message": "สงออกควนตวโดยคณรบความเสยงเอง"
},
"failed": {
"message": "ลมเหลว"
},
"fiat": {
"message": "เงนตรา",
"description": "Exchange type"
},
"fileImportFail": {
"message": "นำเขาไฟลไมสำเหรจ กดท!",
"description": "Helps user import their account from a JSON file"
},
"followTwitter": {
"message": "ตดตามเราบนทวตเตอร"
},
"from": {
"message": "จาก"
},
"fromToSame": {
"message": "แอดเดรสทงกบทบจะตองไมไชนเดยวกน"
},
"fromShapeShift": {
"message": "จาก ShapeShift"
},
"gas": {
"message": "แกส",
"description": "Short indication of gas cost"
},
"gasFee": {
"message": "คาแกส"
},
"gasLimit": {
"message": "วงเงนแกส"
},
"gasLimitCalculation": {
"message": "เราแนะนำวงเงนแกสตามความสำเรจบนเครอขาย"
},
"gasLimitRequired": {
"message": "ตองกำหนดวงเงนแกส"
},
"gasLimitTooLow": {
"message": "วงเงนแกสตองอยางนอย 21000"
},
"generatingSeed": {
"message": "กำลงสรางชด..."
},
"gasPrice": {
"message": "ราคาแกส (GWEI)"
},
"gasPriceCalculation": {
"message": "เราแนะนำราคาแกสตามความสำเรจบนเครอขาย"
},
"gasPriceRequired": {
"message": "ตองมราคาแกส"
},
"getEther": {
"message": "รบอเธอร"
},
"getEtherFromFaucet": {
"message": "รบอเธอรปลอยจาก $1",
"description": "Displays network name for Ether faucet"
},
"greaterThanMin": {
"message": "ตองมากกวาหรอเทากบ $1.",
"description": "helper for inputting hex as decimal input"
},
"here": {
"message": "ท",
"description": "as in -click here- for more information (goes with troubleTokenBalances)"
},
"hereList": {
"message": "รายการอย!!!!"
},
"hide": {
"message": "ซอน"
},
"hideToken": {
"message": "ซอนโทเคน"
},
"hideTokenPrompt": {
"message": "ซอนโทเคนหรอไม?"
},
"howToDeposit": {
"message": "คณตองการฝากอเธอรอยางไร?"
},
"holdEther": {
"message": "ชวยคณถออเทอรและโทเคนและทำหนาทเปนสะพานเชอมตอกบแอพพลเคชนแบบกระจาย"
},
"import": {
"message": "นำเขา",
"description": "Button to import an account from a selected file"
},
"importAccount": {
"message": "นำเขาบญช"
},
"importAccountMsg": {
"message":"บญชนำเขาจะไมกรวมกบบญชสรางดวยคำเเรมตนบนเมตามารสในตอนแรก เรยนรเพมเตมเกยวกบบญชนำเขา"
},
"importAnAccount": {
"message": "นำเขาบญช"
},
"importDen": {
"message": "นำเขา DEN ทอยแลว"
},
"imported": {
"message": "นำเขาเรยบรอย",
"description": "status showing that an account has been fully loaded into the keyring"
},
"infoHelp": {
"message": "ขอมลและความชวยเหลอ"
},
"insufficientFunds": {
"message": "เงนทนไมเพยงพอ"
},
"insufficientTokens": {
"message": "โทเคนไมเพยงพอ"
},
"invalidAddress": {
"message": "แอดแดรสไมกตอง"
},
"invalidAddressRecipient": {
"message": "แอดแดรสผบไมกตอง"
},
"invalidGasParams": {
"message": "ตงคาแกสไมกตอง"
},
"invalidInput": {
"message": "อนพทไมกตอง"
},
"invalidRequest": {
"message": "คำรองขอไมกตอง"
},
"invalidRPC": {
"message": "RPC URI ไมกตอง"
},
"jsonFail": {
"message": "เกดบางอยางผดพลาด โปรดตรวจสอบวาไฟล JSON ของคณมปแบบทกตอง."
},
"jsonFile": {
"message": "ไฟล JSON",
"description": "format for importing an account"
},
"kovan": {
"message": "เครอขายทดสอบ Kovan"
},
"knowledgeDataBase": {
"message": "ไปทคลงความรของเรา"
},
"lessThanMax": {
"message": "ตองนอยกวาหรอเทากบ $1.",
"description": "helper for inputting hex as decimal input"
},
"likeToAddTokens": {
"message": "คณตองการเพมโทเคนเหลานหรอไม?"
},
"limit": {
"message": "ขอจำกด"
},
"loading": {
"message": "กำลงโหลด..."
},
"loadingTokens": {
"message": "กำลงโหลดโทเคน..."
},
"localhost": {
"message": "Localhost 8545"
},
"login": {
"message": "เขาสระบบ"
},
"logout": {
"message": "ออกจากระบบ"
},
"loose": {
"message": "อสระ"
},
"loweCaseWords": {
"message": "กลมคำชดมเพยงตวพมพเลกเทานน"
},
"mainnet": {
"message": "เครอขาย Main Net"
},
"message": {
"message": "ขอความ"
},
"metamaskDescription": {
"message": "MetaMask คอทเกบตวตนนรภยสำหรบอเธอเรยม"
},
"min": {
"message": "ขนตำ"
},
"myAccounts": {
"message": "บญชของฉน"
},
"mustSelectOne": {
"message": "ตองเลอกอยางนอย 1 โทเคน"
},
"needEtherInWallet": {
"message": "คณจะตองมเธอรในกระเปาเงนของคณในการใชงานกบแอพพลเคชนแบบกระจายดวย MetaMask"
},
"needImportFile": {
"message": "คณตองเลอกไฟลจะนำเขา",
"description": "User is important an account and needs to add a file to continue"
},
"needImportPassword": {
"message": "คณตองปอนรหสผานสำหรบไฟลเลอก",
"description": "Password and file needed to import an account"
},
"negativeETH": {
"message": "ไมสามารถสงอเธอรเปนจำนวนตดลบได"
},
"networks": {
"message": "เครอขาย"
},
"newAccount": {
"message": "บญชใหม"
},
"newAccountNumberName": {
"message": "บญช $1",
"description": "Default name of next account to be created on create account screen"
},
"newContract": {
"message": "สรางสญญาใหม"
},
"newPassword": {
"message": "รหสผานใหม(ขนตำ 8 ตวอกษร)"
},
"newRecipient": {
"message": "ผบใหม"
},
"newRPC": {
"message": "RPC URL ใหม"
},
"next": {
"message": "ถดไป"
},
"noAddressForName": {
"message": "ยงไมแอดแดรสไหนตงในชอน"
},
"noDeposits": {
"message": "ไมเงนฝากเขามา"
},
"noTransactionHistory": {
"message": "ไมรายการธรกรรมในอดต"
},
"noTransactions": {
"message": "ยงไมรายการธรกรรม"
},
"notStarted": {
"message": "ยงไมเรม"
},
"oldUI": {
"message": "หนาตาแบบเกา"
},
"oldUIMessage": {
"message": "คณไดเปลยนเปนหนาตาแบบเกาแลว คณสามารถเปลยนเปนหนาตาแบบใหมไดโดยไปทวเลอกตรงเมนมขวาบน"
},
"or": {
"message": "หรอ",
"description": "choice between creating or importing a new account"
},
"passwordCorrect": {
"message": "โปรดตรวจสอบวารหสผานของคณถกตอง"
},
"passwordMismatch": {
"message": "รหสผานไมตรงกน",
"description": "in password creation process, the two new password fields did not match"
},
"passwordShort": {
"message": "รหสผานไมยาวพอ",
"description": "in password creation process, the password is not long enough to be secure"
},
"pastePrivateKey": {
"message": "วางควนตวของคณท:",
"description": "For importing an account from a private key"
},
"pasteSeed": {
"message": "วางคำชดของคณท!"
},
"personalAddressDetected": {
"message": "ตรวจพบแอดแดรสสวนตวแลว ใสแอดแดรสสญญาโทเคน"
},
"pleaseReviewTransaction": {
"message": "โปรดตรวจสอบธรกรรมของคณ"
},
"privacyMsg": {
"message": "นโยบายสความเปนสวนตว"
},
"privateKey": {
"message": "ควนตว",
"description": "select this type of file to use to import an account"
},
"privateKeyWarning": {
"message": "คำเตอน: หามเปดเผยคกคนทวนตวสามารถขโมยขอมลใด ๆ ทเกบไวในบญชของคณได"
},
"privateNetwork": {
"message": "เครอขายสวนตว"
},
"qrCode": {
"message": "แสดง QR Code"
},
"readdToken": {
"message": "คณสามารถเพมโทเคนนในอนาคตไดโดยไปท “เพมโทเคน” ในเมนวเลอกบญชของคณ"
},
"readMore": {
"message": "อานเพมเตมท"
},
"readMore2": {
"message": "อานเพมเตม"
},
"receive": {
"message": "รบ"
},
"recipientAddress": {
"message": "แอดแดรสผบ"
},
"refundAddress": {
"message": "แอดแดรสสำหรบการคนเงนของคณ"
},
"rejected": {
"message": "ถกปฏเสธ"
},
"resetAccount": {
"message": "รเซตบญช"
},
"restoreFromSeed": {
"message": "กนจากกลมคำชด"
},
"required": {
"message": "จำเปน"
},
"retryWithMoreGas": {
"message": "ลองใหมวยราคาแกสทงกวาน"
},
"revealSeedWords": {
"message": "เปดเผยกลมคำชด"
},
"revealSeedWordsWarning": {
"message": "อยาเปดเผยคำกลมคำชดของคณในทสาธารณะ! คำเหลานสามารถใชเพอขโมยบญชงหมดของคณ"
},
"revert": {
"message": "ยอนกลบ"
},
"rinkeby": {
"message": "เครอขายทดสอบ Rinkeby"
},
"ropsten": {
"message": "เครอขายทดสอบ Ropsten"
},
"sampleAccountName": {
"message": "เชน บญชเฮงเฮงของฉน",
"description": "Help user understand concept of adding a human-readable name to their account"
},
"save": {
"message": "บนทก"
},
"saveAsFile": {
"message": "บนทกเปนไฟล",
"description": "Account export process"
},
"saveSeedAsFile": {
"message": "บนทกกลมคำชดเปนไฟล"
},
"search": {
"message": "คนหา"
},
"secretPhrase": {
"message": "ปอนกลมคำสบสองคำเพอกนตเซฟของคณ"
},
"seedPhraseReq": {
"message": "กลมคำชดมความยาว 12 คำ"
},
"select": {
"message": "เลอก"
},
"selectCurrency": {
"message": "เลอกสกลเงน"
},
"selectService": {
"message": "เลอกบรการ"
},
"selectType": {
"message": "เลอกประเภท"
},
"send": {
"message": "สง"
},
"sendETH": {
"message": "สงอเธอร"
},
"sendTokens": {
"message": "สงโทเคน"
},
"sendTokensAnywhere": {
"message": "สงโทเคนไปใหกคนทญชเธอเรยม"
},
"settings": {
"message": "การตงคา"
},
"shapeshiftBuy": {
"message": "ซอดวย Shapeshift"
},
"showPrivateKeys": {
"message": "แสดงควนตว"
},
"showQRCode": {
"message": "แสดง QR Code"
},
"sign": {
"message": "เซนชอ"
},
"signMessage": {
"message": "เซนชอในขอความ"
},
"signNotice": {
"message": "การเซนชอในขอความนอาจจะเปนอนตรายได \nเซนชอเฉพาะขอความจากแหลงทณไววางใจไดจรง ๆ เทานน \nวนตรายนจะถกลบออกในอนาคต"
},
"sigRequest": {
"message": "ขอลายเซน"
},
"sigRequested": {
"message": "ขอลายเซนแลว"
},
"spaceBetween": {
"message": "มองวางไดเพยงตวเดยวระหวางคำเทานน"
},
"status": {
"message": "สถานะ"
},
"stateLogs": {
"message": "บนทกของสถานะ"
},
"stateLogsDescription": {
"message": "บนทกของสถานะประกอบดวยแอดแดรสสาธารณะและธรกรรมทง"
},
"submit": {
"message": "ตกลง"
},
"supportCenter": {
"message": "ไปทนยสนบสนนของเรา"
},
"symbolBetweenZeroTen": {
"message": "สญลกษณองมความยาวตงแต 0 ถง 10 อกขระ"
},
"takesTooLong": {
"message": "ใชเวลานานเกนไปใชหรอไม?"
},
"terms": {
"message": "ขอตกลงในการใชงาน"
},
"testFaucet": {
"message": "ตวแจกจายเพอการทดสอบ"
},
"to": {
"message": "ถง"
},
"toETHviaShapeShift": {
"message": "$1 เปนอเธอรโดย ShapeShift",
"description": "system will fill in deposit type in start of message"
},
"tokenAddress": {
"message": "แอดแดรสโทเคน"
},
"tokenAlreadyAdded": {
"message": "โทเคนไดกเพมไปแลว"
},
"tokenBalance": {
"message": "ยอดโทเคนคงเหลอของคณคอ:"
},
"tokenSelection": {
"message": "คนหาโทเคนหรอเลอกจากรายการโทเคนยอดนยมของเรา"
},
"tokenSymbol": {
"message": "สญลกษณประจำตว"
},
"tokenWarning1": {
"message": "ตดตามโทเคนทณซอดวยบญช MetaMask ของคณ หากคณซอโทเคนโดยใชญชนโทเคนเหลานนจะไมปรากฏท"
},
"total": {
"message": "รวม"
},
"transactions": {
"message": "ธรกรรม"
},
"transactionMemo": {
"message": "บนทกชวยจำของการทำธรกรรม (ไมงคบ)"
},
"transactionNumber": {
"message": "หมายเลขธรกรรม"
},
"transfers": {
"message": "โอน"
},
"troubleTokenBalances": {
"message": "เรามญหาในการโหลดยอดโทเคนคงเหลอของคณ คณสามารถดได",
"description": "Followed by a link (here) to view token balances"
},
"twelveWords": {
"message": "กลมคำ 12 คำเหลานเปนวเดยวทจะกนบญช MetaMask ของคณ \n กรณาเกบไวในทปลอดภยและเกบเปนความลบ"
},
"typePassword": {
"message": "พมพรหสผานของคณ"
},
"uiWelcome": {
"message": "ยนดอนรบสหนาตาใหม (เบตา)"
},
"uiWelcomeMessage": {
"message": "ขณะนณใชงาน Metamask หนาตาใหมแลว ลองใชความสามรถใหม ๆ เชนการสงโทเคนและหากพบปญหากรณาแจงใหเราทราบ"
},
"unavailable": {
"message": "ใชงานไมได"
},
"unknown": {
"message": "ไมก"
},
"unknownNetwork": {
"message": "ไมกเครอขายสวนตว"
},
"unknownNetworkId": {
"message": "ไมกหมายเลขเครอขาย"
},
"uriErrorMsg": {
"message": "URI ตองมคำนำหนาเปน HTTP หรอ HTTPS"
},
"usaOnly": {
"message": "ในสหรฐอเมรกาเทานน",
"description": "Using this exchange is limited to people inside the USA"
},
"usedByClients": {
"message": "ถกใชงานโดยหลายไคลเอนท"
},
"useOldUI": {
"message": "ใชหนาตาเกา"
},
"validFileImport": {
"message": "คณตองเลอกไฟลกตองเพอนำเขา"
},
"vaultCreated": {
"message": "สรางตเซฟแลว"
},
"viewAccount": {
"message": "ดญช"
},
"visitWebSite": {
"message": "เยยมชมเวบไซตของเรา"
},
"warning": {
"message": "คำเตอน"
},
"welcomeBeta": {
"message": "ยนดอนรบส MetaMask เบตา"
},
"whatsThis": {
"message": "นออะไร?"
},
"yourSigRequested": {
"message": "ลายเซนของคณกำลงไดบการรองขอ"
},
"youSign": {
"message": "คณกำลงเซนชอ"
}
}

@ -0,0 +1,903 @@
{
"accept": {
"message": "接受"
},
"account": {
"message": "帳戶"
},
"accountDetails": {
"message": "帳戶詳情"
},
"accountName": {
"message": "帳戶名稱"
},
"address": {
"message": "帳戶地址"
},
"addCustomToken": {
"message": "加入自訂代幣"
},
"addToken": {
"message": "加入代幣"
},
"addTokens": {
"message": "加入多筆代幣"
},
"amount": {
"message": "數額"
},
"amountPlusGas": {
"message": "數額 + Gas"
},
"appDescription": {
"message": "乙太坊瀏覽器擴充插件",
"description": "The description of the application"
},
"appName": {
"message": "MetaMask",
"description": "The name of the application"
},
"approved": {
"message": "已同意"
},
"attemptingConnect": {
"message": "正在嘗試連接區塊鏈。"
},
"attributions": {
"message": "來源"
},
"available": {
"message": "可使用"
},
"back": {
"message": "上一頁"
},
"balance": {
"message": "餘額:"
},
"balances": {
"message": "你的餘額:"
},
"balanceIsInsufficientGas": {
"message": "當前餘額不足以支付 Gas"
},
"beta": {
"message": "BETA"
},
"betweenMinAndMax": {
"message": "必須大於等於 $1 並且小於等於 $2 。",
"description": "helper for inputting hex as decimal input"
},
"blockiesIdenticon": {
"message": "使用 Blockies Identicon"
},
"borrowDharma": {
"message": "透過 Dharma (Beta) 借用"
},
"builtInCalifornia": {
"message": "MetaMask 是在加州設計製造."
},
"buy": {
"message": "購買"
},
"buyCoinbase": {
"message": "在 Coinbase 上購買"
},
"buyCoinbaseExplainer": {
"message": "Coinbase 是世界上最流行的買賣比特幣,以太幣和萊特幣的交易所。"
},
"ok": {
"message": "Ok"
},
"cancel": {
"message": "取消"
},
"classicInterface": {
"message": "使用舊版界面"
},
"clickCopy": {
"message": "點擊複製"
},
"confirm": {
"message": "確認"
},
"confirmed": {
"message": "已確認"
},
"confirmContract": {
"message": "確認合約"
},
"confirmPassword": {
"message": "確認密碼"
},
"confirmTransaction": {
"message": "確認交易"
},
"continue": {
"message": "繼續"
},
"continueToCoinbase": {
"message": "繼續前往 Coinbase"
},
"contractDeployment": {
"message": "合約部署"
},
"conversionProgress": {
"message": "正在取得匯率"
},
"copiedButton": {
"message": "已複製"
},
"copiedClipboard": {
"message": "已複製到剪貼簿"
},
"copiedExclamation": {
"message": "已複製!"
},
"copiedSafe": {
"message": "我已經複製到某個安全的地方了"
},
"copy": {
"message": "複製"
},
"copyToClipboard": {
"message": "複製到剪貼簿"
},
"copyButton": {
"message": " 複製 "
},
"copyPrivateKey": {
"message": "這是你的私鑰(點擊複製)"
},
"create": {
"message": "建立"
},
"createAccount": {
"message": "建立帳戶"
},
"createDen": {
"message": "建立"
},
"crypto": {
"message": "加密",
"description": "Exchange type (cryptocurrencies)"
},
"currentConversion": {
"message": "當前匯率"
},
"currentNetwork": {
"message": "當前網路"
},
"customGas": {
"message": "自訂 Gas"
},
"customToken": {
"message": "自訂代幣"
},
"customize": {
"message": "自訂"
},
"customRPC": {
"message": "自訂 RPC"
},
"decimalsMustZerotoTen": {
"message": "小數點後位數至少為0, 最多為36."
},
"decimal": {
"message": "小數點精度"
},
"defaultNetwork": {
"message": "預設 Ether 交易網路為主網路(Main Net)。"
},
"denExplainer": {
"message": "你的 DEN 是在你的 MetaMask 中的加密密碼儲存庫。"
},
"deposit": {
"message": "存入"
},
"depositBTC": {
"message": "將你的 BTC 存入到下面的地址:"
},
"depositCoin": {
"message": "將你的 $1 存入到下面的地址",
"description": "Tells the user what coin they have selected to deposit with shapeshift"
},
"depositEth": {
"message": "存入 Eth"
},
"depositEther": {
"message": "存入 Ether"
},
"depositFiat": {
"message": "從法定貨幣存入"
},
"depositFromAccount": {
"message": "從其他帳戶存入"
},
"depositShapeShift": {
"message": "從 ShapeShift 存入"
},
"depositShapeShiftExplainer": {
"message": "如果你擁有其他加密貨幣,你可以直接交易並存入 Ether 到你的 MetaMask 錢包。不需要開帳戶。"
},
"details": {
"message": "詳情"
},
"directDeposit": {
"message": "直接存入"
},
"directDepositEther": {
"message": "直接存入 Ether"
},
"directDepositEtherExplainer": {
"message": "如果你已經擁有了一些 Ether,使用直接存入功能是讓你的新錢包最快取得 Ether 的方式。"
},
"done": {
"message": "完成"
},
"downloadStatelogs": {
"message": "下載狀態紀錄"
},
"dropped": {
"message": "丟棄"
},
"edit": {
"message": "編輯"
},
"editAccountName": {
"message": "編輯帳戶名稱"
},
"emailUs": {
"message": "寄 Email 給我們!"
},
"encryptNewDen": {
"message": "加密你的新 DEN"
},
"enterPassword": {
"message": "請輸入密碼"
},
"enterPasswordConfirm": {
"message": "請再次輸入密碼確認"
},
"passwordNotLongEnough": {
"message": "您所輸入的密碼長度不足"
},
"passwordsDontMatch": {
"message": "您所輸入的密碼不一致"
},
"etherscanView": {
"message": "在 Etherscan 上查看帳戶"
},
"exchangeRate": {
"message": "匯率"
},
"exportPrivateKey": {
"message": "導出私鑰"
},
"exportPrivateKeyWarning": {
"message": "您需要自行負擔導出私鑰產生的風險"
},
"failed": {
"message": "失败"
},
"fiat": {
"message": "FIAT",
"description": "Exchange type"
},
"fileImportFail": {
"message": "檔案導入失敗?點擊這裡!",
"description": "Helps user import their account from a JSON file"
},
"followTwitter": {
"message": "追蹤 Twitter"
},
"from": {
"message": "來源地址"
},
"fromToSame": {
"message": "來源和目的地址不能一樣"
},
"fromShapeShift": {
"message": "來自 ShapeShift"
},
"gas": {
"message": "Gas",
"description": "Short indication of gas cost"
},
"gasFee": {
"message": "Gas 費用"
},
"gasLimit": {
"message": "Gas 上限"
},
"gasLimitCalculation": {
"message": "我們根據網路成功率算出建議的 Gas 上限。"
},
"gasLimitRequired": {
"message": "必需填寫 Gas 上限"
},
"gasLimitTooLow": {
"message": "Gas 上限至少為 21000"
},
"generatingSeed": {
"message": "產生助憶詞中..."
},
"gasPrice": {
"message": "Gas 價格 (GWEI)"
},
"gasPriceCalculation": {
"message": "我們根據網路成功率算出建議的 Gas 價格"
},
"gasPriceRequired": {
"message": "必需填寫 Gas 價格"
},
"getEther": {
"message": "取得 Ether"
},
"getEtherFromFaucet": {
"message": "從水管取得$1 Ether",
"description": "Displays network name for Ether faucet"
},
"greaterThanMin": {
"message": "必須要大於等於 $1。",
"description": "helper for inputting hex as decimal input"
},
"here": {
"message": "這裡",
"description": "as in -click here- for more information (goes with troubleTokenBalances)"
},
"hereList": {
"message": "Here's a list!!!!"
},
"hide": {
"message": "隱藏"
},
"hideToken": {
"message": "隱藏代幣"
},
"hideTokenPrompt": {
"message": "隱藏代幣?"
},
"howToDeposit": {
"message": "你想怎麼存入 Ether?"
},
"holdEther": {
"message": "Metamask 讓您能保存 ether 和代幣, 並成為您接觸分散式應用程式的途徑."
},
"import": {
"message": "導入",
"description": "Button to import an account from a selected file"
},
"importAccount": {
"message": "導入帳戶"
},
"importAccountMsg": {
"message":" 匯入的帳戶與您原有 MetaMask 帳戶的助憶詞並無關聯. 請查看與導入帳戶相關的資料 "
},
"importAnAccount": {
"message": "導入一個帳戶"
},
"importDen": {
"message": "導入現成的 DEN"
},
"imported": {
"message": "已導入私鑰",
"description": "status showing that an account has been fully loaded into the keyring"
},
"infoHelp": {
"message": "說明 & 資訊"
},
"insufficientFunds": {
"message": "資金不足."
},
"insufficientTokens": {
"message": "代幣不足."
},
"invalidAddress": {
"message": "錯誤的地址"
},
"invalidAddressRecipient": {
"message": "接收地址錯誤"
},
"invalidGasParams": {
"message": "Gas 參數錯誤"
},
"invalidInput": {
"message": "輸入錯誤。"
},
"invalidRequest": {
"message": "無效的請求"
},
"invalidRPC": {
"message": "無效的 RPC URI"
},
"jsonFail": {
"message": "有東西出錯了. 請確認你的 JSON 檔案格式正確。"
},
"jsonFile": {
"message": "JSON 檔案",
"description": "format for importing an account"
},
"keepTrackTokens": {
"message": "持續追蹤您 MetaMask 帳戶中的代幣。"
},
"kovan": {
"message": "Kovan 測試網路"
},
"knowledgeDataBase": {
"message": "查看我們的知識庫"
},
"max": {
"message": "最大值"
},
"learnMore": {
"message": "了解更多。"
},
"lessThanMax": {
"message": "必須小於等於 $1.",
"description": "helper for inputting hex as decimal input"
},
"likeToAddTokens": {
"message": "您確定要加入這些代幣嗎?"
},
"links": {
"message": "連結"
},
"limit": {
"message": "上限"
},
"loading": {
"message": "載入..."
},
"loadingTokens": {
"message": "載入代幣..."
},
"localhost": {
"message": "Localhost 8545"
},
"login": {
"message": "登入"
},
"logout": {
"message": "登出"
},
"loose": {
"message": "非 MetaMask 帳號"
},
"loweCaseWords": {
"message": "助憶詞僅包含小寫字元"
},
"mainnet": {
"message": "乙太坊 主網路"
},
"message": {
"message": "訊息"
},
"metamaskDescription": {
"message": "MetaMask 是Ethereum的安全身份識別金庫."
},
"min": {
"message": "最小"
},
"myAccounts": {
"message": "我的帳戶"
},
"mustSelectOne": {
"message": "必須選擇至少 1 代幣."
},
"needEtherInWallet": {
"message": "要使用 MetaMask 存取 DAPP 時,您的錢包中需要有 Ether。"
},
"needImportFile": {
"message": "您必須選擇一個檔案來導入。",
"description": "User is important an account and needs to add a file to continue"
},
"needImportPassword": {
"message": "您必須為選擇好的檔案輸入密碼。",
"description": "Password and file needed to import an account"
},
"negativeETH": {
"message": "不能送出負值的 ETH。"
},
"networks": {
"message": "網路"
},
"newAccount": {
"message": "新帳戶"
},
"newAccountNumberName": {
"message": "帳戶 $1",
"description": "Default name of next account to be created on create account screen"
},
"newContract": {
"message": "新合約"
},
"newPassword": {
"message": "新密碼(至少8個字)"
},
"newRecipient": {
"message": "新收款人"
},
"newRPC": {
"message": "New RPC URL"
},
"next": {
"message": "下一頁"
},
"noAddressForName": {
"message": "此 ENS 尚未指定地址。"
},
"noDeposits": {
"message": "尚未有存款"
},
"noTransactionHistory": {
"message": "尚未有交易紀錄。"
},
"noTransactions": {
"message": "尚未有交易"
},
"notStarted": {
"message": "尚未開始"
},
"oldUI": {
"message": "舊版界面"
},
"oldUIMessage": {
"message": "你已經切換到舊版界面。可以通過右上方下拉選單中的選項切換回新的使用者界面。"
},
"or": {
"message": "或",
"description": "choice between creating or importing a new account"
},
"passwordCorrect": {
"message": "請確認您的密碼是正確的。"
},
"passwordMismatch": {
"message": "密碼不一致",
"description": "in password creation process, the two new password fields did not match"
},
"passwordShort": {
"message": "密碼不夠長",
"description": "in password creation process, the password is not long enough to be secure"
},
"pastePrivateKey": {
"message": "請貼上你的私鑰串:",
"description": "For importing an account from a private key"
},
"pasteSeed": {
"message": "請貼上你的助憶詞!"
},
"personalAddressDetected": {
"message": "已偵測到個人地址. 請輸入代幣合約地址."
},
"pleaseReviewTransaction": {
"message": "請檢查你的交易。"
},
"popularTokens": {
"message": "常見的代幣"
},
"privacyMsg": {
"message": "隱私政策"
},
"privateKey": {
"message": "私鑰",
"description": "select this type of file to use to import an account"
},
"privateKeyWarning": {
"message": "注意:永遠不要公開這個私鑰。任何取得這把私鑰的人都可以竊取這個帳號中的任何資產。"
},
"privateNetwork": {
"message": "私有網路"
},
"qrCode": {
"message": "顯示 QR Code"
},
"readdToken": {
"message": "之後還可以透過帳戶選單中的“加入代幣”來加入此代幣。"
},
"readMore": {
"message": "了解更多。"
},
"readMore2": {
"message": "了解更多。"
},
"receive": {
"message": "接收"
},
"recipientAddress": {
"message": "接收地址"
},
"refundAddress": {
"message": "你的退款地址"
},
"rejected": {
"message": "拒絕"
},
"resetAccount": {
"message": "重置帳戶"
},
"restoreFromSeed": {
"message": "透過助憶詞重置"
},
"restoreVault": {
"message": "重置金庫"
},
"required": {
"message": "必填"
},
"retryWithMoreGas": {
"message": "改用更高的 Gas 價格重試"
},
"walletSeed": {
"message": "錢包助憶詞"
},
"revealSeedWords": {
"message": "顯示助憶詞"
},
"revealSeedWordsWarning": {
"message": "別在公共場合回復你的助憶詞!這些詞可被用來竊取你的帳戶."
},
"revert": {
"message": "還原"
},
"rinkeby": {
"message": "Rinkeby 測試網路"
},
"ropsten": {
"message": "Ropsten 測試網路"
},
"currentRpc": {
"message": "當前的 RPC"
},
"connectingToMainnet": {
"message": "連線到主 Ethereum 網路"
},
"connectingToRopsten": {
"message": "連線到 Ropsten 測試網路"
},
"connectingToKovan": {
"message": "連線到 Kovan 測試網路"
},
"connectingToRinkeby": {
"message": "連線到 Rinkeby 測試網路"
},
"connectingToUnknown": {
"message": "連線到未知網路"
},
"sampleAccountName": {
"message": "例如:我的新帳戶",
"description": "Help user understand concept of adding a human-readable name to their account"
},
"save": {
"message": "儲存"
},
"saveAsFile": {
"message": "儲存檔案",
"description": "Account export process"
},
"saveSeedAsFile": {
"message": "將助憶詞儲存成檔案"
},
"search": {
"message": "搜尋"
},
"secretPhrase": {
"message": "在此輸入你的12個祕密助憶詞以回復金庫."
},
"newPassword8Chars": {
"message": "新密碼 (至少 8 個字元)"
},
"seedPhraseReq": {
"message": "助憶詞為 12 個詞語"
},
"select": {
"message": "選擇"
},
"selectCurrency": {
"message": "選擇幣別"
},
"selectService": {
"message": "選擇服務"
},
"selectType": {
"message": "選擇類型"
},
"send": {
"message": "發送"
},
"sendETH": {
"message": "發送 ETH"
},
"sendTokens": {
"message": "發送代幣"
},
"onlySendToEtherAddress": {
"message": "只發送 ETH 到乙太坊地址."
},
"searchTokens": {
"message": "搜尋代幣"
},
"sendTokensAnywhere": {
"message": "發送代幣給擁有乙太坊帳戶的任何人"
},
"settings": {
"message": "設定"
},
"info": {
"message": "資訊"
},
"shapeshiftBuy": {
"message": "從 Shapeshift 購買"
},
"showPrivateKeys": {
"message": "顯示私鑰"
},
"showQRCode": {
"message": "顯示 QR Code"
},
"sign": {
"message": "簽署"
},
"signed": {
"message": "已簽署"
},
"signMessage": {
"message": "簽署訊息"
},
"signNotice": {
"message": "簽署此訊息可能會產生危險地副作用。 \n只從你完全信任的網站上簽署。這種危險的方法;將在未來的版本中被移除。"
},
"sigRequest": {
"message": "請求簽署"
},
"sigRequested": {
"message": "已請求簽署"
},
"spaceBetween": {
"message": "there can only be a space between words"
},
"status": {
"message": "狀態"
},
"stateLogs": {
"message": "狀態紀錄"
},
"stateLogsDescription": {
"message": "狀態紀錄包含你的公開帳戶地址和已傳送的交易資訊."
},
"stateLogError": {
"message": "在取得狀態紀錄時發生錯誤."
},
"submit": {
"message": "送出"
},
"submitted": {
"message": "已送出"
},
"supportCenter": {
"message": "造訪我們的協助中心"
},
"symbolBetweenZeroTen": {
"message": "代號必須介於 0 到 10 字元間."
},
"takesTooLong": {
"message": "花費太長時間?"
},
"terms": {
"message": "使用條款"
},
"testFaucet": {
"message": "測試水管"
},
"to": {
"message": "目的帳號"
},
"toETHviaShapeShift": {
"message": "$1 ETH 透過 ShapeShift",
"description": "system will fill in deposit type in start of message"
},
"tokenAddress": {
"message": "代幣地址"
},
"tokenAlreadyAdded": {
"message": "已加入過此代幣。"
},
"tokenBalance": {
"message": "代幣餘額:"
},
"tokenSelection": {
"message": "搜尋代幣或是從常見代幣列表中選擇。"
},
"tokenSymbol": {
"message": "代幣代號"
},
"tokenWarning1": {
"message": "使用 MetaMask 帳戶追蹤你已購得的代幣。如果你使用不同的帳戶保存購得的代幣,那些代幣就不會出現在這裡。"
},
"total": {
"message": "總量"
},
"transactions": {
"message": "交易紀錄"
},
"transactionMemo": {
"message": "交易備註(選填)"
},
"transactionNumber": {
"message": "交易號碼"
},
"transfers": {
"message": "交易"
},
"troubleTokenBalances": {
"message": "無法取得代幣餘額。您k可以到這裡查看 ",
"description": "Followed by a link (here) to view token balances"
},
"twelveWords": {
"message": "這 12 個單詞是唯一回復你的 MetaMask 帳號的方法。\n將它們儲存到那些安全且隱密的地方吧。"
},
"typePassword": {
"message": "請輸入密碼"
},
"uiWelcome": {
"message": "歡迎使用新版界面 (Beta)"
},
"uiWelcomeMessage": {
"message": "你現在正在使用新版 MetaMask 界面。試試諸如發送代幣等新功能吧,有任何問題請告知我們。"
},
"unapproved": {
"message": "未同意"
},
"unavailable": {
"message": "不可用"
},
"unknown": {
"message": "未知"
},
"unknownNetwork": {
"message": "未知私有網路"
},
"unknownNetworkId": {
"message": "未知網路 ID"
},
"uriErrorMsg": {
"message": "URIs 需要加入適當的 HTTP/HTTPS 前綴."
},
"usaOnly": {
"message": "僅限美國",
"description": "Using this exchange is limited to people inside the USA"
},
"usedByClients": {
"message": "可用於各種不同的客戶端"
},
"useOldUI": {
"message": "使用舊版界面"
},
"validFileImport": {
"message": "您必須選擇一個合法的檔案來導入."
},
"vaultCreated": {
"message": "已建立金庫"
},
"viewAccount": {
"message": "查看帳戶"
},
"visitWebSite": {
"message": "造訪我們的網站"
},
"warning": {
"message": "警告"
},
"welcomeBeta": {
"message": "歡迎到 MetaMask Beta"
},
"whatsThis": {
"message": "這是什麼?"
},
"yourSigRequested": {
"message": "正在請求你的簽署"
},
"youSign": {
"message": "正在簽署"
}
}

@ -1,7 +1,7 @@
{ {
"name": "__MSG_appName__", "name": "__MSG_appName__",
"short_name": "__MSG_appName__", "short_name": "__MSG_appName__",
"version": "4.2.0", "version": "4.4.0",
"manifest_version": 2, "manifest_version": 2,
"author": "https://metamask.io", "author": "https://metamask.io",
"description": "__MSG_appDescription__", "description": "__MSG_appDescription__",

@ -42,6 +42,7 @@ const isIE = !!document.documentMode
const isEdge = !isIE && !!window.StyleMedia const isEdge = !isIE && !!window.StyleMedia
let popupIsOpen = false let popupIsOpen = false
let notificationIsOpen = false
let openMetamaskTabsIDs = {} let openMetamaskTabsIDs = {}
// state persistence // state persistence
@ -83,7 +84,6 @@ async function loadStateFromPersistence () {
// write to disk // write to disk
if (localStore.isSupported) localStore.set(versionedData) if (localStore.isSupported) localStore.set(versionedData)
diskStore.putState(versionedData)
// return just the data // return just the data
return versionedData.data return versionedData.data
@ -120,7 +120,6 @@ function setupController (initState) {
debounce(1000), debounce(1000),
storeTransform(versionifyData), storeTransform(versionifyData),
storeTransform(syncDataWithExtension), storeTransform(syncDataWithExtension),
asStream(diskStore),
(error) => { (error) => {
log.error('pump hit error', error) log.error('pump hit error', error)
} }
@ -165,6 +164,11 @@ function setupController (initState) {
} }
}) })
} }
if (remotePort.name === 'notification') {
endOfStream(portStream, () => {
notificationIsOpen = false
})
}
} else { } else {
// communication with page // communication with page
const originDomain = urlUtil.parse(remotePort.sender.url).hostname const originDomain = urlUtil.parse(remotePort.sender.url).hostname
@ -207,7 +211,8 @@ function setupController (initState) {
function triggerUi () { function triggerUi () {
extension.tabs.query({ active: true }, (tabs) => { extension.tabs.query({ active: true }, (tabs) => {
const currentlyActiveMetamaskTab = tabs.find(tab => openMetamaskTabsIDs[tab.id]) const currentlyActiveMetamaskTab = tabs.find(tab => openMetamaskTabsIDs[tab.id])
if (!popupIsOpen && !currentlyActiveMetamaskTab) notificationManager.showPopup() if (!popupIsOpen && !currentlyActiveMetamaskTab && !notificationIsOpen) notificationManager.showPopup()
notificationIsOpen = true
}) })
} }

@ -13,11 +13,12 @@ class NotificationManager {
this._getPopup((err, popup) => { this._getPopup((err, popup) => {
if (err) throw err if (err) throw err
// Bring focus to chrome popup
if (popup) { if (popup) {
// bring focus to existing popup // bring focus to existing chrome popup
extension.windows.update(popup.id, { focused: true }) extension.windows.update(popup.id, { focused: true })
} else { } else {
// create new popup // create new notification popup
extension.windows.create({ extension.windows.create({
url: 'notification.html', url: 'notification.html',
type: 'popup', type: 'popup',
@ -29,6 +30,7 @@ class NotificationManager {
} }
closePopup () { closePopup () {
// closes notification popup
this._getPopup((err, popup) => { this._getPopup((err, popup) => {
if (err) throw err if (err) throw err
if (!popup) return if (!popup) return
@ -60,9 +62,8 @@ class NotificationManager {
_getPopupIn (windows) { _getPopupIn (windows) {
return windows ? windows.find((win) => { return windows ? windows.find((win) => {
return (win && win.type === 'popup' && // Returns notification popup
win.height === height && return (win && win.type === 'popup')
win.width === width)
}) : null }) : null
} }

@ -1,4 +1,4 @@
const Raven = require('../vendor/raven.min.js') const Raven = require('raven-js')
const METAMASK_DEBUG = 'GULP_METAMASK_DEBUG' const METAMASK_DEBUG = 'GULP_METAMASK_DEBUG'
const PROD = 'https://3567c198f8a8412082d32655da2961d0@sentry.io/273505' const PROD = 'https://3567c198f8a8412082d32655da2961d0@sentry.io/273505'
const DEV = 'https://f59f3dd640d2429d9d0e2445a87ea8e1@sentry.io/273496' const DEV = 'https://f59f3dd640d2429d9d0e2445a87ea8e1@sentry.io/273496'
@ -18,9 +18,35 @@ function setupRaven(opts) {
ravenTarget = PROD ravenTarget = PROD
} }
Raven.config(ravenTarget, { const client = Raven.config(ravenTarget, {
release, release,
}).install() transport: function(opts) {
// modify report urls
const report = opts.data
rewriteReportUrls(report)
// make request normally
client._makeRequest(opts)
},
})
client.install()
return Raven return Raven
} }
function rewriteReportUrls(report) {
// update request url
report.request.url = toMetamaskUrl(report.request.url)
// update exception stack trace
report.exception.values.forEach(item => {
item.stacktrace.frames.forEach(frame => {
frame.filename = toMetamaskUrl(frame.filename)
})
})
}
function toMetamaskUrl(origUrl) {
const filePath = origUrl.split(location.origin)[1]
if (!filePath) return origUrl
const metamaskUrl = `metamask${filePath}`
return metamaskUrl
}

@ -0,0 +1,39 @@
const version = 22
/*
This migration adds submittedTime to the txMeta if it is not their
*/
const clone = require('clone')
module.exports = {
version,
migrate: function (originalVersionedData) {
const versionedData = clone(originalVersionedData)
versionedData.meta.version = version
try {
const state = versionedData.data
const newState = transformState(state)
versionedData.data = newState
} catch (err) {
console.warn(`MetaMask Migration #${version}` + err.stack)
}
return Promise.resolve(versionedData)
},
}
function transformState (state) {
const newState = state
const transactions = newState.TransactionController.transactions
newState.TransactionController.transactions = transactions.map((txMeta) => {
if (txMeta.status !== 'submitted' || txMeta.submittedTime) return txMeta
txMeta.submittedTime = (new Date()).getTime()
return txMeta
})
return newState
}

@ -32,4 +32,5 @@ module.exports = [
require('./019'), require('./019'),
require('./020'), require('./020'),
require('./021'), require('./021'),
require('./022'),
] ]

@ -65,6 +65,7 @@ startPopup({ container, connectionStream }, (err, store) => {
function closePopupIfOpen (windowType) { function closePopupIfOpen (windowType) {
if (windowType !== 'notification') { if (windowType !== 'notification') {
// should close only chrome popup
notificationManager.closePopup() notificationManager.closePopup()
} }
} }

File diff suppressed because one or more lines are too long

@ -339,7 +339,7 @@ function generateBundler(opts, performBundle) {
const browserifyOpts = assign({}, watchify.args, { const browserifyOpts = assign({}, watchify.args, {
entries: ['./app/scripts/'+opts.filename], entries: ['./app/scripts/'+opts.filename],
plugin: 'browserify-derequire', plugin: 'browserify-derequire',
debug: debug, debug: true,
fullPaths: debug, fullPaths: debug,
}) })
@ -405,13 +405,13 @@ function bundleTask(opts) {
.pipe(buffer()) .pipe(buffer())
// sourcemaps // sourcemaps
// loads map from browserify file // loads map from browserify file
.pipe(gulpif(debug, sourcemaps.init({ loadMaps: true }))) .pipe(sourcemaps.init({ loadMaps: true }))
// Minification // Minification
.pipe(gulpif(opts.isBuild, uglify({ .pipe(gulpif(opts.isBuild, uglify({
mangle: { reserved: [ 'MetamaskInpageProvider' ] }, mangle: { reserved: [ 'MetamaskInpageProvider' ] },
}))) })))
// writes .map file // writes .map file
.pipe(gulpif(debug, sourcemaps.write('./'))) .pipe(sourcemaps.write(debug ? './' : '../../sourcemaps'))
// write completed bundles // write completed bundles
.pipe(gulp.dest('./dist/firefox/scripts')) .pipe(gulp.dest('./dist/firefox/scripts'))
.pipe(gulp.dest('./dist/chrome/scripts')) .pipe(gulp.dest('./dist/chrome/scripts'))

@ -122,6 +122,10 @@
width: calc(100vw - 80px); width: calc(100vw - 80px);
} }
.unique-image {
width: auto;
}
.create-password__title, .create-password__title,
.unique-image__title, .unique-image__title,
.tou__title, .tou__title,
@ -221,10 +225,6 @@
max-width: 46rem; max-width: 46rem;
} }
.backup-phrase {
width: 100%;
}
.create-password__title, .create-password__title,
.unique-image__title, .unique-image__title,
.tou__title, .tou__title,
@ -674,7 +674,6 @@ button.backup-phrase__confirm-seed-option:hover {
} }
.buy-ether__action-content-wrapper { .buy-ether__action-content-wrapper {
width: 360px;
display: flex; display: flex;
flex-flow: column nowrap; flex-flow: column nowrap;
} }

@ -10,6 +10,7 @@ import ImportSeedPhraseScreen from './import-seed-phrase-screen'
import { import {
onboardingBuyEthView, onboardingBuyEthView,
unMarkPasswordForgotten, unMarkPasswordForgotten,
showModal,
} from '../../../../ui/app/actions' } from '../../../../ui/app/actions'
class FirstTimeFlow extends Component { class FirstTimeFlow extends Component {
@ -80,7 +81,7 @@ class FirstTimeFlow extends Component {
renderScreen () { renderScreen () {
const {SCREEN_TYPE} = FirstTimeFlow const {SCREEN_TYPE} = FirstTimeFlow
const { const {
goToBuyEtherView, openBuyEtherModal,
address, address,
restoreCreatePasswordScreen, restoreCreatePasswordScreen,
forgottenPassword, forgottenPassword,
@ -131,7 +132,7 @@ class FirstTimeFlow extends Component {
case SCREEN_TYPE.BACK_UP_PHRASE: case SCREEN_TYPE.BACK_UP_PHRASE:
return ( return (
<BackupPhraseScreen <BackupPhraseScreen
next={() => goToBuyEtherView(address)} next={() => openBuyEtherModal()}
/> />
) )
default: default:
@ -167,7 +168,7 @@ export default connect(
}), }),
dispatch => ({ dispatch => ({
leaveImportSeedScreenState: () => dispatch(unMarkPasswordForgotten()), leaveImportSeedScreenState: () => dispatch(unMarkPasswordForgotten()),
goToBuyEtherView: address => dispatch(onboardingBuyEthView(address)), openBuyEtherModal: () => dispatch(showModal({ name: 'DEPOSIT_ETHER'})),
}) })
)(FirstTimeFlow) )(FirstTimeFlow)

68
package-lock.json generated

@ -182,6 +182,48 @@
"through2": "2.0.3" "through2": "2.0.3"
} }
}, },
"@sentry/cli": {
"version": "1.30.3",
"resolved": "https://registry.npmjs.org/@sentry/cli/-/cli-1.30.3.tgz",
"integrity": "sha1-AtD3eBwe5eG+WkMSoyX76LGzcjE=",
"dev": true,
"requires": {
"https-proxy-agent": "2.2.0",
"node-fetch": "1.7.3",
"progress": "2.0.0",
"proxy-from-env": "1.0.0"
},
"dependencies": {
"agent-base": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.2.0.tgz",
"integrity": "sha512-c+R/U5X+2zz2+UCrCFv6odQzJdoqI+YecuhnAJLa1zYaMc13zPfwMwZrr91Pd1DYNo/yPRbiM4WVf9whgwFsIg==",
"dev": true,
"requires": {
"es6-promisify": "5.0.0"
}
},
"debug": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
"integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
"dev": true,
"requires": {
"ms": "2.0.0"
}
},
"https-proxy-agent": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.0.tgz",
"integrity": "sha512-uUWcfXHvy/dwfM9bqa6AozvAjS32dZSTUYd/4SEpYKRg6LEcPLshksnQYRudM9AyNvUARMfAg5TLjUDyX/K4vA==",
"dev": true,
"requires": {
"agent-base": "4.2.0",
"debug": "3.1.0"
}
}
}
},
"@types/node": { "@types/node": {
"version": "8.5.5", "version": "8.5.5",
"resolved": "https://registry.npmjs.org/@types/node/-/node-8.5.5.tgz", "resolved": "https://registry.npmjs.org/@types/node/-/node-8.5.5.tgz",
@ -4946,11 +4988,20 @@
} }
}, },
"es6-promise": { "es6-promise": {
"version": "3.0.2", "version": "4.2.4",
"resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-3.0.2.tgz", "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.4.tgz",
"integrity": "sha1-AQ1YWEI6XxGJeWZfRkhqlcbuK7Y=", "integrity": "sha512-/NdNZVJg+uZgtm9eS3O6lrOLYmQag2DjdEXuPaHlZ6RuVqgqaVZfgYCepEIKsLqwdQArOPtC3XzRLqGGfT8KQQ==",
"dev": true "dev": true
}, },
"es6-promisify": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz",
"integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=",
"dev": true,
"requires": {
"es6-promise": "4.2.4"
}
},
"es6-set": { "es6-set": {
"version": "0.1.5", "version": "0.1.5",
"resolved": "https://registry.npmjs.org/es6-set/-/es6-set-0.1.5.tgz", "resolved": "https://registry.npmjs.org/es6-set/-/es6-set-0.1.5.tgz",
@ -17041,6 +17092,12 @@
} }
} }
}, },
"proxy-from-env": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.0.0.tgz",
"integrity": "sha1-M8UDmPcOp+uW0h97gXYwpVeRx+4=",
"dev": true
},
"prr": { "prr": {
"version": "1.0.1", "version": "1.0.1",
"resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz",
@ -17364,6 +17421,11 @@
"eve-raphael": "0.5.0" "eve-raphael": "0.5.0"
} }
}, },
"raven-js": {
"version": "3.24.0",
"resolved": "https://registry.npmjs.org/raven-js/-/raven-js-3.24.0.tgz",
"integrity": "sha512-+/ygcWib8PXAE7Xq53j1tYxCgkzFyp9z05LYAKp2PA9KwO4Ek74q1tkGwZyPWI/FoXOgas6jNtQ7O3tdPif6uA=="
},
"raw-body": { "raw-body": {
"version": "2.3.2", "version": "2.3.2",
"resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.2.tgz", "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.2.tgz",

@ -12,7 +12,7 @@
"mascara": "gulp build && cross-env METAMASK_DEBUG=true node ./mascara/example/server", "mascara": "gulp build && cross-env METAMASK_DEBUG=true node ./mascara/example/server",
"dist": "npm run dist:clear && npm install && gulp dist", "dist": "npm run dist:clear && npm install && gulp dist",
"dist:clear": "rm -rf node_modules/eth-contract-metadata && rm -rf node_modules/eth-phishing-detect", "dist:clear": "rm -rf node_modules/eth-contract-metadata && rm -rf node_modules/eth-phishing-detect",
"test": "npm run lint && npm run test:coverage && npm run test:integration", "test": "npm run test:unit && npm run test:integration && npm run lint",
"test:unit": "cross-env METAMASK_ENV=test mocha --exit --require babel-core/register --require test/helper.js --recursive \"test/unit/**/*.js\"", "test:unit": "cross-env METAMASK_ENV=test mocha --exit --require babel-core/register --require test/helper.js --recursive \"test/unit/**/*.js\"",
"test:single": "cross-env METAMASK_ENV=test mocha --require test/helper.js", "test:single": "cross-env METAMASK_ENV=test mocha --require test/helper.js",
"test:integration": "npm run test:integration:build && npm run test:flat && npm run test:mascara", "test:integration": "npm run test:integration:build && npm run test:flat && npm run test:mascara",
@ -30,6 +30,13 @@
"test:mascara:build:ui": "browserify mascara/test/test-ui.js -o dist/mascara/ui.js", "test:mascara:build:ui": "browserify mascara/test/test-ui.js -o dist/mascara/ui.js",
"test:mascara:build:background": "browserify mascara/src/background.js -o dist/mascara/background.js", "test:mascara:build:background": "browserify mascara/src/background.js -o dist/mascara/background.js",
"test:mascara:build:tests": "browserify test/integration/lib/first-time.js -o dist/mascara/tests.js", "test:mascara:build:tests": "browserify test/integration/lib/first-time.js -o dist/mascara/tests.js",
"sentry": "export RELEASE=`cat app/manifest.json| jq -r .version` && npm run sentry:release && npm run sentry:upload",
"sentry:release": "npm run sentry:release:new && npm run sentry:release:clean",
"sentry:release:new": "sentry-cli releases --org 'metamask' --project 'metamask' new $RELEASE",
"sentry:release:clean": "sentry-cli releases --org 'metamask' --project 'metamask' files $RELEASE delete --all",
"sentry:upload": "npm run sentry:upload:source && npm run sentry:upload:maps",
"sentry:upload:source": "for FILEPATH in ./dist/chrome/scripts/*.js; do [ -e $FILEPATH ] || continue; export FILE=`basename $FILEPATH` && echo uploading $FILE && sentry-cli releases --org 'metamask' --project 'metamask' files $RELEASE upload $FILEPATH metamask/scripts/$FILE; done;",
"sentry:upload:maps": "sentry-cli releases --org 'metamask' --project 'metamask' files $RELEASE upload-sourcemaps ./dist/sourcemaps/ --url-prefix 'sourcemaps' --rewrite",
"lint": "gulp lint", "lint": "gulp lint",
"lint:fix": "gulp lint:fix", "lint:fix": "gulp lint:fix",
"disc": "gulp disc --debug", "disc": "gulp disc --debug",
@ -145,6 +152,7 @@
"pumpify": "^1.3.4", "pumpify": "^1.3.4",
"qrcode-npm": "0.0.3", "qrcode-npm": "0.0.3",
"ramda": "^0.24.1", "ramda": "^0.24.1",
"raven-js": "^3.24.0",
"react": "^15.6.2", "react": "^15.6.2",
"react-addons-css-transition-group": "^15.6.0", "react-addons-css-transition-group": "^15.6.0",
"react-dom": "^15.6.2", "react-dom": "^15.6.2",
@ -180,6 +188,7 @@
"xtend": "^4.0.1" "xtend": "^4.0.1"
}, },
"devDependencies": { "devDependencies": {
"@sentry/cli": "^1.30.3",
"babel-core": "^6.24.1", "babel-core": "^6.24.1",
"babel-eslint": "^8.0.0", "babel-eslint": "^8.0.0",
"babel-plugin-transform-async-to-generator": "^6.24.1", "babel-plugin-transform-async-to-generator": "^6.24.1",

@ -26,7 +26,7 @@ async function runAddTokenFlowTest (assert, done) {
assert.ok($('.token-list-item').length === 0, 'no tokens added') assert.ok($('.token-list-item').length === 0, 'no tokens added')
// Go to Add Token screen // Go to Add Token screen
let addTokenButton = await queryAsync($, 'button.btn-clear.wallet-view__add-token-button') let addTokenButton = await queryAsync($, 'button.btn-primary.wallet-view__add-token-button')
assert.ok(addTokenButton[0], 'add token button present') assert.ok(addTokenButton[0], 'add token button present')
addTokenButton[0].click() addTokenButton[0].click()
@ -34,26 +34,26 @@ async function runAddTokenFlowTest (assert, done) {
let addTokenWrapper = await queryAsync($, '.add-token__wrapper') let addTokenWrapper = await queryAsync($, '.add-token__wrapper')
assert.ok(addTokenWrapper[0], 'add token wrapper renders') assert.ok(addTokenWrapper[0], 'add token wrapper renders')
let addTokenTitle = await queryAsync($, '.add-token__title') let addTokenTitle = await queryAsync($, '.add-token__header__title')
assert.equal(addTokenTitle[0].textContent, 'Add Token', 'add token title is correct') assert.equal(addTokenTitle[0].textContent, 'Add Tokens', 'add token title is correct')
// Cancel Add Token // Cancel Add Token
const cancelAddTokenButton = await queryAsync($, 'button.btn-cancel.add-token__button') const cancelAddTokenButton = await queryAsync($, 'button.btn-secondary--lg.add-token__cancel-button')
assert.ok(cancelAddTokenButton[0], 'cancel add token button present') assert.ok(cancelAddTokenButton[0], 'cancel add token button present')
cancelAddTokenButton.click() cancelAddTokenButton.click()
assert.ok($('.wallet-view')[0], 'cancelled and returned to account detail wallet view') assert.ok($('.wallet-view')[0], 'cancelled and returned to account detail wallet view')
// Return to Add Token Screen // Return to Add Token Screen
addTokenButton = await queryAsync($, 'button.btn-clear.wallet-view__add-token-button') addTokenButton = await queryAsync($, 'button.btn-primary.wallet-view__add-token-button')
assert.ok(addTokenButton[0], 'add token button present') assert.ok(addTokenButton[0], 'add token button present')
addTokenButton[0].click() addTokenButton[0].click()
// Verify Add Token Screen // Verify Add Token Screen
addTokenWrapper = await queryAsync($, '.add-token__wrapper') addTokenWrapper = await queryAsync($, '.add-token__wrapper')
addTokenTitle = await queryAsync($, '.add-token__title') addTokenTitle = await queryAsync($, '.add-token__header__title')
assert.ok(addTokenWrapper[0], 'add token wrapper renders') assert.ok(addTokenWrapper[0], 'add token wrapper renders')
assert.equal(addTokenTitle[0].textContent, 'Add Token', 'add token title is correct') assert.equal(addTokenTitle[0].textContent, 'Add Tokens', 'add token title is correct')
// Search for token // Search for token
const searchInput = await queryAsync($, 'input.add-token__input') const searchInput = await queryAsync($, 'input.add-token__input')
@ -68,7 +68,7 @@ async function runAddTokenFlowTest (assert, done) {
tokenWrapper[0].click() tokenWrapper[0].click()
// Click Next button // Click Next button
let nextButton = await queryAsync($, 'button.btn-clear.add-token__button') let nextButton = await queryAsync($, 'button.btn-primary--lg')
assert.equal(nextButton[0].textContent, 'Next', 'next button rendered') assert.equal(nextButton[0].textContent, 'Next', 'next button rendered')
nextButton[0].click() nextButton[0].click()
@ -78,8 +78,8 @@ async function runAddTokenFlowTest (assert, done) {
'Would you like to add these tokens?', 'Would you like to add these tokens?',
'confirm add token rendered' 'confirm add token rendered'
) )
assert.ok($('button.btn-clear.add-token__button')[0], 'confirm add token button found') assert.ok($('button.btn-primary--lg')[0], 'confirm add token button found')
$('button.btn-clear.add-token__button')[0].click() $('button.btn-primary--lg')[0].click()
// Verify added token image // Verify added token image
let heroBalance = await queryAsync($, '.hero-balance') let heroBalance = await queryAsync($, '.hero-balance')
@ -87,13 +87,15 @@ async function runAddTokenFlowTest (assert, done) {
assert.ok(tokenImageUrl.indexOf(heroBalance.find('img').attr('src')) > -1, 'token added') assert.ok(tokenImageUrl.indexOf(heroBalance.find('img').attr('src')) > -1, 'token added')
// Return to Add Token Screen // Return to Add Token Screen
addTokenButton = await queryAsync($, 'button.btn-clear.wallet-view__add-token-button') addTokenButton = await queryAsync($, 'button.btn-primary.wallet-view__add-token-button')
assert.ok(addTokenButton[0], 'add token button present') assert.ok(addTokenButton[0], 'add token button present')
addTokenButton[0].click() addTokenButton[0].click()
const addCustom = await queryAsync($, '.add-token__add-custom') const addTokenTabs = await queryAsync($, '.add-token__header__tabs__tab')
assert.ok(addCustom[0], 'add custom token button present') assert.equal(addTokenTabs.length, 2, 'expected number of tabs')
addCustom[0].click() assert.equal(addTokenTabs[1].textContent, 'Custom Token', 'Custom Token tab present')
assert.ok(addTokenTabs[1], 'add custom token tab present')
addTokenTabs[1].click()
// Input token contract address // Input token contract address
const customInput = await queryAsync($, 'input.add-token__add-custom-input') const customInput = await queryAsync($, 'input.add-token__add-custom-input')
@ -101,14 +103,15 @@ async function runAddTokenFlowTest (assert, done) {
reactTriggerChange(customInput[0]) reactTriggerChange(customInput[0])
// Click Next button // Click Next button
nextButton = await queryAsync($, 'button.btn-clear.add-token__button') nextButton = await queryAsync($, 'button.btn-primary--lg')
assert.equal(nextButton[0].textContent, 'Next', 'next button rendered') assert.equal(nextButton[0].textContent, 'Next', 'next button rendered')
nextButton[0].click() nextButton[0].click()
// Verify symbol length error since contract address won't return symbol // Verify symbol length error since contract address won't return symbol
const errorMessage = await queryAsync($, '.add-token__add-custom-error-message') const errorMessage = await queryAsync($, '.add-token__add-custom-error-message')
assert.ok(errorMessage[0], 'error rendered') assert.ok(errorMessage[0], 'error rendered')
$('button.btn-cancel.add-token__button')[0].click()
$('button.btn-secondary--lg')[0].click()
// // Confirm Add token // // Confirm Add token
// assert.equal( // assert.equal(
@ -116,8 +119,8 @@ async function runAddTokenFlowTest (assert, done) {
// 'Would you like to add these tokens?', // 'Would you like to add these tokens?',
// 'confirm add token rendered' // 'confirm add token rendered'
// ) // )
// assert.ok($('button.btn-clear.add-token__button')[0], 'confirm add token button found') // assert.ok($('button.btn-primary--lg')[0], 'confirm add token button found')
// $('button.btn-clear.add-token__button')[0].click() // $('button.btn-primary--lg')[0].click()
// // Verify added token image // // Verify added token image
// heroBalance = await queryAsync($, '.hero-balance') // heroBalance = await queryAsync($, '.hero-balance')

@ -27,7 +27,7 @@ async function runConfirmSigRequestsTest(assert, done) {
let confirmSigRowValue = await queryAsync($, '.request-signature__row-value') let confirmSigRowValue = await queryAsync($, '.request-signature__row-value')
assert.ok(confirmSigRowValue[0].textContent.match(/^\#\sTerms\sof\sUse/)) assert.ok(confirmSigRowValue[0].textContent.match(/^\#\sTerms\sof\sUse/))
let confirmSigSignButton = await queryAsync($, '.request-signature__footer__sign-button') let confirmSigSignButton = await queryAsync($, 'button.btn-primary--lg')
confirmSigSignButton[0].click() confirmSigSignButton[0].click()
confirmSigHeadline = await queryAsync($, '.request-signature__headline') confirmSigHeadline = await queryAsync($, '.request-signature__headline')
@ -39,7 +39,7 @@ async function runConfirmSigRequestsTest(assert, done) {
confirmSigRowValue = await queryAsync($, '.request-signature__row-value') confirmSigRowValue = await queryAsync($, '.request-signature__row-value')
assert.equal(confirmSigRowValue[0].textContent, '0x879a053d4800c6354e76c7985a865d2922c82fb5b3f4577b2fe08b998954f2e0') assert.equal(confirmSigRowValue[0].textContent, '0x879a053d4800c6354e76c7985a865d2922c82fb5b3f4577b2fe08b998954f2e0')
confirmSigSignButton = await queryAsync($, '.request-signature__footer__sign-button') confirmSigSignButton = await queryAsync($, 'button.btn-primary--lg')
confirmSigSignButton[0].click() confirmSigSignButton[0].click()
confirmSigHeadline = await queryAsync($, '.request-signature__headline') confirmSigHeadline = await queryAsync($, '.request-signature__headline')
@ -49,7 +49,7 @@ async function runConfirmSigRequestsTest(assert, done) {
assert.equal(confirmSigRowValue[0].textContent, 'Hi, Alice!') assert.equal(confirmSigRowValue[0].textContent, 'Hi, Alice!')
assert.equal(confirmSigRowValue[1].textContent, '1337') assert.equal(confirmSigRowValue[1].textContent, '1337')
confirmSigSignButton = await queryAsync($, '.request-signature__footer__sign-button') confirmSigSignButton = await queryAsync($, 'button.btn-primary--lg')
confirmSigSignButton[0].click() confirmSigSignButton[0].click()
const txView = await queryAsync($, '.tx-view') const txView = await queryAsync($, '.tx-view')

@ -57,9 +57,9 @@ async function runFirstTimeUsageTest (assert, done) {
;(await findAsync(app, '.first-time-flow__button')).click() ;(await findAsync(app, '.first-time-flow__button')).click()
// Deposit Ether Screen // Deposit Ether Screen
const buyEthTitle = (await findAsync(app, '.buy-ether__title'))[0] const depositEthTitle = (await findAsync(app, '.page-container__title'))[0]
assert.equal(buyEthTitle.textContent, 'Deposit Ether', 'deposit ether screen') assert.equal(depositEthTitle.textContent, 'Deposit Ether', 'deposit ether screen')
;(await findAsync(app, '.buy-ether__do-it-later')).click() ;(await findAsync(app, '.page-container__header-close')).click()
const menu = (await findAsync(app, '.account-menu__icon'))[0] const menu = (await findAsync(app, '.account-menu__icon'))[0]
menu.click() menu.click()

@ -21,13 +21,15 @@ global.ethQuery = {
sendTransaction: () => {}, sendTransaction: () => {},
} }
global.ethereumProvider = {}
async function runSendFlowTest(assert, done) { async function runSendFlowTest(assert, done) {
console.log('*** start runSendFlowTest') console.log('*** start runSendFlowTest')
const selectState = await queryAsync($, 'select') const selectState = await queryAsync($, 'select')
selectState.val('send new ui') selectState.val('send new ui')
reactTriggerChange(selectState[0]) reactTriggerChange(selectState[0])
const sendScreenButton = await queryAsync($, 'button.btn-clear.hero-balance-button') const sendScreenButton = await queryAsync($, 'button.btn-primary.hero-balance-button')
assert.ok(sendScreenButton[1], 'send screen button present') assert.ok(sendScreenButton[1], 'send screen button present')
sendScreenButton[1].click() sendScreenButton[1].click()
@ -120,7 +122,7 @@ async function runSendFlowTest(assert, done) {
'send gas field should show customized gas total converted to USD' 'send gas field should show customized gas total converted to USD'
) )
const sendButton = await queryAsync($, 'button.btn-clear.page-container__footer-button') const sendButton = await queryAsync($, 'button.btn-primary--lg.page-container__footer-button')
assert.equal(sendButton[0].textContent, 'Next', 'next button rendered') assert.equal(sendButton[0].textContent, 'Next', 'next button rendered')
sendButton[0].click() sendButton[0].click()
await timeout() await timeout()
@ -160,7 +162,7 @@ async function runSendFlowTest(assert, done) {
sendAmountFieldInputInEdit.val('1.0') sendAmountFieldInputInEdit.val('1.0')
reactTriggerChange(sendAmountFieldInputInEdit[0]) reactTriggerChange(sendAmountFieldInputInEdit[0])
const sendButtonInEdit = await queryAsync($, '.btn-clear.page-container__footer-button') const sendButtonInEdit = await queryAsync($, '.btn-primary--lg.page-container__footer-button')
assert.equal(sendButtonInEdit[0].textContent, 'Next', 'next button in edit rendered') assert.equal(sendButtonInEdit[0].textContent, 'Next', 'next button in edit rendered')
sendButtonInEdit[0].click() sendButtonInEdit[0].click()

@ -0,0 +1,32 @@
const assert = require('assert')
const migration22 = require('../../../app/scripts/migrations/022')
const properTime = (new Date()).getTime()
const storage = {
"meta": {},
"data": {
"TransactionController": {
"transactions": [
{ "status": "submitted" },
{ "status": "submitted", "submittedTime": properTime },
{"status": "confirmed"},
]
},
},
}
describe('storage is migrated successfully where transactions that are submitted have submittedTimes', () => {
it('should add submittedTime key on the txMeta if appropriate', (done) => {
migration22.migrate(storage)
.then((migratedData) => {
const [txMeta1, txMeta2, txMeta3] = migratedData.data.TransactionController.transactions
assert.equal(migratedData.meta.version, 22)
// should have written a submitted time
assert(txMeta1.submittedTime)
// should not have written a submitted time because it already has one
assert.equal(txMeta2.submittedTime, properTime)
// should not have written a submitted time
assert(!txMeta3.submittedTime)
done()
}).catch(done)
})
})

@ -50,13 +50,13 @@ class JsonImportSubview extends Component {
h('div.new-account-create-form__buttons', {}, [ h('div.new-account-create-form__buttons', {}, [
h('button.new-account-create-form__button-cancel', { h('button.btn-secondary.new-account-create-form__button', {
onClick: () => this.props.goHome(), onClick: () => this.props.goHome(),
}, [ }, [
t('cancel'), t('cancel'),
]), ]),
h('button.new-account-create-form__button-create', { h('button.btn-primary.new-account-create-form__button', {
onClick: () => this.createNewKeychain(), onClick: () => this.createNewKeychain(),
}, [ }, [
t('import'), t('import'),

@ -48,13 +48,13 @@ PrivateKeyImportView.prototype.render = function () {
h('div.new-account-import-form__buttons', {}, [ h('div.new-account-import-form__buttons', {}, [
h('button.new-account-create-form__button-cancel.allcaps', { h('button.btn-secondary--lg.new-account-create-form__button', {
onClick: () => goHome(), onClick: () => goHome(),
}, [ }, [
t('cancel'), t('cancel'),
]), ]),
h('button.new-account-create-form__button-create.allcaps', { h('button.btn-primary--lg.new-account-create-form__button', {
onClick: () => this.createNewKeychain(), onClick: () => this.createNewKeychain(),
}, [ }, [
t('import'), t('import'),

@ -38,13 +38,13 @@ class NewAccountCreateForm extends Component {
h('div.new-account-create-form__buttons', {}, [ h('div.new-account-create-form__buttons', {}, [
h('button.new-account-create-form__button-cancel.allcaps', { h('button.btn-secondary--lg.new-account-create-form__button', {
onClick: () => this.props.goHome(), onClick: () => this.props.goHome(),
}, [ }, [
t('cancel'), t('cancel'),
]), ]),
h('button.new-account-create-form__button-create.allcaps', { h('button.btn-primary--lg.new-account-create-form__button', {
onClick: () => this.props.createAccount(newAccountName || defaultAccountName), onClick: () => this.props.createAccount(newAccountName || defaultAccountName),
}, [ }, [
t('create'), t('create'),

@ -694,10 +694,10 @@ function updateSendFrom (from) {
} }
} }
function updateSendTo (to) { function updateSendTo (to, nickname = '') {
return { return {
type: actions.UPDATE_SEND_TO, type: actions.UPDATE_SEND_TO,
value: to, value: { to, nickname },
} }
} }

@ -55,10 +55,10 @@ function AddTokenScreen () {
customSymbol: '', customSymbol: '',
customDecimals: '', customDecimals: '',
searchQuery: '', searchQuery: '',
isCollapsed: true,
selectedTokens: {}, selectedTokens: {},
errors: {}, errors: {},
autoFilled: false, autoFilled: false,
displayedTab: 'SEARCH',
} }
this.tokenAddressDidChange = this.tokenAddressDidChange.bind(this) this.tokenAddressDidChange = this.tokenAddressDidChange.bind(this)
this.tokenSymbolDidChange = this.tokenSymbolDidChange.bind(this) this.tokenSymbolDidChange = this.tokenSymbolDidChange.bind(this)
@ -192,7 +192,7 @@ AddTokenScreen.prototype.attemptToAutoFillTokenParams = async function (address)
AddTokenScreen.prototype.renderCustomForm = function () { AddTokenScreen.prototype.renderCustomForm = function () {
const { autoFilled, customAddress, customSymbol, customDecimals, errors } = this.state const { autoFilled, customAddress, customSymbol, customDecimals, errors } = this.state
return !this.state.isCollapsed && ( return (
h('div.add-token__add-custom-form', [ h('div.add-token__add-custom-form', [
h('div', { h('div', {
className: classnames('add-token__add-custom-field', { className: classnames('add-token__add-custom-field', {
@ -247,7 +247,9 @@ AddTokenScreen.prototype.renderTokenList = function () {
}) })
const results = [...addressSearchResult, ...fuseSearchResult] const results = [...addressSearchResult, ...fuseSearchResult]
return Array(6).fill(undefined) return h('div', [
results.length > 0 && h('div.add-token__token-icons-title', t('popularTokens')),
h('div.add-token__token-icons-container', Array(6).fill(undefined)
.map((_, i) => { .map((_, i) => {
const { logo, symbol, name, address } = results[i] || {} const { logo, symbol, name, address } = results[i] || {}
const tokenAlreadyAdded = this.checkExistingAddresses(address) const tokenAlreadyAdded = this.checkExistingAddresses(address)
@ -273,7 +275,8 @@ AddTokenScreen.prototype.renderTokenList = function () {
// ), // ),
]) ])
) )
}) })),
])
} }
AddTokenScreen.prototype.renderConfirmation = function () { AddTokenScreen.prototype.renderConfirmation = function () {
@ -300,7 +303,6 @@ AddTokenScreen.prototype.renderConfirmation = function () {
h('div.add-token', [ h('div.add-token', [
h('div.add-token__wrapper', [ h('div.add-token__wrapper', [
h('div.add-token__title-container.add-token__confirmation-title', [ h('div.add-token__title-container.add-token__confirmation-title', [
h('div.add-token__title', t('addToken')),
h('div.add-token__description', t('likeToAddTokens')), h('div.add-token__description', t('likeToAddTokens')),
]), ]),
h('div.add-token__content-container.add-token__confirmation-content', [ h('div.add-token__content-container.add-token__confirmation-content', [
@ -321,10 +323,10 @@ AddTokenScreen.prototype.renderConfirmation = function () {
]), ]),
]), ]),
h('div.add-token__buttons', [ h('div.add-token__buttons', [
h('button.btn-cancel.add-token__button', { h('button.btn-secondary--lg.add-token__cancel-button', {
onClick: () => this.setState({ isShowingConfirmation: false }), onClick: () => this.setState({ isShowingConfirmation: false }),
}, t('back')), }, t('back')),
h('button.btn-clear.add-token__button', { h('button.btn-primary--lg', {
onClick: () => addTokens(tokens).then(goHome), onClick: () => addTokens(tokens).then(goHome),
}, t('addTokens')), }, t('addTokens')),
]), ]),
@ -332,52 +334,86 @@ AddTokenScreen.prototype.renderConfirmation = function () {
) )
} }
AddTokenScreen.prototype.render = function () { AddTokenScreen.prototype.displayTab = function (selectedTab) {
const { isCollapsed, errors, isShowingConfirmation } = this.state this.setState({ displayedTab: selectedTab })
const { goHome } = this.props }
return isShowingConfirmation AddTokenScreen.prototype.renderTabs = function () {
? this.renderConfirmation() const { displayedTab, errors } = this.state
: (
h('div.add-token', [ return displayedTab === 'CUSTOM_TOKEN'
? this.renderCustomForm()
: h('div', [
h('div.add-token__wrapper', [ h('div.add-token__wrapper', [
h('div.add-token__title-container', [
h('div.add-token__title', t('addToken')),
h('div.add-token__description', t('tokenWarning1')),
h('div.add-token__description', t('tokenSelection')),
]),
h('div.add-token__content-container', [ h('div.add-token__content-container', [
h('div.add-token__info-box', [
h('div.add-token__info-box__close'),
h('div.add-token__info-box__title', t('whatsThis')),
h('div.add-token__info-box__copy', t('keepTrackTokens')),
h('div.add-token__info-box__copy--blue', t('learnMore')),
]),
h('div.add-token__input-container', [ h('div.add-token__input-container', [
h('input.add-token__input', { h('input.add-token__input', {
type: 'text', type: 'text',
placeholder: t('search'), placeholder: t('searchTokens'),
onChange: e => this.setState({ searchQuery: e.target.value }), onChange: e => this.setState({ searchQuery: e.target.value }),
}), }),
h('div.add-token__search-input-error-message', errors.tokenSelector), h('div.add-token__search-input-error-message', errors.tokenSelector),
]), ]),
h(
'div.add-token__token-icons-container',
this.renderTokenList(), this.renderTokenList(),
),
]), ]),
h('div.add-token__footers', [ ]),
h('div.add-token__add-custom', { ])
onClick: () => this.setState({ isCollapsed: !isCollapsed }), }
AddTokenScreen.prototype.render = function () {
const {
isShowingConfirmation,
displayedTab,
} = this.state
const { goHome } = this.props
return h('div.add-token', [
h('div.add-token__header', [
h('div.add-token__header__cancel', {
onClick: () => goHome(),
}, [ }, [
t('addCustomToken'), h('i.fa.fa-angle-left.fa-lg'),
h(`i.fa.fa-angle-${isCollapsed ? 'down' : 'up'}`), h('span', t('cancel')),
]), ]),
this.renderCustomForm(), h('div.add-token__header__title', t('addTokens')),
!isShowingConfirmation && h('div.add-token__header__tabs', [
h('div.add-token__header__tabs__tab', {
className: classnames('add-token__header__tabs__tab', {
'add-token__header__tabs__selected': displayedTab === 'SEARCH',
'add-token__header__tabs__unselected cursor-pointer': displayedTab !== 'SEARCH',
}),
onClick: () => this.displayTab('SEARCH'),
}, t('search')),
h('div.add-token__header__tabs__tab', {
className: classnames('add-token__header__tabs__tab', {
'add-token__header__tabs__selected': displayedTab === 'CUSTOM_TOKEN',
'add-token__header__tabs__unselected cursor-pointer': displayedTab !== 'CUSTOM_TOKEN',
}),
onClick: () => this.displayTab('CUSTOM_TOKEN'),
}, t('customToken')),
]), ]),
]), ]),
h('div.add-token__buttons', [ //
h('button.btn-cancel.add-token__button', { isShowingConfirmation
? this.renderConfirmation()
: this.renderTabs(),
!isShowingConfirmation && h('div.add-token__buttons', [
h('button.btn-secondary--lg.add-token__cancel-button', {
onClick: goHome, onClick: goHome,
}, t('cancel')), }, t('cancel')),
h('button.btn-clear.add-token__button', { h('button.btn-primary--lg.add-token__confirm-button', {
onClick: this.onNext, onClick: this.onNext,
}, t('next')), }, t('next')),
]), ]),
]) ])
)
} }

@ -386,7 +386,7 @@ App.prototype.renderPrimary = function () {
isUnlocked, isUnlocked,
} = props } = props
const isMascaraOnboarding = isMascara && isOnboarding const isMascaraOnboarding = isMascara && isOnboarding
const isBetaUIOnboarding = betaUI && isOnboarding && !props.isPopup && !isRevealingSeedWords const isBetaUIOnboarding = betaUI && isOnboarding
if (!welcomeScreenSeen && betaUI && !isInitialized && !isUnlocked) { if (!welcomeScreenSeen && betaUI && !isInitialized && !isUnlocked) {
return h(WelcomeScreen) return h(WelcomeScreen)
@ -397,7 +397,7 @@ App.prototype.renderPrimary = function () {
} }
// notices // notices
if (!props.noActiveNotices) { if (!props.noActiveNotices && !betaUI) {
log.debug('rendering notice screen for unread notices.') log.debug('rendering notice screen for unread notices.')
return h(NoticeScreen, { return h(NoticeScreen, {
notice: props.lastUnreadNotice, notice: props.lastUnreadNotice,
@ -418,7 +418,7 @@ App.prototype.renderPrimary = function () {
return h(HDRestoreVaultScreen, {key: 'HDRestoreVaultScreen'}) return h(HDRestoreVaultScreen, {key: 'HDRestoreVaultScreen'})
} else if (!props.isInitialized && !props.isUnlocked && !isRevealingSeedWords) { } else if (!props.isInitialized && !props.isUnlocked && !isRevealingSeedWords) {
log.debug('rendering menu screen') log.debug('rendering menu screen')
return props.isPopup return !betaUI
? h(OldUIInitializeMenuScreen, {key: 'menuScreenInit'}) ? h(OldUIInitializeMenuScreen, {key: 'menuScreenInit'})
: h(InitializeMenuScreen, {key: 'menuScreenInit'}) : h(InitializeMenuScreen, {key: 'menuScreenInit'})
} }

@ -302,12 +302,16 @@ CustomizeGasModal.prototype.render = function () {
}, [t('revert')]), }, [t('revert')]),
h('div.send-v2__customize-gas__buttons', [ h('div.send-v2__customize-gas__buttons', [
h('div.send-v2__customize-gas__cancel.allcaps', { h('button.btn-secondary.send-v2__customize-gas__cancel', {
onClick: this.props.hideModal, onClick: this.props.hideModal,
style: {
marginRight: '10px',
},
}, [t('cancel')]), }, [t('cancel')]),
h(`div.send-v2__customize-gas__save${error ? '__error' : ''}.allcaps`, { h('button.btn-primary.send-v2__customize-gas__save', {
onClick: () => !error && this.save(newGasPrice, gasLimit, gasTotal), onClick: () => !error && this.save(newGasPrice, gasLimit, gasTotal),
className: error && 'btn-primary--disabled',
}, [t('save')]), }, [t('save')]),
]), ]),

@ -9,6 +9,7 @@ const networkMap = require('ethjs-ens/lib/network-map.json')
const ensRE = /.+\..+$/ const ensRE = /.+\..+$/
const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000' const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000'
const t = require('../../i18n') const t = require('../../i18n')
const ToAutoComplete = require('./send/to-autocomplete')
module.exports = EnsInput module.exports = EnsInput
@ -22,12 +23,14 @@ EnsInput.prototype.render = function () {
const props = this.props const props = this.props
const opts = extend(props, { const opts = extend(props, {
list: 'addresses', list: 'addresses',
onChange: () => { onChange: (recipient) => {
const network = this.props.network const network = this.props.network
const networkHasEnsSupport = getNetworkEnsSupport(network) const networkHasEnsSupport = getNetworkEnsSupport(network)
if (!networkHasEnsSupport) return if (!networkHasEnsSupport) return
const recipient = document.querySelector('input[name="address"]').value props.onChange(recipient)
if (recipient.match(ensRE) === null) { if (recipient.match(ensRE) === null) {
return this.setState({ return this.setState({
loadingEns: false, loadingEns: false,
@ -39,34 +42,13 @@ EnsInput.prototype.render = function () {
this.setState({ this.setState({
loadingEns: true, loadingEns: true,
}) })
this.checkName() this.checkName(recipient)
}, },
}) })
return h('div', { return h('div', {
style: { width: '100%' }, style: { width: '100%', position: 'relative' },
}, [ }, [
h('input.large-input.send-screen-input', opts), h(ToAutoComplete, { ...opts }),
// The address book functionality.
h('datalist#addresses',
[
// Corresponds to the addresses owned.
Object.keys(props.identities).map((key) => {
const identity = props.identities[key]
return h('option', {
value: identity.address,
label: identity.name,
key: identity.address,
})
}),
// Corresponds to previously sent-to addresses.
props.addressBook.map((identity) => {
return h('option', {
value: identity.address,
label: identity.name,
key: identity.address,
})
}),
]),
this.ensIcon(), this.ensIcon(),
]) ])
} }
@ -83,8 +65,7 @@ EnsInput.prototype.componentDidMount = function () {
} }
} }
EnsInput.prototype.lookupEnsName = function () { EnsInput.prototype.lookupEnsName = function (recipient) {
const recipient = document.querySelector('input[name="address"]').value
const { ensResolution } = this.state const { ensResolution } = this.state
log.info(`ENS attempting to resolve name: ${recipient}`) log.info(`ENS attempting to resolve name: ${recipient}`)
@ -130,8 +111,8 @@ EnsInput.prototype.ensIcon = function (recipient) {
title: hoverText, title: hoverText,
style: { style: {
position: 'absolute', position: 'absolute',
padding: '9px', top: '16px',
transform: 'translatex(-40px)', left: '-25px',
}, },
}, this.ensIconContents(recipient)) }, this.ensIconContents(recipient))
} }

@ -63,12 +63,12 @@ AccountDetailsModal.prototype.render = function () {
h('div.account-modal-divider'), h('div.account-modal-divider'),
h('button.btn-clear.account-modal__button', { h('button.btn-primary.account-modal__button', {
onClick: () => global.platform.openWindow({ url: genAccountLink(address, network) }), onClick: () => global.platform.openWindow({ url: genAccountLink(address, network) }),
}, t('etherscanView')), }, t('etherscanView')),
// Holding on redesign for Export Private Key functionality // Holding on redesign for Export Private Key functionality
h('button.btn-clear.account-modal__button', { h('button.btn-primary.account-modal__button', {
onClick: () => showExportPrivateKeyModal(), onClick: () => showExportPrivateKeyModal(),
}, t('exportPrivateKey')), }, t('exportPrivateKey')),

@ -94,7 +94,7 @@ DepositEtherModal.prototype.renderRow = function ({
]), ]),
!hideButton && h('div.deposit-ether-modal__buy-row__button', [ !hideButton && h('div.deposit-ether-modal__buy-row__button', [
h('button.deposit-ether-modal__deposit-button', { h('button.btn-primary--lg.deposit-ether-modal__deposit-button', {
onClick: onButtonClick, onClick: onButtonClick,
}, [buttonLabel]), }, [buttonLabel]),
]), ]),

@ -81,14 +81,14 @@ ExportPrivateKeyModal.prototype.renderButton = function (className, onClick, lab
ExportPrivateKeyModal.prototype.renderButtons = function (privateKey, password, address, hideModal) { ExportPrivateKeyModal.prototype.renderButtons = function (privateKey, password, address, hideModal) {
return h('div.export-private-key-buttons', {}, [ return h('div.export-private-key-buttons', {}, [
!privateKey && this.renderButton( !privateKey && this.renderButton(
'btn-cancel export-private-key__button export-private-key__button--cancel', 'btn-secondary--lg export-private-key__button export-private-key__button--cancel',
() => hideModal(), () => hideModal(),
'Cancel' 'Cancel'
), ),
(privateKey (privateKey
? this.renderButton('btn-clear export-private-key__button', () => hideModal(), t('done')) ? this.renderButton('btn-primary--lg export-private-key__button', () => hideModal(), t('done'))
: this.renderButton('btn-clear export-private-key__button', () => this.exportAccountAndGetPrivateKey(this.state.password, address), t('confirm')) : this.renderButton('btn-primary--lg export-private-key__button', () => this.exportAccountAndGetPrivateKey(this.state.password, address), t('confirm'))
), ),
]) ])

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

@ -64,13 +64,20 @@ PendingTx.prototype.componentWillMount = async function () {
}) })
} }
try { // inspect tx data for supported special confirmation screens
let isTokenTransaction = false
if (txParams.data) {
const tokenData = abiDecoder.decodeMethod(txParams.data)
const { name: tokenMethodName } = tokenData || {}
isTokenTransaction = (tokenMethodName === 'transfer')
}
if (isTokenTransaction) {
const token = util.getContractAtAddress(txParams.to) const token = util.getContractAtAddress(txParams.to)
const results = await Promise.all([ const results = await Promise.all([
token.symbol(), token.symbol(),
token.decimals(), token.decimals(),
]) ])
const [ symbol, decimals ] = results const [ symbol, decimals ] = results
if (symbol[0] && decimals[0]) { if (symbol[0] && decimals[0]) {
@ -83,11 +90,14 @@ PendingTx.prototype.componentWillMount = async function () {
}) })
} else { } else {
this.setState({ this.setState({
transactionType: TX_TYPES.SEND_ETHER, transactionType: TX_TYPES.SEND_TOKEN,
tokenAddress: txParams.to,
tokenSymbol: null,
tokenDecimals: null,
isFetching: false, isFetching: false,
}) })
} }
} catch (e) { } else {
this.setState({ this.setState({
transactionType: TX_TYPES.SEND_ETHER, transactionType: TX_TYPES.SEND_ETHER,
isFetching: false, isFetching: false,

@ -69,13 +69,13 @@ function mapDispatchToProps (dispatch) {
updateAndApproveTx: txParams => dispatch(actions.updateAndApproveTx(txParams)), updateAndApproveTx: txParams => dispatch(actions.updateAndApproveTx(txParams)),
updateTx: txData => dispatch(actions.updateTransaction(txData)), updateTx: txData => dispatch(actions.updateTransaction(txData)),
setSelectedAddress: address => dispatch(actions.setSelectedAddress(address)), setSelectedAddress: address => dispatch(actions.setSelectedAddress(address)),
addToAddressBook: address => dispatch(actions.addToAddressBook(address)), addToAddressBook: (address, nickname) => dispatch(actions.addToAddressBook(address, nickname)),
updateGasTotal: newTotal => dispatch(actions.updateGasTotal(newTotal)), updateGasTotal: newTotal => dispatch(actions.updateGasTotal(newTotal)),
updateGasPrice: newGasPrice => dispatch(actions.updateGasPrice(newGasPrice)), updateGasPrice: newGasPrice => dispatch(actions.updateGasPrice(newGasPrice)),
updateGasLimit: newGasLimit => dispatch(actions.updateGasLimit(newGasLimit)), updateGasLimit: newGasLimit => dispatch(actions.updateGasLimit(newGasLimit)),
updateSendTokenBalance: tokenBalance => dispatch(actions.updateSendTokenBalance(tokenBalance)), updateSendTokenBalance: tokenBalance => dispatch(actions.updateSendTokenBalance(tokenBalance)),
updateSendFrom: newFrom => dispatch(actions.updateSendFrom(newFrom)), updateSendFrom: newFrom => dispatch(actions.updateSendFrom(newFrom)),
updateSendTo: newTo => dispatch(actions.updateSendTo(newTo)), updateSendTo: (newTo, nickname) => dispatch(actions.updateSendTo(newTo, nickname)),
updateSendAmount: newAmount => dispatch(actions.updateSendAmount(newAmount)), updateSendAmount: newAmount => dispatch(actions.updateSendAmount(newAmount)),
updateSendMemo: newMemo => dispatch(actions.updateSendMemo(newMemo)), updateSendMemo: newMemo => dispatch(actions.updateSendMemo(newMemo)),
updateSendErrors: newError => dispatch(actions.updateSendErrors(newError)), updateSendErrors: newError => dispatch(actions.updateSendErrors(newError)),

@ -236,7 +236,7 @@ ShapeshiftForm.prototype.render = function () {
]), ]),
!depositAddress && h('button.shapeshift-form__shapeshift-buy-btn', { !depositAddress && h('button.btn-primary--lg.shapeshift-form__shapeshift-buy-btn', {
className: btnClass, className: btnClass,
disabled: !token, disabled: !token,
onClick: () => this.onBuyWithShapeShift(), onClick: () => this.onBuyWithShapeShift(),

@ -223,10 +223,10 @@ SignatureRequest.prototype.renderFooter = function () {
} }
return h('div.request-signature__footer', [ return h('div.request-signature__footer', [
h('button.request-signature__footer__cancel-button', { h('button.btn-secondary--lg.request-signature__footer__cancel-button', {
onClick: cancel, onClick: cancel,
}, t('cancel')), }, t('cancel')),
h('button.request-signature__footer__sign-button', { h('button.btn-primary--lg', {
onClick: sign, onClick: sign,
}, t('sign')), }, t('sign')),
]) ])

@ -69,13 +69,13 @@ TxView.prototype.renderButtons = function () {
return !selectedToken return !selectedToken
? ( ? (
h('div.flex-row.flex-center.hero-balance-buttons', [ h('div.flex-row.flex-center.hero-balance-buttons', [
h('button.btn-clear.hero-balance-button.allcaps', { h('button.btn-primary.hero-balance-button', {
onClick: () => showModal({ onClick: () => showModal({
name: 'DEPOSIT_ETHER', name: 'DEPOSIT_ETHER',
}), }),
}, t('deposit')), }, t('deposit')),
h('button.btn-clear.hero-balance-button.allcaps', { h('button.btn-primary.hero-balance-button', {
style: { style: {
marginLeft: '0.8em', marginLeft: '0.8em',
}, },
@ -85,7 +85,7 @@ TxView.prototype.renderButtons = function () {
) )
: ( : (
h('div.flex-row.flex-center.hero-balance-buttons', [ h('div.flex-row.flex-center.hero-balance-buttons', [
h('button.btn-clear.hero-balance-button', { h('button.btn-primary.hero-balance-button', {
onClick: showSendTokenPage, onClick: showSendTokenPage,
}, t('send')), }, t('send')),
]) ])

@ -168,7 +168,7 @@ WalletView.prototype.render = function () {
h(TokenList), h(TokenList),
h('button.btn-clear.wallet-view__add-token-button', { h('button.btn-primary.wallet-view__add-token-button', {
onClick: () => { onClick: () => {
showAddTokenPage() showAddTokenPage()
hideSidebar() hideSidebar()

@ -1,37 +1,118 @@
.add-token { .add-token {
width: 498px; width: 498px;
max-height: 805px;
display: flex; display: flex;
flex-flow: column nowrap; flex-flow: column nowrap;
align-items: center;
position: relative; position: relative;
z-index: 12; z-index: 12;
font-family: 'DIN Next Light'; font-family: 'Roboto';
background: white;
border-radius: 8px;
&__wrapper { &__wrapper {
background-color: $white; background-color: $white;
box-shadow: 0 2px 4px 0 rgba($black, .08);
display: flex; display: flex;
flex-flow: column nowrap; flex-flow: column nowrap;
align-items: center; align-items: center;
flex: 0 0 auto; flex: 0 0 auto;
} }
&__title-container { &__header {
display: flex; display: flex;
flex-flow: column nowrap; flex-flow: column nowrap;
align-items: center; padding: 16px 16px 0px;
padding: 30px 60px 12px; border-bottom: 1px solid $geyser;
border-bottom: 1px solid $gallery;
flex: 0 0 auto; flex: 0 0 auto;
&__cancel {
color: $dodger-blue;
display: flex;
align-items: center;
span {
font-family: Roboto;
font-size: 16px;
line-height: 21px;
margin-left: 8px;
}
} }
&__title { &__title {
color: $scorpion; color: $tundora;
font-size: 20px; font-size: 32px;
line-height: 26px; font-weight: 500;
margin-top: 4px;
}
&__tabs {
margin-left: 22px;
display: flex;
&__tab {
height: 54px;
padding: 15px 10px;
color: $dusty-gray;
font-family: Roboto;
font-size: 18px;
line-height: 24px;
text-align: center; text-align: center;
font-weight: 600; }
margin-bottom: 12px;
&__tab:first-of-type {
margin-right: 20px;
}
&__unselected:hover {
color: $black;
border-bottom: none;
}
&__selected {
color: $curious-blue;
border-bottom: 3px solid $curious-blue;
}
}
}
&__info-box {
height: 96px;
margin: 20px 24px 0px;
border-radius: 4px;
background-color: $alabaster;
position: relative;
padding-left: 18px;
display: flex;
flex-flow: column;
&__close::after {
content: '\00D7';
font-size: 29px;
font-weight: 200;
color: $dusty-gray;
position: absolute;
right: 17px;
cursor: pointer;
}
&__title {
color: $mid-gray;
font-family: Roboto;
font-size: 14px;
margin-top: 15px;
margin-bottom: 9px;
}
&__copy,
&__copy--blue {
color: $mid-gray;
font-family: Roboto;
font-size: 12px;
line-height: 18px;
}
&__copy--blue {
color: $curious-blue;
}
} }
&__description { &__description {
@ -48,19 +129,17 @@
&__content-container { &__content-container {
width: 100%; width: 100%;
border-bottom: 1px solid $gallery;
} }
&__input-container { &__input-container {
padding: 11px 0; display: flex;
width: 263px;
margin: 0 auto;
position: relative; position: relative;
} }
&__search-input-error-message { &__search-input-error-message {
position: absolute; position: absolute;
bottom: -10px; bottom: -10px;
left: 22px;
font-size: 12px; font-size: 12px;
width: 100%; width: 100%;
text-overflow: ellipsis; text-overflow: ellipsis;
@ -69,16 +148,24 @@
color: $red; color: $red;
} }
&__input { &__input,
width: 100%; &__add-custom-input {
border: 2px solid $gallery; height: 54px;
padding: 21px 6px;
border: 1px solid $geyser;
border-radius: 4px; border-radius: 4px;
padding: 5px 15px; margin: 22px 24px;
font-size: 14px; position: relative;
line-height: 19px; flex: 1 0 auto;
color: $scorpion;
font-family: Roboto;
font-size: 16px;
&::placeholder { &::placeholder {
color: $silver; color: $scorpion;
font-family: Roboto;
font-size: 16px;
line-height: 21px;
} }
} }
@ -115,13 +202,14 @@
&__add-custom-form { &__add-custom-form {
display: flex; display: flex;
flex-flow: column nowrap; flex-flow: column nowrap;
margin: 8px 0 51px; margin: 40px 0 30px;
} }
&__add-custom-field { &__add-custom-field {
width: 290px;
margin: 0 auto;
position: relative; position: relative;
display: flex;
flex-flow: column;
flex: 1 0 auto;
&--error { &--error {
.add-token__add-custom-input { .add-token__add-custom-input {
@ -132,7 +220,8 @@
&__add-custom-error-message { &__add-custom-error-message {
position: absolute; position: absolute;
bottom: -21px; bottom: 1px;
left: 22px;
font-size: 12px; font-size: 12px;
width: 100%; width: 100%;
text-overflow: ellipsis; text-overflow: ellipsis;
@ -144,39 +233,50 @@
&__add-custom-label { &__add-custom-label {
font-size: 16px; font-size: 16px;
line-height: 21px; line-height: 21px;
margin-bottom: 8px; margin-left: 22px;
color: $scorpion;
} }
&__add-custom-input { &__add-custom-input {
width: 100%; margin-top: 6px;
border: 1px solid $silver; font-size: 16px;
padding: 5px 15px;
font-size: 14px;
line-height: 19px;
&::placeholder { &::placeholder {
color: $silver; color: $silver;
font-size: 16px;
} }
} }
&__add-custom-field + &__add-custom-field { &__add-custom-field + &__add-custom-field {
margin-top: 21px; margin-top: 6px;
} }
&__buttons { &__buttons {
display: flex; display: flex;
flex-flow: row nowrap; flex-flow: row nowrap;
margin: 30px 0 51px;
flex: 0 0 auto; flex: 0 0 auto;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
padding-bottom: 30px;
padding-top: 20px;
} }
&__button { &__confirm-button,
flex: 1 0 141px; &__cancel-button {
margin: 0 12px; margin: 0 12px;
padding: 10px 22px; padding: 10px 13px;
height: 54px; height: 54px;
width: 133px;
margin-right: 1.2rem;
}
&__token-icons-title {
color: #5B5D67;
font-family: Roboto;
font-size: 18px;
line-height: 24px;
margin-left: 24px;
margin-top: 8px;
} }
&__token-icons-container { &__token-icons-container {
@ -191,7 +291,7 @@
flex: 0 0 42.5%; flex: 0 0 42.5%;
align-items: center; align-items: center;
padding: 12px; padding: 12px;
margin: 2.5%; margin: 0% 2.5% 1.5%;
box-sizing: border-box; box-sizing: border-box;
border-radius: 10px; border-radius: 10px;
cursor: pointer; cursor: pointer;
@ -305,13 +405,14 @@
top: 0; top: 0;
width: 100%; width: 100%;
overflow: hidden; overflow: hidden;
height: 100%; flex: 1 0 auto;
&__wrapper { &__wrapper {
box-shadow: none !important; box-shadow: none !important;
flex: 1 1 auto; flex: 1 1 auto;
width: 100%; width: 100%;
overflow-y: auto; overflow-y: scroll;
height: 400px;
} }
&__footers { &__footers {
@ -334,7 +435,7 @@
} }
&__buttons { &__buttons {
padding: 12px 0; padding: 1rem;
margin: 0; margin: 0;
border-top: 1px solid $gallery; border-top: 1px solid $gallery;
width: 100%; width: 100%;

@ -2,6 +2,76 @@
Buttons Buttons
*/ */
.btn-primary,
.btn-primary--lg,
.btn-secondary,
.btn-secondary--lg {
background: $white;
display: flex;
justify-content: center;
align-items: center;
box-sizing: border-box;
border-radius: 4px;
font-size: 14px;
font-weight: 500;
transition: border-color .3s ease;
padding: 0 20px;
min-width: 140px;
text-transform: uppercase;
}
.btn-primary,
.btn-primary--lg {
color: $curious-blue;
border: 2px solid $spindle;
&:active {
background: $zumthor;
border-color: $curious-blue;
}
&:hover {
border-color: $curious-blue;
}
&--disabled,
&[disabled] {
cursor: auto;
opacity: .5;
pointer-events: none;
}
}
.btn-secondary,
.btn-secondary--lg {
color: $scorpion;
border: 2px solid $dusty-gray;
&:active {
background: $gallery;
border-color: $dusty-gray;
}
&:hover {
border-color: $scorpion;
}
&--disabled,
&[disabled] {
cursor: auto;
opacity: .5;
pointer-events: none;
}
}
.btn-primary, .btn-secondary {
height: 44px;
}
.btn-primary--lg, .btn-secondary--lg {
height: 54px;
}
.btn-green { .btn-green {
background-color: #02c9b1; // TODO: reusable color in colors.css background-color: #02c9b1; // TODO: reusable color in colors.css
} }
@ -130,20 +200,6 @@ button.btn-thin {
font-size: 13px; font-size: 13px;
} }
.btn-secondary {
border: 1px solid #979797;
border-radius: 2px;
background-color: $white;
font-size: 16px;
line-height: 24px;
padding: 16px 42px;
&[disabled] {
background-color: $white !important;
opacity: .5;
}
}
.btn-tertiary { .btn-tertiary {
border: 1px solid transparent; border: 1px solid transparent;
border-radius: 2px; border-radius: 2px;

@ -103,10 +103,11 @@
} }
.hero-balance-button { .hero-balance-button {
min-width: initial;
width: 6rem; width: 6rem;
@media #{$sub-mid-size-breakpoint-range} { @media #{$sub-mid-size-breakpoint-range} {
padding: 0.4rem; padding: .4rem;
width: 4rem; width: 4rem;
display: flex; display: flex;
flex: 1; flex: 1;

@ -261,7 +261,7 @@
.account-modal__button { .account-modal__button {
margin-top: 17px; margin-top: 17px;
padding: 10px 22px; padding: 10px 22px;
width: 235px; width: 286px;
} }
} }
@ -341,9 +341,8 @@
.export-private-key__button { .export-private-key__button {
margin-top: 17px; margin-top: 17px;
padding: 10px 22px;
width: 141px; width: 141px;
height: 54px; min-width: initial;
} }
.export-private-key__button--cancel { .export-private-key__button--cancel {
@ -765,15 +764,7 @@
} }
&__deposit-button, .shapeshift-form__shapeshift-buy-btn { &__deposit-button, .shapeshift-form__shapeshift-buy-btn {
height: 54px;
width: 257px; width: 257px;
border: 1px solid $curious-blue;
border-radius: 4px;
display: flex;
justify-content: center;
font-size: 16px;
color: $curious-blue;
background-color: $white;
} }
.shapeshift-form-wrapper { .shapeshift-form-wrapper {

@ -192,29 +192,8 @@
justify-content: space-between; justify-content: space-between;
} }
&__button-cancel, &__button {
&__button-create {
height: 55px;
width: 150px; width: 150px;
border-radius: 2px; min-width: initial;
background-color: #FFFFFF;
}
&__button-cancel {
border: 1px solid $dusty-gray;
color: $dusty-gray;
font-family: Roboto;
font-size: 16px;
line-height: 21px;
text-align: center;
}
&__button-create {
border: 1px solid $curious-blue;
color: $curious-blue;
font-family: Roboto;
font-size: 16px;
line-height: 21px;
text-align: center;
} }
} }

@ -162,6 +162,7 @@
&__row { &__row {
display: flex; display: flex;
flex-flow: column; flex-flow: column;
flex: 1 0 auto;
} }
&__row-title { &__row-title {
@ -190,41 +191,19 @@
width: 100%; width: 100%;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: space-evenly; justify-content: center;
font-size: 22px; font-size: 22px;
position: relative; position: relative;
flex: 0 0 auto; flex: 0 0 auto;
border-top: 1px solid $geyser; border-top: 1px solid $geyser;
padding: 1.6rem;
&__cancel-button, button {
&__sign-button { width: 165px;
display: flex;
align-items: center;
justify-content: center;
flex: 1 0 auto;
font-family: Roboto;
font-size: 16px;
font-weight: 300;
height: 55px;
line-height: 32px;
cursor: pointer;
border-radius: 2px;
box-shadow: none;
max-width: 162px;
margin: 12px;
} }
&__cancel-button { &__cancel-button {
background: none; margin-right: 1.2rem;
border: 1px solid $dusty-gray;
margin-right: 6px;
}
&__sign-button {
background-color: $caribbean-green;
border-width: 0;
color: $white;
margin-left: 6px;
} }
} }
} }

@ -782,7 +782,6 @@
&__buttons { &__buttons {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
width: 181.75px;
margin-right: 21.25px; margin-right: 21.25px;
} }
@ -800,13 +799,8 @@
} }
&__cancel, &__save, &__save__error { &__cancel, &__save, &__save__error {
height: 34.64px;
width: 85.74px; width: 85.74px;
border: 1px solid $dusty-gray; min-width: initial;
border-radius: 2px;
font-family: 'DIN OT';
font-size: 12px;
color: $dusty-gray;
} }
&__save__error { &__save__error {

@ -130,24 +130,32 @@
cursor: pointer; cursor: pointer;
} }
.settings__clear-button { .settings__button--red {
font-size: 16px; border-color: lighten($monzo, 10%);
border: 1px solid $curious-blue; color: $monzo;
color: $curious-blue;
border-radius: 2px; &:active {
padding: 18px; background: lighten($monzo, 55%);
background-color: $white; border-color: $monzo;
text-transform: uppercase;
} }
.settings__clear-button--red { &:hover {
border: 1px solid $monzo; border-color: $monzo;
color: $monzo; }
}
.settings__button--orange {
border-color: lighten($ecstasy, 20%);
color: $ecstasy;
&:active {
background: lighten($ecstasy, 40%);
border-color: $ecstasy;
} }
.settings__clear-button--orange { &:hover {
border: 1px solid rgba(247, 134, 28, 1); border-color: $ecstasy;
color: rgba(247, 134, 28, 1); }
} }
.settings__info-logo-wrapper { .settings__info-logo-wrapper {

@ -132,7 +132,7 @@ input.large-input {
height: 55px; height: 55px;
font-size: 1rem; font-size: 1rem;
text-transform: uppercase; text-transform: uppercase;
margin-right: 1rem; margin-right: 1.2rem;
border-radius: 2px; border-radius: 2px;
&:last-of-type { &:last-of-type {

@ -51,6 +51,9 @@ $java: #29b6af;
$wild-strawberry: #ff4a8d; $wild-strawberry: #ff4a8d;
$cornflower-blue: #7057ff; $cornflower-blue: #7057ff;
$saffron: #f6c343; $saffron: #f6c343;
$dodger-blue: #3099f2;
$zumthor: #edf7ff;
$ecstasy: #f7861c;
/* /*
Z-Indicies Z-Indicies

@ -39,6 +39,7 @@ function reduceMetamask (state, action) {
maxModeOn: false, maxModeOn: false,
editingTransactionId: null, editingTransactionId: null,
forceGasMin: null, forceGasMin: null,
toNickname: '',
}, },
coinOptions: {}, coinOptions: {},
useBlockie: false, useBlockie: false,
@ -238,7 +239,8 @@ function reduceMetamask (state, action) {
return extend(metamaskState, { return extend(metamaskState, {
send: { send: {
...metamaskState.send, ...metamaskState.send,
to: action.value, to: action.value.to,
toNickname: action.value.nickname,
}, },
}) })

@ -56,8 +56,9 @@ function getSelectedToken (state) {
const tokens = state.metamask.tokens || [] const tokens = state.metamask.tokens || []
const selectedTokenAddress = state.metamask.selectedTokenAddress const selectedTokenAddress = state.metamask.selectedTokenAddress
const selectedToken = tokens.filter(({ address }) => address === selectedTokenAddress)[0] const selectedToken = tokens.filter(({ address }) => address === selectedTokenAddress)[0]
const sendToken = state.metamask.send.token
return selectedToken || null return selectedToken || sendToken || null
} }
function getSelectedTokenExchangeRate (state) { function getSelectedTokenExchangeRate (state) {

@ -7,7 +7,7 @@ const ethAbi = require('ethereumjs-abi')
const ethUtil = require('ethereumjs-util') const ethUtil = require('ethereumjs-util')
const FromDropdown = require('./components/send/from-dropdown') const FromDropdown = require('./components/send/from-dropdown')
const ToAutoComplete = require('./components/send/to-autocomplete') const EnsInput = require('./components/ens-input')
const CurrencyDisplay = require('./components/send/currency-display') const CurrencyDisplay = require('./components/send/currency-display')
const MemoTextArea = require('./components/send/memo-textarea') const MemoTextArea = require('./components/send/memo-textarea')
const GasFeeDisplay = require('./components/send/gas-fee-display-v2') const GasFeeDisplay = require('./components/send/gas-fee-display-v2')
@ -253,7 +253,7 @@ SendTransactionScreen.prototype.renderFromRow = function () {
]) ])
} }
SendTransactionScreen.prototype.handleToChange = function (to) { SendTransactionScreen.prototype.handleToChange = function (to, nickname = '') {
const { const {
updateSendTo, updateSendTo,
updateSendErrors, updateSendErrors,
@ -269,12 +269,12 @@ SendTransactionScreen.prototype.handleToChange = function (to) {
toError = t('fromToSame') toError = t('fromToSame')
} }
updateSendTo(to) updateSendTo(to, nickname)
updateSendErrors({ to: toError }) updateSendErrors({ to: toError })
} }
SendTransactionScreen.prototype.renderToRow = function () { SendTransactionScreen.prototype.renderToRow = function () {
const { toAccounts, errors, to } = this.props const { toAccounts, errors, to, network } = this.props
const { toDropdownOpen } = this.state const { toDropdownOpen } = this.state
@ -289,7 +289,10 @@ SendTransactionScreen.prototype.renderToRow = function () {
]), ]),
h('div.send-v2__form-field', [ h('div.send-v2__form-field', [
h(ToAutoComplete, { h(EnsInput, {
name: 'address',
placeholder: 'Recipient Address',
network,
to, to,
accounts: Object.entries(toAccounts).map(([key, account]) => account), accounts: Object.entries(toAccounts).map(([key, account]) => account),
dropdownOpen: toDropdownOpen, dropdownOpen: toDropdownOpen,
@ -510,13 +513,13 @@ SendTransactionScreen.prototype.renderFooter = function () {
const noErrors = !amountError && toError === null const noErrors = !amountError && toError === null
return h('div.page-container__footer', [ return h('div.page-container__footer', [
h('button.btn-cancel.page-container__footer-button', { h('button.btn-secondary--lg.page-container__footer-button', {
onClick: () => { onClick: () => {
clearSend() clearSend()
goHome() goHome()
}, },
}, t('cancel')), }, t('cancel')),
h('button.btn-clear.page-container__footer-button', { h('button.btn-primary--lg.page-container__footer-button', {
disabled: !noErrors || !gasTotal || missingTokenBalance, disabled: !noErrors || !gasTotal || missingTokenBalance,
onClick: event => this.onSubmit(event), onClick: event => this.onSubmit(event),
}, t('next')), }, t('next')),
@ -538,11 +541,11 @@ SendTransactionScreen.prototype.render = function () {
) )
} }
SendTransactionScreen.prototype.addToAddressBookIfNew = function (newAddress) { SendTransactionScreen.prototype.addToAddressBookIfNew = function (newAddress, nickname = '') {
const { toAccounts, addToAddressBook } = this.props const { toAccounts, addToAddressBook } = this.props
if (!toAccounts.find(({ address }) => newAddress === address)) { if (!toAccounts.find(({ address }) => newAddress === address)) {
// TODO: nickname, i.e. addToAddressBook(recipient, nickname) // TODO: nickname, i.e. addToAddressBook(recipient, nickname)
addToAddressBook(newAddress) addToAddressBook(newAddress, nickname)
} }
} }
@ -603,6 +606,7 @@ SendTransactionScreen.prototype.onSubmit = function (event) {
updateTx, updateTx,
selectedToken, selectedToken,
editingTransactionId, editingTransactionId,
toNickname,
errors: { amount: amountError, to: toError }, errors: { amount: amountError, to: toError },
} = this.props } = this.props
@ -612,7 +616,7 @@ SendTransactionScreen.prototype.onSubmit = function (event) {
return return
} }
this.addToAddressBookIfNew(to) this.addToAddressBookIfNew(to, toNickname)
if (editingTransactionId) { if (editingTransactionId) {
const editedTx = this.getEditedTx() const editedTx = this.getEditedTx()

@ -200,7 +200,7 @@ class Settings extends Component {
]), ]),
h('div.settings__content-item', [ h('div.settings__content-item', [
h('div.settings__content-item-col', [ h('div.settings__content-item-col', [
h('button.settings__clear-button', { h('button.btn-primary--lg.settings__button', {
onClick (event) { onClick (event) {
window.logStateString((err, result) => { window.logStateString((err, result) => {
if (err) { if (err) {
@ -225,7 +225,7 @@ class Settings extends Component {
h('div.settings__content-item', t('revealSeedWords')), h('div.settings__content-item', t('revealSeedWords')),
h('div.settings__content-item', [ h('div.settings__content-item', [
h('div.settings__content-item-col', [ h('div.settings__content-item-col', [
h('button.settings__clear-button.settings__clear-button--red', { h('button.btn-primary--lg.settings__button--red', {
onClick (event) { onClick (event) {
event.preventDefault() event.preventDefault()
revealSeedConfirmation() revealSeedConfirmation()
@ -245,7 +245,7 @@ class Settings extends Component {
h('div.settings__content-item', t('useOldUI')), h('div.settings__content-item', t('useOldUI')),
h('div.settings__content-item', [ h('div.settings__content-item', [
h('div.settings__content-item-col', [ h('div.settings__content-item-col', [
h('button.settings__clear-button.settings__clear-button--orange', { h('button.btn-primary--lg.settings__button--orange', {
onClick (event) { onClick (event) {
event.preventDefault() event.preventDefault()
setFeatureFlagToBeta() setFeatureFlagToBeta()
@ -264,7 +264,7 @@ class Settings extends Component {
h('div.settings__content-item', t('resetAccount')), h('div.settings__content-item', t('resetAccount')),
h('div.settings__content-item', [ h('div.settings__content-item', [
h('div.settings__content-item-col', [ h('div.settings__content-item-col', [
h('button.settings__clear-button.settings__clear-button--orange', { h('button.btn-primary--lg.settings__button--orange', {
onClick (event) { onClick (event) {
event.preventDefault() event.preventDefault()
showResetAccountConfirmationModal() showResetAccountConfirmationModal()

@ -72,6 +72,15 @@
normalize-path "^2.0.1" normalize-path "^2.0.1"
through2 "^2.0.3" through2 "^2.0.3"
"@sentry/cli@^1.30.3":
version "1.30.3"
resolved "https://registry.yarnpkg.com/@sentry/cli/-/cli-1.30.3.tgz#02d0f7781c1ee5e1be5a4312a325fbe8b1b37231"
dependencies:
https-proxy-agent "^2.1.1"
node-fetch "^1.7.3"
progress "2.0.0"
proxy-from-env "^1.0.0"
"@types/node@*": "@types/node@*":
version "8.5.2" version "8.5.2"
resolved "https://registry.yarnpkg.com/@types/node/-/node-8.5.2.tgz#83b8103fa9a2c2e83d78f701a9aa7c9539739aa5" resolved "https://registry.yarnpkg.com/@types/node/-/node-8.5.2.tgz#83b8103fa9a2c2e83d78f701a9aa7c9539739aa5"
@ -201,6 +210,12 @@ agent-base@2:
extend "~3.0.0" extend "~3.0.0"
semver "~5.0.1" semver "~5.0.1"
agent-base@^4.1.0:
version "4.2.0"
resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-4.2.0.tgz#9838b5c3392b962bad031e6a4c5e1024abec45ce"
dependencies:
es6-promisify "^5.0.0"
ajv-keywords@^1.1.1: ajv-keywords@^1.1.1:
version "1.5.1" version "1.5.1"
resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-1.5.1.tgz#314dd0a4b3368fad3dfcdc54ede6171b886daf3c" resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-1.5.1.tgz#314dd0a4b3368fad3dfcdc54ede6171b886daf3c"
@ -3711,6 +3726,16 @@ es6-map@^0.1.3:
es6-symbol "~3.1.1" es6-symbol "~3.1.1"
event-emitter "~0.3.5" event-emitter "~0.3.5"
es6-promise@^4.0.3:
version "4.2.4"
resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.4.tgz#dc4221c2b16518760bd8c39a52d8f356fc00ed29"
es6-promisify@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/es6-promisify/-/es6-promisify-5.0.0.tgz#5109d62f3e56ea967c4b63505aef08291c8a5203"
dependencies:
es6-promise "^4.0.3"
es6-set@~0.1.5: es6-set@~0.1.5:
version "0.1.5" version "0.1.5"
resolved "https://registry.yarnpkg.com/es6-set/-/es6-set-0.1.5.tgz#d2b3ec5d4d800ced818db538d28974db0a73ccb1" resolved "https://registry.yarnpkg.com/es6-set/-/es6-set-0.1.5.tgz#d2b3ec5d4d800ced818db538d28974db0a73ccb1"
@ -5919,6 +5944,13 @@ https-proxy-agent@1:
debug "2" debug "2"
extend "3" extend "3"
https-proxy-agent@^2.1.1:
version "2.2.0"
resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-2.2.0.tgz#7fbba856be8cd677986f42ebd3664f6317257887"
dependencies:
agent-base "^4.1.0"
debug "^3.1.0"
human-standard-token-abi@^1.0.2: human-standard-token-abi@^1.0.2:
version "1.0.2" version "1.0.2"
resolved "https://registry.yarnpkg.com/human-standard-token-abi/-/human-standard-token-abi-1.0.2.tgz#207d7846796ee5bb85fdd336e769cb38045b2ae0" resolved "https://registry.yarnpkg.com/human-standard-token-abi/-/human-standard-token-abi-1.0.2.tgz#207d7846796ee5bb85fdd336e769cb38045b2ae0"
@ -7984,7 +8016,7 @@ nock@^9.0.14:
qs "^6.5.1" qs "^6.5.1"
semver "^5.3.0" semver "^5.3.0"
node-fetch@^1.0.1, node-fetch@~1.7.1: node-fetch@^1.0.1, node-fetch@^1.7.3, node-fetch@~1.7.1:
version "1.7.3" version "1.7.3"
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-1.7.3.tgz#980f6f72d85211a5347c6b2bc18c5b84c3eb47ef" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-1.7.3.tgz#980f6f72d85211a5347c6b2bc18c5b84c3eb47ef"
dependencies: dependencies:
@ -8991,7 +9023,7 @@ process@~0.5.1:
version "0.5.2" version "0.5.2"
resolved "https://registry.yarnpkg.com/process/-/process-0.5.2.tgz#1638d8a8e34c2f440a91db95ab9aeb677fc185cf" resolved "https://registry.yarnpkg.com/process/-/process-0.5.2.tgz#1638d8a8e34c2f440a91db95ab9aeb677fc185cf"
progress@^2.0.0: progress@2.0.0, progress@^2.0.0:
version "2.0.0" version "2.0.0"
resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.0.tgz#8a1be366bf8fc23db2bd23f10c6fe920b4389d1f" resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.0.tgz#8a1be366bf8fc23db2bd23f10c6fe920b4389d1f"
@ -9067,6 +9099,10 @@ proxy-agent@~2.0.0:
pac-proxy-agent "1" pac-proxy-agent "1"
socks-proxy-agent "2" socks-proxy-agent "2"
proxy-from-env@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.0.0.tgz#33c50398f70ea7eb96d21f7b817630a55791c7ee"
prr@~1.0.1: prr@~1.0.1:
version "1.0.1" version "1.0.1"
resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476" resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476"
@ -9245,6 +9281,10 @@ raphael@^2.2.0:
dependencies: dependencies:
eve-raphael "0.5.0" eve-raphael "0.5.0"
raven-js@^3.24.0:
version "3.24.0"
resolved "https://registry.yarnpkg.com/raven-js/-/raven-js-3.24.0.tgz#59464d8bc4b3812ae87a282e9bb98ecad5b4b047"
raw-body@2, raw-body@2.3.2: raw-body@2, raw-body@2.3.2:
version "2.3.2" version "2.3.2"
resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.3.2.tgz#bcd60c77d3eb93cde0050295c3f379389bc88f89" resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.3.2.tgz#bcd60c77d3eb93cde0050295c3f379389bc88f89"

Loading…
Cancel
Save