+
{contract.className}
- {contract.address || 'Interface or not set to deploy'}
- {contract.deploy ? 'Deployed' : 'Not deployed'}
+ {contractDisplay.address}
+ {contractDisplay.state}
);
})
diff --git a/embark-ui/src/components/FiddleResults.js b/embark-ui/src/components/FiddleResults.js
index f3c581743..5bf2460da 100644
--- a/embark-ui/src/components/FiddleResults.js
+++ b/embark-ui/src/components/FiddleResults.js
@@ -57,29 +57,51 @@ class FiddleResults extends Component {
}
render() {
- const {warnings, errors, fatal, isLoading, deployedContracts} = this.props;
-
+ const {warnings, errors, fatalFiddle, fatalFiddleDeploy, isLoading, deployedContracts} = this.props;
+ const hasFatal = fatalFiddle || fatalFiddleDeploy;
let renderings = [];
- if(fatal){
- renderings.push(
-
-
-
-
- Failed to compile
-
-
-
- {fatal}
-
-
-
-
- );
+ if(hasFatal){
+ if(fatalFiddle){
+ renderings.push(
+
+
+
+
+ Failed to compile
+
+
+
+ {fatalFiddle}
+
+
+
+
+ );
+ }
+ if(fatalFiddleDeploy){
+ renderings.push(
+
+
+
+
+ Failed to deploy
+
+
+
+ {fatalFiddleDeploy}
+
+
+
+
+ );
+ }
+
}
else if (deployedContracts){
renderings.push(
@@ -128,9 +150,10 @@ class FiddleResults extends Component {
FiddleResults.propTypes = {
errors: PropTypes.array,
warnings: PropTypes.array,
- fatal: PropTypes.string,
+ fatalFiddle: PropTypes.string,
+ fatalFiddleDeploy: PropTypes.string,
isLoading: PropTypes.bool,
- deployedContracts: PropTypes.array
+ deployedContracts: PropTypes.object
};
export default FiddleResults;
diff --git a/embark-ui/src/components/FiddleResultsSummary.js b/embark-ui/src/components/FiddleResultsSummary.js
index 0689f4057..47cc2bda2 100644
--- a/embark-ui/src/components/FiddleResultsSummary.js
+++ b/embark-ui/src/components/FiddleResultsSummary.js
@@ -6,40 +6,48 @@ import FiddleDeployButton from './FiddleDeployButton';
class FiddleResultsSummary extends Component{
render(){
- const {warnings, errors, isLoading, loadingMessage, hasResult, fatal} = this.props;
+ const {warnings, errors, isLoading, loadingMessage, hasResult, fatalFiddle, fatalFiddleDeploy} = this.props;
let renderings = [];
- if(fatal) {
- renderings.push(
-
-
-
- );
- }
- else if(isLoading){
+ if(isLoading){
renderings.push(
{loadingMessage}
);
}
- else {
- if(hasResult && !errors.length){
- renderings.push(
-
- Compiled
- this.props.onDeployClick(e)} />
-
- );
- }
- if(errors.length) renderings.push(
+ if(fatalFiddle) {
+ renderings.push(
- {errors.length} error{errors.length > 1 ? "s" : ""}
-
- );
- if(warnings.length) renderings.push(
-
- {warnings.length} warning{warnings.length > 1 ? "s" : ""}
+ Compilation
);
}
+
+ if(fatalFiddleDeploy) {
+ renderings.push(
+
+ Deployment
+
+ );
+ }
+
+ if(errors.length) renderings.push(
+
+ {errors.length} error{errors.length > 1 ? "s" : ""}
+
+ );
+ if(warnings.length) renderings.push(
+
+ {warnings.length} warning{warnings.length > 1 ? "s" : ""}
+
+ );
+ if(hasResult && !errors.length){
+ renderings.push(
+
+ Compiled
+ this.props.onDeployClick(e)} />
+
+ );
+ }
+
return (
{renderings}
@@ -55,7 +63,8 @@ FiddleResultsSummary.propTypes = {
isLoading: PropTypes.bool,
loadingMessage: PropTypes.string,
hasResult: PropTypes.bool,
- fatal: PropTypes.string,
+ fatalFiddle: PropTypes.string,
+ fatalFiddleDeploy: PropTypes.string,
onDeployClick: PropTypes.func
};
diff --git a/embark-ui/src/containers/FiddleContainer.js b/embark-ui/src/containers/FiddleContainer.js
index 6e9ed8e51..9dc410670 100644
--- a/embark-ui/src/containers/FiddleContainer.js
+++ b/embark-ui/src/containers/FiddleContainer.js
@@ -82,7 +82,7 @@ class FiddleContainer extends Component {
}
render() {
- const {fiddle, loading, error, deployedContracts} = this.props;
+ const {fiddle, loading, fiddleError, fiddleDeployError, deployedContracts} = this.props;
const {loadingMessage} = this.state;
let renderings = [];
let warnings = [];
@@ -99,7 +99,8 @@ class FiddleContainer extends Component {
isLoading={loading}
loadingMessage={loadingMessage}
hasResult={Boolean(fiddle)}
- fatal={error}
+ fatalFiddle={fiddleError}
+ fatalFiddleDeploy={fiddleDeployError}
onDeployClick={(e) => this._onDeployClick(e)}
/>
);
- if (fiddle || (this.state.value && error)) {
+ if (fiddle || (this.state.value && (fiddleError || fiddleDeployError))) {
renderings.push(
);
@@ -143,23 +145,26 @@ function mapStateToProps(state) {
return {
fiddle: fiddle.data,
deployedContracts: deployedFiddle.data,
- error: fiddle.error || deployedFiddle.error,
+ fiddleError: fiddle.error,
+ fiddleDeployError: deployedFiddle.error,
loading: state.loading
};
}
FiddleContainer.propTypes = {
fiddle: PropTypes.object,
- error: PropTypes.string,
+ fiddleError: PropTypes.string,
+ fiddleDeployError: PropTypes.string,
loading: PropTypes.bool,
postFiddle: PropTypes.func,
- postFiddleDeploy: PropTypes.func
+ postFiddleDeploy: PropTypes.func,
+ deployedContracts: PropTypes.object
};
export default connect(
mapStateToProps,
{
- postFiddle: fiddleAction.request,
- postFiddleDeploy: fiddleDeployAction.request
+ postFiddle: fiddleAction.post,
+ postFiddleDeploy: fiddleDeployAction.post
},
)(FiddleContainer);
diff --git a/embark-ui/src/reducers/selectors.js b/embark-ui/src/reducers/selectors.js
index 847f59ba9..9887a1810 100644
--- a/embark-ui/src/reducers/selectors.js
+++ b/embark-ui/src/reducers/selectors.js
@@ -107,14 +107,14 @@ export function getMessages(state) {
export function getFiddle(state) {
return {
data: _.last(state.entities.fiddles),
- error: _.last(state.errorEntities.fiddles)
+ error: state.errorEntities.fiddles
};
}
export function getFiddleDeploy(state) {
return {
data: _.last(state.entities.fiddleDeploys),
- error: _.last(state.errorEntities.fiddleDeploys)
+ error: state.errorEntities.fiddleDeploys
};
}
diff --git a/embark-ui/src/utils/presentation.js b/embark-ui/src/utils/presentation.js
new file mode 100644
index 000000000..43ff127e4
--- /dev/null
+++ b/embark-ui/src/utils/presentation.js
@@ -0,0 +1,19 @@
+export function formatContractForDisplay(contract) {
+ let address = (contract.address || contract.deployedAddress);
+ let state = 'Deployed';
+ let stateColor = 'success';
+ if (contract.deploy === false) {
+ address = 'Interface or set to not deploy';
+ state = 'N/A';
+ stateColor = 'info';
+ } else if (contract.error) {
+ address = contract.error;
+ state = 'Error';
+ stateColor = 'danger';
+ } else if (!address) {
+ address = '...';
+ state = 'Pending';
+ stateColor = 'warning';
+ }
+ return {address, state, stateColor};
+}
diff --git a/lib/modules/contracts_manager/index.js b/lib/modules/contracts_manager/index.js
index 916c45e93..c2fc69c5c 100644
--- a/lib/modules/contracts_manager/index.js
+++ b/lib/modules/contracts_manager/index.js
@@ -1,6 +1,7 @@
let toposort = require('toposort');
let async = require('async');
const cloneDeep = require('clone-deep');
+const _ = require('lodash');
let utils = require('../../utils/utils.js');
@@ -169,22 +170,44 @@ class ContractsManager {
'post',
'/embark-api/contract/deploy',
(req, res) => {
+ this.logger.trace(`POST request /embark-api/contract/deploy:\n ${JSON.stringify(req.body)}`);
self.compiledContracts = Object.assign(self.compiledContracts, req.body.compiledContract);
+ const contractNames = Object.keys(req.body.compiledContract);
self.build((err, _mgr) => {
- const responseData = {errors: err, contractNames: Object.keys(req.body.compiledContract)};
+ if(err){
+ return res.send({error: err.message});
+ }
+ // pick the compiled contracts that have been built
+ const builtContracts = _.pick(self.contracts, contractNames);
+
+ // for each contract, deploy (in parallel)
+ async.eachOf(builtContracts, (contract, contractName, callback) => {
+ contract.args = []; /* TODO: override contract.args */
+ contract.className = contractName;
+ self.events.request("deploy:contract", contract, (err) => {
+ callback(err);
+ });
+ }, (err) => {
+ let responseData = {};
+ if(err){
+ responseData.error = err.message;
+ }
+ else responseData.result = contractNames;
this.logger.trace(`POST response /embark-api/contract/deploy:\n ${JSON.stringify(responseData)}`);
res.send(responseData);
- }, false);
+ });
+ }, false, false);
}
);
}
- build(done, useContractFiles = true) {
+ build(done, useContractFiles = true, resetContracts = true) {
let self = this;
self.contracts = {};
let compilerOptions = {disableOptimizations: this.disableOptimizations};
+ if(resetContracts) self.contracts = {};
async.waterfall([
function loadContractFiles(callback) {
self.events.request("config:contractsFiles", (contractsFiles) => {
@@ -210,6 +233,12 @@ class ContractsManager {
},
function prepareContractsFromConfig(callback) {
self.events.emit("status", __("Building..."));
+
+ // if we are appending contracts (ie fiddle), we
+ // don't need to build a contract from config, so
+ // we can skip this entirely
+ if(!resetContracts) return callback();
+
let className, contract;
for (className in self.contractsConfig.contracts) {
contract = self.contractsConfig.contracts[className];
diff --git a/lib/modules/solidity/index.js b/lib/modules/solidity/index.js
index ced9c980f..ab30cc13c 100644
--- a/lib/modules/solidity/index.js
+++ b/lib/modules/solidity/index.js
@@ -1,5 +1,6 @@
let async = require('../../utils/async_extend.js');
let SolcW = require('./solcW.js');
+const fs = require('../../core/fs');
class Solidity {
@@ -19,8 +20,12 @@ class Solidity {
'post',
'/embark-api/contract/compile',
(req, res) => {
- const input = {'fiddler': {content: req.body.code.replace(/\r\n/g, '\n')}};
+ const input = {'fiddle': {content: req.body.code.replace(/\r\n/g, '\n')}};
this.compile_solidity_code(input, {}, true, (errors, compilationResult) => {
+ // write code to filesystem so we can view the source after page refresh
+ const filePath = `.embark/fiddles/${Object.keys(compilationResult).join('_')}.sol`;
+ fs.writeFile(filePath, req.body.code, 'utf8'); // async, do not need to wait
+
const responseData = {errors: errors, compilationResult: compilationResult};
this.logger.trace(`POST response /embark-api/contract/compile:\n ${JSON.stringify(responseData)}`);
res.send(responseData);
@@ -122,7 +127,8 @@ class Solidity {
let contract = json[contractFile][contractName];
const className = contractName;
- const filename = contractFile;
+ let filename = contractFile;
+ if(filename === 'fiddle') filename = `.embark/fiddles/${className}.sol`;
compiled_object[className] = {};
compiled_object[className].code = contract.evm.bytecode.object;