Skip to content

Commit

Permalink
Merge #1431
Browse files Browse the repository at this point in the history
1431: Introduce support for React Native r=popzxc a=slumber



Co-authored-by: Chris Sosnin <[email protected]>
Co-authored-by: Chris Sosnin <[email protected]>
  • Loading branch information
3 people authored Mar 4, 2021
2 parents 52f8130 + 4156765 commit 11a2655
Show file tree
Hide file tree
Showing 7 changed files with 71 additions and 12 deletions.
1 change: 1 addition & 0 deletions changelog/js-sdk.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ All notable changes to `zksync.js` will be documented in this file.
### Added

- Method for calculation of transaction hash.
- Support for environments without WebAssembly.

### Changed

Expand Down
8 changes: 8 additions & 0 deletions docs/setup-dev.md
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,14 @@ brew install solidity@5

drone cli used to create promotion jobs [described here](docs/promote.md) <https://docs.drone.io/cli/install/>

## `binaryen`

Provides `wasm2js` utility which is required to build the `zksync-crypto`.

```sh
sudo apt-get install binaryen
```

## Environment

Edit the lines below and add them to your shell profile file (e.g. `~/.bash_profile`):
Expand Down
13 changes: 13 additions & 0 deletions sdk/zksync-crypto/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,24 @@

set -e

ASM=dist/zksync-crypto-bundler_bg_asm.js

which wasm-pack || cargo install wasm-pack

# pack for bundler (!note this verion is used in the pkg.browser field)
wasm-pack build --release --target=bundler --out-name=zksync-crypto-bundler --out-dir=dist

# convert the bundler build into JS in case the environment doesn't support WebAssembly
wasm2js ./dist/zksync-crypto-bundler_bg.wasm -o $ASM

# save another copy for bg_asm import
cp ./dist/zksync-crypto-bundler.js ./dist/zksync-crypto-bundler_asm.js

# fix imports for asm
sed -i "s/^import.*/\
let wasm = require('.\/zksync-crypto-bundler_bg_asm.js');/" ./dist/zksync-crypto-bundler_asm.js
sed -i "s/\.js/_asm\.js/g" $ASM

# pack for browser
wasm-pack build --release --target=web --out-name=zksync-crypto-web --out-dir=dist

Expand Down
2 changes: 1 addition & 1 deletion sdk/zksync-crypto/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "zksync-crypto",
"version": "0.4.5",
"version": "0.5.0",
"browser": "dist/zksync-crypto-web.js",
"main": "dist/zksync-crypto-node.js",
"files": [
Expand Down
16 changes: 16 additions & 0 deletions sdk/zksync-crypto/web-wasm.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ const fs = require('fs');

const wasmFile = './dist/zksync-crypto-web_bg.wasm';
const jsFile = './dist/zksync-crypto-web.js';
// The output of wasm2js with a fixed import.
const asmJsFile = './zksync-crypto-bundler_asm.js';

const wasmData = fs.readFileSync(wasmFile);

Expand Down Expand Up @@ -46,7 +48,21 @@ const wasmResponseInit = {
}
};
export function wasmSupported() {
try {
if (typeof WebAssembly === 'object') {
return true;
}
} catch (e) {
}
return false;
}
export async function loadZkSyncCrypto(wasmFileUrl) {
if (!wasmSupported()) {
// Use the bundler build.
return require(\'${asmJsFile}\');
}
if (!wasmFileUrl) {
const wasmResponse = new Response(wasmBytes, wasmResponseInit);
await init(wasmResponse);
Expand Down
2 changes: 1 addition & 1 deletion sdk/zksync.js/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "zksync",
"version": "0.9.0",
"version": "0.10.0",
"license": "MIT",
"main": "build/index.js",
"types": "build/index.d.ts",
Expand Down
41 changes: 31 additions & 10 deletions sdk/zksync.js/src/crypto.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,32 @@
import { Signature } from './types';

import { private_key_to_pubkey_hash, sign_musig } from 'zksync-crypto';
import * as zks from 'zksync-crypto';
import { utils } from 'ethers';

/**
* This variable stores the zksync-crypto module compiled into
* asm.js for environments without WebAssembly support (e.g. React Native).
* It's either loaded once or left to be undefined, so whenever
* we are using the crypto package, we do it in the following way:
* ```
* const _zks = asmJs || zks;
* const signature = _zks.sign_musig(privKey, bytes);
* ```
*/
let asmJs = undefined;

export async function privateKeyFromSeed(seed: Uint8Array): Promise<Uint8Array> {
await loadZkSyncCrypto();

return zks.privateKeyFromSeed(seed);
const _zks = asmJs || zks;
return _zks.privateKeyFromSeed(seed);
}

export async function signTransactionBytes(privKey: Uint8Array, bytes: Uint8Array): Promise<Signature> {
await loadZkSyncCrypto();

const signaturePacked = sign_musig(privKey, bytes);
const _zks = asmJs || zks;
const signaturePacked = _zks.sign_musig(privKey, bytes);
const pubKey = utils.hexlify(signaturePacked.slice(0, 32)).substr(2);
const signature = utils.hexlify(signaturePacked.slice(32)).substr(2);
return {
Expand All @@ -25,7 +38,8 @@ export async function signTransactionBytes(privKey: Uint8Array, bytes: Uint8Arra
export async function privateKeyToPubKeyHash(privateKey: Uint8Array): Promise<string> {
await loadZkSyncCrypto();

return `sync:${utils.hexlify(private_key_to_pubkey_hash(privateKey)).substr(2)}`;
const _zks = asmJs || zks;
return `sync:${utils.hexlify(_zks.private_key_to_pubkey_hash(privateKey)).substr(2)}`;
}

let zksyncCryptoLoaded = false;
Expand All @@ -34,12 +48,19 @@ export async function loadZkSyncCrypto(wasmFileUrl?: string) {
return;
}
// Only runs in the browser
if ((zks as any).loadZkSyncCrypto) {
// It is ok if wasmFileUrl is not specified.
// Actually, typically it should not be specified,
// since the content of the `.wasm` file is read
// from the `.js` file itself.
await (zks as any).loadZkSyncCrypto(wasmFileUrl);
const _zks = zks as any;
if (_zks.loadZkSyncCrypto) {
if (!_zks.wasmSupported()) {
// Load the asm.js build which will be used instead.
// wasmFileUrl will be ignored.
asmJs = await _zks.loadZkSyncCrypto(wasmFileUrl);
} else {
// It is ok if wasmFileUrl is not specified.
// Actually, typically it should not be specified,
// since the content of the `.wasm` file is read
// from the `.js` file itself.
await _zks.loadZkSyncCrypto(wasmFileUrl);
}
zksyncCryptoLoaded = true;
}
}

0 comments on commit 11a2655

Please sign in to comment.