diff options
Diffstat (limited to 'packages/website/ts/components/eth_wrappers.tsx')
-rw-r--r-- | packages/website/ts/components/eth_wrappers.tsx | 448 |
1 files changed, 0 insertions, 448 deletions
diff --git a/packages/website/ts/components/eth_wrappers.tsx b/packages/website/ts/components/eth_wrappers.tsx deleted file mode 100644 index dc597b18f..000000000 --- a/packages/website/ts/components/eth_wrappers.tsx +++ /dev/null @@ -1,448 +0,0 @@ -import { colors, EtherscanLinkSuffixes, utils as sharedUtils } from '@0x/react-shared'; -import { BigNumber } from '@0x/utils'; -import { Web3Wrapper } from '@0x/web3-wrapper'; -import * as _ from 'lodash'; -import Divider from 'material-ui/Divider'; -import { Table, TableBody, TableHeader, TableHeaderColumn, TableRow, TableRowColumn } from 'material-ui/Table'; -import * as moment from 'moment'; -import * as React from 'react'; -import ReactTooltip from 'react-tooltip'; -import { Blockchain } from 'ts/blockchain'; -import { EthWethConversionButton } from 'ts/components/eth_weth_conversion_button'; -import { Dispatcher } from 'ts/redux/dispatcher'; -import { - OutdatedWrappedEtherByNetworkId, - Side, - Token, - TokenByAddress, - TokenState, - TokenStateByAddress, -} from 'ts/types'; -import { configs } from 'ts/utils/configs'; -import { constants } from 'ts/utils/constants'; -import { utils } from 'ts/utils/utils'; - -const DATE_FORMAT = 'D/M/YY'; -const ICON_DIMENSION = 40; -const ETHER_ICON_PATH = '/images/ether.png'; -const OUTDATED_WETH_ICON_PATH = '/images/wrapped_eth_gray.png'; - -interface EthWrappersProps { - networkId: number; - blockchain: Blockchain; - dispatcher: Dispatcher; - tokenByAddress: TokenByAddress; - userAddress: string; - userEtherBalanceInWei?: BigNumber; - lastForceTokenStateRefetch: number; - isFullWidth?: boolean; -} - -interface EthWrappersState { - ethTokenState: TokenState; - outdatedWETHStateByAddress: TokenStateByAddress; -} - -export class EthWrappers extends React.Component<EthWrappersProps, EthWrappersState> { - public static defaultProps: Partial<EthWrappersProps> = { - isFullWidth: false, - }; - private _isUnmounted: boolean; - constructor(props: EthWrappersProps) { - super(props); - this._isUnmounted = false; - const outdatedWETHAddresses = this._getOutdatedWETHAddresses(); - const outdatedWETHStateByAddress: TokenStateByAddress = {}; - _.each(outdatedWETHAddresses, outdatedWETHAddress => { - outdatedWETHStateByAddress[outdatedWETHAddress] = { - balance: new BigNumber(0), - allowance: new BigNumber(0), - isLoaded: false, - }; - }); - this.state = { - outdatedWETHStateByAddress, - ethTokenState: { - balance: new BigNumber(0), - allowance: new BigNumber(0), - isLoaded: false, - }, - }; - } - public componentWillReceiveProps(nextProps: EthWrappersProps): void { - if ( - nextProps.userAddress !== this.props.userAddress || - nextProps.networkId !== this.props.networkId || - nextProps.lastForceTokenStateRefetch !== this.props.lastForceTokenStateRefetch - ) { - // tslint:disable-next-line:no-floating-promises - this._fetchWETHStateAsync(); - } - } - public componentDidMount(): void { - window.scrollTo(0, 0); - // tslint:disable-next-line:no-floating-promises - this._fetchWETHStateAsync(); - } - public componentWillUnmount(): void { - this._isUnmounted = true; - } - public render(): React.ReactNode { - const etherToken = this._getEthToken(); - const wethBalance = Web3Wrapper.toUnitAmount(this.state.ethTokenState.balance, constants.DECIMAL_PLACES_ETH); - const isBidirectional = true; - const etherscanUrl = sharedUtils.getEtherScanLinkIfExists( - etherToken.address, - this.props.networkId, - EtherscanLinkSuffixes.Address, - ); - const tokenLabel = this._renderToken( - 'Wrapped Ether', - etherToken.address, - utils.getTokenIconUrl(etherToken.symbol), - ); - const userEtherBalanceInEth = !_.isUndefined(this.props.userEtherBalanceInWei) - ? Web3Wrapper.toUnitAmount(this.props.userEtherBalanceInWei, constants.DECIMAL_PLACES_ETH) - : undefined; - const rootClassName = this.props.isFullWidth ? 'clearfix' : 'clearfix lg-px4 md-px4 sm-px2'; - return ( - <div className={rootClassName} style={{ minHeight: 600 }}> - <div className="relative"> - <h3>ETH Wrapper</h3> - <div className="absolute" style={{ top: 0, right: 0 }}> - <a target="_blank" href={constants.URL_WETH_IO} style={{ color: colors.grey }}> - <div className="flex"> - <div>About Wrapped ETH</div> - <div className="pl1"> - <i className="zmdi zmdi-open-in-new" /> - </div> - </div> - </a> - </div> - </div> - <Divider /> - <div> - <div className="py2">Wrap ETH into an ERC20-compliant Ether token. 1 ETH = 1 WETH.</div> - <div> - <Table selectable={false} style={{ backgroundColor: 'transparent' }}> - <TableHeader displaySelectAll={false} adjustForCheckbox={false}> - <TableRow> - <TableHeaderColumn>ETH Token</TableHeaderColumn> - <TableHeaderColumn>Balance</TableHeaderColumn> - <TableHeaderColumn className="center"> - {this._renderActionColumnTitle(isBidirectional)} - </TableHeaderColumn> - </TableRow> - </TableHeader> - <TableBody displayRowCheckbox={false}> - <TableRow key="ETH"> - <TableRowColumn className="py1"> - <div className="flex"> - <img - style={{ - width: ICON_DIMENSION, - height: ICON_DIMENSION, - }} - src={ETHER_ICON_PATH} - /> - <div className="ml2 sm-hide xs-hide" style={{ marginTop: 12 }}> - ETH - </div> - </div> - </TableRowColumn> - <TableRowColumn> - {!_.isUndefined(userEtherBalanceInEth) ? ( - `${userEtherBalanceInEth.toFixed(configs.AMOUNT_DISPLAY_PRECSION)} ETH` - ) : ( - <i className="zmdi zmdi-spinner zmdi-hc-spin" /> - )} - </TableRowColumn> - <TableRowColumn> - <EthWethConversionButton - refetchEthTokenStateAsync={this._refetchEthTokenStateAsync.bind(this)} - lastForceTokenStateRefetch={this.props.lastForceTokenStateRefetch} - userAddress={this.props.userAddress} - networkId={this.props.networkId} - isOutdatedWrappedEther={false} - direction={Side.Deposit} - ethToken={etherToken} - dispatcher={this.props.dispatcher} - blockchain={this.props.blockchain} - userEtherBalanceInWei={this.props.userEtherBalanceInWei} - isDisabled={_.isUndefined(userEtherBalanceInEth)} - /> - </TableRowColumn> - </TableRow> - <TableRow key="WETH"> - <TableRowColumn className="py1"> - {this._renderTokenLink(tokenLabel, etherscanUrl)} - </TableRowColumn> - <TableRowColumn> - {this.state.ethTokenState.isLoaded ? ( - `${wethBalance.toFixed(configs.AMOUNT_DISPLAY_PRECSION)} WETH` - ) : ( - <i className="zmdi zmdi-spinner zmdi-hc-spin" /> - )} - </TableRowColumn> - <TableRowColumn> - <EthWethConversionButton - refetchEthTokenStateAsync={this._refetchEthTokenStateAsync.bind(this)} - lastForceTokenStateRefetch={this.props.lastForceTokenStateRefetch} - userAddress={this.props.userAddress} - networkId={this.props.networkId} - isOutdatedWrappedEther={false} - direction={Side.Receive} - isDisabled={!this.state.ethTokenState.isLoaded} - ethToken={etherToken} - dispatcher={this.props.dispatcher} - blockchain={this.props.blockchain} - userEtherBalanceInWei={this.props.userEtherBalanceInWei} - /> - </TableRowColumn> - </TableRow> - </TableBody> - </Table> - </div> - </div> - <div> - <h4>Outdated WETH</h4> - <Divider /> - <div className="pt2" style={{ lineHeight: 1.5 }}> - The{' '} - <a href={constants.URL_CANONICAL_WETH_POST} target="_blank"> - canonical WETH - </a>{' '} - contract is updated when necessary. Unwrap outdated WETH in order to
retrieve your ETH and move - it to the updated WETH token. - </div> - <div> - <Table selectable={false} style={{ backgroundColor: 'transparent' }}> - <TableHeader displaySelectAll={false} adjustForCheckbox={false}> - <TableRow> - <TableHeaderColumn>WETH Version</TableHeaderColumn> - <TableHeaderColumn>Balance</TableHeaderColumn> - <TableHeaderColumn className="center"> - {this._renderActionColumnTitle(!isBidirectional)} - </TableHeaderColumn> - </TableRow> - </TableHeader> - <TableBody displayRowCheckbox={false}>{this._renderOutdatedWeths(etherToken)}</TableBody> - </Table> - </div> - </div> - </div> - ); - } - private _renderActionColumnTitle(isBidirectional: boolean): React.ReactNode { - let iconClass = 'zmdi-long-arrow-right'; - let leftSymbol = 'WETH'; - let rightSymbol = 'ETH'; - if (isBidirectional) { - iconClass = 'zmdi-swap'; - leftSymbol = 'ETH'; - rightSymbol = 'WETH'; - } - return ( - <div className="flex mx-auto" style={{ width: 85 }}> - <div style={{ paddingTop: 3 }}>{leftSymbol}</div> - <div className="px1"> - <i style={{ fontSize: 18 }} className={`zmdi ${iconClass}`} /> - </div> - <div style={{ paddingTop: 3 }}>{rightSymbol}</div> - </div> - ); - } - private _renderOutdatedWeths(etherToken: Token): React.ReactNode { - const rows = _.map( - configs.OUTDATED_WRAPPED_ETHERS, - (outdatedWETHByNetworkId: OutdatedWrappedEtherByNetworkId) => { - const outdatedWETHIfExists = outdatedWETHByNetworkId[this.props.networkId]; - if (_.isUndefined(outdatedWETHIfExists)) { - return null; // noop - } - const timestampMsRange = outdatedWETHIfExists.timestampMsRange; - let dateRange: string; - if (!_.isUndefined(timestampMsRange)) { - const startMoment = moment(timestampMsRange.startTimestampMs); - const endMoment = moment(timestampMsRange.endTimestampMs); - dateRange = `${startMoment.format(DATE_FORMAT)}-${endMoment.format(DATE_FORMAT)}`; - } else { - dateRange = '-'; - } - const outdatedEtherToken = { - ...etherToken, - address: outdatedWETHIfExists.address, - }; - const outdatedEtherTokenState = this.state.outdatedWETHStateByAddress[outdatedWETHIfExists.address]; - const isStateLoaded = outdatedEtherTokenState.isLoaded; - const balanceInEthIfExists = isStateLoaded - ? Web3Wrapper.toUnitAmount(outdatedEtherTokenState.balance, constants.DECIMAL_PLACES_ETH).toFixed( - configs.AMOUNT_DISPLAY_PRECSION, - ) - : undefined; - const onConversionSuccessful = this._onOutdatedConversionSuccessfulAsync.bind( - this, - outdatedWETHIfExists.address, - ); - const etherscanUrl = sharedUtils.getEtherScanLinkIfExists( - outdatedWETHIfExists.address, - this.props.networkId, - EtherscanLinkSuffixes.Address, - ); - const tokenLabel = this._renderToken(dateRange, outdatedEtherToken.address, OUTDATED_WETH_ICON_PATH); - return ( - <TableRow key={`weth-${outdatedWETHIfExists.address}`}> - <TableRowColumn className="py1"> - {this._renderTokenLink(tokenLabel, etherscanUrl)} - </TableRowColumn> - <TableRowColumn> - {isStateLoaded ? ( - `${balanceInEthIfExists} WETH` - ) : ( - <i className="zmdi zmdi-spinner zmdi-hc-spin" /> - )} - </TableRowColumn> - <TableRowColumn> - <EthWethConversionButton - refetchEthTokenStateAsync={this._refetchEthTokenStateAsync.bind(this)} - lastForceTokenStateRefetch={this.props.lastForceTokenStateRefetch} - userAddress={this.props.userAddress} - networkId={this.props.networkId} - isDisabled={!isStateLoaded} - isOutdatedWrappedEther={true} - direction={Side.Receive} - ethToken={outdatedEtherToken} - dispatcher={this.props.dispatcher} - blockchain={this.props.blockchain} - userEtherBalanceInWei={this.props.userEtherBalanceInWei} - onConversionSuccessful={onConversionSuccessful} - /> - </TableRowColumn> - </TableRow> - ); - }, - ); - return rows; - } - private _renderTokenLink(tokenLabel: React.ReactNode, etherscanUrl: string): React.ReactNode { - return ( - <span> - {_.isUndefined(etherscanUrl) ? ( - tokenLabel - ) : ( - <a href={etherscanUrl} target="_blank" style={{ textDecoration: 'none' }}> - {tokenLabel} - </a> - )} - </span> - ); - } - private _renderToken(name: string, address: string, imgPath: string): React.ReactNode { - const tooltipId = `tooltip-${address}`; - return ( - <div className="flex"> - <img style={{ width: ICON_DIMENSION, height: ICON_DIMENSION }} src={imgPath} /> - <div className="ml2 sm-hide xs-hide" style={{ marginTop: 12 }}> - <span data-tip={true} data-for={tooltipId}> - {name} - </span> - <ReactTooltip id={tooltipId}>{address}</ReactTooltip> - </div> - </div> - ); - } - private async _onOutdatedConversionSuccessfulAsync(outdatedWETHAddress: string): Promise<void> { - const currentOutdatedWETHState = this.state.outdatedWETHStateByAddress[outdatedWETHAddress]; - this.setState({ - outdatedWETHStateByAddress: { - ...this.state.outdatedWETHStateByAddress, - [outdatedWETHAddress]: { - balance: currentOutdatedWETHState.balance, - allowance: currentOutdatedWETHState.allowance, - isLoaded: false, - }, - }, - }); - const userAddressIfExists = _.isEmpty(this.props.userAddress) ? undefined : this.props.userAddress; - const [balance, allowance] = await this.props.blockchain.getTokenBalanceAndAllowanceAsync( - userAddressIfExists, - outdatedWETHAddress, - ); - this.setState({ - outdatedWETHStateByAddress: { - ...this.state.outdatedWETHStateByAddress, - [outdatedWETHAddress]: { - balance, - allowance, - isLoaded: true, - }, - }, - }); - } - private async _fetchWETHStateAsync(): Promise<void> { - const tokens = _.values(this.props.tokenByAddress); - const wethToken = _.find(tokens, token => token.symbol === 'WETH'); - const userAddressIfExists = _.isEmpty(this.props.userAddress) ? undefined : this.props.userAddress; - const [wethBalance, wethAllowance] = await this.props.blockchain.getTokenBalanceAndAllowanceAsync( - userAddressIfExists, - wethToken.address, - ); - - const outdatedWETHAddresses = this._getOutdatedWETHAddresses(); - const outdatedWETHStateByAddress: TokenStateByAddress = {}; - for (const address of outdatedWETHAddresses) { - const [balance, allowance] = await this.props.blockchain.getTokenBalanceAndAllowanceAsync( - userAddressIfExists, - address, - ); - outdatedWETHStateByAddress[address] = { - balance, - allowance, - isLoaded: true, - }; - } - if (!this._isUnmounted) { - this.setState({ - outdatedWETHStateByAddress, - ethTokenState: { - balance: wethBalance, - allowance: wethAllowance, - isLoaded: true, - }, - }); - } - } - private _getOutdatedWETHAddresses(): string[] { - const outdatedWETHAddresses = _.compact( - _.map(configs.OUTDATED_WRAPPED_ETHERS, outdatedWrappedEtherByNetwork => { - const outdatedWrappedEtherIfExists = outdatedWrappedEtherByNetwork[this.props.networkId]; - if (_.isUndefined(outdatedWrappedEtherIfExists)) { - return undefined; - } - const address = outdatedWrappedEtherIfExists.address; - return address; - }), - ); - return outdatedWETHAddresses; - } - private _getEthToken(): Token { - const tokens = _.values(this.props.tokenByAddress); - const etherToken = _.find(tokens, { symbol: 'WETH' }); - return etherToken; - } - private async _refetchEthTokenStateAsync(): Promise<void> { - const etherToken = this._getEthToken(); - const userAddressIfExists = _.isEmpty(this.props.userAddress) ? undefined : this.props.userAddress; - const [balance, allowance] = await this.props.blockchain.getTokenBalanceAndAllowanceAsync( - userAddressIfExists, - etherToken.address, - ); - this.setState({ - ethTokenState: { - balance, - allowance, - isLoaded: true, - }, - }); - } -} // tslint:disable:max-file-line-count |