aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas <tmashuang@gmail.com>2018-03-21 02:35:59 +0800
committerThomas <tmashuang@gmail.com>2018-03-21 02:35:59 +0800
commitd4eb883958e7c13029726484e61d1db01b77d0ff (patch)
treeabe3938f6426040bcb01464bceb74316fd7107e1
parent2c42cfdf1e8c8aff517cae9f6011dd39e503cef3 (diff)
parent716e034c75c53bbcc0d81a36c2eadf140c53ca9c (diff)
downloadtangerine-wallet-browser-d4eb883958e7c13029726484e61d1db01b77d0ff.tar
tangerine-wallet-browser-d4eb883958e7c13029726484e61d1db01b77d0ff.tar.gz
tangerine-wallet-browser-d4eb883958e7c13029726484e61d1db01b77d0ff.tar.bz2
tangerine-wallet-browser-d4eb883958e7c13029726484e61d1db01b77d0ff.tar.lz
tangerine-wallet-browser-d4eb883958e7c13029726484e61d1db01b77d0ff.tar.xz
tangerine-wallet-browser-d4eb883958e7c13029726484e61d1db01b77d0ff.tar.zst
tangerine-wallet-browser-d4eb883958e7c13029726484e61d1db01b77d0ff.zip
Merge branch 'master' into i3571-CompleteI18nTemplates
-rw-r--r--CHANGELOG.md1
-rw-r--r--app/_locales/es/messages.json840
-rw-r--r--app/_locales/it/messages.json819
-rw-r--r--app/_locales/ph/messages.json609
-rw-r--r--app/_locales/pt/messages.json819
-rw-r--r--app/scripts/controllers/transactions.js53
-rw-r--r--app/scripts/lib/tx-state-manager.js42
-rw-r--r--development/states/confirm-new-ui.json2
-rw-r--r--development/states/send-edit.json2
-rw-r--r--development/verify-locale-strings.js96
-rw-r--r--gulpfile.js6
-rw-r--r--old-ui/app/components/transaction-list-item.js18
-rw-r--r--old-ui/app/components/transaction-list.js2
-rw-r--r--old-ui/app/css/index.css4
-rw-r--r--package.json6
-rw-r--r--test/integration/lib/send-new-ui.js8
-rw-r--r--test/unit/tx-controller-test.js45
-rw-r--r--ui/app/actions.js4
-rw-r--r--ui/app/components/customize-gas-modal/index.js31
-rw-r--r--ui/app/components/pending-tx/confirm-send-ether.js90
-rw-r--r--ui/app/components/pending-tx/confirm-send-token.js89
-rw-r--r--ui/app/components/send/gas-fee-display-v2.js11
-rw-r--r--ui/app/components/send/send-v2-container.js1
-rw-r--r--ui/app/components/tx-list-item.js70
-rw-r--r--ui/app/components/tx-list.js13
-rw-r--r--ui/app/conversion-util.js13
-rw-r--r--ui/app/css/itcss/components/account-menu.scss3
-rw-r--r--ui/app/css/itcss/components/network.scss3
-rw-r--r--ui/app/css/itcss/components/newui-sections.scss1
-rw-r--r--ui/app/css/itcss/components/send.scss27
-rw-r--r--ui/app/css/itcss/components/transaction-list.scss55
-rw-r--r--ui/app/css/itcss/generic/index.scss2
-rw-r--r--ui/app/css/itcss/generic/reset.scss4
-rw-r--r--ui/app/css/itcss/settings/variables.scss1
-rw-r--r--ui/app/reducers/metamask.js2
-rw-r--r--ui/app/selectors.js5
-rw-r--r--ui/app/send-v2.js9
37 files changed, 3699 insertions, 107 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index e7d4a09fe..75ba7670f 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,7 @@
## Current Master
+- MetaMask will no longer allow nonces to be specified by the dapp
- Add ability for internationalization.
- Will now throw an error if the `to` field in txParams is not valid.
- Will strip null values from the `to` field.
diff --git a/app/_locales/es/messages.json b/app/_locales/es/messages.json
index 78fc64dbf..f519c194c 100644
--- a/app/_locales/es/messages.json
+++ b/app/_locales/es/messages.json
@@ -1,10 +1,840 @@
{
+ "accept": {
+ "message": "Aceptar"
+ },
+ "account": {
+ "message": "Cuenta"
+ },
+ "accountDetails": {
+ "message": "Detalles de la cuenta"
+ },
+ "accountName": {
+ "message": "Nombre de la cuenta"
+ },
+ "address": {
+ "message": "Dirección"
+ },
+ "addToken": {
+ "message": "Agregar Token"
+ },
+ "amount": {
+ "message": "Cantidad"
+ },
+ "amountPlusGas": {
+ "message": "Cantidad + Gas"
+ },
+ "appDescription": {
+ "message": "Extensión del explorador usar Ethereum",
+ "description": "La descripción de la aplicación"
+ },
"appName": {
"message": "MetaMask",
- "description": "The name of the application"
+ "description": "El nombre de la aplicación"
},
- "appDescription": {
- "message": "Administración de identidad en Ethereum",
- "description": "The description of the application"
+ "attemptingConnect": {
+ "message": "Intentando conectar a la Blockchain"
+ },
+ "available": {
+ "message": "Disponible"
+ },
+ "back": {
+ "message": "Atrás"
+ },
+ "balance": {
+ "message": "Saldo"
+ },
+ "balances": {
+ "message": "Tus saldos"
+ },
+ "balanceIsInsufficientGas": {
+ "message": "Saldo de gas insuficiente"
+ },
+ "beta": {
+ "message": "BETA"
+ },
+ "betweenMinAndMax": {
+ "message": "Debe ser mayor o igual a $1 y menor o igual a $2",
+ "description": "helper para ingresar hex como un ingreso decimal"
+ },
+ "borrowDharma": {
+ "message": "Pedir prestado con Dharma (Beta)"
+ },
+ "buy": {
+ "message": "Comprar"
+ },
+ "buyCoinbase": {
+ "message": "Comprar en Coinbase"
+ },
+ "buyCoinbaseExplainer": {
+ "message": "Coinbase es la manera más popular en el mundo para comprar y vender bitcoin, ethereum y litecoin"
+ },
+ "cancel": {
+ "message": "Cancelar"
+ },
+ "clickCopy": {
+ "message": "Click para copiar"
+ },
+ "confirm": {
+ "message": "Confirmar"
+ },
+ "continue": {
+ "message": "Continuar"
+ },
+ "confirmContract": {
+ "message": "Confirmar contrato"
+ },
+ "confirmPassword": {
+ "message": "Confirmar contraseña"
+ },
+ "enterPasswordConfirm": {
+ "message": "Ingresa tu contraseña para confirmar"
+ },
+ "confirmTransaction": {
+ "message": "Confirmar transacción "
+ },
+ "continueToCoinbase": {
+ "message": "Continuar a Coinbase"
+ },
+ "contractDeployment": {
+ "message": "Deployar contrato"
+ },
+ "currentConversion": {
+ "message": "Conversión Actual"
+ },
+ "conversionProgress": {
+ "message": "Conversión en progreso"
+ },
+ "copiedButton": {
+ "message": "Copiado"
+ },
+ "copiedClipboard": {
+ "message": "Copiado al portapapeles"
+ },
+ "copiedExclamation": {
+ "message": "Copiado!"
+ },
+ "copy": {
+ "message": "Copiar"
+ },
+ "copyToClipboard": {
+ "message": "Copiar al portapapeles"
+ },
+ "copyButton": {
+ "message": " Copiar "
+ },
+ "copyPrivateKey": {
+ "message": "Esta es tu llave privada (Click para copiar)"
+ },
+ "create": {
+ "message": "Crear"
+ },
+ "createAccount": {
+ "message": "Crear Cuenta"
+ },
+ "createDen": {
+ "message": "Crear"
+ },
+ "crypto": {
+ "message": "Crypto",
+ "description": "Tipo de Cambio (criptomonedas)"
+ },
+ "customGas": {
+ "message": "Personalizar Gas"
+ },
+ "customize": {
+ "message": "Personalizar"
+ },
+ "currentRPC": {
+ "message": "RPC actual"
+ },
+ "customRPC": {
+ "message": "RPC Personalizado"
+ },
+ "newRPC": {
+ "message": "Nueva URL del RPC"
+ },
+ "defaultNetwork": {
+ "message": "La red por defecto para las transacciones de Ether es MainNet (red principal)"
+ },
+ "denExplainer": {
+ "message": "Tu DEN es tu contraseña encriptada guardada dentro de MetaMask"
+ },
+ "deposit": {
+ "message": "Depositar"
+ },
+ "depositBTC": {
+ "message": "Deposita tus BTC a la dirección de abajo:"
+ },
+ "depositCoin": {
+ "message": "Deposita tu $1 a la dirección de abajo",
+ "description": "Informa al usuario que moneda ha elegido para depositar en shapeshift"
+ },
+ "depositEth": {
+ "message": "Depositar Eth"
+ },
+ "depositEther": {
+ "message": "Depositar Ether"
+ },
+ "depositFiat": {
+ "message": "Depositar con Fiat (divisa nacional)"
+ },
+ "depositFromAccount": {
+ "message": "Depositar con otra cuenta"
+ },
+ "depositShapeShift": {
+ "message": "Depositar con ShapeShift"
+ },
+ "depositShapeShiftExplainer": {
+ "message": "Si tu tienes otras criptomonedas, puedes intercambiar y depositar Ether directamente en tu billetera de MetaMask. No necesitas tener una cuenta."
+ },
+ "details": {
+ "message": "Detalles"
+ },
+ "directDeposit": {
+ "message": "Deposito directo"
+ },
+ "directDepositEther": {
+ "message": "Depositar Ether directamente"
+ },
+ "directDepositEtherExplainer": {
+ "message": "Si tu tienes algo de Ether, la forma rapida para tener Ether en tu nueva billetera es depositando directamente"
+ },
+ "done": {
+ "message": "Completo"
+ },
+ "edit": {
+ "message": "Editar"
+ },
+ "editAccountName": {
+ "message": "Editar el nombre de la cuenta"
+ },
+ "encryptNewDen": {
+ "message": "Encriptar tu nuevo DEN"
+ },
+ "enterPassword": {
+ "message": "Ingresa contraseña"
+ },
+ "passwordCorrect": {
+ "message": "Asegurate que tu contraseña es correcta"
+ },
+ "etherscanView": {
+ "message": "Ver la cuenta en Etherscan"
+ },
+ "exchangeRate": {
+ "message": "Tipo de cambio"
+ },
+ "exportPrivateKey": {
+ "message": "Exportar llave privada"
+ },
+ "exportPrivateKeyWarning": {
+ "message": "Exportar llaves privadas bajo TU PROPIO riesgo"
+ },
+ "failed": {
+ "message": "Fallo"
+ },
+ "fiat": {
+ "message": "FIAT",
+ "description": "Exchange type"
+ },
+ "fileImportFail": {
+ "message": "No funciona importar el archivo? Haz Click Aquí!",
+ "description": "Ayuda al usuario a importar su cuenta desde un archivo JSON"
+ },
+ "from": {
+ "message": "De:"
+ },
+ "fromShapeShift": {
+ "message": "De ShapeShift"
+ },
+ "gas": {
+ "message": "Gas",
+ "description": "Indicación pequeña del costo de gas"
+ },
+ "gasFee": {
+ "message": "Comisión de gas"
+ },
+ "gasLimit": {
+ "message": "Límite de gas"
+ },
+ "gasLimitCalculation": {
+ "message": "Calculamos el límite de gas sugerido en función de las tasas de éxito de la red"
+ },
+ "gasLimitRequired": {
+ "message": "Límite de Gas requerido"
+ },
+ "gasLimitTooLow": {
+ "message": "El límite de gas debe ser de al menos 21000"
+ },
+ "gasPrice": {
+ "message": "Precio del Gas (GWEI)"
+ },
+ "gasPriceCalculation": {
+ "message": "Calculamos los precios sugeridos del gas en función de las tasas de éxito de la red"
+ },
+ "gasPriceRequired": {
+ "message": "Precio del gas requerido"
+ },
+ "getEther": {
+ "message": "Conseguir Ether"
+ },
+ "getEtherFromFaucet": {
+ "message": "Obtenga Ether de un faucet (grifo) por $1",
+ "description": "Muestra el nombre de la red para el faucet (grifo) de Ether"
+ },
+ "greaterThanMin": {
+ "message": "Debe ser mayor o igual a $1",
+ "description": "helper para ingresar hex como entrada decimal"
+ },
+ "here": {
+ "message": "Aqui",
+ "description": "como en -haz click aquí- para más información"
+ },
+ "hide": {
+ "message": "Ocultar"
+ },
+ "hideToken": {
+ "message": "Ocultar Token"
+ },
+ "hideTokenPrompt": {
+ "message": "Ocultar Token?"
+ },
+ "howToDeposit": {
+ "message": "Cómo te gustaria depositar Ether?"
+ },
+ "import": {
+ "message": "Importar",
+ "description": "Botón para importar una cuenta desde un archivo seleccionado"
+ },
+ "importAccount": {
+ "message": "Importar Cuenta"
+ },
+ "importAnAccount": {
+ "message": "Importar una cuenta"
+ },
+ "importDen": {
+ "message": "Importar DEN existente"
+ },
+ "imported": {
+ "message": "Importado",
+ "description": "estado que muestra que una cuenta ha sido completamente cargada en el llavero"
+ },
+ "infoHelp": {
+ "message": "Informacion y Ayuda"
+ },
+ "invalidAddress": {
+ "message": "Dirección Inválida"
+ },
+ "invalidGasParams": {
+ "message": "Parametros de Gas Inválidos"
+ },
+ "invalidInput": {
+ "message": "Entrada inválida"
+ },
+ "invalidRequest": {
+ "message": "Peticion inválida"
+ },
+ "invalidAddressRecipient": {
+ "message": "Dirección del recipiente invalida"
+ },
+ "fromToSame": {
+ "message": "La dirección de origen y destino no pueden ser la misma"
+ },
+ "jsonFile": {
+ "message": "Archivo JSON",
+ "description": "formato para importar una cuenta"
+ },
+ "jsonFail": {
+ "message": "Algo malo pasó. Asegurate que tu JSON tiene el formato correcto"
+ },
+ "kovan": {
+ "message": "Red de pruebas Kovan"
+ },
+ "lessThanMax": {
+ "message": "Debe ser menor o igual a $1",
+ "description": "helper para ingresar hex como decimal"
+ },
+ "limit": {
+ "message": "Límite"
+ },
+ "loading": {
+ "message": "Cargando..."
+ },
+ "loadingTokens": {
+ "message": "Cargando Tokens..."
+ },
+ "localhost": {
+ "message": "Localhost 8545"
+ },
+ "login": {
+ "message": "Ingresar"
+ },
+ "logout": {
+ "message": "Cerrar sesion"
+ },
+ "loose": {
+ "message": "Loose"
+ },
+ "mainnet": {
+ "message": "Red principal de Ethereum (MainNet)"
+ },
+ "message": {
+ "message": "Mensaje"
+ },
+ "min": {
+ "message": "Minimo"
+ },
+ "myAccounts": {
+ "message": "Mis cuentas"
+ },
+ "needEtherInWallet": {
+ "message": "Para interactuar con una aplicación descentralizada usando MetaMask, vas a necesitar tener Ether en tu billetera"
+ },
+ "needImportFile": {
+ "message": "Debes seleccionar un archivo para importar",
+ "description": "El usuario está importando una cuenta y necesita agregar un archivo para continuar"
+ },
+ "needImportPassword": {
+ "message": "Debes ingresar una contraseña para el archivo seleccionado",
+ "description": "Contraseña y archivo necesarios para importar una cuenta"
+ },
+ "validFileImport": {
+ "message": "Debes selecionar un archivo valido para importar"
+ },
+ "networks": {
+ "message": "Redes"
+ },
+ "newAccount": {
+ "message": "Nueva cuenta"
+ },
+ "newAccountNumberName": {
+ "message": "Cuenta $1",
+ "description": "Nombre por defecto de la próxima cuenta a ser creada o pantalla de creación de cuenta"
+ },
+ "newContract": {
+ "message": "Nuevo contrato"
+ },
+ "newPassword": {
+ "message": "Nueva contraseña (mínimo [8] caracteres)"
+ },
+ "newRecipient": {
+ "message": "Nuevo destinatario"
+ },
+ "next": {
+ "message": "Siguiente"
+ },
+ "noAddressForName": {
+ "message": "No se ha establecido ninguna dirección para este nombre"
+ },
+ "noDeposits": {
+ "message": "No hay depósitos recibidos"
+ },
+ "noTransactionHistory": {
+ "message": "Sin historial de transacciones"
+ },
+ "transactions": {
+ "message": "Transacciones"
+ },
+ "noTransactions": {
+ "message": "Sin transacciones"
+ },
+ "notStarted": {
+ "message": "Sin iniciar"
+ },
+ "oldUI": {
+ "message": "Antigua UI"
+ },
+ "useOldUI": {
+ "message": "Usar UI antigua"
+ },
+ "oldUIMessage": {
+ "message": "Regresaste a la antigua UI. Puedes regresar a la nueva UI mediante la opcion en la barra desplegable del menu de arriba a la derecha."
+ },
+ "or": {
+ "message": "o",
+ "description": "opción entre crear o importar una cuenta"
+ },
+ "passwordMismatch": {
+ "message": "Contraseña no concide",
+ "description": "en el proceso de creación de contraseña, los dos campos de contraseña no coincidieron"
+ },
+ "passwordShort": {
+ "message": "Contraseña no es lo suficientemente larga",
+ "description": "in password creation process, the password is not long enough to be secure"
+ },
+ "pastePrivateKey": {
+ "message": "Pega tu llave privada aqui",
+ "description": "Para importar una cuenta desde una llave privada"
+ },
+ "pasteSeed": {
+ "message": "Pegue su frase semilla aquí!"
+ },
+ "generatingSeed": {
+ "message": "Generando semilla..."
+ },
+ "pleaseReviewTransaction": {
+ "message": "Por favor revisa tu transaccion"
+ },
+ "privateKey": {
+ "message": "Llave privada",
+ "description": "select this type of file to use to import an account"
+ },
+ "privateKeyWarning": {
+ "message": "Advertencia: Nunca revele esta clave. Cualquier persona con sus claves privadas puede robar cualquier activo retenido en su cuenta."
+ },
+ "privateNetwork": {
+ "message": "Red Privada"
+ },
+ "qrCode": {
+ "message": "Mostrar codigo QR"
+ },
+ "readdToken": {
+ "message": "Puede volver a agregar este token en el futuro yendo a 'Agregar token' en el menú de opciones de su cuenta.."
+ },
+ "readMore": {
+ "message": "Leer más aquí"
+ },
+ "receive": {
+ "message": "Recibir"
+ },
+ "recipientAddress": {
+ "message": "Dirección del receptor"
+ },
+ "refundAddress": {
+ "message": "Su dirección de reembolso"
+ },
+ "rejected": {
+ "message": "Rechazado"
+ },
+ "required": {
+ "message": "Requerido"
+ },
+ "retryWithMoreGas": {
+ "message": "Vuelva a intentar con un precio de Gas más alto aquí"
+ },
+ "revert": {
+ "message": "Revertir"
+ },
+ "rinkeby": {
+ "message": "Red privada Rinkeby"
+ },
+ "ropsten": {
+ "message": "Red privada Ropsten"
+ },
+ "sampleAccountName": {
+ "message": "Ej. Mi nueva cuenta",
+ "description": "Ayuda al usuario a entender el concepto de agregar un nombre, leíble por humanos, a su cuenta"
+ },
+ "save": {
+ "message": "Guardar"
+ },
+ "saveAsFile": {
+ "message": "Guardar como archivo",
+ "description": "Proceso de exportación de cuenta"
+ },
+ "selectService": {
+ "message": "Seleccionar servicio"
+ },
+ "send": {
+ "message": "Enviar"
+ },
+ "sendTokens": {
+ "message": "Enviar Tokens"
+ },
+ "sendETH": {
+ "message": "Enviar ETH"
+ },
+ "sendTokensAnywhere": {
+ "message": "Enviar Tokens a cualquiera con una cuenta de Ethereum"
+ },
+ "settings": {
+ "message": "Configuración"
+ },
+ "info": {
+ "message": "Información"
+ },
+ "shapeshiftBuy": {
+ "message": "Comprar con ShapeShift"
+ },
+ "showPrivateKeys": {
+ "message": "Mostrar llaves privadas"
+ },
+ "showQRCode": {
+ "message": "Mostrar codigo QR"
+ },
+ "sign": {
+ "message": "Firmar"
+ },
+ "signMessage": {
+ "message": "Firmar Mensaje"
+ },
+ "signNotice": {
+ "message": "Firmar este mensaje puede tener\n efectos secundarios peligrosos. Firma sólo\nmensajes desde sitios a los cuales tú estés dispuesto a confiar completamente tu cuenta.\nEste método peligroso va a ser \nremovido en una version futura."
+ },
+ "sigRequest": {
+ "message": "Solicitud de firma"
+ },
+ "sigRequested": {
+ "message": "Firma solicitada"
+ },
+ "status": {
+ "message": "Estado"
+ },
+ "submit": {
+ "message": "Enviar"
+ },
+ "takesTooLong": {
+ "message": "¿Está tomando demasiado?"
+ },
+ "testFaucet": {
+ "message": "Testear Faucet"
+ },
+ "to": {
+ "message": "Para:"
+ },
+ "toETHviaShapeShift": {
+ "message": "$1 a ETH via ShapeShift",
+ "description": "el sistema llenará el tipo de depósito al principio del mensaje"
+ },
+ "tokenBalance": {
+ "message": "Tu balance de Tokens es:"
+ },
+ "total": {
+ "message": "Total"
+ },
+ "transactionMemo": {
+ "message": "Memo de transaccion (opcional)"
+ },
+ "transactionNumber": {
+ "message": "Número de transacción"
+ },
+ "transfers": {
+ "message": "Transferencias"
+ },
+ "troubleTokenBalances": {
+ "message": "Tuvimos problemas para cargar sus balances de tokens. Puedes verlos ",
+ "description": "Followed by a link (here) to view token balances"
+ },
+ "typePassword": {
+ "message": "Escribe tu contraseña"
+ },
+ "uiWelcome": {
+ "message": "Bienvenido a la nueva UI (Beta)"
+ },
+ "uiWelcomeMessage": {
+ "message": "Estás usando la nueva UI de MetaMask. Echa un vistazo alrededor, prueba las nuevas características, tales como mandar tokens, y déjanos saber si tienes algún problema"
+ },
+ "unavailable": {
+ "message": "No disponible"
+ },
+ "unknown": {
+ "message": "Desconocido (a)"
+ },
+ "unknownNetwork": {
+ "message": "Red privada desconocida"
+ },
+ "unknownNetworkId": {
+ "message": "ID (identidad) de Red desconocida"
+ },
+ "currentNetwork": {
+ "message": "Red actual"
+ },
+ "usaOnly": {
+ "message": "Sólo USA (Estados Unidos)",
+ "description": "El uso de este exchange (casa de cambio) estaá limitado a las personas dentro de los Estados Unidos de America"
+ },
+ "usedByClients": {
+ "message": "Utilizado por una variedad de clientes diferentes"
+ },
+ "viewAccount": {
+ "message": "Mirar cuenta"
+ },
+ "warning": {
+ "message": "Advertencia"
+ },
+ "whatsThis": {
+ "message": "Qué es esto?"
+ },
+ "yourSigRequested": {
+ "message": "Tu firma ya fue solicidada"
+ },
+ "youSign": {
+ "message": "Usted está firmando"
+ },
+ "importedAccountMsg": {
+ "message": "Cuentas importadas no serán asociadas con tu cuenta original creada con tu MetaMask. Aprende más acerca de importar cuentas. "
+ },
+ "selectType": {
+ "message": "Seleccionar tipo"
+ },
+ "selectCurrency": {
+ "message": "Seleccionar moneda"
+ },
+ "password": {
+ "message": "Contraseña"
+ },
+ "select": {
+ "message": "Seleccionar"
+ },
+ "readMore2": {
+ "message": "Leer más."
+ },
+ "secretPhrase": {
+ "message": "Ingresa tu frase de 12 palabras para restaurar tu bóveda"
+ },
+ "spaceBetween": {
+ "message": "Sólo puede haber un espacio entre las palabras"
+ },
+ "loweCaseWords": {
+ "message": "las frases semilla sólo pueden tener minúsculas"
+ },
+ "seedPhraseReq": {
+ "message": "las frases semilla tienen doce (12) palabras de largo"
+ },
+ "addTokens": {
+ "message": "Agregar tokens"
+ },
+ "addCustomTokens": {
+ "message": "Agregar token personalizados"
+ },
+ "up": {
+ "message": "arriba"
+ },
+ "down": {
+ "message": "abajo"
+ },
+ "tokenWarning1": {
+ "message": "Mantenga un registro de los tokens que ha comprado con su cuenta de MetaMask. Si compraste tokens usando una cuenta diferente, esos tokens no aparecerán aquí."
+ },
+ "tokenSelection": {
+ "message": "Busca tokens o selecciónalo de nuestra lista de tokens populares"
+ },
+ "search": {
+ "message": "Buscar"
+ },
+ "privacyMsg": {
+ "message": "Política de privacidad"
+ },
+ "terms": {
+ "message": "Terminos de Uso"
+ },
+ "attributions": {
+ "message": "Atribuciones"
+ },
+ "supportCenter": {
+ "message": "Visita nuestro centro de atención"
+ },
+ "knowledgeDataBase": {
+ "message": "Visita nuestra base de conocimiento"
+ },
+ "visitWebSite": {
+ "message": "Visita nuestro sitio web"
+ },
+ "followTwitter": {
+ "message": "Síguenos en Twitter"
+ },
+ "emailUs": {
+ "message": "Envíanos un correo!"
+ },
+ "hereList": {
+ "message": "Aquí está una lista!!!"
+ },
+ "insufficientFounds": {
+ "message": "Fondos insuficientes"
+ },
+ "insufficientTokens": {
+ "message": "Tokens insuficientes"
+ },
+ "negativeETH": {
+ "message": "No se pueden mandar cantidades negativas de ETH"
+ },
+ "urlErrorMsg": {
+ "message": "URI necesita el prefijo HTTP/HTTPS apropiado"
+ },
+ "invalidRPC": {
+ "message": "Invalida URL del RPC"
+ },
+ "saveLogs": {
+ "message": "Logs de estado contienen tus direcciones publicas y transacciones enviadas"
+ },
+ "stateLogs": {
+ "message": "Logs de estado"
+ },
+ "downloadStatelogs": {
+ "message": "Descargar logs de estados"
+ },
+ "revealSeedWords": {
+ "message": "Revelar palabras de semilla"
+ },
+ "revealSeedWordsWarning": {
+ "message": "No recuperes tu semilla en un lugar publico! Esas palabras pueden ser usadas para robarte todas tus cuentas"
+ },
+ "resetAccount": {
+ "message": "Reiniciar cuenta"
+ },
+ "builtInCalifornia": {
+ "message": "Metamask fue diseñado y construido en California "
+ },
+ "classicInterface": {
+ "message": "Usar interfaz clasica "
+ },
+ "welcomeBeta": {
+ "message": "Bienvenido a Metamask Beta"
+ },
+ "metamaskDescription": {
+ "message": "Metamask es una identidad segura en Ethereum"
+ },
+ "holdEther": {
+ "message": "Te permite mantener tus ether y tokens, así como puente para aplicaciones descentralizadas"
+ },
+ "decimalsMustZerotoTen": {
+ "message": "Los decimales deben ser al menos 0 y no más de 36"
+ },
+ "symbolBetweenZeroTen": {
+ "message": "Símbolo debe ser entre 0 y 10 caracteres"
+ },
+ "personalAddressDetected": {
+ "message": "Dirección personal detectada. Ingresa la dirección del contrato del token"
+ },
+ "tokenAlreadyAdded": {
+ "message": "El token esta actualmente agregado"
+ },
+ "mustSelectOne": {
+ "message": "Debe seleccionar al menos un (1) token"
+ },
+ "tokenAddress": {
+ "message": "Dirección del token"
+ },
+ "tokenSymbol": {
+ "message": "Símbolo del token"
+ },
+ "decimalsPrecision": {
+ "message": "Decimales de precisión"
+ },
+ "likeToAddTokens": {
+ "message": "¿Te gustaría agregar estos tokens?"
+ },
+ "msgCompose1": {
+ "message": "Solo manda "
+ },
+ "msgCompose2": {
+ "message": " a una dirección de Ethereum"
+ },
+ "blockiesIdenticon": {
+ "message": "Usar Blockies Identicon (Iconos)"
+ },
+ "vaultCreated": {
+ "message": "Bóveda creada"
+ },
+ "twelveWords": {
+ "message": "Estas 12 palabras son la única forma de restablecer sus cuentas de MetaMask. \nGuardalas en un lugar seguro y secreto."
+ },
+ "copiedSafe": {
+ "message": "Ya lo guardé en un lugar seguro"
+ },
+ "saveSeedAsFile": {
+ "message": "Guardar la semilla como archivo"
+ },
+ "restoreFromSeed": {
+ "message": "Restaurar desde semilla"
}
-}
+} \ No newline at end of file
diff --git a/app/_locales/it/messages.json b/app/_locales/it/messages.json
new file mode 100644
index 000000000..f54ef98ca
--- /dev/null
+++ b/app/_locales/it/messages.json
@@ -0,0 +1,819 @@
+{
+ "accept": {
+ "message": "Accetta"
+ },
+ "account": {
+ "message": "Account"
+ },
+ "accountDetails": {
+ "message": "Dettagli Account"
+ },
+ "accountName": {
+ "message": "Nome Account"
+ },
+ "address": {
+ "message": "Indirizzo"
+ },
+ "addCustomToken": {
+ "message": "Aggiungi un token personalizzato"
+ },
+ "addToken": {
+ "message": "Aggiungi Token"
+ },
+ "addTokens": {
+ "message": "Aggiungi più token"
+ },
+ "amount": {
+ "message": "Importo"
+ },
+ "amountPlusGas": {
+ "message": "Importo + Gas"
+ },
+ "appDescription": {
+ "message": "Ethereum Browser Extension",
+ "description": "La descrizione dell'applicazione"
+ },
+ "appName": {
+ "message": "MetaMask",
+ "description": "Il nome dell'applicazione"
+ },
+ "attemptingConnect": {
+ "message": "Tentativo di connessione alla blockchain."
+ },
+ "attributions": {
+ "message": "Attribuzioni"
+ },
+ "available": {
+ "message": "Disponibile"
+ },
+ "back": {
+ "message": "Indietro"
+ },
+ "balance": {
+ "message": "Bilancio:"
+ },
+ "balances": {
+ "message": "I tuoi bilanci"
+ },
+ "balanceIsInsufficientGas": {
+ "message": "Bilancio insufficiente per il gas totale corrente"
+ },
+ "beta": {
+ "message": "BETA"
+ },
+ "betweenMinAndMax": {
+ "message": "deve essere maggiore o uguale a $1 e minore o uguale a $2.",
+ "description": "aiuto per inserire un input esadecimale come decimale"
+ },
+ "blockiesIdenticon": {
+ "message": "Usa le icone Blockie"
+ },
+ "borrowDharma": {
+ "message": "Prendi in presisito con Dharma (Beta)"
+ },
+ "builtInCalifornia": {
+ "message": "MetaMask è progettato e costruito in California."
+ },
+ "buy": {
+ "message": "Compra"
+ },
+ "buyCoinbase": {
+ "message": "Compra su Coinbase"
+ },
+ "buyCoinbaseExplainer": {
+ "message": "Coinbase è il servizio più popolare al mondo per comprare e vendere bitcoin, ethereum e litecoin."
+ },
+ "cancel": {
+ "message": "Cancella"
+ },
+ "classicInterface": {
+ "message": "Usa l'interfaccia classica"
+ },
+ "clickCopy": {
+ "message": "Clicca per Copiare"
+ },
+ "confirm": {
+ "message": "Conferma"
+ },
+ "confirmContract": {
+ "message": "Conferma Contratto"
+ },
+ "confirmPassword": {
+ "message": "Conferma Password"
+ },
+ "confirmTransaction": {
+ "message": "Conferma Transazione"
+ },
+ "continue": {
+ "message": "Continua"
+ },
+ "continueToCoinbase": {
+ "message": "Continua su Coinbase"
+ },
+ "contractDeployment": {
+ "message": "Distribuzione Contratto"
+ },
+ "conversionProgress": {
+ "message": "Conversione in corso"
+ },
+ "copiedButton": {
+ "message": "Copiato"
+ },
+ "copiedClipboard": {
+ "message": "Copiato negli Appunti"
+ },
+ "copiedExclamation": {
+ "message": "Copiato!"
+ },
+ "copiedSafe": {
+ "message": "Le ho copiate in un posto sicuro"
+ },
+ "copy": {
+ "message": "Copia"
+ },
+ "copyToClipboard": {
+ "message": "Copia negli appunti"
+ },
+ "copyButton": {
+ "message": " Copia "
+ },
+ "copyPrivateKey": {
+ "message": "Questa è la tua chiave privata (clicca per copiare)"
+ },
+ "create": {
+ "message": "Crea"
+ },
+ "createAccount": {
+ "message": "Crea Account"
+ },
+ "createDen": {
+ "message": "Crea"
+ },
+ "crypto": {
+ "message": "Crypto",
+ "description": "Tipo di exchange (cryptomonete)"
+ },
+ "currentConversion": {
+ "message": "Cambio Corrente"
+ },
+ "currentNetwork": {
+ "message": "Rete Corrente"
+ },
+ "customGas": {
+ "message": "Personalizza Gas"
+ },
+ "customize": {
+ "message": "Personalizza"
+ },
+ "customRPC": {
+ "message": "RPC Personalizzata"
+ },
+ "decimalsMustZerotoTen": {
+ "message": "Il numero di decimali deve essere almeno 0, e non oltre 36."
+ },
+ "decimal": {
+ "message": "Precisione Decimali"
+ },
+ "defaultNetwork": {
+ "message": "La rete predefinita per transazioni in Ether è la Rete Ethereum Principale."
+ },
+ "denExplainer": {
+ "message": "Il DEN è il tuo archivio crittato con password dentro Metamask."
+ },
+ "deposit": {
+ "message": "Deposita"
+ },
+ "depositBTC": {
+ "message": "Deposita i tuoi BTC all'indirizzo sotto:"
+ },
+ "depositCoin": {
+ "message": "Deposita $1 all'indirizzo sotto",
+ "description": "Dice all'utente quale moneta ha selezionato per depositare con Shapeshift"
+ },
+ "depositEth": {
+ "message": "Deposita Eth"
+ },
+ "depositEther": {
+ "message": "Deposita Ether"
+ },
+ "depositFiat": {
+ "message": "Deposita con moneta Fiat"
+ },
+ "depositFromAccount": {
+ "message": "Deposita da un altro account"
+ },
+ "depositShapeShift": {
+ "message": "Deposita con ShapeShift"
+ },
+ "depositShapeShiftExplainer": {
+ "message": "Se possiedi altre criptomonete, puoi scambiare e depositare Ether direttamente nel tuo portafoglio MetaMask. Nessun account richiesto."
+ },
+ "details": {
+ "message": "Dettagli"
+ },
+ "directDeposit": {
+ "message": "Deposito Diretto"
+ },
+ "directDepositEther": {
+ "message": "Deposita Direttamente Ether"
+ },
+ "directDepositEtherExplainer": {
+ "message": "Se possiedi già degli Ether, questa è la via più veloce per aggiungere Ether al tuo portafoglio con un deposito diretto."
+ },
+ "done": {
+ "message": "Finito"
+ },
+ "downloadStatelogs": {
+ "message": "Scarica i log di Stato"
+ },
+ "edit": {
+ "message": "Modifica"
+ },
+ "editAccountName": {
+ "message": "Modifica Nome Account"
+ },
+ "emailUs": {
+ "message": "Mandaci una mail!"
+ },
+ "encryptNewDen": {
+ "message": "Cripta il tuo nuovo DEN"
+ },
+ "enterPassword": {
+ "message": "Inserisci password"
+ },
+ "enterPasswordConfirm": {
+ "message": "Inserisci la tua password per confermare"
+ },
+ "etherscanView": {
+ "message": "Vedi account su Etherscan"
+ },
+ "exchangeRate": {
+ "message": "Tasso di cambio"
+ },
+ "exportPrivateKey": {
+ "message": "Esporta Chiave Privata"
+ },
+ "exportPrivateKeyWarning": {
+ "message": "Esporta chiave privata a tuo rischio."
+ },
+ "failed": {
+ "message": "Fallito"
+ },
+ "fiat": {
+ "message": "FIAT",
+ "description": "Tipo di scambio"
+ },
+ "fileImportFail": {
+ "message": "Importazione file non funziona? Clicca qui!",
+ "description": "Aiuta gli utenti a importare il loro account da un file JSON"
+ },
+ "followTwitter": {
+ "message": "Seguici su Twitter"
+ },
+ "from": {
+ "message": "Da"
+ },
+ "fromToSame": {
+ "message": "Gli indirizzi Da e A non possono essere uguali"
+ },
+ "fromShapeShift": {
+ "message": "Da ShapeShift"
+ },
+ "gas": {
+ "message": "Gas",
+ "description": "Piccola indicazione del costo del gas"
+ },
+ "gasFee": {
+ "message": "Costo Gas"
+ },
+ "gasLimit": {
+ "message": "Gas Limite"
+ },
+ "gasLimitCalculation": {
+ "message": "Calcoliamo il gas limite suggerito in base al successo delle transazioni in rete."
+ },
+ "gasLimitRequired": {
+ "message": "Gas Limite Richiesto"
+ },
+ "gasLimitTooLow": {
+ "message": "Il Gas Limite deve essere almeno 21000"
+ },
+ "generatingSeed": {
+ "message": "Generando la frase seed..."
+ },
+ "gasPrice": {
+ "message": "Prezzo del Gas (GWEI)"
+ },
+ "gasPriceCalculation": {
+ "message": "Calcoliamo il gas limite suggerito in base al successo delle transazioni in rete."
+ },
+ "gasPriceRequired": {
+ "message": "Prezzo Gas Richiesto"
+ },
+ "getEther": {
+ "message": "Ottieni Ether"
+ },
+ "getEtherFromFaucet": {
+ "message": "Ottieni Get Ether da un faucet per $1",
+ "description": "Visualizza il nome della rete per il faucet Ether"
+ },
+ "greaterThanMin": {
+ "message": "deve essere maggiore o uguale a $1.",
+ "description": "aiuto per inserire un input esadecimale come decimale"
+ },
+ "here": {
+ "message": "qui",
+ "description": "per intendere -clicca qui- per maggiori informazioni (va con troubleTokenBalances)"
+ },
+ "hereList": {
+ "message": "Questa è una lista!!!!"
+ },
+ "hide": {
+ "message": "Nascondi"
+ },
+ "hideToken": {
+ "message": "Nascondi Token"
+ },
+ "hideTokenPrompt": {
+ "message": "Nascondi Token?"
+ },
+ "howToDeposit": {
+ "message": "Come vuoi depositare Ether?"
+ },
+ "holdEther": {
+ "message": "Ti permette di tenere ether & token, e serve da ponte per le applicazioni decentralizzate."
+ },
+ "import": {
+ "message": "Importa",
+ "description": "Tasto per importare un account da un file selezionato"
+ },
+ "importAccount": {
+ "message": "Importa Account"
+ },
+ "importAccountMsg": {
+ "message":" Gli account importati non saranno associati alla frase seed originariamente creata con MetaMask. Impara di più sugli account importati "
+ },
+ "importAnAccount": {
+ "message": "Importa un account"
+ },
+ "importDen": {
+ "message": "Importa un DEN Esistente"
+ },
+ "imported": {
+ "message": "Importato",
+ "description": "stato che conferma che un account è stato totalmente caricato nel portachiavi"
+ },
+ "infoHelp": {
+ "message": "Informazioni & Aiuto"
+ },
+ "insufficientFunds": {
+ "message": "Fondi non sufficienti."
+ },
+ "insufficientTokens": {
+ "message": "Token non sufficienti."
+ },
+ "invalidAddress": {
+ "message": "Indirizzo non valido"
+ },
+ "invalidAddressRecipient": {
+ "message": "Indirizzo destinatario invalido"
+ },
+ "invalidGasParams": {
+ "message": "Parametri del Gas non validi"
+ },
+ "invalidInput": {
+ "message": "Input non valido."
+ },
+ "invalidRequest": {
+ "message": "Richiesta non Valida"
+ },
+ "invalidRPC": {
+ "message": "URI RPC invalido"
+ },
+ "jsonFail": {
+ "message": "Qualcosa è andato storto. Assicurati che il file JSON sia formattato correttamente."
+ },
+ "jsonFile": {
+ "message": "File JSON",
+ "description": "formato per importare un account"
+ },
+ "kovan": {
+ "message": "Rete di test Kovan"
+ },
+ "knowledgeDataBase": {
+ "message": "Visita la nostra Knowledge Base"
+ },
+ "lessThanMax": {
+ "message": "deve essere minore o uguale a $1.",
+ "description": "aiuto per inserire un input esadecimale come decimale"
+ },
+ "likeToAddTokens": {
+ "message": "Vorresti aggiungere questi token?"
+ },
+ "limit": {
+ "message": "Limite"
+ },
+ "loading": {
+ "message": "Caricamento..."
+ },
+ "loadingTokens": {
+ "message": "Caricamento Tokens..."
+ },
+ "localhost": {
+ "message": "Localhost 8545"
+ },
+ "login": {
+ "message": "Connetti"
+ },
+ "logout": {
+ "message": "Disconnetti"
+ },
+ "loose": {
+ "message": "Libero"
+ },
+ "loweCaseWords": {
+ "message": "le frasi seed hanno solo lettere minuscole"
+ },
+ "mainnet": {
+ "message": "Rete Ethereum Principale"
+ },
+ "message": {
+ "message": "Messaggio"
+ },
+ "metamaskDescription": {
+ "message": "MetaMask è una cassaforte sicura per identità su Ethereum."
+ },
+ "min": {
+ "message": "Minimo"
+ },
+ "myAccounts": {
+ "message": "Account Miei"
+ },
+ "mustSelectOne": {
+ "message": "Devi selezionare almeno un token."
+ },
+ "needEtherInWallet": {
+ "message": "Per interagire con applicazioni decentralizzate con MetaMask, devi possedere Ether nel tuo portafoglio."
+ },
+ "needImportFile": {
+ "message": "Devi selezionare un file da importare.",
+ "description": "L'utente sta importando un account e deve aggiungere un file per continuare"
+ },
+ "needImportPassword": {
+ "message": "Dei inserire una password per il file selezionato.",
+ "description": "Password e file necessari per importare un account"
+ },
+ "negativeETH": {
+ "message": "Non puoi inviare una quantità di ETH negativa."
+ },
+ "networks": {
+ "message": "Reti"
+ },
+ "newAccount": {
+ "message": "Nuovo Account"
+ },
+ "newAccountNumberName": {
+ "message": "Account $1",
+ "description": "Nome predefinito per il prossimo account da creare nella schermata di creazione account"
+ },
+ "newContract": {
+ "message": "Nuovo Contratto"
+ },
+ "newPassword": {
+ "message": "Nuova Password (minimo 8 caratteri)"
+ },
+ "newRecipient": {
+ "message": "Nuovo Destinatario"
+ },
+ "newRPC": {
+ "message": "Nuovo URL RPC"
+ },
+ "next": {
+ "message": "Prossimo"
+ },
+ "noAddressForName": {
+ "message": "Nessun indirizzo è stato impostato per questo nome."
+ },
+ "noDeposits": {
+ "message": "Nessun deposito ricevuto"
+ },
+ "noTransactionHistory": {
+ "message": "Nessuna cronologia delle transazioni."
+ },
+ "noTransactions": {
+ "message": "Nessuna Transazione"
+ },
+ "notStarted": {
+ "message": "Non Iniziato"
+ },
+ "oldUI": {
+ "message": "Vecchia interfaccia"
+ },
+ "oldUIMessage": {
+ "message": "Sei ritornato alla vecchia interfaccia. Puoi ritornare alla nuova interfaccia tramite l'opzione nel menu a discesa in alto a destra."
+ },
+ "or": {
+ "message": "o",
+ "description": "scelta tra creare o importare un nuovo account"
+ },
+ "passwordCorrect": {
+ "message": "Assicurati che la password sia corretta."
+ },
+ "passwordMismatch": {
+ "message": "le password non corrispondono",
+ "description": "nella creazione della password, le due password all'interno dei campi non corrispondono"
+ },
+ "passwordShort": {
+ "message": "password non sufficientemente lunga",
+ "description": "nella creazione della password, la password non è lunga abbastanza"
+ },
+ "pastePrivateKey": {
+ "message": "Incolla la tua chiave privata qui:",
+ "description": "Per importare un account da una chiave privata"
+ },
+ "pasteSeed": {
+ "message": "Incolla la tua frase seed qui!"
+ },
+ "personalAddressDetected": {
+ "message": "Rilevato indirizzo personale. Inserisci l'indirizzo del contratto del token."
+ },
+ "pleaseReviewTransaction": {
+ "message": "Ricontrolla la tua transazione."
+ },
+ "privacyMsg": {
+ "message": "Politica sulla Privacy"
+ },
+ "privateKey": {
+ "message": "Chiave Privata",
+ "description": "seleziona questo tipo di file per importare un account"
+ },
+ "privateKeyWarning": {
+ "message": "Attenzione: non dire a nessuno questa chiave! Chiunque con la tua chiave privata può rubare qualsiasi moneta contenuta nel tuo account."
+ },
+ "privateNetwork": {
+ "message": "Rete Privata"
+ },
+ "qrCode": {
+ "message": "Mostra Codice QR"
+ },
+ "readdToken": {
+ "message": "Puoi aggiungere nuovamente questo token in futuro andando in “Aggiungi token” nel menu delle opzioni del tuo account."
+ },
+ "readMore": {
+ "message": "Leggi di più qui."
+ },
+ "readMore2": {
+ "message": "Leggi di più."
+ },
+ "receive": {
+ "message": "Ricevi"
+ },
+ "recipientAddress": {
+ "message": "Indirizzo Destinatario"
+ },
+ "refundAddress": {
+ "message": "Indirizzo di Rimborso"
+ },
+ "rejected": {
+ "message": "Respinta"
+ },
+ "resetAccount": {
+ "message": "Resetta Account"
+ },
+ "restoreFromSeed": {
+ "message": "Ripristina da una frase seed"
+ },
+ "required": {
+ "message": "Richiesto"
+ },
+ "retryWithMoreGas": {
+ "message": "Riprova con un prezzo del Gas maggiore qui"
+ },
+ "revealSeedWords": {
+ "message": "Rivela Frase Seed"
+ },
+ "revealSeedWordsWarning": {
+ "message": "Non ripristinare la tua frase seed in pubblico!. Queste parole possono essere usate per rubare il tuo account."
+ },
+ "revert": {
+ "message": "Annulla"
+ },
+ "rinkeby": {
+ "message": "Rete di test Rinkeby"
+ },
+ "ropsten": {
+ "message": "Rete di test Ropsten"
+ },
+ "sampleAccountName": {
+ "message": "Es: Il mio nuovo account",
+ "description": "Aiuta l'utente a capire il concetto di aggiungere un nome leggibile al loro account"
+ },
+ "save": {
+ "message": "Salva"
+ },
+ "saveAsFile": {
+ "message": "Salva come File",
+ "description": "Processo per esportare un account"
+ },
+ "saveSeedAsFile": {
+ "message": "Salva la Frase Seed come File"
+ },
+ "search": {
+ "message": "Cerca"
+ },
+ "secretPhrase": {
+ "message": "Inserisci la tua frase segreta di dodici parole per ripristinare la cassaforte."
+ },
+ "seedPhraseReq": {
+ "message": "le frasi seed sono lunghe 12 parole"
+ },
+ "select": {
+ "message": "Seleziona"
+ },
+ "selectCurrency": {
+ "message": "Seleziona Moneta"
+ },
+ "selectService": {
+ "message": "Seleziona Servizio"
+ },
+ "selectType": {
+ "message": "Seleziona Tipo"
+ },
+ "send": {
+ "message": "Invia"
+ },
+ "sendETH": {
+ "message": "Invia ETH"
+ },
+ "sendTokens": {
+ "message": "Invia Tokens"
+ },
+ "sendTokensAnywhere": {
+ "message": "Invia Tokens a chiunque abbia un account Ethereum"
+ },
+ "settings": {
+ "message": "Impostazioni"
+ },
+ "shapeshiftBuy": {
+ "message": "Compra con Shapeshift"
+ },
+ "showPrivateKeys": {
+ "message": "Mostra Chiave Privata"
+ },
+ "showQRCode": {
+ "message": "Mostra Codie QR"
+ },
+ "sign": {
+ "message": "Firma"
+ },
+ "signMessage": {
+ "message": "Firma Messaggio"
+ },
+ "signNotice": {
+ "message": "Firmare questo messaggio può avere effetti collaterali pericolosi. \nFirma messaggi da siti di cui ti fidi totalmente. \nQuesto metodo pericoloso sarà rimosso in versioni future."
+ },
+ "sigRequest": {
+ "message": "Firma Richiesta"
+ },
+ "sigRequested": {
+ "message": "Richiesta Firma"
+ },
+ "spaceBetween": {
+ "message": "ci può essere solo uno spazio tra le parole"
+ },
+ "status": {
+ "message": "Stato"
+ },
+ "stateLogs": {
+ "message": "Log di Stato"
+ },
+ "stateLogsDescription": {
+ "message": "I log di stato contengono i tuoi indirizzi pubblici e le transazioni effettuate."
+ },
+ "submit": {
+ "message": "Invia"
+ },
+ "supportCenter": {
+ "message": "Visita il nostro Centro di Supporto"
+ },
+ "symbolBetweenZeroTen": {
+ "message": "Il simbolo deve essere lungo tra 0 e 10 caratteri."
+ },
+ "takesTooLong": {
+ "message": "Ci sta mettendo troppo?"
+ },
+ "terms": {
+ "message": "Termini di Uso"
+ },
+ "testFaucet": {
+ "message": "Prova Faucet"
+ },
+ "to": {
+ "message": "A"
+ },
+ "toETHviaShapeShift": {
+ "message": "$1 a ETH via ShapeShift",
+ "description": "il sistema riempirà il tipo di deposito all'inizio del messaggio"
+ },
+ "tokenAddress": {
+ "message": "Indirizzo Token"
+ },
+ "tokenAlreadyAdded": {
+ "message": "Il token è già stato aggiunto."
+ },
+ "tokenBalance": {
+ "message": "Bilancio Token:"
+ },
+ "tokenSelection": {
+ "message": "Cerca un token o seleziona dalla lista di token più popolari."
+ },
+ "tokenSymbol": {
+ "message": "Simbolo Token"
+ },
+ "tokenWarning1": {
+ "message": "Tieni traccia dei token che hai acquistato con il tuo account MetaMask. Se hai acquistato token con un account diverso, quei token non appariranno qui."
+ },
+ "total": {
+ "message": "Totale"
+ },
+ "transactions": {
+ "message": "transazioni"
+ },
+ "transactionMemo": {
+ "message": "Promemoria Transazione (opzionale)"
+ },
+ "transactionNumber": {
+ "message": "Numero Transazione"
+ },
+ "transfers": {
+ "message": "Trasferimenti"
+ },
+ "troubleTokenBalances": {
+ "message": "Abbiamo avuto un problema a caricare il bilancio dei tuoi token. Puoi vederlo ",
+ "description": "Seguito da un link (qui) per vedere il bilancio dei token"
+ },
+ "twelveWords": {
+ "message": "Queste 12 parole sono l'unico modo per ripristinare i tuoi account MetaMask. \nSalvale in un posto sicuro e segreto."
+ },
+ "typePassword": {
+ "message": "Inserisci Password"
+ },
+ "uiWelcome": {
+ "message": "Benvenuto alla nuova interfaccia (Beta)"
+ },
+ "uiWelcomeMessage": {
+ "message": "Stai utilizzanto la nuova interfaccia di MetaMask. Guarda in giro, prova nuove funzionalità come inviare token, e facci sapere se hai dei problemi."
+ },
+ "unavailable": {
+ "message": "Non Disponibile"
+ },
+ "unknown": {
+ "message": "Sconosciuto"
+ },
+ "unknownNetwork": {
+ "message": "Rete Privata Sconosciuta"
+ },
+ "unknownNetworkId": {
+ "message": "ID rete sconosciuto"
+ },
+ "uriErrorMsg": {
+ "message": "Gli URI richiedono un prefisso HTTP/HTTPS."
+ },
+ "usaOnly": {
+ "message": "Solo USA",
+ "description": "Usare questo sito di scambio è possibile solo per persone residenti in USA."
+ },
+ "usedByClients": {
+ "message": "Usato da una varietà di clients diversi"
+ },
+ "useOldUI": {
+ "message": "Use la vecchia UI"
+ },
+ "validFileImport": {
+ "message": "Devi selezionare un file valido da importare."
+ },
+ "vaultCreated": {
+ "message": "Cassaforte Creata"
+ },
+ "viewAccount": {
+ "message": "Vedi Account"
+ },
+ "visitWebSite": {
+ "message": "Visita il nostro sito web"
+ },
+ "warning": {
+ "message": "Attenzione"
+ },
+ "welcomeBeta": {
+ "message": "Benvenuto nella Beta di MetaMask"
+ },
+ "whatsThis": {
+ "message": "Cos'è questo?"
+ },
+ "yourSigRequested": {
+ "message": "E' richiesta la tua firma"
+ },
+ "youSign": {
+ "message": "Ti stai connettendo"
+ }
+} \ No newline at end of file
diff --git a/app/_locales/ph/messages.json b/app/_locales/ph/messages.json
new file mode 100644
index 000000000..29d63be02
--- /dev/null
+++ b/app/_locales/ph/messages.json
@@ -0,0 +1,609 @@
+{
+ "accept": {
+ "message": "Tanggapin"
+ },
+ "account": {
+ "message": "Account"
+ },
+ "accountDetails": {
+ "message": "Detalye ng Account"
+ },
+ "accountName": {
+ "message": "Pangalan ng Account"
+ },
+ "address": {
+ "message": "Address"
+ },
+ "addToken": {
+ "message": "Magdagdag ng Token"
+ },
+ "amount": {
+ "message": "Halaga"
+ },
+ "amountPlusGas": {
+ "message": "Halaga + Gas"
+ },
+ "appDescription": {
+ "message": "Ethereum Browser Extension",
+ "description": "Ang deskripsyon ng application"
+ },
+ "appName": {
+ "message": "MetaMask",
+ "description": "Ang pangalan ng application"
+ },
+ "attemptingConnect": {
+ "message": "Sinusubukang kumonekta sa blockchain."
+ },
+ "available": {
+ "message": "Magagamit"
+ },
+ "back": {
+ "message": "Bumalik"
+ },
+ "balance": {
+ "message": "Balanse:"
+ },
+ "balanceIsInsufficientGas": {
+ "message": "Kulang ang balanse para sa kasalukuyang gas total"
+ },
+ "beta": {
+ "message": "BETA"
+ },
+ "betweenMinAndMax": {
+ "message": "dapat mas malaki o katumbas ng $1 at mas mababa o katumbas ng $2.",
+ "description": "helper para sa pag-input ng hex bilang decimal input"
+ },
+ "borrowDharma": {
+ "message": "Humiram sa Dharma (Beta)"
+ },
+ "buy": {
+ "message": "Bumili"
+ },
+ "buyCoinbase": {
+ "message": "Bumili sa Coinbase"
+ },
+ "buyCoinbaseExplainer": {
+ "message": "Ang Coinbase ang pinakasikat na paraan upang bumili at magbenta ng bitcoin, ethereum, at litecoin sa buong mundo."
+ },
+ "cancel": {
+ "message": "Kanselahin"
+ },
+ "clickCopy": {
+ "message": "I-click upang Makopya"
+ },
+ "confirm": {
+ "message": "Tiyakin"
+ },
+ "confirmContract": {
+ "message": "Tiyakin ang Contract"
+ },
+ "confirmPassword": {
+ "message": "Tiyakin ang Password"
+ },
+ "confirmTransaction": {
+ "message": "Tiyakin ang Transaksyon"
+ },
+ "continueToCoinbase": {
+ "message": "Magpatuloy sa Coinbase"
+ },
+ "contractDeployment": {
+ "message": "Pag-deploy ng Contract"
+ },
+ "conversionProgress": {
+ "message": "Isinasagawa ang conversion"
+ },
+ "copiedButton": {
+ "message": "Kinopya"
+ },
+ "copiedClipboard": {
+ "message": "Kinopya sa Clipboard"
+ },
+ "copiedExclamation": {
+ "message": "Kinopya!"
+ },
+ "copy": {
+ "message": "Kinopya"
+ },
+ "copyToClipboard": {
+ "message": "Kinopya sa clipboard"
+ },
+ "copyButton": {
+ "message": " Kinopya "
+ },
+ "copyPrivateKey": {
+ "message": "Ito ang iyong private key (i-click upang makopya)"
+ },
+ "create": {
+ "message": "Gumawa"
+ },
+ "createAccount": {
+ "message": "Gumawa ng Account"
+ },
+ "createDen": {
+ "message": "Gumawa"
+ },
+ "crypto": {
+ "message": "Crypto",
+ "description": "Type ng exchange (cryptocurrencies)"
+ },
+ "customGas": {
+ "message": "I-customize ang Gas"
+ },
+ "customize": {
+ "message": "I-customize"
+ },
+ "customRPC": {
+ "message": "Custom RPC"
+ },
+ "defaultNetwork": {
+ "message": "Ang default network para sa Ether transactions ay ang Main Net."
+ },
+ "denExplainer": {
+ "message": "Ang iyong DEN ang nagsisilbing password-encrypted storage mo sa loob ng MetaMask."
+ },
+ "deposit": {
+ "message": "Deposito"
+ },
+ "depositBTC": {
+ "message": "I-deposito ang iyong BTC sa address na ito:"
+ },
+ "depositCoin": {
+ "message": "I-deposito ang iyong $1 sa address na ito",
+ "description": "Sinasabihan ang user kung ano ang coin na kanilang pinili para I-deposito gamit ang shapeshift"
+ },
+ "depositEth": {
+ "message": "I-deposito ang Eth"
+ },
+ "depositEther": {
+ "message": "I-deposito ang Ether"
+ },
+ "depositFiat": {
+ "message": "I-deposito ang Fiat"
+ },
+ "depositFromAccount": {
+ "message": "I-deposito mula sa ibang account"
+ },
+ "depositShapeShift": {
+ "message": "I-deposito gamit ang ShapeShift"
+ },
+ "depositShapeShiftExplainer": {
+ "message": "Kung ikaw ay nagmamay-ari ng iba pang cryptocurrencies, pwede kang mag-trade at mag-deposito ng Ether diretso sa iyong MetaMask wallet. Hindi mo na kailangan ng account."
+ },
+ "details": {
+ "message": "Detalye"
+ },
+ "directDeposit": {
+ "message": "Direktang Deposito"
+ },
+ "directDepositEther": {
+ "message": "Direktang I-deposito ang Ether"
+ },
+ "directDepositEtherExplainer": {
+ "message": "Kung ika ay mayroon nang Ether, ang pinakamabilis na paraan upang makuha ang Ether sa iyong bagong wallet ay sa pamamagitan ng direktang deposito."
+ },
+ "done": {
+ "message": "Tapos na"
+ },
+ "edit": {
+ "message": "I-edit"
+ },
+ "editAccountName": {
+ "message": "I-edit ang Pangalang ng Account"
+ },
+ "encryptNewDen": {
+ "message": "I-encrypt ang iyong bagong DEN"
+ },
+ "enterPassword": {
+ "message": "I-enter ang password"
+ },
+ "etherscanView": {
+ "message": "Tingnan ang account sa Etherscan"
+ },
+ "exchangeRate": {
+ "message": "Exchange Rate"
+ },
+ "exportPrivateKey": {
+ "message": "I-export ang Private Key"
+ },
+ "exportPrivateKeyWarning": {
+ "message": "I-export ang private keys at intindihin ang panganib na kasama nito."
+ },
+ "failed": {
+ "message": "Nabigo"
+ },
+ "fiat": {
+ "message": "FIAT",
+ "description": "Type ng exchange"
+ },
+ "fileImportFail": {
+ "message": "Hindi gumagana ang file import? I-click ito!",
+ "description": "Tinutulungan ang user na i-import ang kanilang account mula sa JSON file"
+ },
+ "from": {
+ "message": "Mula sa"
+ },
+ "fromShapeShift": {
+ "message": "Mula sa ShapeShift"
+ },
+ "gas": {
+ "message": "Gas",
+ "description": "Maikling indikasyon ng gas cost"
+ },
+ "gasFee": {
+ "message": "Gas Fee"
+ },
+ "gasLimit": {
+ "message": "Gas Limit"
+ },
+ "gasLimitCalculation": {
+ "message": "Kinalkula namin ang iminungkahing gas limit base sa network success rates."
+ },
+ "gasLimitRequired": {
+ "message": "Kailangan ang Gas Limit"
+ },
+ "gasLimitTooLow": {
+ "message": "Ang gas limit ay hindi dabat bababa sa 21000"
+ },
+ "gasPrice": {
+ "message": "Gas Price (GWEI)"
+ },
+ "gasPriceCalculation": {
+ "message": "Kinalkula namin ang iminungkahing gas prices base sa network success rates."
+ },
+ "gasPriceRequired": {
+ "message": "Kailangan ang Gas Price"
+ },
+ "getEther": {
+ "message": "Kumuha ng Ether"
+ },
+ "getEtherFromFaucet": {
+ "message": "Kumuha ng Ether mula sa faucet para sa $1",
+ "description": "Ipinapakita ang pangalan ng network para sa Ether faucet"
+ },
+ "greaterThanMin": {
+ "message": "dapat mas malaki o katumbas ng $1.",
+ "description": "helper para sa pag-input ng hex bilang decimal input"
+ },
+ "here": {
+ "message": "i-click ito",
+ "description": "tulad ng -i-click dito- para sa mas maraming impormasyon (kasama ng troubleTokenBalances)"
+ },
+ "hide": {
+ "message": "Itago"
+ },
+ "hideToken": {
+ "message": "Itago ang Token"
+ },
+ "hideTokenPrompt": {
+ "message": "Itago ang Token?"
+ },
+ "howToDeposit": {
+ "message": "Paano mo gustong mag-deposito ng Ether?"
+ },
+ "import": {
+ "message": "I-import",
+ "description": "Button para i-import ang account mula sa napiling file"
+ },
+ "importAccount": {
+ "message": "I-import ang Account"
+ },
+ "importAnAccount": {
+ "message": "I-import ang account"
+ },
+ "importDen": {
+ "message": "I-import ang Existing DEN"
+ },
+ "imported": {
+ "message": "Na-import na",
+ "description": "status na nagpapakita na ang account ay lubos na na-load sa keyring"
+ },
+ "infoHelp": {
+ "message": "Impormasyon at Tulong"
+ },
+ "invalidAddress": {
+ "message": "Invalid ang address"
+ },
+ "invalidGasParams": {
+ "message": "Invalid ang Gas Parameters"
+ },
+ "invalidInput": {
+ "message": "Invalid ang input."
+ },
+ "invalidRequest": {
+ "message": "Invalid ang Request"
+ },
+ "jsonFile": {
+ "message": "JSON File",
+ "description": "format para sa pag-import ng account"
+ },
+ "kovan": {
+ "message": "Kovan Test Network"
+ },
+ "lessThanMax": {
+ "message": "dapat mas mababa o katumbas ng $1.",
+ "description": "helper para sa pag-input ng hex bilang decimal input"
+ },
+ "limit": {
+ "message": "Limitasyon"
+ },
+ "loading": {
+ "message": "Naglo-load..."
+ },
+ "loadingTokens": {
+ "message": "Naglo-load ang Tokens..."
+ },
+ "localhost": {
+ "message": "Localhost 8545"
+ },
+ "logout": {
+ "message": "Log out"
+ },
+ "loose": {
+ "message": "Loose"
+ },
+ "mainnet": {
+ "message": "Main Ethereum Network"
+ },
+ "message": {
+ "message": "Mensahe"
+ },
+ "min": {
+ "message": "Minimum"
+ },
+ "myAccounts": {
+ "message": "Aking mga Account"
+ },
+ "needEtherInWallet": {
+ "message": "Upang makipag-ugnayan sa decentralized applications gamit ang MetaMask, kakailanganin mo ng Ether sa iyong wallet."
+ },
+ "needImportFile": {
+ "message": "Dapat kang pumili ng file para i-import.",
+ "description": "Ang user ay nag-iimport ng account at kailangan magdagdag ng file upang tumuloy"
+ },
+ "needImportPassword": {
+ "message": "Dapat mong i-enter ang password para sa napiling file.",
+ "description": "Password at file na kailangan upang ma-import ang account"
+ },
+ "networks": {
+ "message": "Networks"
+ },
+ "newAccount": {
+ "message": "Bagong Account"
+ },
+ "newAccountNumberName": {
+ "message": "Account $1",
+ "description": "Ang default na pangalan ng susunod na account na gagawin sa create account screen"
+ },
+ "newContract": {
+ "message": "Bagong Contract"
+ },
+ "newPassword": {
+ "message": "Bagong Password (min 8 chars)"
+ },
+ "newRecipient": {
+ "message": "Bagong Recipient"
+ },
+ "next": {
+ "message": "Sunod"
+ },
+ "noAddressForName": {
+ "message": "Walang naka-set na address para sa pangalang ito."
+ },
+ "noDeposits": {
+ "message": "Walang natanggap na mga deposito"
+ },
+ "noTransactionHistory": {
+ "message": "Walang kasaysayan ng transaksyon."
+ },
+ "noTransactions": {
+ "message": "Walang mga Transaksyon"
+ },
+ "notStarted": {
+ "message": "Hindi Sinimulan"
+ },
+ "oldUI": {
+ "message": "Lumang UI"
+ },
+ "oldUIMessage": {
+ "message": "Ikaw ay bumalik sa lumang UI. Maaari kang bumalik sa bagong UI mula sa isang opsyon sa dropdown menu na matatagpuan sa bandang taas at kanan."
+ },
+ "or": {
+ "message": "o",
+ "description": "Pagpili sa pagitan ng paggawa of pag-import ng bagong account"
+ },
+ "passwordMismatch": {
+ "message": "hindi nagtugma ang mga password",
+ "description": "Sa proseso ng paggawa ng password, ang dalawang password fields ay hindi nagtugma"
+ },
+ "passwordShort": {
+ "message": "hindi sapat ang haba ng password",
+ "description": "Sa proseso ng paggawa ng password, ang password ay hindi in password creation process, hind sapat ang haba ng password upang maging ligtas"
+ },
+ "pastePrivateKey": {
+ "message": "I-paste dito ang iyong private key string:",
+ "description": "Para sa pag-import ng account mula sa private key"
+ },
+ "pasteSeed": {
+ "message": "I-paste dito ang iyong seed phrase!"
+ },
+ "pleaseReviewTransaction": {
+ "message": "Mangyaring suriin ang iyong transaksyon."
+ },
+ "privateKey": {
+ "message": "Private Key",
+ "description": "Piliin ang ganitong type ng file upang gamitin sa pag-import ng account"
+ },
+ "privateKeyWarning": {
+ "message": "Babala: Huwag sabihin sa kahit na sino ang key na ito. Maaring makuha at manakaw ng sinumang nakakaalam ng iyong private key ang mga assets sa iyong account."
+ },
+ "privateNetwork": {
+ "message": "Pribadong Network"
+ },
+ "qrCode": {
+ "message": "Ipakita ang QR Code"
+ },
+ "readdToken": {
+ "message": "Upang muling idagdag ang token na ito, pumunta sa “Magdagdag ng Token” sa options menu ng iyong account."
+ },
+ "readMore": {
+ "message": "Alamin ang iba pang impormasyon dito."
+ },
+ "receive": {
+ "message": "Tanggapin"
+ },
+ "recipientAddress": {
+ "message": "Address ng Tatanggap"
+ },
+ "refundAddress": {
+ "message": "Ang Iyong Refund Address"
+ },
+ "rejected": {
+ "message": "Tinanggihan"
+ },
+ "required": {
+ "message": "Kailangan"
+ },
+ "retryWithMoreGas": {
+ "message": "Muling subukan ng may mas mataas na gas price dito"
+ },
+ "revert": {
+ "message": "Ibalik"
+ },
+ "rinkeby": {
+ "message": "Rinkeby Test Network"
+ },
+ "ropsten": {
+ "message": "Ropsten Test Network"
+ },
+ "sampleAccountName": {
+ "message": "Halimbawa: Ang aking bagong account",
+ "description": "Tulungan ang user na intindihin ang konsepto ng pagdagdag ng human-readable name sa kanilang account"
+ },
+ "save": {
+ "message": "I-save"
+ },
+ "saveAsFile": {
+ "message": "I-save bilang File",
+ "description": "Proseso sa pag-export ng Account"
+ },
+ "selectService": {
+ "message": "Piliin ang Service"
+ },
+ "send": {
+ "message": "Magpadala"
+ },
+ "sendTokens": {
+ "message": "Magpadala ng Tokens"
+ },
+ "sendTokensAnywhere": {
+ "message": "Magpadala ng Tokens sa sinumang may Ethereum account"
+ },
+ "settings": {
+ "message": "Mga Setting"
+ },
+ "shapeshiftBuy": {
+ "message": "Bumili gamit ang Shapeshift"
+ },
+ "showPrivateKeys": {
+ "message": "Ipakita ang Private Keys"
+ },
+ "showQRCode": {
+ "message": "Ipakita ang QR Code"
+ },
+ "sign": {
+ "message": "I-sign"
+ },
+ "signMessage": {
+ "message": "I-sign ang mensahe"
+ },
+ "signNotice": {
+ "message": "Ang pag-sign ng mensaheng ito ay maaring magdulot ng mapanganib na epekto. I-sign lamang ang mga mensahe mula sa mga site na pinagkakatiwalaan mo ng iyong account. Ang mapanganib na paraang ito ay aalisin sa isa sa mga susunod na bersyon. "
+ },
+ "sigRequest": {
+ "message": "Hiling na Signature"
+ },
+ "sigRequested": {
+ "message": "Hiniling ang Signature"
+ },
+ "status": {
+ "message": "Istado"
+ },
+ "submit": {
+ "message": "I-submit"
+ },
+ "takesTooLong": {
+ "message": "Masyadong matagal?"
+ },
+ "testFaucet": {
+ "message": "Test Faucet"
+ },
+ "to": {
+ "message": "To"
+ },
+ "toETHviaShapeShift": {
+ "message": "$1 sa ETH sa pamamagitan ng ShapeShift",
+ "description": "Pupunan ng system ang deposit type sa simula ng mensahe"
+ },
+ "tokenBalance": {
+ "message": "Ang iyong Token Balance ay:"
+ },
+ "total": {
+ "message": "Kabuuan"
+ },
+ "transactionMemo": {
+ "message": "Memo ng transaksyon (opsyonal)"
+ },
+ "transactionNumber": {
+ "message": "Numero ng Transaksyon"
+ },
+ "transfers": {
+ "message": "Mga Inilipat"
+ },
+ "troubleTokenBalances": {
+ "message": "Nagkaroon kami ng problema sa paglo-load ng iyong mga balanseng token. Tingnan ito dito ",
+ "description": "Susundan ng link (dito) para tingnan ang token balances"
+ },
+ "typePassword": {
+ "message": "I-type ang iyong Password"
+ },
+ "uiWelcome": {
+ "message": "Maligayang pagdating sa Bagong UI (Beta)"
+ },
+ "uiWelcomeMessage": {
+ "message": "Ginagamit mo na ngayon ang bagong MetaMask UI. I-explore at subukan ang mga bagong features tulad ng pagpapadala ng mga token, at ipaalam sa amin kung mayroon kang anumang mga isyu."
+ },
+ "unavailable": {
+ "message": "Hindi Magagamit"
+ },
+ "unknown": {
+ "message": "Hindi Alam"
+ },
+ "unknownNetwork": {
+ "message": "Hindi Alam ang Pribadong Network"
+ },
+ "unknownNetworkId": {
+ "message": "Hindi alam ang network ID"
+ },
+ "usaOnly": {
+ "message": "USA lamang",
+ "description": "Ang paggamit ng exchange na ito ay limitado sa mga tao sa loob ng Estados Unidos"
+ },
+ "usedByClients": {
+ "message": "Ginagamit ng iba't ibang mga clients"
+ },
+ "viewAccount": {
+ "message": "Tingnan ang Account"
+ },
+ "warning": {
+ "message": "Babala"
+ },
+ "whatsThis": {
+ "message": "Ano ito?"
+ },
+ "yourSigRequested": {
+ "message": "Hinihiling ang iyong signature"
+ },
+ "youSign": {
+ "message": "Ikaw ay nagsa-sign"
+ }
+}
diff --git a/app/_locales/pt/messages.json b/app/_locales/pt/messages.json
new file mode 100644
index 000000000..c9eb178f9
--- /dev/null
+++ b/app/_locales/pt/messages.json
@@ -0,0 +1,819 @@
+{
+ "accept": {
+ "message": "Aceitar"
+ },
+ "account": {
+ "message": "Conta"
+ },
+ "accountDetails": {
+ "message": "Detalhes da Conta"
+ },
+ "accountName": {
+ "message": "Nome da Conta"
+ },
+ "address": {
+ "message": "Endereço"
+ },
+ "addCustomToken": {
+ "message": "Adicionar token customizada"
+ },
+ "addToken": {
+ "message": "Adicionar Token"
+ },
+ "addTokens": {
+ "message": "Adicionar Tokens"
+ },
+ "amount": {
+ "message": "Valor"
+ },
+ "amountPlusGas": {
+ "message": "Valor + Gas"
+ },
+ "appDescription": {
+ "message": "Extensão para o browser de Ethereum",
+ "description": "A descrição da aplicação"
+ },
+ "appName": {
+ "message": "MetaMask",
+ "description": "Nome da aplicação"
+ },
+ "attemptingConnect": {
+ "message": "A tentar ligar à blockchain."
+ },
+ "attributions": {
+ "message": "Atribuições"
+ },
+ "available": {
+ "message": "Disponível"
+ },
+ "back": {
+ "message": "Voltar"
+ },
+ "balance": {
+ "message": "Saldo:"
+ },
+ "balances": {
+ "message": "O meu saldo"
+ },
+ "balanceIsInsufficientGas": {
+ "message": "Saldo insuficiente para a quantidade de gas total"
+ },
+ "beta": {
+ "message": "BETA"
+ },
+ "betweenMinAndMax": {
+ "message": "tem de ser maior ou igual a $1 e menor ou igual a $2.",
+ "description": "ajuda para introduzir hexadecimal como decimal"
+ },
+ "blockiesIdenticon": {
+ "message": "Usar Blockies Identicon"
+ },
+ "borrowDharma": {
+ "message": "Pedir Empréstimo Com Dharma (Beta)"
+ },
+ "builtInCalifornia": {
+ "message": "MetaMask é desenhada e construída na California."
+ },
+ "buy": {
+ "message": "Comprar"
+ },
+ "buyCoinbase": {
+ "message": "Comprar no Coinbase"
+ },
+ "buyCoinbaseExplainer": {
+ "message": "Coinbase é a forma mais conhecida para comprar e vender bitcoin, ethereum, e litecoin."
+ },
+ "cancel": {
+ "message": "Cancelar"
+ },
+ "classicInterface": {
+ "message": "Utilizar interface clássico"
+ },
+ "clickCopy": {
+ "message": "Carregue para copiar"
+ },
+ "confirm": {
+ "message": "Confirmar"
+ },
+ "confirmContract": {
+ "message": "Confirmar Contrato"
+ },
+ "confirmPassword": {
+ "message": "Confirmar Palavra-passe"
+ },
+ "confirmTransaction": {
+ "message": "Confirmar Transação"
+ },
+ "continue": {
+ "message": "Continuar"
+ },
+ "continueToCoinbase": {
+ "message": "Continuar para o Coinbase"
+ },
+ "contractDeployment": {
+ "message": "Distribuição do Contrato"
+ },
+ "conversionProgress": {
+ "message": "Conversão em progresso"
+ },
+ "copiedButton": {
+ "message": "Copiado"
+ },
+ "copiedClipboard": {
+ "message": "Copiado para a Área de Transferência"
+ },
+ "copiedExclamation": {
+ "message": "Copiado!"
+ },
+ "copiedSafe": {
+ "message": "Já copiei para um lugar seguro"
+ },
+ "copy": {
+ "message": "Copiar"
+ },
+ "copyToClipboard": {
+ "message": "Copiar para o clipboard"
+ },
+ "copyButton": {
+ "message": " Copiar "
+ },
+ "copyPrivateKey": {
+ "message": "Esta é a sua chave privada (carregue para copiar)"
+ },
+ "create": {
+ "message": "Criar"
+ },
+ "createAccount": {
+ "message": "Criar Conta"
+ },
+ "createDen": {
+ "message": "Criar"
+ },
+ "crypto": {
+ "message": "Cripto",
+ "description": "Tipo de câmbio (criptomoedas)"
+ },
+ "currentConversion": {
+ "message": "Taxa de Conversão Atual"
+ },
+ "currentNetwork": {
+ "message": "Rede Atual"
+ },
+ "customGas": {
+ "message": "Customizar Gas"
+ },
+ "customize": {
+ "message": "Customizar"
+ },
+ "customRPC": {
+ "message": "Customizar RPC"
+ },
+ "decimalsMustZerotoTen": {
+ "message": "Decimais devem ser no mínimo 0 e não passar de 36."
+ },
+ "decimal": {
+ "message": "Precisão em Decimais"
+ },
+ "defaultNetwork": {
+ "message": "A rede pré definida para transações em Ether é a Main Net."
+ },
+ "denExplainer": {
+ "message": " DEN é o armazenamento encriptado da sua palavra-passe no MetaMask."
+ },
+ "deposit": {
+ "message": "Depósito"
+ },
+ "depositBTC": {
+ "message": "Deposite as suas BTC no endereço abaixo:"
+ },
+ "depositCoin": {
+ "message": "Deposite $1 no endereço abaixo",
+ "description": "Diz ao usuário que moeda selecionou para depositar com shapeshift"
+ },
+ "depositEth": {
+ "message": "Depositar Eth"
+ },
+ "depositEther": {
+ "message": "Depositar Ether"
+ },
+ "depositFiat": {
+ "message": "Depositar moeda fiduciária"
+ },
+ "depositFromAccount": {
+ "message": "Depositar de outra conta"
+ },
+ "depositShapeShift": {
+ "message": "Depositar com ShapeShift"
+ },
+ "depositShapeShiftExplainer": {
+ "message": "Se tem criptomoedas, pode trocar e depositar Ether diretamente na sua carteira MetaMask. Não precisa de conta."
+ },
+ "details": {
+ "message": "Detalhes"
+ },
+ "directDeposit": {
+ "message": "Depósito Direto"
+ },
+ "directDepositEther": {
+ "message": "Depositar Diretamente Ether"
+ },
+ "directDepositEtherExplainer": {
+ "message": "Se já tem Ether, a forma mais rápida de ficar com Ether na sua carteira é através de depósito direto."
+ },
+ "done": {
+ "message": "Finalizado"
+ },
+ "downloadStatelogs": {
+ "message": "Descarregar Registos de Estado"
+ },
+ "edit": {
+ "message": "Editar"
+ },
+ "editAccountName": {
+ "message": "Editar Nome da Conta"
+ },
+ "emailUs": {
+ "message": "Fale connosco!"
+ },
+ "encryptNewDen": {
+ "message": "Encripte o seu novo DEN"
+ },
+ "enterPassword": {
+ "message": "Introduza palavra-passe"
+ },
+ "enterPasswordConfirm": {
+ "message": "Introduza a sua palavra-passe para confirmar"
+ },
+ "etherscanView": {
+ "message": "Ver conta no Etherscan"
+ },
+ "exchangeRate": {
+ "message": "Taxa de Câmbio"
+ },
+ "exportPrivateKey": {
+ "message": "Exportar Chave Privada"
+ },
+ "exportPrivateKeyWarning": {
+ "message": "Exportar chaves privadas por sua conta e risco."
+ },
+ "failed": {
+ "message": "Falhou"
+ },
+ "fiat": {
+ "message": "FIAT",
+ "description": "Tipo de câmbio"
+ },
+ "fileImportFail": {
+ "message": "A importação de ficheiro não está a funcionar? Carregue aqui!",
+ "description": "Ajuda usuários a importar as suas contas a partir de um ficheiro JSON"
+ },
+ "followTwitter": {
+ "message": "Siga-nos no Twitter"
+ },
+ "from": {
+ "message": "De"
+ },
+ "fromToSame": {
+ "message": "Endereços De e Para não podem ser iguais"
+ },
+ "fromShapeShift": {
+ "message": "De ShapeShift"
+ },
+ "gas": {
+ "message": "Gas",
+ "description": "Indicação breve do custo de gas"
+ },
+ "gasFee": {
+ "message": "Taxa de Gas"
+ },
+ "gasLimit": {
+ "message": "Limite de Gas"
+ },
+ "gasLimitCalculation": {
+ "message": "Calculamos o limite sugerido do gas com base nas taxas de sucesso da rede."
+ },
+ "gasLimitRequired": {
+ "message": "Limite de Gas Necessário"
+ },
+ "gasLimitTooLow": {
+ "message": "Limite de Gas deve ser no mínimo 21000"
+ },
+ "generatingSeed": {
+ "message": "A gerar Seed..."
+ },
+ "gasPrice": {
+ "message": "Preço Gas (GWEI)"
+ },
+ "gasPriceCalculation": {
+ "message": "Calculamos o gas sugerido com base nas taxas de sucesso da rede."
+ },
+ "gasPriceRequired": {
+ "message": "Preço Gas Necessário"
+ },
+ "getEther": {
+ "message": "Obter Ether"
+ },
+ "getEtherFromFaucet": {
+ "message": "Obter Ether de um faucet por $1",
+ "description": "Mostra nome da rede para faucet de Ether"
+ },
+ "greaterThanMin": {
+ "message": "tem de ser maior ou igual a $1.",
+ "description": "ajuda para introduzir hexadecimal como decimal"
+ },
+ "here": {
+ "message": "aqui",
+ "description": "como -clicar aqui- para mais informações (associado a troubleTokenBalances)"
+ },
+ "hereList": {
+ "message": "Aqui está uma lista!!!!"
+ },
+ "hide": {
+ "message": "Ocultar"
+ },
+ "hideToken": {
+ "message": "Ocultar Token"
+ },
+ "hideTokenPrompt": {
+ "message": "Ocultar Token?"
+ },
+ "howToDeposit": {
+ "message": "Como gostaria de depositar Ether?"
+ },
+ "holdEther": {
+ "message": "Permite ter ether & tokens, e serve como uma ponte para aplicações descentralizadas."
+ },
+ "import": {
+ "message": "Importar",
+ "description": "Botão para importar uma conta de um ficheiro selecionado"
+ },
+ "importAccount": {
+ "message": "Importar Conta"
+ },
+ "importAccountMsg": {
+ "message":"Contas importadas não irão ser associadas com a frase seed da conta criada originalmente pelo MetaMask. Saiba mais sobre contas importadas."
+ },
+ "importAnAccount": {
+ "message": "Importar uma conta"
+ },
+ "importDen": {
+ "message": "Importar DEN Existente"
+ },
+ "imported": {
+ "message": "Importado",
+ "description": "estado para mostrar que uma conta foi totalmente carregada para o keyring"
+ },
+ "infoHelp": {
+ "message": "Informação & Ajuda"
+ },
+ "insufficientFunds": {
+ "message": "Fundos insuficientes."
+ },
+ "insufficientTokens": {
+ "message": "Tokens insuficientes."
+ },
+ "invalidAddress": {
+ "message": "Endereço inválido"
+ },
+ "invalidAddressRecipient": {
+ "message": "O endereço do destinatário é inválido "
+ },
+ "invalidGasParams": {
+ "message": "Parâmetros para o Gas Inválidos"
+ },
+ "invalidInput": {
+ "message": "Campo inválido."
+ },
+ "invalidRequest": {
+ "message": "Pedido Inválido"
+ },
+ "invalidRPC": {
+ "message": "RPC URI Inválido"
+ },
+ "jsonFail": {
+ "message": "Ocorreu um erro. Por favor confirme que o seu ficheiro JSON está devidamente formatado."
+ },
+ "jsonFile": {
+ "message": "Ficheiro JSON",
+ "description": "Formatar para importar uma conta"
+ },
+ "kovan": {
+ "message": "Rede de Teste Kovan"
+ },
+ "knowledgeDataBase": {
+ "message": "Visite o nosso Centro de Conhecimento"
+ },
+ "lessThanMax": {
+ "message": "tem de ser menor ou igual a $1.",
+ "description": "ajuda para introduzir hexadecimal como decimal"
+ },
+ "likeToAddTokens": {
+ "message": "Gostaria de adicionar estes tokens?"
+ },
+ "limit": {
+ "message": "Limite"
+ },
+ "loading": {
+ "message": "A carregar..."
+ },
+ "loadingTokens": {
+ "message": "A carregar Tokens..."
+ },
+ "localhost": {
+ "message": "Localhost 8545"
+ },
+ "login": {
+ "message": "Entrar"
+ },
+ "logout": {
+ "message": "Sair"
+ },
+ "loose": {
+ "message": "Vago"
+ },
+ "loweCaseWords": {
+ "message": "palavras da seed apenas têm caracteres minúsculos"
+ },
+ "mainnet": {
+ "message": "Rede Principal de Ethereum"
+ },
+ "message": {
+ "message": "Mensagem"
+ },
+ "metamaskDescription": {
+ "message": "O MetaMask é um lugar seguro para guardar a sua identidade em em Ethereum."
+ },
+ "min": {
+ "message": "Mínimo"
+ },
+ "myAccounts": {
+ "message": "As minhas contas"
+ },
+ "mustSelectOne": {
+ "message": "Deve escolher no mínimo 1 token."
+ },
+ "needEtherInWallet": {
+ "message": "Para interagir com applicações descentralizadas usando MetaMask tem de ter Ether na sua carteira."
+ },
+ "needImportFile": {
+ "message": "Deve selecionar um ficheiro para importar.",
+ "description": "O utilizador deve adicionar um ficheiro para continuar"
+ },
+ "needImportPassword": {
+ "message": "Deve introduzir uma palavra-passe para o ficheiro selecionado.",
+ "description": "Palavra-passe e ficheiro necessários para importar uma conta"
+ },
+ "negativeETH": {
+ "message": "Não é possível enviar valores negativos de ETH."
+ },
+ "networks": {
+ "message": "Redes"
+ },
+ "newAccount": {
+ "message": "Conta Nova"
+ },
+ "newAccountNumberName": {
+ "message": "Conta $1",
+ "description": "Nome padrão da próxima conta a ser criado em Criar Conta"
+ },
+ "newContract": {
+ "message": "Contrato Novo"
+ },
+ "newPassword": {
+ "message": "Nova Palavra-passe (min 8 caracteres)"
+ },
+ "newRecipient": {
+ "message": "Recipiente Novo"
+ },
+ "newRPC": {
+ "message": "Novo RPC URL"
+ },
+ "next": {
+ "message": "Próximo"
+ },
+ "noAddressForName": {
+ "message": "Nenhum endereço foi estabelecido para este nome."
+ },
+ "noDeposits": {
+ "message": "Sem depósitos recebidos"
+ },
+ "noTransactionHistory": {
+ "message": "Sem histórico de transações."
+ },
+ "noTransactions": {
+ "message": "Sem Transações"
+ },
+ "notStarted": {
+ "message": "Não Iniciado"
+ },
+ "oldUI": {
+ "message": "UI Antigo"
+ },
+ "oldUIMessage": {
+ "message": "Voltou para o UI antigo. Pode reverter para o Novo UI através da opção no menu do topo direito."
+ },
+ "or": {
+ "message": "ou",
+ "description": "opção entre criar ou importar uma nova conta"
+ },
+ "passwordCorrect": {
+ "message": "Por favor confirme que a sua palavra-passe esteja correta."
+ },
+ "passwordMismatch": {
+ "message": "as palavras-passe não coincidem",
+ "description": "no processo de criação da palavra-passe, as duas palavras-passe não coincidiram"
+ },
+ "passwordShort": {
+ "message": "palavra-passe deve ser mais comprida",
+ "description": "no processo de criação da palavra-passe, a palavra-apasse não é longa o suficiente para ser segura"
+ },
+ "pastePrivateKey": {
+ "message": "Cole aqui a sua chave privada:",
+ "description": "Para importar uma conta através da chave privada"
+ },
+ "pasteSeed": {
+ "message": "Cole aqui a sua frase seed!"
+ },
+ "personalAddressDetected": {
+ "message": "Endereço pessoal detectado. Introduza o endereço do contrato do token."
+ },
+ "pleaseReviewTransaction": {
+ "message": "Por favor reveja a sua transação."
+ },
+ "privacyMsg": {
+ "message": "Política de Privacidade"
+ },
+ "privateKey": {
+ "message": "Chave Privada",
+ "description": "Selecione este tipo de ficheiro para importar uma conta"
+ },
+ "privateKeyWarning": {
+ "message": "Atenção: Nunca revele esta chave. Qualquer pessoa com acesso à sua chave privada pode roubar os bens que esta contém."
+ },
+ "privateNetwork": {
+ "message": "Rede Privada"
+ },
+ "qrCode": {
+ "message": "Mostrar Código QR"
+ },
+ "readdToken": {
+ "message": "Pode adicionar este token de novo clicando na opção “Adicionar token” no menu de opções da sua conta."
+ },
+ "readMore": {
+ "message": "Ler mais aqui."
+ },
+ "readMore2": {
+ "message": "Ler mais."
+ },
+ "receive": {
+ "message": "Receber"
+ },
+ "recipientAddress": {
+ "message": "Endereço do Destinatário"
+ },
+ "refundAddress": {
+ "message": "O seu endereço de reembolso"
+ },
+ "rejected": {
+ "message": "Rejeitado"
+ },
+ "resetAccount": {
+ "message": "Reinicializar Conta"
+ },
+ "restoreFromSeed": {
+ "message": "Restaurar a partir da frase seed"
+ },
+ "required": {
+ "message": "Necessário"
+ },
+ "retryWithMoreGas": {
+ "message": "Tentar novamente com um preço mais elevado aqui"
+ },
+ "revealSeedWords": {
+ "message": "Revelar Palavras Seed"
+ },
+ "revealSeedWordsWarning": {
+ "message": "Não revele as palavras seed num espaço público! Estas palavras podem ser usadas para roubar todas as suas contas."
+ },
+ "revert": {
+ "message": "Reverter"
+ },
+ "rinkeby": {
+ "message": "Rede de Teste Rinkeby"
+ },
+ "ropsten": {
+ "message": "Rede de Teste Ropsten"
+ },
+ "sampleAccountName": {
+ "message": "Ex. A minha conta nova",
+ "description": "Ajuda o utilizador a perceber o conceito de adicionar um nome legível à sua conta"
+ },
+ "save": {
+ "message": "Guardar"
+ },
+ "saveAsFile": {
+ "message": "Guardar como Ficheiro",
+ "description": "Processo de exportação de conta"
+ },
+ "saveSeedAsFile": {
+ "message": "Guardar Palavras Seed como um Ficheiro"
+ },
+ "search": {
+ "message": "Procurar"
+ },
+ "secretPhrase": {
+ "message": "Introduza a sua frase secreta de 12 palavras para recuperar o seu ."
+ },
+ "seedPhraseReq": {
+ "message": "seed phrases are 12 words long"
+ },
+ "select": {
+ "message": "Selecionar"
+ },
+ "selectCurrency": {
+ "message": "Selecionar Moeda"
+ },
+ "selectService": {
+ "message": "Selecionar Serviço"
+ },
+ "selectType": {
+ "message": "Selecionar Tipo"
+ },
+ "send": {
+ "message": "Enviar"
+ },
+ "sendETH": {
+ "message": "Enviar ETH"
+ },
+ "sendTokens": {
+ "message": "Enviar Tokens"
+ },
+ "sendTokensAnywhere": {
+ "message": "Enviar Tokens para qualquer pessoa com uma conta Ethereum"
+ },
+ "settings": {
+ "message": "Definições"
+ },
+ "shapeshiftBuy": {
+ "message": "Comprar com Shapeshift"
+ },
+ "showPrivateKeys": {
+ "message": "Mostrar Chaves Privadas"
+ },
+ "showQRCode": {
+ "message": "Mostrar Código QR"
+ },
+ "sign": {
+ "message": "Assinar"
+ },
+ "signMessage": {
+ "message": "Assinar Mensagem"
+ },
+ "signNotice": {
+ "message": "Assinar esta mensagem pode ter \nefeitos laterais perigosos. Apenas assine mensagens de sites que \ntotalmente confia com a sua conta total.\n Este método perigoso será removido numa versão posterior."
+ },
+ "sigRequest": {
+ "message": "Pedido de Assinatura"
+ },
+ "sigRequested": {
+ "message": "Assinatura Pedida"
+ },
+ "spaceBetween": {
+ "message": "só pode haver um espaço entre palavras"
+ },
+ "status": {
+ "message": "Estado"
+ },
+ "stateLogs": {
+ "message": "Registos de Estado"
+ },
+ "stateLogsDescription": {
+ "message": "Registo de estado podem conter o seu endereço e transações enviadas da sua conta pública."
+ },
+ "submit": {
+ "message": "Submeter"
+ },
+ "supportCenter": {
+ "message": "Visitar o nosso Centro de Suporte"
+ },
+ "symbolBetweenZeroTen": {
+ "message": "Símbolo deve conter entre 0 e 10 characters."
+ },
+ "takesTooLong": {
+ "message": "A demorar muito?"
+ },
+ "terms": {
+ "message": "Termos de Uso"
+ },
+ "testFaucet": {
+ "message": "Faucet de Teste"
+ },
+ "to": {
+ "message": "Para"
+ },
+ "toETHviaShapeShift": {
+ "message": "$1 para ETH via ShapeShift",
+ "description": "o sistema irá preencher o tipo de depósito no início da mensagem"
+ },
+ "tokenAddress": {
+ "message": "Endereço do Token"
+ },
+ "tokenAlreadyAdded": {
+ "message": "Token já foi adicionado."
+ },
+ "tokenBalance": {
+ "message": "O seu balanço é:"
+ },
+ "tokenSelection": {
+ "message": "Procure por tokens ou seleccione da nossa lista de tokens populares."
+ },
+ "tokenSymbol": {
+ "message": "Símbolo do Token"
+ },
+ "tokenWarning1": {
+ "message": "Registe os tokens que comprou com a sua conta MetaMask. Se comprou tokens utilizando uma conta diferente, esses tokens não irão aparecer aqui."
+ },
+ "total": {
+ "message": "Total"
+ },
+ "transactions": {
+ "message": "transações"
+ },
+ "transactionMemo": {
+ "message": "Notas da transação (opcional)"
+ },
+ "transactionNumber": {
+ "message": "Número da Transação"
+ },
+ "transfers": {
+ "message": "Transferências"
+ },
+ "troubleTokenBalances": {
+ "message": "Tivemos um problema a carregar o balanço dos seus tokens. Pode vê-los em ",
+ "description": "Seguido de um link (aqui) para ver o balanço dos seus tokens"
+ },
+ "twelveWords": {
+ "message": "Estas 12 palavras são a única forma de recuperar as suas contas na MetaMask.\nGuarde-as num local seguro e secreto."
+ },
+ "typePassword": {
+ "message": "Digite a sua Palavra-passe"
+ },
+ "uiWelcome": {
+ "message": "Bem-vindo ao seu Novo UI (Beta)"
+ },
+ "uiWelcomeMessage": {
+ "message": "Está agora a usar o novo UI da MetaMask. Dê uma vista de olhos, experimenta as novas funcionalidades como enviar tokens e diga-nos se tiver algum problema."
+ },
+ "unavailable": {
+ "message": "Indisponível"
+ },
+ "unknown": {
+ "message": "Desconhecido"
+ },
+ "unknownNetwork": {
+ "message": "Rede Privada Desconhecida"
+ },
+ "unknownNetworkId": {
+ "message": "Identificador da rede desconhecido"
+ },
+ "uriErrorMsg": {
+ "message": "Links requerem o prefixo HTTP/HTTPS apropriado."
+ },
+ "usaOnly": {
+ "message": "Só nos EUA",
+ "description": "Usar esta taxa de câmbio está limitado a pessoas residentes nos EUA"
+ },
+ "usedByClients": {
+ "message": "Utilizado por vários tipos de clientes"
+ },
+ "useOldUI": {
+ "message": "Utilizar UI antigo"
+ },
+ "validFileImport": {
+ "message": "Deve selecionar um ficheiro válido para importar."
+ },
+ "vaultCreated": {
+ "message": "Cofre Criado"
+ },
+ "viewAccount": {
+ "message": "Ver Conta"
+ },
+ "visitWebSite": {
+ "message": "Visite o nosso site"
+ },
+ "warning": {
+ "message": "Aviso"
+ },
+ "welcomeBeta": {
+ "message": "Bem-vindo ao MetaMask Beta"
+ },
+ "whatsThis": {
+ "message": "O que é isto?"
+ },
+ "yourSigRequested": {
+ "message": "A sua assinatura está a ser pedida"
+ },
+ "youSign": {
+ "message": "Está a assinar"
+ }
+}
diff --git a/app/scripts/controllers/transactions.js b/app/scripts/controllers/transactions.js
index 9c2ca0dc8..3e3909361 100644
--- a/app/scripts/controllers/transactions.js
+++ b/app/scripts/controllers/transactions.js
@@ -6,7 +6,6 @@ const EthQuery = require('ethjs-query')
const TransactionStateManager = require('../lib/tx-state-manager')
const TxGasUtil = require('../lib/tx-gas-utils')
const PendingTransactionTracker = require('../lib/pending-tx-tracker')
-const createId = require('../lib/random-id')
const NonceTracker = require('../lib/nonce-tracker')
/*
@@ -92,8 +91,8 @@ module.exports = class TransactionController extends EventEmitter {
this.pendingTxTracker.on('tx:warning', (txMeta) => {
this.txStateManager.updateTx(txMeta, 'transactions/pending-tx-tracker#event: tx:warning')
})
+ this.pendingTxTracker.on('tx:confirmed', (txId) => this._markNonceDuplicatesDropped(txId))
this.pendingTxTracker.on('tx:failed', this.txStateManager.setTxStatusFailed.bind(this.txStateManager))
- this.pendingTxTracker.on('tx:confirmed', this.txStateManager.setTxStatusConfirmed.bind(this.txStateManager))
this.pendingTxTracker.on('tx:block-update', (txMeta, latestBlockNumber) => {
if (!txMeta.firstRetryBlockNumber) {
txMeta.firstRetryBlockNumber = latestBlockNumber
@@ -186,14 +185,7 @@ module.exports = class TransactionController extends EventEmitter {
// validate
await this.txGasUtil.validateTxParams(txParams)
// construct txMeta
- const txMeta = {
- id: createId(),
- time: (new Date()).getTime(),
- status: 'unapproved',
- metamaskNetworkId: this.getNetwork(),
- txParams: txParams,
- loadingDefaults: true,
- }
+ const txMeta = this.txStateManager.generateTxMeta({txParams})
this.addTx(txMeta)
this.emit('newUnapprovedTx', txMeta)
// add default tx params
@@ -215,7 +207,6 @@ module.exports = class TransactionController extends EventEmitter {
const txParams = txMeta.txParams
// ensure value
txMeta.gasPriceSpecified = Boolean(txParams.gasPrice)
- txMeta.nonceSpecified = Boolean(txParams.nonce)
let gasPrice = txParams.gasPrice
if (!gasPrice) {
gasPrice = this.getGasPrice ? this.getGasPrice() : await this.query.gasPrice()
@@ -226,11 +217,17 @@ module.exports = class TransactionController extends EventEmitter {
return await this.txGasUtil.analyzeGasUsage(txMeta)
}
- async retryTransaction (txId) {
- this.txStateManager.setTxStatusUnapproved(txId)
- const txMeta = this.txStateManager.getTx(txId)
- txMeta.lastGasPrice = txMeta.txParams.gasPrice
- this.txStateManager.updateTx(txMeta, 'retryTransaction: manual retry')
+ async retryTransaction (originalTxId) {
+ const originalTxMeta = this.txStateManager.getTx(originalTxId)
+ const lastGasPrice = originalTxMeta.txParams.gasPrice
+ const txMeta = this.txStateManager.generateTxMeta({
+ txParams: originalTxMeta.txParams,
+ lastGasPrice,
+ loadingDefaults: false,
+ })
+ this.addTx(txMeta)
+ this.emit('newUnapprovedTx', txMeta)
+ return txMeta
}
async updateTransaction (txMeta) {
@@ -253,11 +250,9 @@ module.exports = class TransactionController extends EventEmitter {
// wait for a nonce
nonceLock = await this.nonceTracker.getNonceLock(fromAddress)
// add nonce to txParams
- const nonce = txMeta.nonceSpecified ? txMeta.txParams.nonce : nonceLock.nextNonce
- if (nonce > nonceLock.nextNonce) {
- const message = `Specified nonce may not be larger than account's next valid nonce.`
- throw new Error(message)
- }
+ // if txMeta has lastGasPrice then it is a retry at same nonce with higher
+ // gas price transaction and their for the nonce should not be calculated
+ const nonce = txMeta.lastGasPrice ? txMeta.txParams.nonce : nonceLock.nextNonce
txMeta.txParams.nonce = ethUtil.addHexPrefix(nonce.toString(16))
// add nonce debugging information to txMeta
txMeta.nonceDetails = nonceLock.nonceDetails
@@ -314,6 +309,22 @@ module.exports = class TransactionController extends EventEmitter {
// PRIVATE METHODS
//
+ _markNonceDuplicatesDropped (txId) {
+ this.txStateManager.setTxStatusConfirmed(txId)
+ // get the confirmed transactions nonce and from address
+ const txMeta = this.txStateManager.getTx(txId)
+ const { nonce, from } = txMeta.txParams
+ const sameNonceTxs = this.txStateManager.getFilteredTxList({nonce, from})
+ if (!sameNonceTxs.length) return
+ // mark all same nonce transactions as dropped and give i a replacedBy hash
+ sameNonceTxs.forEach((otherTxMeta) => {
+ if (otherTxMeta.id === txId) return
+ otherTxMeta.replacedBy = txMeta.hash
+ this.txStateManager.updateTx(txMeta, 'transactions/pending-tx-tracker#event: tx:confirmed reference to confirmed txHash with same nonce')
+ this.txStateManager.setTxStatusDropped(otherTxMeta.id)
+ })
+ }
+
_updateMemstore () {
const unapprovedTxs = this.txStateManager.getUnapprovedTxList()
const selectedAddressTxList = this.txStateManager.getFilteredTxList({
diff --git a/app/scripts/lib/tx-state-manager.js b/app/scripts/lib/tx-state-manager.js
index 2eb006380..ad07c813f 100644
--- a/app/scripts/lib/tx-state-manager.js
+++ b/app/scripts/lib/tx-state-manager.js
@@ -1,9 +1,21 @@
const extend = require('xtend')
const EventEmitter = require('events')
const ObservableStore = require('obs-store')
+const createId = require('./random-id')
const ethUtil = require('ethereumjs-util')
const txStateHistoryHelper = require('./tx-state-history-helper')
+// STATUS METHODS
+ // statuses:
+ // - `'unapproved'` the user has not responded
+ // - `'rejected'` the user has responded no!
+ // - `'approved'` the user has approved the tx
+ // - `'signed'` the tx is signed
+ // - `'submitted'` the tx is sent to a server
+ // - `'confirmed'` the tx has been included in a block.
+ // - `'failed'` the tx failed for some reason, included on tx data.
+ // - `'dropped'` the tx nonce was already used
+
module.exports = class TransactionStateManager extends EventEmitter {
constructor ({ initState, txHistoryLimit, getNetwork }) {
super()
@@ -16,6 +28,16 @@ module.exports = class TransactionStateManager extends EventEmitter {
this.getNetwork = getNetwork
}
+ generateTxMeta (opts) {
+ return extend({
+ id: createId(),
+ time: (new Date()).getTime(),
+ status: 'unapproved',
+ metamaskNetworkId: this.getNetwork(),
+ loadingDefaults: true,
+ }, opts)
+ }
+
// Returns the number of txs for the current network.
getTxCount () {
return this.getTxList().length
@@ -164,16 +186,6 @@ module.exports = class TransactionStateManager extends EventEmitter {
})
}
- // STATUS METHODS
- // statuses:
- // - `'unapproved'` the user has not responded
- // - `'rejected'` the user has responded no!
- // - `'approved'` the user has approved the tx
- // - `'signed'` the tx is signed
- // - `'submitted'` the tx is sent to a server
- // - `'confirmed'` the tx has been included in a block.
- // - `'failed'` the tx failed for some reason, included on tx data.
-
// get::set status
// should return the status of the tx.
@@ -202,7 +214,11 @@ module.exports = class TransactionStateManager extends EventEmitter {
}
// should update the status of the tx to 'submitted'.
+ // and add a time stamp for when it was called
setTxStatusSubmitted (txId) {
+ const txMeta = this.getTx(txId)
+ txMeta.submittedTime = (new Date()).getTime()
+ this.updateTx(txMeta, 'txStateManager - add submitted time stamp')
this._setTxStatus(txId, 'submitted')
}
@@ -211,6 +227,12 @@ module.exports = class TransactionStateManager extends EventEmitter {
this._setTxStatus(txId, 'confirmed')
}
+ // should update the status dropped
+ setTxStatusDropped (txId) {
+ this._setTxStatus(txId, 'dropped')
+ }
+
+
setTxStatusFailed (txId, err) {
const txMeta = this.getTx(txId)
txMeta.err = {
diff --git a/development/states/confirm-new-ui.json b/development/states/confirm-new-ui.json
index 6ea8e64cd..6981781a9 100644
--- a/development/states/confirm-new-ui.json
+++ b/development/states/confirm-new-ui.json
@@ -116,7 +116,7 @@
"send": {
"gasLimit": "0xea60",
"gasPrice": "0xba43b7400",
- "gasTotal": "0xb451dc41b578",
+ "gasTotal": "0xaa87bee538000",
"tokenBalance": null,
"from": {
"address": "0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb",
diff --git a/development/states/send-edit.json b/development/states/send-edit.json
index 6ea8e64cd..6981781a9 100644
--- a/development/states/send-edit.json
+++ b/development/states/send-edit.json
@@ -116,7 +116,7 @@
"send": {
"gasLimit": "0xea60",
"gasPrice": "0xba43b7400",
- "gasTotal": "0xb451dc41b578",
+ "gasTotal": "0xaa87bee538000",
"tokenBalance": null,
"from": {
"address": "0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb",
diff --git a/development/verify-locale-strings.js b/development/verify-locale-strings.js
new file mode 100644
index 000000000..b8fe5a7dc
--- /dev/null
+++ b/development/verify-locale-strings.js
@@ -0,0 +1,96 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// Locale verification script
+//
+// usage:
+//
+// node app/scripts/verify-locale-strings.js <locale>
+//
+// will check the given locale against the strings in english
+//
+////////////////////////////////////////////////////////////////////////////////
+
+var fs = require('fs')
+var path = require('path')
+
+console.log('Locale Verification')
+
+var locale = process.argv[2]
+if (!locale || locale == '') {
+ console.log('Must enter a locale as argument. exitting')
+ process.exit(1)
+}
+
+console.log("verifying for locale " + locale)
+
+localeFilePath = path.join(process.cwd(), 'app', '_locales', locale, 'messages.json')
+try {
+ localeObj = JSON.parse(fs.readFileSync(localeFilePath, 'utf8'));
+} catch (e) {
+ if(e.code == 'ENOENT') {
+ console.log('Locale file not found')
+ } else {
+ console.log('Error opening your locale file: ', e)
+ }
+ process.exit(1)
+}
+
+englishFilePath = path.join(process.cwd(), 'app', '_locales', 'en', 'messages.json')
+try {
+ englishObj = JSON.parse(fs.readFileSync(englishFilePath, 'utf8'));
+} catch (e) {
+ if(e.code == 'ENOENT') {
+ console.log("English File not found")
+ } else {
+ console.log("Error opening english locale file: ", e)
+ }
+ process.exit(1)
+}
+
+console.log('\tverifying whether all your locale strings are contained in the english one')
+
+var counter = 0
+var foundErrorA = false
+var notFound = [];
+Object.keys(localeObj).forEach(function(key){
+ if (!englishObj[key]) {
+ foundErrorA = true
+ notFound.push(key)
+ }
+ counter++
+})
+
+if (foundErrorA) {
+ console.log('\nThe following string(s) is(are) not found in the english locale:')
+ notFound.forEach(function(key) {
+ console.log(key)
+ })
+} else {
+ console.log('\tall ' + counter +' strings declared in your locale were found in the english one')
+}
+
+console.log('\n\tverifying whether your locale contains all english strings')
+
+var counter = 0
+var foundErrorB = false
+var notFound = [];
+Object.keys(englishObj).forEach(function(key){
+ if (!localeObj[key]) {
+ foundErrorB = true
+ notFound.push(key)
+ }
+ counter++
+})
+
+if (foundErrorB) {
+ console.log('\nThe following string(s) is(are) not found in the your locale:')
+ notFound.forEach(function(key) {
+ console.log(key)
+ })
+} else {
+ console.log('\tall ' + counter +' english strings were found in your locale!')
+}
+
+if (!foundErrorA && !foundErrorB) {
+ console.log('You are good to go')
+} \ No newline at end of file
diff --git a/gulpfile.js b/gulpfile.js
index adfb148a9..dbbb1e4ff 100644
--- a/gulpfile.js
+++ b/gulpfile.js
@@ -408,7 +408,11 @@ function bundleTask(opts) {
.pipe(gulpif(debug, sourcemaps.init({ loadMaps: true })))
// Minification
.pipe(gulpif(opts.isBuild, uglify({
- mangle: { reserved: [ 'MetamaskInpageProvider' ] },
+ mangle: { reserved: [ 'MetamaskInpageProvider' ] },
+ })))
+ // Transpile to ES5
+ .pipe(gulpif(opts.isBuild, babel({
+ presets: ['env']
})))
// writes .map file
.pipe(gulpif(debug, sourcemaps.write('./')))
diff --git a/old-ui/app/components/transaction-list-item.js b/old-ui/app/components/transaction-list-item.js
index e7251df8d..7ab3414e5 100644
--- a/old-ui/app/components/transaction-list-item.js
+++ b/old-ui/app/components/transaction-list-item.js
@@ -29,9 +29,16 @@ function TransactionListItem () {
}
TransactionListItem.prototype.showRetryButton = function () {
- const { transaction = {} } = this.props
- const { status, time } = transaction
- return status === 'submitted' && Date.now() - time > 30000
+ const { transaction = {}, transactions } = this.props
+ const { status, submittedTime, txParams } = transaction
+ const currentNonce = txParams.nonce
+ const currentNonceTxs = transactions.filter(tx => tx.txParams.nonce === currentNonce)
+ const currentNonceSubmittedTxs = currentNonceTxs.filter(tx => tx.status === 'submitted')
+ const lastSubmittedTxWithCurrentNonce = currentNonceSubmittedTxs[0]
+ const currentTxIsLatestWithNonce = lastSubmittedTxWithCurrentNonce
+ && lastSubmittedTxWithCurrentNonce.id === transaction.id
+
+ return currentTxIsLatestWithNonce && Date.now() - submittedTime > 30000
}
TransactionListItem.prototype.render = function () {
@@ -201,6 +208,11 @@ function formatDate (date) {
function renderErrorOrWarning (transaction) {
const { status, err, warning } = transaction
+ // show dropped
+ if (status === 'dropped') {
+ return h('span.dropped', ' (Dropped)')
+ }
+
// show rejected
if (status === 'rejected') {
return h('span.error', ' (Rejected)')
diff --git a/old-ui/app/components/transaction-list.js b/old-ui/app/components/transaction-list.js
index 345e3ca16..c77852921 100644
--- a/old-ui/app/components/transaction-list.js
+++ b/old-ui/app/components/transaction-list.js
@@ -62,7 +62,7 @@ TransactionList.prototype.render = function () {
}
return h(TransactionListItem, {
transaction, i, network, key,
- conversionRate,
+ conversionRate, transactions,
showTx: (txId) => {
this.props.viewPendingTx(txId)
},
diff --git a/old-ui/app/css/index.css b/old-ui/app/css/index.css
index 67c327f62..7af713336 100644
--- a/old-ui/app/css/index.css
+++ b/old-ui/app/css/index.css
@@ -247,6 +247,10 @@ app sections
color: #FFAE00;
}
+.dropped {
+ color: #6195ED;
+}
+
.lock {
width: 50px;
height: 50px;
diff --git a/package.json b/package.json
index 00587ece6..8f05bc7f1 100644
--- a/package.json
+++ b/package.json
@@ -10,9 +10,10 @@
"mock": "beefy development/mock-dev.js:bundle.js --live --open --index=./development/index.html --cwd ./",
"watch": "mocha watch --recursive \"test/unit/**/*.js\"",
"mascara": "gulp build && cross-env METAMASK_DEBUG=true node ./mascara/example/server",
- "dist": "npm run dist:clear && npm install && gulp dist",
+ "dist": "npm run dist:clear && npm install && gulp dist && npm run test:es5",
"dist:clear": "rm -rf node_modules/eth-contract-metadata && rm -rf node_modules/eth-phishing-detect",
"test": "npm run lint && npm run test:coverage && npm run test:integration",
+ "test:es5": "es-check es5 ./dist/**/*.js",
"test:unit": "cross-env METAMASK_ENV=test mocha --exit --require babel-core/register --require test/helper.js --recursive \"test/unit/**/*.js\"",
"test:single": "cross-env METAMASK_ENV=test mocha --require test/helper.js",
"test:integration": "npm run test:integration:build && npm run test:flat && npm run test:mascara",
@@ -25,7 +26,7 @@
"test:flat:build:states": "node development/genStates.js",
"test:flat:build:ui": "npm run test:flat:build:states && browserify ./development/mock-dev.js -o ./development/bundle.js",
"test:mascara": "npm run test:mascara:build && karma start test/mascara.conf.js",
- "test:mascara:build": "mkdir -p dist/mascara && npm run test:mascara:build:ui && npm run test:mascara:build:background && npm run test:mascara:build:tests",
+ "test:mascara:build": "mkdirp dist/mascara && npm run test:mascara:build:ui && npm run test:mascara:build:background && npm run test:mascara:build:tests",
"test:mascara:build:ui": "browserify mascara/test/test-ui.js -o dist/mascara/ui.js",
"test:mascara:build:background": "browserify mascara/src/background.js -o dist/mascara/background.js",
"test:mascara:build:tests": "browserify test/integration/lib/first-time.js -o dist/mascara/tests.js",
@@ -200,6 +201,7 @@
"envify": "^4.0.0",
"enzyme": "^3.3.0",
"enzyme-adapter-react-15": "^1.0.5",
+ "es-check": "^2.0.2",
"eslint-plugin-chai": "0.0.1",
"eslint-plugin-mocha": "^4.9.0",
"eslint-plugin-react": "^7.4.0",
diff --git a/test/integration/lib/send-new-ui.js b/test/integration/lib/send-new-ui.js
index 594f5f0b0..573faaee3 100644
--- a/test/integration/lib/send-new-ui.js
+++ b/test/integration/lib/send-new-ui.js
@@ -93,7 +93,7 @@ async function runSendFlowTest(assert, done) {
'send gas field should show estimated gas total converted to USD'
)
- const sendGasOpenCustomizeModalButton = await queryAsync($, '.send-v2__sliders-icon-container')
+ const sendGasOpenCustomizeModalButton = await queryAsync($, '.sliders-icon-container')
sendGasOpenCustomizeModalButton[0].click()
const customizeGasModal = await queryAsync($, '.send-v2__customize-gas')
@@ -135,9 +135,9 @@ async function runSendFlowTest(assert, done) {
assert.equal(confirmToName[0].textContent, 'Send Account 3', 'confirm screen should show correct to name')
const confirmScreenRows = await queryAsync($, '.confirm-screen-rows')
- const confirmScreenGas = confirmScreenRows.find('.confirm-screen-row-info')[2]
- assert.equal(confirmScreenGas.textContent, '3.6 USD', 'confirm screen should show correct gas')
- const confirmScreenTotal = confirmScreenRows.find('.confirm-screen-row-info')[3]
+ const confirmScreenGas = confirmScreenRows.find('.currency-display__converted-value')[0]
+ assert.equal(confirmScreenGas.textContent, '3.60 USD', 'confirm screen should show correct gas')
+ const confirmScreenTotal = confirmScreenRows.find('.confirm-screen-row-info')[2]
assert.equal(confirmScreenTotal.textContent, '2405.36 USD', 'confirm screen should show correct total')
const confirmScreenBackButton = await queryAsync($, '.confirm-screen-back-button')
diff --git a/test/unit/tx-controller-test.js b/test/unit/tx-controller-test.js
index cc99afee4..712097fce 100644
--- a/test/unit/tx-controller-test.js
+++ b/test/unit/tx-controller-test.js
@@ -392,6 +392,49 @@ describe('Transaction Controller', function () {
})
})
+ describe('#retryTransaction', function () {
+ it('should create a new txMeta with the same txParams as the original one', function (done) {
+ let txParams = {
+ nonce: '0x00',
+ from: '0xB09d8505E1F4EF1CeA089D47094f5DD3464083d4',
+ to: '0xB09d8505E1F4EF1CeA089D47094f5DD3464083d4',
+ data: '0x0',
+ }
+ txController.txStateManager._saveTxList([
+ { id: 1, status: 'submitted', metamaskNetworkId: currentNetworkId, txParams },
+ ])
+ txController.retryTransaction(1)
+ .then((txMeta) => {
+ assert.equal(txMeta.txParams.nonce, txParams.nonce, 'nonce should be the same')
+ assert.equal(txMeta.txParams.from, txParams.from, 'from should be the same')
+ assert.equal(txMeta.txParams.to, txParams.to, 'to should be the same')
+ assert.equal(txMeta.txParams.data, txParams.data, 'data should be the same')
+ assert.ok(('lastGasPrice' in txMeta), 'should have the key `lastGasPrice`')
+ assert.equal(txController.txStateManager.getTxList().length, 2)
+ done()
+ }).catch(done)
+ })
+ })
+
+ describe('#_markNonceDuplicatesDropped', function () {
+ it('should mark all nonce duplicates as dropped without marking the confirmed transaction as dropped', function () {
+ txController.txStateManager._saveTxList([
+ { id: 1, status: 'confirmed', metamaskNetworkId: currentNetworkId, history: [{}], txParams: { nonce: '0x01' } },
+ { id: 2, status: 'submitted', metamaskNetworkId: currentNetworkId, history: [{}], txParams: { nonce: '0x01' } },
+ { id: 3, status: 'submitted', metamaskNetworkId: currentNetworkId, history: [{}], txParams: { nonce: '0x01' } },
+ { id: 4, status: 'submitted', metamaskNetworkId: currentNetworkId, history: [{}], txParams: { nonce: '0x01' } },
+ { id: 5, status: 'submitted', metamaskNetworkId: currentNetworkId, history: [{}], txParams: { nonce: '0x01' } },
+ { id: 6, status: 'submitted', metamaskNetworkId: currentNetworkId, history: [{}], txParams: { nonce: '0x01' } },
+ { id: 7, status: 'submitted', metamaskNetworkId: currentNetworkId, history: [{}], txParams: { nonce: '0x01' } },
+ ])
+ txController._markNonceDuplicatesDropped(1)
+ const confirmedTx = txController.txStateManager.getTx(1)
+ const droppedTxs = txController.txStateManager.getFilteredTxList({ nonce: '0x01', status: 'dropped' })
+ assert.equal(confirmedTx.status, 'confirmed', 'the confirmedTx should remain confirmed')
+ assert.equal(droppedTxs.length, 6, 'their should be 6 dropped txs')
+
+ })
+ })
describe('#getPendingTransactions', function () {
beforeEach(function () {
@@ -401,7 +444,7 @@ describe('Transaction Controller', function () {
{ id: 3, status: 'approved', metamaskNetworkId: currentNetworkId, txParams: {} },
{ id: 4, status: 'signed', metamaskNetworkId: currentNetworkId, txParams: {} },
{ id: 5, status: 'submitted', metamaskNetworkId: currentNetworkId, txParams: {} },
- { id: 6, status: 'confimed', metamaskNetworkId: currentNetworkId, txParams: {} },
+ { id: 6, status: 'confirmed', metamaskNetworkId: currentNetworkId, txParams: {} },
{ id: 7, status: 'failed', metamaskNetworkId: currentNetworkId, txParams: {} },
])
})
diff --git a/ui/app/actions.js b/ui/app/actions.js
index 092af080b..bc7ee3d07 100644
--- a/ui/app/actions.js
+++ b/ui/app/actions.js
@@ -1278,8 +1278,10 @@ function retryTransaction (txId) {
if (err) {
return dispatch(actions.displayWarning(err.message))
}
+ const { selectedAddressTxList } = newState
+ const { id: newTxId } = selectedAddressTxList[selectedAddressTxList.length - 1]
dispatch(actions.updateMetamaskState(newState))
- dispatch(actions.viewPendingTx(txId))
+ dispatch(actions.viewPendingTx(newTxId))
})
}
}
diff --git a/ui/app/components/customize-gas-modal/index.js b/ui/app/components/customize-gas-modal/index.js
index 920dfeab6..d8384c19d 100644
--- a/ui/app/components/customize-gas-modal/index.js
+++ b/ui/app/components/customize-gas-modal/index.js
@@ -22,12 +22,14 @@ const {
conversionUtil,
multiplyCurrencies,
conversionGreaterThan,
+ conversionMax,
subtractCurrencies,
} = require('../../conversion-util')
const {
getGasPrice,
getGasLimit,
+ getForceGasMin,
conversionRateSelector,
getSendAmount,
getSelectedToken,
@@ -45,6 +47,7 @@ function mapStateToProps (state) {
return {
gasPrice: getGasPrice(state),
gasLimit: getGasLimit(state),
+ forceGasMin: getForceGasMin(state),
conversionRate,
amount: getSendAmount(state),
maxModeOn: getSendMaxModeState(state),
@@ -115,9 +118,9 @@ CustomizeGasModal.prototype.save = function (gasPrice, gasLimit, gasTotal) {
updateSendAmount(maxAmount)
}
- updateGasPrice(gasPrice)
- updateGasLimit(gasLimit)
- updateGasTotal(gasTotal)
+ updateGasPrice(ethUtil.addHexPrefix(gasPrice))
+ updateGasLimit(ethUtil.addHexPrefix(gasLimit))
+ updateGasTotal(ethUtil.addHexPrefix(gasTotal))
hideModal()
}
@@ -218,7 +221,7 @@ CustomizeGasModal.prototype.convertAndSetGasPrice = function (newGasPrice) {
}
CustomizeGasModal.prototype.render = function () {
- const { hideModal } = this.props
+ const { hideModal, forceGasMin } = this.props
const { gasPrice, gasLimit, gasTotal, error, priceSigZeros, priceSigDec } = this.state
let convertedGasPrice = conversionUtil(gasPrice, {
@@ -230,6 +233,22 @@ CustomizeGasModal.prototype.render = function () {
convertedGasPrice += convertedGasPrice.match(/[.]/) ? priceSigZeros : `${priceSigDec}${priceSigZeros}`
+ let newGasPrice = gasPrice
+ if (forceGasMin) {
+ const convertedMinPrice = conversionUtil(forceGasMin, {
+ fromNumericBase: 'hex',
+ toNumericBase: 'dec',
+ })
+ convertedGasPrice = conversionMax(
+ { value: convertedMinPrice, fromNumericBase: 'dec' },
+ { value: convertedGasPrice, fromNumericBase: 'dec' }
+ )
+ newGasPrice = conversionMax(
+ { value: gasPrice, fromNumericBase: 'hex' },
+ { value: forceGasMin, fromNumericBase: 'hex' }
+ )
+ }
+
const convertedGasLimit = conversionUtil(gasLimit, {
fromNumericBase: 'hex',
toNumericBase: 'dec',
@@ -252,7 +271,7 @@ CustomizeGasModal.prototype.render = function () {
h(GasModalCard, {
value: convertedGasPrice,
- min: MIN_GAS_PRICE_GWEI,
+ min: forceGasMin || MIN_GAS_PRICE_GWEI,
// max: 1000,
step: multiplyCurrencies(MIN_GAS_PRICE_GWEI, 10),
onChange: value => this.convertAndSetGasPrice(value),
@@ -288,7 +307,7 @@ CustomizeGasModal.prototype.render = function () {
}, [t('cancel')]),
h(`div.send-v2__customize-gas__save${error ? '__error' : ''}.allcaps`, {
- onClick: () => !error && this.save(gasPrice, gasLimit, gasTotal),
+ onClick: () => !error && this.save(newGasPrice, gasLimit, gasTotal),
}, [t('save')]),
]),
diff --git a/ui/app/components/pending-tx/confirm-send-ether.js b/ui/app/components/pending-tx/confirm-send-ether.js
index 908df3671..f36def9d5 100644
--- a/ui/app/components/pending-tx/confirm-send-ether.js
+++ b/ui/app/components/pending-tx/confirm-send-ether.js
@@ -8,7 +8,12 @@ const Identicon = require('../identicon')
const ethUtil = require('ethereumjs-util')
const BN = ethUtil.BN
const hexToBn = require('../../../../app/scripts/lib/hex-to-bn')
-const { conversionUtil, addCurrencies } = require('../../conversion-util')
+const {
+ conversionUtil,
+ addCurrencies,
+ multiplyCurrencies,
+} = require('../../conversion-util')
+const GasFeeDisplay = require('../send/gas-fee-display-v2')
const t = require('../../../i18n')
const { MIN_GAS_PRICE_HEX } = require('../send/send-constants')
@@ -44,6 +49,7 @@ function mapDispatchToProps (dispatch) {
to,
value: amount,
} = txParams
+
dispatch(actions.updateSend({
gasLimit,
gasPrice,
@@ -56,6 +62,29 @@ function mapDispatchToProps (dispatch) {
dispatch(actions.showSendPage())
},
cancelTransaction: ({ id }) => dispatch(actions.cancelTx({ id })),
+ showCustomizeGasModal: (txMeta, sendGasLimit, sendGasPrice, sendGasTotal) => {
+ const { id, txParams, lastGasPrice } = txMeta
+ const { gas: txGasLimit, gasPrice: txGasPrice } = txParams
+
+ let forceGasMin
+ if (lastGasPrice) {
+ forceGasMin = ethUtil.addHexPrefix(multiplyCurrencies(lastGasPrice, 1.1, {
+ multiplicandBase: 16,
+ multiplierBase: 10,
+ toNumericBase: 'hex',
+ fromDenomination: 'WEI',
+ }))
+ }
+
+ dispatch(actions.updateSend({
+ gasLimit: sendGasLimit || txGasLimit,
+ gasPrice: sendGasPrice || txGasPrice,
+ editingTransactionId: id,
+ gasTotal: sendGasTotal,
+ forceGasMin,
+ }))
+ dispatch(actions.showModal({ name: 'CUSTOMIZE_GAS' }))
+ },
}
}
@@ -140,6 +169,7 @@ ConfirmSendEther.prototype.getGasFee = function () {
return {
FIAT,
ETH,
+ gasFeeInHex: txFeeBn.toString(16),
}
}
@@ -147,7 +177,7 @@ ConfirmSendEther.prototype.getData = function () {
const { identities } = this.props
const txMeta = this.gatherTxMeta()
const txParams = txMeta.txParams || {}
- const { FIAT: gasFeeInFIAT, ETH: gasFeeInETH } = this.getGasFee()
+ const { FIAT: gasFeeInFIAT, ETH: gasFeeInETH, gasFeeInHex } = this.getGasFee()
const { FIAT: amountInFIAT, ETH: amountInETH } = this.getAmount()
const totalInFIAT = addCurrencies(gasFeeInFIAT, amountInFIAT, {
@@ -175,11 +205,20 @@ ConfirmSendEther.prototype.getData = function () {
amountInETH,
totalInFIAT,
totalInETH,
+ gasFeeInHex,
}
}
ConfirmSendEther.prototype.render = function () {
- const { editTransaction, currentCurrency, clearSend } = this.props
+ const {
+ editTransaction,
+ currentCurrency,
+ clearSend,
+ conversionRate,
+ currentCurrency: convertedCurrency,
+ showCustomizeGasModal,
+ send: { gasTotal, gasLimit: sendGasLimit, gasPrice: sendGasPrice },
+ } = this.props
const txMeta = this.gatherTxMeta()
const txParams = txMeta.txParams || {}
@@ -193,13 +232,17 @@ ConfirmSendEther.prototype.render = function () {
name: toName,
},
memo,
- gasFeeInFIAT,
- gasFeeInETH,
+ gasFeeInHex,
amountInFIAT,
totalInFIAT,
totalInETH,
} = this.getData()
+ const title = txMeta.lastGasPrice ? 'Reprice Transaction' : 'Confirm'
+ const subtitle = txMeta.lastGasPrice
+ ? 'Increase your gas fee to attempt to overwrite and speed up your transaction'
+ : 'Please review your transaction.'
+
// This is from the latest master
// It handles some of the errors that we are not currently handling
// Leaving as comments fo reference
@@ -218,11 +261,11 @@ ConfirmSendEther.prototype.render = function () {
// Main Send token Card
h('div.page-container', [
h('div.page-container__header', [
- h('button.confirm-screen-back-button', {
+ !txMeta.lastGasPrice && h('button.confirm-screen-back-button', {
onClick: () => editTransaction(txMeta),
}, 'Edit'),
- h('div.page-container__title', 'Confirm'),
- h('div.page-container__subtitle', `Please review your transaction.`),
+ h('div.page-container__title', title),
+ h('div.page-container__subtitle', subtitle),
]),
h('.page-container__content', [
h('div.flex-row.flex-center.confirm-screen-identicons', [
@@ -286,13 +329,15 @@ ConfirmSendEther.prototype.render = function () {
h('section.flex-row.flex-center.confirm-screen-row', [
h('span.confirm-screen-label.confirm-screen-section-column', [ t('gasFee') ]),
h('div.confirm-screen-section-column', [
- h('div.confirm-screen-row-info', `${gasFeeInFIAT} ${currentCurrency.toUpperCase()}`),
-
- h('div.confirm-screen-row-detail', `${gasFeeInETH} ETH`),
+ h(GasFeeDisplay, {
+ gasTotal: gasTotal || gasFeeInHex,
+ conversionRate,
+ convertedCurrency,
+ onClick: () => showCustomizeGasModal(txMeta, sendGasLimit, sendGasPrice, gasTotal),
+ }),
]),
]),
-
h('section.flex-row.flex-center.confirm-screen-row.confirm-screen-total-box ', [
h('div.confirm-screen-section-column', [
h('span.confirm-screen-label', [ t('total') + ' ' ]),
@@ -450,6 +495,27 @@ ConfirmSendEther.prototype.gatherTxMeta = function () {
const state = this.state
const txData = clone(state.txData) || clone(props.txData)
+ const { gasPrice: sendGasPrice, gas: sendGasLimit } = props.send
+ const {
+ lastGasPrice,
+ txParams: {
+ gasPrice: txGasPrice,
+ gas: txGasLimit,
+ },
+ } = txData
+
+ let forceGasMin
+ if (lastGasPrice) {
+ forceGasMin = ethUtil.addHexPrefix(multiplyCurrencies(lastGasPrice, 1.1, {
+ multiplicandBase: 16,
+ multiplierBase: 10,
+ toNumericBase: 'hex',
+ }))
+ }
+
+ txData.txParams.gasPrice = sendGasPrice || forceGasMin || txGasPrice
+ txData.txParams.gas = sendGasLimit || txGasLimit
+
// log.debug(`UI has defaulted to tx meta ${JSON.stringify(txData)}`)
return txData
}
diff --git a/ui/app/components/pending-tx/confirm-send-token.js b/ui/app/components/pending-tx/confirm-send-token.js
index 0a4182014..ccd87c0a4 100644
--- a/ui/app/components/pending-tx/confirm-send-token.js
+++ b/ui/app/components/pending-tx/confirm-send-token.js
@@ -9,6 +9,7 @@ const actions = require('../../actions')
const t = require('../../../i18n')
const clone = require('clone')
const Identicon = require('../identicon')
+const GasFeeDisplay = require('../send/gas-fee-display-v2.js')
const ethUtil = require('ethereumjs-util')
const BN = ethUtil.BN
const {
@@ -89,6 +90,39 @@ function mapDispatchToProps (dispatch, ownProps) {
}))
dispatch(actions.showSendTokenPage())
},
+ showCustomizeGasModal: (txMeta, sendGasLimit, sendGasPrice, sendGasTotal) => {
+ const { id, txParams, lastGasPrice } = txMeta
+ const { gas: txGasLimit, gasPrice: txGasPrice } = txParams
+ const tokenData = txParams.data && abiDecoder.decodeMethod(txParams.data)
+ const { params = [] } = tokenData
+ const { value: to } = params[0] || {}
+ const { value: tokenAmountInDec } = params[1] || {}
+ const tokenAmountInHex = conversionUtil(tokenAmountInDec, {
+ fromNumericBase: 'dec',
+ toNumericBase: 'hex',
+ })
+
+ let forceGasMin
+ if (lastGasPrice) {
+ forceGasMin = ethUtil.addHexPrefix(multiplyCurrencies(lastGasPrice, 1.1, {
+ multiplicandBase: 16,
+ multiplierBase: 10,
+ toNumericBase: 'hex',
+ fromDenomination: 'WEI',
+ }))
+ }
+
+ dispatch(actions.updateSend({
+ gasLimit: sendGasLimit || txGasLimit,
+ gasPrice: sendGasPrice || txGasPrice,
+ editingTransactionId: id,
+ gasTotal: sendGasTotal,
+ to,
+ amount: tokenAmountInHex,
+ forceGasMin,
+ }))
+ dispatch(actions.showModal({ name: 'CUSTOMIZE_GAS' }))
+ },
}
}
@@ -188,6 +222,7 @@ ConfirmSendToken.prototype.getGasFee = function () {
token: tokenExchangeRate
? tokenGas
: null,
+ gasFeeInHex: gasTotal.toString(16),
}
}
@@ -240,19 +275,25 @@ ConfirmSendToken.prototype.renderHeroAmount = function () {
}
ConfirmSendToken.prototype.renderGasFee = function () {
- const { token: { symbol }, currentCurrency } = this.props
- const { fiat: fiatGas, token: tokenGas, eth: ethGas } = this.getGasFee()
+ const {
+ currentCurrency: convertedCurrency,
+ conversionRate,
+ send: { gasTotal, gasLimit: sendGasLimit, gasPrice: sendGasPrice },
+ showCustomizeGasModal,
+ } = this.props
+ const txMeta = this.gatherTxMeta()
+ const { gasFeeInHex } = this.getGasFee()
return (
h('section.flex-row.flex-center.confirm-screen-row', [
h('span.confirm-screen-label.confirm-screen-section-column', [ t('gasFee') ]),
h('div.confirm-screen-section-column', [
- h('div.confirm-screen-row-info', `${fiatGas} ${currentCurrency}`),
-
- h(
- 'div.confirm-screen-row-detail',
- tokenGas ? `${tokenGas} ${symbol}` : `${ethGas} ETH`
- ),
+ h(GasFeeDisplay, {
+ gasTotal: gasTotal || gasFeeInHex,
+ conversionRate,
+ convertedCurrency,
+ onClick: () => showCustomizeGasModal(txMeta, sendGasLimit, sendGasPrice, gasTotal),
+ }),
]),
])
)
@@ -308,16 +349,21 @@ ConfirmSendToken.prototype.render = function () {
this.inputs = []
+ const title = txMeta.lastGasPrice ? 'Reprice Transaction' : t('confirm')
+ const subtitle = txMeta.lastGasPrice
+ ? 'Increase your gas fee to attempt to overwrite and speed up your transaction'
+ : t('pleaseReviewTransaction')
+
return (
h('div.confirm-screen-container.confirm-send-token', [
// Main Send token Card
h('div.page-container', [
h('div.page-container__header', [
- h('button.confirm-screen-back-button', {
+ !txMeta.lastGasPrice && h('button.confirm-screen-back-button', {
onClick: () => editTransaction(txMeta),
}, t('edit')),
- h('div.page-container__title', t('confirm')),
- h('div.page-container__subtitle', t('pleaseReviewTransaction')),
+ h('div.page-container__title', title),
+ h('div.page-container__subtitle', subtitle),
]),
h('.page-container__content', [
h('div.flex-row.flex-center.confirm-screen-identicons', [
@@ -441,6 +487,27 @@ ConfirmSendToken.prototype.gatherTxMeta = function () {
const state = this.state
const txData = clone(state.txData) || clone(props.txData)
+ const { gasPrice: sendGasPrice, gas: sendGasLimit } = props.send
+ const {
+ lastGasPrice,
+ txParams: {
+ gasPrice: txGasPrice,
+ gas: txGasLimit,
+ },
+ } = txData
+
+ let forceGasMin
+ if (lastGasPrice) {
+ forceGasMin = ethUtil.addHexPrefix(multiplyCurrencies(lastGasPrice, 1.1, {
+ multiplicandBase: 16,
+ multiplierBase: 10,
+ toNumericBase: 'hex',
+ }))
+ }
+
+ txData.txParams.gasPrice = sendGasPrice || forceGasMin || txGasPrice
+ txData.txParams.gas = sendGasLimit || txGasLimit
+
// log.debug(`UI has defaulted to tx meta ${JSON.stringify(txData)}`)
return txData
}
diff --git a/ui/app/components/send/gas-fee-display-v2.js b/ui/app/components/send/gas-fee-display-v2.js
index 0c6f76303..f6af13454 100644
--- a/ui/app/components/send/gas-fee-display-v2.js
+++ b/ui/app/components/send/gas-fee-display-v2.js
@@ -18,6 +18,7 @@ GasFeeDisplay.prototype.render = function () {
onClick,
primaryCurrency = 'ETH',
convertedCurrency,
+ gasLoadingError,
} = this.props
return h('div.send-v2__gas-fee-display', [
@@ -31,13 +32,15 @@ GasFeeDisplay.prototype.render = function () {
convertedPrefix: '$',
readOnly: true,
})
- : h('div.currency-display', t('loading')),
+ : gasLoadingError
+ ? h('div..currency-display.currency-display--message', 'Set with the gas price customizer.')
+ : h('div.currency-display', t('loading')),
- h('button.send-v2__sliders-icon-container', {
+ h('button.sliders-icon-container', {
onClick,
- disabled: !gasTotal,
+ disabled: !gasTotal && !gasLoadingError,
}, [
- h('i.fa.fa-sliders.send-v2__sliders-icon'),
+ h('i.fa.fa-sliders.sliders-icon'),
]),
])
diff --git a/ui/app/components/send/send-v2-container.js b/ui/app/components/send/send-v2-container.js
index 1106902b7..d1319b6dc 100644
--- a/ui/app/components/send/send-v2-container.js
+++ b/ui/app/components/send/send-v2-container.js
@@ -48,6 +48,7 @@ function mapStateToProps (state) {
primaryCurrency,
convertedCurrency: getCurrentCurrency(state),
data,
+ selectedAddress,
amountConversionRate: selectedToken ? tokenToFiatRate : conversionRate,
tokenContract: getSelectedTokenContract(state),
unapprovedTxs: state.metamask.unapprovedTxs,
diff --git a/ui/app/components/tx-list-item.js b/ui/app/components/tx-list-item.js
index 849d70489..5ff1820a6 100644
--- a/ui/app/components/tx-list-item.js
+++ b/ui/app/components/tx-list-item.js
@@ -9,19 +9,28 @@ abiDecoder.addABI(abi)
const Identicon = require('./identicon')
const contractMap = require('eth-contract-metadata')
+const actions = require('../actions')
const { conversionUtil, multiplyCurrencies } = require('../conversion-util')
const { calcTokenAmount } = require('../token-util')
const { getCurrentCurrency } = require('../selectors')
const t = require('../../i18n')
-module.exports = connect(mapStateToProps)(TxListItem)
+module.exports = connect(mapStateToProps, mapDispatchToProps)(TxListItem)
function mapStateToProps (state) {
return {
tokens: state.metamask.tokens,
currentCurrency: getCurrentCurrency(state),
tokenExchangeRates: state.metamask.tokenExchangeRates,
+ selectedAddressTxList: state.metamask.selectedAddressTxList,
+ }
+}
+
+function mapDispatchToProps (dispatch) {
+ return {
+ setSelectedToken: tokenAddress => dispatch(actions.setSelectedToken(tokenAddress)),
+ retryTransaction: transactionId => dispatch(actions.retryTransaction(transactionId)),
}
}
@@ -32,6 +41,7 @@ function TxListItem () {
this.state = {
total: null,
fiatTotal: null,
+ isTokenTx: null,
}
}
@@ -40,12 +50,13 @@ TxListItem.prototype.componentDidMount = async function () {
const decodedData = txParams.data && abiDecoder.decodeMethod(txParams.data)
const { name: txDataName } = decodedData || {}
+ const isTokenTx = txDataName === 'transfer'
- const { total, fiatTotal } = txDataName === 'transfer'
+ const { total, fiatTotal } = isTokenTx
? await this.getSendTokenTotal()
: this.getSendEtherTotal()
- this.setState({ total, fiatTotal })
+ this.setState({ total, fiatTotal, isTokenTx })
}
TxListItem.prototype.getAddressText = function () {
@@ -168,22 +179,49 @@ TxListItem.prototype.getSendTokenTotal = async function () {
}
}
+TxListItem.prototype.showRetryButton = function () {
+ const {
+ transactionSubmittedTime,
+ selectedAddressTxList,
+ transactionId,
+ txParams,
+ } = this.props
+ const currentNonce = txParams.nonce
+ const currentNonceTxs = selectedAddressTxList.filter(tx => tx.txParams.nonce === currentNonce)
+ const currentNonceSubmittedTxs = currentNonceTxs.filter(tx => tx.status === 'submitted')
+ const lastSubmittedTxWithCurrentNonce = currentNonceSubmittedTxs[currentNonceSubmittedTxs.length - 1]
+ const currentTxIsLatestWithNonce = lastSubmittedTxWithCurrentNonce
+ && lastSubmittedTxWithCurrentNonce.id === transactionId
+
+ return currentTxIsLatestWithNonce && Date.now() - transactionSubmittedTime > 30000
+}
+
+TxListItem.prototype.setSelectedToken = function (tokenAddress) {
+ this.props.setSelectedToken(tokenAddress)
+}
+
+TxListItem.prototype.resubmit = function () {
+ const { transactionId } = this.props
+ this.props.retryTransaction(transactionId)
+}
+
TxListItem.prototype.render = function () {
const {
transactionStatus,
transactionAmount,
onClick,
- transActionId,
+ transactionId,
dateString,
address,
className,
+ txParams,
} = this.props
- const { total, fiatTotal } = this.state
+ const { total, fiatTotal, isTokenTx } = this.state
const showFiatTotal = transactionAmount !== '0x0' && fiatTotal
return h(`div${className || ''}`, {
- key: transActionId,
- onClick: () => onClick && onClick(transActionId),
+ key: transactionId,
+ onClick: () => onClick && onClick(transactionId),
}, [
h(`div.flex-column.tx-list-item-wrapper`, {}, [
@@ -224,6 +262,7 @@ TxListItem.prototype.render = function () {
className: classnames('tx-list-status', {
'tx-list-status--rejected': transactionStatus === 'rejected',
'tx-list-status--failed': transactionStatus === 'failed',
+ 'tx-list-status--dropped': transactionStatus === 'dropped',
}),
},
transactionStatus,
@@ -241,6 +280,23 @@ TxListItem.prototype.render = function () {
]),
]),
+
+ this.showRetryButton() && h('div.tx-list-item-retry-container', [
+
+ h('span.tx-list-item-retry-copy', 'Taking too long?'),
+
+ h('span.tx-list-item-retry-link', {
+ onClick: (event) => {
+ event.stopPropagation()
+ if (isTokenTx) {
+ this.setSelectedToken(txParams.to)
+ }
+ this.resubmit()
+ },
+ }, 'Increase the gas price on your transaction'),
+
+ ]),
+
]), // holding on icon from design
])
}
diff --git a/ui/app/components/tx-list.js b/ui/app/components/tx-list.js
index b6538347c..037c7de8c 100644
--- a/ui/app/components/tx-list.js
+++ b/ui/app/components/tx-list.js
@@ -75,9 +75,10 @@ TxList.prototype.renderTransactionListItem = function (transaction, conversionRa
address: transaction.txParams.to,
transactionStatus: transaction.status,
transactionAmount: transaction.txParams.value,
- transActionId: transaction.id,
+ transactionId: transaction.id,
transactionHash: transaction.hash,
transactionNetworkId: transaction.metamaskNetworkId,
+ transactionSubmittedTime: transaction.submittedTime,
}
const {
@@ -85,29 +86,31 @@ TxList.prototype.renderTransactionListItem = function (transaction, conversionRa
transactionStatus,
transactionAmount,
dateString,
- transActionId,
+ transactionId,
transactionHash,
transactionNetworkId,
+ transactionSubmittedTime,
} = props
const { showConfTxPage } = this.props
const opts = {
- key: transActionId || transactionHash,
+ key: transactionId || transactionHash,
txParams: transaction.txParams,
transactionStatus,
- transActionId,
+ transactionId,
dateString,
address,
transactionAmount,
transactionHash,
conversionRate,
tokenInfoGetter: this.tokenInfoGetter,
+ transactionSubmittedTime,
}
const isUnapproved = transactionStatus === 'unapproved'
if (isUnapproved) {
- opts.onClick = () => showConfTxPage({id: transActionId})
+ opts.onClick = () => showConfTxPage({id: transactionId})
opts.transactionStatus = t('Not Started')
} else if (transactionHash) {
opts.onClick = () => this.view(transactionHash, transactionNetworkId)
diff --git a/ui/app/conversion-util.js b/ui/app/conversion-util.js
index ee42ebea1..d484ed16d 100644
--- a/ui/app/conversion-util.js
+++ b/ui/app/conversion-util.js
@@ -187,6 +187,18 @@ const conversionGreaterThan = (
return firstValue.gt(secondValue)
}
+const conversionMax = (
+ { ...firstProps },
+ { ...secondProps },
+) => {
+ const firstIsGreater = conversionGreaterThan(
+ { ...firstProps },
+ { ...secondProps }
+ )
+
+ return firstIsGreater ? firstProps.value : secondProps.value
+}
+
const conversionGTE = (
{ ...firstProps },
{ ...secondProps },
@@ -216,6 +228,7 @@ module.exports = {
conversionGreaterThan,
conversionGTE,
conversionLTE,
+ conversionMax,
toNegative,
subtractCurrencies,
}
diff --git a/ui/app/css/itcss/components/account-menu.scss b/ui/app/css/itcss/components/account-menu.scss
index 4752741aa..c4037d862 100644
--- a/ui/app/css/itcss/components/account-menu.scss
+++ b/ui/app/css/itcss/components/account-menu.scss
@@ -87,7 +87,6 @@
flex: 1 0 auto;
display: flex;
flex-flow: column nowrap;
- padding-top: 4px;
}
&__check-mark {
@@ -115,13 +114,11 @@
color: $white;
font-size: 18px;
font-weight: 300;
- line-height: 16px;
}
&__balance {
color: $dusty-gray;
font-size: 14px;
- line-height: 19px;
}
&__action {
diff --git a/ui/app/css/itcss/components/network.scss b/ui/app/css/itcss/components/network.scss
index c32d1de5e..374cb71b6 100644
--- a/ui/app/css/itcss/components/network.scss
+++ b/ui/app/css/itcss/components/network.scss
@@ -10,8 +10,9 @@
.network-component.pointer {
border: 2px solid $silver;
border-radius: 82px;
- padding: 3px;
+ padding: 7px 3px;
flex: 0 0 auto;
+ display: flex;
&.ethereum-network .menu-icon-circle div {
background-color: rgba(3, 135, 137, .7) !important;
diff --git a/ui/app/css/itcss/components/newui-sections.scss b/ui/app/css/itcss/components/newui-sections.scss
index 5cdda5e6c..777a82318 100644
--- a/ui/app/css/itcss/components/newui-sections.scss
+++ b/ui/app/css/itcss/components/newui-sections.scss
@@ -265,7 +265,6 @@ $wallet-view-bg: $alabaster;
.account-name {
font-size: 24px;
font-weight: 300;
- line-height: 20px;
color: $black;
margin-top: 8px;
margin-bottom: .9rem;
diff --git a/ui/app/css/itcss/components/send.scss b/ui/app/css/itcss/components/send.scss
index bb17e53cd..bdea1b008 100644
--- a/ui/app/css/itcss/components/send.scss
+++ b/ui/app/css/itcss/components/send.scss
@@ -660,6 +660,13 @@
&__gas-fee-display {
width: 100%;
+ position: relative;
+
+ .currency-display--message {
+ padding: 8px 38px 8px 10px;
+ display: flex;
+ align-items: center;
+ }
}
&__sliders-icon-container {
@@ -885,3 +892,23 @@
}
}
}
+
+.sliders-icon-container {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ height: 24px;
+ width: 24px;
+ border: 1px solid $curious-blue;
+ border-radius: 4px;
+ background-color: $white;
+ position: absolute;
+ right: 15px;
+ top: 14px;
+ cursor: pointer;
+ font-size: 1em;
+}
+
+.sliders-icon {
+ color: $curious-blue;
+} \ No newline at end of file
diff --git a/ui/app/css/itcss/components/transaction-list.scss b/ui/app/css/itcss/components/transaction-list.scss
index c3df493df..c13f24953 100644
--- a/ui/app/css/itcss/components/transaction-list.scss
+++ b/ui/app/css/itcss/components/transaction-list.scss
@@ -97,7 +97,7 @@
.tx-list-content-wrapper {
align-items: stretch;
- margin-bottom: 4px;
+ margin: 4px 0;
flex: 1 0 auto;
width: 100%;
display: flex;
@@ -126,6 +126,53 @@
}
}
+.tx-list-item-retry-container {
+ background: #d1edff;
+ width: 100%;
+ border-radius: 4px;
+ font-size: 0.8em;
+ display: flex;
+ justify-content: center;
+ margin-left: 44px;
+ width: calc(100% - 44px);
+
+ @media screen and (min-width: 576px) and (max-width: 679px) {
+ flex-flow: column;
+ align-items: center;
+ }
+
+ @media screen and (min-width: 380px) and (max-width: 575px) {
+ flex-flow: row;
+ }
+
+ @media screen and (max-width: 379px) {
+ flex-flow: column;
+ align-items: center;
+ }
+}
+
+.tx-list-item-retry-copy {
+ font-family: Roboto;
+}
+
+.tx-list-item-retry-link {
+ text-decoration: underline;
+ margin-left: 6px;
+ cursor: pointer;
+
+ @media screen and (min-width: 576px) and (max-width: 679px) {
+ margin-left: 0px;
+ }
+
+ @media screen and (min-width: 380px) and (max-width: 575px) {
+ margin-left: 6px;
+ }
+
+ @media screen and (max-width: 379px) {
+ margin-left: 0px;
+ }
+}
+
.tx-list-date {
color: $dusty-gray;
font-size: 12px;
@@ -136,6 +183,7 @@
align-self: center;
flex: 0 0 auto;
margin-right: 16px;
+ display: flex;
}
.tx-list-account-and-status-wrapper {
@@ -189,9 +237,14 @@
.tx-list-status--failed {
color: $monzo;
}
+
+ .tx-list-status--dropped {
+ opacity: 0.5;
+ }
}
.tx-list-item {
+ height: 80px;
border-top: 1px solid rgb(231, 231, 231);
flex: 0 0 auto;
display: flex;
diff --git a/ui/app/css/itcss/generic/index.scss b/ui/app/css/itcss/generic/index.scss
index 1fbd9896f..1e226b93e 100644
--- a/ui/app/css/itcss/generic/index.scss
+++ b/ui/app/css/itcss/generic/index.scss
@@ -13,7 +13,6 @@ body {
font-family: Roboto, Arial;
color: #4d4d4d;
font-weight: 300;
- line-height: 1.4em;
background: #f7f7f7;
width: 100%;
height: 100%;
@@ -103,6 +102,7 @@ input.large-input {
&::after {
content: '\00D7';
font-size: 40px;
+ line-height: 20px;
}
}
diff --git a/ui/app/css/itcss/generic/reset.scss b/ui/app/css/itcss/generic/reset.scss
index e054d533e..a417a0453 100644
--- a/ui/app/css/itcss/generic/reset.scss
+++ b/ui/app/css/itcss/generic/reset.scss
@@ -112,10 +112,6 @@ section {
display: block;
}
-body {
- line-height: 1;
-}
-
ol,
ul {
list-style: none;
diff --git a/ui/app/css/itcss/settings/variables.scss b/ui/app/css/itcss/settings/variables.scss
index d96c1ae43..640fd95b8 100644
--- a/ui/app/css/itcss/settings/variables.scss
+++ b/ui/app/css/itcss/settings/variables.scss
@@ -46,6 +46,7 @@ $manatee: #93949d;
$spindle: #c7ddec;
$mid-gray: #5b5d67;
$cape-cod: #38393a;
+$onahau: #d1edff;
$java: #29b6af;
$wild-strawberry: #ff4a8d;
$cornflower-blue: #7057ff;
diff --git a/ui/app/reducers/metamask.js b/ui/app/reducers/metamask.js
index 4ca7d221e..e6e02d057 100644
--- a/ui/app/reducers/metamask.js
+++ b/ui/app/reducers/metamask.js
@@ -38,6 +38,7 @@ function reduceMetamask (state, action) {
errors: {},
maxModeOn: false,
editingTransactionId: null,
+ forceGasMin: null,
},
coinOptions: {},
useBlockie: false,
@@ -297,6 +298,7 @@ function reduceMetamask (state, action) {
memo: '',
errors: {},
editingTransactionId: null,
+ forceGasMin: null,
},
})
diff --git a/ui/app/selectors.js b/ui/app/selectors.js
index 5d2635775..d37c26f7e 100644
--- a/ui/app/selectors.js
+++ b/ui/app/selectors.js
@@ -18,6 +18,7 @@ const selectors = {
getCurrentAccountWithSendEtherInfo,
getGasPrice,
getGasLimit,
+ getForceGasMin,
getAddressBook,
getSendFrom,
getCurrentCurrency,
@@ -130,6 +131,10 @@ function getGasLimit (state) {
return state.metamask.send.gasLimit
}
+function getForceGasMin (state) {
+ return state.metamask.send.forceGasMin
+}
+
function getSendFrom (state) {
return state.metamask.send.from
}
diff --git a/ui/app/send-v2.js b/ui/app/send-v2.js
index dbfa6025d..31118378d 100644
--- a/ui/app/send-v2.js
+++ b/ui/app/send-v2.js
@@ -43,6 +43,7 @@ function SendTransactionScreen () {
to: null,
amount: null,
},
+ gasLoadingError: false,
}
this.handleToChange = this.handleToChange.bind(this)
@@ -129,6 +130,10 @@ SendTransactionScreen.prototype.updateGas = function () {
.then(([gasPrice, gas]) => {
const newGasTotal = this.getGasTotal(gas, gasPrice)
updateGasTotal(newGasTotal)
+ this.setState({ gasLoadingError: false })
+ })
+ .catch(err => {
+ this.setState({ gasLoadingError: true })
})
} else {
const newGasTotal = this.getGasTotal(gasLimit, gasPrice)
@@ -436,6 +441,7 @@ SendTransactionScreen.prototype.renderGasRow = function () {
showCustomizeGasModal,
gasTotal,
} = this.props
+ const { gasLoadingError } = this.state
return h('div.send-v2__form-row', [
@@ -448,6 +454,7 @@ SendTransactionScreen.prototype.renderGasRow = function () {
conversionRate,
convertedCurrency,
onClick: showCustomizeGasModal,
+ gasLoadingError,
}),
]),
@@ -571,9 +578,11 @@ SendTransactionScreen.prototype.getEditedTx = function () {
data,
})
} else {
+ const data = unapprovedTxs[editingTransactionId].txParams.data
Object.assign(editingTx.txParams, {
value: ethUtil.addHexPrefix(amount),
to: ethUtil.addHexPrefix(to),
+ data,
})
}