mirror of https://github.com/embarklabs/embark.git
feat(cockpit): introduce transaction decoder component
This commit adds a new component to decode and analyze transactions. It's similar to the transaction component that's already available, with the difference that it takes advantage of the ReactJson tree view for better analysis experience.
This commit is contained in:
parent
fb29e5a7c8
commit
923bacf22f
|
@ -39,7 +39,8 @@ const sidebarNavItems = {items: [
|
|||
{url: "/embark/utilities/converter", icon: "fa fa-plug", name: "Converter"},
|
||||
{url: "/embark/utilities/communication", icon: "fa fa-phone", name: "Communication"},
|
||||
{url: "/embark/utilities/ens", icon: "fa fa-circle", name: "ENS"},
|
||||
{url: "/embark/utilities/sign-and-verify", icon: "fa fa-edit", name: "Sign & Verify"}
|
||||
{url: "/embark/utilities/sign-and-verify", icon: "fa fa-edit", name: "Sign & Verify"},
|
||||
{url: "/embark/utilities/transaction-decoder", icon: "fa fa-edit", name: "Transaction Decoder"}
|
||||
]}
|
||||
]};
|
||||
|
||||
|
|
|
@ -0,0 +1,68 @@
|
|||
import React from 'react';
|
||||
import {withRouter} from 'react-router-dom';
|
||||
import {
|
||||
Card,
|
||||
CardHeader,
|
||||
CardBody,
|
||||
Form,
|
||||
FormGroup,
|
||||
Input,
|
||||
InputGroup,
|
||||
InputGroupAddon,
|
||||
Button,
|
||||
Alert
|
||||
} from 'reactstrap';
|
||||
import ReactJson from 'react-json-view';
|
||||
|
||||
class TransactionDecoder extends React.Component {
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
transactionHash: this.props.transactionHash || ''
|
||||
};
|
||||
}
|
||||
|
||||
handleTransactionHashChange(event) {
|
||||
const transactionHash = event.target.value;
|
||||
this.setState({transactionHash});
|
||||
}
|
||||
|
||||
fetchTransaction(e) {
|
||||
e.preventDefault();
|
||||
if (this.state.transactionHash !== '') {
|
||||
this.props.history.push({
|
||||
search: `hash=${this.state.transactionHash}`
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<strong>Transaction Decoder</strong>
|
||||
</CardHeader>
|
||||
<CardBody>
|
||||
<Form onSubmit={e => this.fetchTransaction(e)}>
|
||||
<FormGroup>
|
||||
<InputGroup>
|
||||
<Input type="text" id="transactionHash" placeholder="Enter transaction hash" value={this.state.transactionHash} onChange={e => this.handleTransactionHashChange(e)}/>
|
||||
<InputGroupAddon addonType="append">
|
||||
<Button color="primary" type="submit">Decode</Button>
|
||||
</InputGroupAddon>
|
||||
</InputGroup>
|
||||
</FormGroup>
|
||||
</Form>
|
||||
{this.props.transactionHash && !this.props.transaction && <Alert color="danger">Couldn't find transaction for hash {this.props.transactionHash}</Alert>}
|
||||
|
||||
<div className="mt-3">
|
||||
{this.props.transaction && <ReactJson src={this.props.transaction} theme="monokai" sortKeys={true} collapsed={1} />}
|
||||
</div>
|
||||
</CardBody>
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default withRouter(TransactionDecoder);
|
|
@ -5,6 +5,7 @@ import ConverterContainer from '../containers/ConverterContainer';
|
|||
import CommunicationContainer from '../containers/CommunicationContainer';
|
||||
import EnsContainer from '../containers/EnsContainer';
|
||||
import SignAndVerifyContainer from '../containers/SignAndVerifyContainer';
|
||||
import TransactionDecoderContainer from '../containers/TransactionDecoderContainer';
|
||||
|
||||
const UtilsLayout = () => (
|
||||
<Switch>
|
||||
|
@ -12,6 +13,7 @@ const UtilsLayout = () => (
|
|||
<Route exact path="/embark/utilities/communication" component={CommunicationContainer} />
|
||||
<Route exact path="/embark/utilities/ens" component={EnsContainer} />
|
||||
<Route exact path="/embark/utilities/sign-and-verify" component={SignAndVerifyContainer} />
|
||||
<Route exact path="/embark/utilities/transaction-decoder" component={TransactionDecoderContainer} />
|
||||
</Switch>
|
||||
);
|
||||
|
||||
|
|
|
@ -0,0 +1,58 @@
|
|||
import React, { Component } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import qs from 'qs';
|
||||
import {withRouter} from 'react-router-dom';
|
||||
import TransactionDecoder from '../components/TransactionDecoder';
|
||||
import { Row, Col } from 'reactstrap';
|
||||
import { transaction as transactionAction } from '../actions';
|
||||
import {getTransaction} from "../reducers/selectors";
|
||||
|
||||
const getQueryParams = (props) => {
|
||||
return qs.parse(props.location.search, {
|
||||
ignoreQueryPrefix: true
|
||||
});
|
||||
}
|
||||
|
||||
class TransactionDecoderContainer extends Component {
|
||||
|
||||
componentDidMount() {
|
||||
const { hash } = getQueryParams(this.props);
|
||||
if (hash) {
|
||||
this.props.fetchTransaction(hash);
|
||||
}
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps) {
|
||||
const hash = getQueryParams(this.props).hash;
|
||||
const prevHash = getQueryParams(prevProps).hash;
|
||||
|
||||
if (hash && hash !== prevHash) {
|
||||
this.props.fetchTransaction(hash);
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<Row className="mt-3">
|
||||
<Col>
|
||||
<TransactionDecoder transaction={this.props.transaction}
|
||||
transactionHash={getQueryParams(this.props).hash}/>
|
||||
</Col>
|
||||
</Row>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function mapStateToProps(state, props) {
|
||||
return {
|
||||
transaction: getTransaction(state, getQueryParams(props).hash),
|
||||
error: state.errorMessage,
|
||||
loading: state.loading
|
||||
};
|
||||
}
|
||||
export default withRouter(connect(
|
||||
mapStateToProps,
|
||||
{
|
||||
fetchTransaction: transactionAction.request
|
||||
}
|
||||
)(TransactionDecoderContainer));
|
Loading…
Reference in New Issue