Skip to content

Commit

Permalink
Merge pull request #141 from poanetwork/support-rsk
Browse files Browse the repository at this point in the history
Added support of work through public RPC nodes that do not support `eth_getLogs` call: e.g. Rootstock public RPC.
  • Loading branch information
akolotov authored Dec 11, 2018
2 parents b82c2a8 + 671f054 commit b8a4306
Show file tree
Hide file tree
Showing 18 changed files with 223 additions and 68 deletions.
10 changes: 10 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ REACT_APP_HOME_NATIVE_NAME=POA
REACT_APP_HOME_NETWORK_NAME="POA Sokol"
REACT_APP_FOREIGN_NETWORK_NAME=Kovan

# Set to true if network doesn't support events
REACT_APP_HOME_WITHOUT_EVENTS=false
REACT_APP_FOREIGN_WITHOUT_EVENTS=false

REACT_APP_HOME_EXPLORER_TX_TEMPLATE=https://blockscout.com/poa/sokol/tx/%s
REACT_APP_FOREIGN_EXPLORER_TX_TEMPLATE=https://blockscout.com/eth/kovan/tx/%s
REACT_APP_HOME_EXPLORER_ADDRESS_TEMPLATE=https://blockscout.com/poa/sokol/address/%s
Expand All @@ -21,3 +25,9 @@ REACT_APP_FOREIGN_GAS_PRICE_ORACLE_URL=https://gasprice.poa.network/
REACT_APP_FOREIGN_GAS_PRICE_SPEED_TYPE=standard
REACT_APP_FOREIGN_GAS_PRICE_FALLBACK=5000000000
REACT_APP_FOREIGN_GAS_PRICE_UPDATE_INTERVAL=15000

# Default
REACT_APP_DESCRIPTION="The POA cross-chain bridge serves as a method of transferring POA native tokens from the POA Network to the Ethereum network in a quick and cost-efficient manner."

# RSK
#REACT_APP_DESCRIPTION="The TokenBridge serves as a method of transferring Bancor Network tokens between the Ethereum network to Rootstock network in a quick and cost-efficient manner."
7 changes: 5 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# POA Bridge - User Interface (UI) Application

