npm package: @qiwitech/mastersuite
Description: Masterchain JS suite
Author: Ivan Khrulev
Latest version: 0.1.3

# Masterchain JS suite

Suite for Masterchain blockchain platform.

## Precaution

This software may work with sensitive cryptographic data such as passwords, certificates and private keys. To prevent such data to be accidentally exposed, compromised or lost, always be sure to check your execution environment.

## Contents

This is a NPM [monorepo](https://github.com/babel/babel/blob/master/doc/design/monorepo.md) maintained using [Yarn](https://yarnpkg.com/) with [Workspaces](https://yarnpkg.com/blog/2017/08/02/introducing-workspaces/).

This meta-package contains the following packages:

[@qiwitech/masterchain](https://www.npmjs.com/package/@qiwitech/masterchain)

[@qiwitech/cryptopro](https://www.npmjs.com/package/@qiwitech/cryptopro)

[@qiwitech/gostcrypto](https://www.npmjs.com/package/@qiwitech/gostcrypto)

## Installation

Needless to say, you need [Node.js](https://nodejs.org/) to be installed.

Also, [Yarn](https://yarnpkg.com/) is needed, since its [Workspaces](https://yarnpkg.com/blog/2017/08/02/introducing-workspaces/) are used.

```shell
yarn install --production=false
```

Note that `devDependencies` are not installed with `NODE_ENV=production`, so it's necessary to override the environment on first installation, especially on CI/CD runner.

### Browser note

To use [Crypto-Pro CAdES browser plugin](https://www.cryptopro.ru/sites/default/files/products/cades/demopage/main.html), you should load its vendor script [cadesplugin_api.js](https://www.cryptopro.ru/sites/default/files/products/cades/cadesplugin_api.js) which isn't included to this package.

```html
<script type="text/javascript" src="https://www.cryptopro.ru/sites/default/files/products/cades/cadesplugin_api.js"></script>
```

## Testing

### Warning!

Do not run auto-tests in environments where any sensitive cryptographic data are available, such as certificates or private keys. You may lose them accidentally, without the possibility of recovery, due to clean-up process. Also, some other data could be encrypted and/or signed on your behalf automatically without any prompt, possibly compromising your keys. Additionally, test certificates may be automatically installed into your personal certificate store.

### Automatic

There are 3 levels of [Mocha](https://mochajs.org/) tests:

* High-level test suites which provide automation and configuration.
* [Tasty](https://www.npmjs.com/package/tasty) integration tests.
* [Karma](http://karma-runner.github.io/) module tests.

Before running tests, you need to add some hosts into Crypto-Pro whitelist for test runner not to stuck waiting for popup from Crypto-Pro CAdES Browser plugin.

The whitelist could be edited on [special page](chrome-extension://iifchhfnnmpdbibifmljnfjhpififfog/trusted_sites.html) of corresponding Chrome extension. Current list is:

```
http://localhost
http://localhost:8765
http://localhost:9876
```

After that, in Windows Registry, inside `HKEY_CURRENT_USER\Software\Crypto Pro\CAdESplugin` must be a key named `TrustedSites` of type `REG_MULTI_SZ` containing URLs listed above, separated by two zero bytes. See the exact format in [whitelist.reg](packages/cryptopro/test/data/whitelist.reg).

See [cryptopro's README.md](packages/cryptopro/README.md) for more info.

```shell
yarn test
```

See [test/runner.js](test/runner.js) for details.

### Manual

```shell
yarn start
```

Open `http://localhost:8888/masterchain.html` in a browser for manual testing.

## Examples

### Start using Crypto-Pro

```typescript
import { cryptopro, masterchain } from '@qiwitech/mastersuite';
import { Web3 } from 'web3';

const web3 = new Web3(
	new Web3.providers.HttpProvider('...')
);

const plugin = await cryptopro.getPlugin(window),
	helper = await cryptopro.createHelper(plugin),
	crypto = {
		subtle: await cryptopro.createSubtleCrypto(helper)
	};

const client = new masterchain.Client(web3, crypto);
```

### Start using gostCrypto

```typescript
import { gostcrypto, masterchain } from '@qiwitech/mastersuite';
import { Web3 } from 'web3';

const web3 = new Web3(
	new Web3.providers.HttpProvider('...')
);

const client = new masterchain.Client(web3, gostcrypto);
```

### Create account

```typescript
let account = await client.createAccount();
// NOTE account.address is already exists.

if (account.certificateRequest) {
	// NOTE account.privateKey is null, account.sendTransaction throws,
	// we need to issue and install certificate first.

	downloadBlob(
		account.certificateRequest.name,
		account.certificateRequest.blob
	);

	// TODO send downloaded file to CA and upload issued certificate.

	const file = ...,
		x509 = await readFile(file);
	account = await client.certificateToAccount(x509);
}

account.sendTransaction(...);
```