From 5d7c2810a701097ef1a4f9de23948418340f9cb4 Mon Sep 17 00:00:00 2001 From: Dan Finlay Date: Mon, 18 Jun 2018 15:05:41 -0700 Subject: Begin adding eth_watchToken --- app/scripts/background.js | 2 ++ app/scripts/controllers/preferences.js | 25 +++++++++++++++++++++++++ app/scripts/metamask-controller.js | 1 + 3 files changed, 28 insertions(+) (limited to 'app/scripts') diff --git a/app/scripts/background.js b/app/scripts/background.js index 2451cddb6..2be600c4b 100644 --- a/app/scripts/background.js +++ b/app/scripts/background.js @@ -248,6 +248,7 @@ function setupController (initState, initLangCode) { showUnconfirmedMessage: triggerUi, unlockAccountMessage: triggerUi, showUnapprovedTx: triggerUi, + showAddTokenUi: triggerUi, // initial state initState, // initial locale code @@ -436,3 +437,4 @@ extension.runtime.onInstalled.addListener(function (details) { extension.tabs.create({url: 'https://metamask.io/#how-it-works'}) } }) + diff --git a/app/scripts/controllers/preferences.js b/app/scripts/controllers/preferences.js index 8411e3a28..8a8b9a335 100644 --- a/app/scripts/controllers/preferences.js +++ b/app/scripts/controllers/preferences.js @@ -25,6 +25,7 @@ class PreferencesController { frequentRpcList: [], currentAccountTab: 'history', tokens: [], + suggestedTokens: [], useBlockie: false, featureFlags: {}, currentLocale: opts.initLangCode, @@ -48,6 +49,30 @@ class PreferencesController { this.store.updateState({ useBlockie: val }) } + getSuggestedTokens () { + return this.store.getState().suggestedTokens + } + + /** + * RPC engine middleware for requesting new token added + * + * @param req + * @param res + * @param {Function} - next + * @param {Function} - end + */ + requestAddToken(req, res, next, end) { + if (req.method === 'eth_watchToken') { + // Validate params! + // this.suggestedTokens.push(req.params) + const [ rawAddress, symbol, decimals ] = req.params + this.addToken(rawAddress, symbol, decimals) + end(null, rawAddress) + } else { + next() + } + } + /** * Getter for the `useBlockie` property * diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index d40a351a5..0af7c5051 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -1077,6 +1077,7 @@ module.exports = class MetamaskController extends EventEmitter { engine.push(createOriginMiddleware({ origin })) engine.push(createLoggerMiddleware({ origin })) engine.push(filterMiddleware) + engine.push(this.preferencesController.requestAddToken.bind(this.preferencesController)) engine.push(createProviderMiddleware({ provider: this.provider })) // setup connection -- cgit v1.2.3 From f14ed329801ab65c31e84f8e9d8d93700ed56670 Mon Sep 17 00:00:00 2001 From: Dan Finlay Date: Mon, 18 Jun 2018 15:33:50 -0700 Subject: Begin letting UI show suggested tokens --- app/scripts/controllers/preferences.js | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) (limited to 'app/scripts') diff --git a/app/scripts/controllers/preferences.js b/app/scripts/controllers/preferences.js index 8a8b9a335..b76141be4 100644 --- a/app/scripts/controllers/preferences.js +++ b/app/scripts/controllers/preferences.js @@ -25,7 +25,7 @@ class PreferencesController { frequentRpcList: [], currentAccountTab: 'history', tokens: [], - suggestedTokens: [], + suggestedTokens: {}, useBlockie: false, featureFlags: {}, currentLocale: opts.initLangCode, @@ -53,6 +53,13 @@ class PreferencesController { return this.store.getState().suggestedTokens } + addSuggestedToken (tokenOpts) { + // TODO: Validate params + const suggested = this.getSuggestedTokens() + suggested[tokenOpts.address] = suggested + this.store.updateState({ suggestedTokens: suggested }) + } + /** * RPC engine middleware for requesting new token added * @@ -63,13 +70,24 @@ class PreferencesController { */ requestAddToken(req, res, next, end) { if (req.method === 'eth_watchToken') { - // Validate params! - // this.suggestedTokens.push(req.params) + // TODO: Validate params! const [ rawAddress, symbol, decimals ] = req.params - this.addToken(rawAddress, symbol, decimals) - end(null, rawAddress) + + const tokenOpts = { + address: rawAddress, + decimals, + symbol, + } + + this.suggestWatchToken() + + return end(null, { + result: rawAddress, + "jsonrpc": "2.0", + id: req.id, + }) } else { - next() + return next() } } -- cgit v1.2.3 From 5e4f3e430a9057b073cfc82255fe62c5e8550e44 Mon Sep 17 00:00:00 2001 From: Dan Finlay Date: Mon, 18 Jun 2018 15:37:37 -0700 Subject: Get popup appearing when suggesting new token --- app/scripts/controllers/preferences.js | 4 +++- app/scripts/metamask-controller.js | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) (limited to 'app/scripts') diff --git a/app/scripts/controllers/preferences.js b/app/scripts/controllers/preferences.js index b76141be4..e33501cd0 100644 --- a/app/scripts/controllers/preferences.js +++ b/app/scripts/controllers/preferences.js @@ -36,6 +36,7 @@ class PreferencesController { this.diagnostics = opts.diagnostics this.store = new ObservableStore(initState) + this.showAddTokenUi = opts.showAddTokenUi } // PUBLIC METHODS @@ -79,7 +80,8 @@ class PreferencesController { symbol, } - this.suggestWatchToken() + this.addSuggestedToken(tokenOpts) + this.showAddTokenUi() return end(null, { result: rawAddress, diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index 0af7c5051..d5627a0d1 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -85,6 +85,7 @@ module.exports = class MetamaskController extends EventEmitter { this.preferencesController = new PreferencesController({ initState: initState.PreferencesController, initLangCode: opts.initLangCode, + showAddTokenUi: opts.showAddTokenUi, }) // currency controller -- cgit v1.2.3 From 0481335dda447ba4c228d146834952bac0ad641b Mon Sep 17 00:00:00 2001 From: Dan Finlay Date: Mon, 18 Jun 2018 15:50:27 -0700 Subject: Improved rpc-engine usage --- app/scripts/controllers/preferences.js | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'app/scripts') diff --git a/app/scripts/controllers/preferences.js b/app/scripts/controllers/preferences.js index e33501cd0..f1bd66889 100644 --- a/app/scripts/controllers/preferences.js +++ b/app/scripts/controllers/preferences.js @@ -83,11 +83,7 @@ class PreferencesController { this.addSuggestedToken(tokenOpts) this.showAddTokenUi() - return end(null, { - result: rawAddress, - "jsonrpc": "2.0", - id: req.id, - }) + return end(rawAddress) } else { return next() } -- cgit v1.2.3 From 081884bd8095b2027e88fabdfe297f6d2fc8c38e Mon Sep 17 00:00:00 2001 From: Esteban MIno Date: Fri, 3 Aug 2018 16:42:13 -0400 Subject: rpc-engine not crashing when eth_watchToken --- app/scripts/controllers/preferences.js | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'app/scripts') diff --git a/app/scripts/controllers/preferences.js b/app/scripts/controllers/preferences.js index 8a4a63bb6..50f716852 100644 --- a/app/scripts/controllers/preferences.js +++ b/app/scripts/controllers/preferences.js @@ -57,7 +57,7 @@ class PreferencesController { addSuggestedToken (tokenOpts) { // TODO: Validate params const suggested = this.getSuggestedTokens() - suggested[tokenOpts.address] = suggested + suggested[tokenOpts.address] = tokenOpts this.store.updateState({ suggestedTokens: suggested }) } @@ -69,11 +69,10 @@ class PreferencesController { * @param {Function} - next * @param {Function} - end */ - requestAddToken(req, res, next, end) { + requestAddToken (req, res, next, end) { if (req.method === 'eth_watchToken') { // TODO: Validate params! const [ rawAddress, symbol, decimals ] = req.params - const tokenOpts = { address: rawAddress, decimals, @@ -82,8 +81,8 @@ class PreferencesController { this.addSuggestedToken(tokenOpts) this.showAddTokenUi() - - return end(rawAddress) + res.result = rawAddress + return end() } else { return next() } -- cgit v1.2.3 From 9ac9f53a73357238ed2ee0ce57c65de592cfd968 Mon Sep 17 00:00:00 2001 From: Esteban MIno Date: Fri, 3 Aug 2018 19:24:12 -0400 Subject: eth_watchToken working --- app/scripts/controllers/preferences.js | 7 +++++++ app/scripts/metamask-controller.js | 1 + 2 files changed, 8 insertions(+) (limited to 'app/scripts') diff --git a/app/scripts/controllers/preferences.js b/app/scripts/controllers/preferences.js index 50f716852..521a68a66 100644 --- a/app/scripts/controllers/preferences.js +++ b/app/scripts/controllers/preferences.js @@ -211,6 +211,13 @@ class PreferencesController { return selected } + removeSuggestedTokens () { + return new Promise((resolve, reject) => { + this.store.updateState({ suggestedTokens: {} }) + resolve() + }) + } + /** * Setter for the `selectedAddress` property * diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index e843ec660..801363cb0 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -392,6 +392,7 @@ module.exports = class MetamaskController extends EventEmitter { setSelectedAddress: nodeify(preferencesController.setSelectedAddress, preferencesController), addToken: nodeify(preferencesController.addToken, preferencesController), removeToken: nodeify(preferencesController.removeToken, preferencesController), + removeSuggestedTokens: nodeify(preferencesController.removeSuggestedTokens, preferencesController), setCurrentAccountTab: nodeify(preferencesController.setCurrentAccountTab, preferencesController), setAccountLabel: nodeify(preferencesController.setAccountLabel, preferencesController), setFeatureFlag: nodeify(preferencesController.setFeatureFlag, preferencesController), -- cgit v1.2.3 From 78ad3c38e2c9cfce8b0756c7d0df8264316d1d21 Mon Sep 17 00:00:00 2001 From: Esteban MIno Date: Mon, 6 Aug 2018 18:28:47 -0400 Subject: add suggested token params validation --- app/scripts/controllers/preferences.js | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) (limited to 'app/scripts') diff --git a/app/scripts/controllers/preferences.js b/app/scripts/controllers/preferences.js index 521a68a66..3bbd48f06 100644 --- a/app/scripts/controllers/preferences.js +++ b/app/scripts/controllers/preferences.js @@ -1,5 +1,6 @@ const ObservableStore = require('obs-store') const normalizeAddress = require('eth-sig-util').normalize +const isValidAddress = require('ethereumjs-util').isValidAddress const extend = require('xtend') @@ -55,9 +56,12 @@ class PreferencesController { } addSuggestedToken (tokenOpts) { - // TODO: Validate params + this._validateSuggestedTokenParams(tokenOpts) const suggested = this.getSuggestedTokens() - suggested[tokenOpts.address] = tokenOpts + const { rawAddress, symbol, decimals } = tokenOpts + const address = normalizeAddress(rawAddress) + const newEntry = { address, symbol, decimals } + suggested[address] = newEntry this.store.updateState({ suggestedTokens: suggested }) } @@ -71,10 +75,10 @@ class PreferencesController { */ requestAddToken (req, res, next, end) { if (req.method === 'eth_watchToken') { - // TODO: Validate params! const [ rawAddress, symbol, decimals ] = req.params + this._validateSuggestedTokenParams({ rawAddress, symbol, decimals }) const tokenOpts = { - address: rawAddress, + rawAddress, decimals, symbol, } @@ -423,6 +427,23 @@ class PreferencesController { // // PRIVATE METHODS // + + /** + * Validates that the passed options for suggested token have all required properties. + * + * @param {Object} opts The options object to validate + * @throws {string} Throw a custom error indicating that address, symbol and/or decimals + * doesn't fulfill requirements + * + */ + _validateSuggestedTokenParams (opts) { + const { rawAddress, symbol, decimals } = opts + if (!rawAddress || !symbol || !decimals) throw new Error(`Cannot suggest token without address, symbol, and decimals`) + if (!(symbol.length < 5)) throw new Error(`Invalid symbol ${symbol} more than four characters`) + const numDecimals = parseInt(decimals, 10) + if (isNaN(numDecimals) || numDecimals > 18 || numDecimals < 0) throw new Error(`Invalid decimals ${decimals}`) + if (!isValidAddress(rawAddress)) throw new Error(`Invalid address ${rawAddress}`) + } } module.exports = PreferencesController -- cgit v1.2.3 From 15ea8c04b28a9f89999c96caf188d157e5230a55 Mon Sep 17 00:00:00 2001 From: Esteban MIno Date: Tue, 7 Aug 2018 17:53:36 -0400 Subject: fix merge --- app/scripts/controllers/preferences.js | 1 + 1 file changed, 1 insertion(+) (limited to 'app/scripts') diff --git a/app/scripts/controllers/preferences.js b/app/scripts/controllers/preferences.js index a42bb77b3..a6530424d 100644 --- a/app/scripts/controllers/preferences.js +++ b/app/scripts/controllers/preferences.js @@ -454,6 +454,7 @@ class PreferencesController { const numDecimals = parseInt(decimals, 10) if (isNaN(numDecimals) || numDecimals > 18 || numDecimals < 0) throw new Error(`Invalid decimals ${decimals}`) if (!isValidAddress(rawAddress)) throw new Error(`Invalid address ${rawAddress}`) + } /** * Subscription to network provider type. -- cgit v1.2.3 From 33357e3538b5157a852323d5f1e2db7f19b3303e Mon Sep 17 00:00:00 2001 From: Esteban MIno Date: Tue, 7 Aug 2018 19:12:16 -0400 Subject: refactor unused code --- app/scripts/controllers/preferences.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'app/scripts') diff --git a/app/scripts/controllers/preferences.js b/app/scripts/controllers/preferences.js index a6530424d..4aa91534d 100644 --- a/app/scripts/controllers/preferences.js +++ b/app/scripts/controllers/preferences.js @@ -452,10 +452,12 @@ class PreferencesController { if (!rawAddress || !symbol || !decimals) throw new Error(`Cannot suggest token without address, symbol, and decimals`) if (!(symbol.length < 5)) throw new Error(`Invalid symbol ${symbol} more than four characters`) const numDecimals = parseInt(decimals, 10) - if (isNaN(numDecimals) || numDecimals > 18 || numDecimals < 0) throw new Error(`Invalid decimals ${decimals}`) + if (isNaN(numDecimals) || numDecimals > 36 || numDecimals < 0) { + throw new Error(`Invalid decimals ${decimals} must be at least 0, and not over 36`) + } if (!isValidAddress(rawAddress)) throw new Error(`Invalid address ${rawAddress}`) } - + /** * Subscription to network provider type. * -- cgit v1.2.3 From 8f5b80a0fe13c53a602a5b2883ae1cdfba0123e1 Mon Sep 17 00:00:00 2001 From: Esteban MIno Date: Tue, 14 Aug 2018 13:58:47 -0300 Subject: update method to metamask_watchToken --- app/scripts/controllers/preferences.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'app/scripts') diff --git a/app/scripts/controllers/preferences.js b/app/scripts/controllers/preferences.js index 4aa91534d..4cc08a9af 100644 --- a/app/scripts/controllers/preferences.js +++ b/app/scripts/controllers/preferences.js @@ -77,7 +77,7 @@ class PreferencesController { * @param {Function} - end */ requestAddToken (req, res, next, end) { - if (req.method === 'eth_watchToken') { + if (req.method === 'metamask_watchToken') { const [ rawAddress, symbol, decimals ] = req.params this._validateSuggestedTokenParams({ rawAddress, symbol, decimals }) const tokenOpts = { -- cgit v1.2.3 From a4c3f6b65c9a25da0319b9077d830c23f729b32f Mon Sep 17 00:00:00 2001 From: Esteban MIno Date: Tue, 14 Aug 2018 20:08:12 -0300 Subject: add support for images base64 and urls on new ui --- app/scripts/controllers/preferences.js | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'app/scripts') diff --git a/app/scripts/controllers/preferences.js b/app/scripts/controllers/preferences.js index 4cc08a9af..a92db15c7 100644 --- a/app/scripts/controllers/preferences.js +++ b/app/scripts/controllers/preferences.js @@ -61,9 +61,9 @@ class PreferencesController { addSuggestedToken (tokenOpts) { this._validateSuggestedTokenParams(tokenOpts) const suggested = this.getSuggestedTokens() - const { rawAddress, symbol, decimals } = tokenOpts + const { rawAddress, symbol, decimals, imageUrl } = tokenOpts const address = normalizeAddress(rawAddress) - const newEntry = { address, symbol, decimals } + const newEntry = { address, symbol, decimals, imageUrl } suggested[address] = newEntry this.store.updateState({ suggestedTokens: suggested }) } @@ -78,12 +78,13 @@ class PreferencesController { */ requestAddToken (req, res, next, end) { if (req.method === 'metamask_watchToken') { - const [ rawAddress, symbol, decimals ] = req.params + const [ rawAddress, symbol, decimals, imageUrl ] = req.params this._validateSuggestedTokenParams({ rawAddress, symbol, decimals }) const tokenOpts = { rawAddress, decimals, symbol, + imageUrl, } this.addSuggestedToken(tokenOpts) @@ -283,10 +284,9 @@ class PreferencesController { * @returns {Promise} Promises the new array of AddedToken objects. * */ - async addToken (rawAddress, symbol, decimals) { + async addToken (rawAddress, symbol, decimals, imageUrl) { const address = normalizeAddress(rawAddress) - const newEntry = { address, symbol, decimals } - + const newEntry = { address, symbol, decimals, imageUrl } const tokens = this.store.getState().tokens const previousEntry = tokens.find((token, index) => { return token.address === address @@ -299,6 +299,7 @@ class PreferencesController { tokens.push(newEntry) } this._updateAccountTokens(tokens) + return Promise.resolve(tokens) } -- cgit v1.2.3 From a4b6b2357a2eee7a4286a8490b8d31aac487120d Mon Sep 17 00:00:00 2001 From: Esteban MIno Date: Tue, 14 Aug 2018 20:09:56 -0300 Subject: watchToken to watchAsset --- app/scripts/controllers/preferences.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'app/scripts') diff --git a/app/scripts/controllers/preferences.js b/app/scripts/controllers/preferences.js index a92db15c7..04c9a3254 100644 --- a/app/scripts/controllers/preferences.js +++ b/app/scripts/controllers/preferences.js @@ -77,7 +77,7 @@ class PreferencesController { * @param {Function} - end */ requestAddToken (req, res, next, end) { - if (req.method === 'metamask_watchToken') { + if (req.method === 'metamask_watchAsset') { const [ rawAddress, symbol, decimals, imageUrl ] = req.params this._validateSuggestedTokenParams({ rawAddress, symbol, decimals }) const tokenOpts = { -- cgit v1.2.3 From b766104c8d8fc4d4b1c5660af54b791243836f30 Mon Sep 17 00:00:00 2001 From: Esteban MIno Date: Wed, 15 Aug 2018 18:34:57 -0300 Subject: add suggested tokens objects in metamask state --- app/scripts/controllers/preferences.js | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) (limited to 'app/scripts') diff --git a/app/scripts/controllers/preferences.js b/app/scripts/controllers/preferences.js index 04c9a3254..bda521bdd 100644 --- a/app/scripts/controllers/preferences.js +++ b/app/scripts/controllers/preferences.js @@ -15,6 +15,7 @@ class PreferencesController { * @property {string} store.currentAccountTab Indicates the selected tab in the ui * @property {array} store.tokens The tokens the user wants display in their token lists * @property {object} store.accountTokens The tokens stored per account and then per network type + * @property {object} store.objects Contains assets objects related to * @property {boolean} store.useBlockie The users preference for blockie identicons within the UI * @property {object} store.featureFlags A key-boolean map, where keys refer to features and booleans to whether the * user wishes to see that feature @@ -28,6 +29,7 @@ class PreferencesController { currentAccountTab: 'history', accountTokens: {}, tokens: [], + objects: {}, suggestedTokens: {}, useBlockie: false, featureFlags: {}, @@ -58,6 +60,10 @@ class PreferencesController { return this.store.getState().suggestedTokens } + getObjects () { + return this.store.getState().objects + } + addSuggestedToken (tokenOpts) { this._validateSuggestedTokenParams(tokenOpts) const suggested = this.getSuggestedTokens() @@ -286,8 +292,9 @@ class PreferencesController { */ async addToken (rawAddress, symbol, decimals, imageUrl) { const address = normalizeAddress(rawAddress) - const newEntry = { address, symbol, decimals, imageUrl } + const newEntry = { address, symbol, decimals } const tokens = this.store.getState().tokens + const objects = this.getObjects() const previousEntry = tokens.find((token, index) => { return token.address === address }) @@ -298,8 +305,9 @@ class PreferencesController { } else { tokens.push(newEntry) } - this._updateAccountTokens(tokens) - + objects[address] = imageUrl + this._updateAccountTokens(tokens, objects) + console.log('OBJECTS OBJET', this.getObjects()) return Promise.resolve(tokens) } @@ -312,8 +320,10 @@ class PreferencesController { */ removeToken (rawAddress) { const tokens = this.store.getState().tokens + const objects = this.getObjects() const updatedTokens = tokens.filter(token => token.address !== rawAddress) - this._updateAccountTokens(updatedTokens) + const updatedObjects = Object.keys(objects).filter(key => key !== rawAddress) + this._updateAccountTokens(updatedTokens, updatedObjects) return Promise.resolve(updatedTokens) } @@ -477,10 +487,10 @@ class PreferencesController { * @param {array} tokens Array of tokens to be updated. * */ - _updateAccountTokens (tokens) { + _updateAccountTokens (tokens, objects) { const { accountTokens, providerType, selectedAddress } = this._getTokenRelatedStates() accountTokens[selectedAddress][providerType] = tokens - this.store.updateState({ accountTokens, tokens }) + this.store.updateState({ accountTokens, tokens, objects }) } /** -- cgit v1.2.3 From 5289a36664f180fae1dc6da07ccc80d307f7408c Mon Sep 17 00:00:00 2001 From: Esteban MIno Date: Wed, 15 Aug 2018 20:01:59 -0300 Subject: change watchAsset to new spec for type ERC20 --- app/scripts/controllers/preferences.js | 42 ++++++++++++++++++++++------------ 1 file changed, 27 insertions(+), 15 deletions(-) (limited to 'app/scripts') diff --git a/app/scripts/controllers/preferences.js b/app/scripts/controllers/preferences.js index bda521bdd..9f5826dd9 100644 --- a/app/scripts/controllers/preferences.js +++ b/app/scripts/controllers/preferences.js @@ -75,7 +75,7 @@ class PreferencesController { } /** - * RPC engine middleware for requesting new token added + * RPC engine middleware for requesting new asset added * * @param req * @param res @@ -84,21 +84,18 @@ class PreferencesController { */ requestAddToken (req, res, next, end) { if (req.method === 'metamask_watchAsset') { - const [ rawAddress, symbol, decimals, imageUrl ] = req.params - this._validateSuggestedTokenParams({ rawAddress, symbol, decimals }) - const tokenOpts = { - rawAddress, - decimals, - symbol, - imageUrl, + const { type, options } = req.params + switch (type) { + case 'ERC20': + this._handleWatchAssetERC20(options, res) + res.result = options.address + break + default: + // TODO return promise for not handled assets } - - this.addSuggestedToken(tokenOpts) - this.showAddTokenUi() - res.result = rawAddress - return end() + end() } else { - return next() + next() } } @@ -307,7 +304,6 @@ class PreferencesController { } objects[address] = imageUrl this._updateAccountTokens(tokens, objects) - console.log('OBJECTS OBJET', this.getObjects()) return Promise.resolve(tokens) } @@ -520,6 +516,22 @@ class PreferencesController { const tokens = accountTokens[selectedAddress][providerType] return { tokens, accountTokens, providerType, selectedAddress } } + + /** + * Handle the suggestion of an ERC20 asset through `watchAsset` + * * + * @param {Object} options Parameters according to addition of ERC20 token + * + */ + _handleWatchAssetERC20 (options) { + // TODO handle bad parameters + const { address, symbol, decimals, imageUrl } = options + const rawAddress = address + this._validateSuggestedTokenParams({ rawAddress, symbol, decimals }) + const tokenOpts = { rawAddress, decimals, symbol, imageUrl } + this.addSuggestedToken(tokenOpts) + this.showAddTokenUi() + } } module.exports = PreferencesController -- cgit v1.2.3 From a36ea0e2328e6ffedd5b526470dc1133c4f2f556 Mon Sep 17 00:00:00 2001 From: Esteban MIno Date: Thu, 16 Aug 2018 12:04:43 -0300 Subject: show watch asset image from hide token modal --- app/scripts/controllers/preferences.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'app/scripts') diff --git a/app/scripts/controllers/preferences.js b/app/scripts/controllers/preferences.js index 9f5826dd9..59c24f987 100644 --- a/app/scripts/controllers/preferences.js +++ b/app/scripts/controllers/preferences.js @@ -15,7 +15,7 @@ class PreferencesController { * @property {string} store.currentAccountTab Indicates the selected tab in the ui * @property {array} store.tokens The tokens the user wants display in their token lists * @property {object} store.accountTokens The tokens stored per account and then per network type - * @property {object} store.objects Contains assets objects related to + * @property {object} store.objects Contains assets objects related to assets added * @property {boolean} store.useBlockie The users preference for blockie identicons within the UI * @property {object} store.featureFlags A key-boolean map, where keys refer to features and booleans to whether the * user wishes to see that feature -- cgit v1.2.3 From bb868f58348962d4a85415380d11f72892a2e28c Mon Sep 17 00:00:00 2001 From: Esteban MIno Date: Thu, 16 Aug 2018 20:19:19 -0300 Subject: correct behavior when notification is closed when popup --- app/scripts/controllers/preferences.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'app/scripts') diff --git a/app/scripts/controllers/preferences.js b/app/scripts/controllers/preferences.js index 59c24f987..1438d6f7f 100644 --- a/app/scripts/controllers/preferences.js +++ b/app/scripts/controllers/preferences.js @@ -237,7 +237,7 @@ class PreferencesController { removeSuggestedTokens () { return new Promise((resolve, reject) => { this.store.updateState({ suggestedTokens: {} }) - resolve() + resolve({}) }) } -- cgit v1.2.3 From dbab9a007fc9663427cebdbe1d41c51df67fd1fe Mon Sep 17 00:00:00 2001 From: Esteban MIno Date: Thu, 16 Aug 2018 21:17:02 -0300 Subject: delete according image when token added with watchToken deleted --- app/scripts/controllers/preferences.js | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) (limited to 'app/scripts') diff --git a/app/scripts/controllers/preferences.js b/app/scripts/controllers/preferences.js index 1438d6f7f..611d2d067 100644 --- a/app/scripts/controllers/preferences.js +++ b/app/scripts/controllers/preferences.js @@ -15,7 +15,7 @@ class PreferencesController { * @property {string} store.currentAccountTab Indicates the selected tab in the ui * @property {array} store.tokens The tokens the user wants display in their token lists * @property {object} store.accountTokens The tokens stored per account and then per network type - * @property {object} store.objects Contains assets objects related to assets added + * @property {object} store.imageObjects Contains assets objects related to assets added * @property {boolean} store.useBlockie The users preference for blockie identicons within the UI * @property {object} store.featureFlags A key-boolean map, where keys refer to features and booleans to whether the * user wishes to see that feature @@ -28,8 +28,8 @@ class PreferencesController { frequentRpcList: [], currentAccountTab: 'history', accountTokens: {}, + imageObjects: {}, tokens: [], - objects: {}, suggestedTokens: {}, useBlockie: false, featureFlags: {}, @@ -60,8 +60,8 @@ class PreferencesController { return this.store.getState().suggestedTokens } - getObjects () { - return this.store.getState().objects + getImageObjects () { + return this.store.getState().imageObjects } addSuggestedToken (tokenOpts) { @@ -89,11 +89,12 @@ class PreferencesController { case 'ERC20': this._handleWatchAssetERC20(options, res) res.result = options.address + end() break default: // TODO return promise for not handled assets + end(new Error(`Asset of type ${type} not supported`)) } - end() } else { next() } @@ -291,7 +292,7 @@ class PreferencesController { const address = normalizeAddress(rawAddress) const newEntry = { address, symbol, decimals } const tokens = this.store.getState().tokens - const objects = this.getObjects() + const imageObjects = this.getImageObjects() const previousEntry = tokens.find((token, index) => { return token.address === address }) @@ -302,8 +303,8 @@ class PreferencesController { } else { tokens.push(newEntry) } - objects[address] = imageUrl - this._updateAccountTokens(tokens, objects) + imageObjects[address] = imageUrl + this._updateAccountTokens(tokens, imageObjects) return Promise.resolve(tokens) } @@ -316,10 +317,10 @@ class PreferencesController { */ removeToken (rawAddress) { const tokens = this.store.getState().tokens - const objects = this.getObjects() + const imageObjects = this.getImageObjects() const updatedTokens = tokens.filter(token => token.address !== rawAddress) - const updatedObjects = Object.keys(objects).filter(key => key !== rawAddress) - this._updateAccountTokens(updatedTokens, updatedObjects) + delete imageObjects[rawAddress] + this._updateAccountTokens(updatedTokens, imageObjects) return Promise.resolve(updatedTokens) } @@ -483,10 +484,10 @@ class PreferencesController { * @param {array} tokens Array of tokens to be updated. * */ - _updateAccountTokens (tokens, objects) { + _updateAccountTokens (tokens, imageObjects) { const { accountTokens, providerType, selectedAddress } = this._getTokenRelatedStates() accountTokens[selectedAddress][providerType] = tokens - this.store.updateState({ accountTokens, tokens, objects }) + this.store.updateState({ accountTokens, tokens, imageObjects }) } /** -- cgit v1.2.3 From 68c1b4c17049e3ef18397ae83b0eb9da8cccab2c Mon Sep 17 00:00:00 2001 From: Esteban MIno Date: Mon, 20 Aug 2018 22:32:14 -0300 Subject: watchAsset returns result wether token was added or not --- app/scripts/background.js | 20 +++++++++++++++++++- app/scripts/controllers/preferences.js | 16 +++++++++------- app/scripts/metamask-controller.js | 4 ++-- 3 files changed, 30 insertions(+), 10 deletions(-) (limited to 'app/scripts') diff --git a/app/scripts/background.js b/app/scripts/background.js index 029ad139a..1913d35dd 100644 --- a/app/scripts/background.js +++ b/app/scripts/background.js @@ -256,7 +256,7 @@ function setupController (initState, initLangCode) { showUnconfirmedMessage: triggerUi, unlockAccountMessage: triggerUi, showUnapprovedTx: triggerUi, - showAddTokenUi: triggerUi, + showWatchAssetUi: showWatchAssetUi, // initial state initState, // initial locale code @@ -444,6 +444,24 @@ function triggerUi () { }) } +/** + * Opens the browser popup for user confirmation of watchAsset + * then it waits until user interact with the UI + */ +function showWatchAssetUi () { + triggerUi() + return new Promise( + (resolve) => { + var interval = setInterval(() => { + if (!notificationIsOpen) { + clearInterval(interval) + resolve() + } + }, 1000) + } + ) +} + // On first install, open a window to MetaMask website to how-it-works. extension.runtime.onInstalled.addListener(function (details) { if ((details.reason === 'install') && (!METAMASK_DEBUG)) { diff --git a/app/scripts/controllers/preferences.js b/app/scripts/controllers/preferences.js index 611d2d067..11f36e284 100644 --- a/app/scripts/controllers/preferences.js +++ b/app/scripts/controllers/preferences.js @@ -41,7 +41,7 @@ class PreferencesController { this.diagnostics = opts.diagnostics this.network = opts.network this.store = new ObservableStore(initState) - this.showAddTokenUi = opts.showAddTokenUi + this.showWatchAssetUi = opts.showWatchAssetUi this._subscribeProviderType() } // PUBLIC METHODS @@ -82,13 +82,12 @@ class PreferencesController { * @param {Function} - next * @param {Function} - end */ - requestAddToken (req, res, next, end) { + async requestWatchAsset (req, res, next, end) { if (req.method === 'metamask_watchAsset') { const { type, options } = req.params switch (type) { case 'ERC20': - this._handleWatchAssetERC20(options, res) - res.result = options.address + res.result = await this._handleWatchAssetERC20(options) end() break default: @@ -521,17 +520,20 @@ class PreferencesController { /** * Handle the suggestion of an ERC20 asset through `watchAsset` * * - * @param {Object} options Parameters according to addition of ERC20 token + * @param {Boolean} assetAdded Boolean according to addition of ERC20 token * */ - _handleWatchAssetERC20 (options) { + async _handleWatchAssetERC20 (options) { // TODO handle bad parameters const { address, symbol, decimals, imageUrl } = options const rawAddress = address this._validateSuggestedTokenParams({ rawAddress, symbol, decimals }) const tokenOpts = { rawAddress, decimals, symbol, imageUrl } this.addSuggestedToken(tokenOpts) - this.showAddTokenUi() + return this.showWatchAssetUi().then(() => { + const tokenAddresses = this.getTokens().filter(token => token.address === normalizeAddress(rawAddress)) + return tokenAddresses.length > 0 + }) } } diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index 57001fdff..0ee9d730c 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -88,7 +88,7 @@ module.exports = class MetamaskController extends EventEmitter { this.preferencesController = new PreferencesController({ initState: initState.PreferencesController, initLangCode: opts.initLangCode, - showAddTokenUi: opts.showAddTokenUi, + showWatchAssetUi: opts.showWatchAssetUi, network: this.networkController, }) @@ -1241,7 +1241,7 @@ module.exports = class MetamaskController extends EventEmitter { engine.push(createOriginMiddleware({ origin })) engine.push(createLoggerMiddleware({ origin })) engine.push(filterMiddleware) - engine.push(this.preferencesController.requestAddToken.bind(this.preferencesController)) + engine.push(this.preferencesController.requestWatchAsset.bind(this.preferencesController)) engine.push(createProviderMiddleware({ provider: this.provider })) // setup connection -- cgit v1.2.3 From 6fa889abcb2e907073e227379e1fc930d22bfe2d Mon Sep 17 00:00:00 2001 From: Esteban MIno Date: Tue, 21 Aug 2018 12:59:42 -0300 Subject: refactor watchToken related functions --- app/scripts/controllers/preferences.js | 73 +++++++++++++++++----------------- 1 file changed, 36 insertions(+), 37 deletions(-) (limited to 'app/scripts') diff --git a/app/scripts/controllers/preferences.js b/app/scripts/controllers/preferences.js index 11f36e284..04a9f2e75 100644 --- a/app/scripts/controllers/preferences.js +++ b/app/scripts/controllers/preferences.js @@ -15,7 +15,7 @@ class PreferencesController { * @property {string} store.currentAccountTab Indicates the selected tab in the ui * @property {array} store.tokens The tokens the user wants display in their token lists * @property {object} store.accountTokens The tokens stored per account and then per network type - * @property {object} store.imageObjects Contains assets objects related to assets added + * @property {object} store.assetImages Contains assets objects related to assets added * @property {boolean} store.useBlockie The users preference for blockie identicons within the UI * @property {object} store.featureFlags A key-boolean map, where keys refer to features and booleans to whether the * user wishes to see that feature @@ -28,7 +28,7 @@ class PreferencesController { frequentRpcList: [], currentAccountTab: 'history', accountTokens: {}, - imageObjects: {}, + assetImages: {}, tokens: [], suggestedTokens: {}, useBlockie: false, @@ -60,12 +60,12 @@ class PreferencesController { return this.store.getState().suggestedTokens } - getImageObjects () { - return this.store.getState().imageObjects + getAssetImages () { + return this.store.getState().assetImages } - addSuggestedToken (tokenOpts) { - this._validateSuggestedTokenParams(tokenOpts) + addSuggestedERC20Asset (tokenOpts) { + this._validateERC20AssetParams(tokenOpts) const suggested = this.getSuggestedTokens() const { rawAddress, symbol, decimals, imageUrl } = tokenOpts const address = normalizeAddress(rawAddress) @@ -291,7 +291,7 @@ class PreferencesController { const address = normalizeAddress(rawAddress) const newEntry = { address, symbol, decimals } const tokens = this.store.getState().tokens - const imageObjects = this.getImageObjects() + const assetImages = this.getAssetImages() const previousEntry = tokens.find((token, index) => { return token.address === address }) @@ -302,8 +302,8 @@ class PreferencesController { } else { tokens.push(newEntry) } - imageObjects[address] = imageUrl - this._updateAccountTokens(tokens, imageObjects) + assetImages[address] = imageUrl + this._updateAccountTokens(tokens, assetImages) return Promise.resolve(tokens) } @@ -316,10 +316,10 @@ class PreferencesController { */ removeToken (rawAddress) { const tokens = this.store.getState().tokens - const imageObjects = this.getImageObjects() + const assetImages = this.getAssetImages() const updatedTokens = tokens.filter(token => token.address !== rawAddress) - delete imageObjects[rawAddress] - this._updateAccountTokens(updatedTokens, imageObjects) + delete assetImages[rawAddress] + this._updateAccountTokens(updatedTokens, assetImages) return Promise.resolve(updatedTokens) } @@ -446,25 +446,6 @@ class PreferencesController { // PRIVATE METHODS // - /** - * Validates that the passed options for suggested token have all required properties. - * - * @param {Object} opts The options object to validate - * @throws {string} Throw a custom error indicating that address, symbol and/or decimals - * doesn't fulfill requirements - * - */ - _validateSuggestedTokenParams (opts) { - const { rawAddress, symbol, decimals } = opts - if (!rawAddress || !symbol || !decimals) throw new Error(`Cannot suggest token without address, symbol, and decimals`) - if (!(symbol.length < 5)) throw new Error(`Invalid symbol ${symbol} more than four characters`) - const numDecimals = parseInt(decimals, 10) - if (isNaN(numDecimals) || numDecimals > 36 || numDecimals < 0) { - throw new Error(`Invalid decimals ${decimals} must be at least 0, and not over 36`) - } - if (!isValidAddress(rawAddress)) throw new Error(`Invalid address ${rawAddress}`) - } - /** * Subscription to network provider type. * @@ -483,10 +464,10 @@ class PreferencesController { * @param {array} tokens Array of tokens to be updated. * */ - _updateAccountTokens (tokens, imageObjects) { + _updateAccountTokens (tokens, assetImages) { const { accountTokens, providerType, selectedAddress } = this._getTokenRelatedStates() accountTokens[selectedAddress][providerType] = tokens - this.store.updateState({ accountTokens, tokens, imageObjects }) + this.store.updateState({ accountTokens, tokens, assetImages }) } /** @@ -520,21 +501,39 @@ class PreferencesController { /** * Handle the suggestion of an ERC20 asset through `watchAsset` * * - * @param {Boolean} assetAdded Boolean according to addition of ERC20 token + * @param {Promise} promise Promise according to addition of ERC20 token * */ async _handleWatchAssetERC20 (options) { - // TODO handle bad parameters const { address, symbol, decimals, imageUrl } = options const rawAddress = address - this._validateSuggestedTokenParams({ rawAddress, symbol, decimals }) + this._validateERC20AssetParams({ rawAddress, symbol, decimals }) const tokenOpts = { rawAddress, decimals, symbol, imageUrl } - this.addSuggestedToken(tokenOpts) + this.addSuggestedERC20Asset(tokenOpts) return this.showWatchAssetUi().then(() => { const tokenAddresses = this.getTokens().filter(token => token.address === normalizeAddress(rawAddress)) return tokenAddresses.length > 0 }) } + + /** + * Validates that the passed options for suggested token have all required properties. + * + * @param {Object} opts The options object to validate + * @throws {string} Throw a custom error indicating that address, symbol and/or decimals + * doesn't fulfill requirements + * + */ + _validateERC20AssetParams (opts) { + const { rawAddress, symbol, decimals } = opts + if (!rawAddress || !symbol || !decimals) throw new Error(`Cannot suggest token without address, symbol, and decimals`) + if (!(symbol.length < 6)) throw new Error(`Invalid symbol ${symbol} more than five characters`) + const numDecimals = parseInt(decimals, 10) + if (isNaN(numDecimals) || numDecimals > 36 || numDecimals < 0) { + throw new Error(`Invalid decimals ${decimals} must be at least 0, and not over 36`) + } + if (!isValidAddress(rawAddress)) throw new Error(`Invalid address ${rawAddress}`) + } } module.exports = PreferencesController -- cgit v1.2.3 From 3a3732eb2471c83722d41f2389f34c8759b5e2cb Mon Sep 17 00:00:00 2001 From: Esteban MIno Date: Tue, 21 Aug 2018 13:12:45 -0300 Subject: returning error in watchAsset --- app/scripts/controllers/preferences.js | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) (limited to 'app/scripts') diff --git a/app/scripts/controllers/preferences.js b/app/scripts/controllers/preferences.js index 04a9f2e75..a03abbf79 100644 --- a/app/scripts/controllers/preferences.js +++ b/app/scripts/controllers/preferences.js @@ -87,11 +87,15 @@ class PreferencesController { const { type, options } = req.params switch (type) { case 'ERC20': - res.result = await this._handleWatchAssetERC20(options) - end() + const result = await this._handleWatchAssetERC20(options) + if (result instanceof Error) { + end(result) + } else { + res.result = result + end() + } break default: - // TODO return promise for not handled assets end(new Error(`Asset of type ${type} not supported`)) } } else { @@ -507,7 +511,11 @@ class PreferencesController { async _handleWatchAssetERC20 (options) { const { address, symbol, decimals, imageUrl } = options const rawAddress = address - this._validateERC20AssetParams({ rawAddress, symbol, decimals }) + try { + this._validateERC20AssetParams({ rawAddress, symbol, decimals }) + } catch (err) { + return err + } const tokenOpts = { rawAddress, decimals, symbol, imageUrl } this.addSuggestedERC20Asset(tokenOpts) return this.showWatchAssetUi().then(() => { -- cgit v1.2.3 From 56bed3f1bce3cde176784026b10bc3bbe8e819d0 Mon Sep 17 00:00:00 2001 From: Esteban MIno Date: Wed, 22 Aug 2018 18:14:10 -0300 Subject: expose web3.metamask.watchAsset --- app/scripts/lib/auto-reload.js | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'app/scripts') diff --git a/app/scripts/lib/auto-reload.js b/app/scripts/lib/auto-reload.js index cce31c3d2..f3c89ecdb 100644 --- a/app/scripts/lib/auto-reload.js +++ b/app/scripts/lib/auto-reload.js @@ -14,6 +14,23 @@ function setupDappAutoReload (web3, observable) { console.warn('MetaMask: web3 will be deprecated in the near future in favor of the ethereumProvider \nhttps://github.com/MetaMask/faq/blob/master/detecting_metamask.md#web3-deprecation') hasBeenWarned = true } + // setup wallet + if (key === 'metamask') { + return { + watchAsset: (params) => { + return new Promise((resolve, reject) => { + web3.currentProvider.sendAsync({ + jsonrpc: '2.0', + method: 'metamask_watchAsset', + params, + }, (err, res) => { + if (err) reject(err) + resolve(res) + }) + }) + }, + } + } // get the time of use lastTimeUsed = Date.now() // return value normally -- cgit v1.2.3 From b59a1e91b8f4b595500a0785f325e833fa35407d Mon Sep 17 00:00:00 2001 From: Esteban MIno Date: Thu, 23 Aug 2018 15:54:40 -0300 Subject: typo watchAsset imageUrl to image --- app/scripts/controllers/preferences.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'app/scripts') diff --git a/app/scripts/controllers/preferences.js b/app/scripts/controllers/preferences.js index a03abbf79..d57aec71a 100644 --- a/app/scripts/controllers/preferences.js +++ b/app/scripts/controllers/preferences.js @@ -67,9 +67,9 @@ class PreferencesController { addSuggestedERC20Asset (tokenOpts) { this._validateERC20AssetParams(tokenOpts) const suggested = this.getSuggestedTokens() - const { rawAddress, symbol, decimals, imageUrl } = tokenOpts + const { rawAddress, symbol, decimals, image } = tokenOpts const address = normalizeAddress(rawAddress) - const newEntry = { address, symbol, decimals, imageUrl } + const newEntry = { address, symbol, decimals, image } suggested[address] = newEntry this.store.updateState({ suggestedTokens: suggested }) } @@ -291,7 +291,7 @@ class PreferencesController { * @returns {Promise} Promises the new array of AddedToken objects. * */ - async addToken (rawAddress, symbol, decimals, imageUrl) { + async addToken (rawAddress, symbol, decimals, image) { const address = normalizeAddress(rawAddress) const newEntry = { address, symbol, decimals } const tokens = this.store.getState().tokens @@ -306,7 +306,7 @@ class PreferencesController { } else { tokens.push(newEntry) } - assetImages[address] = imageUrl + assetImages[address] = image this._updateAccountTokens(tokens, assetImages) return Promise.resolve(tokens) } @@ -509,14 +509,14 @@ class PreferencesController { * */ async _handleWatchAssetERC20 (options) { - const { address, symbol, decimals, imageUrl } = options + const { address, symbol, decimals, image } = options const rawAddress = address try { this._validateERC20AssetParams({ rawAddress, symbol, decimals }) } catch (err) { return err } - const tokenOpts = { rawAddress, decimals, symbol, imageUrl } + const tokenOpts = { rawAddress, decimals, symbol, image } this.addSuggestedERC20Asset(tokenOpts) return this.showWatchAssetUi().then(() => { const tokenAddresses = this.getTokens().filter(token => token.address === normalizeAddress(rawAddress)) -- cgit v1.2.3 From 053e262ae738af29cfe67e702350f1f046b4b311 Mon Sep 17 00:00:00 2001 From: Esteban MIno Date: Thu, 23 Aug 2018 16:32:04 -0300 Subject: delete web3.metamassk.watchAsset --- app/scripts/lib/auto-reload.js | 17 ----------------- 1 file changed, 17 deletions(-) (limited to 'app/scripts') diff --git a/app/scripts/lib/auto-reload.js b/app/scripts/lib/auto-reload.js index f3c89ecdb..cce31c3d2 100644 --- a/app/scripts/lib/auto-reload.js +++ b/app/scripts/lib/auto-reload.js @@ -14,23 +14,6 @@ function setupDappAutoReload (web3, observable) { console.warn('MetaMask: web3 will be deprecated in the near future in favor of the ethereumProvider \nhttps://github.com/MetaMask/faq/blob/master/detecting_metamask.md#web3-deprecation') hasBeenWarned = true } - // setup wallet - if (key === 'metamask') { - return { - watchAsset: (params) => { - return new Promise((resolve, reject) => { - web3.currentProvider.sendAsync({ - jsonrpc: '2.0', - method: 'metamask_watchAsset', - params, - }, (err, res) => { - if (err) reject(err) - resolve(res) - }) - }) - }, - } - } // get the time of use lastTimeUsed = Date.now() // return value normally -- cgit v1.2.3 From 3106374cc31b66e5a0faadd657b4430e21aa48b2 Mon Sep 17 00:00:00 2001 From: Esteban MIno Date: Mon, 27 Aug 2018 22:10:14 -0300 Subject: watchAsset small changes --- app/scripts/controllers/preferences.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'app/scripts') diff --git a/app/scripts/controllers/preferences.js b/app/scripts/controllers/preferences.js index d57aec71a..4798b2ad6 100644 --- a/app/scripts/controllers/preferences.js +++ b/app/scripts/controllers/preferences.js @@ -1,6 +1,6 @@ const ObservableStore = require('obs-store') const normalizeAddress = require('eth-sig-util').normalize -const isValidAddress = require('ethereumjs-util').isValidAddress +const { isValidAddress } = require('ethereumjs-util') const extend = require('xtend') -- cgit v1.2.3