mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-11-22 09:57:02 +01:00
Merge pull request #7466 from MetaMask/Version-v7.6.0
Version v7.6.0 RC
This commit is contained in:
commit
86c39c806e
@ -77,7 +77,7 @@ workflows:
|
||||
jobs:
|
||||
create_release_pull_request:
|
||||
docker:
|
||||
- image: circleci/node:8.15.1-browsers
|
||||
- image: circleci/node:10.17-browsers
|
||||
steps:
|
||||
- checkout
|
||||
- run:
|
||||
@ -89,7 +89,7 @@ jobs:
|
||||
|
||||
prep-deps:
|
||||
docker:
|
||||
- image: circleci/node:10.16-browsers
|
||||
- image: circleci/node:10.17-browsers
|
||||
steps:
|
||||
- checkout
|
||||
- run:
|
||||
@ -108,7 +108,7 @@ jobs:
|
||||
|
||||
prep-build:
|
||||
docker:
|
||||
- image: circleci/node:10.16-browsers
|
||||
- image: circleci/node:10.17-browsers
|
||||
steps:
|
||||
- checkout
|
||||
- attach_workspace:
|
||||
@ -127,7 +127,7 @@ jobs:
|
||||
|
||||
prep-docs:
|
||||
docker:
|
||||
- image: circleci/node:10.16-browsers
|
||||
- image: circleci/node:10.17-browsers
|
||||
steps:
|
||||
- checkout
|
||||
- attach_workspace:
|
||||
@ -142,7 +142,7 @@ jobs:
|
||||
|
||||
prep-scss:
|
||||
docker:
|
||||
- image: circleci/node:10.16-browsers
|
||||
- image: circleci/node:10.17-browsers
|
||||
steps:
|
||||
- checkout
|
||||
- attach_workspace:
|
||||
@ -161,7 +161,7 @@ jobs:
|
||||
|
||||
test-lint:
|
||||
docker:
|
||||
- image: circleci/node:10.16-browsers
|
||||
- image: circleci/node:10.17-browsers
|
||||
steps:
|
||||
- checkout
|
||||
- attach_workspace:
|
||||
@ -175,7 +175,7 @@ jobs:
|
||||
|
||||
test-deps:
|
||||
docker:
|
||||
- image: circleci/node:10.16-browsers
|
||||
- image: circleci/node:10.17-browsers
|
||||
steps:
|
||||
- checkout
|
||||
- attach_workspace:
|
||||
@ -186,7 +186,7 @@ jobs:
|
||||
|
||||
test-e2e-chrome:
|
||||
docker:
|
||||
- image: circleci/node:10.16-browsers
|
||||
- image: circleci/node:10.17-browsers
|
||||
steps:
|
||||
- checkout
|
||||
- attach_workspace:
|
||||
@ -201,7 +201,7 @@ jobs:
|
||||
|
||||
test-e2e-firefox:
|
||||
docker:
|
||||
- image: circleci/node:10.16-browsers
|
||||
- image: circleci/node:10.17-browsers
|
||||
steps:
|
||||
- checkout
|
||||
- run:
|
||||
@ -219,7 +219,7 @@ jobs:
|
||||
|
||||
job-publish-prerelease:
|
||||
docker:
|
||||
- image: circleci/node:10.16-browsers
|
||||
- image: circleci/node:10.17-browsers
|
||||
steps:
|
||||
- checkout
|
||||
- attach_workspace:
|
||||
@ -249,7 +249,7 @@ jobs:
|
||||
|
||||
job-publish-release:
|
||||
docker:
|
||||
- image: circleci/node:10.16-browsers
|
||||
- image: circleci/node:10.17-browsers
|
||||
steps:
|
||||
- checkout
|
||||
- attach_workspace:
|
||||
@ -273,7 +273,7 @@ jobs:
|
||||
|
||||
test-unit:
|
||||
docker:
|
||||
- image: circleci/node:10.16-browsers
|
||||
- image: circleci/node:10.17-browsers
|
||||
steps:
|
||||
- checkout
|
||||
- attach_workspace:
|
||||
@ -288,7 +288,7 @@ jobs:
|
||||
- coverage
|
||||
test-unit-global:
|
||||
docker:
|
||||
- image: circleci/node:10.16-browsers
|
||||
- image: circleci/node:10.17-browsers
|
||||
steps:
|
||||
- checkout
|
||||
- attach_workspace:
|
||||
@ -298,7 +298,7 @@ jobs:
|
||||
command: yarn test:unit:global
|
||||
test-mozilla-lint:
|
||||
docker:
|
||||
- image: circleci/node:10.16-browsers
|
||||
- image: circleci/node:10.17-browsers
|
||||
steps:
|
||||
- checkout
|
||||
- attach_workspace:
|
||||
@ -309,7 +309,7 @@ jobs:
|
||||
|
||||
test-integration-flat-firefox:
|
||||
docker:
|
||||
- image: circleci/node:10.16-browsers
|
||||
- image: circleci/node:10.17-browsers
|
||||
steps:
|
||||
- checkout
|
||||
- attach_workspace:
|
||||
@ -325,7 +325,7 @@ jobs:
|
||||
environment:
|
||||
browsers: '["Chrome"]'
|
||||
docker:
|
||||
- image: circleci/node:10.16-browsers
|
||||
- image: circleci/node:10.17-browsers
|
||||
steps:
|
||||
- checkout
|
||||
- attach_workspace:
|
||||
@ -336,7 +336,7 @@ jobs:
|
||||
|
||||
all-tests-pass:
|
||||
docker:
|
||||
- image: circleci/node:10.16-browsers
|
||||
- image: circleci/node:10.17-browsers
|
||||
steps:
|
||||
- run:
|
||||
name: All Tests Passed
|
||||
@ -344,7 +344,7 @@ jobs:
|
||||
|
||||
coveralls-upload:
|
||||
docker:
|
||||
- image: circleci/node:10.16-browsers
|
||||
- image: circleci/node:10.17-browsers
|
||||
steps:
|
||||
- checkout
|
||||
- attach_workspace:
|
||||
|
@ -148,7 +148,10 @@
|
||||
"operator-linebreak": [2, "after", { "overrides": { "?": "ignore", ":": "ignore" } }],
|
||||
"padded-blocks": "off",
|
||||
"quotes": [2, "single", {"avoidEscape": true, "allowTemplateLiterals": true}],
|
||||
"react/jsx-curly-brace-presence": [2, { "props": "never", "children": "never" }],
|
||||
"react/jsx-equals-spacing": 2,
|
||||
"react/no-deprecated": 0,
|
||||
"react/default-props-match-prop-types": 2,
|
||||
"semi": [2, "never"],
|
||||
"semi-spacing": [2, { "before": false, "after": true }],
|
||||
"space-before-blocks": [2, "always"],
|
||||
|
@ -2,6 +2,8 @@
|
||||
|
||||
## Current Develop Branch
|
||||
|
||||
## 7.6.0 Mon Nov 18 2019
|
||||
|
||||
## 7.5.3 Fri Nov 15 2019
|
||||
- [#7412](https://github.com/MetaMask/metamask-extension/pull/7412): lock eth-contract-metadata (#7412)
|
||||
- [#7416](https://github.com/MetaMask/metamask-extension/pull/7416): Add eslint import plugin to help detect unresolved paths
|
||||
|
@ -1,4 +1,10 @@
|
||||
{
|
||||
"migrateSai": {
|
||||
"message": "A message from Maker: The new Multi-Collateral Dai token has been released. Your old tokens are now called Sai. Please upgrade your Sai tokens to the new Dai."
|
||||
},
|
||||
"migrate": {
|
||||
"message": "Migrate"
|
||||
},
|
||||
"showIncomingTransactions": {
|
||||
"message": "Show Incoming Transactions"
|
||||
},
|
||||
|
@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "__MSG_appName__",
|
||||
"short_name": "__MSG_appName__",
|
||||
"version": "7.5.3",
|
||||
"version": "7.6.0",
|
||||
"manifest_version": 2,
|
||||
"author": "https://metamask.io",
|
||||
"description": "__MSG_appDescription__",
|
||||
|
67
app/scripts/migrations/039.js
Normal file
67
app/scripts/migrations/039.js
Normal file
@ -0,0 +1,67 @@
|
||||
const version = 39
|
||||
const clone = require('clone')
|
||||
const ethUtil = require('ethereumjs-util')
|
||||
|
||||
const DAI_V1_CONTRACT_ADDRESS = '0x89d24A6b4CcB1B6fAA2625fE562bDD9a23260359'
|
||||
const DAI_V1_TOKEN_SYMBOL = 'DAI'
|
||||
const SAI_TOKEN_SYMBOL = 'SAI'
|
||||
|
||||
function isOldDai (token = {}) {
|
||||
return token && typeof token === 'object' &&
|
||||
token.symbol === DAI_V1_TOKEN_SYMBOL &&
|
||||
ethUtil.toChecksumAddress(token.address) === DAI_V1_CONTRACT_ADDRESS
|
||||
}
|
||||
|
||||
/**
|
||||
* This migration renames the Dai token to Sai.
|
||||
*
|
||||
* As of 2019-11-18 Dai is now called Sai (refs https://git.io/JeooP) to facilitate
|
||||
* Maker's upgrade to Multi-Collateral Dai and this migration renames the token
|
||||
* at the old address.
|
||||
*/
|
||||
module.exports = {
|
||||
version,
|
||||
migrate: async function (originalVersionedData) {
|
||||
const versionedData = clone(originalVersionedData)
|
||||
versionedData.meta.version = version
|
||||
const state = versionedData.data
|
||||
versionedData.data = transformState(state)
|
||||
return versionedData
|
||||
},
|
||||
}
|
||||
|
||||
function transformState (state) {
|
||||
const { PreferencesController } = state
|
||||
|
||||
if (PreferencesController) {
|
||||
const tokens = PreferencesController.tokens || []
|
||||
if (Array.isArray(tokens)) {
|
||||
for (const token of tokens) {
|
||||
if (isOldDai(token)) {
|
||||
token.symbol = SAI_TOKEN_SYMBOL
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const accountTokens = PreferencesController.accountTokens || {}
|
||||
if (accountTokens && typeof accountTokens === 'object') {
|
||||
for (const address of Object.keys(accountTokens)) {
|
||||
const networkTokens = accountTokens[address]
|
||||
if (networkTokens && typeof networkTokens === 'object') {
|
||||
for (const network of Object.keys(networkTokens)) {
|
||||
const tokensOnNetwork = networkTokens[network]
|
||||
if (Array.isArray(tokensOnNetwork)) {
|
||||
for (const token of tokensOnNetwork) {
|
||||
if (isOldDai(token)) {
|
||||
token.symbol = SAI_TOKEN_SYMBOL
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return state
|
||||
}
|
@ -49,4 +49,5 @@ module.exports = [
|
||||
require('./036'),
|
||||
require('./037'),
|
||||
require('./038'),
|
||||
require('./039'),
|
||||
]
|
||||
|
@ -87,7 +87,7 @@
|
||||
"dnode": "^1.2.2",
|
||||
"end-of-stream": "^1.1.0",
|
||||
"eth-block-tracker": "^4.4.2",
|
||||
"eth-contract-metadata": "1.9.3",
|
||||
"eth-contract-metadata": "^1.11.0",
|
||||
"eth-ens-namehash": "^2.0.8",
|
||||
"eth-json-rpc-errors": "^1.1.0",
|
||||
"eth-json-rpc-filters": "^4.1.1",
|
||||
@ -114,7 +114,7 @@
|
||||
"extensionizer": "^1.0.1",
|
||||
"fast-json-patch": "^2.0.4",
|
||||
"fuse.js": "^3.2.0",
|
||||
"gaba": "^1.8.0",
|
||||
"gaba": "^1.9.0",
|
||||
"human-standard-token-abi": "^2.0.0",
|
||||
"jazzicon": "^1.2.0",
|
||||
"json-rpc-engine": "^5.1.5",
|
||||
|
419
test/unit/migrations/039-test.js
Normal file
419
test/unit/migrations/039-test.js
Normal file
@ -0,0 +1,419 @@
|
||||
const assert = require('assert')
|
||||
const migration39 = require('../../../app/scripts/migrations/039')
|
||||
|
||||
describe('migration #39', () => {
|
||||
it('should update the version metadata', (done) => {
|
||||
const oldStorage = {
|
||||
'meta': {
|
||||
'version': 38,
|
||||
},
|
||||
'data': {},
|
||||
}
|
||||
|
||||
migration39.migrate(oldStorage)
|
||||
.then((newStorage) => {
|
||||
assert.deepEqual(newStorage.meta, {
|
||||
'version': 39,
|
||||
})
|
||||
done()
|
||||
})
|
||||
.catch(done)
|
||||
})
|
||||
|
||||
it('should update old DAI token symbol to SAI in tokens', (done) => {
|
||||
const oldStorage = {
|
||||
'meta': {},
|
||||
'data': {
|
||||
'PreferencesController': {
|
||||
'tokens': [{
|
||||
'address': '0x89d24a6b4ccb1b6faa2625fe562bdd9a23260359',
|
||||
'decimals': 18,
|
||||
'symbol': 'DAI',
|
||||
}, {
|
||||
'address': '0x0d8775f648430679a709e98d2b0cb6250d2887ef',
|
||||
'symbol': 'BAT',
|
||||
'decimals': 18,
|
||||
}, {
|
||||
'address': '0x617b3f8050a0bd94b6b1da02b4384ee5b4df13f4',
|
||||
'symbol': 'META',
|
||||
'decimals': 18,
|
||||
}],
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
migration39.migrate(oldStorage)
|
||||
.then((newStorage) => {
|
||||
assert.deepEqual(newStorage.data.PreferencesController, {
|
||||
'tokens': [{
|
||||
'address': '0x89d24a6b4ccb1b6faa2625fe562bdd9a23260359',
|
||||
'decimals': 18,
|
||||
'symbol': 'SAI',
|
||||
}, {
|
||||
'address': '0x0d8775f648430679a709e98d2b0cb6250d2887ef',
|
||||
'symbol': 'BAT',
|
||||
'decimals': 18,
|
||||
}, {
|
||||
'address': '0x617b3f8050a0bd94b6b1da02b4384ee5b4df13f4',
|
||||
'symbol': 'META',
|
||||
'decimals': 18,
|
||||
}],
|
||||
})
|
||||
done()
|
||||
})
|
||||
.catch(done)
|
||||
})
|
||||
|
||||
it('should update old DAI token symbol to SAI in accountTokens', (done) => {
|
||||
const oldStorage = {
|
||||
'meta': {},
|
||||
'data': {
|
||||
'PreferencesController': {
|
||||
'accountTokens': {
|
||||
'0x7250739de134d33ec7ab1ee592711e15098c9d2d': {
|
||||
'mainnet': [
|
||||
{
|
||||
'address': '0x89d24a6b4ccb1b6faa2625fe562bdd9a23260359',
|
||||
'decimals': 18,
|
||||
'symbol': 'DAI',
|
||||
},
|
||||
],
|
||||
},
|
||||
'0x8e5d75d60224ea0c33d0041e75de68b1c3cb6dd5': {
|
||||
'mainnet': [],
|
||||
'rinkeby': [],
|
||||
},
|
||||
'0x8e5d75d60224ea0c33d1041e75de68b1c3cb6dd5': {},
|
||||
'0xb3958fb96c8201486ae20be1d5c9f58083df343a': {
|
||||
'mainnet': [
|
||||
{
|
||||
'address': '0x89d24a6b4ccb1b6faa2625fe562bdd9a23260359',
|
||||
'decimals': 18,
|
||||
'symbol': 'DAI',
|
||||
},
|
||||
{
|
||||
'address': '0x0d8775f648430679a709e98d2b0cb6250d2887ef',
|
||||
'decimals': 18,
|
||||
'symbol': 'BAT',
|
||||
},
|
||||
{
|
||||
'address': '0x617b3f8050a0bd94b6b1da02b4384ee5b4df13f4',
|
||||
'decimals': 18,
|
||||
'symbol': 'META',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
migration39.migrate(oldStorage)
|
||||
.then((newStorage) => {
|
||||
assert.deepEqual(newStorage.data.PreferencesController, {
|
||||
'accountTokens': {
|
||||
'0x7250739de134d33ec7ab1ee592711e15098c9d2d': {
|
||||
'mainnet': [
|
||||
{
|
||||
'address': '0x89d24a6b4ccb1b6faa2625fe562bdd9a23260359',
|
||||
'decimals': 18,
|
||||
'symbol': 'SAI',
|
||||
},
|
||||
],
|
||||
},
|
||||
'0x8e5d75d60224ea0c33d0041e75de68b1c3cb6dd5': {
|
||||
'mainnet': [],
|
||||
'rinkeby': [],
|
||||
},
|
||||
'0x8e5d75d60224ea0c33d1041e75de68b1c3cb6dd5': {},
|
||||
'0xb3958fb96c8201486ae20be1d5c9f58083df343a': {
|
||||
'mainnet': [
|
||||
{
|
||||
'address': '0x89d24a6b4ccb1b6faa2625fe562bdd9a23260359',
|
||||
'decimals': 18,
|
||||
'symbol': 'SAI',
|
||||
},
|
||||
{
|
||||
'address': '0x0d8775f648430679a709e98d2b0cb6250d2887ef',
|
||||
'decimals': 18,
|
||||
'symbol': 'BAT',
|
||||
},
|
||||
{
|
||||
'address': '0x617b3f8050a0bd94b6b1da02b4384ee5b4df13f4',
|
||||
'decimals': 18,
|
||||
'symbol': 'META',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
})
|
||||
done()
|
||||
})
|
||||
.catch(done)
|
||||
})
|
||||
|
||||
it('should NOT change any state if accountTokens is not an object', (done) => {
|
||||
const oldStorage = {
|
||||
'meta': {},
|
||||
'data': {
|
||||
'PreferencesController': {
|
||||
'accountTokens': [],
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
migration39.migrate(oldStorage)
|
||||
.then((newStorage) => {
|
||||
assert.deepEqual(newStorage.data, oldStorage.data)
|
||||
done()
|
||||
})
|
||||
.catch(done)
|
||||
})
|
||||
|
||||
it('should NOT change any state if accountTokens is an object with invalid values', (done) => {
|
||||
const oldStorage = {
|
||||
'meta': {},
|
||||
'data': {
|
||||
'PreferencesController': {
|
||||
'accountTokens': {
|
||||
'0x7250739de134d33ec7ab1ee592711e15098c9d2d': [
|
||||
{
|
||||
'address': '0x89d24a6b4ccb1b6faa2625fe562bdd9a23260359',
|
||||
'decimals': 18,
|
||||
'symbol': 'DAI',
|
||||
},
|
||||
],
|
||||
'0x89d24a6b4ccb1b6faa2625fe562bdd9a23260359': null,
|
||||
'0x8e5d75d60224ea0c33d0041e75de68b1c3cb6dd5': {
|
||||
'mainnet': [
|
||||
null,
|
||||
undefined,
|
||||
[],
|
||||
42,
|
||||
],
|
||||
'rinkeby': null,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
migration39.migrate(oldStorage)
|
||||
.then((newStorage) => {
|
||||
assert.deepEqual(newStorage.data, oldStorage.data)
|
||||
done()
|
||||
})
|
||||
.catch(done)
|
||||
})
|
||||
|
||||
it('should NOT change any state if accountTokens includes the new DAI token', (done) => {
|
||||
const oldStorage = {
|
||||
'meta': {},
|
||||
'data': {
|
||||
'PreferencesController': {
|
||||
'accountTokens': {
|
||||
'0x7250739de134d33ec7ab1ee592711e15098c9d2d': {
|
||||
'mainnet': [
|
||||
{
|
||||
'address': '0x6B175474E89094C44Da98b954EedeAC495271d0F',
|
||||
'decimals': 18,
|
||||
'symbol': 'DAI',
|
||||
},
|
||||
],
|
||||
},
|
||||
'0x8e5d75d60224ea0c33d0041e75de68b1c3cb6dd5': {
|
||||
'mainnet': [],
|
||||
'rinkeby': [],
|
||||
},
|
||||
'0x8e5d75d60224ea0c33d1041e75de68b1c3cb6dd5': {},
|
||||
'0xb3958fb96c8201486ae20be1d5c9f58083df343a': {
|
||||
'mainnet': [
|
||||
{
|
||||
'address': '0x6B175474E89094C44Da98b954EedeAC495271d0F',
|
||||
'decimals': 18,
|
||||
'symbol': 'DAI',
|
||||
},
|
||||
{
|
||||
'address': '0x0d8775f648430679a709e98d2b0cb6250d2887ef',
|
||||
'decimals': 18,
|
||||
'symbol': 'BAT',
|
||||
},
|
||||
{
|
||||
'address': '0x617b3f8050a0bd94b6b1da02b4384ee5b4df13f4',
|
||||
'decimals': 18,
|
||||
'symbol': 'META',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
migration39.migrate(oldStorage)
|
||||
.then((newStorage) => {
|
||||
assert.deepEqual(newStorage.data, oldStorage.data)
|
||||
done()
|
||||
})
|
||||
.catch(done)
|
||||
})
|
||||
|
||||
it('should NOT change any state if tokens includes the new DAI token', (done) => {
|
||||
const oldStorage = {
|
||||
'meta': {},
|
||||
'data': {
|
||||
'PreferencesController': {
|
||||
'tokens': [{
|
||||
'address': '0x6B175474E89094C44Da98b954EedeAC495271d0F',
|
||||
'symbol': 'DAI',
|
||||
'decimals': 18,
|
||||
}, {
|
||||
'address': '0x617b3f8050a0bd94b6b1da02b4384ee5b4df13f4',
|
||||
'symbol': 'META',
|
||||
'decimals': 18,
|
||||
}],
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
migration39.migrate(oldStorage)
|
||||
.then((newStorage) => {
|
||||
assert.deepEqual(newStorage.data, oldStorage.data)
|
||||
done()
|
||||
})
|
||||
.catch(done)
|
||||
})
|
||||
|
||||
it('should NOT change any state if tokens does not include DAI', (done) => {
|
||||
const oldStorage = {
|
||||
'meta': {},
|
||||
'data': {
|
||||
'PreferencesController': {
|
||||
'tokens': [{
|
||||
'address': '0x0d8775f648430679a709e98d2b0cb6250d2887ef',
|
||||
'symbol': 'BAT',
|
||||
'decimals': 18,
|
||||
}, {
|
||||
'address': '0x617b3f8050a0bd94b6b1da02b4384ee5b4df13f4',
|
||||
'symbol': 'META',
|
||||
'decimals': 18,
|
||||
}],
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
migration39.migrate(oldStorage)
|
||||
.then((newStorage) => {
|
||||
assert.deepEqual(newStorage.data, oldStorage.data)
|
||||
done()
|
||||
})
|
||||
.catch(done)
|
||||
})
|
||||
|
||||
it('should NOT change any state if a tokens property has invalid entries', (done) => {
|
||||
const oldStorage = {
|
||||
'meta': {},
|
||||
'data': {
|
||||
'PreferencesController': {
|
||||
'tokens': [
|
||||
null,
|
||||
[],
|
||||
undefined,
|
||||
42,
|
||||
],
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
migration39.migrate(oldStorage)
|
||||
.then((newStorage) => {
|
||||
assert.deepEqual(newStorage.data, oldStorage.data)
|
||||
done()
|
||||
})
|
||||
.catch(done)
|
||||
})
|
||||
|
||||
it('should NOT change any state if a tokens property is not an array', (done) => {
|
||||
const oldStorage = {
|
||||
'meta': {},
|
||||
'data': {
|
||||
'PreferencesController': {
|
||||
'tokens': {},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
migration39.migrate(oldStorage)
|
||||
.then((newStorage) => {
|
||||
assert.deepEqual(newStorage.data, oldStorage.data)
|
||||
done()
|
||||
})
|
||||
.catch(done)
|
||||
})
|
||||
|
||||
it('should NOT change any state if a tokens property is null', (done) => {
|
||||
const oldStorage = {
|
||||
'meta': {},
|
||||
'data': {
|
||||
'PreferencesController': {
|
||||
'tokens': null,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
migration39.migrate(oldStorage)
|
||||
.then((newStorage) => {
|
||||
assert.deepEqual(newStorage.data, oldStorage.data)
|
||||
done()
|
||||
})
|
||||
.catch(done)
|
||||
})
|
||||
|
||||
it('should NOT change any state if a tokens property is missing', (done) => {
|
||||
const oldStorage = {
|
||||
'meta': {},
|
||||
'data': {
|
||||
'PreferencesController': {
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
migration39.migrate(oldStorage)
|
||||
.then((newStorage) => {
|
||||
assert.deepEqual(newStorage.data, oldStorage.data)
|
||||
done()
|
||||
})
|
||||
.catch(done)
|
||||
})
|
||||
|
||||
it('should NOT change any state if a accountTokens property is missing', (done) => {
|
||||
const oldStorage = {
|
||||
'meta': {},
|
||||
'data': {
|
||||
'PreferencesController': {
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
migration39.migrate(oldStorage)
|
||||
.then((newStorage) => {
|
||||
assert.deepEqual(newStorage.data, oldStorage.data)
|
||||
done()
|
||||
})
|
||||
.catch(done)
|
||||
})
|
||||
|
||||
it('should NOT change any state if PreferencesController is missing', (done) => {
|
||||
const oldStorage = {
|
||||
'meta': {},
|
||||
'data': {},
|
||||
}
|
||||
|
||||
migration39.migrate(oldStorage)
|
||||
.then((newStorage) => {
|
||||
assert.deepEqual(newStorage.data, oldStorage.data)
|
||||
done()
|
||||
})
|
||||
.catch(done)
|
||||
})
|
||||
})
|
@ -37,12 +37,12 @@ describe('Token Cell', () => {
|
||||
wrapper = mount(
|
||||
<Provider store={store}>
|
||||
<TokenCell
|
||||
address={'0xAnotherToken'}
|
||||
symbol={'TEST'}
|
||||
string={'5.000'}
|
||||
address="0xAnotherToken"
|
||||
symbol="TEST"
|
||||
string="5.000"
|
||||
network={22}
|
||||
currentCurrency={'usd'}
|
||||
image={'./test-image'}
|
||||
currentCurrency="usd"
|
||||
image="./test-image"
|
||||
/>
|
||||
</Provider>
|
||||
)
|
||||
|
@ -76,7 +76,7 @@ export default class AccountDetails extends Component {
|
||||
</div>
|
||||
</div>
|
||||
<Tooltip
|
||||
position={'bottom'}
|
||||
position="bottom"
|
||||
title={hasCopied ? t('copiedExclamation') : t('copyToClipboard')}
|
||||
wrapperClassName="account-details__tooltip"
|
||||
>
|
||||
|
@ -14,15 +14,15 @@ describe('Confirm Detail Row Component', function () {
|
||||
beforeEach(() => {
|
||||
wrapper = shallow(
|
||||
<ConfirmDetailRow
|
||||
errorType={'mockErrorType'}
|
||||
label={'mockLabel'}
|
||||
errorType="mockErrorType"
|
||||
label="mockLabel"
|
||||
showError={false}
|
||||
primaryText = {'mockFiatText'}
|
||||
secondaryText = {'mockEthText'}
|
||||
primaryValueTextColor= {'mockColor'}
|
||||
onHeaderClick= {propsMethodSpies.onHeaderClick}
|
||||
headerText = {'mockHeaderText'}
|
||||
headerTextClassName = {'mockHeaderClass'}
|
||||
primaryText="mockFiatText"
|
||||
secondaryText="mockEthText"
|
||||
primaryValueTextColor="mockColor"
|
||||
onHeaderClick={propsMethodSpies.onHeaderClick}
|
||||
headerText="mockHeaderText"
|
||||
headerTextClassName="mockHeaderClass"
|
||||
/>
|
||||
)
|
||||
})
|
||||
|
@ -0,0 +1,46 @@
|
||||
import React, { PureComponent } from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import HomeNotification from '../home-notification'
|
||||
|
||||
export default class DaiV1MigrationNotification extends PureComponent {
|
||||
static contextTypes = {
|
||||
t: PropTypes.func,
|
||||
}
|
||||
|
||||
static defaultProps = {
|
||||
string: '',
|
||||
symbol: '',
|
||||
}
|
||||
|
||||
static propTypes = {
|
||||
string: PropTypes.string,
|
||||
symbol: PropTypes.string,
|
||||
}
|
||||
|
||||
render () {
|
||||
const { t } = this.context
|
||||
const { string: balanceString, symbol } = this.props
|
||||
|
||||
if (!balanceString || !symbol) {
|
||||
return null
|
||||
}
|
||||
|
||||
if (balanceString === '0') {
|
||||
return null
|
||||
}
|
||||
|
||||
return (
|
||||
<HomeNotification
|
||||
descriptionText={t('migrateSai')}
|
||||
acceptText={t('migrate')}
|
||||
onAccept={() => {
|
||||
window.open('https://migrate.makerdao.com', '_blank', 'noopener')
|
||||
}}
|
||||
ignoreText={t('learnMore')}
|
||||
onIgnore={() => {
|
||||
window.open('https://blog.makerdao.com/multi-collateral-dai-is-live/', '_blank', 'noopener')
|
||||
}}
|
||||
/>
|
||||
)
|
||||
}
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
import { connect } from 'react-redux'
|
||||
import { compose } from 'recompose'
|
||||
import DaiMigrationNotification from './dai-migration-notification.component'
|
||||
import withTokenTracker from '../../../helpers/higher-order-components/with-token-tracker'
|
||||
import { getSelectedAddress, getDaiV1Token } from '../../../selectors/selectors'
|
||||
|
||||
const mapStateToProps = (state) => {
|
||||
const userAddress = getSelectedAddress(state)
|
||||
const oldDai = getDaiV1Token(state)
|
||||
|
||||
return {
|
||||
userAddress,
|
||||
token: oldDai,
|
||||
}
|
||||
}
|
||||
|
||||
export default compose(
|
||||
connect(mapStateToProps),
|
||||
withTokenTracker,
|
||||
)(DaiMigrationNotification)
|
1
ui/app/components/app/dai-migration-component/index.js
Normal file
1
ui/app/components/app/dai-migration-component/index.js
Normal file
@ -0,0 +1 @@
|
||||
export { default } from './dai-migration-notification.container'
|
@ -4,8 +4,6 @@ const h = require('react-hyperscript')
|
||||
const MenuDroppo = require('../../menu-droppo')
|
||||
const extend = require('xtend')
|
||||
|
||||
const noop = () => {}
|
||||
|
||||
class Dropdown extends Component {
|
||||
render () {
|
||||
const {
|
||||
@ -55,8 +53,6 @@ class Dropdown extends Component {
|
||||
}
|
||||
|
||||
Dropdown.defaultProps = {
|
||||
isOpen: false,
|
||||
onClick: noop,
|
||||
useCssTransition: false,
|
||||
}
|
||||
|
||||
|
@ -12,9 +12,9 @@ describe('Dropdown', () => {
|
||||
beforeEach(() => {
|
||||
wrapper = shallow(
|
||||
<DropdownMenuItem
|
||||
onClick = {onClickSpy}
|
||||
style = {{test: 'style'}}
|
||||
closeMenu = {closeMenuSpy}
|
||||
onClick={onClickSpy}
|
||||
style={{test: 'style'}}
|
||||
closeMenu={closeMenuSpy}
|
||||
>
|
||||
</DropdownMenuItem>
|
||||
)
|
||||
|
@ -11,7 +11,7 @@ describe('Dropdown Menu Components', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
wrapper = shallow(
|
||||
<Menu className = {'Test Class'} isShowing = {true}/>
|
||||
<Menu className="Test Class" isShowing={true}/>
|
||||
)
|
||||
})
|
||||
|
||||
@ -29,10 +29,10 @@ describe('Dropdown Menu Components', () => {
|
||||
beforeEach(() => {
|
||||
wrapper = shallow(
|
||||
<Item
|
||||
icon = {'test icon'}
|
||||
text = {'test text'}
|
||||
className = {'test className'}
|
||||
onClick = {onClickSpy}
|
||||
icon="test icon"
|
||||
text="test text"
|
||||
className="test className"
|
||||
onClick={onClickSpy}
|
||||
/>
|
||||
)
|
||||
})
|
||||
@ -74,7 +74,7 @@ describe('Dropdown Menu Components', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
wrapper = shallow(<CloseArea
|
||||
onClick = {onClickSpy}
|
||||
onClick={onClickSpy}
|
||||
/>)
|
||||
})
|
||||
|
||||
|
@ -8,10 +8,10 @@ describe('Network Dropdown Icon', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
wrapper = shallow(<NetworkDropdownIcon
|
||||
backgroundColor = {'red'}
|
||||
isSelected = {false}
|
||||
innerBorder = {'none'}
|
||||
diameter = {'12'}
|
||||
backgroundColor="red"
|
||||
isSelected={false}
|
||||
innerBorder="none"
|
||||
diameter="12"
|
||||
/>)
|
||||
})
|
||||
|
||||
|
@ -21,10 +21,10 @@ describe('AdvancedTabContent Component', function () {
|
||||
wrapper = shallow(<AdvancedTabContent
|
||||
updateCustomGasPrice={propsMethodSpies.updateCustomGasPrice}
|
||||
updateCustomGasLimit={propsMethodSpies.updateCustomGasLimit}
|
||||
customModalGasPriceInHex={'11'}
|
||||
customModalGasLimitInHex={'23456'}
|
||||
timeRemaining={'21500'}
|
||||
transactionFee={'$0.25'}
|
||||
customModalGasPriceInHex="11"
|
||||
customModalGasLimitInHex="23456"
|
||||
timeRemaining="21500"
|
||||
transactionFee="$0.25"
|
||||
insufficientBalance={false}
|
||||
customPriceIsSafe={true}
|
||||
isSpeedUp={false}
|
||||
|
@ -116,7 +116,7 @@ export default class GasModalPageContainer extends Component {
|
||||
<span className="gas-modal-content__info-row__send-info__value">{sendAmount}</span>
|
||||
</div>
|
||||
<div className="gas-modal-content__info-row__transaction-info">
|
||||
<span className={'gas-modal-content__info-row__transaction-info__label'}>{this.context.t('transactionFee')}</span>
|
||||
<span className="gas-modal-content__info-row__transaction-info__label">{this.context.t('transactionFee')}</span>
|
||||
<span className="gas-modal-content__info-row__transaction-info__value">{transactionFee}</span>
|
||||
</div>
|
||||
<div className="gas-modal-content__info-row__total-info">
|
||||
|
@ -74,9 +74,9 @@ describe('GasModalPageContainer Component', function () {
|
||||
customGasLimit={54321}
|
||||
gasPriceButtonGroupProps={mockGasPriceButtonGroupProps}
|
||||
infoRowProps={mockInfoRowProps}
|
||||
currentTimeEstimate={'1 min 31 sec'}
|
||||
customGasPriceInHex={'mockCustomGasPriceInHex'}
|
||||
customGasLimitInHex={'mockCustomGasLimitInHex'}
|
||||
currentTimeEstimate="1 min 31 sec"
|
||||
customGasPriceInHex="mockCustomGasPriceInHex"
|
||||
customGasLimitInHex="mockCustomGasLimitInHex"
|
||||
insufficientBalance={false}
|
||||
disableSave={false}
|
||||
/>)
|
||||
@ -195,9 +195,9 @@ describe('GasModalPageContainer Component', function () {
|
||||
customGasLimit={54321}
|
||||
gasPriceButtonGroupProps={mockGasPriceButtonGroupProps}
|
||||
infoRowProps={mockInfoRowProps}
|
||||
currentTimeEstimate={'1 min 31 sec'}
|
||||
customGasPriceInHex={'mockCustomGasPriceInHex'}
|
||||
customGasLimitInHex={'mockCustomGasLimitInHex'}
|
||||
currentTimeEstimate="1 min 31 sec"
|
||||
customGasPriceInHex="mockCustomGasPriceInHex"
|
||||
customGasLimitInHex="mockCustomGasLimitInHex"
|
||||
insufficientBalance={false}
|
||||
disableSave={false}
|
||||
hideBasic={true}
|
||||
|
@ -8,7 +8,7 @@
|
||||
background: rgba(36, 41, 46, 0.9);
|
||||
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.12);
|
||||
border-radius: 8px;
|
||||
height: 116px;
|
||||
min-height: 116px;
|
||||
padding: 16px;
|
||||
|
||||
@media screen and (min-width: 576px) {
|
||||
@ -29,6 +29,11 @@
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
&__icon {
|
||||
height: 16px;
|
||||
align-self: center;
|
||||
}
|
||||
|
||||
&__text {
|
||||
font-family: Roboto, 'sans-serif';
|
||||
font-style: normal;
|
||||
@ -95,6 +100,7 @@
|
||||
&__buttons {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
margin-top: 10px;
|
||||
justify-content: flex-start;
|
||||
flex-direction: row-reverse;
|
||||
}
|
||||
|
@ -84,4 +84,6 @@
|
||||
|
||||
@import 'home-notification/index';
|
||||
|
||||
@import 'multiple-notifications/index';
|
||||
|
||||
@import 'signature-request/index';
|
||||
|
@ -48,7 +48,7 @@ export default class ConfirmRemoveAccount extends Component {
|
||||
<a
|
||||
className=""
|
||||
href={genAccountLink(identity.address, this.props.network)}
|
||||
target={'_blank'}
|
||||
target="_blank"
|
||||
title={this.context.t('etherscanView')}
|
||||
>
|
||||
<img src="images/popout.svg" />
|
||||
|
@ -120,6 +120,7 @@ ExportPrivateKeyModal.prototype.renderButtons = function (privateKey, address, h
|
||||
type: 'secondary',
|
||||
large: true,
|
||||
className: 'export-private-key__button',
|
||||
disabled: !this.state.password,
|
||||
onClick: () => this.exportAccountAndGetPrivateKey(this.state.password, address),
|
||||
}, this.context.t('confirm'))
|
||||
)
|
||||
|
@ -12,7 +12,7 @@ const LoadingNetworkError = (props, context) => {
|
||||
submitText={t('tryAgain')}
|
||||
>
|
||||
<ModalContent
|
||||
description={'Oops! Something went wrong.'}
|
||||
description="Oops! Something went wrong."
|
||||
/>
|
||||
</Modal>
|
||||
)
|
||||
|
@ -102,7 +102,7 @@ export default class MetaMetricsOptInModal extends Component {
|
||||
hideModal()
|
||||
})
|
||||
}}
|
||||
cancelText={'No Thanks'}
|
||||
cancelText="No Thanks"
|
||||
hideCancel={false}
|
||||
onSubmit={() => {
|
||||
setParticipateInMetaMetrics(true)
|
||||
@ -118,8 +118,8 @@ export default class MetaMetricsOptInModal extends Component {
|
||||
hideModal()
|
||||
})
|
||||
}}
|
||||
submitText={'I agree'}
|
||||
submitButtonType={'confirm'}
|
||||
submitText="I agree"
|
||||
submitButtonType="confirm"
|
||||
disabled={false}
|
||||
/>
|
||||
</div>
|
||||
|
@ -142,14 +142,14 @@ export default class QrScanner extends Component {
|
||||
|
||||
renderVideo () {
|
||||
return (
|
||||
<div className={'qr-scanner__content__video-wrapper'}>
|
||||
<div className="qr-scanner__content__video-wrapper">
|
||||
<video
|
||||
id="video"
|
||||
style={{
|
||||
display: this.state.ready ? 'block' : 'none',
|
||||
}}
|
||||
/>
|
||||
{ !this.state.ready ? <Spinner color={'#F7C06C'} /> : null}
|
||||
{ !this.state.ready ? <Spinner color="#F7C06C" /> : null}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@ -172,12 +172,12 @@ export default class QrScanner extends Component {
|
||||
<div className="qr-scanner__close" onClick={this.stopAndClose}></div>
|
||||
|
||||
<div className="qr-scanner__image">
|
||||
<img src={'images/webcam.svg'} width={70} height={70} />
|
||||
<img src="images/webcam.svg" width={70} height={70} />
|
||||
</div>
|
||||
<div className="qr-scanner__title">
|
||||
{ title }
|
||||
</div>
|
||||
<div className={'qr-scanner__error'}>
|
||||
<div className="qr-scanner__error">
|
||||
{msg}
|
||||
</div>
|
||||
<PageContainerFooter
|
||||
@ -207,7 +207,7 @@ export default class QrScanner extends Component {
|
||||
<div className="qr-scanner__content">
|
||||
{ this.renderVideo() }
|
||||
</div>
|
||||
<div className={'qr-scanner__status'}>
|
||||
<div className="qr-scanner__status">
|
||||
{this.state.msg}
|
||||
</div>
|
||||
</div>
|
||||
|
@ -3,6 +3,11 @@ import classnames from 'classnames'
|
||||
import PropTypes from 'prop-types'
|
||||
|
||||
export default class MultipleNotifications extends PureComponent {
|
||||
static defaultProps = {
|
||||
children: [],
|
||||
classNames: [],
|
||||
}
|
||||
|
||||
static propTypes = {
|
||||
children: PropTypes.array,
|
||||
classNames: PropTypes.array,
|
||||
@ -14,7 +19,7 @@ export default class MultipleNotifications extends PureComponent {
|
||||
|
||||
render () {
|
||||
const { showAll } = this.state
|
||||
const { children, classNames = [] } = this.props
|
||||
const { children, classNames } = this.props
|
||||
|
||||
const childrenToRender = children.filter(child => child)
|
||||
if (childrenToRender.length === 0) {
|
||||
|
@ -34,9 +34,9 @@ export default class Sidebar extends Component {
|
||||
const { transaction = {} } = sidebarProps
|
||||
switch (type) {
|
||||
case WALLET_VIEW_SIDEBAR:
|
||||
return <WalletView responsiveDisplayClassname={'sidebar-right' } />
|
||||
return <WalletView responsiveDisplayClassname="sidebar-right" />
|
||||
case 'customize-gas':
|
||||
return <div className={'sidebar-left'}><CustomizeGas transaction={transaction} /></div>
|
||||
return <div className="sidebar-left"><CustomizeGas transaction={transaction} /></div>
|
||||
default:
|
||||
return null
|
||||
}
|
||||
|
@ -19,8 +19,8 @@ describe('Sidebar Component', function () {
|
||||
wrapper = shallow(<Sidebar
|
||||
sidebarOpen={false}
|
||||
hideSidebar={propsMethodSpies.hideSidebar}
|
||||
transitionName={'someTransition'}
|
||||
type={'wallet-view'}
|
||||
transitionName="someTransition"
|
||||
type="wallet-view"
|
||||
/>)
|
||||
})
|
||||
|
||||
|
@ -12,9 +12,9 @@ sinon.spy(ButtonGroup.prototype, 'handleButtonClick')
|
||||
sinon.spy(ButtonGroup.prototype, 'renderButtons')
|
||||
|
||||
const mockButtons = [
|
||||
<button onClick={childButtonSpies.onClick} key={'a'}><div className="mockClass" /></button>,
|
||||
<button onClick={childButtonSpies.onClick} key={'b'}></button>,
|
||||
<button onClick={childButtonSpies.onClick} key={'c'}></button>,
|
||||
<button onClick={childButtonSpies.onClick} key="a"><div className="mockClass" /></button>,
|
||||
<button onClick={childButtonSpies.onClick} key="b"></button>,
|
||||
<button onClick={childButtonSpies.onClick} key="c"></button>,
|
||||
]
|
||||
|
||||
describe('ButtonGroup Component', function () {
|
||||
|
@ -12,12 +12,12 @@ describe('Page Footer', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
wrapper = shallow(<PageFooter
|
||||
onCancel = {onCancel}
|
||||
onSubmit = {onSubmit}
|
||||
cancelText = {'Cancel'}
|
||||
submitText = {'Submit'}
|
||||
disabled = {false}
|
||||
submitButtonType = {'Test Type'}
|
||||
onCancel={onCancel}
|
||||
onSubmit={onSubmit}
|
||||
cancelText="Cancel"
|
||||
submitText="Submit"
|
||||
disabled={false}
|
||||
submitButtonType="Test Type"
|
||||
/>)
|
||||
})
|
||||
|
||||
|
@ -13,13 +13,13 @@ describe('Page Container Header', () => {
|
||||
onClose = sinon.spy()
|
||||
|
||||
wrapper = shallow(<PageContainerHeader
|
||||
showBackButton = {true}
|
||||
onBackButtonClick = {onBackButtonClick}
|
||||
backButtonStyles = {style}
|
||||
title = {'Test Title'}
|
||||
subtitle = {'Test Subtitle'}
|
||||
tabs = {'Test Tab'}
|
||||
onClose = {onClose}
|
||||
showBackButton={true}
|
||||
onBackButtonClick={onBackButtonClick}
|
||||
backButtonStyles={style}
|
||||
title="Test Title"
|
||||
subtitle="Test Subtitle"
|
||||
tabs="Test Tab"
|
||||
onClose={onClose}
|
||||
/>)
|
||||
})
|
||||
|
||||
|
@ -7,7 +7,6 @@ export default class Tooltip extends PureComponent {
|
||||
arrow: true,
|
||||
children: null,
|
||||
containerClassName: '',
|
||||
hideOnClick: false,
|
||||
html: null,
|
||||
onHidden: null,
|
||||
position: 'left',
|
||||
|
@ -56,7 +56,7 @@ export default class ConfirmDeployContract extends Component {
|
||||
render () {
|
||||
return (
|
||||
<ConfirmTransactionBase
|
||||
actionKey={'contractDeployment'}
|
||||
actionKey="contractDeployment"
|
||||
dataComponent={this.renderData()}
|
||||
/>
|
||||
)
|
||||
|
@ -30,7 +30,7 @@ export default class ConfirmSendEther extends Component {
|
||||
|
||||
return (
|
||||
<ConfirmTransactionBase
|
||||
actionKey={'confirm'}
|
||||
actionKey="confirm"
|
||||
hideData={hideData}
|
||||
onEdit={confirmTransactionData => this.handleEdit(confirmTransactionData)}
|
||||
/>
|
||||
|
@ -104,7 +104,7 @@ export default class MetaMetricsOptIn extends Component {
|
||||
})
|
||||
})
|
||||
}}
|
||||
cancelText={'No Thanks'}
|
||||
cancelText="No Thanks"
|
||||
hideCancel={false}
|
||||
onSubmit={() => {
|
||||
setParticipateInMetaMetrics(true)
|
||||
@ -137,8 +137,8 @@ export default class MetaMetricsOptIn extends Component {
|
||||
})
|
||||
})
|
||||
}}
|
||||
submitText={'I agree'}
|
||||
submitButtonType={'primary'}
|
||||
submitText="I agree"
|
||||
submitButtonType="primary"
|
||||
disabled={false}
|
||||
/>
|
||||
<div className="metametrics-opt-in__bottom-text">
|
||||
|
@ -25,7 +25,6 @@ class DraggableSeed extends Component {
|
||||
|
||||
static defaultProps = {
|
||||
className: '',
|
||||
onClick () {},
|
||||
}
|
||||
|
||||
componentWillReceiveProps (nextProps) {
|
||||
|
@ -4,6 +4,7 @@ import Media from 'react-media'
|
||||
import { Redirect } from 'react-router-dom'
|
||||
import { formatDate } from '../../helpers/utils/util'
|
||||
import HomeNotification from '../../components/app/home-notification'
|
||||
import DaiMigrationNotification from '../../components/app/dai-migration-component'
|
||||
import MultipleNotifications from '../../components/app/multiple-notifications'
|
||||
import WalletView from '../../components/app/wallet-view'
|
||||
import TransactionView from '../../components/app/transaction-view'
|
||||
@ -23,6 +24,7 @@ export default class Home extends PureComponent {
|
||||
|
||||
static defaultProps = {
|
||||
unsetMigratedPrivacyMode: null,
|
||||
hasDaiV1Token: false,
|
||||
}
|
||||
|
||||
static propTypes = {
|
||||
@ -43,6 +45,7 @@ export default class Home extends PureComponent {
|
||||
restoreFromThreeBox: PropTypes.func,
|
||||
setShowRestorePromptToFalse: PropTypes.func,
|
||||
threeBoxLastUpdated: PropTypes.number,
|
||||
hasDaiV1Token: PropTypes.bool,
|
||||
}
|
||||
|
||||
componentWillMount () {
|
||||
@ -86,6 +89,7 @@ export default class Home extends PureComponent {
|
||||
forgottenPassword,
|
||||
providerRequests,
|
||||
history,
|
||||
hasDaiV1Token,
|
||||
showPrivacyModeNotification,
|
||||
unsetMigratedPrivacyMode,
|
||||
shouldShowSeedPhraseReminder,
|
||||
@ -117,9 +121,7 @@ export default class Home extends PureComponent {
|
||||
{ !history.location.pathname.match(/^\/confirm-transaction/)
|
||||
? (
|
||||
<TransactionView>
|
||||
<MultipleNotifications
|
||||
className
|
||||
>
|
||||
<MultipleNotifications>
|
||||
{
|
||||
showPrivacyModeNotification
|
||||
? <HomeNotification
|
||||
@ -174,6 +176,11 @@ export default class Home extends PureComponent {
|
||||
/>
|
||||
: null
|
||||
}
|
||||
{
|
||||
hasDaiV1Token
|
||||
? <DaiMigrationNotification />
|
||||
: null
|
||||
}
|
||||
</MultipleNotifications>
|
||||
</TransactionView>
|
||||
)
|
||||
|
@ -3,7 +3,7 @@ import { compose } from 'recompose'
|
||||
import { connect } from 'react-redux'
|
||||
import { withRouter } from 'react-router-dom'
|
||||
import { unconfirmedTransactionsCountSelector } from '../../selectors/confirm-transaction'
|
||||
import { getCurrentEthBalance } from '../../selectors/selectors'
|
||||
import { getCurrentEthBalance, getDaiV1Token } from '../../selectors/selectors'
|
||||
import {
|
||||
unsetMigratedPrivacyMode,
|
||||
restoreFromThreeBox,
|
||||
@ -44,6 +44,7 @@ const mapStateToProps = state => {
|
||||
showRestorePrompt,
|
||||
selectedAddress,
|
||||
threeBoxLastUpdated,
|
||||
hasDaiV1Token: Boolean(getDaiV1Token(state)),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -25,10 +25,10 @@ describe('AccountListItem Component', function () {
|
||||
beforeEach(() => {
|
||||
wrapper = shallow(<AccountListItem
|
||||
account={ { address: 'mockAddress', name: 'mockName', balance: 'mockBalance' } }
|
||||
className={'mockClassName'}
|
||||
className="mockClassName"
|
||||
conversionRate={4}
|
||||
currentCurrency={'mockCurrentyCurrency'}
|
||||
nativeCurrency={'ETH'}
|
||||
currentCurrency="mockCurrentyCurrency"
|
||||
nativeCurrency="ETH"
|
||||
displayAddress={false}
|
||||
displayBalance={false}
|
||||
handleClick={propsMethodSpies.handleClick}
|
||||
|
@ -23,9 +23,9 @@ describe('AddRecipient Component', function () {
|
||||
closeToDropdown={propsMethodSpies.closeToDropdown}
|
||||
inError={false}
|
||||
inWarning={false}
|
||||
network={'mockNetwork'}
|
||||
network="mockNetwork"
|
||||
openToDropdown={propsMethodSpies.openToDropdown}
|
||||
to={'mockTo'}
|
||||
to="mockTo"
|
||||
toAccounts={['mockAccount']}
|
||||
toDropdownOpen={false}
|
||||
updateGas={propsMethodSpies.updateGas}
|
||||
|
@ -64,7 +64,7 @@ export default class AmountMaxButton extends Component {
|
||||
const { maxModeOn, buttonDataLoading, inError } = this.props
|
||||
|
||||
return (
|
||||
<div className={'send-v2__amount-max'} onClick={buttonDataLoading || inError ? null : this.onMaxClick}>
|
||||
<div className="send-v2__amount-max" onClick={buttonDataLoading || inError ? null : this.onMaxClick}>
|
||||
<input type="checkbox" checked={maxModeOn} />
|
||||
<div className={classnames('send-v2__amount-max__button', { 'send-v2__amount-max__button__disabled': buttonDataLoading || inError })}>
|
||||
{this.context.t('max')}
|
||||
|
@ -19,13 +19,13 @@ describe('AmountMaxButton Component', function () {
|
||||
|
||||
beforeEach(() => {
|
||||
wrapper = shallow(<AmountMaxButton
|
||||
balance={'mockBalance'}
|
||||
gasTotal={'mockGasTotal'}
|
||||
balance="mockBalance"
|
||||
gasTotal="mockGasTotal"
|
||||
maxModeOn={false}
|
||||
selectedToken={ { address: 'mockTokenAddress' } }
|
||||
setAmountToMax={propsMethodSpies.setAmountToMax}
|
||||
setMaxModeTo={propsMethodSpies.setMaxModeTo}
|
||||
tokenBalance={'mockTokenBalance'}
|
||||
tokenBalance="mockTokenBalance"
|
||||
/>, {
|
||||
context: {
|
||||
t: str => str + '_t',
|
||||
|
@ -108,7 +108,7 @@ export default class SendAmountRow extends Component {
|
||||
<SendRowWrapper
|
||||
label={`${this.context.t('amount')}:`}
|
||||
showError={inError}
|
||||
errorType={'amount'}
|
||||
errorType="amount"
|
||||
>
|
||||
{gasTotal && <AmountMaxButton inError={inError} />}
|
||||
{ this.renderInput() }
|
||||
|
@ -26,17 +26,17 @@ describe('SendAmountRow Component', function () {
|
||||
|
||||
beforeEach(() => {
|
||||
wrapper = shallow(<SendAmountRow
|
||||
amount={'mockAmount'}
|
||||
amountConversionRate={'mockAmountConversionRate'}
|
||||
balance={'mockBalance'}
|
||||
amount="mockAmount"
|
||||
amountConversionRate="mockAmountConversionRate"
|
||||
balance="mockBalance"
|
||||
conversionRate={7}
|
||||
convertedCurrency={'mockConvertedCurrency'}
|
||||
gasTotal={'mockGasTotal'}
|
||||
convertedCurrency="mockConvertedCurrency"
|
||||
gasTotal="mockGasTotal"
|
||||
inError={false}
|
||||
primaryCurrency={'mockPrimaryCurrency'}
|
||||
primaryCurrency="mockPrimaryCurrency"
|
||||
selectedToken={ { address: 'mockTokenAddress' } }
|
||||
setMaxModeTo={propsMethodSpies.setMaxModeTo}
|
||||
tokenBalance={'mockTokenBalance'}
|
||||
tokenBalance="mockTokenBalance"
|
||||
updateGasFeeError={propsMethodSpies.updateGasFeeError}
|
||||
updateSendAmount={propsMethodSpies.updateSendAmount}
|
||||
updateSendAmountError={propsMethodSpies.updateSendAmountError}
|
||||
|
@ -17,7 +17,7 @@ export default class SendDropdownList extends Component {
|
||||
|
||||
getListItemIcon (accountAddress, activeAddress) {
|
||||
return accountAddress === activeAddress
|
||||
? <i className={`fa fa-check fa-lg`} style={ { color: '#02c9b1' } }/>
|
||||
? <i className="fa fa-check fa-lg" style={ { color: '#02c9b1' } }/>
|
||||
: null
|
||||
}
|
||||
|
||||
|
@ -25,7 +25,7 @@ describe('SendDropdownList Component', function () {
|
||||
]}
|
||||
closeDropdown={propsMethodSpies.closeDropdown}
|
||||
onSelect={propsMethodSpies.onSelect}
|
||||
activeAddress={'mockAddress2'}
|
||||
activeAddress="mockAddress2"
|
||||
/>, { context: { t: str => str + '_t' } })
|
||||
})
|
||||
|
||||
@ -39,7 +39,7 @@ describe('SendDropdownList Component', function () {
|
||||
it('should return check icon if the passed addresses are the same', () => {
|
||||
assert.deepEqual(
|
||||
wrapper.instance().getListItemIcon('mockAccount0', 'mockAccount0'),
|
||||
<i className={`fa fa-check fa-lg`} style={ { color: '#02c9b1' } }/>
|
||||
<i className="fa fa-check fa-lg" style={ { color: '#02c9b1' } }/>
|
||||
)
|
||||
})
|
||||
|
||||
|
@ -17,9 +17,9 @@ describe('GasFeeDisplay Component', function () {
|
||||
beforeEach(() => {
|
||||
wrapper = shallow(<GasFeeDisplay
|
||||
conversionRate={20}
|
||||
gasTotal={'mockGasTotal'}
|
||||
primaryCurrency={'mockPrimaryCurrency'}
|
||||
convertedCurrency={'mockConvertedCurrency'}
|
||||
gasTotal="mockGasTotal"
|
||||
primaryCurrency="mockPrimaryCurrency"
|
||||
convertedCurrency="mockConvertedCurrency"
|
||||
showGasButtonGroup={propsMethodSpies.showCustomizeGasModal}
|
||||
onReset={propsMethodSpies.onReset}
|
||||
/>, {context: {t: str => str + '_t'}})
|
||||
|
@ -152,7 +152,7 @@ export default class SendGasRow extends Component {
|
||||
<SendRowWrapper
|
||||
label={`${this.context.t('transactionFee')}:`}
|
||||
showError={gasFeeError}
|
||||
errorType={'gasFee'}
|
||||
errorType="gasFee"
|
||||
>
|
||||
{ this.renderContent() }
|
||||
</SendRowWrapper>
|
||||
|
@ -19,10 +19,10 @@ describe('SendGasRow Component', function () {
|
||||
beforeEach(() => {
|
||||
wrapper = shallow(<SendGasRow
|
||||
conversionRate={20}
|
||||
convertedCurrency={'mockConvertedCurrency'}
|
||||
gasFeeError={'mockGasFeeError'}
|
||||
convertedCurrency="mockConvertedCurrency"
|
||||
gasFeeError="mockGasFeeError"
|
||||
gasLoadingError={false}
|
||||
gasTotal={'mockGasTotal'}
|
||||
gasTotal="mockGasTotal"
|
||||
gasButtonGroupShown={false}
|
||||
showCustomizeGasModal={propsMethodSpies.showCustomizeGasModal}
|
||||
resetGasButtons={propsMethodSpies.resetGasButtons}
|
||||
|
@ -29,7 +29,7 @@ export default class SendHexDataRow extends Component {
|
||||
<SendRowWrapper
|
||||
label={`${t('hexData')}:`}
|
||||
showError={inError}
|
||||
errorType={'amount'}
|
||||
errorType="amount"
|
||||
>
|
||||
<textarea
|
||||
onInput={this.onInput}
|
||||
|
@ -9,7 +9,7 @@ describe('SendRowErrorMessage Component', function () {
|
||||
beforeEach(() => {
|
||||
wrapper = shallow(<SendRowErrorMessage
|
||||
errors={{ error1: 'abc', error2: 'def' }}
|
||||
errorType={'error3'}
|
||||
errorType="error3"
|
||||
/>, { context: { t: str => str + '_t' } })
|
||||
})
|
||||
|
||||
|
@ -10,8 +10,8 @@ describe('SendContent Component', function () {
|
||||
|
||||
beforeEach(() => {
|
||||
wrapper = shallow(<SendRowWrapper
|
||||
errorType={'mockErrorType'}
|
||||
label={'mockLabel'}
|
||||
errorType="mockErrorType"
|
||||
label="mockLabel"
|
||||
showError={false}
|
||||
>
|
||||
<span>Mock Form Field</span>
|
||||
@ -54,8 +54,8 @@ describe('SendContent Component', function () {
|
||||
|
||||
it('should render its second child as a child of the send-v2__form-field, if it has two children', () => {
|
||||
wrapper = shallow(<SendRowWrapper
|
||||
errorType={'mockErrorType'}
|
||||
label={'mockLabel'}
|
||||
errorType="mockErrorType"
|
||||
label="mockLabel"
|
||||
showError={false}
|
||||
>
|
||||
<span>Mock Custom Label Content</span>
|
||||
@ -66,8 +66,8 @@ describe('SendContent Component', function () {
|
||||
|
||||
it('should render its first child as the last child of the send-v2__form-label, if it has two children', () => {
|
||||
wrapper = shallow(<SendRowWrapper
|
||||
errorType={'mockErrorType'}
|
||||
label={'mockLabel'}
|
||||
errorType="mockErrorType"
|
||||
label="mockLabel"
|
||||
showError={false}
|
||||
>
|
||||
<span>Mock Custom Label Content</span>
|
||||
|
@ -27,22 +27,22 @@ describe('SendFooter Component', function () {
|
||||
beforeEach(() => {
|
||||
wrapper = shallow(<SendFooter
|
||||
addToAddressBookIfNew={propsMethodSpies.addToAddressBookIfNew}
|
||||
amount={'mockAmount'}
|
||||
amount="mockAmount"
|
||||
clearSend={propsMethodSpies.clearSend}
|
||||
disabled={true}
|
||||
editingTransactionId={'mockEditingTransactionId'}
|
||||
editingTransactionId="mockEditingTransactionId"
|
||||
errors={{}}
|
||||
from={ { address: 'mockAddress', balance: 'mockBalance' } }
|
||||
gasLimit={'mockGasLimit'}
|
||||
gasPrice={'mockGasPrice'}
|
||||
gasTotal={'mockGasTotal'}
|
||||
gasLimit="mockGasLimit"
|
||||
gasPrice="mockGasPrice"
|
||||
gasTotal="mockGasTotal"
|
||||
history={historySpies}
|
||||
inError={false}
|
||||
selectedToken={{ mockProp: 'mockSelectedTokenProp' }}
|
||||
sign={propsMethodSpies.sign}
|
||||
to={'mockTo'}
|
||||
to="mockTo"
|
||||
toAccounts={['mockAccount']}
|
||||
tokenBalance={'mockTokenBalance'}
|
||||
tokenBalance="mockTokenBalance"
|
||||
unapprovedTxs={['mockTx']}
|
||||
update={propsMethodSpies.update}
|
||||
sendErrors={{}}
|
||||
@ -184,22 +184,22 @@ describe('SendFooter Component', function () {
|
||||
sinon.stub(SendFooter.prototype, 'formShouldBeDisabled').returns('formShouldBeDisabledReturn')
|
||||
wrapper = shallow(<SendFooter
|
||||
addToAddressBookIfNew={propsMethodSpies.addToAddressBookIfNew}
|
||||
amount={'mockAmount'}
|
||||
amount="mockAmount"
|
||||
clearSend={propsMethodSpies.clearSend}
|
||||
disabled={true}
|
||||
editingTransactionId={'mockEditingTransactionId'}
|
||||
editingTransactionId="mockEditingTransactionId"
|
||||
errors={{}}
|
||||
from={ { address: 'mockAddress', balance: 'mockBalance' } }
|
||||
gasLimit={'mockGasLimit'}
|
||||
gasPrice={'mockGasPrice'}
|
||||
gasTotal={'mockGasTotal'}
|
||||
gasLimit="mockGasLimit"
|
||||
gasPrice="mockGasPrice"
|
||||
gasTotal="mockGasTotal"
|
||||
history={historySpies}
|
||||
inError={false}
|
||||
selectedToken={{ mockProp: 'mockSelectedTokenProp' }}
|
||||
sign={propsMethodSpies.sign}
|
||||
to={'mockTo'}
|
||||
to="mockTo"
|
||||
toAccounts={['mockAccount']}
|
||||
tokenBalance={'mockTokenBalance'}
|
||||
tokenBalance="mockTokenBalance"
|
||||
unapprovedTxs={['mockTx']}
|
||||
update={propsMethodSpies.update}
|
||||
/>, { context: { t: str => str, metricsEvent: () => ({}) } })
|
||||
|
@ -23,7 +23,7 @@ describe('SendHeader Component', function () {
|
||||
wrapper = shallow(<SendHeader
|
||||
clearSend={propsMethodSpies.clearSend}
|
||||
history={historySpies}
|
||||
titleKey={'mockTitleKey'}
|
||||
titleKey="mockTitleKey"
|
||||
/>, { context: { t: (str1, str2) => str2 ? str1 + str2 : str1 } })
|
||||
})
|
||||
|
||||
|
@ -41,26 +41,26 @@ describe('Send Component', function () {
|
||||
|
||||
beforeEach(() => {
|
||||
wrapper = shallow(<SendTransactionScreen
|
||||
amount={'mockAmount'}
|
||||
amountConversionRate={'mockAmountConversionRate'}
|
||||
blockGasLimit={'mockBlockGasLimit'}
|
||||
amount="mockAmount"
|
||||
amountConversionRate="mockAmountConversionRate"
|
||||
blockGasLimit="mockBlockGasLimit"
|
||||
conversionRate={10}
|
||||
editingTransactionId={'mockEditingTransactionId'}
|
||||
editingTransactionId="mockEditingTransactionId"
|
||||
fetchBasicGasEstimates={propsMethodSpies.fetchBasicGasEstimates}
|
||||
fetchGasEstimates={propsMethodSpies.fetchGasEstimates}
|
||||
from={ { address: 'mockAddress', balance: 'mockBalance' } }
|
||||
gasLimit={'mockGasLimit'}
|
||||
gasPrice={'mockGasPrice'}
|
||||
gasTotal={'mockGasTotal'}
|
||||
gasLimit="mockGasLimit"
|
||||
gasPrice="mockGasPrice"
|
||||
gasTotal="mockGasTotal"
|
||||
history={{ mockProp: 'history-abc'}}
|
||||
network={'3'}
|
||||
primaryCurrency={'mockPrimaryCurrency'}
|
||||
network="3"
|
||||
primaryCurrency="mockPrimaryCurrency"
|
||||
recentBlocks={['mockBlock']}
|
||||
selectedAddress={'mockSelectedAddress'}
|
||||
selectedToken={'mockSelectedToken'}
|
||||
selectedAddress="mockSelectedAddress"
|
||||
selectedToken="mockSelectedToken"
|
||||
showHexData={true}
|
||||
tokenBalance={'mockTokenBalance'}
|
||||
tokenContract={'mockTokenContract'}
|
||||
tokenBalance="mockTokenBalance"
|
||||
tokenContract="mockTokenContract"
|
||||
updateAndSetGasLimit={propsMethodSpies.updateAndSetGasLimit}
|
||||
updateSendErrors={propsMethodSpies.updateSendErrors}
|
||||
updateSendTokenBalance={propsMethodSpies.updateSendTokenBalance}
|
||||
|
@ -26,7 +26,7 @@ export default class ToAutoComplete extends Component {
|
||||
|
||||
getListItemIcon (listItemAddress, toAddress) {
|
||||
return toAddress && listItemAddress === toAddress
|
||||
? <i className={'fa fa-check fa-lg'}
|
||||
? <i className="fa fa-check fa-lg"
|
||||
style={{
|
||||
color: '#02c9b1',
|
||||
}}
|
||||
@ -48,13 +48,13 @@ export default class ToAutoComplete extends Component {
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className={'send-v2__from-dropdown__close-area'} onClick={closeDropdown} />
|
||||
<div className={'send-v2__from-dropdown__list'}>
|
||||
<div className="send-v2__from-dropdown__close-area" onClick={closeDropdown} />
|
||||
<div className="send-v2__from-dropdown__list">
|
||||
{accountsToRender.map((account, i) => (
|
||||
<AccountListItem
|
||||
key={i}
|
||||
account={account}
|
||||
className={'account-list-item__dropdown'}
|
||||
className="account-list-item__dropdown"
|
||||
handleClick={() => {
|
||||
onChange(account.address)
|
||||
closeDropdown()
|
||||
@ -106,7 +106,7 @@ export default class ToAutoComplete extends Component {
|
||||
} = this.props
|
||||
|
||||
return (
|
||||
<div className={'send-v2__to-autocomplete'}>
|
||||
<div className="send-v2__to-autocomplete">
|
||||
<input
|
||||
className={classnames('send-v2__to-autocomplete__input', {
|
||||
'send-v2__error-border': inError,
|
||||
@ -122,7 +122,7 @@ export default class ToAutoComplete extends Component {
|
||||
{
|
||||
to
|
||||
? null
|
||||
: <i className={'fa fa-caret-down fa-lg send-v2__to-autocomplete__down-caret'}
|
||||
: <i className="fa fa-caret-down fa-lg send-v2__to-autocomplete__down-caret"
|
||||
onClick={() => this.handleInputEvent()}
|
||||
style={{
|
||||
style: {color: '#dedede'},
|
||||
|
@ -123,7 +123,7 @@ export default class AddContact extends PureComponent {
|
||||
history.push(CONTACT_LIST_ROUTE)
|
||||
}}
|
||||
submitText={this.context.t('save')}
|
||||
submitButtonType={'confirm'}
|
||||
submitButtonType="confirm"
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
|
@ -133,7 +133,7 @@ export default class EditContact extends PureComponent {
|
||||
history.push(`${viewRoute}/${address}`)
|
||||
}}
|
||||
submitText={this.context.t('save')}
|
||||
submitButtonType={'confirm'}
|
||||
submitButtonType="confirm"
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
|
@ -49,6 +49,7 @@ const selectors = {
|
||||
getAccountType,
|
||||
getNumberOfAccounts,
|
||||
getNumberOfTokens,
|
||||
getDaiV1Token,
|
||||
isEthereumNetwork,
|
||||
getMetaMetricState,
|
||||
getRpcPrefsForCurrentProvider,
|
||||
@ -225,6 +226,12 @@ function getAddressBookEntryName (state, address) {
|
||||
return entry && entry.name !== '' ? entry.name : addressSlicer(address)
|
||||
}
|
||||
|
||||
function getDaiV1Token (state) {
|
||||
const OLD_DAI_CONTRACT_ADDRESS = '0x89d24A6b4CcB1B6fAA2625fE562bDD9a23260359'
|
||||
const tokens = state.metamask.tokens || []
|
||||
return tokens.find(({address}) => checksumAddress(address) === OLD_DAI_CONTRACT_ADDRESS)
|
||||
}
|
||||
|
||||
function accountsWithSendEtherInfoSelector (state) {
|
||||
const accounts = getMetaMaskAccounts(state)
|
||||
const { identities } = state.metamask
|
||||
|
18
yarn.lock
18
yarn.lock
@ -10038,10 +10038,10 @@ eth-block-tracker@^4.4.2:
|
||||
pify "^3.0.0"
|
||||
safe-event-emitter "^1.0.1"
|
||||
|
||||
eth-contract-metadata@1.9.3, eth-contract-metadata@^1.9.1:
|
||||
version "1.9.3"
|
||||
resolved "https://registry.yarnpkg.com/eth-contract-metadata/-/eth-contract-metadata-1.9.3.tgz#d627d81cb6dadbe9d9261ec9594617ada38a25f2"
|
||||
integrity sha512-qDdH9n2yw5GqWW5E6wrh7KZ8WicpEzofrpuJG3FWiJew+Yt6RapnqtXN8ljvxY+UTZPd1QzLXswKfpJyzsH4Tw==
|
||||
eth-contract-metadata@^1.11.0:
|
||||
version "1.11.0"
|
||||
resolved "https://registry.yarnpkg.com/eth-contract-metadata/-/eth-contract-metadata-1.11.0.tgz#4d23a8208d5d53be9d4c0696ed8492b505c6bca1"
|
||||
integrity sha512-Bbvio71M+lH+qXd8XXddpTc8hhjL9m4fNPOxmZFIX8z0/VooUdwV8YmmDAbkU5WVioZi+Jp1XaoO7VwzXnDboA==
|
||||
|
||||
eth-ens-namehash@2.0.8, eth-ens-namehash@^2.0.8:
|
||||
version "2.0.8"
|
||||
@ -12160,13 +12160,13 @@ fuse.js@^3.4.4:
|
||||
resolved "https://registry.yarnpkg.com/fuse.js/-/fuse.js-3.4.5.tgz#8954fb43f9729bd5dbcb8c08f251db552595a7a6"
|
||||
integrity sha512-s9PGTaQIkT69HaeoTVjwGsLfb8V8ScJLx5XGFcKHg0MqLUH/UZ4EKOtqtXX9k7AFqCGxD1aJmYb8Q5VYDibVRQ==
|
||||
|
||||
gaba@^1.8.0:
|
||||
version "1.8.0"
|
||||
resolved "https://registry.yarnpkg.com/gaba/-/gaba-1.8.0.tgz#5370e5d662de6aa8e4e41de791da0996a7e12dbe"
|
||||
integrity sha512-M20fZ6yKRefxgxb82l5Of0VutFxvc1Uxg8LSncaiq5kWQZO1UNe5pkxQc4EQT9rGAcBm6ASv7FG0B04syIELRA==
|
||||
gaba@^1.9.0:
|
||||
version "1.9.0"
|
||||
resolved "https://registry.yarnpkg.com/gaba/-/gaba-1.9.0.tgz#ccd9f99c56687b5acd39f9e3ceb435b2a59b6aa1"
|
||||
integrity sha512-HoVreAdZssL0jNHuzZ7WP+YKZ0riu44jVDWxhQ9hsgPuzxbVEsz9fO/HDxqAdNZS1Cswayq6+ciZ3HSCFWMKbQ==
|
||||
dependencies:
|
||||
await-semaphore "^0.1.3"
|
||||
eth-contract-metadata "^1.9.1"
|
||||
eth-contract-metadata "^1.11.0"
|
||||
eth-ens-namehash "^2.0.8"
|
||||
eth-json-rpc-infura "^4.0.1"
|
||||
eth-keyring-controller "^5.3.0"
|
||||
|
Loading…
Reference in New Issue
Block a user