Merge branch 'develop'

This commit is contained in:
Iuri Matias 2017-06-28 06:56:51 -04:00
commit 10106067a7
81 changed files with 6676 additions and 5740 deletions

1
.gitignore vendored
View File

@ -12,3 +12,4 @@ test_app/.embark/development/
test_app/config/production/password test_app/config/production/password
test_app/node_modules/ test_app/node_modules/
test_app/chains.json test_app/chains.json
.idea

View File

@ -1,8 +1,7 @@
language: node_js language: node_js
node_js: node_js:
- "7"
- "6" - "6"
- "5"
- "4"
addons: addons:
code_climate: code_climate:
repo_token: 7454b1a666015e244c384d19f48c34e35d1ae58c3aa428ec542f10bbcb848358 repo_token: 7454b1a666015e244c384d19f48c34e35d1ae58c3aa428ec542f10bbcb848358

92
CONTRIBUTING.md Normal file
View File

@ -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/

29
Class Hierarchy.mmd Normal file
View File

@ -0,0 +1,29 @@
Mind Map generated by NB MindMap plugin
> __version__=`1.1`,showJumps=`true`
---
# Embark
## Config
## CLI
## Engine
> leftSide=`true`
### Plugins
#### DefaultLogger
#### DefaultPipeline
### Services
## DefaultLogger
## Utils
> leftSide=`true`
## DeployManager

View File

@ -21,8 +21,16 @@ module.exports = (grunt) ->
mochaTest: mochaTest:
test: test:
src: ['test/**/*.js'] src: ['test/**/*.js']
jshint: jshint:
all: ['bin/embark', 'lib/**/*.js', 'js/mine.js', 'js/embark.js'] all: ['bin/embark', 'lib/**/*.js']
options: grunt.file.readJSON('package.json').jshintConfig
with_overrides:
options:
undef: false
esversion: 5
files:
src: ['js/mine.js', 'js/embark.js']
grunt.loadTasks "tasks" grunt.loadTasks "tasks"
require('matchdep').filterAll(['grunt-*','!grunt-cli']).forEach(grunt.loadNpmTasks) require('matchdep').filterAll(['grunt-*','!grunt-cli']).forEach(grunt.loadNpmTasks)

View File

