From 2eab0082a62e00ef969cb06a7282e1cd1660eee6 Mon Sep 17 00:00:00 2001 From: Daniel Ternyak Date: Fri, 23 Jun 2017 20:25:12 -0500 Subject: [PATCH 01/13] Redux: Add partOneComplete actions/action creators/reducers. --- common/actions/swap.js | 10 +++++++++- common/actions/swapConstants.js | 1 + common/reducers/swap.js | 13 ++++++++++--- 3 files changed, 20 insertions(+), 4 deletions(-) diff --git a/common/actions/swap.js b/common/actions/swap.js index 15f2a4d0..cdb3b1e1 100644 --- a/common/actions/swap.js +++ b/common/actions/swap.js @@ -3,7 +3,8 @@ import { SWAP_DESTINATION_KIND, SWAP_ORIGIN_AMOUNT, SWAP_ORIGIN_KIND, - SWAP_UPDATE_BITY_RATES + SWAP_UPDATE_BITY_RATES, + SWAP_PART_ONE_COMPLETE } from './swapConstants'; export const originKindSwap = value => { @@ -40,3 +41,10 @@ export const updateBityRatesSwap = value => { value }; }; + +export const partOneCompleteSwap = (value: boolean) => { + return { + type: SWAP_PART_ONE_COMPLETE, + value + }; +}; diff --git a/common/actions/swapConstants.js b/common/actions/swapConstants.js index ca72fc2c..fe4cff5c 100644 --- a/common/actions/swapConstants.js +++ b/common/actions/swapConstants.js @@ -3,3 +3,4 @@ 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'; +export const SWAP_PART_ONE_COMPLETE = 'SWAP_PART_ONE_COMPLETE'; diff --git a/common/reducers/swap.js b/common/reducers/swap.js index b827df05..06fbb2b9 100644 --- a/common/reducers/swap.js +++ b/common/reducers/swap.js @@ -3,15 +3,16 @@ import { SWAP_DESTINATION_KIND, SWAP_ORIGIN_AMOUNT, SWAP_ORIGIN_KIND, - SWAP_UPDATE_BITY_RATES + SWAP_UPDATE_BITY_RATES, + SWAP_PART_ONE_COMPLETE } from 'actions/swapConstants'; import { combineAndUpper } from 'api/bity'; export const ALL_CRYPTO_KIND_OPTIONS = ['BTC', 'ETH', 'REP']; const initialState = { - originAmount: 0, - destinationAmount: 0, + originAmount: '', + destinationAmount: '', originKind: 'BTC', destinationKind: 'ETH', destinationKindOptions: ALL_CRYPTO_KIND_OPTIONS.filter( @@ -20,6 +21,7 @@ const initialState = { originKindOptions: ALL_CRYPTO_KIND_OPTIONS.filter( element => element !== 'REP' ), + partOneComplete: false, bityRates: {} }; @@ -94,6 +96,11 @@ export function swap(state = initialState, action) { ...action.value } }; + case SWAP_PART_ONE_COMPLETE: + return { + ...state, + partOneComplete: action.value + }; default: return state; } From fc94460af089771f9bfcbe59f8e228ed638a4bbb Mon Sep 17 00:00:00 2001 From: Daniel Ternyak Date: Fri, 23 Jun 2017 20:26:08 -0500 Subject: [PATCH 02/13] Prototype Extesion: Create toFixedIfLarger and add test (that doesn't work yet) --- common/index.jsx | 90 +++++++++++++++++++++++------------------ spec/extensions.spec.js | 10 +++++ 2 files changed, 61 insertions(+), 39 deletions(-) create mode 100644 spec/extensions.spec.js diff --git a/common/index.jsx b/common/index.jsx index be993df6..20f22c48 100644 --- a/common/index.jsx +++ b/common/index.jsx @@ -1,54 +1,66 @@ -import React from 'react' -import {render} from 'react-dom' -import {syncHistoryWithStore, routerMiddleware} from 'react-router-redux' -import {composeWithDevTools} from 'redux-devtools-extension' -import Perf from 'react-addons-perf' -import {createStore, applyMiddleware} from 'redux' -import RootReducer from './reducers' -import {Root} from 'components' -import {Routing, history} from './routing' -import {createLogger} from 'redux-logger' -import createSagaMiddleware from 'redux-saga' -import notificationsSaga from './sagas/notifications' +import React from 'react'; +import { render } from 'react-dom'; +import { syncHistoryWithStore, routerMiddleware } from 'react-router-redux'; +import { composeWithDevTools } from 'redux-devtools-extension'; +import Perf from 'react-addons-perf'; +import { createStore, applyMiddleware } from 'redux'; +import RootReducer from './reducers'; +import { Root } from 'components'; +import { Routing, history } from './routing'; +import { createLogger } from 'redux-logger'; +import createSagaMiddleware from 'redux-saga'; +import notificationsSaga from './sagas/notifications'; // application styles -import 'assets/styles/etherwallet-master.less' +import 'assets/styles/etherwallet-master.less'; -const sagaMiddleware = createSagaMiddleware() +const sagaMiddleware = createSagaMiddleware(); const configureStore = () => { - let sagaApplied = applyMiddleware(sagaMiddleware); - let store; - let middleware; + let sagaApplied = applyMiddleware(sagaMiddleware); + let store; + let middleware; - if (process.env.NODE_ENV !== 'production') { - window.Perf = Perf; - sagaApplied = composeWithDevTools(sagaApplied); - const logger = createLogger({ - collapsed: true - }); - middleware = applyMiddleware(routerMiddleware(history), logger); - } else { - middleware = applyMiddleware(routerMiddleware(history)); - } + if (process.env.NODE_ENV !== 'production') { + window.Perf = Perf; + sagaApplied = composeWithDevTools(sagaApplied); + const logger = createLogger({ + collapsed: true + }); + middleware = applyMiddleware(routerMiddleware(history), logger); + } else { + middleware = applyMiddleware(routerMiddleware(history)); + } - store = createStore(RootReducer, sagaApplied, middleware); - sagaMiddleware.run(notificationsSaga) - return store + store = createStore(RootReducer, sagaApplied, middleware); + sagaMiddleware.run(notificationsSaga); + return store; }; -const renderRoot = (Root) => { - let store = configureStore(); - let syncedHistory = syncHistoryWithStore(history, store); - render( - , document.getElementById('app')) +const renderRoot = Root => { + let store = configureStore(); + let syncedHistory = syncHistoryWithStore(history, store); + render( + , + document.getElementById('app') + ); }; renderRoot(Root); if (module.hot) { - module.hot.accept() + module.hot.accept(); } + +Number.prototype.toFixedIfLarger = function(fixedAmount: number) { + if (this > fixedAmount) { + return this.toFixed(fixedAmount); + } else { + return this; + } +}; diff --git a/spec/extensions.spec.js b/spec/extensions.spec.js new file mode 100644 index 00000000..77be11d5 --- /dev/null +++ b/spec/extensions.spec.js @@ -0,0 +1,10 @@ +describe('Number.prototype.toFixedIfLarger', () => { + it('true', () => { + expect(true); + }); + // TODO - figure out why toFixedIfLarger is not in scope + // it('should fix number to decimal place because number decimal is larger than input', () => { + // const exNumber = 0.0123; + // expect(exNumber.toFixedIfLarger(2) === 0.01); + // }); +}); From 943a0532d7fa2eb559f7dea008ed5418abb00922 Mon Sep 17 00:00:00 2001 From: Daniel Ternyak Date: Fri, 23 Jun 2017 20:26:54 -0500 Subject: [PATCH 03/13] Swap: Create components/adjust containers as neccesasary for part 2 of swap --- .../Tabs/Swap/components/wantToSwapMy.js | 7 +- .../Tabs/Swap/components/yourInformation.js | 73 +++++++++++++++++++ .../Tabs/Swap/components/yourReceiving.js | 41 +++++++++++ common/containers/Tabs/Swap/index.js | 34 +++++++-- 4 files changed, 148 insertions(+), 7 deletions(-) create mode 100644 common/containers/Tabs/Swap/components/yourInformation.js create mode 100644 common/containers/Tabs/Swap/components/yourReceiving.js diff --git a/common/containers/Tabs/Swap/components/wantToSwapMy.js b/common/containers/Tabs/Swap/components/wantToSwapMy.js index f82da9f0..f223c1d2 100644 --- a/common/containers/Tabs/Swap/components/wantToSwapMy.js +++ b/common/containers/Tabs/Swap/components/wantToSwapMy.js @@ -47,10 +47,13 @@ export default class WantToSwapMy extends Component { originKindSwap: PropTypes.func, destinationKindSwap: PropTypes.func, originAmountSwap: PropTypes.func, - destinationAmountSwap: PropTypes.func + destinationAmountSwap: PropTypes.func, + partOneCompleteSwap: PropTypes.func }; - onClickStartSwap() {} + onClickStartSwap = () => { + this.props.partOneCompleteSwap(true); + }; onChangeOriginAmount = amount => { let originAmountAsNumber = parseFloat(amount); diff --git a/common/containers/Tabs/Swap/components/yourInformation.js b/common/containers/Tabs/Swap/components/yourInformation.js new file mode 100644 index 00000000..69fe98de --- /dev/null +++ b/common/containers/Tabs/Swap/components/yourInformation.js @@ -0,0 +1,73 @@ +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; + +export default class YourInformation 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 ( +
+
+
Your Information
+ +
+
+
+

