This commit introduces two new plugin APIs `registerTestContractFactory()` and
`registerCustomContractGenerator()`, which can be used to register a factory function
for the creation of web3 contract instances within tests, and custom code generation
for `embark console` respectively.
Example:
```
// some.plugin.js
module.exports = function (embark) {
embark.registerTestContractFactory(function (contractRecipe, web3) {
// do something with web3 and contractRecipe and return contract instance here
});
};
```
**Notice that**:
- This factory function is used for contract instance creation within tests.
A `contractRecipe` and a `web3` instance is accessible within the factory.
Example:
```
// some.plugin.js
module.exports = function (embark) {
embark.registerCustomContractGenerator(function (contractRecipe) {
// returns code string that will be eval'ed
});
};
```
**Notice that**:
- Once registered, this generator will be used for **all** contract instances
that will be created for `embark console`, including built-in once like
ENSRegistry.
- While this does affect contract creation in client-side code, it doesn't
actually affect the instances created for deployment hooks **if** deployment
hooks are written as functions.
Closes#1066
Always use custom generator and fallback to vanilla
Include yarn's global path when modifying `NODE_PATH` since dependencies are
deduped when a package is installed globally with yarn, which is different from
npm's behavior.
Fix webpack resolution by listing relative `'node_modules'` in
`resolve/Loader:{modules:[...]}`. This ensures that dependecies' dependecies
are resolved correctly when webpack builds a DApp.
Remove the invocation of `.catch()` on a subscription object which lacks that
method.
**TL;DR**
These changes affect workflow with yarn. To prevent embark's `prepare` script
from running undesirably:
- If node_modules is in place and you're reinstalling after switching branches:
```
yarn run install_all
```
- If node_modules is missing (fresh clone or deleted):
```
EMBARK_NO_PREPARE=t yarn install && yarn run install_all
```
It's not recommended to set `EMBARK_NO_PREPARE` in your environment (e.g. in
`.bashrc`) since that would interfere with embark's `release` script if/when
you run it.
-----------------
**1.** Specify embark's build-related steps in the `prepare` script of
package.json.
When embark is installed directly from GitHub the `prepare` script results in a
"pre install" phase (handled automatically by npm/yarn) that fetches
devDependencies, builds embark (including embark-ui), packs a tarball with the
same steps (minus testing and tree-checking) as would happen during an embark
release, and finally does a production install from that tarball.
Important point: installs from GitHub must be performed with yarn; they're no
longer possible with npm since during the "pre install" phase npm will honor
embark's `.npmrc` and `"engines"` settings.
The following will work correctly after this commit is merged:
```
yarn [global] add git+https://github.com/embark-framework/embark.git
```
Use of "hosted git" shortcuts (e.g. `embark-framework/embark#bracnh`) won't
work correctly because yarn doesn't fully support them. See:
https://github.com/yarnpkg/yarn/issues/5235.
It's important to use `git+https` urls. Following a succesful install with
`git+https` it is possible to use a "hosted git" shortcut or `https` url, but
that's owing to a subtle and unreliable interaction between yarn's cache and
yarn's logic for installing from a url/shortcut.
**2.** Adjust the npm configs (`.npmrc`) for embark/-ui so that `yarn run [cmd]
[--opt]` can be used in place of `npm run [cmd] -- [--opt]`.
Either way is okay for running scripts, they're equivalent, but note the
requirement to use `--` before specifying command options with `npm run`.
**3.** Introduce yarn configs (`.yarnrc`) for embark/-ui and include the
`check-files` directive.
H/t to @alaibe for the recommendation.
**4.** Ignore embark's `dist/typings` and `scripts` directories when packing a
tarball.
**5.** Refactor embark/-ui's npm-scripts in relation to the `prepare` script,
and make other small improvements.
Notably, if the environment variable `EMBARK_NO_PREPARE` is truthy (from JS
perspective) then embark's `prepare` script will exit early. This prevents
`install_all` and `prepare` from getting stuck in a loop (`install:core` uses
cross-env to set `EMBARK_NO_PREPARE`) and provides a mechanism for users to
skip the `prepare` script when doing a fresh install:
```
EMBARK_NO_PREPARE=t yarn install
```
**6.** Give `.js` extensions to node scripts in embark's `scripts/`, remove the
shebang lines, and have npm-scripts explicitly invoke them with node.
This arrangement works for all platforms: Linux, macOS, and Windows.
**7.** Adjust travis and appveyor configs.
Since at present there aren't any tests or other CI steps that make use of
embark-ui's production build, set `EMBARK_NO_PREPARE` in the CI environments
and invoke `build:node` directly.
Check the working tree after `yarn install` for embark/-ui. This detects
situations where changes should have been committed to `yarn.lock` but were
not. Check the working tree again at the end to detect situations where ignore
files should have been adjusted but were not. Both checks could also detect
other surprising behavior that needs to be investigated. Any time the working
tree is not clean (there are untracked files or changes) CI will fail.
Drop CI runs for node 8.11.3 because that version ships with an older npm that
results in unstaged changes to the test apps' `package-lock.json` files,
causing the working tree check to fail at the end of the CI run. A simple
workaround isn't apparent, but the matter can be revisited.
**8.** Refactor embark's `release` script in light of the `prepare` script.
Notably, do the push step only after `npm publish` completes successfully. This
allows embark's `prepare` and `prepublishOnly` scripts to detect problems
before a commit and tag are pushed to GitHub, avoiding a need to rebase/revert
the remote release branch; the local branch will still need to have a commit
dropped and tag deleted before rerunning the `release` script.
Prompt the user if the `release` script is not being run in `--dry-run` mode.
Provide additional visual indicators of `--dry-run` mode.
Force the user to supply `--repo-branch [branch]` if the intention is to
release from a branch other than `master`.
Ignore the sequence of bytes `03:ef:bf:bd` that are sent between
Chrome/Firefox (others?) and the node process when a browser connected via
websocket to the blockchain proxy is closed/reloaded. The theory is that
sequence is part of a socket control frame that is leaking to `parseJsonMaybe`
from `http-proxy-middleware`.
Use proper stream parsing to consistently track JSON-RPC messages.
For HTTP POST requests use the `stream-json` package to assemble request and
response message objects.
For WebSocket requests continue to use `simples/lib/parsers/ws` to process
stream frames into messages. For Websocket responses use the Receiver class of
the `ws` package to process stream data into messages. In both cases, make use
of the `cloneable-readable` and `stream-chain` packages to avoid leaks.
This mishmash of stream parsing approaches is the result of much
experimentation to find a working solution. For example,
`simples/lib/parsers/ws` does't work for processing WebSocket responses and
`ws.Receiver` doesn't work for processing requests. Additional revisions may be
necessary.
Revise `blockchain_process/dev_funds.js` to use web3's HTTP provider if a DApp
disables the WebSocket proxy.
As discussed in #1121, the `eject-webpack` command in Embark's CLI
exposes implementation details of the CLI's build process, namely webpack.
If we ever change our internal build tooling, commands like this
will become obsolete immediately. That's why this commit introduces
a new command `eject-build-config`, with `eject-webpack` being an alias for it.
So the following commands are the same:
```
$ embark eject-build-config
```
and
```
$ embark eject-webpack
```
The `eject-webpack` command can now be marked as deprecated and removed in future
versions of Embark.
Closes#1121
This commit allows dapp developers to specify an ABI for contracts that are
already deployed and which source they don't own.
Prior to this commit there were two options to use web3 contract instances of 3rd
party contracts in Embark:
1. Define an interface for the 3rd party contract and have Embark compile that
2. Define path to source file of 3rd party contract and have Embark compile that
Both options result in Embark getting hold of the contracts ABI so it can be used
by web3 to create instances.
Now there's a third option that doesn't require creating an interface, nor the
source of the 3rd party contract.
Example:
```
// config/contracts.js
...
contracts: {
SimpleStorage: {
address: '0x0bFb07f9144729EEF54A9057Af0Fcf87aC7Cbba9',
abiDefinition: [...] // full ABI
}
},
afterDeploy: async(deps) => {
const simpleStorage = deps.contracts.SimpleStorage;
const value = await simpleStorage.methods.get().call();
console.log('value', value);
}
```
In d3f6b43986 we ensured that Embark automatically
expands `0x0` address to full zero addresses in order to stay backward compatible
with existing projects that made use of `0x0`, even after we've upgraded web3,
which doesn't allow that syntax anymore.
Turns out however, that the address expansion for `afterDeploy` hook was
done in the wrong place. This was due to a bug in our documentation that has been
fixed in 66a5bec46d
We've introduced a regression in 2dfaaa8201 where zero addresses
have been replaced with a constant, including the ones within ENSFunctions.
The problem is that this code is as well added to the EmbarkJS client, where importing
`../../utils/addressUtils` won't work as it isn't available.
This commit reverts back to have ENSFunctions having its own ZERO_ADDRESS constant.
This commit fixes a bug in a scenario where dapp developers choose to refer
to an already deployed Smart Contract (they don't own) and want to use its web3 instance
on the client-side, or in deployment hooks.
For example, Dapp developers might want to do something like this:
```
// config/contract.js
...
contracts: {
SimpleStorage: {
address: '0x1234...' // SimpleStorage is already deployed
}
},
afterDeploy: async (deps) => {
const simpleStorage = deps.contracts.SimpleStorage; // this is the web3 instance created from an ABI
const value = await simpleStorage.methods.get().call();
console.log(value);
}
...
```
In order for Embark to create ready-to-use web3 Smart Contract instances,
it needs the contract's ABI. At the moment there are two possible ways to
achieve this for contracts we don't own:
1. Set the `address` of the already deployed contract and create a Solidity
interface with the same name of the existing Contract that matches that
Contract's interface. Embark is then going to compile that interface
which will output an ABI whic can be used for web3 instance creation.
2. If the source of the 3rd party Smart Contract is available, use the
`file` option to specify the path to the source, which Embark then picks
up for compilation. Again, this results in ABI code which is then used
for web3 instance creation.
As of now option 1) doesn't actually work, at least web3 is going to throw
an error when trying to access Smart Contract instances that have been created
that way. The reason for that is that the instance doesn't have a `deployedAddress`.
This commit ensures that the `deployedAddress` is set when the Smart Contract
config comes with a preconfigured `address`.