Skip to content

Commit

Permalink
Merge pull request #2 from chrisfranko/develop
Browse files Browse the repository at this point in the history
Optional Chain Id
  • Loading branch information
chrisfranko authored Aug 23, 2018
2 parents f495c0e + 089e84e commit 8fa8eaf
Show file tree
Hide file tree
Showing 46 changed files with 543 additions and 172 deletions.
6 changes: 6 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 Expand Up @@ -835,6 +838,9 @@
"connectingToRinkeby": {
"message": "Connecting to Rinkeby Test Network"
},
"connectingToClassic": {
"message": "Connecting to Ethereum Classic Network"
},
"connectingToUnknown": {
"message": "Connecting to Unknown Network"
},
Expand Down
20 changes: 20 additions & 0 deletions app/images/etc_logo.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
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
59 changes: 49 additions & 10 deletions app/scripts/controllers/network/network.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ const createInfuraClient = require('./createInfuraClient')
const createJsonRpcClient = require('./createJsonRpcClient')
const createLocalhostClient = require('./createLocalhostClient')
const { createSwappableProxy, createEventEmitterProxy } = require('swappable-obj-proxy')
const extend = require('xtend')

const {
ROPSTEN,
Expand All @@ -20,6 +21,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 +31,10 @@ const defaultProviderConfig = {
type: testMode ? RINKEBY : MAINNET,
}

const defaultNetworkConfig = {
ticker: 'ETH',
}

module.exports = class NetworkController extends EventEmitter {

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

Expand All @@ -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)
}

Expand All @@ -85,25 +105,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 +154,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 +164,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 +174,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 +187,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
26 changes: 13 additions & 13 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,29 +329,29 @@ 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 > 2) {
if (rpcList.length > 3) {
rpcList.shift()
}
return Promise.resolve(rpcList)
}

/**
* 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 @@ -181,6 +181,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 @@ -1348,10 +1350,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 @@ -1372,7 +1377,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 @@ -1392,9 +1398,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

0 comments on commit 8fa8eaf

Please sign in to comment.