import * as _ from 'lodash'; import RaisedButton from 'material-ui/RaisedButton'; import * as React from 'react'; import DocumentTitle = require('react-document-title'); import { Link } from 'react-router-dom'; import { Footer } from 'ts/components/footer'; import { TopBar } from 'ts/components/top_bar'; import { ScreenWidths, WebsitePaths } from 'ts/types'; import { colors } from 'ts/utils/colors'; import { constants } from 'ts/utils/constants'; import { utils } from 'ts/utils/utils'; interface BoxContent { title: string; description: string; imageUrl: string; classNames: string; } interface AssetType { title: string; imageUrl: string; style?: React.CSSProperties; } interface UseCase { imageUrl: string; type: string; description: string; classNames: string; style?: React.CSSProperties; projectIconUrls: string[]; } interface Project { logoFileName: string; projectUrl: string; } const THROTTLE_TIMEOUT = 100; const boxContents: BoxContent[] = [ { title: 'Trustless exchange', description: "Built on Ethereum's distributed network with no centralized \ point of failure and no down time, each trade is settled atomically \ and without counterparty risk.", imageUrl: '/images/landing/distributed_network.png', classNames: '', }, { title: 'Shared liquidity', description: 'By sharing a standard API, relayers can easily aggregate liquidity pools, \ creating network effects around liquidity that compound as more relayers come online.', imageUrl: '/images/landing/liquidity.png', classNames: 'mx-auto', }, { title: 'Open source', description: '0x is open source, permissionless and free to use. Trade directly with a known \ counterparty for free or pay a relayer some ZRX tokens to access their liquidity \ pool.', imageUrl: '/images/landing/open_source.png', classNames: 'right', }, ]; const projects: Project[] = [ { logoFileName: 'ethfinex-top.png', projectUrl: constants.PROJECT_URL_ETHFINEX, }, { logoFileName: 'radar_relay_top.png', projectUrl: constants.PROJECT_URL_RADAR_RELAY, }, { logoFileName: 'paradex_top.png', projectUrl: constants.PROJECT_URL_PARADEX, }, { logoFileName: 'the_ocean.png', projectUrl: constants.PROJECT_URL_0CEAN, }, { logoFileName: 'dydx.png', projectUrl: constants.PROJECT_URL_DYDX, }, { logoFileName: 'melonport.png', projectUrl: constants.PROJECT_URL_MELONPORT, }, { logoFileName: 'maker.png', projectUrl: constants.PROJECT_URL_MAKER, }, { logoFileName: 'dharma.png', projectUrl: constants.PROJECT_URL_DHARMA, }, { logoFileName: 'lendroid.png', projectUrl: constants.PROJECT_URL_LENDROID, }, { logoFileName: 'district0x.png', projectUrl: constants.PROJECT_URL_DISTRICT_0X, }, { logoFileName: 'aragon.png', projectUrl: constants.PROJECT_URL_ARAGON, }, { logoFileName: 'blocknet.png', projectUrl: constants.PROJECT_URL_BLOCKNET, }, { logoFileName: 'status.png', projectUrl: constants.PROJECT_URL_STATUS, }, { logoFileName: 'augur.png', projectUrl: constants.PROJECT_URL_AUGUR, }, { logoFileName: 'anx.png', projectUrl: constants.PROJECT_URL_OPEN_ANX, }, { logoFileName: 'auctus.png', projectUrl: constants.PROJECT_URL_AUCTUS, }, ]; export interface LandingProps { location: Location; } interface LandingState { screenWidth: ScreenWidths; } export class Landing extends React.Component { private _throttledScreenWidthUpdate: () => void; constructor(props: LandingProps) { super(props); this.state = { screenWidth: utils.getScreenWidth(), }; this._throttledScreenWidthUpdate = _.throttle(this._updateScreenWidth.bind(this), THROTTLE_TIMEOUT); } public componentDidMount() { window.addEventListener('resize', this._throttledScreenWidthUpdate); window.scrollTo(0, 0); } public componentWillUnmount() { window.removeEventListener('resize', this._throttledScreenWidthUpdate); } public render() { return (
{this._renderHero()} {this._renderProjects()} {this._renderTokenizationSection()} {this._renderProtocolSection()} {this._renderInfoBoxes()} {this._renderBuildingBlocksSection()} {this._renderUseCases()} {this._renderCallToAction()}
); } private _renderHero() { const isSmallScreen = this.state.screenWidth === ScreenWidths.Sm; const buttonLabelStyle: React.CSSProperties = { textTransform: 'none', fontSize: isSmallScreen ? 12 : 14, fontWeight: 400, }; const lightButtonStyle: React.CSSProperties = { borderRadius: 6, border: '1px solid #D8D8D8', lineHeight: '33px', height: 38, }; const left = 'col lg-col-7 md-col-7 col-12 lg-pt4 md-pt4 sm-pt0 mt1 lg-pl4 md-pl4 sm-pl0 sm-px3 sm-center'; return (
Powering decentralized exchange
0x is an open, permissionless protocol allowing for ERC20 tokens to be traded on the Ethereum blockchain.
); } private _renderProjects() { const isSmallScreen = this.state.screenWidth === ScreenWidths.Sm; const isMediumScreen = this.state.screenWidth === ScreenWidths.Md; const projectList = _.map(projects, (project: Project, i: number) => { const colWidth = isSmallScreen ? 3 : isMediumScreen ? 4 : 2 - i % 2; return (
); }); const titleStyle: React.CSSProperties = { fontFamily: 'Roboto Mono', color: colors.grey, textTransform: 'uppercase', fontWeight: 300, letterSpacing: 3, }; return (
Projects building on 0x
{projectList}
view the{' '} full list
); } private _renderTokenizationSection() { const isSmallScreen = this.state.screenWidth === ScreenWidths.Sm; return (
{isSmallScreen && this._renderTokenCloud()}
The world's value is becoming tokenized
{isSmallScreen ? ( The Ethereum blockchain is an open, borderless financial system that represents a wide variety of assets as cryptographic tokens. In the future, most digital assets and goods will be tokenized. ) : (
The Ethereum blockchain is an open, borderless financial system that represents
a wide variety of assets as cryptographic tokens. In the future, most digital assets and goods will be tokenized.
)}
{this._renderAssetTypes()}
{!isSmallScreen && this._renderTokenCloud()}
); } private _renderProtocolSection() { const isSmallScreen = this.state.screenWidth === ScreenWidths.Sm; return (
Off-chain order relay
On-chain settlement
In 0x protocol, orders are transported off-chain, massively reducing gas costs and eliminating blockchain bloat. Relayers help broadcast orders and collect a fee each time they facilitate a trade. Anyone can build a relayer.
RELAYERS BUILDING ON 0X
view all
); } private _renderBuildingBlocksSection() { const isSmallScreen = this.state.screenWidth === ScreenWidths.Sm; const descriptionStyle: React.CSSProperties = { fontFamily: 'Roboto Mono', lineHeight: isSmallScreen ? 1.5 : 2, fontWeight: 300, fontSize: 15, maxWidth: isSmallScreen ? 375 : 'none', }; const callToActionStyle: React.CSSProperties = { fontFamily: 'Roboto Mono', fontSize: 15, fontWeight: 300, maxWidth: isSmallScreen ? 375 : 441, }; return (
{isSmallScreen && this._renderBlockChipImage()}
A building block for dApps
0x protocol is a pluggable building block for dApps that require exchange functionality. Join the many developers that are already using 0x in their web applications and smart contracts.
Learn how in our{' '} 0x.js {' '} and{' '} smart contract {' '} docs
{!isSmallScreen && this._renderBlockChipImage()}
); } private _renderBlockChipImage() { const isSmallScreen = this.state.screenWidth === ScreenWidths.Sm; return (
); } private _renderTokenCloud() { const isSmallScreen = this.state.screenWidth === ScreenWidths.Sm; return (
); } private _renderAssetTypes() { const isSmallScreen = this.state.screenWidth === ScreenWidths.Sm; const assetTypes: AssetType[] = [ { title: 'Currency', imageUrl: '/images/landing/currency.png', }, { title: 'Traditional assets', imageUrl: '/images/landing/stocks.png', style: { paddingLeft: isSmallScreen ? 41 : 56, paddingRight: isSmallScreen ? 41 : 56, }, }, { title: 'Digital goods', imageUrl: '/images/landing/digital_goods.png', }, ]; const assets = _.map(assetTypes, (assetType: AssetType) => { const style = _.isUndefined(assetType.style) ? {} : assetType.style; return (
{assetType.title}
); }); return assets; } private _renderInfoBoxes() { const isSmallScreen = this.state.screenWidth === ScreenWidths.Sm; const boxStyle: React.CSSProperties = { maxWidth: 252, height: 386, backgroundColor: colors.grey50, borderRadius: 5, padding: '10px 24px 24px', }; const boxes = _.map(boxContents, (boxContent: BoxContent) => { return (
{boxContent.title}
{boxContent.description}
); }); return (
{boxes}
); } private _renderUseCases() { const isSmallScreen = this.state.screenWidth === ScreenWidths.Sm; const useCases: UseCase[] = [ { imageUrl: '/images/landing/governance_icon.png', type: 'Decentralized governance', description: 'Decentralized organizations use tokens to represent ownership and \ guide their governance logic. 0x allows decentralized organizations \ to seamlessly and safely trade ownership for startup capital.', projectIconUrls: ['/images/landing/aragon.png'], classNames: 'lg-px2 md-px2', }, { imageUrl: '/images/landing/prediction_market_icon.png', type: 'Prediction markets', description: 'Decentralized prediction market platforms generate sets of tokens that \ represent a financial stake in the outcomes of real-world events. 0x allows \ these tokens to be instantly tradable.', projectIconUrls: ['/images/landing/augur.png'], classNames: 'lg-px2 md-px2', }, { imageUrl: '/images/landing/stable_tokens_icon.png', type: 'Stable tokens', description: 'Novel economic constructs such as stable coins require efficient, liquid \ markets to succeed. 0x will facilitate the underlying economic mechanisms \ that allow these tokens to remain stable.', projectIconUrls: ['/images/landing/maker.png'], classNames: 'lg-px2 md-px2', }, { imageUrl: '/images/landing/loans_icon.png', type: 'Decentralized loans', description: 'Efficient lending requires liquid markets where investors can buy and re-sell loans. \ 0x enables an ecosystem of lenders to self-organize and efficiently determine \ market prices for all outstanding loans.', projectIconUrls: ['/images/landing/dharma.png', '/images/landing/lendroid.png'], classNames: 'lg-pr2 md-pr2 lg-col-6 md-col-6', style: { width: 291, float: 'right', marginTop: !isSmallScreen ? 38 : 0, }, }, { imageUrl: '/images/landing/fund_management_icon.png', type: 'Fund management', description: 'Decentralized fund management limits fund managers to investing in pre-agreed \ upon asset classes. Embedding 0x into fund management smart contracts enables \ them to enforce these security constraints.', projectIconUrls: ['/images/landing/melonport.png'], classNames: 'lg-pl2 md-pl2 lg-col-6 md-col-6', style: { width: 291, marginTop: !isSmallScreen ? 38 : 0 }, }, ]; const cases = _.map(useCases, (useCase: UseCase) => { const style = _.isUndefined(useCase.style) || isSmallScreen ? {} : useCase.style; const useCaseBoxStyle = { color: colors.grey, border: '1px solid #565656', borderRadius: 4, maxWidth: isSmallScreen ? 375 : 'none', ...style, }; const typeStyle: React.CSSProperties = { color: colors.lightGrey, fontSize: 13, textTransform: 'uppercase', fontFamily: 'Roboto Mono', fontWeight: 300, }; return (
{useCase.type}
{useCase.description}
); }); return (
{cases}
); } private _renderCallToAction() { const isSmallScreen = this.state.screenWidth === ScreenWidths.Sm; const buttonLabelStyle: React.CSSProperties = { textTransform: 'none', fontSize: 15, fontWeight: 400, }; const lightButtonStyle: React.CSSProperties = { borderRadius: 6, border: '1px solid #a0a0a0', lineHeight: '33px', height: 49, }; const callToActionClassNames = 'col lg-col-8 md-col-8 col-12 lg-pr3 md-pr3 \ lg-right-align md-right-align sm-center sm-px3 h4'; return (
Get started on building the decentralized future
); } private _updateScreenWidth() { const newScreenWidth = utils.getScreenWidth(); if (newScreenWidth !== this.state.screenWidth) { this.setState({ screenWidth: newScreenWidth, }); } } } // tslint:disable:max-file-line-count