mirror of
https://github.com/embarklabs/embark.git
synced 2025-02-20 01:18:52 +00:00
conflict in saga
This commit is contained in:
parent
9d262e6a25
commit
5690c2e054
@ -200,17 +200,10 @@ export const files = {
|
|||||||
failure: (error) => action(FILES[FAILURE], {error})
|
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 GAS_ORACLE = createRequestTypes('GAS_ORACLE');
|
||||||
export const gasOracle = {
|
export const gasOracle = {
|
||||||
request: () => action(GAS_ORACLE[REQUEST]),
|
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})
|
failure: (error) => action(GAS_ORACLE[FAILURE], {error})
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -109,7 +109,7 @@ export function fetchContractFile(payload) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function getEthGasAPI() {
|
export function getEthGasAPI() {
|
||||||
return get('/json/ethgasAPI.json', {}, 'https://ethgasstation.info');
|
return get('/blockchain/gas/oracle', {});
|
||||||
}
|
}
|
||||||
|
|
||||||
export function fetchLastFiddle() {
|
export function fetchLastFiddle() {
|
||||||
|
@ -4,8 +4,8 @@ import {connect} from 'react-redux';
|
|||||||
import {withRouter} from "react-router-dom";
|
import {withRouter} from "react-router-dom";
|
||||||
import {Card, Form, Grid, StampCard, Stamp} from 'tabler-react';
|
import {Card, Form, Grid, StampCard, Stamp} from 'tabler-react';
|
||||||
import {CopyToClipboard} from 'react-copy-to-clipboard';
|
import {CopyToClipboard} from 'react-copy-to-clipboard';
|
||||||
import {listenToGasOracle} from "../actions";
|
import {listenToGasOracle, gasOracle as ethGasAction} from "../actions";
|
||||||
import {getOracleGasStats} from "../reducers/selectors";
|
import {getGasStats, getOracleGasStats} from "../reducers/selectors";
|
||||||
|
|
||||||
const COLORS = {
|
const COLORS = {
|
||||||
good: 'green',
|
good: 'green',
|
||||||
@ -16,42 +16,20 @@ const COLORS = {
|
|||||||
class GasStation extends Component {
|
class GasStation extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
if (!props.gasStats) {
|
|
||||||
return console.error('gasStats is a needed Prop for GasStation');
|
|
||||||
}
|
|
||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
gasSliderIndex: 0,
|
|
||||||
gasOracleSliderIndex: 0,
|
gasOracleSliderIndex: 0,
|
||||||
copied: false
|
copied: false
|
||||||
};
|
};
|
||||||
this.formattedGasStats = GasStation.formatGasStats(props.gasStats);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
|
this.props.fetchEthGas();
|
||||||
if (!this.props.gasOracleStats.length) {
|
if (!this.props.gasOracleStats.length) {
|
||||||
this.props.listenToGasOracle();
|
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() {
|
getGasOracleFormatted() {
|
||||||
const gasPrices = Object.keys(this.props.gasOracleStats);
|
const gasPrices = Object.keys(this.props.gasOracleStats);
|
||||||
if (!gasPrices.length) {
|
if (!gasPrices.length) {
|
||||||
@ -59,9 +37,11 @@ class GasStation extends Component {
|
|||||||
}
|
}
|
||||||
return gasPrices.map(gasPrice => {
|
return gasPrices.map(gasPrice => {
|
||||||
return {
|
return {
|
||||||
gasPrice: gasPrice,
|
gasPrice,
|
||||||
wait: this.props.gasOracleStats[gasPrice].averageWait
|
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) {
|
static getColorForWait(wait) {
|
||||||
if (wait <= 1) {
|
if (wait <= 60) {
|
||||||
return COLORS.good;
|
return COLORS.good;
|
||||||
}
|
}
|
||||||
if (wait <= 3) {
|
if (wait <= 180) {
|
||||||
return COLORS.medium;
|
return COLORS.medium;
|
||||||
}
|
}
|
||||||
return COLORS.bad;
|
return COLORS.bad;
|
||||||
}
|
}
|
||||||
|
|
||||||
static getColorForPrice(gasPrice) {
|
static getColorForPrice(gasPrice) {
|
||||||
if (gasPrice <= 20) {
|
if (gasPrice <= 20000000000) {
|
||||||
return COLORS.good;
|
return COLORS.good;
|
||||||
}
|
}
|
||||||
if (gasPrice <= 40) {
|
if (gasPrice <= 40000000000) {
|
||||||
return COLORS.medium;
|
return COLORS.medium;
|
||||||
}
|
}
|
||||||
return COLORS.bad;
|
return COLORS.bad;
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const currentGasStep = this.formattedGasStats.gasSteps[this.state.gasSliderIndex];
|
|
||||||
const formattedGasOracleStats = this.getGasOracleFormatted();
|
const formattedGasOracleStats = this.getGasOracleFormatted();
|
||||||
|
const currentGasStep = formattedGasOracleStats[this.state.gasOracleSliderIndex];
|
||||||
|
if (!formattedGasOracleStats.length) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
return <Grid.Row>
|
return <Grid.Row>
|
||||||
<Grid.Col>
|
<Grid.Col>
|
||||||
<Card>
|
<Card>
|
||||||
<Card.Header>
|
<Card.Header>
|
||||||
<Card.Title>Gas Price Estimator (for Mainnet)</Card.Title>
|
<Card.Title>Gas Price Estimator</Card.Title>
|
||||||
<Card.Options>
|
<Card.Options>
|
||||||
<CopyToClipboard text={currentGasStep.price / 10}
|
<CopyToClipboard text={currentGasStep.gasPrice / 1000000000}
|
||||||
onCopy={() => this.setState({copied: true})}
|
onCopy={() => this.setState({copied: true})}
|
||||||
title="Copy gas price to clipboard">
|
title="Copy gas price to clipboard">
|
||||||
<span><Stamp color="blue" icon="copy"/></span>
|
<span><Stamp color="blue" icon="copy"/></span>
|
||||||
@ -112,40 +95,31 @@ class GasStation extends Component {
|
|||||||
{this.state.copied && <p>Copied Gas Price</p>}
|
{this.state.copied && <p>Copied Gas Price</p>}
|
||||||
<Grid.Row cards={true}>
|
<Grid.Row cards={true}>
|
||||||
<Grid.Col lg={6} md={6} sm={12}>
|
<Grid.Col lg={6} md={6} sm={12}>
|
||||||
<StampCard icon="sliders" color={GasStation.getColorForPrice(currentGasStep.price)}>
|
<StampCard icon="sliders" color={GasStation.getColorForPrice(currentGasStep.gasPrice)}>
|
||||||
{currentGasStep.price / 10} GWei
|
{currentGasStep.gasPrice / 1000000000} Wei
|
||||||
</StampCard>
|
</StampCard>
|
||||||
</Grid.Col>
|
</Grid.Col>
|
||||||
<Grid.Col lg={6} md={6} sm={12}>
|
<Grid.Col lg={6} md={6} sm={12}>
|
||||||
<StampCard icon="clock" color={GasStation.getColorForWait(currentGasStep.wait)}>
|
<StampCard icon="clock" color={GasStation.getColorForWait(currentGasStep.wait)}>
|
||||||
{currentGasStep.wait} minutes
|
{currentGasStep.wait} seconds
|
||||||
</StampCard>
|
</StampCard>
|
||||||
</Grid.Col>
|
</Grid.Col>
|
||||||
</Grid.Row>
|
</Grid.Row>
|
||||||
|
|
||||||
<Form.Group>
|
<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"
|
<input type="range" className="slider"
|
||||||
max={formattedGasOracleStats.length - 1}
|
max={formattedGasOracleStats.length - 1}
|
||||||
min={0}
|
min={0}
|
||||||
step={1}
|
step={1}
|
||||||
value={this.state.gasOracleSliderIndex}
|
value={this.state.gasOracleSliderIndex}
|
||||||
onChange={(e) => this.gasSliderChange(e, 'gasOracleSliderIndex')}
|
onChange={(e) => this.gasSliderChange(e, 'gasOracleSliderIndex')}
|
||||||
/>}
|
/>
|
||||||
</Form.Group>
|
</Form.Group>
|
||||||
|
|
||||||
<Grid.Row cards={true}>
|
{/*<Grid.Row cards={true}>
|
||||||
<Grid.Col lg={4} md={6} sm={12}>
|
<Grid.Col lg={4} md={6} sm={12}>
|
||||||
<StampCard icon="sliders" color="grey">
|
<StampCard icon="sliders" color="grey">
|
||||||
Average Price: {this.formattedGasStats.average.price / 10} Gwei
|
Average Price: {this.formattedGasStats.average.price} Wei
|
||||||
</StampCard>
|
</StampCard>
|
||||||
</Grid.Col>
|
</Grid.Col>
|
||||||
<Grid.Col lg={4} md={6} sm={12}>
|
<Grid.Col lg={4} md={6} sm={12}>
|
||||||
@ -158,7 +132,7 @@ class GasStation extends Component {
|
|||||||
Last Block: {this.formattedGasStats.blockNum}
|
Last Block: {this.formattedGasStats.blockNum}
|
||||||
</StampCard>
|
</StampCard>
|
||||||
</Grid.Col>
|
</Grid.Col>
|
||||||
</Grid.Row>
|
</Grid.Row>*/}
|
||||||
</Card.Body>
|
</Card.Body>
|
||||||
</Card>
|
</Card>
|
||||||
</Grid.Col>
|
</Grid.Col>
|
||||||
@ -167,20 +141,22 @@ class GasStation extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
GasStation.propTypes = {
|
GasStation.propTypes = {
|
||||||
gasStats: PropTypes.object.isRequired,
|
gasOracleStats: PropTypes.object,
|
||||||
gasOracleStats: PropTypes.array,
|
listenToGasOracle: PropTypes.func,
|
||||||
listenToGasOracle: PropTypes.func
|
fetchEthGas: PropTypes.func
|
||||||
};
|
};
|
||||||
|
|
||||||
function mapStateToProps(state, _props) {
|
function mapStateToProps(state, _props) {
|
||||||
return {
|
return {
|
||||||
gasOracleStats: getOracleGasStats(state)
|
gasOracleStats: getOracleGasStats(state),
|
||||||
|
gasStats: getGasStats(state)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export default withRouter(connect(
|
export default withRouter(connect(
|
||||||
mapStateToProps,
|
mapStateToProps,
|
||||||
{
|
{
|
||||||
listenToGasOracle: listenToGasOracle
|
listenToGasOracle: listenToGasOracle,
|
||||||
|
fetchEthGas: ethGasAction.request
|
||||||
}
|
}
|
||||||
)(GasStation));
|
)(GasStation));
|
||||||
|
@ -3,11 +3,7 @@ import {connect} from 'react-redux';
|
|||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import {withRouter} from 'react-router-dom';
|
import {withRouter} from 'react-router-dom';
|
||||||
|
|
||||||
import {
|
import {contractProfile as contractProfileAction, contractDeploy as contractDeployAction} from '../actions';
|
||||||
contractProfile as contractProfileAction,
|
|
||||||
contractDeploy as contractDeployAction,
|
|
||||||
ethGas as ethGasAction
|
|
||||||
} from '../actions';
|
|
||||||
import ContractFunctions from '../components/ContractFunctions';
|
import ContractFunctions from '../components/ContractFunctions';
|
||||||
import DataWrapper from "../components/DataWrapper";
|
import DataWrapper from "../components/DataWrapper";
|
||||||
import GasStation from "../components/GasStation";
|
import GasStation from "../components/GasStation";
|
||||||
@ -16,7 +12,6 @@ import {getContractProfile, getContractDeploys, getGasStats} from "../reducers/s
|
|||||||
class ContractDeploymentContainer extends Component {
|
class ContractDeploymentContainer extends Component {
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
this.props.fetchContractProfile(this.props.match.params.contractName);
|
this.props.fetchContractProfile(this.props.match.params.contractName);
|
||||||
this.props.fetchEthGas();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
@ -30,12 +25,7 @@ class ContractDeploymentContainer extends Component {
|
|||||||
onlyConstructor
|
onlyConstructor
|
||||||
postContractFunction={postContractDeploy}/>
|
postContractFunction={postContractDeploy}/>
|
||||||
)}/>
|
)}/>
|
||||||
|
<GasStation/>
|
||||||
<DataWrapper shouldRender={this.props.gasStats !== undefined}
|
|
||||||
{...this.props}
|
|
||||||
render={({gasStats}) => (
|
|
||||||
<GasStation gasStats={gasStats}/>
|
|
||||||
)}/>
|
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -57,7 +47,6 @@ ContractDeploymentContainer.propTypes = {
|
|||||||
contractFunctions: PropTypes.arrayOf(PropTypes.object),
|
contractFunctions: PropTypes.arrayOf(PropTypes.object),
|
||||||
postContractDeploy: PropTypes.func,
|
postContractDeploy: PropTypes.func,
|
||||||
fetchContractProfile: PropTypes.func,
|
fetchContractProfile: PropTypes.func,
|
||||||
fetchEthGas: PropTypes.func,
|
|
||||||
error: PropTypes.string
|
error: PropTypes.string
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -65,7 +54,6 @@ export default withRouter(connect(
|
|||||||
mapStateToProps,
|
mapStateToProps,
|
||||||
{
|
{
|
||||||
fetchContractProfile: contractProfileAction.request,
|
fetchContractProfile: contractProfileAction.request,
|
||||||
postContractDeploy: contractDeployAction.post,
|
postContractDeploy: contractDeployAction.post
|
||||||
fetchEthGas: ethGasAction.request
|
|
||||||
}
|
}
|
||||||
)(ContractDeploymentContainer));
|
)(ContractDeploymentContainer));
|
||||||
|
@ -3,20 +3,15 @@ import {connect} from 'react-redux';
|
|||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import {withRouter} from 'react-router-dom';
|
import {withRouter} from 'react-router-dom';
|
||||||
|
|
||||||
import {
|
import {contractProfile as contractProfileAction, contractFunction as contractFunctionAction} from '../actions';
|
||||||
contractProfile as contractProfileAction,
|
|
||||||
contractFunction as contractFunctionAction,
|
|
||||||
ethGas as ethGasAction
|
|
||||||
} from '../actions';
|
|
||||||
import ContractFunctions from '../components/ContractFunctions';
|
import ContractFunctions from '../components/ContractFunctions';
|
||||||
import DataWrapper from "../components/DataWrapper";
|
import DataWrapper from "../components/DataWrapper";
|
||||||
import GasStation from "../components/GasStation";
|
import GasStation from "../components/GasStation";
|
||||||
import {getContractProfile, getContractFunctions, getGasStats} from "../reducers/selectors";
|
import {getContractProfile, getContractFunctions} from "../reducers/selectors";
|
||||||
|
|
||||||
class ContractFunctionsContainer extends Component {
|
class ContractFunctionsContainer extends Component {
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
this.props.fetchContractProfile(this.props.match.params.contractName);
|
this.props.fetchContractProfile(this.props.match.params.contractName);
|
||||||
this.props.fetchEthGas();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
@ -32,8 +27,8 @@ class ContractFunctionsContainer extends Component {
|
|||||||
|
|
||||||
<DataWrapper shouldRender={this.props.gasStats !== undefined}
|
<DataWrapper shouldRender={this.props.gasStats !== undefined}
|
||||||
{...this.props}
|
{...this.props}
|
||||||
render={({gasStats}) => (
|
render={() => (
|
||||||
<GasStation gasStats={gasStats}/>
|
<GasStation/>
|
||||||
)}/>
|
)}/>
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
);
|
);
|
||||||
@ -44,7 +39,6 @@ function mapStateToProps(state, props) {
|
|||||||
return {
|
return {
|
||||||
contractProfile: getContractProfile(state, props.match.params.contractName),
|
contractProfile: getContractProfile(state, props.match.params.contractName),
|
||||||
contractFunctions: getContractFunctions(state, props.match.params.contractName),
|
contractFunctions: getContractFunctions(state, props.match.params.contractName),
|
||||||
gasStats: getGasStats(state),
|
|
||||||
error: state.errorMessage,
|
error: state.errorMessage,
|
||||||
loading: state.loading
|
loading: state.loading
|
||||||
};
|
};
|
||||||
@ -64,7 +58,6 @@ export default withRouter(connect(
|
|||||||
mapStateToProps,
|
mapStateToProps,
|
||||||
{
|
{
|
||||||
fetchContractProfile: contractProfileAction.request,
|
fetchContractProfile: contractProfileAction.request,
|
||||||
postContractFunction: contractFunctionAction.post,
|
postContractFunction: contractFunctionAction.post
|
||||||
fetchEthGas: ethGasAction.request
|
|
||||||
}
|
}
|
||||||
)(ContractFunctionsContainer));
|
)(ContractFunctionsContainer));
|
||||||
|
@ -42,7 +42,7 @@ export const sendMessage = doRequest.bind(null, messageSend, api.sendMessage);
|
|||||||
export const fetchEnsRecord = doRequest.bind(null, ensRecord, api.fetchEnsRecord);
|
export const fetchEnsRecord = doRequest.bind(null, ensRecord, api.fetchEnsRecord);
|
||||||
export const postEnsRecord = doRequest.bind(null, ensRecords, api.postEnsRecord);
|
export const postEnsRecord = doRequest.bind(null, ensRecords, api.postEnsRecord);
|
||||||
export const fetchFiles = doRequest.bind(null, files, api.fetchFiles);
|
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() {
|
export function *watchFetchTransaction() {
|
||||||
yield takeEvery(actions.TRANSACTION[actions.REQUEST], fetchTransaction);
|
yield takeEvery(actions.TRANSACTION[actions.REQUEST], fetchTransaction);
|
||||||
@ -153,7 +153,7 @@ export function *watchFetchFiles() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function *watchFetchEthGas() {
|
export function *watchFetchEthGas() {
|
||||||
yield takeEvery(actions.ETH_GAS[actions.REQUEST], fetchEthGas);
|
yield takeEvery(actions.GAS_ORACLE[actions.REQUEST], fetchEthGas);
|
||||||
}
|
}
|
||||||
|
|
||||||
function createChannel(socket) {
|
function createChannel(socket) {
|
||||||
@ -212,7 +212,7 @@ export function *listenGasOracle() {
|
|||||||
const channel = yield call(createChannel, socket);
|
const channel = yield call(createChannel, socket);
|
||||||
while (true) {
|
while (true) {
|
||||||
const gasOracleStats = yield take(channel);
|
const gasOracleStats = yield take(channel);
|
||||||
yield put(gasOracle.success([gasOracleStats]));
|
yield put(gasOracle.success(gasOracleStats));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,6 +56,13 @@ class TransactionTracker {
|
|||||||
|
|
||||||
registerAPICalls() {
|
registerAPICalls() {
|
||||||
const self = this;
|
const self = this;
|
||||||
|
self.embark.registerAPICall(
|
||||||
|
'get',
|
||||||
|
'/embark-api/blockchain/gas/oracle',
|
||||||
|
(req, res) => {
|
||||||
|
res.send(self.calculateGasPriceSpeeds());
|
||||||
|
}
|
||||||
|
);
|
||||||
self.embark.registerAPICall(
|
self.embark.registerAPICall(
|
||||||
'ws',
|
'ws',
|
||||||
'/embark-api/blockchain/gas/oracle',
|
'/embark-api/blockchain/gas/oracle',
|
||||||
|
Loading…
x
Reference in New Issue
Block a user