A Metamask fork with Infura removed and default networks editable
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
ciphermask/ui/app/components/shapeshift-form.js

246 lines
6.3 KiB

const h = require('react-hyperscript')
const inherits = require('util').inherits
const Component = require('react').Component
const connect = require('react-redux').connect
const classnames = require('classnames')
const { qrcode } = require('qrcode-npm')
const { shapeShiftSubview, pairUpdate, buyWithShapeShift } = require('../actions')
const { isValidAddress } = require('../util')
const SimpleDropdown = require('./dropdowns/simple-dropdown')
function mapStateToProps (state) {
const {
coinOptions,
tokenExchangeRates,
selectedAddress,
} = state.metamask
const { warning } = state.appState
return {
coinOptions,
tokenExchangeRates,
selectedAddress,
warning,
}
}
function mapDispatchToProps (dispatch) {
return {
shapeShiftSubview: () => dispatch(shapeShiftSubview()),
pairUpdate: coin => dispatch(pairUpdate(coin)),
buyWithShapeShift: data => dispatch(buyWithShapeShift(data)),
}
}
module.exports = connect(mapStateToProps, mapDispatchToProps)(ShapeshiftForm)
inherits(ShapeshiftForm, Component)
function ShapeshiftForm () {
Component.call(this)
this.state = {
depositCoin: 'btc',
refundAddress: '',
showQrCode: false,
depositAddress: '',
errorMessage: '',
isLoading: false,
bought: false,
}
}
ShapeshiftForm.prototype.componentWillMount = function () {
this.props.shapeShiftSubview()
}
ShapeshiftForm.prototype.onCoinChange = function (coin) {
this.setState({
depositCoin: coin,
errorMessage: '',
})
this.props.pairUpdate(coin)
}
ShapeshiftForm.prototype.onBuyWithShapeShift = function () {
this.setState({
isLoading: true,
showQrCode: true,
})
const {
buyWithShapeShift,
selectedAddress: withdrawal,
} = this.props
const {
refundAddress: returnAddress,
depositCoin,
} = this.state
const pair = `${depositCoin}_eth`
const data = {
withdrawal,
pair,
returnAddress,
// Public api key
'apiKey': '803d1f5df2ed1b1476e4b9e6bcd089e34d8874595dda6a23b67d93c56ea9cc2445e98a6748b219b2b6ad654d9f075f1f1db139abfa93158c04e825db122c14b6',
}
if (isValidAddress(withdrawal)) {
buyWithShapeShift(data)
.then(d => this.setState({
showQrCode: true,
depositAddress: d.deposit,
isLoading: false,
}))
.catch(() => this.setState({
showQrCode: false,
errorMessage: 'Invalid Request',
isLoading: false,
}))
}
}
ShapeshiftForm.prototype.renderMetadata = function (label, value) {
return h('div', {className: 'shapeshift-form__metadata-wrapper'}, [
h('div.shapeshift-form__metadata-label', {}, [
h('span', `${label}:`),
]),
h('div.shapeshift-form__metadata-value', {}, [
h('span', value),
]),
])
}
ShapeshiftForm.prototype.renderMarketInfo = function () {
const { depositCoin } = this.state
const coinPair = `${depositCoin}_eth`
const { tokenExchangeRates } = this.props
const {
limit,
rate,
minimum,
} = tokenExchangeRates[coinPair] || {}
return h('div.shapeshift-form__metadata', {}, [
this.renderMetadata('Status', limit ? 'Available' : 'Unavailable'),
this.renderMetadata('Limit', limit),
this.renderMetadata('Exchange Rate', rate),
this.renderMetadata('Minimum', minimum),
])
}
ShapeshiftForm.prototype.renderQrCode = function () {
const { depositAddress, isLoading, depositCoin } = this.state
const qrImage = qrcode(4, 'M')
qrImage.addData(depositAddress)
qrImage.make()
return h('div.shapeshift-form', {}, [
h('div.shapeshift-form__deposit-instruction', [
`Deposit your ${depositCoin.toUpperCase()} to the address below:`,
]),
h('div', depositAddress),
h('div.shapeshift-form__qr-code', [
isLoading
? h('img', {
src: 'images/loading.svg',
style: { width: '60px'},
})
: h('div', {
dangerouslySetInnerHTML: { __html: qrImage.createTableTag(4) },
}),
]),
this.renderMarketInfo(),
])
}
ShapeshiftForm.prototype.render = function () {
const { coinOptions, btnClass, warning } = this.props
const { depositCoin, errorMessage, showQrCode, depositAddress } = this.state
const coinPair = `${depositCoin}_eth`
const { tokenExchangeRates } = this.props
const token = tokenExchangeRates[coinPair]
return h('div.shapeshift-form-wrapper', [
showQrCode
? this.renderQrCode()
: h('div.shapeshift-form', [
h('div.shapeshift-form__selectors', [
h('div.shapeshift-form__selector', [
h('div.shapeshift-form__selector-label', 'Deposit'),
h(SimpleDropdown, {
selectedOption: this.state.depositCoin,
onSelect: (coin) => this.onCoinChange(coin),
options: Object.entries(coinOptions).map(([coin]) => ({
value: coin.toLowerCase(),
displayValue: coin,
})),
}),
]),
h('div.icon.shapeshift-form__caret', {
style: { backgroundImage: 'url(images/caret-right.svg)'},
}),
h('div.shapeshift-form__selector', [
h('div.shapeshift-form__selector-label', [
'Receive',
]),
h('div.shapeshift-form__selector-input', ['ETH']),
]),
]),
warning && h('div.shapeshift-form__address-input-label', warning),
!warning && h('div', {
className: classnames('shapeshift-form__address-input-wrapper', {
'shapeshift-form__address-input-wrapper--error': errorMessage,
}),
}, [
h('div.shapeshift-form__address-input-label', [
'Your Refund Address',
]),
h('input.shapeshift-form__address-input', {
type: 'text',
onChange: e => this.setState({
refundAddress: e.target.value,
errorMessage: '',
}),
}),
h('divshapeshift-form__address-input-error-message', [errorMessage]),
]),
!warning && this.renderMarketInfo(),
]),
!depositAddress && h('button.shapeshift-form__shapeshift-buy-btn', {
className: btnClass,
disabled: !token,
onClick: () => this.onBuyWithShapeShift(),
}, ['Buy']),
])
}