Make call successfully
This commit is contained in:
parent
c234a850e3
commit
3c9cea594c
|
@ -111,6 +111,13 @@ export const contractFile = {
|
|||
failure: (error) => action(CONTRACT_FILE[FAILURE], {error})
|
||||
};
|
||||
|
||||
export const CONTRACT_FUNCTION = createRequestTypes('CONTRACT_FUNCTION');
|
||||
export const contractFunction = {
|
||||
post: (contractName, method, inputs) => action(CONTRACT_FUNCTION[REQUEST], {contractName, method, inputs}),
|
||||
success: (result, payload) => action(CONTRACT_FUNCTION[SUCCESS], {contractFunctions: [{...result, ...payload}]}),
|
||||
failure: (error) => action(CONTRACT_FUNCTION[FAILURE], {error})
|
||||
};
|
||||
|
||||
export const VERSIONS = createRequestTypes('VERSIONS');
|
||||
export const versions = {
|
||||
request: () => action(VERSIONS[REQUEST]),
|
||||
|
|
|
@ -68,6 +68,10 @@ export function fetchContract(payload) {
|
|||
return get(`/contract/${payload.contractName}`);
|
||||
}
|
||||
|
||||
export function postContractFunction(payload) {
|
||||
return post(`/contract/${payload.contractName}/function`, payload);
|
||||
}
|
||||
|
||||
export function fetchVersions() {
|
||||
return get('/versions');
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import PropTypes from "prop-types";
|
||||
import React from 'react';
|
||||
import React, {Component} from 'react';
|
||||
import {
|
||||
Page,
|
||||
Grid,
|
||||
|
@ -8,44 +8,74 @@ import {
|
|||
Card
|
||||
} from "tabler-react";
|
||||
|
||||
const ContractFunction = ({method}) => (
|
||||
<Grid.Row>
|
||||
<Grid.Col>
|
||||
<Card>
|
||||
<Card.Header>
|
||||
<Card.Title>{method.name}</Card.Title>
|
||||
</Card.Header>
|
||||
{method.inputs.length > 0 &&
|
||||
<Card.Body>
|
||||
{method.inputs.map(input => (
|
||||
<Form.Group key={input.name} label={input.name}>
|
||||
<Form.Input placeholder={input.type}/>
|
||||
</Form.Group>
|
||||
))}
|
||||
</Card.Body>
|
||||
}
|
||||
<Card.Footer>
|
||||
<Button color="primary">Call</Button>
|
||||
</Card.Footer>
|
||||
</Card>
|
||||
</Grid.Col>
|
||||
</Grid.Row>
|
||||
);
|
||||
class ContractFunction extends Component {
|
||||
constructor(props) {
|
||||
super(props)
|
||||
this.state = { inputs: {} };
|
||||
}
|
||||
|
||||
handleChange(e, name) {
|
||||
let newInputs = this.state.inputs;
|
||||
newInputs[name] = e.target.value;
|
||||
this.setState({ inputs: newInputs});
|
||||
}
|
||||
|
||||
handleCall(e) {
|
||||
e.preventDefault();
|
||||
const inputs = this.props.method.inputs.map(input => this.state.inputs[input.name]);
|
||||
this.props.postContractFunction(this.props.contractProfile.name, this.props.method.name, inputs);
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<Grid.Row>
|
||||
<Grid.Col>
|
||||
<Card>
|
||||
<Card.Header>
|
||||
<Card.Title>{this.props.method.name}</Card.Title>
|
||||
</Card.Header>
|
||||
{this.props.method.inputs.length > 0 &&
|
||||
<Card.Body>
|
||||
{this.props.method.inputs.map(input => (
|
||||
<Form.Group key={input.name} label={input.name}>
|
||||
<Form.Input placeholder={input.type} onChange={(e) => this.handleChange(e, input.name)}/>
|
||||
</Form.Group>
|
||||
))}
|
||||
</Card.Body>
|
||||
}
|
||||
<Card.Footer>
|
||||
<Button color="primary" onClick={(e) => this.handleCall(e)}>Call</Button>
|
||||
</Card.Footer>
|
||||
</Card>
|
||||
</Grid.Col>
|
||||
</Grid.Row>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ContractFunction.propTypes = {
|
||||
method: PropTypes.object
|
||||
contractProfile: PropTypes.object,
|
||||
method: PropTypes.object,
|
||||
contractFunctions: PropTypes.arrayOf(PropTypes.object),
|
||||
postContractFunction: PropTypes.func
|
||||
};
|
||||
|
||||
const ContractFunctions = ({contractProfile}) => (
|
||||
<Page.Content title={contractProfile.name + ' Functions'}>
|
||||
{contractProfile.methods
|
||||
.filter(method => method.name !== 'constructor')
|
||||
.map(method => <ContractFunction key={method.name} method={method} />)}
|
||||
</Page.Content>
|
||||
);
|
||||
const ContractFunctions = (props) => {
|
||||
const {contractProfile} = props;
|
||||
return (
|
||||
<Page.Content title={contractProfile.name + ' Functions'}>
|
||||
{contractProfile.methods
|
||||
.filter(method => method.name !== 'constructor')
|
||||
.map(method => <ContractFunction key={method.name} method={method} {...props} />)}
|
||||
</Page.Content>
|
||||
)
|
||||
};
|
||||
|
||||
ContractFunctions.propTypes = {
|
||||
contractProfile: PropTypes.object
|
||||
contractProfile: PropTypes.object,
|
||||
contractFunctions: PropTypes.arrayOf(PropTypes.object),
|
||||
postContractFunction: PropTypes.func
|
||||
};
|
||||
|
||||
export default ContractFunctions;
|
||||
|
|
|
@ -3,10 +3,10 @@ import {connect} from 'react-redux';
|
|||
import PropTypes from 'prop-types';
|
||||
import {withRouter} from 'react-router-dom';
|
||||
|
||||
import {contractProfile as contractProfileAction} from '../actions';
|
||||
import {contractProfile as contractProfileAction, contractFunction as contractFunctionAction} from '../actions';
|
||||
import ContractFunctions from '../components/ContractFunctions';
|
||||
import DataWrapper from "../components/DataWrapper";
|
||||
import {getContractProfile} from "../reducers/selectors";
|
||||
import {getContractProfile, getContractFunctions} from "../reducers/selectors";
|
||||
|
||||
class ContractFunctionsContainer extends Component {
|
||||
componentDidMount() {
|
||||
|
@ -15,8 +15,12 @@ class ContractFunctionsContainer extends Component {
|
|||
|
||||
render() {
|
||||
return (
|
||||
<DataWrapper shouldRender={this.props.contractProfile !== undefined } {...this.props} render={({contractProfile}) => (
|
||||
<ContractFunctions contractProfile={contractProfile} />
|
||||
<DataWrapper shouldRender={this.props.contractProfile !== undefined }
|
||||
{...this.props}
|
||||
render={({contractProfile, contractFunctions, postContractFunction}) => (
|
||||
<ContractFunctions contractProfile={contractProfile}
|
||||
contractFunctions={contractFunctions}
|
||||
postContractFunction={postContractFunction} />
|
||||
)} />
|
||||
);
|
||||
}
|
||||
|
@ -25,6 +29,7 @@ class ContractFunctionsContainer extends Component {
|
|||
function mapStateToProps(state, props) {
|
||||
return {
|
||||
contractProfile: getContractProfile(state, props.match.params.contractName),
|
||||
contractFunctions: getContractFunctions(state, props.match.params.contractName),
|
||||
error: state.errorMessage,
|
||||
loading: state.loading
|
||||
};
|
||||
|
@ -33,6 +38,8 @@ function mapStateToProps(state, props) {
|
|||
ContractFunctionsContainer.propTypes = {
|
||||
match: PropTypes.object,
|
||||
contractProfile: PropTypes.object,
|
||||
contractFunctions: PropTypes.arrayOf(PropTypes.object),
|
||||
postContractFunction: PropTypes.func,
|
||||
fetchContractProfile: PropTypes.func,
|
||||
error: PropTypes.string
|
||||
};
|
||||
|
@ -40,6 +47,7 @@ ContractFunctionsContainer.propTypes = {
|
|||
export default withRouter(connect(
|
||||
mapStateToProps,
|
||||
{
|
||||
fetchContractProfile: contractProfileAction.request
|
||||
fetchContractProfile: contractProfileAction.request,
|
||||
postContractFunction: contractFunctionAction.post
|
||||
}
|
||||
)(ContractFunctionsContainer));
|
||||
|
|
|
@ -13,6 +13,7 @@ const entitiesDefaultState = {
|
|||
contracts: [],
|
||||
contractProfiles: [],
|
||||
contractFiles: [],
|
||||
contractFunctions: [],
|
||||
contractLogs: [],
|
||||
commands: [],
|
||||
messages: [],
|
||||
|
|
|
@ -66,6 +66,10 @@ export function getContractFile(state, filename) {
|
|||
return state.entities.contractFiles.find((contractFile => contractFile.filename === filename));
|
||||
}
|
||||
|
||||
export function getContractFunctions(state, contractName) {
|
||||
return state.entities.contractFunctions.filter((contractFunction => contractFunction.contractName === contractName));
|
||||
}
|
||||
|
||||
export function getVersions(state) {
|
||||
return state.entities.versions;
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ import {all, call, fork, put, takeEvery, take} from 'redux-saga/effects';
|
|||
|
||||
const {account, accounts, block, blocks, transaction, transactions, processes, commands, processLogs,
|
||||
contracts, contract, contractProfile, messageSend, versions, plugins, messageListen, fiddle,
|
||||
ensRecord, ensRecords, contractLogs, contractFile} = actions;
|
||||
ensRecord, ensRecords, contractLogs, contractFile, contractFunction} = actions;
|
||||
|
||||
function *doRequest(entity, apiFn, payload) {
|
||||
const {response, error} = yield call(apiFn, payload);
|
||||
|
@ -32,6 +32,7 @@ export const fetchContracts = doRequest.bind(null, contracts, api.fetchContracts
|
|||
export const fetchContract = doRequest.bind(null, contract, api.fetchContract);
|
||||
export const fetchContractProfile = doRequest.bind(null, contractProfile, api.fetchContractProfile);
|
||||
export const fetchContractFile = doRequest.bind(null, contractFile, api.fetchContractFile);
|
||||
export const postContractFunction = doRequest.bind(null, contractFunction, api.postContractFunction);
|
||||
export const fetchFiddle = doRequest.bind(null, fiddle, api.fetchFiddle);
|
||||
export const sendMessage = doRequest.bind(null, messageSend, api.sendMessage);
|
||||
export const fetchEnsRecord = doRequest.bind(null, ensRecord, api.fetchEnsRecord);
|
||||
|
@ -93,6 +94,10 @@ export function *watchFetchContractFile() {
|
|||
yield takeEvery(actions.CONTRACT_FILE[actions.REQUEST], fetchContractFile);
|
||||
}
|
||||
|
||||
export function *watchPostContractFunction() {
|
||||
yield takeEvery(actions.CONTRACT_FUNCTION[actions.REQUEST], postContractFunction);
|
||||
}
|
||||
|
||||
export function *watchFetchVersions() {
|
||||
yield takeEvery(actions.VERSIONS[actions.REQUEST], fetchVersions);
|
||||
}
|
||||
|
@ -200,6 +205,7 @@ export default function *root() {
|
|||
fork(watchFetchContracts),
|
||||
fork(watchFetchContractProfile),
|
||||
fork(watchFetchContractFile),
|
||||
fork(watchPostContractFunction),
|
||||
fork(watchListenToMessages),
|
||||
fork(watchSendMessage),
|
||||
fork(watchFetchContract),
|
||||
|
|
|
@ -93,12 +93,12 @@ class ContractsManager {
|
|||
);
|
||||
|
||||
plugin.registerAPICall(
|
||||
'get',
|
||||
'post',
|
||||
'/embark-api/contract/:contractName/function',
|
||||
(req, res) => {
|
||||
async.parallel({
|
||||
contract: (callback) => {
|
||||
self.events.request('contracts:contract', req.params.contractName, (contract) => callback(null, contract));
|
||||
self.events.request('contracts:contract', req.body.contractName, (contract) => callback(null, contract));
|
||||
},
|
||||
account: (callback) => {
|
||||
self.events.request("blockchain:defaultAccount:get", (account) => callback(null, account));
|
||||
|
@ -109,9 +109,9 @@ class ContractsManager {
|
|||
}
|
||||
const {account, contract} = result;
|
||||
const contractObj = new web3.eth.Contract(contract.abiDefinition, contract.deployedAddress);
|
||||
const abi = contract.abiDefinition.find(definition => definition.name === req.query.method);
|
||||
const abi = contract.abiDefinition.find(definition => definition.name === req.body.method);
|
||||
const funcCall = (abi.constant === true || abi.stateMutability === 'view' || abi.stateMutability === 'pure') ? 'call' : 'send';
|
||||
contractObj.methods[req.query.method].apply(this, req.query.inputs)[funcCall]({from: account}, (err, result) => {
|
||||
contractObj.methods[req.body.method].apply(this, req.body.inputs)[funcCall]({from: account}, (err, result) => {
|
||||
if (err) {
|
||||
return res.send({error: err.message});
|
||||
}
|
||||
|
|
|
@ -1 +1,22 @@
|
|||
{}
|
||||
{
|
||||
"0xf957b38706f783689e96d5b17c2c24a2a1b2093b8e7c5f43e748878a73456984": {
|
||||
"contracts": {
|
||||
"0xa72e15b4fc637528e678fdcab66f178b753f609a6d2a66564f1676fde4d51ed3": {
|
||||
"name": "SimpleStorage",
|
||||
"address": "0x595dE951E7458Cf6e49606C91294A764098248AD"
|
||||
},
|
||||
"0x05a320b7f23891fc8c8c40312e0ae5a104d4734b3c0692eb24f9e99fca0ada3f": {
|
||||
"name": "ENSRegistry",
|
||||
"address": "0x07dF106F12b516a36e29e23b2acF1e47b26Cb81B"
|
||||
},
|
||||
"0xa971bc944c276c3a2f98bdad24d102d00615680517267a9e48cf7091ce512c88": {
|
||||
"name": "Resolver",
|
||||
"address": "0x8e43bD6a0357385D5a35980baCa7A2644459038b"
|
||||
},
|
||||
"0x618f78549c37a154c4931bb2f10e4b92fbf8004fc1dfa6c11b3276257d3c84f0": {
|
||||
"name": "FIFSRegistrar",
|
||||
"address": "0xf2086ADff73E5B6412c1ca089250b77f9B28984B"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue