From a1fdefa35e359466db5e1db95155ca7a4d6a1d68 Mon Sep 17 00:00:00 2001 From: Shahin Safaraliyev Date: Tue, 27 Jan 2026 20:58:38 +0400 Subject: [PATCH 01/39] feat: support address creation with BIP44 --- packages/profiles/source/wallet.factory.ts | 28 ++++++++++++++++------ 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/packages/profiles/source/wallet.factory.ts b/packages/profiles/source/wallet.factory.ts index 728510e4..30d511be 100644 --- a/packages/profiles/source/wallet.factory.ts +++ b/packages/profiles/source/wallet.factory.ts @@ -1,7 +1,7 @@ /* istanbul ignore file */ import { Enums } from "@ardenthq/sdk"; -import { BIP38, BIP39, UUID } from "@ardenthq/sdk-cryptography"; +import { BIP38, BIP39, UUID, secp256k1, HDKey } from "@ardenthq/sdk-cryptography"; import { IAddressOptions, @@ -75,12 +75,26 @@ export class WalletFactory implements IWalletFactory { /** {@inheritDoc IWalletFactory.fromMnemonicWithBIP44} */ public async fromMnemonicWithBIP44(options: IMnemonicDerivativeOptions): Promise { - return this.#fromMnemonicWithDerivative({ - derivationType: "bip44", - featureFlag: Enums.FeatureFlag.AddressMnemonicBip44, - importMethod: WalletImportMethod.BIP44.MNEMONIC, - options, - }); + const path = "m/44'/111'/0'/0/0"; + + const seed = BIP39.toSeed(options.mnemonic); + + const hd = HDKey.fromSeed(seed); + const child = hd.derive(path); + + const publicKey = secp256k1.publicKeyCreate(child.privateKey, true).toString("hex"); + + const wallet: IReadWriteWallet = new Wallet(UUID.random(), {}, this.#profile); + wallet.data().set(WalletData.ImportMethod, WalletImportMethod.BIP44.MNEMONIC); + wallet.data().set(WalletData.PublicKey, publicKey); + wallet.data().set(WalletData.Status, WalletFlag.Cold); + + await wallet.mutator().coin(options.coin, options.network); + + const address = await wallet.coin().address().fromPublicKey(publicKey); + await wallet.mutator().address(address); + + return wallet; } /** {@inheritDoc IWalletFactory.fromMnemonicWithBIP49} */ From 822670535cf7ea81e07fad67ab82d14a3d862a30 Mon Sep 17 00:00:00 2001 From: Shahin Safaraliyev Date: Tue, 27 Jan 2026 22:35:07 +0400 Subject: [PATCH 02/39] feat: support address creation with BIP44 --- .github/workflows/cd.yml | 2 +- .github/workflows/ci.yml | 2 +- .github/workflows/validators.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/cd.yml b/.github/workflows/cd.yml index b91a57b3..7b8ba57d 100644 --- a/.github/workflows/cd.yml +++ b/.github/workflows/cd.yml @@ -11,7 +11,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - node-version: [16.x] + node-version: [18.x] concurrency: group: ${{ github.head_ref }}-publish cancel-in-progress: true diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2c7b3cfa..cc5ac90a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -21,7 +21,7 @@ jobs: version: 8.8.0 - uses: actions/setup-node@v2 with: - node-version: "16" + node-version: "18" cache: "pnpm" - name: Build run: | diff --git a/.github/workflows/validators.yml b/.github/workflows/validators.yml index 0770b2ae..9ebe4b90 100644 --- a/.github/workflows/validators.yml +++ b/.github/workflows/validators.yml @@ -15,7 +15,7 @@ jobs: version: 8.8.0 - uses: actions/setup-node@v2 with: - node-version: "16" + node-version: "18" cache: "pnpm" - name: Build run: | From f46ff515b43a3a0e646f50e29264387701c39949 Mon Sep 17 00:00:00 2001 From: Shahin Safaraliyev Date: Tue, 27 Jan 2026 22:53:20 +0400 Subject: [PATCH 03/39] feat: support address creation with BIP44 --- .github/workflows/cd.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/cd.yml b/.github/workflows/cd.yml index 7b8ba57d..d124ee7e 100644 --- a/.github/workflows/cd.yml +++ b/.github/workflows/cd.yml @@ -32,7 +32,7 @@ jobs: - name: Install pnpm uses: pnpm/action-setup@v2 with: - version: 6.20.4 + version: 8.15.9 - name: Install dependencies run: pnpm install - name: Publish From 81c4de9274d9063dd2063a1c28e81115e11e11f5 Mon Sep 17 00:00:00 2001 From: Shahin Safaraliyev Date: Tue, 27 Jan 2026 22:58:11 +0400 Subject: [PATCH 04/39] feat: support address creation with BIP44 --- .github/workflows/ci.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index cc5ac90a..dabb55ee 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,11 +15,11 @@ jobs: group: ${{ github.head_ref }}-test cancel-in-progress: true steps: - - uses: actions/checkout@v2 - - uses: pnpm/action-setup@v2 + - uses: actions/checkout@v3 + - uses: pnpm/action-setup@v3 with: version: 8.8.0 - - uses: actions/setup-node@v2 + - uses: actions/setup-node@v3 with: node-version: "18" cache: "pnpm" From b6dbc8753b7a3efa723639963d7c3e417168ec5d Mon Sep 17 00:00:00 2001 From: Shahin Safaraliyev Date: Tue, 27 Jan 2026 23:05:17 +0400 Subject: [PATCH 05/39] feat: support address creation with BIP44 --- packages/profiles/source/wallet.factory.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/profiles/source/wallet.factory.ts b/packages/profiles/source/wallet.factory.ts index 30d511be..598c4c1c 100644 --- a/packages/profiles/source/wallet.factory.ts +++ b/packages/profiles/source/wallet.factory.ts @@ -79,7 +79,7 @@ export class WalletFactory implements IWalletFactory { const seed = BIP39.toSeed(options.mnemonic); - const hd = HDKey.fromSeed(seed); + const hd = HDKey.fromSeed(Buffer.from(seed)); const child = hd.derive(path); const publicKey = secp256k1.publicKeyCreate(child.privateKey, true).toString("hex"); From 9a0d75ef3e06cb290dbad6b83ef6e47e5483b48f Mon Sep 17 00:00:00 2001 From: Shahin Safaraliyev Date: Wed, 28 Jan 2026 14:23:55 +0400 Subject: [PATCH 06/39] feat: support address creation with BIP44 --- .github/workflows/cd.yml | 8 ++++---- .github/workflows/label.yml | 2 +- .github/workflows/validators.yml | 6 +++--- packages/profiles/source/wallet.factory.ts | 18 ++++++++++++------ 4 files changed, 20 insertions(+), 14 deletions(-) diff --git a/.github/workflows/cd.yml b/.github/workflows/cd.yml index d124ee7e..109651a9 100644 --- a/.github/workflows/cd.yml +++ b/.github/workflows/cd.yml @@ -16,13 +16,13 @@ jobs: group: ${{ github.head_ref }}-publish cancel-in-progress: true steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v1 + uses: actions/setup-node@v3 with: node-version: ${{ matrix.node-version }} - name: Cache pnpm modules - uses: actions/cache@v2 + uses: actions/cache@v3 env: cache-name: cache-pnpm-modules with: @@ -30,7 +30,7 @@ jobs: key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ matrix.node-version }}-${{ hashFiles('**/package.json') }} restore-keys: ${{ runner.os }}-build-${{ env.cache-name }}-${{ matrix.node-version }}- - name: Install pnpm - uses: pnpm/action-setup@v2 + uses: pnpm/action-setup@v3 with: version: 8.15.9 - name: Install dependencies diff --git a/.github/workflows/label.yml b/.github/workflows/label.yml index 7e9fab0b..5fb806c3 100644 --- a/.github/workflows/label.yml +++ b/.github/workflows/label.yml @@ -10,7 +10,7 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: ref: ${{ github.head_ref }} diff --git a/.github/workflows/validators.yml b/.github/workflows/validators.yml index 9ebe4b90..81887c9c 100644 --- a/.github/workflows/validators.yml +++ b/.github/workflows/validators.yml @@ -9,11 +9,11 @@ jobs: compile: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 - - uses: pnpm/action-setup@v2 + - uses: actions/checkout@v3 + - uses: pnpm/action-setup@v3 with: version: 8.8.0 - - uses: actions/setup-node@v2 + - uses: actions/setup-node@v3 with: node-version: "18" cache: "pnpm" diff --git a/packages/profiles/source/wallet.factory.ts b/packages/profiles/source/wallet.factory.ts index 598c4c1c..b4939ed7 100644 --- a/packages/profiles/source/wallet.factory.ts +++ b/packages/profiles/source/wallet.factory.ts @@ -75,7 +75,18 @@ export class WalletFactory implements IWalletFactory { /** {@inheritDoc IWalletFactory.fromMnemonicWithBIP44} */ public async fromMnemonicWithBIP44(options: IMnemonicDerivativeOptions): Promise { - const path = "m/44'/111'/0'/0/0"; + const wallet: IReadWriteWallet = new Wallet(UUID.random(), {}, this.#profile); + wallet.data().set(WalletData.ImportMethod, WalletImportMethod.BIP44.MNEMONIC); + wallet.data().set(WalletData.Status, WalletFlag.Cold); + + await wallet.mutator().coin(options.coin, options.network); + + const slip = wallet.config().get("network.constants.slip44"); + const account = options.levels.account ?? 0; + const change = options.levels.change ?? 0; + const addressIndex= options.levels.address_index ?? 0; + + const path = `m/44'/${slip}'/${account}'/${change}/${addressIndex}`; const seed = BIP39.toSeed(options.mnemonic); @@ -84,12 +95,7 @@ export class WalletFactory implements IWalletFactory { const publicKey = secp256k1.publicKeyCreate(child.privateKey, true).toString("hex"); - const wallet: IReadWriteWallet = new Wallet(UUID.random(), {}, this.#profile); - wallet.data().set(WalletData.ImportMethod, WalletImportMethod.BIP44.MNEMONIC); wallet.data().set(WalletData.PublicKey, publicKey); - wallet.data().set(WalletData.Status, WalletFlag.Cold); - - await wallet.mutator().coin(options.coin, options.network); const address = await wallet.coin().address().fromPublicKey(publicKey); await wallet.mutator().address(address); From bba9daedc2f87fd2c51ad2c6088f9d16e7451929 Mon Sep 17 00:00:00 2001 From: Shahin Safaraliyev Date: Wed, 28 Jan 2026 14:25:10 +0400 Subject: [PATCH 07/39] feat: support address creation with BIP44 --- packages/profiles/source/wallet.factory.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/profiles/source/wallet.factory.ts b/packages/profiles/source/wallet.factory.ts index b4939ed7..89746746 100644 --- a/packages/profiles/source/wallet.factory.ts +++ b/packages/profiles/source/wallet.factory.ts @@ -84,7 +84,7 @@ export class WalletFactory implements IWalletFactory { const slip = wallet.config().get("network.constants.slip44"); const account = options.levels.account ?? 0; const change = options.levels.change ?? 0; - const addressIndex= options.levels.address_index ?? 0; + const addressIndex= options.levels.addressIndex ?? 0; const path = `m/44'/${slip}'/${account}'/${change}/${addressIndex}`; From d7e091bc8c7558445bebf977e17f3f947da03569 Mon Sep 17 00:00:00 2001 From: shahin-hq Date: Wed, 28 Jan 2026 10:27:33 +0000 Subject: [PATCH 08/39] style: resolve style guide violations --- packages/profiles/source/wallet.factory.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/profiles/source/wallet.factory.ts b/packages/profiles/source/wallet.factory.ts index 89746746..7b5ea2d7 100644 --- a/packages/profiles/source/wallet.factory.ts +++ b/packages/profiles/source/wallet.factory.ts @@ -84,7 +84,7 @@ export class WalletFactory implements IWalletFactory { const slip = wallet.config().get("network.constants.slip44"); const account = options.levels.account ?? 0; const change = options.levels.change ?? 0; - const addressIndex= options.levels.addressIndex ?? 0; + const addressIndex = options.levels.addressIndex ?? 0; const path = `m/44'/${slip}'/${account}'/${change}/${addressIndex}`; From feb6e408ed93e0c6cf2d79d0c7cbfa4f1858b52a Mon Sep 17 00:00:00 2001 From: Shahin Safaraliyev Date: Wed, 28 Jan 2026 15:30:32 +0400 Subject: [PATCH 09/39] feat: support address creation with BIP44 --- packages/profiles/source/wallet.factory.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/packages/profiles/source/wallet.factory.ts b/packages/profiles/source/wallet.factory.ts index 89746746..e1c43fed 100644 --- a/packages/profiles/source/wallet.factory.ts +++ b/packages/profiles/source/wallet.factory.ts @@ -100,6 +100,11 @@ export class WalletFactory implements IWalletFactory { const address = await wallet.coin().address().fromPublicKey(publicKey); await wallet.mutator().address(address); + if (options.password) { + wallet.data().set(WalletData.ImportMethod, WalletImportMethod.BIP44.MNEMONIC_WITH_ENCRYPTION); + await wallet.signingKey().set(options.mnemonic, options.password); + } + return wallet; } From 3df4a6ba7875f322c783cc48b532c3d73cf9c31c Mon Sep 17 00:00:00 2001 From: Shahin Safaraliyev Date: Wed, 28 Jan 2026 15:50:11 +0400 Subject: [PATCH 10/39] feat: support address creation with BIP44 --- packages/profiles/source/serialiser.ts | 1 + packages/profiles/source/wallet.contract.ts | 16 ++++++++++++++++ packages/profiles/source/wallet.enum.ts | 1 + packages/profiles/source/wallet.factory.ts | 6 +----- packages/profiles/source/wallet.ts | 10 ++++++++++ 5 files changed, 29 insertions(+), 5 deletions(-) diff --git a/packages/profiles/source/serialiser.ts b/packages/profiles/source/serialiser.ts index caa8f8cf..38cedb28 100644 --- a/packages/profiles/source/serialiser.ts +++ b/packages/profiles/source/serialiser.ts @@ -49,6 +49,7 @@ export class WalletSerialiser { [WalletData.LedgerModel]: this.#wallet.data().get(WalletData.LedgerModel), [WalletData.Status]: this.#wallet.data().get(WalletData.Status), [WalletData.IsPrimary]: this.#wallet.data().get(WalletData.IsPrimary, false), + [WalletData.AddressIndex]: this.#wallet.data().get(WalletData.AddressIndex), }, id: this.#wallet.id(), settings: this.#wallet.settings().all(), diff --git a/packages/profiles/source/wallet.contract.ts b/packages/profiles/source/wallet.contract.ts index 3889e01a..665cbb7b 100644 --- a/packages/profiles/source/wallet.contract.ts +++ b/packages/profiles/source/wallet.contract.ts @@ -688,6 +688,22 @@ export interface IReadWriteWallet { */ actsWithMnemonic(): boolean; + /** + * Determines if the wallet has been imported with a BIP44 mnemonic + * + * @return {*} {boolean} + * @memberof IReadWriteWallet + */ + actsWithBip44Mnemonic(): boolean; + + /** + * Determines if the wallet has been imported with a BIP44 mnemonic with encryption + * + * @return {*} {boolean} + * @memberof IReadWriteWallet + */ + actsWithBip44MnemonicWithEncryption(): boolean; + /** * Determines if the wallet has been imported with a address. * diff --git a/packages/profiles/source/wallet.enum.ts b/packages/profiles/source/wallet.enum.ts index bf9413ff..42237eb1 100644 --- a/packages/profiles/source/wallet.enum.ts +++ b/packages/profiles/source/wallet.enum.ts @@ -30,6 +30,7 @@ export enum WalletData { LedgerModel = "LEDGER_MODEL", Status = "STATUS", IsPrimary = "IS_PRIMARY", + AddressIndex = "Address_Index", } /** diff --git a/packages/profiles/source/wallet.factory.ts b/packages/profiles/source/wallet.factory.ts index f940c239..091d3e56 100644 --- a/packages/profiles/source/wallet.factory.ts +++ b/packages/profiles/source/wallet.factory.ts @@ -96,15 +96,11 @@ export class WalletFactory implements IWalletFactory { const publicKey = secp256k1.publicKeyCreate(child.privateKey, true).toString("hex"); wallet.data().set(WalletData.PublicKey, publicKey); + wallet.data().set(WalletData.AddressIndex, addressIndex); const address = await wallet.coin().address().fromPublicKey(publicKey); await wallet.mutator().address(address); - if (options.password) { - wallet.data().set(WalletData.ImportMethod, WalletImportMethod.BIP44.MNEMONIC_WITH_ENCRYPTION); - await wallet.signingKey().set(options.mnemonic, options.password); - } - return wallet; } diff --git a/packages/profiles/source/wallet.ts b/packages/profiles/source/wallet.ts index a28822e3..43d5a32f 100644 --- a/packages/profiles/source/wallet.ts +++ b/packages/profiles/source/wallet.ts @@ -579,6 +579,16 @@ export class Wallet implements IReadWriteWallet { ].includes(this.data().get(WalletData.ImportMethod)!); } + /** {@inheritDoc IReadWriteWallet.actsWithBip44Mnemonic} */ + public actsWithBip44Mnemonic(): boolean { + return this.data().get(WalletData.ImportMethod) === WalletImportMethod.BIP44.MNEMONIC; + } + + /** {@inheritDoc IReadWriteWallet.actsWithBip44Mnemonic} */ + public actsWithBip44MnemonicWithEncryption(): boolean { + return this.data().get(WalletData.ImportMethod) === WalletImportMethod.BIP44.MNEMONIC_WITH_ENCRYPTION; + } + /** {@inheritDoc IReadWriteWallet.actsWithAddress} */ public actsWithAddress(): boolean { return this.data().get(WalletData.ImportMethod) === WalletImportMethod.Address; From fabd36c4d7fc6b3486aa8067ff70b6e19c50f8a4 Mon Sep 17 00:00:00 2001 From: Shahin Safaraliyev Date: Wed, 28 Jan 2026 15:55:54 +0400 Subject: [PATCH 11/39] feat: support address creation with BIP44 --- packages/profiles/source/wallet.enum.ts | 2 +- packages/profiles/source/wallet.test.ts | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/profiles/source/wallet.enum.ts b/packages/profiles/source/wallet.enum.ts index 42237eb1..f1262f6b 100644 --- a/packages/profiles/source/wallet.enum.ts +++ b/packages/profiles/source/wallet.enum.ts @@ -30,7 +30,7 @@ export enum WalletData { LedgerModel = "LEDGER_MODEL", Status = "STATUS", IsPrimary = "IS_PRIMARY", - AddressIndex = "Address_Index", + AddressIndex = "ADDRESS_INDEX", } /** diff --git a/packages/profiles/source/wallet.test.ts b/packages/profiles/source/wallet.test.ts index 68561312..87240971 100644 --- a/packages/profiles/source/wallet.test.ts +++ b/packages/profiles/source/wallet.test.ts @@ -454,6 +454,7 @@ describe("Wallet", ({ beforeAll, beforeEach, loader, nock, assert, stub, it }) = VOTES_AVAILABLE: 0, VOTES_USED: 0, IS_PRIMARY: false, + ADDRESS_INDEX: undefined, }); assert.object(actual.settings); assert.string(actual.settings.AVATAR); From 0f2af8198eb876d9d015cdaae6e5e90190c6471b Mon Sep 17 00:00:00 2001 From: Shahin Safaraliyev Date: Wed, 28 Jan 2026 16:00:51 +0400 Subject: [PATCH 12/39] feat: support address creation with BIP44 --- packages/profiles/source/wallet.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/profiles/source/wallet.ts b/packages/profiles/source/wallet.ts index 43d5a32f..38905ca6 100644 --- a/packages/profiles/source/wallet.ts +++ b/packages/profiles/source/wallet.ts @@ -573,7 +573,6 @@ export class Wallet implements IReadWriteWallet { public actsWithMnemonic(): boolean { return [ WalletImportMethod.BIP39.MNEMONIC, - WalletImportMethod.BIP44.MNEMONIC, WalletImportMethod.BIP49.MNEMONIC, WalletImportMethod.BIP84.MNEMONIC, ].includes(this.data().get(WalletData.ImportMethod)!); From c0f74df8417d9b81cbdeaa38610c47068ff74152 Mon Sep 17 00:00:00 2001 From: Shahin Safaraliyev Date: Wed, 28 Jan 2026 16:01:12 +0400 Subject: [PATCH 13/39] feat: support address creation with BIP44 --- packages/profiles/source/wallet.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/profiles/source/wallet.ts b/packages/profiles/source/wallet.ts index 38905ca6..ec8d170a 100644 --- a/packages/profiles/source/wallet.ts +++ b/packages/profiles/source/wallet.ts @@ -616,7 +616,6 @@ export class Wallet implements IReadWriteWallet { public actsWithMnemonicWithEncryption(): boolean { return [ WalletImportMethod.BIP39.MNEMONIC_WITH_ENCRYPTION, - WalletImportMethod.BIP44.MNEMONIC_WITH_ENCRYPTION, WalletImportMethod.BIP49.MNEMONIC_WITH_ENCRYPTION, WalletImportMethod.BIP84.MNEMONIC_WITH_ENCRYPTION, ].includes(this.data().get(WalletData.ImportMethod)!); From e749e0bae7bc3a607a5ee289a27b5fa83f433945 Mon Sep 17 00:00:00 2001 From: Shahin Safaraliyev Date: Wed, 28 Jan 2026 16:14:04 +0400 Subject: [PATCH 14/39] feat: support address creation with BIP44 --- packages/profiles/source/wallet.identifier.factory.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/profiles/source/wallet.identifier.factory.ts b/packages/profiles/source/wallet.identifier.factory.ts index 740dadbb..372f6fd7 100644 --- a/packages/profiles/source/wallet.identifier.factory.ts +++ b/packages/profiles/source/wallet.identifier.factory.ts @@ -12,7 +12,7 @@ export class WalletIdentifierFactory { return this.#address(wallet); } - if (wallet.actsWithMnemonic()) { + if (wallet.actsWithMnemonic() || wallet.actsWithBip44Mnemonic()) { return this.#addressOrPublicKey(wallet); } @@ -20,7 +20,7 @@ export class WalletIdentifierFactory { return this.#addressOrPublicKey(wallet); } - if (wallet.actsWithMnemonicWithEncryption()) { + if (wallet.actsWithMnemonicWithEncryption() || wallet.actsWithBip44MnemonicWithEncryption()) { return this.#addressOrPublicKey(wallet); } From df9ca7ae3cb90b4a64866b310a40aa2c4045de47 Mon Sep 17 00:00:00 2001 From: Shahin Safaraliyev Date: Wed, 28 Jan 2026 19:06:57 +0400 Subject: [PATCH 15/39] feat: support address creation with BIP44 --- packages/ark/source/address.service.ts | 3 ++- packages/ark/source/crypto/identities/address.ts | 4 ++-- packages/ark/source/crypto/identities/keys.ts | 11 ++++++++++- .../ark/source/crypto/identities/public-key.ts | 6 ++++-- packages/ark/source/public-key.service.ts | 3 ++- packages/profiles/source/wallet.factory.ts | 14 ++++---------- packages/profiles/source/wallet.ts | 2 +- 7 files changed, 25 insertions(+), 18 deletions(-) diff --git a/packages/ark/source/address.service.ts b/packages/ark/source/address.service.ts index 10a2f5d6..04e4839c 100644 --- a/packages/ark/source/address.service.ts +++ b/packages/ark/source/address.service.ts @@ -20,11 +20,12 @@ export class AddressService extends Services.AbstractAddressService { public override async fromMnemonic( mnemonic: string, options?: Services.IdentityOptions, + path?: string, ): Promise { abort_unless(BIP39.compatible(mnemonic), "The given value is not BIP39 compliant."); return { - address: BaseAddress.fromPassphrase(mnemonic, this.#config.network), + address: BaseAddress.fromPassphrase(mnemonic, this.#config.network, path), type: "bip39", }; } diff --git a/packages/ark/source/crypto/identities/address.ts b/packages/ark/source/crypto/identities/address.ts index d6759576..ac81bd38 100644 --- a/packages/ark/source/crypto/identities/address.ts +++ b/packages/ark/source/crypto/identities/address.ts @@ -7,8 +7,8 @@ import { getPubKeyHash } from "./helpers.js"; import { PublicKey } from "./public-key.js"; export class Address { - public static fromPassphrase(passphrase: string, network?: Network): string { - return Address.fromPublicKey(PublicKey.fromPassphrase(passphrase), network); + public static fromPassphrase(passphrase: string, network?: Network, path?: string): string { + return Address.fromPublicKey(PublicKey.fromPassphrase(passphrase, path), network); } public static fromPublicKey(publicKey: string, network?: Network): string { diff --git a/packages/ark/source/crypto/identities/keys.ts b/packages/ark/source/crypto/identities/keys.ts index 05aead02..93108b99 100644 --- a/packages/ark/source/crypto/identities/keys.ts +++ b/packages/ark/source/crypto/identities/keys.ts @@ -1,4 +1,4 @@ -import { Hash, secp256k1, WIF } from "@ardenthq/sdk-cryptography"; +import { Hash, secp256k1, WIF, BIP39, HDKey } from "@ardenthq/sdk-cryptography"; import { Network } from "../interfaces/networks.js"; import { KeyPair } from "./contracts.js"; @@ -10,6 +10,15 @@ export class Keys { return Keys.fromPrivateKey(Hash.sha256(Buffer.from(passphrase, "utf8")), compressed); } + public static fromBip44Mnemonic(mnemonic: string, path: string, compressed = true): KeyPair { + const seed = BIP39.toSeed(mnemonic); + + const hd = HDKey.fromSeed(Buffer.from(seed)); + const child = hd.derive(path); + + return Keys.fromPrivateKey(child.privateKey, compressed); + } + public static fromPrivateKey(privateKey: Buffer | string, compressed = true): KeyPair { privateKey = privateKey instanceof Buffer ? privateKey : Buffer.from(privateKey, "hex"); diff --git a/packages/ark/source/crypto/identities/public-key.ts b/packages/ark/source/crypto/identities/public-key.ts index af06f1d5..6084513d 100644 --- a/packages/ark/source/crypto/identities/public-key.ts +++ b/packages/ark/source/crypto/identities/public-key.ts @@ -7,8 +7,10 @@ import { InvalidMultiSignatureAssetError, PublicKeyError } from "./errors.js"; import { Keys } from "./keys.js"; export class PublicKey { - public static fromPassphrase(passphrase: string): string { - return Keys.fromPassphrase(passphrase).publicKey; + public static fromPassphrase(passphrase: string, path?: string): string { + return path + ? Keys.fromBip44Mnemonic(passphrase, path).publicKey + : Keys.fromPassphrase(passphrase).publicKey; } public static fromWIF(wif: string, network?: Network): string { diff --git a/packages/ark/source/public-key.service.ts b/packages/ark/source/public-key.service.ts index 73554604..457f9943 100644 --- a/packages/ark/source/public-key.service.ts +++ b/packages/ark/source/public-key.service.ts @@ -18,11 +18,12 @@ export class PublicKeyService extends Services.AbstractPublicKeyService { public override async fromMnemonic( mnemonic: string, options?: Services.IdentityOptions, + path?: string, ): Promise { abort_unless(BIP39.compatible(mnemonic), "The given value is not BIP39 compliant."); return { - publicKey: BasePublicKey.fromPassphrase(mnemonic), + publicKey: BasePublicKey.fromPassphrase(mnemonic, path), }; } diff --git a/packages/profiles/source/wallet.factory.ts b/packages/profiles/source/wallet.factory.ts index 091d3e56..7c84ce44 100644 --- a/packages/profiles/source/wallet.factory.ts +++ b/packages/profiles/source/wallet.factory.ts @@ -88,18 +88,12 @@ export class WalletFactory implements IWalletFactory { const path = `m/44'/${slip}'/${account}'/${change}/${addressIndex}`; - const seed = BIP39.toSeed(options.mnemonic); - - const hd = HDKey.fromSeed(Buffer.from(seed)); - const child = hd.derive(path); - - const publicKey = secp256k1.publicKeyCreate(child.privateKey, true).toString("hex"); - - wallet.data().set(WalletData.PublicKey, publicKey); wallet.data().set(WalletData.AddressIndex, addressIndex); + wallet.data().set(WalletData.DerivationPath, path); + + const address = (await wallet.coin().address().fromMnemonic(options.mnemonic, undefined, path)).address; - const address = await wallet.coin().address().fromPublicKey(publicKey); - await wallet.mutator().address(address); + await wallet.mutator().address({ address }); return wallet; } diff --git a/packages/profiles/source/wallet.ts b/packages/profiles/source/wallet.ts index ec8d170a..06d83038 100644 --- a/packages/profiles/source/wallet.ts +++ b/packages/profiles/source/wallet.ts @@ -312,7 +312,7 @@ export class Wallet implements IReadWriteWallet { /** {@inheritDoc IReadWriteWallet.isLedger} */ public isLedger(): boolean { - return this.data().get(WalletData.DerivationPath) !== undefined; + return this.data().get(WalletData.DerivationPath) !== undefined && this.data().get(WalletData.AddressIndex) === undefined; } /** {@inheritDoc IReadWriteWallet.isLedgerNanoX} */ From b444521a2f1e704325253c82e76b59e80d5a9ee2 Mon Sep 17 00:00:00 2001 From: Shahin Safaraliyev Date: Wed, 28 Jan 2026 19:10:25 +0400 Subject: [PATCH 16/39] feat: support address creation with BIP44 --- packages/sdk/source/address.contract.ts | 2 +- packages/sdk/source/address.service.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/sdk/source/address.contract.ts b/packages/sdk/source/address.contract.ts index af213c2b..afa6776e 100644 --- a/packages/sdk/source/address.contract.ts +++ b/packages/sdk/source/address.contract.ts @@ -7,7 +7,7 @@ export interface AddressDataTransferObject { } export interface AddressService { - fromMnemonic(mnemonic: string, options?: IdentityOptions): Promise; + fromMnemonic(mnemonic: string, options?: IdentityOptions, path?: string): Promise; fromMultiSignature( input: MultisignatureAddressInput, options?: IdentityOptions, diff --git a/packages/sdk/source/address.service.ts b/packages/sdk/source/address.service.ts index 4145b865..879cb9ae 100644 --- a/packages/sdk/source/address.service.ts +++ b/packages/sdk/source/address.service.ts @@ -17,7 +17,7 @@ export class AbstractAddressService implements AddressService { this.hostSelector = container.get(BindingType.NetworkHostSelector); } - public async fromMnemonic(mnemonic: string, options?: IdentityOptions): Promise { + public async fromMnemonic(mnemonic: string, options?: IdentityOptions, path?: string): Promise { throw new NotImplemented(this.constructor.name, this.fromMultiSignature.name); } From 532fffff26d8c9ad31ae8dbd73db7f9b60417bd0 Mon Sep 17 00:00:00 2001 From: shahin-hq Date: Wed, 28 Jan 2026 15:12:48 +0000 Subject: [PATCH 17/39] style: resolve style guide violations --- packages/ark/source/crypto/identities/public-key.ts | 4 +--- packages/profiles/source/wallet.ts | 5 ++++- packages/sdk/source/address.service.ts | 6 +++++- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/packages/ark/source/crypto/identities/public-key.ts b/packages/ark/source/crypto/identities/public-key.ts index 6084513d..934b1365 100644 --- a/packages/ark/source/crypto/identities/public-key.ts +++ b/packages/ark/source/crypto/identities/public-key.ts @@ -8,9 +8,7 @@ import { Keys } from "./keys.js"; export class PublicKey { public static fromPassphrase(passphrase: string, path?: string): string { - return path - ? Keys.fromBip44Mnemonic(passphrase, path).publicKey - : Keys.fromPassphrase(passphrase).publicKey; + return path ? Keys.fromBip44Mnemonic(passphrase, path).publicKey : Keys.fromPassphrase(passphrase).publicKey; } public static fromWIF(wif: string, network?: Network): string { diff --git a/packages/profiles/source/wallet.ts b/packages/profiles/source/wallet.ts index 06d83038..fc1787db 100644 --- a/packages/profiles/source/wallet.ts +++ b/packages/profiles/source/wallet.ts @@ -312,7 +312,10 @@ export class Wallet implements IReadWriteWallet { /** {@inheritDoc IReadWriteWallet.isLedger} */ public isLedger(): boolean { - return this.data().get(WalletData.DerivationPath) !== undefined && this.data().get(WalletData.AddressIndex) === undefined; + return ( + this.data().get(WalletData.DerivationPath) !== undefined && + this.data().get(WalletData.AddressIndex) === undefined + ); } /** {@inheritDoc IReadWriteWallet.isLedgerNanoX} */ diff --git a/packages/sdk/source/address.service.ts b/packages/sdk/source/address.service.ts index 879cb9ae..b0fe5b48 100644 --- a/packages/sdk/source/address.service.ts +++ b/packages/sdk/source/address.service.ts @@ -17,7 +17,11 @@ export class AbstractAddressService implements AddressService { this.hostSelector = container.get(BindingType.NetworkHostSelector); } - public async fromMnemonic(mnemonic: string, options?: IdentityOptions, path?: string): Promise { + public async fromMnemonic( + mnemonic: string, + options?: IdentityOptions, + path?: string, + ): Promise { throw new NotImplemented(this.constructor.name, this.fromMultiSignature.name); } From da8f60384112c42ac0dd3ee086e7a4cdfaabc12d Mon Sep 17 00:00:00 2001 From: Shahin Safaraliyev Date: Wed, 28 Jan 2026 19:16:06 +0400 Subject: [PATCH 18/39] feat: support address creation with BIP44 --- packages/sdk/source/public-key.contract.ts | 2 +- packages/sdk/source/public-key.service.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/sdk/source/public-key.contract.ts b/packages/sdk/source/public-key.contract.ts index 2627e0bc..a8dfc5e7 100644 --- a/packages/sdk/source/public-key.contract.ts +++ b/packages/sdk/source/public-key.contract.ts @@ -6,7 +6,7 @@ export interface PublicKeyDataTransferObject { } export interface PublicKeyService { - fromMnemonic(mnemonic: string, options?: IdentityOptions): Promise; + fromMnemonic(mnemonic: string, options?: IdentityOptions, path?: string): Promise; fromMultiSignature(min: number, publicKeys: string[]): Promise; fromWIF(wif: string): Promise; fromSecret(secret: string): Promise; diff --git a/packages/sdk/source/public-key.service.ts b/packages/sdk/source/public-key.service.ts index cd6e115c..3f1643cf 100644 --- a/packages/sdk/source/public-key.service.ts +++ b/packages/sdk/source/public-key.service.ts @@ -17,7 +17,7 @@ export class AbstractPublicKeyService implements PublicKeyService { this.hostSelector = container.get(BindingType.NetworkHostSelector); } - public async fromMnemonic(mnemonic: string, options?: IdentityOptions): Promise { + public async fromMnemonic(mnemonic: string, options?: IdentityOptions, path?: string): Promise { throw new NotImplemented(this.constructor.name, this.fromMultiSignature.name); } From a48affcd84b87b11467a550d46108078ba9243bb Mon Sep 17 00:00:00 2001 From: shahin-hq Date: Wed, 28 Jan 2026 15:18:25 +0000 Subject: [PATCH 19/39] style: resolve style guide violations --- packages/sdk/source/public-key.service.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/sdk/source/public-key.service.ts b/packages/sdk/source/public-key.service.ts index 3f1643cf..9c1ec8f3 100644 --- a/packages/sdk/source/public-key.service.ts +++ b/packages/sdk/source/public-key.service.ts @@ -17,7 +17,11 @@ export class AbstractPublicKeyService implements PublicKeyService { this.hostSelector = container.get(BindingType.NetworkHostSelector); } - public async fromMnemonic(mnemonic: string, options?: IdentityOptions, path?: string): Promise { + public async fromMnemonic( + mnemonic: string, + options?: IdentityOptions, + path?: string, + ): Promise { throw new NotImplemented(this.constructor.name, this.fromMultiSignature.name); } From 701af68e6675db20f403bfa32ea84bf0539ad087 Mon Sep 17 00:00:00 2001 From: Shahin Safaraliyev Date: Thu, 29 Jan 2026 14:43:27 +0400 Subject: [PATCH 20/39] feat: support address creation with BIP44 --- .../source/crypto/identities/private-key.ts | 4 +-- .../transactions/builders/transaction.ts | 4 +-- packages/ark/source/private-key.service.ts | 3 ++- packages/ark/source/transaction.service.ts | 25 +++++++++++++++---- .../source/signatory.factory.contract.ts | 1 + packages/profiles/source/signatory.factory.ts | 9 +++++-- .../source/wallet-transaction.service.ts | 10 ++------ packages/sdk/source/abstract.signatory.ts | 8 ++++++ packages/sdk/source/private-key.contract.ts | 2 +- packages/sdk/source/private-key.service.ts | 6 ++++- packages/sdk/source/public-key.service.ts | 6 ++++- packages/sdk/source/signatory.service.ts | 9 ++++--- packages/sdk/source/signatory.ts | 9 +++++++ 13 files changed, 69 insertions(+), 27 deletions(-) diff --git a/packages/ark/source/crypto/identities/private-key.ts b/packages/ark/source/crypto/identities/private-key.ts index 492d3723..e23ef6c5 100644 --- a/packages/ark/source/crypto/identities/private-key.ts +++ b/packages/ark/source/crypto/identities/private-key.ts @@ -2,8 +2,8 @@ import { Network } from "../interfaces/networks.js"; import { Keys } from "./keys.js"; export class PrivateKey { - public static fromPassphrase(passphrase: string): string { - return Keys.fromPassphrase(passphrase).privateKey; + public static fromPassphrase(passphrase: string, path?: string): string { + return path ? Keys.fromBip44Mnemonic(passphrase, path).privateKey : Keys.fromPassphrase(passphrase).privateKey; } public static fromWIF(wif: string, network?: Network): string { diff --git a/packages/ark/source/crypto/transactions/builders/transaction.ts b/packages/ark/source/crypto/transactions/builders/transaction.ts index 5bcd1cba..7b1bb87c 100644 --- a/packages/ark/source/crypto/transactions/builders/transaction.ts +++ b/packages/ark/source/crypto/transactions/builders/transaction.ts @@ -97,8 +97,8 @@ export abstract class TransactionBuilder { abort_unless(BIP39.compatible(mnemonic), "The given value is not BIP39 compliant."); return { - privateKey: BasePrivateKey.fromPassphrase(mnemonic), + privateKey: BasePrivateKey.fromPassphrase(mnemonic, path), }; } diff --git a/packages/ark/source/transaction.service.ts b/packages/ark/source/transaction.service.ts index e45ce8ac..f1b95cc4 100644 --- a/packages/ark/source/transaction.service.ts +++ b/packages/ark/source/transaction.service.ts @@ -195,9 +195,24 @@ export class TransactionService extends Services.AbstractTransactionService { const transaction = Transactions.BuilderFactory[type](); transaction.version(2); - if (input.signatory.actsWithMnemonic() || input.signatory.actsWithConfirmationMnemonic()) { - address = (await this.#addressService.fromMnemonic(input.signatory.signingKey())).address; - senderPublicKey = (await this.#publicKeyService.fromMnemonic(input.signatory.signingKey())).publicKey; + const path = input.signatory.actsWithBip44Mnemonic() ? input.signatory.path() : undefined; + + if ( + input.signatory.actsWithMnemonic() || + input.signatory.actsWithConfirmationMnemonic() || + input.signatory.actsWithBip44Mnemonic() + ) { + address = ( + await this.#addressService.fromMnemonic(input.signatory.signingKey(), undefined, path) + ).address; + + senderPublicKey = ( + await this.#publicKeyService.fromMnemonic( + input.signatory.signingKey(), + undefined, + path, + ) + ).publicKey; } if (input.signatory.actsWithSecret() || input.signatory.actsWithConfirmationSecret()) { @@ -311,8 +326,8 @@ export class TransactionService extends Services.AbstractTransactionService { await this.#ledgerService.disconnect(); } - if (input.signatory.actsWithMnemonic()) { - transaction.sign(input.signatory.signingKey()); + if (input.signatory.actsWithMnemonic() || input.signatory.actsWithBip44Mnemonic()) { + transaction.sign(input.signatory.signingKey(), path); } if (input.signatory.actsWithConfirmationMnemonic()) { diff --git a/packages/profiles/source/signatory.factory.contract.ts b/packages/profiles/source/signatory.factory.contract.ts index a8a5b903..6150cb73 100644 --- a/packages/profiles/source/signatory.factory.contract.ts +++ b/packages/profiles/source/signatory.factory.contract.ts @@ -8,6 +8,7 @@ export interface SignatoryInput { secondSecret?: string; wif?: string; privateKey?: string; + path?: string; } export interface ISignatoryFactory { diff --git a/packages/profiles/source/signatory.factory.ts b/packages/profiles/source/signatory.factory.ts index 60711b95..ac74eade 100644 --- a/packages/profiles/source/signatory.factory.ts +++ b/packages/profiles/source/signatory.factory.ts @@ -18,13 +18,14 @@ export class SignatoryFactory implements ISignatoryFactory { secondSecret, wif, privateKey, + path, }: SignatoryInput): Promise { if (mnemonic && secondMnemonic) { return this.#wallet.signatory().confirmationMnemonic(mnemonic, secondMnemonic); } if (mnemonic) { - return this.#wallet.signatory().mnemonic(mnemonic); + return this.#wallet.signatory().mnemonic(mnemonic, undefined, path); } if (encryptionPassword) { @@ -50,7 +51,11 @@ export class SignatoryFactory implements ISignatoryFactory { return this.#wallet.signatory().secret(await this.#wallet.signingKey().get(encryptionPassword)); } - return this.#wallet.signatory().mnemonic(await this.#wallet.signingKey().get(encryptionPassword)); + return this.#wallet.signatory().mnemonic( + await this.#wallet.signingKey().get(encryptionPassword), + undefined, + path, + ); } if (this.#wallet.isMultiSignature()) { diff --git a/packages/profiles/source/wallet-transaction.service.ts b/packages/profiles/source/wallet-transaction.service.ts index acc9c52f..332944b1 100644 --- a/packages/profiles/source/wallet-transaction.service.ts +++ b/packages/profiles/source/wallet-transaction.service.ts @@ -441,10 +441,7 @@ export class TransactionService implements ITransactionService { } async #syncPendingMultiSignatures(): Promise { - const transactions = await this.#wallet - .coin() - .multiSignature() - .allWithPendingState(this.#getPublicKey()); + const transactions = await this.#wallet.coin().multiSignature().allWithPendingState(this.#getPublicKey()); this.#pending = {}; @@ -456,10 +453,7 @@ export class TransactionService implements ITransactionService { } async #syncReadyMultiSignatures(): Promise { - const transactions = await this.#wallet - .coin() - .multiSignature() - .allWithReadyState(this.#getPublicKey()); + const transactions = await this.#wallet.coin().multiSignature().allWithReadyState(this.#getPublicKey()); this.#signed = {}; diff --git a/packages/sdk/source/abstract.signatory.ts b/packages/sdk/source/abstract.signatory.ts index da9430c4..38466307 100644 --- a/packages/sdk/source/abstract.signatory.ts +++ b/packages/sdk/source/abstract.signatory.ts @@ -6,6 +6,7 @@ export abstract class AbstractSignatory { readonly #publicKey: string; readonly #privateKey: string; readonly #options?: IdentityOptions; + readonly #path?: string; public constructor({ signingKey, @@ -13,18 +14,21 @@ export abstract class AbstractSignatory { publicKey, privateKey, options, + path, }: { signingKey: string; address: string; publicKey: string; privateKey: string; options?: IdentityOptions; + path?: string; }) { this.#signingKey = signingKey.normalize("NFD"); this.#address = address; this.#publicKey = publicKey; this.#privateKey = privateKey; this.#options = options; + this.#path = path; } public signingKey(): string { @@ -46,4 +50,8 @@ export abstract class AbstractSignatory { public options(): IdentityOptions | undefined { return this.#options; } + + public path(): string | undefined { + return this.#path; + } } diff --git a/packages/sdk/source/private-key.contract.ts b/packages/sdk/source/private-key.contract.ts index 97e498a4..d6d2c03f 100644 --- a/packages/sdk/source/private-key.contract.ts +++ b/packages/sdk/source/private-key.contract.ts @@ -6,7 +6,7 @@ export interface PrivateKeyDataTransferObject { } export interface PrivateKeyService { - fromMnemonic(mnemonic: string, options?: IdentityOptions): Promise; + fromMnemonic(mnemonic: string, options?: IdentityOptions, path?: string): Promise; fromWIF(wif: string): Promise; fromSecret(secret: string): Promise; } diff --git a/packages/sdk/source/private-key.service.ts b/packages/sdk/source/private-key.service.ts index f8594de4..b3e56958 100644 --- a/packages/sdk/source/private-key.service.ts +++ b/packages/sdk/source/private-key.service.ts @@ -17,7 +17,11 @@ export class AbstractPrivateKeyService implements PrivateKeyService { this.hostSelector = container.get(BindingType.NetworkHostSelector); } - public async fromMnemonic(mnemonic: string, options?: IdentityOptions): Promise { + public async fromMnemonic( + mnemonic: string, + options?: IdentityOptions, + path?: string, + ): Promise { throw new NotImplemented(this.constructor.name, this.fromMnemonic.name); } diff --git a/packages/sdk/source/public-key.service.ts b/packages/sdk/source/public-key.service.ts index 3f1643cf..9c1ec8f3 100644 --- a/packages/sdk/source/public-key.service.ts +++ b/packages/sdk/source/public-key.service.ts @@ -17,7 +17,11 @@ export class AbstractPublicKeyService implements PublicKeyService { this.hostSelector = container.get(BindingType.NetworkHostSelector); } - public async fromMnemonic(mnemonic: string, options?: IdentityOptions, path?: string): Promise { + public async fromMnemonic( + mnemonic: string, + options?: IdentityOptions, + path?: string, + ): Promise { throw new NotImplemented(this.constructor.name, this.fromMultiSignature.name); } diff --git a/packages/sdk/source/signatory.service.ts b/packages/sdk/source/signatory.service.ts index 84ffb2c8..4ec57c8d 100644 --- a/packages/sdk/source/signatory.service.ts +++ b/packages/sdk/source/signatory.service.ts @@ -32,14 +32,15 @@ export class AbstractSignatoryService implements SignatoryService { this.#publicKeyService = container.get(BindingType.PublicKeyService); } - public async mnemonic(mnemonic: string, options?: IdentityOptions): Promise { + public async mnemonic(mnemonic: string, options?: IdentityOptions, path?: string): Promise { return new Signatory( new MnemonicSignatory({ - address: (await this.#addressService.fromMnemonic(mnemonic, options)).address, + address: (await this.#addressService.fromMnemonic(mnemonic, options, path)).address, options, - privateKey: (await this.#privateKeyService.fromMnemonic(mnemonic, options)).privateKey, - publicKey: (await this.#publicKeyService.fromMnemonic(mnemonic, options)).publicKey, + privateKey: (await this.#privateKeyService.fromMnemonic(mnemonic, options, path)).privateKey, + publicKey: (await this.#publicKeyService.fromMnemonic(mnemonic, options, path)).publicKey, signingKey: mnemonic, + path, }), options?.multiSignature, ); diff --git a/packages/sdk/source/signatory.ts b/packages/sdk/source/signatory.ts index ec233082..dee39efb 100644 --- a/packages/sdk/source/signatory.ts +++ b/packages/sdk/source/signatory.ts @@ -111,6 +111,11 @@ export class Signatory { } public path(): string { + const path = this.#signatory.path(); + if (path) { + return path; + } + if (this.#signatory instanceof LedgerSignatory) { return this.#signatory.signingKey(); } @@ -154,6 +159,10 @@ export class Signatory { return this.#signatory instanceof MnemonicSignatory; } + public actsWithBip44Mnemonic(): boolean { + return this.#signatory instanceof MnemonicSignatory && this.#signatory.path() !== undefined; + } + public actsWithConfirmationMnemonic(): boolean { return this.#signatory instanceof ConfirmationMnemonicSignatory; } From 1356e5320bd3beb643646ee7bf313f76061e563d Mon Sep 17 00:00:00 2001 From: Shahin Safaraliyev Date: Thu, 29 Jan 2026 14:48:28 +0400 Subject: [PATCH 21/39] feat: support address creation with BIP44 --- packages/sdk/source/signatory.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/packages/sdk/source/signatory.ts b/packages/sdk/source/signatory.ts index dee39efb..e73d6ddf 100644 --- a/packages/sdk/source/signatory.ts +++ b/packages/sdk/source/signatory.ts @@ -111,9 +111,8 @@ export class Signatory { } public path(): string { - const path = this.#signatory.path(); - if (path) { - return path; + if (this.#signatory instanceof MnemonicSignatory && this.#signatory.path()) { + return this.#signatory.path() as string; } if (this.#signatory instanceof LedgerSignatory) { From 0838e86de105946901f220ac34b9075548850b4c Mon Sep 17 00:00:00 2001 From: Shahin Safaraliyev Date: Thu, 29 Jan 2026 14:53:01 +0400 Subject: [PATCH 22/39] feat: support address creation with BIP44 --- packages/sdk/source/signatory.contract.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/sdk/source/signatory.contract.ts b/packages/sdk/source/signatory.contract.ts index d42abbf2..18835290 100644 --- a/packages/sdk/source/signatory.contract.ts +++ b/packages/sdk/source/signatory.contract.ts @@ -3,7 +3,7 @@ import { IdentityOptions } from "./shared.contract.js"; import { Signatory } from "./signatories.js"; export interface SignatoryService { - mnemonic(mnemonic: string, options?: IdentityOptions): Promise; + mnemonic(mnemonic: string, options?: IdentityOptions, path?: string): Promise; confirmationMnemonic(mnemonic: string, confirmation: string, options?: IdentityOptions): Promise; From db2163aeef2e2103755ab6ee872b5ad2375c2545 Mon Sep 17 00:00:00 2001 From: shahin-hq Date: Thu, 29 Jan 2026 10:55:10 +0000 Subject: [PATCH 23/39] style: resolve style guide violations --- packages/ark/source/transaction.service.ts | 13 +++---------- packages/profiles/source/signatory.factory.ts | 8 +++----- .../profiles/source/wallet-transaction.service.ts | 10 ++++++++-- 3 files changed, 14 insertions(+), 17 deletions(-) diff --git a/packages/ark/source/transaction.service.ts b/packages/ark/source/transaction.service.ts index f1b95cc4..345aa46b 100644 --- a/packages/ark/source/transaction.service.ts +++ b/packages/ark/source/transaction.service.ts @@ -202,17 +202,10 @@ export class TransactionService extends Services.AbstractTransactionService { input.signatory.actsWithConfirmationMnemonic() || input.signatory.actsWithBip44Mnemonic() ) { - address = ( - await this.#addressService.fromMnemonic(input.signatory.signingKey(), undefined, path) - ).address; + address = (await this.#addressService.fromMnemonic(input.signatory.signingKey(), undefined, path)).address; - senderPublicKey = ( - await this.#publicKeyService.fromMnemonic( - input.signatory.signingKey(), - undefined, - path, - ) - ).publicKey; + senderPublicKey = (await this.#publicKeyService.fromMnemonic(input.signatory.signingKey(), undefined, path)) + .publicKey; } if (input.signatory.actsWithSecret() || input.signatory.actsWithConfirmationSecret()) { diff --git a/packages/profiles/source/signatory.factory.ts b/packages/profiles/source/signatory.factory.ts index ac74eade..5e2012a0 100644 --- a/packages/profiles/source/signatory.factory.ts +++ b/packages/profiles/source/signatory.factory.ts @@ -51,11 +51,9 @@ export class SignatoryFactory implements ISignatoryFactory { return this.#wallet.signatory().secret(await this.#wallet.signingKey().get(encryptionPassword)); } - return this.#wallet.signatory().mnemonic( - await this.#wallet.signingKey().get(encryptionPassword), - undefined, - path, - ); + return this.#wallet + .signatory() + .mnemonic(await this.#wallet.signingKey().get(encryptionPassword), undefined, path); } if (this.#wallet.isMultiSignature()) { diff --git a/packages/profiles/source/wallet-transaction.service.ts b/packages/profiles/source/wallet-transaction.service.ts index 332944b1..acc9c52f 100644 --- a/packages/profiles/source/wallet-transaction.service.ts +++ b/packages/profiles/source/wallet-transaction.service.ts @@ -441,7 +441,10 @@ export class TransactionService implements ITransactionService { } async #syncPendingMultiSignatures(): Promise { - const transactions = await this.#wallet.coin().multiSignature().allWithPendingState(this.#getPublicKey()); + const transactions = await this.#wallet + .coin() + .multiSignature() + .allWithPendingState(this.#getPublicKey()); this.#pending = {}; @@ -453,7 +456,10 @@ export class TransactionService implements ITransactionService { } async #syncReadyMultiSignatures(): Promise { - const transactions = await this.#wallet.coin().multiSignature().allWithReadyState(this.#getPublicKey()); + const transactions = await this.#wallet + .coin() + .multiSignature() + .allWithReadyState(this.#getPublicKey()); this.#signed = {}; From 2c67de7985cf6f4c16c98bbea4b0ab027002297a Mon Sep 17 00:00:00 2001 From: Shahin Safaraliyev Date: Thu, 29 Jan 2026 16:14:54 +0400 Subject: [PATCH 24/39] feat: support address creation with BIP44 --- packages/profiles/source/wallet.factory.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/packages/profiles/source/wallet.factory.ts b/packages/profiles/source/wallet.factory.ts index 7c84ce44..7d7c18cc 100644 --- a/packages/profiles/source/wallet.factory.ts +++ b/packages/profiles/source/wallet.factory.ts @@ -95,6 +95,11 @@ export class WalletFactory implements IWalletFactory { await wallet.mutator().address({ address }); + if (options.password) { + wallet.data().set(WalletData.ImportMethod, WalletImportMethod.BIP44.MNEMONIC_WITH_ENCRYPTION); + await wallet.signingKey().set(options.mnemonic, options.password); + } + return wallet; } From c6844062c033c8db53c6112b7bd73f6263372a18 Mon Sep 17 00:00:00 2001 From: Shahin Safaraliyev Date: Mon, 2 Feb 2026 16:13:43 +0400 Subject: [PATCH 25/39] feat: support address creation with BIP44 --- packages/ark/source/address.service.ts | 15 +++++++++++++-- .../ark/source/crypto/identities/address.ts | 8 ++++++-- .../source/crypto/identities/private-key.ts | 6 +++++- .../ark/source/crypto/identities/public-key.ts | 8 ++++++-- packages/ark/source/public-key.service.ts | 11 +++++++++++ packages/ark/source/transaction.service.ts | 18 ++++++++++-------- .../source/wallet-transaction.service.ts | 10 ++-------- packages/sdk/source/address.contract.ts | 3 ++- packages/sdk/source/address.service.ts | 10 +++++----- packages/sdk/source/private-key.contract.ts | 3 ++- packages/sdk/source/private-key.service.ts | 10 +++++----- packages/sdk/source/public-key.contract.ts | 1 + packages/sdk/source/public-key.service.ts | 10 +++++----- 13 files changed, 73 insertions(+), 40 deletions(-) diff --git a/packages/ark/source/address.service.ts b/packages/ark/source/address.service.ts index 04e4839c..d1667508 100644 --- a/packages/ark/source/address.service.ts +++ b/packages/ark/source/address.service.ts @@ -20,16 +20,27 @@ export class AddressService extends Services.AbstractAddressService { public override async fromMnemonic( mnemonic: string, options?: Services.IdentityOptions, - path?: string, ): Promise { abort_unless(BIP39.compatible(mnemonic), "The given value is not BIP39 compliant."); return { - address: BaseAddress.fromPassphrase(mnemonic, this.#config.network, path), + address: BaseAddress.fromPassphrase(mnemonic, this.#config.network), type: "bip39", }; } + public override async fromBip44Mnemonic( + mnemonic: string, + path: string, + ): Promise { + abort_unless(BIP39.compatible(mnemonic), "The given value is not BIP39 compliant."); + + return { + address: BaseAddress.fromBip44Mnemonic(mnemonic, path, this.#config.network), + type: "bip44", + }; + } + public override async fromMultiSignature({ min, publicKeys, diff --git a/packages/ark/source/crypto/identities/address.ts b/packages/ark/source/crypto/identities/address.ts index ac81bd38..645369c1 100644 --- a/packages/ark/source/crypto/identities/address.ts +++ b/packages/ark/source/crypto/identities/address.ts @@ -7,8 +7,12 @@ import { getPubKeyHash } from "./helpers.js"; import { PublicKey } from "./public-key.js"; export class Address { - public static fromPassphrase(passphrase: string, network?: Network, path?: string): string { - return Address.fromPublicKey(PublicKey.fromPassphrase(passphrase, path), network); + public static fromPassphrase(passphrase: string, network?: Network): string { + return Address.fromPublicKey(PublicKey.fromPassphrase(passphrase), network); + } + + public static fromBip44Mnemonic(mnemonic: string, path: string, network?: Network): string { + return Address.fromPublicKey(PublicKey.fromBip44Mnemonic(mnemonic, path), network); } public static fromPublicKey(publicKey: string, network?: Network): string { diff --git a/packages/ark/source/crypto/identities/private-key.ts b/packages/ark/source/crypto/identities/private-key.ts index e23ef6c5..f50af49e 100644 --- a/packages/ark/source/crypto/identities/private-key.ts +++ b/packages/ark/source/crypto/identities/private-key.ts @@ -2,10 +2,14 @@ import { Network } from "../interfaces/networks.js"; import { Keys } from "./keys.js"; export class PrivateKey { - public static fromPassphrase(passphrase: string, path?: string): string { + public static fromPassphrase(passphrase: string): string { return path ? Keys.fromBip44Mnemonic(passphrase, path).privateKey : Keys.fromPassphrase(passphrase).privateKey; } + public static fromBip44Mnemonic(passphrase: string, path: string): string { + return Keys.fromBip44Mnemonic(passphrase, path).privateKey; + } + public static fromWIF(wif: string, network?: Network): string { return Keys.fromWIF(wif, network).privateKey; } diff --git a/packages/ark/source/crypto/identities/public-key.ts b/packages/ark/source/crypto/identities/public-key.ts index 934b1365..87c4ee6b 100644 --- a/packages/ark/source/crypto/identities/public-key.ts +++ b/packages/ark/source/crypto/identities/public-key.ts @@ -7,8 +7,12 @@ import { InvalidMultiSignatureAssetError, PublicKeyError } from "./errors.js"; import { Keys } from "./keys.js"; export class PublicKey { - public static fromPassphrase(passphrase: string, path?: string): string { - return path ? Keys.fromBip44Mnemonic(passphrase, path).publicKey : Keys.fromPassphrase(passphrase).publicKey; + public static fromPassphrase(passphrase: string): string { + return Keys.fromPassphrase(passphrase).publicKey; + } + + public static fromBip44Mnemonic(passphrase: string, path: string): string { + return Keys.fromBip44Mnemonic(passphrase, path).publicKey; } public static fromWIF(wif: string, network?: Network): string { diff --git a/packages/ark/source/public-key.service.ts b/packages/ark/source/public-key.service.ts index 457f9943..d7ef49b2 100644 --- a/packages/ark/source/public-key.service.ts +++ b/packages/ark/source/public-key.service.ts @@ -27,6 +27,17 @@ export class PublicKeyService extends Services.AbstractPublicKeyService { }; } + public override async fromBip44Mnemonic( + mnemonic: string, + path: string, + ): Promise { + abort_unless(BIP39.compatible(mnemonic), "The given value is not BIP39 compliant."); + + return { + publicKey: BasePublicKey.fromBip44Mnemonic(mnemonic, path), + }; + } + public override async fromMultiSignature( min: number, publicKeys: string[], diff --git a/packages/ark/source/transaction.service.ts b/packages/ark/source/transaction.service.ts index 345aa46b..978c4337 100644 --- a/packages/ark/source/transaction.service.ts +++ b/packages/ark/source/transaction.service.ts @@ -195,16 +195,18 @@ export class TransactionService extends Services.AbstractTransactionService { const transaction = Transactions.BuilderFactory[type](); transaction.version(2); - const path = input.signatory.actsWithBip44Mnemonic() ? input.signatory.path() : undefined; + if (input.signatory.actsWithMnemonic() || input.signatory.actsWithConfirmationMnemonic()) { + address = (await this.#addressService.fromMnemonic(input.signatory.signingKey())).address; - if ( - input.signatory.actsWithMnemonic() || - input.signatory.actsWithConfirmationMnemonic() || - input.signatory.actsWithBip44Mnemonic() - ) { - address = (await this.#addressService.fromMnemonic(input.signatory.signingKey(), undefined, path)).address; + senderPublicKey = (await this.#publicKeyService.fromMnemonic(input.signatory.signingKey())).publicKey; + } + + if (input.signatory.actsWithBip44Mnemonic()) { + const path = input.signatory.path(); + + address = (await this.#addressService.fromBip44Mnemonic(input.signatory.signingKey(), path)).address; - senderPublicKey = (await this.#publicKeyService.fromMnemonic(input.signatory.signingKey(), undefined, path)) + senderPublicKey = (await this.#publicKeyService.fromBip44Mnemonic(input.signatory.signingKey(), path)) .publicKey; } diff --git a/packages/profiles/source/wallet-transaction.service.ts b/packages/profiles/source/wallet-transaction.service.ts index acc9c52f..332944b1 100644 --- a/packages/profiles/source/wallet-transaction.service.ts +++ b/packages/profiles/source/wallet-transaction.service.ts @@ -441,10 +441,7 @@ export class TransactionService implements ITransactionService { } async #syncPendingMultiSignatures(): Promise { - const transactions = await this.#wallet - .coin() - .multiSignature() - .allWithPendingState(this.#getPublicKey()); + const transactions = await this.#wallet.coin().multiSignature().allWithPendingState(this.#getPublicKey()); this.#pending = {}; @@ -456,10 +453,7 @@ export class TransactionService implements ITransactionService { } async #syncReadyMultiSignatures(): Promise { - const transactions = await this.#wallet - .coin() - .multiSignature() - .allWithReadyState(this.#getPublicKey()); + const transactions = await this.#wallet.coin().multiSignature().allWithReadyState(this.#getPublicKey()); this.#signed = {}; diff --git a/packages/sdk/source/address.contract.ts b/packages/sdk/source/address.contract.ts index afa6776e..d5d0f95e 100644 --- a/packages/sdk/source/address.contract.ts +++ b/packages/sdk/source/address.contract.ts @@ -7,7 +7,8 @@ export interface AddressDataTransferObject { } export interface AddressService { - fromMnemonic(mnemonic: string, options?: IdentityOptions, path?: string): Promise; + fromMnemonic(mnemonic: string, options?: IdentityOptions): Promise; + fromBip44Mnemonic(mnemonic: string, path?: string): Promise; fromMultiSignature( input: MultisignatureAddressInput, options?: IdentityOptions, diff --git a/packages/sdk/source/address.service.ts b/packages/sdk/source/address.service.ts index b0fe5b48..90a384ed 100644 --- a/packages/sdk/source/address.service.ts +++ b/packages/sdk/source/address.service.ts @@ -17,11 +17,11 @@ export class AbstractAddressService implements AddressService { this.hostSelector = container.get(BindingType.NetworkHostSelector); } - public async fromMnemonic( - mnemonic: string, - options?: IdentityOptions, - path?: string, - ): Promise { + public async fromMnemonic(mnemonic: string, options?: IdentityOptions): Promise { + throw new NotImplemented(this.constructor.name, this.fromMultiSignature.name); + } + + public async fromBip44Mnemonic(mnemonic: string, path: string): Promise { throw new NotImplemented(this.constructor.name, this.fromMultiSignature.name); } diff --git a/packages/sdk/source/private-key.contract.ts b/packages/sdk/source/private-key.contract.ts index d6d2c03f..a769251a 100644 --- a/packages/sdk/source/private-key.contract.ts +++ b/packages/sdk/source/private-key.contract.ts @@ -6,7 +6,8 @@ export interface PrivateKeyDataTransferObject { } export interface PrivateKeyService { - fromMnemonic(mnemonic: string, options?: IdentityOptions, path?: string): Promise; + fromMnemonic(mnemonic: string, options?: IdentityOptions): Promise; + fromBip44Mnemonic(mnemonic: string, path?: string): Promise; fromWIF(wif: string): Promise; fromSecret(secret: string): Promise; } diff --git a/packages/sdk/source/private-key.service.ts b/packages/sdk/source/private-key.service.ts index b3e56958..de01d537 100644 --- a/packages/sdk/source/private-key.service.ts +++ b/packages/sdk/source/private-key.service.ts @@ -17,11 +17,11 @@ export class AbstractPrivateKeyService implements PrivateKeyService { this.hostSelector = container.get(BindingType.NetworkHostSelector); } - public async fromMnemonic( - mnemonic: string, - options?: IdentityOptions, - path?: string, - ): Promise { + public async fromMnemonic(mnemonic: string, options?: IdentityOptions): Promise { + throw new NotImplemented(this.constructor.name, this.fromMnemonic.name); + } + + public async fromBip44Mnemonic(mnemonic: string, path: string): Promise { throw new NotImplemented(this.constructor.name, this.fromMnemonic.name); } diff --git a/packages/sdk/source/public-key.contract.ts b/packages/sdk/source/public-key.contract.ts index a8dfc5e7..85c6fb1d 100644 --- a/packages/sdk/source/public-key.contract.ts +++ b/packages/sdk/source/public-key.contract.ts @@ -7,6 +7,7 @@ export interface PublicKeyDataTransferObject { export interface PublicKeyService { fromMnemonic(mnemonic: string, options?: IdentityOptions, path?: string): Promise; + fromBip44Mnemonic(mnemonic: string, path: string): Promise; fromMultiSignature(min: number, publicKeys: string[]): Promise; fromWIF(wif: string): Promise; fromSecret(secret: string): Promise; diff --git a/packages/sdk/source/public-key.service.ts b/packages/sdk/source/public-key.service.ts index 9c1ec8f3..49465637 100644 --- a/packages/sdk/source/public-key.service.ts +++ b/packages/sdk/source/public-key.service.ts @@ -17,11 +17,11 @@ export class AbstractPublicKeyService implements PublicKeyService { this.hostSelector = container.get(BindingType.NetworkHostSelector); } - public async fromMnemonic( - mnemonic: string, - options?: IdentityOptions, - path?: string, - ): Promise { + public async fromMnemonic(mnemonic: string, options?: IdentityOptions): Promise { + throw new NotImplemented(this.constructor.name, this.fromMultiSignature.name); + } + + public async fromBip44Mnemonic(mnemonic: string, path: string): Promise { throw new NotImplemented(this.constructor.name, this.fromMultiSignature.name); } From 425d235d69bc70e3b07e540f4bfdf16452b4f76c Mon Sep 17 00:00:00 2001 From: Shahin Safaraliyev Date: Mon, 2 Feb 2026 16:16:55 +0400 Subject: [PATCH 26/39] feat: support address creation with BIP44 --- packages/ark/source/crypto/identities/private-key.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/ark/source/crypto/identities/private-key.ts b/packages/ark/source/crypto/identities/private-key.ts index f50af49e..909f69fe 100644 --- a/packages/ark/source/crypto/identities/private-key.ts +++ b/packages/ark/source/crypto/identities/private-key.ts @@ -3,7 +3,7 @@ import { Keys } from "./keys.js"; export class PrivateKey { public static fromPassphrase(passphrase: string): string { - return path ? Keys.fromBip44Mnemonic(passphrase, path).privateKey : Keys.fromPassphrase(passphrase).privateKey; + return Keys.fromPassphrase(passphrase).privateKey; } public static fromBip44Mnemonic(passphrase: string, path: string): string { From 8fd218fe89ccf820bec6b568fc68d34f0a870438 Mon Sep 17 00:00:00 2001 From: Shahin Safaraliyev Date: Mon, 2 Feb 2026 16:18:18 +0400 Subject: [PATCH 27/39] feat: support address creation with BIP44 --- packages/ark/source/private-key.service.ts | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/packages/ark/source/private-key.service.ts b/packages/ark/source/private-key.service.ts index 0f7d821e..64c93ad5 100644 --- a/packages/ark/source/private-key.service.ts +++ b/packages/ark/source/private-key.service.ts @@ -18,12 +18,22 @@ export class PrivateKeyService extends Services.AbstractPrivateKeyService { public override async fromMnemonic( mnemonic: string, options?: Services.IdentityOptions, - path?: string, ): Promise { abort_unless(BIP39.compatible(mnemonic), "The given value is not BIP39 compliant."); return { - privateKey: BasePrivateKey.fromPassphrase(mnemonic, path), + privateKey: BasePrivateKey.fromPassphrase(mnemonic), + }; + } + + public override async fromBip44Mnemonic( + mnemonic: string, + path: string, + ): Promise { + abort_unless(BIP39.compatible(mnemonic), "The given value is not BIP39 compliant."); + + return { + privateKey: BasePrivateKey.fromBip44Mnemonic(mnemonic, path), }; } From e0435654ff98fc5a53edcecd3978f523b33218f7 Mon Sep 17 00:00:00 2001 From: Shahin Safaraliyev Date: Mon, 2 Feb 2026 16:20:14 +0400 Subject: [PATCH 28/39] feat: support address creation with BIP44 --- packages/ark/source/public-key.service.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/ark/source/public-key.service.ts b/packages/ark/source/public-key.service.ts index d7ef49b2..c5782f07 100644 --- a/packages/ark/source/public-key.service.ts +++ b/packages/ark/source/public-key.service.ts @@ -18,12 +18,11 @@ export class PublicKeyService extends Services.AbstractPublicKeyService { public override async fromMnemonic( mnemonic: string, options?: Services.IdentityOptions, - path?: string, ): Promise { abort_unless(BIP39.compatible(mnemonic), "The given value is not BIP39 compliant."); return { - publicKey: BasePublicKey.fromPassphrase(mnemonic, path), + publicKey: BasePublicKey.fromPassphrase(mnemonic), }; } From 816c67f94140c2aae92b102dd47239536d7f16ac Mon Sep 17 00:00:00 2001 From: Shahin Safaraliyev Date: Mon, 2 Feb 2026 16:25:05 +0400 Subject: [PATCH 29/39] feat: support address creation with BIP44 --- packages/profiles/source/wallet.factory.ts | 2 +- packages/sdk/source/address.contract.ts | 2 +- packages/sdk/source/private-key.contract.ts | 2 +- packages/sdk/source/public-key.contract.ts | 2 +- packages/sdk/source/signatory.contract.ts | 2 ++ packages/sdk/source/signatory.service.ts | 12 ++++++++++++ 6 files changed, 18 insertions(+), 4 deletions(-) diff --git a/packages/profiles/source/wallet.factory.ts b/packages/profiles/source/wallet.factory.ts index 7d7c18cc..3fe106d7 100644 --- a/packages/profiles/source/wallet.factory.ts +++ b/packages/profiles/source/wallet.factory.ts @@ -91,7 +91,7 @@ export class WalletFactory implements IWalletFactory { wallet.data().set(WalletData.AddressIndex, addressIndex); wallet.data().set(WalletData.DerivationPath, path); - const address = (await wallet.coin().address().fromMnemonic(options.mnemonic, undefined, path)).address; + const address = (await wallet.coin().address().fromBip44Mnemonic(options.mnemonic, path)).address; await wallet.mutator().address({ address }); diff --git a/packages/sdk/source/address.contract.ts b/packages/sdk/source/address.contract.ts index d5d0f95e..1561e426 100644 --- a/packages/sdk/source/address.contract.ts +++ b/packages/sdk/source/address.contract.ts @@ -8,7 +8,7 @@ export interface AddressDataTransferObject { export interface AddressService { fromMnemonic(mnemonic: string, options?: IdentityOptions): Promise; - fromBip44Mnemonic(mnemonic: string, path?: string): Promise; + fromBip44Mnemonic(mnemonic: string, path: string): Promise; fromMultiSignature( input: MultisignatureAddressInput, options?: IdentityOptions, diff --git a/packages/sdk/source/private-key.contract.ts b/packages/sdk/source/private-key.contract.ts index a769251a..ca3f5756 100644 --- a/packages/sdk/source/private-key.contract.ts +++ b/packages/sdk/source/private-key.contract.ts @@ -7,7 +7,7 @@ export interface PrivateKeyDataTransferObject { export interface PrivateKeyService { fromMnemonic(mnemonic: string, options?: IdentityOptions): Promise; - fromBip44Mnemonic(mnemonic: string, path?: string): Promise; + fromBip44Mnemonic(mnemonic: string, path: string): Promise; fromWIF(wif: string): Promise; fromSecret(secret: string): Promise; } diff --git a/packages/sdk/source/public-key.contract.ts b/packages/sdk/source/public-key.contract.ts index 85c6fb1d..c97f0e2e 100644 --- a/packages/sdk/source/public-key.contract.ts +++ b/packages/sdk/source/public-key.contract.ts @@ -6,7 +6,7 @@ export interface PublicKeyDataTransferObject { } export interface PublicKeyService { - fromMnemonic(mnemonic: string, options?: IdentityOptions, path?: string): Promise; + fromMnemonic(mnemonic: string, options?: IdentityOptions): Promise; fromBip44Mnemonic(mnemonic: string, path: string): Promise; fromMultiSignature(min: number, publicKeys: string[]): Promise; fromWIF(wif: string): Promise; diff --git a/packages/sdk/source/signatory.contract.ts b/packages/sdk/source/signatory.contract.ts index 18835290..220ad6d7 100644 --- a/packages/sdk/source/signatory.contract.ts +++ b/packages/sdk/source/signatory.contract.ts @@ -5,6 +5,8 @@ import { Signatory } from "./signatories.js"; export interface SignatoryService { mnemonic(mnemonic: string, options?: IdentityOptions, path?: string): Promise; + bip44mnemonic(mnemonic: string, path?: string): Promise; + confirmationMnemonic(mnemonic: string, confirmation: string, options?: IdentityOptions): Promise; wif(mnemonic: string): Promise; diff --git a/packages/sdk/source/signatory.service.ts b/packages/sdk/source/signatory.service.ts index 4ec57c8d..b9b6a156 100644 --- a/packages/sdk/source/signatory.service.ts +++ b/packages/sdk/source/signatory.service.ts @@ -46,6 +46,18 @@ export class AbstractSignatoryService implements SignatoryService { ); } + public async bip44Mnemonic(mnemonic: string, path: string): Promise { + return new Signatory( + new MnemonicSignatory({ + address: (await this.#addressService.fromBip44Mnemonic(mnemonic, path)).address, + privateKey: (await this.#privateKeyService.fromBip44Mnemonic(mnemonic, path)).privateKey, + publicKey: (await this.#publicKeyService.fromBip44Mnemonic(mnemonic, path)).publicKey, + signingKey: mnemonic, + path, + }), + ); + } + public async confirmationMnemonic( signingKey: string, confirmKey: string, From 83407278ae8497602a78c988075305730cfcbba4 Mon Sep 17 00:00:00 2001 From: Shahin Safaraliyev Date: Mon, 2 Feb 2026 16:25:41 +0400 Subject: [PATCH 30/39] feat: support address creation with BIP44 --- packages/sdk/source/signatory.contract.ts | 2 +- packages/sdk/source/signatory.service.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/sdk/source/signatory.contract.ts b/packages/sdk/source/signatory.contract.ts index 220ad6d7..740adc40 100644 --- a/packages/sdk/source/signatory.contract.ts +++ b/packages/sdk/source/signatory.contract.ts @@ -3,7 +3,7 @@ import { IdentityOptions } from "./shared.contract.js"; import { Signatory } from "./signatories.js"; export interface SignatoryService { - mnemonic(mnemonic: string, options?: IdentityOptions, path?: string): Promise; + mnemonic(mnemonic: string, options?: IdentityOptions): Promise; bip44mnemonic(mnemonic: string, path?: string): Promise; diff --git a/packages/sdk/source/signatory.service.ts b/packages/sdk/source/signatory.service.ts index b9b6a156..197ac09d 100644 --- a/packages/sdk/source/signatory.service.ts +++ b/packages/sdk/source/signatory.service.ts @@ -32,7 +32,7 @@ export class AbstractSignatoryService implements SignatoryService { this.#publicKeyService = container.get(BindingType.PublicKeyService); } - public async mnemonic(mnemonic: string, options?: IdentityOptions, path?: string): Promise { + public async mnemonic(mnemonic: string, options?: IdentityOptions): Promise { return new Signatory( new MnemonicSignatory({ address: (await this.#addressService.fromMnemonic(mnemonic, options, path)).address, From 14fd269edb65a8a59d05e064fbb891585250a700 Mon Sep 17 00:00:00 2001 From: Shahin Safaraliyev Date: Mon, 2 Feb 2026 16:27:59 +0400 Subject: [PATCH 31/39] feat: support address creation with BIP44 --- packages/sdk/source/signatory.service.ts | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/packages/sdk/source/signatory.service.ts b/packages/sdk/source/signatory.service.ts index 197ac09d..f01349b4 100644 --- a/packages/sdk/source/signatory.service.ts +++ b/packages/sdk/source/signatory.service.ts @@ -35,12 +35,11 @@ export class AbstractSignatoryService implements SignatoryService { public async mnemonic(mnemonic: string, options?: IdentityOptions): Promise { return new Signatory( new MnemonicSignatory({ - address: (await this.#addressService.fromMnemonic(mnemonic, options, path)).address, + address: (await this.#addressService.fromMnemonic(mnemonic, options)).address, options, - privateKey: (await this.#privateKeyService.fromMnemonic(mnemonic, options, path)).privateKey, - publicKey: (await this.#publicKeyService.fromMnemonic(mnemonic, options, path)).publicKey, + privateKey: (await this.#privateKeyService.fromMnemonic(mnemonic, options)).privateKey, + publicKey: (await this.#publicKeyService.fromMnemonic(mnemonic, options)).publicKey, signingKey: mnemonic, - path, }), options?.multiSignature, ); From 8c646fca8af1e2baa265f8f78b3f711422d0a9cc Mon Sep 17 00:00:00 2001 From: Shahin Safaraliyev Date: Mon, 2 Feb 2026 16:29:48 +0400 Subject: [PATCH 32/39] feat: support address creation with BIP44 --- packages/profiles/source/signatory.factory.ts | 6 +++++- packages/sdk/source/signatory.contract.ts | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/profiles/source/signatory.factory.ts b/packages/profiles/source/signatory.factory.ts index 5e2012a0..e78b37b0 100644 --- a/packages/profiles/source/signatory.factory.ts +++ b/packages/profiles/source/signatory.factory.ts @@ -24,8 +24,12 @@ export class SignatoryFactory implements ISignatoryFactory { return this.#wallet.signatory().confirmationMnemonic(mnemonic, secondMnemonic); } + if (mnemonic && path) { + return this.#wallet.signatory().bip44Mnemonic(mnemonic, path); + } + if (mnemonic) { - return this.#wallet.signatory().mnemonic(mnemonic, undefined, path); + return this.#wallet.signatory().mnemonic(mnemonic); } if (encryptionPassword) { diff --git a/packages/sdk/source/signatory.contract.ts b/packages/sdk/source/signatory.contract.ts index 740adc40..4129b027 100644 --- a/packages/sdk/source/signatory.contract.ts +++ b/packages/sdk/source/signatory.contract.ts @@ -5,7 +5,7 @@ import { Signatory } from "./signatories.js"; export interface SignatoryService { mnemonic(mnemonic: string, options?: IdentityOptions): Promise; - bip44mnemonic(mnemonic: string, path?: string): Promise; + bip44mnemonic(mnemonic: string, path: string): Promise; confirmationMnemonic(mnemonic: string, confirmation: string, options?: IdentityOptions): Promise; From c796a1705c0587c8ab73f0dba2b1c997a75a2a30 Mon Sep 17 00:00:00 2001 From: Shahin Safaraliyev Date: Mon, 2 Feb 2026 16:32:45 +0400 Subject: [PATCH 33/39] feat: support address creation with BIP44 --- packages/profiles/source/signatory.factory.ts | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/packages/profiles/source/signatory.factory.ts b/packages/profiles/source/signatory.factory.ts index e78b37b0..d8321729 100644 --- a/packages/profiles/source/signatory.factory.ts +++ b/packages/profiles/source/signatory.factory.ts @@ -55,9 +55,13 @@ export class SignatoryFactory implements ISignatoryFactory { return this.#wallet.signatory().secret(await this.#wallet.signingKey().get(encryptionPassword)); } - return this.#wallet - .signatory() - .mnemonic(await this.#wallet.signingKey().get(encryptionPassword), undefined, path); + if (this.#wallet.actsWithBip44MnemonicWithEncryption()) { + return this.#wallet + .signatory() + .bip44Mnemonic(await this.#wallet.signingKey().get(encryptionPassword), path); + } + + return this.#wallet.signatory().mnemonic(await this.#wallet.signingKey().get(encryptionPassword)); } if (this.#wallet.isMultiSignature()) { From 455bc73165245bd9bab23f0269a15e8ab492efaa Mon Sep 17 00:00:00 2001 From: Shahin Safaraliyev Date: Mon, 2 Feb 2026 16:38:30 +0400 Subject: [PATCH 34/39] feat: support address creation with BIP44 --- .../source/crypto/transactions/builders/transaction.ts | 5 +++++ packages/ark/source/transaction.service.ts | 8 ++++++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/packages/ark/source/crypto/transactions/builders/transaction.ts b/packages/ark/source/crypto/transactions/builders/transaction.ts index 7b1bb87c..9d817267 100644 --- a/packages/ark/source/crypto/transactions/builders/transaction.ts +++ b/packages/ark/source/crypto/transactions/builders/transaction.ts @@ -102,6 +102,11 @@ export abstract class TransactionBuilder Date: Mon, 2 Feb 2026 16:39:08 +0400 Subject: [PATCH 35/39] feat: support address creation with BIP44 --- packages/ark/source/crypto/transactions/builders/transaction.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/ark/source/crypto/transactions/builders/transaction.ts b/packages/ark/source/crypto/transactions/builders/transaction.ts index 9d817267..5daa9abc 100644 --- a/packages/ark/source/crypto/transactions/builders/transaction.ts +++ b/packages/ark/source/crypto/transactions/builders/transaction.ts @@ -98,7 +98,7 @@ export abstract class TransactionBuilder Date: Mon, 2 Feb 2026 16:39:22 +0400 Subject: [PATCH 36/39] feat: support address creation with BIP44 --- packages/ark/source/crypto/transactions/builders/transaction.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/ark/source/crypto/transactions/builders/transaction.ts b/packages/ark/source/crypto/transactions/builders/transaction.ts index 5daa9abc..9c5d85e3 100644 --- a/packages/ark/source/crypto/transactions/builders/transaction.ts +++ b/packages/ark/source/crypto/transactions/builders/transaction.ts @@ -97,7 +97,7 @@ export abstract class TransactionBuilder Date: Mon, 2 Feb 2026 16:40:37 +0400 Subject: [PATCH 37/39] feat: support address creation with BIP44 --- packages/sdk/source/signatory.contract.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/sdk/source/signatory.contract.ts b/packages/sdk/source/signatory.contract.ts index 4129b027..6c381ff5 100644 --- a/packages/sdk/source/signatory.contract.ts +++ b/packages/sdk/source/signatory.contract.ts @@ -5,7 +5,7 @@ import { Signatory } from "./signatories.js"; export interface SignatoryService { mnemonic(mnemonic: string, options?: IdentityOptions): Promise; - bip44mnemonic(mnemonic: string, path: string): Promise; + bip44Mnemonic(mnemonic: string, path: string): Promise; confirmationMnemonic(mnemonic: string, confirmation: string, options?: IdentityOptions): Promise; From 0f4b11524d12d7a1590ccef6ee95fd9113d0e03f Mon Sep 17 00:00:00 2001 From: Shahin Safaraliyev Date: Mon, 2 Feb 2026 16:42:53 +0400 Subject: [PATCH 38/39] feat: support address creation with BIP44 --- packages/profiles/source/signatory.factory.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/profiles/source/signatory.factory.ts b/packages/profiles/source/signatory.factory.ts index d8321729..c36d7d5e 100644 --- a/packages/profiles/source/signatory.factory.ts +++ b/packages/profiles/source/signatory.factory.ts @@ -58,7 +58,7 @@ export class SignatoryFactory implements ISignatoryFactory { if (this.#wallet.actsWithBip44MnemonicWithEncryption()) { return this.#wallet .signatory() - .bip44Mnemonic(await this.#wallet.signingKey().get(encryptionPassword), path); + .bip44Mnemonic(await this.#wallet.signingKey().get(encryptionPassword), path as string); } return this.#wallet.signatory().mnemonic(await this.#wallet.signingKey().get(encryptionPassword)); From 55d91e9c746c94e3de8a1af7693ba6117cf3b4dc Mon Sep 17 00:00:00 2001 From: shahin-hq Date: Mon, 2 Feb 2026 12:44:59 +0000 Subject: [PATCH 39/39] style: resolve style guide violations --- packages/profiles/source/wallet-transaction.service.ts | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/packages/profiles/source/wallet-transaction.service.ts b/packages/profiles/source/wallet-transaction.service.ts index 332944b1..acc9c52f 100644 --- a/packages/profiles/source/wallet-transaction.service.ts +++ b/packages/profiles/source/wallet-transaction.service.ts @@ -441,7 +441,10 @@ export class TransactionService implements ITransactionService { } async #syncPendingMultiSignatures(): Promise { - const transactions = await this.#wallet.coin().multiSignature().allWithPendingState(this.#getPublicKey()); + const transactions = await this.#wallet + .coin() + .multiSignature() + .allWithPendingState(this.#getPublicKey()); this.#pending = {}; @@ -453,7 +456,10 @@ export class TransactionService implements ITransactionService { } async #syncReadyMultiSignatures(): Promise { - const transactions = await this.#wallet.coin().multiSignature().allWithReadyState(this.#getPublicKey()); + const transactions = await this.#wallet + .coin() + .multiSignature() + .allWithReadyState(this.#getPublicKey()); this.#signed = {};