@bzxnetwork/portal
Version:
Frontend demo portal for bZx
208 lines (194 loc) • 6.42 kB
JSX
import { Fragment } from "react";
import styled from "styled-components";
import Dialog from "@material-ui/core/Dialog";
import DialogContent from "@material-ui/core/DialogContent";
import DialogTitle from "@material-ui/core/DialogTitle";
import Button from "@material-ui/core/Button";
import TokenPicker from "../common/TokenPicker";
import Section, { SectionLabel, Divider } from "../common/FormSection";
import { getTokenConversionAmount, fromBigNumber } from "../common/utils";
import { getDecimals } from "../common/tokens";
const TxHashLink = styled.a.attrs({
target: `_blank`,
rel: `noopener noreferrer`
})`
font-family: monospace;
display: block;
text-overflow: ellipsis;
overflow: auto;
}
`;
const defaultToken = tokens => {
let token = tokens.filter(t => t.symbol === `KNC`);
if (token.length > 0) {
token = token[0]; // eslint-disable-line prefer-destructuring
} else {
token = tokens[0]; // eslint-disable-line prefer-destructuring
}
return token;
};
export default class TradeOracleDialog extends React.Component {
state = {
tradeToken: defaultToken(this.props.tokens),
expectedAmount: 0
};
componentDidMount = async () => {
await this.setTokenAddress(this.state.tradeToken.address);
};
setTokenAddress = async tokenAddress => {
if (!this.props.order) await this.props.getSingleOrder();
const tradeToken = this.props.tokens.filter(
t => t.address === tokenAddress
)[0];
let expectedAmount = 0;
expectedAmount = await getTokenConversionAmount(
this.props.positionTokenAddressFilled,
tokenAddress,
this.props.positionTokenAmountFilled,
this.props.order.oracleAddress,
this.props.bZx
);
this.setState({
tradeToken,
expectedAmount: fromBigNumber(
expectedAmount,
10 ** getDecimals(this.props.tokens, tokenAddress)
)
});
};
executeChange = async () => {
const { bZx, web3, accounts, loanOrderHash } = this.props;
const { tradeToken } = this.state;
const notAllowed = {
1: [`BZRX`, `BZRXFAKE`],
3: [`BZRX`, `BZRXFAKE`],
4: [`BZRX`],
42: [`BZRX`],
50: [`BZRX`]
};
if (
notAllowed[bZx.networkId] &&
notAllowed[bZx.networkId].includes(tradeToken && tradeToken.symbol)
) {
alert(
`Token ${
tradeToken.symbol
} is not yet supported for trading with this oracle. Please choose a different token.`
);
return;
}
const txOpts = {
from: accounts[0],
gas: 2000000,
gasPrice: window.defaultGasPrice.toString()
};
console.log(`Executing trade with Kyber:`);
console.log({
orderHash: loanOrderHash,
tradeTokenAddress: tradeToken.address,
txOpts
});
if (bZx.portalProviderName !== `MetaMask`) {
alert(`Please confirm this transaction on your device.`);
}
const txObj = await bZx.tradePositionWithOracle({
orderHash: loanOrderHash,
tradeTokenAddress: tradeToken.address,
getObject: true
});
try {
await txObj
.estimateGas(txOpts)
.then(gas => {
console.log(gas);
txOpts.gas = window.gasValue(gas);
txObj
.send(txOpts)
.once(`transactionHash`, hash => {
alert(`Transaction submitted, transaction hash:`, {
component: () => (
<TxHashLink href={`${bZx.etherscanURL}tx/${hash}`}>
{hash}
</TxHashLink>
)
});
})
.then(() => {
alert(`Trade execution complete. Please refresh to see changes.`);
this.props.onClose();
})
.catch(error => {
console.error(error);
alert(`We were not able to execute this trade.`);
this.props.onClose();
});
})
.catch(error => {
console.error(error);
alert(
`The transaction is failing. This trade cannot be executed at this time.`
);
this.props.onClose();
});
} catch (error) {
console.error(error);
alert(
`The transaction is failing. This trade cannot be executed at this time.`
);
this.props.onClose();
}
};
render() {
return (
<Dialog open={this.props.open} onClose={this.props.onClose}>
<DialogTitle>Execute Trade with Kyber Oracle</DialogTitle>
<DialogContent>
<Section>
<SectionLabel>1. Choose your target token</SectionLabel>
<TokenPicker
tokens={this.props.tokens.filter(
t =>
this.state.tradeToken.address === this.props.positionTokenAddressFilled ||
t.address !== this.props.positionTokenAddressFilled
)}
setAddress={this.setTokenAddress}
value={this.state.tradeToken.address}
/>
</Section>
<Divider />
<Section>
<SectionLabel>2. Execute the trade</SectionLabel>
<p>
When you click the button below, we will attempt to execute a
market order trade via Kyber for your target token.
{this.state.expectedAmount > 0 ? (
<Fragment>
<br />
<br />
Estimated purchase amount is {this.state.expectedAmount}
{` `}
{this.state.tradeToken.symbol}.
</Fragment>
) : (
<Fragment>
<br />
<br />
Sorry, but Kyber can't handle this large of a trade for
{` `}
{this.state.tradeToken.symbol}. Please try again later.
</Fragment>
)}
</p>
<Button
onClick={this.executeChange}
variant="raised"
color="primary"
>
Execute trade with Kyber
</Button>
</Section>
</DialogContent>
</Dialog>
);
}
}