@ -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 [![Build
Status](https://travis-ci.org/iurimatias/embark-framework.svg?branch=develop)](https://travis-ci.org/iurimatias/embark-framework) 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) [![Code Climate](https://codeclimate.com/github/iurimatias/embark-framework/badges/gpa.svg)](https://codeclimate.com/github/iurimatias/embark-framework)
@ -8,9 +9,9 @@ What is Embark
Embark is a framework that allows you to easily develop and deploy Decentralized Applications (DApps). Embark is a framework that allows you to easily develop and deploy Decentralized Applications (DApps).
A Decentralized Application is serverless html5 application that uses one or more decentralized technologies. A Decentralized Application is a serverless html5 application that uses one or more decentralized technologies.
Embark currently integrates with EVM blockchains (Ethereum), Decentralized Storages (IPFS), and Decentralizaed communication platforms (Whisper and Orbit). Swarm is supported for deployment. Embark currently integrates with EVM blockchains (Ethereum), Decentralized Storages (IPFS), and Decentralized communication platforms (Whisper and Orbit). Swarm is supported for deployment.
With Embark you can: With Embark you can:
@ -18,12 +19,12 @@ With Embark you can:
* Automatically deploy contracts and make them available in your JS code. Embark watches for changes, and if you update a contract, Embark will automatically redeploy the contracts (if needed) and the dapp. * Automatically deploy contracts and make them available in your JS code. Embark watches for changes, and if you update a contract, Embark will automatically redeploy the contracts (if needed) and the dapp.
* Contracts are available in JS with Promises. * Contracts are available in JS with Promises.
* Do Test Driven Development with Contracts using Javascript. * Do Test Driven Development with Contracts using Javascript.
* Keep track of deployed contracts, deploy only when truly needed. * Keep track of deployed contracts; deploy only when truly needed.
* Manage different chains (e.g testnet, private net, livenet) * Manage different chains (e.g testnet, private net, livenet)
* Easily manage complex systems of interdependent contracts. * Easily manage complex systems of interdependent contracts.
**Decentralized Storage (IPFS)** **Decentralized Storage (IPFS)**
* Easily Store & Retrieve Data on the DApp through EmbarkJS. Includin uploading and retrieving files. * Easily Store & Retrieve Data on the DApp through EmbarkJS. Including uploading and retrieving files.
* Deploy the full application to IPFS or Swarm. * Deploy the full application to IPFS or Swarm.
@ -41,20 +42,20 @@ Table of Contents
* [Dashboard](#dashboard) * [Dashboard](#dashboard)
* [Creating a new DApp](#creating-a-new-dapp) * [Creating a new DApp](#creating-a-new-dapp)
* [Libraries and APIs available](#libraries-and-languages-available) * [Libraries and APIs available](#libraries-and-languages-available)
* [Using and Configuring Contracts](#dapp-structure) * [Using and Configuring Contracts](#using-contracts)
* [EmbarkJS](#embarkjs) * [EmbarkJS](#embarkjs)
* [EmbarkJS - Storage (IPFS)](#embarkjs---storage) * [EmbarkJS - Storage (IPFS)](#embarkjs---storage)
* [EmbarkJS - Communication (Whisper/Orbit)](#embarkjs---communication) * [EmbarkJS - Communication (Whisper/Orbit)](#embarkjs---communication)
* [Testing Contracts](#tests) * [Testing Contracts](#tests)
* [Working with different chains](#working-with-different-chains) * [Working with different chains](#working-with-different-chains)
* [Custom Application Structure](#structuring-application) * [Custom Application Structure](#structuring-application)
* [Deploying to IPFS](#deploying-to-ipfs) * [Deploying to IPFS](#deploying-to-ipfs-and-swarm)
* [Extending Functionality with Plugins](#plugins) * [Extending Functionality with Plugins](#plugins)
* [Donations](#donations) * [Donations](#donations)
Installation Installation
====== ======
Requirements: geth (1.5.8 or higher), node (6.9.1 or higher is recommended) and npm Requirements: geth (1.6.5 or higher), node (6.9.1 or higher is recommended) and npm
Optional: testrpc (3.0 or higher) if using the simulator or the test functionality. Optional: testrpc (3.0 or higher) if using the simulator or the test functionality.
Further: depending on the dapp stack you choose: [IPFS](https://ipfs.io/) Further: depending on the dapp stack you choose: [IPFS](https://ipfs.io/)
@ -68,7 +69,7 @@ $ npm -g install ethereumjs-testrpc
See [Complete Installation Instructions](https://github.com/iurimatias/embark-framework/wiki/Installation). See [Complete Installation Instructions](https://github.com/iurimatias/embark-framework/wiki/Installation).
**updating from embark 1** **updating from Embark 1**
Embark's npm package has changed from ```embark-framework``` to ```embark```, this sometimes can create conflicts. To update first uninstall embark-framework 1 to avoid any conflicts. ```npm uninstall -g embark-framework``` then ```npm install -g embark``` Embark's npm package has changed from ```embark-framework``` to ```embark```, this sometimes can create conflicts. To update first uninstall embark-framework 1 to avoid any conflicts. ```npm uninstall -g embark-framework``` then ```npm install -g embark```
@ -96,7 +97,7 @@ Alternatively, to use an ethereum rpc simulator simply run:
$ embark simulator $ embark simulator
``` ```
By default embark blockchain will mine a minimum amount of ether and will only mine when new transactions come in. This is quite usefull to keep a low CPU. The option can be configured at ```config/blockchain.json```. Note that running a real node requires at least 2GB of free ram, please take this into account if running it in a VM. By default Embark blockchain will mine a minimum amount of ether and will only mine when new transactions come in. This is quite useful to keep a low CPU. The option can be configured at ```config/blockchain.json```. Note that running a real node requires at least 2GB of free ram, please take this into account if running it in a VM.
Then, in another command line: Then, in another command line:
@ -105,7 +106,7 @@ $ embark run
``` ```
This will automatically deploy the contracts, update their JS bindings and deploy your DApp to a local server at http://localhost:8000 This will automatically deploy the contracts, update their JS bindings and deploy your DApp to a local server at http://localhost:8000
Note that if you update your code it will automatically be re-deployed, contracts included. There is no need to restart embark, refreshing the page on the browser will do. Note that if you update your code, it will automatically be re-deployed, contracts included. There is no need to restart embark, refreshing the page on the browser will do.
Dashboard Dashboard
===== =====
@ -114,20 +115,20 @@ Embark 2 comes with a terminal dashboard.
![Dashboard](http://i.imgur.com/s4OQZpu.jpg) ![Dashboard](http://i.imgur.com/s4OQZpu.jpg)
The dashboard will tell you the state of your contracts, the enviroment you are using, and what embark is doing at the moment. The dashboard will tell you the state of your contracts, the environment you are using, and what Embark is doing at the moment.
**available services** **available services**
Available Services will display the services available to your dapp in green, if one of these is down then it will be displayed in red. Available Services will display the services available to your dapp in green. If a service is down, then it will be displayed in red.
**logs and console** **logs and console**
There is a console at the bottom which can be used to interact with contracts or with embark itself. type ```help``` to see a list of available commands, more commands will be added with each version of Embark. There is a console at the bottom which can be used to interact with contracts or with Embark itself. Type ```help``` to see a list of available commands. More commands will be added with each version of Embark.
Creating a new DApp Creating a new DApp
====== ======
If you want to create a blank new app. If you want to create a blank new app:
```Bash ```Bash
$ embark new AppName $ embark new AppName
@ -144,13 +145,16 @@ DApp Structure
|___ css/ |___ css/
|___ js/ |___ js/
config/ config/
|___ blockchain.json #environments configuration |___ blockchain.json #rpc and blockchain configuration
|___ contracts.json #contracts configuration |___ contracts.json #ethereum contracts configuration
|___ storage.json #ipfs configuration
|___ communication.json #whisper/orbit configuration
|___ webserver.json #dev webserver configuration
test/ test/
|___ #contracts tests |___ #contracts tests
``` ```
Solidity/Serpent files in the contracts directory will automatically be deployed with embark run. Changes in any files will automatically be reflected in app, changes to contracts will result in a redeployment and update of their JS Bindings Solidity/Serpent files in the contracts directory will automatically be deployed with Embark run. Changes in any files will automatically be reflected in app, changes to contracts will result in a redeployment and update of their JS Bindings
Libraries and languages available Libraries and languages available
====== ======
@ -223,7 +227,7 @@ If you are using multiple contracts, you can pass a reference to another contrac
"SimpleStorage": { "SimpleStorage": {
"args": [ "args": [
100, 100,
$MyStorage "$MyStorage"
] ]
}, },
"MyStorage": { "MyStorage": {
@ -233,7 +237,7 @@ If you are using multiple contracts, you can pass a reference to another contrac
}, },
"MyMainContract": { "MyMainContract": {
"args": [ "args": [
$SimpleStorage "$SimpleStorage"
] ]
} }
} }
@ -274,7 +278,7 @@ You can now deploy many instances of the same contract. e.g
... ...
``` ```
Contracts addresses can be defined, If an address is defined the contract wouldn't be deployed but its defined address will be used instead. Contracts addresses can be defined. If an address is defined, Embark uses the defined address instead of deploying the contract.
```Json ```Json
@ -322,14 +326,20 @@ events:
Client side deployment will be automatically available in Embark for existing contracts: Client side deployment will be automatically available in Embark for existing contracts:
```Javascript ```Javascript
SimpleStorage.deploy().then(function(anotherSimpleStorage) {}); SimpleStorage.deploy([args], {options}).then(function(anotherSimpleStorage) {});
``` ```
or it can be manually definied as or it can be manually definied as
```Javascript ```Javascript
var myContract = new EmbarkJS.Contract({abi: abiObject, code: code}); 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 EmbarkJS - Storage
@ -337,7 +347,7 @@ EmbarkJS - Storage
**initialization** **initialization**
The current available storage is IPFS. it can be initialized as The current available storage is IPFS. It can be initialized as
```Javascript ```Javascript
EmbarkJS.Storage.setProvider('ipfs',{server: 'localhost', port: '5001'}) EmbarkJS.Storage.setProvider('ipfs',{server: 'localhost', port: '5001'})
@ -422,7 +432,7 @@ Tests
You can run specs with ```embark test```, it will run any test files under ```test/```. You can run specs with ```embark test```, it will run any test files under ```test/```.
Embark includes a testing lib to fastly run & test your contracts in a EVM. Embark includes a testing lib to rapidly run & test your contracts in a EVM.
```Javascript ```Javascript
# test/simple_storage_spec.js # test/simple_storage_spec.js
@ -434,6 +444,7 @@ var web3 = EmbarkSpec.web3;
describe("SimpleStorage", function() { describe("SimpleStorage", function() {
before(function(done) { before(function(done) {
this.timeout(0);
var contractsConfig = { var contractsConfig = {
"SimpleStorage": { "SimpleStorage": {
args: [100] args: [100]
@ -459,6 +470,7 @@ describe("SimpleStorage", function() {
}); });
}); });
``` ```
Embark uses [Mocha](http://mochajs.org/) by default, but you can use any testing framework you want. Embark uses [Mocha](http://mochajs.org/) by default, but you can use any testing framework you want.
@ -521,20 +533,20 @@ To deploy a dapp to SWARM, all you need to do is run a local SWARM node and then
Plugins Plugins
====== ======
It's possible to extend Embarks functionality with plugins. For example the following is possible: It's possible to extend Embark's functionality with plugins. For example, the following is possible:
* plugin to add support for es6, jsx, coffescript, etc (``embark.registerPipeline``) * plugin to add support for es6, jsx, coffescript, etc (``embark.registerPipeline``)
* plugin to add standard contracts or a contract framework (``embark.registerContractConfiguration`` and ``embark.addContractFile``) * plugin to add standard contracts or a contract framework (``embark.registerContractConfiguration`` and ``embark.addContractFile``)
* plugin to make some contracts available in all environments for use by other contracts or the dapp itself e.g a Token, a DAO, ENS, etc.. (``embark.registerContractConfiguration`` and ``embark.addContractFile``) * plugin to make some contracts available in all environments for use by other contracts or the dapp itself e.g a Token, a DAO, ENS, etc.. (``embark.registerContractConfiguration`` and ``embark.addContractFile``)
* plugin to add a libraries such as react or boostrap (``embark.addFileToPipeline``) * plugin to add a libraries such as react or bootstrap (``embark.addFileToPipeline``)
* plugin to specify a particular web3 initialization for special provider uses (``embark.registerClientWeb3Provider``) * plugin to specify a particular web3 initialization for special provider uses (``embark.registerClientWeb3Provider``)
* plugin to create a different contract wrapper (``embark.registerContractsGeneration``) * plugin to create a different contract wrapper (``embark.registerContractsGeneration``)
* plugin to add new console commands (``embark.registerConsoleCommand``) * plugin to add new console commands (``embark.registerConsoleCommand``)
* plugin to add support for another contract language such as viper, LLL, etc (``embark.registerCompiler``) * plugin to add support for another contract language such as viper, LLL, etc (``embark.registerCompiler``)
For more information on how to develop your own plugin please see the [plugin documentation](http://embark.readthedocs.io/en/latest/plugins.html) For more information on how to develop your own plugin, please see the [plugin documentation](http://embark.readthedocs.io/en/latest/plugins.html)
Donations Donations
====== ======
If you like Embark please consider donating to 0x8811FdF0F988f0CD1B7E9DE252ABfA5b18c1cDb1 If you like Embark, please consider donating to 0x8811FdF0F988f0CD1B7E9DE252ABfA5b18c1cDb1

View File

@ -1,4 +1,4 @@
#!/usr/bin/env node #!/usr/bin/env node
var Cmd = require('../lib/cmd');
var Embark = require('..'); var cli = new Cmd();
Embark.process(process.argv); cli.process(process.argv);

View File

@ -6,6 +6,6 @@
</head> </head>
<body> <body>
<h3>Welcome to Embark!</h3> <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> </body>
</html> </html>

View File

@ -1,4 +1,5 @@
{ {
"config": {},
"nonce": "0x0000000000000042", "nonce": "0x0000000000000042",
"difficulty": "0x0", "difficulty": "0x0",
"alloc": { "alloc": {

View File

@ -9,7 +9,7 @@
"license": "ISC", "license": "ISC",
"homepage": "", "homepage": "",
"devDependencies": { "devDependencies": {
"embark": "^2.4.2", "embark": "^2.5.0",
"mocha": "^2.2.5" "mocha": "^2.2.5"
} }
} }

View File

@ -3,8 +3,9 @@ var Embark = require('embark');
var EmbarkSpec = Embark.initTests(); var EmbarkSpec = Embark.initTests();
var web3 = EmbarkSpec.web3; var web3 = EmbarkSpec.web3;
//describe("SimpleStorage", function() { // describe("SimpleStorage", function() {
// before(function(done) { // before(function(done) {
// this.timeout(0);
// var contractsConfig = { // var contractsConfig = {
// "SimpleStorage": { // "SimpleStorage": {
// args: [100, '0x123'] // args: [100, '0x123']
@ -29,4 +30,4 @@ var web3 = EmbarkSpec.web3;
// }); // });
// }); // });
// //
//}); // });

View File

@ -77,6 +77,7 @@
</div> </div>
<div role="tabpanel" class="tab-pane" id="communication"> <div role="tabpanel" class="tab-pane" id="communication">
<div class="error alert alert-danger" role="alert">The node you are using does not support Whisper</div> <div class="error alert alert-danger" role="alert">The node you are using does not support Whisper</div>
<div class="errorVersion alert alert-danger" role="alert">The node uses an unsupported version of Whisper</div>
<div id="communication-controls"> <div id="communication-controls">
<h3>Listen To channel</h3> <h3>Listen To channel</h3>
<div class="form-group form-inline listen"> <div class="form-group form-inline listen">

View File

@ -32,6 +32,9 @@ $(document).ready(function() {
//EmbarkJS.Storage.setProvider('ipfs',{server: 'localhost', port: '5001'}); //EmbarkJS.Storage.setProvider('ipfs',{server: 'localhost', port: '5001'});
$("#storage .error").hide(); $("#storage .error").hide();
EmbarkJS.Storage.setProvider('ipfs')
.then(function(){
console.log('Provider set to IPFS');
EmbarkJS.Storage.ipfsConnection.ping() EmbarkJS.Storage.ipfsConnection.ping()
.then(function(){ .then(function(){
$("#status-storage").addClass('status-online'); $("#status-storage").addClass('status-online');
@ -45,22 +48,39 @@ $(document).ready(function() {
$("#storage-controls").hide(); $("#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() { $("#storage button.setIpfsText").click(function() {
var value = $("#storage input.ipfsText").val(); var value = $("#storage input.ipfsText").val();
EmbarkJS.Storage.saveText(value).then(function(hash) { EmbarkJS.Storage.saveText(value).then(function(hash) {
$("span.textHash").html(hash); $("span.textHash").html(hash);
$("input.textHash").val(hash); $("input.textHash").val(hash);
});
addToLog("#storage", "EmbarkJS.Storage.saveText('" + value + "').then(function(hash) { })"); addToLog("#storage", "EmbarkJS.Storage.saveText('" + value + "').then(function(hash) { })");
})
.catch(function(err) {
if(err){
console.log("IPFS saveText Error => " + err.message);
}
});
}); });
$("#storage button.loadIpfsHash").click(function() { $("#storage button.loadIpfsHash").click(function() {
var value = $("#storage input.textHash").val(); var value = $("#storage input.textHash").val();
EmbarkJS.Storage.get(value).then(function(content) { EmbarkJS.Storage.get(value).then(function(content) {
$("span.ipfsText").html(content); $("span.ipfsText").html(content);
});
addToLog("#storage", "EmbarkJS.Storage.get('" + value + "').then(function(content) { })"); addToLog("#storage", "EmbarkJS.Storage.get('" + value + "').then(function(content) { })");
})
.catch(function(err) {
if(err){
console.log("IPFS get Error => " + err.message);
}
});
}); });
$("#storage button.uploadFile").click(function() { $("#storage button.uploadFile").click(function() {
@ -68,8 +88,13 @@ $(document).ready(function() {
EmbarkJS.Storage.uploadFile(input).then(function(hash) { EmbarkJS.Storage.uploadFile(input).then(function(hash) {
$("span.fileIpfsHash").html(hash); $("span.fileIpfsHash").html(hash);
$("input.fileIpfsHash").val(hash); $("input.fileIpfsHash").val(hash);
});
addToLog("#storage", "EmbarkJS.Storage.uploadFile($('input[type=file]')).then(function(hash) { })"); addToLog("#storage", "EmbarkJS.Storage.uploadFile($('input[type=file]')).then(function(hash) { })");
})
.catch(function(err) {
if(err){
console.log("IPFS uploadFile Error => " + err.message);
}
});
}); });
$("#storage button.loadIpfsFile").click(function() { $("#storage button.loadIpfsFile").click(function() {
@ -89,11 +114,15 @@ $(document).ready(function() {
$(document).ready(function() { $(document).ready(function() {
$("#communication .error").hide(); $("#communication .error").hide();
web3.version.getWhisper(function(err, res) { web3.version.getWhisper(function(err, version) {
if (err) { if (err) {
$("#communication .error").show(); $("#communication .error").show();
$("#communication-controls").hide(); $("#communication-controls").hide();
+ $("#status-communication").addClass('status-offline'); $("#status-communication").addClass('status-offline');
} else if (version >= 5) {
$("#communication .errorVersion").show();
$("#communication-controls").hide();
$("#status-communication").addClass('status-offline');
} else { } else {
EmbarkJS.Messages.setProvider('whisper'); EmbarkJS.Messages.setProvider('whisper');
$("#status-communication").addClass('status-online'); $("#status-communication").addClass('status-online');

View File

@ -1,4 +1,5 @@
{ {
"config": {},
"nonce": "0x0000000000000042", "nonce": "0x0000000000000042",
"difficulty": "0x0", "difficulty": "0x0",
"alloc": { "alloc": {

View File

@ -10,7 +10,7 @@
"license": "ISC", "license": "ISC",
"homepage": "", "homepage": "",
"devDependencies": { "devDependencies": {
"embark": "^2.4.2", "embark": "^2.5.0",
"mocha": "^2.2.5" "mocha": "^2.2.5"
} }
} }

View File

@ -5,6 +5,7 @@ var web3 = EmbarkSpec.web3;
describe("SimpleStorage", function() { describe("SimpleStorage", function() {
before(function(done) { before(function(done) {
this.timeout(0);
var contractsConfig = { var contractsConfig = {
"SimpleStorage": { "SimpleStorage": {
args: [100] args: [100]

View File

@ -58,9 +58,9 @@ author = u'Iuri Matias'
# built documents. # built documents.
# #
# The short X.Y version. # The short X.Y version.
version = u'2.4' version = u'2.5'
# The full version, including alpha/beta/rc tags. # The full version, including alpha/beta/rc tags.
release = u'2.4.2' release = u'2.5.0'
# The language for content autogenerated by Sphinx. Refer to documentation # The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages. # for a list of supported languages.

View File

@ -13,13 +13,25 @@ The current available storage is IPFS. it can be initialized as
.. code:: javascript .. 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** **Retrieving Data/Text**
.. code:: javascript .. 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** **Uploading a file**
@ -30,7 +42,13 @@ The current available storage is IPFS. it can be initialized as
.. code:: javascript .. code:: javascript
var input = $("input[type=file"]); 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** **Generate URL to file**

View File

@ -20,11 +20,17 @@ existing contracts:
.. code:: javascript .. code:: javascript
SimpleStorage.deploy().then(function(anotherSimpleStorage) {}); SimpleStorage.deploy([args], {options}).then(function(anotherSimpleStorage) {});
or it can be manually definied as or it can be manually definied as
.. code:: javascript .. code:: javascript
var myContract = new EmbarkJS.Contract({abi: abiObject, code: code}); 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) {});

View File

@ -64,7 +64,7 @@ with the correct address for the contract.
"SimpleStorage": { "SimpleStorage": {
"args": [ "args": [
100, 100,
$MyStorage "$MyStorage"
] ]
}, },
"MyStorage": { "MyStorage": {
@ -74,7 +74,7 @@ with the correct address for the contract.
}, },
"MyMainContract": { "MyMainContract": {
"args": [ "args": [
$SimpleStorage "$SimpleStorage"
] ]
} }
} }

View File

@ -48,8 +48,11 @@ var EmbarkJS =
/*jshint esversion: 6 */ /*jshint esversion: 6 */
//var Ipfs = require('./ipfs.js'); //var Ipfs = require('./ipfs.js');
var EmbarkJS = { //=========================================================
}; // Embark Smart Contracts
//=========================================================
var EmbarkJS = {};
EmbarkJS.Contract = function(options) { EmbarkJS.Contract = function(options) {
var self = this; var self = this;
@ -86,7 +89,7 @@ var EmbarkJS =
}; };
this._originalContractObject = ContractClass.at(this.address); this._originalContractObject = ContractClass.at(this.address);
this._methods = Object.getOwnPropertyNames(this._originalContractObject).filter(function (p) { this._methods = Object.getOwnPropertyNames(this._originalContractObject).filter(function(p) {
// TODO: check for forbidden properties // TODO: check for forbidden properties
if (self.eventList.indexOf(p) >= 0) { if (self.eventList.indexOf(p) >= 0) {
@ -170,7 +173,11 @@ var EmbarkJS =
if (err) { if (err) {
reject(err); reject(err);
} else if (transaction.address !== undefined) { } else if (transaction.address !== undefined) {
resolve(new EmbarkJS.Contract({abi: self.abi, code: self.code, address: transaction.address})); resolve(new EmbarkJS.Contract({
abi: self.abi,
code: self.code,
address: transaction.address
}));
} }
}); });
@ -184,31 +191,101 @@ var EmbarkJS =
return promise; return promise;
}; };
EmbarkJS.IPFS = 'ipfs'; EmbarkJS.Contract.prototype.new = EmbarkJS.Contract.prototype.deploy;
EmbarkJS.Storage = { EmbarkJS.Contract.prototype.at = function(address) {
return new EmbarkJS.Contract({ abi: this.abi, code: this.code, address: address });
};
EmbarkJS.Contract.prototype.send = function(value, unit, _options) {
var options, wei;
if (typeof unit === 'object') {
options = unit;
wei = value;
} else {
options = _options || {};
wei = this.web3.toWei(value, unit);
}
options.to = this.address;
options.value = wei;
console.log(options);
this.web3.eth.sendTransaction(options);
};
//=========================================================
// Embark Storage
//=========================================================
EmbarkJS.Storage = {};
EmbarkJS.Storage.Providers = {
IPFS: 'ipfs',
SWARM: 'swarm'
};
EmbarkJS.Storage.IPFS = {};
EmbarkJS.Storage.saveText = function(text) {
return this.currentStorage.saveText(text);
};
EmbarkJS.Storage.get = function(hash) {
return this.currentStorage.get(hash);
};
EmbarkJS.Storage.uploadFile = function(inputSelector) {
return this.currentStorage.uploadFile(inputSelector);
};
EmbarkJS.Storage.getUrl = function(hash) {
return this.currentStorage.getUrl(hash);
}; };
EmbarkJS.Storage.setProvider = function(provider, options) { EmbarkJS.Storage.setProvider = function(provider, options) {
if (provider === 'ipfs') { var self = this;
this.currentStorage = EmbarkJS.Storage.IPFS; 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) { if (options === undefined) {
this.ipfsConnection = IpfsApi('localhost', '5001'); self.ipfsConnection = IpfsApi('localhost', '5001');
} else { } else {
this.ipfsConnection = IpfsApi(options.server, options.port); 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 { } else {
throw Error('unknown provider'); reject('Unknown storage provider');
} }
});
return promise;
}; };
EmbarkJS.Storage.saveText = function(text) { EmbarkJS.Storage.IPFS.saveText = function(text) {
var self = this;
if (!this.ipfsConnection) {
this.setProvider('ipfs');
}
var promise = new Promise(function(resolve, reject) { var promise = new Promise(function(resolve, reject) {
self.ipfsConnection.add((new self.ipfsConnection.Buffer(text)), function(err, result) { 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) { if (err) {
reject(err); reject(err);
} else { } else {
@ -220,24 +297,41 @@ var EmbarkJS =
return promise; return promise;
}; };
EmbarkJS.Storage.uploadFile = function(inputSelector) { EmbarkJS.Storage.IPFS.get = function(hash) {
var self = this; // 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]; var file = inputSelector[0].files[0];
if (file === undefined) { if (file === undefined) {
throw new Error('no file found'); throw new Error('no file found');
} }
if (!this.ipfsConnection) {
this.setProvider('ipfs');
}
var promise = new Promise(function(resolve, reject) { 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(); var reader = new FileReader();
reader.onloadend = function() { reader.onloadend = function() {
var fileContent = reader.result; var fileContent = reader.result;
var buffer = self.ipfsConnection.Buffer.from(fileContent); var buffer = EmbarkJS.Storage.ipfsConnection.Buffer.from(fileContent);
self.ipfsConnection.add(buffer, function(err, result) { EmbarkJS.Storage.ipfsConnection.add(buffer, function(err, result) {
if (err) { if (err) {
reject(err); reject(err);
} else { } else {
@ -251,31 +345,17 @@ var EmbarkJS =
return promise; return promise;
}; };
EmbarkJS.Storage.get = function(hash) { EmbarkJS.Storage.IPFS.getUrl = function(hash) {
var self = this;
// TODO: detect type, then convert if needed
//var ipfsHash = web3.toAscii(hash);
if (!this.ipfsConnection) {
this.setProvider('ipfs');
}
var promise = new Promise(function(resolve, reject) {
self.ipfsConnection.object.get([hash]).then(function(node) {
resolve(node.data);
});
});
return promise;
};
EmbarkJS.Storage.getUrl = function(hash) {
//var ipfsHash = web3.toAscii(hash); //var ipfsHash = web3.toAscii(hash);
return 'http://localhost:8080/ipfs/' + hash; return 'http://localhost:8080/ipfs/' + hash;
}; };
EmbarkJS.Messages = { //=========================================================
}; // Embark Messaging
//=========================================================
EmbarkJS.Messages = {};
EmbarkJS.Messages.setProvider = function(provider, options) { EmbarkJS.Messages.setProvider = function(provider, options) {
var self = this; var self = this;
@ -292,6 +372,8 @@ var EmbarkJS =
web3.version.getWhisper(function(err, res) { web3.version.getWhisper(function(err, res) {
if (err) { if (err) {
console.log("whisper not available"); console.log("whisper not available");
} else if (web3.version.whisper >= 5) {
console.log("this version of whisper is not supported yet; try a version of geth bellow 1.6.1");
} else { } else {
self.currentMessages.identity = web3.shh.newIdentity(); self.currentMessages.identity = web3.shh.newIdentity();
} }
@ -301,12 +383,16 @@ var EmbarkJS =
if (options === undefined) { if (options === undefined) {
ipfs = HaadIpfsApi('localhost', '5001'); ipfs = HaadIpfsApi('localhost', '5001');
} else { } else {
ipfs = HaadIpfsApi(options.server, options.port); ipfs = HaadIpfsApi(options.host, options.port);
} }
this.currentMessages.orbit = new Orbit(ipfs); this.currentMessages.orbit = new Orbit(ipfs);
this.currentMessages.orbit.connect(web3.eth.accounts[0]); if (typeof(web3) === "undefined") {
this.currentMessages.orbit.connect(Math.random().toString(36).substring(2));
} else { } else {
throw Error('unknown provider'); this.currentMessages.orbit.connect(web3.eth.accounts[0]);
}
} else {
throw Error('Unknown message provider');
} }
}; };
@ -318,8 +404,7 @@ var EmbarkJS =
return this.currentMessages.listenTo(options); return this.currentMessages.listenTo(options);
}; };
EmbarkJS.Messages.Whisper = { EmbarkJS.Messages.Whisper = {};
};
EmbarkJS.Messages.Whisper.sendMessage = function(options) { EmbarkJS.Messages.Whisper.sendMessage = function(options) {
var topics = options.topic || options.topics; var topics = options.topic || options.topics;
@ -418,8 +503,7 @@ var EmbarkJS =
return promise; return promise;
}; };
EmbarkJS.Messages.Orbit = { EmbarkJS.Messages.Orbit = {};
};
EmbarkJS.Messages.Orbit.sendMessage = function(options) { EmbarkJS.Messages.Orbit.sendMessage = function(options) {
var topics = options.topic || options.topics; var topics = options.topic || options.topics;

View File

@ -1,8 +1,11 @@
/*jshint esversion: 6 */ /*jshint esversion: 6 */
//var Ipfs = require('./ipfs.js'); //var Ipfs = require('./ipfs.js');
var EmbarkJS = { //=========================================================
}; // Embark Smart Contracts
//=========================================================
var EmbarkJS = {};
EmbarkJS.Contract = function(options) { EmbarkJS.Contract = function(options) {
var self = this; var self = this;
@ -39,7 +42,7 @@ EmbarkJS.Contract = function(options) {
}; };
this._originalContractObject = ContractClass.at(this.address); this._originalContractObject = ContractClass.at(this.address);
this._methods = Object.getOwnPropertyNames(this._originalContractObject).filter(function (p) { this._methods = Object.getOwnPropertyNames(this._originalContractObject).filter(function(p) {
// TODO: check for forbidden properties // TODO: check for forbidden properties
if (self.eventList.indexOf(p) >= 0) { if (self.eventList.indexOf(p) >= 0) {
@ -123,7 +126,11 @@ EmbarkJS.Contract.prototype.deploy = function(args, _options) {
if (err) { if (err) {
reject(err); reject(err);
} else if (transaction.address !== undefined) { } else if (transaction.address !== undefined) {
resolve(new EmbarkJS.Contract({abi: self.abi, code: self.code, address: transaction.address})); resolve(new EmbarkJS.Contract({
abi: self.abi,
code: self.code,
address: transaction.address
}));
} }
}); });
@ -137,31 +144,101 @@ EmbarkJS.Contract.prototype.deploy = function(args, _options) {
return promise; return promise;
}; };
EmbarkJS.IPFS = 'ipfs'; EmbarkJS.Contract.prototype.new = EmbarkJS.Contract.prototype.deploy;
EmbarkJS.Storage = { EmbarkJS.Contract.prototype.at = function(address) {
return new EmbarkJS.Contract({ abi: this.abi, code: this.code, address: address });
};
EmbarkJS.Contract.prototype.send = function(value, unit, _options) {
var options, wei;
if (typeof unit === 'object') {
options = unit;
wei = value;
} else {
options = _options || {};
wei = this.web3.toWei(value, unit);
}
options.to = this.address;
options.value = wei;
console.log(options);
this.web3.eth.sendTransaction(options);
};
//=========================================================
// Embark Storage
//=========================================================
EmbarkJS.Storage = {};
EmbarkJS.Storage.Providers = {
IPFS: 'ipfs',
SWARM: 'swarm'
};
EmbarkJS.Storage.IPFS = {};
EmbarkJS.Storage.saveText = function(text) {
return this.currentStorage.saveText(text);
};
EmbarkJS.Storage.get = function(hash) {
return this.currentStorage.get(hash);
};
EmbarkJS.Storage.uploadFile = function(inputSelector) {
return this.currentStorage.uploadFile(inputSelector);
};
EmbarkJS.Storage.getUrl = function(hash) {
return this.currentStorage.getUrl(hash);
}; };
EmbarkJS.Storage.setProvider = function(provider, options) { EmbarkJS.Storage.setProvider = function(provider, options) {
if (provider === 'ipfs') { var self = this;
this.currentStorage = EmbarkJS.Storage.IPFS; 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) { if (options === undefined) {
this.ipfsConnection = IpfsApi('localhost', '5001'); self.ipfsConnection = IpfsApi('localhost', '5001');
} else { } else {
this.ipfsConnection = IpfsApi(options.server, options.port); 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 { } else {
throw Error('unknown provider'); reject('Unknown storage provider');
} }
});
return promise;
}; };
EmbarkJS.Storage.saveText = function(text) { EmbarkJS.Storage.IPFS.saveText = function(text) {
var self = this;
if (!this.ipfsConnection) {
this.setProvider('ipfs');
}
var promise = new Promise(function(resolve, reject) { var promise = new Promise(function(resolve, reject) {
self.ipfsConnection.add((new self.ipfsConnection.Buffer(text)), function(err, result) { 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) { if (err) {
reject(err); reject(err);
} else { } else {
@ -173,24 +250,41 @@ EmbarkJS.Storage.saveText = function(text) {
return promise; return promise;
}; };
EmbarkJS.Storage.uploadFile = function(inputSelector) { EmbarkJS.Storage.IPFS.get = function(hash) {
var self = this; // 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]; var file = inputSelector[0].files[0];
if (file === undefined) { if (file === undefined) {
throw new Error('no file found'); throw new Error('no file found');
} }
if (!this.ipfsConnection) {
this.setProvider('ipfs');
}
var promise = new Promise(function(resolve, reject) { 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(); var reader = new FileReader();
reader.onloadend = function() { reader.onloadend = function() {
var fileContent = reader.result; var fileContent = reader.result;
var buffer = self.ipfsConnection.Buffer.from(fileContent); var buffer = EmbarkJS.Storage.ipfsConnection.Buffer.from(fileContent);
self.ipfsConnection.add(buffer, function(err, result) { EmbarkJS.Storage.ipfsConnection.add(buffer, function(err, result) {
if (err) { if (err) {
reject(err); reject(err);
} else { } else {
@ -204,31 +298,17 @@ EmbarkJS.Storage.uploadFile = function(inputSelector) {
return promise; return promise;
}; };
EmbarkJS.Storage.get = function(hash) { EmbarkJS.Storage.IPFS.getUrl = function(hash) {
var self = this;
// TODO: detect type, then convert if needed
//var ipfsHash = web3.toAscii(hash);
if (!this.ipfsConnection) {
this.setProvider('ipfs');
}
var promise = new Promise(function(resolve, reject) {
self.ipfsConnection.object.get([hash]).then(function(node) {
resolve(node.data);
});
});
return promise;
};
EmbarkJS.Storage.getUrl = function(hash) {
//var ipfsHash = web3.toAscii(hash); //var ipfsHash = web3.toAscii(hash);
return 'http://localhost:8080/ipfs/' + hash; return 'http://localhost:8080/ipfs/' + hash;
}; };
EmbarkJS.Messages = { //=========================================================
}; // Embark Messaging
//=========================================================
EmbarkJS.Messages = {};
EmbarkJS.Messages.setProvider = function(provider, options) { EmbarkJS.Messages.setProvider = function(provider, options) {
var self = this; var self = this;
@ -245,6 +325,8 @@ EmbarkJS.Messages.setProvider = function(provider, options) {
web3.version.getWhisper(function(err, res) { web3.version.getWhisper(function(err, res) {
if (err) { if (err) {
console.log("whisper not available"); console.log("whisper not available");
} else if (web3.version.whisper >= 5) {
console.log("this version of whisper is not supported yet; try a version of geth bellow 1.6.1");
} else { } else {
self.currentMessages.identity = web3.shh.newIdentity(); self.currentMessages.identity = web3.shh.newIdentity();
} }
@ -254,12 +336,16 @@ EmbarkJS.Messages.setProvider = function(provider, options) {
if (options === undefined) { if (options === undefined) {
ipfs = HaadIpfsApi('localhost', '5001'); ipfs = HaadIpfsApi('localhost', '5001');
} else { } else {
ipfs = HaadIpfsApi(options.server, options.port); ipfs = HaadIpfsApi(options.host, options.port);
} }
this.currentMessages.orbit = new Orbit(ipfs); this.currentMessages.orbit = new Orbit(ipfs);
this.currentMessages.orbit.connect(web3.eth.accounts[0]); if (typeof(web3) === "undefined") {
this.currentMessages.orbit.connect(Math.random().toString(36).substring(2));
} else { } else {
throw Error('unknown provider'); this.currentMessages.orbit.connect(web3.eth.accounts[0]);
}
} else {
throw Error('Unknown message provider');
} }
}; };
@ -271,8 +357,7 @@ 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) { EmbarkJS.Messages.Whisper.sendMessage = function(options) {
var topics = options.topic || options.topics; var topics = options.topic || options.topics;
@ -371,8 +456,7 @@ EmbarkJS.Messages.Whisper.listenTo = function(options) {
return promise; return promise;
}; };
EmbarkJS.Messages.Orbit = { EmbarkJS.Messages.Orbit = {};
};
EmbarkJS.Messages.Orbit.sendMessage = function(options) { EmbarkJS.Messages.Orbit.sendMessage = function(options) {
var topics = options.topic || options.topics; var topics = options.topic || options.topics;

View File

@ -1842,7 +1842,7 @@ module.exports = function (value, options) {
}; };
},{"crypto-js":59,"crypto-js/sha3":80}],20:[function(require,module,exports){ },{"crypto-js":58,"crypto-js/sha3":79}],20:[function(require,module,exports){
/* /*
This file is part of web3.js. This file is part of web3.js.
@ -2104,7 +2104,7 @@ var toHex = function (val) {
if (isBigNumber(val)) if (isBigNumber(val))
return fromDecimal(val); return fromDecimal(val);
if (isObject(val)) if (typeof val === 'object')
return fromUtf8(JSON.stringify(val)); return fromUtf8(JSON.stringify(val));
// if its a negative number, pass it through fromDecimal // if its a negative number, pass it through fromDecimal
@ -2258,8 +2258,6 @@ var isAddress = function (address) {
} }
}; };
/** /**
* Checks if the given string is a checksummed address * Checks if the given string is a checksummed address
* *
@ -2370,7 +2368,7 @@ var isFunction = function (object) {
* @return {Boolean} * @return {Boolean}
*/ */
var isObject = function (object) { var isObject = function (object) {
return typeof object === 'object'; return object !== null && !(object instanceof Array) && typeof object === 'object';
}; };
/** /**
@ -2410,6 +2408,38 @@ var isJson = function (str) {
} }
}; };
/**
* Returns true if given string is a valid Ethereum block header bloom.
*
* @method isBloom
* @param {String} hex encoded bloom filter
* @return {Boolean}
*/
var isBloom = function (bloom) {
if (!/^(0x)?[0-9a-f]{512}$/i.test(bloom)) {
return false;
} else if (/^(0x)?[0-9a-f]{512}$/.test(bloom) || /^(0x)?[0-9A-F]{512}$/.test(bloom)) {
return true;
}
return false;
};
/**
* Returns true if given string is a valid log topic.
*
* @method isTopic
* @param {String} hex encoded topic
* @return {Boolean}
*/
var isTopic = function (topic) {
if (!/^(0x)?[0-9a-f]{64}$/i.test(topic)) {
return false;
} else if (/^(0x)?[0-9a-f]{64}$/.test(topic) || /^(0x)?[0-9A-F]{64}$/.test(topic)) {
return true;
}
return false;
};
module.exports = { module.exports = {
padLeft: padLeft, padLeft: padLeft,
padRight: padRight, padRight: padRight,
@ -2438,12 +2468,14 @@ module.exports = {
isObject: isObject, isObject: isObject,
isBoolean: isBoolean, isBoolean: isBoolean,
isArray: isArray, isArray: isArray,
isJson: isJson isJson: isJson,
isBloom: isBloom,
isTopic: isTopic,
}; };
},{"./sha3.js":19,"bignumber.js":"bignumber.js","utf8":85}],21:[function(require,module,exports){ },{"./sha3.js":19,"bignumber.js":"bignumber.js","utf8":84}],21:[function(require,module,exports){
module.exports={ module.exports={
"version": "0.18.2" "version": "0.19.0"
} }
},{}],22:[function(require,module,exports){ },{}],22:[function(require,module,exports){
@ -2549,6 +2581,8 @@ Web3.prototype.isAddress = utils.isAddress;
Web3.prototype.isChecksumAddress = utils.isChecksumAddress; Web3.prototype.isChecksumAddress = utils.isChecksumAddress;
Web3.prototype.toChecksumAddress = utils.toChecksumAddress; Web3.prototype.toChecksumAddress = utils.toChecksumAddress;
Web3.prototype.isIBAN = utils.isIBAN; Web3.prototype.isIBAN = utils.isIBAN;
Web3.prototype.padLeft = utils.padLeft;
Web3.prototype.padRight = utils.padRight;
Web3.prototype.sha3 = function(string, options) { Web3.prototype.sha3 = function(string, options) {
@ -2957,7 +2991,7 @@ var ContractFactory = function (eth, abi) {
if (options.value > 0) { if (options.value > 0) {
var constructorAbi = abi.filter(function (json) { var constructorAbi = abi.filter(function (json) {
return json.type === 'constructor' && json.inputs.length === args.length; return json.type === 'constructor' && json.inputs.length === args.length;
})[0] || {}; })[0] || {};
if (!constructorAbi.payable) { if (!constructorAbi.payable) {
throw new Error('Cannot send value to non-payable constructor'); throw new Error('Cannot send value to non-payable constructor');
@ -3092,8 +3126,11 @@ module.exports = ContractFactory;
*/ */
module.exports = { module.exports = {
InvalidNumberOfParams: function () { InvalidNumberOfSolidityArgs: function () {
return new Error('Invalid number of input parameters'); return new Error('Invalid number of arguments to Solidity function');
},
InvalidNumberOfRPCParams: function () {
return new Error('Invalid number of input parameters to RPC method');
}, },
InvalidConnection: function (host){ InvalidConnection: function (host){
return new Error('CONNECTION ERROR: Couldn\'t connect to node '+ host +'.'); return new Error('CONNECTION ERROR: Couldn\'t connect to node '+ host +'.');
@ -3523,7 +3560,9 @@ var Filter = function (requestManager, options, methods, formatter, callback, fi
self.callbacks.forEach(function(cb){ self.callbacks.forEach(function(cb){
cb(error); cb(error);
}); });
if (typeof filterCreationErrorCallback === 'function') {
filterCreationErrorCallback(error); filterCreationErrorCallback(error);
}
} else { } else {
self.filterId = id; self.filterId = id;
@ -3937,6 +3976,7 @@ module.exports = {
var coder = require('../solidity/coder'); var coder = require('../solidity/coder');
var utils = require('../utils/utils'); var utils = require('../utils/utils');
var errors = require('./errors');
var formatters = require('./formatters'); var formatters = require('./formatters');
var sha3 = require('../utils/sha3'); var sha3 = require('../utils/sha3');
@ -3969,6 +4009,23 @@ SolidityFunction.prototype.extractDefaultBlock = function (args) {
} }
}; };
/**
* Should be called to check if the number of arguments is correct
*
* @method validateArgs
* @param {Array} arguments
* @throws {Error} if it is not
*/
SolidityFunction.prototype.validateArgs = function (args) {
var inputArgs = args.filter(function (a) {
// filter the options object but not arguments that are arrays
return !(utils.isObject(a) === true && utils.isArray(a) === false);
});
if (inputArgs.length !== this._inputTypes.length) {
throw errors.InvalidNumberOfSolidityArgs();
}
};
/** /**
* Should be used to create payload from arguments * Should be used to create payload from arguments
* *
@ -3981,6 +4038,7 @@ SolidityFunction.prototype.toPayload = function (args) {
if (args.length > this._inputTypes.length && utils.isObject(args[args.length -1])) { if (args.length > this._inputTypes.length && utils.isObject(args[args.length -1])) {
options = args[args.length - 1]; options = args[args.length - 1];
} }
this.validateArgs(args);
options.to = this._address; options.to = this._address;
options.data = '0x' + this.signature() + coder.encodeParams(this._inputTypes, args); options.data = '0x' + this.signature() + coder.encodeParams(this._inputTypes, args);
return options; return options;
@ -4175,8 +4233,7 @@ SolidityFunction.prototype.attachToContract = function (contract) {
module.exports = SolidityFunction; module.exports = SolidityFunction;
},{"../solidity/coder":7,"../utils/sha3":19,"../utils/utils":20,"./errors":26,"./formatters":30}],32:[function(require,module,exports){
},{"../solidity/coder":7,"../utils/sha3":19,"../utils/utils":20,"./formatters":30}],32:[function(require,module,exports){
/* /*
This file is part of web3.js. This file is part of web3.js.
@ -4331,7 +4388,7 @@ HttpProvider.prototype.isConnected = function() {
module.exports = HttpProvider; module.exports = HttpProvider;
},{"./errors":26,"xhr2":86,"xmlhttprequest":17}],33:[function(require,module,exports){ },{"./errors":26,"xhr2":85,"xmlhttprequest":17}],33:[function(require,module,exports){
/* /*
This file is part of web3.js. This file is part of web3.js.
@ -4928,7 +4985,7 @@ Method.prototype.extractCallback = function (args) {
*/ */
Method.prototype.validateArgs = function (args) { Method.prototype.validateArgs = function (args) {
if (args.length !== this.params) { if (args.length !== this.params) {
throw errors.InvalidNumberOfParams(); throw errors.InvalidNumberOfRPCParams();
} }
}; };
@ -5022,7 +5079,6 @@ Method.prototype.request = function () {
module.exports = Method; module.exports = Method;
},{"../utils/utils":20,"./errors":26}],37:[function(require,module,exports){ },{"../utils/utils":20,"./errors":26}],37:[function(require,module,exports){
/* /*
This file is part of web3.js. This file is part of web3.js.
@ -5296,6 +5352,13 @@ var methods = function () {
inputFormatter: [formatters.inputTransactionFormatter] inputFormatter: [formatters.inputTransactionFormatter]
}); });
var signTransaction = new Method({
name: 'signTransaction',
call: 'eth_signTransaction',
params: 1,
inputFormatter: [formatters.inputTransactionFormatter]
});
var sign = new Method({ var sign = new Method({
name: 'sign', name: 'sign',
call: 'eth_sign', call: 'eth_sign',
@ -5364,6 +5427,7 @@ var methods = function () {
call, call,
estimateGas, estimateGas,
sendRawTransaction, sendRawTransaction,
signTransaction,
sendTransaction, sendTransaction,
sign, sign,
compileSolidity, compileSolidity,
@ -5421,8 +5485,8 @@ Eth.prototype.contract = function (abi) {
return factory; return factory;
}; };
Eth.prototype.filter = function (fil, callback) { Eth.prototype.filter = function (fil, callback, filterCreationErrorCallback) {
return new Filter(this._requestManager, fil, watches.eth(), formatters.outputLogFormatter, callback); return new Filter(this._requestManager, fil, watches.eth(), formatters.outputLogFormatter, callback, filterCreationErrorCallback);
}; };
Eth.prototype.namereg = function () { Eth.prototype.namereg = function () {
@ -5439,7 +5503,6 @@ Eth.prototype.isSyncing = function (callback) {
module.exports = Eth; module.exports = Eth;
},{"../../utils/config":18,"../../utils/utils":20,"../contract":25,"../filter":29,"../formatters":30,"../iban":33,"../method":36,"../namereg":44,"../property":45,"../syncing":48,"../transfer":49,"./watches":43}],39:[function(require,module,exports){ },{"../../utils/config":18,"../../utils/utils":20,"../contract":25,"../filter":29,"../formatters":30,"../iban":33,"../method":36,"../namereg":44,"../property":45,"../syncing":48,"../transfer":49,"./watches":43}],39:[function(require,module,exports){
/* /*
This file is part of web3.js. This file is part of web3.js.
@ -5548,6 +5611,25 @@ var methods = function () {
inputFormatter: [null] inputFormatter: [null]
}); });
var importRawKey = new Method({
name: 'importRawKey',
call: 'personal_importRawKey',
params: 2
});
var sign = new Method({
name: 'sign',
call: 'personal_sign',
params: 3,
inputFormatter: [null, formatters.inputAddressFormatter, null]
});
var ecRecover = new Method({
name: 'ecRecover',
call: 'personal_ecRecover',
params: 2
});
var unlockAccount = new Method({ var unlockAccount = new Method({
name: 'unlockAccount', name: 'unlockAccount',
call: 'personal_unlockAccount', call: 'personal_unlockAccount',
@ -5571,7 +5653,10 @@ var methods = function () {
return [ return [
newAccount, newAccount,
importRawKey,
unlockAccount, unlockAccount,
ecRecover,
sign,
sendTransaction, sendTransaction,
lockAccount lockAccount
]; ];
@ -6595,8 +6680,6 @@ module.exports = transfer;
},{"../contracts/SmartExchange.json":3,"./iban":33}],50:[function(require,module,exports){ },{"../contracts/SmartExchange.json":3,"./iban":33}],50:[function(require,module,exports){
},{}],51:[function(require,module,exports){
;(function (root, factory, undef) { ;(function (root, factory, undef) {
if (typeof exports === "object") { if (typeof exports === "object") {
// CommonJS // CommonJS
@ -6829,7 +6912,7 @@ module.exports = transfer;
return CryptoJS.AES; return CryptoJS.AES;
})); }));
},{"./cipher-core":52,"./core":53,"./enc-base64":54,"./evpkdf":56,"./md5":61}],52:[function(require,module,exports){ },{"./cipher-core":51,"./core":52,"./enc-base64":53,"./evpkdf":55,"./md5":60}],51:[function(require,module,exports){
;(function (root, factory) { ;(function (root, factory) {
if (typeof exports === "object") { if (typeof exports === "object") {
// CommonJS // CommonJS
@ -7705,7 +7788,7 @@ module.exports = transfer;
})); }));
},{"./core":53}],53:[function(require,module,exports){ },{"./core":52}],52:[function(require,module,exports){
;(function (root, factory) { ;(function (root, factory) {
if (typeof exports === "object") { if (typeof exports === "object") {
// CommonJS // CommonJS
@ -8466,7 +8549,7 @@ module.exports = transfer;
return CryptoJS; return CryptoJS;
})); }));
},{}],54:[function(require,module,exports){ },{}],53:[function(require,module,exports){
;(function (root, factory) { ;(function (root, factory) {
if (typeof exports === "object") { if (typeof exports === "object") {
// CommonJS // CommonJS
@ -8602,7 +8685,7 @@ module.exports = transfer;
return CryptoJS.enc.Base64; return CryptoJS.enc.Base64;
})); }));
},{"./core":53}],55:[function(require,module,exports){ },{"./core":52}],54:[function(require,module,exports){
;(function (root, factory) { ;(function (root, factory) {
if (typeof exports === "object") { if (typeof exports === "object") {
// CommonJS // CommonJS
@ -8752,7 +8835,7 @@ module.exports = transfer;
return CryptoJS.enc.Utf16; return CryptoJS.enc.Utf16;
})); }));
},{"./core":53}],56:[function(require,module,exports){ },{"./core":52}],55:[function(require,module,exports){
;(function (root, factory, undef) { ;(function (root, factory, undef) {
if (typeof exports === "object") { if (typeof exports === "object") {
// CommonJS // CommonJS
@ -8885,7 +8968,7 @@ module.exports = transfer;
return CryptoJS.EvpKDF; return CryptoJS.EvpKDF;
})); }));
},{"./core":53,"./hmac":58,"./sha1":77}],57:[function(require,module,exports){ },{"./core":52,"./hmac":57,"./sha1":76}],56:[function(require,module,exports){
;(function (root, factory, undef) { ;(function (root, factory, undef) {
if (typeof exports === "object") { if (typeof exports === "object") {
// CommonJS // CommonJS
@ -8952,7 +9035,7 @@ module.exports = transfer;
return CryptoJS.format.Hex; return CryptoJS.format.Hex;
})); }));
},{"./cipher-core":52,"./core":53}],58:[function(require,module,exports){ },{"./cipher-core":51,"./core":52}],57:[function(require,module,exports){
;(function (root, factory) { ;(function (root, factory) {
if (typeof exports === "object") { if (typeof exports === "object") {
// CommonJS // CommonJS
@ -9096,7 +9179,7 @@ module.exports = transfer;
})); }));
},{"./core":53}],59:[function(require,module,exports){ },{"./core":52}],58:[function(require,module,exports){
;(function (root, factory, undef) { ;(function (root, factory, undef) {
if (typeof exports === "object") { if (typeof exports === "object") {
// CommonJS // CommonJS
@ -9115,7 +9198,7 @@ module.exports = transfer;
return CryptoJS; return CryptoJS;
})); }));
},{"./aes":51,"./cipher-core":52,"./core":53,"./enc-base64":54,"./enc-utf16":55,"./evpkdf":56,"./format-hex":57,"./hmac":58,"./lib-typedarrays":60,"./md5":61,"./mode-cfb":62,"./mode-ctr":64,"./mode-ctr-gladman":63,"./mode-ecb":65,"./mode-ofb":66,"./pad-ansix923":67,"./pad-iso10126":68,"./pad-iso97971":69,"./pad-nopadding":70,"./pad-zeropadding":71,"./pbkdf2":72,"./rabbit":74,"./rabbit-legacy":73,"./rc4":75,"./ripemd160":76,"./sha1":77,"./sha224":78,"./sha256":79,"./sha3":80,"./sha384":81,"./sha512":82,"./tripledes":83,"./x64-core":84}],60:[function(require,module,exports){ },{"./aes":50,"./cipher-core":51,"./core":52,"./enc-base64":53,"./enc-utf16":54,"./evpkdf":55,"./format-hex":56,"./hmac":57,"./lib-typedarrays":59,"./md5":60,"./mode-cfb":61,"./mode-ctr":63,"./mode-ctr-gladman":62,"./mode-ecb":64,"./mode-ofb":65,"./pad-ansix923":66,"./pad-iso10126":67,"./pad-iso97971":68,"./pad-nopadding":69,"./pad-zeropadding":70,"./pbkdf2":71,"./rabbit":73,"./rabbit-legacy":72,"./rc4":74,"./ripemd160":75,"./sha1":76,"./sha224":77,"./sha256":78,"./sha3":79,"./sha384":80,"./sha512":81,"./tripledes":82,"./x64-core":83}],59:[function(require,module,exports){
;(function (root, factory) { ;(function (root, factory) {
if (typeof exports === "object") { if (typeof exports === "object") {
// CommonJS // CommonJS
@ -9192,7 +9275,7 @@ module.exports = transfer;
return CryptoJS.lib.WordArray; return CryptoJS.lib.WordArray;
})); }));
},{"./core":53}],61:[function(require,module,exports){ },{"./core":52}],60:[function(require,module,exports){
;(function (root, factory) { ;(function (root, factory) {
if (typeof exports === "object") { if (typeof exports === "object") {
// CommonJS // CommonJS
@ -9461,7 +9544,7 @@ module.exports = transfer;
return CryptoJS.MD5; return CryptoJS.MD5;
})); }));
},{"./core":53}],62:[function(require,module,exports){ },{"./core":52}],61:[function(require,module,exports){
;(function (root, factory, undef) { ;(function (root, factory, undef) {
if (typeof exports === "object") { if (typeof exports === "object") {
// CommonJS // CommonJS
@ -9540,7 +9623,7 @@ module.exports = transfer;
return CryptoJS.mode.CFB; return CryptoJS.mode.CFB;
})); }));
},{"./cipher-core":52,"./core":53}],63:[function(require,module,exports){ },{"./cipher-core":51,"./core":52}],62:[function(require,module,exports){
;(function (root, factory, undef) { ;(function (root, factory, undef) {
if (typeof exports === "object") { if (typeof exports === "object") {
// CommonJS // CommonJS
@ -9657,7 +9740,7 @@ module.exports = transfer;
return CryptoJS.mode.CTRGladman; return CryptoJS.mode.CTRGladman;
})); }));
},{"./cipher-core":52,"./core":53}],64:[function(require,module,exports){ },{"./cipher-core":51,"./core":52}],63:[function(require,module,exports){
;(function (root, factory, undef) { ;(function (root, factory, undef) {
if (typeof exports === "object") { if (typeof exports === "object") {
// CommonJS // CommonJS
@ -9716,7 +9799,7 @@ module.exports = transfer;
return CryptoJS.mode.CTR; return CryptoJS.mode.CTR;
})); }));
},{"./cipher-core":52,"./core":53}],65:[function(require,module,exports){ },{"./cipher-core":51,"./core":52}],64:[function(require,module,exports){
;(function (root, factory, undef) { ;(function (root, factory, undef) {
if (typeof exports === "object") { if (typeof exports === "object") {
// CommonJS // CommonJS
@ -9757,7 +9840,7 @@ module.exports = transfer;
return CryptoJS.mode.ECB; return CryptoJS.mode.ECB;
})); }));
},{"./cipher-core":52,"./core":53}],66:[function(require,module,exports){ },{"./cipher-core":51,"./core":52}],65:[function(require,module,exports){
;(function (root, factory, undef) { ;(function (root, factory, undef) {
if (typeof exports === "object") { if (typeof exports === "object") {
// CommonJS // CommonJS
@ -9812,7 +9895,7 @@ module.exports = transfer;
return CryptoJS.mode.OFB; return CryptoJS.mode.OFB;
})); }));
},{"./cipher-core":52,"./core":53}],67:[function(require,module,exports){ },{"./cipher-core":51,"./core":52}],66:[function(require,module,exports){
;(function (root, factory, undef) { ;(function (root, factory, undef) {
if (typeof exports === "object") { if (typeof exports === "object") {
// CommonJS // CommonJS
@ -9862,7 +9945,7 @@ module.exports = transfer;
return CryptoJS.pad.Ansix923; return CryptoJS.pad.Ansix923;
})); }));
},{"./cipher-core":52,"./core":53}],68:[function(require,module,exports){ },{"./cipher-core":51,"./core":52}],67:[function(require,module,exports){
;(function (root, factory, undef) { ;(function (root, factory, undef) {
if (typeof exports === "object") { if (typeof exports === "object") {
// CommonJS // CommonJS
@ -9907,7 +9990,7 @@ module.exports = transfer;
return CryptoJS.pad.Iso10126; return CryptoJS.pad.Iso10126;
})); }));
},{"./cipher-core":52,"./core":53}],69:[function(require,module,exports){ },{"./cipher-core":51,"./core":52}],68:[function(require,module,exports){
;(function (root, factory, undef) { ;(function (root, factory, undef) {
if (typeof exports === "object") { if (typeof exports === "object") {
// CommonJS // CommonJS
@ -9948,7 +10031,7 @@ module.exports = transfer;
return CryptoJS.pad.Iso97971; return CryptoJS.pad.Iso97971;
})); }));
},{"./cipher-core":52,"./core":53}],70:[function(require,module,exports){ },{"./cipher-core":51,"./core":52}],69:[function(require,module,exports){
;(function (root, factory, undef) { ;(function (root, factory, undef) {
if (typeof exports === "object") { if (typeof exports === "object") {
// CommonJS // CommonJS
@ -9979,7 +10062,7 @@ module.exports = transfer;
return CryptoJS.pad.NoPadding; return CryptoJS.pad.NoPadding;
})); }));
},{"./cipher-core":52,"./core":53}],71:[function(require,module,exports){ },{"./cipher-core":51,"./core":52}],70:[function(require,module,exports){
;(function (root, factory, undef) { ;(function (root, factory, undef) {
if (typeof exports === "object") { if (typeof exports === "object") {
// CommonJS // CommonJS
@ -10025,7 +10108,7 @@ module.exports = transfer;
return CryptoJS.pad.ZeroPadding; return CryptoJS.pad.ZeroPadding;
})); }));
},{"./cipher-core":52,"./core":53}],72:[function(require,module,exports){ },{"./cipher-core":51,"./core":52}],71:[function(require,module,exports){
;(function (root, factory, undef) { ;(function (root, factory, undef) {
if (typeof exports === "object") { if (typeof exports === "object") {
// CommonJS // CommonJS
@ -10171,7 +10254,7 @@ module.exports = transfer;
return CryptoJS.PBKDF2; return CryptoJS.PBKDF2;
})); }));
},{"./core":53,"./hmac":58,"./sha1":77}],73:[function(require,module,exports){ },{"./core":52,"./hmac":57,"./sha1":76}],72:[function(require,module,exports){
;(function (root, factory, undef) { ;(function (root, factory, undef) {
if (typeof exports === "object") { if (typeof exports === "object") {
// CommonJS // CommonJS
@ -10362,7 +10445,7 @@ module.exports = transfer;
return CryptoJS.RabbitLegacy; return CryptoJS.RabbitLegacy;
})); }));
},{"./cipher-core":52,"./core":53,"./enc-base64":54,"./evpkdf":56,"./md5":61}],74:[function(require,module,exports){ },{"./cipher-core":51,"./core":52,"./enc-base64":53,"./evpkdf":55,"./md5":60}],73:[function(require,module,exports){
;(function (root, factory, undef) { ;(function (root, factory, undef) {
if (typeof exports === "object") { if (typeof exports === "object") {
// CommonJS // CommonJS
@ -10555,7 +10638,7 @@ module.exports = transfer;
return CryptoJS.Rabbit; return CryptoJS.Rabbit;
})); }));
},{"./cipher-core":52,"./core":53,"./enc-base64":54,"./evpkdf":56,"./md5":61}],75:[function(require,module,exports){ },{"./cipher-core":51,"./core":52,"./enc-base64":53,"./evpkdf":55,"./md5":60}],74:[function(require,module,exports){
;(function (root, factory, undef) { ;(function (root, factory, undef) {
if (typeof exports === "object") { if (typeof exports === "object") {
// CommonJS // CommonJS
@ -10695,7 +10778,7 @@ module.exports = transfer;
return CryptoJS.RC4; return CryptoJS.RC4;
})); }));
},{"./cipher-core":52,"./core":53,"./enc-base64":54,"./evpkdf":56,"./md5":61}],76:[function(require,module,exports){ },{"./cipher-core":51,"./core":52,"./enc-base64":53,"./evpkdf":55,"./md5":60}],75:[function(require,module,exports){
;(function (root, factory) { ;(function (root, factory) {
if (typeof exports === "object") { if (typeof exports === "object") {
// CommonJS // CommonJS
@ -10963,7 +11046,7 @@ module.exports = transfer;
return CryptoJS.RIPEMD160; return CryptoJS.RIPEMD160;
})); }));
},{"./core":53}],77:[function(require,module,exports){ },{"./core":52}],76:[function(require,module,exports){
;(function (root, factory) { ;(function (root, factory) {
if (typeof exports === "object") { if (typeof exports === "object") {
// CommonJS // CommonJS
@ -11114,7 +11197,7 @@ module.exports = transfer;
return CryptoJS.SHA1; return CryptoJS.SHA1;
})); }));
},{"./core":53}],78:[function(require,module,exports){ },{"./core":52}],77:[function(require,module,exports){
;(function (root, factory, undef) { ;(function (root, factory, undef) {
if (typeof exports === "object") { if (typeof exports === "object") {
// CommonJS // CommonJS
@ -11195,7 +11278,7 @@ module.exports = transfer;
return CryptoJS.SHA224; return CryptoJS.SHA224;
})); }));
},{"./core":53,"./sha256":79}],79:[function(require,module,exports){ },{"./core":52,"./sha256":78}],78:[function(require,module,exports){
;(function (root, factory) { ;(function (root, factory) {
if (typeof exports === "object") { if (typeof exports === "object") {
// CommonJS // CommonJS
@ -11395,7 +11478,7 @@ module.exports = transfer;
return CryptoJS.SHA256; return CryptoJS.SHA256;
})); }));
},{"./core":53}],80:[function(require,module,exports){ },{"./core":52}],79:[function(require,module,exports){
;(function (root, factory, undef) { ;(function (root, factory, undef) {
if (typeof exports === "object") { if (typeof exports === "object") {
// CommonJS // CommonJS
@ -11719,7 +11802,7 @@ module.exports = transfer;
return CryptoJS.SHA3; return CryptoJS.SHA3;
})); }));
},{"./core":53,"./x64-core":84}],81:[function(require,module,exports){ },{"./core":52,"./x64-core":83}],80:[function(require,module,exports){
;(function (root, factory, undef) { ;(function (root, factory, undef) {
if (typeof exports === "object") { if (typeof exports === "object") {
// CommonJS // CommonJS
@ -11803,7 +11886,7 @@ module.exports = transfer;
return CryptoJS.SHA384; return CryptoJS.SHA384;
})); }));
},{"./core":53,"./sha512":82,"./x64-core":84}],82:[function(require,module,exports){ },{"./core":52,"./sha512":81,"./x64-core":83}],81:[function(require,module,exports){
;(function (root, factory, undef) { ;(function (root, factory, undef) {
if (typeof exports === "object") { if (typeof exports === "object") {
// CommonJS // CommonJS
@ -12127,7 +12210,7 @@ module.exports = transfer;
return CryptoJS.SHA512; return CryptoJS.SHA512;
})); }));
},{"./core":53,"./x64-core":84}],83:[function(require,module,exports){ },{"./core":52,"./x64-core":83}],82:[function(require,module,exports){
;(function (root, factory, undef) { ;(function (root, factory, undef) {
if (typeof exports === "object") { if (typeof exports === "object") {
// CommonJS // CommonJS
@ -12898,7 +12981,7 @@ module.exports = transfer;
return CryptoJS.TripleDES; return CryptoJS.TripleDES;
})); }));
},{"./cipher-core":52,"./core":53,"./enc-base64":54,"./evpkdf":56,"./md5":61}],84:[function(require,module,exports){ },{"./cipher-core":51,"./core":52,"./enc-base64":53,"./evpkdf":55,"./md5":60}],83:[function(require,module,exports){
;(function (root, factory) { ;(function (root, factory) {
if (typeof exports === "object") { if (typeof exports === "object") {
// CommonJS // CommonJS
@ -13203,7 +13286,7 @@ module.exports = transfer;
return CryptoJS; return CryptoJS;
})); }));
},{"./core":53}],85:[function(require,module,exports){ },{"./core":52}],84:[function(require,module,exports){
/*! https://mths.be/utf8js v2.1.2 by @mathias */ /*! https://mths.be/utf8js v2.1.2 by @mathias */
;(function(root) { ;(function(root) {
@ -13449,25 +13532,25 @@ module.exports = transfer;
}(this)); }(this));
},{}],86:[function(require,module,exports){ },{}],85:[function(require,module,exports){
module.exports = XMLHttpRequest; module.exports = XMLHttpRequest;
},{}],"bignumber.js":[function(require,module,exports){ },{}],"bignumber.js":[function(require,module,exports){
/*! bignumber.js v2.0.7 https://github.com/MikeMcl/bignumber.js/LICENCE */ /*! bignumber.js v4.0.2 https://github.com/MikeMcl/bignumber.js/LICENCE */
;(function (global) { ;(function (globalObj) {
'use strict'; 'use strict';
/* /*
bignumber.js v2.0.7 bignumber.js v4.0.2
A JavaScript library for arbitrary-precision arithmetic. A JavaScript library for arbitrary-precision arithmetic.
https://github.com/MikeMcl/bignumber.js https://github.com/MikeMcl/bignumber.js
Copyright (c) 2015 Michael Mclaughlin <M8ch88l@gmail.com> Copyright (c) 2017 Michael Mclaughlin <M8ch88l@gmail.com>
MIT Expat Licence MIT Expat Licence
*/ */
var BigNumber, crypto, parseNumeric, var BigNumber,
isNumeric = /^-?(\d+(\.\d*)?|\.\d+)(e[+-]?\d+)?$/i, isNumeric = /^-?(\d+(\.\d*)?|\.\d+)(e[+-]?\d+)?$/i,
mathceil = Math.ceil, mathceil = Math.ceil,
mathfloor = Math.floor, mathfloor = Math.floor,
@ -13493,8 +13576,8 @@ module.exports = XMLHttpRequest;
/* /*
* Create and return a BigNumber constructor. * Create and return a BigNumber constructor.
*/ */
function another(configObj) { function constructorFactory(config) {
var div, var div, parseNumeric,
// id tracks the caller function, so its name can be included in error messages. // id tracks the caller function, so its name can be included in error messages.
id = 0, id = 0,
@ -13580,7 +13663,7 @@ module.exports = XMLHttpRequest;
// The maximum number of significant digits of the result of the toPower operation. // The maximum number of significant digits of the result of the toPower operation.
// If POW_PRECISION is 0, there will be unlimited significant digits. // If POW_PRECISION is 0, there will be unlimited significant digits.
POW_PRECISION = 100, // 0 to MAX POW_PRECISION = 0, // 0 to MAX
// The format specification used by the BigNumber.prototype.toFormat method. // The format specification used by the BigNumber.prototype.toFormat method.
FORMAT = { FORMAT = {
@ -13713,7 +13796,9 @@ module.exports = XMLHttpRequest;
// Disallow numbers with over 15 significant digits if number type. // Disallow numbers with over 15 significant digits if number type.
// 'new BigNumber() number type has more than 15 significant digits: {n}' // 'new BigNumber() number type has more than 15 significant digits: {n}'
if ( num && ERRORS && len > 15 ) raise( id, tooManyDigits, x.s * n ); if ( num && ERRORS && len > 15 && ( n > MAX_SAFE_INTEGER || n !== mathfloor(n) ) ) {
raise( id, tooManyDigits, x.s * n );
}
e = e - i - 1; e = e - i - 1;
@ -13768,7 +13853,7 @@ module.exports = XMLHttpRequest;
// CONSTRUCTOR PROPERTIES // CONSTRUCTOR PROPERTIES
BigNumber.another = another; BigNumber.another = constructorFactory;
BigNumber.ROUND_UP = 0; BigNumber.ROUND_UP = 0;
BigNumber.ROUND_DOWN = 1; BigNumber.ROUND_DOWN = 1;
@ -13815,7 +13900,7 @@ module.exports = XMLHttpRequest;
* Ignore properties/parameters set to null or undefined. * Ignore properties/parameters set to null or undefined.
* Return an object with the properties current values. * Return an object with the properties current values.
*/ */
BigNumber.config = function () { BigNumber.config = BigNumber.set = function () {
var v, p, var v, p,
i = 0, i = 0,
r = {}, r = {},
@ -13895,9 +13980,19 @@ module.exports = XMLHttpRequest;
// 'config() crypto unavailable: {crypto}' // 'config() crypto unavailable: {crypto}'
if ( has( p = 'CRYPTO' ) ) { if ( has( p = 'CRYPTO' ) ) {
if ( v === !!v || v === 1 || v === 0 ) { if ( v === true || v === false || v === 1 || v === 0 ) {
CRYPTO = !!( v && crypto && typeof crypto == 'object' ); if (v) {
if ( v && !CRYPTO && ERRORS ) raise( 2, 'crypto unavailable', crypto ); v = typeof crypto == 'undefined';
if ( !v && crypto && (crypto.getRandomValues || crypto.randomBytes)) {
CRYPTO = true;
} else if (ERRORS) {
raise( 2, 'crypto unavailable', v ? void 0 : crypto );
} else {
CRYPTO = false;
}
} else {
CRYPTO = false;
}
} else if (ERRORS) { } else if (ERRORS) {
raise( 2, p + notBool, v ); raise( 2, p + notBool, v );
} }
@ -13987,7 +14082,7 @@ module.exports = XMLHttpRequest;
if (CRYPTO) { if (CRYPTO) {
// Browsers supporting crypto.getRandomValues. // Browsers supporting crypto.getRandomValues.
if ( crypto && crypto.getRandomValues ) { if (crypto.getRandomValues) {
a = crypto.getRandomValues( new Uint32Array( k *= 2 ) ); a = crypto.getRandomValues( new Uint32Array( k *= 2 ) );
@ -14020,7 +14115,7 @@ module.exports = XMLHttpRequest;
i = k / 2; i = k / 2;
// Node.js supporting crypto.randomBytes. // Node.js supporting crypto.randomBytes.
} else if ( crypto && crypto.randomBytes ) { } else if (crypto.randomBytes) {
// buffer // buffer
a = crypto.randomBytes( k *= 7 ); a = crypto.randomBytes( k *= 7 );
@ -14045,13 +14140,14 @@ module.exports = XMLHttpRequest;
} }
} }
i = k / 7; i = k / 7;
} else if (ERRORS) { } else {
raise( 14, 'crypto unavailable', crypto ); CRYPTO = false;
if (ERRORS) raise( 14, 'crypto unavailable', crypto );
} }
} }
// Use Math.random: CRYPTO is false or crypto is unavailable and ERRORS is false. // Use Math.random.
if (!i) { if (!CRYPTO) {
for ( ; i < k; ) { for ( ; i < k; ) {
v = random53bitInt(); v = random53bitInt();
@ -14077,7 +14173,7 @@ module.exports = XMLHttpRequest;
} else { } else {
// Remove leading elements which are zero and adjust exponent accordingly. // Remove leading elements which are zero and adjust exponent accordingly.
for ( e = -1 ; c[0] === 0; c.shift(), e -= LOG_BASE); for ( e = -1 ; c[0] === 0; c.splice(0, 1), e -= LOG_BASE);
// Count the digits of the first element of c to determine leading zeros, and... // Count the digits of the first element of c to determine leading zeros, and...
for ( i = 1, v = c[0]; v >= 10; v /= 10, i++); for ( i = 1, v = c[0]; v >= 10; v /= 10, i++);
@ -14170,7 +14266,7 @@ module.exports = XMLHttpRequest;
if ( !d ) { if ( !d ) {
++e; ++e;
xc.unshift(1); xc = [1].concat(xc);
} }
} }
} }
@ -14208,7 +14304,7 @@ module.exports = XMLHttpRequest;
x[i] = temp % base; x[i] = temp % base;
} }
if (carry) x.unshift(carry); if (carry) x = [carry].concat(x);
return x; return x;
} }
@ -14242,7 +14338,7 @@ module.exports = XMLHttpRequest;
} }
// Remove leading zeros. // Remove leading zeros.
for ( ; !a[0] && a.length > 1; a.shift() ); for ( ; !a[0] && a.length > 1; a.splice(0, 1) );
} }
// x: dividend, y: divisor. // x: dividend, y: divisor.
@ -14311,7 +14407,7 @@ module.exports = XMLHttpRequest;
// Add zeros to make remainder as long as divisor. // Add zeros to make remainder as long as divisor.
for ( ; remL < yL; rem[remL++] = 0 ); for ( ; remL < yL; rem[remL++] = 0 );
yz = yc.slice(); yz = yc.slice();
yz.unshift(0); yz = [0].concat(yz);
yc0 = yc[0]; yc0 = yc[0];
if ( yc[1] >= base / 2 ) yc0++; if ( yc[1] >= base / 2 ) yc0++;
// Not necessary, but to prevent trial digit n > base, when using base 3. // Not necessary, but to prevent trial digit n > base, when using base 3.
@ -14382,7 +14478,7 @@ module.exports = XMLHttpRequest;
prodL = prod.length; prodL = prod.length;
} }
if ( prodL < remL ) prod.unshift(0); if ( prodL < remL ) prod = [0].concat(prod);
// Subtract product from remainder. // Subtract product from remainder.
subtract( rem, prod, remL, base ); subtract( rem, prod, remL, base );
@ -14423,7 +14519,7 @@ module.exports = XMLHttpRequest;
more = rem[0] != null; more = rem[0] != null;
// Leading zero? // Leading zero?
if ( !qc[0] ) qc.shift(); if ( !qc[0] ) qc.splice(0, 1);
} }
if ( base == BASE ) { if ( base == BASE ) {
@ -14583,11 +14679,11 @@ module.exports = XMLHttpRequest;
// Handle values that fail the validity test in BigNumber. // Handle values that fail the validity test in BigNumber.
parseNumeric = (function () { parseNumeric = (function () {
var basePrefix = /^(-?)0([xbo])/i, var basePrefix = /^(-?)0([xbo])(?=\w[\w.]*$)/i,
dotAfter = /^([^.]+)\.$/, dotAfter = /^([^.]+)\.$/,
dotBefore = /^\.([^.]+)$/, dotBefore = /^\.([^.]+)$/,
isInfinityOrNaN = /^-?(Infinity|NaN)$/, isInfinityOrNaN = /^-?(Infinity|NaN)$/,
whitespaceOrPlus = /^\s*\+|^\s+|\s+$/g; whitespaceOrPlus = /^\s*\+(?=[\w.])|^\s+|\s+$/g;
return function ( x, str, num, b ) { return function ( x, str, num, b ) {
var base, var base,
@ -14755,7 +14851,7 @@ module.exports = XMLHttpRequest;
sd -= x.e + 1; sd -= x.e + 1;
// 1, 0.1, 0.01, 0.001, 0.0001 etc. // 1, 0.1, 0.01, 0.001, 0.0001 etc.
xc[0] = pows10[ sd % LOG_BASE ]; xc[0] = pows10[ ( LOG_BASE - sd % LOG_BASE ) % LOG_BASE ];
x.e = -sd || 0; x.e = -sd || 0;
} else { } else {
@ -15133,7 +15229,7 @@ module.exports = XMLHttpRequest;
} }
// Remove leading zeros and adjust exponent accordingly. // Remove leading zeros and adjust exponent accordingly.
for ( ; xc[0] == 0; xc.shift(), --ye ); for ( ; xc[0] == 0; xc.splice(0, 1), --ye );
// Zero? // Zero?
if ( !xc[0] ) { if ( !xc[0] ) {
@ -15297,11 +15393,11 @@ module.exports = XMLHttpRequest;
// Only start adding at yc.length - 1 as the further digits of xc can be ignored. // Only start adding at yc.length - 1 as the further digits of xc can be ignored.
for ( a = 0; b; ) { for ( a = 0; b; ) {
a = ( xc[--b] = xc[b] + yc[b] + a ) / BASE | 0; a = ( xc[--b] = xc[b] + yc[b] + a ) / BASE | 0;
xc[b] %= BASE; xc[b] = BASE === xc[b] ? 0 : xc[b] % BASE;
} }
if (a) { if (a) {
xc.unshift(a); xc = [a].concat(xc);
++ye; ++ye;
} }
@ -15590,7 +15686,7 @@ module.exports = XMLHttpRequest;
if (c) { if (c) {
++e; ++e;
} else { } else {
zc.shift(); zc.splice(0, 1);
} }
return normalise( y, zc, e ); return normalise( y, zc, e );
@ -15808,59 +15904,91 @@ module.exports = XMLHttpRequest;
* Return the value of this BigNumber converted to a number primitive. * Return the value of this BigNumber converted to a number primitive.
*/ */
P.toNumber = function () { P.toNumber = function () {
var x = this; return +this;
// Ensure zero has correct sign.
return +x || ( x.s ? x.s * 0 : NaN );
}; };
/* /*
* Return a BigNumber whose value is the value of this BigNumber raised to the power n. * Return a BigNumber whose value is the value of this BigNumber raised to the power n.
* If m is present, return the result modulo m.
* If n is negative round according to DECIMAL_PLACES and ROUNDING_MODE. * If n is negative round according to DECIMAL_PLACES and ROUNDING_MODE.
* If POW_PRECISION is not 0, round to POW_PRECISION using ROUNDING_MODE. * If POW_PRECISION is non-zero and m is not present, round to POW_PRECISION using
* ROUNDING_MODE.
* *
* n {number} Integer, -9007199254740992 to 9007199254740992 inclusive. * The modular power operation works efficiently when x, n, and m are positive integers,
* (Performs 54 loop iterations for n of 9007199254740992.) * otherwise it is equivalent to calculating x.toPower(n).modulo(m) (with POW_PRECISION 0).
*
* n {number} Integer, -MAX_SAFE_INTEGER to MAX_SAFE_INTEGER inclusive.
* [m] {number|string|BigNumber} The modulus.
* *
* 'pow() exponent not an integer: {n}' * 'pow() exponent not an integer: {n}'
* 'pow() exponent out of range: {n}' * 'pow() exponent out of range: {n}'
*
* Performs 54 loop iterations for n of 9007199254740991.
*/ */
P.toPower = P.pow = function (n) { P.toPower = P.pow = function ( n, m ) {
var k, y, var k, y, z,
i = mathfloor( n < 0 ? -n : +n ), i = mathfloor( n < 0 ? -n : +n ),
x = this; x = this;
if ( m != null ) {
id = 23;
m = new BigNumber(m);
}
// Pass ±Infinity to Math.pow if exponent is out of range. // Pass ±Infinity to Math.pow if exponent is out of range.
if ( !isValidInt( n, -MAX_SAFE_INTEGER, MAX_SAFE_INTEGER, 23, 'exponent' ) && if ( !isValidInt( n, -MAX_SAFE_INTEGER, MAX_SAFE_INTEGER, 23, 'exponent' ) &&
( !isFinite(n) || i > MAX_SAFE_INTEGER && ( n /= 0 ) || ( !isFinite(n) || i > MAX_SAFE_INTEGER && ( n /= 0 ) ||
parseFloat(n) != n && !( n = NaN ) ) ) { parseFloat(n) != n && !( n = NaN ) ) || n == 0 ) {
return new BigNumber( Math.pow( +x, n ) ); k = Math.pow( +x, n );
return new BigNumber( m ? k % m : k );
}
if (m) {
if ( n > 1 && x.gt(ONE) && x.isInt() && m.gt(ONE) && m.isInt() ) {
x = x.mod(m);
} else {
z = m;
// Nullify m so only a single mod operation is performed at the end.
m = null;
}
} else if (POW_PRECISION) {
// Truncating each coefficient array to a length of k after each multiplication
// equates to truncating significant digits to POW_PRECISION + [28, 41],
// i.e. there will be a minimum of 28 guard digits retained.
// (Using + 1.5 would give [9, 21] guard digits.)
k = mathceil( POW_PRECISION / LOG_BASE + 2 );
} }
// Truncating each coefficient array to a length of k after each multiplication equates
// to truncating significant digits to POW_PRECISION + [28, 41], i.e. there will be a
// minimum of 28 guard digits retained. (Using + 1.5 would give [9, 21] guard digits.)
k = POW_PRECISION ? mathceil( POW_PRECISION / LOG_BASE + 2 ) : 0;
y = new BigNumber(ONE); y = new BigNumber(ONE);
for ( ; ; ) { for ( ; ; ) {
if ( i % 2 ) { if ( i % 2 ) {
y = y.times(x); y = y.times(x);
if ( !y.c ) break; if ( !y.c ) break;
if ( k && y.c.length > k ) y.c.length = k; if (k) {
if ( y.c.length > k ) y.c.length = k;
} else if (m) {
y = y.mod(m);
}
} }
i = mathfloor( i / 2 ); i = mathfloor( i / 2 );
if ( !i ) break; if ( !i ) break;
x = x.times(x); x = x.times(x);
if ( k && x.c && x.c.length > k ) x.c.length = k; if (k) {
if ( x.c && x.c.length > k ) x.c.length = k;
} else if (m) {
x = x.mod(m);
}
} }
if (m) return y;
if ( n < 0 ) y = ONE.div(y); if ( n < 0 ) y = ONE.div(y);
return k ? round( y, POW_PRECISION, ROUNDING_MODE ) : y;
return z ? y.mod(z) : k ? round( y, POW_PRECISION, ROUNDING_MODE ) : y;
}; };
@ -15938,26 +16066,30 @@ module.exports = XMLHttpRequest;
}; };
/* /*
* Return as toString, but do not accept a base argument. * Return as toString, but do not accept a base argument, and include the minus sign for
* negative zero.
*/ */
P.valueOf = P.toJSON = function () { P.valueOf = P.toJSON = function () {
return this.toString(); var str,
n = this,
e = n.e;
if ( e === null ) return n.toString();
str = coeffToString( n.c );
str = e <= TO_EXP_NEG || e >= TO_EXP_POS
? toExponential( str, e )
: toFixedPoint( str, e );
return n.s < 0 ? '-' + str : str;
}; };
// Aliases for BigDecimal methods. P.isBigNumber = true;
//P.add = P.plus; // P.add included above
//P.subtract = P.minus; // P.sub included above
//P.multiply = P.times; // P.mul included above
//P.divide = P.div;
//P.remainder = P.mod;
//P.compareTo = P.cmp;
//P.negate = P.neg;
if ( config != null ) BigNumber.config(config);
if ( configObj != null ) BigNumber.config(configObj);
return BigNumber; return BigNumber;
} }
@ -16120,24 +16252,26 @@ module.exports = XMLHttpRequest;
// EXPORT // EXPORT
BigNumber = another(); BigNumber = constructorFactory();
BigNumber['default'] = BigNumber.BigNumber = BigNumber;
// AMD. // AMD.
if ( typeof define == 'function' && define.amd ) { if ( typeof define == 'function' && define.amd ) {
define( function () { return BigNumber; } ); define( function () { return BigNumber; } );
// Node and other environments that support module.exports. // Node.js and other environments that support module.exports.
} else if ( typeof module != 'undefined' && module.exports ) { } else if ( typeof module != 'undefined' && module.exports ) {
module.exports = BigNumber; module.exports = BigNumber;
if ( !crypto ) try { crypto = require('crypto'); } catch (e) {}
// Browser. // Browser.
} else { } else {
global.BigNumber = BigNumber; if ( !globalObj ) globalObj = typeof self != 'undefined' ? self : Function('return this')();
globalObj.BigNumber = BigNumber;
} }
})(this); })(this);
},{"crypto":50}],"web3":[function(require,module,exports){ },{}],"web3":[function(require,module,exports){
var Web3 = require('./lib/web3'); var Web3 = require('./lib/web3');
// dont override global variable // dont override global variable

View File

@ -1,13 +1,17 @@
var program = require('commander'); let program = require('commander');
var colors = require('colors'); let colors = require('colors');
var shelljs = require('shelljs'); let shelljs = require('shelljs');
let promptly = require('promptly');
let path = require('path');
const Embark = require('../lib/index');
let embark = new Embark;
var Cmd = function(Embark) { class Cmd {
this.Embark = Embark; constructor() {
program.version(Embark.version); program.version(embark.version);
}; }
Cmd.prototype.process = function(args) { process(args) {
this.newApp(); this.newApp();
this.demo(); this.demo();
this.build(); this.build();
@ -24,46 +28,63 @@ Cmd.prototype.process = function(args) {
} }
program.parse(args); program.parse(args);
}; }
newApp(name) {
let 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');
}
};
Cmd.prototype.newApp = function() {
var self = this;
program program
.command('new [name]') .command('new [name]')
.description('new application') .description('new application')
.action(function(name, options) { .action(function (name) {
if (name === undefined) { if (name === undefined) {
console.log("please specify your app Name".red); return promptly.prompt("Name your app (default is embarkDApp):", {
console.log("e.g embark new MyApp".green); default: "embarkDApp",
console.log("e.g embark new --help for more information".green); validator: validateName
process.exit(code); }, 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
embark.generateTemplate('boilerplate', './', inputvalue);
} }
self.Embark.generateTemplate('boilerplate', './', name);
}); });
}; } else {
embark.generateTemplate('boilerplate', './', name);
}
Cmd.prototype.demo = function() { });
var self = this; }
demo() {
program program
.command('demo') .command('demo')
.description('create a working dapp with a SimpleStorage contract') .description('create a working dapp with a SimpleStorage contract')
.action(function() { .action(function () {
self.Embark.generateTemplate('demo', './', 'embark_demo'); embark.generateTemplate('demo', './', 'embark_demo');
}); });
}; }
Cmd.prototype.build = function() { build() {
var self = this;
program program
.command('build [environment]') .command('build [environment]')
.description('deploy and build dapp at dist/ (default: development)') .description('deploy and build dapp at dist/ (default: development)')
.action(function(env, options) { .action(function (env, options) {
self.Embark.build({env: env || 'development'}); embark.build({env: env || 'development'});
}); });
}; }
Cmd.prototype.run = function() { run() {
var self = this;
program program
.command('run [environment]') .command('run [environment]')
.option('-p, --port [port]', 'port to run the dev webserver (default: 8000)') .option('-p, --port [port]', 'port to run the dev webserver (default: 8000)')
@ -72,8 +93,8 @@ Cmd.prototype.run = function() {
.option('--nodashboard', 'simple mode, disables the dashboard') .option('--nodashboard', 'simple mode, disables the dashboard')
.option('--no-color', 'no colors in case it\'s needed for compatbility purposes') .option('--no-color', 'no colors in case it\'s needed for compatbility purposes')
.description('run dapp (default: development)') .description('run dapp (default: development)')
.action(function(env, options) { .action(function (env, options) {
self.Embark.run({ embark.run({
env: env || 'development', env: env || 'development',
serverPort: options.port, serverPort: options.port,
serverHost: options.host, serverHost: options.host,
@ -81,70 +102,69 @@ Cmd.prototype.run = function() {
useDashboard: !options.nodashboard useDashboard: !options.nodashboard
}); });
}); });
}; }
Cmd.prototype.blockchain = function() { blockchain() {
var self = this;
program program
.command('blockchain [environment]') .command('blockchain [environment]')
.option('-c, --client [client]', 'Use a specific ethereum client or simulator (supported: geth, parity, ethersim, testrpc') .option('-c, --client [client]', 'Use a specific ethereum client or simulator (supported: geth, parity, ethersim, testrpc')
.description('run blockchain server (default: development)') .description('run blockchain server (default: development)')
.action(function(env ,options) { .action(function (env, options) {
self.Embark.initConfig(env || 'development', { embark.initConfig(env || 'development', {
embarkConfig: 'embark.json', embarkConfig: 'embark.json',
interceptLogs: false interceptLogs: false
}); });
self.Embark.blockchain(env || 'development', options.client || 'geth'); embark.blockchain(env || 'development', options.client || 'geth');
}); });
}; }
Cmd.prototype.simulator = function() { simulator() {
var self = this;
program program
.command('simulator [environment]') .command('simulator [environment]')
.description('run a fast ethereum rpc simulator') .description('run a fast ethereum rpc simulator')
.option('--testrpc', 'use testrpc as the rpc simulator [default]') .option('--testrpc', 'use testrpc as the rpc simulator [default]')
.option('-p, --port [port]', 'port to run the rpc simulator (default: 8000)') .option('-p, --port [port]', 'port to run the rpc simulator (default: 8000)')
.option('-h, --host [host]', 'host to run the rpc simulator (default: localhost)') .option('-h, --host [host]', 'host to run the rpc simulator (default: localhost)')
.action(function(env, options) { .action(function (env, options) {
self.Embark.initConfig(env || 'development', { embark.initConfig(env || 'development', {
embarkConfig: 'embark.json', embarkConfig: 'embark.json',
interceptLogs: false interceptLogs: false
}); });
self.Embark.simulator({port: options.port, host: options.host}); embark.simulator({port: options.port, host: options.host});
}); });
}; }
Cmd.prototype.test = function() { test() {
program program
.command('test') .command('test')
.description('run tests') .description('run tests')
.action(function() { .action(function () {
shelljs.exec('mocha test/ --no-timeouts'); shelljs.exec('mocha test');
}); });
}; }
Cmd.prototype.upload = function() { upload() {
var self = this;
program program
.command('upload [platform] [environment]') .command('upload [platform] [environment]')
.description('upload your dapp to a decentralized storage. possible options: ipfs, swarm (e.g embark upload swarm)') .description('upload your dapp to a decentralized storage. possible options: ipfs, swarm (e.g embark upload swarm)')
.action(function(platform, env, options) { .action(function (platform, env, options) {
// TODO: get env in cmd line as well // TODO: get env in cmd line as well
self.Embark.initConfig(env || 'development', { embark.initConfig(env || 'development', {
embarkConfig: 'embark.json', interceptLogs: false embarkConfig: 'embark.json', interceptLogs: false
}); });
self.Embark.upload(platform); embark.upload(platform);
}); });
}; }
Cmd.prototype.otherCommands = function() { otherCommands() {
program program
.action(function(env){ .action(function (env) {
console.log('unknown command "%s"'.red, env); console.log('unknown command "%s"'.red, env);
console.log("type embark --help to see the available commands"); console.log("type embark --help to see the available commands");
process.exit(0); process.exit(0);
}); });
}; }
}
module.exports = Cmd; module.exports = Cmd;

View File

@ -35,9 +35,9 @@ var Blockchain = function(options) {
this.client = new options.client({config: this.config, env: this.env}); this.client = new options.client({config: this.config, env: this.env});
}; };
Blockchain.prototype.runCommand = function(cmd) { Blockchain.prototype.runCommand = function(cmd, options) {
console.log(("running: " + cmd.underline).green); console.log(("running: " + cmd.underline).green);
return shelljs.exec(cmd); return shelljs.exec(cmd, options);
}; };
Blockchain.prototype.run = function() { Blockchain.prototype.run = function() {
@ -49,7 +49,7 @@ Blockchain.prototype.run = function() {
console.log("===============================================================================".magenta); console.log("===============================================================================".magenta);
var address = this.initChainAndGetAddress(); var address = this.initChainAndGetAddress();
this.client.mainCommand(address, function(cmd) { this.client.mainCommand(address, function(cmd) {
self.runCommand(cmd); self.runCommand(cmd, {async: true});
}); });
}; };
@ -65,7 +65,7 @@ Blockchain.prototype.initChainAndGetAddress = function() {
// check if an account already exists, create one if not, return address // check if an account already exists, create one if not, return address
result = this.runCommand(this.client.listAccountsCommand()); result = this.runCommand(this.client.listAccountsCommand());
if (result.output === undefined || result.output === '' || result.output.indexOf("Fatal") >= 0) { if (result.output === undefined || result.output.match(/{(\w+)}/) === null || result.output.indexOf("Fatal") >= 0) {
console.log("no accounts found".green); console.log("no accounts found".green);
if (this.config.genesisBlock) { if (this.config.genesisBlock) {
console.log("initializing genesis block".green); console.log("initializing genesis block".green);

View File

@ -1,16 +1,17 @@
var async = require('async'); let async = require('async');
// TODO: make all of this async // TODO: make all of this async
var GethCommands = function(options) { class GethCommands {
this.config = options.config; constructor(options) {
this.env = options.env || 'development'; this.config = options && options.hasOwnProperty('config') ? options.config : {};
this.env = options && options.hasOwnProperty('env') ? options.env : 'development';
this.name = "Go-Ethereum (https://github.com/ethereum/go-ethereum)"; this.name = "Go-Ethereum (https://github.com/ethereum/go-ethereum)";
this.geth_bin = this.config.geth_bin || "geth"; this.geth_bin = this.config.geth_bin || "geth";
}; }
GethCommands.prototype.commonOptions = function() { commonOptions() {
var config = this.config; let config = this.config;
var cmd = ""; let cmd = "";
cmd += this.determineNetworkType(config); cmd += this.determineNetworkType(config);
@ -31,10 +32,10 @@ GethCommands.prototype.commonOptions = function() {
} }
return cmd; return cmd;
}; }
GethCommands.prototype.determineNetworkType = function(config) { determineNetworkType(config) {
var cmd = ""; let cmd = "";
if (config.networkType === 'testnet') { if (config.networkType === 'testnet') {
cmd += "--testnet "; cmd += "--testnet ";
} else if (config.networkType === 'olympic') { } else if (config.networkType === 'olympic') {
@ -43,29 +44,29 @@ GethCommands.prototype.determineNetworkType = function(config) {
cmd += "--networkid " + config.networkId + " "; cmd += "--networkid " + config.networkId + " ";
} }
return cmd; return cmd;
}; }
GethCommands.prototype.initGenesisCommmand = function() { initGenesisCommmand() {
var config = this.config; let config = this.config;
var cmd = this.geth_bin + " " + this.commonOptions(); let cmd = this.geth_bin + " " + this.commonOptions();
if (config.genesisBlock) { if (config.genesisBlock) {
cmd += "init \"" + config.genesisBlock + "\" "; cmd += "init \"" + config.genesisBlock + "\" ";
} }
return cmd; return cmd;
}; }
GethCommands.prototype.newAccountCommand = function() { newAccountCommand() {
return this.geth_bin + " " + this.commonOptions() + "account new "; return this.geth_bin + " " + this.commonOptions() + "account new ";
}; }
GethCommands.prototype.listAccountsCommand = function() { listAccountsCommand() {
return this.geth_bin + " " + this.commonOptions() + "account list "; return this.geth_bin + " " + this.commonOptions() + "account list ";
}; }
GethCommands.prototype.determineRpcOptions = function(config) { determineRpcOptions(config) {
var cmd = ""; let cmd = "";
cmd += "--port " + config.port + " "; cmd += "--port " + config.port + " ";
cmd += "--rpc "; cmd += "--rpc ";
@ -85,20 +86,20 @@ GethCommands.prototype.determineRpcOptions = function(config) {
} }
return cmd; return cmd;
}; }
GethCommands.prototype.mainCommand = function(address, done) { mainCommand(address, done) {
var self = this; let self = this;
var config = this.config; let config = this.config;
var rpc_api = (this.config.rpcApi || ['eth', 'web3', 'net']); let rpc_api = (this.config.rpcApi || ['eth', 'web3', 'net']);
async.series([ async.series([
function commonOptions(callback) { function commonOptions(callback) {
var cmd = self.commonOptions(); let cmd = self.commonOptions();
callback(null, cmd); callback(null, cmd);
}, },
function rpcOptions(callback) { function rpcOptions(callback) {
var cmd = self.determineRpcOptions(self.config); let cmd = self.determineRpcOptions(self.config);
callback(null, cmd); callback(null, cmd);
}, },
function dontGetPeers(callback) { function dontGetPeers(callback) {
@ -114,7 +115,7 @@ GethCommands.prototype.mainCommand = function(address, done) {
callback(null, ""); callback(null, "");
}, },
function maxPeers(callback) { function maxPeers(callback) {
var cmd = "--maxpeers " + config.maxpeers; let cmd = "--maxpeers " + config.maxpeers;
callback(null, cmd); callback(null, cmd);
}, },
function mining(callback) { function mining(callback) {
@ -140,7 +141,12 @@ GethCommands.prototype.mainCommand = function(address, done) {
callback(null, '--rpcapi "' + rpc_api.join(',') + '"'); callback(null, '--rpcapi "' + rpc_api.join(',') + '"');
}, },
function accountToUnlock(callback) { function accountToUnlock(callback) {
var accountAddress = config.account.address || address; let accountAddress = "";
if(config.hasOwnProperty('address') && config.account.hasOwnProperty('address')) {
accountAddress = config.account.address;
} else {
accountAddress = address;
}
if (accountAddress) { if (accountAddress) {
return callback(null, "--unlock=" + accountAddress); return callback(null, "--unlock=" + accountAddress);
} }
@ -152,13 +158,14 @@ GethCommands.prototype.mainCommand = function(address, done) {
} }
callback(null, ""); callback(null, "");
} }
], function(err, results) { ], function (err, results) {
if (err) { if (err) {
throw new Error(err.message); throw new Error(err.message);
} }
done(self.geth_bin + " " + results.join(" ")); done(self.geth_bin + " " + results.join(" "));
}); });
}; }
}
module.exports = GethCommands; module.exports = GethCommands;

View File

@ -1,18 +1,20 @@
var shelljs = require('shelljs'); let shelljs = require('shelljs');
var Simulator = function(options) { class Simulator {
constructor(options) {
this.blockchainConfig = options.blockchainConfig; this.blockchainConfig = options.blockchainConfig;
}; }
Simulator.prototype.run = function(options) { run(options) {
var cmds = []; let cmds = [];
cmds.push("-p " + (this.blockchainConfig.rpcPort || options.port || 8545)); cmds.push("-p " + (this.blockchainConfig.rpcPort || options.port || 8545));
cmds.push("-h " + (this.blockchainConfig.rpcHost || options.host || 'localhost')); cmds.push("-h " + (this.blockchainConfig.rpcHost || options.host || 'localhost'));
cmds.push("-a " + (options.num || 10)); cmds.push("-a " + (options.num || 10));
shelljs.exec('testrpc ' + cmds.join(' ')); shelljs.exec('testrpc ' + cmds.join(' '), {async : true});
}; }
}
module.exports = Simulator; module.exports = Simulator;

View File

@ -1,32 +1,35 @@
var fs = require('../core/fs.js'); let fs = require('../core/fs.js');
var utils = require('../core/utils.js'); let utils = require('../utils/utils.js');
var TemplateGenerator = function(templateName) { class TemplateGenerator {
constructor(templateName) {
this.templateName = templateName; this.templateName = templateName;
}; }
TemplateGenerator.prototype.generate = function(destinationFolder, name) { generate(destinationFolder, name) {
var templatePath = fs.embarkPath(this.templateName); let templatePath = fs.embarkPath(this.templateName);
console.log('Initializing Embark Template....'.green); console.log('Initializing Embark Template....'.green);
let fspath = utils.joinPath(destinationFolder, name);
fs.copySync(templatePath, destinationFolder + name); fs.copySync(templatePath, fspath);
utils.cd(destinationFolder + name); utils.cd(fspath);
utils.sed('package.json', '%APP_NAME%', name); utils.sed('package.json', '%APP_NAME%', name);
console.log('Installing packages.. this can take a few seconds'.green); console.log('Installing packages.. this can take a few seconds'.green);
utils.runCmd('npm install'); utils.runCmd('npm install');
console.log('Init complete'.green); console.log('Init complete'.green);
console.log('\nApp ready at '.green + destinationFolder + name); console.log('\nApp ready at '.green + fspath);
if (name === 'embark_demo') { if (name === 'embark_demo') {
console.log('-------------------'.yellow); console.log('-------------------'.yellow);
console.log('Next steps:'.green); console.log('Next steps:'.green);
console.log(('-> ' + ('cd ' + destinationFolder + name).bold.cyan).green); console.log(('-> ' + ('cd ' + fspath).bold.cyan).green);
console.log('-> '.green + 'embark blockchain'.bold.cyan + ' or '.green + 'embark simulator'.bold.cyan); console.log('-> '.green + 'embark blockchain'.bold.cyan + ' or '.green + 'embark simulator'.bold.cyan);
console.log('open another console in the same directory and run'.green); console.log('open another console in the same directory and run'.green);
console.log('-> '.green + 'embark run'.bold.cyan); console.log('-> '.green + 'embark run'.bold.cyan);
console.log('For more info go to http://github.com/iurimatias/embark-framework'.green); console.log('For more info go to http://github.com/iurimatias/embark-framework'.green);
} }
}; }
}
module.exports = TemplateGenerator; module.exports = TemplateGenerator;

View File

@ -1,5 +1,5 @@
class ABIGenerator {
var ABIGenerator = function(options) { constructor(options) {
this.blockchainConfig = options.blockchainConfig || {}; this.blockchainConfig = options.blockchainConfig || {};
this.storageConfig = options.storageConfig || {}; this.storageConfig = options.storageConfig || {};
this.communicationConfig = options.communicationConfig || {}; this.communicationConfig = options.communicationConfig || {};
@ -7,20 +7,20 @@ var ABIGenerator = function(options) {
this.rpcHost = options.blockchainConfig && options.blockchainConfig.rpcHost; this.rpcHost = options.blockchainConfig && options.blockchainConfig.rpcHost;
this.rpcPort = options.blockchainConfig && options.blockchainConfig.rpcPort; this.rpcPort = options.blockchainConfig && options.blockchainConfig.rpcPort;
this.plugins = options.plugins; this.plugins = options.plugins;
}; }
ABIGenerator.prototype.generateProvider = function() { generateProvider() {
var self = this; let self = this;
var result = ""; let result = "";
var providerPlugins; let providerPlugins;
if (self.blockchainConfig === {} || self.blockchainConfig.enabled === false) { if (self.blockchainConfig === {} || self.blockchainConfig.enabled === false) {
return ""; return "";
} }
result += "\nvar whenEnvIsLoaded = function(cb) {"; result += "\nvar whenEnvIsLoaded = function(cb) {";
result += "\n if (typeof window !== 'undefined' && window !== null) {"; result += "\n if (typeof document !== 'undefined' && document !== null) {";
result += "\n window.addEventListener('load', cb);"; result += "\n document.addEventListener('DOMContentLoaded', cb);";
result += "\n } else {"; result += "\n } else {";
result += "\n cb();"; result += "\n cb();";
result += "\n }"; result += "\n }";
@ -46,12 +46,12 @@ ABIGenerator.prototype.generateProvider = function() {
} }
return result; return result;
}; }
ABIGenerator.prototype.generateContracts = function(useEmbarkJS) { generateContracts(useEmbarkJS) {
var self = this; let self = this;
var result = "\n"; let result = "\n";
var contractsPlugins; let contractsPlugins;
if (self.blockchainConfig === {} || self.blockchainConfig.enabled === false) { if (self.blockchainConfig === {} || self.blockchainConfig.enabled === false) {
return ""; return "";
@ -62,23 +62,25 @@ ABIGenerator.prototype.generateContracts = function(useEmbarkJS) {
} }
if (this.plugins && contractsPlugins.length > 0) { if (this.plugins && contractsPlugins.length > 0) {
contractsPlugins.forEach(function(plugin) { contractsPlugins.forEach(function (plugin) {
result += plugin.generateContracts({contracts: self.contractsManager.contracts}); result += plugin.generateContracts({contracts: self.contractsManager.contracts});
}); });
} else { } else {
for(var className in this.contractsManager.contracts) { for (let className in this.contractsManager.contracts) {
var contract = this.contractsManager.contracts[className]; let contract = this.contractsManager.contracts[className];
var abi = JSON.stringify(contract.abiDefinition); let abi = JSON.stringify(contract.abiDefinition);
var gasEstimates = JSON.stringify(contract.gasEstimates); let gasEstimates = JSON.stringify(contract.gasEstimates);
// TODO: refactor this // TODO: refactor this
result += "\nvar whenEnvIsLoaded = function(cb) {"; result += "\nif (whenEnvIsLoaded === undefined) {";
result += "\n if (typeof window !== 'undefined' && window !== null) {"; result += "\n var whenEnvIsLoaded = function(cb) {";
result += "\n window.addEventListener('load', cb);"; result += "\n if (typeof document !== 'undefined' && document !== null) {";
result += "\n document.addEventListener('DOMContentLoaded', cb);";
result += "\n } else {"; result += "\n } else {";
result += "\n cb();"; result += "\n cb();";
result += "\n }"; result += "\n }";
result += "\n }";
result += "\n}"; result += "\n}";
result += "\nwhenEnvIsLoaded(function() {"; result += "\nwhenEnvIsLoaded(function() {";
@ -94,11 +96,11 @@ ABIGenerator.prototype.generateContracts = function(useEmbarkJS) {
} }
return result; return result;
}; }
ABIGenerator.prototype.generateStorageInitialization = function(useEmbarkJS) { generateStorageInitialization(useEmbarkJS) {
var self = this; let self = this;
var result = "\n"; let result = "\n";
if (!useEmbarkJS || self.storageConfig === {}) return ""; if (!useEmbarkJS || self.storageConfig === {}) return "";
@ -107,25 +109,29 @@ ABIGenerator.prototype.generateStorageInitialization = function(useEmbarkJS) {
} }
return result; return result;
}; }
ABIGenerator.prototype.generateCommunicationInitialization = function(useEmbarkJS) { generateCommunicationInitialization(useEmbarkJS) {
var self = this; let self = this;
var result = "\n"; let result = "\n";
if (!useEmbarkJS || self.communicationConfig === {}) return ""; if (!useEmbarkJS || self.communicationConfig === {}) return "";
if (self.communicationConfig.provider === 'whisper' && self.communicationConfig.enabled === true) { if (self.communicationConfig.provider === 'whisper' && self.communicationConfig.enabled === true) {
result += "\nEmbarkJS.Messages.setProvider('" + self.communicationConfig.provider + "');"; result += "\nEmbarkJS.Messages.setProvider('" + self.communicationConfig.provider + "');";
} else if (self.communicationConfig.provider === 'orbit' && self.communicationConfig.enabled === true) { } else if (self.communicationConfig.provider === 'orbit' && self.communicationConfig.enabled === true) {
if (self.communicationConfig.host === undefined && self.communicationConfig.port === undefined) {
result += "\nEmbarkJS.Messages.setProvider('" + self.communicationConfig.provider + "');";
} else {
result += "\nEmbarkJS.Messages.setProvider('" + self.communicationConfig.provider + "', {server: '" + self.communicationConfig.host + "', port: '" + self.communicationConfig.port + "'});"; result += "\nEmbarkJS.Messages.setProvider('" + self.communicationConfig.provider + "', {server: '" + self.communicationConfig.host + "', port: '" + self.communicationConfig.port + "'});";
} }
}
return result; return result;
}; }
ABIGenerator.prototype.generateABI = function(options) { generateABI(options) {
var result = ""; let result = "";
result += this.generateProvider(); result += this.generateProvider();
result += this.generateContracts(options.useEmbarkJS); result += this.generateContracts(options.useEmbarkJS);
@ -133,6 +139,32 @@ ABIGenerator.prototype.generateABI = function(options) {
result += this.generateCommunicationInitialization(options.useEmbarkJS); result += this.generateCommunicationInitialization(options.useEmbarkJS);
return result; return result;
}; }
generateContractsJSON() {
let contracts = {};
for (let className in this.contractsManager.contracts) {
let contract = this.contractsManager.contracts[className];
let contractJSON = {};
let abi = JSON.stringify(contract.abiDefinition);
let gasEstimates = JSON.stringify(contract.gasEstimates);
contractJSON.contract_name = className;
contractJSON.code = contract.code;
contractJSON.runtime_bytecode = contract.runtimeBytecode;
contractJSON.real_runtime_bytecode = contract.realRuntimeBytecode;
contractJSON.swarm_hash = contract.swarmHash;
contractJSON.gas_estimates = contract.gasEstimates;
contractJSON.function_hashes = contract.functionHashes;
contractJSON.abi = contract.abiDefinition;
contracts[className] = contractJSON;
}
return contracts;
}
}
module.exports = ABIGenerator; module.exports = ABIGenerator;

View File

@ -1,52 +1,41 @@
/*jshint esversion: 6, loopfunc: true */ /*jshint esversion: 6, loopfunc: true */
var async = require('async'); let async = require('../utils/async_extend.js');
var SolcW = require('./solcW.js'); let SolcW = require('./solcW.js');
function asyncEachObject(object, iterator, callback) { class Compiler {
async.each( constructor(options) {
Object.keys(object || {}),
function(key, next){
iterator(key, object[key], next);
},
callback
);
}
async.eachObject = asyncEachObject;
var Compiler = function(options) {
this.plugins = options.plugins; this.plugins = options.plugins;
this.logger = options.logger; this.logger = options.logger;
}; }
Compiler.prototype.compile_contracts = function(contractFiles, cb) { compile_contracts(contractFiles, cb) {
var self = this;
var available_compilers = { let available_compilers = {
//".se": this.compile_serpent //".se": this.compile_serpent
".sol": this.compile_solidity.bind(this) ".sol": this.compile_solidity.bind(this)
}; };
if (this.plugins) { if (this.plugins) {
var compilerPlugins = this.plugins.getPluginsFor('compilers'); let compilerPlugins = this.plugins.getPluginsFor('compilers');
if (compilerPlugins.length > 0) { if (compilerPlugins.length > 0) {
compilerPlugins.forEach(function(plugin) { compilerPlugins.forEach(function (plugin) {
plugin.compilers.forEach(function(compilerObject) { plugin.compilers.forEach(function (compilerObject) {
available_compilers[compilerObject.extension] = compilerObject.cb; available_compilers[compilerObject.extension] = compilerObject.cb;
}); });
}); });
} }
} }
var compiledObject = {}; let compiledObject = {};
async.eachObject(available_compilers, async.eachObject(available_compilers,
function(extension, compiler, callback) { function (extension, compiler, callback) {
// TODO: warn about files it doesn't know how to compile // TODO: warn about files it doesn't know how to compile
var matchingFiles = contractFiles.filter(function(file) { let matchingFiles = contractFiles.filter(function (file) {
return (file.filename.match(/\.[0-9a-z]+$/)[0] === extension); return (file.filename.match(/\.[0-9a-z]+$/)[0] === extension);
}); });
compiler.call(compiler, matchingFiles || [], function(err, compileResult) { compiler.call(compiler, matchingFiles || [], function (err, compileResult) {
Object.assign(compiledObject, compileResult); Object.assign(compiledObject, compileResult);
callback(err, compileResult); callback(err, compileResult);
}); });
@ -55,17 +44,17 @@ Compiler.prototype.compile_contracts = function(contractFiles, cb) {
cb(err, compiledObject); cb(err, compiledObject);
} }
); );
}; }
Compiler.prototype.compile_solidity = function(contractFiles, cb) { compile_solidity(contractFiles, cb) {
var self = this; let self = this;
var input = {}; let input = {};
var solcW; let solcW;
async.waterfall([ async.waterfall([
function prepareInput(callback) { function prepareInput(callback) {
for (var i = 0; i < contractFiles.length; i++){ for (let i = 0; i < contractFiles.length; i++) {
// TODO: this depends on the config // TODO: this depends on the config
var filename = contractFiles[i].filename.replace('app/contracts/',''); let filename = contractFiles[i].filename.replace('app/contracts/', '');
input[filename] = contractFiles[i].content.toString(); input[filename] = contractFiles[i].content.toString();
} }
callback(); callback();
@ -78,41 +67,49 @@ Compiler.prototype.compile_solidity = function(contractFiles, cb) {
} }
self.logger.info("loading solc compiler.."); self.logger.info("loading solc compiler..");
solcW.load_compiler(function(){ solcW.load_compiler(function () {
callback(); callback();
}); });
}, },
function compileContracts(callback) { function compileContracts(callback) {
self.logger.info("compiling contracts..."); self.logger.info("compiling contracts...");
solcW.compile({sources: input}, 1, function(output) { solcW.compile({sources: input}, 1, function (output) {
if (output.errors) { if (output.errors) {
return callback(new Error ("Solidity errors: " + output.errors).message); return callback(new Error("Solidity errors: " + output.errors).message);
} }
callback(null, output); callback(null, output);
}); });
}, },
function createCompiledObject(output, callback) { function createCompiledObject(output, callback) {
var json = output.contracts; let json = output.contracts;
compiled_object = {}; let compiled_object = {};
for (var className in json) { for (let contractName in json) {
var contract = json[className]; let contract = json[contractName];
// Pull out filename:classname
// [0] filename:classname
// [1] filename
// [2] classname
const regex = /(.*):(.*)/;
const className = contractName.match(regex)[2];
compiled_object[className] = {}; compiled_object[className] = {};
compiled_object[className].code = contract.bytecode; compiled_object[className].code = contract.bytecode;
compiled_object[className].runtimeBytecode = contract.runtimeBytecode; compiled_object[className].runtimeBytecode = contract.runtimeBytecode;
compiled_object[className].realRuntimeBytecode = contract.runtimeBytecode.slice(0, -68); compiled_object[className].realRuntimeBytecode = contract.runtimeBytecode.slice(0, -68);
compiled_object[className].swarmHash = contract.runtimeBytecode.slice(-68).slice(0,64); compiled_object[className].swarmHash = contract.runtimeBytecode.slice(-68).slice(0, 64);
compiled_object[className].gasEstimates = contract.gasEstimates; compiled_object[className].gasEstimates = contract.gasEstimates;
compiled_object[className].functionHashes = contract.functionHashes; compiled_object[className].functionHashes = contract.functionHashes;
compiled_object[className].abiDefinition = JSON.parse(contract.interface); compiled_object[className].abiDefinition = JSON.parse(contract.interface);
} }
callback(null, compiled_object); callback(null, compiled_object);
} }
], function(err, result) { ], function (err, result) {
cb(err, result); cb(err, result);
}); });
}; }
}
module.exports = Compiler; module.exports = Compiler;

View File

@ -1,31 +1,12 @@
var toposort = require('toposort'); let toposort = require('toposort');
var async = require('async'); let async = require('async');
var Compiler = require('./compiler.js'); let Compiler = require('./compiler.js');
// TODO: create a contract object // TODO: create a contract object
var adjustGas = function(contract) { class ContractsManager {
var maxGas, adjustedGas; constructor(options) {
if (contract.gas === 'auto') {
if (contract.deploy || contract.deploy === undefined) {
if (contract.gasEstimates.creation !== undefined) {
// TODO: should sum it instead
maxGas = Math.max(contract.gasEstimates.creation[0], contract.gasEstimates.creation[1], 500000);
} else {
maxGas = 500000;
}
} else {
maxGas = 500000;
}
// TODO: put a check so it doesn't go over the block limit
adjustedGas = Math.round(maxGas * 1.40);
adjustedGas += 25000;
contract.gas = adjustedGas;
}
};
var ContractsManager = function(options) {
this.contractFiles = options.contractFiles; this.contractFiles = options.contractFiles;
this.contractsConfig = options.contractsConfig; this.contractsConfig = options.contractsConfig;
this.contracts = {}; this.contracts = {};
@ -33,21 +14,21 @@ var ContractsManager = function(options) {
this.plugins = options.plugins; this.plugins = options.plugins;
this.contractDependencies = {}; this.contractDependencies = {};
}; }
ContractsManager.prototype.build = function(done) { build(done) {
var self = this; let self = this;
async.waterfall([ async.waterfall([
function compileContracts(callback) { function compileContracts(callback) {
var compiler = new Compiler({plugins: self.plugins, logger: self.logger}); let compiler = new Compiler({plugins: self.plugins, logger: self.logger});
compiler.compile_contracts(self.contractFiles, function(err, compiledObject) { compiler.compile_contracts(self.contractFiles, function (err, compiledObject) {
self.compiledContracts = compiledObject; self.compiledContracts = compiledObject;
callback(err); callback(err);
}); });
}, },
function prepareContractsFromConfig(callback) { function prepareContractsFromConfig(callback) {
var className, contract; let className, contract;
for(className in self.contractsConfig.contracts) { for (className in self.contractsConfig.contracts) {
contract = self.contractsConfig.contracts[className]; contract = self.contractsConfig.contracts[className];
contract.className = className; contract.className = className;
@ -58,16 +39,16 @@ ContractsManager.prototype.build = function(done) {
callback(); callback();
}, },
function setDeployIntention(callback) { function setDeployIntention(callback) {
var className, contract; let className, contract;
for(className in self.contracts) { for (className in self.contracts) {
contract = self.contracts[className]; contract = self.contracts[className];
contract.deploy = (contract.deploy === undefined) || contract.deploy; contract.deploy = (contract.deploy === undefined) || contract.deploy;
} }
callback(); callback();
}, },
function prepareContractsFromCompilation(callback) { function prepareContractsFromCompilation(callback) {
var className, compiledContract, contractConfig, contract; let className, compiledContract, contractConfig, contract;
for(className in self.compiledContracts) { for (className in self.compiledContracts) {
compiledContract = self.compiledContracts[className]; compiledContract = self.compiledContracts[className];
contractConfig = self.contractsConfig.contracts[className]; contractConfig = self.contractsConfig.contracts[className];
@ -82,7 +63,7 @@ ContractsManager.prototype.build = function(done) {
contract.abiDefinition = compiledContract.abiDefinition; contract.abiDefinition = compiledContract.abiDefinition;
contract.gas = (contractConfig && contractConfig.gas) || self.contractsConfig.gas || 'auto'; contract.gas = (contractConfig && contractConfig.gas) || self.contractsConfig.gas || 'auto';
adjustGas(contract); self.adjustGas(contract);
contract.gasPrice = contract.gasPrice || self.contractsConfig.gasPrice; contract.gasPrice = contract.gasPrice || self.contractsConfig.gasPrice;
contract.type = 'file'; contract.type = 'file';
@ -94,12 +75,14 @@ ContractsManager.prototype.build = function(done) {
}, },
/*eslint complexity: ["error", 11]*/ /*eslint complexity: ["error", 11]*/
function dealWithSpecialConfigs(callback) { function dealWithSpecialConfigs(callback) {
var className, contract, parentContractName, parentContract; let className, contract, parentContractName, parentContract;
for(className in self.contracts) { for (className in self.contracts) {
contract = self.contracts[className]; contract = self.contracts[className];
if (contract.instanceOf === undefined) { continue; } if (contract.instanceOf === undefined) {
continue;
}
parentContractName = contract.instanceOf; parentContractName = contract.instanceOf;
parentContract = self.contracts[parentContractName]; parentContract = self.contracts[parentContractName];
@ -136,8 +119,8 @@ ContractsManager.prototype.build = function(done) {
callback(); callback();
}, },
function removeContractsWithNoCode(callback) { function removeContractsWithNoCode(callback) {
var className, contract; let className, contract;
for(className in self.contracts) { for (className in self.contracts) {
contract = self.contracts[className]; contract = self.contracts[className];
if (contract.code === undefined) { if (contract.code === undefined) {
@ -149,15 +132,15 @@ ContractsManager.prototype.build = function(done) {
callback(); callback();
}, },
function determineDependencies(callback) { function determineDependencies(callback) {
var className, contract; let className, contract;
for(className in self.contracts) { for (className in self.contracts) {
contract = self.contracts[className]; contract = self.contracts[className];
if (contract.args === []) continue; if (contract.args === []) continue;
var ref = contract.args; let ref = contract.args;
for (var j = 0; j < ref.length; j++) { for (let j = 0; j < ref.length; j++) {
var arg = ref[j]; let arg = ref[j];
if (arg[0] === "$") { if (arg[0] === "$") {
self.contractDependencies[className] = self.contractDependencies[className] || []; self.contractDependencies[className] = self.contractDependencies[className] || [];
self.contractDependencies[className].push(arg.substr(1)); self.contractDependencies[className].push(arg.substr(1));
@ -166,57 +149,57 @@ ContractsManager.prototype.build = function(done) {
} }
callback(); callback();
} }
], function(err, result) { ], function (err, result) {
if (err) { if (err) {
self.logger.error("Error Compiling/Building contracts: " + err); self.logger.error("Error Compiling/Building contracts: " + err);
} }
self.logger.trace("finished".underline); self.logger.trace("finished".underline);
done(err, self); done(err, self);
}); });
}; }
ContractsManager.prototype.getContract = function(className) { getContract(className) {
return this.contracts[className]; return this.contracts[className];
}; }
ContractsManager.prototype.sortContracts = function(contractList) { sortContracts(contractList) {
var converted_dependencies = [], i; let converted_dependencies = [], i;
for(var contract in this.contractDependencies) { for (let contract in this.contractDependencies) {
var dependencies = this.contractDependencies[contract]; let dependencies = this.contractDependencies[contract];
for(i=0; i < dependencies.length; i++) { for (i = 0; i < dependencies.length; i++) {
converted_dependencies.push([contract, dependencies[i]]); converted_dependencies.push([contract, dependencies[i]]);
} }
} }
var orderedDependencies = toposort(converted_dependencies).reverse(); let orderedDependencies = toposort(converted_dependencies).reverse();
var newList = contractList.sort(function(a,b) { let newList = contractList.sort(function (a, b) {
var order_a = orderedDependencies.indexOf(a.className); let order_a = orderedDependencies.indexOf(a.className);
var order_b = orderedDependencies.indexOf(b.className); let order_b = orderedDependencies.indexOf(b.className);
return order_a - order_b; return order_a - order_b;
}); });
return newList; return newList;
}; }
// TODO: should be built contracts // TODO: should be built contracts
ContractsManager.prototype.listContracts = function() { listContracts() {
var contracts = []; let contracts = [];
for(var className in this.contracts) { for (let className in this.contracts) {
var contract = this.contracts[className]; let contract = this.contracts[className];
contracts.push(contract); contracts.push(contract);
} }
return this.sortContracts(contracts); return this.sortContracts(contracts);
}; }
ContractsManager.prototype.contractsState = function() { contractsState() {
var data = []; let data = [];
for(var className in this.contracts) { for (let className in this.contracts) {
var contract = this.contracts[className]; let contract = this.contracts[className];
var contractData; let contractData;
if (contract.deploy === false) { if (contract.deploy === false) {
contractData = [ contractData = [
@ -242,6 +225,27 @@ ContractsManager.prototype.contractsState = function() {
} }
return data; return data;
}; }
adjustGas(contract) {
let maxGas, adjustedGas;
if (contract.gas === 'auto') {
if (contract.deploy || contract.deploy === undefined) {
if (contract.gasEstimates.creation !== undefined) {
// TODO: should sum it instead
maxGas = Math.max(contract.gasEstimates.creation[0], contract.gasEstimates.creation[1], 500000);
} else {
maxGas = 500000;
}
} else {
maxGas = 500000;
}
// TODO: put a check so it doesn't go over the block limit
adjustedGas = Math.round(maxGas * 1.40);
adjustedGas += 25000;
contract.gas = adjustedGas;
}
}
}
module.exports = ContractsManager; module.exports = ContractsManager;

View File

@ -1,11 +1,12 @@
var async = require('async'); let async = require('async');
var RunCode = require('../core/runCode.js'); let RunCode = require('../core/runCode.js');
var DeployTracker = require('./deploy_tracker.js'); let DeployTracker = require('./deploy_tracker.js');
var ABIGenerator = require('./abi.js'); let ABIGenerator = require('./abi.js');
var Deploy = function(options) { class Deploy {
constructor(options) {
this.web3 = options.web3; this.web3 = options.web3;
this.contractsManager = options.contractsManager; this.contractsManager = options.contractsManager;
this.logger = options.logger; this.logger = options.logger;
@ -14,10 +15,10 @@ var Deploy = function(options) {
this.deployTracker = new DeployTracker({ this.deployTracker = new DeployTracker({
logger: options.logger, chainConfig: options.chainConfig, web3: options.web3, env: this.env logger: options.logger, chainConfig: options.chainConfig, web3: options.web3, env: this.env
}); });
}; }
Deploy.prototype.determineArguments = function(suppliedArgs) { determineArguments(suppliedArgs) {
var realArgs = [], l, arg, contractName, referedContract; let realArgs = [], l, arg, contractName, referedContract;
for (l = 0; l < suppliedArgs.length; l++) { for (l = 0; l < suppliedArgs.length; l++) {
arg = suppliedArgs[l]; arg = suppliedArgs[l];
@ -31,16 +32,16 @@ Deploy.prototype.determineArguments = function(suppliedArgs) {
} }
return realArgs; return realArgs;
}; }
Deploy.prototype.checkAndDeployContract = function(contract, params, callback) { checkAndDeployContract(contract, params, callback) {
var self = this; let self = this;
var suppliedArgs; let suppliedArgs;
var realArgs; let realArgs;
var arg; let arg;
var l; let l;
var contractName; let contractName;
var referedContract; let referedContract;
contract.error = false; contract.error = false;
if (contract.deploy === false) { if (contract.deploy === false) {
@ -59,7 +60,7 @@ Deploy.prototype.checkAndDeployContract = function(contract, params, callback) {
return callback(); return callback();
} }
var trackedContract = self.deployTracker.getContract(contract.className, contract.realRuntimeBytecode, contract.args); let trackedContract = self.deployTracker.getContract(contract.className, contract.realRuntimeBytecode, contract.args);
if (trackedContract && this.web3.eth.getCode(trackedContract.address) !== "0x") { if (trackedContract && this.web3.eth.getCode(trackedContract.address) !== "0x") {
self.logger.info(contract.className.bold.cyan + " already deployed at ".green + trackedContract.address.bold.cyan); self.logger.info(contract.className.bold.cyan + " already deployed at ".green + trackedContract.address.bold.cyan);
@ -70,7 +71,7 @@ Deploy.prototype.checkAndDeployContract = function(contract, params, callback) {
realArgs = self.determineArguments(params || contract.args); realArgs = self.determineArguments(params || contract.args);
this.deployContract(contract, realArgs, function(err, address) { this.deployContract(contract, realArgs, function (err, address) {
if (err) { if (err) {
return callback(new Error(err)); return callback(new Error(err));
} }
@ -80,9 +81,9 @@ Deploy.prototype.checkAndDeployContract = function(contract, params, callback) {
if (contract.onDeploy !== undefined) { if (contract.onDeploy !== undefined) {
self.logger.info('executing onDeploy commands'); self.logger.info('executing onDeploy commands');
var abiGenerator = new ABIGenerator({contractsManager: self.contractsManager}); let abiGenerator = new ABIGenerator({contractsManager: self.contractsManager});
var abi = abiGenerator.generateContracts(false); let abi = abiGenerator.generateContracts(false);
var cmds = contract.onDeploy.join(';\n'); let cmds = contract.onDeploy.join(';\n');
RunCode.doEval(abi + "\n" + cmds, self.web3); RunCode.doEval(abi + "\n" + cmds, self.web3);
} }
@ -91,15 +92,15 @@ Deploy.prototype.checkAndDeployContract = function(contract, params, callback) {
}); });
} }
}; }
Deploy.prototype.deployContract = function(contract, params, callback) { deployContract(contract, params, callback) {
var self = this; let self = this;
var contractObject = this.web3.eth.contract(contract.abiDefinition); let contractObject = this.web3.eth.contract(contract.abiDefinition);
var contractParams = (params || contract.args).slice(); let contractParams = (params || contract.args).slice();
this.web3.eth.getAccounts(function(err, accounts) { this.web3.eth.getAccounts(function (err, accounts) {
if (err) { if (err) {
return callback(new Error(err)); return callback(new Error(err));
} }
@ -116,12 +117,12 @@ Deploy.prototype.deployContract = function(contract, params, callback) {
}); });
self.logger.info("deploying " + contract.className.bold.cyan + " with ".green + contract.gas + " gas".green); self.logger.info("deploying " + contract.className.bold.cyan + " with ".green + contract.gas + " gas".green);
contractParams.push(function(err, transaction) { contractParams.push(function (err, transaction) {
self.logger.contractsState(self.contractsManager.contractsState()); self.logger.contractsState(self.contractsManager.contractsState());
if (err) { if (err) {
self.logger.error("error deploying contract: " + contract.className.cyan); self.logger.error("error deploying contract: " + contract.className.cyan);
var errMsg = err.toString(); let errMsg = err.toString();
if (errMsg === 'Error: The contract code couldn\'t be stored, please check your gas amount.') { if (errMsg === 'Error: The contract code couldn\'t be stored, please check your gas amount.') {
errMsg = 'The contract code couldn\'t be stored, out of gas or constructor error'; errMsg = 'The contract code couldn\'t be stored, out of gas or constructor error';
} }
@ -138,18 +139,18 @@ Deploy.prototype.deployContract = function(contract, params, callback) {
contractObject["new"].apply(contractObject, contractParams); contractObject["new"].apply(contractObject, contractParams);
}); });
}; }
Deploy.prototype.deployAll = function(done) { deployAll(done) {
var self = this; let self = this;
this.logger.info("deploying contracts"); this.logger.info("deploying contracts");
async.eachOfSeries(this.contractsManager.listContracts(), async.eachOfSeries(this.contractsManager.listContracts(),
function(contract, key, callback) { function (contract, key, callback) {
self.logger.trace(arguments); self.logger.trace(arguments);
self.checkAndDeployContract(contract, null, callback); self.checkAndDeployContract(contract, null, callback);
}, },
function(err, results) { function (err, results) {
if (err) { if (err) {
self.logger.error("error deploying contracts"); self.logger.error("error deploying contracts");
self.logger.error(err.message); self.logger.error(err.message);
@ -161,6 +162,7 @@ Deploy.prototype.deployAll = function(done) {
} }
); );
}; }
}
module.exports = Deploy; module.exports = Deploy;

View File

@ -1,31 +1,30 @@
var async = require('async'); let async = require('async');
var Web3 = require('web3'); let Deploy = require('./deploy.js');
let ContractsManager = require('./contracts.js');
var Deploy = require('./deploy.js'); class DeployManager {
var ContractsManager = require('./contracts.js'); constructor(options) {
var DeployManager = function(options) {
this.config = options.config; this.config = options.config;
this.logger = options.logger; this.logger = options.logger;
this.blockchainConfig = this.config.blockchainConfig; this.blockchainConfig = this.config.blockchainConfig;
this.plugins = options.plugins;
this.events = options.events; this.events = options.events;
this.plugins = options.plugins;
this.web3 = options.web3; this.web3 = options.web3;
this.chainConfig = (options.trackContracts !== false) ? this.config.chainTracker : false; this.chainConfig = (options.trackContracts !== false) ? this.config.chainTracker : false;
}; }
DeployManager.prototype.deployContracts = function(done) { deployContracts(done) {
var self = this; let self = this;
if (self.blockchainConfig === {} || self.blockchainConfig.enabled === false) { if (self.blockchainConfig === {} || self.blockchainConfig.enabled === false) {
self.logger.info("Blockchain component is disabled in the config".underline); self.logger.info("Blockchain component is disabled in the config".underline);
self.events.emit('blockchainDisabled', {}); this.events.emit('blockchainDisabled', {});
return done(); return done();
} }
async.waterfall([ async.waterfall([
function buildContracts(callback) { function buildContracts(callback) {
var contractsManager = new ContractsManager({ let contractsManager = new ContractsManager({
contractFiles: self.config.contractsFiles, contractFiles: self.config.contractsFiles,
contractsConfig: self.config.contractsConfig, contractsConfig: self.config.contractsConfig,
logger: self.logger, logger: self.logger,
@ -33,53 +32,59 @@ DeployManager.prototype.deployContracts = function(done) {
}); });
contractsManager.build(callback); contractsManager.build(callback);
}, },
function connectWithWeb3(contractsManager, callback) { function checkWeb3IsConnected(contractsManager, callback) {
var web3; if (!self.web3) {
if (self.web3) { return callback(Error("no web3 instance found"));
web3 = self.web3; }
} else { if (self.web3.currentProvider.isConnected !== undefined && !self.web3.isConnected()) {
web3 = new Web3(); self.logger.error(("Couldn't connect to an Ethereum node are you sure it's on?").red);
var web3Endpoint = 'http://' + self.config.blockchainConfig.rpcHost + ':' + self.config.blockchainConfig.rpcPort; self.logger.info("make sure you have an Ethereum node or simulator running. e.g 'embark blockchain'".magenta);
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")); 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) { function setDefaultAccount(contractsManager, web3, callback) {
web3.eth.getAccounts(function(err, accounts) { web3.eth.getAccounts(function (err, accounts) {
if (err) { if (err) {
return callback(new Error(err)); return callback(new Error(err));
} }
var accountConfig = self.config.blockchainConfig.account; let accountConfig = self.config.blockchainConfig.account;
var selectedAccount = accountConfig && accountConfig.address; let selectedAccount = accountConfig && accountConfig.address;
web3.eth.defaultAccount = (selectedAccount || accounts[0]); web3.eth.defaultAccount = (selectedAccount || accounts[0]);
callback(null, contractsManager, web3); callback(null, contractsManager, web3);
}); });
}, },
function deployAllContracts(contractsManager, web3, callback) { function deployAllContracts(contractsManager, web3, callback) {
var deploy = new Deploy({ let deploy = new Deploy({
web3: web3, web3: web3,
contractsManager: contractsManager, contractsManager: contractsManager,
logger: self.logger, logger: self.logger,
chainConfig: self.chainConfig, chainConfig: self.chainConfig,
env: self.config.env env: self.config.env
}); });
deploy.deployAll(function() { deploy.deployAll(function () {
self.events.emit('contractsDeployed', contractsManager); self.events.emit('contractsDeployed', contractsManager);
callback(null, contractsManager); callback(null, contractsManager);
}); });
} }
], function(err, result) { ], function (err, result) {
if (err) { if (err) {
done(err, null); done(err, null);
} else { } else {
done(null, result); done(null, result);
} }
}); });
}; }
}
module.exports = DeployManager; module.exports = DeployManager;

View File

@ -1,6 +1,7 @@
var fs = require('../core/fs.js'); let fs = require('../core/fs.js');
var DeployTracker = function(options) { class DeployTracker {
constructor(options) {
this.logger = options.logger; this.logger = options.logger;
this.env = options.env; this.env = options.env;
this.chainConfig = options.chainConfig; this.chainConfig = options.chainConfig;
@ -12,8 +13,8 @@ var DeployTracker = function(options) {
} }
// TODO: need to make this async // TODO: need to make this async
var block = this.web3.eth.getBlock(0); let block = this.web3.eth.getBlock(0);
var chainId = block.hash; let chainId = block.hash;
if (this.chainConfig[chainId] === undefined) { if (this.chainConfig[chainId] === undefined) {
this.chainConfig[chainId] = {contracts: {}}; this.chainConfig[chainId] = {contracts: {}};
@ -25,32 +26,37 @@ var DeployTracker = function(options) {
// TODO: add other params // TODO: add other params
//this.currentChain.networkId = ""; //this.currentChain.networkId = "";
//this.currentChain.networkType = "custom" //this.currentChain.networkType = "custom"
}; }
DeployTracker.prototype.loadConfig = function(config) { loadConfig(config) {
this.chainConfig = config; this.chainConfig = config;
return this; return this;
}; }
DeployTracker.prototype.trackContract = function(contractName, code, args, address) { trackContract(contractName, code, args, address) {
this.currentChain.contracts[this.web3.sha3(code + contractName + args.join(','))] = { this.currentChain.contracts[this.web3.sha3(code + contractName + args.join(','))] = {
name: contractName, name: contractName,
address: address address: address
}; };
}; }
DeployTracker.prototype.getContract = function(contractName, code, args) { getContract(contractName, code, args) {
var contract = this.currentChain.contracts[this.web3.sha3(code + contractName + args.join(','))]; let contract = this.currentChain.contracts[this.web3.sha3(code + contractName + args.join(','))];
if (contract && contract.address === undefined) { return false; } if (contract && contract.address === undefined) {
return false;
}
return contract; return contract;
}; }
// TODO: abstract this // TODO: abstract this
// chainConfig can be an abstract PersistentObject // chainConfig can be an abstract PersistentObject
DeployTracker.prototype.save = function() { save() {
if (this.chainConfig === false) { return; } if (this.chainConfig === false) {
fs.writeJSONSync("./chains.json", this.chainConfig); return;
}; }
fs.writeJSONSync("./chains.json", this.chainConfig, {spaces: 2});
}
}
module.exports = DeployTracker; module.exports = DeployTracker;

View File

@ -1,18 +1,18 @@
var solc; let solc;
process.on('message', function(msg) { process.on('message', function (msg) {
if (msg.action === 'loadCompiler') { if (msg.action === 'loadCompiler') {
solc = require('solc'); solc = require('solc');
process.send({result: "loadedCompiler"}); process.send({result: "loadedCompiler"});
} }
if (msg.action === 'compile') { if (msg.action === 'compile') {
var output = solc.compile(msg.obj, msg.optimize); let output = solc.compile(msg.obj, msg.optimize);
process.send({result: "compilation", output: output}); process.send({result: "compilation", output: output});
} }
}); });
process.on('exit', function() { process.on('exit', function () {
process.exit(0); process.exit(0);
}); });

View File

@ -1,14 +1,15 @@
var utils = require('../core/utils.js'); let utils = require('../utils/utils.js');
var solcProcess; let solcProcess;
var compilerLoaded = false; let compilerLoaded = false;
var SolcW = function() { class SolcW {
};
SolcW.prototype.load_compiler = function(done) { load_compiler(done) {
if (compilerLoaded) { done(); } if (compilerLoaded) {
done();
}
solcProcess = require('child_process').fork(utils.joinPath(__dirname, '/solcP.js')); solcProcess = require('child_process').fork(utils.joinPath(__dirname, '/solcP.js'));
solcProcess.once('message', function(msg) { solcProcess.once('message', function (msg) {
if (msg.result !== 'loadedCompiler') { if (msg.result !== 'loadedCompiler') {
return; return;
} }
@ -16,21 +17,22 @@ SolcW.prototype.load_compiler = function(done) {
done(); done();
}); });
solcProcess.send({action: 'loadCompiler'}); solcProcess.send({action: 'loadCompiler'});
}; }
SolcW.prototype.isCompilerLoaded = function() { isCompilerLoaded() {
return (compilerLoaded === true); return (compilerLoaded === true);
}; }
SolcW.prototype.compile = function(obj, optimize, done) { compile(obj, optimize, done) {
solcProcess.once('message', function(msg) { solcProcess.once('message', function (msg) {
if (msg.result !== 'compilation') { if (msg.result !== 'compilation') {
return; return;
} }
done(msg.output); done(msg.output);
}); });
solcProcess.send({action: 'compile', obj: obj, optimize: optimize}); solcProcess.send({action: 'compile', obj: obj, optimize: optimize});
}; }
}
module.exports = SolcW; module.exports = SolcW;

View File

@ -1,6 +1,6 @@
var fs = require('./fs.js'); var fs = require('./fs.js');
var Plugins = require('./plugins.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 // TODO: add wrapper for fs so it can also work in the browser
// can work with both read and save // can work with both read and save

View File

@ -1,5 +1,5 @@
class Core {
var Core = function() {}; }
module.exports = Core; module.exports = Core;

View File

@ -1,44 +1,65 @@
var Events = require('./events.js'); let Web3 = require('web3');
var Logger = require('./logger.js'); let utils = require('../utils/utils.js');
var Config = require('./config.js'); let Events = require('./events.js');
let Logger = require('./logger.js');
let Config = require('./config.js');
let DeployManager = require('../contracts/deploy_manager.js');
let ABIGenerator = require('../contracts/abi.js');
let ServicesMonitor = require('./services_monitor.js');
let Pipeline = require('../pipeline/pipeline.js');
let Server = require('../pipeline/server.js');
let Watch = require('../pipeline/watch.js');
var DeployManager = require('../contracts/deploy_manager.js'); class Engine {
var ABIGenerator = require('../contracts/abi.js'); constructor(options) {
var Dashboard = require('../dashboard/dashboard.js');
var ServicesMonitor = require('./services.js');
var Pipeline = require('../pipeline/pipeline.js');
var Server = require('../pipeline/server.js');
var Watch = require('../pipeline/watch.js');
var Engine = function(options) {
this.env = options.env; this.env = options.env;
this.embarkConfig = options.embarkConfig; this.embarkConfig = options.embarkConfig;
this.interceptLogs = options.interceptLogs; this.interceptLogs = options.interceptLogs;
this.version = "2.4.2"; this.version = options.version;
}; }
Engine.prototype.init = function(_options) { init(_options) {
var options = _options || {}; let self = this;
let options = _options || {};
this.events = new Events(); this.events = new Events();
this.logger = options.logger || new Logger({logLevel: 'debug'}); this.logger = options.logger || new Logger({logLevel: options.logLevel || 'debug'});
this.config = new Config({env: this.env, logger: this.logger, events: this.events}); this.config = new Config({env: this.env, logger: this.logger, events: this.events});
this.config.loadConfigFiles({embarkConfig: this.embarkConfig, interceptLogs: this.interceptLogs}); this.config.loadConfigFiles({embarkConfig: this.embarkConfig, interceptLogs: this.interceptLogs});
this.plugins = this.config.plugins; this.plugins = this.config.plugins;
};
Engine.prototype.startService = function(serviceName, _options) { this.servicesMonitor = new ServicesMonitor({events: this.events, logger: this.logger});
var options = _options || {}; this.servicesMonitor.addCheck('embarkVersion', function (cb) {
return cb({name: 'Embark ' + self.version, status: 'on'});
}, 0);
}
var services = { startMonitor() {
"monitor": this.monitorService, let self = this;
if (this.plugins) {
let 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();
}
startService(serviceName, _options) {
let options = _options || {};
let services = {
"pipeline": this.pipelineService, "pipeline": this.pipelineService,
"abi": this.abiService, "abi": this.abiService,
"deployment": this.deploymentService, "deployment": this.deploymentService,
"fileWatcher": this.fileWatchService, "fileWatcher": this.fileWatchService,
"webServer": this.webServerService "webServer": this.webServerService,
"ipfs": this.ipfsService,
"web3": this.web3Service
}; };
var service = services[serviceName]; let service = services[serviceName];
if (!service) { if (!service) {
throw new Error("unknown service: " + serviceName); throw new Error("unknown service: " + serviceName);
@ -47,33 +68,22 @@ Engine.prototype.startService = function(serviceName, _options) {
// need to be careful with circular references due to passing the web3 object // need to be careful with circular references due to passing the web3 object
//this.logger.trace("calling: " + serviceName + "(" + JSON.stringify(options) + ")"); //this.logger.trace("calling: " + serviceName + "(" + JSON.stringify(options) + ")");
return service.apply(this, [options]); return service.apply(this, [options]);
}; }
Engine.prototype.monitorService = function(options) { pipelineService(options) {
var servicesMonitor = new ServicesMonitor({ let self = this;
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"); this.logger.setStatus("Building Assets");
var pipeline = new Pipeline({ let pipeline = new Pipeline({
buildDir: this.config.buildDir, buildDir: this.config.buildDir,
contractsFiles: this.config.contractsFiles, contractsFiles: this.config.contractsFiles,
assetFiles: this.config.assetFiles, assetFiles: this.config.assetFiles,
logger: this.logger, logger: this.logger,
plugins: this.plugins plugins: this.plugins
}); });
this.events.on('abi', function(abi) { this.events.on('abi', function (abi, contractsJSON) {
self.currentAbi = abi; self.currentAbi = abi;
pipeline.build(abi); self.contractsJSON = contractsJSON;
pipeline.build(abi, contractsJSON);
self.events.emit('outputDone'); self.events.emit('outputDone');
}); });
// TODO: still need to redeploy contracts because the original contracts // TODO: still need to redeploy contracts because the original contracts
@ -81,38 +91,39 @@ Engine.prototype.pipelineService = function(options) {
//this.events.on('file-event', function(fileType, path) { //this.events.on('file-event', function(fileType, path) {
// if (fileType === 'asset') { // if (fileType === 'asset') {
// self.config.reloadConfig(); // self.config.reloadConfig();
// pipeline.build(self.abi, path); // pipeline.build(self.abi, self.contractsJSON, path);
// self.events.emit('outputDone'); // self.events.emit('outputDone');
// } // }
//}); //});
}; }
Engine.prototype.abiService = function(options) { abiService(options) {
var self = this; let self = this;
var generateABICode = function(contractsManager) { let generateABICode = function (contractsManager) {
var abiGenerator = new ABIGenerator({ let abiGenerator = new ABIGenerator({
blockchainConfig: self.config.blockchainConfig, blockchainConfig: self.config.blockchainConfig,
contractsManager: contractsManager, contractsManager: contractsManager,
plugins: self.plugins, plugins: self.plugins,
storageConfig: self.config.storageConfig, storageConfig: self.config.storageConfig,
communicationConfig: self.config.communicationConfig communicationConfig: self.config.communicationConfig
}); });
var embarkJSABI = abiGenerator.generateABI({useEmbarkJS: true}); let embarkJSABI = abiGenerator.generateABI({useEmbarkJS: true});
var vanillaABI = abiGenerator.generateABI({useEmbarkJS: false}); let vanillaABI = abiGenerator.generateABI({useEmbarkJS: false});
var vanillaContractsABI = abiGenerator.generateContracts(false); let vanillaContractsABI = abiGenerator.generateContracts(false);
let contractsJSON = abiGenerator.generateContractsJSON();
self.events.emit('abi-contracts-vanila', vanillaContractsABI); self.events.emit('abi-contracts-vanila', vanillaContractsABI, contractsJSON);
self.events.emit('abi-vanila', vanillaABI); self.events.emit('abi-vanila', vanillaABI, contractsJSON);
self.events.emit('abi', embarkJSABI); self.events.emit('abi', embarkJSABI, contractsJSON);
}; };
this.events.on('contractsDeployed', generateABICode); this.events.on('contractsDeployed', generateABICode);
this.events.on('blockchainDisabled', generateABICode); this.events.on('blockchainDisabled', generateABICode);
}; }
Engine.prototype.deploymentService = function(options) { deploymentService(options) {
var self = this; let self = this;
this.deployManager = new DeployManager({ this.deployManager = new DeployManager({
web3: options.web3, web3: options.web3 || self.web3,
trackContracts: options.trackContracts, trackContracts: options.trackContracts,
config: this.config, config: this.config,
logger: this.logger, logger: this.logger,
@ -120,32 +131,121 @@ Engine.prototype.deploymentService = function(options) {
events: this.events events: this.events
}); });
this.events.on('file-event', function(fileType, path) { this.events.on('file-event', function (fileType, path) {
// TODO: for now need to deploy on asset chanes as well // TODO: for now need to deploy on asset chanes as well
// because the contractsManager config is corrupted after a deploy // because the contractsManager config is corrupted after a deploy
//if (fileType === 'contract' || fileType === 'config') { //if (fileType === 'contract' || fileType === 'config') {
self.config.reloadConfig(); self.config.reloadConfig();
self.deployManager.deployContracts(function() {}); self.deployManager.deployContracts(function () {
});
//} //}
}); });
}; }
Engine.prototype.fileWatchService = function(options) { fileWatchService(options) {
this.logger.setStatus("Watching for changes"); this.logger.setStatus("Watching for changes");
var watch = new Watch({logger: this.logger, events: this.events}); let watch = new Watch({logger: this.logger, events: this.events});
watch.start(); watch.start();
}; }
webServerService(options) {
let self = this;
let webServerConfig = this.config.webServerConfig;
if (!webServerConfig.enabled) {
return;
}
let host = options.host || webServerConfig.host;
let port = options.port || webServerConfig.port;
Engine.prototype.webServerService = function(options) {
var webServerConfig = this.config.webServerConfig;
if (!webServerConfig.enabled) { return; }
this.logger.setStatus("Starting Server"); this.logger.setStatus("Starting Server");
var server = new Server({ let server = new Server({
logger: this.logger, logger: this.logger,
host: options.host || webServerConfig.host, host: host,
port: options.port || webServerConfig.port port: port
}); });
server.start(function(){});
}; self.servicesMonitor.addCheck('Webserver', function (cb) {
let devServer = 'Webserver (http://' + host + ':' + port + ')';
return cb({name: devServer, status: 'on'});
});
server.start(function () {
});
}
ipfsService(options) {
let 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...");
utils.httpGet('http://localhost:5001/api/v0/version', function (res) {
let body = '';
res.on('data', function (d) {
body += d;
});
res.on('end', function () {
try {
let parsed = JSON.parse(body);
if (parsed.Version) {
return cb({name: ("IPFS " + parsed.Version), status: 'on'});
}
else {
return cb({name: "IPFS ", status: 'on'});
}
}
catch (e) {
return cb({name: "IPFS ", status: 'off'});
}
});
res.on('error', function (err) {
self.logger.trace("Check IPFS version error: " + err);
return cb({name: "IPFS ", status: 'off'});
});
});
}
else {
return cb({name: "IPFS ", status: 'off'});
}
});
});
}
web3Service(options) {
let self = this;
this.web3 = options.web3;
if (this.web3 === undefined) {
this.web3 = new Web3();
let 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: 'on'
});
} else {
return cb({name: "No Blockchain node found", status: 'off'});
}
});
self.servicesMonitor.addCheck('Whisper', function (cb) {
self.web3.version.getWhisper(function (err, version) {
if (err) {
return cb({name: 'Whisper', status: 'off'});
} else if (version >= 5) {
return cb({name: 'Whisper (version ' + version + ') - unsupported', status: 'warn'});
} else {
return cb({name: 'Whisper (version ' + version + ')', status: 'on'});
}
});
});
}
}
module.exports = Engine; module.exports = Engine;

View File

@ -1,5 +1,5 @@
var fs = require('fs-extra'); let fs = require('fs-extra');
var utils = require('./utils.js'); let utils = require('../utils/utils.js');
function mkdirpSync() { function mkdirpSync() {
return fs.mkdirpSync.apply(fs.mkdirpSync, arguments); return fs.mkdirpSync.apply(fs.mkdirpSync, arguments);
@ -25,7 +25,7 @@ function writeJSONSync() {
return fs.writeJSONSync.apply(fs.writeJSONSync, arguments); return fs.writeJSONSync.apply(fs.writeJSONSync, arguments);
} }
function existsSync(){ function existsSync() {
return fs.existsSync.apply(fs.existsSync, arguments); return fs.existsSync.apply(fs.existsSync, arguments);
} }

View File

@ -1,40 +1,52 @@
var colors = require('colors'); let colors = require('colors');
var Logger = function(options) { class Logger {
constructor(options) {
this.logLevels = ['error', 'warn', 'info', 'debug', 'trace']; this.logLevels = ['error', 'warn', 'info', 'debug', 'trace'];
this.logLevel = options.logLevel || 'info'; this.logLevel = options.logLevel || 'info';
this.logFunction = options.logFunction || console.log; this.logFunction = options.logFunction || console.log;
this.contractsState = options.contractsState || function() {}; this.contractsState = options.contractsState || function () {
this.availableServices = options.availableServices || function() {}; };
this.setStatus = options.setStatus || console.log; this.setStatus = options.setStatus || console.log;
}; }
}
Logger.prototype.error = function(txt) { Logger.prototype.error = function (txt) {
if (!(this.shouldLog('error'))) { return; } if (!txt || !(this.shouldLog('error'))) {
return;
}
this.logFunction(txt.red); this.logFunction(txt.red);
}; };
Logger.prototype.warn = function(txt) { Logger.prototype.warn = function (txt) {
if (!(this.shouldLog('warn'))) { return; } if (!txt || !(this.shouldLog('warn'))) {
return;
}
this.logFunction(txt.yellow); this.logFunction(txt.yellow);
}; };
Logger.prototype.info = function(txt) { Logger.prototype.info = function (txt) {
if (!(this.shouldLog('info'))) { return; } if (!txt || !(this.shouldLog('info'))) {
return;
}
this.logFunction(txt.green); this.logFunction(txt.green);
}; };
Logger.prototype.debug = function(txt) { Logger.prototype.debug = function (txt) {
if (!(this.shouldLog('debug'))) { return; } if (!txt || !(this.shouldLog('debug'))) {
return;
}
this.logFunction(txt); this.logFunction(txt);
}; };
Logger.prototype.trace = function(txt) { Logger.prototype.trace = function (txt) {
if (!(this.shouldLog('trace'))) { return; } if (!txt || !(this.shouldLog('trace'))) {
return;
}
this.logFunction(txt); this.logFunction(txt);
}; };
Logger.prototype.shouldLog = function(level) { Logger.prototype.shouldLog = function (level) {
return (this.logLevels.indexOf(level) <= this.logLevels.indexOf(this.logLevel)); return (this.logLevels.indexOf(level) <= this.logLevels.indexOf(this.logLevel));
}; };

View File

@ -1,6 +1,6 @@
/*jshint esversion: 6, loopfunc: true */ /*jshint esversion: 6, loopfunc: true */
var fs = require('./fs.js'); 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.. // TODO: pass other params like blockchainConfig, contract files, etc..
var Plugin = function(options) { var Plugin = function(options) {
@ -17,6 +17,7 @@ var Plugin = function(options) {
this.contractsConfigs = []; this.contractsConfigs = [];
this.contractsFiles = []; this.contractsFiles = [];
this.compilers = []; this.compilers = [];
this.serviceChecks = [];
this.pluginTypes = []; this.pluginTypes = [];
this.logger = options.logger; this.logger = options.logger;
this.events = options.events; this.events = options.events;
@ -98,6 +99,11 @@ Plugin.prototype.registerConsoleCommand = function(cb) {
this.pluginTypes.push('console'); 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) { Plugin.prototype.has = function(pluginType) {
return this.pluginTypes.indexOf(pluginType) >= 0; return this.pluginTypes.indexOf(pluginType) >= 0;
}; };

View File

@ -1,5 +1,5 @@
var Plugin = require('./plugin.js'); var Plugin = require('./plugin.js');
var utils = require('./utils.js'); var utils = require('../utils/utils.js');
var Plugins = function(options) { var Plugins = function(options) {
this.pluginList = options.plugins || []; this.pluginList = options.plugins || [];

View File

@ -1,5 +1,5 @@
var Web3 = require('web3'); let Web3 = require('web3');
var web3; let web3;
// ====================== // ======================
// the eval is used for evaluating some of the contact calls for different purposes // the eval is used for evaluating some of the contact calls for different purposes

View File

@ -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;

View File

@ -0,0 +1,80 @@
let async = require('../utils/async_extend.js');
class ServicesMonitor {
constructor(options) {
this.events = options.events;
this.logger = options.logger;
this.checkList = {};
this.checkTimers = {};
this.checkState = {};
this.working = false;
}
}
ServicesMonitor.prototype.initCheck = function (checkName) {
let self = this;
let check = this.checkList[checkName];
if (!check) {
return false;
}
self.events.on('check:' + checkName, function (obj) {
if (check && check.status === 'off' && obj.status === 'on') {
self.events.emit('check:backOnline:' + checkName);
}
if (check && check.status === 'on' && obj.status === 'off') {
self.events.emit('check:wentOffline:' + checkName);
}
self.checkState[checkName] = {name: obj.name, status: 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) {
let 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 () {
let 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;

View File

@ -12,6 +12,7 @@ var Deploy = require('../contracts/deploy.js');
var Config = require('./config.js'); var Config = require('./config.js');
var RunCode = require('./runCode.js'); var RunCode = require('./runCode.js');
var TestLogger = require('./test_logger.js'); var TestLogger = require('./test_logger.js');
var web3;
var getSimulator = function() { var getSimulator = function() {
try { try {
@ -45,7 +46,7 @@ var Test = function(options) {
}); });
this.engine.init({ this.engine.init({
logger: new TestLogger({logLevel: this.options.logLevel || 'debug'}) logger: new TestLogger({logLevel: 'debug'})
}); });
this.sim = getSimulator(); this.sim = getSimulator();

View File

@ -1,52 +1,65 @@
var colors = require('colors'); let colors = require('colors');
// TODO: just logFunction changes, probably doesn't need a whole new module just // TODO: just logFunction changes, probably doesn't need a whole new module just
// for this // for this
var TestLogger = function(options) { class TestLogger {
constructor(options) {
this.logLevels = ['error', 'warn', 'info', 'debug', 'trace']; this.logLevels = ['error', 'warn', 'info', 'debug', 'trace'];
this.logs = []; this.logs = [];
this.logLevel = options.logLevel || 'info'; this.logLevel = options.logLevel || 'info';
}; }
TestLogger.prototype.logFunction = function() { logFunction() {
this.logs.push(arguments); this.logs.push(arguments);
}; }
TestLogger.prototype.contractsState = function() { contractsState() {
this.logs.push(arguments); this.logs.push(arguments);
}; }
TestLogger.prototype.availableServices = function() { availableServices() {
this.logs.push(arguments); this.logs.push(arguments);
}; }
TestLogger.prototype.error = function(txt) { error(txt) {
if (!(this.shouldLog('error'))) { return; } if (!(this.shouldLog('error'))) {
return;
}
this.logFunction(txt.red); this.logFunction(txt.red);
}; }
TestLogger.prototype.warn = function(txt) { warn(txt) {
if (!(this.shouldLog('warn'))) { return; } if (!(this.shouldLog('warn'))) {
return;
}
this.logFunction(txt.yellow); this.logFunction(txt.yellow);
}; }
TestLogger.prototype.info = function(txt) { info(txt) {
if (!(this.shouldLog('info'))) { return; } if (!(this.shouldLog('info'))) {
return;
}
this.logFunction(txt.green); this.logFunction(txt.green);
}; }
TestLogger.prototype.debug = function(txt) { debug(txt) {
if (!(this.shouldLog('debug'))) { return; } if (!(this.shouldLog('debug'))) {
return;
}
this.logFunction(txt); this.logFunction(txt);
}; }
TestLogger.prototype.trace = function(txt) { trace(txt) {
if (!(this.shouldLog('trace'))) { return; } if (!(this.shouldLog('trace'))) {
return;
}
this.logFunction(txt); this.logFunction(txt);
}; }
TestLogger.prototype.shouldLog = function(level) { shouldLog(level) {
return (this.logLevels.indexOf(level) <= this.logLevels.indexOf(this.logLevel)); return (this.logLevels.indexOf(level) <= this.logLevels.indexOf(this.logLevel));
}; }
}
module.exports = TestLogger; module.exports = TestLogger;

View File

@ -1,28 +1,29 @@
class CommandHistory {
var CommandHistory = function() { constructor() {
this.history = []; this.history = [];
this.pointer = -1; this.pointer = -1;
}; }
CommandHistory.prototype.addCommand = function(cmd) { addCommand(cmd) {
this.history.push(cmd); this.history.push(cmd);
this.pointer = this.history.length; this.pointer = this.history.length;
}; }
CommandHistory.prototype.getPreviousCommand = function(cmd) { getPreviousCommand(cmd) {
if (this.pointer >= 0) { if (this.pointer >= 0) {
this.pointer--; this.pointer--;
} }
return this.history[this.pointer]; return this.history[this.pointer];
}; }
CommandHistory.prototype.getNextCommand = function(cmd) { getNextCommand(cmd) {
if (this.pointer >= this.history.length) { if (this.pointer >= this.history.length) {
this.pointer = this.history.length - 1; this.pointer = this.history.length - 1;
return ''; return '';
} }
this.pointer++; this.pointer++;
return this.history[this.pointer]; return this.history[this.pointer];
}; }
}
module.exports = CommandHistory; module.exports = CommandHistory;

View File

@ -1,18 +1,19 @@
var utils = require('../core/utils.js'); let utils = require('../utils/utils.js');
var RunCode = require('../core/runCode.js'); let RunCode = require('../core/runCode.js');
var Console = function(options) { class Console {
constructor(options) {
this.plugins = options.plugins; this.plugins = options.plugins;
this.version = options.version; this.version = options.version;
}; }
Console.prototype.runCode = function(code) { runCode(code) {
RunCode.doEval(code); // jshint ignore:line RunCode.doEval(code); // jshint ignore:line
}; }
Console.prototype.processEmbarkCmd = function(cmd) { processEmbarkCmd (cmd) {
if (cmd === 'help') { if (cmd === 'help') {
var helpText = [ let helpText = [
'Welcome to Embark ' + this.version, 'Welcome to Embark ' + this.version,
'', '',
'possible commands are:', 'possible commands are:',
@ -28,9 +29,9 @@ Console.prototype.processEmbarkCmd = function(cmd) {
utils.exit(); utils.exit();
} }
return false; return false;
}; }
Console.prototype.executeCmd = function(cmd, callback) { executeCmd(cmd, callback) {
var plugin, pluginOutput; var plugin, pluginOutput;
var plugins = this.plugins.getPluginsFor('console'); var plugins = this.plugins.getPluginsFor('console');
for (var i = 0; i < plugins.length; i++) { for (var i = 0; i < plugins.length; i++) {
@ -39,22 +40,23 @@ Console.prototype.executeCmd = function(cmd, callback) {
if (pluginOutput !== false && pluginOutput !== 'false') return callback(pluginOutput); if (pluginOutput !== false && pluginOutput !== 'false') return callback(pluginOutput);
} }
var output = this.processEmbarkCmd(cmd); let output = this.processEmbarkCmd(cmd);
if (output) { if (output) {
return callback(output); return callback(output);
} }
try { try {
var result = RunCode.doEval(cmd); let result = RunCode.doEval(cmd);
return callback(result); return callback(result);
} }
catch(e) { catch (e) {
if (e.message.indexOf('not defined') > 0) { if (e.message.indexOf('not defined') > 0) {
return callback(("error: " + e.message).red + ("\nType " + "help".bold + " to see the list of available commands").cyan); return callback(("error: " + e.message).red + ("\nType " + "help".bold + " to see the list of available commands").cyan);
} else { } else {
return callback(e.message); return callback(e.message);
} }
} }
}; }
}
module.exports = Console; module.exports = Console;

View File

@ -1,18 +1,19 @@
var async = require('async'); let async = require('async');
var Monitor = require('./monitor.js'); let Monitor = require('./monitor.js');
var Console = require('./console.js'); let Console = require('./console.js');
var Dashboard = function(options) { class Dashboard {
constructor(options) {
this.logger = options.logger; this.logger = options.logger;
this.plugins = options.plugins; this.plugins = options.plugins;
this.version = options.version; this.version = options.version;
this.env = options.env; this.env = options.env;
}; }
Dashboard.prototype.start = function(done) { start(done) {
var console, monitor; let console, monitor;
var self = this; let self = this;
async.waterfall([ async.waterfall([
function startConsole(callback) { function startConsole(callback) {
@ -23,7 +24,6 @@ Dashboard.prototype.start = function(done) {
monitor = new Monitor({env: self.env, console: console}); monitor = new Monitor({env: self.env, console: console});
self.logger.logFunction = monitor.logEntry; self.logger.logFunction = monitor.logEntry;
self.logger.contractsState = monitor.setContracts; self.logger.contractsState = monitor.setContracts;
self.logger.availableServices = monitor.availableServices;
self.logger.setStatus = monitor.setStatus.bind(monitor); self.logger.setStatus = monitor.setStatus.bind(monitor);
self.logger.info('========================'.bold.green); self.logger.info('========================'.bold.green);
@ -33,11 +33,13 @@ Dashboard.prototype.start = function(done) {
// TODO: do this after monitor is rendered // TODO: do this after monitor is rendered
callback(); callback();
} }
], function() { ], function () {
self.console = console; self.console = console;
self.monitor = monitor; self.monitor = monitor;
done(); done();
}); });
}; }
}
module.exports = Dashboard; module.exports = Dashboard;

View File

@ -1,10 +1,11 @@
/*jshint esversion: 6 */ /*jshint esversion: 6 */
var blessed = require("blessed"); let blessed = require("blessed");
var CommandHistory = require('./command_history.js'); let CommandHistory = require('./command_history.js');
function Dashboard(options) { class Dashboard {
var title = (options && options.title) || "Embark 2.4.2"; constructor(options) {
let title = (options && options.title) || "Embark " + options.version;
this.env = options.env; this.env = options.env;
this.console = options.console; this.console = options.console;
this.history = new CommandHistory(); this.history = new CommandHistory();
@ -25,7 +26,7 @@ function Dashboard(options) {
this.layoutModules(); this.layoutModules();
this.layoutCmd(); this.layoutCmd();
this.screen.key(["C-c"], function() { this.screen.key(["C-c"], function () {
process.exit(0); process.exit(0);
}); });
@ -37,37 +38,52 @@ function Dashboard(options) {
this.screen.render(); this.screen.render();
this.input.focus(); this.input.focus();
} }
availableServices(_services) {
let services = [];
let check;
for (check in _services) {
let checkObj = _services[check];
if (checkObj.status === 'on') {
services.push(checkObj.name.green);
} else if (checkObj.status === 'off') {
services.push(checkObj.name.red);
} else if (checkObj.status === 'warn') {
services.push(checkObj.name.grey);
} else {
services.push(checkObj.name);
}
}
Dashboard.prototype.availableServices = function(services) {
this.progress.setContent(services.join('\n')); this.progress.setContent(services.join('\n'));
this.screen.render(); this.screen.render();
}; }
Dashboard.prototype.setStatus = function(status) { setStatus(status) {
this.operations.setContent(status); this.operations.setContent(status);
this.screen.render(); this.screen.render();
}; }
Dashboard.prototype.setContracts = function(contracts) { setContracts(contracts) {
var data = []; let data = [];
data.push(["Contract Name", "Address", "Status"]); data.push(["Contract Name", "Address", "Status"]);
contracts.forEach(function(row) { contracts.forEach(function (row) {
data.push(row); data.push(row);
}); });
this.moduleTable.setData(data); this.moduleTable.setData(data);
this.screen.render(); this.screen.render();
}; }
Dashboard.prototype.logEntry = function(text) { logEntry(text) {
this.logText.log(text); this.logText.log(text);
this.screen.render(); this.screen.render();
}; }
Dashboard.prototype.layoutLog = function() { layoutLog() {
this.log = blessed.box({ this.log = blessed.box({
label: "Logs", label: "Logs",
padding: 1, padding: 1,
@ -104,9 +120,9 @@ Dashboard.prototype.layoutLog = function() {
}); });
this.screen.append(this.log); this.screen.append(this.log);
}; }
Dashboard.prototype.layoutModules = function() { layoutModules() {
this.modules = blessed.box({ this.modules = blessed.box({
label: "Contracts", label: "Contracts",
tags: true, tags: true,
@ -147,9 +163,9 @@ Dashboard.prototype.layoutModules = function() {
}); });
this.screen.append(this.modules); this.screen.append(this.modules);
}; }
Dashboard.prototype.layoutAssets = function() { layoutAssets() {
this.assets = blessed.box({ this.assets = blessed.box({
label: "Asset Pipeline", label: "Asset Pipeline",
tags: true, tags: true,
@ -188,9 +204,9 @@ Dashboard.prototype.layoutAssets = function() {
}); });
this.screen.append(this.assets); this.screen.append(this.assets);
}; }
Dashboard.prototype.layoutStatus = function() { layoutStatus() {
this.wrapper = blessed.layout({ this.wrapper = blessed.layout({
width: "25%", width: "25%",
@ -264,10 +280,9 @@ Dashboard.prototype.layoutStatus = function() {
}); });
this.screen.append(this.wrapper); this.screen.append(this.wrapper);
}; }
layoutCmd() {
Dashboard.prototype.layoutCmd = function() {
this.consoleBox = blessed.box({ this.consoleBox = blessed.box({
label: 'Console', label: 'Console',
tags: true, tags: true,
@ -307,34 +322,34 @@ Dashboard.prototype.layoutCmd = function() {
} }
}); });
var self = this; let self = this;
this.input.key(["C-c"], function() { this.input.key(["C-c"], function () {
process.exit(0); process.exit(0);
}); });
this.input.key(["C-w"], function() { this.input.key(["C-w"], function () {
self.input.clearValue(); self.input.clearValue();
self.input.focus(); self.input.focus();
}); });
this.input.key(["up"], function() { this.input.key(["up"], function () {
var cmd = self.history.getPreviousCommand(); let cmd = self.history.getPreviousCommand();
self.input.setValue(cmd); self.input.setValue(cmd);
self.input.focus(); self.input.focus();
}); });
this.input.key(["down"], function() { this.input.key(["down"], function () {
var cmd = self.history.getNextCommand(); let cmd = self.history.getNextCommand();
self.input.setValue(cmd); self.input.setValue(cmd);
self.input.focus(); self.input.focus();
}); });
this.input.on('submit', function(data) { this.input.on('submit', function (data) {
if (data !== '') { if (data !== '') {
self.history.addCommand(data); self.history.addCommand(data);
self.logText.log('console> '.bold.green + data); self.logText.log('console> '.bold.green + data);
self.console.executeCmd(data, function(result) { self.console.executeCmd(data, function (result) {
self.logText.log(result); self.logText.log(result);
}); });
} }
@ -343,6 +358,8 @@ Dashboard.prototype.layoutCmd = function() {
}); });
this.screen.append(this.consoleBox); this.screen.append(this.consoleBox);
}; }
}
module.exports = Dashboard; module.exports = Dashboard;

View File

@ -1,74 +1,68 @@
/*jshint esversion: 6 */ /*jshint esversion: 6 */
var async = require('async'); let async = require('async');
//require("./core/debug_util.js")(__filename, async); // require("./utils/debug_util.js")(__filename, async);
var Web3 = require('web3'); let colors = require('colors');
var colors = require('colors');
var Engine = require('./core/engine.js'); let Engine = require('./core/engine.js');
var Blockchain = require('./cmds/blockchain/blockchain.js'); let IPFS = require('./upload/ipfs.js');
var Simulator = require('./cmds/simulator.js'); let Swarm = require('./upload/swarm.js');
var TemplateGenerator = require('./cmds/template_generator.js');
var Test = require('./core/test.js'); let version = require('../package.json').version;
var Logger = require('./core/logger.js');
var Config = require('./core/config.js');
var Events = require('./core/events.js');
var Dashboard = require('./dashboard/dashboard.js'); class Embark {
var IPFS = require('./upload/ipfs.js'); constructor (options) {
var Swarm = require('./upload/swarm.js'); this.version = version;
this.options = options || {};
}
var Cmd = require('./cmd.js'); initConfig(env, options) {
let Events = require('./core/events.js');
let Logger = require('./core/logger.js');
let Config = require('./core/config.js');
var Embark = {
version: '2.4.2',
process: function(args) {
var cmd = new Cmd(Embark);
cmd.process(args);
},
initConfig: function(env, options) {
this.events = new Events(); this.events = new Events();
this.logger = new Logger({logLevel: 'debug'}); this.logger = new Logger({logLevel: 'debug'});
this.config = new Config({env: env, logger: this.logger, events: this.events}); this.config = new Config({env: env, logger: this.logger, events: this.events});
this.config.loadConfigFiles(options); this.config.loadConfigFiles(options);
this.plugins = this.config.plugins; this.plugins = this.config.plugins;
}, }
blockchain: function(env, client) { blockchain(env, client) {
var blockchain = Blockchain(this.config.blockchainConfig, client, env); return require('./cmds/blockchain/blockchain.js')(this.config.blockchainConfig, client, env).run();
blockchain.run(); }
},
simulator: function(options) { simulator(options) {
var simulator = new Simulator({blockchainConfig: this.config.blockchainConfig}); let Simulator = require('./cmds/simulator.js');
let simulator = new Simulator({blockchainConfig: this.config.blockchainConfig});
simulator.run(options); simulator.run(options);
}, }
generateTemplate: function(templateName, destinationFolder, name) { generateTemplate(templateName, destinationFolder, name) {
var templateGenerator = new TemplateGenerator(templateName); let TemplateGenerator = require('./cmds/template_generator.js');
let templateGenerator = new TemplateGenerator(templateName);
templateGenerator.generate(destinationFolder, name); templateGenerator.generate(destinationFolder, name);
}, }
run: function(options) { run(options) {
var self = this; let self = this;
var env = options.env; let Dashboard = require('./dashboard/dashboard.js');
var engine = new Engine({ let env = options.env;
let engine = new Engine({
env: options.env, env: options.env,
embarkConfig: 'embark.json' version: this.version,
embarkConfig: options.embarkConfig || 'embark.json'
}); });
engine.init(); engine.init();
if (!options.useDashboard) { if (!options.useDashboard) {
console.log('========================'.bold.green); console.log('========================'.bold.green);
console.log(('Welcome to Embark ' + Embark.version).yellow.bold); console.log(('Welcome to Embark ' + this.version).yellow.bold);
console.log('========================'.bold.green); console.log('========================'.bold.green);
} }
@ -78,38 +72,47 @@ var Embark = {
return callback(); return callback();
} }
var dashboard = new Dashboard({ let dashboard = new Dashboard({
logger: engine.logger, logger: engine.logger,
plugins: engine.plugins, plugins: engine.plugins,
version: engine.version, version: self.version,
env: engine.env env: engine.env
}); });
dashboard.start(function() { dashboard.start(function () {
engine.events.on('abi-vanila', function(abi) { engine.events.on('abi-vanila', function (abi) {
dashboard.console.runCode(abi); dashboard.console.runCode(abi);
}); });
engine.logger.info('dashboard start');
engine.events.on('servicesState', function (servicesState) {
dashboard.monitor.availableServices(servicesState);
});
callback(); callback();
}); });
}, },
function (callback) { function (callback) {
var pluginList = engine.plugins.listPlugins(); let pluginList = engine.plugins.listPlugins();
if (pluginList.length > 0) { if (pluginList.length > 0) {
engine.logger.info("loaded plugins: " + pluginList.join(", ")); engine.logger.info("loaded plugins: " + pluginList.join(", "));
} }
if (options.useDashboard) { engine.startMonitor();
engine.startService("monitor", { engine.startService("web3");
serverHost: options.serverHost,
serverPort: options.serverPort,
runWebserver: options.runWebserver
});
}
engine.startService("pipeline"); engine.startService("pipeline");
engine.startService("abi"); engine.startService("abi");
engine.startService("deployment"); engine.startService("deployment");
engine.startService("ipfs");
engine.deployManager.deployContracts(function() { 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 (err) {
engine.startService("fileWatcher"); engine.startService("fileWatcher");
if (options.runWebserver) { if (options.runWebserver) {
engine.startService("webServer", { engine.startService("webServer", {
@ -117,12 +120,13 @@ var Embark = {
port: options.serverPort port: options.serverPort
}); });
} }
callback(); callback(err);
}); });
} }
], function(err, result) { ], function (err, result) {
if (err) { if (err) {
engine.logger.error(err.message); engine.logger.error(err.message);
engine.logger.info(err.stack);
} else { } else {
engine.logger.setStatus("Ready".green); engine.logger.setStatus("Ready".green);
engine.logger.info("Looking for documentation? you can find it at ".cyan + "http://embark.readthedocs.io/".green.underline); engine.logger.info("Looking for documentation? you can find it at ".cyan + "http://embark.readthedocs.io/".green.underline);
@ -130,13 +134,13 @@ var Embark = {
engine.events.emit('firstDeploymentDone'); engine.events.emit('firstDeploymentDone');
} }
}); });
}, }
build: function(options) { build(options) {
var self = this;
var engine = new Engine({ let engine = new Engine({
env: options.env, env: options.env,
version: this.version,
embarkConfig: 'embark.json', embarkConfig: 'embark.json',
interceptLogs: false interceptLogs: false
}); });
@ -144,43 +148,46 @@ var Embark = {
async.waterfall([ async.waterfall([
function startServices(callback) { function startServices(callback) {
var pluginList = engine.plugins.listPlugins(); let pluginList = engine.plugins.listPlugins();
if (pluginList.length > 0) { if (pluginList.length > 0) {
engine.logger.info("loaded plugins: " + pluginList.join(", ")); engine.logger.info("loaded plugins: " + pluginList.join(", "));
} }
engine.startService("web3");
engine.startService("pipeline"); engine.startService("pipeline");
engine.startService("abi"); engine.startService("abi");
engine.startService("deployment"); engine.startService("deployment");
callback(); callback();
}, },
function deploy(callback) { function deploy(callback) {
engine.deployManager.deployContracts(function() { engine.deployManager.deployContracts(function (err) {
callback(); callback(err);
}); });
} }
], function(err, result) { ], function (err, result) {
if (err) { if (err) {
engine.logger.error(err.message); engine.logger.error(err.message);
engine.logger.debug(err.stack);
} else { } else {
engine.logger.info("finished building".underline); engine.logger.info("finished building".underline);
} }
// needed due to child processes // needed due to child processes
process.exit(); process.exit();
}); });
}, }
initTests: function(options) { initTests(options) {
let Test = require('./core/test.js');
return new Test(options); return new Test(options);
}, }
// TODO: should deploy if it hasn't already // TODO: should deploy if it hasn't already
upload: function(platform) { upload(platform) {
if (platform === 'ipfs') { if (platform === 'ipfs') {
var ipfs = new IPFS({buildDir: 'dist/', plugins: this.plugins, storageConfig: this.config.storageConfig}); let ipfs = new IPFS({buildDir: 'dist/', plugins: this.plugins, storageConfig: this.config.storageConfig});
ipfs.deploy(); ipfs.deploy();
} else if (platform === 'swarm') { } else if (platform === 'swarm') {
var swarm = new Swarm({buildDir: 'dist/', plugins: this.plugins, storageConfig: this.config.storageConfig}); let swarm = new Swarm({buildDir: 'dist/', plugins: this.plugins, storageConfig: this.config.storageConfig});
swarm.deploy(); swarm.deploy();
} else { } else {
console.log(("unknown platform: " + platform).red); console.log(("unknown platform: " + platform).red);
@ -188,7 +195,12 @@ var Embark = {
} }
} }
}
// temporary until next refactor
Embark.initTests = function(options) {
let Test = require('./core/test.js');
return new Test(options);
}; };
module.exports = Embark; module.exports = Embark;

View File

@ -1,22 +1,24 @@
/*jshint esversion: 6, loopfunc: true */ /*jshint esversion: 6, loopfunc: true */
var fs = require('../core/fs.js'); let fs = require('../core/fs.js');
var Pipeline = function(options) { class Pipeline {
constructor(options) {
this.buildDir = options.buildDir; this.buildDir = options.buildDir;
this.contractsFiles = options.contractsFiles; this.contractsFiles = options.contractsFiles;
this.assetFiles = options.assetFiles; this.assetFiles = options.assetFiles;
this.logger = options.logger; this.logger = options.logger;
this.plugins = options.plugins; this.plugins = options.plugins;
}; }
Pipeline.prototype.build = function(abi, path) { build(abi, contractsJSON, path) {
var self = this; let self = this;
for(var targetFile in this.assetFiles) { for (let targetFile in this.assetFiles) {
var contentFiles = this.assetFiles[targetFile].map(file => { let contentFiles = this.assetFiles[targetFile].map(file => {
self.logger.trace("reading " + file.filename); self.logger.trace("reading " + file.filename);
var pipelinePlugins = this.plugins.getPluginsFor('pipeline'); let pipelinePlugins = this.plugins.getPluginsFor('pipeline');
if (file.filename === 'embark.js') { if (file.filename === 'embark.js') {
return {content: file.content + "\n" + abi, filename: file.filename, path: file.path, modified: true}; return {content: file.content + "\n" + abi, filename: file.filename, path: file.path, modified: true};
@ -28,7 +30,7 @@ Pipeline.prototype.build = function(abi, path) {
} else { } else {
if (pipelinePlugins.length > 0) { if (pipelinePlugins.length > 0) {
pipelinePlugins.forEach(function(plugin) { pipelinePlugins.forEach(function (plugin) {
try { try {
if (file.options && file.options.skipPipeline) { if (file.options && file.options.skipPipeline) {
return; return;
@ -36,7 +38,7 @@ Pipeline.prototype.build = function(abi, path) {
file.content = plugin.runPipeline({targetFile: file.filename, source: file.content}); file.content = plugin.runPipeline({targetFile: file.filename, source: file.content});
file.modified = true; file.modified = true;
} }
catch(err) { catch (err) {
self.logger.error(err.message); self.logger.error(err.message);
} }
}); });
@ -46,27 +48,27 @@ Pipeline.prototype.build = function(abi, path) {
} }
}); });
var dir = targetFile.split('/').slice(0, -1).join('/'); let dir = targetFile.split('/').slice(0, -1).join('/');
self.logger.trace("creating dir " + this.buildDir + dir); self.logger.trace("creating dir " + this.buildDir + dir);
fs.mkdirpSync(this.buildDir + dir); fs.mkdirpSync(this.buildDir + dir);
// if it's a directory // if it's a directory
if (targetFile.slice(-1) === '/' || targetFile.indexOf('.') === -1) { if (targetFile.slice(-1) === '/' || targetFile.indexOf('.') === -1) {
var targetDir = targetFile; let targetDir = targetFile;
if (targetDir.slice(-1) !== '/') { if (targetDir.slice(-1) !== '/') {
targetDir = targetDir + '/'; targetDir = targetDir + '/';
} }
contentFiles.map(function(file) { contentFiles.map(function (file) {
var filename = file.filename.replace('app/', ''); let filename = file.filename.replace('app/', '');
filename = filename.replace(targetDir, ''); filename = filename.replace(targetDir, '');
self.logger.info("writing file " + (self.buildDir + targetDir + filename).bold.dim); self.logger.info("writing file " + (self.buildDir + targetDir + filename).bold.dim);
fs.copySync(self.buildDir + targetDir + filename, file.path, {overwrite: true}); fs.copySync(self.buildDir + targetDir + filename, file.path, {overwrite: true});
}); });
} else { } else {
var content = contentFiles.map(function(file) { let content = contentFiles.map(function (file) {
return file.content; return file.content;
}).join("\n"); }).join("\n");
@ -74,7 +76,19 @@ Pipeline.prototype.build = function(abi, path) {
fs.writeFileSync(this.buildDir + targetFile, content); fs.writeFileSync(this.buildDir + targetFile, content);
} }
} }
};
this.buildContracts(contractsJSON);
}
buildContracts(contractsJSON) {
fs.mkdirpSync(this.buildDir + 'contracts');
for (let className in contractsJSON) {
let contract = contractsJSON[className];
fs.writeJSONSync(this.buildDir + 'contracts/' + className + ".json", contract, {spaces: 2});
}
}
}
module.exports = Pipeline; module.exports = Pipeline;

View File

@ -1,24 +1,27 @@
var finalhandler = require('finalhandler'); let finalhandler = require('finalhandler');
var http = require('http'); let http = require('http');
var serveStatic = require('serve-static'); let serveStatic = require('serve-static');
var Server = function(options) { class Server {
constructor(options) {
this.dist = options.dist || 'dist/'; this.dist = options.dist || 'dist/';
this.port = options.port || 8000; this.port = options.port || 8000;
this.hostname = options.host || 'localhost'; this.hostname = options.host || 'localhost';
this.logger = options.logger; this.logger = options.logger;
}; }
Server.prototype.start = function(callback) { start(callback) {
var serve = serveStatic(this.dist, {'index': ['index.html', 'index.htm']}); let serve = serveStatic(this.dist, {'index': ['index.html', 'index.htm']});
var server = http.createServer(function onRequest (req, res) { let server = http.createServer(function onRequest(req, res) {
serve(req, res, finalhandler(req, res)); serve(req, res, finalhandler(req, res));
}); });
this.logger.info("webserver available at " + ("http://" + this.hostname + ":" + this.port).bold.underline.green); this.logger.info("webserver available at " + ("http://" + this.hostname + ":" + this.port).bold.underline.green);
server.listen(this.port, this.hostname) ; server.listen(this.port, this.hostname);
callback(); callback();
}; }
}
module.exports = Server; module.exports = Server;

View File

@ -1,93 +1,94 @@
/*jshint esversion: 6 */ /*jshint esversion: 6 */
var chokidar = require('chokidar'); let chokidar = require('chokidar');
var fs = require('../core/fs.js'); let fs = require('../core/fs.js');
// TODO: this should be receiving the config object not re-reading the // TODO: this should be receiving the config object not re-reading the
// embark.json file // embark.json file
var Watch = function(options) { class Watch {
constructor(options) {
this.logger = options.logger; this.logger = options.logger;
this.events = options.events; this.events = options.events;
}; }
Watch.prototype.start = function() { start() {
var self = this; let self = this;
// TODO: should come from the config object instead of reading the file // TODO: should come from the config object instead of reading the file
// directly // directly
var embarkConfig = fs.readJSONSync("embark.json"); let embarkConfig = fs.readJSONSync("embark.json");
this.watchAssets(embarkConfig, function() { this.watchAssets(embarkConfig, function () {
self.logger.trace('ready to watch asset changes'); self.logger.trace('ready to watch asset changes');
}); });
this.watchContracts(embarkConfig, function() { this.watchContracts(embarkConfig, function () {
self.logger.trace('ready to watch contract changes'); self.logger.trace('ready to watch contract changes');
}); });
this.watchConfigs(function() { this.watchConfigs(function () {
self.logger.trace('ready to watch config changes'); self.logger.trace('ready to watch config changes');
}); });
this.logger.info("ready to watch file changes"); this.logger.info("ready to watch file changes");
}; }
Watch.prototype.watchAssets = function(embarkConfig, callback) { watchAssets(embarkConfig, callback) {
var self = this; let self = this;
var appConfig = embarkConfig.app; let appConfig = embarkConfig.app;
var filesToWatch = []; let filesToWatch = [];
for(var targetFile in appConfig) { for (let targetFile in appConfig) {
filesToWatch.push(appConfig[targetFile]); filesToWatch.push(appConfig[targetFile]);
} }
this.watchFiles( this.watchFiles(
filesToWatch, filesToWatch,
function(eventName, path) { function (eventName, path) {
self.logger.info(`${eventName}: ${path}`); self.logger.info(`${eventName}: ${path}`);
self.events.emit('file-' + eventName, 'asset', path); self.events.emit('file-' + eventName, 'asset', path);
self.events.emit('file-event', 'asset', path); self.events.emit('file-event', 'asset', path);
}, },
function() { function () {
callback(); callback();
} }
); );
}; }
Watch.prototype.watchContracts = function(embarkConfig, callback) { watchContracts(embarkConfig, callback) {
var self = this; let self = this;
this.watchFiles( this.watchFiles(
[embarkConfig.contracts], [embarkConfig.contracts],
function(eventName, path) { function (eventName, path) {
self.logger.info(`${eventName}: ${path}`); self.logger.info(`${eventName}: ${path}`);
self.events.emit('file-' + eventName, 'contract', path); self.events.emit('file-' + eventName, 'contract', path);
self.events.emit('file-event', 'contract', path); self.events.emit('file-event', 'contract', path);
}, },
function() { function () {
callback(); callback();
} }
); );
}; }
Watch.prototype.watchConfigs = function(callback) { watchConfigs(callback) {
var self = this; let self = this;
this.watchFiles( this.watchFiles(
"config/**/contracts.json", "config/**/contracts.json",
function(eventName, path) { function (eventName, path) {
self.logger.info(`${eventName}: ${path}`); self.logger.info(`${eventName}: ${path}`);
self.events.emit('file-' + eventName, 'config', path); self.events.emit('file-' + eventName, 'config', path);
self.events.emit('file-event', 'config', path); self.events.emit('file-event', 'config', path);
}, },
function() { function () {
callback(); callback();
} }
); );
}; }
Watch.prototype.watchFiles = function(files, changeCallback, doneCallback) { watchFiles(files, changeCallback, doneCallback) {
this.logger.trace('watchFiles'); this.logger.trace('watchFiles');
this.logger.trace(files); this.logger.trace(files);
var configWatcher = chokidar.watch(files, { let configWatcher = chokidar.watch(files, {
ignored: /[\/\\]\./, persistent: true, ignoreInitial: true, followSymlinks: true ignored: /[\/\\]\./, persistent: true, ignoreInitial: true, followSymlinks: true
}); });
@ -96,6 +97,8 @@ Watch.prototype.watchFiles = function(files, changeCallback, doneCallback) {
.on('change', path => changeCallback('change', path)) .on('change', path => changeCallback('change', path))
.on('unlink', path => changeCallback('remove', path)) .on('unlink', path => changeCallback('remove', path))
.on('ready', doneCallback); .on('ready', doneCallback);
}; }
}
module.exports = Watch; module.exports = Watch;

View File

@ -1,22 +1,24 @@
var colors = require('colors'); let colors = require('colors');
var async = require('async'); let async = require('async');
var shelljs = require('shelljs'); let shelljs = require('shelljs');
var IPFS = function(options) { class IPFS {
constructor(options) {
this.options = options; this.options = options;
this.buildDir = options.buildDir || 'dist/'; this.buildDir = options.buildDir || 'dist/';
this.plugins = options.plugins; this.plugins = options.plugins;
this.storageConfig = options.storageConfig; this.storageConfig = options.storageConfig;
this.configIpfsBin = this.storageConfig.ipfs_bin || "ipfs"; this.configIpfsBin = this.storageConfig.ipfs_bin || "ipfs";
}; }
IPFS.prototype.deploy = function() { deploy() {
var self = this; let self = this;
async.waterfall([ async.waterfall([
function findBinary(callback) { function findBinary(callback) {
var ipfs_bin = shelljs.exec('which ' + self.configIpfsBin).output.split("\n")[0]; let ipfs_bin = shelljs.exec('which ' + self.configIpfsBin).output.split("\n")[0];
if (ipfs_bin === 'ipfs not found' || ipfs_bin === ''){ if (ipfs_bin === 'ipfs not found' || ipfs_bin === '') {
console.log(('=== WARNING: ' + self.configIpfsBin + ' not found or not in the path. Guessing ~/go/bin/ipfs for path').yellow); console.log(('=== WARNING: ' + self.configIpfsBin + ' not found or not in the path. Guessing ~/go/bin/ipfs for path').yellow);
ipfs_bin = "~/go/bin/ipfs"; ipfs_bin = "~/go/bin/ipfs";
} }
@ -24,17 +26,17 @@ IPFS.prototype.deploy = function() {
return callback(null, ipfs_bin); return callback(null, ipfs_bin);
}, },
function runCommand(ipfs_bin, callback) { function runCommand(ipfs_bin, callback) {
var cmd = ipfs_bin + " add -r " + self.buildDir; let cmd = ipfs_bin + " add -r " + self.buildDir;
console.log(("=== adding " + self.buildDir + " to ipfs").green); console.log(("=== adding " + self.buildDir + " to ipfs").green);
console.log(cmd.green); console.log(cmd.green);
var result = shelljs.exec(cmd); let result = shelljs.exec(cmd);
return callback(null, result); return callback(null, result);
}, },
function getHashFromOutput(result, callback) { function getHashFromOutput(result, callback) {
var rows = result.output.split("\n"); let rows = result.output.split("\n");
var dir_row = rows[rows.length - 2]; let dir_row = rows[rows.length - 2];
var dir_hash = dir_row.split(" ")[1]; let dir_hash = dir_row.split(" ")[1];
return callback(null, dir_hash); return callback(null, dir_hash);
}, },
@ -44,13 +46,15 @@ IPFS.prototype.deploy = function() {
return callback(); return callback();
} }
], function(err, result) { ], function (err, result) {
if (err) { if (err) {
console.log("error uploading to ipfs".red); console.log("error uploading to ipfs".red);
console.log(err); console.log(err);
} }
}); });
}; }
}
module.exports = IPFS; module.exports = IPFS;

View File

@ -1,19 +1,20 @@
var colors = require('colors'); let colors = require('colors');
var async = require('async'); let async = require('async');
var shelljs = require('shelljs'); let shelljs = require('shelljs');
var Swarm = function(options) { class Swarm {
constructor(options) {
this.options = options; this.options = options;
this.buildDir = options.buildDir || 'dist/'; this.buildDir = options.buildDir || 'dist/';
}; }
Swarm.prototype.deploy = function() { deploy() {
var self = this; let self = this;
async.waterfall([ async.waterfall([
function findBinary(callback) { function findBinary(callback) {
var swarm_bin = shelljs.exec('which swarm').output.split("\n")[0]; let swarm_bin = shelljs.exec('which swarm').output.split("\n")[0];
if (swarm_bin==='swarm not found' || swarm_bin === ''){ if (swarm_bin === 'swarm not found' || swarm_bin === '') {
console.log('=== WARNING: Swarm not in an executable path. Guessing ~/go/bin/swarm for path'.yellow); console.log('=== WARNING: Swarm not in an executable path. Guessing ~/go/bin/swarm for path'.yellow);
swarm_bin = "~/go/bin/swarm"; swarm_bin = "~/go/bin/swarm";
} }
@ -21,10 +22,10 @@ Swarm.prototype.deploy = function() {
return callback(null, swarm_bin); return callback(null, swarm_bin);
}, },
function runCommand(swarm_bin, callback) { function runCommand(swarm_bin, callback) {
var cmd = swarm_bin + " --defaultpath " + self.buildDir + "index.html --recursive up " + self.buildDir; let cmd = swarm_bin + " --defaultpath " + self.buildDir + "index.html --recursive up " + self.buildDir;
console.log(("=== adding " + self.buildDir + " to swarm").green); console.log(("=== adding " + self.buildDir + " to swarm").green);
console.log(cmd.green); console.log(cmd.green);
var result = shelljs.exec(cmd); let result = shelljs.exec(cmd);
return callback(null, result); return callback(null, result);
}, },
@ -33,8 +34,8 @@ Swarm.prototype.deploy = function() {
return callback("couldn't upload, is the swarm daemon running?"); return callback("couldn't upload, is the swarm daemon running?");
} }
var rows = result.output.split("\n"); let rows = result.output.split("\n");
var dir_hash = rows.reverse()[1]; let dir_hash = rows.reverse()[1];
return callback(null, dir_hash); return callback(null, dir_hash);
}, },
@ -43,13 +44,14 @@ Swarm.prototype.deploy = function() {
return callback(); return callback();
} }
], function(err, result) { ], function (err, result) {
if (err) { if (err) {
console.log("error uploading to swarm".red); console.log("error uploading to swarm".red);
console.log(err); console.log(err);
} }
}); });
}; }
}
module.exports = Swarm; module.exports = Swarm;

15
lib/utils/async_extend.js Normal file
View File

@ -0,0 +1,15 @@
let 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;

View File

@ -5,9 +5,9 @@ function extend(filename, async) {
return; return;
} }
async._waterfall = async.waterfall; async._waterfall = async.waterfall;
async.waterfall = function(_tasks, callback) { async.waterfall = function (_tasks, callback) {
var tasks = _tasks.map(function(t) { let tasks = _tasks.map(function (t) {
var fn = function() { let fn = function () {
console.log("async " + filename + ": " + t.name); console.log("async " + filename + ": " + t.name);
t.apply(t, arguments); t.apply(t, arguments);
}; };

View File

@ -1,9 +1,9 @@
/*global exit */ /*global exit */
var path = require('path'); let path = require('path');
var globule = require('globule'); let globule = require('globule');
var merge = require('merge'); let merge = require('merge');
var http = require('http'); let http = require('http');
var shelljs = require('shelljs'); let shelljs = require('shelljs');
function joinPath() { function joinPath() {
return path.join.apply(path.join, arguments); return path.join.apply(path.join, arguments);
@ -22,15 +22,19 @@ function recursiveMerge(target, source) {
} }
function checkIsAvailable(url, callback) { function checkIsAvailable(url, callback) {
http.get(url, function(res) { http.get(url, function (res) {
callback(true); callback(true);
}).on('error', function(res) { }).on('error', function (res) {
callback(false); callback(false);
}); });
} }
function httpGet(url, callback) {
return http.get(url, callback);
}
function runCmd(cmd, options) { function runCmd(cmd, options) {
var result = shelljs.exec(cmd, options || {silent: true}); let result = shelljs.exec(cmd, options || {silent: true});
if (result.code !== 0) { if (result.code !== 0) {
console.log("error doing.. " + cmd); console.log("error doing.. " + cmd);
console.log(result.output); console.log(result.output);
@ -53,12 +57,14 @@ function exit(code) {
process.exit(code); process.exit(code);
} }
//TODO: Maybe desired to just `module.exports = this` ?
module.exports = { module.exports = {
joinPath: joinPath, joinPath: joinPath,
filesMatchingPattern: filesMatchingPattern, filesMatchingPattern: filesMatchingPattern,
fileMatchesPattern: fileMatchesPattern, fileMatchesPattern: fileMatchesPattern,
recursiveMerge: recursiveMerge, recursiveMerge: recursiveMerge,
checkIsAvailable: checkIsAvailable, checkIsAvailable: checkIsAvailable,
httpGet: httpGet,
runCmd: runCmd, runCmd: runCmd,
cd: cd, cd: cd,
sed: sed, sed: sed,

View File

@ -1,6 +1,6 @@
{ {
"name": "embark", "name": "embark",
"version": "2.4.2", "version": "2.5.0",
"description": "Embark is a framework that allows you to easily develop and deploy DApps", "description": "Embark is a framework that allows you to easily develop and deploy DApps",
"scripts": { "scripts": {
"test": "grunt jshint && mocha test/ --no-timeouts" "test": "grunt jshint && mocha test/ --no-timeouts"
@ -26,11 +26,14 @@
"fs-extra": "^2.0.0", "fs-extra": "^2.0.0",
"globule": "^1.1.0", "globule": "^1.1.0",
"merge": "^1.2.0", "merge": "^1.2.0",
"promptly": "^2.1.0",
"serve-static": "^1.11.1", "serve-static": "^1.11.1",
"shelljs": "^0.5.0", "shelljs": "^0.5.0",
"solc": "0.4.8", "solc": "0.4.11",
"toposort": "^1.0.0", "toposort": "^1.0.0",
"web3": "^0.18.2" "underscore": "^1.8.3",
"underscore.string": "^3.3.4",
"web3": "^0.19.1"
}, },
"author": "Iuri Matias <iuri.matias@gmail.com>", "author": "Iuri Matias <iuri.matias@gmail.com>",
"contributors": [], "contributors": [],
@ -49,6 +52,8 @@
"devDependencies": { "devDependencies": {
"grunt": "^1.0.1", "grunt": "^1.0.1",
"grunt-cli": "^1.2.0", "grunt-cli": "^1.2.0",
"grunt-contrib-clean": "^1.0.0",
"grunt-contrib-coffee": "^1.0.0",
"grunt-contrib-jshint": "^1.0.0", "grunt-contrib-jshint": "^1.0.0",
"grunt-mocha-test": "^0.13.2", "grunt-mocha-test": "^0.13.2",
"matchdep": "^1.0.1", "matchdep": "^1.0.1",
@ -56,5 +61,19 @@
"mocha-sinon": "^1.1.4", "mocha-sinon": "^1.1.4",
"sinon": "^1.15.4", "sinon": "^1.15.4",
"toposort": "^1.0.0" "toposort": "^1.0.0"
},
"jshintConfig": {
"indent": 2,
"white": true,
"node": true,
"undef": true,
"-W058": true,
"-W014": true,
"expr": true,
"esversion": 6,
"unused": false,
"globals": {
"node": true
}
} }
} }

View File

@ -1,23 +1,23 @@
/*globals describe, it*/ /*globals describe, it*/
var ABIGenerator = require('../lib/contracts/abi.js'); let ABIGenerator = require('../lib/contracts/abi.js');
var assert = require('assert'); let assert = require('assert');
// TODO: instead 'eval' the code with a fake web3 object // TODO: instead 'eval' the code with a fake web3 object
// and check the generate code interacts as expected // and check the generate code interacts as expected
describe('embark.ABIGenerator', function() { describe('embark.ABIGenerator', function() {
this.timeout(0);
describe('#generateProvider', function() { describe('#generateProvider', function() {
var generator = new ABIGenerator({blockchainConfig: {rpcHost: 'somehost', rpcPort: '1234'}, contractsManager: {}}); let generator = new ABIGenerator({blockchainConfig: {rpcHost: 'somehost', rpcPort: '1234'}, contractsManager: {}});
it('should generate code to connect to a provider', function() { it('should generate code to connect to a provider', function() {
var providerCode = "\nvar whenEnvIsLoaded = function(cb) {\n if (typeof window !== 'undefined' && window !== null) {\n window.addEventListener('load', cb);\n } else {\n cb();\n }\n}\nwhenEnvIsLoaded(function() {\nif (typeof web3 !== 'undefined' && typeof Web3 !== 'undefined') {\n\tweb3 = new Web3(web3.currentProvider);\n} else if (typeof Web3 !== 'undefined') {\n\tweb3 = new Web3(new Web3.providers.HttpProvider(\"http://somehost:1234\"));\n}\nweb3.eth.defaultAccount = web3.eth.accounts[0];\n})" var providerCode = "\nvar whenEnvIsLoaded = function(cb) {\n if (typeof document !== 'undefined' && document !== null) {\n document.addEventListener('DOMContentLoaded', cb);\n } else {\n cb();\n }\n}\nwhenEnvIsLoaded(function() {\nif (typeof web3 !== 'undefined' && typeof Web3 !== 'undefined') {\n\tweb3 = new Web3(web3.currentProvider);\n} else if (typeof Web3 !== 'undefined') {\n\tweb3 = new Web3(new Web3.providers.HttpProvider(\"http://somehost:1234\"));\n}\nweb3.eth.defaultAccount = web3.eth.accounts[0];\n})"
assert.equal(generator.generateProvider(), providerCode); assert.equal(generator.generateProvider(), providerCode);
}); });
}); });
describe('#generateContracts', function() { describe('#generateContracts', function() {
var generator = new ABIGenerator({blockchainConfig: {}, contractsManager: { let generator = new ABIGenerator({blockchainConfig: {}, contractsManager: {
contracts: { contracts: {
SimpleStorage: { SimpleStorage: {
abiDefinition: [{"constant":true,"inputs":[],"name":"storedData","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"x","type":"uint256"}],"name":"set","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"get","outputs":[{"name":"retVal","type":"uint256"}],"payable":false,"type":"function"},{"inputs":[{"name":"initialValue","type":"uint256"}],"type":"constructor"}], abiDefinition: [{"constant":true,"inputs":[],"name":"storedData","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"x","type":"uint256"}],"name":"set","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"get","outputs":[{"name":"retVal","type":"uint256"}],"payable":false,"type":"function"},{"inputs":[{"name":"initialValue","type":"uint256"}],"type":"constructor"}],
@ -35,19 +35,19 @@ describe('embark.ABIGenerator', function() {
}}); }});
describe('with EmbarkJS', function() { describe('with EmbarkJS', function() {
var withEmbarkJS = true; let withEmbarkJS = true;
it('should generate contract code', function() { it('should generate contract code', function() {
var contractCode = "\n\nwhenEnvIsLoaded(function() {\nSimpleStorage = new EmbarkJS.Contract({abi: [{\"constant\":true,\"inputs\":[],\"name\":\"storedData\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"x\",\"type\":\"uint256\"}],\"name\":\"set\",\"outputs\":[],\"payable\":false,\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"get\",\"outputs\":[{\"name\":\"retVal\",\"type\":\"uint256\"}],\"payable\":false,\"type\":\"function\"},{\"inputs\":[{\"name\":\"initialValue\",\"type\":\"uint256\"}],\"type\":\"constructor\"}], address: '0x123', code: '12345', gasEstimates: 12000});\n});\nwhenEnvIsLoaded(function() {\nFoo = new EmbarkJS.Contract({abi: [{\"constant\":true,\"inputs\":[],\"name\":\"storedData\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"x\",\"type\":\"uint256\"}],\"name\":\"set\",\"outputs\":[],\"payable\":false,\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"get\",\"outputs\":[{\"name\":\"retVal\",\"type\":\"uint256\"}],\"payable\":false,\"type\":\"function\"},{\"inputs\":[{\"name\":\"initialValue\",\"type\":\"uint256\"}],\"type\":\"constructor\"}], address: '0x124', code: '123456', gasEstimates: 12000});\n});"; var contractCode = "\n\nif (whenEnvIsLoaded === undefined) {\n var whenEnvIsLoaded = function(cb) {\n if (typeof document !== 'undefined' && document !== null) {\n document.addEventListener('DOMContentLoaded', cb);\n } else {\n cb();\n }\n }\n}\nwhenEnvIsLoaded(function() {\nSimpleStorage = new EmbarkJS.Contract({abi: [{\"constant\":true,\"inputs\":[],\"name\":\"storedData\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"x\",\"type\":\"uint256\"}],\"name\":\"set\",\"outputs\":[],\"payable\":false,\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"get\",\"outputs\":[{\"name\":\"retVal\",\"type\":\"uint256\"}],\"payable\":false,\"type\":\"function\"},{\"inputs\":[{\"name\":\"initialValue\",\"type\":\"uint256\"}],\"type\":\"constructor\"}], address: '0x123', code: '12345', gasEstimates: 12000});\n});\nif (whenEnvIsLoaded === undefined) {\n var whenEnvIsLoaded = function(cb) {\n if (typeof document !== 'undefined' && document !== null) {\n document.addEventListener('DOMContentLoaded', cb);\n } else {\n cb();\n }\n }\n}\nwhenEnvIsLoaded(function() {\nFoo = new EmbarkJS.Contract({abi: [{\"constant\":true,\"inputs\":[],\"name\":\"storedData\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"x\",\"type\":\"uint256\"}],\"name\":\"set\",\"outputs\":[],\"payable\":false,\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"get\",\"outputs\":[{\"name\":\"retVal\",\"type\":\"uint256\"}],\"payable\":false,\"type\":\"function\"},{\"inputs\":[{\"name\":\"initialValue\",\"type\":\"uint256\"}],\"type\":\"constructor\"}], address: '0x124', code: '123456', gasEstimates: 12000});\n});";
assert.equal(generator.generateContracts(withEmbarkJS), contractCode); assert.equal(generator.generateContracts(withEmbarkJS), contractCode);
}); });
}); });
describe('with default interface', function() { describe('with default interface', function() {
var withEmbarkJS = false; let withEmbarkJS = false;
it('should generate contract code', function() { it('should generate contract code', function() {
var contractCode = "\n\nwhenEnvIsLoaded(function() {\nSimpleStorageAbi = [{\"constant\":true,\"inputs\":[],\"name\":\"storedData\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"x\",\"type\":\"uint256\"}],\"name\":\"set\",\"outputs\":[],\"payable\":false,\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"get\",\"outputs\":[{\"name\":\"retVal\",\"type\":\"uint256\"}],\"payable\":false,\"type\":\"function\"},{\"inputs\":[{\"name\":\"initialValue\",\"type\":\"uint256\"}],\"type\":\"constructor\"}];\nSimpleStorageContract = web3.eth.contract(SimpleStorageAbi);\nSimpleStorage = SimpleStorageContract.at('0x123');\n});\nwhenEnvIsLoaded(function() {\nFooAbi = [{\"constant\":true,\"inputs\":[],\"name\":\"storedData\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"x\",\"type\":\"uint256\"}],\"name\":\"set\",\"outputs\":[],\"payable\":false,\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"get\",\"outputs\":[{\"name\":\"retVal\",\"type\":\"uint256\"}],\"payable\":false,\"type\":\"function\"},{\"inputs\":[{\"name\":\"initialValue\",\"type\":\"uint256\"}],\"type\":\"constructor\"}];\nFooContract = web3.eth.contract(FooAbi);\nFoo = FooContract.at('0x124');\n});"; var contractCode = "\n\nif (whenEnvIsLoaded === undefined) {\n var whenEnvIsLoaded = function(cb) {\n if (typeof document !== 'undefined' && document !== null) {\n document.addEventListener('DOMContentLoaded', cb);\n } else {\n cb();\n }\n }\n}\nwhenEnvIsLoaded(function() {\nSimpleStorageAbi = [{\"constant\":true,\"inputs\":[],\"name\":\"storedData\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"x\",\"type\":\"uint256\"}],\"name\":\"set\",\"outputs\":[],\"payable\":false,\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"get\",\"outputs\":[{\"name\":\"retVal\",\"type\":\"uint256\"}],\"payable\":false,\"type\":\"function\"},{\"inputs\":[{\"name\":\"initialValue\",\"type\":\"uint256\"}],\"type\":\"constructor\"}];\nSimpleStorageContract = web3.eth.contract(SimpleStorageAbi);\nSimpleStorage = SimpleStorageContract.at('0x123');\n});\nif (whenEnvIsLoaded === undefined) {\n var whenEnvIsLoaded = function(cb) {\n if (typeof document !== 'undefined' && document !== null) {\n document.addEventListener('DOMContentLoaded', cb);\n } else {\n cb();\n }\n }\n}\nwhenEnvIsLoaded(function() {\nFooAbi = [{\"constant\":true,\"inputs\":[],\"name\":\"storedData\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"x\",\"type\":\"uint256\"}],\"name\":\"set\",\"outputs\":[],\"payable\":false,\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"get\",\"outputs\":[{\"name\":\"retVal\",\"type\":\"uint256\"}],\"payable\":false,\"type\":\"function\"},{\"inputs\":[{\"name\":\"initialValue\",\"type\":\"uint256\"}],\"type\":\"constructor\"}];\nFooContract = web3.eth.contract(FooAbi);\nFoo = FooContract.at('0x124');\n});";
assert.equal(generator.generateContracts(withEmbarkJS), contractCode); assert.equal(generator.generateContracts(withEmbarkJS), contractCode);
}); });
}); });

View File

@ -1,17 +1,18 @@
/*globals describe, it*/ /*globals describe, it*/
var Blockchain = require('../lib/cmds/blockchain/blockchain.js'); const Blockchain = require('../lib/cmds/blockchain/blockchain');
var assert = require('assert');
describe('embark.Blockchain', function() { const assert = require('assert');
//var Client = function() {};
describe('embark.Blockchain', function () {
//let Client = function() {};
//Client.prototype.name = "ClientName"; //Client.prototype.name = "ClientName";
describe('#initializer', function() { describe('#initializer', function () {
//var client = new Client(); //let client = new Client();
describe('with empty config', function() { describe('with empty config', function () {
it('should have a default config', function() { it('should have a default config', function (done) {
var config = { let config = {
networkType: 'custom', networkType: 'custom',
genesisBlock: false, genesisBlock: false,
geth_bin: 'geth', geth_bin: 'geth',
@ -31,15 +32,16 @@ describe('embark.Blockchain', function() {
account: {}, account: {},
bootnodes: "" bootnodes: ""
}; };
var blockchain = Blockchain(config, 'geth'); let blockchain = new Blockchain(config, 'geth');
assert.deepEqual(blockchain.config, config); assert.deepEqual(blockchain.config, config);
done();
}); });
}); });
describe('with config', function() { describe('with config', function () {
it('should take config params', function() { it('should take config params', function (done) {
var config = { let config = {
networkType: 'livenet', networkType: 'livenet',
genesisBlock: 'foo/bar/genesis.json', genesisBlock: 'foo/bar/genesis.json',
geth_bin: 'geth', geth_bin: 'geth',
@ -59,9 +61,10 @@ describe('embark.Blockchain', function() {
account: {}, account: {},
bootnodes: "" bootnodes: ""
}; };
var blockchain = Blockchain(config, 'geth'); let blockchain = new Blockchain(config, 'geth');
assert.deepEqual(blockchain.config, config); assert.deepEqual(blockchain.config, config);
done();
}); });
}); });

52
test/cmd.js Normal file
View File

@ -0,0 +1,52 @@
let Embark = require('../lib/index');
let Cmd = require('../lib/cmd');
// Function to send a line to stdin
function sendLine(line) {
setImmediate(function () {
process.stdin.emit('data', line + '\n');
});
}
let passingLines = function () {
let 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);
describe('#new', function () {
it('it should create an app with a name', function (done) {
let cmd = new Cmd(Embark);
let pl = passingLines();
let appname = 'deleteapp';
cmd.newApp(appname, function (output) {
let 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) {
let cmd = new Cmd(Embark);
let pl = passingLines();
let appname = 'deleteapp';
cmd.newApp(undefined, function (output) {
let lines = output.split('\n');
console.log(lines);
sendLine(appname + '\n');
assert.equal(lines[0], pl[0]);
});
done();
});
});
});

File diff suppressed because one or more lines are too long

View File

@ -1,11 +1,10 @@
/*globals describe, it*/ /*globals describe, it*/
var Config = require('../lib/core/config.js'); let Config = require('../lib/core/config.js');
var Plugins = require('../lib/core/plugins.js'); let Plugins = require('../lib/core/plugins.js');
var assert = require('assert'); let assert = require('assert');
var fs = require('fs');
describe('embark.Config', function() { describe('embark.Config', function() {
var config = new Config({ let config = new Config({
env: 'myenv', env: 'myenv',
configDir: './test/test1/config/' configDir: './test/test1/config/'
}); });
@ -14,7 +13,7 @@ describe('embark.Config', function() {
describe('#loadBlockchainConfigFile', function() { describe('#loadBlockchainConfigFile', function() {
it('should load blockchain config correctly', function() { it('should load blockchain config correctly', function() {
config.loadBlockchainConfigFile(); config.loadBlockchainConfigFile();
var expectedConfig = { let expectedConfig = {
"enabled": true, "enabled": true,
"networkType": "custom", "networkType": "custom",
"genesisBlock": "config/development/genesis.json", "genesisBlock": "config/development/genesis.json",
@ -36,7 +35,7 @@ describe('embark.Config', function() {
describe('#loadContractsConfigFile', function() { describe('#loadContractsConfigFile', function() {
it('should load contract config correctly', function() { it('should load contract config correctly', function() {
config.loadContractsConfigFile(); config.loadContractsConfigFile();
var expectedConfig = { let expectedConfig = {
"gas": "auto", "gas": "auto",
"contracts": { "contracts": {
"SimpleStorage": { "SimpleStorage": {

View File

@ -1,11 +1,12 @@
/*globals describe, it*/ /*globals describe, it*/
var Console = require('../lib/dashboard/console.js'); let Console = require('../lib/dashboard/console.js');
var Plugins = require('../lib/core/plugins.js'); let Plugins = require('../lib/core/plugins.js');
var assert = require('assert'); let assert = require('assert');
let version = require('../package.json').version;
describe('embark.Console', function() { describe('embark.Console', function() {
var plugins = new Plugins({plugins: {}}); let plugins = new Plugins({plugins: {}});
var console = new Console({plugins: plugins, version: '2.3.1'}); let console = new Console({plugins: plugins, version: version});
describe('#executeCmd', function() { describe('#executeCmd', function() {
@ -13,8 +14,8 @@ describe('embark.Console', function() {
it('it should provide a help text', function(done) { it('it should provide a help text', function(done) {
console.executeCmd('help', function(output) { console.executeCmd('help', function(output) {
var lines = output.split('\n'); let lines = output.split('\n');
assert.equal(lines[0], 'Welcome to Embark 2.3.1'); assert.equal(lines[0], 'Welcome to Embark ' + version);
assert.equal(lines[2], 'possible commands are:'); assert.equal(lines[2], 'possible commands are:');
done(); done();
}); });

View File

@ -1,16 +1,17 @@
/*globals describe, it*/ /*globals describe, it*/
var ContractsManager = require('../lib/contracts/contracts.js'); let ContractsManager = require('../lib/contracts/contracts.js');
var Logger = require('../lib/core/logger.js'); let Logger = require('../lib/core/logger.js');
var assert = require('assert'); let assert = require('assert');
var fs = require('fs'); let fs = require('fs');
var readFile = function(file) { let readFile = function(file) {
return {filename: file, content: fs.readFileSync(file).toString()}; return {filename: file, content: fs.readFileSync(file).toString()};
}; };
describe('embark.Contratcs', function() { describe('embark.Contratcs', function() {
this.timeout(0);
describe('simple', function() { describe('simple', function() {
var contractsManager = new ContractsManager({ let contractsManager = new ContractsManager({
contractFiles: [ contractFiles: [
readFile('test/contracts/simple_storage.sol'), readFile('test/contracts/simple_storage.sol'),
readFile('test/contracts/token.sol') readFile('test/contracts/token.sol')
@ -40,7 +41,7 @@ describe('embark.Contratcs', function() {
throw err; throw err;
} }
var contracts = contractsManager.listContracts(); let contracts = contractsManager.listContracts();
assert.equal(contracts.length, 2); assert.equal(contracts.length, 2);
assert.equal(contracts[0].deploy, true); assert.equal(contracts[0].deploy, true);
@ -69,7 +70,7 @@ describe('embark.Contratcs', function() {
}); });
describe('config with contract instances', function() { describe('config with contract instances', function() {
var contractsManager = new ContractsManager({ let contractsManager = new ContractsManager({
contractFiles: [ contractFiles: [
readFile('test/contracts/simple_storage.sol'), readFile('test/contracts/simple_storage.sol'),
readFile('test/contracts/token_storage.sol') readFile('test/contracts/token_storage.sol')
@ -109,7 +110,7 @@ describe('embark.Contratcs', function() {
throw err; throw err;
} }
var contracts = contractsManager.listContracts(); let contracts = contractsManager.listContracts();
assert.equal(contracts.length, 4); assert.equal(contracts.length, 4);
assert.equal(contracts[0].className, "MySimpleStorage"); assert.equal(contracts[0].className, "MySimpleStorage");
@ -126,7 +127,7 @@ describe('embark.Contratcs', function() {
//assert.equal(contracts[3].code, ''); //assert.equal(contracts[3].code, '');
//assert.equal(contracts[3].runtimeBytecode, ''); //assert.equal(contracts[3].runtimeBytecode, '');
var parentContract = contracts[2]; let parentContract = contracts[2];
//MySimpleStorage //MySimpleStorage
assert.equal(contracts[0].deploy, true); assert.equal(contracts[0].deploy, true);

View File

@ -2,6 +2,8 @@ pragma solidity ^0.4.7;
contract SimpleStorage { contract SimpleStorage {
uint public storedData; uint public storedData;
function() payable { }
function SimpleStorage(uint initialValue) { function SimpleStorage(uint initialValue) {
storedData = initialValue; storedData = initialValue;
} }

View File

@ -24,3 +24,27 @@ div {
margin-bottom: 0; margin-bottom: 0;
} }
.status-offline {
vertical-align: middle;
margin-left: 5px;
margin-top: 4px;
width: 12px;
height: 12px;
background: red;
-moz-border-radius: 10px;
-webkit-border-radius: 10px;
border-radius: 10px;
}
.status-online {
vertical-align: middle;
margin-left: 5px;
margin-top: 4px;
width: 12px;
height: 12px;
background: mediumseagreen;
-moz-border-radius: 10px;
-webkit-border-radius: 10px;
border-radius: 10px;
}

View File

@ -9,8 +9,8 @@
<ul class="nav nav-tabs" role="tablist" id="myTabs"> <ul class="nav nav-tabs" role="tablist" id="myTabs">
<li role="presentation" class="active"><a href="#blockchain" aria-controls="blockchain" role="tab" data-toggle="tab">Blockchain</a></li> <li role="presentation" class="active"><a href="#blockchain" aria-controls="blockchain" role="tab" data-toggle="tab">Blockchain</a></li>
<li role="presentation"><a href="#storage" aria-controls="storage" role="tab" data-toggle="tab">Decentralized Storage (IPFS)</a></li> <li role="presentation"><a href="#storage" aria-controls="storage" role="tab" data-toggle="tab">Decentralized Storage (IPFS)<span class="pull-right" id="status-storage"></a></li>
<li role="presentation"><a href="#communication" aria-controls="communication" role="tab" data-toggle="tab">P2P communication (whisper/orbit)</a></li> <li role="presentation"><a href="#communication" aria-controls="communication" role="tab" data-toggle="tab">P2P communication (Whisper/Orbit)<span class="pull-right" id="status-communication"></span></a></li>
</ul> </ul>
<div class="tab-content"> <div class="tab-content">
@ -37,7 +37,8 @@
</div> </div>
</div> </div>
<div role="tabpanel" class="tab-pane" id="storage"> <div role="tabpanel" class="tab-pane" id="storage">
note: You need to have an IPFS node running <div class="error alert alert-danger" role="alert">The node you are using does not support IPFS. Please ensure <a href="https://github.com/ipfs/js-ipfs-api#cors" target="_blank">CORS</a> is setup for the IPFS node.</div>
<div id="storage-controls">
<h3>Save text to IPFS</h3> <h3>Save text to IPFS</h3>
<div class="form-group form-inline"> <div class="form-group form-inline">
@ -72,11 +73,12 @@
<div class="logs"> <div class="logs">
<br> EmbarkJS.Storage.setProvider('ipfs',{server: 'localhost', port: '5001'}) <br> EmbarkJS.Storage.setProvider('ipfs',{server: 'localhost', port: '5001'})
</div> </div>
</div>
</div> </div>
<div role="tabpanel" class="tab-pane" id="communication"> <div role="tabpanel" class="tab-pane" id="communication">
<span class="error">The node you are using does not support whisper</span> <div class="error alert alert-danger" role="alert">The node you are using does not support Whisper</div>
<div class="errorVersion alert alert-danger" role="alert">The node uses an unsupported version of Whisper</div>
<div id="communication-controls">
<h3>Listen To channel</h3> <h3>Listen To channel</h3>
<div class="form-group form-inline listen"> <div class="form-group form-inline listen">
<input type="text" class="channel text form-control" placeholder="channel"> <input type="text" class="channel text form-control" placeholder="channel">
@ -97,7 +99,7 @@
<div class="logs"> <div class="logs">
<br> EmbarkJS.Messages.setProvider('whisper') <br> EmbarkJS.Messages.setProvider('whisper')
</div> </div>
</div>
</div> </div>
</div> </div>

View File

@ -28,23 +28,59 @@ $(document).ready(function() {
// Storage (IPFS) example // Storage (IPFS) example
// =========================== // ===========================
$(document).ready(function() { $(document).ready(function() {
// automatic set if config/storage.json has "enabled": true and "provider": "ipfs"
//EmbarkJS.Storage.setProvider('ipfs',{server: 'localhost', port: '5001'}); //EmbarkJS.Storage.setProvider('ipfs',{server: 'localhost', port: '5001'});
$("#storage .error").hide();
EmbarkJS.Storage.setProvider('ipfs')
.then(function(){
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){
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() { $("#storage button.setIpfsText").click(function() {
var value = $("#storage input.ipfsText").val(); var value = $("#storage input.ipfsText").val();
EmbarkJS.Storage.saveText(value).then(function(hash) { EmbarkJS.Storage.saveText(value).then(function(hash) {
$("span.textHash").html(hash); $("span.textHash").html(hash);
$("input.textHash").val(hash); $("input.textHash").val(hash);
});
addToLog("#storage", "EmbarkJS.Storage.saveText('" + value + "').then(function(hash) { })"); addToLog("#storage", "EmbarkJS.Storage.saveText('" + value + "').then(function(hash) { })");
})
.catch(function(err) {
if(err){
console.log("IPFS saveText Error => " + err.message);
}
});
}); });
$("#storage button.loadIpfsHash").click(function() { $("#storage button.loadIpfsHash").click(function() {
var value = $("#storage input.textHash").val(); var value = $("#storage input.textHash").val();
EmbarkJS.Storage.get(value).then(function(content) { EmbarkJS.Storage.get(value).then(function(content) {
$("span.ipfsText").html(content); $("span.ipfsText").html(content);
});
addToLog("#storage", "EmbarkJS.Storage.get('" + value + "').then(function(content) { })"); addToLog("#storage", "EmbarkJS.Storage.get('" + value + "').then(function(content) { })");
})
.catch(function(err) {
if(err){
console.log("IPFS get Error => " + err.message);
}
});
}); });
$("#storage button.uploadFile").click(function() { $("#storage button.uploadFile").click(function() {
@ -52,8 +88,13 @@ $(document).ready(function() {
EmbarkJS.Storage.uploadFile(input).then(function(hash) { EmbarkJS.Storage.uploadFile(input).then(function(hash) {
$("span.fileIpfsHash").html(hash); $("span.fileIpfsHash").html(hash);
$("input.fileIpfsHash").val(hash); $("input.fileIpfsHash").val(hash);
});
addToLog("#storage", "EmbarkJS.Storage.uploadFile($('input[type=file]')).then(function(hash) { })"); addToLog("#storage", "EmbarkJS.Storage.uploadFile($('input[type=file]')).then(function(hash) { })");
})
.catch(function(err) {
if(err){
console.log("IPFS uploadFile Error => " + err.message);
}
});
}); });
$("#storage button.loadIpfsFile").click(function() { $("#storage button.loadIpfsFile").click(function() {
@ -73,13 +114,21 @@ $(document).ready(function() {
$(document).ready(function() { $(document).ready(function() {
$("#communication .error").hide(); $("#communication .error").hide();
//web3.version.getWhisper(function(err, res) { $("#communication .errorVersion").hide();
// if (err) { web3.version.getWhisper(function(err, version) {
// $("#communication .error").show(); if (err) {
// } else { $("#communication .error").show();
// EmbarkJS.Messages.setProvider('whisper'); $("#communication-controls").hide();
// } $("#status-communication").addClass('status-offline');
//}); } else if (version >= 5) {
$("#communication .errorVersion").show();
$("#communication-controls").hide();
$("#status-communication").addClass('status-offline');
} else {
EmbarkJS.Messages.setProvider('whisper');
$("#status-communication").addClass('status-online');
}
});
$("#communication button.listenToChannel").click(function() { $("#communication button.listenToChannel").click(function() {
var channel = $("#communication .listen input.channel").val(); var channel = $("#communication .listen input.channel").val();
@ -98,4 +147,3 @@ $(document).ready(function() {
}); });
}); });

View File

@ -1,4 +1,5 @@
{ {
"config": {},
"nonce": "0x0000000000000042", "nonce": "0x0000000000000042",
"difficulty": "0x0", "difficulty": "0x0",
"alloc": { "alloc": {

View File

@ -14,6 +14,7 @@
"buildDir": "dist/", "buildDir": "dist/",
"config": "config/", "config": "config/",
"plugins": { "plugins": {
"embark-babel": {"files": ["**/*.js", "**/*.jsx", "!**/_vendor/*.js"]} "embark-babel": {"files": ["**/*.js", "**/*.jsx", "!**/_vendor/*.js"]},
"embark-service": {}
} }
} }

View File

@ -0,0 +1,5 @@
module.exports = function(embark) {
embark.registerServiceCheck('PluginService', function(cb) {
cb({name: "ServiceName", status: "on"});
});
};

View File

@ -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"
}

View File

@ -10,11 +10,12 @@
"license": "ISC", "license": "ISC",
"homepage": "", "homepage": "",
"devDependencies": { "devDependencies": {
"embark": "../", "embark": "file:../",
"mocha": "^2.2.5" "mocha": "^2.2.5"
}, },
"dependencies": { "dependencies": {
"embark-babel": "^1.0.0", "embark-babel": "^1.0.0",
"embark-service": "./extensions/embark-service",
"ethereumjs-testrpc": "^3.0.3" "ethereumjs-testrpc": "^3.0.3"
} }
} }

View File

@ -5,6 +5,7 @@ var web3 = EmbarkSpec.web3;
describe("AnotherStorage", function() { describe("AnotherStorage", function() {
before(function(done) { before(function(done) {
this.timeout(0);
var contractsConfig = { var contractsConfig = {
"SimpleStorage": { "SimpleStorage": {
args: [100] args: [100]

View File

@ -5,6 +5,7 @@ var web3 = EmbarkSpec.web3;
describe("SimpleStorage", function() { describe("SimpleStorage", function() {
before(function(done) { before(function(done) {
this.timeout(0);
var contractsConfig = { var contractsConfig = {
"SimpleStorage": { "SimpleStorage": {
args: [100] args: [100]

View File

@ -5,6 +5,7 @@ var web3 = EmbarkSpec.web3;
describe("Token", function() { describe("Token", function() {
before(function(done) { before(function(done) {
this.timeout(0);
var contractsConfig = { var contractsConfig = {
"SimpleStorage": { "SimpleStorage": {
args: [100] args: [100]