mirror of
https://github.com/status-im/MyCrypto.git
synced 2025-02-11 10:36:53 +00:00
commit
227abd5ff6
42
common/actions/swap.js
Normal file
42
common/actions/swap.js
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
import {
|
||||||
|
SWAP_DESTINATION_AMOUNT,
|
||||||
|
SWAP_DESTINATION_KIND,
|
||||||
|
SWAP_ORIGIN_AMOUNT,
|
||||||
|
SWAP_ORIGIN_KIND,
|
||||||
|
SWAP_UPDATE_BITY_RATES
|
||||||
|
} from './swapConstants';
|
||||||
|
|
||||||
|
export const SWAP_ORIGIN_KIND_TO = value => {
|
||||||
|
return {
|
||||||
|
type: SWAP_ORIGIN_KIND,
|
||||||
|
value
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export const SWAP_DESTINATION_KIND_TO = value => {
|
||||||
|
return {
|
||||||
|
type: SWAP_DESTINATION_KIND,
|
||||||
|
value
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export const SWAP_ORIGIN_AMOUNT_TO = value => {
|
||||||
|
return {
|
||||||
|
type: SWAP_ORIGIN_AMOUNT,
|
||||||
|
value
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export const SWAP_DESTINATION_AMOUNT_TO = value => {
|
||||||
|
return {
|
||||||
|
type: SWAP_DESTINATION_AMOUNT,
|
||||||
|
value
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export const SWAP_UPDATE_BITY_RATES_TO = value => {
|
||||||
|
return {
|
||||||
|
type: SWAP_UPDATE_BITY_RATES,
|
||||||
|
value
|
||||||
|
};
|
||||||
|
};
|
5
common/actions/swapConstants.js
Normal file
5
common/actions/swapConstants.js
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
export const SWAP_ORIGIN_KIND = 'SWAP_ORIGIN_KIND';
|
||||||
|
export const SWAP_DESTINATION_KIND = 'SWAP_DESTINATION_KIND';
|
||||||
|
export const SWAP_ORIGIN_AMOUNT = 'SWAP_ORIGIN_AMOUNT';
|
||||||
|
export const SWAP_DESTINATION_AMOUNT = 'SWAP_DESTINATION_AMOUNT';
|
||||||
|
export const SWAP_UPDATE_BITY_RATES = 'SWAP_UPDATE_BITY_RATES';
|
62
common/api/bity.js
Normal file
62
common/api/bity.js
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
import axios from 'axios';
|
||||||
|
import bityConfig from 'config/bity';
|
||||||
|
|
||||||
|
// https://stackoverflow.com/questions/9828684/how-to-get-all-arguments-of-a-callback-function
|
||||||
|
export function combineAndUpper() {
|
||||||
|
const args = [];
|
||||||
|
let newString = '';
|
||||||
|
for (let i = 0; i < arguments.length; ++i) args[i] = arguments[i];
|
||||||
|
args.forEach(each => {
|
||||||
|
newString = newString.concat(each.toUpperCase());
|
||||||
|
});
|
||||||
|
return newString;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default class Bity {
|
||||||
|
findRateFromBityRateList(rateObjects, pairName) {
|
||||||
|
return rateObjects.find(x => x.pair === pairName);
|
||||||
|
}
|
||||||
|
|
||||||
|
_getRate(bityRates, origin, destination) {
|
||||||
|
const pairName = combineAndUpper(origin, destination);
|
||||||
|
const rateObjects = bityRates.data.objects;
|
||||||
|
return this.findRateFromBityRateList(rateObjects, pairName);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gives you multiple rates from Bitys API without making multiple API calls
|
||||||
|
* @param arrayOfOriginAndDestinationDicts - [{origin: 'BTC', destination: 'ETH'}, {origin: 'BTC', destination: 'REP}]
|
||||||
|
*/
|
||||||
|
getMultipleRates(arrayOfOriginAndDestinationDicts) {
|
||||||
|
const mappedRates = {};
|
||||||
|
return this.requestAllRates().then(bityRates => {
|
||||||
|
arrayOfOriginAndDestinationDicts.forEach(each => {
|
||||||
|
const origin = each.origin;
|
||||||
|
const destination = each.destination;
|
||||||
|
const pairName = combineAndUpper(origin, destination);
|
||||||
|
const rate = this._getRate(bityRates, origin, destination);
|
||||||
|
mappedRates[pairName] = parseFloat(rate.rate_we_sell);
|
||||||
|
});
|
||||||
|
return mappedRates;
|
||||||
|
});
|
||||||
|
// TODO - catch errors
|
||||||
|
}
|
||||||
|
|
||||||
|
getAllRates() {
|
||||||
|
const mappedRates = {};
|
||||||
|
return this.requestAllRates().then(bityRates => {
|
||||||
|
bityRates.data.objects.forEach(each => {
|
||||||
|
const pairName = each.pair;
|
||||||
|
mappedRates[pairName] = parseFloat(each.rate_we_sell);
|
||||||
|
});
|
||||||
|
return mappedRates;
|
||||||
|
});
|
||||||
|
// TODO - catch errors
|
||||||
|
}
|
||||||
|
|
||||||
|
requestAllRates() {
|
||||||
|
const path = '/v1/rate2/';
|
||||||
|
const bityURL = bityConfig.bityAPI + path;
|
||||||
|
return axios.get(bityURL);
|
||||||
|
}
|
||||||
|
}
|
18
common/config/bity.js
Normal file
18
common/config/bity.js
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
export default {
|
||||||
|
SERVERURL: 'https://myetherapi.com',
|
||||||
|
bityAPI: 'https://bity.com/api',
|
||||||
|
decimals: 6,
|
||||||
|
ethExplorer: 'https://etherscan.io/tx/[[txHash]]',
|
||||||
|
btcExplorer: 'https://blockchain.info/tx/[[txHash]]',
|
||||||
|
validStatus: ['RCVE', 'FILL', 'CONF', 'EXEC'],
|
||||||
|
invalidStatus: ['CANC'],
|
||||||
|
mainPairs: ['REP', 'ETH'],
|
||||||
|
min: 0.01,
|
||||||
|
max: 3,
|
||||||
|
priceLoaded: false,
|
||||||
|
postConfig: {
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json; charse:UTF-8'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
@ -27,11 +27,6 @@ class App extends Component {
|
|||||||
nodeSelection: PropTypes.object
|
nodeSelection: PropTypes.object
|
||||||
};
|
};
|
||||||
|
|
||||||
componentWillMount() {
|
|
||||||
let { handleWindowResize } = this.props;
|
|
||||||
window.addEventListener('resize', handleWindowResize);
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
let {
|
let {
|
||||||
children,
|
children,
|
||||||
@ -46,7 +41,6 @@ class App extends Component {
|
|||||||
location,
|
location,
|
||||||
changeLanguage,
|
changeLanguage,
|
||||||
languageSelection,
|
languageSelection,
|
||||||
|
|
||||||
changeNode,
|
changeNode,
|
||||||
nodeSelection
|
nodeSelection
|
||||||
};
|
};
|
||||||
|
117
common/containers/Tabs/Swap/components/currentRates.js
Normal file
117
common/containers/Tabs/Swap/components/currentRates.js
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
import React, { Component } from 'react';
|
||||||
|
import translate from 'translations';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
|
||||||
|
export default class CurrentRates extends Component {
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
this.state = {
|
||||||
|
ETHBTCAmount: 1,
|
||||||
|
ETHREPAmount: 1,
|
||||||
|
BTCETHAmount: 1,
|
||||||
|
BTCREPAmount: 1
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
static propTypes = {
|
||||||
|
ETHBTC: PropTypes.number,
|
||||||
|
ETHREP: PropTypes.number,
|
||||||
|
BTCETH: PropTypes.number,
|
||||||
|
BTCREP: PropTypes.number
|
||||||
|
};
|
||||||
|
|
||||||
|
onChange = event => {
|
||||||
|
const target = event.target;
|
||||||
|
const value = target.value;
|
||||||
|
const name = target.name;
|
||||||
|
this.setState({
|
||||||
|
[name]: value
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// TODO - A little code duplication here, but simple enough to where it doesn't seem worth the time to fix.
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<article className="swap-rates">
|
||||||
|
<section className="row">
|
||||||
|
<h5 className="col-xs-6 col-xs-offset-3">
|
||||||
|
{translate('SWAP_rates')}
|
||||||
|
</h5>
|
||||||
|
</section>
|
||||||
|
<section className="row order-panel">
|
||||||
|
<div className="col-sm-6 order-info">
|
||||||
|
<p className="mono">
|
||||||
|
<input
|
||||||
|
className="form-control input-sm"
|
||||||
|
onChange={this.onChange}
|
||||||
|
value={this.state.ETHBTCAmount}
|
||||||
|
name="ETHBTCAmount"
|
||||||
|
/>
|
||||||
|
<span>
|
||||||
|
ETH = {(this.state.ETHBTCAmount * this.props.ETHBTC).toFixed(
|
||||||
|
6
|
||||||
|
)}{' '}
|
||||||
|
BTC
|
||||||
|
</span>
|
||||||
|
</p>
|
||||||
|
<p className="mono">
|
||||||
|
<input
|
||||||
|
className="form-control input-sm"
|
||||||
|
onChange={this.onChange}
|
||||||
|
value={this.state.ETHREPAmount}
|
||||||
|
name="ETHREPAmount"
|
||||||
|
/>
|
||||||
|
<span>
|
||||||
|
ETH = {(this.state.ETHREPAmount * this.props.ETHREP).toFixed(
|
||||||
|
6
|
||||||
|
)}{' '}
|
||||||
|
REP
|
||||||
|
</span>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div className="col-sm-6 order-info">
|
||||||
|
<p className="mono">
|
||||||
|
<input
|
||||||
|
className="form-control input-sm"
|
||||||
|
onChange={this.onChange}
|
||||||
|
value={this.state.BTCETHAmount}
|
||||||
|
name="BTCETHAmount"
|
||||||
|
/>
|
||||||
|
<span>
|
||||||
|
BTC = {(this.state.BTCETHAmount * this.props.BTCETH).toFixed(
|
||||||
|
6
|
||||||
|
)}{' '}
|
||||||
|
ETH
|
||||||
|
</span>
|
||||||
|
</p>
|
||||||
|
<p className="mono">
|
||||||
|
<input
|
||||||
|
className="form-control input-sm"
|
||||||
|
onChange={this.onChange}
|
||||||
|
value={this.state.BTCREPAmount}
|
||||||
|
name="BTCREPAmount"
|
||||||
|
/>
|
||||||
|
<span>
|
||||||
|
BTC = {(this.state.BTCREPAmount * this.props.BTCREP).toFixed(
|
||||||
|
6
|
||||||
|
)}{' '}
|
||||||
|
REP
|
||||||
|
</span>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<a
|
||||||
|
className="link bity-logo"
|
||||||
|
href="https://bity.com/af/jshkb37v"
|
||||||
|
target="_blank"
|
||||||
|
>
|
||||||
|
<img
|
||||||
|
src={'https://www.myetherwallet.com/images/logo-bity-white.svg'}
|
||||||
|
width={120}
|
||||||
|
height={49}
|
||||||
|
/>
|
||||||
|
</a>
|
||||||
|
</section>
|
||||||
|
</article>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
153
common/containers/Tabs/Swap/components/wantToSwapMy.js
Normal file
153
common/containers/Tabs/Swap/components/wantToSwapMy.js
Normal file
@ -0,0 +1,153 @@
|
|||||||
|
import React, { Component } from 'react';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import translate from 'translations';
|
||||||
|
import { combineAndUpper } from 'api/bity';
|
||||||
|
|
||||||
|
class CoinTypeDropDown extends Component {
|
||||||
|
constructor(props, context) {
|
||||||
|
super(props, context);
|
||||||
|
}
|
||||||
|
|
||||||
|
static propTypes = {
|
||||||
|
kind: PropTypes.any,
|
||||||
|
onChange: PropTypes.any,
|
||||||
|
kindOptions: PropTypes.any
|
||||||
|
};
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<span className="dropdown">
|
||||||
|
<select
|
||||||
|
value={this.props.kind}
|
||||||
|
className="btn btn-default"
|
||||||
|
onChange={this.props.onChange.bind(this)}
|
||||||
|
>
|
||||||
|
{this.props.kindOptions.map((obj, i) => {
|
||||||
|
return <option value={obj} key={i}>{obj}</option>;
|
||||||
|
})}
|
||||||
|
</select>
|
||||||
|
</span>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default class WantToSwapMy extends Component {
|
||||||
|
constructor(props, context) {
|
||||||
|
super(props, context);
|
||||||
|
}
|
||||||
|
|
||||||
|
static propTypes = {
|
||||||
|
bityRates: PropTypes.any,
|
||||||
|
originAmount: PropTypes.any,
|
||||||
|
destinationAmount: PropTypes.any,
|
||||||
|
originKind: PropTypes.string,
|
||||||
|
destinationKind: PropTypes.string,
|
||||||
|
destinationKindOptions: PropTypes.array,
|
||||||
|
originKindOptions: PropTypes.array,
|
||||||
|
SWAP_ORIGIN_KIND_TO: PropTypes.func,
|
||||||
|
SWAP_DESTINATION_KIND_TO: PropTypes.func,
|
||||||
|
SWAP_ORIGIN_AMOUNT_TO: PropTypes.func,
|
||||||
|
SWAP_DESTINATION_AMOUNT_TO: PropTypes.func
|
||||||
|
};
|
||||||
|
|
||||||
|
onClickStartSwap() {}
|
||||||
|
|
||||||
|
onChangeOriginAmount = amount => {
|
||||||
|
let originAmountAsNumber = parseFloat(amount);
|
||||||
|
if (originAmountAsNumber) {
|
||||||
|
let pairName = combineAndUpper(
|
||||||
|
this.props.originKind,
|
||||||
|
this.props.destinationKind
|
||||||
|
);
|
||||||
|
let bityRate = this.props.bityRates[pairName];
|
||||||
|
this.props.SWAP_ORIGIN_AMOUNT_TO(originAmountAsNumber);
|
||||||
|
this.props.SWAP_DESTINATION_AMOUNT_TO(originAmountAsNumber * bityRate);
|
||||||
|
} else {
|
||||||
|
this.props.SWAP_ORIGIN_AMOUNT_TO('');
|
||||||
|
this.props.SWAP_DESTINATION_AMOUNT_TO('');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
onChangeDestinationAmount(amount) {
|
||||||
|
let destinationAmountAsNumber = parseFloat(amount);
|
||||||
|
if (destinationAmountAsNumber) {
|
||||||
|
this.props.SWAP_DESTINATION_AMOUNT_TO(destinationAmountAsNumber);
|
||||||
|
let pairName = combineAndUpper(
|
||||||
|
this.props.destinationKind,
|
||||||
|
this.props.originKind
|
||||||
|
);
|
||||||
|
let bityRate = this.props.bityRates[pairName];
|
||||||
|
this.props.SWAP_ORIGIN_AMOUNT_TO(destinationAmountAsNumber * bityRate);
|
||||||
|
} else {
|
||||||
|
this.props.SWAP_ORIGIN_AMOUNT_TO('');
|
||||||
|
this.props.SWAP_DESTINATION_AMOUNT_TO('');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async onChangeDestinationKind(event) {
|
||||||
|
let newDestinationKind = event.target.value;
|
||||||
|
this.props.SWAP_DESTINATION_KIND_TO(newDestinationKind);
|
||||||
|
}
|
||||||
|
|
||||||
|
async onChangeOriginKind(event) {
|
||||||
|
let newOriginKind = event.target.value;
|
||||||
|
this.props.SWAP_ORIGIN_KIND_TO(newOriginKind);
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const {
|
||||||
|
originAmount,
|
||||||
|
destinationAmount,
|
||||||
|
originKind,
|
||||||
|
destinationKind,
|
||||||
|
destinationKindOptions,
|
||||||
|
originKindOptions
|
||||||
|
} = this.props;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<article className="swap-panel">
|
||||||
|
<h1>{translate('SWAP_init_1')}</h1>
|
||||||
|
<input
|
||||||
|
className={`form-control ${this.props.originAmount !== '' &&
|
||||||
|
this.props.originAmount > 0
|
||||||
|
? 'is-valid'
|
||||||
|
: 'is-invalid'}`}
|
||||||
|
type="number"
|
||||||
|
placeholder="Amount"
|
||||||
|
onChange={e => this.onChangeOriginAmount(e.target.value)}
|
||||||
|
value={originAmount}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<CoinTypeDropDown
|
||||||
|
kind={originKind}
|
||||||
|
onChange={this.onChangeOriginKind.bind(this)}
|
||||||
|
kindOptions={originKindOptions}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<h1>{translate('SWAP_init_2')}</h1>
|
||||||
|
|
||||||
|
<input
|
||||||
|
className={`form-control ${this.props.destinationAmount !== '' &&
|
||||||
|
this.props.destinationAmount > 0
|
||||||
|
? 'is-valid'
|
||||||
|
: 'is-invalid'}`}
|
||||||
|
type="number"
|
||||||
|
placeholder="Amount"
|
||||||
|
value={destinationAmount}
|
||||||
|
onChange={e => this.onChangeDestinationAmount(e.target.value)}
|
||||||
|
/>
|
||||||
|
<CoinTypeDropDown
|
||||||
|
kind={destinationKind}
|
||||||
|
onChange={this.onChangeDestinationKind.bind(this)}
|
||||||
|
kindOptions={destinationKindOptions}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<div className="col-xs-12 clearfix text-center">
|
||||||
|
<a onClick={this.onClickStartSwap} className="btn btn-info btn-lg">
|
||||||
|
<span>{translate('SWAP_init_CTA')}</span>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</article>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
100
common/containers/Tabs/Swap/index.js
Normal file
100
common/containers/Tabs/Swap/index.js
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
import React, { Component } from 'react';
|
||||||
|
import WantToSwapMy from './components/wantToSwapMy';
|
||||||
|
import CurrentRates from './components/currentRates';
|
||||||
|
import { connect } from 'react-redux';
|
||||||
|
import * as swapActions from 'actions/swap';
|
||||||
|
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import Bity from 'api/bity';
|
||||||
|
|
||||||
|
class Swap extends Component {
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
this.bity = new Bity();
|
||||||
|
}
|
||||||
|
|
||||||
|
static propTypes = {
|
||||||
|
bityRates: PropTypes.any,
|
||||||
|
originAmount: PropTypes.any,
|
||||||
|
destinationAmount: PropTypes.any,
|
||||||
|
originKind: PropTypes.string,
|
||||||
|
destinationKind: PropTypes.string,
|
||||||
|
destinationKindOptions: PropTypes.array,
|
||||||
|
originKindOptions: PropTypes.array,
|
||||||
|
SWAP_ORIGIN_KIND_TO: PropTypes.func,
|
||||||
|
SWAP_DESTINATION_KIND_TO: PropTypes.func,
|
||||||
|
SWAP_ORIGIN_AMOUNT_TO: PropTypes.func,
|
||||||
|
SWAP_DESTINATION_AMOUNT_TO: PropTypes.func,
|
||||||
|
SWAP_UPDATE_BITY_RATES_TO: PropTypes.func
|
||||||
|
};
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
let { bityRates } = this.props;
|
||||||
|
|
||||||
|
if (
|
||||||
|
!bityRates.ETHBTC ||
|
||||||
|
!bityRates.ETHREP ||
|
||||||
|
!bityRates.BTCETH ||
|
||||||
|
!bityRates.BTCREP
|
||||||
|
) {
|
||||||
|
this.bity.getAllRates().then(data => {
|
||||||
|
this.props.SWAP_UPDATE_BITY_RATES_TO(data);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
let {
|
||||||
|
bityRates,
|
||||||
|
originAmount,
|
||||||
|
destinationAmount,
|
||||||
|
originKind,
|
||||||
|
destinationKind,
|
||||||
|
destinationKindOptions,
|
||||||
|
originKindOptions,
|
||||||
|
SWAP_ORIGIN_KIND_TO,
|
||||||
|
SWAP_DESTINATION_KIND_TO,
|
||||||
|
SWAP_ORIGIN_AMOUNT_TO,
|
||||||
|
SWAP_DESTINATION_AMOUNT_TO
|
||||||
|
} = this.props;
|
||||||
|
|
||||||
|
let wantToSwapMyProps = {
|
||||||
|
bityRates,
|
||||||
|
originAmount,
|
||||||
|
destinationAmount,
|
||||||
|
originKind,
|
||||||
|
destinationKind,
|
||||||
|
destinationKindOptions,
|
||||||
|
originKindOptions,
|
||||||
|
SWAP_ORIGIN_KIND_TO,
|
||||||
|
SWAP_DESTINATION_KIND_TO,
|
||||||
|
SWAP_ORIGIN_AMOUNT_TO,
|
||||||
|
SWAP_DESTINATION_AMOUNT_TO
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<section className="container" style={{ minHeight: '50%' }}>
|
||||||
|
<div className="tab-content">
|
||||||
|
<main className="tab-pane swap-tab">
|
||||||
|
<CurrentRates {...bityRates} />
|
||||||
|
<WantToSwapMy {...wantToSwapMyProps} />
|
||||||
|
</main>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function mapStateToProps(state) {
|
||||||
|
return {
|
||||||
|
originAmount: state.swap.originAmount,
|
||||||
|
destinationAmount: state.swap.destinationAmount,
|
||||||
|
originKind: state.swap.originKind,
|
||||||
|
destinationKind: state.swap.destinationKind,
|
||||||
|
destinationKindOptions: state.swap.destinationKindOptions,
|
||||||
|
originKindOptions: state.swap.originKindOptions,
|
||||||
|
bityRates: state.swap.bityRates
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export default connect(mapStateToProps, swapActions)(Swap);
|
@ -1,5 +1,7 @@
|
|||||||
import * as generateWallet from './generateWallet'
|
import * as generateWallet from './generateWallet'
|
||||||
import * as config from './config'
|
import * as config from './config'
|
||||||
|
import * as swap from './swap'
|
||||||
|
|
||||||
import { reducer as formReducer } from 'redux-form'
|
import { reducer as formReducer } from 'redux-form'
|
||||||
import {combineReducers} from 'redux';
|
import {combineReducers} from 'redux';
|
||||||
import {routerReducer} from 'react-router-redux'
|
import {routerReducer} from 'react-router-redux'
|
||||||
@ -7,6 +9,7 @@ import {routerReducer} from 'react-router-redux'
|
|||||||
export default combineReducers({
|
export default combineReducers({
|
||||||
...generateWallet,
|
...generateWallet,
|
||||||
...config,
|
...config,
|
||||||
|
...swap,
|
||||||
form: formReducer,
|
form: formReducer,
|
||||||
routing: routerReducer
|
routing: routerReducer
|
||||||
})
|
})
|
||||||
|
100
common/reducers/swap.js
Normal file
100
common/reducers/swap.js
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
import {
|
||||||
|
SWAP_DESTINATION_AMOUNT,
|
||||||
|
SWAP_DESTINATION_KIND,
|
||||||
|
SWAP_ORIGIN_AMOUNT,
|
||||||
|
SWAP_ORIGIN_KIND,
|
||||||
|
SWAP_UPDATE_BITY_RATES
|
||||||
|
} from 'actions/swapConstants';
|
||||||
|
import { combineAndUpper } from 'api/bity';
|
||||||
|
|
||||||
|
export const ALL_CRYPTO_KIND_OPTIONS = ['BTC', 'ETH', 'REP'];
|
||||||
|
|
||||||
|
const initialState = {
|
||||||
|
originAmount: 0,
|
||||||
|
destinationAmount: 0,
|
||||||
|
originKind: 'BTC',
|
||||||
|
destinationKind: 'ETH',
|
||||||
|
destinationKindOptions: ALL_CRYPTO_KIND_OPTIONS.filter(
|
||||||
|
element => element !== 'BTC'
|
||||||
|
),
|
||||||
|
originKindOptions: ALL_CRYPTO_KIND_OPTIONS.filter(
|
||||||
|
element => element !== 'REP'
|
||||||
|
),
|
||||||
|
bityRates: {}
|
||||||
|
};
|
||||||
|
|
||||||
|
const buildDestinationAmount = (
|
||||||
|
originAmount,
|
||||||
|
originKind,
|
||||||
|
destinationKind,
|
||||||
|
bityRates
|
||||||
|
) => {
|
||||||
|
let pairName = combineAndUpper(originKind, destinationKind);
|
||||||
|
let bityRate = bityRates[pairName];
|
||||||
|
return originAmount * bityRate;
|
||||||
|
};
|
||||||
|
|
||||||
|
const buildDestinationKind = (originKind, destinationKind) => {
|
||||||
|
if (originKind === destinationKind) {
|
||||||
|
return ALL_CRYPTO_KIND_OPTIONS.filter(element => element !== originKind)[0];
|
||||||
|
} else {
|
||||||
|
return destinationKind;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export function swap(state = initialState, action) {
|
||||||
|
switch (action.type) {
|
||||||
|
case SWAP_ORIGIN_KIND: {
|
||||||
|
const newDestinationKind = buildDestinationKind(
|
||||||
|
action.value,
|
||||||
|
state.destinationKind
|
||||||
|
);
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
originKind: action.value,
|
||||||
|
destinationKind: newDestinationKind,
|
||||||
|
destinationKindOptions: ALL_CRYPTO_KIND_OPTIONS.filter(
|
||||||
|
element => element !== action.value
|
||||||
|
),
|
||||||
|
destinationAmount: buildDestinationAmount(
|
||||||
|
state.originAmount,
|
||||||
|
action.value,
|
||||||
|
newDestinationKind,
|
||||||
|
state.bityRates
|
||||||
|
)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
case SWAP_DESTINATION_KIND: {
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
destinationKind: action.value,
|
||||||
|
destinationAmount: buildDestinationAmount(
|
||||||
|
state.originAmount,
|
||||||
|
state.originKind,
|
||||||
|
action.value,
|
||||||
|
state.bityRates
|
||||||
|
)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
case SWAP_ORIGIN_AMOUNT:
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
originAmount: action.value
|
||||||
|
};
|
||||||
|
case SWAP_DESTINATION_AMOUNT:
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
destinationAmount: action.value
|
||||||
|
};
|
||||||
|
case SWAP_UPDATE_BITY_RATES:
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
bityRates: {
|
||||||
|
...state.bityRates,
|
||||||
|
...action.value
|
||||||
|
}
|
||||||
|
};
|
||||||
|
default:
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
}
|
@ -5,6 +5,7 @@ import {App} from 'containers';
|
|||||||
import GenerateWallet from 'containers/Tabs/GenerateWallet'
|
import GenerateWallet from 'containers/Tabs/GenerateWallet'
|
||||||
import ViewWallet from 'containers/Tabs/ViewWallet'
|
import ViewWallet from 'containers/Tabs/ViewWallet'
|
||||||
import Help from 'containers/Tabs/Help'
|
import Help from 'containers/Tabs/Help'
|
||||||
|
import Swap from 'containers/Tabs/Swap'
|
||||||
|
|
||||||
export const history = getHistory()
|
export const history = getHistory()
|
||||||
|
|
||||||
@ -13,6 +14,7 @@ export const Routing = () => (
|
|||||||
<Route name="GenerateWallet" path="/" component={GenerateWallet}/>
|
<Route name="GenerateWallet" path="/" component={GenerateWallet}/>
|
||||||
<Route name="ViewWallet" path="/view-wallet" component={ViewWallet}/>
|
<Route name="ViewWallet" path="/view-wallet" component={ViewWallet}/>
|
||||||
<Route name="Help" path="/help" component={Help}/>
|
<Route name="Help" path="/help" component={Help}/>
|
||||||
|
<Route name="Swap" path="/swap" component={Swap}/>
|
||||||
|
|
||||||
<Redirect from="/*" to="/"/>
|
<Redirect from="/*" to="/"/>
|
||||||
</Route>
|
</Route>
|
||||||
|
@ -4,6 +4,8 @@
|
|||||||
"main": "common/index.jsx",
|
"main": "common/index.jsx",
|
||||||
"description": "MyEtherWallet v4",
|
"description": "MyEtherWallet v4",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"axios": "^0.16.2",
|
||||||
|
"lodash": "^4.17.4",
|
||||||
"prop-types": "^15.5.8",
|
"prop-types": "^15.5.8",
|
||||||
"react": "^15.4.2",
|
"react": "^15.4.2",
|
||||||
"react-dom": "^15.4.2",
|
"react-dom": "^15.4.2",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user