diff --git a/.circleci/config.yml b/.circleci/config.yml
index 8e7245369..023da9251 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -39,6 +39,16 @@ jobs:
- codecov/upload:
file: coverage.html
+ test_js:
+ machine:
+ image: circleci/classic:201808-01
+ steps:
+ - checkout
+ # js tests do not need to in docker, however nodejs crashes
+ # while running mocha when not using image above (not OOM).
+ # above image needs newer go so docker is used.
+ - run: docker-compose run burrow make npm_install test_js
+
test_integration:
machine:
image: circleci/classic:201808-01
@@ -90,6 +100,10 @@ workflows:
filters:
<<: *tags_filters
+ - test_js:
+ filters:
+ <<: *tags_filters
+
- build_docker:
filters:
# tags filters and branch filters are applied disjunctively, so we
@@ -101,6 +115,7 @@ workflows:
requires:
- test
- test_integration
+ - test_js
filters:
branches:
only: develop
@@ -109,6 +124,7 @@ workflows:
requires:
- test
- test_integration
+ - test_js
filters:
<<: *tags_filters
branches:
diff --git a/.gitignore b/.gitignore
index d086be907..e0afbb022 100644
--- a/.gitignore
+++ b/.gitignore
@@ -21,4 +21,5 @@ commit_hash.txt
tests/keys/
.output.json
-vendor/
\ No newline at end of file
+vendor/
+node_modules
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 6e0a3ed00..3b98e80ae 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,11 @@
# [Hyperledger Burrow](https://github.com/hyperledger/burrow) Changelog
-## [Unreleased]
+## [0.28.1] - 2019-08-21
+### Fixed
+- [Vent] Log for _vent_log insert now faithfully captures what is being inserted
+- [Vent] Remove arbitrary 100 character limits on system table text fields
+
+### Added
+- [JS] Burrow.js now included in Burrow repo and tested with Burrow CI! Future burrow.js releases will now match version of Burrow.
## [0.28.0] - 2019-08-14
@@ -541,7 +547,7 @@ This release marks the start of Eris-DB as the full permissioned blockchain node
- [Blockchain] Fix getBlocks to respect block height cap.
-[Unreleased]: https://github.com/hyperledger/burrow/compare/v0.28.0...HEAD
+[0.28.1]: https://github.com/hyperledger/burrow/compare/v0.28.0...v0.28.1
[0.28.0]: https://github.com/hyperledger/burrow/compare/v0.27.0...v0.28.0
[0.27.0]: https://github.com/hyperledger/burrow/compare/v0.26.2...v0.27.0
[0.26.2]: https://github.com/hyperledger/burrow/compare/v0.26.1...v0.26.2
diff --git a/Makefile b/Makefile
index ef158c612..175517765 100644
--- a/Makefile
+++ b/Makefile
@@ -174,6 +174,17 @@ solidity: $(SOLIDITY_GO_FILES)
.PHONY: solang
solang: $(SOLANG_GO_FILES)
+# node/js
+#
+# Install dependency
+.PHONY: npm_install
+npm_install:
+ npm install
+
+.PHONY: test_js
+test_js: bin/solc build_burrow
+ ./tests/scripts/bin_wrapper.sh npm test
+
# Test
.PHONY: test
diff --git a/NOTES.md b/NOTES.md
index fc4b0a62a..011cfdf4b 100644
--- a/NOTES.md
+++ b/NOTES.md
@@ -1,21 +1,7 @@
-### Changed
-- [State] IterateStreamEvents now takes inclusive start and end points (end used to be exclusive) avoid bug-prone conversion
-- [Dump] Improved structure and API
-- [Dump] Default to JSON output and use protobuf for binary output
-
### Fixed
-- [Dump] Fix dump missing events emitted at end height provided
-- [Dump] EVM events were not dumped if no height was provided to burrow dump remote commandline
-- [RPC/Info] Fix panic in /names and implement properly - now accepts a 'regex' parameter which is a regular expression to match names. Empty for all names.
-- [Configure] burrow configure flags --separate-genesis-doc and --pool now work together
+- [Vent] Log for _vent_log insert now faithfully captures what is being inserted
+- [Vent] Remove arbitrary 100 character limits on system table text fields
### Added
-- [State] Burrow now remembers contact ABIs (which describe how to pack bits when calling contracts) - burrow deploy and vent will both use chain-hosted ABI if they are available
-- [State] Bond and unbond transactions are now implement to allow validators to transfer native token into validator power.
-- [Dump] Better tests, mock, and benchmarks - suitable for profiling IAVL
-- [Events] Filters now support OR connective
-- [Vent] Projection filters can now have filters longer than 100 characters.
-- [Vent] Falls back to local ABI
-- [CLI/RPC] Contracts now hold metadata, including contract name, source file, and function names
-
+- [JS] Burrow.js now included in Burrow repo and tested with Burrow CI! Future burrow.js releases will now match version of Burrow.
diff --git a/README.md b/README.md
index 97a4d3660..ab037c674 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-# Hyperledger Burrow
+# [Hyperledger Burrow](https://hyperledger.github.io/burrow)
[![version](https://img.shields.io/github/tag/hyperledger/burrow.svg)](https://github.com/hyperledger/burrow/releases/latest)
[![GoDoc](https://godoc.org/github.com/burrow?status.png)](https://godoc.org/github.com/hyperledger/burrow)
@@ -13,7 +13,7 @@ Branch | Linux
Hyperledger Burrow is a permissioned Ethereum smart-contract blockchain node. It executes Ethereum EVM smart contract code (usually written in [Solidity](https://solidity.readthedocs.io)) on a permissioned virtual machine. Burrow provides transaction finality and high transaction throughput on a proof-of-stake [Tendermint](https://tendermint.com) consensus engine.
-![burrow logo](docs/assets/images/burrow.png)
+![burrow logo](docs/assets/burrow.png)
## What is Burrow
@@ -26,6 +26,10 @@ Hyperledger Burrow is a permissioned blockchain node that executes smart contrac
- **Application Binary Interface (ABI):** Transactions need to be formulated in a binary format that can be processed by the blockchain node. Current tooling provides functionality to compile, deploy and link solidity smart contracts and formulate transactions to call smart contracts on the chain.
- **API Gateway:** Burrow exposes REST and JSON-RPC endpoints to interact with the blockchain network and the application state through broadcasting transactions, or querying the current state of the application. Websockets allow subscribing to events, which is particularly valuable as the consensus engine and smart contract application can give unambiguously finalised results to transactions within one blocktime of about one second.
+## JavaScript Client
+
+There is a [JavaScript API](https://github.com/hyperledger/burrow/tree/develop/js)
+
## Project Roadmap
Project information generally updated on a quarterly basis can be found on the [Hyperledger Burrow Wiki](https://wiki.hyperledger.org/display/burrow).
diff --git a/docs/INSTALL.md b/docs/INSTALL.md
index 281627497..ace629217 100644
--- a/docs/INSTALL.md
+++ b/docs/INSTALL.md
@@ -1,18 +1,18 @@
-## Minimum requirements
+# Installation
-Requirement|Notes
----|---
-Go version | Go1.11 or higher
+## Binary
-## Installation
+Download a binary from our list of [releases](https://github.com/hyperledger/burrow/releases)
+and copy it to a suitable location.
-- [Install go](https://golang.org/doc/install) version 1.11 or above and have `$GOPATH` set
+
+## Source
+
+[Install Go](https://golang.org/doc/install) (Version >= 1.11) and set `$GOPATH`.
```
go get github.com/hyperledger/burrow
cd $GOPATH/src/github.com/hyperledger/burrow
-# We need to force enable module support to build from within GOPATH (our protobuf build depends on path, otherwise any checkout location should work)
-export GO111MODULE=on
make build
```
@@ -20,3 +20,21 @@ This will build the `burrow` binary and put it in the `bin/` directory. It can b
You can also install `burrow` into `$BIN_PATH/bin` with `make install`, where `$BIN_PATH` defaults to `$HOME/go/bin`
if not set in environment.
+
+
+## Docker
+
+Each release is also tagged and pushed to [Docker Hub](https://hub.docker.com/r/hyperledger/burrow).
+This can act as a direct replacement for the burrow binary, for example the following commands are equivalent:
+
+```bash
+burrow spec -v4
+docker run hyperledger/burrow spec -v4
+```
+
+Note: ensure to mount local volumes for secrets / configurations when running a container to prevent data loss.
+
+## Kubernetes
+
+Use our official [helm charts](https://github.com/helm/charts/tree/master/stable/burrow) to configure and run
+a burrow chain in your cluster.
\ No newline at end of file
diff --git a/docs/README.md b/docs/README.md
index 15d0abbbd..1618b605a 100644
--- a/docs/README.md
+++ b/docs/README.md
@@ -2,9 +2,9 @@
Hyperledger Burrow is a permissioned Ethereum smart-contract blockchain node. It executes Ethereum EVM smart contract code (usually written in [Solidity](https://solidity.readthedocs.io)) on a permissioned virtual machine. Burrow provides transaction finality and high transaction throughput on a proof-of-stake [Tendermint](https://tendermint.com) consensus engine.
-![burrow logo](assets/images/burrow.png)
+![burrow logo](assets/burrow.png)
-## What is Burrow
+## What is Burrow?
Hyperledger Burrow is a permissioned blockchain node that executes smart contract code following the Ethereum specification. Burrow is built for a multi-chain universe with application specific optimization in mind. Burrow as a node is constructed out of three main components: the consensus engine, the permissioned Ethereum virtual machine and the rpc gateway. More specifically Burrow consists of the following:
diff --git a/docs/_sidebar.md b/docs/_sidebar.md
index 2598a6a08..8363c87de 100644
--- a/docs/_sidebar.md
+++ b/docs/_sidebar.md
@@ -1,15 +1,20 @@
- Burrow
- [Introduction](README.md)
- [Installation](INSTALL.md)
+ - [JS API](js-api.md)
+
+- Transactions
+ - [Bond / Unbond](txs/bond.md)
+
- Tutorials
- - [Single Node](quickstart/single-full-node.md)
- - [Send Transactions](quickstart/send-transactions.md)
- - [Deploy Contracts](quickstart/deploy-contracts.md)
- - [Multiple Validators](quickstart/multiple-validators.md)
- - [Add Validators](quickstart/bonding-validators.md)
- - [Seed Nodes](quickstart/seed-nodes.md)
- - [Dump-Restore](quickstart/dump-restore.md)
- - [Kubernetes](https://github.com/helm/charts/tree/master/stable/burrow)
+ - [Single Node](tutorials/1-run-full-node.md)
+ - [Send Transactions](tutorials/2-send-transactions.md)
+ - [Deploy Contracts](tutorials/3-deploy-contracts.md)
+ - [Multiple Validators](tutorials/4-multiple-validators.md)
+ - [Bonding](tutorials/5-bonding-validators.md)
+ - [Seed Nodes](tutorials/6-seed-nodes.md)
+ - [Dump / Restore](tutorials/7-dump-restore.md)
+
- Reference
- [Genesis](reference/genesis.md)
- [Logging](reference/logging.md)
diff --git a/docs/assets/images/burrow.png b/docs/assets/burrow.png
similarity index 100%
rename from docs/assets/images/burrow.png
rename to docs/assets/burrow.png
diff --git a/docs/assets/adr-1/burrow-logo.png b/docs/assets/logo.png
similarity index 100%
rename from docs/assets/adr-1/burrow-logo.png
rename to docs/assets/logo.png
diff --git a/docs/index.html b/docs/index.html
index ae986d73c..5ce369952 100644
--- a/docs/index.html
+++ b/docs/index.html
@@ -2,9 +2,9 @@
- Document
+ Hyperledger Burrow
-
+
@@ -14,8 +14,10 @@
window.$docsify = {
name: 'Hyperledger Burrow',
repo: 'https://github.com/hyperledger/burrow',
+ auto2top: true,
loadSidebar: true,
- subMaxLevel: 2
+ subMaxLevel: 2,
+ themeColor: '#3FBB86'
}
diff --git a/docs/js-api.md b/docs/js-api.md
new file mode 100644
index 000000000..b58083d5c
--- /dev/null
+++ b/docs/js-api.md
@@ -0,0 +1,523 @@
+# JS API
+
+Burrow has a JavaScript API for communicating with a [Hyperledger Burrow](https://github.com/hyperledger/burrow) server, which implements the GRPC spec.
+
+## Prerequisites
+
+- Burrow version 0.20 or higher
+- Node.js version 7 or higher
+
+You can check the installed version of Node.js with the command:
+
+```bash
+$ node --version
+```
+
+If your distribution of Linux has a version older than 6 then you can update it.
+
+## Install
+
+``` bash
+$ npm install @monax/burrow
+```
+
+## Usage
+
+You will need to know the : of the burrow instance you wish to connect to. If running locally this will be 'localhost' and the default port, which is '10997'. DO NOT INCLUDE A PROTOCOL.
+
+The main class is `Burrow`. A standard `Burrow` instance is created like this:
+
+```JavaScript
+const monax = require('@monax/burrow');
+var burrowURL = ":"; // localhost:10997 if running locally on default port
+var account = 'ABCDEF01234567890123'; // address of the account to use for signing, hex string representation
+var options = {objectReturn: true};
+var burrow = monax.createInstance(burrowURL, account, options);
+```
+
+The parameters for `createInstance` is the server URL as a string or as an object `{host:, port:}`. An account in the form of a hex-encoded address must be provided.
+
+> Note: the instance of burrow you are connecting to must have the associated key (if you want local signing you should be running a local node of burrow. Other local signing options might be made available at a later point).
+
+And finally an optional options object. Allowed options are:
+
+* objectReturn: If True, communicating with contracts an object returns an object of the form: `{values:{...}, raw:[]}` where the values objects attempts to name the returns based on the abi and the raw is the decoded array of return values. If False just the array of decoded return values is returned.
+
+
+## API Reference
+
+There are bindings for all the GRPC methods. All functions are on the form `function(param1, param2, ... [, callback])`, where the callback is a function on the form `function(error, data)`. The `data` object is the same as you would get by calling the corresponding RPC method directly. If no callback is provided, a promise will be returned instead. If calling a response streaming GRPC call, the callback is not optional and will be called with `data` anytime it is recieved.
+
+The structure of the library is such that there are lower-level access to the GRPC services and higher level wrappers of these services. The structure of the library is outlined below
+
+### Burrow
+
+The table below links to the reference schema for either the protobuf files governing the component or the Javascript interface.
+
+| Component Name | Accessor |
+| :----------- | :--------------- |
+| Transactions | [Burrow.transact](https://github.com/hyperledger/burrow/blob/develop/protobuf/rpctransact.proto) |
+| Queries | [Burrow.query](https://github.com/hyperledger/burrow/blob/develop/protobuf/rpcquery.proto) |
+| EventStream | [Burrow.eventStream](https://github.com/hyperledger/burrow/blob/develop/protobuf/rpcevents.proto) |
+| Events | [Burrow.events](https://github.com/hyperledger/burrow/blob/develop/lib/events.js) |
+| NameReg | [Burrow.namereg](https://github.com/hyperledger/burrow/blob/develop/lib/namereg.js) |
+
+| Contracts | [Burrow.contracts](https://github.com/hyperledger/burrow/blob/develop/lib/contractManager.js) |
+
+### GRPC Access Components
+
+Burrow provides access to three GRPC services; Transactions, Queries, and ExecutionEvents in the form of automatically generated code endpoints. Below details how to access these methods and links to the request and return objects defined in the protobuf specs. The format for all calls is `function(object[, callback])` The callback is optional for non-streaming endpoints in which case a promise will be returned.
+
+#### Sending Funds and Creating Accounts
+
+In Burrow an account must already exist in order to be used as a input account (the sender of a transaction). An account can be created once the chain is running (accounts at genesis can be described in the genesis document in the accounts section) in the following ways:
+
+1. Issuing a `SendTx` to the address to be created (see below) - where the input account must have both the `Send` and `CreateAccount` permission.
+2. Sending value to the address to created from a smart contract using the CALL opcode - where the caller contract must have the `CreateAccount` permission.
+3. Issuing a `GovTx` where accounts can be created/updated in bulk provided the input has the `Root` permission.
+
+The conventional way to create an new account to use as an input for transactions is the following:
+
+First create a key - you will want to create an account for which you have access to the private key controlling that account (as defined by the address of the public key):
+
+```shell
+# Create a new key against the key store of a locally running Burrow (or burrow keys standalone server):
+$ address=$(burrow keys gen -n --name NewKey)
+
+# The address will be printed to stdout so the above captures it in $address, you can also list named keys:
+$ burrow keys list
+Address:"6075EADD0C7A33EE6153F3FA1B21E4D80045FCE2" KeyName:"NewKey"
+```
+
+Note creating the key _does not_ create the account - it just generates a key pair in your local key store (it is not in anyway known the blockchain network).
+
+Now we would like to use a `SendTx` to create the address, here's how to do that in Javscript:
+
+```javascript
+// Using account and burrow defined in snippet from [Usage](#usage)
+
+// Address we want to create
+var addressToCreate = "6075EADD0C7A33EE6153F3FA1B21E4D80045FCE2"
+
+// The amount we send is arbitrary
+var amount = 20
+
+burrow.transact.SendTxSync(
+ {
+ Inputs: [{
+ Address: Buffer.from(account, 'hex'),
+ Amount: amount
+ }],
+ Outputs: [{
+ Address: Buffer.from(addressToCreate, 'hex'),
+ Amount: amount
+ }]
+ })
+ .then(txe => console.log(txe))
+ .catch(err => console.error(err))
+```
+
+The return `txe` (short for `TxExecution`) logged to the console in the `then` block contains the history and fingerprint of the `SendTx` execution. You can see an example of this in [basic app](../example/basic-app/app.js).
+
+#### NameReg access
+
+Here is an example of usage in setting and getting a name:
+
+```javascript
+var setPayload = {
+ Input: {
+ Address: Buffer.from(account,'hex'),
+ Amount: 50000
+ },
+ Name: "DOUG",
+ Data: "Marmot",
+ Fee: 5000
+}
+
+var getPayload = {Name: "DOUG"}
+
+// Using a callback
+burrow.transact.NameTxSync(setPayload, function(error, data){
+ if (error) throw error; // or something more sensible
+ // data object contains detailed information of the transaction execution.
+
+ // Get a name this time using a promise
+ burrow.query.GetName(getPayload)
+ .then((data) => {console.log(data);}) // should print "Marmot"
+ .catch((error)=> {throw error;})
+})
+
+```
+
+#### Transactions
+
+`burrow.transact` provides access to the burrow GRPC service `rpctransact`. As a GRPC wrapper all the endpoints take a data argument and an optional callback. The format of the data object is specified in the [rpctransact protobuf file](./protobuf/rpctransact.proto). A note on RPC naming, any method which ends in `Sync` will wait until the transaction generated is included in a block. Any `Async` method will return a receipt of the transaction immediately but does not guarantee it has been included. `Sim` methods request that the transaction be simulated and the result returned as if it had been executed. SIMULATED CALLS DO NOT GET COMMITTED AND DO NOT CHANGE STATE.
+
+| Method | Passed | Returns |
+| :----- | :--------- | :---- |
+| burrow.transact.BroadcastTxSync | [TxEnvelopeParam](https://github.com/hyperledger/burrow/blob/develop/protobuf/rpctransact.proto#L74-L79) | [TxExecution](https://github.com/hyperledger/burrow/blob/develop/protobuf/exec.proto#L34-L56) |
+| burrow.transact.BroadcastTxASync | [TxEnvelopeParam](https://github.com/hyperledger/burrow/blob/develop/protobuf/rpctransact.proto#L74-L79) | [Receipt](https://github.com/hyperledger/burrow/blob/develop/protobuf/txs.proto#L38-L47) |
+| burrow.transact.SignTx | [TxEnvelopeParam](https://github.com/hyperledger/burrow/blob/develop/protobuf/rpctransact.proto#L74-L79) | [TxEnvelope](https://github.com/hyperledger/burrow/blob/develop/protobuf/rpctransact.proto#L70-L72) |
+| burrow.transact.FormulateTx | [PayloadParam](https://github.com/hyperledger/burrow/blob/develop/protobuf/rpctransact.proto#L64-L68) | [TxEnvelope](https://github.com/hyperledger/burrow/blob/develop/protobuf/rpctransact.proto#L70-L72) |
+| burrow.transact.CallTxSync | [CallTx](https://github.com/hyperledger/burrow/blob/develop/protobuf/payload.proto#L53-L66) | [TxExecution](https://github.com/hyperledger/burrow/blob/develop/protobuf/exec.proto#L34-L56) |
+| burrow.transact.CallTxAsync | [CallTx](https://github.com/hyperledger/burrow/blob/develop/protobuf/payload.proto#L53-L66) | [Receipt](https://github.com/hyperledger/burrow/blob/develop/protobuf/txs.proto#L38-L47) |
+| burrow.transact.CallTxSim | [CallTx](https://github.com/hyperledger/burrow/blob/develop/protobuf/payload.proto#L53-L66) | [TxExecution](https://github.com/hyperledger/burrow/blob/develop/protobuf/exec.proto#L34-L56) |
+| burrow.transact.SendTxSync | [SendTx](https://github.com/hyperledger/burrow/blob/develop/protobuf/payload.proto#L69-L76) | [TxExecution](https://github.com/hyperledger/burrow/blob/develop/protobuf/exec.proto#L34-L56) |
+| burrow.transact.SendTxAsync | [SendTx](https://github.com/hyperledger/burrow/blob/develop/protobuf/payload.proto#L69-L76) | [Receipt](https://github.com/hyperledger/burrow/blob/develop/protobuf/txs.proto#L38-L47) |
+| burrow.transact.NameTxSync | [NameTx](https://github.com/hyperledger/burrow/blob/develop/protobuf/payload.proto#L88-L98) | [TxExecution](https://github.com/hyperledger/burrow/blob/develop/protobuf/exec.proto#L34-L56) |
+| burrow.transact.NameTxAsync | [NameTx](https://github.com/hyperledger/burrow/blob/develop/protobuf/payload.proto#L88-L98) | [Receipt](https://github.com/hyperledger/burrow/blob/develop/protobuf/txs.proto#L38-L47) |
+
+
+#### Queries
+
+`Burrow.query` provides access to the burrow GRPC service `rpcquery`. As a GRPC wrapper all the endpoints take a data argument and an optional callback. The format of the data object is specified in the [protobuf files](https://github.com/hyperledger/burrow/tree/develop/js/protobuf). Note that "STREAM" functions take a callback `function(error, data)` which is mandatory and is called any time data is returned. For list Accounts the queryable tags are Address, PublicKey, Sequence, Balance, Code, Permissions (Case sensitive). As an example you can get all accounts with a balance greater than 1000 by `burrow.query.ListAccounts('Balance > 1000', callback)`. Multiple tag criteria can be combined using 'AND' and 'OR' for an example of a combined query see [here](https://github.com/hyperledger/burrow/blob/develop/protobuf/rpcevents.proto#L87). Similarly for ListNames, the avaible tags are Name, Data, Owner and Exires (once again case sensitive) use is identical to List accounts.
+
+| Method | Passed | Returns | Notes |
+| :----- | :--------- | :---- | :------- |
+| burrow.query.GetAccount | [GetAccountParam](https://github.com/hyperledger/burrow/blob/develop/protobuf/rpcquery.proto#L25-L27) | [ConcreteAccount](https://github.com/hyperledger/burrow/blob/develop/protobuf/acm.proto#L23-L31) | |
+| burrow.query.ListAccounts | [ListAccountsParam](https://github.com/hyperledger/burrow/blob/develop/protobuf/rpcquery.proto#L29-L31) | [ConcreteAccount](https://github.com/hyperledger/burrow/blob/develop/protobuf/acm.proto#L23-L31) | STREAM |
+| burrow.query.GetNameParam | [GetNameParam](https://github.com/hyperledger/burrow/blob/develop/protobuf/rpcquery.proto#L33-L35) | [Entry](https://github.com/hyperledger/burrow/blob/develop/protobuf/names.proto#L22-L32) | |
+| burrow.query.ListNames | [ListNamesParam](https://github.com/hyperledger/burrow/blob/develop/protobuf/rpcquery.proto#L37-L39) | [Entry](https://github.com/hyperledger/burrow/blob/develop/protobuf/names.proto#L22-L32) | STREAM|
+
+#### EventStream
+
+NB: When listening to contract events it is easier to use the contract interface (described below)
+
+`Burrow.executionEvents` provides access to the burrow GRPC service `ExecutionEvents`. As a GRPC wrapper all the endpoints take a data argument and an optional callback. The format of the data object is specified in the [protobuf files](https://github.com/hyperledger/burrow/tree/develop/js/protobuf). Note that "STREAM" functions take a callback `function(error, data)` which is mandatory and is called any time data is returned.
+
+| Method | Passed | Returns | Notes |
+| :----- | :--------- | :---- | :------- |
+| burrow.executionEvents.GetBlock | [GetBlockRequest](https://github.com/hyperledger/burrow/blob/develop/protobuf/rpcevents.proto#L37-L42) | [BlockExecution](https://github.com/hyperledger/burrow/blob/develop/protobuf/exec.proto#L20-L27) | |
+| burrow.executionEvents.GetBlocks | [BlocksRequest](https://github.com/hyperledger/burrow/blob/develop/protobuf/rpcevents.proto#L51-L89) | [BlockExecution](https://github.com/hyperledger/burrow/blob/develop/protobuf/exec.proto#L20-L27) | STREAM |
+| burrow.executionEvents.GetTx | [GetTxRequest](https://github.com/hyperledger/burrow/blob/develop/protobuf/rpcevents.proto#L44-L49) | [TxExecution](https://github.com/hyperledger/burrow/blob/develop/protobuf/exec.proto#L34-L56) | |
+| burrow.executionEvents.GetTxs | [BlocksRequest](https://github.com/hyperledger/burrow/blob/develop/protobuf/rpcevents.proto#L51-L89) | [GetTxsResponse](https://github.com/hyperledger/burrow/blob/develop/protobuf/rpcevents.proto#L96-L99) | STREAM |
+| burrow.executionEvents.GetEvents | [BlocksRequest](https://github.com/hyperledger/burrow/blob/develop/protobuf/rpcevents.proto#L51-L89) | [GetEventsResponse](https://github.com/hyperledger/burrow/blob/develop/protobuf/rpcevents.proto#L91-L94) | STREAM |
+
+
+***
+
+### High-Level Components
+
+In addition to direct access to the grpc services, the burrow object also provides access to *three* higher level components which wrap the low level access for convenience. These are ```.namereg```, ```.events```, and ```.contracts```. All high level components use the account provided during creation of the burrow instance for constructing transactions. Component ```contracts``` is the most important of the three, as events and namereg are really just helpful wrappers.
+
+
+#### 1. Namereg
+
+`burrow.namereg` is a convenience wrapper for setting and getting entries from the name registry.
+
+##### burrow.namereg.get
+```burrow.namereg.get(name[,callback])```
+
+Gets an entry stored at the name. It returns a promise if callback not provided.
+###### Parameters
+1. `String` - Name you wish to retrieve from the namereg
+2. `function` - (optional) Function to call upon completion of form `function(error, data)`.
+###### Returns
+`Object` - The return data object is of the form:
+
+```javascript
+{
+ Name: (registered name) (string)
+ Owner: (address of name owner) (buffer)
+ Data: (stored data) (string)
+ Expires: (block at which entry expires) (int)
+}
+```
+
+##### burrow.namereg.set
+```burrow.namereg.set(name, data, lease[, callback])```
+
+Sets an entry in the namereg. It returns a promise if callback not provided.
+###### Parameters
+1. `String` - The name you wish to register
+2. `String` - The string data you wish to store at the registered name (longer string = larger fee)
+3. `int` - The number of blocks to register the name for (more blocks = larger fee)
+4. `function` - (optional) Function to call upon completion of form `function(error, data)`.
+###### Returns
+`TxExecution` - The return data object is a [TxExecution](https://github.com/hyperledger/burrow/blob/develop/protobuf/exec.proto#L34-L56).
+###### Example
+
+```javascript
+// Using a callback
+burrow.namereg.set("DOUG", "Marmot", 5000, function(error, data){
+ if (error) throw error; // or something more sensible
+ // data object contains detailed information of the transaction execution.
+
+ // Get a name this time using a promise
+ burrow.namereg.get("DOUG")
+ .then((data) => {console.log(data);}) // Should print "Marmot"
+ .catch((error)=> {throw error;})
+})
+```
+
+> Note: this example is nearly identical to the example above except that the objects are not explicitly constructed by you.
+
+
+
+#### 2. Events
+
+`burrow.events` contains convenience wrappers for streaming executionEvents.
+
+##### burrow.events.listen
+```burrow.events.listen(query, options, callback)```
+
+Listens to execution events which satisfy the filter query.
+###### Parameters
+1. `String` - a pegjs querystring for filtering the returned events see [here]() for grammar specification
+2. `Object` - Currently unused. pass `{}`
+3. `function` - Signature of `function(error, data)` mandatory
+###### Returns
+`GetEventsResponse` - The return data object is a [GetEventsResponse](https://github.com/hyperledger/burrow/blob/develop/protobuf/rpcevents.proto#L91-L94)
+
+
+
+##### burrow.events.subContractEvents
+```burrow.events.subContractEvents(address, signature, options, callback)```
+
+Listens to EVM event executions from specific contract.
+###### Parameters
+1. `String` - hex string of the contract address of interest
+2. `String` - event abi signature
+3. `Object` - Currently unused. pass `{}`
+4. `function` - Signature of `function(error, data)` mandatory.
+###### Returns
+`GetEventsResponse` - The return data object is a [GetEventsResponse](https://github.com/hyperledger/burrow/blob/develop/protobuf/rpcevents.proto#L91-L94)
+
+
+
+#### 3. Contracts
+
+`burrow.contracts` is arguably the most important component of the burrow it exposes two functions, `.deploy` and `.new` both of which return a Contract interface object (sometimes refered to as contract object). The difference between them is that `new` simply creates an interface to a contract and `deploy` will first create an instance and then deploy a copy of it to the blockchain.
+
+
+##### burrow.contracts.deploy
+```burrow.contracts.deploy(abi, bytecode, params... [, callback])```
+
+Deploys a contract and returns a contract interface either to the callback or a promise once deploy is successful. It returns a promise if callback not provided.
+
+When the contract interface object is created via deploy, the default address is set to the address of the deployed contract (which can be accessed as contract.address). This interface object can still be used as a generic interface but care must be taken to use the `.at()` and `.atSim()` versions of functions.
+
+###### Parameters
+1. `Object` - the object corresponding to the json ABI of the contract you wish to interface with.
+2. `String` - Hex encoded string of bytecode of the contract to deploy
+3. `params` - arguments to the constructor function (if there are any)
+4. `function` - (optional) Format of `function(error, contract)` where contract is the contract interface object.
+###### Returns
+`Object` - The return data object is a contract interface, which refers to the contract which is deployed at `contract.address`. (This functionality used to be called `new`.)
+
+##### burrow.contracts.new
+```burrow.contracts.address(address)```
+
+Returns a new contract interface object, without having to pass in the ABI. The ABI is retrieved from burrow; the contract must have been deployed with burrow deploy 0.28.0 or later.
+
+###### Parameters
+3. `String` - Hex encoded address of the default contract you want the interface to access
+###### Returns
+`Object` - The return data object is a contract interface.
+
+##### burrow.contracts.new
+```burrow.contracts.new(abi, [bytecode[, address]])```
+
+Returns a new contract interface object. All you really need to create an interface is the abi, however you can also include the bytecode of the contract. If you do so you can create new contracts of this type by calling `contract._constructor(...)` which will deploy a new contract and return its address. If you provide an address, then this will be the default contract address used however you can also omit this at be sure to use the `.at()` and `.atSim()` versions of functions. Also note you must provide bytecode is you wish to provide address, though bytecode argument can be null.
+
+###### Parameters
+1. `Object` - the object corresponding to the json ABI of the contract you wish to interface with.
+2. `String` - Hex encoded string of bytecode of the contract to deploy
+3. `String` - (optional) Hex encoded address of the default contract you want the interface to access
+###### Returns
+`Object` - The return data object is a contract interface.
+
+
+#### 3.1. Contract interface object
+
+The contract interface object allows for easy access of solidity contract function calls and subscription to events. When created, javascript functions for all functions specified in the abi are generated. All of these functions have the same form `Contract.functionname(params...[, callback])`, where `params` are the arguments to the contract constructor. Arguments of the "bytes" type should be properly hex encoded before passing, to avoid improper encoding. If a callback is not provided a promise is returned.
+
+> Note: if the burrow object was created with ```{objectReturn: True}``` the return from these function calls is formatted as `{values:{...}, raw:[]}` otherwise an array of decoded values is provided. The values object names the decoded values according to the abi spec, if a return value has no name it won't be included in the values object and must be retrieved from its position on the raw array.
+
+
+In the case of a REVERT op-code being called in the contract function call, an error will be passed with the revert string as the `.message` field. These errors can be distinguished from other errors as the `.code` field will be `ERR_EXECUTION_REVERT`.
+
+In addition to the standard function call, there are three other forms: `contract.functionname.sim`, `contract.functionname.at`, `contract.functionname.atSim`.
+
+
+##### contract.functionname.sim
+```contract.functionname.sim(params... [, callback])```
+
+The "Sim" forms will force a simulated call so that does not change state. Although, the data returned is identical to what would have been returned if the call had been submitted. Useful for querying data or checking if a transaction passes some tests.
+###### Parameters
+1. `params` - the arguments to the function (if there are any)
+2. `function`- (optional) Function to call upon completion of form `function(error, data)`.
+
+
+
+##### contract.functionname.at
+```contract.functionname.at(address, params... [, callback])```
+
+The "at" forms allow you to specify which contract you wish to submit the transaction to. This allows you to use a single contract interface instance to access any contract with the same abi. Useful if for example there is a factory contract on the chain and you wish to connect to any of its children. The at forms MUST be used if a default address was not provided or created.
+###### Parameters
+1. `String` - Hex encoded address of the default contract you want the interface to access
+2. `params` - the arguments to the function (if there are any)
+3. `function`- (optional) Function to call upon completion of form `function(error, data)`.
+
+
+
+##### contract.functionname.atSim
+```contract.functionname.at(address, params... [, callback])```
+
+
+###### Parameters
+1. `String` - Hex encoded address of the default contract you want the interface to access
+2. `params` - the arguments to the function (if there are any)
+3. `function`- (optional) Function to call upon completion of form `function(error, data)`
+
+
+##### contract._constructor
+```contract._constructor(params... [, callback])```
+
+Deploys a new contract from the same interface (no need to create a new interface object via .deploy). Once completed it will return the created contract's address.
+
+
+###### Parameters
+1. `params` - the arguments to the function (if there are any)
+3. `function`- (optional) Function to call upon completion of form `function(error, data)`.
+###### Returns
+`String` - The return data String is the created contract's address.
+
+
+#### 3.2. Encoding and Decoding Params
+
+Occassionally you may wish to encode the parameters to a function call but not actually make the call. The most common use of this is in forwarding contracts which take pre-encoded arguments along with function signature bytes and then call another function passing that data for specifying the call.
+
+The Contract interface object supports this use case through `Contract.functionname.encode(...args)` which will return a hex string with the encoded arguments. This functionality is also available through `Monax.utils.encode(abi, functionname, ...args)`. In addition the complement also exists, `Contract.functionname.decode(data)` will produce the return object as if the data was just returned from a call.
+
+
+#### 3.3. Contract Events
+
+##### contract.eventname
+```contract.eventname(callback)```
+
+The contract interface object exposes subscription to Solidity events under event's name.
+ where the provided callback with be passed an error and data of the form:
+
+###### Parameters
+1. `function` - Function to call upon completion of form `function(error, data)`. The data object has the following form:
+```
+{
+ event: [fulleventname],
+ address: [address of contract emitting event],
+ args: {argname: argvalue}
+}
+```
+
+
+##### contract.eventname.at
+```contract.eventname.at(address, callback)```
+
+Similarly to functions' contract it is possible to start listening to a non-default contract address.
+
+###### Parameters
+1. `String` - hex string of the contract address of interest
+2. `function` - Function to call upon completion of form `function(error, data)`. The data object has the following form:
+```
+{
+ event: [fulleventname],
+ address: [address of contract emitting event],
+ args: {argname: argvalue}
+}
+```
+
+
+
+
+### Example:
+
+The following contract is a simple contract which takes a "name" to the constructor and also has a function `getName` which returns the name.
+
+````solidity
+pragma solidity ^0.4.18;
+contract SimpleContract {
+
+ string private name;
+
+ function SimpleContract(string _newName) public {
+ name = _newName;
+ }
+
+ function getName() public constant returns (string thename) {
+ return name;
+ }
+
+}
+````
+
+Here I provide an example of communicating to the contract above from start to finish:
+
+```javascript
+const monax = require('@monax/burrow');
+const assert = require('assert');
+
+var burrowURL = ":"; // localhost:10997 if running locally on default port
+var account = 'ABCDEF01234567890123'; // address of the account to use for signing, hex string representation
+var options = {objectReturn: false};
+var burrow = monax.createInstance(burrowURL, account, options);
+
+// Get the contractABIJSON from somewhere such as solc
+var abi = json.parse(contractABIJSON) // Get the contractABIJSON from somewhere such as solc
+var bytecode = contractBytecode // Get this from somewhere such as solc
+
+
+
+// I'm going to use new to create a contract interface followed by a double direct call to the _constructor to deploy two contracts
+const contract = burrow.contracts.new(abi, bytecode);
+return Promise.all( // Deployment of two contracts
+ [
+ contract._constructor('contract1'),
+ contract._constructor('contract2')
+ ]
+).then( ([address1, address2]) => { // Collection of contracts' addresses
+ console.log(address1 + " - contract1");
+ console.log(address2 + " - contract2");
+ return Promise.all( // Execution of getName functions
+ [
+ contract.getName.at(address1), // Using the .at() to specify the second deployed contract
+ contract.getName.at(address2)
+ ]
+ ).then( ([name1, name2]) => { // Collection of contracts' names
+ console.log(address1 + " - " + name1);
+ assert.equal(name1, 'contract1');
+ console.log(address2 + " - " + name2);
+ assert.equal(name2, 'contract2');
+ });
+});
+```
+
+
+
diff --git a/docs/js-design.md b/docs/js-design.md
new file mode 100644
index 000000000..ed2d8fa33
--- /dev/null
+++ b/docs/js-design.md
@@ -0,0 +1,65 @@
+Hello unfortunate inheritor of the JS libs,
+
+Please forgive me, I did my best. This note is an attempt to explain the structure and decisions that led to burrow.js having the form it does.
+
+First the high level overview. Burrow.js is the javascript interface to connect to, and communicate with a burrow chain. Burrow exposes a GRPC interface which at the lowest level this library wraps. Burrow, if you are unaware, runs an EVM implementation which allows us to use solidity as the smart contract language. This choice however means that in order to be useful we need to format data being passed to the grpc endpoints to be packed according to the ABI of the contract in question. So the overarching goal of this library is to handle:
+
+1. Connecting to burrow
+2. Allow the deployment of, or connection to contracts
+3. Provide objects which have attached functions facilitating the ability to call contract functions from javascript and hide the intermediate steps
+4. Allow listening to event coming from the chain as well as query non contract data from burrow (name registry for example)
+
+
+## Connecting to Burrow
+
+The index.js file is what is loaded when burrow.js is required. It simply loads up the Burrow file which is responsible for actually creating connection objects to Burrow. It also for convenience exposes the createinstance function which returns the Burrow connection object and the utils file which simply contains some ease of use functions. There has been a push to remove some of these exposed util functions as it is felt that they shouldn’t be relied upon. However they have been inherited from the oldest versions of the js libraries so they have remained for the time being to avoid surprises from removing them.
+
+## lib/Burrow.js
+
+This is the main object for connecting to Burrow is here, along with a helpful creator function which returns it. Note that three things are needed for this, first a url for Burrow which if using the creator function can be either an object with host and port or just a string. An account which will be used by this connection for all calls to burrow that require them (including contract calls) and an options object which is solely used by the contract manager.
+
+During creation first the connection to the various GRPC services are set up, the Service object is a wrapper of the GRPC library that will bind copies of the grpc functions after they have been wrapped to tha same names as before. Its honestly a bit opaque and its main purpose is to make setting up listeners on streaming grpc channels easier. If you want to remove it, go for it, you will need to update the handling of all streaming endpoints in namereg, events etc.
+The Burrow connection object exposes all of the low level GRPC functions (in case a user wants direct access to them) but also provides some high level interfaces as well. Namely to events, name registry and most usefully contracts.
+
+There is also the creation of a pipe object which might seem bizarre as it simply wraps other functions from the various services. The pipe is another old piece that has been left solely for ease of a feature that was discussed occasionally but never implemented. Namely that the JS libs we have implemented might be compatible with the main ethereum project. The idea was that if the pipe could serve as an interface from the contract manager to the lower level resources then another pipe could be written that would interface to different low level resources such as those connecting to ethereum. This work stalled though and never progressed. There also did not seem to be a huge need for that functionality.
+
+Events and namereg are both just wrappers of lower level services to ease calling them.
+
+
+
+## Contract manager
+
+Contracts are arguably the most important piece of the lib. In order to successfully make a call to an on chain contract a series of steps must be followed. First the ABI of the contract’s function you are calling is needed in order to properly format the arguments to the function in a byte string. Second the formatting must actually take place along with constructing the payload. formatting the data is actually performed by ethereum-js but in order to use it correctly, some pre-formatting of the arguments is required. The payload for the query is sent to burrow either to the “call” or “transact” endpoints of the burrow server. The server will process the payload and then send back the result which will often include return data which must then be processed into return objects and passed to the original caller either in a promise or a callback.
+
+Events are another important part of contracts but luckily much simpler. for events you simply pass a handler which will listen to the event stream of all events matching the pegjs query string. the data is similarly unpacked.
+
+Now for some more detail. All of the contract interfacing code is located in /lib/contracts however the so-called “contract manager” which operates as a contract object constructor is located at /lib/contractmanager.js. There are three files in /lib/contracts/, contract.js, function.js, and event.js. contract.js is the code that constructs the actual contract object that will often be passed around in the user code.
+
+Contract creation is handled by the contract manager (accessible to the user at burrow.contracts) which has two main functions, .new and .deploy. Contract objects should be thought of as interfaces to an abi type which will have a default contract address (sometimes) which calls and queries will go to, however as an interface it will also expose the ability to supply an address which will override the default if there is any. The idea is that if you have a bunch of contracts which all have the same abi, there is no reason you should need to create a new object for each contract on chain. This is particularly true for contract which come from contract factories as they will by definition all have the same abi. The difference between deploy and new then is simply what occurs before the contract object is returned. With deploy, bytecode for the contract is provided alongside the abi and a new contract is created on the chain first. A contract object is then created which points to this newly created contract by default. new on the other hand will not make any calls to the burrow and will just create a contract object immediately. This means deploy is asynchronous and new is synchronous. A default address can be provided to new which will then be used by future calls.
+
+You will notice some code here dedicated to “handlers” which are passed as an object with two named fields holding functions call and con. Their purpose is to process the return from either calls or contract creation (CONstructor) before being returned to the end user. Note that these handlers will be run after all function calls to that contract object, they also can be provided as an option to the burrow object creation or directly. If a per function handler is desired it was decided that this should be handled by simply using promise chaining for that particular function rather than attempt a complicated name matching procedure.
+
+contract.js as previously mentioned holds the contract object definition itself. During creation of a contract object, the abi and sometimes byte code is saved followed by dynamically adding the functions and events as callable objects by name. This is done in the addFunctionsToContract and addEventsToContract functions. Taking a look at the addFunctions functions we see that multiple objects are returned from a call to create a solidity function. the displayname and typename are only for the dynamic assignment of the function to the contract object, call, encode and decode are the meat of what will be attached. Call performs all the steps of encoding the data sending it to burrow and decoding the response. However due to the use of proxy contracts (contracts which can call other arbitrary contracts) it was important to be able to access the encoding and decoding functionalities on their own so the payload could be encoded and then sent to the proxy contract as an argument.
+
+These functions are bound to the contract object (so they can all use this. properties of the contract object such as the pipe and address). In addition there are multiple types of calls. for example two main types are calls (transactions) and simulated calls the difference being how burrow handles them. These cases are handled by providing a boolean indicating if the call should be simulated or not. If simulated no changes are made to the chain state. Since these have identical payload structures its easiest to simply provide different values to these functions. by default contract.functionname() will use the function abi’s .constant field to determine if the call should be simulated or not. in addition there are .at() forms which allow overwritingthe default address with a provided one. The object is then added to the contract under the displayname.
+
+A similar process is carried out for attaching events.
+
+We are almost done the hard bits. Just a bit further.
+
+Lets discuss the function.js file because it is probably by far the most messy file to consider. THe first several functions are intended to be “functional” in the sense that they take in data and return data without changing the original data. We have functions for constructing function names and signatures putting together the payload for burrow, and encoding and decoding the arguments to be passed as byte data. most of these should be self explanatory. they each serve a role without touching the pathway to burrow. the convert module is used to side step formatting issue that have been the bane of my existence since taking this over. my abiToBurrow and back functions are an attempt to be aware of what type of data it is supposed to be in order to correctly format it before passing it to burrow or ethereum-js. The endless debate has been the 0x prepended to byte and address strings. The short story is that ethereum-js expects hex strings to be 0x prepended or it will attempt asciitohex conversion which causes nightmares but manually prepending 0x to all the hex strings has been unpopular. so the convert module smooths over that. if it is a byte like argument convert will prepend with 0x. It assume you are sending proper hex and will not asciitohex convert for you. suck it up. this has proven the least controversial option.
+
+Anyways the Solidity function is the meat of the function.js. looking through it you will notice that its not the function that gets attached but rather a function which returns functions to get attached to the contract. encode and decode essentially route to the functional versions. and the call function does the full pathway.
+
+arguments are shifted into variables in order to handle the optional components. Then a promise is constructed which holds the whole pathway to burrow and back. inside the promise decisions are made on if this is a simulated call etc, a post processing callback function is created which will hand the decoding of returns along with processing of execution errors. then the payload is constructed, and the pipe of the contract this function is bound to will be called. The solidity function will either return the promise of it will resolve the promise into a callback is provided. this is a common pattern throughout.
+
+events is basically the same. so yeah.
+
+I think that covers most of it. Once again I’m sorry. I did my best
+
+88224646AB
+
+Long live the DOUG!
+
+Dennis
+
diff --git a/docs/quickstart/single-full-node.md b/docs/tutorials/1-run-full-node.md
similarity index 80%
rename from docs/quickstart/single-full-node.md
rename to docs/tutorials/1-run-full-node.md
index dedbbb5b3..90a8aff91 100644
--- a/docs/quickstart/single-full-node.md
+++ b/docs/tutorials/1-run-full-node.md
@@ -1,12 +1,7 @@
-# Set up a single full account node
-
-## Usage
-
-The end result will be a `burrow.toml` that will be read in from your current working directory when starting `burrow`.
+# Configure & Run Burrow
## Configuration
-### Configure Burrow
The quick-and-dirty one-liner looks like:
```shell
@@ -14,7 +9,7 @@ The quick-and-dirty one-liner looks like:
burrow spec -p1 -f1 | burrow configure -s- > burrow.toml
```
-which translates into:
+Which translates into:
```shell
# This is a place we can store config files and burrow's working directory '.burrow'
diff --git a/docs/quickstart/send-transactions.md b/docs/tutorials/2-send-transactions.md
similarity index 100%
rename from docs/quickstart/send-transactions.md
rename to docs/tutorials/2-send-transactions.md
diff --git a/docs/quickstart/deploy-contracts.md b/docs/tutorials/3-deploy-contracts.md
similarity index 100%
rename from docs/quickstart/deploy-contracts.md
rename to docs/tutorials/3-deploy-contracts.md
diff --git a/docs/quickstart/multiple-validators.md b/docs/tutorials/4-multiple-validators.md
similarity index 100%
rename from docs/quickstart/multiple-validators.md
rename to docs/tutorials/4-multiple-validators.md
diff --git a/docs/quickstart/bonding-validators.md b/docs/tutorials/5-bonding-validators.md
similarity index 92%
rename from docs/quickstart/bonding-validators.md
rename to docs/tutorials/5-bonding-validators.md
index 4a3c33130..8ed16ca7e 100644
--- a/docs/quickstart/bonding-validators.md
+++ b/docs/tutorials/5-bonding-validators.md
@@ -1,9 +1,5 @@
# Bonding Validators
-As Burrow runs on Tendermint, it supports the notion of bonding validators.
-
-## Example
-
We need at least one validator to start the chain, so run the following to construct
a genesis of two accounts with the `Bond` permission, one of which is pre-bonded:
diff --git a/docs/quickstart/seed-nodes.md b/docs/tutorials/6-seed-nodes.md
similarity index 96%
rename from docs/quickstart/seed-nodes.md
rename to docs/tutorials/6-seed-nodes.md
index a55b7aedd..53d49406c 100644
--- a/docs/quickstart/seed-nodes.md
+++ b/docs/tutorials/6-seed-nodes.md
@@ -1,6 +1,6 @@
# Network with seed nodes
-## What is a seed node
+## What is a seed node?
According to [Tendermint documentation](https://tendermint.com/docs/tendermint-core/using-tendermint.html#seed):
>A seed node is a node who relays the addresses of other peers which they know
diff --git a/docs/quickstart/dump-restore.md b/docs/tutorials/7-dump-restore.md
similarity index 75%
rename from docs/quickstart/dump-restore.md
rename to docs/tutorials/7-dump-restore.md
index c431ca843..a88939c97 100644
--- a/docs/quickstart/dump-restore.md
+++ b/docs/tutorials/7-dump-restore.md
@@ -1,9 +1,9 @@
-## Dump chain state and bring up a new chain with that state
+# Dump / Restore
Sometimes there are breaking changes in burrow. This provides a method for dumping an old chain, and restoring a new chain
with that state.
-# Dumping existing state
+## Dumping existing state
The `burrow dump` command connects to burrow node and retrieves the following:
@@ -16,27 +16,33 @@ This can be dumped in json or go-amino format. The structure is described in (pr
it saved in go-amino, but it can be saved in json format by specify `--json`. It is also possible to dump the state at a specific
height using `--height`.
-# Creating a new chain genesis with state
+## Creating a new chain genesis with state
So you will need the `.keys` directory of the old chain, the `genesis.json` (called genesis-original in the example below)
from the old chain and the dump file (called `dump.json` here).
-`burrow configure -m BurrowTestRestoreNode -n "Restored Chain" -g genesis-original.json -w genesis.json --restore-dump dump.json > burrow.toml`
+```bash
+burrow configure -m BurrowTestRestoreNode -n "Restored Chain" -g genesis-original.json -w genesis.json --restore-dump dump.json > burrow.toml
+```
Note that the chain genesis will contain an `AppHash` specific to this restore file.
-# Restart the chain with the state
+## Restart the chain with the state
This will populate the `.burrow` directory with the state.
-`burrow restore dump.json`
+```bash
+burrow restore dump.json
+```
This will create a block 0 with the restored state. Normally burrow chains start a height 1.
-# Run the new chain
+## Run the new chain
Simply start `burrow` as you would normally.
-`burrow start`
+```bash
+burrow start
+```
Now burrow should start making blocks at 1 as usual.
\ No newline at end of file
diff --git a/docs/txs/bond.md b/docs/txs/bond.md
new file mode 100644
index 000000000..b8bf0931d
--- /dev/null
+++ b/docs/txs/bond.md
@@ -0,0 +1,32 @@
+# Bond / Unbond
+
+Burrow adopts the notion of Bonded Proof-of-Stake (BPoS). This means that in order to
+participate in consensus, a node must give some value of its token as collateral.
+The more token that is bonded, the higher the chance of 'mining' a block.
+
+## How it Works
+
+When starting a burrow node, we provide an address which links to an owned key-pair.
+Each running node thus has an identity which may active in the validator set. Assuming we have
+connected to a network, our node will replay state downloaded from its peers - from which we will
+be able to discern any native token stored at our address. If this amount is non-negligible
+we can submit a signed BondTx to be gossiped amongst the current validators who should include it
+in a block. When executing this transaction against our global state, burrow will first check that the
+input address has correctly signed the payload, that the respective account exists with the bonding
+permission and has enough token to stake. If successful, then this will subtract the token from the
+account and raise the new validators power - enabling it to vote and propose new blocks. The procedure
+for unbonding is antithetical, diminishing the validator accounts power on success.
+
+One nuance with altering the validator set is to do with a concept we call the 'max flow'.
+To prevent the validator pool changing too quickly over a single block whilst ensuring the
+majority of validators are non-byzantine after the transition, we allow up to `ceil((t)/3) - 1`
+to be changed where `t` is the current total validator power.
+
+
+## Future Work
+
+Currently a validator must bond or unbond themselves directly - we enforce a strict relationship
+that prohibits staking token to another account. Funds may be send to another account however,
+and providing that also has permission to bond, then it may join the validator set. In the future we
+hope to extend our model to allow for delegation, whereby any party with native token may stake it
+against a running validator and receive a share of the rewards.
\ No newline at end of file
diff --git a/example/basic-app-website/.gitignore b/example/basic-app-website/.gitignore
new file mode 100644
index 000000000..2badab3e7
--- /dev/null
+++ b/example/basic-app-website/.gitignore
@@ -0,0 +1,6 @@
+.keys
+burrow.toml
+genesis.json
+account.json
+deploy.output.json
+bin
diff --git a/example/basic-app-website/Makefile b/example/basic-app-website/Makefile
new file mode 100644
index 000000000..f7b94a749
--- /dev/null
+++ b/example/basic-app-website/Makefile
@@ -0,0 +1,80 @@
+#
+# basic-app is intended to provide an example end-to-end use of burrow and burrow module in a node.js app
+#
+
+
+# One of: Darwin_i386, Darwin_x86_64, Linux_i386, Linux_x86_64
+BURROW_ARCH := Linux_x86_64
+BURROW_VERSION := 0.27.0
+BURROW_RELEASE_URL := "https://github.com/hyperledger/burrow/releases/download/v${BURROW_VERSION}/burrow_${BURROW_VERSION}_${BURROW_ARCH}.tar.gz "
+# Set to 'burrow' to use whatever is on PATH instead
+BURROW_BIN := bin/burrow
+
+#
+# Running the chain
+#
+# Make a simple single node chain
+.PHONY: chain
+chain: bin/burrow burrow.toml
+
+# Get the burrow binary
+bin/burrow:
+ mkdir -p bin
+ curl -L ${BURROW_RELEASE_URL} | tar zx -C bin burrow
+
+# Generate the chain
+burrow.toml genesis.json:
+ ${BURROW_BIN} spec --full-accounts 1 | ${BURROW_BIN} configure --genesis-spec=- --separate-genesis-doc=genesis.json > burrow.toml
+
+# Dump account information to file for app
+account.json: genesis.json
+ jq '.Accounts[] | select(.Name == "Full_0")' genesis.json > account.json
+
+# Reset burrow state
+.PHONY: reset_chain
+reset_chain:
+ rm -rf .burrow
+
+# Remove burrow chain completely
+.PHONY: remove_chain
+remove_chain:
+ rm -rf burrow.toml genesis.json .keys .burrow
+
+# remake and reset chain
+.PHONY: rechain
+rechain: | remove_chain chain
+
+.PHONY: start_chain
+start_chain: chain
+ ${BURROW_BIN} start -v0
+
+.PHONY: restart
+restart: | rechain start_chain
+
+#
+# Deploying the contract
+#
+deploy.output.json: simplestorage.sol deploy.yaml account.json
+ ${BURROW_BIN} deploy --address $(shell jq '.Address' account.json) deploy.yaml
+
+.PHONY: delete_deploy
+delete_deploy:
+ rm -rf deploy.output.json
+
+.PHONY: deploy
+deploy: deploy.output.json
+
+.PHONY: redeploy
+redeploy: | delete_deploy deploy.output.json
+
+#
+# Running the app
+#
+
+.PHONY: npm_install
+npm_install:
+ npm install
+
+.PHONY: start_app
+start_app: npm_install deploy
+ node app.js
diff --git a/example/basic-app-website/README.md b/example/basic-app-website/README.md
new file mode 100644
index 000000000..4df853efd
--- /dev/null
+++ b/example/basic-app-website/README.md
@@ -0,0 +1,55 @@
+# Example basic-app (with website)
+
+Note that this example is the same as the the basic-app example, apart from step 3.
+
+This example contains an example solidity contract [simplestorage](simplestorage.sol) and a [node.js application](app.js) that interacts with the contract using [burrow](../../js/README.md). It also contains a [makefile](makefile) that will set up a single node chain, deploy the contract using `burrow deploy`. The node app configures itself to use the the single node chain my looking for [account.json](account.json) and [deploy.output.json](deploy.output.json) files that are emitted by `burrow deploy` and the makefile.
+
+The makefile provides some examples of using the `burrow` command line tooling and you are invited to modify it for your purposes.
+
+## Dependencies
+To run the makefile you will need to have installed:
+
+- GNU Make
+- Node.js (the `node` binary)
+- npm (the node package manager)
+- jq (the JSON tool)
+
+Burrow will be downloaded for you when using the makefile, but you may override `BURROW_BIN` and `BURROW_ARCH` in the makefile to change this behaviour. By default Burrow is downloaded for `Linux_x86_64.
+
+## Running the example
+
+All commands should be run from the same directory as this readme file.
+
+### Step one
+Start the chain
+
+```shell
+make start_chain
+```
+
+This will install burrow, create a new chain as necessary.
+
+If successful you will see continuous output in your terminal, you can shutdown Burrow by sending the interrupt signal with Ctrl-C, and restart it again with whatever state has accumulated with `make start_chain`. If you would like to destroy the existing chain and start completely fresh (including deleting keys) run `make rechain`. If you would like to keep existing keys and chain config run `make reset_chain`.
+
+You can redeploy the contract (to a new address) with `make redeploy`. The node app will then use this new contract by reading the address deploy.output.json. Be sure to do this if you wish to modify simplestorage.sol.
+
+### Step two
+Leave burrow running and in a separate terminal start the app which runs a simple HTTP server with:
+
+```shell
+make start_app
+```
+
+This will deploy the contract if necessary, install any node dependencies, and then start an expressjs server, which will run until interrupted.
+
+### Step three
+Open a web browser and type:
+
+```shell
+ http://localhost:3000/
+```
+
+You will see two buttons:
+* Set Value - that allows you to change the value stored in the associated smart contract
+* Get Value - that allows you to retrieve the value stored in the associated smart contract, which will be displayed underneath the button
+
diff --git a/example/basic-app-website/app.js b/example/basic-app-website/app.js
new file mode 100644
index 000000000..4e2a04030
--- /dev/null
+++ b/example/basic-app-website/app.js
@@ -0,0 +1,96 @@
+const fs = require('fs')
+const burrow = require('@monax/burrow')
+const express = require('express')
+const bodyParser = require('body-parser')
+
+// Burrow address
+let chainURL = '127.0.0.1:10997'
+const abiFile = 'bin/simplestorage.bin'
+const deployFile = 'deploy.output.json'
+const accountFile = 'account.json'
+
+// Port to run example on locally
+const exampleAppPort = 3000
+
+function slurp (file) {
+ return JSON.parse(fs.readFileSync(file, 'utf8'))
+}
+
+// Grab the account file that is expected to have 'Address' field
+let account = slurp(accountFile)
+// Connect to running burrow chain using the account address to identify our input account and return values as an object
+// using named returns where provided
+let chain = burrow.createInstance(chainURL, account.Address, {objectReturn: true})
+// The ABI file produced by the solidity compiler (through burrow deploy) that acts as a manifest for our deployed contract
+let abi = slurp(abiFile).Abi
+// The deployment receipt written to disk by burrow deploy that contains the deployed address of the contract amongst other things
+let deploy = slurp(deployFile)
+// The contract we will call
+let contractAddress = deploy.simplestorage
+// A Javascript object that wraps our simplestorage contract and will handle translating Javascript calls to EVM invocations
+let store = chain.contracts.new(abi, null, contractAddress)
+
+// For this example we use a simple router based on expressjs
+const app = express()
+// Apparently this needs to be its own module...
+app.use(bodyParser.json())
+app.use(express.static('public'))
+app.use(bodyParser.urlencoded({ extended: true }))
+app.set('view engine', 'ejs')
+
+// Some helpers for parsing/validating input
+let asInteger = value => new Promise((resolve, reject) =>
+ (i => isNaN(i) ? reject(`${value} is ${typeof value} not integer`) : resolve(i))(parseInt(value)))
+
+let param = (obj, prop) => new Promise((resolve, reject) =>
+ prop in obj ? resolve(obj[prop]) : reject(`expected key '${prop}' in ${JSON.stringify(obj)}`))
+
+let handlerError = err => { console.log(err); return err.toString() }
+
+// We define some method endpoints
+// Get the value from the contract by calling the Solidity 'get' method
+app.get('/', (req, res) => store.get()
+ .then(ret => res.render('index', {valueIs: ret.values.value, error: null}))
+ .catch(err => res.send(handlerError(err))))
+
+// this next get occurs when the user presses the get value button on the website
+// Get the value from the contract by calling the Solidity 'get' method
+app.get('/getValue', (req, res) => store.get()
+ .then(ret => res.render('index', {valueIs: ret.values.value, error: null}))
+ .catch(err => res.send(handlerError(err))))
+
+// Sets the value by accepting a value in HTTP POST data and calling the Solidity 'set' method
+app.post('/', (req, res) => param(req.body, 'valueNum')
+ .then(valueNum => asInteger(valueNum))
+ .then(valueNum => store.set(valueNum))
+ .then(ret => res.render('index', {valueIs: 'logged', error: null}))
+
+ .catch(err => res.send(handlerError(err))))
+
+// Sets a value by HTTP POSTing to the value you expect to be stored encoded in the URL - so that the value can be
+// updated atomically
+app.post('/:test', (req, res) => param(req.body, 'value')
+ .then(value => Promise.all([asInteger(req.params.test), asInteger(value)]))
+ .then(([test, value]) => store.testAndSet(test, value))
+ .then(ret => res.send(ret.values))
+ .catch(err => res.send(handlerError(err))))
+
+const url = `http://127.0.0.1:${exampleAppPort}`
+
+// Listen for requests
+app.listen(exampleAppPort, () => console.log(`Example app listening on ${url}...
+
+You may wish to try the following:
+# Inspect current stored value
+ $ curl ${url}
+
+# Set the value to 2000
+ $ curl -d '{"value": 2000}' -H "Content-Type: application/json" -X POST ${url}
+
+# Set the value via a testAndSet operation
+ $ curl -d '{"value": 30}' -H "Content-Type: application/json" -X POST ${url}/2000
+
+# Attempt the same testAndSet which now fails since the value stored is no longer '2000'
+ $ curl -d '{"value": 30}' -H "Content-Type: application/json" -X POST ${url}/2000
+ $ curl ${url}
+ `))
diff --git a/example/basic-app-website/deploy.yaml b/example/basic-app-website/deploy.yaml
new file mode 100644
index 000000000..932279077
--- /dev/null
+++ b/example/basic-app-website/deploy.yaml
@@ -0,0 +1,29 @@
+jobs:
+
+- name: valueToSet
+ set:
+ val: 10
+
+- name: simplestorage
+ deploy:
+ contract: simplestorage.sol
+ data:
+ - 0
+
+- name: setStorage
+ call:
+ destination: $simplestorage
+ function: set
+ data:
+ - $valueToSet
+
+- name: queryStorage
+ query-contract:
+ destination: $simplestorage
+ function: get
+
+- name: assertStorage
+ assert:
+ key: $queryStorage
+ relation: eq
+ val: $valueToSet
diff --git a/example/basic-app-website/package-lock.json b/example/basic-app-website/package-lock.json
new file mode 100644
index 000000000..00f76c4ba
--- /dev/null
+++ b/example/basic-app-website/package-lock.json
@@ -0,0 +1,1487 @@
+{
+ "name": "basic-app",
+ "version": "1.0.0",
+ "lockfileVersion": 1,
+ "requires": true,
+ "dependencies": {
+ "@grpc/proto-loader": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.4.0.tgz",
+ "integrity": "sha512-Jm6o+75uWT7E6+lt8edg4J1F/9+BedOjaMgwE14pxS/AO43/0ZqK+rCLVVrXLoExwSAZvgvOD2B0ivy3Spsspw==",
+ "requires": {
+ "lodash.camelcase": "^4.3.0",
+ "protobufjs": "^6.8.6"
+ }
+ },
+ "@monax/burrow": {
+ "version": "0.24.3",
+ "resolved": "https://registry.npmjs.org/@monax/burrow/-/burrow-0.24.3.tgz",
+ "integrity": "sha512-HVqPF+5KGkt+UkBj/Mn8JGEH6+7x67m/0TApBmvTdbbT6TG5IouzP4kP1pooo0e8RAGmxybPJMalZcReFDpAUw==",
+ "requires": {
+ "@grpc/proto-loader": "^0.4.0",
+ "crypto-js": "3.1.4",
+ "ethereumjs-abi": "^0.6.5",
+ "grpc": "^1.18.0",
+ "protobufjs": "^6.8.6"
+ }
+ },
+ "@protobufjs/aspromise": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz",
+ "integrity": "sha1-m4sMxmPWaafY9vXQiToU00jzD78="
+ },
+ "@protobufjs/base64": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz",
+ "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg=="
+ },
+ "@protobufjs/codegen": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz",
+ "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg=="
+ },
+ "@protobufjs/eventemitter": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz",
+ "integrity": "sha1-NVy8mLr61ZePntCV85diHx0Ga3A="
+ },
+ "@protobufjs/fetch": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz",
+ "integrity": "sha1-upn7WYYUr2VwDBYZ/wbUVLDYTEU=",
+ "requires": {
+ "@protobufjs/aspromise": "^1.1.1",
+ "@protobufjs/inquire": "^1.1.0"
+ }
+ },
+ "@protobufjs/float": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz",
+ "integrity": "sha1-Xp4avctz/Ap8uLKR33jIy9l7h9E="
+ },
+ "@protobufjs/inquire": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz",
+ "integrity": "sha1-/yAOPnzyQp4tyvwRQIKOjMY48Ik="
+ },
+ "@protobufjs/path": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz",
+ "integrity": "sha1-bMKyDFya1q0NzP0hynZz2Nf79o0="
+ },
+ "@protobufjs/pool": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz",
+ "integrity": "sha1-Cf0V8tbTq/qbZbw2ZQbWrXhG/1Q="
+ },
+ "@protobufjs/utf8": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz",
+ "integrity": "sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA="
+ },
+ "@types/long": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.0.tgz",
+ "integrity": "sha512-1w52Nyx4Gq47uuu0EVcsHBxZFJgurQ+rTKS3qMHxR1GY2T8c2AJYd6vZoZ9q1rupaDjU0yT+Jc2XTyXkjeMA+Q=="
+ },
+ "@types/node": {
+ "version": "10.14.15",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-10.14.15.tgz",
+ "integrity": "sha512-CBR5avlLcu0YCILJiDIXeU2pTw7UK/NIxfC63m7d7CVamho1qDEzXKkOtEauQRPMy6MI8mLozth+JJkas7HY6g=="
+ },
+ "accepts": {
+ "version": "1.3.5",
+ "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.5.tgz",
+ "integrity": "sha1-63d99gEXI6OxTopywIBcjoZ0a9I=",
+ "requires": {
+ "mime-types": "~2.1.18",
+ "negotiator": "0.6.1"
+ }
+ },
+ "ansi-regex": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
+ "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8="
+ },
+ "array-flatten": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
+ "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI="
+ },
+ "ascli": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/ascli/-/ascli-1.0.1.tgz",
+ "integrity": "sha1-vPpZdKYvGOgcq660lzKrSoj5Brw=",
+ "requires": {
+ "colour": "~0.7.1",
+ "optjs": "~3.2.2"
+ }
+ },
+ "balanced-match": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
+ "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c="
+ },
+ "bindings": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz",
+ "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==",
+ "requires": {
+ "file-uri-to-path": "1.0.0"
+ }
+ },
+ "bip66": {
+ "version": "1.1.5",
+ "resolved": "https://registry.npmjs.org/bip66/-/bip66-1.1.5.tgz",
+ "integrity": "sha1-AfqHSHhcpwlV1QESF9GzE5lpyiI=",
+ "requires": {
+ "safe-buffer": "^5.0.1"
+ }
+ },
+ "bn.js": {
+ "version": "4.11.8",
+ "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz",
+ "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA=="
+ },
+ "body-parser": {
+ "version": "1.18.3",
+ "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.3.tgz",
+ "integrity": "sha1-WykhmP/dVTs6DyDe0FkrlWlVyLQ=",
+ "requires": {
+ "bytes": "3.0.0",
+ "content-type": "~1.0.4",
+ "debug": "2.6.9",
+ "depd": "~1.1.2",
+ "http-errors": "~1.6.3",
+ "iconv-lite": "0.4.23",
+ "on-finished": "~2.3.0",
+ "qs": "6.5.2",
+ "raw-body": "2.3.3",
+ "type-is": "~1.6.16"
+ },
+ "dependencies": {
+ "qs": {
+ "version": "6.5.2",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz",
+ "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA=="
+ }
+ }
+ },
+ "brace-expansion": {
+ "version": "1.1.11",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+ "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+ "requires": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "brorand": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz",
+ "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8="
+ },
+ "browserify-aes": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz",
+ "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==",
+ "requires": {
+ "buffer-xor": "^1.0.3",
+ "cipher-base": "^1.0.0",
+ "create-hash": "^1.1.0",
+ "evp_bytestokey": "^1.0.3",
+ "inherits": "^2.0.1",
+ "safe-buffer": "^5.0.1"
+ }
+ },
+ "buffer-xor": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz",
+ "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk="
+ },
+ "bytebuffer": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/bytebuffer/-/bytebuffer-5.0.1.tgz",
+ "integrity": "sha1-WC7qSxqHO20CCkjVjfhfC7ps/d0=",
+ "requires": {
+ "long": "~3"
+ },
+ "dependencies": {
+ "long": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/long/-/long-3.2.0.tgz",
+ "integrity": "sha1-2CG3E4yhy1gcFymQ7xTbIAtcR0s="
+ }
+ }
+ },
+ "bytes": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz",
+ "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg="
+ },
+ "camelcase": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz",
+ "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8="
+ },
+ "cipher-base": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz",
+ "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==",
+ "requires": {
+ "inherits": "^2.0.1",
+ "safe-buffer": "^5.0.1"
+ }
+ },
+ "cliui": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz",
+ "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=",
+ "requires": {
+ "string-width": "^1.0.1",
+ "strip-ansi": "^3.0.1",
+ "wrap-ansi": "^2.0.0"
+ }
+ },
+ "code-point-at": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
+ "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c="
+ },
+ "colour": {
+ "version": "0.7.1",
+ "resolved": "https://registry.npmjs.org/colour/-/colour-0.7.1.tgz",
+ "integrity": "sha1-nLFpkX7F0SwHNtPoaFdG3xyt93g="
+ },
+ "concat-map": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+ "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
+ },
+ "content-disposition": {
+ "version": "0.5.2",
+ "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz",
+ "integrity": "sha1-DPaLud318r55YcOoUXjLhdunjLQ="
+ },
+ "content-type": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
+ "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA=="
+ },
+ "cookie": {
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz",
+ "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s="
+ },
+ "cookie-signature": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
+ "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw="
+ },
+ "create-hash": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz",
+ "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==",
+ "requires": {
+ "cipher-base": "^1.0.1",
+ "inherits": "^2.0.1",
+ "md5.js": "^1.3.4",
+ "ripemd160": "^2.0.1",
+ "sha.js": "^2.4.0"
+ }
+ },
+ "create-hmac": {
+ "version": "1.1.7",
+ "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz",
+ "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==",
+ "requires": {
+ "cipher-base": "^1.0.3",
+ "create-hash": "^1.1.0",
+ "inherits": "^2.0.1",
+ "ripemd160": "^2.0.0",
+ "safe-buffer": "^5.0.1",
+ "sha.js": "^2.4.8"
+ }
+ },
+ "crypto-js": {
+ "version": "3.1.4",
+ "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-3.1.4.tgz",
+ "integrity": "sha1-IWTxbeLykVELZS10a84302SYMK0="
+ },
+ "debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "decamelize": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
+ "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA="
+ },
+ "depd": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
+ "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak="
+ },
+ "destroy": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
+ "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA="
+ },
+ "drbg.js": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/drbg.js/-/drbg.js-1.0.1.tgz",
+ "integrity": "sha1-Pja2xCs3BDgjzbwzLVjzHiRFSAs=",
+ "requires": {
+ "browserify-aes": "^1.0.6",
+ "create-hash": "^1.1.2",
+ "create-hmac": "^1.1.4"
+ }
+ },
+ "ee-first": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
+ "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0="
+ },
+ "ejs": {
+ "version": "2.6.2",
+ "resolved": "https://registry.npmjs.org/ejs/-/ejs-2.6.2.tgz",
+ "integrity": "sha512-PcW2a0tyTuPHz3tWyYqtK6r1fZ3gp+3Sop8Ph+ZYN81Ob5rwmbHEzaqs10N3BEsaGTkh/ooniXK+WwszGlc2+Q=="
+ },
+ "elliptic": {
+ "version": "6.5.0",
+ "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.0.tgz",
+ "integrity": "sha512-eFOJTMyCYb7xtE/caJ6JJu+bhi67WCYNbkGSknu20pmM8Ke/bqOfdnZWxyoGN26JgfxTbXrsCkEw4KheCT/KGg==",
+ "requires": {
+ "bn.js": "^4.4.0",
+ "brorand": "^1.0.1",
+ "hash.js": "^1.0.0",
+ "hmac-drbg": "^1.0.0",
+ "inherits": "^2.0.1",
+ "minimalistic-assert": "^1.0.0",
+ "minimalistic-crypto-utils": "^1.0.0"
+ }
+ },
+ "encodeurl": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
+ "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k="
+ },
+ "escape-html": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
+ "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg="
+ },
+ "etag": {
+ "version": "1.8.1",
+ "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
+ "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc="
+ },
+ "ethereumjs-abi": {
+ "version": "0.6.8",
+ "resolved": "https://registry.npmjs.org/ethereumjs-abi/-/ethereumjs-abi-0.6.8.tgz",
+ "integrity": "sha512-Tx0r/iXI6r+lRsdvkFDlut0N08jWMnKRZ6Gkq+Nmw75lZe4e6o3EkSnkaBP5NF6+m5PTGAr9JP43N3LyeoglsA==",
+ "requires": {
+ "bn.js": "^4.11.8",
+ "ethereumjs-util": "^6.0.0"
+ }
+ },
+ "ethereumjs-util": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.1.0.tgz",
+ "integrity": "sha512-URESKMFbDeJxnAxPppnk2fN6Y3BIatn9fwn76Lm8bQlt+s52TpG8dN9M66MLPuRAiAOIqL3dfwqWJf0sd0fL0Q==",
+ "requires": {
+ "bn.js": "^4.11.0",
+ "create-hash": "^1.1.2",
+ "ethjs-util": "0.1.6",
+ "keccak": "^1.0.2",
+ "rlp": "^2.0.0",
+ "safe-buffer": "^5.1.1",
+ "secp256k1": "^3.0.1"
+ }
+ },
+ "ethjs-util": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/ethjs-util/-/ethjs-util-0.1.6.tgz",
+ "integrity": "sha512-CUnVOQq7gSpDHZVVrQW8ExxUETWrnrvXYvYz55wOU8Uj4VCgw56XC2B/fVqQN+f7gmrnRHSLVnFAwsCuNwji8w==",
+ "requires": {
+ "is-hex-prefixed": "1.0.0",
+ "strip-hex-prefix": "1.0.0"
+ }
+ },
+ "evp_bytestokey": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz",
+ "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==",
+ "requires": {
+ "md5.js": "^1.3.4",
+ "safe-buffer": "^5.1.1"
+ }
+ },
+ "express": {
+ "version": "4.16.3",
+ "resolved": "https://registry.npmjs.org/express/-/express-4.16.3.tgz",
+ "integrity": "sha1-avilAjUNsyRuzEvs9rWjTSL37VM=",
+ "requires": {
+ "accepts": "~1.3.5",
+ "array-flatten": "1.1.1",
+ "body-parser": "1.18.2",
+ "content-disposition": "0.5.2",
+ "content-type": "~1.0.4",
+ "cookie": "0.3.1",
+ "cookie-signature": "1.0.6",
+ "debug": "2.6.9",
+ "depd": "~1.1.2",
+ "encodeurl": "~1.0.2",
+ "escape-html": "~1.0.3",
+ "etag": "~1.8.1",
+ "finalhandler": "1.1.1",
+ "fresh": "0.5.2",
+ "merge-descriptors": "1.0.1",
+ "methods": "~1.1.2",
+ "on-finished": "~2.3.0",
+ "parseurl": "~1.3.2",
+ "path-to-regexp": "0.1.7",
+ "proxy-addr": "~2.0.3",
+ "qs": "6.5.1",
+ "range-parser": "~1.2.0",
+ "safe-buffer": "5.1.1",
+ "send": "0.16.2",
+ "serve-static": "1.13.2",
+ "setprototypeof": "1.1.0",
+ "statuses": "~1.4.0",
+ "type-is": "~1.6.16",
+ "utils-merge": "1.0.1",
+ "vary": "~1.1.2"
+ },
+ "dependencies": {
+ "body-parser": {
+ "version": "1.18.2",
+ "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.2.tgz",
+ "integrity": "sha1-h2eKGdhLR9hZuDGZvVm84iKxBFQ=",
+ "requires": {
+ "bytes": "3.0.0",
+ "content-type": "~1.0.4",
+ "debug": "2.6.9",
+ "depd": "~1.1.1",
+ "http-errors": "~1.6.2",
+ "iconv-lite": "0.4.19",
+ "on-finished": "~2.3.0",
+ "qs": "6.5.1",
+ "raw-body": "2.3.2",
+ "type-is": "~1.6.15"
+ }
+ },
+ "iconv-lite": {
+ "version": "0.4.19",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz",
+ "integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ=="
+ },
+ "raw-body": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.2.tgz",
+ "integrity": "sha1-vNYMd9Prk83gBQKVw/N5OJvIj4k=",
+ "requires": {
+ "bytes": "3.0.0",
+ "http-errors": "1.6.2",
+ "iconv-lite": "0.4.19",
+ "unpipe": "1.0.0"
+ },
+ "dependencies": {
+ "depd": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.1.tgz",
+ "integrity": "sha1-V4O04cRZ8G+lyif5kfPQbnoxA1k="
+ },
+ "http-errors": {
+ "version": "1.6.2",
+ "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.2.tgz",
+ "integrity": "sha1-CgAsyFcHGSp+eUbO7cERVfYOxzY=",
+ "requires": {
+ "depd": "1.1.1",
+ "inherits": "2.0.3",
+ "setprototypeof": "1.0.3",
+ "statuses": ">= 1.3.1 < 2"
+ }
+ },
+ "setprototypeof": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.0.3.tgz",
+ "integrity": "sha1-ZlZ+NwQ+608E2RvWWMDL77VbjgQ="
+ }
+ }
+ }
+ }
+ },
+ "file-uri-to-path": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz",
+ "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw=="
+ },
+ "finalhandler": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.1.tgz",
+ "integrity": "sha512-Y1GUDo39ez4aHAw7MysnUD5JzYX+WaIj8I57kO3aEPT1fFRL4sr7mjei97FgnwhAyyzRYmQZaTHb2+9uZ1dPtg==",
+ "requires": {
+ "debug": "2.6.9",
+ "encodeurl": "~1.0.2",
+ "escape-html": "~1.0.3",
+ "on-finished": "~2.3.0",
+ "parseurl": "~1.3.2",
+ "statuses": "~1.4.0",
+ "unpipe": "~1.0.0"
+ }
+ },
+ "forwarded": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz",
+ "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ="
+ },
+ "fresh": {
+ "version": "0.5.2",
+ "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
+ "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac="
+ },
+ "fs.realpath": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
+ "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
+ },
+ "glob": {
+ "version": "7.1.4",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz",
+ "integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==",
+ "requires": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.0.4",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ }
+ },
+ "grpc": {
+ "version": "1.22.2",
+ "resolved": "https://registry.npmjs.org/grpc/-/grpc-1.22.2.tgz",
+ "integrity": "sha512-gaK59oAA5/mlOIn+hQO5JROPoAzsaGRpEMcrAayW5WGETS8QScpBoQ+XBxEWAAF0kbeGIELuGRCVEObKS1SLmw==",
+ "requires": {
+ "lodash.camelcase": "^4.3.0",
+ "lodash.clone": "^4.5.0",
+ "nan": "^2.13.2",
+ "node-pre-gyp": "^0.13.0",
+ "protobufjs": "^5.0.3"
+ },
+ "dependencies": {
+ "abbrev": {
+ "version": "1.1.1",
+ "bundled": true
+ },
+ "ansi-regex": {
+ "version": "2.1.1",
+ "bundled": true
+ },
+ "aproba": {
+ "version": "1.2.0",
+ "bundled": true
+ },
+ "are-we-there-yet": {
+ "version": "1.1.5",
+ "bundled": true,
+ "requires": {
+ "delegates": "^1.0.0",
+ "readable-stream": "^2.0.6"
+ }
+ },
+ "balanced-match": {
+ "version": "1.0.0",
+ "bundled": true
+ },
+ "brace-expansion": {
+ "version": "1.1.11",
+ "bundled": true,
+ "requires": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "chownr": {
+ "version": "1.1.1",
+ "bundled": true
+ },
+ "code-point-at": {
+ "version": "1.1.0",
+ "bundled": true
+ },
+ "concat-map": {
+ "version": "0.0.1",
+ "bundled": true
+ },
+ "console-control-strings": {
+ "version": "1.1.0",
+ "bundled": true
+ },
+ "core-util-is": {
+ "version": "1.0.2",
+ "bundled": true
+ },
+ "deep-extend": {
+ "version": "0.6.0",
+ "bundled": true
+ },
+ "delegates": {
+ "version": "1.0.0",
+ "bundled": true
+ },
+ "detect-libc": {
+ "version": "1.0.3",
+ "bundled": true
+ },
+ "fs-minipass": {
+ "version": "1.2.6",
+ "bundled": true,
+ "requires": {
+ "minipass": "^2.2.1"
+ }
+ },
+ "fs.realpath": {
+ "version": "1.0.0",
+ "bundled": true
+ },
+ "gauge": {
+ "version": "2.7.4",
+ "bundled": true,
+ "requires": {
+ "aproba": "^1.0.3",
+ "console-control-strings": "^1.0.0",
+ "has-unicode": "^2.0.0",
+ "object-assign": "^4.1.0",
+ "signal-exit": "^3.0.0",
+ "string-width": "^1.0.1",
+ "strip-ansi": "^3.0.1",
+ "wide-align": "^1.1.0"
+ }
+ },
+ "has-unicode": {
+ "version": "2.0.1",
+ "bundled": true
+ },
+ "iconv-lite": {
+ "version": "0.4.23",
+ "bundled": true,
+ "requires": {
+ "safer-buffer": ">= 2.1.2 < 3"
+ }
+ },
+ "ignore-walk": {
+ "version": "3.0.1",
+ "bundled": true,
+ "requires": {
+ "minimatch": "^3.0.4"
+ }
+ },
+ "inflight": {
+ "version": "1.0.6",
+ "bundled": true,
+ "requires": {
+ "once": "^1.3.0",
+ "wrappy": "1"
+ }
+ },
+ "inherits": {
+ "version": "2.0.3",
+ "bundled": true
+ },
+ "ini": {
+ "version": "1.3.5",
+ "bundled": true
+ },
+ "is-fullwidth-code-point": {
+ "version": "1.0.0",
+ "bundled": true,
+ "requires": {
+ "number-is-nan": "^1.0.0"
+ }
+ },
+ "isarray": {
+ "version": "1.0.0",
+ "bundled": true
+ },
+ "minimatch": {
+ "version": "3.0.4",
+ "bundled": true,
+ "requires": {
+ "brace-expansion": "^1.1.7"
+ }
+ },
+ "minimist": {
+ "version": "1.2.0",
+ "bundled": true
+ },
+ "minipass": {
+ "version": "2.3.5",
+ "bundled": true,
+ "requires": {
+ "safe-buffer": "^5.1.2",
+ "yallist": "^3.0.0"
+ }
+ },
+ "minizlib": {
+ "version": "1.2.1",
+ "bundled": true,
+ "requires": {
+ "minipass": "^2.2.1"
+ }
+ },
+ "mkdirp": {
+ "version": "0.5.1",
+ "bundled": true,
+ "requires": {
+ "minimist": "0.0.8"
+ },
+ "dependencies": {
+ "minimist": {
+ "version": "0.0.8",
+ "bundled": true
+ }
+ }
+ },
+ "needle": {
+ "version": "2.4.0",
+ "bundled": true,
+ "requires": {
+ "debug": "^3.2.6",
+ "iconv-lite": "^0.4.4",
+ "sax": "^1.2.4"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "3.2.6",
+ "bundled": true,
+ "requires": {
+ "ms": "^2.1.1"
+ }
+ },
+ "ms": {
+ "version": "2.1.2",
+ "bundled": true
+ }
+ }
+ },
+ "node-pre-gyp": {
+ "version": "0.13.0",
+ "bundled": true,
+ "requires": {
+ "detect-libc": "^1.0.2",
+ "mkdirp": "^0.5.1",
+ "needle": "^2.2.1",
+ "nopt": "^4.0.1",
+ "npm-packlist": "^1.1.6",
+ "npmlog": "^4.0.2",
+ "rc": "^1.2.7",
+ "rimraf": "^2.6.1",
+ "semver": "^5.3.0",
+ "tar": "^4"
+ }
+ },
+ "nopt": {
+ "version": "4.0.1",
+ "bundled": true,
+ "requires": {
+ "abbrev": "1",
+ "osenv": "^0.1.4"
+ }
+ },
+ "npm-bundled": {
+ "version": "1.0.6",
+ "bundled": true
+ },
+ "npm-packlist": {
+ "version": "1.4.1",
+ "bundled": true,
+ "requires": {
+ "ignore-walk": "^3.0.1",
+ "npm-bundled": "^1.0.1"
+ }
+ },
+ "npmlog": {
+ "version": "4.1.2",
+ "bundled": true,
+ "requires": {
+ "are-we-there-yet": "~1.1.2",
+ "console-control-strings": "~1.1.0",
+ "gauge": "~2.7.3",
+ "set-blocking": "~2.0.0"
+ }
+ },
+ "number-is-nan": {
+ "version": "1.0.1",
+ "bundled": true
+ },
+ "object-assign": {
+ "version": "4.1.1",
+ "bundled": true
+ },
+ "once": {
+ "version": "1.4.0",
+ "bundled": true,
+ "requires": {
+ "wrappy": "1"
+ }
+ },
+ "os-homedir": {
+ "version": "1.0.2",
+ "bundled": true
+ },
+ "os-tmpdir": {
+ "version": "1.0.2",
+ "bundled": true
+ },
+ "osenv": {
+ "version": "0.1.5",
+ "bundled": true,
+ "requires": {
+ "os-homedir": "^1.0.0",
+ "os-tmpdir": "^1.0.0"
+ }
+ },
+ "path-is-absolute": {
+ "version": "1.0.1",
+ "bundled": true
+ },
+ "process-nextick-args": {
+ "version": "2.0.1",
+ "bundled": true
+ },
+ "protobufjs": {
+ "version": "5.0.3",
+ "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-5.0.3.tgz",
+ "integrity": "sha512-55Kcx1MhPZX0zTbVosMQEO5R6/rikNXd9b6RQK4KSPcrSIIwoXTtebIczUrXlwaSrbz4x8XUVThGPob1n8I4QA==",
+ "requires": {
+ "ascli": "~1",
+ "bytebuffer": "~5",
+ "glob": "^7.0.5",
+ "yargs": "^3.10.0"
+ }
+ },
+ "rc": {
+ "version": "1.2.8",
+ "bundled": true,
+ "requires": {
+ "deep-extend": "^0.6.0",
+ "ini": "~1.3.0",
+ "minimist": "^1.2.0",
+ "strip-json-comments": "~2.0.1"
+ }
+ },
+ "readable-stream": {
+ "version": "2.3.6",
+ "bundled": true,
+ "requires": {
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.3",
+ "isarray": "~1.0.0",
+ "process-nextick-args": "~2.0.0",
+ "safe-buffer": "~5.1.1",
+ "string_decoder": "~1.1.1",
+ "util-deprecate": "~1.0.1"
+ }
+ },
+ "rimraf": {
+ "version": "2.6.3",
+ "bundled": true,
+ "requires": {
+ "glob": "^7.1.3"
+ },
+ "dependencies": {
+ "glob": {
+ "version": "7.1.4",
+ "bundled": true,
+ "requires": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.0.4",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ }
+ }
+ }
+ },
+ "safe-buffer": {
+ "version": "5.1.2",
+ "bundled": true
+ },
+ "safer-buffer": {
+ "version": "2.1.2",
+ "bundled": true
+ },
+ "sax": {
+ "version": "1.2.4",
+ "bundled": true
+ },
+ "semver": {
+ "version": "5.7.0",
+ "bundled": true
+ },
+ "set-blocking": {
+ "version": "2.0.0",
+ "bundled": true
+ },
+ "signal-exit": {
+ "version": "3.0.1",
+ "bundled": true
+ },
+ "string-width": {
+ "version": "1.0.2",
+ "bundled": true,
+ "requires": {
+ "code-point-at": "^1.0.0",
+ "is-fullwidth-code-point": "^1.0.0",
+ "strip-ansi": "^3.0.0"
+ }
+ },
+ "string_decoder": {
+ "version": "1.1.1",
+ "bundled": true,
+ "requires": {
+ "safe-buffer": "~5.1.0"
+ }
+ },
+ "strip-ansi": {
+ "version": "3.0.1",
+ "bundled": true,
+ "requires": {
+ "ansi-regex": "^2.0.0"
+ }
+ },
+ "strip-json-comments": {
+ "version": "2.0.1",
+ "bundled": true
+ },
+ "tar": {
+ "version": "4.4.10",
+ "bundled": true,
+ "requires": {
+ "chownr": "^1.1.1",
+ "fs-minipass": "^1.2.5",
+ "minipass": "^2.3.5",
+ "minizlib": "^1.2.1",
+ "mkdirp": "^0.5.0",
+ "safe-buffer": "^5.1.2",
+ "yallist": "^3.0.3"
+ }
+ },
+ "util-deprecate": {
+ "version": "1.0.2",
+ "bundled": true
+ },
+ "wide-align": {
+ "version": "1.1.3",
+ "bundled": true,
+ "requires": {
+ "string-width": "^1.0.2 || 2"
+ }
+ },
+ "wrappy": {
+ "version": "1.0.2",
+ "bundled": true
+ },
+ "yallist": {
+ "version": "3.0.3",
+ "bundled": true
+ }
+ }
+ },
+ "hash-base": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz",
+ "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=",
+ "requires": {
+ "inherits": "^2.0.1",
+ "safe-buffer": "^5.0.1"
+ }
+ },
+ "hash.js": {
+ "version": "1.1.7",
+ "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz",
+ "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==",
+ "requires": {
+ "inherits": "^2.0.3",
+ "minimalistic-assert": "^1.0.1"
+ }
+ },
+ "hmac-drbg": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz",
+ "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=",
+ "requires": {
+ "hash.js": "^1.0.3",
+ "minimalistic-assert": "^1.0.0",
+ "minimalistic-crypto-utils": "^1.0.1"
+ }
+ },
+ "http-errors": {
+ "version": "1.6.3",
+ "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz",
+ "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=",
+ "requires": {
+ "depd": "~1.1.2",
+ "inherits": "2.0.3",
+ "setprototypeof": "1.1.0",
+ "statuses": ">= 1.4.0 < 2"
+ }
+ },
+ "iconv-lite": {
+ "version": "0.4.23",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz",
+ "integrity": "sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==",
+ "requires": {
+ "safer-buffer": ">= 2.1.2 < 3"
+ }
+ },
+ "inflight": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
+ "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
+ "requires": {
+ "once": "^1.3.0",
+ "wrappy": "1"
+ }
+ },
+ "inherits": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
+ "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
+ },
+ "invert-kv": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz",
+ "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY="
+ },
+ "ipaddr.js": {
+ "version": "1.8.0",
+ "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.8.0.tgz",
+ "integrity": "sha1-6qM9bd16zo9/b+DJygRA5wZzix4="
+ },
+ "is-fullwidth-code-point": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
+ "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
+ "requires": {
+ "number-is-nan": "^1.0.0"
+ }
+ },
+ "is-hex-prefixed": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-hex-prefixed/-/is-hex-prefixed-1.0.0.tgz",
+ "integrity": "sha1-fY035q135dEnFIkTxXPggtd39VQ="
+ },
+ "keccak": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/keccak/-/keccak-1.4.0.tgz",
+ "integrity": "sha512-eZVaCpblK5formjPjeTBik7TAg+pqnDrMHIffSvi9Lh7PQgM1+hSzakUeZFCk9DVVG0dacZJuaz2ntwlzZUIBw==",
+ "requires": {
+ "bindings": "^1.2.1",
+ "inherits": "^2.0.3",
+ "nan": "^2.2.1",
+ "safe-buffer": "^5.1.0"
+ }
+ },
+ "lcid": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz",
+ "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=",
+ "requires": {
+ "invert-kv": "^1.0.0"
+ }
+ },
+ "lodash.camelcase": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz",
+ "integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY="
+ },
+ "lodash.clone": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/lodash.clone/-/lodash.clone-4.5.0.tgz",
+ "integrity": "sha1-GVhwRQ9aExkkeN9Lw9I9LeoZB7Y="
+ },
+ "long": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz",
+ "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA=="
+ },
+ "md5.js": {
+ "version": "1.3.5",
+ "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz",
+ "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==",
+ "requires": {
+ "hash-base": "^3.0.0",
+ "inherits": "^2.0.1",
+ "safe-buffer": "^5.1.2"
+ },
+ "dependencies": {
+ "safe-buffer": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz",
+ "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg=="
+ }
+ }
+ },
+ "media-typer": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
+ "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g="
+ },
+ "merge-descriptors": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
+ "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E="
+ },
+ "methods": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
+ "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4="
+ },
+ "mime": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz",
+ "integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ=="
+ },
+ "mime-db": {
+ "version": "1.36.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.36.0.tgz",
+ "integrity": "sha512-L+xvyD9MkoYMXb1jAmzI/lWYAxAMCPvIBSWur0PZ5nOf5euahRLVqH//FKW9mWp2lkqUgYiXPgkzfMUFi4zVDw=="
+ },
+ "mime-types": {
+ "version": "2.1.20",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.20.tgz",
+ "integrity": "sha512-HrkrPaP9vGuWbLK1B1FfgAkbqNjIuy4eHlIYnFi7kamZyLLrGlo2mpcx0bBmNpKqBtYtAfGbodDddIgddSJC2A==",
+ "requires": {
+ "mime-db": "~1.36.0"
+ }
+ },
+ "minimalistic-assert": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz",
+ "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A=="
+ },
+ "minimalistic-crypto-utils": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz",
+ "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo="
+ },
+ "minimatch": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
+ "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
+ "requires": {
+ "brace-expansion": "^1.1.7"
+ }
+ },
+ "ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
+ },
+ "nan": {
+ "version": "2.14.0",
+ "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz",
+ "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg=="
+ },
+ "negotiator": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz",
+ "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk="
+ },
+ "number-is-nan": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz",
+ "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0="
+ },
+ "on-finished": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
+ "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=",
+ "requires": {
+ "ee-first": "1.1.1"
+ }
+ },
+ "once": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+ "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
+ "requires": {
+ "wrappy": "1"
+ }
+ },
+ "optjs": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/optjs/-/optjs-3.2.2.tgz",
+ "integrity": "sha1-aabOicRCpEQDFBrS+bNwvVu29O4="
+ },
+ "os-locale": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz",
+ "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=",
+ "requires": {
+ "lcid": "^1.0.0"
+ }
+ },
+ "parseurl": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz",
+ "integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M="
+ },
+ "path-is-absolute": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+ "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18="
+ },
+ "path-to-regexp": {
+ "version": "0.1.7",
+ "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
+ "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w="
+ },
+ "protobufjs": {
+ "version": "6.8.8",
+ "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.8.8.tgz",
+ "integrity": "sha512-AAmHtD5pXgZfi7GMpllpO3q1Xw1OYldr+dMUlAnffGTAhqkg72WdmSY71uKBF/JuyiKs8psYbtKrhi0ASCD8qw==",
+ "requires": {
+ "@protobufjs/aspromise": "^1.1.2",
+ "@protobufjs/base64": "^1.1.2",
+ "@protobufjs/codegen": "^2.0.4",
+ "@protobufjs/eventemitter": "^1.1.0",
+ "@protobufjs/fetch": "^1.1.0",
+ "@protobufjs/float": "^1.0.2",
+ "@protobufjs/inquire": "^1.1.0",
+ "@protobufjs/path": "^1.1.2",
+ "@protobufjs/pool": "^1.1.0",
+ "@protobufjs/utf8": "^1.1.0",
+ "@types/long": "^4.0.0",
+ "@types/node": "^10.1.0",
+ "long": "^4.0.0"
+ }
+ },
+ "proxy-addr": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.4.tgz",
+ "integrity": "sha512-5erio2h9jp5CHGwcybmxmVqHmnCBZeewlfJ0pex+UW7Qny7OOZXTtH56TGNyBizkgiOwhJtMKrVzDTeKcySZwA==",
+ "requires": {
+ "forwarded": "~0.1.2",
+ "ipaddr.js": "1.8.0"
+ }
+ },
+ "qs": {
+ "version": "6.5.1",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz",
+ "integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A=="
+ },
+ "range-parser": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz",
+ "integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4="
+ },
+ "raw-body": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.3.tgz",
+ "integrity": "sha512-9esiElv1BrZoI3rCDuOuKCBRbuApGGaDPQfjSflGxdy4oyzqghxu6klEkkVIvBje+FF0BX9coEv8KqW6X/7njw==",
+ "requires": {
+ "bytes": "3.0.0",
+ "http-errors": "1.6.3",
+ "iconv-lite": "0.4.23",
+ "unpipe": "1.0.0"
+ }
+ },
+ "ripemd160": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz",
+ "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==",
+ "requires": {
+ "hash-base": "^3.0.0",
+ "inherits": "^2.0.1"
+ }
+ },
+ "rlp": {
+ "version": "2.2.3",
+ "resolved": "https://registry.npmjs.org/rlp/-/rlp-2.2.3.tgz",
+ "integrity": "sha512-l6YVrI7+d2vpW6D6rS05x2Xrmq8oW7v3pieZOJKBEdjuTF4Kz/iwk55Zyh1Zaz+KOB2kC8+2jZlp2u9L4tTzCQ==",
+ "requires": {
+ "bn.js": "^4.11.1",
+ "safe-buffer": "^5.1.1"
+ }
+ },
+ "safe-buffer": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz",
+ "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg=="
+ },
+ "safer-buffer": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
+ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
+ },
+ "secp256k1": {
+ "version": "3.7.1",
+ "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-3.7.1.tgz",
+ "integrity": "sha512-1cf8sbnRreXrQFdH6qsg2H71Xw91fCCS9Yp021GnUNJzWJS/py96fS4lHbnTnouLp08Xj6jBoBB6V78Tdbdu5g==",
+ "requires": {
+ "bindings": "^1.5.0",
+ "bip66": "^1.1.5",
+ "bn.js": "^4.11.8",
+ "create-hash": "^1.2.0",
+ "drbg.js": "^1.0.1",
+ "elliptic": "^6.4.1",
+ "nan": "^2.14.0",
+ "safe-buffer": "^5.1.2"
+ },
+ "dependencies": {
+ "safe-buffer": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz",
+ "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg=="
+ }
+ }
+ },
+ "send": {
+ "version": "0.16.2",
+ "resolved": "https://registry.npmjs.org/send/-/send-0.16.2.tgz",
+ "integrity": "sha512-E64YFPUssFHEFBvpbbjr44NCLtI1AohxQ8ZSiJjQLskAdKuriYEP6VyGEsRDH8ScozGpkaX1BGvhanqCwkcEZw==",
+ "requires": {
+ "debug": "2.6.9",
+ "depd": "~1.1.2",
+ "destroy": "~1.0.4",
+ "encodeurl": "~1.0.2",
+ "escape-html": "~1.0.3",
+ "etag": "~1.8.1",
+ "fresh": "0.5.2",
+ "http-errors": "~1.6.2",
+ "mime": "1.4.1",
+ "ms": "2.0.0",
+ "on-finished": "~2.3.0",
+ "range-parser": "~1.2.0",
+ "statuses": "~1.4.0"
+ }
+ },
+ "serve-static": {
+ "version": "1.13.2",
+ "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.13.2.tgz",
+ "integrity": "sha512-p/tdJrO4U387R9oMjb1oj7qSMaMfmOyd4j9hOFoxZe2baQszgHcSWjuya/CiT5kgZZKRudHNOA0pYXOl8rQ5nw==",
+ "requires": {
+ "encodeurl": "~1.0.2",
+ "escape-html": "~1.0.3",
+ "parseurl": "~1.3.2",
+ "send": "0.16.2"
+ }
+ },
+ "setprototypeof": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz",
+ "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ=="
+ },
+ "sha.js": {
+ "version": "2.4.11",
+ "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz",
+ "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==",
+ "requires": {
+ "inherits": "^2.0.1",
+ "safe-buffer": "^5.0.1"
+ }
+ },
+ "statuses": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz",
+ "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew=="
+ },
+ "string-width": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
+ "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
+ "requires": {
+ "code-point-at": "^1.0.0",
+ "is-fullwidth-code-point": "^1.0.0",
+ "strip-ansi": "^3.0.0"
+ }
+ },
+ "strip-ansi": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
+ "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
+ "requires": {
+ "ansi-regex": "^2.0.0"
+ }
+ },
+ "strip-hex-prefix": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/strip-hex-prefix/-/strip-hex-prefix-1.0.0.tgz",
+ "integrity": "sha1-DF8VX+8RUTczd96du1iNoFUA428=",
+ "requires": {
+ "is-hex-prefixed": "1.0.0"
+ }
+ },
+ "type-is": {
+ "version": "1.6.16",
+ "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.16.tgz",
+ "integrity": "sha512-HRkVv/5qY2G6I8iab9cI7v1bOIdhm94dVjQCPFElW9W+3GeDOSHmy2EBYe4VTApuzolPcmgFTN3ftVJRKR2J9Q==",
+ "requires": {
+ "media-typer": "0.3.0",
+ "mime-types": "~2.1.18"
+ }
+ },
+ "unpipe": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
+ "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw="
+ },
+ "utils-merge": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
+ "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM="
+ },
+ "vary": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
+ "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw="
+ },
+ "window-size": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.4.tgz",
+ "integrity": "sha1-+OGqHuWlPsW/FR/6CXQqatdpeHY="
+ },
+ "wrap-ansi": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz",
+ "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=",
+ "requires": {
+ "string-width": "^1.0.1",
+ "strip-ansi": "^3.0.1"
+ }
+ },
+ "wrappy": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+ "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
+ },
+ "y18n": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz",
+ "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE="
+ },
+ "yargs": {
+ "version": "3.32.0",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.32.0.tgz",
+ "integrity": "sha1-AwiOnr+edWtpdRYR0qXvWRSCyZU=",
+ "requires": {
+ "camelcase": "^2.0.1",
+ "cliui": "^3.0.3",
+ "decamelize": "^1.1.1",
+ "os-locale": "^1.4.0",
+ "string-width": "^1.0.1",
+ "window-size": "^0.1.4",
+ "y18n": "^3.2.0"
+ }
+ }
+ }
+}
diff --git a/example/basic-app-website/package.json b/example/basic-app-website/package.json
new file mode 100644
index 000000000..fedd4ceb8
--- /dev/null
+++ b/example/basic-app-website/package.json
@@ -0,0 +1,17 @@
+{
+ "name": "basic-app",
+ "version": "1.0.0",
+ "description": "Simple end-to-end Burrow app",
+ "main": "app.js",
+ "scripts": {
+ "test": "node app.js"
+ },
+ "author": "Silas Davis, website section added by Luke Riley",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@monax/burrow": "^0.24.3",
+ "body-parser": "^1.18.3",
+ "express": "^4.16.3",
+ "ejs": "^2.6.2"
+ }
+}
diff --git a/example/basic-app-website/public/css/style.css b/example/basic-app-website/public/css/style.css
new file mode 100644
index 000000000..f9015ef92
--- /dev/null
+++ b/example/basic-app-website/public/css/style.css
@@ -0,0 +1,74 @@
+/*
+ Styles from this codepen:
+ https://codepen.io/official_naveen/pen/rgknI
+*/
+
+body {
+ width: 800px;
+ margin: 0 auto;
+ font-family: 'Open Sans', sans-serif;
+}
+.container {
+ width: 600px;
+ margin: 0 auto;
+}
+fieldset {
+ display: block;
+ -webkit-margin-start: 0px;
+ -webkit-margin-end: 0px;
+ -webkit-padding-before: 0em;
+ -webkit-padding-start: 0em;
+ -webkit-padding-end: 0em;
+ -webkit-padding-after: 0em;
+ border: 0px;
+ border-image-source: initial;
+ border-image-slice: initial;
+ border-image-width: initial;
+ border-image-outset: initial;
+ border-image-repeat: initial;
+ min-width: -webkit-min-content;
+ padding: 30px;
+}
+.ghost-input, p {
+ display: block;
+ font-weight:300;
+ width: 100%;
+ font-size: 25px;
+ border:0px;
+ outline: none;
+ width: 100%;
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+ color: #4b545f;
+ background: #fff;
+ font-family: Open Sans,Verdana;
+ padding: 10px 15px;
+ margin: 30px 0px;
+ -webkit-transition: all 0.1s ease-in-out;
+ -moz-transition: all 0.1s ease-in-out;
+ -ms-transition: all 0.1s ease-in-out;
+ -o-transition: all 0.1s ease-in-out;
+ transition: all 0.1s ease-in-out;
+}
+.ghost-input:focus {
+ border-bottom:1px solid #ddd;
+}
+.ghost-button {
+ background-color: transparent;
+ border:2px solid #ddd;
+ padding:10px 30px;
+ width: 100%;
+ min-width: 350px;
+ -webkit-transition: all 0.1s ease-in-out;
+ -moz-transition: all 0.1s ease-in-out;
+ -ms-transition: all 0.1s ease-in-out;
+ -o-transition: all 0.1s ease-in-out;
+ transition: all 0.1s ease-in-out;
+}
+.ghost-button:hover {
+ border:2px solid #515151;
+}
+p {
+ color: #E64A19;
+}
diff --git a/example/basic-app-website/simplestorage.sol b/example/basic-app-website/simplestorage.sol
new file mode 100644
index 000000000..a5340eff0
--- /dev/null
+++ b/example/basic-app-website/simplestorage.sol
@@ -0,0 +1,28 @@
+pragma solidity >=0.0.0;
+
+
+contract simplestorage {
+ uint public storedData;
+
+ constructor(uint initVal) public {
+ storedData = initVal;
+ }
+
+ function set(uint value) public {
+ storedData = value;
+ }
+
+ function get() public view returns (uint value) {
+ return storedData;
+ }
+
+ // Since transactions are executed atomically we can implement this concurrency primitive in Solidity with the
+ // desired behaviour
+ function testAndSet(uint expected, uint newValue) public returns (uint value, bool success) {
+ if (storedData == expected) {
+ storedData = newValue;
+ return (storedData, true);
+ }
+ return (storedData, false);
+ }
+}
diff --git a/example/basic-app-website/views/index.ejs b/example/basic-app-website/views/index.ejs
new file mode 100644
index 000000000..c4cfb32e1
--- /dev/null
+++ b/example/basic-app-website/views/index.ejs
@@ -0,0 +1,32 @@
+
+
+
+
+
+ Test
+
+
+
+
+