aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--app/_locales/de/messages.json2
-rw-r--r--app/_locales/es/messages.json2
-rw-r--r--app/_locales/hn/messages.json2
-rw-r--r--app/_locales/nl/messages.json2
-rw-r--r--app/_locales/ru/messages.json423
-rw-r--r--app/_locales/sl/messages.json2
-rw-r--r--app/_locales/th/messages.json2
-rw-r--r--app/_locales/zh_TW/messages.json2
-rw-r--r--app/scripts/controllers/transactions.js4
-rw-r--r--app/scripts/metamask-controller.js7
-rw-r--r--development/states/tx-list-items.js128
-rw-r--r--development/verify-locale-strings.js133
-rw-r--r--docs/translating-guide.md9
-rw-r--r--gulpfile.js11
-rw-r--r--old-ui/app/components/transaction-list-item.js5
-rw-r--r--package-lock.json733
-rw-r--r--package.json3
-rw-r--r--test/integration/lib/tx-list-items.js61
-rw-r--r--ui/app/components/customize-gas-modal/index.js3
-rw-r--r--ui/app/components/identicon.js5
-rw-r--r--ui/app/components/pending-tx/confirm-send-ether.js74
-rw-r--r--ui/app/components/pending-tx/confirm-send-token.js69
-rw-r--r--ui/app/components/send/send-utils.js12
-rw-r--r--ui/app/components/tx-list-item.js21
-rw-r--r--ui/app/components/tx-list.js5
-rw-r--r--ui/app/css/itcss/components/confirm.scss25
-rw-r--r--ui/app/send-v2.js17
27 files changed, 1120 insertions, 642 deletions
diff --git a/app/_locales/de/messages.json b/app/_locales/de/messages.json
index 5116764d1..1d2619672 100644
--- a/app/_locales/de/messages.json
+++ b/app/_locales/de/messages.json
@@ -232,7 +232,7 @@
"done": {
"message": "Fertig"
},
- "downloadStatelogs": {
+ "downloadStateLogs": {
"message": "Statelogs herunterladen"
},
"dropped": {
diff --git a/app/_locales/es/messages.json b/app/_locales/es/messages.json
index fa28b09da..f287674f1 100644
--- a/app/_locales/es/messages.json
+++ b/app/_locales/es/messages.json
@@ -247,7 +247,7 @@
"done": {
"message": "Completo"
},
- "downloadStatelogs": {
+ "downloadStateLogs": {
"message": "Descargar logs de estado"
},
"dropped": {
diff --git a/app/_locales/hn/messages.json b/app/_locales/hn/messages.json
index 3703faa13..323f4b4b3 100644
--- a/app/_locales/hn/messages.json
+++ b/app/_locales/hn/messages.json
@@ -223,7 +223,7 @@
"done": {
"message": "संपन्न"
},
- "downloadStatelogs": {
+ "downloadStateLogs": {
"message": "राज्य लॉग डाउनलोड करें"
},
"edit": {
diff --git a/app/_locales/nl/messages.json b/app/_locales/nl/messages.json
index 487002add..38289f602 100644
--- a/app/_locales/nl/messages.json
+++ b/app/_locales/nl/messages.json
@@ -223,7 +223,7 @@
"done": {
"message": "Gedaan"
},
- "downloadStatelogs": {
+ "downloadStateLogs": {
"message": "Staatslogboeken downloaden"
},
"edit": {
diff --git a/app/_locales/ru/messages.json b/app/_locales/ru/messages.json
index e3a1935f5..cd43416ad 100644
--- a/app/_locales/ru/messages.json
+++ b/app/_locales/ru/messages.json
@@ -3,13 +3,13 @@
"message": "Принять"
},
"account": {
- "message": "Аккаунт"
+ "message": "Счет"
},
"accountDetails": {
- "message": "Детали Аккаунта"
+ "message": "Детали счета"
},
"accountName": {
- "message": "Имя Пользователя"
+ "message": "Название счета"
},
"address": {
"message": "Адрес"
@@ -21,13 +21,13 @@
"message": "Добавить токен"
},
"addTokens": {
- "message": "Добавить Токены"
+ "message": "Добавить токены"
},
"amount": {
- "message": "Количество"
+ "message": "Сумма"
},
"amountPlusGas": {
- "message": "Количество + газ"
+ "message": "Сумма + газ"
},
"appDescription": {
"message": "Расширение браузера для Ethereum",
@@ -37,11 +37,14 @@
"message": "MetaMask",
"description": "The name of the application"
},
+ "approved": {
+ "message": "Одобрена"
+ },
"attemptingConnect": {
"message": "Попытка подключиться к блокчейн сети."
},
"attributions": {
- "message": "Опознания"
+ "message": "Атрибуция"
},
"available": {
"message": "Доступный"
@@ -53,13 +56,13 @@
"message": "Баланс:"
},
"balances": {
- "message": "Ваши балансы"
+ "message": "Ваш баланс"
},
"balanceIsInsufficientGas": {
"message": "Недостаточный баланс для текущего объема газа"
},
"beta": {
- "message": "БЕТА"
+ "message": "BETA"
},
"betweenMinAndMax": {
"message": "должно быть больше или равно $1 и меньше или равно $2.",
@@ -69,10 +72,10 @@
"message": "Использовать Blockies Identicon"
},
"borrowDharma": {
- "message": "Заимствовать с Dharma (бета)"
+ "message": "Взять в долг на Dharma (Beta)"
},
"builtInCalifornia": {
- "message": "MetaMask спроектирован и построен в Калифорнии."
+ "message": "MetaMask спроектирован и разработан в Калифорнии."
},
"buy": {
"message": "Купить"
@@ -81,7 +84,10 @@
"message": "Купить на Coinbase"
},
"buyCoinbaseExplainer": {
- "message": "Coinbase - самый популярный в мире способ купить и продать биткойн, ethereum и litecoin."
+ "message": "Биржа Coinbase – это наиболее популярный способ купить или продать bitcoin, ethereum и litecoin."
+ },
+ "ok": {
+ "message": "ОК"
},
"cancel": {
"message": "Отмена"
@@ -95,14 +101,17 @@
"confirm": {
"message": "Подтвердить"
},
+ "confirmed": {
+ "message": "Подтверждена"
+ },
"confirmContract": {
- "message": "Подтвердить Контракт"
+ "message": "Подтвердить контракт"
},
"confirmPassword": {
- "message": "Подтвердите Пароль"
+ "message": "Подтвердите пароль"
},
"confirmTransaction": {
- "message": "Подтвердить Транзакцию"
+ "message": "Подтвердить транзакцию"
},
"continue": {
"message": "Продолжить"
@@ -114,7 +123,7 @@
"message": "Развертывание контракта"
},
"conversionProgress": {
- "message": "Выполняется конверсия"
+ "message": "Выполняется конвертация"
},
"copiedButton": {
"message": "Скопировано"
@@ -126,7 +135,7 @@
"message": "Скопировано!"
},
"copiedSafe": {
- "message": "Я скопировал его где-то в безопасности"
+ "message": "Я скопировал это в безопасное место"
},
"copy": {
"message": "Скопировать"
@@ -138,29 +147,32 @@
"message": " Скопировать "
},
"copyPrivateKey": {
- "message": "Это ваш личный ключ (нажмите, чтобы скопировать)"
+ "message": "Это ваш закрытый ключ (нажмите, чтобы скопировать)"
},
"create": {
"message": "Создать"
},
"createAccount": {
- "message": "Регистрация"
+ "message": "Создать счет"
},
"createDen": {
"message": "Создать"
},
"crypto": {
- "message": "Крипто",
+ "message": "Криптовалюта",
"description": "Exchange type (cryptocurrencies)"
},
"currentConversion": {
- "message": "Текущая конверсия"
+ "message": "Текущая конвертация"
},
"currentNetwork": {
"message": "Текущая сеть"
},
"customGas": {
- "message": "Настроить Газ"
+ "message": "Настроить газ"
+ },
+ "customToken": {
+ "message": "Пользовательский токен"
},
"customize": {
"message": "Настроить"
@@ -169,112 +181,114 @@
"message": "Пользовательский RPC"
},
"decimalsMustZerotoTen": {
- "message": "Десятичные числа должны быть не менее 0, и не более 36."
+ "message": "Количество десятичных разрядов должно быть минимум 0 и максимум 36."
},
"decimal": {
- "message": "Десятичные значения точности"
+ "message": "Количество десятичных разрядов"
},
"defaultNetwork": {
- "message": "Сеть по умолчанию для транзакций Ether - это Main Net."
+ "message": "Основная сеть Ethereum – это сеть по умолчанию для Ether транзакций."
},
"denExplainer": {
- "message": "Ваш DEN - это ваше зашифрованное паролем хранилище в MetaMask."
+ "message": "DEN – это зашифрованное паролем хранилище внутри MetaMask."
},
"deposit": {
- "message": "Депозит"
+ "message": "Пополнить"
},
"depositBTC": {
- "message": "Депозит BTC по адресу:"
+ "message": "Отправьте ваш BTC на адрес ниже:"
},
"depositCoin": {
- "message": "Депозит $1 по указанному ниже адресу",
+ "message": "Отправьте ваш $1 на адрес ниже",
"description": "Tells the user what coin they have selected to deposit with shapeshift"
},
"depositEth": {
- "message": "Депозит Eth"
+ "message": "Пополнить Eth"
},
"depositEther": {
- "message": "Депозит Эфир"
+ "message": "Пополнить Ether"
},
"depositFiat": {
- "message": "Депозит с деньгами"
+ "message": "Пополнить деньгами"
},
"depositFromAccount": {
- "message": "Депозит с другого счета"
+ "message": "Пополнить с другого счета"
},
"depositShapeShift": {
- "message": "Депозит с ShapeShift"
+ "message": "Пополнить через ShapeShift"
},
"depositShapeShiftExplainer": {
- "message": "Если у вас есть другие крипторесурсы, вы можете торговать и вносить Эфир непосредственно в кошелек MetaMask. Нет необходимости в аккаунте."
+ "message": "Если у вас есть другие криптовалюты, вы можете торговать и пополнять Ether напрямую в ваш MetaMask кошелек. Нет необходимости в счете."
},
"details": {
"message": "Детали"
},
"directDeposit": {
- "message": "Прямой Депозит"
+ "message": "Прямое пополнение"
},
"directDepositEther": {
- "message": "Прямой Депозит Эфира"
+ "message": "Прямое пополнение Ether"
},
"directDepositEtherExplainer": {
- "message": "Если у вас уже есть Эфир, самый быстрый способ получить Эфир в вашем новом кошельке это прямым депозитом."
+ "message": "Если у вас уже есть Ether, то самый быстрый способ получить Ether в ваш новый кошелек – это прямое пополнение."
},
"done": {
"message": "Готово"
},
- "downloadStatelogs": {
- "message": "Загрузить логи статус"
+ "downloadStateLogs": {
+ "message": "Скачать журнал состояния"
+ "dropped": {
+ "message": "Отброшена"
},
"edit": {
"message": "Редактировать"
},
"editAccountName": {
- "message": "Изменить Имя Аккаунта"
+ "message": "Редактировать название счета"
},
"emailUs": {
"message": "Свяжитесь с нами по электронной почте!"
},
"encryptNewDen": {
- "message": "Шифруйте новый DEN"
+ "message": "Зашифровать ваш новый DEN"
},
"enterPassword": {
"message": "Введите пароль"
},
"enterPasswordConfirm": {
- "message": "Введите свой пароль для подтверждения"
+ "message": "Введите ваш пароль для подтверждения"
},
"etherscanView": {
- "message": "Просмотреть аккаунт на Etherscan"
+ "message": "Просмотреть счет на Etherscan"
},
"exchangeRate": {
- "message": "Обменный Курс"
+ "message": "Обменный курс"
},
"exportPrivateKey": {
- "message": "Экспорт закрытого ключа"
+ "message": "Экспортировать закрытый ключ"
},
"exportPrivateKeyWarning": {
- "message": "Экспорт секретных ключей на свой страх и риск."
+ "message": "Вы экспортируете закрытые ключи на свой страх и риск."
},
"failed": {
- "message": "Не смогли"
+ "message": "Неудачна"
},
"fiat": {
- "message": "Бумажные деньги",
+ "message": "Валюта",
"description": "Exchange type"
},
"fileImportFail": {
- "message": "Ошибка импорта файлов? Кликните сюда!",
+ "message": "Не работает импорт файла? Нажмите тут!",
"description": "Helps user import their account from a JSON file"
},
"followTwitter": {
- "message": "Следуйте за нами на Twitter"
+ "message": "Читайте нас в Twitter"
},
"from": {
- "message": "Из"
+ "message": "Отправитель"
},
"fromToSame": {
- "message": "От и до адреса не могут быть одинаковым"
+ "message": "Адрес отправителя и получателя не могут быть одинаковыми"
},
"fromShapeShift": {
"message": "Из ShapeShift"
@@ -284,37 +298,37 @@
"description": "Short indication of gas cost"
},
"gasFee": {
- "message": "Плата за Газ"
+ "message": "Комиссия за газ"
},
"gasLimit": {
- "message": "Газовый Предел"
+ "message": "Лимит газа"
},
"gasLimitCalculation": {
- "message": "Мы рассчитываем предполагаемый предел газа на основе коэффициентов успешности сети."
+ "message": "Мы расчитываем предлагаемый лимит газа на основании успешных ставок в сети."
},
"gasLimitRequired": {
- "message": "Требуется ограничение на Газ"
+ "message": "Установите лимит газа"
},
"gasLimitTooLow": {
- "message": "Предел газа должен быть не менее 21000"
+ "message": "Лимит газа должен быть как минимум 21000"
},
"generatingSeed": {
- "message": "Создание Семян ..."
+ "message": "Генерируем фразу..."
},
"gasPrice": {
- "message": "Цена на Газ (GWEI)"
+ "message": "Цена за газ (GWEI)"
},
"gasPriceCalculation": {
- "message": "Мы вычисляем предлагаемые цены на газ на основе коэффициентов успеха сети."
+ "message": "Мы расчитываем предлагаемые цены за газ на основании успешных ставок в сети."
},
"gasPriceRequired": {
- "message": "Требуется цена на Газ"
+ "message": "Установите стоимость газа"
},
"getEther": {
- "message": "Получить Эфир"
+ "message": "Получить Ether"
},
"getEtherFromFaucet": {
- "message": "Получите Эфир из крана $1",
+ "message": "Получить Ether из крана для $1",
"description": "Displays network name for Ether faucet"
},
"greaterThanMin": {
@@ -322,14 +336,14 @@
"description": "helper for inputting hex as decimal input"
},
"here": {
- "message": "здесь",
+ "message": "тут",
"description": "as in -click here- for more information (goes with troubleTokenBalances)"
},
"hereList": {
- "message": "Вот список !!!!"
+ "message": "Вот список!!!!"
},
"hide": {
- "message": "Спрятать"
+ "message": "Скрыть"
},
"hideToken": {
"message": "Скрыть токен"
@@ -338,33 +352,33 @@
"message": "Скрыть токен?"
},
"howToDeposit": {
- "message": "Как бы вы хотели поместить Эфир?"
+ "message": "Как бы вы хотели пополнить Ether?"
},
"holdEther": {
- "message": "Это позволяет вам использовать эфир и токены и служит мостом для децентрализованных приложений."
+ "message": "Позволяет вам хранить ether и токены и служит в качестве моста в децентрализированные приложения."
},
"import": {
"message": "Импортировать",
"description": "Button to import an account from a selected file"
},
"importAccount": {
- "message": "Импорт Аккаунта"
+ "message": "Импортировать счет"
},
"importAccountMsg": {
- "message": " Импортированные аккаунты не будут связаны с вашей первоначально созданным аккаунтом MetaMask. Подробнее о импортированных аккаунтах "
+ "message":" Импортированные счета не будут ассоциированы с вашей ключевой фразой, созданной MetaMask. Узнать больше про импорт счетов "
},
"importAnAccount": {
"message": "Импортировать аккаунт"
},
"importDen": {
- "message": "Импорт существующих DEN"
+ "message": "Импортировать существующий DEN"
},
"imported": {
"message": "Импортирован",
"description": "status showing that an account has been fully loaded into the keyring"
},
"infoHelp": {
- "message": "Информация и Помощь"
+ "message": "Информация и помощь"
},
"insufficientFunds": {
"message": "Недостаточно средств."
@@ -373,35 +387,44 @@
"message": "Недостаточно токенов."
},
"invalidAddress": {
- "message": "Недействительный адрес"
+ "message": "Неверный адрес"
},
"invalidAddressRecipient": {
- "message": "Недопустимый адрес получателя."
+ "message": "Неверный адрес получателя"
},
"invalidGasParams": {
- "message": "Недопустимые параметры Газа"
+ "message": "Неверные параметры газа"
},
"invalidInput": {
- "message": "Неправильный ввод."
+ "message": "Неверный ввод."
},
"invalidRequest": {
- "message": "Неверный Запрос"
+ "message": "Неверный запрос"
},
"invalidRPC": {
- "message": "Недопустимый URI RPC"
+ "message": "Неверный RPC URI"
},
"jsonFail": {
- "message": "Что-то пошло не так. Убедитесь, что ваш файл JSON правильно отформатирован."
+ "message": "Что-то пошло не так. Убедитесь, что ваш JSON файл правильно отформатирован."
},
"jsonFile": {
- "message": "Файл JSON",
+ "message": "JSON файл",
"description": "format for importing an account"
},
+ "keepTrackTokens": {
+ "message": "Следите за купленными вами токенами с помощью аккаунта MetaMask."
+ },
"kovan": {
- "message": "Kovan тестовая сеть"
+ "message": "Тестовая сеть Kovan"
},
"knowledgeDataBase": {
- "message": "Посетите нашу базу знаний"
+ "message": "Посмотрите нашу Базу Знаний"
+ },
+ "max": {
+ "message": "Максимум"
+ },
+ "learnMore": {
+ "message": "Узнать больше."
},
"lessThanMax": {
"message": "должно быть меньше или равно $1.",
@@ -410,29 +433,32 @@
"likeToAddTokens": {
"message": "Вы хотите добавить эти токены?"
},
+ "links": {
+ "message": "Ссылки"
+ },
"limit": {
- "message": "Предел"
+ "message": "Лимит"
},
"loading": {
"message": "Загрузка..."
},
"loadingTokens": {
- "message": "Загрузка токенов ..."
+ "message": "Загрузка токенов..."
},
"localhost": {
- "message": "Локальный адрес 8545"
+ "message": "Localhost 8545"
},
"login": {
- "message": "Авторизоваться"
+ "message": "Вход"
},
"logout": {
- "message": "Выйти"
+ "message": "Выход"
},
"loose": {
- "message": "Рыхлый"
+ "message": "Несвязанный"
},
"loweCaseWords": {
- "message": "семенные слова имеют только символы нижнего регистра"
+ "message": "ключевая фраза может содержать только символы нижнего регистра"
},
"mainnet": {
"message": "Основная сеть Ethereum"
@@ -441,19 +467,19 @@
"message": "Сообщение"
},
"metamaskDescription": {
- "message": "MetaMask - это безопасное хранилище для Ethereum."
+ "message": "MetaMask – безопасный кошелек для Ethereum."
},
"min": {
"message": "Минимум"
},
"myAccounts": {
- "message": "Мои Аккаунты"
+ "message": "Мои счета"
},
"mustSelectOne": {
- "message": "Необходимо выбрать не менее 1 токена."
+ "message": "Необходимо выбрать как минимум 1 токен."
},
"needEtherInWallet": {
- "message": "Чтобы взаимодействовать с децентрализованными приложениями с помощью MetaMask, вам понадобится Эфир в вашем кошельке."
+ "message": "Для взаимодействия с децентрализованными приложениями с помощью MetaMask нужен Ether в вашем кошельке."
},
"needImportFile": {
"message": "Вы должны выбрать файл для импорта.",
@@ -464,60 +490,60 @@
"description": "Password and file needed to import an account"
},
"negativeETH": {
- "message": "Невозможно отправить отрицательные количества ETH."
+ "message": "Невозможно отправить отрицательную сумму ETH."
},
"networks": {
"message": "Сети"
},
"newAccount": {
- "message": "Новый Аккаунт"
+ "message": "Новый счет"
},
"newAccountNumberName": {
- "message": "Аккаунт $1",
+ "message": "Счет $1",
"description": "Default name of next account to be created on create account screen"
},
"newContract": {
- "message": "Новый Контракт"
+ "message": "Новый контракт"
},
"newPassword": {
"message": "Новый пароль (мин. 8 символов)"
},
"newRecipient": {
- "message": "Новый Получатель"
+ "message": "Новый получатель"
},
"newRPC": {
- "message": "Новый URL-адрес RPC"
+ "message": "Новый RPC URL"
},
"next": {
"message": "Далее"
},
"noAddressForName": {
- "message": "Для этого имени не задан адрес."
+ "message": "Дла этого названия не установлен адрес."
},
"noDeposits": {
- "message": "Не было получено никаких депозитов"
+ "message": "Пополнения не получены"
},
"noTransactionHistory": {
"message": "Нет истории транзакций."
},
"noTransactions": {
- "message": "Нет Транзакций"
+ "message": "Нет транзакций"
},
"notStarted": {
- "message": "Не Начался"
+ "message": "Не запущен"
},
"oldUI": {
- "message": "Старый Интерфейс"
+ "message": "Старая версия интерфейса"
},
"oldUIMessage": {
- "message": "Вы вернулись к старому интерфейсу. Вы можете вернуться к новому с помощью опции в раскрывающемся меню в правом верхнем углу."
+ "message": "Вы вернулись к старой версии интерфейса пользователя. Вы можете переключиться на новую с помощью опции выпадающего меню в правом верхнем углу."
},
"or": {
"message": "или",
"description": "choice between creating or importing a new account"
},
"passwordCorrect": {
- "message": "Убедитесь, что ваш пароль правильный."
+ "message": "Убедитесь, что ваш пароль верный."
},
"passwordMismatch": {
"message": "пароли не совпадают",
@@ -528,27 +554,30 @@
"description": "in password creation process, the password is not long enough to be secure"
},
"pastePrivateKey": {
- "message": "Вставьте свою личную строку:",
+ "message": "Вставьте ваш закрытый ключ тут:",
"description": "For importing an account from a private key"
},
"pasteSeed": {
- "message": "Вставьте здесь свою семенную фразу!"
+ "message": "Вставьте вашу ключевую фразу!"
},
"personalAddressDetected": {
- "message": "Персональный адрес обнаружен. Введите адрес контракта токена."
+ "message": "Обнаружен персональный адрес. Введите адрес контракта токена."
},
"pleaseReviewTransaction": {
"message": "Проверьте транзакцию."
},
+ "popularTokens": {
+ "message": "Популярные токены"
+ },
"privacyMsg": {
- "message": "Политика Конфиденциальности"
+ "message": "Политика конфиденциальности"
},
"privateKey": {
"message": "Закрытый ключ",
"description": "select this type of file to use to import an account"
},
"privateKeyWarning": {
- "message": "Предупреждение: никогда не раскрывайте этот ключ. Любой, у кого есть ваши личные ключи, может украсть любые активы, хранящиеся в вашем аккаунте."
+ "message": "Предупреждение: Никогда не раскрывайте этот ключ. Любой, у кого есть ваши закрытые ключи, может украсть любые активы, хранящиеся на счету."
},
"privateNetwork": {
"message": "Частная сеть"
@@ -557,126 +586,165 @@
"message": "Показать QR-код"
},
"readdToken": {
- "message": "Вы можете добавить этот токен в будущем, перейдя в “Добавить токен” в меню параметров вашего аккаунта."
+ "message": "Вы можете в будущем добавить обратно этот токен, выбрав пункт меню “Добавить токен”."
},
"readMore": {
- "message": "Подробнее читайте здесь."
+ "message": "Узнать больше тут."
},
"readMore2": {
- "message": "Прочитайте больше."
+ "message": "Узнать больше."
},
"receive": {
"message": "Получить"
},
"recipientAddress": {
- "message": "Адрес Получателя"
+ "message": "Адрес получателя"
},
"refundAddress": {
- "message": "Ваш Адрес Возврата"
+ "message": "Ваш адрес для возврата средств"
},
"rejected": {
- "message": "Отклонено"
+ "message": "Отклонена"
},
"resetAccount": {
"message": "Сбросить аккаунт"
},
"restoreFromSeed": {
- "message": "Восстановить от семенной фразы"
+ "message": "Восстановить из ключевой фразы"
+ },
+ "restoreVault": {
+ "message": "Восстановить кошелек"
},
"required": {
- "message": "Необходимо"
+ "message": "Обязательное поле"
},
"retryWithMoreGas": {
- "message": "Повторите попытку с более высокой ценой на газ здесь"
+ "message": "Повторите попытку с большей ценой за газRetry with a higher gas price here"
+ },
+ "walletSeed": {
+ "message": "Ключевая фраза кошелька"
},
"revealSeedWords": {
- "message": "Раскрыть семенные слова"
+ "message": "Показать ключевую фразу"
},
"revealSeedWordsWarning": {
- "message": "Не восстанавливайте семенные слова в общественном месте! Эти слова могут использоваться для кражи всех ваших аккаунтах."
+ "message": "Не восстанавливайте ключевую фразу в общественном месте! Она может быть использована для кражи всех ваших счетов."
},
"revert": {
- "message": "Откат"
+ "message": "Восстановить"
},
"rinkeby": {
- "message": "Rinkeby тестовая сеть"
+ "message": "Тестовая сеть Rinkeby"
},
"ropsten": {
- "message": "Ropsten тестовая сеть"
+ "message": "Тестовая сеть Ropsten"
+ },
+ "currentRpc": {
+ "message": "Current RPC"
+ },
+ "connectingToMainnet": {
+ "message": "Соединение с основной сетью Ethereum"
+ },
+ "connectingToRopsten": {
+ "message": "Соединение с тестовой сетью Ropsten"
+ },
+ "connectingToKovan": {
+ "message": "Соединение с тестовой сетью Kovan"
+ },
+ "connectingToRinkeby": {
+ "message": "Соединение с тестовой сетью Rinkeby"
+ },
+ "connectingToUnknown": {
+ "message": "Соединение с неизвестной сетью"
},
"sampleAccountName": {
- "message": "Например, Мой новый аккаунт",
+ "message": "Например, Мой новый счет",
"description": "Help user understand concept of adding a human-readable name to their account"
},
"save": {
"message": "Сохранить"
},
"saveAsFile": {
- "message": "Сохранить как Файл",
+ "message": "Сохранить в виде файла",
"description": "Account export process"
},
"saveSeedAsFile": {
- "message": "Сохранить Семенные Слова Как Файл"
+ "message": "Сохранить ключевую фразу в виде файла"
},
"search": {
"message": "Поиск"
},
"secretPhrase": {
- "message": "Введите свою секретную двенадцатисловную фразу здесь, чтобы восстановить хранилище."
+ "message": "Введите вашу ключевую фразу из 12 слов, чтобы восстановить кошелек."
+ },
+ "newPassword8Chars": {
+ "message": "Новый пароль (мин. 8 символов)"
},
"seedPhraseReq": {
- "message": "семенные фразы длиной 12 слов"
+ "message": "ключевые фразы имеют длину 12 слов"
},
"select": {
"message": "Выбрать"
},
"selectCurrency": {
- "message": "Выберите Валюту"
+ "message": "Выберите валюту"
},
"selectService": {
- "message": "Выберите Сервис"
+ "message": "Выберите сервис"
},
"selectType": {
- "message": "Выберите Тип"
+ "message": "Выберите тип"
},
"send": {
- "message": "Послать"
+ "message": "Отправить"
},
"sendETH": {
"message": "Отправить ETH"
},
"sendTokens": {
- "message": "Отправить Токены"
+ "message": "Отправить токены"
+ },
+ "onlySendToEtherAddress": {
+ "message": "Отправляйте ETH только на Ethereum адреса."
+ },
+ "searchTokens": {
+ "message": "Поиск токенов"
},
"sendTokensAnywhere": {
- "message": "Отправить Токены кому-либо с аккаунтом Ethereum"
+ "message": "Отправить токены любому, у кого есть счет Ethereum"
},
"settings": {
"message": "Настройки"
},
+ "info": {
+ "message": "Информация"
+ },
"shapeshiftBuy": {
- "message": "Купить с помощью Shapeshift"
+ "message": "Купить через Shapeshift"
},
"showPrivateKeys": {
- "message": "Показать приватные ключи"
+ "message": "Показать закрытые ключи"
},
"showQRCode": {
"message": "Показать QR-код"
},
"sign": {
- "message": "Знак"
+ "message": "Подпись"
+ },
+ "signed": {
+ "message": "Подписана"
},
"signMessage": {
- "message": "Нодписать сообщение"
+ "message": "Подписать сообщение"
},
"signNotice": {
- "message": "Подписание этого сообщения может иметь \nопасные побочные эффекты. Только подписывайте сообщения \nс сайтов, которым вы полностью доверяете своим аккаунтом. Этот опасный метод будет удален в будущей версии."
+ "message": "Подпись этого сообщения может иметь \nопасные побочные эффекты. Подписывайте только сообщения \nс сайтов, которым вы полностью доверяете свой аккаунт. Этот опасный метод будет удален в будущей версии."
},
"sigRequest": {
- "message": "Запрос на подпись"
+ "message": "Запрос подписи"
},
"sigRequested": {
- "message": "Подпись Запрошена"
+ "message": "Подпись запрошена"
},
"spaceBetween": {
"message": "между словами может быть только пробел"
@@ -685,53 +753,59 @@
"message": "Статус"
},
"stateLogs": {
- "message": "Логи Статуса"
+ "message": "Журнал состояния"
},
"stateLogsDescription": {
- "message": "Логи статуса содержат ваши общедоступные адреса и отправленные транзакции."
+ "message": "Журнал состояния содержит ваши публичные адреса счетов и совершенные транзакции."
+ },
+ "stateLogError": {
+ "message": "Ошибка при получении журнала состояния."
},
"submit": {
"message": "Отправить"
},
+ "submitted": {
+ "message": "Отправлена"
+ },
"supportCenter": {
- "message": "Посетите наш Центр поддержки"
+ "message": "Перейти в наш Центр поддержки"
},
"symbolBetweenZeroTen": {
"message": "Символ должен быть от 0 до 10 символов."
},
"takesTooLong": {
- "message": "Занимает слишком долго?"
+ "message": "Слишком долго?"
},
"terms": {
- "message": "Условия Эксплуатации"
+ "message": "Условия пользования"
},
"testFaucet": {
- "message": "Тестовый Кран"
+ "message": "Тестовый кран"
},
"to": {
- "message": "К"
+ "message": "Получатель: "
},
"toETHviaShapeShift": {
"message": "$1 в ETH через ShapeShift",
"description": "system will fill in deposit type in start of message"
},
"tokenAddress": {
- "message": "Адрес Токена"
+ "message": "Адрес токена"
},
"tokenAlreadyAdded": {
- "message": "Токен уже добавлен."
+ "message": "Токен уже был добавлен."
},
"tokenBalance": {
- "message": "Баланс Вашых Tокенов:"
+ "message": "Баланс ваших токенов:"
},
"tokenSelection": {
- "message": "Поиск токенов или выбор из нашего списка популярных токенов."
+ "message": "Поищите токен или выберите из нашего списка популярных токенов."
},
"tokenSymbol": {
- "message": "Символ Токена"
+ "message": "Символ токена"
},
"tokenWarning1": {
- "message": "Следите за токенами, которые вы купили с помощью аккаунта MetaMask. Если вы купили токены, используя другой аккаунт, эти токены здесь не появятся."
+ "message": "Отслеживаются токены, купленные на счет в MetaMask. Если вы купили токены, используя другой счет, такие токены не будут тут отображены."
},
"total": {
"message": "Всего"
@@ -740,35 +814,38 @@
"message": "транзакции"
},
"transactionMemo": {
- "message": "Транзакционная записка (необязательно)"
+ "message": "Транзакционные данные (необязательный)"
},
"transactionNumber": {
- "message": "Номер Транзакции"
+ "message": "Номер транзакции"
},
"transfers": {
"message": "Переводы"
},
"troubleTokenBalances": {
- "message": "У нас были проблемы с загрузкой ваших токенов. Вы можете просмотреть их ",
+ "message": "Возникли проблемы при загрузке балансов токенов. Вы можете посмотреть их ",
"description": "Followed by a link (here) to view token balances"
},
"twelveWords": {
- "message": "Эти 12 слов - единственный способ восстановить ваши учетные записи MetaMask.\nСохраните их где-нибудь в безопасности и в тайне."
+ "message": "Эти 12 слов являются единственной возможностью восстановить ваши счета в MetaMask.\nСохраните из в надежном секретном месте."
},
"typePassword": {
- "message": "Введите Пароль"
+ "message": "Введите пароль"
},
"uiWelcome": {
- "message": "Добро пожаловать в новый интерфейс (бета-версия)"
+ "message": "Новый интерфейс (Beta)"
},
"uiWelcomeMessage": {
- "message": "Теперь вы используете новый интерфейс Metamask. Осмотритесь, попробуйте новые функции, такие как отправку токенов, и сообщите нам, есть ли у вас какие-либо проблемы."
+ "message": "Теперь вы используете новый интерфейс пользователя MetaMask. Осмотритесь, попробуйте новые функции, например, отправить токены и, если возникнут проблемы, сообщите нам."
+ },
+ "unapproved": {
+ "message": "Не одобрена"
},
"unavailable": {
- "message": "Недоступен"
+ "message": "Недоступный"
},
"unknown": {
- "message": "Неизвестный"
+ "message": "Неизвестно"
},
"unknownNetwork": {
"message": "Неизвестная частная сеть"
@@ -777,7 +854,7 @@
"message": "Неизвестный идентификатор сети"
},
"uriErrorMsg": {
- "message": "Для URI требуется соответствующий префикс HTTP / HTTPS."
+ "message": "Для URI требуется соответствующий префикс HTTP/HTTPS."
},
"usaOnly": {
"message": "Только США",
@@ -787,19 +864,19 @@
"message": "Используется различными клиентами"
},
"useOldUI": {
- "message": "Использовать старый интерфейс"
+ "message": "Использовать старый интерфейс пользователя"
},
"validFileImport": {
- "message": "Вы должны выбрать действительный файл для импорта."
+ "message": "Вам нужно выбрать правильный файл для импорта."
},
"vaultCreated": {
- "message": "Создано хранилище"
+ "message": "Кошелек был создан"
},
"viewAccount": {
- "message": "Посмотреть аккаунт"
+ "message": "Посмотреть счет"
},
"visitWebSite": {
- "message": "Посетите наш сайт"
+ "message": "Перейти на наш сайт"
},
"warning": {
"message": "Предупреждение"
@@ -811,7 +888,7 @@
"message": "Что это?"
},
"yourSigRequested": {
- "message": "Ваша подпись запрашивается"
+ "message": "Запрашивается ваша подпись"
},
"youSign": {
"message": "Вы подписываете"
diff --git a/app/_locales/sl/messages.json b/app/_locales/sl/messages.json
index 0532f11b2..b089f3476 100644
--- a/app/_locales/sl/messages.json
+++ b/app/_locales/sl/messages.json
@@ -223,7 +223,7 @@
"done": {
"message": "Končano"
},
- "downloadStatelogs": {
+ "downloadStateLogs": {
"message": "Prenesi state dnevnike"
},
"edit": {
diff --git a/app/_locales/th/messages.json b/app/_locales/th/messages.json
index 887714f3f..3d7dec226 100644
--- a/app/_locales/th/messages.json
+++ b/app/_locales/th/messages.json
@@ -223,7 +223,7 @@
"done": {
"message": "เสร็จสิ้น"
},
- "downloadStatelogs": {
+ "downloadStateLogs": {
"message": "ดาวน์โหลดล็อกสถานะ"
},
"edit": {
diff --git a/app/_locales/zh_TW/messages.json b/app/_locales/zh_TW/messages.json
index e39793430..9aaee0e16 100644
--- a/app/_locales/zh_TW/messages.json
+++ b/app/_locales/zh_TW/messages.json
@@ -235,7 +235,7 @@
"done": {
"message": "完成"
},
- "downloadStatelogs": {
+ "downloadStateLogs": {
"message": "下載狀態紀錄"
},
"dropped": {
diff --git a/app/scripts/controllers/transactions.js b/app/scripts/controllers/transactions.js
index 7e2cc15da..a18a2d2e2 100644
--- a/app/scripts/controllers/transactions.js
+++ b/app/scripts/controllers/transactions.js
@@ -161,9 +161,11 @@ module.exports = class TransactionController extends EventEmitter {
this.emit(`${txMeta.id}:unapproved`, txMeta)
}
- async newUnapprovedTransaction (txParams) {
+ async newUnapprovedTransaction (txParams, opts = {}) {
log.debug(`MetaMaskController newUnapprovedTransaction ${JSON.stringify(txParams)}`)
const initialTxMeta = await this.addUnapprovedTransaction(txParams)
+ initialTxMeta.origin = opts.origin
+ this.txStateManager.updateTx(initialTxMeta, '#newUnapprovedTransaction - adding the origin')
// listen for tx completion (success, fail)
return new Promise((resolve, reject) => {
this.txStateManager.once(`${initialTxMeta.id}:finished`, (finishedTxMeta) => {
diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js
index 4422a5cf3..b96acc9da 100644
--- a/app/scripts/metamask-controller.js
+++ b/app/scripts/metamask-controller.js
@@ -57,7 +57,6 @@ module.exports = class MetamaskController extends EventEmitter {
this.defaultMaxListeners = 20
this.sendUpdate = debounce(this.privateSendUpdate.bind(this), 200)
-
this.opts = opts
const initState = opts.initState || {}
this.recordFirstTimeInfo(initState)
@@ -242,6 +241,11 @@ module.exports = class MetamaskController extends EventEmitter {
static: {
eth_syncing: false,
web3_clientVersion: `MetaMask/v${version}`,
+ eth_sendTransaction: (payload, next, end) => {
+ const origin = payload.origin
+ const txParams = payload.params[0]
+ nodeify(this.txController.newUnapprovedTransaction, this.txController)(txParams, { origin }, end)
+ },
},
// account mgmt
getAccounts: (cb) => {
@@ -256,7 +260,6 @@ module.exports = class MetamaskController extends EventEmitter {
cb(null, result)
},
// tx signing
- processTransaction: nodeify(async (txParams) => await this.txController.newUnapprovedTransaction(txParams), this),
// old style msg signing
processMessage: this.newUnsignedMessage.bind(this),
// personal_sign msg signing
diff --git a/development/states/tx-list-items.js b/development/states/tx-list-items.js
new file mode 100644
index 000000000..d567e3fed
--- /dev/null
+++ b/development/states/tx-list-items.js
@@ -0,0 +1,128 @@
+{
+ "metamask": {
+ "isInitialized": true,
+ "isUnlocked": true,
+ "featureFlags": {"betaUI": true},
+ "rpcTarget": "https://rawtestrpc.metamask.io/",
+ "identities": {
+ "0xfdea65c8e26263f6d9a1b5de9555d2931a33b825": {
+ "address": "0xfdea65c8e26263f6d9a1b5de9555d2931a33b825",
+ "name": "Send Account 1"
+ },
+ "0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb": {
+ "address": "0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb",
+ "name": "Send Account 2"
+ },
+ "0x2f8d4a878cfa04a6e60d46362f5644deab66572d": {
+ "address": "0x2f8d4a878cfa04a6e60d46362f5644deab66572d",
+ "name": "Send Account 3"
+ },
+ "0xd85a4b6a394794842887b8284293d69163007bbb": {
+ "address": "0xd85a4b6a394794842887b8284293d69163007bbb",
+ "name": "Send Account 4"
+ }
+ },
+ "currentCurrency": "USD",
+ "conversionRate": 1200.88200327,
+ "conversionDate": 1489013762,
+ "noActiveNotices": true,
+ "frequentRpcList": [],
+ "network": "1",
+ "accounts": {
+ "0xfdea65c8e26263f6d9a1b5de9555d2931a33b825": {
+ "code": "0x",
+ "balance": "0x47c9d71831c76efe",
+ "nonce": "0x1b",
+ "address": "0xfdea65c8e26263f6d9a1b5de9555d2931a33b825"
+ },
+ "0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb": {
+ "code": "0x",
+ "balance": "0x37452b1315889f80",
+ "nonce": "0xa",
+ "address": "0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb"
+ },
+ "0x2f8d4a878cfa04a6e60d46362f5644deab66572d": {
+ "code": "0x",
+ "balance": "0x30c9d71831c76efe",
+ "nonce": "0x1c",
+ "address": "0x2f8d4a878cfa04a6e60d46362f5644deab66572d"
+ },
+ "0xd85a4b6a394794842887b8284293d69163007bbb": {
+ "code": "0x",
+ "balance": "0x0",
+ "nonce": "0x0",
+ "address": "0xd85a4b6a394794842887b8284293d69163007bbb"
+ }
+ },
+ "addressBook": [
+ {
+ "address": "0x06195827297c7a80a443b6894d3bdb8824b43896",
+ "name": "Address Book Account 1"
+ }
+ ],
+ "tokens": [],
+ "transactions": {},
+ "selectedAddressTxList": [
+ {"err":{"message":"Error: [ethjs-rpc] rpc error with payload {\"id\":8726092611900,\"jsonrpc\":\"2.0\",\"params\":[\"0xf8610384773594008094f45d68f31b3c9ac84ff0d07b86c59b753a60b1e3808029a052e5246c9a404f756a246b8cec545099741aeb4e6e0add935a5b7a366fa88f95a0538eaa2421e50377c534244dcdcd15ace00bf9c0adbd9eb162baae2b9e89a36f\"],\"method\":\"eth_sendRawTransaction\"} Error: intrinsic gas too low","stack":"Error: [ethjs-rpc] rpc error with payload {\"id\":8726092611900,\"jsonrpc\":\"2.0\",\"params\":[\"0xf8610384773594008094f45d68f31b3c9ac84ff0d07b86c59b753a60b1e3808029a052e5246c9a404f756a246b8cec545099741aeb4e6e0add935a5b7a366fa88f95a0538eaa2421e50377c534244dcdcd15ace00bf9c0adbd9eb162baae2b9e89a36f\"],\"method\":\"eth_sendRawTransaction\"} Error: intrinsic gas too low\n at chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:72360:28\n at chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:103521:9\n at chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27180:16\n at replenish (chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27024:25)\n at iterateeCallback (chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27014:17)\n at chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27196:16\n at chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:103503:9\n at chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27315:16\n at replenish (chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27029:17)\n at iterateeCallback (chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27014:17)\n at chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27196:16\n at chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:103503:9\n at chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27315:16\n at replenish (chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27029:17)\n at iterateeCallback (chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27014:17)\n at chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27196:16\n at chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:106691:25\n at chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:103501:9\n at chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27315:16\n at replenish (chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27029:17)\n at iterateeCallback (chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27014:17)\n at chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27196:16\n at chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:103503:9\n at chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27315:16\n at replenish (chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27029:17)\n at iterateeCallback (chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27014:17)\n at chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27196:16\n at chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:103503:9\n at chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27315:16\n at replenish (chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27029:17)\n at iterateeCallback (chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27014:17)\n at chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27196:16\n at chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:103503:9\n at chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27315:16\n at replenish (chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27029:17)\n at iterateeCallback (chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27014:17)\n at chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27196:16\n at chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:103503:9\n at chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27315:16\n at replenish (chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27029:17)\n at iterateeCallback (chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27014:17)\n at chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27196:16\n at chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:103503:9\n at chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27315:16\n at replenish (chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27029:17)\n at chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27033:9\n at eachLimit (chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:26723:36)\n at chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:26937:16\n at end (chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:103498:5)\n at chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:106913:40"},"estimatedGas":"0xcf08","gasLimitSpecified":true,"gasPriceSpecified":true,"history":[{"id":4068311466147836,"loadingDefaults":true,"metamaskNetworkId":"1","status":"unapproved","time":1522378334455,"txParams":{"from":"0x5b1cbd5636d484bf1cb6927a9425db9e7dc73ce4","gas":"0xcf08","gasPrice":"0x77359400","to":"0xf45d68f31b3c9ac84ff0d07b86c59b753a60b1e3","value":"0x0"}},[{"op":"replace","path":"/loadingDefaults","value":false},{"op":"add","path":"/gasPriceSpecified","value":true},{"op":"add","path":"/gasLimitSpecified","value":true},{"op":"add","path":"/estimatedGas","value":"0xcf08"}],[{"note":"confTx: user approved transaction","op":"replace","path":"/txParams/gas","value":"0x0"}],[{"note":"txStateManager: setting status to approved","op":"replace","path":"/status","value":"approved"}],[{"note":"transactions#approveTransaction","op":"add","path":"/txParams/nonce","value":"0x3"},{"op":"add","path":"/nonceDetails","value":{"local":{"details":{"highest":3,"startPoint":3},"name":"local","nonce":3},"network":{"details":{"baseCount":3},"name":"network","nonce":3},"params":{"highestLocalNonce":3,"highestSuggested":3,"nextNetworkNonce":3}}}],[{"note":"txStateManager: setting status to signed","op":"add","path":"/txParams/chainId","value":"0x3"},{"op":"replace","path":"/status","value":"signed"}],[{"note":"transactions#publishTransaction","op":"add","path":"/rawTx","value":"0xf8610384773594008094f45d68f31b3c9ac84ff0d07b86c59b753a60b1e3808029a052e5246c9a404f756a246b8cec545099741aeb4e6e0add935a5b7a366fa88f95a0538eaa2421e50377c534244dcdcd15ace00bf9c0adbd9eb162baae2b9e89a36f"}],[{"op":"add","path":"/err","value":{"message":"Error: [ethjs-rpc] rpc error with payload {\"id\":8726092611900,\"jsonrpc\":\"2.0\",\"params\":[\"0xf8610384773594008094f45d68f31b3c9ac84ff0d07b86c59b753a60b1e3808029a052e5246c9a404f756a246b8cec545099741aeb4e6e0add935a5b7a366fa88f95a0538eaa2421e50377c534244dcdcd15ace00bf9c0adbd9eb162baae2b9e89a36f\"],\"method\":\"eth_sendRawTransaction\"} Error: intrinsic gas too low","stack":"Error: [ethjs-rpc] rpc error with payload {\"id\":8726092611900,\"jsonrpc\":\"2.0\",\"params\":[\"0xf8610384773594008094f45d68f31b3c9ac84ff0d07b86c59b753a60b1e3808029a052e5246c9a404f756a246b8cec545099741aeb4e6e0add935a5b7a366fa88f95a0538eaa2421e50377c534244dcdcd15ace00bf9c0adbd9eb162baae2b9e89a36f\"],\"method\":\"eth_sendRawTransaction\"} Error: intrinsic gas too low\n at chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:72360:28\n at chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:103521:9\n at chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27180:16\n at replenish (chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27024:25)\n at iterateeCallback (chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27014:17)\n at chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27196:16\n at chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:103503:9\n at chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27315:16\n at replenish (chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27029:17)\n at iterateeCallback (chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27014:17)\n at chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27196:16\n at chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:103503:9\n at chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27315:16\n at replenish (chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27029:17)\n at iterateeCallback (chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27014:17)\n at chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27196:16\n at chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:106691:25\n at chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:103501:9\n at chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27315:16\n at replenish (chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27029:17)\n at iterateeCallback (chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27014:17)\n at chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27196:16\n at chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:103503:9\n at chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27315:16\n at replenish (chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27029:17)\n at iterateeCallback (chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27014:17)\n at chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27196:16\n at chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:103503:9\n at chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27315:16\n at replenish (chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27029:17)\n at iterateeCallback (chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27014:17)\n at chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27196:16\n at chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:103503:9\n at chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27315:16\n at replenish (chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27029:17)\n at iterateeCallback (chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27014:17)\n at chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27196:16\n at chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:103503:9\n at chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27315:16\n at replenish (chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27029:17)\n at iterateeCallback (chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27014:17)\n at chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27196:16\n at chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:103503:9\n at chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27315:16\n at replenish (chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27029:17)\n at chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:27033:9\n at eachLimit (chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:26723:36)\n at chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:26937:16\n at end (chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:103498:5)\n at chrome-extension://kedndjddlegigbgiknllkjcmbpcnoakf/scripts/background.js:106913:40"}}]],"id":4068311466147836,"loadingDefaults":false,"metamaskNetworkId":"1","nonceDetails":{"local":{"details":{"highest":3,"startPoint":3},"name":"local","nonce":3},"network":{"details":{"baseCount":3},"name":"network","nonce":3},"params":{"highestLocalNonce":3,"highestSuggested":3,"nextNetworkNonce":3}},"rawTx":"0xf8610384773594008094f45d68f31b3c9ac84ff0d07b86c59b753a60b1e3808029a052e5246c9a404f756a246b8cec545099741aeb4e6e0add935a5b7a366fa88f95a0538eaa2421e50377c534244dcdcd15ace00bf9c0adbd9eb162baae2b9e89a36f","status":"failed","time":1522378334455,"txParams":{"chainId":"0x3","from":"0x5b1cbd5636d484bf1cb6927a9425db9e7dc73ce4","gas":"0x0","gasPrice":"0x77359400","nonce":"0x3","to":"0xf45d68f31b3c9ac84ff0d07b86c59b753a60b1e3","value":"0x0"}},
+ {"id":2315363930841933,"time":1522378572149,"status":"approved","metamaskNetworkId":"1","loadingDefaults":false,"txParams":{"from":"0x5b1cbd5636d484bf1cb6927a9425db9e7dc73ce4","to":"0xf45d68f31b3c9ac84ff0d07b86c59b753a60b1e3","value":"0x0","gas":"0x0","gasPrice":"0x5f5e100"},"history":[{"id":2315363930841933,"time":1522378572149,"status":"unapproved","metamaskNetworkId":"1","loadingDefaults":true,"txParams":{"from":"0x5b1cbd5636d484bf1cb6927a9425db9e7dc73ce4","to":"0xf45d68f31b3c9ac84ff0d07b86c59b753a60b1e3","value":"0x0","gas":"0xcf08","gasPrice":"0x5f5e100"}},[{"op":"replace","path":"/loadingDefaults","value":false},{"op":"add","path":"/gasPriceSpecified","value":true},{"op":"add","path":"/gasLimitSpecified","value":true},{"op":"add","path":"/estimatedGas","value":"0xcf08"}],[{"op":"replace","path":"/txParams/gas","value":"0x0","note":"confTx: user approved transaction"}],[{"op":"replace","path":"/status","value":"approved","note":"txStateManager: setting status to approved"}]],"gasPriceSpecified":true,"gasLimitSpecified":true,"estimatedGas":"0xcf08"},
+ {"estimatedGas":"8d41","firstRetryBlockNumber":"0x2cbc70","gasLimitSpecified":false,"gasPriceSpecified":false,"hash":"0xfbd997bf9bb85ca1598952ca23e7910502d527e06cb6ee1bbe7e7dd59d6909cd","history":[{"id":2079438776801906,"loadingDefaults":true,"metamaskNetworkId":"1","status":"unapproved","time":1522346270251,"txParams":{"data":"0xa9059cbb000000000000000000000000e7884118ee52ec3f4eef715cb022279d7d4181a9000000000000000000000000000000000000000000000000000000000000000b","from":"0x5b1cbd5636d484bf1cb6927a9425db9e7dc73ce4","to":"0x66f30b996a7d345cd00badcfe75e81e25dc5e1eb"}},[{"op":"add","path":"/txParams/gasPrice","value":"0x37e11d600"},{"op":"add","path":"/txParams/value","value":"0x0"},{"op":"add","path":"/txParams/gas","value":"0xd3e1"},{"op":"replace","path":"/loadingDefaults","value":false},{"op":"add","path":"/gasPriceSpecified","value":false},{"op":"add","path":"/gasLimitSpecified","value":false},{"op":"add","path":"/estimatedGas","value":"8d41"}],[{"note":"confTx: user approved transaction","op":"replace","path":"/txParams/gasPrice","value":"0x5f5e100"}],[{"note":"txStateManager: setting status to approved","op":"replace","path":"/status","value":"approved"}],[{"note":"transactions#approveTransaction","op":"add","path":"/txParams/nonce","value":"0x2"},{"op":"add","path":"/nonceDetails","value":{"local":{"details":{"highest":2,"startPoint":2},"name":"local","nonce":2},"network":{"details":{"baseCount":2},"name":"network","nonce":2},"params":{"highestLocalNonce":2,"highestSuggested":2,"nextNetworkNonce":2}}}],[{"note":"txStateManager: setting status to signed","op":"add","path":"/txParams/chainId","value":"0x3"},{"op":"replace","path":"/status","value":"signed"}],[{"note":"transactions#publishTransaction","op":"add","path":"/rawTx","value":"0xf8a8028405f5e10082d3e19466f30b996a7d345cd00badcfe75e81e25dc5e1eb80b844a9059cbb000000000000000000000000e7884118ee52ec3f4eef715cb022279d7d4181a9000000000000000000000000000000000000000000000000000000000000000b2aa05cb38a3a68e49008da2e93839f6dedeb96b1630c2a73c4cf5eb3fcc74299a100a039f17c0807469bd101165fa0749dc7065832b4a7c3a382b6cf7e29228c2a683d"}],[{"note":"transactions#setTxHash","op":"add","path":"/hash","value":"0xfbd997bf9bb85ca1598952ca23e7910502d527e06cb6ee1bbe7e7dd59d6909cd"}],[{"note":"txStateManager - add submitted time stamp","op":"add","path":"/submittedTime","value":1522346282571}],[{"note":"txStateManager: setting status to submitted","op":"replace","path":"/status","value":"submitted"}],[{"note":"transactions/pending-tx-tracker#event: tx:block-update","op":"add","path":"/firstRetryBlockNumber","value":"0x2cbc70"}],[{"note":"txStateManager: setting status to confirmed","op":"replace","path":"/status","value":"confirmed"}]],"id":2079438776801906,"loadingDefaults":false,"metamaskNetworkId":"1","nonceDetails":{"local":{"details":{"highest":2,"startPoint":2},"name":"local","nonce":2},"network":{"details":{"baseCount":2},"name":"network","nonce":2},"params":{"highestLocalNonce":2,"highestSuggested":2,"nextNetworkNonce":2}},"rawTx":"0xf8a8028405f5e10082d3e19466f30b996a7d345cd00badcfe75e81e25dc5e1eb80b844a9059cbb000000000000000000000000e7884118ee52ec3f4eef715cb022279d7d4181a9000000000000000000000000000000000000000000000000000000000000000b2aa05cb38a3a68e49008da2e93839f6dedeb96b1630c2a73c4cf5eb3fcc74299a100a039f17c0807469bd101165fa0749dc7065832b4a7c3a382b6cf7e29228c2a683d","status":"confirmed","submittedTime":1522346282571,"time":1522346270251,"txParams":{"chainId":"0x3","data":"0xa9059cbb000000000000000000000000e7884118ee52ec3f4eef715cb022279d7d4181a9000000000000000000000000000000000000000000000000000000000000000b","from":"0x5b1cbd5636d484bf1cb6927a9425db9e7dc73ce4","gas":"0xd3e1","gasPrice":"0x5f5e100","nonce":"0x2","to":"0x66f30b996a7d345cd00badcfe75e81e25dc5e1eb","value":"0x0"}},
+ {"id":4087002078467524,"time":1522379587999,"status":"submitted","metamaskNetworkId":"1","loadingDefaults":false,"txParams":{"from":"0x5b1cbd5636d484bf1cb6927a9425db9e7dc73ce4","to":"0xf45d68f31b3c9ac84ff0d07b86c59b753a60b1e3","value":"0x0","gas":"0xcf08","gasPrice":"0x5f5e100","nonce":"0x3","chainId":"0x3"},"history":[{"id":4087002078467524,"time":1522379587999,"status":"unapproved","metamaskNetworkId":"1","loadingDefaults":true,"txParams":{"from":"0x5b1cbd5636d484bf1cb6927a9425db9e7dc73ce4","to":"0xf45d68f31b3c9ac84ff0d07b86c59b753a60b1e3","value":"0x0","gas":"0xcf08","gasPrice":"0x5f5e100"}},[{"op":"replace","path":"/loadingDefaults","value":false},{"op":"add","path":"/gasPriceSpecified","value":true},{"op":"add","path":"/gasLimitSpecified","value":true},{"op":"add","path":"/estimatedGas","value":"0xcf08"}],[],[{"op":"replace","path":"/status","value":"approved","note":"txStateManager: setting status to approved"}],[{"op":"add","path":"/txParams/nonce","value":"0x3","note":"transactions#approveTransaction"},{"op":"add","path":"/nonceDetails","value":{"params":{"highestLocalNonce":3,"highestSuggested":3,"nextNetworkNonce":3},"local":{"name":"local","nonce":3,"details":{"startPoint":3,"highest":3}},"network":{"name":"network","nonce":3,"details":{"baseCount":3}}}}],[{"op":"add","path":"/txParams/chainId","value":"0x3","note":"txStateManager: setting status to signed"},{"op":"replace","path":"/status","value":"signed"}],[{"op":"add","path":"/rawTx","value":"0xf863038405f5e10082cf0894f45d68f31b3c9ac84ff0d07b86c59b753a60b1e3808029a0d64ed427733ef67fe788fe85d3cfe51c43cfc83d07fa4ab8af5d3bc8c8199895a02699c131cc0ffcf842b54776ac611bdd165fdb87dd3ecff1554ec8da1bf3ff39","note":"transactions#publishTransaction"}],[{"op":"add","path":"/hash","value":"0x52f0929fc143d76f4e6255d95cebfc76b74f43726191bd4081a5ae9bd6c1fa4a","note":"transactions#setTxHash"}],[{"op":"add","path":"/submittedTime","value":1522379590158,"note":"txStateManager - add submitted time stamp"}],[{"op":"replace","path":"/status","value":"submitted","note":"txStateManager: setting status to submitted"}],[{"op":"add","path":"/firstRetryBlockNumber","value":"0x2cc718","note":"transactions/pending-tx-tracker#event: tx:block-update"}]],"gasPriceSpecified":true,"gasLimitSpecified":true,"estimatedGas":"0xcf08","nonceDetails":{"params":{"highestLocalNonce":3,"highestSuggested":3,"nextNetworkNonce":3},"local":{"name":"local","nonce":3,"details":{"startPoint":3,"highest":3}},"network":{"name":"network","nonce":3,"details":{"baseCount":3}}},"rawTx":"0xf863038405f5e10082cf0894f45d68f31b3c9ac84ff0d07b86c59b753a60b1e3808029a0d64ed427733ef67fe788fe85d3cfe51c43cfc83d07fa4ab8af5d3bc8c8199895a02699c131cc0ffcf842b54776ac611bdd165fdb87dd3ecff1554ec8da1bf3ff39","hash":"0x52f0929fc143d76f4e6255d95cebfc76b74f43726191bd4081a5ae9bd6c1fa4a","submittedTime":1522379590158,"firstRetryBlockNumber":"0x2cc718"},
+ {"estimatedGas":"0x5208","gasLimitSpecified":false,"gasPriceSpecified":false,"history":[{"id":6301441591225658,"loadingDefaults":true,"metamaskNetworkId":"1","status":"unapproved","time":1522346051227,"txParams":{"from":"0x5b1cbd5636d484bf1cb6927a9425db9e7dc73ce4","to":"0x81b7e08f65bdf5648606c89998a9cc8164397647","value":"0xde0b6b3a7640000"}},[{"op":"add","path":"/txParams/gasPrice","value":"0x4a817c800"},{"op":"add","path":"/txParams/gas","value":"0x5208"},{"op":"replace","path":"/loadingDefaults","value":false},{"op":"add","path":"/gasPriceSpecified","value":false},{"op":"add","path":"/gasLimitSpecified","value":false},{"op":"add","path":"/simpleSend","value":true},{"op":"add","path":"/estimatedGas","value":"0x5208"}],[{"note":"txStateManager: setting status to rejected","op":"replace","path":"/status","value":"rejected"}]],"id":6301441591225658,"loadingDefaults":false,"metamaskNetworkId":"1","simpleSend":true,"status":"rejected","time":1522346051227,"txParams":{"from":"0x5b1cbd5636d484bf1cb6927a9425db9e7dc73ce4","gas":"0x5208","gasPrice":"0x4a817c800","to":"0x81b7e08f65bdf5648606c89998a9cc8164397647","value":"0xde0b6b3a7640000"}},
+ {"id":2699829174766090,"time":1522381785750,"status":"unapproved","metamaskNetworkId":"1","loadingDefaults":false,"txParams":{"from":"0x5b1cbd5636d484bf1cb6927a9425db9e7dc73ce4","to":"0xf45d68f31b3c9ac84ff0d07b86c59b753a60b1e3","value":"0x0","gas":"0xcf08","gasPrice":"0x5f5e100"},"history":[{"id":2699829174766090,"time":1522381785750,"status":"unapproved","metamaskNetworkId":"1","loadingDefaults":true,"txParams":{"from":"0x5b1cbd5636d484bf1cb6927a9425db9e7dc73ce4","to":"0xf45d68f31b3c9ac84ff0d07b86c59b753a60b1e3","value":"0x0","gas":"0xcf08","gasPrice":"0x5f5e100"}},[{"op":"replace","path":"/loadingDefaults","value":false},{"op":"add","path":"/gasPriceSpecified","value":true},{"op":"add","path":"/gasLimitSpecified","value":true},{"op":"add","path":"/estimatedGas","value":"0xcf08"}]],"gasPriceSpecified":true,"gasLimitSpecified":true,"estimatedGas":"0xcf08"}
+ ],
+ "unapprovedTxs": {"2699829174766090":{"id":2699829174766090,"time":1522381785750,"status":"unapproved","metamaskNetworkId":"1","loadingDefaults":false,"txParams":{"from":"0x5b1cbd5636d484bf1cb6927a9425db9e7dc73ce4","to":"0xf45d68f31b3c9ac84ff0d07b86c59b753a60b1e3","value":"0x0","gas":"0xcf08","gasPrice":"0x5f5e100"},"history":[{"id":2699829174766090,"time":1522381785750,"status":"unapproved","metamaskNetworkId":"1","loadingDefaults":true,"txParams":{"from":"0x5b1cbd5636d484bf1cb6927a9425db9e7dc73ce4","to":"0xf45d68f31b3c9ac84ff0d07b86c59b753a60b1e3","value":"0x0","gas":"0xcf08","gasPrice":"0x5f5e100"}},[{"op":"replace","path":"/loadingDefaults","value":false},{"op":"add","path":"/gasPriceSpecified","value":true},{"op":"add","path":"/gasLimitSpecified","value":true},{"op":"add","path":"/estimatedGas","value":"0xcf08"}]],"gasPriceSpecified":true,"gasLimitSpecified":true,"estimatedGas":"0xcf08"}},
+ "unapprovedMsgs": {"2315363930841932":{"id":2315363930841932,"msgParams":{"from":"0x5b1cbd5636d484bf1cb6927a9425db9e7dc73ce4","data":"0x879a053d4800c6354e76c7985a865d2922c82fb5b3f4577b2fe08b998954f2e0"},"time":1522378539686,"status":"unapproved","type":"eth_sign"}},
+ "unapprovedMsgCount": 0,
+ "unapprovedPersonalMsgs": {},
+ "unapprovedPersonalMsgCount": 0,
+ "keyringTypes": [
+ "Simple Key Pair",
+ "HD Key Tree"
+ ],
+ "keyrings": [
+ {
+ "type": "HD Key Tree",
+ "accounts": [
+ "fdea65c8e26263f6d9a1b5de9555d2931a33b825",
+ "c5b8dbac4c1d3f152cdeb400e2313f309c410acb",
+ "2f8d4a878cfa04a6e60d46362f5644deab66572d"
+ ]
+ },
+ {
+ "type": "Simple Key Pair",
+ "accounts": [
+ "0xd85a4b6a394794842887b8284293d69163007bbb"
+ ]
+ }
+ ],
+ "selectedAddress": "0xd85a4b6a394794842887b8284293d69163007bbb",
+ "provider": {
+ "type": "testnet"
+ },
+ "shapeShiftTxList": [{"depositAddress":"34vJ3AfmNcLiziA4VFgEVcQTwxVLD1qkke","depositType":"BTC","key":"shapeshift","response":{"status":"no_deposits","address":"34vJ3AfmNcLiziA4VFgEVcQTwxVLD1qkke"},"time":1522377459106}],
+ "lostAccounts": [],
+ "send": {},
+ "currentLocale": "en"
+ },
+ "appState": {
+ "menuOpen": false,
+ "currentView": {
+ "name": "confTx",
+ "detailView": null,
+ "context": 0
+ },
+ "accountDetail": {
+ "subview": "transactions"
+ },
+ "modal": {
+ "modalState": {},
+ "previousModalState": {}
+ },
+ "transForward": true,
+ "isLoading": false,
+ "warning": null,
+ "scrollToBottom": false,
+ "forgottenPassword": null
+ },
+ "identities": {}
+}
diff --git a/development/verify-locale-strings.js b/development/verify-locale-strings.js
index b8fe5a7dc..8dc0a30f1 100644
--- a/development/verify-locale-strings.js
+++ b/development/verify-locale-strings.js
@@ -10,87 +10,88 @@
//
////////////////////////////////////////////////////////////////////////////////
-var fs = require('fs')
-var path = require('path')
+const fs = require('fs')
+const path = require('path')
+const localeIndex = require('../app/_locales/index.json')
console.log('Locale Verification')
-var locale = process.argv[2]
-if (!locale || locale == '') {
- console.log('Must enter a locale as argument. exitting')
- process.exit(1)
+const specifiedLocale = process.argv[2]
+if (specifiedLocale) {
+ console.log(`Verifying selected locale "${specifiedLocale}":\n\n`)
+ const locale = localeIndex.find(localeMeta => localeMeta.code === specifiedLocale)
+ verifyLocale({ localeMeta })
+} else {
+ console.log('Verifying all locales:\n\n')
+ localeIndex.forEach(localeMeta => {
+ verifyLocale({ localeMeta })
+ console.log('\n')
+ })
}
-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)
+
+function verifyLocale({ localeMeta }) {
+ const localeCode = localeMeta.code
+ const localeName = localeMeta.name
+
+ try {
+ const localeFilePath = path.join(process.cwd(), 'app', '_locales', localeCode, 'messages.json')
+ targetLocale = 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 ("${localeCode}") file: `, e)
+ }
+ process.exit(1)
}
- 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)
+ try {
+ const englishFilePath = path.join(process.cwd(), 'app', '_locales', 'en', 'messages.json')
+ englishLocale = 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)
}
- process.exit(1)
-}
-console.log('\tverifying whether all your locale strings are contained in the english one')
+ // console.log(' verifying whether all your locale ("${localeCode}") strings are contained in the english one')
+ const extraItems = compareLocalesForMissingItems({ base: targetLocale, subject: englishLocale })
+ // console.log('\n verifying whether your locale ("${localeCode}") contains all english strings')
+ const missingItems = compareLocalesForMissingItems({ base: englishLocale, subject: targetLocale })
-var counter = 0
-var foundErrorA = false
-var notFound = [];
-Object.keys(localeObj).forEach(function(key){
- if (!englishObj[key]) {
- foundErrorA = true
- notFound.push(key)
- }
- counter++
-})
+ const englishEntryCount = Object.keys(englishLocale).length
+ const coveragePercent = 100 * (englishEntryCount - missingItems.length) / englishEntryCount
-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(`Status of **${localeName} (${localeCode})** ${coveragePercent.toFixed(2)}% coverage:`)
-console.log('\n\tverifying whether your locale contains all english strings')
+ if (extraItems.length) {
+ console.log('\nMissing from english locale:')
+ extraItems.forEach(function(key) {
+ console.log(` - [ ] ${key}`)
+ })
+ } else {
+ // console.log(` all ${counter} strings declared in your locale ("${localeCode}") were found in the english one`)
+ }
-var counter = 0
-var foundErrorB = false
-var notFound = [];
-Object.keys(englishObj).forEach(function(key){
- if (!localeObj[key]) {
- foundErrorB = true
- notFound.push(key)
+ if (missingItems.length) {
+ console.log(`\nMissing:`)
+ missingItems.forEach(function(key) {
+ console.log(` - [ ] ${key}`)
+ })
+ } else {
+ // console.log(` all ${counter} english strings were found in your locale ("${localeCode}")!`)
}
- 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 (!extraItems.length && !missingItems.length) {
+ console.log('Full coverage : )')
+ }
}
-if (!foundErrorA && !foundErrorB) {
- console.log('You are good to go')
-} \ No newline at end of file
+function compareLocalesForMissingItems({ base, subject }) {
+ return Object.keys(base).filter((key) => !subject[key])
+}
diff --git a/docs/translating-guide.md b/docs/translating-guide.md
index ae2dfecd3..8b2bc1785 100644
--- a/docs/translating-guide.md
+++ b/docs/translating-guide.md
@@ -6,9 +6,12 @@ The MetaMask browser extension supports new translations added in the form of ne
## Adding a new Language
-Each supported language is represented by a folder in `app/_locales` whose name is that language's subtag ([look up a language subtag using this tool](https://r12a.github.io/app-subtags/)).
+- Each supported language is represented by a folder in `app/_locales` whose name is that language's subtag (example: `app/_locales/es/`). (look up a language subtag using the [r12a "Find" tool](https://r12a.github.io/app-subtags/) or this [wikipedia list](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes)).
+- Inside that folder there should be a `messages.json`.
+- An easy way to start your translation is to first **make a copy** of `app/_locales/en/messages.json` (the english translation), and then **translate the `message` key** for each in-app message.
+- **The `description` key** is just to add context for what the translation is about, it **does not need to be translated**.
+- Add the language to the [locales index](https://github.com/MetaMask/metamask-extension/blob/master/app/_locales/index.json) `app/_locales/index.json`
-Inside that folder there should be a `messages.json` file that follows the specified format. An easy way to start your translation is to first duplicate `app/_locales/en/messages.json` (the english translation), and then update the `message` key for each in-app message.
That's it! When MetaMask is loaded on a computer with that language set as the system language, they will see your translation instead of the default one.
@@ -20,7 +23,7 @@ To automatically see if you are missing any phrases to translate, we have a scri
node development/verify-locale-strings.js $YOUR_LOCALE
```
-Where `$YOUR_LOCALE` is your [locale string](https://r12a.github.io/app-subtags/), i.e. the name of your language folder.
+Where `$YOUR_LOCALE` is your locale string (example: `es`), i.e. the name of your language folder.
To verify that your translation works in the app, you will need to [build a local copy](https://github.com/MetaMask/metamask-extension#building-locally) of MetaMask. You will need to change your browser language, your operating system language, and restart your browser (sorry it's so much work!).
diff --git a/gulpfile.js b/gulpfile.js
index 3ca0c65de..1eb0a974b 100644
--- a/gulpfile.js
+++ b/gulpfile.js
@@ -16,7 +16,6 @@ const eslint = require('gulp-eslint')
const fs = require('fs')
const path = require('path')
const manifest = require('./app/manifest.json')
-const gulpif = require('gulp-if')
const replace = require('gulp-replace')
const mkdirp = require('mkdirp')
const asyncEach = require('async/each')
@@ -31,8 +30,6 @@ const debug = require('gulp-debug')
const pify = require('pify')
const endOfStream = pify(require('end-of-stream'))
-const disableDebugTools = gutil.env.disableDebugTools
-const debugMode = gutil.env.debug
const browserPlatforms = [
'firefox',
@@ -181,12 +178,12 @@ gulp.task('manifest:production', function() {
],{base: './dist/'})
// Exclude chromereload script in production:
- .pipe(gulpif(!debugMode,jsoneditor(function(json) {
+ .pipe(jsoneditor(function(json) {
json.background.scripts = json.background.scripts.filter((script) => {
return !script.includes('chromereload')
})
return json
- })))
+ }))
.pipe(gulp.dest('./dist/', { overwrite: true }))
})
@@ -311,6 +308,7 @@ function createTasksForBuildJsExtension({ buildJsFiles, taskPrefix, devMode, bun
minifyBuild: !devMode,
buildWithFullPaths: devMode,
watch: devMode,
+ devMode,
}, bundleTaskOpts)
createTasksForBuildJs({ rootDir, taskPrefix, bundleTaskOpts, destinations, buildPhase1, buildPhase2 })
}
@@ -326,6 +324,7 @@ function createTasksForBuildJsMascara({ taskPrefix, devMode, bundleTaskOpts = {}
minifyBuild: !devMode,
buildWithFullPaths: devMode,
watch: devMode,
+ devMode,
}, bundleTaskOpts)
createTasksForBuildJs({ rootDir, taskPrefix, bundleTaskOpts, destinations, buildPhase1 })
}
@@ -541,7 +540,7 @@ function bundleTask(opts) {
// convert bundle stream to gulp vinyl stream
.pipe(source(opts.filename))
// inject variables into bundle
- .pipe(replace('\'GULP_METAMASK_DEBUG\'', debugMode))
+ .pipe(replace('\'GULP_METAMASK_DEBUG\'', opts.devMode))
// buffer file contents (?)
.pipe(buffer())
diff --git a/old-ui/app/components/transaction-list-item.js b/old-ui/app/components/transaction-list-item.js
index 7ab3414e5..f7d59005a 100644
--- a/old-ui/app/components/transaction-list-item.js
+++ b/old-ui/app/components/transaction-list-item.js
@@ -31,6 +31,11 @@ function TransactionListItem () {
TransactionListItem.prototype.showRetryButton = function () {
const { transaction = {}, transactions } = this.props
const { status, submittedTime, txParams } = transaction
+
+ if (!txParams) {
+ return false
+ }
+
const currentNonce = txParams.nonce
const currentNonceTxs = transactions.filter(tx => tx.txParams.nonce === currentNonce)
const currentNonceSubmittedTxs = currentNonceTxs.filter(tx => tx.status === 'submitted')
diff --git a/package-lock.json b/package-lock.json
index 2c9aab522..2f02f637d 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -4336,36 +4336,6 @@
"escope": "3.6.0",
"through2": "2.0.3",
"yargs": "6.6.0"
- },
- "dependencies": {
- "yargs": {
- "version": "6.6.0",
- "resolved": "https://registry.npmjs.org/yargs/-/yargs-6.6.0.tgz",
- "integrity": "sha1-eC7CHvQDNF+DCoCMo9UTr1YGUgg=",
- "requires": {
- "camelcase": "3.0.0",
- "cliui": "3.2.0",
- "decamelize": "1.2.0",
- "get-caller-file": "1.0.2",
- "os-locale": "1.4.0",
- "read-pkg-up": "1.0.1",
- "require-directory": "2.1.1",
- "require-main-filename": "1.0.1",
- "set-blocking": "2.0.0",
- "string-width": "1.0.2",
- "which-module": "1.0.0",
- "y18n": "3.2.1",
- "yargs-parser": "4.2.1"
- }
- },
- "yargs-parser": {
- "version": "4.2.1",
- "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-4.2.1.tgz",
- "integrity": "sha1-KczqwNxPA8bIe0qfIX3RjJ90hxw=",
- "requires": {
- "camelcase": "3.0.0"
- }
- }
}
},
"des.js": {
@@ -5923,7 +5893,7 @@
"ethereumjs-vm": "2.3.2",
"through2": "2.0.3",
"treeify": "1.1.0",
- "web3-provider-engine": "13.6.0"
+ "web3-provider-engine": "13.8.0"
}
},
"ethereum-common": {
@@ -7342,12 +7312,6 @@
"resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
"integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE="
},
- "fork-stream": {
- "version": "0.0.4",
- "resolved": "https://registry.npmjs.org/fork-stream/-/fork-stream-0.0.4.tgz",
- "integrity": "sha1-24Sfznf2cIpfjzhq5TOgkHtUrnA=",
- "dev": true
- },
"form-data": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.1.tgz",
@@ -8880,7 +8844,7 @@
"isurl": "1.0.0",
"lowercase-keys": "1.0.1",
"mimic-response": "1.0.0",
- "p-cancelable": "0.4.0",
+ "p-cancelable": "0.4.1",
"p-timeout": "2.0.1",
"pify": "3.0.0",
"safe-buffer": "5.1.1",
@@ -9150,17 +9114,6 @@
"gulp-util": "3.0.8"
}
},
- "gulp-if": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/gulp-if/-/gulp-if-2.0.2.tgz",
- "integrity": "sha1-pJe351cwBQQcqivIt92jyARE1ik=",
- "dev": true,
- "requires": {
- "gulp-match": "1.0.3",
- "ternary-stream": "2.0.1",
- "through2": "2.0.3"
- }
- },
"gulp-json-editor": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/gulp-json-editor/-/gulp-json-editor-2.2.1.tgz",
@@ -9312,15 +9265,6 @@
}
}
},
- "gulp-match": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/gulp-match/-/gulp-match-1.0.3.tgz",
- "integrity": "sha1-kcfA1/Kb7NZgbVfYCn+Hdqh6uo4=",
- "dev": true,
- "requires": {
- "minimatch": "3.0.4"
- }
- },
"gulp-replace": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/gulp-replace/-/gulp-replace-0.6.1.tgz",
@@ -9717,7 +9661,7 @@
"dev": true,
"requires": {
"anymatch": "1.3.2",
- "chokidar": "2.0.1",
+ "chokidar": "2.0.3",
"glob-parent": "3.1.0",
"gulp-util": "3.0.8",
"object-assign": "4.1.1",
@@ -9741,9 +9685,9 @@
"dev": true
},
"braces": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.0.tgz",
- "integrity": "sha512-P4O8UQRdGiMLWSizsApmXVQDBS6KCt7dSexgLKBmH5Hr1CZq7vsnscFh8oR1sP1ab1Zj0uCHCEzZeV6SfUf3rA==",
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.1.tgz",
+ "integrity": "sha512-SO5lYHA3vO6gz66erVvedSCkp7AKWdv6VcQ2N4ysXfPxdAlxAMMAdwegGGcv1Bqwm7naF1hNdk5d6AAIEHV2nQ==",
"dev": true,
"requires": {
"arr-flatten": "1.1.0",
@@ -9752,22 +9696,43 @@
"extend-shallow": "2.0.1",
"fill-range": "4.0.0",
"isobject": "3.0.1",
+ "kind-of": "6.0.2",
"repeat-element": "1.1.2",
"snapdragon": "0.8.1",
"snapdragon-node": "2.1.1",
"split-string": "3.1.0",
- "to-regex": "3.0.1"
+ "to-regex": "3.0.2"
+ },
+ "dependencies": {
+ "define-property": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
+ "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "1.0.2"
+ }
+ },
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "dev": true,
+ "requires": {
+ "is-extendable": "0.1.1"
+ }
+ }
}
},
"chokidar": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.0.1.tgz",
- "integrity": "sha512-rv5iP8ENhpqvDWr677rAXcB+SMoPQ1urd4ch79+PhM4lQwbATdJUQK69t0lJIKNB+VXpqxt5V1gvqs59XEPKnw==",
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.0.3.tgz",
+ "integrity": "sha512-zW8iXYZtXMx4kux/nuZVXjkLP+CyIK5Al5FHnj1OgTKGZfp4Oy6/ymtMSKFv3GD8DviEmUPmJg9eFdJ/JzudMg==",
"dev": true,
"requires": {
"anymatch": "2.0.0",
"async-each": "1.0.1",
- "braces": "2.3.0",
+ "braces": "2.3.1",
"fsevents": "1.1.3",
"glob-parent": "3.1.0",
"inherits": "2.0.3",
@@ -9776,7 +9741,7 @@
"normalize-path": "2.1.1",
"path-is-absolute": "1.0.1",
"readdirp": "2.1.0",
- "upath": "1.0.0"
+ "upath": "1.0.4"
},
"dependencies": {
"anymatch": {
@@ -9785,12 +9750,22 @@
"integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==",
"dev": true,
"requires": {
- "micromatch": "3.1.5",
+ "micromatch": "3.1.10",
"normalize-path": "2.1.1"
}
}
}
},
+ "define-property": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz",
+ "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "1.0.2",
+ "isobject": "3.0.1"
+ }
+ },
"expand-brackets": {
"version": "2.1.4",
"resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz",
@@ -9803,7 +9778,7 @@
"posix-character-classes": "0.1.1",
"regex-not": "1.0.0",
"snapdragon": "0.8.1",
- "to-regex": "3.0.1"
+ "to-regex": "3.0.2"
},
"dependencies": {
"define-property": {
@@ -9814,6 +9789,53 @@
"requires": {
"is-descriptor": "0.1.6"
}
+ },
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "dev": true,
+ "requires": {
+ "is-extendable": "0.1.1"
+ }
+ },
+ "is-descriptor": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz",
+ "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==",
+ "dev": true,
+ "requires": {
+ "is-accessor-descriptor": "0.1.6",
+ "is-data-descriptor": "0.1.4",
+ "kind-of": "5.1.0"
+ }
+ },
+ "kind-of": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
+ "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==",
+ "dev": true
+ }
+ }
+ },
+ "extend-shallow": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz",
+ "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=",
+ "dev": true,
+ "requires": {
+ "assign-symbols": "1.0.0",
+ "is-extendable": "1.0.1"
+ },
+ "dependencies": {
+ "is-extendable": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
+ "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
+ "dev": true,
+ "requires": {
+ "is-plain-object": "2.0.4"
+ }
}
}
},
@@ -9830,7 +9852,27 @@
"fragment-cache": "0.2.1",
"regex-not": "1.0.0",
"snapdragon": "0.8.1",
- "to-regex": "3.0.1"
+ "to-regex": "3.0.2"
+ },
+ "dependencies": {
+ "define-property": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
+ "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "1.0.2"
+ }
+ },
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "dev": true,
+ "requires": {
+ "is-extendable": "0.1.1"
+ }
+ }
}
},
"fill-range": {
@@ -9843,6 +9885,17 @@
"is-number": "3.0.0",
"repeat-string": "1.6.1",
"to-regex-range": "2.1.1"
+ },
+ "dependencies": {
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "dev": true,
+ "requires": {
+ "is-extendable": "0.1.1"
+ }
+ }
}
},
"glob-parent": {
@@ -9906,25 +9959,6 @@
}
}
},
- "is-descriptor": {
- "version": "0.1.6",
- "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz",
- "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==",
- "dev": true,
- "requires": {
- "is-accessor-descriptor": "0.1.6",
- "is-data-descriptor": "0.1.4",
- "kind-of": "5.1.0"
- },
- "dependencies": {
- "kind-of": {
- "version": "5.1.0",
- "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
- "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==",
- "dev": true
- }
- }
- },
"is-extglob": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
@@ -9973,24 +10007,48 @@
"dev": true
},
"micromatch": {
- "version": "3.1.5",
- "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.5.tgz",
- "integrity": "sha512-ykttrLPQrz1PUJcXjwsTUjGoPJ64StIGNE2lGVD1c9CuguJ+L7/navsE8IcDNndOoCMvYV0qc/exfVbMHkUhvA==",
+ "version": "3.1.10",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz",
+ "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==",
"dev": true,
"requires": {
"arr-diff": "4.0.0",
"array-unique": "0.3.2",
- "braces": "2.3.0",
- "define-property": "1.0.0",
- "extend-shallow": "2.0.1",
+ "braces": "2.3.1",
+ "define-property": "2.0.2",
+ "extend-shallow": "3.0.2",
"extglob": "2.0.4",
"fragment-cache": "0.2.1",
"kind-of": "6.0.2",
- "nanomatch": "1.2.7",
+ "nanomatch": "1.2.9",
"object.pick": "1.3.0",
"regex-not": "1.0.0",
"snapdragon": "0.8.1",
- "to-regex": "3.0.1"
+ "to-regex": "3.0.2"
+ }
+ },
+ "to-regex": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz",
+ "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==",
+ "dev": true,
+ "requires": {
+ "define-property": "2.0.2",
+ "extend-shallow": "3.0.2",
+ "regex-not": "1.0.2",
+ "safe-regex": "1.1.0"
+ },
+ "dependencies": {
+ "regex-not": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz",
+ "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==",
+ "dev": true,
+ "requires": {
+ "extend-shallow": "3.0.2",
+ "safe-regex": "1.1.0"
+ }
+ }
}
}
}
@@ -11187,22 +11245,19 @@
}
},
"is-odd": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-odd/-/is-odd-1.0.0.tgz",
- "integrity": "sha1-O4qTLrAos3dcObsJ6RdnrM22kIg=",
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-odd/-/is-odd-2.0.0.tgz",
+ "integrity": "sha512-OTiixgpZAT1M4NHgS5IguFp/Vz2VI3U7Goh4/HA1adtwyLtSBrxYlcSYkhpAE07s4fKEcjrFxyvtQBND4vFQyQ==",
"dev": true,
"requires": {
- "is-number": "3.0.0"
+ "is-number": "4.0.0"
},
"dependencies": {
"is-number": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
- "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
- "dev": true,
- "requires": {
- "kind-of": "3.2.2"
- }
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz",
+ "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==",
+ "dev": true
}
}
},
@@ -11508,7 +11563,7 @@
"babel-preset-es2015": "6.24.1",
"babel-preset-stage-1": "6.24.1",
"babel-register": "6.26.0",
- "babylon": "7.0.0-beta.42",
+ "babylon": "7.0.0-beta.43",
"colors": "1.2.1",
"flow-parser": "0.69.0",
"lodash": "4.17.4",
@@ -11534,9 +11589,9 @@
"dev": true
},
"babylon": {
- "version": "7.0.0-beta.42",
- "resolved": "https://registry.npmjs.org/babylon/-/babylon-7.0.0-beta.42.tgz",
- "integrity": "sha512-h6E/OkkvcBw/JimbL0p8dIaxrcuQn3QmIYGC/GtJlRYif5LTKBYPHXYwqluJpfS/kOXoz0go+9mkmOVC0M+zWw==",
+ "version": "7.0.0-beta.43",
+ "resolved": "https://registry.npmjs.org/babylon/-/babylon-7.0.0-beta.43.tgz",
+ "integrity": "sha512-kvgnRG/fXBtvezILk/oxGGMHKUznYqRDrnNfj/aJ1r3b1Mqx4PO3vaUrkkJIfqxLM+uwzKGcmornX3NT4pu5xw==",
"dev": true
},
"chalk": {
@@ -14119,15 +14174,6 @@
"resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
"integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E="
},
- "merge-stream": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-1.0.1.tgz",
- "integrity": "sha1-QEEgLVCKNCugAXQAjfDCUbjBNeE=",
- "dev": true,
- "requires": {
- "readable-stream": "2.3.3"
- }
- },
"merkle-patricia-tree": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/merkle-patricia-tree/-/merkle-patricia-tree-2.3.0.tgz",
@@ -14627,18 +14673,19 @@
"integrity": "sha1-7XFfP+neArV6XmJS2QqWZ14fCFo="
},
"nanomatch": {
- "version": "1.2.7",
- "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.7.tgz",
- "integrity": "sha512-/5ldsnyurvEw7wNpxLFgjVvBLMta43niEYOy0CJ4ntcYSbx6bugRUTQeFb4BR/WanEL1o3aQgHuVLHQaB6tOqg==",
+ "version": "1.2.9",
+ "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.9.tgz",
+ "integrity": "sha512-n8R9bS8yQ6eSXaV6jHUpKzD8gLsin02w1HSFiegwrs9E098Ylhw5jdyKPaYqvHknHaSCKTPp7C8dGCQ0q9koXA==",
"dev": true,
"requires": {
"arr-diff": "4.0.0",
"array-unique": "0.3.2",
- "define-property": "1.0.0",
- "extend-shallow": "2.0.1",
+ "define-property": "2.0.2",
+ "extend-shallow": "3.0.2",
"fragment-cache": "0.2.1",
- "is-odd": "1.0.0",
- "kind-of": "5.1.0",
+ "is-odd": "2.0.0",
+ "is-windows": "1.0.2",
+ "kind-of": "6.0.2",
"object.pick": "1.3.0",
"regex-not": "1.0.0",
"snapdragon": "0.8.1",
@@ -14657,10 +14704,45 @@
"integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=",
"dev": true
},
+ "define-property": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz",
+ "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "1.0.2",
+ "isobject": "3.0.1"
+ }
+ },
+ "extend-shallow": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz",
+ "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=",
+ "dev": true,
+ "requires": {
+ "assign-symbols": "1.0.0",
+ "is-extendable": "1.0.1"
+ }
+ },
+ "is-extendable": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
+ "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
+ "dev": true,
+ "requires": {
+ "is-plain-object": "2.0.4"
+ }
+ },
+ "isobject": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+ "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
+ "dev": true
+ },
"kind-of": {
- "version": "5.1.0",
- "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
- "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==",
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
+ "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==",
"dev": true
}
}
@@ -17553,9 +17635,9 @@
}
},
"p-cancelable": {
- "version": "0.4.0",
- "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-0.4.0.tgz",
- "integrity": "sha512-/AodqPe1y/GYbhSlnMjxukLGQfQIgsmjSy2CXCNB96kg4ozKvmlovuHEKICToOO/yS3LLWgrWI1dFtFfrePS1g==",
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-0.4.1.tgz",
+ "integrity": "sha512-HNa1A8LvB1kie7cERyy21VNeHb2CWJJYqyyC2o3klWFfMGlFmWv2Z7sFgZH8ZiaYL95ydToKTFVXgMV/Os0bBQ==",
"dev": true
},
"p-each-series": {
@@ -19929,6 +20011,15 @@
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz",
"integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg=="
},
+ "safe-regex": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz",
+ "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=",
+ "dev": true,
+ "requires": {
+ "ret": "0.1.15"
+ }
+ },
"samsam": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/samsam/-/samsam-1.3.0.tgz",
@@ -20290,6 +20381,126 @@
"requires": {
"once": "1.4.0",
"yargs": "11.0.0"
+ },
+ "dependencies": {
+ "ansi-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
+ "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
+ "dev": true
+ },
+ "camelcase": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz",
+ "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=",
+ "dev": true
+ },
+ "cliui": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.0.0.tgz",
+ "integrity": "sha512-nY3W5Gu2racvdDk//ELReY+dHjb9PlIcVDFXP72nVIhq2Gy3LuVXYwJoPVudwQnv1shtohpgkdCKT2YaKY0CKw==",
+ "dev": true,
+ "requires": {
+ "string-width": "2.1.1",
+ "strip-ansi": "4.0.0",
+ "wrap-ansi": "2.1.0"
+ }
+ },
+ "execa": {
+ "version": "0.7.0",
+ "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz",
+ "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=",
+ "dev": true,
+ "requires": {
+ "cross-spawn": "5.1.0",
+ "get-stream": "3.0.0",
+ "is-stream": "1.1.0",
+ "npm-run-path": "2.0.2",
+ "p-finally": "1.0.0",
+ "signal-exit": "3.0.2",
+ "strip-eof": "1.0.0"
+ }
+ },
+ "find-up": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz",
+ "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=",
+ "dev": true,
+ "requires": {
+ "locate-path": "2.0.0"
+ }
+ },
+ "is-fullwidth-code-point": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
+ "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
+ "dev": true
+ },
+ "os-locale": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-2.1.0.tgz",
+ "integrity": "sha512-3sslG3zJbEYcaC4YVAvDorjGxc7tv6KVATnLPZONiljsUncvihe9BQoVCEs0RZ1kmf4Hk9OBqlZfJZWI4GanKA==",
+ "dev": true,
+ "requires": {
+ "execa": "0.7.0",
+ "lcid": "1.0.0",
+ "mem": "1.1.0"
+ }
+ },
+ "string-width": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
+ "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
+ "dev": true,
+ "requires": {
+ "is-fullwidth-code-point": "2.0.0",
+ "strip-ansi": "4.0.0"
+ }
+ },
+ "strip-ansi": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
+ "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "3.0.0"
+ }
+ },
+ "which-module": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz",
+ "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=",
+ "dev": true
+ },
+ "yargs": {
+ "version": "11.0.0",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-11.0.0.tgz",
+ "integrity": "sha512-Rjp+lMYQOWtgqojx1dEWorjCofi1YN7AoFvYV7b1gx/7dAAeuI4kN5SZiEvr0ZmsZTOpDRcCqrpI10L31tFkBw==",
+ "dev": true,
+ "requires": {
+ "cliui": "4.0.0",
+ "decamelize": "1.2.0",
+ "find-up": "2.1.0",
+ "get-caller-file": "1.0.2",
+ "os-locale": "2.1.0",
+ "require-directory": "2.1.1",
+ "require-main-filename": "1.0.1",
+ "set-blocking": "2.0.0",
+ "string-width": "2.1.1",
+ "which-module": "2.0.0",
+ "y18n": "3.2.1",
+ "yargs-parser": "9.0.2"
+ }
+ },
+ "yargs-parser": {
+ "version": "9.0.2",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-9.0.2.tgz",
+ "integrity": "sha1-nM9qQ0YP5O1Aqbto9I1DuKaMwHc=",
+ "dev": true,
+ "requires": {
+ "camelcase": "4.1.0"
+ }
+ }
}
},
"shell-quote": {
@@ -20730,9 +20941,9 @@
}
},
"solc": {
- "version": "0.4.20",
- "resolved": "https://registry.npmjs.org/solc/-/solc-0.4.20.tgz",
- "integrity": "sha512-LrP3Jp4FS3y8sduIR67y8Ss1riR3fggk5sMnx4OSCcU88Ro0e51+KVXyfH3NP6ghLo7COrLx/lGUaDDugCzdgA==",
+ "version": "0.4.21",
+ "resolved": "https://registry.npmjs.org/solc/-/solc-0.4.21.tgz",
+ "integrity": "sha512-8lJmimVjOG9AJOQRWS2ph4rSctPMsPGZ4H360HLs5iI+euUlt7iAvUxSLeFZZzwk0kas4Qta7HmlMXNU3yYwhw==",
"requires": {
"fs-extra": "0.30.0",
"memorystream": "0.3.1",
@@ -22225,18 +22436,6 @@
}
}
},
- "ternary-stream": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/ternary-stream/-/ternary-stream-2.0.1.tgz",
- "integrity": "sha1-Bk5Im0tb9gumpre8fy9cJ07Pgmk=",
- "dev": true,
- "requires": {
- "duplexify": "3.5.1",
- "fork-stream": "0.0.4",
- "merge-stream": "1.0.1",
- "through2": "2.0.3"
- }
- },
"testem": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/testem/-/testem-2.0.0.tgz",
@@ -22965,12 +23164,6 @@
"integrity": "sha1-YaajIBBiKvoHljvzJSA88SI51gQ=",
"dev": true
},
- "underscore.string": {
- "version": "2.3.3",
- "resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-2.3.3.tgz",
- "integrity": "sha1-ccCL9rQosRM/N+ePo6Icgvcymw0=",
- "dev": true
- },
"undertaker": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/undertaker/-/undertaker-1.2.0.tgz",
@@ -23137,22 +23330,10 @@
"dev": true
},
"upath": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/upath/-/upath-1.0.0.tgz",
- "integrity": "sha1-tHBrlGHKhHOt+JEz0jVonKF/NlY=",
- "dev": true,
- "requires": {
- "lodash": "3.10.1",
- "underscore.string": "2.3.3"
- },
- "dependencies": {
- "lodash": {
- "version": "3.10.1",
- "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz",
- "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=",
- "dev": true
- }
- }
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/upath/-/upath-1.0.4.tgz",
+ "integrity": "sha512-d4SJySNBXDaQp+DPrziv3xGS6w3d2Xt69FijJr86zMPBy23JEloMCEOUBBzuN7xCtjLCnmB9tI/z7SBCahHBOw==",
+ "dev": true
},
"urix": {
"version": "0.1.0",
@@ -23461,9 +23642,9 @@
},
"dependencies": {
"clone": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.3.tgz",
- "integrity": "sha1-KY1+IjFmD0DAA8LtMUDezz9TCF8=",
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz",
+ "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=",
"dev": true
},
"clone-stats": {
@@ -23490,7 +23671,7 @@
"integrity": "sha1-XIgDbPVl5d8FVYv8kR+GVt8hiIQ=",
"dev": true,
"requires": {
- "clone": "1.0.3",
+ "clone": "1.0.4",
"clone-stats": "0.0.1",
"replace-ext": "0.0.1"
}
@@ -23832,9 +24013,9 @@
}
},
"web3-provider-engine": {
- "version": "13.6.0",
- "resolved": "https://registry.npmjs.org/web3-provider-engine/-/web3-provider-engine-13.6.0.tgz",
- "integrity": "sha512-iCsAlAeLWHxgx6EXuBm5GNg5VBqKtzmnrhEOfJBv8Cetukush7yOvo4RPjDZIynKxg9jfAlMmWqCk6wLxA6coQ==",
+ "version": "13.8.0",
+ "resolved": "https://registry.npmjs.org/web3-provider-engine/-/web3-provider-engine-13.8.0.tgz",
+ "integrity": "sha512-fZXhX5VWwWpoFfrfocslyg6P7cN3YWPG/ASaevNfeO80R+nzgoPUBXcWQekSGSsNDkeRTis4aMmpmofYf1TNtQ==",
"requires": {
"async": "2.6.0",
"clone": "2.1.1",
@@ -23842,7 +24023,7 @@
"eth-sig-util": "1.4.2",
"ethereumjs-block": "1.7.0",
"ethereumjs-tx": "1.3.3",
- "ethereumjs-util": "5.1.4",
+ "ethereumjs-util": "5.1.5",
"ethereumjs-vm": "2.3.2",
"fetch-ponyfill": "4.1.0",
"json-rpc-error": "2.0.0",
@@ -23851,16 +24032,16 @@
"readable-stream": "2.3.3",
"request": "2.83.0",
"semaphore": "1.1.0",
- "solc": "0.4.20",
+ "solc": "0.4.21",
"tape": "4.8.0",
"xhr": "2.4.1",
"xtend": "4.0.1"
},
"dependencies": {
"ethereumjs-util": {
- "version": "5.1.4",
- "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.1.4.tgz",
- "integrity": "sha512-wbeTc5prEzIWFSQUcEsCAZbqubtJKy6yS+oZMY1cGG6GLYzLjm4YhC2RNrWIg8hRYnclWpnZmx2zkiufQkmd3w==",
+ "version": "5.1.5",
+ "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.1.5.tgz",
+ "integrity": "sha512-xPaSEATYJpMTCGowIt0oMZwFP4R1bxd6QsWgkcDvFL0JtXsr39p32WEcD14RscCjfP41YXZPCVWA4yAg0nrJmw==",
"requires": {
"bn.js": "4.11.8",
"create-hash": "1.1.3",
@@ -23999,58 +24180,6 @@
"version": "0.0.2",
"resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz",
"integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8="
- },
- "yargs": {
- "version": "6.6.0",
- "resolved": "https://registry.npmjs.org/yargs/-/yargs-6.6.0.tgz",
- "integrity": "sha1-eC7CHvQDNF+DCoCMo9UTr1YGUgg=",
- "requires": {
- "camelcase": "3.0.0",
- "cliui": "3.2.0",
- "decamelize": "1.2.0",
- "get-caller-file": "1.0.2",
- "os-locale": "1.4.0",
- "read-pkg-up": "1.0.1",
- "require-directory": "2.1.1",
- "require-main-filename": "1.0.1",
- "set-blocking": "2.0.0",
- "string-width": "1.0.2",
- "which-module": "1.0.0",
- "y18n": "3.2.1",
- "yargs-parser": "4.2.1"
- },
- "dependencies": {
- "camelcase": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz",
- "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo="
- },
- "cliui": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz",
- "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=",
- "requires": {
- "string-width": "1.0.2",
- "strip-ansi": "3.0.1",
- "wrap-ansi": "2.1.0"
- }
- }
- }
- },
- "yargs-parser": {
- "version": "4.2.1",
- "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-4.2.1.tgz",
- "integrity": "sha1-KczqwNxPA8bIe0qfIX3RjJ90hxw=",
- "requires": {
- "camelcase": "3.0.0"
- },
- "dependencies": {
- "camelcase": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz",
- "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo="
- }
- }
}
}
},
@@ -24193,7 +24322,7 @@
"v8-compile-cache": "1.1.2",
"webpack-addons": "1.1.5",
"yargs": "11.0.0",
- "yeoman-environment": "2.0.5",
+ "yeoman-environment": "2.0.6",
"yeoman-generator": "2.0.3"
},
"dependencies": {
@@ -24736,125 +24865,31 @@
"integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI="
},
"yargs": {
- "version": "11.0.0",
- "resolved": "https://registry.npmjs.org/yargs/-/yargs-11.0.0.tgz",
- "integrity": "sha512-Rjp+lMYQOWtgqojx1dEWorjCofi1YN7AoFvYV7b1gx/7dAAeuI4kN5SZiEvr0ZmsZTOpDRcCqrpI10L31tFkBw==",
- "dev": true,
+ "version": "6.6.0",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-6.6.0.tgz",
+ "integrity": "sha1-eC7CHvQDNF+DCoCMo9UTr1YGUgg=",
"requires": {
- "cliui": "4.0.0",
+ "camelcase": "3.0.0",
+ "cliui": "3.2.0",
"decamelize": "1.2.0",
- "find-up": "2.1.0",
"get-caller-file": "1.0.2",
- "os-locale": "2.1.0",
+ "os-locale": "1.4.0",
+ "read-pkg-up": "1.0.1",
"require-directory": "2.1.1",
"require-main-filename": "1.0.1",
"set-blocking": "2.0.0",
- "string-width": "2.1.1",
- "which-module": "2.0.0",
+ "string-width": "1.0.2",
+ "which-module": "1.0.0",
"y18n": "3.2.1",
- "yargs-parser": "9.0.2"
- },
- "dependencies": {
- "ansi-regex": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
- "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
- "dev": true
- },
- "cliui": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.0.0.tgz",
- "integrity": "sha512-nY3W5Gu2racvdDk//ELReY+dHjb9PlIcVDFXP72nVIhq2Gy3LuVXYwJoPVudwQnv1shtohpgkdCKT2YaKY0CKw==",
- "dev": true,
- "requires": {
- "string-width": "2.1.1",
- "strip-ansi": "4.0.0",
- "wrap-ansi": "2.1.0"
- }
- },
- "execa": {
- "version": "0.7.0",
- "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz",
- "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=",
- "dev": true,
- "requires": {
- "cross-spawn": "5.1.0",
- "get-stream": "3.0.0",
- "is-stream": "1.1.0",
- "npm-run-path": "2.0.2",
- "p-finally": "1.0.0",
- "signal-exit": "3.0.2",
- "strip-eof": "1.0.0"
- }
- },
- "find-up": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz",
- "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=",
- "dev": true,
- "requires": {
- "locate-path": "2.0.0"
- }
- },
- "is-fullwidth-code-point": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
- "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
- "dev": true
- },
- "os-locale": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-2.1.0.tgz",
- "integrity": "sha512-3sslG3zJbEYcaC4YVAvDorjGxc7tv6KVATnLPZONiljsUncvihe9BQoVCEs0RZ1kmf4Hk9OBqlZfJZWI4GanKA==",
- "dev": true,
- "requires": {
- "execa": "0.7.0",
- "lcid": "1.0.0",
- "mem": "1.1.0"
- }
- },
- "string-width": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
- "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
- "dev": true,
- "requires": {
- "is-fullwidth-code-point": "2.0.0",
- "strip-ansi": "4.0.0"
- }
- },
- "strip-ansi": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
- "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
- "dev": true,
- "requires": {
- "ansi-regex": "3.0.0"
- }
- },
- "which-module": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz",
- "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=",
- "dev": true
- }
+ "yargs-parser": "4.2.1"
}
},
"yargs-parser": {
- "version": "9.0.2",
- "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-9.0.2.tgz",
- "integrity": "sha1-nM9qQ0YP5O1Aqbto9I1DuKaMwHc=",
- "dev": true,
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-4.2.1.tgz",
+ "integrity": "sha1-KczqwNxPA8bIe0qfIX3RjJ90hxw=",
"requires": {
- "camelcase": "4.1.0"
- },
- "dependencies": {
- "camelcase": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz",
- "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=",
- "dev": true
- }
+ "camelcase": "3.0.0"
}
},
"yauzl": {
@@ -24882,9 +24917,9 @@
"dev": true
},
"yeoman-environment": {
- "version": "2.0.5",
- "resolved": "https://registry.npmjs.org/yeoman-environment/-/yeoman-environment-2.0.5.tgz",
- "integrity": "sha512-6/W7/B54OPHJXob0n0+pmkwFsirC8cokuQkPSmT/D0lCcSxkKtg/BA6ZnjUBIwjuGqmw3DTrT4en++htaUju5g==",
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/yeoman-environment/-/yeoman-environment-2.0.6.tgz",
+ "integrity": "sha512-jzHBTTy8EPI4ImV8dpUMt+Q5zELkSU5xvGpndHcHudQ4tqN6YgIWaCGmRFl+HDchwRUkcgyjQ+n6/w5zlJBCPg==",
"dev": true,
"requires": {
"chalk": "2.3.2",
@@ -25006,7 +25041,7 @@
"shelljs": "0.8.1",
"text-table": "0.2.0",
"through2": "2.0.3",
- "yeoman-environment": "2.0.5"
+ "yeoman-environment": "2.0.6"
},
"dependencies": {
"ansi-styles": {
diff --git a/package.json b/package.json
index 72abebba0..f869a9ca6 100644
--- a/package.json
+++ b/package.json
@@ -188,7 +188,7 @@
"valid-url": "^1.0.9",
"vreme": "^3.0.2",
"web3": "^0.20.1",
- "web3-provider-engine": "^13.5.6",
+ "web3-provider-engine": "^13.8.0",
"web3-stream-provider": "^3.0.1",
"xtend": "^4.0.1"
},
@@ -226,7 +226,6 @@
"gulp": "github:gulpjs/gulp#6d71a658c61edb3090221579d8f97dbe086ba2ed",
"gulp-babel": "^7.0.0",
"gulp-eslint": "^4.0.0",
- "gulp-if": "^2.0.2",
"gulp-json-editor": "^2.2.1",
"gulp-livereload": "^3.8.1",
"gulp-replace": "^0.6.1",
diff --git a/test/integration/lib/tx-list-items.js b/test/integration/lib/tx-list-items.js
new file mode 100644
index 000000000..d0056eb94
--- /dev/null
+++ b/test/integration/lib/tx-list-items.js
@@ -0,0 +1,61 @@
+const reactTriggerChange = require('../../lib/react-trigger-change')
+const {
+ timeout,
+ queryAsync,
+ findAsync,
+} = require('../../lib/util')
+
+QUnit.module('tx list items')
+
+QUnit.test('renders list items successfully', (assert) => {
+ const done = assert.async()
+ runTxListItemsTest(assert).then(done).catch((err) => {
+ assert.notOk(err, `Error was thrown: ${err.stack}`)
+ done()
+ })
+})
+
+async function runTxListItemsTest(assert, done) {
+ console.log('*** start runTxListItemsTest')
+ const selectState = await queryAsync($, 'select')
+ selectState.val('tx list items')
+ reactTriggerChange(selectState[0])
+
+ const metamaskLogo = await queryAsync($, '.left-menu-wrapper')
+ assert.ok(metamaskLogo[0], 'metamask logo present')
+ metamaskLogo[0].click()
+
+ const txListItems = await queryAsync($, '.tx-list-item')
+ assert.equal(txListItems.length, 8, 'all tx list items are rendered')
+
+ const unapprovedTx = txListItems[0]
+ assert.equal($(unapprovedTx).hasClass('tx-list-pending-item-container'), true, 'unapprovedTx has the correct class')
+
+ const retryTx = txListItems[1]
+ const retryTxLink = await findAsync($(retryTx), '.tx-list-item-retry-link')
+ assert.equal(retryTxLink[0].textContent, 'Increase the gas price on your transaction', 'retryTx has expected link')
+
+ const approvedTx = txListItems[2]
+ const approvedTxRenderedStatus = await findAsync($(approvedTx), '.tx-list-status')
+ assert.equal(approvedTxRenderedStatus[0].textContent, 'Approved', 'approvedTx has correct label')
+
+ const unapprovedMsg = txListItems[3]
+ const unapprovedMsgDescription = await findAsync($(unapprovedMsg), '.tx-list-account')
+ assert.equal(unapprovedMsgDescription[0].textContent, 'Signature Request', 'unapprovedMsg has correct description')
+
+ const failedTx = txListItems[4]
+ const failedTxRenderedStatus = await findAsync($(failedTx), '.tx-list-status')
+ assert.equal(failedTxRenderedStatus[0].textContent, 'Failed', 'failedTx has correct label')
+
+ const shapeShiftTx = txListItems[5]
+ const shapeShiftTxStatus = await findAsync($(shapeShiftTx), '.flex-column div:eq(1)')
+ assert.equal(shapeShiftTxStatus[0].textContent, 'No deposits received', 'shapeShiftTx has correct status')
+
+ const confirmedTokenTx = txListItems[6]
+ const confirmedTokenTxAddress = await findAsync($(confirmedTokenTx), '.tx-list-account')
+ assert.equal(confirmedTokenTxAddress[0].textContent, '0xe7884118...81a9', 'confirmedTokenTx has correct address')
+
+ const rejectedTx = txListItems[7]
+ const rejectedTxRenderedStatus = await findAsync($(rejectedTx), '.tx-list-status')
+ assert.equal(rejectedTxRenderedStatus[0].textContent, 'Rejected', 'rejectedTx has correct label')
+}
diff --git a/ui/app/components/customize-gas-modal/index.js b/ui/app/components/customize-gas-modal/index.js
index 825366cb2..4c693d1c3 100644
--- a/ui/app/components/customize-gas-modal/index.js
+++ b/ui/app/components/customize-gas-modal/index.js
@@ -65,6 +65,7 @@ function mapDispatchToProps (dispatch) {
updateGasLimit: newGasLimit => dispatch(actions.updateGasLimit(newGasLimit)),
updateGasTotal: newGasTotal => dispatch(actions.updateGasTotal(newGasTotal)),
updateSendAmount: newAmount => dispatch(actions.updateSendAmount(newAmount)),
+ updateSendErrors: error => dispatch(actions.updateSendErrors(error)),
}
}
@@ -112,6 +113,7 @@ CustomizeGasModal.prototype.save = function (gasPrice, gasLimit, gasTotal) {
selectedToken,
balance,
updateSendAmount,
+ updateSendErrors,
} = this.props
if (maxModeOn && !selectedToken) {
@@ -126,6 +128,7 @@ CustomizeGasModal.prototype.save = function (gasPrice, gasLimit, gasTotal) {
updateGasPrice(ethUtil.addHexPrefix(gasPrice))
updateGasLimit(ethUtil.addHexPrefix(gasLimit))
updateGasTotal(ethUtil.addHexPrefix(gasTotal))
+ updateSendErrors({ insufficientFunds: false })
hideModal()
}
diff --git a/ui/app/components/identicon.js b/ui/app/components/identicon.js
index 7cc5a4de0..dce9b0449 100644
--- a/ui/app/components/identicon.js
+++ b/ui/app/components/identicon.js
@@ -105,9 +105,8 @@ IdenticonComponent.prototype.componentDidUpdate = function () {
function _generateBlockie (container, address, diameter) {
const img = new Image()
img.src = toDataUrl(address)
- const dia = !diameter || diameter < 50 ? 50 : diameter
- img.height = dia * 1.25
- img.width = dia * 1.25
+ img.height = diameter
+ img.width = diameter
container.appendChild(img)
}
diff --git a/ui/app/components/pending-tx/confirm-send-ether.js b/ui/app/components/pending-tx/confirm-send-ether.js
index b68de4704..2474516d4 100644
--- a/ui/app/components/pending-tx/confirm-send-ether.js
+++ b/ui/app/components/pending-tx/confirm-send-ether.js
@@ -8,11 +8,16 @@ const clone = require('clone')
const ethUtil = require('ethereumjs-util')
const BN = ethUtil.BN
const hexToBn = require('../../../../app/scripts/lib/hex-to-bn')
+const classnames = require('classnames')
const {
conversionUtil,
addCurrencies,
multiplyCurrencies,
} = require('../../conversion-util')
+const {
+ getGasTotal,
+ isBalanceSufficient,
+} = require('../send/send-utils')
const GasFeeDisplay = require('../send/gas-fee-display-v2')
const SenderToRecipient = require('../sender-to-recipient')
const NetworkDisplay = require('../network-display')
@@ -35,12 +40,14 @@ function mapStateToProps (state) {
} = state.metamask
const accounts = state.metamask.accounts
const selectedAddress = state.metamask.selectedAddress || Object.keys(accounts)[0]
+ const { balance } = accounts[selectedAddress]
return {
conversionRate,
identities,
selectedAddress,
currentCurrency,
send,
+ balance,
}
}
@@ -91,6 +98,7 @@ function mapDispatchToProps (dispatch) {
}))
dispatch(actions.showModal({ name: 'CUSTOMIZE_GAS' }))
},
+ updateSendErrors: error => dispatch(actions.updateSendErrors(error)),
}
}
@@ -101,6 +109,18 @@ function ConfirmSendEther () {
this.onSubmit = this.onSubmit.bind(this)
}
+ConfirmSendEther.prototype.componentWillMount = function () {
+ const { updateSendErrors } = this.props
+ const txMeta = this.gatherTxMeta()
+ const balanceIsSufficient = this.isBalanceSufficient(txMeta)
+
+ updateSendErrors({
+ insufficientFunds: balanceIsSufficient
+ ? false
+ : this.context.t('insufficientFunds'),
+ })
+}
+
ConfirmSendEther.prototype.getAmount = function () {
const { conversionRate, currentCurrency } = this.props
const txMeta = this.gatherTxMeta()
@@ -223,7 +243,12 @@ ConfirmSendEther.prototype.render = function () {
conversionRate,
currentCurrency: convertedCurrency,
showCustomizeGasModal,
- send: { gasTotal, gasLimit: sendGasLimit, gasPrice: sendGasPrice },
+ send: {
+ gasTotal,
+ gasLimit: sendGasLimit,
+ gasPrice: sendGasPrice,
+ errors,
+ },
} = this.props
const txMeta = this.gatherTxMeta()
const txParams = txMeta.txParams || {}
@@ -331,7 +356,12 @@ ConfirmSendEther.prototype.render = function () {
]),
h('section.flex-row.flex-center.confirm-screen-row.confirm-screen-total-box ', [
- h('div.confirm-screen-section-column', [
+ h('div', {
+ className: classnames({
+ 'confirm-screen-section-column--with-error': errors['insufficientFunds'],
+ 'confirm-screen-section-column': !errors['insufficientFunds'],
+ }),
+ }, [
h('span.confirm-screen-label', [ this.context.t('total') + ' ' ]),
h('div.confirm-screen-total-box__subtitle', [ this.context.t('amountPlusGas') ]),
]),
@@ -340,6 +370,8 @@ ConfirmSendEther.prototype.render = function () {
h('div.confirm-screen-row-info', `${totalInFIAT} ${currentCurrency.toUpperCase()}`),
h('div.confirm-screen-row-detail', `${totalInETH} ETH`),
]),
+
+ this.renderErrorMessage('insufficientFunds'),
]),
]),
@@ -444,16 +476,28 @@ ConfirmSendEther.prototype.render = function () {
)
}
+ConfirmSendEther.prototype.renderErrorMessage = function (message) {
+ const { send: { errors } } = this.props
+
+ return errors[message]
+ ? h('div.confirm-screen-error', [ errors[message] ])
+ : null
+}
+
ConfirmSendEther.prototype.onSubmit = function (event) {
event.preventDefault()
+ const { updateSendErrors } = this.props
const txMeta = this.gatherTxMeta()
const valid = this.checkValidity()
+ const balanceIsSufficient = this.isBalanceSufficient(txMeta)
this.setState({ valid, submitting: true })
- if (valid && this.verifyGasParams()) {
+ if (valid && this.verifyGasParams() && balanceIsSufficient) {
this.props.sendTransaction(txMeta, event)
+ } else if (!balanceIsSufficient) {
+ updateSendErrors({ insufficientFunds: this.context.t('insufficientFunds') })
} else {
- this.props.dispatch(actions.displayWarning(this.context.t('invalidGasParams')))
+ updateSendErrors({ invalidGasParams: this.context.t('invalidGasParams') })
this.setState({ submitting: false })
}
}
@@ -465,6 +509,28 @@ ConfirmSendEther.prototype.cancel = function (event, txMeta) {
cancelTransaction(txMeta)
}
+ConfirmSendEther.prototype.isBalanceSufficient = function (txMeta) {
+ const {
+ balance,
+ conversionRate,
+ } = this.props
+ const {
+ txParams: {
+ gas,
+ gasPrice,
+ value: amount,
+ },
+ } = txMeta
+ const gasTotal = getGasTotal(gas, gasPrice)
+
+ return isBalanceSufficient({
+ amount,
+ gasTotal,
+ balance,
+ conversionRate,
+ })
+}
+
ConfirmSendEther.prototype.checkValidity = function () {
const form = this.getFormEl()
const valid = form.checkValidity()
diff --git a/ui/app/components/pending-tx/confirm-send-token.js b/ui/app/components/pending-tx/confirm-send-token.js
index 7fe260a61..dd9fdc23f 100644
--- a/ui/app/components/pending-tx/confirm-send-token.js
+++ b/ui/app/components/pending-tx/confirm-send-token.js
@@ -18,8 +18,13 @@ const {
addCurrencies,
} = require('../../conversion-util')
const {
+ getGasTotal,
+ isBalanceSufficient,
+} = require('../send/send-utils')
+const {
calcTokenAmount,
} = require('../../token-util')
+const classnames = require('classnames')
const { MIN_GAS_PRICE_HEX } = require('../send/send-constants')
@@ -46,9 +51,10 @@ function mapStateToProps (state, ownProps) {
identities,
currentCurrency,
} = state.metamask
+ const accounts = state.metamask.accounts
const selectedAddress = getSelectedAddress(state)
const tokenExchangeRate = getTokenExchangeRate(state, symbol)
-
+ const { balance } = accounts[selectedAddress]
return {
conversionRate,
identities,
@@ -58,6 +64,7 @@ function mapStateToProps (state, ownProps) {
currentCurrency: currentCurrency.toUpperCase(),
send: state.metamask.send,
tokenContract: getSelectedTokenContract(state),
+ balance,
}
}
@@ -129,6 +136,7 @@ function mapDispatchToProps (dispatch, ownProps) {
}))
dispatch(actions.showModal({ name: 'CUSTOMIZE_GAS' }))
},
+ updateSendErrors: error => dispatch(actions.updateSendErrors(error)),
}
}
@@ -140,12 +148,20 @@ function ConfirmSendToken () {
}
ConfirmSendToken.prototype.componentWillMount = function () {
- const { tokenContract, selectedAddress } = this.props
+ const { tokenContract, selectedAddress, updateSendErrors} = this.props
+ const txMeta = this.gatherTxMeta()
+ const balanceIsSufficient = this.isBalanceSufficient(txMeta)
tokenContract && tokenContract
.balanceOf(selectedAddress)
.then(usersToken => {
})
this.props.updateTokenExchangeRate()
+
+ updateSendErrors({
+ insufficientFunds: balanceIsSufficient
+ ? false
+ : this.context.t('insufficientFunds'),
+ })
}
ConfirmSendToken.prototype.getAmount = function () {
@@ -306,7 +322,7 @@ ConfirmSendToken.prototype.renderGasFee = function () {
}
ConfirmSendToken.prototype.renderTotalPlusGas = function () {
- const { token: { symbol }, currentCurrency } = this.props
+ const { token: { symbol }, currentCurrency, send: { errors } } = this.props
const { fiat: fiatAmount, token: tokenAmount } = this.getAmount()
const { fiat: fiatGas, token: tokenGas } = this.getGasFee()
@@ -326,7 +342,12 @@ ConfirmSendToken.prototype.renderTotalPlusGas = function () {
)
: (
h('section.flex-row.flex-center.confirm-screen-row.confirm-screen-total-box ', [
- h('div.confirm-screen-section-column', [
+ h('div', {
+ className: classnames({
+ 'confirm-screen-section-column--with-error': errors['insufficientFunds'],
+ 'confirm-screen-section-column': !errors['insufficientFunds'],
+ }),
+ }, [
h('span.confirm-screen-label', [ this.context.t('total') + ' ' ]),
h('div.confirm-screen-total-box__subtitle', [ this.context.t('amountPlusGas') ]),
]),
@@ -335,10 +356,20 @@ ConfirmSendToken.prototype.renderTotalPlusGas = function () {
h('div.confirm-screen-row-info', `${tokenAmount} ${symbol}`),
h('div.confirm-screen-row-detail', `+ ${fiatGas} ${currentCurrency} ${this.context.t('gas')}`),
]),
+
+ this.renderErrorMessage('insufficientFunds'),
])
)
}
+ConfirmSendToken.prototype.renderErrorMessage = function (message) {
+ const { send: { errors } } = this.props
+
+ return errors[message]
+ ? h('div.confirm-screen-error', [ errors[message] ])
+ : null
+}
+
ConfirmSendToken.prototype.render = function () {
const { editTransaction } = this.props
const txMeta = this.gatherTxMeta()
@@ -455,18 +486,44 @@ ConfirmSendToken.prototype.render = function () {
ConfirmSendToken.prototype.onSubmit = function (event) {
event.preventDefault()
+ const { updateSendErrors } = this.props
const txMeta = this.gatherTxMeta()
const valid = this.checkValidity()
+ const balanceIsSufficient = this.isBalanceSufficient(txMeta)
this.setState({ valid, submitting: true })
- if (valid && this.verifyGasParams()) {
+ if (valid && this.verifyGasParams() && balanceIsSufficient) {
this.props.sendTransaction(txMeta, event)
+ } else if (!balanceIsSufficient) {
+ updateSendErrors({ insufficientFunds: this.context.t('insufficientFunds') })
} else {
- this.props.dispatch(actions.displayWarning(this.context.t('invalidGasParams')))
+ updateSendErrors({ invalidGasParams: this.context.t('invalidGasParams') })
this.setState({ submitting: false })
}
}
+ConfirmSendToken.prototype.isBalanceSufficient = function (txMeta) {
+ const {
+ balance,
+ conversionRate,
+ } = this.props
+ const {
+ txParams: {
+ gas,
+ gasPrice,
+ },
+ } = txMeta
+ const gasTotal = getGasTotal(gas, gasPrice)
+
+ return isBalanceSufficient({
+ amount: '0',
+ gasTotal,
+ balance,
+ conversionRate,
+ })
+}
+
+
ConfirmSendToken.prototype.cancel = function (event, txMeta) {
event.preventDefault()
const { cancelTransaction } = this.props
diff --git a/ui/app/components/send/send-utils.js b/ui/app/components/send/send-utils.js
index d8211930d..71bfb2668 100644
--- a/ui/app/components/send/send-utils.js
+++ b/ui/app/components/send/send-utils.js
@@ -2,6 +2,7 @@ const {
addCurrencies,
conversionUtil,
conversionGTE,
+ multiplyCurrencies,
} = require('../../conversion-util')
const {
calcTokenAmount,
@@ -31,7 +32,7 @@ function isBalanceSufficient ({
{
value: totalAmount,
fromNumericBase: 'hex',
- conversionRate: amountConversionRate,
+ conversionRate: amountConversionRate || conversionRate,
fromCurrency: primaryCurrency,
},
)
@@ -62,7 +63,16 @@ function isTokenBalanceSufficient ({
return tokenBalanceIsSufficient
}
+function getGasTotal (gasLimit, gasPrice) {
+ return multiplyCurrencies(gasLimit, gasPrice, {
+ toNumericBase: 'hex',
+ multiplicandBase: 16,
+ multiplierBase: 16,
+ })
+}
+
module.exports = {
+ getGasTotal,
isBalanceSufficient,
isTokenBalanceSufficient,
}
diff --git a/ui/app/components/tx-list-item.js b/ui/app/components/tx-list-item.js
index 622664786..42c008798 100644
--- a/ui/app/components/tx-list-item.js
+++ b/ui/app/components/tx-list-item.js
@@ -68,20 +68,24 @@ TxListItem.prototype.getAddressText = function () {
const {
address,
txParams = {},
+ isMsg,
} = this.props
const decodedData = txParams.data && abiDecoder.decodeMethod(txParams.data)
const { name: txDataName, params = [] } = decodedData || {}
const { value } = params[0] || {}
- switch (txDataName) {
- case 'transfer':
- return `${value.slice(0, 10)}...${value.slice(-4)}`
- default:
- return address
- ? `${address.slice(0, 10)}...${address.slice(-4)}`
- : this.context.t('contractDeployment')
+ let addressText
+ if (txDataName === 'transfer' || address) {
+ const addressToRender = txDataName === 'transfer' ? value : address
+ addressText = `${addressToRender.slice(0, 10)}...${addressToRender.slice(-4)}`
+ } else if (isMsg) {
+ addressText = this.context.t('sigRequest')
+ } else {
+ addressText = this.context.t('contractDeployment')
}
+
+ return addressText
}
TxListItem.prototype.getSendEtherTotal = function () {
@@ -191,6 +195,9 @@ TxListItem.prototype.showRetryButton = function () {
transactionId,
txParams,
} = this.props
+ if (!txParams) {
+ return false
+ }
const currentNonce = txParams.nonce
const currentNonceTxs = selectedAddressTxList.filter(tx => tx.txParams.nonce === currentNonce)
const currentNonceSubmittedTxs = currentNonceTxs.filter(tx => tx.status === 'submitted')
diff --git a/ui/app/components/tx-list.js b/ui/app/components/tx-list.js
index fa01c7b29..740c4a4ab 100644
--- a/ui/app/components/tx-list.js
+++ b/ui/app/components/tx-list.js
@@ -77,9 +77,9 @@ TxList.prototype.renderTransactionListItem = function (transaction, conversionRa
const props = {
dateString: formatDate(transaction.time),
- address: transaction.txParams.to,
+ address: transaction.txParams && transaction.txParams.to,
transactionStatus: transaction.status,
- transactionAmount: transaction.txParams.value,
+ transactionAmount: transaction.txParams && transaction.txParams.value,
transactionId: transaction.id,
transactionHash: transaction.hash,
transactionNetworkId: transaction.metamaskNetworkId,
@@ -101,6 +101,7 @@ TxList.prototype.renderTransactionListItem = function (transaction, conversionRa
const opts = {
key: transactionId || transactionHash,
txParams: transaction.txParams,
+ isMsg: Boolean(transaction.msgParams),
transactionStatus,
transactionId,
dateString,
diff --git a/ui/app/css/itcss/components/confirm.scss b/ui/app/css/itcss/components/confirm.scss
index abe138f54..85ff14e6e 100644
--- a/ui/app/css/itcss/components/confirm.scss
+++ b/ui/app/css/itcss/components/confirm.scss
@@ -266,6 +266,7 @@ section .confirm-screen-account-number,
.confirm-screen-total-box {
background-color: $wild-sand;
+ position: relative;
.confirm-screen-label {
line-height: 21px;
@@ -287,6 +288,30 @@ section .confirm-screen-account-number,
}
}
+.confirm-screen-error {
+ font-size: 12px;
+ line-height: 12px;
+ color: #f00;
+ position: absolute;
+ right: 12px;
+ width: 80px;
+ text-align: right;
+}
+
+.confirm-screen-row.confirm-screen-total-box {
+ .confirm-screen-section-column--with-error {
+ flex: 0.6;
+ }
+}
+
+@media screen and (max-width: 379px) {
+ .confirm-screen-row.confirm-screen-total-box {
+ .confirm-screen-section-column--with-error {
+ flex: 0.4;
+ }
+ }
+}
+
.confirm-screen-confirm-button {
height: 50px;
border-radius: 4px;
diff --git a/ui/app/send-v2.js b/ui/app/send-v2.js
index 910312b47..0f2997fb2 100644
--- a/ui/app/send-v2.js
+++ b/ui/app/send-v2.js
@@ -27,6 +27,7 @@ const {
const {
isBalanceSufficient,
isTokenBalanceSufficient,
+ getGasTotal,
} = require('./components/send/send-utils')
const { isValidAddress } = require('./util')
@@ -132,7 +133,7 @@ SendTransactionScreen.prototype.updateGas = function () {
estimateGas(estimateGasParams),
])
.then(([gasPrice, gas]) => {
- const newGasTotal = this.getGasTotal(gas, gasPrice)
+ const newGasTotal = getGasTotal(gas, gasPrice)
updateGasTotal(newGasTotal)
this.setState({ gasLoadingError: false })
})
@@ -140,19 +141,11 @@ SendTransactionScreen.prototype.updateGas = function () {
this.setState({ gasLoadingError: true })
})
} else {
- const newGasTotal = this.getGasTotal(gasLimit, gasPrice)
+ const newGasTotal = getGasTotal(gasLimit, gasPrice)
updateGasTotal(newGasTotal)
}
}
-SendTransactionScreen.prototype.getGasTotal = function (gasLimit, gasPrice) {
- return multiplyCurrencies(gasLimit, gasPrice, {
- toNumericBase: 'hex',
- multiplicandBase: 16,
- multiplierBase: 16,
- })
-}
-
SendTransactionScreen.prototype.componentDidUpdate = function (prevProps) {
const {
from: { balance },
@@ -642,6 +635,10 @@ SendTransactionScreen.prototype.onSubmit = function (event) {
txParams.to = to
}
+ Object.keys(txParams).forEach(key => {
+ txParams[key] = ethUtil.addHexPrefix(txParams[key])
+ })
+
selectedToken
? signTokenTx(selectedToken.address, to, amount, txParams)
: signTx(txParams)