Commit 22b6c0b0 authored by Chi Kei Chan's avatar Chi Kei Chan

Copy changes and add Create Exchange button

parent bbe6410a
...@@ -211,7 +211,20 @@ ...@@ -211,7 +211,20 @@
&--no-exchange { &--no-exchange {
color: $dove-gray; color: $dove-gray;
justify-content: center; justify-content: center;
background-color: darken($concrete-gray, 1);; background-color: darken($concrete-gray, 1);
}
&--create-exchange {
color: $white;
justify-content: center;
background-color: $malibu-blue;
&:hover {
background-color: lighten($malibu-blue, 1)
}
&:active {
background-color: darken($malibu-blue, 1);
}
} }
} }
......
...@@ -3,6 +3,7 @@ import { connect } from 'react-redux'; ...@@ -3,6 +3,7 @@ import { connect } from 'react-redux';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { CSSTransitionGroup } from "react-transition-group"; import { CSSTransitionGroup } from "react-transition-group";
import classnames from 'classnames'; import classnames from 'classnames';
import { withRouter } from 'react-router-dom';
import Fuse from '../../helpers/fuse'; import Fuse from '../../helpers/fuse';
import Modal from '../Modal'; import Modal from '../Modal';
import TokenLogo from '../TokenLogo'; import TokenLogo from '../TokenLogo';
...@@ -110,6 +111,7 @@ class CurrencyInputPanel extends Component { ...@@ -110,6 +111,7 @@ class CurrencyInputPanel extends Component {
factoryAddress, factoryAddress,
exchangeAddresses: { fromToken }, exchangeAddresses: { fromToken },
addExchange, addExchange,
history,
} = this.props; } = this.props;
if (web3 && web3.utils && web3.utils.isAddress(searchQuery)) { if (web3 && web3.utils && web3.utils.isAddress(searchQuery)) {
...@@ -140,6 +142,25 @@ class CurrencyInputPanel extends Component { ...@@ -140,6 +142,25 @@ class CurrencyInputPanel extends Component {
results = fuse.search(this.state.searchQuery); results = fuse.search(this.state.searchQuery);
} }
if (!results.length && web3.utils.isAddress(searchQuery)) {
const { label } = selectors().getBalance(account, searchQuery);
return [
<div key="token-modal-no-exchange" className="token-modal__token-row token-modal__token-row--no-exchange">
<div>No Exchange Found</div>
</div>,
<div
key="token-modal-create-exchange"
className="token-modal__token-row token-modal__token-row--create-exchange"
onClick={() => {
this.setState({ isShowingModal: false });
history.push(`/create-exchange/${searchQuery}`);
}}
>
<div>{`Create exchange fro ${label}`}</div>
</div>
]
}
if (!results.length) { if (!results.length) {
return ( return (
<div className="token-modal__token-row token-modal__token-row--no-exchange"> <div className="token-modal__token-row token-modal__token-row--no-exchange">
...@@ -346,18 +367,20 @@ class CurrencyInputPanel extends Component { ...@@ -346,18 +367,20 @@ class CurrencyInputPanel extends Component {
} }
} }
export default connect( export default withRouter(
state => ({ connect(
factoryAddress: state.addresses.factoryAddress, state => ({
exchangeAddresses: state.addresses.exchangeAddresses, factoryAddress: state.addresses.factoryAddress,
tokenAddresses: state.addresses.tokenAddresses, exchangeAddresses: state.addresses.exchangeAddresses,
contracts: state.contracts, tokenAddresses: state.addresses.tokenAddresses,
account: state.web3connect.account, contracts: state.contracts,
approvals: state.web3connect.approvals, account: state.web3connect.account,
web3: state.web3connect.web3, approvals: state.web3connect.approvals,
}), web3: state.web3connect.web3,
dispatch => ({ }),
selectors: () => dispatch(selectors()), dispatch => ({
addExchange: opts => dispatch(addExchange(opts)), selectors: () => dispatch(selectors()),
}), addExchange: opts => dispatch(addExchange(opts)),
)(CurrencyInputPanel); }),
)(CurrencyInputPanel)
);
...@@ -55,7 +55,7 @@ class App extends Component { ...@@ -55,7 +55,7 @@ class App extends Component {
<Route exact path="/send" component={Send} /> <Route exact path="/send" component={Send} />
<Route exact path="/add-liquidity" component={Pool} /> <Route exact path="/add-liquidity" component={Pool} />
<Route exact path="/remove-liquidity" component={Pool} /> <Route exact path="/remove-liquidity" component={Pool} />
<Route exact path="/create-exchange" component={Pool} /> <Route exact path="/create-exchange/:tokenAddress?" component={Pool} />
<Redirect exact from="/" to="/swap" /> <Redirect exact from="/" to="/swap" />
</AnimatedSwitch> </AnimatedSwitch>
</BrowserRouter> </BrowserRouter>
......
...@@ -38,6 +38,7 @@ class AddLiquidity extends Component { ...@@ -38,6 +38,7 @@ class AddLiquidity extends Component {
inputCurrency: 'ETH', inputCurrency: 'ETH',
outputCurrency: '', outputCurrency: '',
lastEditedField: '', lastEditedField: '',
totalSupply: BN(0),
showSummaryModal: false, showSummaryModal: false,
}; };
...@@ -71,20 +72,29 @@ class AddLiquidity extends Component { ...@@ -71,20 +72,29 @@ class AddLiquidity extends Component {
this.recalcForm(); this.recalcForm();
} }
recalcForm = () => { recalcForm = async () => {
const { const {
outputCurrency, outputCurrency,
inputValue, inputValue,
outputValue, outputValue,
lastEditedField, lastEditedField,
totalSupply: oldTotalSupply,
} = this.state; } = this.state;
const { exchangeAddresses: { fromToken }, web3 } = this.props;
const exchangeAddress = fromToken[outputCurrency];
const exchangeRate = this.getExchangeRate(); const exchangeRate = this.getExchangeRate();
const append = {}; const append = {};
if (!outputCurrency || this.isNewExchange()) { if (!outputCurrency || this.isNewExchange() || !web3) {
return; return;
} }
const exchange = new web3.eth.Contract(EXCHANGE_ABI, exchangeAddress);
const totalSupply = await exchange.methods.totalSupply().call();
if (!oldTotalSupply.isEqualTo(BN(totalSupply))) {
append.totalSupply = BN(totalSupply);
}
if (lastEditedField === INPUT) { if (lastEditedField === INPUT) {
const newOutputValue = exchangeRate.multipliedBy(inputValue).toFixed(7); const newOutputValue = exchangeRate.multipliedBy(inputValue).toFixed(7);
if (newOutputValue !== outputValue) { if (newOutputValue !== outputValue) {
...@@ -100,7 +110,7 @@ class AddLiquidity extends Component { ...@@ -100,7 +110,7 @@ class AddLiquidity extends Component {
} }
this.setState(append); this.setState(append);
} };
getBalance(currency) { getBalance(currency) {
const { selectors, account } = this.props; const { selectors, account } = this.props;
...@@ -298,21 +308,32 @@ class AddLiquidity extends Component { ...@@ -298,21 +308,32 @@ class AddLiquidity extends Component {
<span className="swap__exchange-rate">Current Pool Size</span> <span className="swap__exchange-rate">Current Pool Size</span>
<span> - </span> <span> - </span>
</div> </div>
<div className="pool__exchange-rate-wrapper">
<span className="swap__exchange-rate">Your Pool Share</span>
<span> - </span>
</div>
</div> </div>
); );
const { selectors, exchangeAddresses: { fromToken } } = this.props; const { selectors, exchangeAddresses: { fromToken }, account } = this.props;
const { getBalance } = selectors(); const { getBalance } = selectors();
const { inputCurrency, outputCurrency, inputValue, outputValue } = this.state; const { inputCurrency, outputCurrency, inputValue, outputValue, totalSupply } = this.state;
const eth = [inputCurrency, outputCurrency].filter(currency => currency === 'ETH')[0]; const eth = [inputCurrency, outputCurrency].filter(currency => currency === 'ETH')[0];
const token = [inputCurrency, outputCurrency].filter(currency => currency !== 'ETH')[0]; const token = [inputCurrency, outputCurrency].filter(currency => currency !== 'ETH')[0];
const exchangeAddress = fromToken[token];
if (!eth || !token) { if (!eth || !token || !exchangeAddress) {
return blank; return blank;
} }
const { value: tokenValue, decimals, label } = getBalance(fromToken[token], token); const { value: tokenValue, decimals, label } = getBalance(exchangeAddress, token);
const { value: ethValue } = getBalance(fromToken[token]); const { value: ethValue } = getBalance(exchangeAddress);
const { value: liquidityBalance } = getBalance(account, exchangeAddress);
const ownership = liquidityBalance.dividedBy(totalSupply);
const ethPer = ethValue.dividedBy(totalSupply);
const tokenPer = tokenValue.dividedBy(totalSupply);
const ownedEth = ethPer.multipliedBy(liquidityBalance).dividedBy(10 ** 18);
const ownedToken = tokenPer.multipliedBy(liquidityBalance).dividedBy(10 ** decimals);
if (this.isNewExchange()) { if (this.isNewExchange()) {
const rate = BN(outputValue).dividedBy(inputValue); const rate = BN(outputValue).dividedBy(inputValue);
...@@ -325,7 +346,13 @@ class AddLiquidity extends Component { ...@@ -325,7 +346,13 @@ class AddLiquidity extends Component {
</div> </div>
<div className="pool__exchange-rate-wrapper"> <div className="pool__exchange-rate-wrapper">
<span className="swap__exchange-rate">Current Pool Size</span> <span className="swap__exchange-rate">Current Pool Size</span>
<span>{` ${ethValue.dividedBy(10 ** 18).toFixed(2)} ${eth} / ${tokenValue.dividedBy(10 ** decimals).toFixed(2)} ${label}`}</span> <span>{` ${ethValue.dividedBy(10 ** 18).toFixed(2)} ${eth} + ${tokenValue.dividedBy(10 ** decimals).toFixed(2)} ${label}`}</span>
</div>
<div className="pool__exchange-rate-wrapper">
<span className="swap__exchange-rate">
Your Pool Share ({ownership.multipliedBy(100).toFixed(2)}%)
</span>
<span>{`${ownedEth.toFixed(2)} ETH + ${ownedToken.toFixed(2)} ${label}`}</span>
</div> </div>
</div> </div>
) )
...@@ -345,6 +372,12 @@ class AddLiquidity extends Component { ...@@ -345,6 +372,12 @@ class AddLiquidity extends Component {
<span className="swap__exchange-rate">Current Pool Size</span> <span className="swap__exchange-rate">Current Pool Size</span>
<span>{` ${ethValue.dividedBy(10 ** 18).toFixed(2)} ${eth} + ${tokenValue.dividedBy(10 ** decimals).toFixed(2)} ${label}`}</span> <span>{` ${ethValue.dividedBy(10 ** 18).toFixed(2)} ${eth} + ${tokenValue.dividedBy(10 ** decimals).toFixed(2)} ${label}`}</span>
</div> </div>
<div className="pool__exchange-rate-wrapper">
<span className="swap__exchange-rate">
Your Pool Share ({ownership.multipliedBy(100).toFixed(2)}%)
</span>
<span>{`${ownedEth.toFixed(2)} ETH + ${ownedToken.toFixed(2)} ${label}`}</span>
</div>
</div> </div>
) )
} }
......
import React, { Component } from 'react'; import React, { Component } from 'react';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { withRouter } from 'react-router-dom';
import {selectors} from "../../ducks/web3connect"; import {selectors} from "../../ducks/web3connect";
import classnames from "classnames"; import classnames from "classnames";
import NavigationTabs from "../../components/NavigationTabs"; import NavigationTabs from "../../components/NavigationTabs";
...@@ -24,11 +25,16 @@ class CreateExchange extends Component { ...@@ -24,11 +25,16 @@ class CreateExchange extends Component {
}).isRequired, }).isRequired,
}; };
state = { constructor(props) {
tokenAddress: '', super(props);
label: '', const { match: { params: { tokenAddress } } } = this.props;
decimals: 0,
}; this.state = {
tokenAddress,
label: '',
decimals: 0,
};
}
validate() { validate() {
const { tokenAddress } = this.state; const { tokenAddress } = this.state;
...@@ -210,17 +216,19 @@ class CreateExchange extends Component { ...@@ -210,17 +216,19 @@ class CreateExchange extends Component {
} }
} }
export default connect( export default withRouter(
state => ({ connect(
isConnected: Boolean(state.web3connect.account) && state.web3connect.networkId == (process.env.REACT_APP_NETWORK_ID||1), state => ({
account: state.web3connect.account, isConnected: Boolean(state.web3connect.account) && state.web3connect.networkId == (process.env.REACT_APP_NETWORK_ID||1),
balances: state.web3connect.balances, account: state.web3connect.account,
web3: state.web3connect.web3, balances: state.web3connect.balances,
exchangeAddresses: state.addresses.exchangeAddresses, web3: state.web3connect.web3,
factoryAddress: state.addresses.factoryAddress, exchangeAddresses: state.addresses.exchangeAddresses,
}), factoryAddress: state.addresses.factoryAddress,
dispatch => ({ }),
selectors: () => dispatch(selectors()), dispatch => ({
addExchange: opts => dispatch(addExchange(opts)), selectors: () => dispatch(selectors()),
}) addExchange: opts => dispatch(addExchange(opts)),
)(CreateExchange); })
\ No newline at end of file )(CreateExchange)
);
\ No newline at end of file
import React, { Component } from 'react'; import React, { Component } from 'react';
import { withRouter } from 'react-router-dom'; import { withRouter } from 'react-router-dom';
import OversizedPanel from "../../components/OversizedPanel"; import OversizedPanel from "../../components/OversizedPanel";
import Dropdown from "../../assets/images/dropdown.svg"; import Dropdown from "../../assets/images/dropdown-blue.svg";
import Modal from "../../components/Modal"; import Modal from "../../components/Modal";
import {CSSTransitionGroup} from "react-transition-group"; import {CSSTransitionGroup} from "react-transition-group";
......
...@@ -8,7 +8,7 @@ import ModeSelector from "./ModeSelector"; ...@@ -8,7 +8,7 @@ import ModeSelector from "./ModeSelector";
import CurrencyInputPanel from "../../components/CurrencyInputPanel"; import CurrencyInputPanel from "../../components/CurrencyInputPanel";
import { selectors } from '../../ducks/web3connect'; import { selectors } from '../../ducks/web3connect';
import OversizedPanel from "../../components/OversizedPanel"; import OversizedPanel from "../../components/OversizedPanel";
import ArrowPlus from "../../assets/images/plus-blue.svg"; import ArrowPlus from "../../assets/images/arrow-down-blue.svg";
import EXCHANGE_ABI from "../../abi/exchange"; import EXCHANGE_ABI from "../../abi/exchange";
import promisify from "../../helpers/web3-promisfy"; import promisify from "../../helpers/web3-promisfy";
import ReactGA from "react-ga"; import ReactGA from "react-ga";
...@@ -232,13 +232,13 @@ class RemoveLiquidity extends Component { ...@@ -232,13 +232,13 @@ class RemoveLiquidity extends Component {
</div> </div>
<div className="pool__exchange-rate-wrapper"> <div className="pool__exchange-rate-wrapper">
<span className="swap__exchange-rate">Current Pool Size</span> <span className="swap__exchange-rate">Current Pool Size</span>
<span>{`${ethReserve.dividedBy(10 ** 18).toFixed(2)} ETH / ${tokenReserve.dividedBy(10 ** tokenDecimals).toFixed(2)} ${label}`}</span> <span>{`${ethReserve.dividedBy(10 ** 18).toFixed(2)} ETH + ${tokenReserve.dividedBy(10 ** tokenDecimals).toFixed(2)} ${label}`}</span>
</div> </div>
<div className="pool__exchange-rate-wrapper"> <div className="pool__exchange-rate-wrapper">
<span className="swap__exchange-rate"> <span className="swap__exchange-rate">
Your Pool Share ({ownership.multipliedBy(100).toFixed(2)}%) Your Pool Share ({ownership.multipliedBy(100).toFixed(2)}%)
</span> </span>
<span>{`${ownedEth.toFixed(2)} ETH / ${ownedToken.toFixed(2)} ${label}`}</span> <span>{`${ownedEth.toFixed(2)} ETH + ${ownedToken.toFixed(2)} ${label}`}</span>
</div> </div>
</div> </div>
</OversizedPanel> </OversizedPanel>
......
...@@ -22,7 +22,7 @@ class Pool extends Component { ...@@ -22,7 +22,7 @@ class Pool extends Component {
<Switch> <Switch>
<Route exact path="/add-liquidity" component={AddLiquidity} /> <Route exact path="/add-liquidity" component={AddLiquidity} />
<Route exact path="/remove-liquidity" component={RemoveLiquidity} /> <Route exact path="/remove-liquidity" component={RemoveLiquidity} />
<Route exact path="/create-exchange" component={CreateExchange} /> <Route exact path="/create-exchange/:tokenAddress?" component={CreateExchange} />
</Switch> </Switch>
</div> </div>
); );
......
...@@ -11,7 +11,9 @@ ...@@ -11,7 +11,9 @@
font-size: .75rem; font-size: .75rem;
padding: .625rem 1rem; padding: .625rem 1rem;
font-size: .75rem; font-size: .75rem;
color: $dove-gray; color: $royal-blue;
font-weight: 500;
cursor: pointer;
img { img {
height: .75rem; height: .75rem;
......
...@@ -792,7 +792,7 @@ class Send extends Component { ...@@ -792,7 +792,7 @@ class Send extends Component {
} }
export default connect( export default connect(
state => console.log(state) || ({ state => ({
balances: state.web3connect.balances, balances: state.web3connect.balances,
isConnected: !!state.web3connect.account && state.web3connect.networkId == (process.env.REACT_APP_NETWORK_ID||1), isConnected: !!state.web3connect.account && state.web3connect.networkId == (process.env.REACT_APP_NETWORK_ID||1),
account: state.web3connect.account, account: state.web3connect.account,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment