mirror of
https://github.com/status-im/MyCrypto.git
synced 2025-01-11 03:26:14 +00:00
merge develop
This commit is contained in:
commit
240007fe43
@ -3,7 +3,9 @@ import {
|
|||||||
SWAP_DESTINATION_KIND,
|
SWAP_DESTINATION_KIND,
|
||||||
SWAP_ORIGIN_AMOUNT,
|
SWAP_ORIGIN_AMOUNT,
|
||||||
SWAP_ORIGIN_KIND,
|
SWAP_ORIGIN_KIND,
|
||||||
SWAP_UPDATE_BITY_RATES
|
SWAP_UPDATE_BITY_RATES,
|
||||||
|
SWAP_PART_ONE_COMPLETE,
|
||||||
|
SWAP_RECEIVING_ADDRESS
|
||||||
} from './swapConstants';
|
} from './swapConstants';
|
||||||
|
|
||||||
export const originKindSwap = value => {
|
export const originKindSwap = value => {
|
||||||
@ -40,3 +42,17 @@ export const updateBityRatesSwap = value => {
|
|||||||
value
|
value
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const partOneCompleteSwap = (value: boolean) => {
|
||||||
|
return {
|
||||||
|
type: SWAP_PART_ONE_COMPLETE,
|
||||||
|
value
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export const receivingAddressSwap = value => {
|
||||||
|
return {
|
||||||
|
type: SWAP_RECEIVING_ADDRESS,
|
||||||
|
value
|
||||||
|
};
|
||||||
|
};
|
||||||
|
@ -3,3 +3,5 @@ export const SWAP_DESTINATION_KIND = 'SWAP_DESTINATION_KIND';
|
|||||||
export const SWAP_ORIGIN_AMOUNT = 'SWAP_ORIGIN_AMOUNT';
|
export const SWAP_ORIGIN_AMOUNT = 'SWAP_ORIGIN_AMOUNT';
|
||||||
export const SWAP_DESTINATION_AMOUNT = 'SWAP_DESTINATION_AMOUNT';
|
export const SWAP_DESTINATION_AMOUNT = 'SWAP_DESTINATION_AMOUNT';
|
||||||
export const SWAP_UPDATE_BITY_RATES = 'SWAP_UPDATE_BITY_RATES';
|
export const SWAP_UPDATE_BITY_RATES = 'SWAP_UPDATE_BITY_RATES';
|
||||||
|
export const SWAP_PART_ONE_COMPLETE = 'SWAP_PART_ONE_COMPLETE';
|
||||||
|
export const SWAP_RECEIVING_ADDRESS = 'SWAP_RECEIVING_ADDRESS';
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
import translate, { getTranslators } from 'translations';
|
import translate, { getTranslators } from 'translations';
|
||||||
|
import { DONATION_ADDRESSES_MAP } from 'config/data';
|
||||||
|
|
||||||
export default class Footer extends Component {
|
export default class Footer extends Component {
|
||||||
render() {
|
render() {
|
||||||
const translators = getTranslators()
|
const translators = getTranslators();
|
||||||
return (
|
return (
|
||||||
<footer role="contentinfo" aria-label="footer">
|
<footer role="contentinfo" aria-label="footer">
|
||||||
<div className="container">
|
<div className="container">
|
||||||
@ -14,87 +14,189 @@ export default class Footer extends Component {
|
|||||||
<p aria-hidden="true">
|
<p aria-hidden="true">
|
||||||
<a href="/">
|
<a href="/">
|
||||||
{/* TODO - don't hardcode image path*/}
|
{/* TODO - don't hardcode image path*/}
|
||||||
<img src={'https://www.myetherwallet.com/images/logo-myetherwallet.svg'}
|
<img
|
||||||
height="55px" width="auto" alt="Ether Wallet"/>
|
src={
|
||||||
|
'https://www.myetherwallet.com/images/logo-myetherwallet.svg'
|
||||||
|
}
|
||||||
|
height="55px"
|
||||||
|
width="auto"
|
||||||
|
alt="Ether Wallet"
|
||||||
|
/>
|
||||||
</a>
|
</a>
|
||||||
</p>
|
</p>
|
||||||
<p><span>{translate('FOOTER_1')}</span>
|
<p>
|
||||||
|
<span>{translate('FOOTER_1')}</span>
|
||||||
<span>{translate('FOOTER_1b')}</span>
|
<span>{translate('FOOTER_1b')}</span>
|
||||||
<a aria-label="kvhnuke's github"
|
<a
|
||||||
|
aria-label="kvhnuke's github"
|
||||||
href="https://github.com/kvhnuke"
|
href="https://github.com/kvhnuke"
|
||||||
target="_blank">kvhnuke</a>
|
target="_blank"
|
||||||
|
>
|
||||||
|
kvhnuke
|
||||||
|
</a>
|
||||||
{' & '}
|
{' & '}
|
||||||
<a aria-label="tayvano's github"
|
<a
|
||||||
|
aria-label="tayvano's github"
|
||||||
href="https://github.com/tayvano"
|
href="https://github.com/tayvano"
|
||||||
target="_blank">tayvano</a>.
|
target="_blank"
|
||||||
|
>
|
||||||
|
tayvano
|
||||||
|
</a>.
|
||||||
</p>
|
</p>
|
||||||
<br />
|
<br />
|
||||||
</div>
|
</div>
|
||||||
<div className="col-sm-6 footer-2">
|
<div className="col-sm-6 footer-2">
|
||||||
<h5><i aria-hidden="true">💝</i>{translate('FOOTER_2')}</h5>
|
<h5><i aria-hidden="true">💝</i>{translate('FOOTER_2')}</h5>
|
||||||
<ul>
|
<ul>
|
||||||
<li> ETH: <span
|
<li>
|
||||||
className="mono wrap">0x7cB57B5A97eAbe94205C07890BE4c1aD31E486A8</span>
|
{' '}ETH:{' '}
|
||||||
|
<span className="mono wrap">
|
||||||
|
{DONATION_ADDRESSES_MAP.ETH}
|
||||||
|
</span>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
{' '}BTC:{' '}
|
||||||
|
<span className="mono wrap">
|
||||||
|
{DONATION_ADDRESSES_MAP.BTC}
|
||||||
|
</span>
|
||||||
</li>
|
</li>
|
||||||
<li> BTC: <span className="mono wrap">1MEWT2SGbqtz6mPCgFcnea8XmWV5Z4Wc6</span></li>
|
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<h5><i aria-hidden="true">👫</i>{translate('ADD_Warning_1')}</h5>
|
<h5>
|
||||||
|
<i aria-hidden="true">👫</i>{translate('ADD_Warning_1')}
|
||||||
|
</h5>
|
||||||
<p>Consider using our affiliate links to...</p>
|
<p>Consider using our affiliate links to...</p>
|
||||||
<ul>
|
<ul>
|
||||||
<li><a aria-label="Swap Ether or Bitcoin via Bity.com"
|
<li>
|
||||||
href="https://bity.com/af/jshkb37v" target="_blank">Swap ETH/BTC/EUR/CHF via
|
<a
|
||||||
Bity.com</a></li>
|
aria-label="Swap Ether or Bitcoin via Bity.com"
|
||||||
<li><a href="https://www.ledgerwallet.com/r/fa4b?path=/products/" target="_blank">Buy
|
href="https://bity.com/af/jshkb37v"
|
||||||
|
target="_blank"
|
||||||
|
>
|
||||||
|
Swap ETH/BTC/EUR/CHF via
|
||||||
|
Bity.com
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a
|
||||||
|
href="https://www.ledgerwallet.com/r/fa4b?path=/products/"
|
||||||
|
target="_blank"
|
||||||
|
>
|
||||||
|
Buy
|
||||||
a
|
a
|
||||||
Ledger Nano S</a></li>
|
Ledger Nano S
|
||||||
<li><a href="https://trezor.io/?a=myetherwallet.com" target="_blank">Buy a
|
</a>
|
||||||
TREZOR</a>
|
</li>
|
||||||
|
<li>
|
||||||
|
<a
|
||||||
|
href="https://trezor.io/?a=myetherwallet.com"
|
||||||
|
target="_blank"
|
||||||
|
>
|
||||||
|
Buy a
|
||||||
|
TREZOR
|
||||||
|
</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
{!!translators.length &&
|
{!!translators.length &&
|
||||||
<h5> <i>🏅</i> <span>{translate('Translator_Desc')}</span></h5>
|
<h5>
|
||||||
}
|
{' '}<i>🏅</i> <span>{translate('Translator_Desc')}</span>
|
||||||
|
</h5>}
|
||||||
{!!translators.length &&
|
{!!translators.length &&
|
||||||
<ul>
|
<ul>
|
||||||
<li>{translators.map(key => <span key={key}>{translate(key)}</span>)}</li>
|
<li>
|
||||||
</ul>
|
{translators.map(key =>
|
||||||
}
|
<span key={key}>{translate(key)}</span>
|
||||||
|
)}
|
||||||
|
</li>
|
||||||
|
</ul>}
|
||||||
</div>
|
</div>
|
||||||
<div className="col-sm-3 footer-3">
|
<div className="col-sm-3 footer-3">
|
||||||
<h5><i aria-hidden="true">🌎</i> On the Web</h5>
|
<h5><i aria-hidden="true">🌎</i> On the Web</h5>
|
||||||
<ul>
|
<ul>
|
||||||
<li><a aria-label="my ether wallet.com" href="https://www.MyEtherWallet.com"
|
<li>
|
||||||
target="_blank">www.MyEtherWallet.com</a></li>
|
<a
|
||||||
<li><a aria-label="my ether wallet github"
|
aria-label="my ether wallet.com"
|
||||||
href="https://github.com/kvhnuke/etherwallet"
|
href="https://www.MyEtherWallet.com"
|
||||||
target="_blank">Github: MyEtherWallet.com & CX</a></li>
|
target="_blank"
|
||||||
<li><a aria-label="our organization on github"
|
>
|
||||||
href="https://github.com/MyEtherWallet"
|
www.MyEtherWallet.com
|
||||||
target="_blank">Github: MyEtherWallet (Org)</a></li>
|
</a>
|
||||||
<li><a aria-label="join our slack" href="https://myetherwallet.herokuapp.com/"
|
</li>
|
||||||
target="_blank">Join Our Slack</a></li>
|
<li>
|
||||||
<li><a aria-label="twitter" href="https://twitter.com/myetherwallet"
|
<a
|
||||||
target="_blank">Twitter</a>
|
aria-label="my ether wallet github"
|
||||||
|
href="https://github.com/kvhnuke/etherwallet"
|
||||||
|
target="_blank"
|
||||||
|
>
|
||||||
|
Github: MyEtherWallet.com & CX
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a
|
||||||
|
aria-label="our organization on github"
|
||||||
|
href="https://github.com/MyEtherWallet"
|
||||||
|
target="_blank"
|
||||||
|
>
|
||||||
|
Github: MyEtherWallet (Org)
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a
|
||||||
|
aria-label="join our slack"
|
||||||
|
href="https://myetherwallet.herokuapp.com/"
|
||||||
|
target="_blank"
|
||||||
|
>
|
||||||
|
Join Our Slack
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a
|
||||||
|
aria-label="twitter"
|
||||||
|
href="https://twitter.com/myetherwallet"
|
||||||
|
target="_blank"
|
||||||
|
>
|
||||||
|
Twitter
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a
|
||||||
|
aria-label="facebook"
|
||||||
|
href="https://www.facebook.com/MyEtherWallet/"
|
||||||
|
target="_blank"
|
||||||
|
>
|
||||||
|
Facebook
|
||||||
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li><a aria-label="facebook" href="https://www.facebook.com/MyEtherWallet/"
|
|
||||||
target="_blank">Facebook</a></li>
|
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<h5><i aria-hidden="true">🙏</i> Support</h5>
|
<h5><i aria-hidden="true">🙏</i> Support</h5>
|
||||||
<ul>
|
<ul>
|
||||||
<li><a aria-label="email support at myetherwallet.com"
|
<li>
|
||||||
href="mailto:support@myetherwallet.com" target="_blank">Email</a></li>
|
<a
|
||||||
<li><a aria-label="open a github issue"
|
aria-label="email support at myetherwallet.com"
|
||||||
href="https://github.com/kvhnuke/etherwallet/issues" target="_blank">Github
|
href="mailto:support@myetherwallet.com"
|
||||||
Issue</a></li>
|
target="_blank"
|
||||||
|
>
|
||||||
|
Email
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a
|
||||||
|
aria-label="open a github issue"
|
||||||
|
href="https://github.com/kvhnuke/etherwallet/issues"
|
||||||
|
target="_blank"
|
||||||
|
>
|
||||||
|
Github
|
||||||
|
Issue
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
</section>
|
</section>
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,9 @@
|
|||||||
|
export const DONATION_ADDRESSES_MAP = {
|
||||||
|
BTC: '1MEWT2SGbqtz6mPCgFcnea8XmWV5Z4Wc6',
|
||||||
|
ETH: '0x7cB57B5A97eAbe94205C07890BE4c1aD31E486A8',
|
||||||
|
REP: '0x7cB57B5A97eAbe94205C07890BE4c1aD31E486A8'
|
||||||
|
};
|
||||||
|
|
||||||
export const languages = [
|
export const languages = [
|
||||||
{
|
{
|
||||||
sign: 'en',
|
sign: 'en',
|
||||||
|
@ -31,9 +31,9 @@ class CoinTypeDropDown extends Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class WantToSwapMy extends Component {
|
export default class CurrencySwap extends Component {
|
||||||
constructor(props, context) {
|
constructor(props) {
|
||||||
super(props, context);
|
super(props);
|
||||||
}
|
}
|
||||||
|
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
@ -47,10 +47,13 @@ export default class WantToSwapMy extends Component {
|
|||||||
originKindSwap: PropTypes.func,
|
originKindSwap: PropTypes.func,
|
||||||
destinationKindSwap: PropTypes.func,
|
destinationKindSwap: PropTypes.func,
|
||||||
originAmountSwap: PropTypes.func,
|
originAmountSwap: PropTypes.func,
|
||||||
destinationAmountSwap: PropTypes.func
|
destinationAmountSwap: PropTypes.func,
|
||||||
|
partOneCompleteSwap: PropTypes.func
|
||||||
};
|
};
|
||||||
|
|
||||||
onClickStartSwap() {}
|
onClickStartSwap = () => {
|
||||||
|
this.props.partOneCompleteSwap(true);
|
||||||
|
};
|
||||||
|
|
||||||
onChangeOriginAmount = amount => {
|
onChangeOriginAmount = amount => {
|
||||||
let originAmountAsNumber = parseFloat(amount);
|
let originAmountAsNumber = parseFloat(amount);
|
@ -1,6 +1,7 @@
|
|||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
import translate from 'translations';
|
import translate from 'translations';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
|
import { toFixedIfLarger } from 'utils/formatters';
|
||||||
|
|
||||||
export default class CurrentRates extends Component {
|
export default class CurrentRates extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
@ -48,10 +49,10 @@ export default class CurrentRates extends Component {
|
|||||||
name="ETHBTCAmount"
|
name="ETHBTCAmount"
|
||||||
/>
|
/>
|
||||||
<span>
|
<span>
|
||||||
ETH = {(this.state.ETHBTCAmount * this.props.ETHBTC).toFixed(
|
{` ETH = ${toFixedIfLarger(
|
||||||
|
this.state.ETHBTCAmount * this.props.ETHBTC,
|
||||||
6
|
6
|
||||||
)}{' '}
|
)} BTC`}
|
||||||
BTC
|
|
||||||
</span>
|
</span>
|
||||||
</p>
|
</p>
|
||||||
<p className="mono">
|
<p className="mono">
|
||||||
@ -62,10 +63,10 @@ export default class CurrentRates extends Component {
|
|||||||
name="ETHREPAmount"
|
name="ETHREPAmount"
|
||||||
/>
|
/>
|
||||||
<span>
|
<span>
|
||||||
ETH = {(this.state.ETHREPAmount * this.props.ETHREP).toFixed(
|
{` ETH = ${toFixedIfLarger(
|
||||||
|
this.state.ETHREPAmount * this.props.ETHREP,
|
||||||
6
|
6
|
||||||
)}{' '}
|
)} REP`}
|
||||||
REP
|
|
||||||
</span>
|
</span>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
@ -78,10 +79,10 @@ export default class CurrentRates extends Component {
|
|||||||
name="BTCETHAmount"
|
name="BTCETHAmount"
|
||||||
/>
|
/>
|
||||||
<span>
|
<span>
|
||||||
BTC = {(this.state.BTCETHAmount * this.props.BTCETH).toFixed(
|
{` BTC = ${toFixedIfLarger(
|
||||||
|
this.state.BTCETHAmount * this.props.BTCETH,
|
||||||
6
|
6
|
||||||
)}{' '}
|
)} ETH`}
|
||||||
ETH
|
|
||||||
</span>
|
</span>
|
||||||
</p>
|
</p>
|
||||||
<p className="mono">
|
<p className="mono">
|
||||||
@ -92,10 +93,10 @@ export default class CurrentRates extends Component {
|
|||||||
name="BTCREPAmount"
|
name="BTCREPAmount"
|
||||||
/>
|
/>
|
||||||
<span>
|
<span>
|
||||||
BTC = {(this.state.BTCREPAmount * this.props.BTCREP).toFixed(
|
{` BTC = ${toFixedIfLarger(
|
||||||
|
this.state.BTCREPAmount * this.props.BTCREP,
|
||||||
6
|
6
|
||||||
)}{' '}
|
)} REP`}
|
||||||
REP
|
|
||||||
</span>
|
</span>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
67
common/containers/Tabs/Swap/components/receivingAddress.js
Normal file
67
common/containers/Tabs/Swap/components/receivingAddress.js
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
import React, { Component } from 'react';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import { DONATION_ADDRESSES_MAP } from 'config/data';
|
||||||
|
import Validator from 'libs/validator';
|
||||||
|
import translate from 'translations';
|
||||||
|
|
||||||
|
export default class ReceivingAddress extends Component {
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
this.validator = new Validator();
|
||||||
|
this.state = {
|
||||||
|
validAddress: false
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
static propTypes = {
|
||||||
|
destinationKind: PropTypes.string.isRequired,
|
||||||
|
receivingAddressSwap: PropTypes.func.isRequired,
|
||||||
|
receivingAddress: PropTypes.string
|
||||||
|
};
|
||||||
|
|
||||||
|
onChangeReceivingAddress = event => {
|
||||||
|
const value = event.target.value;
|
||||||
|
this.props.receivingAddressSwap(value);
|
||||||
|
let validAddress;
|
||||||
|
// TODO - find better pattern here once currencies move beyond BTC, ETH, REP
|
||||||
|
if (this.props.destinationKind === 'BTC') {
|
||||||
|
validAddress = this.validator.isValidBTCAddress(value);
|
||||||
|
} else {
|
||||||
|
validAddress = this.validator.isValidETHAddress(value);
|
||||||
|
}
|
||||||
|
this.setState({ validAddress });
|
||||||
|
};
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const { destinationKind, receivingAddress } = this.props;
|
||||||
|
const { validAddress } = this.state;
|
||||||
|
return (
|
||||||
|
<article className="swap-start">
|
||||||
|
<section className="swap-address block">
|
||||||
|
<section className="row">
|
||||||
|
<div className="col-sm-8 col-sm-offset-2 col-xs-12">
|
||||||
|
<label>
|
||||||
|
<span>{translate('SWAP_rec_add')}</span>
|
||||||
|
<strong> ({destinationKind})</strong>
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
className={`form-control ${validAddress
|
||||||
|
? 'is-valid'
|
||||||
|
: 'is-invalid'}`}
|
||||||
|
type="text"
|
||||||
|
value={receivingAddress}
|
||||||
|
onChange={this.onChangeReceivingAddress}
|
||||||
|
placeholder={DONATION_ADDRESSES_MAP[destinationKind]}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
<section className="row text-center">
|
||||||
|
<button disabled={!validAddress} className="btn btn-primary btn-lg">
|
||||||
|
<span>{translate('SWAP_start_CTA')}</span>
|
||||||
|
</button>
|
||||||
|
</section>
|
||||||
|
</section>
|
||||||
|
</article>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
79
common/containers/Tabs/Swap/components/swapInformation.js
Normal file
79
common/containers/Tabs/Swap/components/swapInformation.js
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
import React, { Component } from 'react';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import { toFixedIfLarger } from 'utils/formatters';
|
||||||
|
import translate from 'translations';
|
||||||
|
|
||||||
|
export default class SwapInformation extends Component {
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
}
|
||||||
|
|
||||||
|
static propTypes = {
|
||||||
|
originAmount: PropTypes.number.isRequired,
|
||||||
|
destinationAmount: PropTypes.number.isRequired,
|
||||||
|
originKind: PropTypes.string.isRequired,
|
||||||
|
destinationKind: PropTypes.string.isRequired
|
||||||
|
};
|
||||||
|
|
||||||
|
computedOriginDestinationRatio = () => {
|
||||||
|
return this.props.destinationAmount / this.props.originAmount;
|
||||||
|
};
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const {
|
||||||
|
originAmount,
|
||||||
|
originKind,
|
||||||
|
destinationAmount,
|
||||||
|
destinationKind
|
||||||
|
} = this.props;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<article className="swap-start">
|
||||||
|
<section className="row">
|
||||||
|
<h5 className="col-xs-6 col-xs-offset-3">
|
||||||
|
{translate('SWAP_information')}
|
||||||
|
</h5>
|
||||||
|
<div className="col-xs-3">
|
||||||
|
<a
|
||||||
|
className="link"
|
||||||
|
href="https://bity.com/af/jshkb37v"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener"
|
||||||
|
>
|
||||||
|
{/* Todo - fix*/}
|
||||||
|
<img
|
||||||
|
className="pull-right"
|
||||||
|
src={'https://www.myetherwallet.com/images/logo-bity.svg'}
|
||||||
|
width={100}
|
||||||
|
height={38}
|
||||||
|
/>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
<section className="order-info-wrap row">
|
||||||
|
<div className="col-sm-4 order-info">
|
||||||
|
<h4>
|
||||||
|
{` ${toFixedIfLarger(originAmount, 6)} ${originKind}`}
|
||||||
|
</h4>
|
||||||
|
<p>{translate('SEND_amount')}</p>
|
||||||
|
</div>
|
||||||
|
<div className="col-sm-4 order-info">
|
||||||
|
<h4>
|
||||||
|
{` ${toFixedIfLarger(destinationAmount, 6)} ${destinationKind}`}
|
||||||
|
</h4>
|
||||||
|
<p>{translate('SWAP_rec_amt')}</p>
|
||||||
|
</div>
|
||||||
|
<div className="col-sm-4 order-info">
|
||||||
|
<h4>
|
||||||
|
{` ${toFixedIfLarger(
|
||||||
|
this.computedOriginDestinationRatio(),
|
||||||
|
6
|
||||||
|
)} ${originKind}/${destinationKind} `}
|
||||||
|
</h4>
|
||||||
|
<p>{translate('SWAP_your_rate')}</p>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</article>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -1,6 +1,9 @@
|
|||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
import WantToSwapMy from './components/wantToSwapMy';
|
import CurrencySwap from './components/currencySwap';
|
||||||
|
import SwapInformation from './components/swapInformation';
|
||||||
import CurrentRates from './components/currentRates';
|
import CurrentRates from './components/currentRates';
|
||||||
|
import ReceivingAddress from './components/receivingAddress';
|
||||||
|
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import * as swapActions from 'actions/swap';
|
import * as swapActions from 'actions/swap';
|
||||||
|
|
||||||
@ -18,14 +21,18 @@ class Swap extends Component {
|
|||||||
originAmount: PropTypes.any,
|
originAmount: PropTypes.any,
|
||||||
destinationAmount: PropTypes.any,
|
destinationAmount: PropTypes.any,
|
||||||
originKind: PropTypes.string,
|
originKind: PropTypes.string,
|
||||||
|
partOneComplete: PropTypes.bool,
|
||||||
destinationKind: PropTypes.string,
|
destinationKind: PropTypes.string,
|
||||||
destinationKindOptions: PropTypes.array,
|
destinationKindOptions: PropTypes.array,
|
||||||
originKindOptions: PropTypes.array,
|
originKindOptions: PropTypes.array,
|
||||||
|
receivingAddress: PropTypes.string,
|
||||||
originKindSwap: PropTypes.func,
|
originKindSwap: PropTypes.func,
|
||||||
destinationKindSwap: PropTypes.func,
|
destinationKindSwap: PropTypes.func,
|
||||||
originAmountSwap: PropTypes.func,
|
originAmountSwap: PropTypes.func,
|
||||||
destinationAmountSwap: PropTypes.func,
|
destinationAmountSwap: PropTypes.func,
|
||||||
updateBityRatesSwap: PropTypes.func
|
updateBityRatesSwap: PropTypes.func,
|
||||||
|
partOneCompleteSwap: PropTypes.func,
|
||||||
|
receivingAddressSwap: PropTypes.func
|
||||||
};
|
};
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
@ -55,7 +62,11 @@ class Swap extends Component {
|
|||||||
originKindSwap,
|
originKindSwap,
|
||||||
destinationKindSwap,
|
destinationKindSwap,
|
||||||
originAmountSwap,
|
originAmountSwap,
|
||||||
destinationAmountSwap
|
destinationAmountSwap,
|
||||||
|
partOneComplete,
|
||||||
|
partOneCompleteSwap,
|
||||||
|
receivingAddressSwap,
|
||||||
|
receivingAddress
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
let wantToSwapMyProps = {
|
let wantToSwapMyProps = {
|
||||||
@ -69,15 +80,37 @@ class Swap extends Component {
|
|||||||
originKindSwap,
|
originKindSwap,
|
||||||
destinationKindSwap,
|
destinationKindSwap,
|
||||||
originAmountSwap,
|
originAmountSwap,
|
||||||
destinationAmountSwap
|
destinationAmountSwap,
|
||||||
|
partOneCompleteSwap
|
||||||
|
};
|
||||||
|
|
||||||
|
let yourInformationProps = {
|
||||||
|
originAmount,
|
||||||
|
destinationAmount,
|
||||||
|
originKind,
|
||||||
|
destinationKind
|
||||||
|
};
|
||||||
|
|
||||||
|
let yourReceivingProps = {
|
||||||
|
destinationKind,
|
||||||
|
receivingAddressSwap,
|
||||||
|
receivingAddress
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<section className="container" style={{ minHeight: '50%' }}>
|
<section className="container" style={{ minHeight: '50%' }}>
|
||||||
<div className="tab-content">
|
<div className="tab-content">
|
||||||
<main className="tab-pane swap-tab">
|
<main className="tab-pane swap-tab">
|
||||||
|
{!partOneComplete &&
|
||||||
|
<div>
|
||||||
<CurrentRates {...bityRates} />
|
<CurrentRates {...bityRates} />
|
||||||
<WantToSwapMy {...wantToSwapMyProps} />
|
<CurrencySwap {...wantToSwapMyProps} />
|
||||||
|
</div>}
|
||||||
|
{partOneComplete &&
|
||||||
|
<div>
|
||||||
|
<SwapInformation {...yourInformationProps} />
|
||||||
|
<ReceivingAddress {...yourReceivingProps} />
|
||||||
|
</div>}
|
||||||
</main>
|
</main>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
@ -87,6 +120,8 @@ class Swap extends Component {
|
|||||||
|
|
||||||
function mapStateToProps(state) {
|
function mapStateToProps(state) {
|
||||||
return {
|
return {
|
||||||
|
receivingAddress: state.swap.receivingAddress,
|
||||||
|
partOneComplete: state.swap.partOneComplete,
|
||||||
originAmount: state.swap.originAmount,
|
originAmount: state.swap.originAmount,
|
||||||
destinationAmount: state.swap.destinationAmount,
|
destinationAmount: state.swap.destinationAmount,
|
||||||
originKind: state.swap.originKind,
|
originKind: state.swap.originKind,
|
||||||
|
16
common/libs/validator.js
Normal file
16
common/libs/validator.js
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
import WalletAddressValidator from 'wallet-address-validator';
|
||||||
|
import ethUtil from 'ethereumjs-util';
|
||||||
|
|
||||||
|
export default class Validator {
|
||||||
|
isValidETHAddress = function(address) {
|
||||||
|
if (address && address === '0x0000000000000000000000000000000000000000')
|
||||||
|
return false;
|
||||||
|
if (address) {
|
||||||
|
return ethUtil.isValidAddress(address);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
isValidBTCAddress = function(address) {
|
||||||
|
return WalletAddressValidator.validate(address, 'BTC');
|
||||||
|
};
|
||||||
|
}
|
@ -3,15 +3,17 @@ import {
|
|||||||
SWAP_DESTINATION_KIND,
|
SWAP_DESTINATION_KIND,
|
||||||
SWAP_ORIGIN_AMOUNT,
|
SWAP_ORIGIN_AMOUNT,
|
||||||
SWAP_ORIGIN_KIND,
|
SWAP_ORIGIN_KIND,
|
||||||
SWAP_UPDATE_BITY_RATES
|
SWAP_UPDATE_BITY_RATES,
|
||||||
|
SWAP_PART_ONE_COMPLETE,
|
||||||
|
SWAP_RECEIVING_ADDRESS
|
||||||
} from 'actions/swapConstants';
|
} from 'actions/swapConstants';
|
||||||
import { combineAndUpper } from 'api/bity';
|
import { combineAndUpper } from 'api/bity';
|
||||||
|
|
||||||
export const ALL_CRYPTO_KIND_OPTIONS = ['BTC', 'ETH', 'REP'];
|
export const ALL_CRYPTO_KIND_OPTIONS = ['BTC', 'ETH', 'REP'];
|
||||||
|
|
||||||
const initialState = {
|
const initialState = {
|
||||||
originAmount: 0,
|
originAmount: '',
|
||||||
destinationAmount: 0,
|
destinationAmount: '',
|
||||||
originKind: 'BTC',
|
originKind: 'BTC',
|
||||||
destinationKind: 'ETH',
|
destinationKind: 'ETH',
|
||||||
destinationKindOptions: ALL_CRYPTO_KIND_OPTIONS.filter(
|
destinationKindOptions: ALL_CRYPTO_KIND_OPTIONS.filter(
|
||||||
@ -20,7 +22,9 @@ const initialState = {
|
|||||||
originKindOptions: ALL_CRYPTO_KIND_OPTIONS.filter(
|
originKindOptions: ALL_CRYPTO_KIND_OPTIONS.filter(
|
||||||
element => element !== 'REP'
|
element => element !== 'REP'
|
||||||
),
|
),
|
||||||
bityRates: {}
|
partOneComplete: false,
|
||||||
|
bityRates: {},
|
||||||
|
receivingAddress: ''
|
||||||
};
|
};
|
||||||
|
|
||||||
const buildDestinationAmount = (
|
const buildDestinationAmount = (
|
||||||
@ -94,6 +98,16 @@ export function swap(state = initialState, action) {
|
|||||||
...action.value
|
...action.value
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
case SWAP_PART_ONE_COMPLETE:
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
partOneComplete: action.value
|
||||||
|
};
|
||||||
|
case SWAP_RECEIVING_ADDRESS:
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
receivingAddress: action.value
|
||||||
|
};
|
||||||
default:
|
default:
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
5
common/utils/formatters.js
Normal file
5
common/utils/formatters.js
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
//flow
|
||||||
|
|
||||||
|
export function toFixedIfLarger(number: number, fixedSize: number = 6): string {
|
||||||
|
return parseFloat(number.toFixed(fixedSize)).toString();
|
||||||
|
}
|
@ -20,6 +20,7 @@
|
|||||||
"redux-logger": "^3.0.1",
|
"redux-logger": "^3.0.1",
|
||||||
"redux-saga": "^0.15.3",
|
"redux-saga": "^0.15.3",
|
||||||
"store2": "^2.5.0",
|
"store2": "^2.5.0",
|
||||||
|
"wallet-address-validator": "^0.1.0",
|
||||||
"whatwg-fetch": "^2.0.2"
|
"whatwg-fetch": "^2.0.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
34
spec/libs/validator.spec.js
Normal file
34
spec/libs/validator.spec.js
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
import Validator from '../../common/libs/validator';
|
||||||
|
import { DONATION_ADDRESSES_MAP } from '../../common/config/data';
|
||||||
|
|
||||||
|
describe('Validator', () => {
|
||||||
|
it('should validate correct BTC address as true', () => {
|
||||||
|
const validator = new Validator();
|
||||||
|
expect(
|
||||||
|
validator.isValidBTCAddress(DONATION_ADDRESSES_MAP.BTC)
|
||||||
|
).toBeTruthy();
|
||||||
|
});
|
||||||
|
it('should validate incorrect BTC address as false', () => {
|
||||||
|
const validator = new Validator();
|
||||||
|
expect(
|
||||||
|
validator.isValidBTCAddress(
|
||||||
|
'nonsense' + DONATION_ADDRESSES_MAP.BTC + 'nonsense'
|
||||||
|
)
|
||||||
|
).toBeFalsy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should validate correct ETH address as true', () => {
|
||||||
|
const validator = new Validator();
|
||||||
|
expect(
|
||||||
|
validator.isValidETHAddress(DONATION_ADDRESSES_MAP.ETH)
|
||||||
|
).toBeTruthy();
|
||||||
|
});
|
||||||
|
it('should validate incorrect ETH address as false', () => {
|
||||||
|
const validator = new Validator();
|
||||||
|
expect(
|
||||||
|
validator.isValidETHAddress(
|
||||||
|
'nonsense' + DONATION_ADDRESSES_MAP.ETH + 'nonsense'
|
||||||
|
)
|
||||||
|
).toBeFalsy();
|
||||||
|
});
|
||||||
|
});
|
17
spec/utils/formatters.spec.js
Normal file
17
spec/utils/formatters.spec.js
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
import { toFixedIfLarger } from '../../common/utils/formatters';
|
||||||
|
|
||||||
|
describe('toFixedIfLarger', () => {
|
||||||
|
it('should return same value if decimal isnt longer than default', () => {
|
||||||
|
const numExample = 7.002;
|
||||||
|
expect(toFixedIfLarger(numExample)).toEqual(String(numExample));
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return shortened value rounded up if decimal is longer than default', () => {
|
||||||
|
const numExample = 7.1234567;
|
||||||
|
expect(toFixedIfLarger(numExample)).toEqual(String(7.123457));
|
||||||
|
});
|
||||||
|
it('should return shortened value if decimal is longer than passed fixedSize', () => {
|
||||||
|
const numExample = 7.12345678;
|
||||||
|
expect(toFixedIfLarger(numExample, 2)).toEqual(String(7.12));
|
||||||
|
});
|
||||||
|
});
|
Loading…
x
Reference in New Issue
Block a user