From 2f6530a4948743fe156dc3519f04bd44f7c6e2ae Mon Sep 17 00:00:00 2001 From: hackyminer Date: Sat, 20 Oct 2018 00:45:59 +0900 Subject: support both eth_chainId and net_version get the real chainId using eth_chainId and use net_version as a fallback --- app/scripts/controllers/network/network.js | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) (limited to 'app/scripts/controllers') diff --git a/app/scripts/controllers/network/network.js b/app/scripts/controllers/network/network.js index c1667d9a6..b386161da 100644 --- a/app/scripts/controllers/network/network.js +++ b/app/scripts/controllers/network/network.js @@ -86,10 +86,17 @@ module.exports = class NetworkController extends EventEmitter { return log.warn('NetworkController - lookupNetwork aborted due to missing provider') } const ethQuery = new EthQuery(this._provider) - ethQuery.sendAsync({ method: 'net_version' }, (err, network) => { - if (err) return this.setNetworkState('loading') - log.info('web3.getNetwork returned ' + network) - this.setNetworkState(network) + ethQuery.sendAsync({ method: 'eth_chainId' }, (err, chainId) => { + if (err) { + ethQuery.sendAsync({ method: 'net_version' }, (err, network) => { + if (err) return this.setNetworkState('loading') + log.info('web3.getNetwork returned net_version = ' + network) + this.setNetworkState(network) + }) + return + } + log.info('web3.getNetwork returned chainId = ' + parseInt(chainId)) + this.setNetworkState(parseInt(chainId)) }) } -- cgit From 75661673e5b2573ee9ab3a378130e4383c4c034f Mon Sep 17 00:00:00 2001 From: Esteban MIno Date: Fri, 19 Oct 2018 13:57:11 -0300 Subject: add support for wallet_watchAsset --- app/scripts/controllers/preferences.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'app/scripts/controllers') diff --git a/app/scripts/controllers/preferences.js b/app/scripts/controllers/preferences.js index 8eb2bce0c..16620ca96 100644 --- a/app/scripts/controllers/preferences.js +++ b/app/scripts/controllers/preferences.js @@ -104,7 +104,7 @@ class PreferencesController { * @param {Function} - end */ async requestWatchAsset (req, res, next, end) { - if (req.method === 'metamask_watchAsset') { + if (req.method === 'metamask_watchAsset' || req.method === 'wallet_watchAsset') { const { type, options } = req.params switch (type) { case 'ERC20': -- cgit From 61c7bbb1c1f0c216d5f8cd0d0753c78bc635624e Mon Sep 17 00:00:00 2001 From: kumavis Date: Sun, 21 Oct 2018 01:20:08 -0400 Subject: network - improve logging and type conversion --- app/scripts/controllers/network/network.js | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'app/scripts/controllers') diff --git a/app/scripts/controllers/network/network.js b/app/scripts/controllers/network/network.js index b386161da..904c20cff 100644 --- a/app/scripts/controllers/network/network.js +++ b/app/scripts/controllers/network/network.js @@ -86,17 +86,19 @@ module.exports = class NetworkController extends EventEmitter { return log.warn('NetworkController - lookupNetwork aborted due to missing provider') } const ethQuery = new EthQuery(this._provider) - ethQuery.sendAsync({ method: 'eth_chainId' }, (err, chainId) => { + ethQuery.sendAsync({ method: 'eth_chainId' }, (err, chainIdHex) => { if (err) { + // if eth_chainId is not supported, fallback to net_verion ethQuery.sendAsync({ method: 'net_version' }, (err, network) => { if (err) return this.setNetworkState('loading') - log.info('web3.getNetwork returned net_version = ' + network) + log.info(`net_version returned ${network}`) this.setNetworkState(network) }) return } - log.info('web3.getNetwork returned chainId = ' + parseInt(chainId)) - this.setNetworkState(parseInt(chainId)) + const chainId = Number.parseInt(chainIdHex, 16) + log.info(`net_version returned ${chainId}`) + this.setNetworkState(chainId) }) } -- cgit From b62d07f3a5bdfde7e295f17b7f601c6f2d5314ef Mon Sep 17 00:00:00 2001 From: kumavis Date: Sun, 21 Oct 2018 04:32:07 -0400 Subject: Update network.js --- app/scripts/controllers/network/network.js | 1 + 1 file changed, 1 insertion(+) (limited to 'app/scripts/controllers') diff --git a/app/scripts/controllers/network/network.js b/app/scripts/controllers/network/network.js index 904c20cff..6a5369f06 100644 --- a/app/scripts/controllers/network/network.js +++ b/app/scripts/controllers/network/network.js @@ -86,6 +86,7 @@ module.exports = class NetworkController extends EventEmitter { return log.warn('NetworkController - lookupNetwork aborted due to missing provider') } const ethQuery = new EthQuery(this._provider) + // first attempt to perform lookup via eth_chainId ethQuery.sendAsync({ method: 'eth_chainId' }, (err, chainIdHex) => { if (err) { // if eth_chainId is not supported, fallback to net_verion -- cgit From 54a8ade2669cb5f8f046509873bc2a9c25425847 Mon Sep 17 00:00:00 2001 From: HackyMiner Date: Fri, 26 Oct 2018 17:26:43 +0900 Subject: Add support for RPC endpoints with custom chain IDs (#5134) --- app/scripts/controllers/currency.js | 52 +++++++++++++++++++++++--- app/scripts/controllers/network/network.js | 60 +++++++++++++++++++++++++----- app/scripts/controllers/preferences.js | 31 ++++++++------- 3 files changed, 115 insertions(+), 28 deletions(-) (limited to 'app/scripts/controllers') diff --git a/app/scripts/controllers/currency.js b/app/scripts/controllers/currency.js index d5bc5fe2b..1e866d2c9 100644 --- a/app/scripts/controllers/currency.js +++ b/app/scripts/controllers/currency.js @@ -21,6 +21,7 @@ class CurrencyController { * since midnight of January 1, 1970 * @property {number} conversionInterval The id of the interval created by the scheduleConversionInterval method. * Used to clear an existing interval on subsequent calls of that method. + * @property {string} nativeCurrency The ticker/symbol of the native chain currency * */ constructor (opts = {}) { @@ -28,6 +29,7 @@ class CurrencyController { currentCurrency: 'usd', conversionRate: 0, conversionDate: 'N/A', + nativeCurrency: 'ETH', }, opts.initState) this.store = new ObservableStore(initState) } @@ -36,6 +38,29 @@ class CurrencyController { // PUBLIC METHODS // + /** + * A getter for the nativeCurrency property + * + * @returns {string} A 2-4 character shorthand that describes the specific currency + * + */ + getNativeCurrency () { + return this.store.getState().nativeCurrency + } + + /** + * A setter for the nativeCurrency property + * + * @param {string} nativeCurrency The new currency to set as the nativeCurrency in the store + * + */ + setNativeCurrency (nativeCurrency) { + this.store.updateState({ + nativeCurrency, + ticker: nativeCurrency, + }) + } + /** * A getter for the currentCurrency property * @@ -104,15 +129,32 @@ class CurrencyController { * */ async updateConversionRate () { - let currentCurrency + let currentCurrency, nativeCurrency try { currentCurrency = this.getCurrentCurrency() - const response = await fetch(`https://api.infura.io/v1/ticker/eth${currentCurrency.toLowerCase()}`) + nativeCurrency = this.getNativeCurrency() + let apiUrl + if (nativeCurrency === 'ETH') { + apiUrl = `https://api.infura.io/v1/ticker/eth${currentCurrency.toLowerCase()}` + } else { + apiUrl = `https://min-api.cryptocompare.com/data/price?fsym=${nativeCurrency.toUpperCase()}&tsyms=${currentCurrency.toUpperCase()}` + } + const response = await fetch(apiUrl) const parsedResponse = await response.json() - this.setConversionRate(Number(parsedResponse.bid)) - this.setConversionDate(Number(parsedResponse.timestamp)) + if (nativeCurrency === 'ETH') { + this.setConversionRate(Number(parsedResponse.bid)) + this.setConversionDate(Number(parsedResponse.timestamp)) + } else { + if (parsedResponse[currentCurrency.toUpperCase()]) { + this.setConversionRate(Number(parsedResponse[currentCurrency.toUpperCase()])) + this.setConversionDate(parseInt((new Date()).getTime() / 1000)) + } else { + this.setConversionRate(0) + this.setConversionDate('N/A') + } + } } catch (err) { - log.warn(`MetaMask - Failed to query currency conversion:`, currentCurrency, err) + log.warn(`MetaMask - Failed to query currency conversion:`, nativeCurrency, currentCurrency, err) this.setConversionRate(0) this.setConversionDate('N/A') } diff --git a/app/scripts/controllers/network/network.js b/app/scripts/controllers/network/network.js index c1667d9a6..b459b8013 100644 --- a/app/scripts/controllers/network/network.js +++ b/app/scripts/controllers/network/network.js @@ -11,6 +11,8 @@ const createInfuraClient = require('./createInfuraClient') const createJsonRpcClient = require('./createJsonRpcClient') const createLocalhostClient = require('./createLocalhostClient') const { createSwappableProxy, createEventEmitterProxy } = require('swappable-obj-proxy') +const extend = require('extend') +const networks = { networkList: {} } const { ROPSTEN, @@ -29,6 +31,10 @@ const defaultProviderConfig = { type: testMode ? RINKEBY : MAINNET, } +const defaultNetworkConfig = { + ticker: 'ETH', +} + module.exports = class NetworkController extends EventEmitter { constructor (opts = {}) { @@ -39,7 +45,8 @@ module.exports = class NetworkController extends EventEmitter { // create stores this.providerStore = new ObservableStore(providerConfig) this.networkStore = new ObservableStore('loading') - this.store = new ComposedStore({ provider: this.providerStore, network: this.networkStore }) + this.networkConfig = new ObservableStore(defaultNetworkConfig) + this.store = new ComposedStore({ provider: this.providerStore, network: this.networkStore, settings: this.networkConfig }) this.on('networkDidChange', this.lookupNetwork) // provider and block tracker this._provider = null @@ -51,8 +58,8 @@ module.exports = class NetworkController extends EventEmitter { initializeProvider (providerParams) { this._baseProviderParams = providerParams - const { type, rpcTarget } = this.providerStore.getState() - this._configureProvider({ type, rpcTarget }) + const { type, rpcTarget, chainId, ticker, nickname } = this.providerStore.getState() + this._configureProvider({ type, rpcTarget, chainId, ticker, nickname }) this.lookupNetwork() } @@ -72,7 +79,20 @@ module.exports = class NetworkController extends EventEmitter { return this.networkStore.getState() } - setNetworkState (network) { + getNetworkConfig () { + return this.networkConfig.getState() + } + + setNetworkState (network, type) { + if (network === 'loading') { + return this.networkStore.putState(network) + } + + // type must be defined + if (!type) { + return + } + network = networks.networkList[type] && networks.networkList[type].chainId ? networks.networkList[type].chainId : network return this.networkStore.putState(network) } @@ -85,18 +105,22 @@ module.exports = class NetworkController extends EventEmitter { if (!this._provider) { return log.warn('NetworkController - lookupNetwork aborted due to missing provider') } + var { type } = this.providerStore.getState() const ethQuery = new EthQuery(this._provider) ethQuery.sendAsync({ method: 'net_version' }, (err, network) => { if (err) return this.setNetworkState('loading') log.info('web3.getNetwork returned ' + network) - this.setNetworkState(network) + this.setNetworkState(network, type) }) } - setRpcTarget (rpcTarget) { + setRpcTarget (rpcTarget, chainId, ticker = 'ETH', nickname = '') { const providerConfig = { type: 'rpc', rpcTarget, + chainId, + ticker, + nickname, } this.providerConfig = providerConfig } @@ -132,7 +156,7 @@ module.exports = class NetworkController extends EventEmitter { } _configureProvider (opts) { - const { type, rpcTarget } = opts + const { type, rpcTarget, chainId, ticker, nickname } = opts // infura type-based endpoints const isInfura = INFURA_PROVIDER_TYPES.includes(type) if (isInfura) { @@ -142,7 +166,7 @@ module.exports = class NetworkController extends EventEmitter { this._configureLocalhostProvider() // url-based rpc endpoints } else if (type === 'rpc') { - this._configureStandardProvider({ rpcUrl: rpcTarget }) + this._configureStandardProvider({ rpcUrl: rpcTarget, chainId, ticker, nickname }) } else { throw new Error(`NetworkController - _configureProvider - unknown type "${type}"`) } @@ -152,6 +176,11 @@ module.exports = class NetworkController extends EventEmitter { log.info('NetworkController - configureInfuraProvider', type) const networkClient = createInfuraClient({ network: type }) this._setNetworkClient(networkClient) + // setup networkConfig + var settings = { + ticker: 'ETH', + } + this.networkConfig.putState(settings) } _configureLocalhostProvider () { @@ -160,9 +189,22 @@ module.exports = class NetworkController extends EventEmitter { this._setNetworkClient(networkClient) } - _configureStandardProvider ({ rpcUrl }) { + _configureStandardProvider ({ rpcUrl, chainId, ticker, nickname }) { log.info('NetworkController - configureStandardProvider', rpcUrl) const networkClient = createJsonRpcClient({ rpcUrl }) + // hack to add a 'rpc' network with chainId + networks.networkList['rpc'] = { + chainId: chainId, + rpcUrl, + ticker: ticker || 'ETH', + nickname, + } + // setup networkConfig + var settings = { + network: chainId, + } + settings = extend(settings, networks.networkList['rpc']) + this.networkConfig.putState(settings) this._setNetworkClient(networkClient) } diff --git a/app/scripts/controllers/preferences.js b/app/scripts/controllers/preferences.js index 20b13398c..120801f06 100644 --- a/app/scripts/controllers/preferences.js +++ b/app/scripts/controllers/preferences.js @@ -25,7 +25,7 @@ class PreferencesController { */ constructor (opts = {}) { const initState = extend({ - frequentRpcList: [], + frequentRpcListDetail: [], currentAccountTab: 'history', accountTokens: {}, assetImages: {}, @@ -39,7 +39,7 @@ class PreferencesController { seedWords: null, forgottenPassword: false, preferences: { - useETHAsPrimaryCurrency: true, + useNativeCurrencyAsPrimaryCurrency: true, }, }, opts.initState) @@ -392,19 +392,22 @@ class PreferencesController { * Adds custom RPC url to state. * * @param {string} url The RPC url to add to frequentRpcList. + * @param {number} chainId Optional chainId of the selected network. + * @param {string} ticker Optional ticker symbol of the selected network. + * @param {string} nickname Optional nickname of the selected network. * @returns {Promise} Promise resolving to updated frequentRpcList. * */ - addToFrequentRpcList (url) { - const rpcList = this.getFrequentRpcList() - const index = rpcList.findIndex((element) => { return element === url }) + addToFrequentRpcList (url, chainId, ticker = 'ETH', nickname = '') { + const rpcList = this.getFrequentRpcListDetail() + const index = rpcList.findIndex((element) => { return element.rpcUrl === url }) if (index !== -1) { rpcList.splice(index, 1) } if (url !== 'http://localhost:8545') { - rpcList.push(url) + rpcList.push({ rpcUrl: url, chainId, ticker, nickname }) } - this.store.updateState({ frequentRpcList: rpcList }) + this.store.updateState({ frequentRpcListiDetail: rpcList }) return Promise.resolve(rpcList) } @@ -416,23 +419,23 @@ class PreferencesController { * */ removeFromFrequentRpcList (url) { - const rpcList = this.getFrequentRpcList() - const index = rpcList.findIndex((element) => { return element === url }) + const rpcList = this.getFrequentRpcListDetail() + const index = rpcList.findIndex((element) => { return element.rpcUrl === url }) if (index !== -1) { rpcList.splice(index, 1) } - this.store.updateState({ frequentRpcList: rpcList }) + this.store.updateState({ frequentRpcListDetail: rpcList }) return Promise.resolve(rpcList) } /** - * Getter for the `frequentRpcList` property. + * Getter for the `frequentRpcListDetail` property. * - * @returns {array} An array of one or two rpc urls. + * @returns {array} An array of rpc urls. * */ - getFrequentRpcList () { - return this.store.getState().frequentRpcList + getFrequentRpcListDetail () { + return this.store.getState().frequentRpcListDetail } /** -- cgit From 986f8b4c2143fd1f1caec1e21aea19b260f3c176 Mon Sep 17 00:00:00 2001 From: kumavis Date: Mon, 29 Oct 2018 18:56:29 -0400 Subject: preferences - fix typo --- app/scripts/controllers/preferences.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'app/scripts/controllers') diff --git a/app/scripts/controllers/preferences.js b/app/scripts/controllers/preferences.js index 120801f06..eaeaee499 100644 --- a/app/scripts/controllers/preferences.js +++ b/app/scripts/controllers/preferences.js @@ -407,7 +407,7 @@ class PreferencesController { if (url !== 'http://localhost:8545') { rpcList.push({ rpcUrl: url, chainId, ticker, nickname }) } - this.store.updateState({ frequentRpcListiDetail: rpcList }) + this.store.updateState({ frequentRpcListDetail: rpcList }) return Promise.resolve(rpcList) } -- cgit