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

(Feature) Support of Ethereum Classic chain #268

Merged
merged 10 commits into from
Mar 27, 2019
8 changes: 8 additions & 0 deletions app/scripts/controllers/network/enums.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ const ROPSTEN = 'ropsten'
const RINKEBY = 'rinkeby'
const KOVAN = 'kovan'
const GOERLI_TESTNET = 'goerli_testnet'
const CLASSIC = 'classic'
const LOCALHOST = 'localhost'

const POA_CODE = 99
Expand All @@ -16,6 +17,7 @@ const ROPSTEN_CODE = 3
const RINKEBY_CODE = 4
const KOVAN_CODE = 42
const GOERLI_TESTNET_CODE = 5
const CLASSIC_CODE = 61

const POA_DISPLAY_NAME = 'POA Network'
const DAI_DISPLAY_NAME = 'xDai Chain'
Expand All @@ -25,6 +27,7 @@ const ROPSTEN_DISPLAY_NAME = 'Ropsten'
const RINKEBY_DISPLAY_NAME = 'Rinkeby'
const KOVAN_DISPLAY_NAME = 'Kovan'
const GOERLI_TESTNET_DISPLAY_NAME = 'Görli Testnet'
const CLASSIC_DISPLAY_NAME = 'Ethereum Classic'

const DROPDOWN_POA_DISPLAY_NAME = POA_DISPLAY_NAME
const DROPDOWN_DAI_DISPLAY_NAME = DAI_DISPLAY_NAME
Expand All @@ -34,6 +37,7 @@ const DROPDOWN_ROPSTEN_DISPLAY_NAME = 'Ropsten Test Net'
const DROPDOWN_RINKEBY_DISPLAY_NAME = 'Rinkeby Test Net'
const DROPDOWN_KOVAN_DISPLAY_NAME = 'Kovan Test Net'
const DROPDOWN_GOERLI_TESTNET_DISPLAY_NAME = 'Görli Test Net'
const DROPDOWN_CLASSIC_DISPLAY_NAME = 'Ethereum Classic'

