@bzxnetwork/portal
Version:
Frontend demo portal for bZx
534 lines (457 loc) • 16.6 kB
JSX
import { Fragment } from "react";
import styled from "styled-components";
import MuiButton from "@material-ui/core/Button";
import BZxComponent from "../../common/BZxComponent";
import { Divider } from "../../common/FormSection";
import { COLORS } from "../../styles/constants";
import { fromBigNumber, toBigNumber } from "../../common/utils";
import { TextField, Input, InputLabel, InputAdornment, FormControl, Dialog, DialogActions, DialogContent, DialogContentText, DialogTitle } from "@material-ui/core";
const IsSaleLive = true;
const InfoContainer = styled.div`
display: flex;
align-items: center;
`;
const ShowInfo = styled.div`
display: inline-block;
margin: 6px;
`;
const Button = styled(MuiButton)`
margin: 6px !important;
`;
const DataPointContainer = styled.div`
display: flex;
justify-content: flex-start;
align-items: center;
margin-bottom: 6px;
`;
const DataPoint = styled.span`
margin-left: 16px;
`;
const Label = styled.span`
font-weight: 600;
color: ${COLORS.gray};
`;
const AddressLink = styled.a.attrs({
target: `_blank`,
rel: `noopener noreferrer`
})`
//display: inline-block;
font-family: monospace;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
max-width: 20ch;
`;
const TxHashLink = styled.a.attrs({
target: `_blank`,
rel: `noopener noreferrer`
})`
font-family: monospace;
display: block;
text-overflow: ellipsis;
overflow: auto;
}
`;
function stringToHex (tmp) {
if (!tmp)
return '';
var str = '',
i = 0,
tmp_len = tmp.length,
c;
for (; i < tmp_len; i += 1) {
c = tmp.charCodeAt(i);
str += c.toString(16);
}
return str;
}
export default class DebugTokenization extends BZxComponent {
state = {
loading: false,
error: false,
iTokenContract: null,
pTokenContract: null,
bzxContract: null,
showRatesDialog: false,
rates: 0,
order: null,
position: null,
currentRate: 0
};
async componentDidMount() {
/*
let iTokenAddress = (await this.props.bZx.getWeb3Contract(`LoanToken`))._address;
const iTokenContract = await this.props.bZx.getWeb3Contract(`LoanToken`, iTokenAddress);
console.log(`iToken contract:`, iTokenContract._address);
let pTokenAddress = (await this.props.bZx.getWeb3Contract(`PositionToken`))._address;
const pTokenContract = await this.props.bZx.getWeb3Contract(`PositionToken`, pTokenAddress);
console.log(`pToken contract:`, pTokenContract._address);
*/
let bzxAddress;
/** TEMP **/
bzxAddress = (await this.props.bZx.getWeb3Contract(`BZx`))._address;
/** TEMP **/
const bzxContract = await this.props.bZx.getWeb3Contract(`BZx`, bzxAddress);
console.log(`bzx contract:`, bzxContract._address);
await this.setState({
//iTokenContract,
//pTokenContract,
bzxContract
});
}
refreshTokenData = async () => {
const { web3, accounts } = this.props;
const { tokenContract, bzxContract } = this.state;
await this.setState({ loading: true });
//console.log(`Token contract:`, tokenContract._address);
let orderFilledAmounts, orderCancelledAmounts;
try {
/*
let order = {};
if (this.props.CurrentHash) {
const orderKeys = [
`loanTokenAddress`,
`interestTokenAddress`,
`collateralTokenAddress`,
`oracleAddress`,
`loanTokenAmount`,
`interestAmount`,
`initialMarginAmount`,
`maintenanceMarginAmount`,
`maxDurationUnixTimestampSec`,
`loanOrderHash`,
]
const orderArr = await this.wrapAndRun(bzxContract.methods.getLoanOrder(this.props.CurrentHash).call());
for(var i=0; i < orderKeys.length; i++) {
order[orderKeys[i]] = orderArr[i];
}
order[`loanTokenAmount`] = toBigNumber(order[`loanTokenAmount`], 10 ** -18).toString() + ` (normalized)`;
order[`interestAmount`] = toBigNumber(order[`interestAmount`], 10 ** -18).toString()+ ` (normalized)`;
orderFilledAmounts = await this.wrapAndRun(bzxContract.methods.orderFilledAmounts(this.props.CurrentHash).call());
orderCancelledAmounts = await this.wrapAndRun(bzxContract.methods.orderCancelledAmounts(this.props.CurrentHash).call());
}
console.log(`this.props.CurrentHash, this.props.CurrentTrader`, this.props.CurrentHash, this.props.CurrentTrader);
let orderAux = {};
if (this.props.CurrentHash) {
const orderAuxKeys = [
`makerAddress`,
`takerAddress`,
`feeRecipientAddress`,
`tradeTokenToFillAddress`,
`lenderRelayFee`,
`traderRelayFee`,
`makerRole`,
`expirationUnixTimestampSec`,
`withdrawOnOpen`,
`description`,
]
const orderAuxArr = await this.wrapAndRun(bzxContract.methods.getLoanOrderAux(this.props.CurrentHash).call());
for(var i=0; i < orderAuxKeys.length; i++) {
orderAux[orderAuxKeys[i]] = orderAuxArr[i];
}
//order[`loanTokenAmount`] = toBigNumber(order[`loanTokenAmount`], 10 ** -18).toString() + ` (normalized)`;
//order[`interestAmount`] = toBigNumber(order[`interestAmount`], 10 ** -18).toString()+ ` (normalized)`;
}
let position = {};
if (this.props.CurrentHash && this.props.CurrentTrader) {
const positionKeys = [
`trader`,
`collateralTokenAddressFilled`,
`positionTokenAddressFilled`,
`loanTokenAmountFilled`,
`loanTokenAmountUsed`,
`collateralTokenAmountFilled`,
`positionTokenAmountFilled`,
`loanStartUnixTimestampSec`,
`loanEndUnixTimestampSec`,
`active`,
`positionId`,
]
const positionArr = await this.wrapAndRun(bzxContract.methods.getLoanPosition(
await this.wrapAndRun(bzxContract.methods.loanPositionsIds(this.props.CurrentHash, this.props.CurrentTrader).call())
).call());
for(var i=0; i < positionKeys.length; i++) {
position[positionKeys[i]] = positionArr[i];
}
position[`loanTokenAmountFilled`] = toBigNumber(position[`loanTokenAmountFilled`], 10 ** -18).toString()+ ` (normalized)`;
position[`collateralTokenAmountFilled`] = toBigNumber(position[`collateralTokenAmountFilled`], 10 ** -18).toString()+ ` (normalized)`;
position[`positionTokenAmountFilled`] = toBigNumber(position[`positionTokenAmountFilled`], 10 ** -18).toString()+ ` (normalized)`;
}
*/
const TradeToken = await this.props.bZx.getWeb3Contract(`TestToken9`);
const LoanedToken = await this.props.bZx.getWeb3Contract(`WETH`);
const oracleContract = await this.props.bZx.getWeb3Contract(`BZxOracle`);
const currentRateObj = await this.wrapAndRun(oracleContract.methods.getTradeData(
TradeToken._address,
LoanedToken._address,
toBigNumber(1, 1e18).toString()
).call());
const currentRate = await toBigNumber(currentRateObj.sourceToDestRate, 10 ** -18).toString();
await this.setState({
loading: false,
error: false,
/*order,
orderAux,
position,
orderFilledAmounts,
orderCancelledAmounts,*/
currentRate
});
} catch(e) {
console.log(e);
this.setState({
error: true,
loading: false
});
}
}
setRates = e => this.setState({ rates: e.target.value });
setStateForInput = key => e => this.setState({ [key]: e.target.value });
toggleRatesDialog = () =>
this.setState(p => ({ showRatesDialog: !p.showRatesDialog }));
changeRates = async () => {
const { web3, bZx, accounts } = this.props;
const { rates } = this.state;
if (bZx.portalProviderName !== `MetaMask`) {
alert(`Please confirm this transaction on your device.`);
}
const oracleContract = await this.props.bZx.getWeb3Contract(`BZxOracle`);
const txOpts = {
to: oracleContract._address,
from: accounts[0],
gas: 2000000,
gasPrice: window.defaultGasPrice.toString()
};
const TradeToken = await this.props.bZx.getWeb3Contract(`TestToken9`);
const LoanedToken = await this.props.bZx.getWeb3Contract(`WETH`);
txOpts.data = web3.eth.abi.encodeFunctionSignature('setRates(address,address,uint256)') +
web3.eth.abi.encodeParameters(['address','address','uint256'], [TradeToken._address,LoanedToken._address,toBigNumber(rates, 10 ** 18).toString()]).substr(2);
console.log(txOpts);
try {
console.log(txOpts);
await web3.eth.sendTransaction(txOpts)
.once(`transactionHash`, hash => {
alert(`Transaction submitted, transaction hash:`, {
component: () => (
<TxHashLink href={`${bZx.etherscanURL}tx/${hash}`}>
{hash}
</TxHashLink>
)
});
this.setState({ showRatesDialog: false });
})
.then(async () => {
alert(`The txn is complete.`);
})
.catch(error => {
console.error(error.message);
alert(`The txn did not complete.`);
this.setState({ showRatesDialog: false });
});
} catch (error) {
console.error(error.message);
alert(`The txn did not complete.`);
this.setState({ showRatesDialog: false });
}
};
halveRate = async () => {
const { web3, bZx, accounts } = this.props;
if (bZx.portalProviderName !== `MetaMask`) {
alert(`Please confirm this transaction on your device.`);
}
await this.refreshTokenData();
const oracleContract = await this.props.bZx.getWeb3Contract(`BZxOracle`);
const txOpts = {
to: oracleContract._address,
from: accounts[0],
gas: 2000000,
gasPrice: window.defaultGasPrice.toString()
};
const TradeToken = await this.props.bZx.getWeb3Contract(`TestToken9`);
const LoanedToken = await this.props.bZx.getWeb3Contract(`WETH`);
txOpts.data = web3.eth.abi.encodeFunctionSignature('setRates(address,address,uint256)') +
web3.eth.abi.encodeParameters(['address','address','uint256'], [TradeToken._address,LoanedToken._address,toBigNumber(this.state.currentRate, 10 ** 18).div(2).toString()]).substr(2);
console.log(txOpts);
try {
console.log(txOpts);
await web3.eth.sendTransaction(txOpts)
.once(`transactionHash`, hash => {
alert(`Transaction submitted, transaction hash:`, {
component: () => (
<TxHashLink href={`${bZx.etherscanURL}tx/${hash}`}>
{hash}
</TxHashLink>
)
});
this.setState({ showRatesDialog: false });
})
.then(async () => {
alert(`The txn is complete.`);
await this.refreshTokenData();
})
.catch(error => {
console.error(error.message);
alert(`The txn did not complete.`);
this.setState({ showRatesDialog: false });
});
} catch (error) {
console.error(error.message);
alert(`The txn did not complete.`);
this.setState({ showRatesDialog: false });
}
};
render() {
const {
loading,
error,
iTokenContract,
order,
orderAux,
position,
orderFilledAmounts,
orderCancelledAmounts,
currentRate
} = this.state;
const { bZx } = this.props;
if (error) {
return (
<div>
<InfoContainer>
<ShowInfo>Web3 error loading. Please refresh in a few minutes.</ShowInfo>
<Button onClick={this.refreshTokenData} variant="raised" disabled={false}>
Refresh
</Button>
</InfoContainer>
</div>
);
}
return (
<div>
{bZx.networkId === 50 ? ( <Fragment>
<p>
concert load couple harbor equip island argue ramp clarify fence smart topic
</p>
<Divider />
</Fragment> ) : ``}
{bZx.networkId == 50 ? ( <Fragment>
<InfoContainer style={{ display: `block` }}>
<DataPointContainer>
<Label>Conversion Rate</Label>
<DataPoint>
{currentRate ? currentRate : `[refresh]`}
</DataPoint>
</DataPointContainer>
<DataPointContainer>
<Button
variant="raised"
color="primary"
onClick={this.toggleRatesDialog}
style={{ marginLeft: `12px` }}
>
Change Conversion Rate
</Button>
<Button
variant="raised"
color="primary"
onClick={this.halveRate}
style={{ marginLeft: `12px` }}
>
Halve Conversion Rate
</Button>
</DataPointContainer>
</InfoContainer>
<br/>
</Fragment> ) : ``}
<InfoContainer>
<Button
onClick={this.refreshTokenData}
variant="raised"
disabled={loading}
>
{loading ? `Refreshing...` : `Refresh`}
</Button>
</InfoContainer>
<br/>
<InfoContainer>
<ShowInfo>
<DataPointContainer>
{this.state.orderFilledAmounts && this.state.orderCancelledAmounts ? (
<Fragment>
<pre>
{JSON.stringify({
"orderFilledAmount": toBigNumber(
orderFilledAmounts,
10 ** -18
).toString()+` (normalized)`,
"orderCancelledAmount": toBigNumber(
orderCancelledAmounts,
10 ** -18
).toString()+` (normalized)`
}, null, ' ')}
</pre>
</Fragment>
) : ``}
</DataPointContainer>
{/*
<DataPointContainer>
{this.state.order ? (
<Fragment>
<pre>
{JSON.stringify(order, null, ' ')}
</pre>
</Fragment>
) : ``}
</DataPointContainer>
<DataPointContainer>
{this.state.orderAux ? (
<Fragment>
<pre>
{JSON.stringify(orderAux, null, ' ')}
</pre>
</Fragment>
) : ``}
</DataPointContainer>
<DataPointContainer>
{this.state.position ? (
<Fragment>
<pre>
{JSON.stringify(position, null, ' ')}
</pre>
</Fragment>
) : ``}
</DataPointContainer>
*/}
</ShowInfo>
</InfoContainer>
<Dialog
open={this.state.showRatesDialog}
onClose={this.toggleRatesDialog}
>
<DialogTitle>Conversion Rate</DialogTitle>
<DialogContent>
<DialogContentText>
</DialogContentText>
<br/>
<FormControl fullWidth>
<InputLabel>Conversion Rate</InputLabel>
<Input
value={this.state.rates}
type="number"
onChange={this.setRates}
endAdornment={
<InputAdornment position="end"> </InputAdornment>
}
/>
</FormControl>
</DialogContent>
<DialogActions>
<Button onClick={this.toggleRatesDialog}>Cancel</Button>
<Button onClick={this.changeRates} color="primary">
Submit
</Button>
</DialogActions>
</Dialog>
</div>
);
}
}