diff --git a/.gitignore b/.gitignore
index af5378f..ac3294a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -16,6 +16,8 @@ lib/
node/
*.log
+#cache
+.rpt2_cache
# Xcode
#
build/
diff --git a/gulpfile.js b/gulpfile.js
new file mode 100644
index 0000000..4c341e3
--- /dev/null
+++ b/gulpfile.js
@@ -0,0 +1,25 @@
+const { task } = require('gulp');
+const del = require('del');
+
+const packages = ['harmony-crypto'];
+
+task('cleanBrowser', async () => {
+ await packages.map((p) => {
+ const pathToLib = `packages/${p}/lib`;
+ return del.sync([pathToLib]);
+ });
+});
+
+task('cleanServer', async () => {
+ await packages.map((p) => {
+ const pathToLib = `packages/${p}/node`;
+ return del.sync([pathToLib]);
+ });
+});
+
+task('cleanDocs', async () => {
+ await packages.map((p) => {
+ const pathToLib = `packages/${p}/doc`;
+ return del.sync([pathToLib]);
+ });
+});
diff --git a/package.json b/package.json
index df92c8a..b94e84f 100644
--- a/package.json
+++ b/package.json
@@ -5,6 +5,8 @@
"packages/*"
],
"scripts": {
+ "packages:cleanBrowser": "gulp cleanBrowser",
+ "packages:browser": "yarn packages:cleanBrowser && rollup --c scripts/rollup/bundleBrowser.js",
"bootstrap": "lerna bootstrap && yarn build",
"build": "yarn build:proto && yarn build:ts",
"build:ts": "tsc -b tsconfig.json",
@@ -60,8 +62,10 @@
"cross-env": "^5.2.0",
"dotenv": "^6.0.0",
"fancy-log": "^1.3.2",
+ "fbjs-scripts": "^0.8.3",
"glob": "^7.1.3",
"glob-parent": "^3.1.0",
+ "gulp": "^4.0.0",
"husky": "^1.1.2",
"jest": "^23.4.2",
"jest-fetch-mock": "^1.6.6",
@@ -88,5 +92,10 @@
"typescript-json-schema": "^0.32.0",
"webpack": "^4.20.2",
"webpack-command": "^0.4.1"
+ },
+ "dependencies": {
+ "del": "^4.0.0",
+ "rollup-plugin-babel": "^4.3.2",
+ "rollup-plugin-license": "^0.8.1"
}
}
diff --git a/packages/harmony-crypto/src/index.ts b/packages/harmony-crypto/src/index.ts
index e69de29..84a8bef 100644
--- a/packages/harmony-crypto/src/index.ts
+++ b/packages/harmony-crypto/src/index.ts
@@ -0,0 +1 @@
+export { randomBytes } from './random';
diff --git a/packages/harmony-crypto/src/random.ts b/packages/harmony-crypto/src/random.ts
index e69de29..225549f 100644
--- a/packages/harmony-crypto/src/random.ts
+++ b/packages/harmony-crypto/src/random.ts
@@ -0,0 +1,29 @@
+/**
+ * @function randomBytes
+ * @description Uses JS-native CSPRNG to generate a specified number of bytes.
+ * NOTE: this method throws if no PRNG is available.
+ * @param {Number} bytes bytes number to generate
+ * @return {String} ramdom hex string
+ */
+export const randomBytes = (bytes: number): string => {
+ let randBz: number[] | Uint8Array;
+
+ if (
+ typeof window !== 'undefined' &&
+ window.crypto &&
+ window.crypto.getRandomValues
+ ) {
+ randBz = window.crypto.getRandomValues(new Uint8Array(bytes));
+ } else if (typeof require !== 'undefined') {
+ randBz = require('crypto').randomBytes(bytes);
+ } else {
+ throw new Error('Unable to generate safe random numbers.');
+ }
+
+ let randStr = '';
+ for (let i = 0; i < bytes; i += 1) {
+ randStr += `00${randBz[i].toString(16)}`.slice(-2);
+ }
+
+ return randStr;
+};
diff --git a/packages/harmony-crypto/temp/temp.html b/packages/harmony-crypto/temp/temp.html
new file mode 100644
index 0000000..1134f13
--- /dev/null
+++ b/packages/harmony-crypto/temp/temp.html
@@ -0,0 +1,56 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ This is Laksa.js simple example, load this html in latest chrome please
+
+
+
Current Provider is:
+
+
+
+
Input address, and get balance of it
+
+
+
+ balance: nonce:
+
+
+
+
+
+
+
+
diff --git a/scripts/babel/babel.browser.config.js b/scripts/babel/babel.browser.config.js
new file mode 100644
index 0000000..ed0335e
--- /dev/null
+++ b/scripts/babel/babel.browser.config.js
@@ -0,0 +1,31 @@
+export default {
+ babelrc: false,
+ runtimeHelpers: true,
+ presets: [
+ [
+ '@babel/env',
+ {
+ modules: false,
+ targets: {
+ browsers: ['>0.25%']
+ },
+ useBuiltIns: 'usage'
+ }
+ ]
+ ],
+ plugins: [
+ ['@babel/transform-runtime'],
+ '@babel/proposal-object-rest-spread',
+ '@babel/proposal-export-default-from',
+ '@babel/proposal-export-namespace-from',
+ [
+ '@babel/plugin-proposal-decorators',
+ {
+ legacy: true
+ }
+ ],
+ '@babel/proposal-class-properties',
+ 'add-module-exports'
+ ],
+ exclude: 'packages/**/node_modules/**'
+}
diff --git a/scripts/babel/babel.server.config.js b/scripts/babel/babel.server.config.js
new file mode 100644
index 0000000..c86eedb
--- /dev/null
+++ b/scripts/babel/babel.server.config.js
@@ -0,0 +1,31 @@
+export default {
+ babelrc: false,
+ // runtimeHelpers: true,
+ presets: [
+ [
+ '@babel/env',
+ {
+ modules: false,
+ targets: {
+ node: 'current'
+ }
+ }
+ ]
+ ],
+
+ plugins: [
+ // ['@babel/transform-runtime'],
+ '@babel/proposal-object-rest-spread',
+ '@babel/proposal-export-default-from',
+ '@babel/proposal-export-namespace-from',
+ [
+ '@babel/plugin-proposal-decorators',
+ {
+ legacy: true
+ }
+ ],
+ '@babel/proposal-class-properties',
+ 'add-module-exports'
+ ],
+ exclude: 'packages/**/node_modules/**'
+}
diff --git a/scripts/babel/babel.src.config.js b/scripts/babel/babel.src.config.js
new file mode 100644
index 0000000..a36e10f
--- /dev/null
+++ b/scripts/babel/babel.src.config.js
@@ -0,0 +1,18 @@
+module.exports = {
+ babelrc: false,
+ presets: ['@babel/env'],
+ plugins: [
+ ['@babel/transform-runtime'],
+ '@babel/proposal-object-rest-spread',
+ '@babel/proposal-export-default-from',
+ '@babel/proposal-export-namespace-from',
+ [
+ '@babel/plugin-proposal-decorators',
+ {
+ legacy: true
+ }
+ ],
+ '@babel/proposal-class-properties',
+ 'add-module-exports'
+ ]
+}
diff --git a/scripts/babel/babel.test.config.js b/scripts/babel/babel.test.config.js
new file mode 100644
index 0000000..10d64d8
--- /dev/null
+++ b/scripts/babel/babel.test.config.js
@@ -0,0 +1,19 @@
+module.exports = {
+ babelrc: false,
+ presets: ['@babel/env'],
+ plugins: [
+ ['@babel/transform-runtime'],
+ '@babel/proposal-object-rest-spread',
+ '@babel/proposal-export-default-from',
+ '@babel/proposal-export-namespace-from',
+ [
+ '@babel/plugin-proposal-decorators',
+ {
+ legacy: true
+ }
+ ],
+ '@babel/proposal-class-properties',
+ 'add-module-exports'
+ ],
+ sourceMaps: 'inline'
+}
diff --git a/scripts/jest/jest.build.config.js b/scripts/jest/jest.build.config.js
new file mode 100644
index 0000000..13ead20
--- /dev/null
+++ b/scripts/jest/jest.build.config.js
@@ -0,0 +1,35 @@
+const { readdirSync, statSync } = require('fs')
+const { join } = require('path')
+const baseConfig = require('./jest.src.config')
+
+// Find all folders in packages/* with package.json
+const packagesRoot = join(__dirname, '..', '..', 'packages')
+const packages = readdirSync(packagesRoot).filter(dir => {
+ if (dir.charAt(0) === '.') {
+ return false
+ }
+ if (dir === 'events') {
+ // There's an actual Node package called "events"
+ // that's used by jsdom so we don't want to alias that.
+ return false
+ }
+ const packagePath = join(packagesRoot, dir, 'package.json')
+ return statSync(packagePath).isFile()
+})
+// Create a module map to point packages to the build output
+const moduleNameMapper = {}
+packages.forEach(name => {
+ // Root entry point
+ moduleNameMapper[`^${name}$`] = `/packages/${name}/lib/index.js`
+ // Named entry points
+ // moduleNameMapper[`^${name}/(.*)$`] = `/dist/node_modules/${name}/$1`
+})
+
+module.exports = Object.assign({}, baseConfig, {
+ // Redirect imports to the compiled bundles
+ moduleNameMapper,
+ // Don't run bundle tests on blacklisted -test.internal.* files
+ testPathIgnorePatterns: ['/node_modules/', '-test.internal.js$'],
+ // Exclude the build output from transforms
+ transformIgnorePatterns: ['/node_modules/', '/build/']
+})
diff --git a/scripts/jest/jest.framework-setup.js b/scripts/jest/jest.framework-setup.js
new file mode 100644
index 0000000..1c276a2
--- /dev/null
+++ b/scripts/jest/jest.framework-setup.js
@@ -0,0 +1,4 @@
+const { matchersWithOptions } = require('jest-json-schema')
+
+expect.extend(matchersWithOptions({ allErrors: true }))
+jest.setTimeout(180000)
diff --git a/scripts/jest/jest.setup.js b/scripts/jest/jest.setup.js
new file mode 100644
index 0000000..b123445
--- /dev/null
+++ b/scripts/jest/jest.setup.js
@@ -0,0 +1,3 @@
+global.fetch = require('jest-fetch-mock')
+
+window.fetch = global.fetch
diff --git a/scripts/jest/jest.src.config.js b/scripts/jest/jest.src.config.js
new file mode 100644
index 0000000..1a1310f
--- /dev/null
+++ b/scripts/jest/jest.src.config.js
@@ -0,0 +1,50 @@
+const config = {
+ transform: {
+ '^.+\\.(t|j)s$': require.resolve('./transformer.js')
+ },
+ testMatch: [
+ '/packages/**/__test__/?(*.)+(spec|test).js'
+ // '/packages/laksa-account/__test__/?(*.)+(spec|test).js',
+ // '/packages/laksa-blockchain/__test__/?(*.)+(spec|test).js',
+ // '/packages/laksa-core/__test__/?(*.)+(spec|test).js'
+ // '/packages/laksa-core-contract/__test__/?(*.)+(spec|test).js'
+ // '/packages/laksa-core-crypto/__test__/?(*.)+(spec|test).js',
+ // '/packages/laksa-core-messenger/__test__/?(*.)+(spec|test).js'
+ // '/packages/laksa-core-provider/__test__/?(*.)+(spec|test).js',
+ // '/packages/laksa-core-transaction/__test__/?(*.)+(spec|test).js',
+ // '/packages/laksa-extend-keystore/__test__/?(*.)+(spec|test).js',
+ // '/packages/laksa-providers-http/__test__/?(*.)+(spec|test).js',
+ // '/packages/laksa-shared/__test__/?(*.)+(spec|test).js'
+ // '/packages/laksa-utils/__test__/?(*.)+(spec|test).js',
+ // '/packages/laksa-wallet/__test__/?(*.)+(spec|test).js'
+ // '/packages/laksa/__test__/?(*.)+(spec|test).js'
+ ],
+ moduleDirectories: ['src', 'node_modules'],
+ moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'],
+ moduleNameMapper: {
+ 'cross-fetch': 'jest-fetch-mock'
+ },
+ testURL: 'http://localhost',
+ coverageThreshold: {
+ global: {
+ branches: 80,
+ functions: 80,
+ lines: 80,
+ statements: 80
+ }
+ },
+ rootDir: process.cwd(),
+ roots: ['/packages', '/scripts'],
+ collectCoverageFrom: [
+ 'packages/!(laksa-hd-wallet)/src/**/*.js'
+ // 'packages/!(laksa-core-crypto)/src/*.js'
+ ],
+ timers: 'fake',
+ setupFiles: ['/scripts/jest/jest.setup.js'],
+ setupTestFrameworkScriptFile: '/scripts/jest/jest.framework-setup.js',
+ testEnvironment: process.env.NODE_ENV === 'development' ? 'node' : 'jsdom',
+ collectCoverage: true,
+ automock: false
+}
+
+module.exports = config
diff --git a/scripts/jest/transformer.js b/scripts/jest/transformer.js
new file mode 100644
index 0000000..aecc3fc
--- /dev/null
+++ b/scripts/jest/transformer.js
@@ -0,0 +1,29 @@
+const path = require('path')
+const babel = require('@babel/core')
+const createCacheKeyFunction = require('fbjs-scripts/jest/createCacheKeyFunction')
+const babelOptions = require('../babel/babel.test.config.js')
+
+// Use require.resolve to be resilient to file moves, npm updates, etc
+const pathToBabel = path.join(require.resolve('@babel/core'), '../', '../', 'package.json')
+const pathToBabelrc = path.join(__dirname, '../babel/babel.test.config.js')
+
+module.exports = {
+ process(src, filePath) {
+ if (!filePath.match(/\/third_party\//)) {
+ const isTestFile = !!filePath.match(/\/__test__\//)
+ const concatOptions = Object.assign(
+ babelOptions,
+ { filename: path.relative(process.cwd(), filePath) },
+ isTestFile
+ ? {
+ plugins: babelOptions.plugins
+ }
+ : {}
+ )
+ const result = babel.transformSync(src, concatOptions)
+ return result.code
+ }
+ return src
+ },
+ getCacheKey: createCacheKeyFunction([__filename, pathToBabel, pathToBabelrc])
+}
diff --git a/scripts/packages.js b/scripts/packages.js
new file mode 100644
index 0000000..d47c2c2
--- /dev/null
+++ b/scripts/packages.js
@@ -0,0 +1,6 @@
+export default [
+ // 'harmony-account,
+ 'harmony-crypto',
+ // 'harmony-network',
+ // 'harmony-utils',
+];
diff --git a/scripts/packagesList.js b/scripts/packagesList.js
new file mode 100644
index 0000000..64de6b6
--- /dev/null
+++ b/scripts/packagesList.js
@@ -0,0 +1,9 @@
+module.exports = [
+ // { name: 'LaksaUtil', dest: 'laksa-utils' },
+ // { name: 'LaksaZil', dest: 'laksa-zil' },
+ // { name: 'LaksaCrypto', dest: 'laksa-core-crypto' },
+ // { name: 'LaksaWallet', dest: 'laksa-wallet' },
+ // { name: 'LaksaHDWallet', dest: 'laksa-hd-wallet' },
+ // { name: 'LaksaContract', dest: 'laksa-core-contract' },
+ // { name: 'Laksa', dest: 'laksa' }
+];
diff --git a/scripts/rollup/bundleBrowser.js b/scripts/rollup/bundleBrowser.js
new file mode 100644
index 0000000..de726e5
--- /dev/null
+++ b/scripts/rollup/bundleBrowser.js
@@ -0,0 +1,49 @@
+import * as path from 'path';
+import camelCase from 'camelcase';
+import babel from 'rollup-plugin-babel';
+import commonjs from 'rollup-plugin-commonjs';
+import license from 'rollup-plugin-license';
+import json from 'rollup-plugin-json';
+import typescript2 from 'rollup-plugin-typescript2';
+import ts from 'typescript';
+import packages from '../packages';
+import browserConfig from '../babel/babel.browser.config.js';
+import { getKeys } from './getDependencies';
+
+function bundles() {
+ return packages.map((p) => {
+ const external = getKeys(p);
+ const externalSetting = getKeys(p).length > 0 ? { external } : {};
+ const normal = {
+ input: `packages/${p}/src/index.ts`,
+ output: {
+ file: `packages/${p}/lib/index.js`,
+ format: 'umd',
+ name: camelCase(p),
+ },
+ plugins: [
+ typescript2({
+ typescript: ts, // ensure we're using the same typescript (3.x) for rollup as for regular builds etc
+ tsconfigOverride: {
+ module: 'esnext',
+ stripInternal: true,
+ emitDeclarationOnly: false,
+ composite: false,
+ declaration: false,
+ declarationMap: false,
+ sourceMap: true,
+ },
+ }),
+ babel(browserConfig),
+ commonjs(),
+ json(),
+ license({
+ banner: `Test Banner`,
+ }),
+ ],
+ };
+ return Object.assign(normal, externalSetting);
+ });
+}
+
+export default bundles();
diff --git a/scripts/rollup/bundleServer.js b/scripts/rollup/bundleServer.js
new file mode 100644
index 0000000..1ba7687
--- /dev/null
+++ b/scripts/rollup/bundleServer.js
@@ -0,0 +1,49 @@
+import babel from 'rollup-plugin-babel'
+import json from 'rollup-plugin-json'
+import license from 'rollup-plugin-license'
+import vuedoc from 'vuepress-jsdoc/cmds/index'
+import packages from '../packages'
+import serverConfig from '../babel/babel.server.config.js'
+import { getKeys } from './getDependencies'
+
+function bundles() {
+ return packages.map(p => {
+ const external = getKeys(p)
+ const externalSetting = getKeys(p).length > 0 ? { external } : {}
+ vuedoc.generate({
+ source: `packages/${p}/src`,
+ dist: `packages/${p}`,
+ folder: 'doc',
+ readme: `packages/${p}/README.md`
+ })
+ const normal = {
+ input: `packages/${p}/src/index.js`,
+ output: {
+ file: `packages/${p}/node/index.js`,
+ format: 'umd',
+ name: 'Laksa'
+ },
+ plugins: [
+ babel(serverConfig),
+ json(),
+ license({
+ banner: `This source code is being disclosed to you solely for the purpose of your participation in
+ testing Zilliqa and Laksa. You may view, compile and run the code for that purpose and pursuant to
+ the protocols and algorithms that are programmed into, and intended by, the code. You may
+ not do anything else with the code without express permission from Zilliqa Research Pte. Ltd.,
+ including modifying or publishing the code (or any part of it), and developing or forming
+ another public or private blockchain network. This source code is provided ‘as is’ and no
+ warranties are given as to title or non-infringement, merchantability or fitness for purpose
+ and, to the extent permitted by law, all liability for your use of the code is disclaimed.
+ Some programs in this code are governed by the GNU General Public License v3.0 (available at
+ https://www.gnu.org/licenses/gpl-3.0.en.html) (‘GPLv3’). The programs that are governed by
+ GPLv3.0 are those programs that are located in the folders src/depends and tests/depends
+ and which include a reference to GPLv3 in their program files.`
+ })
+ ]
+ }
+ return Object.assign(normal, externalSetting)
+ })
+}
+
+export default bundles()
diff --git a/scripts/rollup/getDependencies.js b/scripts/rollup/getDependencies.js
new file mode 100644
index 0000000..b88e752
--- /dev/null
+++ b/scripts/rollup/getDependencies.js
@@ -0,0 +1,13 @@
+import fs from 'fs';
+
+export function getKeys(p) {
+ const packageJsonFile = `${process.cwd()}/packages/${p}/package.json`;
+ const data = fs.readFileSync(packageJsonFile, 'utf-8');
+
+ const { dependencies } = JSON.parse(data);
+
+ const keys = dependencies
+ ? Object.keys(dependencies).filter((d) => !/harmony/.test(d))
+ : [];
+ return keys;
+}