aboutsummaryrefslogtreecommitdiffstats
path: root/mascara/src/app/shapeshift-form/index.js
diff options
context:
space:
mode:
authorChi Kei Chan <chikeichan@gmail.com>2017-09-26 05:51:49 +0800
committerChi Kei Chan <chikeichan@gmail.com>2017-10-21 12:51:37 +0800
commit5cbbb476b3eb7a5fd70b014b2a1a83fea7092b58 (patch)
tree17e4223f56f3a73944b60be5ec28e8bc98c8eefd /mascara/src/app/shapeshift-form/index.js
parent5aaa2d679b00a7a78338b9b72fa72397ad945b35 (diff)
downloadtangerine-wallet-browser-5cbbb476b3eb7a5fd70b014b2a1a83fea7092b58.tar
tangerine-wallet-browser-5cbbb476b3eb7a5fd70b014b2a1a83fea7092b58.tar.gz
tangerine-wallet-browser-5cbbb476b3eb7a5fd70b014b2a1a83fea7092b58.tar.bz2
tangerine-wallet-browser-5cbbb476b3eb7a5fd70b014b2a1a83fea7092b58.tar.lz
tangerine-wallet-browser-5cbbb476b3eb7a5fd70b014b2a1a83fea7092b58.tar.xz
tangerine-wallet-browser-5cbbb476b3eb7a5fd70b014b2a1a83fea7092b58.tar.zst
tangerine-wallet-browser-5cbbb476b3eb7a5fd70b014b2a1a83fea7092b58.zip
ShapeShift Integration
Diffstat (limited to 'mascara/src/app/shapeshift-form/index.js')
-rw-r--r--mascara/src/app/shapeshift-form/index.js217
1 files changed, 217 insertions, 0 deletions
diff --git a/mascara/src/app/shapeshift-form/index.js b/mascara/src/app/shapeshift-form/index.js
new file mode 100644
index 000000000..15c7e95e1
--- /dev/null
+++ b/mascara/src/app/shapeshift-form/index.js
@@ -0,0 +1,217 @@
+import React, {Component, PropTypes} from 'react'
+import classnames from 'classnames'
+import {qrcode} from 'qrcode-npm'
+import {connect} from 'react-redux'
+import {shapeShiftSubview, pairUpdate, buyWithShapeShift} from '../../../../ui/app/actions'
+import {isValidAddress} from '../../../../ui/app/util'
+
+export class ShapeShiftForm extends Component {
+ static propTypes = {
+ selectedAddress: PropTypes.string.isRequired,
+ btnClass: PropTypes.string.isRequired,
+ tokenExchangeRates: PropTypes.object.isRequired,
+ coinOptions: PropTypes.object.isRequired,
+ shapeShiftSubview: PropTypes.func.isRequired,
+ pairUpdate: PropTypes.func.isRequired,
+ buyWithShapeShift: PropTypes.func.isRequired,
+ };
+
+ state = {
+ depositCoin: 'btc',
+ refundAddress: '',
+ showQrCode: false,
+ depositAddress: '',
+ errorMessage: '',
+ isLoading: false,
+ };
+
+ componentWillMount () {
+ this.props.shapeShiftSubview()
+ }
+
+ onCoinChange = e => {
+ const coin = e.target.value
+ this.setState({
+ depositCoin: coin,
+ errorMessage: '',
+ })
+ this.props.pairUpdate(coin)
+ }
+
+ onBuyWithShapeShift = () => {
+ 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,
+ }))
+ }
+ }
+
+ renderMetadata (label, value) {
+ return (
+ <div className='shapeshift-form__metadata-wrapper'>
+ <div className='shapeshift-form__metadata-label'>
+ {label}:
+ </div>
+ <div className='shapeshift-form__metadata-value'>
+ {value}
+ </div>
+ </div>
+ )
+ }
+
+ renderMarketInfo () {
+ const { depositCoin } = this.state
+ const coinPair = `${depositCoin}_eth`
+ const { tokenExchangeRates } = this.props
+ const {
+ limit,
+ rate,
+ minimum,
+ } = tokenExchangeRates[coinPair] || {}
+
+ return (
+ <div className='shapeshift-form__metadata'>
+ {this.renderMetadata('Status', limit ? 'Available' : 'Unavailable')}
+ {this.renderMetadata('Limit', limit)}
+ {this.renderMetadata('Exchange Rate', rate)}
+ {this.renderMetadata('Minimum', minimum)}
+ </div>
+ )
+ }
+
+ renderQrCode () {
+ const { depositAddress, isLoading } = this.state
+ const qrImage = qrcode(4, 'M')
+ qrImage.addData(depositAddress)
+ qrImage.make()
+
+ return (
+ <div className='shapeshift-form'>
+ <div className='shapeshift-form__deposit-instruction'>
+ Deposit your BTC to the address bellow:
+ </div>
+ <div className='shapeshift-form__qr-code'>
+ {isLoading
+ ? <img src='images/loading.svg' style={{ width: '60px' }} />
+ : <div dangerouslySetInnerHTML={{ __html: qrImage.createTableTag(4) }} />
+ }
+ </div>
+ {this.renderMarketInfo()}
+ </div>
+ )
+ }
+
+ render () {
+ const { coinOptions, btnClass } = this.props
+ const { depositCoin, errorMessage, showQrCode } = this.state
+ const coinPair = `${depositCoin}_eth`
+ const { tokenExchangeRates } = this.props
+ const token = tokenExchangeRates[coinPair]
+
+ return showQrCode ? this.renderQrCode() : (
+ <div>
+ <div className='shapeshift-form'>
+ <div className='shapeshift-form__selectors'>
+ <div className='shapeshift-form__selector'>
+ <div className='shapeshift-form__selector-label'>
+ Deposit
+ </div>
+ <select
+ className='shapeshift-form__selector-input'
+ value={this.state.depositCoin}
+ onChange={this.onCoinChange}
+ >
+ {Object.entries(coinOptions).map(([coin]) => (
+ <option key={coin} value={coin.toLowerCase()}>
+ {coin}
+ </option>
+ ))}
+ </select>
+ </div>
+ <div
+ className='icon shapeshift-form__caret'
+ style={{ backgroundImage: 'url(images/caret-right.svg)'}}
+ />
+ <div className='shapeshift-form__selector'>
+ <div className='shapeshift-form__selector-label'>
+ Receive
+ </div>
+ <div className='shapeshift-form__selector-input'>
+ ETH
+ </div>
+ </div>
+ </div>
+ <div
+ className={classnames('shapeshift-form__address-input-wrapper', {
+ 'shapeshift-form__address-input-wrapper--error': errorMessage,
+ })}
+ >
+ <div className='shapeshift-form__address-input-label'>
+ Your Refund Address
+ </div>
+ <input
+ type='text'
+ className='shapeshift-form__address-input'
+ onChange={e => this.setState({
+ refundAddress: e.target.value,
+ errorMessage: '',
+ })}
+ />
+ <div className='shapeshift-form__address-input-error-message'>
+ {errorMessage}
+ </div>
+ </div>
+ {this.renderMarketInfo()}
+ </div>
+ <button
+ className={btnClass}
+ disabled={!token}
+ onClick={this.onBuyWithShapeShift}
+ >
+ Buy
+ </button>
+ </div>
+ )
+ }
+}
+
+export default connect(
+ ({ metamask: { coinOptions, tokenExchangeRates, selectedAddress } }) => ({
+ coinOptions, tokenExchangeRates, selectedAddress,
+ }),
+ dispatch => ({
+ shapeShiftSubview: () => dispatch(shapeShiftSubview()),
+ pairUpdate: coin => dispatch(pairUpdate(coin)),
+ buyWithShapeShift: data => dispatch(buyWithShapeShift(data)),
+ })
+)(ShapeShiftForm)