merge develop
This commit is contained in:
commit
ed7de6af93
|
@ -0,0 +1,92 @@
|
|||
# Contributing
|
||||
|
||||
When contributing to this repository, please first discuss the change you wish to make via issue,
|
||||
email, or any other method with the owners of this repository before making a change.
|
||||
|
||||
Please note we have a code of conduct, please follow it in all your interactions with the project.
|
||||
|
||||
## Pull Request Process
|
||||
|
||||
1. Ensure any install or build dependencies are removed before the end of the layer when doing a
|
||||
build.
|
||||
2. Update the README.md with details of changes to the interface, this includes new environment
|
||||
variables, exposed ports, useful file locations and container parameters.
|
||||
3. Increase the version numbers in any examples files and the README.md to the new version that this
|
||||
Pull Request would represent. The versioning scheme we use is [SemVer](http://semver.org/).
|
||||
4. You may merge the Pull Request in once you have the sign-off of two other developers, or if you
|
||||
do not have permission to do that, you may request the second reviewer to merge it for you.
|
||||
|
||||
## Code of Conduct
|
||||
|
||||
### Our Pledge
|
||||
|
||||
In the interest of fostering an open and welcoming environment, we as
|
||||
contributors and maintainers pledge to making participation in our project and
|
||||
our community a harassment-free experience for everyone, regardless of age, body
|
||||
size, disability, ethnicity, gender identity and expression, level of experience,
|
||||
nationality, personal appearance, race, religion, or sexual identity and
|
||||
orientation.
|
||||
|
||||
### Our Standards
|
||||
|
||||
Examples of behavior that contributes to creating a positive environment
|
||||
include:
|
||||
|
||||
* Using welcoming and inclusive language
|
||||
* Being respectful of differing viewpoints and experiences
|
||||
* Gracefully accepting constructive criticism
|
||||
* Focusing on what is best for the community
|
||||
* Showing empathy towards other community members
|
||||
|
||||
Examples of unacceptable behavior by participants include:
|
||||
|
||||
* The use of sexualized language or imagery and unwelcome sexual attention or
|
||||
advances
|
||||
* Trolling, insulting/derogatory comments, and personal or political attacks
|
||||
* Public or private harassment
|
||||
* Publishing others' private information, such as a physical or electronic
|
||||
address, without explicit permission
|
||||
* Other conduct which could reasonably be considered inappropriate in a
|
||||
professional setting
|
||||
|
||||
### Our Responsibilities
|
||||
|
||||
Project maintainers are responsible for clarifying the standards of acceptable
|
||||
behavior and are expected to take appropriate and fair corrective action in
|
||||
response to any instances of unacceptable behavior.
|
||||
|
||||
Project maintainers have the right and responsibility to remove, edit, or
|
||||
reject comments, commits, code, wiki edits, issues, and other contributions
|
||||
that are not aligned to this Code of Conduct, or to ban temporarily or
|
||||
permanently any contributor for other behaviors that they deem inappropriate,
|
||||
threatening, offensive, or harmful.
|
||||
|
||||
### Scope
|
||||
|
||||
This Code of Conduct applies both within project spaces and in public spaces
|
||||
when an individual is representing the project or its community. Examples of
|
||||
representing a project or community include using an official project e-mail
|
||||
address, posting via an official social media account, or acting as an appointed
|
||||
representative at an online or offline event. Representation of a project may be
|
||||
further defined and clarified by project maintainers.
|
||||
|
||||
### Enforcement
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||
reported by contacting the project team at [INSERT EMAIL ADDRESS]. All
|
||||
complaints will be reviewed and investigated and will result in a response that
|
||||
is deemed necessary and appropriate to the circumstances. The project team is
|
||||
obligated to maintain confidentiality with regard to the reporter of an incident.
|
||||
Further details of specific enforcement policies may be posted separately.
|
||||
|
||||
Project maintainers who do not follow or enforce the Code of Conduct in good
|
||||
faith may face temporary or permanent repercussions as determined by other
|
||||
members of the project's leadership.
|
||||
|
||||
### Attribution
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
|
||||
available at [http://contributor-covenant.org/version/1/4][version]
|
||||
|
||||
[homepage]: http://contributor-covenant.org
|
||||
[version]: http://contributor-covenant.org/version/1/4/
|
34
README.md
34
README.md
|
@ -1,4 +1,5 @@
|
|||
[![Join the chat at https://gitter.im/iurimatias/embark-framework](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/iurimatias/embark-framework?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||
[![npm](https://img.shields.io/npm/dm/embark.svg)]()
|
||||
[![Gitter](https://img.shields.io/gitter/room/iurimatias/embark-framework.svg)]()
|
||||
[![Build
|
||||
Status](https://travis-ci.org/iurimatias/embark-framework.svg?branch=develop)](https://travis-ci.org/iurimatias/embark-framework)
|
||||
[![Code Climate](https://codeclimate.com/github/iurimatias/embark-framework/badges/gpa.svg)](https://codeclimate.com/github/iurimatias/embark-framework)
|
||||
|
@ -41,14 +42,14 @@ Table of Contents
|
|||
* [Dashboard](#dashboard)
|
||||
* [Creating a new DApp](#creating-a-new-dapp)
|
||||
* [Libraries and APIs available](#libraries-and-languages-available)
|
||||
* [Using and Configuring Contracts](#dapp-structure)
|
||||
* [Using and Configuring Contracts](#using-contracts)
|
||||
* [EmbarkJS](#embarkjs)
|
||||
* [EmbarkJS - Storage (IPFS)](#embarkjs---storage)
|
||||
* [EmbarkJS - Communication (Whisper/Orbit)](#embarkjs---communication)
|
||||
* [Testing Contracts](#tests)
|
||||
* [Working with different chains](#working-with-different-chains)
|
||||
* [Custom Application Structure](#structuring-application)
|
||||
* [Deploying to IPFS](#deploying-to-ipfs)
|
||||
* [Deploying to IPFS](#deploying-to-ipfs-and-swarm)
|
||||
* [Extending Functionality with Plugins](#plugins)
|
||||
* [Donations](#donations)
|
||||
|
||||
|
@ -144,8 +145,11 @@ DApp Structure
|
|||
|___ css/
|
||||
|___ js/
|
||||
config/
|
||||
|___ blockchain.json #environments configuration
|
||||
|___ contracts.json #contracts configuration
|
||||
|___ blockchain.json #rpc and blockchain configuration
|
||||
|___ contracts.json #ethereum contracts configuration
|
||||
|___ storage.json #ipfs configuration
|
||||
|___ communication.json #whisper/orbit configuration
|
||||
|___ webserver.json #dev webserver configuration
|
||||
test/
|
||||
|___ #contracts tests
|
||||
```
|
||||
|
@ -223,7 +227,7 @@ If you are using multiple contracts, you can pass a reference to another contrac
|
|||
"SimpleStorage": {
|
||||
"args": [
|
||||
100,
|
||||
$MyStorage
|
||||
"$MyStorage"
|
||||
]
|
||||
},
|
||||
"MyStorage": {
|
||||
|
@ -233,7 +237,7 @@ If you are using multiple contracts, you can pass a reference to another contrac
|
|||
},
|
||||
"MyMainContract": {
|
||||
"args": [
|
||||
$SimpleStorage
|
||||
"$SimpleStorage"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
@ -322,14 +326,20 @@ events:
|
|||
Client side deployment will be automatically available in Embark for existing contracts:
|
||||
|
||||
```Javascript
|
||||
SimpleStorage.deploy().then(function(anotherSimpleStorage) {});
|
||||
SimpleStorage.deploy([args], {options}).then(function(anotherSimpleStorage) {});
|
||||
```
|
||||
|
||||
or it can be manually definied as
|
||||
|
||||
```Javascript
|
||||
var myContract = new EmbarkJS.Contract({abi: abiObject, code: code});
|
||||
myContract.deploy().then(function(anotherMyContractObject) {});
|
||||
myContract.deploy([args], {options}).then(function(anotherMyContractObject) {});
|
||||
```
|
||||
|
||||
so you can define your gas as
|
||||
|
||||
```Javascript
|
||||
myContract.deploy([100, "seconde argument"], {gas: 800000}).then(function(anotherMyContractObject) {});
|
||||
```
|
||||
|
||||
EmbarkJS - Storage
|
||||
|
@ -428,12 +438,11 @@ Embark includes a testing lib to fastly run & test your contracts in a EVM.
|
|||
# test/simple_storage_spec.js
|
||||
|
||||
var assert = require('assert');
|
||||
var Embark = require('embark');
|
||||
var EmbarkSpec = Embark.initTests();
|
||||
var web3 = EmbarkSpec.web3;
|
||||
var EmbarkSpec = require('embark/lib/core/test.js');
|
||||
|
||||
describe("SimpleStorage", function() {
|
||||
before(function(done) {
|
||||
this.timeout(0);
|
||||
var contractsConfig = {
|
||||
"SimpleStorage": {
|
||||
args: [100]
|
||||
|
@ -459,6 +468,7 @@ describe("SimpleStorage", function() {
|
|||
});
|
||||
|
||||
});
|
||||
|
||||
```
|
||||
|
||||
Embark uses [Mocha](http://mochajs.org/) by default, but you can use any testing framework you want.
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#!/usr/bin/env node
|
||||
|
||||
var Embark = require('..');
|
||||
Embark.process(process.argv);
|
||||
var Cmd = require('../lib/cmd');
|
||||
var cli = new Cmd();
|
||||
cli.process(process.argv);
|
||||
|
|
|
@ -6,6 +6,6 @@
|
|||
</head>
|
||||
<body>
|
||||
<h3>Welcome to Embark!</h3>
|
||||
<p>See the <a href="https://github.com/iurimatias/embark-framework/wiki">Wiki</a> to see what you can do with Embark!</p>
|
||||
<p>See the <a href="http://embark.readthedocs.io/en/latest/index.html" target="_blank">Embark's documentation</a> to see what you can do with Embark!</p>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
var assert = require('assert');
|
||||
var Embark = require('embark');
|
||||
var EmbarkSpec = Embark.initTests();
|
||||
var web3 = EmbarkSpec.web3;
|
||||
var EmbarkSpec = require('embark/lib/core/test.js');
|
||||
|
||||
//describe("SimpleStorage", function() {
|
||||
|
||||
// describe("SimpleStorage", function() {
|
||||
// before(function(done) {
|
||||
// this.timeout(0);
|
||||
// var contractsConfig = {
|
||||
|
@ -30,4 +29,4 @@ var web3 = EmbarkSpec.web3;
|
|||
// });
|
||||
// });
|
||||
//
|
||||
//});
|
||||
// });
|
|
@ -32,35 +32,55 @@ $(document).ready(function() {
|
|||
//EmbarkJS.Storage.setProvider('ipfs',{server: 'localhost', port: '5001'});
|
||||
|
||||
$("#storage .error").hide();
|
||||
EmbarkJS.Storage.ipfsConnection.ping()
|
||||
EmbarkJS.Storage.setProvider('ipfs')
|
||||
.then(function(){
|
||||
$("#status-storage").addClass('status-online');
|
||||
$("#storage-controls").show();
|
||||
console.log('Provider set to IPFS');
|
||||
EmbarkJS.Storage.ipfsConnection.ping()
|
||||
.then(function(){
|
||||
$("#status-storage").addClass('status-online');
|
||||
$("#storage-controls").show();
|
||||
})
|
||||
.catch(function(err) {
|
||||
if(err){
|
||||
console.log("IPFS Connection Error => " + err.message);
|
||||
$("#storage .error").show();
|
||||
$("#status-storage").addClass('status-offline');
|
||||
$("#storage-controls").hide();
|
||||
}
|
||||
});
|
||||
})
|
||||
.catch(function(err) {
|
||||
if(err){
|
||||
console.log("IPFS Connection Error => " + err.message);
|
||||
$("#storage .error").show();
|
||||
$("#status-storage").addClass('status-offline');
|
||||
$("#storage-controls").hide();
|
||||
}
|
||||
});
|
||||
.catch(function(err){
|
||||
console.log('Failed to set IPFS as Provider:', err.message);
|
||||
$("#storage .error").show();
|
||||
$("#status-storage").addClass('status-offline');
|
||||
$("#storage-controls").hide();
|
||||
});
|
||||
|
||||
$("#storage button.setIpfsText").click(function() {
|
||||
var value = $("#storage input.ipfsText").val();
|
||||
EmbarkJS.Storage.saveText(value).then(function(hash) {
|
||||
$("span.textHash").html(hash);
|
||||
$("input.textHash").val(hash);
|
||||
addToLog("#storage", "EmbarkJS.Storage.saveText('" + value + "').then(function(hash) { })");
|
||||
})
|
||||
.catch(function(err) {
|
||||
if(err){
|
||||
console.log("IPFS saveText Error => " + err.message);
|
||||
}
|
||||
});
|
||||
addToLog("#storage", "EmbarkJS.Storage.saveText('" + value + "').then(function(hash) { })");
|
||||
});
|
||||
|
||||
$("#storage button.loadIpfsHash").click(function() {
|
||||
var value = $("#storage input.textHash").val();
|
||||
EmbarkJS.Storage.get(value).then(function(content) {
|
||||
$("span.ipfsText").html(content);
|
||||
addToLog("#storage", "EmbarkJS.Storage.get('" + value + "').then(function(content) { })");
|
||||
})
|
||||
.catch(function(err) {
|
||||
if(err){
|
||||
console.log("IPFS get Error => " + err.message);
|
||||
}
|
||||
});
|
||||
addToLog("#storage", "EmbarkJS.Storage.get('" + value + "').then(function(content) { })");
|
||||
});
|
||||
|
||||
$("#storage button.uploadFile").click(function() {
|
||||
|
@ -68,8 +88,13 @@ $(document).ready(function() {
|
|||
EmbarkJS.Storage.uploadFile(input).then(function(hash) {
|
||||
$("span.fileIpfsHash").html(hash);
|
||||
$("input.fileIpfsHash").val(hash);
|
||||
addToLog("#storage", "EmbarkJS.Storage.uploadFile($('input[type=file]')).then(function(hash) { })");
|
||||
})
|
||||
.catch(function(err) {
|
||||
if(err){
|
||||
console.log("IPFS uploadFile Error => " + err.message);
|
||||
}
|
||||
});
|
||||
addToLog("#storage", "EmbarkJS.Storage.uploadFile($('input[type=file]')).then(function(hash) { })");
|
||||
});
|
||||
|
||||
$("#storage button.loadIpfsFile").click(function() {
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
"license": "ISC",
|
||||
"homepage": "",
|
||||
"devDependencies": {
|
||||
"embark": "^2.4.0",
|
||||
"embark": "^2.4.1",
|
||||
"mocha": "^2.2.5"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,13 +13,25 @@ The current available storage is IPFS. it can be initialized as
|
|||
|
||||
.. code:: javascript
|
||||
|
||||
EmbarkJS.Storage.saveText("hello world").then(function(hash) {});
|
||||
EmbarkJS.Storage.saveText("hello world")
|
||||
.then(function(hash) {})
|
||||
.catch(function(err) {
|
||||
if(err){
|
||||
console.log("IPFS saveText Error => " + err.message);
|
||||
}
|
||||
});
|
||||
|
||||
**Retrieving Data/Text**
|
||||
|
||||
.. code:: javascript
|
||||
|
||||
EmbarkJS.Storage.get(hash).then(function(content) {});
|
||||
EmbarkJS.Storage.get(hash)
|
||||
.then(function(content) {})
|
||||
.catch(function(err) {
|
||||
if(err){
|
||||
console.log("IPFS get Error => " + err.message);
|
||||
}
|
||||
});
|
||||
|
||||
**Uploading a file**
|
||||
|
||||
|
@ -30,7 +42,13 @@ The current available storage is IPFS. it can be initialized as
|
|||
.. code:: javascript
|
||||
|
||||
var input = $("input[type=file"]);
|
||||
EmbarkJS.Storage.uploadFile(input).then(function(hash) {});
|
||||
EmbarkJS.Storage.uploadFile(input)
|
||||
.then(function(hash) {})
|
||||
.catch(function(err) {
|
||||
if(err){
|
||||
console.log("IPFS uploadFile Error => " + err.message);
|
||||
}
|
||||
});
|
||||
|
||||
**Generate URL to file**
|
||||
|
||||
|
|
|
@ -20,11 +20,17 @@ existing contracts:
|
|||
|
||||
.. code:: javascript
|
||||
|
||||
SimpleStorage.deploy().then(function(anotherSimpleStorage) {});
|
||||
SimpleStorage.deploy([args], {options}).then(function(anotherSimpleStorage) {});
|
||||
|
||||
or it can be manually definied as
|
||||
|
||||
.. code:: javascript
|
||||
|
||||
var myContract = new EmbarkJS.Contract({abi: abiObject, code: code});
|
||||
myContract.deploy().then(function(anotherMyContractObject) {});
|
||||
myContract.deploy([args], {options}).then(function(anotherMyContractObject) {});
|
||||
|
||||
so you can define your gas as
|
||||
|
||||
.. code:: javascript
|
||||
|
||||
myContract.deploy([100, "seconde argument"], {gas: 800000}).then(function(anotherMyContractObject) {});
|
||||
|
|
|
@ -64,7 +64,7 @@ with the correct address for the contract.
|
|||
"SimpleStorage": {
|
||||
"args": [
|
||||
100,
|
||||
$MyStorage
|
||||
"$MyStorage"
|
||||
]
|
||||
},
|
||||
"MyStorage": {
|
||||
|
@ -74,7 +74,7 @@ with the correct address for the contract.
|
|||
},
|
||||
"MyMainContract": {
|
||||
"args": [
|
||||
$SimpleStorage
|
||||
"$SimpleStorage"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
759
js/embark.js
759
js/embark.js
|
@ -1,446 +1,501 @@
|
|||
/*jshint esversion: 6 */
|
||||
//var Ipfs = require('./ipfs.js');
|
||||
|
||||
var EmbarkJS = {
|
||||
};
|
||||
//=========================================================
|
||||
// Embark Smart Contracts
|
||||
//=========================================================
|
||||
|
||||
var EmbarkJS = {};
|
||||
|
||||
EmbarkJS.Contract = function(options) {
|
||||
var self = this;
|
||||
var i, abiElement;
|
||||
var self = this;
|
||||
var i, abiElement;
|
||||
|
||||
this.abi = options.abi;
|
||||
this.address = options.address;
|
||||
this.code = '0x' + options.code;
|
||||
this.web3 = options.web3 || web3;
|
||||
this.abi = options.abi;
|
||||
this.address = options.address;
|
||||
this.code = '0x' + options.code;
|
||||
this.web3 = options.web3 || web3;
|
||||
|
||||
var ContractClass = this.web3.eth.contract(this.abi);
|
||||
var ContractClass = this.web3.eth.contract(this.abi);
|
||||
|
||||
this.eventList = [];
|
||||
this.eventList = [];
|
||||
|
||||
if (this.abi) {
|
||||
for (i = 0; i < this.abi.length; i++) {
|
||||
abiElement = this.abi[i];
|
||||
if (abiElement.type === 'event') {
|
||||
this.eventList.push(abiElement.name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var messageEvents = function() {
|
||||
this.cb = function() {};
|
||||
};
|
||||
|
||||
messageEvents.prototype.then = function(cb) {
|
||||
this.cb = cb;
|
||||
};
|
||||
|
||||
messageEvents.prototype.error = function(err) {
|
||||
return err;
|
||||
};
|
||||
|
||||
this._originalContractObject = ContractClass.at(this.address);
|
||||
this._methods = Object.getOwnPropertyNames(this._originalContractObject).filter(function (p) {
|
||||
// TODO: check for forbidden properties
|
||||
if (self.eventList.indexOf(p) >= 0) {
|
||||
|
||||
self[p] = function() {
|
||||
var promise = new messageEvents();
|
||||
var args = Array.prototype.slice.call(arguments);
|
||||
args.push(function(err, result) {
|
||||
if (err) {
|
||||
promise.error(err);
|
||||
} else {
|
||||
promise.cb(result);
|
||||
}
|
||||
});
|
||||
|
||||
self._originalContractObject[p].apply(self._originalContractObject[p], args);
|
||||
return promise;
|
||||
};
|
||||
return true;
|
||||
} else if (typeof self._originalContractObject[p] === 'function') {
|
||||
self[p] = function(_args) {
|
||||
var args = Array.prototype.slice.call(arguments);
|
||||
var fn = self._originalContractObject[p];
|
||||
var props = self.abi.find((x) => x.name == p);
|
||||
|
||||
var promise = new Promise(function(resolve, reject) {
|
||||
args.push(function(err, transaction) {
|
||||
promise.tx = transaction;
|
||||
if (err) {
|
||||
return reject(err);
|
||||
if (this.abi) {
|
||||
for (i = 0; i < this.abi.length; i++) {
|
||||
abiElement = this.abi[i];
|
||||
if (abiElement.type === 'event') {
|
||||
this.eventList.push(abiElement.name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var getConfirmation = function() {
|
||||
self.web3.eth.getTransactionReceipt(transaction, function(err, receipt) {
|
||||
if (err) {
|
||||
return reject(err);
|
||||
}
|
||||
var messageEvents = function() {
|
||||
this.cb = function() {};
|
||||
};
|
||||
|
||||
if (receipt !== null) {
|
||||
return resolve(receipt);
|
||||
}
|
||||
messageEvents.prototype.then = function(cb) {
|
||||
this.cb = cb;
|
||||
};
|
||||
|
||||
setTimeout(getConfirmation, 1000);
|
||||
});
|
||||
messageEvents.prototype.error = function(err) {
|
||||
return err;
|
||||
};
|
||||
|
||||
this._originalContractObject = ContractClass.at(this.address);
|
||||
this._methods = Object.getOwnPropertyNames(this._originalContractObject).filter(function(p) {
|
||||
// TODO: check for forbidden properties
|
||||
if (self.eventList.indexOf(p) >= 0) {
|
||||
|
||||
self[p] = function() {
|
||||
var promise = new messageEvents();
|
||||
var args = Array.prototype.slice.call(arguments);
|
||||
args.push(function(err, result) {
|
||||
if (err) {
|
||||
promise.error(err);
|
||||
} else {
|
||||
promise.cb(result);
|
||||
}
|
||||
});
|
||||
|
||||
self._originalContractObject[p].apply(self._originalContractObject[p], args);
|
||||
return promise;
|
||||
};
|
||||
return true;
|
||||
} else if (typeof self._originalContractObject[p] === 'function') {
|
||||
self[p] = function(_args) {
|
||||
var args = Array.prototype.slice.call(arguments);
|
||||
var fn = self._originalContractObject[p];
|
||||
var props = self.abi.find((x) => x.name == p);
|
||||
|
||||
if (typeof(transaction) !== "string" || props.constant) {
|
||||
resolve(transaction);
|
||||
} else {
|
||||
getConfirmation();
|
||||
}
|
||||
});
|
||||
var promise = new Promise(function(resolve, reject) {
|
||||
args.push(function(err, transaction) {
|
||||
promise.tx = transaction;
|
||||
if (err) {
|
||||
return reject(err);
|
||||
}
|
||||
|
||||
fn.apply(fn, args);
|
||||
});
|
||||
var getConfirmation = function() {
|
||||
self.web3.eth.getTransactionReceipt(transaction, function(err, receipt) {
|
||||
if (err) {
|
||||
return reject(err);
|
||||
}
|
||||
|
||||
return promise;
|
||||
};
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
if (receipt !== null) {
|
||||
return resolve(receipt);
|
||||
}
|
||||
|
||||
setTimeout(getConfirmation, 1000);
|
||||
});
|
||||
};
|
||||
|
||||
if (typeof(transaction) !== "string" || props.constant) {
|
||||
resolve(transaction);
|
||||
} else {
|
||||
getConfirmation();
|
||||
}
|
||||
});
|
||||
|
||||
fn.apply(fn, args);
|
||||
});
|
||||
|
||||
return promise;
|
||||
};
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
};
|
||||
|
||||
EmbarkJS.Contract.prototype.deploy = function(args, _options) {
|
||||
var self = this;
|
||||
var contractParams;
|
||||
var options = _options || {};
|
||||
var self = this;
|
||||
var contractParams;
|
||||
var options = _options || {};
|
||||
|
||||
contractParams = args || [];
|
||||
contractParams = args || [];
|
||||
|
||||
contractParams.push({
|
||||
from: this.web3.eth.accounts[0],
|
||||
data: this.code,
|
||||
gas: options.gas || 800000
|
||||
});
|
||||
|
||||
var contractObject = this.web3.eth.contract(this.abi);
|
||||
|
||||
var promise = new Promise(function(resolve, reject) {
|
||||
contractParams.push(function(err, transaction) {
|
||||
if (err) {
|
||||
reject(err);
|
||||
} else if (transaction.address !== undefined) {
|
||||
resolve(new EmbarkJS.Contract({abi: self.abi, code: self.code, address: transaction.address}));
|
||||
}
|
||||
contractParams.push({
|
||||
from: this.web3.eth.accounts[0],
|
||||
data: this.code,
|
||||
gas: options.gas || 800000
|
||||
});
|
||||
|
||||
// returns promise
|
||||
// deploys contract
|
||||
// wraps it around EmbarkJS.Contract
|
||||
contractObject["new"].apply(contractObject, contractParams);
|
||||
});
|
||||
var contractObject = this.web3.eth.contract(this.abi);
|
||||
|
||||
|
||||
return promise;
|
||||
var promise = new Promise(function(resolve, reject) {
|
||||
contractParams.push(function(err, transaction) {
|
||||
if (err) {
|
||||
reject(err);
|
||||
} else if (transaction.address !== undefined) {
|
||||
resolve(new EmbarkJS.Contract({
|
||||
abi: self.abi,
|
||||
code: self.code,
|
||||
address: transaction.address
|
||||
}));
|
||||
}
|
||||
});
|
||||
|
||||
// returns promise
|
||||
// deploys contract
|
||||
// wraps it around EmbarkJS.Contract
|
||||
contractObject["new"].apply(contractObject, contractParams);
|
||||
});
|
||||
|
||||
|
||||
return promise;
|
||||
};
|
||||
|
||||
EmbarkJS.IPFS = 'ipfs';
|
||||
//=========================================================
|
||||
// Embark Storage
|
||||
//=========================================================
|
||||
|
||||
EmbarkJS.Storage = {
|
||||
EmbarkJS.Storage = {};
|
||||
|
||||
EmbarkJS.Storage.Providers = {
|
||||
IPFS: 'ipfs',
|
||||
SWARM: 'swarm'
|
||||
};
|
||||
|
||||
EmbarkJS.Storage.setProvider = function(provider, options) {
|
||||
if (provider === 'ipfs') {
|
||||
this.currentStorage = EmbarkJS.Storage.IPFS;
|
||||
if (options === undefined) {
|
||||
this.ipfsConnection = IpfsApi('localhost', '5001');
|
||||
} else {
|
||||
this.ipfsConnection = IpfsApi(options.server, options.port);
|
||||
}
|
||||
} else {
|
||||
throw Error('unknown provider');
|
||||
}
|
||||
};
|
||||
EmbarkJS.Storage.IPFS = {};
|
||||
|
||||
EmbarkJS.Storage.saveText = function(text) {
|
||||
var self = this;
|
||||
if (!this.ipfsConnection) {
|
||||
this.setProvider('ipfs');
|
||||
}
|
||||
var promise = new Promise(function(resolve, reject) {
|
||||
self.ipfsConnection.add((new self.ipfsConnection.Buffer(text)), function(err, result) {
|
||||
if (err) {
|
||||
reject(err);
|
||||
} else {
|
||||
resolve(result[0].path);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
return promise;
|
||||
};
|
||||
|
||||
EmbarkJS.Storage.uploadFile = function(inputSelector) {
|
||||
var self = this;
|
||||
var file = inputSelector[0].files[0];
|
||||
|
||||
if (file === undefined) {
|
||||
throw new Error('no file found');
|
||||
}
|
||||
|
||||
if (!this.ipfsConnection) {
|
||||
this.setProvider('ipfs');
|
||||
}
|
||||
|
||||
var promise = new Promise(function(resolve, reject) {
|
||||
var reader = new FileReader();
|
||||
reader.onloadend = function() {
|
||||
var fileContent = reader.result;
|
||||
var buffer = self.ipfsConnection.Buffer.from(fileContent);
|
||||
self.ipfsConnection.add(buffer, function(err, result) {
|
||||
if (err) {
|
||||
reject(err);
|
||||
} else {
|
||||
resolve(result[0].path);
|
||||
}
|
||||
});
|
||||
};
|
||||
reader.readAsArrayBuffer(file);
|
||||
});
|
||||
|
||||
return promise;
|
||||
return this.currentStorage.saveText(text);
|
||||
};
|
||||
|
||||
EmbarkJS.Storage.get = function(hash) {
|
||||
var self = this;
|
||||
// TODO: detect type, then convert if needed
|
||||
//var ipfsHash = web3.toAscii(hash);
|
||||
if (!this.ipfsConnection) {
|
||||
this.setProvider('ipfs');
|
||||
}
|
||||
return this.currentStorage.get(hash);
|
||||
};
|
||||
|
||||
var promise = new Promise(function(resolve, reject) {
|
||||
self.ipfsConnection.object.get([hash]).then(function(node) {
|
||||
resolve(node.data);
|
||||
});
|
||||
});
|
||||
|
||||
return promise;
|
||||
EmbarkJS.Storage.uploadFile = function(inputSelector) {
|
||||
return this.currentStorage.uploadFile(inputSelector);
|
||||
};
|
||||
|
||||
EmbarkJS.Storage.getUrl = function(hash) {
|
||||
//var ipfsHash = web3.toAscii(hash);
|
||||
|
||||
return 'http://localhost:8080/ipfs/' + hash;
|
||||
return this.currentStorage.getUrl(hash);
|
||||
};
|
||||
|
||||
EmbarkJS.Messages = {
|
||||
EmbarkJS.Storage.setProvider = function(provider, options) {
|
||||
var self = this;
|
||||
var promise = new Promise(function(resolve, reject) {
|
||||
if (provider.toLowerCase() === EmbarkJS.Storage.Providers.IPFS) {
|
||||
//I don't think currentStorage is used anywhere, this might not be needed
|
||||
//for now until additional storage providers are supported. But keeping it
|
||||
//anyways
|
||||
self.currentStorage = EmbarkJS.Storage.IPFS;
|
||||
|
||||
try {
|
||||
if (options === undefined) {
|
||||
self.ipfsConnection = IpfsApi('localhost', '5001');
|
||||
} else {
|
||||
self.ipfsConnection = IpfsApi(options.server, options.port);
|
||||
}
|
||||
resolve(self);
|
||||
} catch (err) {
|
||||
self.ipfsConnection = null;
|
||||
reject(new Error('Failed to connect to IPFS'));
|
||||
}
|
||||
} else if (provider.toLowerCase() === EmbarkJS.Storage.SWARM) {
|
||||
reject('Swarm not implemented');
|
||||
// TODO Implement Swarm
|
||||
// this.currentStorage = EmbarkJS.Storage.SWARM;
|
||||
// if (options === undefined) {
|
||||
// //Connect to default Swarm node
|
||||
// } else {
|
||||
// //Connect using options
|
||||
// }
|
||||
} else {
|
||||
reject('Unknown storage provider');
|
||||
}
|
||||
});
|
||||
return promise;
|
||||
};
|
||||
|
||||
EmbarkJS.Storage.IPFS.saveText = function(text) {
|
||||
var promise = new Promise(function(resolve, reject) {
|
||||
if (!EmbarkJS.Storage.ipfsConnection) {
|
||||
var connectionError = new Error('No IPFS connection. Please ensure to call Embark.Storage.setProvider()');
|
||||
reject(connectionError);
|
||||
}
|
||||
EmbarkJS.Storage.ipfsConnection.add((new EmbarkJS.Storage.ipfsConnection.Buffer(text)), function(err, result) {
|
||||
if (err) {
|
||||
reject(err);
|
||||
} else {
|
||||
resolve(result[0].path);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
return promise;
|
||||
};
|
||||
|
||||
EmbarkJS.Storage.IPFS.get = function(hash) {
|
||||
// TODO: detect type, then convert if needed
|
||||
//var ipfsHash = web3.toAscii(hash);
|
||||
var promise = new Promise(function(resolve, reject) {
|
||||
if (!EmbarkJS.Storage.ipfsConnection) {
|
||||
var connectionError = new Error('No IPFS connection. Please ensure to call Embark.Storage.setProvider()');
|
||||
reject(connectionError);
|
||||
}
|
||||
EmbarkJS.Storage.ipfsConnection.object.get([hash]).then(function(node) {
|
||||
resolve(node.data);
|
||||
}).catch(function(err) {
|
||||
reject(err);
|
||||
});
|
||||
});
|
||||
|
||||
return promise;
|
||||
};
|
||||
|
||||
EmbarkJS.Storage.IPFS.uploadFile = function(inputSelector) {
|
||||
var file = inputSelector[0].files[0];
|
||||
|
||||
if (file === undefined) {
|
||||
throw new Error('no file found');
|
||||
}
|
||||
|
||||
var promise = new Promise(function(resolve, reject) {
|
||||
if (!EmbarkJS.Storage.ipfsConnection) {
|
||||
var connectionError = new Error('No IPFS connection. Please ensure to call Embark.Storage.setProvider()');
|
||||
reject(connectionError);
|
||||
}
|
||||
var reader = new FileReader();
|
||||
reader.onloadend = function() {
|
||||
var fileContent = reader.result;
|
||||
var buffer = EmbarkJS.Storage.ipfsConnection.Buffer.from(fileContent);
|
||||
EmbarkJS.Storage.ipfsConnection.add(buffer, function(err, result) {
|
||||
if (err) {
|
||||
reject(err);
|
||||
} else {
|
||||
resolve(result[0].path);
|
||||
}
|
||||
});
|
||||
};
|
||||
reader.readAsArrayBuffer(file);
|
||||
});
|
||||
|
||||
return promise;
|
||||
};
|
||||
|
||||
EmbarkJS.Storage.IPFS.getUrl = function(hash) {
|
||||
//var ipfsHash = web3.toAscii(hash);
|
||||
|
||||
return 'http://localhost:8080/ipfs/' + hash;
|
||||
};
|
||||
|
||||
//=========================================================
|
||||
// Embark Messaging
|
||||
//=========================================================
|
||||
|
||||
EmbarkJS.Messages = {};
|
||||
|
||||
EmbarkJS.Messages.setProvider = function(provider, options) {
|
||||
var self = this;
|
||||
var ipfs;
|
||||
if (provider === 'whisper') {
|
||||
this.currentMessages = EmbarkJS.Messages.Whisper;
|
||||
if (typeof variable === 'undefined') {
|
||||
if (options === undefined) {
|
||||
web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545"));
|
||||
} else {
|
||||
web3 = new Web3(new Web3.providers.HttpProvider("http://" + options.server + ':' + options.port));
|
||||
}
|
||||
}
|
||||
web3.version.getWhisper(function(err, res) {
|
||||
if (err) {
|
||||
console.log("whisper not available");
|
||||
} else {
|
||||
self.currentMessages.identity = web3.shh.newIdentity();
|
||||
}
|
||||
});
|
||||
} else if (provider === 'orbit') {
|
||||
this.currentMessages = EmbarkJS.Messages.Orbit;
|
||||
if (options === undefined) {
|
||||
ipfs = HaadIpfsApi('localhost', '5001');
|
||||
var self = this;
|
||||
var ipfs;
|
||||
if (provider === 'whisper') {
|
||||
this.currentMessages = EmbarkJS.Messages.Whisper;
|
||||
if (typeof variable === 'undefined') {
|
||||
if (options === undefined) {
|
||||
web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545"));
|
||||
} else {
|
||||
web3 = new Web3(new Web3.providers.HttpProvider("http://" + options.server + ':' + options.port));
|
||||
}
|
||||
}
|
||||
web3.version.getWhisper(function(err, res) {
|
||||
if (err) {
|
||||
console.log("whisper not available");
|
||||
} else {
|
||||
self.currentMessages.identity = web3.shh.newIdentity();
|
||||
}
|
||||
});
|
||||
} else if (provider === 'orbit') {
|
||||
this.currentMessages = EmbarkJS.Messages.Orbit;
|
||||
if (options === undefined) {
|
||||
ipfs = HaadIpfsApi('localhost', '5001');
|
||||
} else {
|
||||
ipfs = HaadIpfsApi(options.server, options.port);
|
||||
}
|
||||
this.currentMessages.orbit = new Orbit(ipfs);
|
||||
this.currentMessages.orbit.connect(web3.eth.accounts[0]);
|
||||
} else {
|
||||
ipfs = HaadIpfsApi(options.server, options.port);
|
||||
throw Error('Unknown message provider');
|
||||
}
|
||||
this.currentMessages.orbit = new Orbit(ipfs);
|
||||
this.currentMessages.orbit.connect(web3.eth.accounts[0]);
|
||||
} else {
|
||||
throw Error('unknown provider');
|
||||
}
|
||||
};
|
||||
|
||||
EmbarkJS.Messages.sendMessage = function(options) {
|
||||
return this.currentMessages.sendMessage(options);
|
||||
return this.currentMessages.sendMessage(options);
|
||||
};
|
||||
|
||||
EmbarkJS.Messages.listenTo = function(options) {
|
||||
return this.currentMessages.listenTo(options);
|
||||
return this.currentMessages.listenTo(options);
|
||||
};
|
||||
|
||||
EmbarkJS.Messages.Whisper = {
|
||||
};
|
||||
EmbarkJS.Messages.Whisper = {};
|
||||
|
||||
EmbarkJS.Messages.Whisper.sendMessage = function(options) {
|
||||
var topics = options.topic || options.topics;
|
||||
var data = options.data || options.payload;
|
||||
var identity = options.identity || this.identity || web3.shh.newIdentity();
|
||||
var ttl = options.ttl || 100;
|
||||
var priority = options.priority || 1000;
|
||||
var _topics;
|
||||
var topics = options.topic || options.topics;
|
||||
var data = options.data || options.payload;
|
||||
var identity = options.identity || this.identity || web3.shh.newIdentity();
|
||||
var ttl = options.ttl || 100;
|
||||
var priority = options.priority || 1000;
|
||||
var _topics;
|
||||
|
||||
if (topics === undefined) {
|
||||
throw new Error("missing option: topic");
|
||||
}
|
||||
|
||||
if (data === undefined) {
|
||||
throw new Error("missing option: data");
|
||||
}
|
||||
|
||||
// do fromAscii to each topics unless it's already a string
|
||||
if (typeof topics === 'string') {
|
||||
_topics = [web3.fromAscii(topics)];
|
||||
} else {
|
||||
// TODO: replace with es6 + babel;
|
||||
for (var i = 0; i < topics.length; i++) {
|
||||
_topics.push(web3.fromAscii(topics[i]));
|
||||
if (topics === undefined) {
|
||||
throw new Error("missing option: topic");
|
||||
}
|
||||
}
|
||||
topics = _topics;
|
||||
|
||||
var payload = JSON.stringify(data);
|
||||
if (data === undefined) {
|
||||
throw new Error("missing option: data");
|
||||
}
|
||||
|
||||
var message = {
|
||||
from: identity,
|
||||
topics: topics,
|
||||
payload: web3.fromAscii(payload),
|
||||
ttl: ttl,
|
||||
priority: priority
|
||||
};
|
||||
// do fromAscii to each topics unless it's already a string
|
||||
if (typeof topics === 'string') {
|
||||
_topics = [web3.fromAscii(topics)];
|
||||
} else {
|
||||
// TODO: replace with es6 + babel;
|
||||
for (var i = 0; i < topics.length; i++) {
|
||||
_topics.push(web3.fromAscii(topics[i]));
|
||||
}
|
||||
}
|
||||
topics = _topics;
|
||||
|
||||
return web3.shh.post(message, function() {});
|
||||
var payload = JSON.stringify(data);
|
||||
|
||||
var message = {
|
||||
from: identity,
|
||||
topics: topics,
|
||||
payload: web3.fromAscii(payload),
|
||||
ttl: ttl,
|
||||
priority: priority
|
||||
};
|
||||
|
||||
return web3.shh.post(message, function() {});
|
||||
};
|
||||
|
||||
EmbarkJS.Messages.Whisper.listenTo = function(options) {
|
||||
var topics = options.topic || options.topics;
|
||||
var _topics = [];
|
||||
var topics = options.topic || options.topics;
|
||||
var _topics = [];
|
||||
|
||||
if (typeof topics === 'string') {
|
||||
_topics = [topics];
|
||||
} else {
|
||||
// TODO: replace with es6 + babel;
|
||||
for (var i = 0; i < topics.length; i++) {
|
||||
_topics.push(topics[i]);
|
||||
}
|
||||
}
|
||||
topics = _topics;
|
||||
|
||||
var filterOptions = {
|
||||
topics: topics
|
||||
};
|
||||
|
||||
var messageEvents = function() {
|
||||
this.cb = function() {};
|
||||
};
|
||||
|
||||
messageEvents.prototype.then = function(cb) {
|
||||
this.cb = cb;
|
||||
};
|
||||
|
||||
messageEvents.prototype.error = function(err) {
|
||||
return err;
|
||||
};
|
||||
|
||||
messageEvents.prototype.stop = function() {
|
||||
this.filter.stopWatching();
|
||||
};
|
||||
|
||||
var promise = new messageEvents();
|
||||
|
||||
var filter = web3.shh.filter(filterOptions, function(err, result) {
|
||||
var payload = JSON.parse(web3.toAscii(result.payload));
|
||||
var data;
|
||||
if (err) {
|
||||
promise.error(err);
|
||||
if (typeof topics === 'string') {
|
||||
_topics = [topics];
|
||||
} else {
|
||||
data = {
|
||||
topic: topics,
|
||||
data: payload,
|
||||
from: result.from,
|
||||
time: (new Date(result.sent * 1000))
|
||||
};
|
||||
promise.cb(payload, data, result);
|
||||
// TODO: replace with es6 + babel;
|
||||
for (var i = 0; i < topics.length; i++) {
|
||||
_topics.push(topics[i]);
|
||||
}
|
||||
}
|
||||
});
|
||||
topics = _topics;
|
||||
|
||||
promise.filter = filter;
|
||||
var filterOptions = {
|
||||
topics: topics
|
||||
};
|
||||
|
||||
return promise;
|
||||
var messageEvents = function() {
|
||||
this.cb = function() {};
|
||||
};
|
||||
|
||||
messageEvents.prototype.then = function(cb) {
|
||||
this.cb = cb;
|
||||
};
|
||||
|
||||
messageEvents.prototype.error = function(err) {
|
||||
return err;
|
||||
};
|
||||
|
||||
messageEvents.prototype.stop = function() {
|
||||
this.filter.stopWatching();
|
||||
};
|
||||
|
||||
var promise = new messageEvents();
|
||||
|
||||
var filter = web3.shh.filter(filterOptions, function(err, result) {
|
||||
var payload = JSON.parse(web3.toAscii(result.payload));
|
||||
var data;
|
||||
if (err) {
|
||||
promise.error(err);
|
||||
} else {
|
||||
data = {
|
||||
topic: topics,
|
||||
data: payload,
|
||||
from: result.from,
|
||||
time: (new Date(result.sent * 1000))
|
||||
};
|
||||
promise.cb(payload, data, result);
|
||||
}
|
||||
});
|
||||
|
||||
promise.filter = filter;
|
||||
|
||||
return promise;
|
||||
};
|
||||
|
||||
EmbarkJS.Messages.Orbit = {
|
||||
};
|
||||
EmbarkJS.Messages.Orbit = {};
|
||||
|
||||
EmbarkJS.Messages.Orbit.sendMessage = function(options) {
|
||||
var topics = options.topic || options.topics;
|
||||
var data = options.data || options.payload;
|
||||
var topics = options.topic || options.topics;
|
||||
var data = options.data || options.payload;
|
||||
|
||||
if (topics === undefined) {
|
||||
throw new Error("missing option: topic");
|
||||
}
|
||||
if (topics === undefined) {
|
||||
throw new Error("missing option: topic");
|
||||
}
|
||||
|
||||
if (data === undefined) {
|
||||
throw new Error("missing option: data");
|
||||
}
|
||||
if (data === undefined) {
|
||||
throw new Error("missing option: data");
|
||||
}
|
||||
|
||||
if (typeof topics === 'string') {
|
||||
topics = topics;
|
||||
} else {
|
||||
// TODO: better to just send to different channels instead
|
||||
topics = topics.join(',');
|
||||
}
|
||||
if (typeof topics === 'string') {
|
||||
topics = topics;
|
||||
} else {
|
||||
// TODO: better to just send to different channels instead
|
||||
topics = topics.join(',');
|
||||
}
|
||||
|
||||
this.orbit.join(topics);
|
||||
this.orbit.join(topics);
|
||||
|
||||
var payload = JSON.stringify(data);
|
||||
var payload = JSON.stringify(data);
|
||||
|
||||
this.orbit.send(topics, data);
|
||||
this.orbit.send(topics, data);
|
||||
};
|
||||
|
||||
EmbarkJS.Messages.Orbit.listenTo = function(options) {
|
||||
var self = this;
|
||||
var topics = options.topic || options.topics;
|
||||
var self = this;
|
||||
var topics = options.topic || options.topics;
|
||||
|
||||
if (typeof topics === 'string') {
|
||||
topics = topics;
|
||||
} else {
|
||||
topics = topics.join(',');
|
||||
}
|
||||
if (typeof topics === 'string') {
|
||||
topics = topics;
|
||||
} else {
|
||||
topics = topics.join(',');
|
||||
}
|
||||
|
||||
this.orbit.join(topics);
|
||||
this.orbit.join(topics);
|
||||
|
||||
var messageEvents = function() {
|
||||
this.cb = function() {};
|
||||
};
|
||||
var messageEvents = function() {
|
||||
this.cb = function() {};
|
||||
};
|
||||
|
||||
messageEvents.prototype.then = function(cb) {
|
||||
this.cb = cb;
|
||||
};
|
||||
messageEvents.prototype.then = function(cb) {
|
||||
this.cb = cb;
|
||||
};
|
||||
|
||||
messageEvents.prototype.error = function(err) {
|
||||
return err;
|
||||
};
|
||||
messageEvents.prototype.error = function(err) {
|
||||
return err;
|
||||
};
|
||||
|
||||
var promise = new messageEvents();
|
||||
var promise = new messageEvents();
|
||||
|
||||
this.orbit.events.on('message', (channel, message) => {
|
||||
// TODO: looks like sometimes it's receving messages from all topics
|
||||
if (topics !== channel) return;
|
||||
self.orbit.getPost(message.payload.value, true).then((post) => {
|
||||
var data = {
|
||||
topic: channel,
|
||||
data: post.content,
|
||||
from: post.meta.from.name,
|
||||
time: (new Date(post.meta.ts))
|
||||
};
|
||||
promise.cb(post.content, data, post);
|
||||
this.orbit.events.on('message', (channel, message) => {
|
||||
// TODO: looks like sometimes it's receving messages from all topics
|
||||
if (topics !== channel) return;
|
||||
self.orbit.getPost(message.payload.value, true).then((post) => {
|
||||
var data = {
|
||||
topic: channel,
|
||||
data: post.content,
|
||||
from: post.meta.from.name,
|
||||
time: (new Date(post.meta.ts))
|
||||
};
|
||||
promise.cb(post.content, data, post);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
return promise;
|
||||
return promise;
|
||||
};
|
||||
|
||||
module.exports = EmbarkJS;
|
||||
|
|
74
lib/cmd.js
74
lib/cmd.js
|
@ -1,15 +1,12 @@
|
|||
var program = require('commander');
|
||||
var colors = require('colors');
|
||||
var shelljs = require('shelljs');
|
||||
var promptly = require('promptly');
|
||||
var path = require('path');
|
||||
var Embark = require('../lib/index');
|
||||
|
||||
var Cmd = function(Embark) {
|
||||
this.Embark = Embark;
|
||||
var Cmd = function() {
|
||||
program.version(Embark.version);
|
||||
};
|
||||
|
||||
|
||||
Cmd.prototype.process = function(args) {
|
||||
this.newApp();
|
||||
this.demo();
|
||||
|
@ -30,64 +27,40 @@ Cmd.prototype.process = function(args) {
|
|||
};
|
||||
|
||||
Cmd.prototype.newApp = function() {
|
||||
var self = this;
|
||||
|
||||
var validateName = function (value) {
|
||||
try {
|
||||
if(value.match(/^[a-zA-Z\s\-]+$/)) return value;
|
||||
} catch (e) {
|
||||
throw new Error('Name must be only letters, spaces, or dashes');
|
||||
}
|
||||
};
|
||||
|
||||
program
|
||||
.command('new [name]')
|
||||
.description('new application')
|
||||
.action(function (name, options) {
|
||||
var parentDirectory = path.dirname(__dirname).split("/").pop();
|
||||
if (name === undefined) {
|
||||
return promptly.prompt("Name your app: (default: " + parentDirectory + ")", {
|
||||
default: parentDirectory,
|
||||
validator: validateName
|
||||
}, function (err, inputvalue) {
|
||||
if (err) {
|
||||
console.error('Invalid name:', err.message);
|
||||
// Manually call retry
|
||||
// The passed error has a retry method to easily prompt again.
|
||||
err.retry();
|
||||
} else {
|
||||
//slightly different assignment of name since it comes from child prompt
|
||||
self.Embark.generateTemplate('boilerplate', parentDirectory, inputvalue);
|
||||
}
|
||||
});
|
||||
}
|
||||
.command('new [name]')
|
||||
.description('new application')
|
||||
.action(function(name, options) {
|
||||
if (name === undefined) {
|
||||
|
||||
self.Embark.generateTemplate('boilerplate', './', name);
|
||||
});
|
||||
console.log("please specify your app Name".red);
|
||||
console.log("e.g embark new MyApp".green);
|
||||
console.log("e.g embark new --help for more information".green);
|
||||
process.exit(9);
|
||||
}
|
||||
Embark.generateTemplate('boilerplate', './', name);
|
||||
});
|
||||
};
|
||||
|
||||
Cmd.prototype.demo = function() {
|
||||
var self = this;
|
||||
program
|
||||
.command('demo')
|
||||
.description('create a working dapp with a SimpleStorage contract')
|
||||
.action(function() {
|
||||
self.Embark.generateTemplate('demo', './', 'embark_demo');
|
||||
Embark.generateTemplate('demo', './', 'embark_demo');
|
||||
});
|
||||
};
|
||||
|
||||
Cmd.prototype.build = function() {
|
||||
var self = this;
|
||||
program
|
||||
.command('build [environment]')
|
||||
.description('deploy and build dapp at dist/ (default: development)')
|
||||
.action(function(env, options) {
|
||||
self.Embark.build({env: env || 'development'});
|
||||
Embark.build({env: env || 'development'});
|
||||
});
|
||||
};
|
||||
|
||||
Cmd.prototype.run = function() {
|
||||
var self = this;
|
||||
program
|
||||
.command('run [environment]')
|
||||
.option('-p, --port [port]', 'port to run the dev webserver (default: 8000)')
|
||||
|
@ -97,7 +70,7 @@ Cmd.prototype.run = function() {
|
|||
.option('--no-color', 'no colors in case it\'s needed for compatbility purposes')
|
||||
.description('run dapp (default: development)')
|
||||
.action(function(env, options) {
|
||||
self.Embark.run({
|
||||
Embark.run({
|
||||
env: env || 'development',
|
||||
serverPort: options.port,
|
||||
serverHost: options.host,
|
||||
|
@ -108,22 +81,20 @@ Cmd.prototype.run = function() {
|
|||
};
|
||||
|
||||
Cmd.prototype.blockchain = function() {
|
||||
var self = this;
|
||||
program
|
||||
.command('blockchain [environment]')
|
||||
.option('-c, --client [client]', 'Use a specific ethereum client or simulator (supported: geth, parity, ethersim, testrpc')
|
||||
.description('run blockchain server (default: development)')
|
||||
.action(function(env ,options) {
|
||||
self.Embark.initConfig(env || 'development', {
|
||||
Embark.initConfig(env || 'development', {
|
||||
embarkConfig: 'embark.json',
|
||||
interceptLogs: false
|
||||
});
|
||||
self.Embark.blockchain(env || 'development', options.client || 'geth');
|
||||
Embark.blockchain(env || 'development', options.client || 'geth');
|
||||
});
|
||||
};
|
||||
|
||||
Cmd.prototype.simulator = function() {
|
||||
var self = this;
|
||||
program
|
||||
.command('simulator [environment]')
|
||||
.description('run a fast ethereum rpc simulator')
|
||||
|
@ -131,11 +102,11 @@ Cmd.prototype.simulator = function() {
|
|||
.option('-p, --port [port]', 'port to run the rpc simulator (default: 8000)')
|
||||
.option('-h, --host [host]', 'host to run the rpc simulator (default: localhost)')
|
||||
.action(function(env, options) {
|
||||
self.Embark.initConfig(env || 'development', {
|
||||
Embark.initConfig(env || 'development', {
|
||||
embarkConfig: 'embark.json',
|
||||
interceptLogs: false
|
||||
});
|
||||
self.Embark.simulator({port: options.port, host: options.host});
|
||||
Embark.simulator({port: options.port, host: options.host});
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -149,16 +120,15 @@ Cmd.prototype.test = function() {
|
|||
};
|
||||
|
||||
Cmd.prototype.upload = function() {
|
||||
var self = this;
|
||||
program
|
||||
.command('upload [platform] [environment]')
|
||||
.description('upload your dapp to a decentralized storage. possible options: ipfs, swarm (e.g embark upload swarm)')
|
||||
.action(function(platform, env, options) {
|
||||
// TODO: get env in cmd line as well
|
||||
self.Embark.initConfig(env || 'development', {
|
||||
Embark.initConfig(env || 'development', {
|
||||
embarkConfig: 'embark.json', interceptLogs: false
|
||||
});
|
||||
self.Embark.upload(platform);
|
||||
Embark.upload(platform);
|
||||
});
|
||||
};
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
var fs = require('../core/fs.js');
|
||||
var utils = require('../core/utils.js');
|
||||
var utils = require('../utils/utils.js');
|
||||
|
||||
var TemplateGenerator = function(templateName) {
|
||||
this.templateName = templateName;
|
||||
|
|
|
@ -1,18 +1,7 @@
|
|||
/*jshint esversion: 6, loopfunc: true */
|
||||
var async = require('async');
|
||||
var async = require('../utils/async_extend.js');
|
||||
var SolcW = require('./solcW.js');
|
||||
|
||||
function asyncEachObject(object, iterator, callback) {
|
||||
async.each(
|
||||
Object.keys(object || {}),
|
||||
function(key, next){
|
||||
iterator(key, object[key], next);
|
||||
},
|
||||
callback
|
||||
);
|
||||
}
|
||||
async.eachObject = asyncEachObject;
|
||||
|
||||
var Compiler = function(options) {
|
||||
this.plugins = options.plugins;
|
||||
this.logger = options.logger;
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
var async = require('async');
|
||||
var Web3 = require('web3');
|
||||
|
||||
var Deploy = require('./deploy.js');
|
||||
var ContractsManager = require('./contracts.js');
|
||||
|
@ -33,21 +32,25 @@ DeployManager.prototype.deployContracts = function(done) {
|
|||
});
|
||||
contractsManager.build(callback);
|
||||
},
|
||||
function connectWithWeb3(contractsManager, callback) {
|
||||
var web3;
|
||||
if (self.web3) {
|
||||
web3 = self.web3;
|
||||
} else {
|
||||
web3 = new Web3();
|
||||
var web3Endpoint = 'http://' + self.config.blockchainConfig.rpcHost + ':' + self.config.blockchainConfig.rpcPort;
|
||||
web3.setProvider(new web3.providers.HttpProvider(web3Endpoint));
|
||||
if (!web3.isConnected()) {
|
||||
self.logger.error(("Couldn't connect to " + web3Endpoint.underline + " are you sure it's on?").red);
|
||||
self.logger.info("make sure you have an ethereum node or simulator running. e.g 'embark blockchain'".magenta);
|
||||
return callback(Error("error connecting to blockchain node"));
|
||||
}
|
||||
function checkWeb3IsConnected(contractsManager, callback) {
|
||||
if (!self.web3) {
|
||||
return callback(Error("no web3 instance found"));
|
||||
}
|
||||
if (self.web3.currentProvider.isConnected !== undefined && !self.web3.isConnected()) {
|
||||
self.logger.error(("Couldn't connect to an Ethereum node are you sure it's on?").red);
|
||||
self.logger.info("make sure you have an Ethereum node or simulator running. e.g 'embark blockchain'".magenta);
|
||||
return callback(Error("error connecting to blockchain node"));
|
||||
}
|
||||
if (self.web3.currentProvider.isConnected === undefined) {
|
||||
self.web3.version.getNode(function(err, version) {
|
||||
if (err) {
|
||||
return callback(Error("error connecting to blockchain node"));
|
||||
}
|
||||
return callback(null, contractsManager, self.web3);
|
||||
});
|
||||
} else {
|
||||
return callback(null, contractsManager, self.web3);
|
||||
}
|
||||
callback(null, contractsManager, web3);
|
||||
},
|
||||
function setDefaultAccount(contractsManager, web3, callback) {
|
||||
web3.eth.getAccounts(function(err, accounts) {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
var utils = require('../core/utils.js');
|
||||
var utils = require('../utils/utils.js');
|
||||
var solcProcess;
|
||||
var compilerLoaded = false;
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
var fs = require('./fs.js');
|
||||
var Plugins = require('./plugins.js');
|
||||
var utils = require('./utils.js');
|
||||
var utils = require('../utils/utils.js');
|
||||
|
||||
// TODO: add wrapper for fs so it can also work in the browser
|
||||
// can work with both read and save
|
||||
|
|
|
@ -1,11 +1,14 @@
|
|||
var http = require('http');
|
||||
var Web3 = require('web3');
|
||||
var utils = require('../utils/utils.js');
|
||||
|
||||
var Events = require('./events.js');
|
||||
var Logger = require('./logger.js');
|
||||
var Config = require('./config.js');
|
||||
|
||||
var DeployManager = require('../contracts/deploy_manager.js');
|
||||
var ABIGenerator = require('../contracts/abi.js');
|
||||
var Dashboard = require('../dashboard/dashboard.js');
|
||||
var ServicesMonitor = require('./services.js');
|
||||
var ServicesMonitor = require('./services_monitor.js');
|
||||
var Pipeline = require('../pipeline/pipeline.js');
|
||||
var Server = require('../pipeline/server.js');
|
||||
var Watch = require('../pipeline/watch.js');
|
||||
|
@ -19,24 +22,44 @@ var Engine = function(options) {
|
|||
};
|
||||
|
||||
Engine.prototype.init = function(_options) {
|
||||
var self = this;
|
||||
var options = _options || {};
|
||||
this.events = new Events();
|
||||
this.logger = options.logger || new Logger({logLevel: 'debug'});
|
||||
this.config = new Config({env: this.env, logger: this.logger, events: this.events});
|
||||
this.config.loadConfigFiles({embarkConfig: this.embarkConfig, interceptLogs: this.interceptLogs});
|
||||
this.plugins = this.config.plugins;
|
||||
|
||||
this.servicesMonitor = new ServicesMonitor({events: this.events, logger: this.logger});
|
||||
this.servicesMonitor.addCheck('embarkVersion', function(cb) {
|
||||
return cb({name: 'Embark ' + self.version, status: 'green'});
|
||||
}, 0);
|
||||
};
|
||||
|
||||
Engine.prototype.startMonitor = function() {
|
||||
var self = this;
|
||||
if (this.plugins) {
|
||||
var servicePlugins = this.plugins.getPluginsFor('serviceChecks');
|
||||
servicePlugins.forEach(function(plugin) {
|
||||
plugin.serviceChecks.forEach(function(pluginCheck) {
|
||||
self.servicesMonitor.addCheck(pluginCheck.checkName, pluginCheck.checkFn, pluginCheck.time);
|
||||
});
|
||||
});
|
||||
}
|
||||
this.servicesMonitor.startMonitor();
|
||||
};
|
||||
|
||||
Engine.prototype.startService = function(serviceName, _options) {
|
||||
var options = _options || {};
|
||||
|
||||
var services = {
|
||||
"monitor": this.monitorService,
|
||||
"pipeline": this.pipelineService,
|
||||
"abi": this.abiService,
|
||||
"deployment": this.deploymentService,
|
||||
"fileWatcher": this.fileWatchService,
|
||||
"webServer": this.webServerService
|
||||
"webServer": this.webServerService,
|
||||
"ipfs": this.ipfsService,
|
||||
"web3": this.web3Service
|
||||
};
|
||||
|
||||
var service = services[serviceName];
|
||||
|
@ -50,18 +73,6 @@ Engine.prototype.startService = function(serviceName, _options) {
|
|||
return service.apply(this, [options]);
|
||||
};
|
||||
|
||||
Engine.prototype.monitorService = function(options) {
|
||||
var servicesMonitor = new ServicesMonitor({
|
||||
logger: this.logger,
|
||||
config: this.config,
|
||||
serverHost: options.serverHost,
|
||||
serverPort: options.serverPort,
|
||||
runWebserver: options.runWebserver,
|
||||
version: this.version
|
||||
});
|
||||
servicesMonitor.startMonitor();
|
||||
};
|
||||
|
||||
Engine.prototype.pipelineService = function(options) {
|
||||
var self = this;
|
||||
this.logger.setStatus("Building Assets");
|
||||
|
@ -77,13 +88,15 @@ Engine.prototype.pipelineService = function(options) {
|
|||
pipeline.build(abi);
|
||||
self.events.emit('outputDone');
|
||||
});
|
||||
this.events.on('file-event', function(fileType, path) {
|
||||
if (fileType === 'asset') {
|
||||
self.config.reloadConfig();
|
||||
pipeline.build(self.abi, path);
|
||||
self.events.emit('outputDone');
|
||||
}
|
||||
});
|
||||
// TODO: still need to redeploy contracts because the original contracts
|
||||
// config is being corrupted
|
||||
//this.events.on('file-event', function(fileType, path) {
|
||||
// if (fileType === 'asset') {
|
||||
// self.config.reloadConfig();
|
||||
// pipeline.build(self.abi, path);
|
||||
// self.events.emit('outputDone');
|
||||
// }
|
||||
//});
|
||||
};
|
||||
|
||||
Engine.prototype.abiService = function(options) {
|
||||
|
@ -111,7 +124,7 @@ Engine.prototype.abiService = function(options) {
|
|||
Engine.prototype.deploymentService = function(options) {
|
||||
var self = this;
|
||||
this.deployManager = new DeployManager({
|
||||
web3: options.web3,
|
||||
web3: options.web3 || self.web3,
|
||||
trackContracts: options.trackContracts,
|
||||
config: this.config,
|
||||
logger: this.logger,
|
||||
|
@ -120,10 +133,12 @@ Engine.prototype.deploymentService = function(options) {
|
|||
});
|
||||
|
||||
this.events.on('file-event', function(fileType, path) {
|
||||
if (fileType === 'contract' || fileType === 'config') {
|
||||
// TODO: for now need to deploy on asset chanes as well
|
||||
// because the contractsManager config is corrupted after a deploy
|
||||
//if (fileType === 'contract' || fileType === 'config') {
|
||||
self.config.reloadConfig();
|
||||
self.deployManager.deployContracts(function() {});
|
||||
}
|
||||
//}
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -134,15 +149,96 @@ Engine.prototype.fileWatchService = function(options) {
|
|||
};
|
||||
|
||||
Engine.prototype.webServerService = function(options) {
|
||||
var self = this;
|
||||
var webServerConfig = this.config.webServerConfig;
|
||||
if (!webServerConfig.enabled) { return; }
|
||||
|
||||
var host = options.host || webServerConfig.host;
|
||||
var port = options.port || webServerConfig.port;
|
||||
|
||||
this.logger.setStatus("Starting Server");
|
||||
var server = new Server({
|
||||
logger: this.logger,
|
||||
host: options.host || webServerConfig.host,
|
||||
port: options.port || webServerConfig.port
|
||||
host: host,
|
||||
port: port
|
||||
});
|
||||
|
||||
self.servicesMonitor.addCheck('Webserver', function(cb) {
|
||||
var devServer = 'Webserver (http://' + host + ':' + port + ')';
|
||||
return cb({name: devServer, status: 'green'});
|
||||
});
|
||||
|
||||
server.start(function(){
|
||||
});
|
||||
server.start(function(){});
|
||||
};
|
||||
|
||||
Engine.prototype.ipfsService = function(options) {
|
||||
var self = this;
|
||||
self.servicesMonitor.addCheck('IPFS', function(cb) {
|
||||
utils.checkIsAvailable('http://localhost:5001', function(available) {
|
||||
if (available) {
|
||||
//Ideally this method should be in an IPFS API JSONRPC wrapper
|
||||
//The URL should also be flexible to accept non-default IPFS url
|
||||
self.logger.trace("Checking IPFS version...");
|
||||
http.get('http://localhost:5001/api/v0/version', function(res) {
|
||||
var body = '';
|
||||
res.on('data', function(d) {
|
||||
body += d;
|
||||
});
|
||||
res.on('end', function() {
|
||||
try{
|
||||
var parsed = JSON.parse(body);
|
||||
if(parsed.Version){
|
||||
return cb({name: ("IPFS " + parsed.Version), status: 'green'});
|
||||
}
|
||||
else{
|
||||
return cb({name: "IPFS ", status: 'green'});
|
||||
}
|
||||
}
|
||||
catch (e){
|
||||
return cb({name: "IPFS ", status: 'red'});
|
||||
}
|
||||
});
|
||||
res.on('error', function(err) {
|
||||
self.logger.trace("Check IPFS version error: " + err);
|
||||
return cb({name: "IPFS ", status: 'red'});
|
||||
});
|
||||
});
|
||||
}
|
||||
else {
|
||||
return cb({name: "IPFS ", status: 'red'});
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
Engine.prototype.web3Service = function(options) {
|
||||
var self = this;
|
||||
this.web3 = options.web3;
|
||||
if (this.web3 === undefined) {
|
||||
this.web3 = new Web3();
|
||||
var web3Endpoint = 'http://' + this.config.blockchainConfig.rpcHost + ':' + this.config.blockchainConfig.rpcPort;
|
||||
this.web3.setProvider(new this.web3.providers.HttpProvider(web3Endpoint));
|
||||
}
|
||||
|
||||
self.servicesMonitor.addCheck('Ethereum', function(cb) {
|
||||
if (self.web3.isConnected()) {
|
||||
return cb({name: (self.web3.version.node.split("/")[0] + " " + self.web3.version.node.split("/")[1].split("-")[0] + " (Ethereum)"), status: 'green'});
|
||||
} else {
|
||||
return cb({name: "No Blockchain node found", status: 'red'});
|
||||
}
|
||||
});
|
||||
|
||||
self.servicesMonitor.addCheck('Whisper', function(cb) {
|
||||
self.web3.version.getWhisper(function(err, res) {
|
||||
if (err) {
|
||||
return cb({name: 'Whisper', status: 'red'});
|
||||
} else {
|
||||
return cb({name: 'Whisper', status: 'green'});
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
module.exports = Engine;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
var fs = require('fs-extra');
|
||||
var utils = require('./utils.js');
|
||||
var utils = require('../utils/utils.js');
|
||||
|
||||
function mkdirpSync() {
|
||||
return fs.mkdirpSync.apply(fs.mkdirpSync, arguments);
|
||||
|
|
|
@ -5,7 +5,6 @@ var Logger = function(options) {
|
|||
this.logLevel = options.logLevel || 'info';
|
||||
this.logFunction = options.logFunction || console.log;
|
||||
this.contractsState = options.contractsState || function() {};
|
||||
this.availableServices = options.availableServices || function() {};
|
||||
this.setStatus = options.setStatus || console.log;
|
||||
};
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*jshint esversion: 6, loopfunc: true */
|
||||
var fs = require('./fs.js');
|
||||
var utils = require('./utils.js');
|
||||
var utils = require('../utils/utils.js');
|
||||
|
||||
// TODO: pass other params like blockchainConfig, contract files, etc..
|
||||
var Plugin = function(options) {
|
||||
|
@ -17,6 +17,7 @@ var Plugin = function(options) {
|
|||
this.contractsConfigs = [];
|
||||
this.contractsFiles = [];
|
||||
this.compilers = [];
|
||||
this.serviceChecks = [];
|
||||
this.pluginTypes = [];
|
||||
this.logger = options.logger;
|
||||
this.events = options.events;
|
||||
|
@ -98,6 +99,11 @@ Plugin.prototype.registerConsoleCommand = function(cb) {
|
|||
this.pluginTypes.push('console');
|
||||
};
|
||||
|
||||
Plugin.prototype.registerServiceCheck = function(checkName, checkFn, time) {
|
||||
this.serviceChecks.push({checkName: checkName, checkFn: checkFn, time: time});
|
||||
this.pluginTypes.push('serviceChecks');
|
||||
};
|
||||
|
||||
Plugin.prototype.has = function(pluginType) {
|
||||
return this.pluginTypes.indexOf(pluginType) >= 0;
|
||||
};
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
var Plugin = require('./plugin.js');
|
||||
var utils = require('./utils.js');
|
||||
var utils = require('../utils/utils.js');
|
||||
|
||||
var Plugins = function(options) {
|
||||
this.pluginList = options.plugins || [];
|
||||
|
|
|
@ -1,113 +0,0 @@
|
|||
var Web3 = require('web3');
|
||||
var async = require('async');
|
||||
var http = require('http');
|
||||
var utils = require('./utils.js');
|
||||
|
||||
// TODO: needs a refactor and be done in a different way
|
||||
var ServicesMonitor = function(options) {
|
||||
this.logger = options.logger;
|
||||
this.interval = options.interval || 5000;
|
||||
this.config = options.config;
|
||||
this.serverHost = options.serverHost || 'localhost';
|
||||
this.serverPort = options.serverPort || 8000;
|
||||
this.runWebserver = options.runWebserver;
|
||||
this.version = options.version;
|
||||
};
|
||||
|
||||
ServicesMonitor.prototype.startMonitor = function() {
|
||||
this.check();
|
||||
this.monitor = setInterval(this.check.bind(this), this.interval);
|
||||
};
|
||||
|
||||
ServicesMonitor.prototype.stopMonitor = function() {
|
||||
};
|
||||
|
||||
ServicesMonitor.prototype.check = function() {
|
||||
var self = this;
|
||||
async.waterfall([
|
||||
function connectWeb3(callback) {
|
||||
self.logger.trace('connectWeb3');
|
||||
var web3 = new Web3();
|
||||
var web3Endpoint = 'http://' + self.config.blockchainConfig.rpcHost + ':' + self.config.blockchainConfig.rpcPort;
|
||||
web3.setProvider(new web3.providers.HttpProvider(web3Endpoint));
|
||||
callback(null, web3, []);
|
||||
},
|
||||
function addEmbarkVersion(web3, result, callback) {
|
||||
self.logger.trace('addEmbarkVersion');
|
||||
result.push(('Embark ' + self.version).green);
|
||||
callback(null, web3, result);
|
||||
},
|
||||
function checkEthereum(web3, result, callback) {
|
||||
self.logger.trace('checkEthereum');
|
||||
var service;
|
||||
if (web3.isConnected()) {
|
||||
service = (web3.version.node.split("/")[0] + " " + web3.version.node.split("/")[1].split("-")[0] + " (Ethereum)").green;
|
||||
} else {
|
||||
service = "No Blockchain node found".red;
|
||||
}
|
||||
result.push(service);
|
||||
callback(null, web3, result);
|
||||
},
|
||||
function checkWhisper(web3, result, callback) {
|
||||
self.logger.trace('checkWhisper');
|
||||
web3.version.getWhisper(function(err, res) {
|
||||
var service = 'Whisper';
|
||||
result.push(err ? service.red : service.green);
|
||||
callback(null, result);
|
||||
});
|
||||
},
|
||||
function checkIPFS(result, callback) {
|
||||
self.logger.trace('checkIPFS');
|
||||
|
||||
utils.checkIsAvailable('http://localhost:5001', function(available) {
|
||||
if (available) {
|
||||
//Ideally this method should be in an IPFS API JSONRPC wrapper
|
||||
//The URL should also be flexible to accept non-default IPFS url
|
||||
self.logger.trace("Checking IPFS version...");
|
||||
http.get('http://localhost:5001/api/v0/version', function(res) {
|
||||
var body = '';
|
||||
res.on('data', function(d) {
|
||||
body += d;
|
||||
});
|
||||
res.on('end', function() {
|
||||
var parsed = JSON.parse(body);
|
||||
if(parsed.Version){
|
||||
result.push(("IPFS " + parsed.Version).green);
|
||||
}
|
||||
else{
|
||||
result.push("IPFS".green);
|
||||
}
|
||||
callback(null, result);
|
||||
});
|
||||
res.on('error', function(err) {
|
||||
self.logger.trace("Check IPFS version error: " + err);
|
||||
result.push("IPFS".green);
|
||||
callback(null, result);
|
||||
});
|
||||
});
|
||||
}
|
||||
else {
|
||||
result.push('IPFS'.red);
|
||||
return callback(null, result);
|
||||
}
|
||||
});
|
||||
},
|
||||
function checkDevServer(result, callback) {
|
||||
var host = self.serverHost || self.config.webServerConfig.host;
|
||||
var port = self.serverPort || self.config.webServerConfig.port;
|
||||
self.logger.trace('checkDevServer');
|
||||
var devServer = 'Webserver (http://' + host + ':' + port + ')';
|
||||
devServer = (self.runWebserver) ? devServer.green : devServer.red;
|
||||
result.push(devServer);
|
||||
callback(null, result);
|
||||
}
|
||||
], function(err, result) {
|
||||
if (err) {
|
||||
self.logger.error(err.message);
|
||||
} else {
|
||||
self.logger.availableServices(result);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
module.exports = ServicesMonitor;
|
|
@ -0,0 +1,80 @@
|
|||
var async = require('../utils/async_extend.js');
|
||||
|
||||
// TODO: need to separate colors from states
|
||||
// i.e use status: /on|off|warn/ not /red|green/
|
||||
// it's up to the logger or console to determine the color
|
||||
var ServicesMonitor = function(options) {
|
||||
this.events = options.events;
|
||||
this.logger = options.logger;
|
||||
this.checkList = {};
|
||||
this.checkTimers = {};
|
||||
this.checkState = {};
|
||||
this.working = false;
|
||||
};
|
||||
|
||||
ServicesMonitor.prototype.initCheck = function(checkName) {
|
||||
var self = this;
|
||||
var check = this.checkList[checkName];
|
||||
|
||||
if (!check) { return false; }
|
||||
|
||||
self.events.on('check:' + checkName, function(obj) {
|
||||
// TODO: see todo above
|
||||
if (check && check.status === 'red' && obj.status === 'green') {
|
||||
self.events.emit('check:backOnline:' + checkName);
|
||||
}
|
||||
if (check && check.status === 'green' && obj.status === 'red') {
|
||||
self.events.emit('check:wentOffline:' + checkName);
|
||||
}
|
||||
self.checkState[checkName] = obj.name[obj.status];
|
||||
check.status = obj.status;
|
||||
self.events.emit("servicesState", self.checkState);
|
||||
});
|
||||
|
||||
if (check.interval !== 0) {
|
||||
self.checkTimers[checkName] = setInterval(function() {
|
||||
check.fn.call(check.fn, function(obj) {
|
||||
self.events.emit('check:' + checkName, obj);
|
||||
});
|
||||
}, check.interval);
|
||||
}
|
||||
|
||||
check.fn.call(check.fn, function(obj) {
|
||||
self.events.emit('check:' + checkName, obj);
|
||||
});
|
||||
};
|
||||
|
||||
ServicesMonitor.prototype.addCheck = function(checkName, checkFn, time) {
|
||||
var self = this;
|
||||
this.logger.trace('add check: ' + checkName);
|
||||
this.checkList[checkName] = {fn: checkFn, interval: time || 5000};
|
||||
|
||||
if (this.working) {
|
||||
this.initCheck(checkName);
|
||||
}
|
||||
};
|
||||
|
||||
ServicesMonitor.prototype.stopCheck = function(name) {
|
||||
clearInterval(this.checkTimers[name]);
|
||||
delete this.checkTimers[name];
|
||||
delete this.checkList[name];
|
||||
delete this.checkState[name];
|
||||
};
|
||||
|
||||
ServicesMonitor.prototype.startMonitor = function() {
|
||||
var self = this;
|
||||
this.working = true;
|
||||
this.logger.trace('startMonitor');
|
||||
|
||||
async.eachObject(this.checkList, function(checkName, check, callback) {
|
||||
self.initCheck(checkName);
|
||||
callback();
|
||||
}, function(err) {
|
||||
if (err) {
|
||||
self.logger.error("error running service check");
|
||||
self.logger.error(err.message);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
module.exports = ServicesMonitor;
|
109
lib/core/test.js
109
lib/core/test.js
|
@ -1,22 +1,6 @@
|
|||
var async = require('async');
|
||||
var Web3 = require('web3');
|
||||
|
||||
var Embark = require('../index.js');
|
||||
|
||||
var Engine = require('./engine.js');
|
||||
|
||||
var ABIGenerator = require('../contracts/abi.js');
|
||||
var ContractsManager = require('../contracts/contracts.js');
|
||||
var Deploy = require('../contracts/deploy.js');
|
||||
|
||||
var Config = require('./config.js');
|
||||
var RunCode = require('./runCode.js');
|
||||
var TestLogger = require('./test_logger.js');
|
||||
|
||||
var getSimulator = function() {
|
||||
try {
|
||||
var sim = require('ethereumjs-testrpc');
|
||||
return sim;
|
||||
return require('ethereumjs-testrpc');
|
||||
} catch (e) {
|
||||
if (e.code === 'MODULE_NOT_FOUND') {
|
||||
console.log('Simulator not found; Please install it with "npm install ethereumjs-testrpc --save"');
|
||||
|
@ -33,30 +17,44 @@ var getSimulator = function() {
|
|||
}
|
||||
};
|
||||
|
||||
var Test = function(options) {
|
||||
this.options = options || {};
|
||||
var simOptions = this.options.simulatorOptions || {};
|
||||
var Test;
|
||||
Test = (function (options) {
|
||||
var async = require('async');
|
||||
var opts = options === undefined ? {} : options;
|
||||
opts.logLevel = opts.hasOwnProperty('logLevel') ? opts.logLevel : 'debug';
|
||||
opts.simulatorOptions = opts.hasOwnProperty('simulatorOptions') ? opts.simulatorOptions : {};
|
||||
var sim = getSimulator();
|
||||
|
||||
this.engine = new Engine({
|
||||
env: this.options.env || 'test',
|
||||
// TODO: confi will need to detect if this is a obj
|
||||
embarkConfig: this.options.embarkConfig || 'embark.json',
|
||||
interceptLogs: false
|
||||
});
|
||||
function newWebThree() {
|
||||
try {
|
||||
var Web3 = require('web3');
|
||||
var web3 = new Web3();
|
||||
web3.setProvider(sim.provider(opts.simulatorOptions));
|
||||
return web3;
|
||||
} catch (e) {
|
||||
throw new Error(e);
|
||||
}
|
||||
}
|
||||
|
||||
this.engine.init({
|
||||
logger: new TestLogger({logLevel: this.options.logLevel || 'debug'})
|
||||
});
|
||||
function deployAll(contractsConfig, cb) {
|
||||
var RunCode = require('./runCode.js');
|
||||
var self = this;
|
||||
|
||||
this.sim = getSimulator();
|
||||
this.web3 = new Web3();
|
||||
this.web3.setProvider(this.sim.provider(simOptions));
|
||||
};
|
||||
function newEngine () {
|
||||
var Engine = require('./engine.js');
|
||||
return new Engine({
|
||||
env: opts.env || 'test',
|
||||
// TODO: confi will need to detect if this is a obj
|
||||
embarkConfig: opts.embarkConfig || 'embark.json',
|
||||
interceptLogs: false
|
||||
});
|
||||
}
|
||||
|
||||
Test.prototype.deployAll = function(contractsConfig, cb) {
|
||||
var self = this;
|
||||
self.web3 = newWebThree();
|
||||
self.engine = newEngine();
|
||||
self.engine.init();
|
||||
|
||||
async.waterfall([
|
||||
async.waterfall([
|
||||
function getConfig(callback) {
|
||||
self.engine.config.contractsConfig = {contracts: contractsConfig};
|
||||
callback();
|
||||
|
@ -71,32 +69,39 @@ Test.prototype.deployAll = function(contractsConfig, cb) {
|
|||
callback();
|
||||
},
|
||||
function deploy(callback) {
|
||||
self.engine.events.on('abi-contracts-vanila', function(vanillaABI) {
|
||||
self.engine.events.on('abi-contracts-vanila', function (vanillaABI) {
|
||||
callback(null, vanillaABI);
|
||||
});
|
||||
self.engine.deployManager.deployContracts(function(err, result) {
|
||||
self.engine.deployManager.deployContracts(function (err, result) {
|
||||
if (err) {
|
||||
console.log(err);
|
||||
callback(err);
|
||||
}
|
||||
});
|
||||
}
|
||||
], function(err, result) {
|
||||
if (err) {
|
||||
console.log("got error");
|
||||
process.exit();
|
||||
}
|
||||
// this should be part of the waterfall and not just something done at the
|
||||
// end
|
||||
self.web3.eth.getAccounts(function(err, accounts) {
|
||||
], function (err, result) {
|
||||
if (err) {
|
||||
throw new Error(err);
|
||||
console.log("got error");
|
||||
process.exit();
|
||||
}
|
||||
self.web3.eth.defaultAccount = accounts[0];
|
||||
RunCode.doEval(result, self.web3); // jshint ignore:line
|
||||
cb();
|
||||
// this should be part of the waterfall and not just something done at the
|
||||
// end
|
||||
self.web3.eth.getAccounts(function (err, accounts) {
|
||||
if (err) {
|
||||
throw new Error(err);
|
||||
}
|
||||
self.web3.eth.defaultAccount = accounts[0];
|
||||
RunCode.doEval(result, self.web3); // jshint ignore:line
|
||||
cb();
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
return {
|
||||
deployAll: deployAll,
|
||||
sim: sim
|
||||
};
|
||||
}());
|
||||
|
||||
module.exports = Test;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
var utils = require('../core/utils.js');
|
||||
var utils = require('../utils/utils.js');
|
||||
var RunCode = require('../core/runCode.js');
|
||||
|
||||
var Console = function(options) {
|
||||
|
|
|
@ -23,7 +23,6 @@ Dashboard.prototype.start = function(done) {
|
|||
monitor = new Monitor({env: self.env, console: console});
|
||||
self.logger.logFunction = monitor.logEntry;
|
||||
self.logger.contractsState = monitor.setContracts;
|
||||
self.logger.availableServices = monitor.availableServices;
|
||||
self.logger.setStatus = monitor.setStatus.bind(monitor);
|
||||
|
||||
self.logger.info('========================'.bold.green);
|
||||
|
|
|
@ -40,7 +40,13 @@ function Dashboard(options) {
|
|||
this.input.focus();
|
||||
}
|
||||
|
||||
Dashboard.prototype.availableServices = function(services) {
|
||||
Dashboard.prototype.availableServices = function(_services) {
|
||||
var services = [];
|
||||
var checkName;
|
||||
for (checkName in _services) {
|
||||
services.push(_services[checkName]);
|
||||
}
|
||||
|
||||
this.progress.setContent(services.join('\n'));
|
||||
this.screen.render();
|
||||
};
|
||||
|
|
104
lib/index.js
104
lib/index.js
|
@ -1,64 +1,49 @@
|
|||
/*jshint esversion: 6 */
|
||||
var async = require('async');
|
||||
//require("./core/debug_util.js")(__filename, async);
|
||||
// require("./utils/debug_util.js")(__filename, async);
|
||||
|
||||
var Web3 = require('web3');
|
||||
var colors = require('colors');
|
||||
|
||||
var Engine = require('./core/engine.js');
|
||||
|
||||
var Blockchain = require('./cmds/blockchain/blockchain.js');
|
||||
var Simulator = require('./cmds/simulator.js');
|
||||
var TemplateGenerator = require('./cmds/template_generator.js');
|
||||
|
||||
var Test = require('./core/test.js');
|
||||
var Logger = require('./core/logger.js');
|
||||
var Config = require('./core/config.js');
|
||||
var Events = require('./core/events.js');
|
||||
|
||||
var Dashboard = require('./dashboard/dashboard.js');
|
||||
|
||||
var IPFS = require('./upload/ipfs.js');
|
||||
var Swarm = require('./upload/swarm.js');
|
||||
|
||||
var Cmd = require('./cmd.js');
|
||||
var version = require('../package.json').version;
|
||||
|
||||
var Embark = {
|
||||
var Embark = (function () {
|
||||
function initConfig (env, options) {
|
||||
var Events = require('./core/events.js');
|
||||
var Logger = require('./core/logger.js');
|
||||
var Config = require('./core/config.js');
|
||||
|
||||
version: version,
|
||||
|
||||
process: function(args) {
|
||||
var cmd = new Cmd(Embark);
|
||||
cmd.process(args);
|
||||
},
|
||||
|
||||
initConfig: function(env, options) {
|
||||
this.events = new Events();
|
||||
this.logger = new Logger({logLevel: 'debug'});
|
||||
|
||||
this.config = new Config({env: env, logger: this.logger, events: this.events});
|
||||
this.config.loadConfigFiles(options);
|
||||
this.plugins = this.config.plugins;
|
||||
},
|
||||
}
|
||||
|
||||
blockchain: function(env, client) {
|
||||
var blockchain = Blockchain(this.config.blockchainConfig, client, env);
|
||||
blockchain.run();
|
||||
},
|
||||
function blockchain (env, client) {
|
||||
return require('./cmds/blockchain/blockchain.js')(this.config.blockchainConfig, client, env).run();
|
||||
}
|
||||
|
||||
simulator: function(options) {
|
||||
function simulator (options) {
|
||||
var Simulator = require('./cmds/simulator.js');
|
||||
var simulator = new Simulator({blockchainConfig: this.config.blockchainConfig});
|
||||
simulator.run(options);
|
||||
},
|
||||
}
|
||||
|
||||
generateTemplate: function(templateName, destinationFolder, name) {
|
||||
function generateTemplate (templateName, destinationFolder, name) {
|
||||
var TemplateGenerator = require('./cmds/template_generator.js');
|
||||
var templateGenerator = new TemplateGenerator(templateName);
|
||||
templateGenerator.generate(destinationFolder, name);
|
||||
},
|
||||
}
|
||||
|
||||
function run (options) {
|
||||
var Dashboard = require('./dashboard/dashboard.js');
|
||||
|
||||
run: function(options) {
|
||||
var self = this;
|
||||
var env = options.env;
|
||||
|
||||
var engine = new Engine({
|
||||
|
@ -90,6 +75,11 @@ var Embark = {
|
|||
dashboard.console.runCode(abi);
|
||||
});
|
||||
|
||||
engine.logger.info('dashboard start');
|
||||
engine.events.on('servicesState', function(servicesState) {
|
||||
dashboard.monitor.availableServices(servicesState);
|
||||
});
|
||||
|
||||
callback();
|
||||
});
|
||||
},
|
||||
|
@ -99,16 +89,20 @@ var Embark = {
|
|||
engine.logger.info("loaded plugins: " + pluginList.join(", "));
|
||||
}
|
||||
|
||||
if (options.useDashboard) {
|
||||
engine.startService("monitor", {
|
||||
serverHost: options.serverHost,
|
||||
serverPort: options.serverPort,
|
||||
runWebserver: options.runWebserver
|
||||
});
|
||||
}
|
||||
engine.startMonitor();
|
||||
engine.startService("web3");
|
||||
engine.startService("pipeline");
|
||||
engine.startService("abi");
|
||||
engine.startService("deployment");
|
||||
engine.startService("ipfs");
|
||||
|
||||
engine.events.on('check:backOnline:Ethereum', function() {
|
||||
engine.logger.info('Ethereum node detected..');
|
||||
engine.config.reloadConfig();
|
||||
engine.deployManager.deployContracts(function() {
|
||||
engine.logger.info('Deployment Done');
|
||||
});
|
||||
});
|
||||
|
||||
engine.deployManager.deployContracts(function() {
|
||||
engine.startService("fileWatcher");
|
||||
|
@ -131,10 +125,9 @@ var Embark = {
|
|||
engine.events.emit('firstDeploymentDone');
|
||||
}
|
||||
});
|
||||
},
|
||||
}
|
||||
|
||||
build: function(options) {
|
||||
var self = this;
|
||||
function build (options) {
|
||||
|
||||
var engine = new Engine({
|
||||
env: options.env,
|
||||
|
@ -169,14 +162,15 @@ var Embark = {
|
|||
// needed due to child processes
|
||||
process.exit();
|
||||
});
|
||||
},
|
||||
}
|
||||
|
||||
initTests: function(options) {
|
||||
function initTests (options) {
|
||||
var Test = require('./core/test.js');
|
||||
return new Test(options);
|
||||
},
|
||||
}
|
||||
|
||||
// TODO: should deploy if it hasn't already
|
||||
upload: function(platform) {
|
||||
function upload (platform) {
|
||||
if (platform === 'ipfs') {
|
||||
var ipfs = new IPFS({buildDir: 'dist/', plugins: this.plugins, storageConfig: this.config.storageConfig});
|
||||
ipfs.deploy();
|
||||
|
@ -189,7 +183,19 @@ var Embark = {
|
|||
}
|
||||
}
|
||||
|
||||
};
|
||||
return {
|
||||
version: version,
|
||||
initConfig: initConfig,
|
||||
blockchain: blockchain,
|
||||
simulator: simulator,
|
||||
generateTemplate: generateTemplate,
|
||||
run: run,
|
||||
build: build,
|
||||
initTests: initTests,
|
||||
upload: upload
|
||||
};
|
||||
|
||||
})();
|
||||
|
||||
module.exports = Embark;
|
||||
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
var async = require('async');
|
||||
|
||||
function asyncEachObject(object, iterator, callback) {
|
||||
async.each(
|
||||
Object.keys(object || {}),
|
||||
function(key, next){
|
||||
iterator(key, object[key], next);
|
||||
},
|
||||
callback
|
||||
);
|
||||
}
|
||||
async.eachObject = asyncEachObject;
|
||||
|
||||
module.exports = async;
|
57
test/cmd.js
57
test/cmd.js
|
@ -1,42 +1,41 @@
|
|||
var Embark = require('../lib/index');
|
||||
var Cmd = require('../lib/cmd');
|
||||
|
||||
var passingLines = function () {
|
||||
var lines = [];
|
||||
lines.push('Initializing Embark Template....');
|
||||
lines.push('Installing packages.. this can take a few seconds');
|
||||
lines.push('Init complete');
|
||||
return lines;
|
||||
};
|
||||
|
||||
describe('embark.Cmd', function () {
|
||||
this.timeout(0);
|
||||
var cmd = new Cmd(Embark);
|
||||
var pl = passingLines();
|
||||
var appname = 'deleteapp';
|
||||
|
||||
describe('#new', function () {
|
||||
this.timeout(0);
|
||||
it('it should create an app with a `name` argument set', function (done) {
|
||||
cmd.newApp(appname, function (output) {
|
||||
var lines = output.split('\n');
|
||||
console.log(lines);
|
||||
assert.equal(lines[0], pl[0]);
|
||||
assert.equal(lines[1], pl[1]);
|
||||
assert.equal(lines[2], pl[2]);
|
||||
assert.equal(lines[3], 'App ready at ./' + appname);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('it should prompt when given an empty app name', function (done) {
|
||||
it('it should not create an app without a name', function (done) {
|
||||
cmd.newApp(undefined, function (output) {
|
||||
var lines = output.split('\n');
|
||||
console.log(lines);
|
||||
process.stdin.write(appname + '\n');
|
||||
assert.equal(lines[0], pl[0]);
|
||||
done();
|
||||
assert.equal(lines[0], 'please specify your app Name');
|
||||
assert.equal(lines[1], 'e.g embark new MyApp');
|
||||
assert.equal(lines[2], 'e.g embark new --help for more information');
|
||||
});
|
||||
done();
|
||||
});
|
||||
|
||||
it('it should create an app with a name', function (done) {
|
||||
var appname = 'deleteapp';
|
||||
cmd.newApp(appname, function (output) {
|
||||
var lines = output.split('\n');
|
||||
assert.equal(lines[0], 'Initializing Embark Template....');
|
||||
assert.equal(lines[1], 'Installing packages.. this can take a few seconds');
|
||||
assert.equal(lines[2], 'Init complete');
|
||||
assert.equal(lines[3], 'App ready at ./' + appname);
|
||||
});
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
// describe("#help", function () {
|
||||
// it('it should spit out helpful text if no arguments are supplied', function (done) {
|
||||
// cmd.process([], function (output) {
|
||||
// var lines = output.split('\n');
|
||||
// assert.equal(lines[0], '\n');
|
||||
// assert.equal(lines[1], 'Usage:');
|
||||
// done();
|
||||
// });
|
||||
// })
|
||||
// })
|
||||
});
|
|
@ -14,6 +14,7 @@
|
|||
"buildDir": "dist/",
|
||||
"config": "config/",
|
||||
"plugins": {
|
||||
"embark-babel": {"files": ["**/*.js", "**/*.jsx", "!**/_vendor/*.js"]}
|
||||
"embark-babel": {"files": ["**/*.js", "**/*.jsx", "!**/_vendor/*.js"]},
|
||||
"embark-service": {}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
module.exports = function(embark) {
|
||||
embark.registerServiceCheck('PluginService', function(cb) {
|
||||
cb({name: "ServiceName", status: "green"});
|
||||
});
|
||||
};
|
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"name": "embark-service",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"author": "",
|
||||
"license": "ISC"
|
||||
}
|
|
@ -10,11 +10,12 @@
|
|||
"license": "ISC",
|
||||
"homepage": "",
|
||||
"devDependencies": {
|
||||
"embark": "../",
|
||||
"embark": "file:../",
|
||||
"mocha": "^2.2.5"
|
||||
},
|
||||
"dependencies": {
|
||||
"embark-babel": "^1.0.0",
|
||||
"embark-service": "./extensions/embark-service",
|
||||
"ethereumjs-testrpc": "^3.0.3"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
var assert = require('assert');
|
||||
var Embark = require('embark');
|
||||
var EmbarkSpec = Embark.initTests();
|
||||
var web3 = EmbarkSpec.web3;
|
||||
var EmbarkSpec = require('embark/lib/core/test.js');
|
||||
|
||||
describe("AnotherStorage", function() {
|
||||
before(function(done) {
|
||||
this.timeout(0);
|
||||
var contractsConfig = {
|
||||
"SimpleStorage": {
|
||||
args: [100]
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
var assert = require('assert');
|
||||
var Embark = require('embark');
|
||||
var EmbarkSpec = Embark.initTests();
|
||||
var web3 = EmbarkSpec.web3;
|
||||
var EmbarkSpec = require('embark/lib/core/test.js');
|
||||
|
||||
describe("SimpleStorage", function() {
|
||||
before(function(done) {
|
||||
this.timeout(0);
|
||||
var contractsConfig = {
|
||||
"SimpleStorage": {
|
||||
args: [100]
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
var assert = require('assert');
|
||||
var Embark = require('embark');
|
||||
var EmbarkSpec = Embark.initTests();
|
||||
var web3 = EmbarkSpec.web3;
|
||||
var EmbarkSpec = require('embark/lib/core/test.js');
|
||||
|
||||
describe("Token", function() {
|
||||
before(function(done) {
|
||||
this.timeout(0);
|
||||
var contractsConfig = {
|
||||
"SimpleStorage": {
|
||||
args: [100]
|
||||
|
|
Loading…
Reference in New Issue