From bf9ca8e24d0bceea622310c84bc8e23246a00047 Mon Sep 17 00:00:00 2001 From: theanmolsharma Date: Sat, 30 Dec 2023 17:57:48 +0530 Subject: [PATCH] feat: added leveldb Signed-off-by: theanmolsharma --- .gitignore | 3 + package-lock.json | 147 +++++++++++++++++++++++++++++++++- package.json | 1 + src/wallet/db/index.ts | 1 + src/wallet/db/level/db.ts | 39 +++++++++ src/wallet/db/level/index.ts | 2 + src/wallet/db/level/layout.ts | 4 + test/wallet-db.spec.ts | 29 +++++++ 8 files changed, 225 insertions(+), 1 deletion(-) create mode 100644 src/wallet/db/level/db.ts create mode 100644 src/wallet/db/level/index.ts create mode 100644 src/wallet/db/level/layout.ts create mode 100644 test/wallet-db.spec.ts diff --git a/.gitignore b/.gitignore index ad2efbc..0e7e1fe 100644 --- a/.gitignore +++ b/.gitignore @@ -22,3 +22,6 @@ coverage *.njsproj *.sln *.sw? + +# test +test/wallet-db diff --git a/package-lock.json b/package-lock.json index 2785ade..8735dcd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,6 +13,7 @@ "bech32": "^2.0.0", "buffer": "^6.0.3", "create-hash": "^1.2.0", + "level": "^8.0.0", "secp256k1": "^5.0.0" }, "devDependencies": { @@ -2289,6 +2290,23 @@ "@vue/language-core": "1.8.8" } }, + "node_modules/abstract-level": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/abstract-level/-/abstract-level-1.0.3.tgz", + "integrity": "sha512-t6jv+xHy+VYwc4xqZMn2Pa9DjcdzvzZmQGRjTFc8spIbRGHgBrEKbPq+rYXc7CCo0lxgYvSgKVg9qZAhpVQSjA==", + "dependencies": { + "buffer": "^6.0.3", + "catering": "^2.1.0", + "is-buffer": "^2.0.5", + "level-supports": "^4.0.0", + "level-transcoder": "^1.0.1", + "module-error": "^1.0.1", + "queue-microtask": "^1.2.3" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/acorn": { "version": "8.10.0", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", @@ -2578,6 +2596,17 @@ "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==" }, + "node_modules/browser-level": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/browser-level/-/browser-level-1.0.1.tgz", + "integrity": "sha512-XECYKJ+Dbzw0lbydyQuJzwNXtOpbMSq737qxJN11sIRTErOMShvDpbzTlgju7orJKvx4epULolZAuJGLzCmWRQ==", + "dependencies": { + "abstract-level": "^1.0.2", + "catering": "^2.1.1", + "module-error": "^1.0.2", + "run-parallel-limit": "^1.1.0" + } + }, "node_modules/browserslist": { "version": "4.21.10", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.10.tgz", @@ -2698,6 +2727,14 @@ } ] }, + "node_modules/catering": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/catering/-/catering-2.1.1.tgz", + "integrity": "sha512-K7Qy8O9p76sL3/3m7/zLKbRkyOlSZAgzEaLhyj2mXS8PsCud2Eo4hAb8aLtZqHh0QGqLcb9dlJSu6lHRVENm1w==", + "engines": { + "node": ">=6" + } + }, "node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -2753,6 +2790,22 @@ "integrity": "sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ==", "dev": true }, + "node_modules/classic-level": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/classic-level/-/classic-level-1.3.0.tgz", + "integrity": "sha512-iwFAJQYtqRTRM0F6L8h4JCt00ZSGdOyqh7yVrhhjrOpFhmBjNlRUey64MCiyo6UmQHMJ+No3c81nujPv+n9yrg==", + "hasInstallScript": true, + "dependencies": { + "abstract-level": "^1.0.2", + "catering": "^2.1.0", + "module-error": "^1.0.1", + "napi-macros": "^2.2.2", + "node-gyp-build": "^4.3.0" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/cliui": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", @@ -3975,6 +4028,28 @@ "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", "dev": true }, + "node_modules/is-buffer": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", + "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "engines": { + "node": ">=4" + } + }, "node_modules/is-core-module": { "version": "2.13.0", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.0.tgz", @@ -4783,6 +4858,42 @@ "integrity": "sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==", "dev": true }, + "node_modules/level": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/level/-/level-8.0.0.tgz", + "integrity": "sha512-ypf0jjAk2BWI33yzEaaotpq7fkOPALKAgDBxggO6Q9HGX2MRXn0wbP1Jn/tJv1gtL867+YOjOB49WaUF3UoJNQ==", + "dependencies": { + "browser-level": "^1.0.1", + "classic-level": "^1.2.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/level" + } + }, + "node_modules/level-supports": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/level-supports/-/level-supports-4.0.1.tgz", + "integrity": "sha512-PbXpve8rKeNcZ9C1mUicC9auIYFyGpkV9/i6g76tLgANwWhtG2v7I4xNBUlkn3lE2/dZF3Pi0ygYGtLc4RXXdA==", + "engines": { + "node": ">=12" + } + }, + "node_modules/level-transcoder": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/level-transcoder/-/level-transcoder-1.0.1.tgz", + "integrity": "sha512-t7bFwFtsQeD8cl8NIoQ2iwxA0CL/9IFw7/9gAjOonH0PWTTiRfY7Hq+Ejbsxh86tXobDQ6IOiddjNYIfOBs06w==", + "dependencies": { + "buffer": "^6.0.3", + "module-error": "^1.0.1" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/leven": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", @@ -4986,6 +5097,14 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/module-error": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/module-error/-/module-error-1.0.2.tgz", + "integrity": "sha512-0yuvsqSCv8LbaOKhnsQ/T5JhyFlCYLPXK3U2sgV10zoKQwzs/MyfuQUOZQ1V/6OCOJsK/TRgNVrPuPDqtdMFtA==", + "engines": { + "node": ">=10" + } + }, "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -5016,6 +5135,11 @@ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, + "node_modules/napi-macros": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/napi-macros/-/napi-macros-2.2.2.tgz", + "integrity": "sha512-hmEVtAGYzVQpCKdbQea4skABsdXW4RUh5t5mJ2zzqowJS2OyXZTU1KhDVFhx+NlWZ4ap9mqR9TcDO3LTTttd+g==" + }, "node_modules/natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", @@ -5416,7 +5540,6 @@ "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true, "funding": [ { "type": "github", @@ -5580,6 +5703,28 @@ "queue-microtask": "^1.2.2" } }, + "node_modules/run-parallel-limit": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/run-parallel-limit/-/run-parallel-limit-1.1.0.tgz", + "integrity": "sha512-jJA7irRNM91jaKc3Hcl1npHsFLOXOoTkPCUL1JEa1R82O2miplXXRaGdjW/KM/98YQWDhJLiSs793CnXfblJUw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, "node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", diff --git a/package.json b/package.json index 29fc315..0e0e50a 100644 --- a/package.json +++ b/package.json @@ -44,6 +44,7 @@ "bech32": "^2.0.0", "buffer": "^6.0.3", "create-hash": "^1.2.0", + "level": "^8.0.0", "secp256k1": "^5.0.0" }, "devDependencies": { diff --git a/src/wallet/db/index.ts b/src/wallet/db/index.ts index 18b212c..e92aa6d 100644 --- a/src/wallet/db/index.ts +++ b/src/wallet/db/index.ts @@ -1 +1,2 @@ export * from './db.interface.ts'; +export * from './level'; diff --git a/src/wallet/db/level/db.ts b/src/wallet/db/level/db.ts new file mode 100644 index 0000000..7892200 --- /dev/null +++ b/src/wallet/db/level/db.ts @@ -0,0 +1,39 @@ +import { Level } from 'level'; +import { wdb } from './layout.ts'; +import { DbInterface } from '../db.interface.ts'; + +export type LevelDBConfigOptions = { + location: string; +}; + +export class WalletDB implements DbInterface { + private readonly db; + + constructor(config: LevelDBConfigOptions) { + this.db = new Level(config.location, { + valueEncoding: 'json', + keyEncoding: 'utf-8', + createIfMissing: true, + }); + } + + public async open(): Promise { + await this.db.open(); + } + + public async close(): Promise { + await this.db.close(); + } + + public getStatus(): string { + return this.db.status; + } + + public async getVersion(): Promise { + return parseInt(await this.db.get(wdb.V)); + } + + public async setVersion(version: number): Promise { + this.db.put(wdb.V, version.toString()); + } +} diff --git a/src/wallet/db/level/index.ts b/src/wallet/db/level/index.ts new file mode 100644 index 0000000..d71f385 --- /dev/null +++ b/src/wallet/db/level/index.ts @@ -0,0 +1,2 @@ +export * from './db.ts'; +export * from './layout.ts'; diff --git a/src/wallet/db/level/layout.ts b/src/wallet/db/level/layout.ts new file mode 100644 index 0000000..f55278d --- /dev/null +++ b/src/wallet/db/level/layout.ts @@ -0,0 +1,4 @@ +// Database layout +export const wdb = { + V: 'V', // Version +}; diff --git a/test/wallet-db.spec.ts b/test/wallet-db.spec.ts new file mode 100644 index 0000000..cfdc5f5 --- /dev/null +++ b/test/wallet-db.spec.ts @@ -0,0 +1,29 @@ +import { WalletDB } from '../src/wallet'; + +describe('Wallet DB', () => { + let walletDB: WalletDB; + + beforeAll(async () => { + walletDB = new WalletDB({ + location: './test/wallet-db', + }); + + await walletDB.open(); + }); + + it('should open the wallet database', async () => { + expect(walletDB.getStatus()).toBe('open'); + }); + + it('should set the wallet database version', async () => { + await walletDB.setVersion(1); + }); + + it('should get the wallet database version', async () => { + expect(await walletDB.getVersion()).toBe(1); + }); + + afterAll(async () => { + await walletDB.close(); + }); +});