Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions packages/extension/src/libs/keyring/public-keyring.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,20 @@ class PublicKeyRing {
isHardware: false,
isTestWallet: true,
};
allKeys[
'bc1qwgpekhhfekclmp58kyzmlsdzey948d4395nvs8'
] = {
address:
'bc1qwgpekhhfekclmp58kyzmlsdzey948d4395nvs8',
basePath: "m/49'/2'/0'/1",
name: 'fake btc account #1',
pathIndex: 0,
publicKey: '0x0',
signerType: SignerType.secp256k1btc,
walletType: WalletType.mnemonic,
isHardware: false,
isTestWallet: true,
};
Comment on lines +86 to +99
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Verify the test account's basePath matches the intended test scenario.

The basePath "m/49'/2'/0'/1" appears inconsistent with the account details:

  • BIP49 (m/49') is typically for P2SH-wrapped SegWit addresses (starting with 3), not native SegWit
  • Coin type 2' per SLIP-44 is Litecoin testnet, not Bitcoin
  • The bc1q address prefix indicates Bitcoin native SegWit, which typically uses BIP84 (m/84') with coin type 0'

Since this is test data, please confirm this path matches your intended test scenario for Bitcoin accounts.

allKeys['77hREDDaAiimedtD9bR1JDMgYLW3AA5yPvD91pvrueRp'] = {
address: '77hREDDaAiimedtD9bR1JDMgYLW3AA5yPvD91pvrueRp',
basePath: "m/44'/501'/0'/1",
Expand Down
81 changes: 81 additions & 0 deletions packages/hw-wallets/README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,84 @@
# @enkryptcom/hw-wallets

## v0.0.12

## Hardware wallet manager for enkrypt

### Getting started

#### Minimum Node version

`node v20`

#### Installation

NPM: `npm install @enkryptcom/hw-wallets @enkryptcom/types`
Yarn: `yarn add @enkryptcom/hw-wallets @enkryptcom/types`
PNPM `pnpm add @enkryptcom/hw-wallets @enkryptcom/types`

### How to use

1. Create an instance of `HWwalletManager`

```
import HWwalletManager from @enkryptcom/hw-wallets

const hwManager = new HWwalletManager()
```

2. Call methods within class, passing network names and providers. Class automatically handles which wallet to use.

### API

#### `getAddress(options: getAddressRequest): Promise<AddressResponse>`

Returns wallet address based off of the path provided in the `getAddressRequest`.

#### `signPersonalMessage(options: SignMessageRequest): Promise<string>`

Signs personal message.

#### `signTransaction(options: SignTransactionRequest): Promise<string>`

Returns an RPC sign you can then add to a transaction object.

#### `getSupportedPaths(options: isConnectedRequest): Promise<PathType[]>`

Returns supported paths based on options provided.

#### `isNetworkSupported(networkName: NetworkNames): boolean`

Checks network name support.

#### `isConnected(options: isConnectedRequest): Promise<boolean>`

Checks connection status.

#### `close(): Promise<void>`

Closes all HW wallet connections

### Types

`NetworkNames`: https://github.com/enkryptcom/enKrypt/blob/main/packages/types/src/networks.ts#L1
`getAddressRequest`: https://github.com/enkryptcom/enKrypt/blob/main/packages/hw-wallets/src/types.ts#L74
`AddressResponse`: https://github.com/enkryptcom/enKrypt/blob/main/packages/hw-wallets/src/types.ts#L31
`SignMessageRequest`: https://github.com/enkryptcom/enKrypt/blob/main/packages/hw-wallets/src/types.ts#L54
`SignTransactionRequest`: https://github.com/enkryptcom/enKrypt/blob/main/packages/hw-wallets/src/types.ts#L65
`isConnectedRequest`: https://github.com/enkryptcom/enKrypt/blob/main/packages/hw-wallets/src/types.ts#L78

### Adding more paths

Navigate to `src/configs.ts` and add your new derivation path at the bottom.
Make sure to follow the configuration in that file.
Import path in the corresponding `Trezor` provider `config.ts`.
See `src/trezor/ethereum/configs.ts` for example.

### Notes

Connection request to hardware wallet actually happens on `getAddress()` request.
`Ledger` can't have any paths as each paths are defined by the corresponding app.

#### For Vue devs

`ref/reactive` will mess with how Vue compiles these classes because of how Vue utilizes proxies. If you want to store an instance into a ref or reactive, use [`makeRaw`](https://vuejs.org/api/reactivity-advanced#markraw).
12 changes: 10 additions & 2 deletions packages/hw-wallets/package.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,17 @@
{
"name": "@enkryptcom/hw-wallets",
"version": "0.0.13",
"version": "0.0.14",
"description": "Hardware wallet manager for enkrypt",
"type": "module",
"main": "src/index.ts",
"module": "src/index.ts",
"exports": {
".": {
"types": "./dist/index.d.ts",
"import": "./dist/index.js",
"require": "./dist/index.cjs"
}
},
"publishConfig": {
"main": "dist/index.cjs",
"module": "dist/index.js",
Expand All @@ -19,7 +26,7 @@
"test": "vitest run"
},
"engines": {
"node": ">=14.15.0"
"node": ">=20"
},
Comment on lines 28 to 30
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify Node 20 compatibility and transport package versions

echo "=== Checking package.json for transport dependencies ==="
cat packages/hw-wallets/package.json | grep -A 20 '"dependencies"'

echo -e "\n=== Checking for Node version config files ==="
cd packages/hw-wallets
for file in .nvmrc .node-version; do
  if [ -f "$file" ]; then
    echo "Found $file:"; cat "$file"
  fi
done

cd ../..
echo -e "\n=== Checking root .nvmrc or node version config ==="
for file in .nvmrc .node-version; do
  if [ -f "$file" ]; then
    echo "Found $file:"; cat "$file"
  fi
done

echo -e "\n=== Checking for CHANGELOG or migration docs ==="
fd -i changelog -i migration -i "release.*notes" packages/hw-wallets/ || echo "No changelog found in hw-wallets"

echo -e "\n=== Checking if Node version requirement is documented in README ==="
if [ -f "packages/hw-wallets/README.md" ]; then
  echo "Checking README.md:"; grep -i "node" packages/hw-wallets/README.md || echo "No Node version mentioned"
fi

echo -e "\n=== Checking git for any Node version changes ==="
git log --oneline --all -S ">=20" -- "packages/hw-wallets/package.json" 2>/dev/null | head -5 || echo "Git history not available"

echo -e "\n=== Checking for any CI/CD config mentioning Node version ==="
fd "\.github|\.gitlab|\.circleci|\.travis" -t d || echo "No CI configs found"

Repository: enkryptcom/enKrypt

Length of output: 1532


🏁 Script executed:

#!/bin/bash
# Check if hw-wallets .nvmrc is the issue and confirm package version compatibility

echo "=== Checking Node versions represented by .nvmrc files ==="
echo "lts/fermium = Node 14 (EOL)"
echo "v22.18.0 = Node 22 LTS"

echo -e "\n=== Verifying hw-wallets/.nvmrc content ==="
cat packages/hw-wallets/.nvmrc

echo -e "\n=== Checking @ledgerhq peer dependencies in lock file ==="
if [ -f "pnpm-lock.yaml" ]; then
  echo "Checking pnpm-lock.yaml for @ledgerhq transport conflicts..."
  rg -A 3 "@ledgerhq/hw-transport" pnpm-lock.yaml | head -40
elif [ -f "package-lock.json" ]; then
  echo "Checking package-lock.json..."
  grep -A 5 "@ledgerhq/hw-transport" package-lock.json | head -30
fi

echo -e "\n=== Checking if transport package versions have peer dependency constraints ==="
# Search for package metadata that might indicate version conflicts
rg "peerDependencies|engines" packages/hw-wallets/package.json

Repository: enkryptcom/enKrypt

Length of output: 382


Update hw-wallets/.nvmrc to align with Node >=20 requirement.

The package.json correctly specifies engines.node: ">=20" and this is documented in the README. However, packages/hw-wallets/.nvmrc contains lts/fermium (Node 14), which creates a developer experience issue—tools like nvm will override to Node 14 despite the package requiring Node >=20. Update this file to v20 or higher to match the enforced constraint.

🤖 Prompt for AI Agents
In packages/hw-wallets/.nvmrc (related to package.json lines 28-30) the .nvmrc
currently pins lts/fermium (Node 14) which conflicts with package.json's
engines.node ">=20"; update packages/hw-wallets/.nvmrc to "v20" (or a newer vX
where X>=20) so tools like nvm will use Node 20+, ensuring it matches the
enforced constraint and README.

"devDependencies": {
"@types/node": "^24.10.1",
Expand Down Expand Up @@ -56,6 +63,7 @@
"@ledgerhq/hw-app-eth": "^6.47.0",
"@ledgerhq/hw-app-solana": "^7.6.0",
"@ledgerhq/hw-transport": "^6.31.13",
"@ledgerhq/hw-transport-web-ble": "^6.29.13",
"@ledgerhq/hw-transport-webusb": "^6.29.13",
"@ledgerhq/live-common": "^34.20.0",
"@metamask/eth-sig-util": "^8.2.0",
Expand Down
152 changes: 152 additions & 0 deletions packages/hw-wallets/src/configs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ const ledgerAppNames = {
[NetworkNames.Karura]: "Karura",
[NetworkNames.Edgeware]: "Edgeware",
[NetworkNames.Bitcoin]: "Bitcoin",
[NetworkNames.BitcoinTest]: "Bitcoin Test",
[NetworkNames.Litecoin]: "Litecoin",
[NetworkNames.Dogecoin]: "Dogecoin",
[NetworkNames.Solana]: "Solana",
Expand Down Expand Up @@ -61,6 +62,11 @@ const bip44Paths = {
basePath: "m/44'/137'/0'/0",
label: "Rootstock",
},
rootstockTestnet: {
path: "m/44'/37310'/0'/0/{index}",
basePath: "m/44'/37310'/0'/0",
label: 'Rootstock Testnet'
},
ethereumClassic: {
path: "m/44'/61'/0'/0/{index}",
basePath: "m/44'/61'/0'/0",
Expand All @@ -81,6 +87,11 @@ const bip44Paths = {
basePath: "m/84'/0'",
label: "Bitcoin",
},
bitcoinTestSegwitLedger: {
path: "m/84'/1'/{index}'/0/0",
basePath: "m/84'/1'",
label: "Bitcoin Test",
},
litecoinSegwitLedger: {
path: "m/84'/2'/{index}'/0/0",
basePath: "m/84'/2'",
Expand All @@ -106,6 +117,11 @@ const bip44Paths = {
basePath: "m/84'/0'/0'/0",
label: "Bitcoin",
},
bitcoinTestSegwitTrezor: {
path: "m/84'/1'/0'/0/{index}",
basePath: "m/84'/1'/0'/0",
label: "Bitcoin Test",
},
litecoinSegwitTrezor: {
path: "m/84'/2'/0'/0/{index}",
basePath: "m/84'/2'/0'/0",
Expand All @@ -116,5 +132,141 @@ const bip44Paths = {
basePath: "m/44'/3'/0'/0",
label: "Dogecoin",
},
// Additional paths from MyEtherWallet
poaNetwork: {
path: "m/44'/60'/0'/0/{index}",
basePath: "m/44'/60'/0'/0",
label: 'POA network'
},
expanse: {
path: "m/44'/40'/0'/0/{index}",
basePath: "m/44'/40'/0'/0",
label: 'Expanse'
},
ubiq: {
path: "m/44'/108'/0'/0/{index}",
basePath: "m/44'/108'/0'/0",
label: 'Ubiq'
},
ellaism: {
path: "m/44'/163'/0'/0/{index}",
basePath: "m/44'/163'/0'/0",
label: 'Ellaism'
},
etherGem: {
path: "m/44'/1987'/0'/0/{index}",
basePath: "m/44'/1987'/0'/0",
label: 'EtherGem'
},
callisto: {
path: "m/44'/820'/0'/0/{index}",
basePath: "m/44'/820'/0'/0",
label: 'Callisto'
},
ethereumSocial: {
path: "m/44'/1128'/0'/0/{index}",
basePath: "m/44'/1128'/0'/0",
label: 'Ethereum Social'
},
musicoin: {
path: "m/44'/184'/0'/0/{index}",
basePath: "m/44'/184'/0'/0",
label: 'Musicoin'
},
goChain: {
path: "m/44'/6060'/0'/0/{index}",
basePath: "m/44'/6060'/0'/0",
label: 'GoChain'
},
eosClassic: {
path: "m/44'/2018'/0'/0/{index}",
basePath: "m/44'/2018'/0'/0",
label: 'EOS Classic'
},
akroma: {
path: "m/44'/200625'/0'/0/{index}",
basePath: "m/44'/200625'/0'/0",
label: 'Akroma'
},
etherSocialNetwork: {
path: "m/44'/31102'/0'/0/{index}",
basePath: "m/44'/31102'/0'/0",
label: 'EtherSocial Network'
},
pirl: {
path: "m/44'/164'/0'/0/{index}",
basePath: "m/44'/164'/0'/0",
label: 'PIRL'
},
ether1: {
path: "m/44'/1313114'/0'/0/{index}",
basePath: "m/44'/1313114'/0'/0",
label: 'Ether-1'
},
atheios: {
path: "m/44'/1620'/0'/0/{index}",
basePath: "m/44'/1620'/0'/0",
label: 'Atheios'
},
tomoChain: {
path: "m/44'/889'/0'/0/{index}",
basePath: "m/44'/889'/0'/0",
label: 'TomoChain'
},
mixBlockchain: {
path: "m/44'/76'/0'/0/{index}",
basePath: "m/44'/76'/0'/0",
label: 'Mix Blockchain'
},
iolite: {
path: "m/44'/1171337'/0'/0/{index}",
basePath: "m/44'/1171337'/0'/0",
label: 'Iolite'
},
thundercore: {
path: "m/44'/1001'/0'/0/{index}",
basePath: "m/44'/1001'/0'/0",
label: 'ThunderCore'
},
solidum: {
path: "m/44'/997'/0'/0/{index}",
basePath: "m/44'/997'/0'/0",
label: 'Solidum'
},
metadium: {
path: "m/44'/916'/0'/0/{index}",
basePath: "m/44'/916'/0'/0",
label: 'Metadium'
},
reoscChain: {
path: "m/44'/2894'/0'/0/{index}",
basePath: "m/44'/2894'/0'/0",
label: 'REOSC'
},
dexon: {
path: "m/44'/237'/0'/0/{index}",
basePath: "m/44'/237'/0'/0",
label: 'DEXON Network'
},
lightstreamsNetwork: {
path: "m/44'/60'/0'/{index}",
basePath: "m/44'/60'/0'",
label: 'Lightstreams Network'
},
mintmeComCoin: {
path: "m/44'/227'/0'/0/{index}",
basePath: "m/44'/227'/0'/0",
label: 'MintMe.com Coin'
},
ethercore: {
path: "m/44'/466'/0'/0/{index}",
basePath: "m/44'/466'/0'/0",
label: 'EtherCore'
},
binanceChain: {
path: "m/44'/714'/{index}",
basePath: "m/44'/714'",
label: 'Binance Chain'
},
};
export { walletConfigs, MessengerName, ledgerAppNames, bip44Paths };
12 changes: 11 additions & 1 deletion packages/hw-wallets/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ class HWwalletManager {
LedgerEthereum,
LedgerSubstrate,
LedgerBitcoin,
LedgerSolana,
LedgerSolana
],
[HWwalletType.trezor]: [TrezorEthereum, TrezorBitcoin, TrezorSolana],
};
Expand Down Expand Up @@ -122,3 +122,13 @@ class HWwalletManager {
export default HWwalletManager;

export { ledgerAppNames };

export type {
AddressResponse,
getAddressRequest,
HWWalletProvider,
isConnectedRequest,
PathType,
SignMessageRequest,
SignTransactionRequest,
}
1 change: 1 addition & 0 deletions packages/hw-wallets/src/ledger/bitcoin/configs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { bip44Paths } from "../../configs";

const supportedPaths = {
[NetworkNames.Bitcoin]: [bip44Paths.bitcoinSegwitLedger],
[NetworkNames.BitcoinTest]: [bip44Paths.bitcoinTestSegwitLedger],
[NetworkNames.Litecoin]: [bip44Paths.litecoinSegwitLedger],
[NetworkNames.Dogecoin]: [bip44Paths.dogecoinLedger],
};
Expand Down
Loading