[![Build Status](https://travis-ci.org/patitonar/bridge-ui.svg?branch=master)](https://travis-ci.org/patitonar/bridge-ui)
[![Build Status](https://travis-ci.org/poanetwork/bridge-ui.svg?branch=master)](https://travis-ci.org/poanetwork/bridge-ui)
[![Gitter](https://badges.gitter.im/poanetwork/poa-bridge.svg)](https://gitter.im/poanetwork/poa-bridge?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
[![Coverage Status](https://coveralls.io/repos/github/patitonar/bridge-ui/badge.svg?branch=master)](https://coveralls.io/github/patitonar/bridge-ui?branch=master)
[![Coverage Status](https://coveralls.io/repos/github/poanetwork/bridge-ui/badge.svg?branch=master)](https://coveralls.io/github/poanetwork/bridge-ui?branch=master)
[![dependencies Status](https://david-dm.org/poanetwork/bridge-ui/status.svg)](https://david-dm.org/poanetwork/bridge-ui)

Welcome to the POA Bridge! Following is an overview of the POA Bridge and Bridge UI Application, as well as [basic instructions for getting started](#getting-started).
Expand Down Expand Up @@ -165,6 +165,8 @@ REACT_APP_HOME_HTTP_PARITY_URL | http public rpc node for Foreign Network
REACT_APP_HOME_NATIVE_NAME | name of the home native coin
REACT_APP_HOME_NETWORK_NAME | name to be displayed for home network
REACT_APP_FOREIGN_NETWORK_NAME | name to be displayed for foreign network
REACT_APP_HOME_WITHOUT_EVENTS | `true` if home network doesn't support events
REACT_APP_FOREIGN_WITHOUT_EVENTS | `true` if foreign network doesn't support events
REACT_APP_HOME_EXPLORER_TX_TEMPLATE | template link to transaction on home explorer. `%s` will be replaced by transaction hash
REACT_APP_FOREIGN_EXPLORER_TX_TEMPLATE | template link to transaction on foreign explorer. `%s` will be replaced by transaction hash
REACT_APP_HOME_EXPLORER_ADDRESS_TEMPLATE | template link to address on home explorer. `%s` will be replaced by address
Expand All @@ -177,6 +179,7 @@ REACT_APP_FOREIGN_GAS_PRICE_ORACLE_URL | The URL used to get a JSON response fro
REACT_APP_FOREIGN_GAS_PRICE_SPEED_TYPE | Gas Price speed (slow, standard, fast, instant)
REACT_APP_FOREIGN_GAS_PRICE_FALLBACK | The gas price (in Wei) that is used if both the oracle and the fall back gas price specified in the Foreign Bridge contract are not available.
REACT_APP_FOREIGN_GAS_PRICE_UPDATE_INTERVAL | An interval in milliseconds used to get the updated gas price value either from the oracle or from the Foreign Bridge contract.
REACT_APP_DESCRIPTION | The meta description for the deployed bridge page

* Run `npm run start`
* Make sure your web3 wallet (Nifty Wallet or MetaMask) is funded and connected to the POA Sokol Network (see step 2)
Expand Down
30 changes: 24 additions & 6 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
"react-app-rewired": "^1.5.0",
"react-copy-to-clipboard": "^5.0.1",
"react-dom": "^16.2.0",
"react-router": "^4.3.1",
"react-router-dom": "^4.2.2",
"react-scripts": "1.1.1",
"react-transition-group": "^2.2.1",
Expand Down
2 changes: 1 addition & 1 deletion public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="theme-color" content="#000000">
<meta property="og:title" content="POA Bridge UI" />
<meta property="og:description" content="The POA cross-chain bridge serves as a method of transferring POA native tokens from the POA Network to the Ethereum network in a quick and cost-efficient manner. " />
<meta property="og:description" content="%REACT_APP_DESCRIPTION%" />
<meta property="og:url" content="https://poanetwork.github.io/bridge-ui" />
<meta property="og:type" content="website" />
<meta property="og:image" content="/images/bridgeogimage.jpg">
Expand Down
2 changes: 1 addition & 1 deletion src/assets/stylesheets/application.css

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions src/assets/stylesheets/application/header.scss
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
display: flex;
justify-content: space-between;
align-items: center;
width: 600px;
max-width: 700px;

@media screen and (max-width: $mobile-width) {
display: none;
Expand All @@ -57,7 +57,7 @@
}

.link {
margin-left: 30px;
margin: 0 15px;
line-height: 16px;
text-decoration: none;
font-weight: bold;
Expand Down
6 changes: 4 additions & 2 deletions src/components/Bridge.js
Original file line number Diff line number Diff line change
Expand Up @@ -94,11 +94,13 @@ export class Bridge extends React.Component {
tokenAddress: homeStore.tokenAddress
})
} else {
const value = Web3Utils.toHex(Web3Utils.toWei(amount))
return txStore.doSend({
to: homeStore.HOME_BRIDGE_ADDRESS,
from: web3Store.defaultAccount.address,
value: Web3Utils.toHex(Web3Utils.toWei(amount)),
data: '0x'
value,
data: '0x',
sentValue: value
})
}
} catch (e) {
Expand Down
41 changes: 26 additions & 15 deletions src/components/Header.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,42 +6,53 @@ import menuOpenIcon from '../assets/images/icons/icon-close.svg'
import { Wallet } from './Wallet'
import { DailyQuotaModal } from './DailyQuotaModal'
import { inject, observer } from 'mobx-react/index'
import yn from './utils/yn'

const getMobileMenuLinks = (onMenuToggle) =>
const getMobileMenuLinks = (onMenuToggle, withoutEvents) =>
(<div className="links_container_mobile">
<Link to='/events' className="link" onClick={onMenuToggle}>
<i className="icon_events" /><span className='link_text'>Events</span>
</Link>
{withoutEvents ? null :
<Link to='/events' className="link" onClick={onMenuToggle}>
<i className="icon_events" /><span className='link_text'>Events</span>
</Link>
}
<Link to='/status' className="link" onClick={onMenuToggle}>
<i className="icon_status" /><span className='link_text'>Status</span>
</Link>
<Link to='/statistics' className="link" onClick={onMenuToggle}>
<i className="icon_statistics" /><span className='link_text'>Statistics</span>
</Link>
{withoutEvents ? null :
<Link to='/statistics' className="link" onClick={onMenuToggle}>
<i className="icon_statistics" /><span className='link_text'>Statistics</span>
</Link>
}
</div>)


@inject("RootStore")
@observer
export class Header extends React.Component {
render () {
const {showMobileMenu, onMenuToggle, RootStore: {alertStore}} = this.props
const { showMobileMenu, onMenuToggle, RootStore: { alertStore, web3Store } } = this.props
const { REACT_APP_HOME_WITHOUT_EVENTS: HOME, REACT_APP_FOREIGN_WITHOUT_EVENTS: FOREIGN } = process.env
const withoutEvents = web3Store.metamaskNet.id === web3Store.homeNet.id.toString() ? yn(HOME) : yn(FOREIGN)
return (
<header className="header">
{showMobileMenu && (<div className="header-mobile-menu-container">{getMobileMenuLinks(onMenuToggle)}</div>)}
{showMobileMenu && (<div className="header-mobile-menu-container">{getMobileMenuLinks(onMenuToggle, withoutEvents)}</div>)}
<div className="container">
<Link to="/" onClick={showMobileMenu ? onMenuToggle : null}><img className="header-logo" src={logo}
alt=""/></Link>
<div className="links_container">
<Link to='/events' className="link">
<i className="icon_events"/><span className='link_text'>Events</span>
</Link>
{withoutEvents ? null :
<Link to='/events' className="link">
<i className="icon_events"/><span className='link_text'>Events</span>
</Link>
}
<Link to='/status' className="link">
<i className="icon_status"/><span className='link_text'>Status</span>
</Link>
<Link to='/statistics' className="link">
<i className="icon_statistics"/><span className='link_text'>Statistics</span>
</Link>
{withoutEvents ? null :
<Link to='/statistics' className="link">
<i className="icon_statistics"/><span className='link_text'>Statistics</span>
</Link>
}
<Wallet/>
</div>
<div className="mobile-menu">
Expand Down
8 changes: 6 additions & 2 deletions src/components/RelayEvents.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import React from 'react';
import { inject, observer } from "mobx-react";
import { EventsListHeader } from './index'
import { Event } from './index'
import yn from './utils/yn'
import { Redirect } from 'react-router'


const WAIT_INTERVAL = 700;
Expand Down Expand Up @@ -132,12 +134,14 @@ export class RelayEvents extends React.Component {
}

render(){
const { homeStore, foreignStore } = this.props.RootStore
const { homeStore, foreignStore, web3Store } = this.props.RootStore
const { selectedList } = this.state
const home = this.getHomeEvents(homeStore, foreignStore)
const foreign = this.getForeignEvents(foreignStore, homeStore)
const { REACT_APP_HOME_WITHOUT_EVENTS: HOME, REACT_APP_FOREIGN_WITHOUT_EVENTS: FOREIGN } = process.env
const withoutEvents = web3Store.metamaskNet.id === web3Store.homeNet.id.toString() ? yn(HOME) : yn(FOREIGN)

return(
return withoutEvents ? (<Redirect to="/" />) : (
<div className="events-page">
<div className="events-container">
<EventsListHeader
Expand Down
25 changes: 15 additions & 10 deletions src/components/StatisticsPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,30 +4,35 @@ import pattern from '../assets/images/pattern.svg'
import { BridgeStatistics } from './index'
import { TransactionsStatistics } from './TransactionsStatistics'
import { BRIDGE_MODES } from '../stores/utils/bridgeMode'
import yn from './utils/yn'
import { Redirect } from 'react-router'

@inject("RootStore")
@observer
export class StatisticsPage extends React.Component {

render(){
const { homeStore, foreignStore, bridgeMode } = this.props.RootStore
const { homeStore, foreignStore, bridgeMode, web3Store } = this.props.RootStore
const isNativeToErc = bridgeMode === BRIDGE_MODES.NATIVE_TO_ERC
const leftTitle = isNativeToErc ? 'Deposits' : 'Withdraws'
const rightTitle = isNativeToErc ? 'Withdraws' : 'Deposits'
return(
const { REACT_APP_HOME_WITHOUT_EVENTS: HOME, REACT_APP_FOREIGN_WITHOUT_EVENTS: FOREIGN } = process.env
const withoutEvents = web3Store.metamaskNet.id === web3Store.homeNet.id.toString() ? yn(HOME) : yn(FOREIGN)

return withoutEvents ? ( <Redirect to="/" />) : (
<div className="statistics-page">
<div className='statistics-left-container' />
<div className='statistics-page-container'>
<div className='statistics-bridge-container'>
<span className='statistics-bridge-title statistics-title'>Bridge Statistics</span>
<BridgeStatistics
users={homeStore.statistics.finished ? homeStore.statistics.users.size : ''}
totalBridged={homeStore.statistics.finished ? homeStore.statistics.totalBridged.toString() : ''}
homeBalance={homeStore.balance}
homeSymbol={homeStore.symbol}
homeNativeSupplyTitle={isNativeToErc}
foreignSymbol={foreignStore.symbol}
foreignSupply={foreignStore.totalSupply} />
<BridgeStatistics
users={homeStore.statistics.finished ? homeStore.statistics.users.size : ''}
totalBridged={homeStore.statistics.finished ? homeStore.statistics.totalBridged.toString() : ''}
homeBalance={homeStore.balance}
homeSymbol={homeStore.symbol}
homeNativeSupplyTitle={isNativeToErc}
foreignSymbol={foreignStore.symbol}
foreignSupply={foreignStore.totalSupply} />
</div>
<div className='statistics-transaction-container'>
<div className='statistics-deposit-container'>
Expand Down
22 changes: 14 additions & 8 deletions src/components/StatusPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { inject, observer } from "mobx-react"
import { Configuration } from './Configuration'
import { Authority } from './Authority'
import pattern from '../assets/images/pattern.svg'
import yn from './utils/yn'


@inject("RootStore")
Expand All @@ -13,11 +14,14 @@ export class StatusPage extends React.Component {
const { homeStore, foreignStore, web3Store } = this.props.RootStore
const isHome = web3Store.metamaskNet.id.toString() === web3Store.homeNet.id.toString()
const requiredSignatures = isHome ? homeStore.requiredSignatures : foreignStore.requiredSignatures
const authorities = isHome ? homeStore.validators.length : foreignStore.validators.length
const authorities = isHome ? homeStore.validatorsCount : foreignStore.validatorsCount
const symbol = isHome ? homeStore.symbol : foreignStore.symbol
const maxSingleDeposit = isHome ? homeStore.maxPerTx : foreignStore.maxPerTx
const maxTotalBalance = isHome ? homeStore.maxCurrentDeposit : foreignStore.maxCurrentDeposit
const validatorsList = isHome ? homeStore.validators : foreignStore.validators
const { REACT_APP_HOME_WITHOUT_EVENTS: HOME, REACT_APP_FOREIGN_WITHOUT_EVENTS: FOREIGN } = process.env
const withoutEvents = web3Store.metamaskNet.id === web3Store.homeNet.id.toString() ? yn(HOME) : yn(FOREIGN)

return (
<div className="status-page">
<div className='status-left-container' />
Expand All @@ -31,14 +35,16 @@ export class StatusPage extends React.Component {
maxSingleDeposit={maxSingleDeposit}
maxTotalBalance={maxTotalBalance} />
</div>
<div className='status-authorities-container'>
<span className='status-authorities-title status-title'>Authorities</span>
<div className='status-authorities-data'>
{validatorsList.map((validator,i) => (
<Authority key={validator} address={validator} number={(i+1)} logoIndex={(i) % 3} />
))}
{withoutEvents ? null :
<div className='status-authorities-container'>
<span className='status-authorities-title status-title'>Authorities</span>
<div className='status-authorities-data'>
{validatorsList.map((validator,i) => (
<Authority key={validator} address={validator} number={(i+1)} logoIndex={(i) % 3} />
))}
</div>
</div>
</div>
}
</div>
<div className='status-right-container'>
<img className='status-right-image' src={pattern} alt=""/>
Expand Down
15 changes: 15 additions & 0 deletions src/components/utils/yn.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
const yn = input => {
input = String(input).trim();

if (/^(?:y|yes|true|1)$/i.test(input)) {
return true;
}

if (/^(?:n|no|false|0)$/i.test(input)) {
return false;
}

return false;
};

export default yn
Loading

0 comments on commit b8a4306

Please sign in to comment.