@exodus/hw-ledger 4.0.0 → 4.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -3,6 +3,35 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ ## [4.0.2](https://github.com/ExodusMovement/exodus/compare/@exodus/hw-ledger@4.0.1...@exodus/hw-ledger@4.0.2) (2026-09-28)
7
+
8
+ ### Bug Fixes
9
+
10
+ - fix(hw-ledger): surface blind-signing requirement for unknown Tron TRC-20 tokens (#42652)
11
+
12
+ ## [4.0.1](https://github.com/ExodusMovement/exodus-hydra/compare/@exodus/hw-ledger@4.0.0...@exodus/hw-ledger@4.0.1) (2026-06-29)
13
+
14
+ ### ⚠ BREAKING CHANGES
15
+
16
+ - **eslint-config-exodus:** @exodus/eslint-config-exodus no longer enforces
17
+ no-floating-promises or no-unnecessary-condition and no longer sets
18
+ parserOptions.project. Consumers relying on these without oxlint
19
+ --type-aware lose the coverage; adopt oxlint type-aware.
20
+
21
+ Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
22
+
23
+ - chore: drop redundant local no-floating-promises disable
24
+
25
+ @exodus/eslint-config-exodus no longer enables no-floating-promises, so
26
+
27
+ ### Features
28
+
29
+ - **eslint-config-exodus:** retire type-aware eslint rules, drop parserOptions.project ([#17273](https://github.com/ExodusMovement/exodus-hydra/issues/17273)) ([622ec93](https://github.com/ExodusMovement/exodus-hydra/commit/622ec935f14f0b7d54ee6f2b034995606383397c)), closes [#7693](https://github.com/ExodusMovement/exodus-hydra/issues/7693) [#17253](https://github.com/ExodusMovement/exodus-hydra/issues/17253)
30
+
31
+ ### Bug Fixes
32
+
33
+ - **hw-ledger:** bump ledgerhq deps + re-enable skipped test suites ([#17394](https://github.com/ExodusMovement/exodus-hydra/issues/17394)) ([2d9f631](https://github.com/ExodusMovement/exodus-hydra/commit/2d9f631af8451a2cac4a8aca9e843f86a5cda87d))
34
+
6
35
  ## [4.0.0](https://github.com/ExodusMovement/exodus-hydra/compare/@exodus/hw-ledger@3.9.2...@exodus/hw-ledger@4.0.0) (2026-06-09)
7
36
 
8
37
  ### ⚠ BREAKING CHANGES
package/README.md CHANGED
@@ -5,7 +5,7 @@ This Exodus SDK feature handles all hardware wallet actions that are specific to
5
5
  ## Install
6
6
 
7
7
  ```sh
8
- yarn add @exodus/hw-ledger
8
+ pnpm add @exodus/hw-ledger
9
9
  ```
10
10
 
11
11
  ## Usage
@@ -4,6 +4,6 @@ declare const metadata: {
4
4
  supportedVersions: string;
5
5
  primaryAssetName: string;
6
6
  }[];
7
- handler: (transport: import("../types.js").Transport) => Promise<import("@exodus/hw-common").HardwareWalletAssetHandler>;
7
+ handler: (transport: import("../types.js").Transport) => Promise<import("@exodus/hw-common").HardwareWalletAssetHandler<import("./ethereum.js").EthereumMessage>>;
8
8
  };
9
9
  export default metadata;
@@ -1,6 +1,11 @@
1
- import type { HardwareWalletAssetHandler } from '@exodus/hw-common';
1
+ import type { Bytes, HardwareWalletAssetHandler } from '@exodus/hw-common';
2
+ import type { EIP712Message } from '@exodus/ledgerhq-hw-app-eth/lib/modules/EIP712/EIP712.types.js';
2
3
  import type { Transport } from '../types.js';
3
- declare function createHandler(transport: Transport): Promise<HardwareWalletAssetHandler>;
4
+ export interface EthereumMessage {
5
+ rawMessage?: Bytes;
6
+ EIP712Message?: EIP712Message;
7
+ }
8
+ declare function createHandler(transport: Transport): Promise<HardwareWalletAssetHandler<EthereumMessage>>;
4
9
  declare const metadata: {
5
10
  applications: {
6
11
  applicationName: string;
@@ -1,5 +1,5 @@
1
1
  import * as secp256k1 from '@exodus/crypto/secp256k1';
2
- import * as ethers from '@exodus/ethersproject-transactions';
2
+ import * as ethers from '@exodus/ethereumjs/ethers5-transactions';
3
3
  import AppEthImport, { ledgerService } from '@exodus/ledgerhq-hw-app-eth';
4
4
  import { TypedDataUtils, SignTypedDataVersion } from '@exodus/ethereumjs/eth-sig-util';
5
5
  import assert from 'minimalistic-assert';
@@ -94,7 +94,7 @@ async function createHandler(transport) {
94
94
  });
95
95
  }
96
96
  catch (err) {
97
- if (err.name === 'EthAppNftNotSupported') {
97
+ if (err instanceof Error && err.name === 'EthAppNftNotSupported') {
98
98
  response = await signTransaction({
99
99
  derivationPath: params.derivationPaths[0],
100
100
  serializedTransactionHex,
@@ -102,7 +102,7 @@ async function createHandler(transport) {
102
102
  nft: false,
103
103
  });
104
104
  }
105
- else if (err.name === 'EthAppPleaseEnableContractData') {
105
+ else if (err instanceof Error && err.name === 'EthAppPleaseEnableContractData') {
106
106
  throw new RequiresBlindSigningError();
107
107
  }
108
108
  else {
@@ -121,19 +121,20 @@ async function createHandler(transport) {
121
121
  ];
122
122
  },
123
123
  signMessage: async (params) => {
124
- const message = params.message;
124
+ const { message } = params;
125
125
  let signingPromise;
126
126
  if (message.rawMessage) {
127
127
  assert(Buffer.isBuffer(params.message.rawMessage), 'rawMessage must be a buffer');
128
128
  signingPromise = app.signPersonalMessage(params.derivationPath, Buffer.from(message.rawMessage).toString('hex'));
129
129
  }
130
130
  else if (message.EIP712Message) {
131
- assert(isEIP712Message(message.EIP712Message), 'EIP712Message must be EIP712 conformant message');
131
+ const eip712Message = message.EIP712Message;
132
+ assert(isEIP712Message(eip712Message), 'EIP712Message must be EIP712 conformant message');
132
133
  signingPromise = app
133
- .signEIP712Message(params.derivationPath, message.EIP712Message)
134
+ .signEIP712Message(params.derivationPath, eip712Message)
134
135
  .catch((err) => {
135
136
  if (err.message.includes('INS_NOT_SUPPORTED')) {
136
- const { domainSeparator, hashStructMessage } = hashEIP712Message(message.EIP712Message);
137
+ const { domainSeparator, hashStructMessage } = hashEIP712Message(eip712Message);
137
138
  return app.signEIP712HashedMessage(params.derivationPath, domainSeparator.toString('hex'), hashStructMessage.toString('hex'));
138
139
  }
139
140
  throw err;
@@ -24,7 +24,8 @@ export const applicationNameToBaseAssetNames = Object.entries(assetApplications)
24
24
  if (!Array.isArray(mapping[applicationName])) {
25
25
  mapping[applicationName] = [];
26
26
  }
27
- const isPrimaryAssetForApplication = applications[applicationName]?.primaryAssetName === assetName;
27
+ const isPrimaryAssetForApplication = Object.values(applications).some((application) => application.applicationName === applicationName &&
28
+ application.primaryAssetName === assetName);
28
29
  if (isPrimaryAssetForApplication) {
29
30
  mapping[applicationName].unshift(assetName);
30
31
  }
@@ -4,6 +4,6 @@ declare const metadata: {
4
4
  supportedVersions: string;
5
5
  primaryAssetName: string;
6
6
  }[];
7
- handler: (transport: import("../types.js").Transport) => Promise<import("@exodus/hw-common").HardwareWalletAssetHandler>;
7
+ handler: (transport: import("../types.js").Transport) => Promise<import("@exodus/hw-common").HardwareWalletAssetHandler<import("./ethereum.js").EthereumMessage>>;
8
8
  };
9
9
  export default metadata;
@@ -28,7 +28,7 @@ async function createHandler(transport) {
28
28
  else if (params.signableTransaction instanceof Uint8Array) {
29
29
  serializedTransaction = Buffer.from(params.signableTransaction);
30
30
  }
31
- else if (params.signableTransaction.serialize) {
31
+ else if ('serialize' in params.signableTransaction) {
32
32
  serializedTransaction = Buffer.from(params.signableTransaction.serialize());
33
33
  }
34
34
  if (!Buffer.isBuffer(serializedTransaction)) {
@@ -3,8 +3,9 @@ import assert from 'minimalistic-assert';
3
3
  import { XPubUnsupportedError } from '@exodus/hw-common';
4
4
  import * as secp256k1 from '@exodus/crypto/secp256k1';
5
5
  import applications from './applications.js';
6
- const AppTron = (AppTronImport.default ??
7
- AppTronImport);
6
+ import { RequiresBlindSigningError } from '../errors.js';
7
+ const E_MISSING_SETTING_CUSTOM_CONTRACT = 0x6a_8d;
8
+ const AppTron = (AppTronImport.default ?? AppTronImport);
8
9
  async function createHandler(transport) {
9
10
  const app = new AppTron(transport);
10
11
  const getAddress = async (params) => {
@@ -27,7 +28,15 @@ async function createHandler(transport) {
27
28
  if (!Buffer.isBuffer(params.signableTransaction)) {
28
29
  throw new TypeError(`signableTransaction must be Buffer or serializable to a Buffer.`);
29
30
  }
30
- const signature = await app.signTransaction(params.derivationPaths[0].replace('m/', ''), params.signableTransaction.toString('hex'), []);
31
+ const signature = await app
32
+ .signTransaction(params.derivationPaths[0].replace('m/', ''), params.signableTransaction.toString('hex'), [])
33
+ .catch((error) => {
34
+ if (error?.statusCode ===
35
+ E_MISSING_SETTING_CUSTOM_CONTRACT) {
36
+ throw new RequiresBlindSigningError();
37
+ }
38
+ throw error;
39
+ });
31
40
  return [
32
41
  {
33
42
  signature: Buffer.from(signature, 'hex'),
@@ -1,9 +1,9 @@
1
- import type { PsbtV2 } from '@exodus/ledger-bitcoin';
1
+ import type { AppClient, PsbtV2 } from '@exodus/ledger-bitcoin';
2
2
  import { WalletPolicy } from '@exodus/ledger-bitcoin';
3
3
  import type { MultisigData } from '@exodus/hw-common';
4
4
  export declare function assertPsbtOnlyHasAllowedDerivationPaths(psbt: PsbtV2, masterFingerprint: string, derivationPaths: string[]): void;
5
5
  export declare function tagPsbtWithDerivationPaths(psbt: PsbtV2, masterFingerprint: string, derivationPathToPublicKeyMap: Record<string, Buffer>, addressToDerivationPathMap?: Record<string, string>): string[];
6
- export declare const getWalletPolicy: (fpr: string, xpub: string, purpose: string, coin: string, account: string) => any;
6
+ export declare const getWalletPolicy: (fpr: string, xpub: string, purpose: string, coin: string, account: string) => WalletPolicy;
7
7
  export declare const getMultisigWalletPolicy: (fpr: string, xpub: string, purpose: string, coin: string, account: string, multisigData: MultisigData) => WalletPolicy;
8
- export declare function derivationPathsToWalletPolicy(fpr: string, app: any, derivationPaths: string[], multisigData?: MultisigData): Promise<WalletPolicy[]>;
8
+ export declare function derivationPathsToWalletPolicy(fpr: string, app: AppClient, derivationPaths: string[], multisigData?: MultisigData): Promise<WalletPolicy[]>;
9
9
  export declare function addDummyInputs(psbt: PsbtV2): void;
@@ -1,6 +1,7 @@
1
1
  import type LedgerTransport from '@ledgerhq/hw-transport';
2
2
  import type { TransportTypes } from '@exodus/hw-common';
3
3
  import type { Subscription } from '@ledgerhq/hw-transport';
4
+ import type { BluetoothStatus } from '../atoms/index.js';
4
5
  export type TransportFactory = (typeof LedgerTransport)['default'];
5
6
  export type Transport = InstanceType<TransportFactory>;
6
7
  export type TransportFactories = Partial<Record<TransportTypes, TransportFactory>> & {
@@ -10,9 +11,7 @@ export type TransportFactories = Partial<Record<TransportTypes, TransportFactory
10
11
  error: (err: Error) => void;
11
12
  }) => Subscription;
12
13
  observeState?: (observer: {
13
- next: (evt: {
14
- available: boolean;
15
- }) => void;
14
+ next: (evt: BluetoothStatus) => void;
16
15
  error: (err: Error) => void;
17
16
  }) => Subscription;
18
17
  };
@@ -1,5 +1,5 @@
1
1
  import id from './id.js';
2
- import initialState from './initial-state.js';
2
+ import initialState, {} from './initial-state.js';
3
3
  import selectorDefinitions from './selectors/index.js';
4
4
  const exchangeReduxDefinition = {
5
5
  id,
package/package.json CHANGED
@@ -1,16 +1,16 @@
1
1
  {
2
2
  "name": "@exodus/hw-ledger",
3
- "version": "4.0.0",
3
+ "version": "4.0.2",
4
4
  "description": "The ledger module",
5
5
  "author": "Exodus Movement, Inc.",
6
6
  "repository": {
7
7
  "type": "git",
8
- "url": "git+https://github.com/ExodusMovement/exodus-hydra.git"
8
+ "url": "git+https://github.com/ExodusMovement/exodus.git"
9
9
  },
10
- "homepage": "https://github.com/ExodusMovement/exodus-hydra/tree/master/features/hw-ledger",
10
+ "homepage": "https://github.com/ExodusMovement/exodus/tree/master/libs/features/hw-ledger",
11
11
  "license": "MIT",
12
12
  "bugs": {
13
- "url": "https://github.com/ExodusMovement/exodus-hydra/issues?q=is%3Aissue+is%3Aopen+label%3Ahw-ledger"
13
+ "url": "https://github.com/ExodusMovement/exodus/issues?q=is%3Aissue+is%3Aopen+label%3Ahw-ledger"
14
14
  },
15
15
  "main": "lib/index.js",
16
16
  "type": "module",
@@ -32,32 +32,31 @@
32
32
  "./CHANGELOG.md"
33
33
  ],
34
34
  "scripts": {
35
- "build": "run -T tsc -p tsconfig.build.json",
36
- "build:watch": "run -T tsc -w -p tsconfig.build.json",
37
- "clean": "run -T tsc --build --clean",
38
- "test": "run -T exodus-test --jest --esbuild",
39
- "typecheck": "run -T tsc -p tsconfig.json --noEmit",
35
+ "build": "pnpm exec tsc -p tsconfig.build.json",
36
+ "build:watch": "pnpm exec tsc -w -p tsconfig.build.json",
37
+ "clean": "pnpm exec tsc --build --clean",
38
+ "test": "pnpm exec exodus-test --jest --esbuild",
39
+ "typecheck": "pnpm exec tsc -p tsconfig.json --noEmit",
40
40
  "zemu:install": "docker pull zondax/builder-zemu:speculos-ef9610662dc90a1eeddba7c991e3ef7c53c4e258",
41
- "test:integration": "yarn zemu:install && RUN_TESTS=integration run test",
42
- "lint": "run -T eslint .",
43
- "lint:fix": "yarn lint --fix",
44
- "prepublishOnly": "yarn run -T build --scope @exodus/hw-ledger"
41
+ "test:integration": "pnpm run zemu:install && RUN_TESTS=integration pnpm run test",
42
+ "lint": "pnpm exec eslint .",
43
+ "lint:fix": "pnpm run lint --fix",
44
+ "prepublishOnly": "pnpm -w run build --scope @exodus/hw-ledger"
45
45
  },
46
46
  "dependencies": {
47
- "@exodus/atoms": "^10.3.3",
48
- "@exodus/bip322-js": "^3.1.0",
47
+ "@exodus/atoms": "^10.3.4",
48
+ "@exodus/bip322-js": "^3.2.2",
49
49
  "@exodus/bitcoinjs": "^2.0.0",
50
50
  "@exodus/bytes": "^1.0.0-rc.6",
51
51
  "@exodus/crypto": "^1.0.0-rc.29",
52
- "@exodus/ethereumjs": "^1.5.0",
53
- "@exodus/ethersproject-transactions": "^5.4.2-exodus.0",
54
- "@exodus/hw-common": "^3.4.0",
52
+ "@exodus/ethereumjs": "^1.13.0",
53
+ "@exodus/hw-common": "^3.5.0",
55
54
  "@exodus/ledger-bitcoin": "^0.2.3-exodus.6",
56
- "@exodus/ledgerhq-devices": "^8.1.0-exodus.3",
57
- "@exodus/ledgerhq-hw-app-eth": "^6.33.7-exodus.8",
55
+ "@exodus/ledgerhq-devices": "^8.1.0-exodus.7",
56
+ "@exodus/ledgerhq-hw-app-eth": "^6.33.7-exodus.13",
58
57
  "@exodus/redux-dependency-injection": "^5.0.0",
59
58
  "@exodus/ripple-binary-codec": "^0.3.0",
60
- "@exodus/storage-interface": "^1.0.0",
59
+ "@exodus/storage-interface": "^1.0.1",
61
60
  "@ledgerhq/hw-app-solana": "^7.0.10",
62
61
  "@ledgerhq/hw-app-trx": "^6.29.4",
63
62
  "@ledgerhq/hw-app-xrp": "^6.32.7",
@@ -66,7 +65,7 @@
66
65
  "semver": "^7.3.5"
67
66
  },
68
67
  "devDependencies": {
69
- "@exodus/bip32": "^4.1.0",
68
+ "@exodus/bip32": "^4.3.1",
70
69
  "@exodus/dependency-types": "^2.1.1",
71
70
  "@solana/web3.js": "^1.78.0",
72
71
  "@types/minimalistic-assert": "^1.0.1",
@@ -80,5 +79,5 @@
80
79
  "access": "public",
81
80
  "provenance": false
82
81
  },
83
- "gitHead": "f12f42d2a4062112458a94a2026fcf3cc1913fc6"
82
+ "gitHead": "2c794454cd4f006cc77b59f165900379929b4f93"
84
83
  }
package/redux.js CHANGED
@@ -1,2 +1 @@
1
- // eslint-disable-next-line import/no-unresolved -- shim re-exports built artifact
2
1
  export { default } from './lib/redux/index.js'