Merge pull request #268 from poanetwork/classic

(Feature) Support of Ethereum Classic chain
This commit is contained in:
Victor Baranov 2019-03-27 21:41:39 +03:00 committed by GitHub
commit 16d942e64b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 293 additions and 404 deletions

View File

@ -35,10 +35,10 @@ workflows:
requires:
- prep-deps-npm
- prep-scss
- test-integration-mascara-firefox:
requires:
- prep-deps-npm
- prep-scss
# - test-integration-mascara-firefox:
# requires:
# - prep-deps-npm
# - prep-scss
- test-integration-flat-chrome:
requires:
- prep-deps-npm
@ -54,7 +54,7 @@ workflows:
- test-e2e-chrome
# - test-e2e-firefox
- test-integration-mascara-chrome
- test-integration-mascara-firefox
# - test-integration-mascara-firefox
- test-integration-flat-chrome
- test-integration-flat-firefox
- job-screens:
@ -193,8 +193,8 @@ jobs:
- run: #STABLE
name: Install Chromedriver latest version
command: |
sudo apt-get update
sudo apt-get install lsb-release libappindicator3-1
# sudo apt-get update
# sudo apt-get install lsb-release libappindicator3-1
curl -L -o google-chrome.deb https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb
sudo dpkg -i google-chrome.deb
sudo sed -i 's|HERE/chrome"|HERE/chrome" --no-sandbox|g' /opt/google/chrome/google-chrome

View File

@ -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
@ -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'
@ -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
@ -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,
@ -49,6 +53,7 @@ module.exports = {
RINKEBY,
KOVAN,
GOERLI_TESTNET,
CLASSIC,
LOCALHOST,
POA_CODE,
DAI_CODE,
@ -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,
@ -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,
@ -74,5 +81,6 @@ module.exports = {
DROPDOWN_RINKEBY_DISPLAY_NAME,
DROPDOWN_KOVAN_DISPLAY_NAME,
DROPDOWN_GOERLI_TESTNET_DISPLAY_NAME,
DROPDOWN_CLASSIC_DISPLAY_NAME,
chainTypes,
}

View File

@ -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,
@ -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]
@ -90,6 +93,7 @@ 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')
@ -97,6 +101,11 @@ module.exports = class NetworkController extends EventEmitter {
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)
})
@ -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
@ -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

View File

@ -7,6 +7,7 @@ const {
RINKEBY,
KOVAN,
GOERLI_TESTNET,
CLASSIC,
POA_CODE,
DAI_CODE,
POA_SOKOL_CODE,
@ -15,6 +16,7 @@ const {
RINKEBY_CODE,
KOVAN_CODE,
GOERLI_TESTNET_CODE,
CLASSIC_CODE,
POA_DISPLAY_NAME,
DAI_DISPLAY_NAME,
POA_SOKOL_DISPLAY_NAME,
@ -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,
@ -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')
@ -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,
@ -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,
@ -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,
@ -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,

View File

@ -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
@ -32,6 +34,7 @@ function getBuyEthUrl ({ network, amount, address, ind }) {
case MAINNET_CODE:
case POA_CODE:
case DAI_CODE:
case CLASSIC_CODE:
url = getExchanges({network, amount, address})[ind].link
break
case ROPSTEN_CODE:
@ -73,7 +76,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',
@ -92,7 +102,7 @@ function getExchanges ({network, amount, address}) {
link: 'https://hitbtc.com/POA-to-ETH',
},
]
case 100:
case DAI_CODE:
return [
{
name: 'xDai TokenBridge',

View File

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

View File

@ -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 {
@ -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 {

View File

@ -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)
@ -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: '',

View File

@ -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:
@ -32,6 +50,8 @@ const getBlockscoutApiNetworkSuffix = (network) => {
return 'ropsten'
case 4:
return 'rinkeby'
case NaN:
return 'mainnet'
default:
return ''
}
@ -39,8 +59,9 @@ const getBlockscoutApiNetworkSuffix = (network) => {
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}`

View File

@ -23,6 +23,7 @@ const { POA_CODE,
RINKEBY_CODE,
KOVAN_CODE,
GOERLI_TESTNET_CODE,
CLASSIC_CODE,
} = require('../../../app/scripts/controllers/network/enums')
const mapDispatchToProps = dispatch => {
@ -74,7 +75,7 @@ TransactionListItem.prototype.render = function () {
var date = formatDate(transaction.time)
let isLinkable = false
const numericNet = parseInt(network)
const numericNet = isNaN(network) ? network : parseInt(network)
isLinkable = numericNet === MAINNET_CODE ||
numericNet === ROPSTEN_CODE ||
numericNet === RINKEBY_CODE ||
@ -82,7 +83,8 @@ TransactionListItem.prototype.render = function () {
numericNet === POA_SOKOL_CODE ||
numericNet === POA_CODE ||
numericNet === DAI_CODE ||
numericNet === GOERLI_TESTNET_CODE
numericNet === GOERLI_TESTNET_CODE ||
numericNet === CLASSIC_CODE
var isMsg = ('msgParams' in transaction)
var isTx = ('txParams' in transaction)

529
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -118,7 +118,7 @@
"eth-keychain-controller": "github:vbaranov/KeyringController#simple-address",
"eth-ledger-bridge-keyring": "github:vbaranov/eth-ledger-bridge-keyring#0.1.0-clear-accounts-flag",
"eth-method-registry": "^1.0.0",
"eth-net-props": "^1.0.14",
"eth-net-props": "^1.0.19",
"eth-phishing-detect": "^1.1.4",
"eth-query": "^2.1.2",
"eth-sig-util": "^2.0.2",
@ -205,6 +205,7 @@
"sw-controller": "^1.0.3",
"sw-stream": "^2.0.2",
"swappable-obj-proxy": "^1.1.0",
"url-parse": "^1.4.4",
"valid-url": "^1.0.9",
"vreme": "^3.0.2",
"web3": "^0.20.1",

View File

@ -395,6 +395,7 @@ module.exports = {
DAI: 'dai',
SOKOL: 'sokol',
MAINNET: 'mainnet',
CLASSIC: 'classic',
ROPSTEN: 'ropsten',
KOVAN: 'kovan',
RINKEBY: 'rinkeby',

View File

@ -123,26 +123,29 @@ class Functions {
case NETWORKS.MAINNET:
counter = 3
break
case NETWORKS.ROPSTEN:
case NETWORKS.CLASSIC:
counter = 4
break
case NETWORKS.KOVAN:
case NETWORKS.ROPSTEN:
counter = 5
break
case NETWORKS.RINKEBY:
case NETWORKS.KOVAN:
counter = 6
break
case NETWORKS.GOERLI:
case NETWORKS.RINKEBY:
counter = 7
break
case NETWORKS.LOCALHOST:
case NETWORKS.GOERLI:
counter = 8
break
case NETWORKS.CUSTOM:
case NETWORKS.LOCALHOST:
counter = 9
break
case NETWORKS.CUSTOM:
counter = 10
break
default:
counter = 8
counter = 9
}
await this.driver.executeScript("document.getElementsByClassName('dropdown-menu-item')[" + counter + '].click();')
}