Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Optional Chain_id w/o Native ETC Support #5130

Closed
wants to merge 15 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions app/_locales/en/messages.json
Original file line number Diff line number Diff line change
Expand Up @@ -635,6 +635,9 @@
"newRPC": {
"message": "New RPC URL"
},
"optionalChainId": {
"message": "ChainId (optional)"
},
"next": {
"message": "Next"
},
Expand Down
32 changes: 27 additions & 5 deletions app/scripts/controllers/currency.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ class CurrencyController {
*/
constructor (opts = {}) {
const initState = extend({
fromCurrency: 'ETH',
currentCurrency: 'usd',
conversionRate: 0,
conversionDate: 'N/A',
Expand All @@ -36,6 +37,26 @@ class CurrencyController {
// PUBLIC METHODS
//

/**
* A getter for the fromCurrency property
*
* @returns {string} A 2-4 character shorthand that describes the specific currency
*
*/
getFromCurrency () {
return this.store.getState().fromCurrency
}

/**
* A setter for the fromCurrency property
*
* @param {string} fromCurrency The new currency to set as the fromCurrency in the store
*
*/
setFromCurrency (fromCurrency) {
this.store.updateState({ ticker: fromCurrency, fromCurrency })
}

/**
* A getter for the currentCurrency property
*
Expand Down Expand Up @@ -104,15 +125,16 @@ class CurrencyController {
*
*/
async updateConversionRate () {
let currentCurrency
let currentCurrency, fromCurrency
try {
currentCurrency = this.getCurrentCurrency()
const response = await fetch(`https://api.infura.io/v1/ticker/eth${currentCurrency.toLowerCase()}`)
fromCurrency = this.getFromCurrency()
const response = await fetch(`https://min-api.cryptocompare.com/data/pricehistorical?fsym=${fromCurrency.toUpperCase()}&tsyms=${currentCurrency.toUpperCase()}`)
const parsedResponse = await response.json()
this.setConversionRate(Number(parsedResponse.bid))
this.setConversionDate(Number(parsedResponse.timestamp))
this.setConversionRate(Number(parsedResponse[fromCurrency.toUpperCase()][currentCurrency.toUpperCase()]))
this.setConversionDate(parseInt(new Date().getTime() / 1000))
} catch (err) {
log.warn(`MetaMask - Failed to query currency conversion:`, currentCurrency, err)
log.warn(`MetaMask - Failed to query currency conversion:`, fromCurrency, currentCurrency, err)
this.setConversionRate(0)
this.setConversionDate('N/A')
}
Expand Down
60 changes: 50 additions & 10 deletions app/scripts/controllers/network/network.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ const createInfuraClient = require('./createInfuraClient')
const createJsonRpcClient = require('./createJsonRpcClient')
const createLocalhostClient = require('./createLocalhostClient')
const { createSwappableProxy, createEventEmitterProxy } = require('swappable-obj-proxy')
const networks = require('./networks')
const extend = require('xtend')

const {
ROPSTEN,
Expand All @@ -20,6 +22,7 @@ const {
LOCALHOST,
} = require('./enums')
const INFURA_PROVIDER_TYPES = [ROPSTEN, RINKEBY, KOVAN, MAINNET]
const ALL_PROVIDER_TYPES = [ROPSTEN, RINKEBY, KOVAN, MAINNET]

const env = process.env.METAMASK_ENV
const METAMASK_DEBUG = process.env.METAMASK_DEBUG
Expand All @@ -29,6 +32,10 @@ const defaultProviderConfig = {
type: testMode ? RINKEBY : MAINNET,
}

const defaultNetworkConfig = {
ticker: 'ETH',
}

module.exports = class NetworkController extends EventEmitter {

constructor (opts = {}) {
Expand All @@ -39,7 +46,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
Expand All @@ -51,8 +59,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 } = this.providerStore.getState()
this._configureProvider({ type, rpcTarget, chainId })
this.lookupNetwork()
}

Expand All @@ -72,7 +80,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)
}

Expand All @@ -85,25 +106,27 @@ 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) {
const providerConfig = {
type: 'rpc',
rpcTarget,
chainId,
}
this.providerConfig = providerConfig
}

async setProviderType (type) {
assert.notEqual(type, 'rpc', `NetworkController - cannot call "setProviderType" with type 'rpc'. use "setRpcTarget"`)
assert(INFURA_PROVIDER_TYPES.includes(type) || type === LOCALHOST, `NetworkController - Unknown rpc type "${type}"`)
assert(ALL_PROVIDER_TYPES.includes(type) || type === LOCALHOST, `NetworkController - Unknown rpc type "${type}"`)
const providerConfig = { type }
this.providerConfig = providerConfig
}
Expand Down Expand Up @@ -132,7 +155,7 @@ module.exports = class NetworkController extends EventEmitter {
}

_configureProvider (opts) {
const { type, rpcTarget } = opts
const { type, rpcTarget, chainId } = opts
// infura type-based endpoints
const isInfura = INFURA_PROVIDER_TYPES.includes(type)
if (isInfura) {
Expand All @@ -142,7 +165,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 })
} else {
throw new Error(`NetworkController - _configureProvider - unknown type "${type}"`)
}
Expand All @@ -152,6 +175,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 () {
Expand All @@ -160,9 +188,21 @@ module.exports = class NetworkController extends EventEmitter {
this._setNetworkClient(networkClient)
}

_configureStandardProvider ({ rpcUrl }) {
_configureStandardProvider ({ rpcUrl, chainId }) {
log.info('NetworkController - configureStandardProvider', rpcUrl)
const networkClient = createJsonRpcClient({ rpcUrl })
// hack to add a 'rpc' network with chainId
networks.networkList['rpc'] = {
chainId: chainId,
rpcUrl,
ticker: 'ETH',
}
// setup networkConfig
var settings = {
network: chainId,
}
settings = extend(settings, networks.networkList['rpc'])
this.networkConfig.putState(settings)
this._setNetworkClient(networkClient)
}

Expand Down
8 changes: 8 additions & 0 deletions app/scripts/controllers/network/networks.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
'use strict'
var networks = function() {}

networks.networkList = {

}

module.exports = networks
24 changes: 12 additions & 12 deletions app/scripts/controllers/preferences.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ class PreferencesController {
*/
constructor (opts = {}) {
const initState = extend({
frequentRpcList: [],
frequentRpcListDetail: [],
currentAccountTab: 'history',
accountTokens: {},
tokens: [],
Expand Down Expand Up @@ -298,10 +298,10 @@ class PreferencesController {
* @returns {Promise<void>} Promise resolves with undefined
*
*/
updateFrequentRpcList (_url) {
return this.addToFrequentRpcList(_url)
updateFrequentRpcList (_url, chainId) {
return this.addToFrequentRpcList(_url, chainId)
.then((rpcList) => {
this.store.updateState({ frequentRpcList: rpcList })
this.store.updateState({ frequentRpcListDetail: rpcList })
return Promise.resolve()
})
}
Expand Down Expand Up @@ -329,14 +329,14 @@ class PreferencesController {
* @returns {Promise<array>} The updated frequentRpcList.
*
*/
addToFrequentRpcList (_url) {
const rpcList = this.getFrequentRpcList()
const index = rpcList.findIndex((element) => { return element === _url })
addToFrequentRpcList (_url, chainId) {
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 })
}
if (rpcList.length > 3) {
rpcList.shift()
Expand All @@ -345,13 +345,13 @@ class PreferencesController {
}

/**
* Getter for the `frequentRpcList` property.
* Getter for the `frequentRpcListDetail` property.
*
* @returns {array<string>} An array of one or two rpc urls.
* @returns {array<array>} An array of rpc urls.
*
*/
getFrequentRpcList () {
return this.store.getState().frequentRpcList
getFrequentRpcListDetail () {
return this.store.getState().frequentRpcListDetail
}

/**
Expand Down
10 changes: 9 additions & 1 deletion app/scripts/lib/buy-eth-url.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ module.exports = getBuyEthUrl
* network does not match any of the specified cases, or if no network is given, returns undefined.
*
*/
function getBuyEthUrl ({ network, amount, address }) {
function getBuyEthUrl ({ network, amount, address, link }) {
let url
switch (network) {
case '1':
Expand All @@ -29,6 +29,14 @@ function getBuyEthUrl ({ network, amount, address }) {
case '42':
url = 'https://github.com/kovan-testnet/faucet'
break

default:
if (link) {
url = link.replace('[[amount]]', amount).replace('[[address]]', address)
} else {
url = ''
}
break
}
return url
}
14 changes: 10 additions & 4 deletions app/scripts/metamask-controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,8 @@ module.exports = class MetamaskController extends EventEmitter {
})
this.networkController.on('networkDidChange', () => {
this.balancesController.updateAllBalances()
var currentCurrency = this.currencyController.getCurrentCurrency()
this.setCurrentCurrency(currentCurrency, function() {})
})
this.balancesController.updateAllBalances()

Expand Down Expand Up @@ -1368,10 +1370,13 @@ module.exports = class MetamaskController extends EventEmitter {
* @param {Function} cb - A callback function returning currency info.
*/
setCurrentCurrency (currencyCode, cb) {
const { ticker } = this.networkController.getNetworkConfig()
try {
this.currencyController.setFromCurrency(ticker)
this.currencyController.setCurrentCurrency(currencyCode)
this.currencyController.updateConversionRate()
const data = {
fromCurrency: ticker || 'ETH',
conversionRate: this.currencyController.getConversionRate(),
currentCurrency: this.currencyController.getCurrentCurrency(),
conversionDate: this.currencyController.getConversionDate(),
Expand All @@ -1392,7 +1397,8 @@ module.exports = class MetamaskController extends EventEmitter {
buyEth (address, amount) {
if (!amount) amount = '5'
const network = this.networkController.getNetworkState()
const url = getBuyEthUrl({ network, address, amount })
const link = this.networkController.getNetworkConfig().buyUrl
const url = getBuyEthUrl({ network, address, amount, link })
if (url) this.platform.openWindow({ url })
}

Expand All @@ -1412,9 +1418,9 @@ module.exports = class MetamaskController extends EventEmitter {
* @param {string} rpcTarget - A URL for a valid Ethereum RPC API.
* @returns {Promise<String>} - The RPC Target URL confirmed.
*/
async setCustomRpc (rpcTarget) {
this.networkController.setRpcTarget(rpcTarget)
await this.preferencesController.updateFrequentRpcList(rpcTarget)
async setCustomRpc (rpcTarget, chainId) {
this.networkController.setRpcTarget(rpcTarget, chainId)
await this.preferencesController.updateFrequentRpcList(rpcTarget, chainId)
return rpcTarget
}

Expand Down
2 changes: 1 addition & 1 deletion old-ui/app/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ function mapStateToProps (state) {
forgottenPassword: state.appState.forgottenPassword,
nextUnreadNotice: state.metamask.nextUnreadNotice,
lostAccounts: state.metamask.lostAccounts,
frequentRpcList: state.metamask.frequentRpcList || [],
frequentRpcListDetail: state.metamask.frequentRpcListDetail || [],
featureFlags,

// state needed to get account dropdown temporarily rendering from app bar
Expand Down
Loading