const chainTypes = {
TEST: 1,
Expand All @@ -49,6 +53,7 @@ module.exports = {
RINKEBY,
KOVAN,
GOERLI_TESTNET,
CLASSIC,
LOCALHOST,
POA_CODE,
DAI_CODE,
Expand All @@ -58,6 +63,7 @@ module.exports = {
RINKEBY_CODE,
KOVAN_CODE,
GOERLI_TESTNET_CODE,
CLASSIC_CODE,
POA_DISPLAY_NAME,
DAI_DISPLAY_NAME,
POA_SOKOL_DISPLAY_NAME,
Expand All @@ -66,6 +72,7 @@ module.exports = {
RINKEBY_DISPLAY_NAME,
KOVAN_DISPLAY_NAME,
GOERLI_TESTNET_DISPLAY_NAME,
CLASSIC_DISPLAY_NAME,
DROPDOWN_POA_DISPLAY_NAME,
DROPDOWN_DAI_DISPLAY_NAME,
DROPDOWN_POA_SOKOL_DISPLAY_NAME,
Expand All @@ -74,5 +81,6 @@ module.exports = {
DROPDOWN_RINKEBY_DISPLAY_NAME,
DROPDOWN_KOVAN_DISPLAY_NAME,
DROPDOWN_GOERLI_TESTNET_DISPLAY_NAME,
DROPDOWN_CLASSIC_DISPLAY_NAME,
chainTypes,
}
14 changes: 13 additions & 1 deletion app/scripts/controllers/network/network.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ const createJsonRpcClient = require('./createJsonRpcClient')
const createLocalhostClient = require('./createLocalhostClient')
const { createSwappableProxy, createEventEmitterProxy } = require('swappable-obj-proxy')
const ethNetProps = require('eth-net-props')
const parse = require('url-parse')

const {
ROPSTEN,
Expand All @@ -23,10 +24,12 @@ const {
POA,
DAI,
GOERLI_TESTNET,
CLASSIC,
POA_CODE,
DAI_CODE,
POA_SOKOL_CODE,
GOERLI_TESTNET_CODE,
CLASSIC_CODE,
} = require('./enums')
const INFURA_PROVIDER_TYPES = [ROPSTEN, RINKEBY, KOVAN, MAINNET]

Expand Down Expand Up @@ -90,13 +93,19 @@ module.exports = class NetworkController extends EventEmitter {
}

lookupNetwork () {
const { type, rpcTarget } = this.providerStore.getState()
// Prevent firing when provider is not defined.
if (!this._provider) {
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')
const targetHost = parse(rpcTarget, true).host
const classicHost = parse(ethNetProps.RPCEndpoints(CLASSIC_CODE)[0], true).host
if (type === CLASSIC || targetHost === classicHost) {
network = CLASSIC_CODE.toString()
} // workaround to avoid Mainnet and Classic are having the same network ID
log.info('web3.getNetwork returned ' + network)
this.setNetworkState(network)
})
Expand All @@ -117,7 +126,8 @@ module.exports = class NetworkController extends EventEmitter {
type === POA_SOKOL ||
type === POA ||
type === DAI ||
type === GOERLI_TESTNET
type === GOERLI_TESTNET ||
type === CLASSIC
, `NetworkController - Unknown rpc type "${type}"`)
const providerConfig = { type }
this.providerConfig = providerConfig
Expand Down Expand Up @@ -161,6 +171,8 @@ module.exports = class NetworkController extends EventEmitter {
this._configureStandardProvider({ rpcUrl: ethNetProps.RPCEndpoints(POA_SOKOL_CODE)[0] })
} else if (type === GOERLI_TESTNET) {
this._configureStandardProvider({ rpcUrl: ethNetProps.RPCEndpoints(GOERLI_TESTNET_CODE)[0] })
} else if (type === CLASSIC) {
this._configureStandardProvider({ rpcUrl: ethNetProps.RPCEndpoints(CLASSIC_CODE)[0] })
} else if (type === LOCALHOST) {
this._configureLocalhostProvider()
// url-based rpc endpoints
Expand Down
23 changes: 19 additions & 4 deletions app/scripts/controllers/network/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ const {
RINKEBY,
KOVAN,
GOERLI_TESTNET,
CLASSIC,
POA_CODE,
DAI_CODE,
POA_SOKOL_CODE,
Expand All @@ -15,6 +16,7 @@ const {
RINKEBY_CODE,
KOVAN_CODE,
GOERLI_TESTNET_CODE,
CLASSIC_CODE,
POA_DISPLAY_NAME,
DAI_DISPLAY_NAME,
POA_SOKOL_DISPLAY_NAME,
Expand All @@ -23,6 +25,7 @@ const {
RINKEBY_DISPLAY_NAME,
KOVAN_DISPLAY_NAME,
GOERLI_TESTNET_DISPLAY_NAME,
CLASSIC_DISPLAY_NAME,
DROPDOWN_POA_DISPLAY_NAME,
DROPDOWN_DAI_DISPLAY_NAME,
DROPDOWN_POA_SOKOL_DISPLAY_NAME,
Expand All @@ -31,6 +34,7 @@ const {
DROPDOWN_RINKEBY_DISPLAY_NAME,
DROPDOWN_KOVAN_DISPLAY_NAME,
DROPDOWN_GOERLI_TESTNET_DISPLAY_NAME,
DROPDOWN_CLASSIC_DISPLAY_NAME,
chainTypes,
} = require('./enums')

Expand Down Expand Up @@ -81,8 +85,19 @@ const MAINNET_OBJ = {
networks[MAINNET_CODE] = MAINNET_OBJ
networks[MAINNET] = MAINNET_OBJ

const ROPSTEN_OBJ = {
const CLASSIC_OBJ = {
order: 5,
chainType: PROD,
providerName: CLASSIC,
networkID: CLASSIC_CODE,
displayName: CLASSIC_DISPLAY_NAME,
displayNameDropdown: DROPDOWN_CLASSIC_DISPLAY_NAME,
}
networks[CLASSIC_CODE] = CLASSIC_OBJ
networks[CLASSIC] = CLASSIC_OBJ

const ROPSTEN_OBJ = {
order: 6,
chainType: TEST,
providerName: ROPSTEN,
networkID: ROPSTEN_CODE,
Expand All @@ -93,7 +108,7 @@ networks[ROPSTEN_CODE] = ROPSTEN_OBJ
networks[ROPSTEN] = ROPSTEN_OBJ

const KOVAN_OBJ = {
order: 6,
order: 7,
chainType: TEST,
providerName: KOVAN,
networkID: KOVAN_CODE,
Expand All @@ -104,7 +119,7 @@ networks[KOVAN_CODE] = KOVAN_OBJ
networks[KOVAN] = KOVAN_OBJ

const RINKEBY_OBJ = {
order: 7,
order: 8,
chainType: TEST,
providerName: RINKEBY,
networkID: RINKEBY_CODE,
Expand All @@ -115,7 +130,7 @@ networks[RINKEBY_CODE] = RINKEBY_OBJ
networks[RINKEBY] = RINKEBY_OBJ

const GOERLI_TESTNET_OBJ = {
order: 7,
order: 9,
providerName: GOERLI_TESTNET,
networkID: GOERLI_TESTNET_CODE,
displayName: GOERLI_TESTNET_DISPLAY_NAME,
Expand Down
24 changes: 19 additions & 5 deletions app/scripts/lib/buy-eth-url.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,16 @@ module.exports = {
}
const ethNetProps = require('eth-net-props')

const { POA_CODE,
const {
POA_CODE,
DAI_CODE,
POA_SOKOL_CODE,
MAINNET_CODE,
CLASSIC_CODE,
ROPSTEN_CODE,
RINKEBY_CODE,
KOVAN_CODE,
GOERLI_TESTNET_CODE } = require('../controllers/network/enums')
GOERLI_TESTNET_CODE} = require('../controllers/network/enums')

/**
* Gives the caller a url at which the user can acquire coin, depending on the network they are in
Expand All @@ -28,7 +30,12 @@ const { POA_CODE,
*/
function getBuyEthUrl ({ network, amount, address, ind }) {
let url
switch (Number(network)) {
switch (Number(network) || isNaN(network)) {
case true:
if (network === CLASSIC_CODE) {
url = getExchanges({network, amount, address})[ind].link
}
break
case MAINNET_CODE:
case POA_CODE:
case DAI_CODE:
Expand Down Expand Up @@ -73,7 +80,14 @@ function getExchanges ({network, amount, address}) {
link: `https://buy.coinbase.com/?code=9ec56d01-7e81-5017-930c-513daa27bb6a&amount=${amount}&address=${address}&crypto_currency=ETH`,
},
]
case 99:
case CLASSIC_CODE:
return [
{
name: 'Binance',
link: 'https://www.binance.com/en/trade/ETC_ETH',
},
]
case POA_CODE:
return [
{
name: 'Binance',
Expand All @@ -92,7 +106,7 @@ function getExchanges ({network, amount, address}) {
link: 'https://hitbtc.com/POA-to-ETH',
},
]
case 100:
case DAI_CODE:
return [
{
name: 'xDai TokenBridge',
Expand Down
2 changes: 1 addition & 1 deletion app/scripts/metamask-controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -1518,7 +1518,7 @@ module.exports = class MetamaskController extends EventEmitter {
const networkId = parseInt(networkIdStr)
const isPOA = networkId === POA_SOKOL_CODE || networkId === POA_CODE || networkId === DAI_CODE

// Return 1 gwei if using a POA network of if there are no blocks have been observed:
// Return 1 gwei if using a POA network or if there are no blocks have been observed:
if (isPOA || recentBlocks.length === 0) {
return '0x' + GWEI_BN.toString(16)
}
Expand Down
6 changes: 4 additions & 2 deletions app/scripts/platforms/extension.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ const {
POA_CODE,
DAI_CODE,
POA_SOKOL_CODE,
GOERLI_TESTNET_CODE } = require('../controllers/network/enums')
GOERLI_TESTNET_CODE,
CLASSIC_CODE } = require('../controllers/network/enums')

class ExtensionPlatform {

Expand Down Expand Up @@ -133,7 +134,8 @@ class ExtensionPlatform {
if (networkId === POA_CODE ||
networkId === DAI_CODE ||
networkId === POA_SOKOL_CODE ||
networkId === GOERLI_TESTNET_CODE
networkId === GOERLI_TESTNET_CODE ||
networkId === CLASSIC_CODE
) {
explorerName = 'BlockScout'
} else {
Expand Down
33 changes: 0 additions & 33 deletions old-ui/app/accounts/import/contract.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,6 @@ import CopyButton from '../../components/copy/copy-button'
import ErrorComponent from '../../components/error'
import { getFullABI } from './helpers'

import { POA_CODE,
DAI_CODE,
POA_SOKOL_CODE,
MAINNET_CODE,
ROPSTEN_CODE,
RINKEBY_CODE,
KOVAN_CODE,
GOERLI_TESTNET_CODE } from '../../../../app/scripts/controllers/network/enums'

class ContractImportView extends Component {
constructor (props) {
super(props)
Expand Down Expand Up @@ -195,30 +186,6 @@ class ContractImportView extends Component {
.catch()
}

getBlockscoutApiNetworkSuffix () {
const { network } = this.props
switch (Number(network)) {
case MAINNET_CODE:
return 'mainnet'
case POA_CODE:
return 'core'
case POA_SOKOL_CODE:
return 'sokol'
case DAI_CODE:
return 'dai'
case KOVAN_CODE:
return 'kovan'
case ROPSTEN_CODE:
return 'ropsten'
case RINKEBY_CODE:
return 'rinkeby'
case GOERLI_TESTNET_CODE:
return 'goerli'
default:
return ''
}
}

clearInputs () {
this.setState({
contractAddr: '',
Expand Down
23 changes: 22 additions & 1 deletion old-ui/app/accounts/import/helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,24 @@ const jsonObjToArray = (jsonObj) => {
}, [])
}

const getBlockscoutApiNetworkPrefix = (network) => {
switch (Number(network)) {
case 1:
case 42:
case 3:
case 4:
return 'mainnet'
case 99:
case 77:
case 100:
return 'poa'
case NaN:
return 'etc'
default:
return ''
}
}

const getBlockscoutApiNetworkSuffix = (network) => {
switch (Number(network)) {
case 1:
Expand All @@ -32,15 +50,18 @@ const getBlockscoutApiNetworkSuffix = (network) => {
return 'ropsten'
case 4:
return 'rinkeby'
case NaN:
return 'mainnet'
default:
return ''
}
}

const fetchABI = (addr, network) => {
return new Promise((resolve, reject) => {
const networkParent = getBlockscoutApiNetworkPrefix(network)
const networkName = getBlockscoutApiNetworkSuffix(network)
const bloscoutApiLink = `https://blockscout.com/poa/${networkName}/api`
const bloscoutApiLink = `https://blockscout.com/${networkParent}/${networkName}/api`
const bloscoutApiContractPath = '?module=contract'
const blockscoutApiGetAbiPath = `&action=getabi&address=${addr}`
const apiLink = `${bloscoutApiLink}${bloscoutApiContractPath}${blockscoutApiGetAbiPath}`
Expand Down
Loading