diff --git a/app/scripts/lib/buy-eth-url.js b/app/scripts/lib/buy-eth-url.js index ca04fe264..db2fafd82 100644 --- a/app/scripts/lib/buy-eth-url.js +++ b/app/scripts/lib/buy-eth-url.js @@ -1,53 +1,89 @@ -module.exports = getBuyEthUrl +module.exports = { + getBuyEthUrl, + getFaucets, + getExchanges, +} +const ethNetProps = require('eth-net-props') /** - * Gives the caller a url at which the user can acquire eth, depending on the network they are in + * Gives the caller a url at which the user can acquire coin, depending on the network they are in * * @param {object} opts Options required to determine the correct url * @param {string} opts.network The network for which to return a url * @param {string} opts.amount The amount of ETH to buy on coinbase. Only relevant if network === '1'. * @param {string} opts.address The address the bought ETH should be sent to. Only relevant if network === '1'. + * @param {number} opts.ind The position of the link (to faucet, or exchange) in the array of links for selected network * @returns {string|undefined} The url at which the user can access ETH, while in the given network. If the passed * network does not match any of the specified cases, or if no network is given, returns undefined. * */ -function getBuyEthUrl ({ network, amount, address, exchange }) { +function getBuyEthUrl ({ network, amount, address, ind }) { let url switch (network) { case '1': - url = `https://buy.coinbase.com/?code=9ec56d01-7e81-5017-930c-513daa27bb6a&amount=${amount}&address=${address}&crypto_currency=ETH` + case '99': + case '100': + url = getExchanges({network, amount, address})[ind].link break - case '3': - url = 'https://faucet.metamask.io/' - break - case '4': - url = 'https://www.rinkeby.io/' - break - case '42': - url = 'https://github.com/kovan-testnet/faucet' - break - case '77': - url = 'https://faucet.poa.network/' + url = getFaucets(network)[ind] break - - case '99': { - switch (exchange) { - case 'binance': - url = 'https://www.binance.com/en/trade/POA_ETH' - break - case 'bibox': - url = 'https://www.bibox.com/exchange?coinPair=POA_ETH' - break - case 'cex.plus': - url = 'http://cex.plus/market/poa_eth' - break - } - break - } } return url } + +/** + * Retrieves the array of faucets for given network ID of testnet + * + * @param {string} The network ID + * @returns {array} The array of faucets for given network ID + */ +function getFaucets (network) { + return ethNetProps.faucetLinks(network) +} + +/** + * Retrieves the array of exchanges for given network ID of production chain + * + * @param {object} opts Options required to determine the correct exchange service url + * @param {string} opts.network The network ID + * @param {string} opts.amount The amount of ETH to buy on coinbase. Only relevant if network === '1'. + * @param {string} opts.address The address the bought ETH should be sent to. Only relevant if network === '1'. + * @returns {array} The array of exchanges for given network ID + */ +function getExchanges ({network, amount, address}) { + const networkID = Number(network) + switch (networkID) { + case 1: + return [ + { + link: `https://buy.coinbase.com/?code=9ec56d01-7e81-5017-930c-513daa27bb6a&amount=${amount}&address=${address}&crypto_currency=ETH`, + }, + ] + case 99: + return [ + { + name: 'Binance', + link: 'https://www.binance.com/en/trade/POA_ETH', + }, + { + name: 'BiBox', + link: 'https://www.bibox.com/exchange?coinPair=POA_ETH', + }, + { + name: 'CEX Plus', + link: 'http://cex.plus/market/poa_eth', + }, + ] + case 100: + return [ + { + name: 'xDai TokenBridge', + link: 'https://dai-bridge.poa.network/', + }, + ] + } +} diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index af21ee2f2..4ed4104a9 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -39,7 +39,6 @@ const TokenRatesController = require('./controllers/token-rates') const DetectTokensController = require('./controllers/detect-tokens') const nodeify = require('./lib/nodeify') const accountImporter = require('./account-import-strategies') -const getBuyEthUrl = require('./lib/buy-eth-url') const Mutex = require('await-semaphore').Mutex const version = require('../manifest.json').version const BN = require('ethereumjs-util').BN @@ -359,8 +358,6 @@ module.exports = class MetamaskController extends EventEmitter { unMarkPasswordForgotten: this.unMarkPasswordForgotten.bind(this), getGasPrice: (cb) => cb(null, this.getGasPrice()), - // coinbase - buyEth: this.buyEth.bind(this), // shapeshift createShapeShiftTx: this.createShapeShiftTx.bind(this), @@ -1459,20 +1456,6 @@ module.exports = class MetamaskController extends EventEmitter { } } - /** - * A method for forwarding the user to the easiest way to obtain ether, - * or the network "gas" currency, for the current selected network. - * - * @param {string} address - The address to fund. - * @param {string} amount - The amount of ether desired, as a base 10 string. - */ - buyEth (address, amount, exchange) { - if (!amount) amount = '5' - const network = this.networkController.getNetworkState() - const url = getBuyEthUrl({ network, address, amount, exchange }) - if (url) this.platform.openWindow({ url }) - } - /** * A method for triggering a shapeshift currency transfer. * @param {string} depositAddress - The address to deposit to. diff --git a/old-ui/app/components/buy-button-subview.js b/old-ui/app/components/buy-button-subview.js index 945c2f8b9..295d23964 100644 --- a/old-ui/app/components/buy-button-subview.js +++ b/old-ui/app/components/buy-button-subview.js @@ -1,17 +1,197 @@ -const Component = require('react').Component -const h = require('react-hyperscript') -const inherits = require('util').inherits -const connect = require('react-redux').connect -const actions = require('../../../ui/app/actions') -const CoinbaseForm = require('./coinbase-form') -const ShapeshiftForm = require('./shapeshift-form') -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') +import React, {Component} from 'react' +import { connect } from 'react-redux' +import actions from '../../../ui/app/actions' +import CoinbaseForm from './coinbase-form' +import ShapeshiftForm from './shapeshift-form' +import Loading from './loading' +import AccountPanel from './account-panel' +import RadioList from './custom-radio-list' +import { getNetworkDisplayName } from '../../../app/scripts/controllers/network/util' +import { getFaucets, getExchanges } from '../../../app/scripts/lib/buy-eth-url' +import ethNetProps from 'eth-net-props' +import PropTypes from 'prop-types' -module.exports = connect(mapStateToProps)(BuyButtonSubview) +class BuyButtonSubview extends Component { + render () { + return ( +
+ { this.headerSubview() } + { this.primarySubview() } +
+ ) + } + + headerSubview () { + const props = this.props + const { network } = props + const isLoading = props.isSubLoading + const coinName = ethNetProps.props.getNetworkCoinName(network) + return ( +
+ { /* loading indication*/ } +
+ +
+ { /* account panel*/ } +
+ +
+ { /* header bar (back button, label)*/ } +
+ this.backButtonContext()} + style={{ + position: 'absolute', + left: '30px', + }} + /> +

{`Buy ${coinName}`}

+
+
+

Select Service

+
+
+ ) + } + + primarySubview () { + const props = this.props + const network = props.network + + switch (network) { + case 'loading': + return + + case '1': + return this.mainnetSubview() + + default: + return ( +
+ { this._getBuyOptionsView(network) } +
+ ) + } + } + + _getBuyOptionsView (network) { + const isTestnet = ethNetProps.props.isTestnet(network) + if (isTestnet) { + return this._getFaucetsView(network) + } else { + return this._getExchangesView(network) + } + } + + _getExchangesView (network) { + const exchanges = getExchanges({network}) + return exchanges.map((exchange, ind) => { + return

this.props.dispatch(actions.buyEth({ network, ind }))} + > + { exchange.name } +

+ }) + } + + _getFaucetsView (network) { + const faucets = getFaucets(network) + if (faucets.length === 0) { + return

Unknown network ID

+ } + const networkName = getNetworkDisplayName(network) + return faucets.map((faucet, ind) => { + const faucetNum = faucets.length > 1 ? (ind + 1) : '' + const faucetLabel = `${networkName} Test Faucet ${faucetNum}` + return

this.props.dispatch(actions.buyEth({ network, ind }))} + > + { faucetLabel } +

+ }) + } + + mainnetSubview () { + const props = this.props + + return ( +
+
+ this.radioHandler(event)} + /> +
+

+ { props.buyView.subview } +

+ { this.formVersionSubview() } +
+ ) + } + + formVersionSubview () { + const network = this.props.network + if (network === '1') { + if (this.props.buyView.formView.coinbase) { + return + } else if (this.props.buyView.formView.shapeshift) { + return + } + } + } + + backButtonContext () { + if (this.props.context === 'confTx') { + this.props.dispatch(actions.showConfTxPage(false)) + } else { + this.props.dispatch(actions.goHome()) + } + } + + radioHandler (event) { + switch (event.target.title) { + case 'Coinbase': + return this.props.dispatch(actions.coinBaseSubview()) + case 'ShapeShift': + return this.props.dispatch(actions.shapeShiftSubview(this.props.provider.type)) + } + } +} + +BuyButtonSubview.propTypes = { + dispatch: PropTypes.func, + network: PropTypes.string, + buyView: PropTypes.object, + context: PropTypes.string, + provider: PropTypes.object, +} function mapStateToProps (state) { return { @@ -26,246 +206,4 @@ function mapStateToProps (state) { } } -inherits(BuyButtonSubview, Component) -function BuyButtonSubview () { - Component.call(this) -} - -BuyButtonSubview.prototype.render = function () { - return ( - h('div', { - style: { - width: '100%', - }, - }, [ - this.headerSubview(), - this.primarySubview(), - ]) - ) -} - -BuyButtonSubview.prototype.headerSubview = function () { - const props = this.props - const { network } = props - const isLoading = props.isSubLoading - const coinName = ethNetProps.props.getNetworkCoinName(network) - return ( - - h('.flex-column', { - style: { - alignItems: 'center', - }, - }, [ - - // loading indication - h('div', { - style: { - position: 'absolute', - top: '57vh', - left: '49vw', - }, - }, [ - h(Loading, { isLoading }), - ]), - - // account panel - h('div', { - style: { - width: '100%', - }, - }, [ - h(AccountPanel, { - showFullAddress: true, - identity: props.identity, - account: props.account, - network: props.network, - }), - ]), - - // header bar (back button, label) - h('.flex-row.section-title', { - style: { - alignItems: 'center', - justifyContent: 'center', - }, - }, [ - h('i.fa.fa-arrow-left.fa-lg.cursor-pointer', { - onClick: this.backButtonContext.bind(this), - style: { - position: 'absolute', - left: '30px', - }, - }), - h('h2.flex-center', { - style: { - width: '100vw', - background: '#ffffff', - color: '#333333', - paddingTop: '4px', - paddingBottom: '4px', - }, - }, `Buy ${coinName}`), - ]), - - h('.flex-row', { - style: { - alignItems: 'center', - width: '100%', - }, - }, [ - h('h3.flex-center', { - style: { - width: '100%', - background: '#ffffff', - color: '#333333', - paddingLeft: '30px', - justifyContent: 'left', - fontFamily: 'Nunito Semibold', - }, - }, 'Select Service'), - ]), - - ]) - - ) -} - - -BuyButtonSubview.prototype.primarySubview = function () { - const props = this.props - const network = props.network - - switch (network) { - case 'loading': - return - - case '1': - return this.mainnetSubview() - - // 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 ( - h('div.flex-column', { - style: { - margin: '20px 30px', - }, - }, [ - 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, - network === '99' ? h('p.exchanges.cursor-pointer', { - onClick: () => this.props.dispatch(actions.buyEth({ network, exchange: 'binance' })), - }, [h('span', {style: {marginRight: '10px', color: '#6729a8'}}, 'Binance')]) : null, - network === '99' ? h('p.exchanges.cursor-pointer', { - onClick: () => this.props.dispatch(actions.buyEth({ network, exchange: 'bibox' })), - }, [h('span', {style: {marginRight: '10px', color: '#6729a8'}}, 'BiBox')]) : null, - network === '99' ? h('p.exchanges.cursor-pointer', { - onClick: () => this.props.dispatch(actions.buyEth({ network, exchange: 'cex.plus' })), - }, [h('span', {style: {marginRight: '10px', color: '#6729a8'}}, 'CEX Plus')]) : null, - // Kovan only: Dharma loans beta - network === '42' ? ( - h('p.exchanges.cursor-pointer', { - onClick: () => this.navigateTo('https://borrow.dharma.io/'), - }, [h('span', {style: {marginRight: '10px', color: '#6729a8'}}, 'Borrow With Dharma (Beta)')]) - ) : null, - ]) - ) - - default: - return ( - h('div', { - style: { - padding: '20px 30px', - }}, - h('h2.error', 'Unknown network ID') - ) - ) - - } -} - -BuyButtonSubview.prototype.mainnetSubview = function () { - const props = this.props - - return ( - - h('.flex-column', [ - - h('.flex-row.selected-exchange', { - style: { - position: 'relative', - marginLeft: '30px', - marginTop: '20px', - marginBottom: '20px', - }, - }, [ - h(RadioList, { - defaultFocus: props.buyView.subview, - labels: [ - 'Coinbase', - 'ShapeShift', - ], - subtext: { - 'Coinbase': 'Crypto/FIAT (USA only)', - 'ShapeShift': 'Crypto', - }, - onClick: this.radioHandler.bind(this), - }), - ]), - - h('h3', { - style: { - padding: '20px 30px', - fontFamily: 'Nunito Semibold', - color: '#333333', - paddingTop: '20px', - paddingBottom: '20px', - borderTop: '1px solid #e2e2e2', - }, - }, props.buyView.subview), - - this.formVersionSubview(), - ]) - - ) -} - -BuyButtonSubview.prototype.formVersionSubview = function () { - const network = this.props.network - if (network === '1') { - if (this.props.buyView.formView.coinbase) { - return h(CoinbaseForm, this.props) - } else if (this.props.buyView.formView.shapeshift) { - return h(ShapeshiftForm, this.props) - } - } -} - -BuyButtonSubview.prototype.navigateTo = function (url) { - global.platform.openWindow({ url }) -} - -BuyButtonSubview.prototype.backButtonContext = function () { - if (this.props.context === 'confTx') { - this.props.dispatch(actions.showConfTxPage(false)) - } else { - this.props.dispatch(actions.goHome()) - } -} - -BuyButtonSubview.prototype.radioHandler = function (event) { - switch (event.target.title) { - case 'Coinbase': - return this.props.dispatch(actions.coinBaseSubview()) - case 'ShapeShift': - return this.props.dispatch(actions.shapeShiftSubview(this.props.provider.type)) - } -} +module.exports = connect(mapStateToProps)(BuyButtonSubview) diff --git a/old-ui/app/components/coinbase-form.js b/old-ui/app/components/coinbase-form.js index cf3263a52..3f2eeed21 100644 --- a/old-ui/app/components/coinbase-form.js +++ b/old-ui/app/components/coinbase-form.js @@ -41,7 +41,7 @@ CoinbaseForm.prototype.render = function () { CoinbaseForm.prototype.toCoinbase = function () { const props = this.props const address = props.buyView.buyAddress - props.dispatch(actions.buyEth({ network: '1', address, amount: 0 })) + props.dispatch(actions.buyEth({ network: '1', address, amount: 0, ind: 0 })) } CoinbaseForm.prototype.renderLoading = function () { diff --git a/old-ui/app/css/index.css b/old-ui/app/css/index.css index 013b548a1..b2c10e122 100644 --- a/old-ui/app/css/index.css +++ b/old-ui/app/css/index.css @@ -292,8 +292,10 @@ app sections color: #60db97; } -p.exchanges { +p.buy-option { margin-bottom: 10px; + margin-right: 10px; + color: #6729a8; } .new-tx { @@ -756,7 +758,24 @@ input.large-input { } .selected-exchange { + position: relative; + margin-left: 30px; + margin-bottom: 20px; +} +.buy-title { + width: 100vw; + background: #ffffff; + color: #333333; + padding-top: 4px; + padding-bottom: 4px; +} + +.select-service { + color: #333333; + padding: 0px 0px 20px 30px; + justify-content: left; + font-family: Nunito Semibold; } .buy-radio { diff --git a/package-lock.json b/package-lock.json index 7bf8ce674..e299a6e4f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10367,12 +10367,13 @@ "resolved": "https://registry.npmjs.org/eth-sig-util/-/eth-sig-util-2.0.1.tgz", "integrity": "sha512-lxHZOQspexk3DaGj4RBbWy4C/qNOWRnxpaJzNnYD3WEmC8shcJ4tHs7Xv878rzvILfJnSFSCCiKQhng1m80oBQ==", "requires": { + "ethereumjs-abi": "git+https://github.com/ethereumjs/ethereumjs-abi.git#2863c40e0982acfc0b7163f0285d4c56427c7799", "ethereumjs-util": "^5.1.1" }, "dependencies": { "ethereumjs-abi": { "version": "git+https://github.com/ethereumjs/ethereumjs-abi.git#2863c40e0982acfc0b7163f0285d4c56427c7799", - "from": "git+https://github.com/ethereumjs/ethereumjs-abi.git#2863c40e0982acfc0b7163f0285d4c56427c7799", + "from": "git+https://github.com/ethereumjs/ethereumjs-abi.git", "requires": { "bn.js": "^4.10.0", "ethereumjs-util": "^5.0.0" @@ -10448,12 +10449,13 @@ "resolved": "https://registry.npmjs.org/eth-sig-util/-/eth-sig-util-1.4.2.tgz", "integrity": "sha1-jZWCAsftuq6Dlwf7pvCf8ydgYhA=", "requires": { + "ethereumjs-abi": "git+https://github.com/ethereumjs/ethereumjs-abi.git#2863c40e0982acfc0b7163f0285d4c56427c7799", "ethereumjs-util": "^5.1.1" }, "dependencies": { "ethereumjs-abi": { "version": "git+https://github.com/ethereumjs/ethereumjs-abi.git#2863c40e0982acfc0b7163f0285d4c56427c7799", - "from": "git+https://github.com/ethereumjs/ethereumjs-abi.git#2863c40e0982acfc0b7163f0285d4c56427c7799", + "from": "git+https://github.com/ethereumjs/ethereumjs-abi.git", "requires": { "bn.js": "^4.10.0", "ethereumjs-util": "^5.0.0" @@ -10606,12 +10608,14 @@ "integrity": "sha1-jZWCAsftuq6Dlwf7pvCf8ydgYhA=", "dev": true, "requires": { + "ethereumjs-abi": "git+https://github.com/ethereumjs/ethereumjs-abi.git#2863c40e0982acfc0b7163f0285d4c56427c7799", "ethereumjs-util": "^5.1.1" }, "dependencies": { "ethereumjs-abi": { "version": "git+https://github.com/ethereumjs/ethereumjs-abi.git#2863c40e0982acfc0b7163f0285d4c56427c7799", - "from": "git+https://github.com/ethereumjs/ethereumjs-abi.git#2863c40e0982acfc0b7163f0285d4c56427c7799", + "from": "git+https://github.com/ethereumjs/ethereumjs-abi.git", + "dev": true, "requires": { "bn.js": "^4.10.0", "ethereumjs-util": "^5.0.0" @@ -10662,7 +10666,7 @@ "dependencies": { "babelify": { "version": "7.3.0", - "resolved": "http://registry.npmjs.org/babelify/-/babelify-7.3.0.tgz", + "resolved": "https://registry.npmjs.org/babelify/-/babelify-7.3.0.tgz", "integrity": "sha1-qlau3nBn/XvVSWZu4W3ChQh+iOU=", "requires": { "babel-core": "^6.0.14", @@ -10674,12 +10678,13 @@ "resolved": "https://registry.npmjs.org/eth-sig-util/-/eth-sig-util-1.4.2.tgz", "integrity": "sha1-jZWCAsftuq6Dlwf7pvCf8ydgYhA=", "requires": { + "ethereumjs-abi": "git+https://github.com/ethereumjs/ethereumjs-abi.git#2863c40e0982acfc0b7163f0285d4c56427c7799", "ethereumjs-util": "^5.1.1" }, "dependencies": { "ethereumjs-abi": { "version": "git+https://github.com/ethereumjs/ethereumjs-abi.git#2863c40e0982acfc0b7163f0285d4c56427c7799", - "from": "git+https://github.com/ethereumjs/ethereumjs-abi.git#2863c40e0982acfc0b7163f0285d4c56427c7799", + "from": "git+https://github.com/ethereumjs/ethereumjs-abi.git", "requires": { "bn.js": "^4.10.0", "ethereumjs-util": "^5.0.0" @@ -10740,12 +10745,13 @@ "resolved": "https://registry.npmjs.org/eth-sig-util/-/eth-sig-util-1.4.2.tgz", "integrity": "sha1-jZWCAsftuq6Dlwf7pvCf8ydgYhA=", "requires": { + "ethereumjs-abi": "git+https://github.com/ethereumjs/ethereumjs-abi.git#2863c40e0982acfc0b7163f0285d4c56427c7799", "ethereumjs-util": "^5.1.1" }, "dependencies": { "ethereumjs-abi": { "version": "git+https://github.com/ethereumjs/ethereumjs-abi.git#2863c40e0982acfc0b7163f0285d4c56427c7799", - "from": "git+https://github.com/ethereumjs/ethereumjs-abi.git#2863c40e0982acfc0b7163f0285d4c56427c7799", + "from": "git+https://github.com/ethereumjs/ethereumjs-abi.git", "requires": { "bn.js": "^4.10.0", "ethereumjs-util": "^5.0.0" @@ -10924,9 +10930,9 @@ } }, "eth-net-props": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/eth-net-props/-/eth-net-props-1.0.7.tgz", - "integrity": "sha512-j+2Ft7crm6BUrm7ovShGhvOc4A6zKjPoZF0JNMGlv9wyHXUh6QCYQ1VM5g76EykLPSUJjbikdIYuL/0LtQPR6Q==", + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/eth-net-props/-/eth-net-props-1.0.10.tgz", + "integrity": "sha512-sCKttmHUFficRcyx95CWUW2AuvQ6rEboy4XcoR49HU7UNMxOdRti3rFyGrkVepRozn1bLLjet/doPKnj8rDG7g==", "requires": { "chai": "^4.1.2" } @@ -11211,12 +11217,13 @@ "resolved": "https://registry.npmjs.org/eth-sig-util/-/eth-sig-util-1.4.2.tgz", "integrity": "sha1-jZWCAsftuq6Dlwf7pvCf8ydgYhA=", "requires": { + "ethereumjs-abi": "git+https://github.com/ethereumjs/ethereumjs-abi.git#2863c40e0982acfc0b7163f0285d4c56427c7799", "ethereumjs-util": "^5.1.1" }, "dependencies": { "ethereumjs-abi": { "version": "git+https://github.com/ethereumjs/ethereumjs-abi.git#2863c40e0982acfc0b7163f0285d4c56427c7799", - "from": "git+https://github.com/ethereumjs/ethereumjs-abi.git#2863c40e0982acfc0b7163f0285d4c56427c7799", + "from": "git+https://github.com/ethereumjs/ethereumjs-abi.git", "requires": { "bn.js": "^4.10.0", "ethereumjs-util": "^5.0.0" @@ -11411,12 +11418,13 @@ "resolved": "https://registry.npmjs.org/eth-sig-util/-/eth-sig-util-1.4.2.tgz", "integrity": "sha1-jZWCAsftuq6Dlwf7pvCf8ydgYhA=", "requires": { + "ethereumjs-abi": "git+https://github.com/ethereumjs/ethereumjs-abi.git#2863c40e0982acfc0b7163f0285d4c56427c7799", "ethereumjs-util": "^5.1.1" }, "dependencies": { "ethereumjs-abi": { "version": "git+https://github.com/ethereumjs/ethereumjs-abi.git#2863c40e0982acfc0b7163f0285d4c56427c7799", - "from": "git+https://github.com/ethereumjs/ethereumjs-abi.git#2863c40e0982acfc0b7163f0285d4c56427c7799", + "from": "git+https://github.com/ethereumjs/ethereumjs-abi.git", "requires": { "bn.js": "^4.10.0", "ethereumjs-util": "^5.0.0" @@ -14786,12 +14794,14 @@ "integrity": "sha1-jZWCAsftuq6Dlwf7pvCf8ydgYhA=", "dev": true, "requires": { + "ethereumjs-abi": "git+https://github.com/ethereumjs/ethereumjs-abi.git#2863c40e0982acfc0b7163f0285d4c56427c7799", "ethereumjs-util": "^5.1.1" }, "dependencies": { "ethereumjs-abi": { "version": "git+https://github.com/ethereumjs/ethereumjs-abi.git#2863c40e0982acfc0b7163f0285d4c56427c7799", - "from": "git+https://github.com/ethereumjs/ethereumjs-abi.git#2863c40e0982acfc0b7163f0285d4c56427c7799", + "from": "git+https://github.com/ethereumjs/ethereumjs-abi.git", + "dev": true, "requires": { "bn.js": "^4.10.0", "ethereumjs-util": "^5.0.0" @@ -34713,6 +34723,7 @@ "version": "3.1.5", "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", + "dev": true, "requires": { "is-typedarray": "^1.0.0" } @@ -35757,6 +35768,7 @@ "resolved": "https://registry.npmjs.org/web3/-/web3-0.20.3.tgz", "integrity": "sha1-yqRDc9yIFayHZ73ba6cwc5ZMqos=", "requires": { + "bignumber.js": "git+https://github.com/frozeman/bignumber.js-nolookahead.git#57692b3ecfc98bbdd6b3a516cb2353652ea49934", "crypto-js": "^3.1.4", "utf8": "^2.1.1", "xhr2": "*", @@ -35765,7 +35777,7 @@ "dependencies": { "bignumber.js": { "version": "git+https://github.com/frozeman/bignumber.js-nolookahead.git#57692b3ecfc98bbdd6b3a516cb2353652ea49934", - "from": "git+https://github.com/frozeman/bignumber.js-nolookahead.git#57692b3ecfc98bbdd6b3a516cb2353652ea49934" + "from": "git+https://github.com/frozeman/bignumber.js-nolookahead.git" } } }, @@ -36163,7 +36175,8 @@ "dev": true, "requires": { "underscore": "1.8.3", - "web3-core-helpers": "1.0.0-beta.34" + "web3-core-helpers": "1.0.0-beta.34", + "websocket": "git://github.com/frozeman/WebSocket-Node.git#6c72925e3f8aaaea8dc8450f97627e85263999f2" }, "dependencies": { "underscore": { @@ -36174,7 +36187,8 @@ }, "websocket": { "version": "git://github.com/frozeman/WebSocket-Node.git#6c72925e3f8aaaea8dc8450f97627e85263999f2", - "from": "git://github.com/frozeman/WebSocket-Node.git#6c72925e3f8aaaea8dc8450f97627e85263999f2", + "from": "git://github.com/frozeman/WebSocket-Node.git#browserifyCompatible", + "dev": true, "requires": { "debug": "^2.2.0", "nan": "^2.3.3", @@ -37530,7 +37544,8 @@ "yaeti": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/yaeti/-/yaeti-0.0.6.tgz", - "integrity": "sha1-8m9ITXJoTPQr7ft2lwqhYI+/lXc=" + "integrity": "sha1-8m9ITXJoTPQr7ft2lwqhYI+/lXc=", + "dev": true }, "yallist": { "version": "2.1.2", diff --git a/package.json b/package.json index b814e01e9..6d5a36a8c 100644 --- a/package.json +++ b/package.json @@ -119,7 +119,7 @@ "eth-keychain-controller": "^5.0.0", "eth-ledger-bridge-keyring": "^0.1.0", "eth-method-registry": "^1.0.0", - "eth-net-props": "^1.0.7", + "eth-net-props": "^1.0.10", "eth-phishing-detect": "^1.1.4", "eth-query": "^2.1.2", "eth-sig-util": "^2.0.2", diff --git a/test/unit/app/buy-eth-url.spec.js b/test/unit/app/buy-eth-url.spec.js index dacc8b25d..79dfc50c6 100644 --- a/test/unit/app/buy-eth-url.spec.js +++ b/test/unit/app/buy-eth-url.spec.js @@ -1,23 +1,32 @@ const assert = require('assert') -const getBuyEthUrl = require('../../../app/scripts/lib/buy-eth-url') +const { getBuyEthUrl, getExchanges } = require('../../../app/scripts/lib/buy-eth-url') describe('', function () { const mainnet = { network: '1', amount: 5, address: '0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc', + ind: 0 } const sokol = { network: '77', + ind: 0 } const ropsten = { network: '3', + ind: 0 } const rinkeby = { network: '4', + ind: 0 } - const kovan = { + const kovan1 = { network: '42', + ind: 0 + } + const kovan2 = { + network: '42', + ind: 1 } it('returns coinbase url with amount and address for network 1', function () { @@ -44,13 +53,53 @@ describe('', function () { it('returns rinkeby dapp for network 4', function () { const rinkebyUrl = getBuyEthUrl(rinkeby) - assert.equal(rinkebyUrl, 'https://www.rinkeby.io/') + assert.equal(rinkebyUrl, 'https://faucet.rinkeby.io/') }) - it('returns kovan github test faucet for network 42', function () { - const kovanUrl = getBuyEthUrl(kovan) - assert.equal(kovanUrl, 'https://github.com/kovan-testnet/faucet') + it('returns kovan github test faucet 1 for network 42', function () { + const kovanUrl = getBuyEthUrl(kovan1) + assert.equal(kovanUrl, 'https://faucet.kovan.network/') }) -}) + it('returns kovan github test faucet 2 for network 42', function () { + const kovanUrl = getBuyEthUrl(kovan2) + assert.equal(kovanUrl, 'https://gitter.im/kovan-testnet/faucet/') + }) + it('returns exchanges for POA core network', function () { + const exchanges = getExchanges({network: 99}) + assert.deepEqual(exchanges, [ + { + name: 'Binance', + link: 'https://www.binance.com/en/trade/POA_ETH', + }, + { + name: 'BiBox', + link: 'https://www.bibox.com/exchange?coinPair=POA_ETH', + }, + { + name: 'CEX Plus', + link: 'http://cex.plus/market/poa_eth', + }, + ]) + }) + + it('returns xDai bridge link for xDai network', function () { + const exchanges = getExchanges({network: 100}) + assert.deepEqual(exchanges, [ + { + name: 'xDai TokenBridge', + link: 'https://dai-bridge.poa.network/', + }, + ]) + }) + + it('returns xDai Coinbase link for Mainnet', function () { + const exchanges = getExchanges({network: 1, amount: 1, address: '0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc'}) + assert.deepEqual(exchanges, [ + { + link: `https://buy.coinbase.com/?code=9ec56d01-7e81-5017-930c-513daa27bb6a&amount=1&address=0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc&crypto_currency=ETH`, + }, + ]) + }) +}) \ No newline at end of file diff --git a/ui/app/actions.js b/ui/app/actions.js index 01938f31f..c511404c2 100644 --- a/ui/app/actions.js +++ b/ui/app/actions.js @@ -1,6 +1,6 @@ const abi = require('human-standard-token-abi') const pify = require('pify') -const getBuyEthUrl = require('../../app/scripts/lib/buy-eth-url') +const { getBuyEthUrl } = require('../../app/scripts/lib/buy-eth-url') const { getTokenAddressFromTokenObject } = require('./util') const { calcGasTotal,