conflict in saga

This commit is contained in:
Jonathan Rainville 2018-08-31 16:48:59 -04:00 committed by Pascal Precht
parent 9d262e6a25
commit 5690c2e054
No known key found for this signature in database
GPG Key ID: 0EE28D8D6FD85D7D
7 changed files with 50 additions and 93 deletions

View File

@ -200,17 +200,10 @@ export const files = {
failure: (error) => action(FILES[FAILURE], {error})
};
export const ETH_GAS = createRequestTypes('ETH_GAS');
export const ethGas = {
request: () => action(ETH_GAS[REQUEST]),
success: (gasStats) => action(ETH_GAS[SUCCESS], {gasStats: [gasStats]}),
failure: (error) => action(ETH_GAS[FAILURE], {error})
};
export const GAS_ORACLE = createRequestTypes('GAS_ORACLE');
export const gasOracle = {
request: () => action(GAS_ORACLE[REQUEST]),
success: (gasOracleStats) => action(GAS_ORACLE[SUCCESS], {gasOracleStats}),
success: (gasOracleStats) => action(GAS_ORACLE[SUCCESS], {gasOracleStats: [gasOracleStats]}),
failure: (error) => action(GAS_ORACLE[FAILURE], {error})
};

View File

@ -109,7 +109,7 @@ export function fetchContractFile(payload) {
}
export function getEthGasAPI() {
return get('/json/ethgasAPI.json', {}, 'https://ethgasstation.info');
return get('/blockchain/gas/oracle', {});
}
export function fetchLastFiddle() {

View File

@ -4,8 +4,8 @@ import {connect} from 'react-redux';
import {withRouter} from "react-router-dom";
import {Card, Form, Grid, StampCard, Stamp} from 'tabler-react';
import {CopyToClipboard} from 'react-copy-to-clipboard';
import {listenToGasOracle} from "../actions";
import {getOracleGasStats} from "../reducers/selectors";
import {listenToGasOracle, gasOracle as ethGasAction} from "../actions";
import {getGasStats, getOracleGasStats} from "../reducers/selectors";
const COLORS = {
good: 'green',
@ -16,42 +16,20 @@ const COLORS = {
class GasStation extends Component {
constructor(props) {
super(props);
if (!props.gasStats) {
return console.error('gasStats is a needed Prop for GasStation');
}
this.state = {
gasSliderIndex: 0,
gasOracleSliderIndex: 0,
copied: false
};
this.formattedGasStats = GasStation.formatGasStats(props.gasStats);
}
componentDidMount() {
this.props.fetchEthGas();
if (!this.props.gasOracleStats.length) {
this.props.listenToGasOracle();
}
}
static formatGasStats(gasStats) {
const {
fast, speed, fastest, avgWait, fastWait, blockNum, safeLowWait,
block_time, fastestWait, safeLow, average
} = gasStats;
return {
average: {price: average, wait: avgWait},
blockTime: block_time,
blockNum,
speed,
gasSteps: [
{price: safeLow, wait: safeLowWait},
{price: fast, wait: fastWait},
{price: fastest, wait: fastestWait}
]
};
}
getGasOracleFormatted() {
const gasPrices = Object.keys(this.props.gasOracleStats);
if (!gasPrices.length) {
@ -59,9 +37,11 @@ class GasStation extends Component {
}
return gasPrices.map(gasPrice => {
return {
gasPrice: gasPrice,
gasPrice,
wait: this.props.gasOracleStats[gasPrice].averageWait
};
}).sort((a, b) => {
return a.gasPrice - b.gasPrice;
});
}
@ -72,35 +52,38 @@ class GasStation extends Component {
}
static getColorForWait(wait) {
if (wait <= 1) {
if (wait <= 60) {
return COLORS.good;
}
if (wait <= 3) {
if (wait <= 180) {
return COLORS.medium;
}
return COLORS.bad;
}
static getColorForPrice(gasPrice) {
if (gasPrice <= 20) {
if (gasPrice <= 20000000000) {
return COLORS.good;
}
if (gasPrice <= 40) {
if (gasPrice <= 40000000000) {
return COLORS.medium;
}
return COLORS.bad;
}
render() {
const currentGasStep = this.formattedGasStats.gasSteps[this.state.gasSliderIndex];
const formattedGasOracleStats = this.getGasOracleFormatted();
const currentGasStep = formattedGasOracleStats[this.state.gasOracleSliderIndex];
if (!formattedGasOracleStats.length) {
return '';
}
return <Grid.Row>
<Grid.Col>
<Card>
<Card.Header>
<Card.Title>Gas Price Estimator (for Mainnet)</Card.Title>
<Card.Title>Gas Price Estimator</Card.Title>
<Card.Options>
<CopyToClipboard text={currentGasStep.price / 10}
<CopyToClipboard text={currentGasStep.gasPrice / 1000000000}
onCopy={() => this.setState({copied: true})}
title="Copy gas price to clipboard">
<span><Stamp color="blue" icon="copy"/></span>
@ -112,40 +95,31 @@ class GasStation extends Component {
{this.state.copied && <p>Copied Gas Price</p>}
<Grid.Row cards={true}>
<Grid.Col lg={6} md={6} sm={12}>
<StampCard icon="sliders" color={GasStation.getColorForPrice(currentGasStep.price)}>
{currentGasStep.price / 10} GWei
<StampCard icon="sliders" color={GasStation.getColorForPrice(currentGasStep.gasPrice)}>
{currentGasStep.gasPrice / 1000000000} Wei
</StampCard>
</Grid.Col>
<Grid.Col lg={6} md={6} sm={12}>
<StampCard icon="clock" color={GasStation.getColorForWait(currentGasStep.wait)}>
{currentGasStep.wait} minutes
{currentGasStep.wait} seconds
</StampCard>
</Grid.Col>
</Grid.Row>
<Form.Group>
<input type="range" className="slider"
max={this.formattedGasStats.gasSteps.length - 1}
min={0}
step={1}
value={this.state.gasSliderIndex}
onChange={(e) => this.gasSliderChange(e, 'gasSliderIndex')}
/>
{formattedGasOracleStats.length > 0 &&
<input type="range" className="slider"
max={formattedGasOracleStats.length - 1}
min={0}
step={1}
value={this.state.gasOracleSliderIndex}
onChange={(e) => this.gasSliderChange(e, 'gasOracleSliderIndex')}
/>}
/>
</Form.Group>
<Grid.Row cards={true}>
{/*<Grid.Row cards={true}>
<Grid.Col lg={4} md={6} sm={12}>
<StampCard icon="sliders" color="grey">
Average Price: {this.formattedGasStats.average.price / 10} Gwei
Average Price: {this.formattedGasStats.average.price} Wei
</StampCard>
</Grid.Col>
<Grid.Col lg={4} md={6} sm={12}>
@ -158,7 +132,7 @@ class GasStation extends Component {
Last Block: {this.formattedGasStats.blockNum}
</StampCard>
</Grid.Col>
</Grid.Row>
</Grid.Row>*/}
</Card.Body>
</Card>
</Grid.Col>
@ -167,20 +141,22 @@ class GasStation extends Component {
}
GasStation.propTypes = {
gasStats: PropTypes.object.isRequired,
gasOracleStats: PropTypes.array,
listenToGasOracle: PropTypes.func
gasOracleStats: PropTypes.object,
listenToGasOracle: PropTypes.func,
fetchEthGas: PropTypes.func
};
function mapStateToProps(state, _props) {
return {
gasOracleStats: getOracleGasStats(state)
gasOracleStats: getOracleGasStats(state),
gasStats: getGasStats(state)
};
}
export default withRouter(connect(
mapStateToProps,
{
listenToGasOracle: listenToGasOracle
listenToGasOracle: listenToGasOracle,
fetchEthGas: ethGasAction.request
}
)(GasStation));

View File

@ -3,11 +3,7 @@ import {connect} from 'react-redux';
import PropTypes from 'prop-types';
import {withRouter} from 'react-router-dom';
import {
contractProfile as contractProfileAction,
contractDeploy as contractDeployAction,
ethGas as ethGasAction
} from '../actions';
import {contractProfile as contractProfileAction, contractDeploy as contractDeployAction} from '../actions';
import ContractFunctions from '../components/ContractFunctions';
import DataWrapper from "../components/DataWrapper";
import GasStation from "../components/GasStation";
@ -16,7 +12,6 @@ import {getContractProfile, getContractDeploys, getGasStats} from "../reducers/s
class ContractDeploymentContainer extends Component {
componentDidMount() {
this.props.fetchContractProfile(this.props.match.params.contractName);
this.props.fetchEthGas();
}
render() {
@ -30,12 +25,7 @@ class ContractDeploymentContainer extends Component {
onlyConstructor
postContractFunction={postContractDeploy}/>
)}/>
<DataWrapper shouldRender={this.props.gasStats !== undefined}
{...this.props}
render={({gasStats}) => (
<GasStation gasStats={gasStats}/>
)}/>
<GasStation/>
</React.Fragment>
);
}
@ -57,7 +47,6 @@ ContractDeploymentContainer.propTypes = {
contractFunctions: PropTypes.arrayOf(PropTypes.object),
postContractDeploy: PropTypes.func,
fetchContractProfile: PropTypes.func,
fetchEthGas: PropTypes.func,
error: PropTypes.string
};
@ -65,7 +54,6 @@ export default withRouter(connect(
mapStateToProps,
{
fetchContractProfile: contractProfileAction.request,
postContractDeploy: contractDeployAction.post,
fetchEthGas: ethGasAction.request
postContractDeploy: contractDeployAction.post
}
)(ContractDeploymentContainer));

View File

@ -3,20 +3,15 @@ import {connect} from 'react-redux';
import PropTypes from 'prop-types';
import {withRouter} from 'react-router-dom';
import {
contractProfile as contractProfileAction,
contractFunction as contractFunctionAction,
ethGas as ethGasAction
} from '../actions';
import {contractProfile as contractProfileAction, contractFunction as contractFunctionAction} from '../actions';
import ContractFunctions from '../components/ContractFunctions';
import DataWrapper from "../components/DataWrapper";
import GasStation from "../components/GasStation";
import {getContractProfile, getContractFunctions, getGasStats} from "../reducers/selectors";
import {getContractProfile, getContractFunctions} from "../reducers/selectors";
class ContractFunctionsContainer extends Component {
componentDidMount() {
this.props.fetchContractProfile(this.props.match.params.contractName);
this.props.fetchEthGas();
}
render() {
@ -32,8 +27,8 @@ class ContractFunctionsContainer extends Component {
<DataWrapper shouldRender={this.props.gasStats !== undefined}
{...this.props}
render={({gasStats}) => (
<GasStation gasStats={gasStats}/>
render={() => (
<GasStation/>
)}/>
</React.Fragment>
);
@ -44,7 +39,6 @@ function mapStateToProps(state, props) {
return {
contractProfile: getContractProfile(state, props.match.params.contractName),
contractFunctions: getContractFunctions(state, props.match.params.contractName),
gasStats: getGasStats(state),
error: state.errorMessage,
loading: state.loading
};
@ -64,7 +58,6 @@ export default withRouter(connect(
mapStateToProps,
{
fetchContractProfile: contractProfileAction.request,
postContractFunction: contractFunctionAction.post,
fetchEthGas: ethGasAction.request
postContractFunction: contractFunctionAction.post
}
)(ContractFunctionsContainer));

View File

@ -42,7 +42,7 @@ export const sendMessage = doRequest.bind(null, messageSend, api.sendMessage);
export const fetchEnsRecord = doRequest.bind(null, ensRecord, api.fetchEnsRecord);
export const postEnsRecord = doRequest.bind(null, ensRecords, api.postEnsRecord);
export const fetchFiles = doRequest.bind(null, files, api.fetchFiles);
export const fetchEthGas = doRequest.bind(null, ethGas, api.getEthGasAPI);
export const fetchEthGas = doRequest.bind(null, gasOracle, api.getEthGasAPI);
export function *watchFetchTransaction() {
yield takeEvery(actions.TRANSACTION[actions.REQUEST], fetchTransaction);
@ -153,7 +153,7 @@ export function *watchFetchFiles() {
}
export function *watchFetchEthGas() {
yield takeEvery(actions.ETH_GAS[actions.REQUEST], fetchEthGas);
yield takeEvery(actions.GAS_ORACLE[actions.REQUEST], fetchEthGas);
}
function createChannel(socket) {
@ -212,7 +212,7 @@ export function *listenGasOracle() {
const channel = yield call(createChannel, socket);
while (true) {
const gasOracleStats = yield take(channel);
yield put(gasOracle.success([gasOracleStats]));
yield put(gasOracle.success(gasOracleStats));
}
}

View File

@ -56,6 +56,13 @@ class TransactionTracker {
registerAPICalls() {
const self = this;
self.embark.registerAPICall(
'get',
'/embark-api/blockchain/gas/oracle',
(req, res) => {
res.send(self.calculateGasPriceSpeeds());
}
);
self.embark.registerAPICall(
'ws',
'/embark-api/blockchain/gas/oracle',