mirror of
https://github.com/embarklabs/embark.git
synced 2025-01-28 06:25:11 +00:00
feat(@cockpit/explorer): enable users to send ether through payable methods (#1649)
This commit is contained in:
parent
ed65b066e7
commit
d10c0b7951
@ -107,6 +107,9 @@ class ContractsManager {
|
|||||||
contract: (callback) => {
|
contract: (callback) => {
|
||||||
self.events.request('contracts:contract', req.body.contractName, (contract) => callback(null, contract));
|
self.events.request('contracts:contract', req.body.contractName, (contract) => callback(null, contract));
|
||||||
},
|
},
|
||||||
|
web3: (callback) => {
|
||||||
|
self.events.request("blockchain:get", web3 => callback(null, web3));
|
||||||
|
},
|
||||||
account: (callback) => {
|
account: (callback) => {
|
||||||
self.events.request("blockchain:defaultAccount:get", (account) => callback(null, account));
|
self.events.request("blockchain:defaultAccount:get", (account) => callback(null, account));
|
||||||
}
|
}
|
||||||
@ -114,14 +117,20 @@ class ContractsManager {
|
|||||||
if (error) {
|
if (error) {
|
||||||
return res.send({error: error.message});
|
return res.send({error: error.message});
|
||||||
}
|
}
|
||||||
const {account, contract} = result;
|
const {account, contract, web3} = result;
|
||||||
const abi = contract.abiDefinition.find(definition => definition.name === req.body.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';
|
const funcCall = (abi.constant === true || abi.stateMutability === 'view' || abi.stateMutability === 'pure') ? 'call' : 'send';
|
||||||
|
|
||||||
self.events.request("blockchain:contract:create", {abi: contract.abiDefinition, address: contract.deployedAddress}, async (contractObj) => {
|
self.events.request("blockchain:contract:create", {abi: contract.abiDefinition, address: contract.deployedAddress}, async (contractObj) => {
|
||||||
try {
|
try {
|
||||||
const gas = await contractObj.methods[req.body.method].apply(this, req.body.inputs).estimateGas();
|
const value = req.body.value !== undefined ? web3.utils.toWei(req.body.value, 'ether') : 0
|
||||||
contractObj.methods[req.body.method].apply(this, req.body.inputs)[funcCall]({from: account, gasPrice: req.body.gasPrice, gas: Math.floor(gas)}, (error, result) => {
|
const gas = await contractObj.methods[req.body.method].apply(this, req.body.inputs).estimateGas({ value });
|
||||||
|
contractObj.methods[req.body.method].apply(this, req.body.inputs)[funcCall]({
|
||||||
|
from: account,
|
||||||
|
gasPrice: req.body.gasPrice,
|
||||||
|
gas: Math.floor(gas),
|
||||||
|
value
|
||||||
|
}, (error, result) => {
|
||||||
const paramString = abi.inputs.map((input, idx) => {
|
const paramString = abi.inputs.map((input, idx) => {
|
||||||
const quote = input.type.indexOf("int") === -1 ? '"' : '';
|
const quote = input.type.indexOf("int") === -1 ? '"' : '';
|
||||||
return quote + req.body.inputs[idx] + quote;
|
return quote + req.body.inputs[idx] + quote;
|
||||||
|
@ -214,7 +214,7 @@ export const contractFile = {
|
|||||||
|
|
||||||
export const CONTRACT_FUNCTION = createRequestTypes('CONTRACT_FUNCTION');
|
export const CONTRACT_FUNCTION = createRequestTypes('CONTRACT_FUNCTION');
|
||||||
export const contractFunction = {
|
export const contractFunction = {
|
||||||
post: (contractName, method, inputs, gasPrice) => action(CONTRACT_FUNCTION[REQUEST], {contractName, method, inputs, gasPrice}),
|
post: (contractName, method, inputs, gasPrice, value) => action(CONTRACT_FUNCTION[REQUEST], {contractName, method, inputs, gasPrice, value}),
|
||||||
success: (result, payload) => action(CONTRACT_FUNCTION[SUCCESS], {contractFunctions: [{...result, ...payload}]}),
|
success: (result, payload) => action(CONTRACT_FUNCTION[SUCCESS], {contractFunctions: [{...result, ...payload}]}),
|
||||||
failure: (error) => action(CONTRACT_FUNCTION[FAILURE], {error})
|
failure: (error) => action(CONTRACT_FUNCTION[FAILURE], {error})
|
||||||
};
|
};
|
||||||
|
@ -28,13 +28,23 @@ import "./ContractOverview.scss";
|
|||||||
class ContractFunction extends Component {
|
class ContractFunction extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
this.state = {inputs: {}, optionsCollapse: false, functionCollapse: false, gasPriceCollapse: false};
|
this.state = {
|
||||||
|
inputs: {},
|
||||||
|
optionsCollapse: false,
|
||||||
|
functionCollapse: false,
|
||||||
|
gasPriceCollapse: false,
|
||||||
|
value: 0
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
static isPureCall(method) {
|
static isPureCall(method) {
|
||||||
return (method.stateMutability === 'view' || method.stateMutability === 'pure');
|
return (method.stateMutability === 'view' || method.stateMutability === 'pure');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static isPayable(method) {
|
||||||
|
return method.payable;
|
||||||
|
}
|
||||||
|
|
||||||
static isEvent(method) {
|
static isEvent(method) {
|
||||||
return !this.isPureCall(method) && (method.type === 'event');
|
return !this.isPureCall(method) && (method.type === 'event');
|
||||||
}
|
}
|
||||||
@ -59,9 +69,13 @@ class ContractFunction extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
handleChange(e, name) {
|
handleChange(e, name) {
|
||||||
const newInputs = this.state.inputs;
|
if (name === `${this.props.method.name}-value`) {
|
||||||
newInputs[name] = e.target.value;
|
this.setState({ value: e.target.value });
|
||||||
this.setState({inputs: newInputs});
|
} else {
|
||||||
|
const newInputs = this.state.inputs;
|
||||||
|
newInputs[name] = e.target.value;
|
||||||
|
this.setState({inputs: newInputs});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
autoSetGasPrice(e) {
|
autoSetGasPrice(e) {
|
||||||
@ -78,7 +92,8 @@ class ContractFunction extends Component {
|
|||||||
this.props.contractName,
|
this.props.contractName,
|
||||||
this.props.method.name,
|
this.props.method.name,
|
||||||
this.inputsAsArray(),
|
this.inputsAsArray(),
|
||||||
this.state.inputs.gasPrice * 1000000000
|
this.state.inputs.gasPrice * 1000000000,
|
||||||
|
this.state.value
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -171,12 +186,25 @@ class ContractFunction extends Component {
|
|||||||
: (ContractFunction.isPureCall(this.props.method) &&
|
: (ContractFunction.isPureCall(this.props.method) &&
|
||||||
this.makeBadge('success', 'white', 'call')) ||
|
this.makeBadge('success', 'white', 'call')) ||
|
||||||
this.makeBadge('warning', 'black', 'send')}
|
this.makeBadge('warning', 'black', 'send')}
|
||||||
|
{ContractFunction.isPayable(this.props.method) &&
|
||||||
|
this.makeBadge('light', 'black', 'payable')
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
</CardTitle>
|
</CardTitle>
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
{!ContractFunction.isFallback(this.props.method) &&
|
{!ContractFunction.isFallback(this.props.method) &&
|
||||||
<Collapse isOpen={this.state.functionCollapse} className="relative">
|
<Collapse isOpen={this.state.functionCollapse} className="relative">
|
||||||
<CardBody>
|
<CardBody>
|
||||||
|
{ContractFunction.isPayable(this.props.method) &&
|
||||||
|
<Form inline>
|
||||||
|
<Label for={this.props.method.name + '-value'} className="mr-2 font-weight-bold contract-function-input">ETH</Label>
|
||||||
|
<Input name={this.props.method.name}
|
||||||
|
id={this.props.method.name + '-value'}
|
||||||
|
onChange={(e) => this.handleChange(e, this.props.method.name + '-value')}
|
||||||
|
onKeyPress={(e) => this.handleKeyPress(e)}
|
||||||
|
/>
|
||||||
|
</Form>
|
||||||
|
}
|
||||||
<Form inline>
|
<Form inline>
|
||||||
{this.props.method.inputs.map((input, idx) => (
|
{this.props.method.inputs.map((input, idx) => (
|
||||||
<FormGroup key={idx}>
|
<FormGroup key={idx}>
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
.contract-function-badge {
|
.contract-function-badge {
|
||||||
cursor: default;
|
cursor: default;
|
||||||
|
margin-left: 1em;
|
||||||
|
|
||||||
code {
|
code {
|
||||||
font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace;
|
font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user