From 22aac260cd6d16729f194a3040aa6e98284b7a0f Mon Sep 17 00:00:00 2001 From: capt-nemo429 Date: Mon, 1 May 2023 00:06:04 -0300 Subject: [PATCH] feat(wallet): add `ErgoHDKey` for key handling --- .versionrc | 1 + README.md | 2 +- package.json | 5 + packages/wallet/LICENSE | 21 +++ packages/wallet/README.md | 3 + packages/wallet/package.json | 49 ++++++ packages/wallet/src/ergoHDKey.spec.ts | 157 ++++++++++++++++++++ packages/wallet/src/ergoHDKey.ts | 97 ++++++++++++ packages/wallet/src/index.ts | 2 + packages/wallet/src/mnemonic.spec.ts | 49 ++++++ packages/wallet/src/mnemonic.ts | 10 ++ packages/wallet/src/tests/keyTestVectors.ts | 39 +++++ packages/wallet/tsconfig.esm.json | 8 + packages/wallet/tsconfig.json | 8 + pnpm-lock.yaml | 44 ++++++ vitest.config.ts | 2 +- 16 files changed, 495 insertions(+), 2 deletions(-) create mode 100644 packages/wallet/LICENSE create mode 100644 packages/wallet/README.md create mode 100644 packages/wallet/package.json create mode 100644 packages/wallet/src/ergoHDKey.spec.ts create mode 100644 packages/wallet/src/ergoHDKey.ts create mode 100644 packages/wallet/src/index.ts create mode 100644 packages/wallet/src/mnemonic.spec.ts create mode 100644 packages/wallet/src/mnemonic.ts create mode 100644 packages/wallet/src/tests/keyTestVectors.ts create mode 100644 packages/wallet/tsconfig.esm.json create mode 100644 packages/wallet/tsconfig.json diff --git a/.versionrc b/.versionrc index 19182daa..a7618dc9 100644 --- a/.versionrc +++ b/.versionrc @@ -3,6 +3,7 @@ "./package.json", "./packages/core/package.json", "./packages/common/package.json", + "./packages/wallet/package.json", "./plugins/babel-fees/package.json" ] } diff --git a/README.md b/README.md index 44395c90..c282b915 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ This is a [monorepository](https://monorepo.tools/) which means this contains ma | ------------------------------------- | -------------------------------------------------------------------------------------------- | :---------------------------------------------------------------------------------------------------: | | [@fleet-sdk/core](/packages/core/) | Core library with transaction builder and basic serialization. | [![npm](https://badgen.net/npm/v/@fleet-sdk/core)](https://www.npmjs.com/package/@fleet-sdk/core) | | [@fleet-sdk/common](/packages/common) | Internal utility functions, constants and types shared across @fleet-sdk packages. | [![npm](https://badgen.net/npm/v/@fleet-sdk/common)](https://www.npmjs.com/package/@fleet-sdk/common) | -| @fleet-sdk/wallet | Wallet related library, with wallet creation, derivation and signing. | `planned` | +| [@fleet-sdk/wallet](/packages/wallet) | Wallet related library, with keys creation, derivation and signing. | [![npm](https://badgen.net/npm/v/@fleet-sdk/wallet)](https://www.npmjs.com/package/@fleet-sdk/wallet) | | @fleet-sdk/interpreter | Sigma state interpreter and serialization library powered by Sigma.JS. | `planned` | | @fleet-sdk/compiler | ErgoScript compiler library powered by Sigma.JS. | `planned` | | @fleet-sdk/graphql-client | Data client library for [ergo-graphql](https://github.com/capt-nemo429/ergo-graphql) server. | `planned` | diff --git a/package.json b/package.json index c36bf5c3..406c6273 100644 --- a/package.json +++ b/package.json @@ -26,6 +26,8 @@ "devDependencies": { "@noble/hashes": "^1.3.0", "@scure/base": "^1.1.1", + "@scure/bip32": "^1.3.0", + "@scure/bip39": "^1.2.0", "@types/node": "^18.15.11", "@typescript-eslint/eslint-plugin": "^5.58.0", "@typescript-eslint/parser": "^5.58.0", @@ -47,5 +49,8 @@ "engines": { "node": ">=10", "pnpm": ">=8.1.1 <9" + }, + "dependencies": { + "ergo-lib-wasm-nodejs": "^0.23.0" } } diff --git a/packages/wallet/LICENSE b/packages/wallet/LICENSE new file mode 100644 index 00000000..c7b0c6c5 --- /dev/null +++ b/packages/wallet/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2023 capt-nemo429 + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/packages/wallet/README.md b/packages/wallet/README.md new file mode 100644 index 00000000..de613cdb --- /dev/null +++ b/packages/wallet/README.md @@ -0,0 +1,3 @@ +# @fleet-sdk/wallet [![License](https://badgen.net/github/license/fleet-sdk/fleet/)](https://github.com/fleet-sdk/fleet/blob/master/LICENSE) [![npm](https://badgen.net/npm/v/@fleet-sdk/wallet)](https://www.npmjs.com/package/@fleet-sdk/wallet) + +Key management and signature for Ergo Platform. diff --git a/packages/wallet/package.json b/packages/wallet/package.json new file mode 100644 index 00000000..089b5b4d --- /dev/null +++ b/packages/wallet/package.json @@ -0,0 +1,49 @@ +{ + "name": "@fleet-sdk/wallet", + "version": "0.1.0-alpha.26", + "description": "Key management and signature for Ergo Platform.", + "main": "dist/cjs/index.js", + "module": "dist/esm/index.js", + "typings": "dist/esm/index.d.ts", + "sideEffects": false, + "repository": { + "type": "git", + "url": "https://github.com/fleet-sdk/fleet.git", + "directory": "packages/wallet" + }, + "license": "MIT", + "publishConfig": { + "access": "public" + }, + "keywords": [ + "ergo", + "blockchain", + "transactions", + "serialization" + ], + "scripts": { + "build": "run-p build:*", + "build:cjs": "tsc -p tsconfig.json", + "build:esm": "tsc -p tsconfig.esm.json", + "watch:build": "tsc -p tsconfig.json -w", + "watch:unit": "vitest" + }, + "dependencies": { + "@fleet-sdk/core": "workspace:^", + "@scure/bip32": "^1.3.0", + "@scure/bip39": "^1.2.0" + }, + "engines": { + "node": ">=10" + }, + "files": [ + "src", + "dist", + "!**/*.spec.*", + "!**/*.json", + "!tests", + "CHANGELOG.md", + "LICENSE", + "README.md" + ] +} diff --git a/packages/wallet/src/ergoHDKey.spec.ts b/packages/wallet/src/ergoHDKey.spec.ts new file mode 100644 index 00000000..a557f039 --- /dev/null +++ b/packages/wallet/src/ergoHDKey.spec.ts @@ -0,0 +1,157 @@ +import { first } from "@fleet-sdk/common"; +import { mnemonicToSeedSync } from "@scure/bip39"; +import SigmaRust from "ergo-lib-wasm-nodejs"; +import { describe, expect, it } from "vitest"; +import { ERGO_HD_CHANGE_PATH, ErgoHDKey } from "./ergoHDKey"; +import { generateMnemonic } from "./mnemonic"; +import { keyAddressesTestVectors } from "./tests/keyTestVectors"; + +describe("Instantiation", () => { + it("Should create from mnemonic and auto derive to ergo's default change path by default", async () => { + const mnemonic = generateMnemonic(); + const key = await ErgoHDKey.fromMnemonic(mnemonic); + + expect(key.publicKey).not.to.be.empty; + expect(key.privateKey).not.to.be.empty; + expect(key.chainCode).not.to.be.empty; + expect(key.index).to.be.equal(0); + expect(key.depth).to.be.equal(4, "should automatically derive Ergo path."); + + const syncKey = ErgoHDKey.fromMnemonicSync(mnemonic); + expect(key).to.be.deep.equal(syncKey); + }); + + it("Should create from master seed and derive to ergo's default change path by default", () => { + const seed = mnemonicToSeedSync(generateMnemonic()); + const key = ErgoHDKey.fromMasterSeed(seed); + + expect(key.publicKey).not.to.be.empty; + expect(key.privateKey).not.to.be.empty; + expect(key.chainCode).not.to.be.empty; + expect(key.index).to.be.equal(0); + expect(key.depth).to.be.equal(4, "should automatically derive Ergo path."); + expect(first(key.address.getPublicKeys())).to.be.deep.equal(key.publicKey); + }); + + it("Should should result in the same key from seed and from equivalent mnemonic", () => { + const mnemonic = generateMnemonic(); + const seed = mnemonicToSeedSync(mnemonic); + const keyFromSeed = ErgoHDKey.fromMasterSeed(seed); + const keyFromMnemonic = ErgoHDKey.fromMnemonicSync(mnemonic); + + expect(keyFromSeed.publicKey).to.be.deep.equal(keyFromMnemonic.publicKey); + expect(keyFromSeed.privateKey).to.be.deep.equal(keyFromMnemonic.privateKey); + expect(keyFromSeed.chainCode).to.be.deep.equal(keyFromMnemonic.chainCode); + expect(keyFromSeed.index).to.be.equal(keyFromMnemonic.index); + expect(keyFromSeed.depth).to.be.equal(keyFromMnemonic.depth); + }); + + it("Should wipe private data", () => { + const key = ErgoHDKey.fromMnemonicSync(generateMnemonic()); + expect(key.privateKey).not.to.be.empty; + + key.wipePrivateData(); + expect(key.privateKey).to.be.null; + }); +}); + +describe("Extended keys", () => { + it("Should create and restore from public extended key", async () => { + const mnemonic = generateMnemonic(); + const key = await ErgoHDKey.fromMnemonic(mnemonic); + + expect(key.privateKey).not.to.be.null; + expect(key.publicKey).not.to.be.null; + expect(key.chainCode).not.to.be.null; + + const recreatedKeyFromPk = ErgoHDKey.fromExtendedKey(key.extendedPublicKey); + + expect(recreatedKeyFromPk.privateKey).to.be.null; + expect(recreatedKeyFromPk.publicKey).to.be.deep.equal(key.publicKey); + expect(recreatedKeyFromPk.chainCode).to.be.deep.equal(key.chainCode); + }); + + it("Should create and restore from private extended key", async () => { + const mnemonic = generateMnemonic(); + const key = await ErgoHDKey.fromMnemonic(mnemonic); + + expect(key.privateKey).not.to.be.null; + expect(key.publicKey).not.to.be.null; + expect(key.chainCode).not.to.be.null; + + const recreatedKeyFromPk = ErgoHDKey.fromExtendedKey(key.extendedPrivateKey); + + expect(recreatedKeyFromPk.privateKey).to.deep.equal(key.privateKey); + expect(recreatedKeyFromPk.publicKey).to.be.deep.equal(key.publicKey); + expect(recreatedKeyFromPk.chainCode).to.be.deep.equal(key.chainCode); + }); +}); + +describe("Key derivation", () => { + it("Should derive and encode the correct addresses from mnemonic", async () => { + for (const tv of keyAddressesTestVectors) { + const key = await ErgoHDKey.fromMnemonic(tv.mnemonic); + + for (let i = 0; i < keyAddressesTestVectors.length; i++) { + expect(key.deriveChild(i).address.encode()).to.be.equal(tv.addresses[i]); + } + } + }); + + it("Should not auto derive to default Ergo path if path == ''", async () => { + for (const tv of keyAddressesTestVectors) { + let key = await ErgoHDKey.fromMnemonic(tv.mnemonic, { path: "" }); + expect(key.depth).to.be.equal(0); + expect(key.index).to.be.equal(0); + + key = key.derive(ERGO_HD_CHANGE_PATH); + expect(key.depth).to.be.equal(4); + expect(key.index).to.be.equal(0); + + for (let i = 0; i < keyAddressesTestVectors.length; i++) { + expect(key.deriveChild(i).address.encode()).to.be.equal(tv.addresses[i]); + } + } + }); + + it("Should be on pair with sigma-rust with no passphrase", () => { + const mnemonic = generateMnemonic(); + + const fleetKey = ErgoHDKey.fromMnemonicSync(mnemonic); + const wasmKey = SigmaRust.ExtSecretKey.derive_master(mnemonicToSeedSync(mnemonic)).derive( + SigmaRust.DerivationPath.from_string(ERGO_HD_CHANGE_PATH) + ); + + expect(fleetKey.publicKey).to.be.deep.equal(wasmKey.public_key().pub_key_bytes()); + expect(fleetKey.privateKey).to.be.deep.equal(wasmKey.secret_key_bytes()); + + for (let i = 0; i < 100; i++) { + const fleetChild = fleetKey.deriveChild(i); + const wasmChild = wasmKey.child(i.toString()); + + expect(fleetChild.publicKey).to.be.deep.equal(wasmChild.public_key().pub_key_bytes()); + expect(fleetChild.privateKey).to.be.deep.equal(wasmChild.secret_key_bytes()); + } + }); + + it("Should be on pair with sigma-rust with passphrase", () => { + const mnemonic = generateMnemonic(); + const passphrase = "test passphrase"; + + const fleetKey = ErgoHDKey.fromMnemonicSync(mnemonic, { passphrase }); + const wasmKey = SigmaRust.ExtSecretKey.derive_master( + SigmaRust.Mnemonic.to_seed(mnemonic, passphrase) + ).derive(SigmaRust.DerivationPath.from_string(ERGO_HD_CHANGE_PATH)); + + expect(fleetKey.publicKey).to.be.deep.equal(wasmKey.public_key().pub_key_bytes()); + expect(fleetKey.privateKey).to.be.deep.equal(wasmKey.secret_key_bytes()); + + for (let i = 0; i < 100; i++) { + const fleetChild = fleetKey.deriveChild(i); + const wasmChild = wasmKey.child(i.toString()); + + expect(fleetChild.publicKey).to.be.deep.equal(wasmChild.public_key().pub_key_bytes()); + expect(fleetChild.privateKey).to.be.deep.equal(wasmChild.secret_key_bytes()); + } + }); +}); diff --git a/packages/wallet/src/ergoHDKey.ts b/packages/wallet/src/ergoHDKey.ts new file mode 100644 index 00000000..97daa322 --- /dev/null +++ b/packages/wallet/src/ergoHDKey.ts @@ -0,0 +1,97 @@ +import { ErgoAddress } from "@fleet-sdk/core"; +import { HDKey } from "@scure/bip32"; +import { mnemonicToSeed, mnemonicToSeedSync } from "@scure/bip39"; + +/** + * Ergo derivation path at change level + */ +export const ERGO_HD_CHANGE_PATH = "m/44'/429'/0'/0"; + +export type FromMnemonicOptions = { + passphrase?: string; + path?: string; +}; + +export class ErgoHDKey { + private readonly _root: HDKey; + private readonly _publicKey: Uint8Array; + private readonly _address: ErgoAddress; + + private constructor(hdKey: HDKey) { + /* istanbul ignore if -- @preserve */ + if (!hdKey.publicKey) { + throw new Error("Public key is not present"); + } + + this._root = hdKey; + this._publicKey = hdKey.publicKey; + this._address = ErgoAddress.fromPublicKey(this._publicKey); + } + + get publicKey(): Uint8Array { + return this._publicKey; + } + + get privateKey(): Uint8Array | null { + return this._root.privateKey; + } + + get chainCode(): Uint8Array | null { + return this._root.chainCode; + } + + get extendedPublicKey(): string { + return this._root.publicExtendedKey; + } + + get extendedPrivateKey(): string { + return this._root.privateExtendedKey; + } + + get index(): number { + return this._root.index; + } + + get depth(): number { + return this._root.depth; + } + + get address(): ErgoAddress { + return this._address; + } + + static async fromMnemonic(mnemonic: string, options?: FromMnemonicOptions): Promise { + return this.fromMasterSeed(await mnemonicToSeed(mnemonic, options?.passphrase), options?.path); + } + + static fromMnemonicSync(mnemonic: string, options?: FromMnemonicOptions): ErgoHDKey { + return this.fromMasterSeed(mnemonicToSeedSync(mnemonic, options?.passphrase), options?.path); + } + + static fromMasterSeed(seed: Uint8Array, path = ERGO_HD_CHANGE_PATH): ErgoHDKey { + const key = HDKey.fromMasterSeed(seed); + if (path !== "") { + return new ErgoHDKey(key.derive(path)); + } + + return new ErgoHDKey(key); + } + + static fromExtendedKey(base58EncodedExtKey: string): ErgoHDKey { + return new ErgoHDKey(HDKey.fromExtendedKey(base58EncodedExtKey)); + } + + deriveChild(index: number): ErgoHDKey { + return new ErgoHDKey(this._root.deriveChild(index)); + } + + derive(path: string): ErgoHDKey { + return new ErgoHDKey(this._root.derive(path)); + } + + wipePrivateData(): ErgoHDKey { + this._root.wipePrivateData(); + + return this; + } +} diff --git a/packages/wallet/src/index.ts b/packages/wallet/src/index.ts new file mode 100644 index 00000000..7a7c4d34 --- /dev/null +++ b/packages/wallet/src/index.ts @@ -0,0 +1,2 @@ +export * from "./ergoHDKey"; +export * from "./mnemonic"; diff --git a/packages/wallet/src/mnemonic.spec.ts b/packages/wallet/src/mnemonic.spec.ts new file mode 100644 index 00000000..26c190c5 --- /dev/null +++ b/packages/wallet/src/mnemonic.spec.ts @@ -0,0 +1,49 @@ +import { describe, expect, it } from "vitest"; +import { generateMnemonic, validateMnemonic } from "./mnemonic"; +import { keyAddressesTestVectors } from "./tests/keyTestVectors"; + +describe("Mnemonic generation", () => { + it("Should create a valid 12 word mnemonic", () => { + const mnemonic = generateMnemonic(128); + + expect(mnemonic.split(" ")).to.have.length(12); + expect(validateMnemonic(mnemonic)).to.be.true; + }); + + it("Should create a valid 15 word mnemonic by default", () => { + const mnemonic = generateMnemonic(); + + expect(mnemonic.split(" ")).to.have.length(15); + expect(validateMnemonic(mnemonic)).to.be.true; + }); + + it("Should create a valid 24 word mnemonic", () => { + const mnemonic = generateMnemonic(256); + + expect(mnemonic.split(" ")).to.have.length(24); + expect(validateMnemonic(mnemonic)).to.be.true; + }); +}); + +describe("Mnemonic validation", () => { + it("Should pass for valid mnemonics", () => { + for (const tv of keyAddressesTestVectors) { + expect(validateMnemonic(tv.mnemonic)).to.be.true; + } + }); + + it("Should not pass for invalid mnemonics", () => { + expect(validateMnemonic("")).to.be.false; + expect( + validateMnemonic( + "brown reason sponsor fix defense pair kit private front next drip fire clip student" + ) + ).to.be.false; + + expect( + validateMnemonic( + "brown acid reason sponsor fix defense pair kit private front next drip clip fire student" + ) + ).to.be.false; + }); +}); diff --git a/packages/wallet/src/mnemonic.ts b/packages/wallet/src/mnemonic.ts new file mode 100644 index 00000000..5d0c085b --- /dev/null +++ b/packages/wallet/src/mnemonic.ts @@ -0,0 +1,10 @@ +import * as bip39 from "@scure/bip39"; +import { wordlist } from "@scure/bip39/wordlists/english"; + +export function generateMnemonic(strength = 160): string { + return bip39.generateMnemonic(wordlist, strength); +} + +export function validateMnemonic(mnemonic: string): boolean { + return bip39.validateMnemonic(mnemonic, wordlist); +} diff --git a/packages/wallet/src/tests/keyTestVectors.ts b/packages/wallet/src/tests/keyTestVectors.ts new file mode 100644 index 00000000..16e9f776 --- /dev/null +++ b/packages/wallet/src/tests/keyTestVectors.ts @@ -0,0 +1,39 @@ +export const keyAddressesTestVectors = [ + { + mnemonic: + "brown acid reason sponsor fix defense pair kit private front next drip fire clip student", + addresses: [ + "9hjEquNmETqhFvnng9s8sRZ9HFFB169jubBfdfKqt5DWTjNEPWQ", + "9fdGiKo71ijaXESLxghxq9c9o7pF966ah4ncdS9PAgWD9EouPnL", + "9g9Be8LM8vXe4GqtVDr5QQrQqxtuU1yLmUWN3BGc717RoyQkfKA" + ] + }, + { + // https://github.com/ergoplatform/ergo/issues/1627 + mnemonic: + "race relax argue hair sorry riot there spirit ready fetch food hedgehog hybrid mobile pretty", + addresses: [ + "9eYMpbGgBf42bCcnB2nG3wQdqPzpCCw5eB1YaWUUen9uCaW3wwm", + "9hbDtY893BDSDowLQMhHG1zvMj97aZ4Dhn5e9waepPp85ZqszAJ", + "9fvZwUVgZRQ1D9fnWo9htki1QbUHPyayz3aZ4PKfZPFgiVTQSUS", + "9hsnY5hUAsjjb3awB8SgwPyxhDoxaxuNWZzqvgCfgnPFZTqY6NQ", + "9iJe5heD3mvMPm6yi6rtZAzXVjZ1Sm12Y5LZb9P7YcYXp1hkd5N", + "9hdCRgAYyrf5fkHkQ9MtZu1bt2K1yosSQXUx4YZcSDamAc6wbwN", + "9eYwqmHR2q6HYQtn4qtgtvFx1KGYcdkJoXn9MTcZDkAGbo5MF2r", + "9i4yUcMTH7GGPPBegt2ZwWMnUaMbYm8243dYS8f6rTEVyQ9Uq3b", + "9gaWSGquk7XjdcfsVzDYeYbY79atawsmB7p8JrBX2ThXR1EGWs6", + "9hBfMj3DdnHSwuEZrMP376WwmNZZvMrtdunxiWbsuw54yL6XM7g", + "9g8eCLchHRE9BiLFwVUBLKj8U81R7QsAg9iFZsq6yv9vzYAJrb4", + "9fS2xETSc6tU6TVSqZZjhSFEdKAFpnXQ1iXGgNNcMFVwyUYh4jQ", + "9egGo9ixEhXSrvfUTBJfTtEzwieiqw7tQcutycmh2PE9GtTxPNw", + "9gE2q8ge3gmv2iThTz6AC5Sj2yPBGxNFMfpYGnrj3xG8ETfo5iN", + "9hui4xxga5SP5YLPH4kqNhWGXPr2rnTuFJ4exreqyKhZVphp4rx", + "9fHfoB4tQByRqF4tAPWe6PpuLYSdWCoVx7L1zCpJDjP8mmG8JjL", + "9gSehpDSTfJYz96dbigfAkrNg6wfaXkkAbZHYw6i4Gd3WZ9H1iY", + "9iFgNga4FbK7Eypua1ftEigKByevCFMrk4uF9DivU1SD9WxbTBL", + "9gsPF8FYVkwojRYQnRxFLVqB4hvEJ93FXMBx738X8YEMZRdJD3R", + "9ffwgMqfr1FuigpWLRZCxVmoN11xJ9UsmTg1zztferWHRChgyMc", + "9exifR7rY8xe9DK6gkDWtLf36yds8qtY5JyeXHqSUyuCoPb7HjU" + ] + } +]; diff --git a/packages/wallet/tsconfig.esm.json b/packages/wallet/tsconfig.esm.json new file mode 100644 index 00000000..76c2936a --- /dev/null +++ b/packages/wallet/tsconfig.esm.json @@ -0,0 +1,8 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "target": "ESNext", + "module": "ESNext", + "outDir": "dist/esm" + } +} diff --git a/packages/wallet/tsconfig.json b/packages/wallet/tsconfig.json new file mode 100644 index 00000000..28724127 --- /dev/null +++ b/packages/wallet/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "rootDir": "./src", + "outDir": "dist/cjs" + }, + "include": ["src/**/*.ts"] +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index efd2c0fa..8bc9ef25 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -3,6 +3,10 @@ lockfileVersion: '6.0' importers: .: + dependencies: + ergo-lib-wasm-nodejs: + specifier: ^0.23.0 + version: 0.23.0 devDependencies: '@noble/hashes': specifier: ^1.3.0 @@ -10,6 +14,12 @@ importers: '@scure/base': specifier: ^1.1.1 version: 1.1.1 + '@scure/bip32': + specifier: ^1.3.0 + version: 1.3.0 + '@scure/bip39': + specifier: ^1.2.0 + version: 1.2.0 '@types/node': specifier: ^18.15.11 version: 18.15.11 @@ -76,6 +86,18 @@ importers: specifier: ^1.1.1 version: 1.1.1 + packages/wallet: + dependencies: + '@fleet-sdk/core': + specifier: workspace:^ + version: link:../core + '@scure/bip32': + specifier: ^1.3.0 + version: 1.3.0 + '@scure/bip39': + specifier: ^1.2.0 + version: 1.2.0 + plugins/babel-fees: dependencies: '@fleet-sdk/common': @@ -606,6 +628,11 @@ packages: '@jridgewell/sourcemap-codec': 1.4.14 dev: true + /@noble/curves@1.0.0: + resolution: {integrity: sha512-2upgEu0iLiDVDZkNLeFV2+ht0BAVgQnEmCk6JsOch9Rp8xfkMCbvbAZlA2pBHQc73dbl+vFOXfqkf4uemdn0bw==} + dependencies: + '@noble/hashes': 1.3.0 + /@noble/hashes@1.3.0: resolution: {integrity: sha512-ilHEACi9DwqJB0pw7kv+Apvh50jiiSyR/cQ3y4W7lOR5mhvn/50FLUfsnfJz0BDZtl/RR16kXvptiv6q1msYZg==} @@ -633,6 +660,19 @@ packages: /@scure/base@1.1.1: resolution: {integrity: sha512-ZxOhsSyxYwLJj3pLZCefNitxsj093tb2vq90mp2txoYeBqbcjDjqFhyM8eUjq/uFm6zJ+mUuqxlS2FkuSY1MTA==} + /@scure/bip32@1.3.0: + resolution: {integrity: sha512-bcKpo1oj54hGholplGLpqPHRbIsnbixFtc06nwuNM5/dwSXOq/AAYoIBRsBmnZJSdfeNW5rnff7NTAz3ZCqR9Q==} + dependencies: + '@noble/curves': 1.0.0 + '@noble/hashes': 1.3.0 + '@scure/base': 1.1.1 + + /@scure/bip39@1.2.0: + resolution: {integrity: sha512-SX/uKq52cuxm4YFXWFaVByaSHJh2w3BnokVSeUJVCv6K7WulT9u2BuNRBhuFl8vAuYnzx9bEu9WgpcNYTrYieg==} + dependencies: + '@noble/hashes': 1.3.0 + '@scure/base': 1.1.1 + /@tokenizer/token@0.3.0: resolution: {integrity: sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==} dev: true @@ -1652,6 +1692,10 @@ packages: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} dev: true + /ergo-lib-wasm-nodejs@0.23.0: + resolution: {integrity: sha512-1CMiu2gM8c9F4LqQ+j4ib2CS9FTTvnwxKYGQvkZN7beaiIqPFr1AQvMVT3dn/9JfQmEz9zcp2OejvIamcQitFQ==} + dev: false + /error-ex@1.3.2: resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} dependencies: diff --git a/vitest.config.ts b/vitest.config.ts index 12e617d7..1d9a4fee 100644 --- a/vitest.config.ts +++ b/vitest.config.ts @@ -8,7 +8,7 @@ export default defineConfig({ reporter: ["text", "json", "html"], lines: 100, statements: 100, - branches: 98.38, + branches: 98.39, functions: 100, thresholdAutoUpdate: true, exclude: ["**/tests/**", "**/*.spec.ts"]