diff --git a/packages/client/CHANGELOG.md b/packages/client/CHANGELOG.md
new file mode 100644
index 0000000..e4d87c4
--- /dev/null
+++ b/packages/client/CHANGELOG.md
@@ -0,0 +1,4 @@
+# Change Log
+
+All notable changes to this project will be documented in this file.
+See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
diff --git a/packages/client/README.md b/packages/client/README.md
new file mode 100644
index 0000000..2671b9b
--- /dev/null
+++ b/packages/client/README.md
@@ -0,0 +1,37 @@
+# Hyperweb Client
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Hyperweb Client is a powerful wrapper around Hyperweb blockchain, designed to simplify and streamline your blockchain interactions process for Hyperweb projects.
+
+
+## Features
+
+- Simple Client to interact with Hyperweb blockchain
+- Built-in support for common Hyperweb project configurations
+- Easy integration with existing projects
+
+## Installation
+
+```sh
+npm install @hyperweb/client
+```
+
+## Usage
+
+Here's a basic example of how to use Hyperweb Client
+
+## License
+
+Hyperweb Client is MIT licensed.
\ No newline at end of file
diff --git a/packages/client/jest.config.js b/packages/client/jest.config.js
new file mode 100644
index 0000000..057a942
--- /dev/null
+++ b/packages/client/jest.config.js
@@ -0,0 +1,18 @@
+/** @type {import('ts-jest').JestConfigWithTsJest} */
+module.exports = {
+ preset: 'ts-jest',
+ testEnvironment: 'node',
+ transform: {
+ '^.+\\.tsx?$': [
+ 'ts-jest',
+ {
+ babelConfig: false,
+ tsconfig: 'tsconfig.json',
+ },
+ ],
+ },
+ transformIgnorePatterns: [`/node_modules/*`],
+ testRegex: '(/__tests__/.*|(\\.|/)(test|spec))\\.(jsx?|tsx?)$',
+ moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'],
+ modulePathIgnorePatterns: ['dist/*']
+};
diff --git a/packages/client/package.json b/packages/client/package.json
new file mode 100644
index 0000000..37256a6
--- /dev/null
+++ b/packages/client/package.json
@@ -0,0 +1,45 @@
+{
+ "name": "@hyperweb/client",
+ "version": "0.0.1",
+ "author": "Hyperweb ",
+ "description": "client for hyperweb",
+ "main": "index.js",
+ "module": "esm/index.js",
+ "types": "index.d.ts",
+ "homepage": "https://github.com/hyperweb-io/hyperweb-build",
+ "license": "SEE LICENSE IN LICENSE",
+ "publishConfig": {
+ "access": "public",
+ "directory": "dist"
+ },
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/hyperweb-io/hyperweb-build"
+ },
+ "bugs": {
+ "url": "https://github.com/hyperweb-io/hyperweb-build/issues"
+ },
+ "scripts": {
+ "copy": "copyfiles -f ../../LICENSE README.md package.json dist",
+ "clean": "rimraf dist/**",
+ "prepare": "npm run build",
+ "build": "npm run clean; tsc; tsc -p tsconfig.esm.json; npm run copy",
+ "build:dev": "npm run clean; tsc --declarationMap; tsc -p tsconfig.esm.json; npm run copy",
+ "lint": "eslint . --fix",
+ "test": "jest",
+ "test:watch": "jest --watch"
+ },
+ "keywords": [],
+ "dependencies": {
+ "chalk": "^4.1.0",
+ "deepmerge": "^4.3.1",
+ "js-yaml": "^4.1.0",
+ "mkdirp": "3.0.1",
+ "shelljs": "^0.8.5",
+ "esbuild": "^0.23.1"
+ },
+ "devDependencies": {
+ "@types/js-yaml": "^4.0.9",
+ "@types/shelljs": "^0.8.15"
+ }
+}
diff --git a/packages/client/src/client.ts b/packages/client/src/client.ts
new file mode 100644
index 0000000..f8947ac
--- /dev/null
+++ b/packages/client/src/client.ts
@@ -0,0 +1,93 @@
+import deepmerge from 'deepmerge';
+import { existsSync, readFileSync, writeFileSync } from 'fs';
+import * as yaml from 'js-yaml';
+import { mkdirp } from 'mkdirp';
+import { dirname, resolve } from 'path';
+import * as shell from 'shelljs';
+
+import { HyperwebConfig } from './config';
+import { readAndParsePackageJson } from './package';
+
+export interface HyperwebContext {
+ name?: string;
+ rpc?: string;
+ config?: string;
+ verbose?: boolean;
+ timeout?: string;
+}
+
+export const defaultHyperwebContext: Partial = {
+ name: '',
+ rpc: 'http://localhost:26657',
+ verbose: false,
+};
+
+export interface HyperwebClientI {
+ ctx: HyperwebContext;
+ version: string;
+ config: HyperwebConfig;
+}
+
+export class HyperwebClient implements HyperwebClientI {
+ ctx: HyperwebContext;
+ version: string;
+ config: HyperwebConfig;
+
+ constructor(ctx: HyperwebContext) {
+ this.ctx = deepmerge(defaultHyperwebContext, ctx);
+ // TODO add semver check against net
+ this.version = readAndParsePackageJson().version;
+ }
+
+ private log(str: string): void {
+ // add log level
+ console.log(str);
+ }
+
+ private exit(code: number): void {
+ shell.exit(code);
+ }
+
+ private loadYaml(filename: string): any {
+ const path = filename.startsWith('/')
+ ? filename
+ : resolve((process.cwd(), filename));
+ const fileContents = readFileSync(path, 'utf8');
+ return yaml.load(fileContents);
+ }
+
+ private saveYaml(filename: string, obj: any): any {
+ const path = filename.startsWith('/')
+ ? filename
+ : resolve((process.cwd(), filename));
+ const yamlContent = yaml.dump(obj);
+ mkdirp.sync(dirname(path));
+ writeFileSync(path, yamlContent, 'utf8');
+ }
+
+ public loadConfig(): void {
+ this.ensureFileExists(this.ctx.config);
+ this.config = this.loadYaml(this.ctx.config) as HyperwebConfig;
+ }
+
+ public saveConfig(): void {
+ this.saveYaml(this.ctx.config, this.config);
+ }
+
+ public setConfig(config: HyperwebConfig): void {
+ this.config = config;
+ }
+
+ public setContext(ctx: HyperwebContext): void {
+ this.ctx = ctx;
+ }
+
+ private ensureFileExists(filename: string): void {
+ const path = filename.startsWith('/')
+ ? filename
+ : resolve((process.cwd(), filename));
+ if (!existsSync(path)) {
+ throw new Error(`Configuration file not found: ${filename}`);
+ }
+ }
+}
\ No newline at end of file
diff --git a/packages/client/src/config.ts b/packages/client/src/config.ts
new file mode 100644
index 0000000..daae2df
--- /dev/null
+++ b/packages/client/src/config.ts
@@ -0,0 +1,6 @@
+export interface HyperwebConfig {
+ name: string;
+ version: string;
+ chainID: string;
+ node: string;
+}
diff --git a/packages/client/src/index.ts b/packages/client/src/index.ts
new file mode 100644
index 0000000..d0e1efb
--- /dev/null
+++ b/packages/client/src/index.ts
@@ -0,0 +1,2 @@
+export * from './client';
+export * from './config';
diff --git a/packages/client/src/package.ts b/packages/client/src/package.ts
new file mode 100644
index 0000000..aa718e5
--- /dev/null
+++ b/packages/client/src/package.ts
@@ -0,0 +1,32 @@
+import { existsSync, readFileSync } from 'fs';
+import { dirname, join } from 'path';
+
+// need to search due to the dist/ folder and src/, etc.
+function findPackageJson(currentDir: string): any {
+ const filePath = join(currentDir, 'package.json');
+
+ // Check if package.json exists in the current directory
+ if (existsSync(filePath)) {
+ return filePath;
+ }
+
+ // Get the parent directory
+ const parentDir = dirname(currentDir);
+
+ // If reached the root directory, package.json is not found
+ if (parentDir === currentDir) {
+ throw new Error('package.json not found in any parent directory');
+ }
+
+ // Recursively look in the parent directory
+ return findPackageJson(parentDir);
+}
+
+export function readAndParsePackageJson() {
+ // Start searching from the current directory
+ const pkgPath = findPackageJson(__dirname);
+
+ // Read and parse the package.json
+ const str = readFileSync(pkgPath, 'utf8');
+ return JSON.parse(str);
+}
diff --git a/packages/client/tsconfig.esm.json b/packages/client/tsconfig.esm.json
new file mode 100644
index 0000000..800d750
--- /dev/null
+++ b/packages/client/tsconfig.esm.json
@@ -0,0 +1,9 @@
+{
+ "extends": "./tsconfig.json",
+ "compilerOptions": {
+ "outDir": "dist/esm",
+ "module": "es2022",
+ "rootDir": "src/",
+ "declaration": false
+ }
+}
diff --git a/packages/client/tsconfig.json b/packages/client/tsconfig.json
new file mode 100644
index 0000000..1a9d569
--- /dev/null
+++ b/packages/client/tsconfig.json
@@ -0,0 +1,9 @@
+{
+ "extends": "../../tsconfig.json",
+ "compilerOptions": {
+ "outDir": "dist",
+ "rootDir": "src/"
+ },
+ "include": ["src/**/*.ts"],
+ "exclude": ["dist", "node_modules", "**/*.spec.*", "**/*.test.*"]
+}
diff --git a/yarn.lock b/yarn.lock
index 514498c..796db0e 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2587,7 +2587,7 @@
dependencies:
"@babel/types" "^7.20.7"
-"@types/glob@^7.1.3":
+"@types/glob@^7.1.3", "@types/glob@~7.2.0":
version "7.2.0"
resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.2.0.tgz#bc1b5bf3aa92f25bd5dd39f35c57361bdce5b2eb"
integrity sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==
@@ -2629,6 +2629,11 @@
expect "^29.0.0"
pretty-format "^29.0.0"
+"@types/js-yaml@^4.0.9":
+ version "4.0.9"
+ resolved "https://registry.yarnpkg.com/@types/js-yaml/-/js-yaml-4.0.9.tgz#cd82382c4f902fed9691a2ed79ec68c5898af4c2"
+ integrity sha512-k4MGaQl5TGo/iipqb2UDG2UwjXziSWkh0uysQelTlJpX1qGlpUZYm8PnO4DxG1qBomtJUdYJ6qR6xdIah10JLg==
+
"@types/json-schema@^7.0.11", "@types/json-schema@^7.0.15":
version "7.0.15"
resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841"
@@ -2700,6 +2705,14 @@
resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.7.3.tgz#3e51a17e291d01d17d3fc61422015a933af7a08f"
integrity sha512-+68kP9yzs4LMp7VNh8gdzMSPZFL44MLGqiHWvttYJe+6qnuVr4Ek9wSBQoveqY/r+LwjCcU29kNVkidwim+kYA==
+"@types/shelljs@^0.8.15":
+ version "0.8.15"
+ resolved "https://registry.yarnpkg.com/@types/shelljs/-/shelljs-0.8.15.tgz#22c6ab9dfe05cec57d8e6cb1a95ea173aee9fcac"
+ integrity sha512-vzmnCHl6hViPu9GNLQJ+DZFd6BQI2DBTUeOvYHqkWQLMfKAAQYMb/xAmZkTogZI/vqXHCWkqDRymDI5p0QTi5Q==
+ dependencies:
+ "@types/glob" "~7.2.0"
+ "@types/node" "*"
+
"@types/stack-utils@^2.0.0":
version "2.0.3"
resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.3.tgz#6209321eb2c1712a7e7466422b8cb1fc0d9dd5d8"
@@ -3880,7 +3893,7 @@ deepmerge@4.2.2:
resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.2.2.tgz#44d2ea3679b8f4d4ffba33f03d865fc1e7bf4955"
integrity sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==
-deepmerge@4.3.1, deepmerge@^4.2.2:
+deepmerge@4.3.1, deepmerge@^4.2.2, deepmerge@^4.3.1:
version "4.3.1"
resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.3.1.tgz#44b5f2147cd3b00d4b56137685966f26fd25dd4a"
integrity sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==
@@ -6671,6 +6684,11 @@ mkdirp@3.0.0:
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-3.0.0.tgz#758101231418bda24435c0888a91d9bd91f1372d"
integrity sha512-7+JDnNsyCvZXoUJdkMR0oUE2AmAdsNXGTmRbiOjYIwQ6q+bL6NwrozGQdPcmYaNcrhH37F50HHBUzoaBV6FITQ==
+mkdirp@3.0.1:
+ version "3.0.1"
+ resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-3.0.1.tgz#e44e4c5607fb279c168241713cc6e0fea9adcb50"
+ integrity sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==
+
modify-values@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/modify-values/-/modify-values-1.0.1.tgz#b3939fa605546474e3e3e3c63d64bd43b4ee6022"
@@ -7991,7 +8009,7 @@ shebang-regex@^3.0.0:
resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172"
integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==
-shelljs@0.8.5:
+shelljs@0.8.5, shelljs@^0.8.5:
version "0.8.5"
resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.8.5.tgz#de055408d8361bed66c669d2f000538ced8ee20c"
integrity sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==