+ {' '}{originAmount.toFixedIfLarger(6)} {originKind}{' '} +

+

Amount to send

+
+
+

+ {' '}{destinationAmount.toFixedIfLarger(6)} {destinationKind}{' '} +

+

Amount to receive

+
+
+

+ {' '}{this.computedOriginDestinationRatio().toFixedIfLarger(6)}{' '} + {originKind}/{destinationKind}{' '} +

+

Your rate

+
+
+
+ ); + } +} diff --git a/common/containers/Tabs/Swap/components/yourReceiving.js b/common/containers/Tabs/Swap/components/yourReceiving.js new file mode 100644 index 00000000..9b18113e --- /dev/null +++ b/common/containers/Tabs/Swap/components/yourReceiving.js @@ -0,0 +1,41 @@ +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; +import { DONATION_ADDRESSES_MAP } from 'config/data'; + +export default class YourReceiving extends Component { + constructor(props) { + super(props); + } + + static propTypes = { + destinationKind: PropTypes.string.isRequired + }; + + render() { + const { destinationKind } = this.props; + return ( +
+
+
+
+ + +
+
+
+ + Start Swap + +
+
+
+ ); + } +} diff --git a/common/containers/Tabs/Swap/index.js b/common/containers/Tabs/Swap/index.js index 62dc6158..a97cfef0 100644 --- a/common/containers/Tabs/Swap/index.js +++ b/common/containers/Tabs/Swap/index.js @@ -1,6 +1,9 @@ import React, { Component } from 'react'; import WantToSwapMy from './components/wantToSwapMy'; +import YourInformation from './components/yourInformation'; import CurrentRates from './components/currentRates'; +import YourReceiving from './components/yourReceiving'; + import { connect } from 'react-redux'; import * as swapActions from 'actions/swap'; @@ -18,6 +21,7 @@ class Swap extends Component { originAmount: PropTypes.any, destinationAmount: PropTypes.any, originKind: PropTypes.string, + partOneComplete: PropTypes.bool, destinationKind: PropTypes.string, destinationKindOptions: PropTypes.array, originKindOptions: PropTypes.array, @@ -25,7 +29,8 @@ class Swap extends Component { destinationKindSwap: PropTypes.func, originAmountSwap: PropTypes.func, destinationAmountSwap: PropTypes.func, - updateBityRatesSwap: PropTypes.func + updateBityRatesSwap: PropTypes.func, + partOneCompleteSwap: PropTypes.func }; componentDidMount() { @@ -55,7 +60,9 @@ class Swap extends Component { originKindSwap, destinationKindSwap, originAmountSwap, - destinationAmountSwap + destinationAmountSwap, + partOneComplete, + partOneCompleteSwap } = this.props; let wantToSwapMyProps = { @@ -69,15 +76,31 @@ class Swap extends Component { originKindSwap, destinationKindSwap, originAmountSwap, - destinationAmountSwap + destinationAmountSwap, + partOneCompleteSwap + }; + + let yourInformationProps = { + originAmount, + destinationAmount, + originKind, + destinationKind }; return (
- - + {!partOneComplete && +
+ + +
} + {partOneComplete && +
+ + +
}
@@ -87,6 +110,7 @@ class Swap extends Component { function mapStateToProps(state) { return { + partOneComplete: state.swap.partOneComplete, originAmount: state.swap.originAmount, destinationAmount: state.swap.destinationAmount, originKind: state.swap.originKind, From 07bde87658274ba545032dfe8cb57a82834af3d5 Mon Sep 17 00:00:00 2001 From: Daniel Ternyak Date: Fri, 23 Jun 2017 20:27:17 -0500 Subject: [PATCH 04/13] Refactor: Use global donation mapping instead of hardcoding donation address in footer --- common/components/Footer/index.jsx | 290 +++++++++++++++++--------- common/config/data.js | 320 +++++++++++++++-------------- 2 files changed, 359 insertions(+), 251 deletions(-) diff --git a/common/components/Footer/index.jsx b/common/components/Footer/index.jsx index 1c7bdd82..39da157a 100644 --- a/common/components/Footer/index.jsx +++ b/common/components/Footer/index.jsx @@ -1,100 +1,202 @@ -import React, {Component} from 'react'; -import translate, {getTranslators} from 'translations'; - +import React, { Component } from 'react'; +import translate, { getTranslators } from 'translations'; +import { DONATION_ADDRESSES_MAP } from 'config/data'; export default class Footer extends Component { - render() { - const translators = getTranslators() - return ( - + ); + } } diff --git a/common/config/data.js b/common/config/data.js index 0094ba20..dac459b5 100644 --- a/common/config/data.js +++ b/common/config/data.js @@ -1,162 +1,168 @@ +export const DONATION_ADDRESSES_MAP = { + BTC: '1MEWT2SGbqtz6mPCgFcnea8XmWV5Z4Wc6', + ETH: '0x7cB57B5A97eAbe94205C07890BE4c1aD31E486A8', + REP: '0x7cB57B5A97eAbe94205C07890BE4c1aD31E486A8' +}; + export const languages = [ - { - sign: 'en', - name: 'English' - }, - { - sign: 'de', - name: 'Deutsch' - }, - { - sign: 'el', - name: 'Ελληνικά' - }, - { - sign: 'es', - name: 'Español' - }, - { - sign: 'fi', - name: 'Suomi' - }, - { - sign: 'fr', - name: 'Français' - }, - { - sign: 'hu', - name: 'Magyar' - }, - { - sign: 'id', - name: 'Indonesian' - }, - { - sign: 'it', - name: 'Italiano' - }, - { - sign: 'ja', - name: '日本語' - }, - { - sign: 'nl', - name: 'Nederlands' - }, - { - sign: 'no', - name: 'Norsk Bokmål' - }, - { - sign: 'pl', - name: 'Polski' - }, - { - sign: 'pt', - name: 'Português' - }, - { - sign: 'ru', - name: 'Русский' - }, - { - sign: 'ko', - name: 'Korean' - }, - // { - // 'sign': 'sk', - // 'name': 'Slovenčina' - // }, - // { - // 'sign': 'sl', - // 'name': 'Slovenščina' - // }, - // { - // 'sign': 'sv', - // 'name': 'Svenska' - // }, - { - sign: 'tr', - name: 'Türkçe' - }, - { - sign: 'vi', - name: 'Tiếng Việt' - }, - { - sign: 'zhcn', - name: '简体中文' - }, - { - sign: 'zhtw', - name: '繁體中文' - } + { + sign: 'en', + name: 'English' + }, + { + sign: 'de', + name: 'Deutsch' + }, + { + sign: 'el', + name: 'Ελληνικά' + }, + { + sign: 'es', + name: 'Español' + }, + { + sign: 'fi', + name: 'Suomi' + }, + { + sign: 'fr', + name: 'Français' + }, + { + sign: 'hu', + name: 'Magyar' + }, + { + sign: 'id', + name: 'Indonesian' + }, + { + sign: 'it', + name: 'Italiano' + }, + { + sign: 'ja', + name: '日本語' + }, + { + sign: 'nl', + name: 'Nederlands' + }, + { + sign: 'no', + name: 'Norsk Bokmål' + }, + { + sign: 'pl', + name: 'Polski' + }, + { + sign: 'pt', + name: 'Português' + }, + { + sign: 'ru', + name: 'Русский' + }, + { + sign: 'ko', + name: 'Korean' + }, + // { + // 'sign': 'sk', + // 'name': 'Slovenčina' + // }, + // { + // 'sign': 'sl', + // 'name': 'Slovenščina' + // }, + // { + // 'sign': 'sv', + // 'name': 'Svenska' + // }, + { + sign: 'tr', + name: 'Türkçe' + }, + { + sign: 'vi', + name: 'Tiếng Việt' + }, + { + sign: 'zhcn', + name: '简体中文' + }, + { + sign: 'zhtw', + name: '繁體中文' + } ]; export const nodeList = [ - { - name: 'ETH', - blockExplorerTX: 'https://etherscan.io/tx/[[txHash]]', - blockExplorerAddr: 'https://etherscan.io/address/[[address]]', - // 'type': nodes.nodeTypes.ETH, - eip155: true, - chainId: 1, - // 'tokenList': require('./tokens/ethTokens.json'), - // 'abiList': require('./abiDefinitions/ethAbi.json'), - estimateGas: true, - service: 'MyEtherWallet' - // 'lib': new nodes.customNode('https://api.myetherapi.com/eth', '') - }, - { - name: 'ETH', - blockExplorerTX: 'https://etherscan.io/tx/[[txHash]]', - blockExplorerAddr: 'https://etherscan.io/address/[[address]]', - // 'type': nodes.nodeTypes.ETH, - eip155: true, - chainId: 1, - // 'tokenList': require('./tokens/ethTokens.json'), - // 'abiList': require('./abiDefinitions/ethAbi.json'), - estimateGas: false, - service: 'Etherscan.io' - // 'lib': require('./nodeHelpers/etherscan') - }, - { - name: 'Ropsten', - // 'type': nodes.nodeTypes.Ropsten, - blockExplorerTX: 'https://ropsten.etherscan.io/tx/[[txHash]]', - blockExplorerAddr: 'https://ropsten.etherscan.io/address/[[address]]', - eip155: true, - chainId: 3, - // 'tokenList': require('./tokens/ropstenTokens.json'), - // 'abiList': require('./abiDefinitions/ropstenAbi.json'), - estimateGas: false, - service: 'MyEtherWallet' - // 'lib': new nodes.customNode('https://api.myetherapi.com/rop', '') - }, - { - name: 'Kovan', - // 'type': nodes.nodeTypes.Kovan, - blockExplorerTX: 'https://kovan.etherscan.io/tx/[[txHash]]', - blockExplorerAddr: 'https://kovan.etherscan.io/address/[[address]]', - eip155: true, - chainId: 42, - // 'tokenList': require('./tokens/kovanTokens.json'), - // 'abiList': require('./abiDefinitions/kovanAbi.json'), - estimateGas: false, - service: 'Etherscan.io' - // 'lib': require('./nodeHelpers/etherscanKov') - }, - { - name: 'ETC', - blockExplorerTX: 'https://gastracker.io/tx/[[txHash]]', - blockExplorerAddr: 'https://gastracker.io/addr/[[address]]', - // 'type': nodes.nodeTypes.ETC, - eip155: true, - chainId: 61, - // 'tokenList': require('./tokens/etcTokens.json'), - // 'abiList': require('./abiDefinitions/etcAbi.json'), - estimateGas: false, - service: 'Epool.io' - // 'lib': new nodes.customNode('https://mewapi.epool.io', '') - } + { + name: 'ETH', + blockExplorerTX: 'https://etherscan.io/tx/[[txHash]]', + blockExplorerAddr: 'https://etherscan.io/address/[[address]]', + // 'type': nodes.nodeTypes.ETH, + eip155: true, + chainId: 1, + // 'tokenList': require('./tokens/ethTokens.json'), + // 'abiList': require('./abiDefinitions/ethAbi.json'), + estimateGas: true, + service: 'MyEtherWallet' + // 'lib': new nodes.customNode('https://api.myetherapi.com/eth', '') + }, + { + name: 'ETH', + blockExplorerTX: 'https://etherscan.io/tx/[[txHash]]', + blockExplorerAddr: 'https://etherscan.io/address/[[address]]', + // 'type': nodes.nodeTypes.ETH, + eip155: true, + chainId: 1, + // 'tokenList': require('./tokens/ethTokens.json'), + // 'abiList': require('./abiDefinitions/ethAbi.json'), + estimateGas: false, + service: 'Etherscan.io' + // 'lib': require('./nodeHelpers/etherscan') + }, + { + name: 'Ropsten', + // 'type': nodes.nodeTypes.Ropsten, + blockExplorerTX: 'https://ropsten.etherscan.io/tx/[[txHash]]', + blockExplorerAddr: 'https://ropsten.etherscan.io/address/[[address]]', + eip155: true, + chainId: 3, + // 'tokenList': require('./tokens/ropstenTokens.json'), + // 'abiList': require('./abiDefinitions/ropstenAbi.json'), + estimateGas: false, + service: 'MyEtherWallet' + // 'lib': new nodes.customNode('https://api.myetherapi.com/rop', '') + }, + { + name: 'Kovan', + // 'type': nodes.nodeTypes.Kovan, + blockExplorerTX: 'https://kovan.etherscan.io/tx/[[txHash]]', + blockExplorerAddr: 'https://kovan.etherscan.io/address/[[address]]', + eip155: true, + chainId: 42, + // 'tokenList': require('./tokens/kovanTokens.json'), + // 'abiList': require('./abiDefinitions/kovanAbi.json'), + estimateGas: false, + service: 'Etherscan.io' + // 'lib': require('./nodeHelpers/etherscanKov') + }, + { + name: 'ETC', + blockExplorerTX: 'https://gastracker.io/tx/[[txHash]]', + blockExplorerAddr: 'https://gastracker.io/addr/[[address]]', + // 'type': nodes.nodeTypes.ETC, + eip155: true, + chainId: 61, + // 'tokenList': require('./tokens/etcTokens.json'), + // 'abiList': require('./abiDefinitions/etcAbi.json'), + estimateGas: false, + service: 'Epool.io' + // 'lib': new nodes.customNode('https://mewapi.epool.io', '') + } ]; From cb36331c2d60517001a23b151ce10f0391ff00c6 Mon Sep 17 00:00:00 2001 From: Daniel Ternyak Date: Fri, 23 Jun 2017 20:34:13 -0500 Subject: [PATCH 05/13] Refactor: remove stray ng-binding --- common/containers/Tabs/Swap/components/yourReceiving.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/containers/Tabs/Swap/components/yourReceiving.js b/common/containers/Tabs/Swap/components/yourReceiving.js index 9b18113e..584f0f9c 100644 --- a/common/containers/Tabs/Swap/components/yourReceiving.js +++ b/common/containers/Tabs/Swap/components/yourReceiving.js @@ -20,7 +20,7 @@ export default class YourReceiving extends Component {
Date: Sat, 24 Jun 2017 01:08:33 -0500 Subject: [PATCH 06/13] Redux: Add SWAP_RECEIVING_ADDRESS action creators/reducers. --- common/actions/swap.js | 10 +++++++++- common/actions/swapConstants.js | 1 + common/reducers/swap.js | 11 +++++++++-- 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/common/actions/swap.js b/common/actions/swap.js index cdb3b1e1..79c37555 100644 --- a/common/actions/swap.js +++ b/common/actions/swap.js @@ -4,7 +4,8 @@ import { SWAP_ORIGIN_AMOUNT, SWAP_ORIGIN_KIND, SWAP_UPDATE_BITY_RATES, - SWAP_PART_ONE_COMPLETE + SWAP_PART_ONE_COMPLETE, + SWAP_RECEIVING_ADDRESS } from './swapConstants'; export const originKindSwap = value => { @@ -48,3 +49,10 @@ export const partOneCompleteSwap = (value: boolean) => { value }; }; + +export const receivingAddressSwap = value => { + return { + type: SWAP_RECEIVING_ADDRESS, + value + }; +}; diff --git a/common/actions/swapConstants.js b/common/actions/swapConstants.js index fe4cff5c..ecf0fb4a 100644 --- a/common/actions/swapConstants.js +++ b/common/actions/swapConstants.js @@ -4,3 +4,4 @@ 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'; export const SWAP_PART_ONE_COMPLETE = 'SWAP_PART_ONE_COMPLETE'; +export const SWAP_RECEIVING_ADDRESS = 'SWAP_RECEIVING_ADDRESS'; diff --git a/common/reducers/swap.js b/common/reducers/swap.js index 06fbb2b9..3de1b101 100644 --- a/common/reducers/swap.js +++ b/common/reducers/swap.js @@ -4,7 +4,8 @@ import { SWAP_ORIGIN_AMOUNT, SWAP_ORIGIN_KIND, SWAP_UPDATE_BITY_RATES, - SWAP_PART_ONE_COMPLETE + SWAP_PART_ONE_COMPLETE, + SWAP_RECEIVING_ADDRESS } from 'actions/swapConstants'; import { combineAndUpper } from 'api/bity'; @@ -22,7 +23,8 @@ const initialState = { element => element !== 'REP' ), partOneComplete: false, - bityRates: {} + bityRates: {}, + receivingAddress: '' }; const buildDestinationAmount = ( @@ -101,6 +103,11 @@ export function swap(state = initialState, action) { ...state, partOneComplete: action.value }; + case SWAP_RECEIVING_ADDRESS: + return { + ...state, + receivingAddress: action.value + }; default: return state; } From c77f8430c53842f1dc979655a8bc4e8a246f3c31 Mon Sep 17 00:00:00 2001 From: Daniel Ternyak Date: Sat, 24 Jun 2017 01:08:57 -0500 Subject: [PATCH 07/13] Create Validator class and add deps to package.json --- common/libs/validator.js | 16 ++++++++++++++++ package.json | 2 ++ 2 files changed, 18 insertions(+) create mode 100644 common/libs/validator.js diff --git a/common/libs/validator.js b/common/libs/validator.js new file mode 100644 index 00000000..c930f47a --- /dev/null +++ b/common/libs/validator.js @@ -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'); + }; +} diff --git a/package.json b/package.json index ee4c86d0..c18c6355 100644 --- a/package.json +++ b/package.json @@ -5,6 +5,7 @@ "description": "MyEtherWallet v4", "dependencies": { "axios": "^0.16.2", + "ethereumjs-util": "^5.1.2", "lodash": "^4.17.4", "prop-types": "^15.5.8", "react": "^15.4.2", @@ -17,6 +18,7 @@ "redux-logger": "^3.0.1", "redux-saga": "^0.15.3", "store2": "^2.5.0", + "wallet-address-validator": "^0.1.0", "whatwg-fetch": "^2.0.2" }, "devDependencies": { From 28415cd0e8bbdd5c4584e7e04ce5c1f48cd3b79d Mon Sep 17 00:00:00 2001 From: Daniel Ternyak Date: Sat, 24 Jun 2017 01:09:44 -0500 Subject: [PATCH 08/13] Consume new receivingAddressSwap action creator and receivingAddress state, validate receiving address input using Validator class. --- .../Tabs/Swap/components/yourReceiving.js | 35 ++++++++++++++++--- common/containers/Tabs/Swap/index.js | 17 +++++++-- 2 files changed, 44 insertions(+), 8 deletions(-) diff --git a/common/containers/Tabs/Swap/components/yourReceiving.js b/common/containers/Tabs/Swap/components/yourReceiving.js index 584f0f9c..cde16274 100644 --- a/common/containers/Tabs/Swap/components/yourReceiving.js +++ b/common/containers/Tabs/Swap/components/yourReceiving.js @@ -1,18 +1,39 @@ import React, { Component } from 'react'; import PropTypes from 'prop-types'; import { DONATION_ADDRESSES_MAP } from 'config/data'; +import Validator from 'libs/validator'; export default class YourReceiving extends Component { constructor(props) { super(props); + this.validator = new Validator(); + this.state = { + validAddress: false + }; } static propTypes = { - destinationKind: PropTypes.string.isRequired + 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 } = this.props; + const { destinationKind, receivingAddress } = this.props; + const { validAddress } = this.state; return (
@@ -23,16 +44,20 @@ export default class YourReceiving extends Component { ({destinationKind})
- +
diff --git a/common/containers/Tabs/Swap/index.js b/common/containers/Tabs/Swap/index.js index a97cfef0..9e875332 100644 --- a/common/containers/Tabs/Swap/index.js +++ b/common/containers/Tabs/Swap/index.js @@ -25,12 +25,14 @@ class Swap extends Component { destinationKind: PropTypes.string, destinationKindOptions: PropTypes.array, originKindOptions: PropTypes.array, + receivingAddress: PropTypes.string, originKindSwap: PropTypes.func, destinationKindSwap: PropTypes.func, originAmountSwap: PropTypes.func, destinationAmountSwap: PropTypes.func, updateBityRatesSwap: PropTypes.func, - partOneCompleteSwap: PropTypes.func + partOneCompleteSwap: PropTypes.func, + receivingAddressSwap: PropTypes.func }; componentDidMount() { @@ -62,7 +64,9 @@ class Swap extends Component { originAmountSwap, destinationAmountSwap, partOneComplete, - partOneCompleteSwap + partOneCompleteSwap, + receivingAddressSwap, + receivingAddress } = this.props; let wantToSwapMyProps = { @@ -87,6 +91,12 @@ class Swap extends Component { destinationKind }; + let yourReceivingProps = { + destinationKind, + receivingAddressSwap, + receivingAddress + }; + return (
@@ -99,7 +109,7 @@ class Swap extends Component { {partOneComplete &&
- +
}
@@ -110,6 +120,7 @@ class Swap extends Component { function mapStateToProps(state) { return { + receivingAddress: state.swap.receivingAddress, partOneComplete: state.swap.partOneComplete, originAmount: state.swap.originAmount, destinationAmount: state.swap.destinationAmount, From 119dda77e10c840576e859dbf4c6f008072476be Mon Sep 17 00:00:00 2001 From: Daniel Ternyak Date: Sat, 24 Jun 2017 13:17:09 -0500 Subject: [PATCH 09/13] Create toFixedIfLarger function, unit test, and use in app. --- .../Tabs/Swap/components/currentRates.js | 17 +++++++++--- .../Tabs/Swap/components/yourInformation.js | 7 ++--- common/index.jsx | 8 ------ common/utils/formatters.js | 27 +++++++++++++++++++ spec/extensions.spec.js | 10 ------- spec/utils/formatters.spec.js | 17 ++++++++++++ 6 files changed, 61 insertions(+), 25 deletions(-) create mode 100644 common/utils/formatters.js delete mode 100644 spec/extensions.spec.js create mode 100644 spec/utils/formatters.spec.js diff --git a/common/containers/Tabs/Swap/components/currentRates.js b/common/containers/Tabs/Swap/components/currentRates.js index 577df5a4..eed17fd7 100644 --- a/common/containers/Tabs/Swap/components/currentRates.js +++ b/common/containers/Tabs/Swap/components/currentRates.js @@ -1,6 +1,7 @@ import React, { Component } from 'react'; import translate from 'translations'; import PropTypes from 'prop-types'; +import { toFixedIfLarger } from 'utils/formatters'; export default class CurrentRates extends Component { constructor(props) { @@ -48,7 +49,9 @@ export default class CurrentRates extends Component { name="ETHBTCAmount" /> - ETH = {(this.state.ETHBTCAmount * this.props.ETHBTC).toFixed( + ETH ={' '} + {toFixedIfLarger( + this.state.ETHBTCAmount * this.props.ETHBTC, 6 )}{' '} BTC @@ -62,7 +65,9 @@ export default class CurrentRates extends Component { name="ETHREPAmount" /> - ETH = {(this.state.ETHREPAmount * this.props.ETHREP).toFixed( + ETH ={' '} + {toFixedIfLarger( + this.state.ETHREPAmount * this.props.ETHREP, 6 )}{' '} REP @@ -78,7 +83,9 @@ export default class CurrentRates extends Component { name="BTCETHAmount" /> - BTC = {(this.state.BTCETHAmount * this.props.BTCETH).toFixed( + BTC ={' '} + {toFixedIfLarger( + this.state.BTCETHAmount * this.props.BTCETH, 6 )}{' '} ETH @@ -92,7 +99,9 @@ export default class CurrentRates extends Component { name="BTCREPAmount" /> - BTC = {(this.state.BTCREPAmount * this.props.BTCREP).toFixed( + BTC ={' '} + {toFixedIfLarger( + this.state.BTCREPAmount * this.props.BTCREP, 6 )}{' '} REP diff --git a/common/containers/Tabs/Swap/components/yourInformation.js b/common/containers/Tabs/Swap/components/yourInformation.js index 69fe98de..60e71f86 100644 --- a/common/containers/Tabs/Swap/components/yourInformation.js +++ b/common/containers/Tabs/Swap/components/yourInformation.js @@ -1,5 +1,6 @@ import React, { Component } from 'react'; import PropTypes from 'prop-types'; +import { toFixedIfLarger } from 'utils/formatters'; export default class YourInformation extends Component { constructor(props) { @@ -49,19 +50,19 @@ export default class YourInformation extends Component {

- {' '}{originAmount.toFixedIfLarger(6)} {originKind}{' '} + {' '}{toFixedIfLarger(originAmount, 6)} {originKind}{' '}

Amount to send

- {' '}{destinationAmount.toFixedIfLarger(6)} {destinationKind}{' '} + {' '}{toFixedIfLarger(destinationAmount, 6)} {destinationKind}{' '}

Amount to receive

- {' '}{this.computedOriginDestinationRatio().toFixedIfLarger(6)}{' '} + {' '}{toFixedIfLarger(this.computedOriginDestinationRatio(), 6)}{' '} {originKind}/{destinationKind}{' '}

Your rate

diff --git a/common/index.jsx b/common/index.jsx index 20f22c48..3f4d9555 100644 --- a/common/index.jsx +++ b/common/index.jsx @@ -56,11 +56,3 @@ renderRoot(Root); if (module.hot) { module.hot.accept(); } - -Number.prototype.toFixedIfLarger = function(fixedAmount: number) { - if (this > fixedAmount) { - return this.toFixed(fixedAmount); - } else { - return this; - } -}; diff --git a/common/utils/formatters.js b/common/utils/formatters.js new file mode 100644 index 00000000..a575d4d5 --- /dev/null +++ b/common/utils/formatters.js @@ -0,0 +1,27 @@ +//flow + +// https://stackoverflow.com/questions/9539513/is-there-a-reliable-way-in-javascript-to-obtain-the-number-of-decimal-places-of +const decimalPlaces = (function() { + function isInt(n) { + return ( + typeof n === 'number' && parseFloat(n) == parseInt(n, 10) && !isNaN(n) + ); + } + return function(n) { + let a = Math.abs(n); + let c = a, + count = 1; + while (!isInt(c) && isFinite(c)) { + c = a * Math.pow(10, count++); + } + return count - 1; + }; +})(); + +export function toFixedIfLarger(number: number, fixedSize: number = 6): string { + if (decimalPlaces(number) > fixedSize) { + return number.toFixed(fixedSize); + } else { + return String(number); + } +} diff --git a/spec/extensions.spec.js b/spec/extensions.spec.js deleted file mode 100644 index 77be11d5..00000000 --- a/spec/extensions.spec.js +++ /dev/null @@ -1,10 +0,0 @@ -describe('Number.prototype.toFixedIfLarger', () => { - it('true', () => { - expect(true); - }); - // TODO - figure out why toFixedIfLarger is not in scope - // it('should fix number to decimal place because number decimal is larger than input', () => { - // const exNumber = 0.0123; - // expect(exNumber.toFixedIfLarger(2) === 0.01); - // }); -}); diff --git a/spec/utils/formatters.spec.js b/spec/utils/formatters.spec.js new file mode 100644 index 00000000..31b02d46 --- /dev/null +++ b/spec/utils/formatters.spec.js @@ -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)); + }); +}); From d5875614de5ebefb5594b2f8d85cd30b1d1e8b62 Mon Sep 17 00:00:00 2001 From: Daniel Ternyak Date: Sat, 24 Jun 2017 14:53:53 -0500 Subject: [PATCH 10/13] create simplified toFixedIfLarger --- common/utils/formatters.js | 24 +----------------------- 1 file changed, 1 insertion(+), 23 deletions(-) diff --git a/common/utils/formatters.js b/common/utils/formatters.js index a575d4d5..8cc26eb2 100644 --- a/common/utils/formatters.js +++ b/common/utils/formatters.js @@ -1,27 +1,5 @@ //flow -// https://stackoverflow.com/questions/9539513/is-there-a-reliable-way-in-javascript-to-obtain-the-number-of-decimal-places-of -const decimalPlaces = (function() { - function isInt(n) { - return ( - typeof n === 'number' && parseFloat(n) == parseInt(n, 10) && !isNaN(n) - ); - } - return function(n) { - let a = Math.abs(n); - let c = a, - count = 1; - while (!isInt(c) && isFinite(c)) { - c = a * Math.pow(10, count++); - } - return count - 1; - }; -})(); - export function toFixedIfLarger(number: number, fixedSize: number = 6): string { - if (decimalPlaces(number) > fixedSize) { - return number.toFixed(fixedSize); - } else { - return String(number); - } + return parseFloat(number.toFixed(fixedSize)).toString(); } From dab75a48b0bf4fbc958b77168cc5e6aedbe4eae9 Mon Sep 17 00:00:00 2001 From: Daniel Ternyak Date: Sat, 24 Jun 2017 15:39:03 -0500 Subject: [PATCH 11/13] address comments --- .../{wantToSwapMy.js => currencySwap.js} | 6 ++--- .../Tabs/Swap/components/currentRates.js | 24 +++++++------------ .../{yourReceiving.js => receivingAddress.js} | 2 +- ...{yourInformation.js => swapInformation.js} | 12 ++++++---- common/containers/Tabs/Swap/index.js | 12 +++++----- 5 files changed, 25 insertions(+), 31 deletions(-) rename common/containers/Tabs/Swap/components/{wantToSwapMy.js => currencySwap.js} (97%) rename common/containers/Tabs/Swap/components/{yourReceiving.js => receivingAddress.js} (97%) rename common/containers/Tabs/Swap/components/{yourInformation.js => swapInformation.js} (83%) diff --git a/common/containers/Tabs/Swap/components/wantToSwapMy.js b/common/containers/Tabs/Swap/components/currencySwap.js similarity index 97% rename from common/containers/Tabs/Swap/components/wantToSwapMy.js rename to common/containers/Tabs/Swap/components/currencySwap.js index f223c1d2..be58f129 100644 --- a/common/containers/Tabs/Swap/components/wantToSwapMy.js +++ b/common/containers/Tabs/Swap/components/currencySwap.js @@ -31,9 +31,9 @@ class CoinTypeDropDown extends Component { } } -export default class WantToSwapMy extends Component { - constructor(props, context) { - super(props, context); +export default class CurrencySwap extends Component { + constructor(props) { + super(props); } static propTypes = { diff --git a/common/containers/Tabs/Swap/components/currentRates.js b/common/containers/Tabs/Swap/components/currentRates.js index eed17fd7..1016bec4 100644 --- a/common/containers/Tabs/Swap/components/currentRates.js +++ b/common/containers/Tabs/Swap/components/currentRates.js @@ -49,12 +49,10 @@ export default class CurrentRates extends Component { name="ETHBTCAmount" /> - ETH ={' '} - {toFixedIfLarger( + {` ETH = ${toFixedIfLarger( this.state.ETHBTCAmount * this.props.ETHBTC, 6 - )}{' '} - BTC + )} BTC`}

@@ -65,12 +63,10 @@ export default class CurrentRates extends Component { name="ETHREPAmount" /> - ETH ={' '} - {toFixedIfLarger( + {` ETH = ${toFixedIfLarger( this.state.ETHREPAmount * this.props.ETHREP, 6 - )}{' '} - REP + )} REP`}

@@ -83,12 +79,10 @@ export default class CurrentRates extends Component { name="BTCETHAmount" /> - BTC ={' '} - {toFixedIfLarger( + {` BTC = ${toFixedIfLarger( this.state.BTCETHAmount * this.props.BTCETH, 6 - )}{' '} - ETH + )} ETH`}

@@ -99,12 +93,10 @@ export default class CurrentRates extends Component { name="BTCREPAmount" /> - BTC ={' '} - {toFixedIfLarger( + {` BTC = ${toFixedIfLarger( this.state.BTCREPAmount * this.props.BTCREP, 6 - )}{' '} - REP + )} REP`}

diff --git a/common/containers/Tabs/Swap/components/yourReceiving.js b/common/containers/Tabs/Swap/components/receivingAddress.js similarity index 97% rename from common/containers/Tabs/Swap/components/yourReceiving.js rename to common/containers/Tabs/Swap/components/receivingAddress.js index cde16274..a0cd4a80 100644 --- a/common/containers/Tabs/Swap/components/yourReceiving.js +++ b/common/containers/Tabs/Swap/components/receivingAddress.js @@ -3,7 +3,7 @@ import PropTypes from 'prop-types'; import { DONATION_ADDRESSES_MAP } from 'config/data'; import Validator from 'libs/validator'; -export default class YourReceiving extends Component { +export default class ReceivingAddress extends Component { constructor(props) { super(props); this.validator = new Validator(); diff --git a/common/containers/Tabs/Swap/components/yourInformation.js b/common/containers/Tabs/Swap/components/swapInformation.js similarity index 83% rename from common/containers/Tabs/Swap/components/yourInformation.js rename to common/containers/Tabs/Swap/components/swapInformation.js index 60e71f86..272e4c49 100644 --- a/common/containers/Tabs/Swap/components/yourInformation.js +++ b/common/containers/Tabs/Swap/components/swapInformation.js @@ -2,7 +2,7 @@ import React, { Component } from 'react'; import PropTypes from 'prop-types'; import { toFixedIfLarger } from 'utils/formatters'; -export default class YourInformation extends Component { +export default class SwapInformation extends Component { constructor(props) { super(props); } @@ -50,20 +50,22 @@ export default class YourInformation extends Component {

- {' '}{toFixedIfLarger(originAmount, 6)} {originKind}{' '} + {` ${toFixedIfLarger(originAmount, 6)} ${originKind}`}

Amount to send

- {' '}{toFixedIfLarger(destinationAmount, 6)} {destinationKind}{' '} + {` ${toFixedIfLarger(destinationAmount, 6)} ${destinationKind}`}

Amount to receive

- {' '}{toFixedIfLarger(this.computedOriginDestinationRatio(), 6)}{' '} - {originKind}/{destinationKind}{' '} + {` ${toFixedIfLarger( + this.computedOriginDestinationRatio(), + 6 + )} ${originKind}/${destinationKind} `}

Your rate

diff --git a/common/containers/Tabs/Swap/index.js b/common/containers/Tabs/Swap/index.js index 9e875332..e54bb613 100644 --- a/common/containers/Tabs/Swap/index.js +++ b/common/containers/Tabs/Swap/index.js @@ -1,8 +1,8 @@ import React, { Component } from 'react'; -import WantToSwapMy from './components/wantToSwapMy'; -import YourInformation from './components/yourInformation'; +import CurrencySwap from './components/currencySwap'; +import SwapInformation from './components/swapInformation'; import CurrentRates from './components/currentRates'; -import YourReceiving from './components/yourReceiving'; +import ReceivingAddress from './components/receivingAddress'; import { connect } from 'react-redux'; import * as swapActions from 'actions/swap'; @@ -104,12 +104,12 @@ class Swap extends Component { {!partOneComplete &&
- +
} {partOneComplete &&
- - + +
} From 142ed3adc5e97c1dba4c66cfc9d3feee7431e604 Mon Sep 17 00:00:00 2001 From: Daniel Ternyak Date: Sat, 24 Jun 2017 15:46:30 -0500 Subject: [PATCH 12/13] Add tests for Validator --- spec/libs/validator.spec.js | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 spec/libs/validator.spec.js diff --git a/spec/libs/validator.spec.js b/spec/libs/validator.spec.js new file mode 100644 index 00000000..a29b0bc8 --- /dev/null +++ b/spec/libs/validator.spec.js @@ -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(); + }); +}); From afe2adbb5ac6689b93b4a9e058e09ae4134786f5 Mon Sep 17 00:00:00 2001 From: Daniel Ternyak Date: Sun, 25 Jun 2017 00:57:43 -0500 Subject: [PATCH 13/13] add translation support --- .../Tabs/Swap/components/receivingAddress.js | 5 +++-- .../Tabs/Swap/components/swapInformation.js | 11 +++++++---- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/common/containers/Tabs/Swap/components/receivingAddress.js b/common/containers/Tabs/Swap/components/receivingAddress.js index a0cd4a80..c2bc37a8 100644 --- a/common/containers/Tabs/Swap/components/receivingAddress.js +++ b/common/containers/Tabs/Swap/components/receivingAddress.js @@ -2,6 +2,7 @@ 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) { @@ -40,7 +41,7 @@ export default class ReceivingAddress extends Component {
diff --git a/common/containers/Tabs/Swap/components/swapInformation.js b/common/containers/Tabs/Swap/components/swapInformation.js index 272e4c49..def61d99 100644 --- a/common/containers/Tabs/Swap/components/swapInformation.js +++ b/common/containers/Tabs/Swap/components/swapInformation.js @@ -1,6 +1,7 @@ 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) { @@ -29,7 +30,9 @@ export default class SwapInformation extends Component { return (