Merge pull request #153 from poanetwork/dai-chain

(Feature) DAI chain support
This commit is contained in:
Victor Baranov 2018-10-17 22:14:33 +03:00 committed by GitHub
commit f8197e05ea
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 104 additions and 29 deletions

View File

@ -4,6 +4,7 @@ const KOVAN = 'kovan'
const MAINNET = 'mainnet'
const POA_SOKOL = 'sokol'
const POA = 'poa'
const DAI = 'dai'
const LOCALHOST = 'localhost'
const MAINNET_CODE = 1
@ -12,14 +13,24 @@ const RINKEYBY_CODE = 4
const KOVAN_CODE = 42
const POA_SOKOL_CODE = 77
const POA_CODE = 99
const DAI_CODE = 100
const ROPSTEN_DISPLAY_NAME = 'Ropsten'
const RINKEBY_DISPLAY_NAME = 'Rinkeby'
const KOVAN_DISPLAY_NAME = 'Kovan'
const POA_SOKOL_DISPLAY_NAME = 'Sokol'
const POA_DISPLAY_NAME = 'POA Network'
const DAI_DISPLAY_NAME = 'xDai Chain'
const MAINNET_DISPLAY_NAME = 'Main Ethereum Network'
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_POA_SOKOL_DISPLAY_NAME = 'Sokol Network'
const DROPDOWN_POA_DISPLAY_NAME = POA_DISPLAY_NAME
const DROPDOWN_DAI_DISPLAY_NAME = DAI_DISPLAY_NAME
const DROPDOWN_MAINNET_DISPLAY_NAME = 'Main Network'
module.exports = {
ROPSTEN,
RINKEBY,
@ -27,6 +38,7 @@ module.exports = {
MAINNET,
POA_SOKOL,
POA,
DAI,
LOCALHOST,
MAINNET_CODE,
ROPSTEN_CODE,
@ -34,10 +46,19 @@ module.exports = {
KOVAN_CODE,
POA_SOKOL_CODE,
POA_CODE,
DAI_CODE,
ROPSTEN_DISPLAY_NAME,
RINKEBY_DISPLAY_NAME,
KOVAN_DISPLAY_NAME,
MAINNET_DISPLAY_NAME,
POA_SOKOL_DISPLAY_NAME,
POA_DISPLAY_NAME,
DAI_DISPLAY_NAME,
DROPDOWN_ROPSTEN_DISPLAY_NAME,
DROPDOWN_RINKEBY_DISPLAY_NAME,
DROPDOWN_KOVAN_DISPLAY_NAME,
DROPDOWN_POA_SOKOL_DISPLAY_NAME,
DROPDOWN_POA_DISPLAY_NAME,
DROPDOWN_DAI_DISPLAY_NAME,
DROPDOWN_MAINNET_DISPLAY_NAME,
}

View File

@ -18,9 +18,11 @@ const {
LOCALHOST,
POA_SOKOL,
POA,
DAI,
} = require('./enums')
const LOCALHOST_RPC_URL = 'http://localhost:8545'
const POA_RPC_URL = 'https://core.poa.network'
const DAI_RPC_URL = 'https://dai.poa.network'
const SOKOL_RPC_URL = 'https://sokol.poa.network'
const INFURA_PROVIDER_TYPES = [ROPSTEN, RINKEBY, KOVAN, MAINNET]
@ -99,7 +101,7 @@ module.exports = class NetworkController extends EventEmitter {
async setProviderType (type) {
assert.notEqual(type, 'rpc', `NetworkController - cannot call "setProviderType" with type 'rpc'. use "setRpcTarget"`)
assert(INFURA_PROVIDER_TYPES.includes(type) || type === LOCALHOST || type === POA_SOKOL || type === POA, `NetworkController - Unknown rpc type "${type}"`)
assert(INFURA_PROVIDER_TYPES.includes(type) || type === LOCALHOST || type === POA_SOKOL || type === POA || type === DAI, `NetworkController - Unknown rpc type "${type}"`)
const providerConfig = { type }
this.providerConfig = providerConfig
}
@ -136,6 +138,8 @@ module.exports = class NetworkController extends EventEmitter {
// other type-based rpc endpoints
} else if (type === POA) {
this._configureStandardProvider({ rpcUrl: POA_RPC_URL })
} else if (type === DAI) {
this._configureStandardProvider({ rpcUrl: DAI_RPC_URL })
} else if (type === POA_SOKOL) {
this._configureStandardProvider({ rpcUrl: SOKOL_RPC_URL })
} else if (type === LOCALHOST) {

View File

@ -287,6 +287,23 @@ App.prototype.renderNetworkDropdown = function () {
]
),
h(
DropdownMenuItem,
{
key: 'dai',
closeMenu: () => this.setState({ isNetworkMenuOpen: !isOpen }),
onClick: () => props.dispatch(actions.setProviderType('dai')),
style: {
paddingLeft: '20px',
fontSize: '16px',
color: providerType === 'dai' ? 'white' : '',
},
},
[h(providerType === 'dai' ? 'div.selected-network' : ''),
ethNetProps.props.getNetworkDisplayName(100),
]
),
h(
DropdownMenuItem,
{

View File

@ -9,6 +9,7 @@ const Loading = require('./loading')
const AccountPanel = require('./account-panel')
const RadioList = require('./custom-radio-list')
const { getNetworkDisplayName } = require('../../../app/scripts/controllers/network/util')
const ethNetProps = require('eth-net-props')
module.exports = connect(mapStateToProps)(BuyButtonSubview)
@ -47,9 +48,7 @@ BuyButtonSubview.prototype.headerSubview = function () {
const props = this.props
const { network } = props
const isLoading = props.isSubLoading
const isSokol = parseInt(network) === 77
const isPOA = parseInt(network) === 99
const coinName = isPOA ? 'POA' : isSokol ? 'SPOA' : 'ETH'
const coinName = ethNetProps.props.getNetworkCoinName(network)
return (
h('.flex-column', {
@ -143,12 +142,13 @@ BuyButtonSubview.prototype.primarySubview = function () {
case '1':
return this.mainnetSubview()
// Ropsten, Rinkeby, Kovan, Sokol, POA
// Ropsten, Rinkeby, Kovan, Sokol, POA, DAI
case '3':
case '4':
case '42':
case '77':
case '99':
case '100':
const networkName = getNetworkDisplayName(network)
const label = `${networkName} Test Faucet`
return (
@ -157,7 +157,7 @@ BuyButtonSubview.prototype.primarySubview = function () {
margin: '20px 30px',
},
}, [
network !== '99' ? h('p.exchanges.cursor-pointer', {
network !== '99' && network !== '100' ? h('p.exchanges.cursor-pointer', {
onClick: () => this.props.dispatch(actions.buyEth({ network })),
},
[h('span', {style: {marginRight: '10px', color: '#6729a8'}}, label)]) : null,

View File

@ -15,8 +15,11 @@ FiatValue.prototype.render = function () {
let { conversionRate } = props
const { currentCurrency, network } = props
const isSokol = parseInt(network) === 77
const isDai = parseInt(network) === 100
if (isSokol) {
conversionRate = 0
} else if (isDai) {
conversionRate = 1
}
const renderedCurrency = currentCurrency || ''

View File

@ -2,6 +2,15 @@ const Component = require('react').Component
const h = require('react-hyperscript')
const inherits = require('util').inherits
const ethNetProps = require('eth-net-props')
const {
DROPDOWN_ROPSTEN_DISPLAY_NAME,
DROPDOWN_RINKEBY_DISPLAY_NAME,
DROPDOWN_KOVAN_DISPLAY_NAME,
DROPDOWN_POA_SOKOL_DISPLAY_NAME,
DROPDOWN_POA_DISPLAY_NAME,
DROPDOWN_DAI_DISPLAY_NAME,
DROPDOWN_MAINNET_DISPLAY_NAME,
} = require('../../../app/scripts/controllers/network/enums')
module.exports = Network
@ -43,22 +52,25 @@ Network.prototype.render = function () {
])
} else {
if (providerName === 'mainnet' || parseInt(networkNumber) === 1) {
displayName = 'Main Network'
displayName = DROPDOWN_MAINNET_DISPLAY_NAME
hoverText = ethNetProps.props.getNetworkDisplayName(networkNumber)
} else if (providerName === 'ropsten' || parseInt(networkNumber) === 3) {
displayName = 'Ropsten Test Net'
displayName = DROPDOWN_ROPSTEN_DISPLAY_NAME
hoverText = ethNetProps.props.getNetworkDisplayName(networkNumber)
} else if (providerName === 'sokol' || parseInt(networkNumber) === 77) {
displayName = 'Sokol Network'
displayName = DROPDOWN_POA_SOKOL_DISPLAY_NAME
hoverText = ethNetProps.props.getNetworkDisplayName(networkNumber)
} else if (providerName === 'kovan' || parseInt(networkNumber) === 42) {
displayName = 'Kovan Test Net'
displayName = DROPDOWN_KOVAN_DISPLAY_NAME
hoverText = ethNetProps.props.getNetworkDisplayName(networkNumber)
} else if (providerName === 'rinkeby' || parseInt(networkNumber) === 4) {
displayName = 'Rinkeby Test Net'
displayName = DROPDOWN_RINKEBY_DISPLAY_NAME
hoverText = ethNetProps.props.getNetworkDisplayName(networkNumber)
} else if (providerName === 'poa' || parseInt(networkNumber) === 99) {
displayName = 'POA Network'
displayName = DROPDOWN_POA_DISPLAY_NAME
hoverText = ethNetProps.props.getNetworkDisplayName(networkNumber)
} else if (providerName === 'dai' || parseInt(networkNumber) === 100) {
displayName = DROPDOWN_DAI_DISPLAY_NAME
hoverText = ethNetProps.props.getNetworkDisplayName(networkNumber)
} else {
displayName = 'Private Network'

View File

@ -53,8 +53,11 @@ ConfirmTxScreen.prototype.render = function () {
let { conversionRate } = props
const isSokol = parseInt(network) === 77
const isDai = parseInt(network) === 100
if (isSokol) {
conversionRate = 0
} else if (isDai) {
conversionRate = 1
}
var unconfTxList = txHelper(unapprovedTxs, unapprovedMsgs, unapprovedPersonalMsgs, unapprovedTypedMessages, network)

View File

@ -315,6 +315,11 @@ function currentProviderDisplay (metamaskState, state) {
value = ethNetProps.props.getNetworkDisplayName(99)
break
case 'dai':
title = 'Current Network'
value = ethNetProps.props.getNetworkDisplayName(100)
break
default:
title = 'Current RPC'
value = metamaskState.provider.rpcTarget

View File

@ -1,4 +1,5 @@
const ethUtil = require('ethereumjs-util')
const ethNetProps = require('eth-net-props')
var valueTable = {
wei: '1000000000000000000',
@ -112,9 +113,7 @@ function parseBalance (balance) {
// Takes wei hex, returns an object with three properties.
// Its "formatted" property is what we generally use to render values.
function formatBalance (balance, decimalsToKeep, needsParse = true, network, isToken, tokenSymbol) {
const isSokol = parseInt(network) === 77
const isPOA = parseInt(network) === 99
const coinName = isPOA ? 'POA' : isSokol ? 'SPOA' : 'ETH'
const coinName = ethNetProps.props.getNetworkCoinName(network)
const assetName = isToken ? tokenSymbol : coinName
var parsed = needsParse ? parseBalance(balance) : balance.split('.')
var beforeDecimal = parsed[0]

8
package-lock.json generated
View File

@ -8453,7 +8453,7 @@
}
},
"eth-contract-metadata": {
"version": "github:MetaMask/eth-contract-metadata#bd23fa120512dcbb6fad31559297f96f17c3a8e0",
"version": "github:MetaMask/eth-contract-metadata#966a891dd9c79b873fd8968a0155b067ca630502",
"from": "github:MetaMask/eth-contract-metadata#master"
},
"eth-ens-namehash": {
@ -8754,9 +8754,9 @@
}
},
"eth-net-props": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/eth-net-props/-/eth-net-props-1.0.3.tgz",
"integrity": "sha512-iHY/o2/JwEk+HOTFmn5ju1LXsMf+qNsJZ30SdD3WZ9PJH9jc7lqI6fh80xQHWqV7Q2pkZqD5YvO3G6fdrKzQ0Q==",
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/eth-net-props/-/eth-net-props-1.0.7.tgz",
"integrity": "sha512-j+2Ft7crm6BUrm7ovShGhvOc4A6zKjPoZF0JNMGlv9wyHXUh6QCYQ1VM5g76EykLPSUJjbikdIYuL/0LtQPR6Q==",
"requires": {
"chai": "^4.1.2"
}

View File

@ -109,7 +109,7 @@
"eth-json-rpc-filters": "^1.2.6",
"eth-json-rpc-infura": "^3.0.0",
"eth-method-registry": "^1.0.0",
"eth-net-props": "^1.0.3",
"eth-net-props": "^1.0.7",
"eth-phishing-detect": "^1.1.4",
"eth-query": "^2.1.2",
"eth-sig-util": "^1.4.2",

View File

@ -305,6 +305,7 @@ module.exports = {
},
NETWORKS: {
POA: 'poa',
DAI: 'dai',
SOKOL: 'sokol',
MAINNET: 'mainnet',
ROPSTEN: 'ropsten',

View File

@ -829,6 +829,11 @@ describe('Metamask popup page', async function () {
assert.equal(await assertTokensNotDisplayed(), true, 'tokens are displayed')
})
it('token should not be displayed in DAI network', async function () {
await setProvider(NETWORKS.DAI)
assert.equal(await assertTokensNotDisplayed(), true, 'tokens are displayed')
})
it('token should not be displayed in SOKOL network', async function () {
await setProvider(NETWORKS.SOKOL)
assert.equal(await assertTokensNotDisplayed(), true, 'tokens are displayed')
@ -1057,6 +1062,7 @@ describe('Metamask popup page', async function () {
})
})
describe('Check support of token per network basis ', async function () {
describe('Token should be displayed only for network, where it was added ', async function () {
@ -1139,6 +1145,7 @@ describe('Metamask popup page', async function () {
})
})
describe('Transfer tokens', function () {
const account2 = '0x2f318C334780961FB129D2a6c30D0763d9a5C970'
@ -1545,29 +1552,32 @@ describe('Metamask popup page', async function () {
case NETWORKS.POA:
counter = 0
break
case NETWORKS.SOKOL:
case NETWORKS.DAI:
counter = 1
break
case NETWORKS.MAINNET:
case NETWORKS.SOKOL:
counter = 2
break
case NETWORKS.ROPSTEN:
case NETWORKS.MAINNET:
counter = 3
break
case NETWORKS.KOVAN:
case NETWORKS.ROPSTEN:
counter = 4
break
case NETWORKS.RINKEBY:
case NETWORKS.KOVAN:
counter = 5
break
case NETWORKS.LOCALHOST:
case NETWORKS.RINKEBY:
counter = 6
break
case NETWORKS.CUSTOM:
case NETWORKS.LOCALHOST:
counter = 7
break
case NETWORKS.CUSTOM:
counter = 8
break
default:
counter = 6
counter = 7
}
await driver.executeScript("document.getElementsByClassName('dropdown-menu-item')[" + counter + '].click();')
}

View File

@ -1759,7 +1759,7 @@ function setProviderType (type) {
dispatch(actions.setSelectedToken())
})
const newCoin = type === 'poa' || type === 'sokol' ? 'poa' : 'eth'
const newCoin = type === 'poa' || type === 'sokol' ? 'poa' : type === 'dai' ? 'dai' : 'eth'
background.setCurrentCoin(newCoin, (err, data) => {
if (err) {
log.error(err.stack)