@exodus/hw-ledger 3.9.0 → 3.9.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 +24 -0
- package/lib/atoms/index.d.ts +4 -4
- package/lib/atoms/index.js +10 -7
- package/lib/index.d.ts +10 -10
- package/lib/index.js +14 -9
- package/lib/module/assets/applications.js +3 -1
- package/lib/module/assets/basemainnet.d.ts +1 -1
- package/lib/module/assets/basemainnet.js +10 -5
- package/lib/module/assets/bitcoin.js +42 -37
- package/lib/module/assets/ethereum.js +59 -21
- package/lib/module/assets/index.js +28 -22
- package/lib/module/assets/matic.d.ts +1 -1
- package/lib/module/assets/matic.js +10 -5
- package/lib/module/assets/ripple.js +17 -12
- package/lib/module/assets/solana.js +19 -14
- package/lib/module/assets/tronmainnet.js +50 -12
- package/lib/module/assets/utils/bip322.js +43 -7
- package/lib/module/assets/utils/derivation-paths.js +28 -17
- package/lib/module/assets/utils/index.d.ts +3 -3
- package/lib/module/assets/utils/index.js +19 -3
- package/lib/module/assets/utils/psbt.d.ts +3 -3
- package/lib/module/assets/utils/psbt.js +46 -34
- package/lib/module/assets/utils/xpub.d.ts +1 -1
- package/lib/module/assets/utils/xpub.js +6 -3
- package/lib/module/constants.js +4 -1
- package/lib/module/device.d.ts +2 -2
- package/lib/module/device.js +28 -21
- package/lib/module/discovery.d.ts +3 -3
- package/lib/module/discovery.js +18 -14
- package/lib/module/errors.js +12 -5
- package/lib/module/index.d.ts +2 -2
- package/lib/module/index.js +23 -2
- package/lib/module/management/application.js +5 -2
- package/lib/module/types.js +2 -1
- package/lib/plugin/index.d.ts +3 -3
- package/lib/plugin/index.js +6 -4
- package/lib/redux/id.js +3 -1
- package/lib/redux/index.d.ts +5 -5
- package/lib/redux/index.js +12 -7
- package/lib/redux/initial-state.d.ts +1 -1
- package/lib/redux/initial-state.js +3 -1
- package/lib/redux/selectors/bluetoothScanning.d.ts +2 -2
- package/lib/redux/selectors/bluetoothScanning.js +5 -3
- package/lib/redux/selectors/bluetoothStatus.d.ts +3 -3
- package/lib/redux/selectors/bluetoothStatus.js +5 -3
- package/lib/redux/selectors/index.d.ts +4 -4
- package/lib/redux/selectors/index.js +9 -4
- package/package.json +10 -3
- package/redux.js +2 -0
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,30 @@
|
|
|
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
|
+
## [3.9.2](https://github.com/ExodusMovement/exodus-hydra/compare/@exodus/hw-ledger@3.9.1...@exodus/hw-ledger@3.9.2) (2026-05-28)
|
|
7
|
+
|
|
8
|
+
### Features
|
|
9
|
+
|
|
10
|
+
- **typescript:** enable erasableSyntaxOnly across the monorepo ([#16435](https://github.com/ExodusMovement/exodus-hydra/issues/16435)) ([6055ee5](https://github.com/ExodusMovement/exodus-hydra/commit/6055ee57210c9b9a6a67dc0d7b8821077da121e0))
|
|
11
|
+
|
|
12
|
+
### Bug Fixes
|
|
13
|
+
|
|
14
|
+
- **hw-ledger:** unblock nodenext + flip tsconfig ([#16857](https://github.com/ExodusMovement/exodus-hydra/issues/16857)) ([7af2daa](https://github.com/ExodusMovement/exodus-hydra/commit/7af2daa5c2dcd964759d8461494a60ce5a4fd55d))
|
|
15
|
+
|
|
16
|
+
### Performance Improvements
|
|
17
|
+
|
|
18
|
+
- **hw-ledger:** reuse Speculos simulator per describe block ([#16129](https://github.com/ExodusMovement/exodus-hydra/issues/16129)) ([7b333bd](https://github.com/ExodusMovement/exodus-hydra/commit/7b333bd99c37689dffff1b1d2f9feeb105b1aba2))
|
|
19
|
+
|
|
20
|
+
## [3.9.1](https://github.com/ExodusMovement/exodus-hydra/compare/@exodus/hw-ledger@3.9.0...@exodus/hw-ledger@3.9.1) (2026-04-15)
|
|
21
|
+
|
|
22
|
+
### Bug Fixes
|
|
23
|
+
|
|
24
|
+
- fix(hw-ledger): add missing @exodus/storage-interface dependency (#16012)
|
|
25
|
+
|
|
26
|
+
- fix(hw-ledger): use correct variable in listApplications format check (#15064)
|
|
27
|
+
|
|
28
|
+
- fix: remove baseUrl from root tsconfig to fix .d.ts import paths (#15993)
|
|
29
|
+
|
|
6
30
|
## [3.9.0](https://github.com/ExodusMovement/exodus-hydra/compare/@exodus/hw-ledger@3.8.2...@exodus/hw-ledger@3.9.0) (2026-01-21)
|
|
7
31
|
|
|
8
32
|
### Features
|
package/lib/atoms/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Storage } from '
|
|
1
|
+
import type { Storage } from '@exodus/storage-interface';
|
|
2
2
|
export type BluetoothStatus = {
|
|
3
3
|
type: 'Unknown' | 'Resetting' | 'Unsupported' | 'Unauthorized' | 'PoweredOff' | 'PoweredOn';
|
|
4
4
|
available: boolean;
|
|
@@ -6,14 +6,14 @@ export type BluetoothStatus = {
|
|
|
6
6
|
export declare const bluetoothStatusAtomDefinition: {
|
|
7
7
|
readonly id: "bluetoothStatusAtom";
|
|
8
8
|
readonly type: "atom";
|
|
9
|
-
readonly factory: () => import("@exodus/atoms").Atom<BluetoothStatus>;
|
|
9
|
+
readonly factory: () => import("@exodus/atoms", { with: { "resolution-mode": "import" } }).Atom<BluetoothStatus>;
|
|
10
10
|
readonly dependencies: readonly [];
|
|
11
11
|
readonly public: true;
|
|
12
12
|
};
|
|
13
13
|
export declare const bluetoothScanningAtomDefinition: {
|
|
14
14
|
readonly id: "bluetoothScanningAtom";
|
|
15
15
|
readonly type: "atom";
|
|
16
|
-
readonly factory: () => import("@exodus/atoms").Atom<boolean>;
|
|
16
|
+
readonly factory: () => import("@exodus/atoms", { with: { "resolution-mode": "import" } }).Atom<boolean>;
|
|
17
17
|
readonly dependencies: readonly [];
|
|
18
18
|
readonly public: true;
|
|
19
19
|
};
|
|
@@ -23,7 +23,7 @@ type Params = {
|
|
|
23
23
|
export declare const walletPolicyAtomDefinition: {
|
|
24
24
|
readonly id: "walletPolicyAtom";
|
|
25
25
|
readonly type: "atom";
|
|
26
|
-
readonly factory: ({ storage }: Params) => import("@exodus/atoms").Atom<Record<string, Buffer<ArrayBufferLike>> | {}>;
|
|
26
|
+
readonly factory: ({ storage }: Params) => import("@exodus/atoms", { with: { "resolution-mode": "import" } }).Atom<Record<string, Buffer<ArrayBufferLike>> | {}>;
|
|
27
27
|
readonly dependencies: readonly ["storage"];
|
|
28
28
|
readonly public: true;
|
|
29
29
|
};
|
package/lib/atoms/index.js
CHANGED
|
@@ -1,25 +1,28 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.walletPolicyAtomDefinition = exports.bluetoothScanningAtomDefinition = exports.bluetoothStatusAtomDefinition = void 0;
|
|
4
|
+
const atoms_1 = require("@exodus/atoms");
|
|
5
|
+
exports.bluetoothStatusAtomDefinition = {
|
|
3
6
|
id: 'bluetoothStatusAtom',
|
|
4
7
|
type: 'atom',
|
|
5
|
-
factory: () => createInMemoryAtom({
|
|
8
|
+
factory: () => (0, atoms_1.createInMemoryAtom)({
|
|
6
9
|
defaultValue: { type: 'Unknown', available: false },
|
|
7
10
|
}),
|
|
8
11
|
dependencies: [],
|
|
9
12
|
public: true,
|
|
10
13
|
};
|
|
11
|
-
|
|
14
|
+
exports.bluetoothScanningAtomDefinition = {
|
|
12
15
|
id: 'bluetoothScanningAtom',
|
|
13
16
|
type: 'atom',
|
|
14
|
-
factory: () => createInMemoryAtom({ defaultValue: false }),
|
|
17
|
+
factory: () => (0, atoms_1.createInMemoryAtom)({ defaultValue: false }),
|
|
15
18
|
dependencies: [],
|
|
16
19
|
public: true,
|
|
17
20
|
};
|
|
18
|
-
|
|
21
|
+
exports.walletPolicyAtomDefinition = {
|
|
19
22
|
id: 'walletPolicyAtom',
|
|
20
23
|
type: 'atom',
|
|
21
24
|
factory: ({ storage }) => {
|
|
22
|
-
const createStorageAtom = createStorageAtomFactory({ storage });
|
|
25
|
+
const createStorageAtom = (0, atoms_1.createStorageAtomFactory)({ storage });
|
|
23
26
|
return createStorageAtom({
|
|
24
27
|
key: 'walletPolicy',
|
|
25
28
|
defaultValue: {},
|
package/lib/index.d.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import type { HwLedgerConfig } from './module/types';
|
|
1
|
+
import type { HwLedgerConfig } from './module/types.js';
|
|
2
2
|
declare const hardwareWalletLedger: ({ bluetoothScannerTimeout, }?: Partial<HwLedgerConfig>) => {
|
|
3
3
|
readonly id: "hardwareWalletLedger";
|
|
4
4
|
readonly definitions: readonly [{
|
|
5
5
|
readonly definition: {
|
|
6
6
|
readonly id: "bluetoothStatusAtom";
|
|
7
7
|
readonly type: "atom";
|
|
8
|
-
readonly factory: () => import("@exodus/atoms").Atom<import("./atoms").BluetoothStatus>;
|
|
8
|
+
readonly factory: () => import("@exodus/atoms", { with: { "resolution-mode": "import" } }).Atom<import("./atoms/index.js").BluetoothStatus>;
|
|
9
9
|
readonly dependencies: readonly [];
|
|
10
10
|
readonly public: true;
|
|
11
11
|
};
|
|
@@ -13,7 +13,7 @@ declare const hardwareWalletLedger: ({ bluetoothScannerTimeout, }?: Partial<HwLe
|
|
|
13
13
|
readonly definition: {
|
|
14
14
|
readonly id: "bluetoothScanningAtom";
|
|
15
15
|
readonly type: "atom";
|
|
16
|
-
readonly factory: () => import("@exodus/atoms").Atom<boolean>;
|
|
16
|
+
readonly factory: () => import("@exodus/atoms", { with: { "resolution-mode": "import" } }).Atom<boolean>;
|
|
17
17
|
readonly dependencies: readonly [];
|
|
18
18
|
readonly public: true;
|
|
19
19
|
};
|
|
@@ -22,8 +22,8 @@ declare const hardwareWalletLedger: ({ bluetoothScannerTimeout, }?: Partial<HwLe
|
|
|
22
22
|
readonly id: "walletPolicyAtom";
|
|
23
23
|
readonly type: "atom";
|
|
24
24
|
readonly factory: ({ storage }: {
|
|
25
|
-
storage: import("
|
|
26
|
-
}) => import("@exodus/atoms").Atom<Record<string, Buffer<ArrayBufferLike>> | {}>;
|
|
25
|
+
storage: import("@exodus/storage-interface").Storage<Record<string, Buffer>>;
|
|
26
|
+
}) => import("@exodus/atoms", { with: { "resolution-mode": "import" } }).Atom<Record<string, Buffer<ArrayBufferLike>> | {}>;
|
|
27
27
|
readonly dependencies: readonly ["storage"];
|
|
28
28
|
readonly public: true;
|
|
29
29
|
};
|
|
@@ -32,10 +32,10 @@ declare const hardwareWalletLedger: ({ bluetoothScannerTimeout, }?: Partial<HwLe
|
|
|
32
32
|
readonly id: "hardwareWalletLedgerPlugin";
|
|
33
33
|
readonly type: "plugin";
|
|
34
34
|
readonly factory: ({ bluetoothStatusAtom, bluetoothScanningAtom, ledgerDiscovery, port, }: {
|
|
35
|
-
bluetoothStatusAtom: import("@exodus/atoms").Atom<import("./atoms").BluetoothStatus>;
|
|
36
|
-
bluetoothScanningAtom: import("@exodus/atoms").Atom<boolean>;
|
|
37
|
-
ledgerDiscovery: import("./module").LedgerDiscovery;
|
|
38
|
-
port: import("./shared/types").Port;
|
|
35
|
+
bluetoothStatusAtom: import("@exodus/atoms", { with: { "resolution-mode": "import" } }).Atom<import("./atoms/index.js").BluetoothStatus>;
|
|
36
|
+
bluetoothScanningAtom: import("@exodus/atoms", { with: { "resolution-mode": "import" } }).Atom<boolean>;
|
|
37
|
+
ledgerDiscovery: import("./module/discovery.js").LedgerDiscovery;
|
|
38
|
+
port: import("./shared/types.js").Port;
|
|
39
39
|
}) => {
|
|
40
40
|
onUnlock: () => void;
|
|
41
41
|
onLoad: () => void;
|
|
@@ -48,7 +48,7 @@ declare const hardwareWalletLedger: ({ bluetoothScannerTimeout, }?: Partial<HwLe
|
|
|
48
48
|
readonly definition: {
|
|
49
49
|
readonly id: "ledgerDiscovery";
|
|
50
50
|
readonly type: "module";
|
|
51
|
-
readonly factory: (deps: import("./module").Dependencies) => import("./module").LedgerDiscovery;
|
|
51
|
+
readonly factory: (deps: import("./module/discovery.js").Dependencies) => import("./module/discovery.js").LedgerDiscovery;
|
|
52
52
|
readonly dependencies: readonly ["config", "logger", "transportsFactories", "bluetoothStatusAtom", "bluetoothScanningAtom", "walletPolicyAtom"];
|
|
53
53
|
readonly public: true;
|
|
54
54
|
};
|
package/lib/index.js
CHANGED
|
@@ -1,27 +1,32 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const index_js_1 = require("./atoms/index.js");
|
|
7
|
+
const index_js_2 = __importDefault(require("./module/index.js"));
|
|
8
|
+
const index_js_3 = __importDefault(require("./plugin/index.js"));
|
|
4
9
|
const hardwareWalletLedger = ({ bluetoothScannerTimeout = 10_000, } = {}) => {
|
|
5
10
|
return {
|
|
6
11
|
id: 'hardwareWalletLedger',
|
|
7
12
|
definitions: [
|
|
8
13
|
{
|
|
9
|
-
definition: bluetoothStatusAtomDefinition,
|
|
14
|
+
definition: index_js_1.bluetoothStatusAtomDefinition,
|
|
10
15
|
},
|
|
11
16
|
{
|
|
12
|
-
definition: bluetoothScanningAtomDefinition,
|
|
17
|
+
definition: index_js_1.bluetoothScanningAtomDefinition,
|
|
13
18
|
},
|
|
14
19
|
{
|
|
15
|
-
definition: walletPolicyAtomDefinition,
|
|
20
|
+
definition: index_js_1.walletPolicyAtomDefinition,
|
|
16
21
|
},
|
|
17
22
|
{
|
|
18
|
-
definition:
|
|
23
|
+
definition: index_js_3.default,
|
|
19
24
|
},
|
|
20
25
|
{
|
|
21
|
-
definition:
|
|
26
|
+
definition: index_js_2.default,
|
|
22
27
|
config: { bluetoothScannerTimeout },
|
|
23
28
|
},
|
|
24
29
|
],
|
|
25
30
|
};
|
|
26
31
|
};
|
|
27
|
-
|
|
32
|
+
exports.default = hardwareWalletLedger;
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
1
3
|
const Bitcoin = {
|
|
2
4
|
applicationName: 'Bitcoin',
|
|
3
5
|
supportedVersions: '^2.1.2',
|
|
@@ -36,4 +38,4 @@ const applications = {
|
|
|
36
38
|
Tron,
|
|
37
39
|
XRP,
|
|
38
40
|
};
|
|
39
|
-
|
|
41
|
+
exports.default = applications;
|
|
@@ -4,6 +4,6 @@ declare const metadata: {
|
|
|
4
4
|
supportedVersions: string;
|
|
5
5
|
primaryAssetName: string;
|
|
6
6
|
}[];
|
|
7
|
-
handler: (transport: import("@ledgerhq/hw-transport").default) => Promise<import("
|
|
7
|
+
handler: (transport: import("@ledgerhq/hw-transport").default) => Promise<import("@exodus/hw-common", { with: { "resolution-mode": "import" } }).HardwareWalletAssetHandler>;
|
|
8
8
|
};
|
|
9
9
|
export default metadata;
|
|
@@ -1,7 +1,12 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const applications_js_1 = __importDefault(require("./applications.js"));
|
|
7
|
+
const ethereum_js_1 = __importDefault(require("./ethereum.js"));
|
|
3
8
|
const metadata = {
|
|
4
|
-
applications: [
|
|
5
|
-
handler:
|
|
9
|
+
applications: [applications_js_1.default.Ethereum],
|
|
10
|
+
handler: ethereum_js_1.default.handler,
|
|
6
11
|
};
|
|
7
|
-
|
|
12
|
+
exports.default = metadata;
|
|
@@ -1,25 +1,30 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const base58_js_1 = require("@exodus/bytes/base58.js");
|
|
7
|
+
const ledger_bitcoin_1 = require("@exodus/ledger-bitcoin");
|
|
8
|
+
const bip322_js_1 = require("@exodus/bip322-js");
|
|
9
|
+
const index_js_1 = require("./utils/index.js");
|
|
10
|
+
const minimalistic_assert_1 = __importDefault(require("minimalistic-assert"));
|
|
11
|
+
const psbt_js_1 = require("./utils/psbt.js");
|
|
12
|
+
const bip322_js_2 = require("./utils/bip322.js");
|
|
13
|
+
const applications_js_1 = __importDefault(require("./applications.js"));
|
|
9
14
|
async function createHandler(transport, walletPolicyAtom) {
|
|
10
|
-
const app = new AppClient(transport);
|
|
15
|
+
const app = new ledger_bitcoin_1.AppClient(transport);
|
|
11
16
|
const getAddress = async (params) => {
|
|
12
|
-
const [purpose, coin, account, change, address] = splitBip44DerivationPath(params.derivationPath);
|
|
17
|
+
const [purpose, coin, account, change, address] = (0, index_js_1.splitBip44DerivationPath)(params.derivationPath);
|
|
13
18
|
const fpr = await app.getMasterFingerprint();
|
|
14
19
|
const xpub = await app.getExtendedPubkey(`m/${purpose}/${coin}/${account}`);
|
|
15
20
|
let walletPolicy;
|
|
16
21
|
let hmac = null;
|
|
17
22
|
if (params.multisigData) {
|
|
18
|
-
walletPolicy = getMultisigWalletPolicy(fpr, xpub, purpose, coin, account, params.multisigData);
|
|
23
|
+
walletPolicy = (0, psbt_js_1.getMultisigWalletPolicy)(fpr, xpub, purpose, coin, account, params.multisigData);
|
|
19
24
|
hmac = await registerWalletPolicy(walletPolicy);
|
|
20
25
|
}
|
|
21
26
|
else {
|
|
22
|
-
walletPolicy = getWalletPolicy(fpr, xpub, purpose, coin, account);
|
|
27
|
+
walletPolicy = (0, psbt_js_1.getWalletPolicy)(fpr, xpub, purpose, coin, account);
|
|
23
28
|
}
|
|
24
29
|
return app.getWalletAddress(walletPolicy, hmac, Number(change), Number(address), params.displayOnDevice ?? false);
|
|
25
30
|
};
|
|
@@ -28,12 +33,12 @@ async function createHandler(transport, walletPolicyAtom) {
|
|
|
28
33
|
};
|
|
29
34
|
const getPublicKey = async (params) => {
|
|
30
35
|
const pubString = await app.getExtendedPubkey(params.derivationPath);
|
|
31
|
-
return fromBase58(pubString, 'buffer').subarray(45, 45 + 33);
|
|
36
|
+
return (0, base58_js_1.fromBase58)(pubString, 'buffer').subarray(45, 45 + 33);
|
|
32
37
|
};
|
|
33
38
|
const signTransaction = async (params) => {
|
|
34
|
-
|
|
39
|
+
(0, minimalistic_assert_1.default)(Buffer.isBuffer(params.signableTransaction), 'signableTransaction must be PSBT buffer');
|
|
35
40
|
const psbtBuffer = params.signableTransaction;
|
|
36
|
-
const psbt = new PsbtV2();
|
|
41
|
+
const psbt = new ledger_bitcoin_1.PsbtV2();
|
|
37
42
|
psbt.deserialize(psbtBuffer);
|
|
38
43
|
const fpr = await app.getMasterFingerprint();
|
|
39
44
|
const derivationPathToPublicKeyMap = Object.create(null);
|
|
@@ -53,10 +58,10 @@ async function createHandler(transport, walletPolicyAtom) {
|
|
|
53
58
|
});
|
|
54
59
|
derivationPathToPublicKeyMap[derivationPath] = publicKey;
|
|
55
60
|
}
|
|
56
|
-
const derivationPathsToSignFor = tagPsbtWithDerivationPaths(psbt, fpr, derivationPathToPublicKeyMap, addressToDerivationPathMap);
|
|
57
|
-
addDummyInputs(psbt);
|
|
58
|
-
assertPsbtOnlyHasAllowedDerivationPaths(psbt, fpr, params.derivationPaths);
|
|
59
|
-
const walletPolicies = await derivationPathsToWalletPolicy(fpr, app, derivationPathsToSignFor, params.multisigData);
|
|
61
|
+
const derivationPathsToSignFor = (0, psbt_js_1.tagPsbtWithDerivationPaths)(psbt, fpr, derivationPathToPublicKeyMap, addressToDerivationPathMap);
|
|
62
|
+
(0, psbt_js_1.addDummyInputs)(psbt);
|
|
63
|
+
(0, psbt_js_1.assertPsbtOnlyHasAllowedDerivationPaths)(psbt, fpr, params.derivationPaths);
|
|
64
|
+
const walletPolicies = await (0, psbt_js_1.derivationPathsToWalletPolicy)(fpr, app, derivationPathsToSignFor, params.multisigData);
|
|
60
65
|
const signatures = [];
|
|
61
66
|
for (const walletPolicy of walletPolicies) {
|
|
62
67
|
const hmac = params.multisigData ? await registerWalletPolicy(walletPolicy) : null;
|
|
@@ -73,21 +78,21 @@ async function createHandler(transport, walletPolicyAtom) {
|
|
|
73
78
|
};
|
|
74
79
|
const signMessage = async (params) => {
|
|
75
80
|
if (params.message.rawMessage) {
|
|
76
|
-
|
|
81
|
+
(0, minimalistic_assert_1.default)(Buffer.isBuffer(params.message.rawMessage), 'rawMessage must be buffer');
|
|
77
82
|
const signedMessageHex = await app.signMessage(params.message.rawMessage, params.derivationPath);
|
|
78
83
|
return Buffer.from(signedMessageHex, 'base64');
|
|
79
84
|
}
|
|
80
85
|
if (params.message.bip322Message) {
|
|
81
86
|
const { message, address } = params.message.bip322Message;
|
|
82
87
|
const { derivationPath } = params;
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
const [purpose, coin, account] = splitBip44DerivationPath(derivationPath);
|
|
88
|
+
(0, minimalistic_assert_1.default)(Buffer.isBuffer(message), 'bip322Message.message must be buffer');
|
|
89
|
+
(0, minimalistic_assert_1.default)(typeof address === 'string', 'bip322Message.address must be string');
|
|
90
|
+
const [purpose, coin, account] = (0, index_js_1.splitBip44DerivationPath)(derivationPath);
|
|
86
91
|
const fpr = await app.getMasterFingerprint();
|
|
87
92
|
const xpub = await app.getExtendedPubkey(`m/${purpose}/${coin}/${account}`);
|
|
88
|
-
const walletPolicy = getWalletPolicy(fpr, xpub, purpose, coin, account);
|
|
89
|
-
const psbtBip322 = buildBip322PSBT(message.toString(), address);
|
|
90
|
-
const psbt = new PsbtV2();
|
|
93
|
+
const walletPolicy = (0, psbt_js_1.getWalletPolicy)(fpr, xpub, purpose, coin, account);
|
|
94
|
+
const psbtBip322 = (0, bip322_js_2.buildBip322PSBT)(message.toString(), address);
|
|
95
|
+
const psbt = new ledger_bitcoin_1.PsbtV2();
|
|
91
96
|
psbt.deserialize(psbtBip322.toBuffer());
|
|
92
97
|
const derivationPathToPublicKeyMap = {
|
|
93
98
|
[derivationPath]: await getPublicKey({
|
|
@@ -95,7 +100,7 @@ async function createHandler(transport, walletPolicyAtom) {
|
|
|
95
100
|
derivationPath,
|
|
96
101
|
}),
|
|
97
102
|
};
|
|
98
|
-
tagPsbtWithDerivationPaths(psbt, fpr, derivationPathToPublicKeyMap);
|
|
103
|
+
(0, psbt_js_1.tagPsbtWithDerivationPaths)(psbt, fpr, derivationPathToPublicKeyMap);
|
|
99
104
|
const signatures = await app.signPsbt(psbt.serialize(), walletPolicy, null);
|
|
100
105
|
const signature = signatures[0][1];
|
|
101
106
|
const isTaprootSig = signature.pubkey.length === 32;
|
|
@@ -110,7 +115,7 @@ async function createHandler(transport, walletPolicyAtom) {
|
|
|
110
115
|
});
|
|
111
116
|
}
|
|
112
117
|
psbtBip322.finalizeAllInputs();
|
|
113
|
-
const encodedWitness = BIP322.encodeWitness(psbtBip322);
|
|
118
|
+
const encodedWitness = bip322_js_1.BIP322.encodeWitness(psbtBip322);
|
|
114
119
|
return Buffer.from(encodedWitness, 'base64');
|
|
115
120
|
}
|
|
116
121
|
throw new Error('rawMessage or bip322Message must be defined');
|
|
@@ -118,13 +123,13 @@ async function createHandler(transport, walletPolicyAtom) {
|
|
|
118
123
|
const registerWalletPolicy = async (walletPolicy) => {
|
|
119
124
|
const walletPolicies = (await walletPolicyAtom?.get()) ?? {};
|
|
120
125
|
const id = walletPolicy.getId().toString('hex');
|
|
121
|
-
|
|
122
|
-
if (
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
126
|
+
const cached = walletPolicies[id];
|
|
127
|
+
if (cached)
|
|
128
|
+
return cached;
|
|
129
|
+
const [, hmac] = await app.registerWallet(walletPolicy);
|
|
130
|
+
(0, minimalistic_assert_1.default)(hmac, 'app.registerWallet returned no HMAC');
|
|
131
|
+
const updatedPolicies = { ...walletPolicies, [id]: hmac };
|
|
132
|
+
await walletPolicyAtom?.set(updatedPolicies);
|
|
128
133
|
return hmac;
|
|
129
134
|
};
|
|
130
135
|
return {
|
|
@@ -136,7 +141,7 @@ async function createHandler(transport, walletPolicyAtom) {
|
|
|
136
141
|
};
|
|
137
142
|
}
|
|
138
143
|
const metadata = {
|
|
139
|
-
applications: [
|
|
144
|
+
applications: [applications_js_1.default.Bitcoin],
|
|
140
145
|
handler: createHandler,
|
|
141
146
|
};
|
|
142
|
-
|
|
147
|
+
exports.default = metadata;
|
|
@@ -1,14 +1,52 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
const secp256k1 = __importStar(require("@exodus/crypto/secp256k1"));
|
|
40
|
+
const ethers = __importStar(require("@exodus/ethersproject-transactions"));
|
|
41
|
+
const ledgerhq_hw_app_eth_1 = __importStar(require("@exodus/ledgerhq-hw-app-eth"));
|
|
42
|
+
const eth_sig_util_1 = require("@exodus/ethereumjs/eth-sig-util");
|
|
43
|
+
const minimalistic_assert_1 = __importDefault(require("minimalistic-assert"));
|
|
44
|
+
const index_js_1 = require("./utils/index.js");
|
|
45
|
+
const errors_js_1 = require("../errors.js");
|
|
46
|
+
const applications_js_1 = __importDefault(require("./applications.js"));
|
|
9
47
|
function hashEIP712Message(typedData) {
|
|
10
|
-
const version = SignTypedDataVersion.V4;
|
|
11
|
-
const { sanitizeData, hashStruct } = TypedDataUtils;
|
|
48
|
+
const version = eth_sig_util_1.SignTypedDataVersion.V4;
|
|
49
|
+
const { sanitizeData, hashStruct } = eth_sig_util_1.TypedDataUtils;
|
|
12
50
|
const sanitizedData = sanitizeData(typedData);
|
|
13
51
|
const domainSeparator = hashStruct('EIP712Domain', sanitizedData.domain, sanitizedData.types, version);
|
|
14
52
|
let hashStructMessage = Buffer.alloc(0);
|
|
@@ -28,7 +66,7 @@ function isEIP712Message(message) {
|
|
|
28
66
|
return (candidateKeys.length === ownKeys.length && candidateKeys.every((key) => ownKeys.includes(key)));
|
|
29
67
|
}
|
|
30
68
|
async function createHandler(transport) {
|
|
31
|
-
const app = new
|
|
69
|
+
const app = new ledgerhq_hw_app_eth_1.default(transport);
|
|
32
70
|
return {
|
|
33
71
|
getAddress: async (params) => {
|
|
34
72
|
const { address } = await app.getAddress(params.derivationPath.replace('m/', ''));
|
|
@@ -41,7 +79,7 @@ async function createHandler(transport) {
|
|
|
41
79
|
compressed: true,
|
|
42
80
|
format: 'buffer',
|
|
43
81
|
});
|
|
44
|
-
return buildFauxXPUB(compressedPublicKey, Buffer.from(chainCode, 'hex'));
|
|
82
|
+
return (0, index_js_1.buildFauxXPUB)(compressedPublicKey, Buffer.from(chainCode, 'hex'));
|
|
45
83
|
},
|
|
46
84
|
getPublicKey: async (params) => {
|
|
47
85
|
const { publicKey } = await app.getAddress(params.derivationPath.replace('m/', ''));
|
|
@@ -52,8 +90,8 @@ async function createHandler(transport) {
|
|
|
52
90
|
});
|
|
53
91
|
},
|
|
54
92
|
signTransaction: async (params) => {
|
|
55
|
-
|
|
56
|
-
|
|
93
|
+
(0, minimalistic_assert_1.default)(Array.isArray(params.derivationPaths) && params.derivationPaths.length === 1, 'derivationsPath array must be one element long');
|
|
94
|
+
(0, minimalistic_assert_1.default)(Buffer.isBuffer(params.signableTransaction), 'signableTransaction must be Buffer');
|
|
57
95
|
const deserializedTransaction = ethers.parse(params.signableTransaction);
|
|
58
96
|
switch (params.assetName) {
|
|
59
97
|
case 'ethereum': {
|
|
@@ -74,7 +112,7 @@ async function createHandler(transport) {
|
|
|
74
112
|
delete deserializedTransaction.v;
|
|
75
113
|
const serializedTransactionHex = ethers.serialize(deserializedTransaction).slice(2);
|
|
76
114
|
const signTransaction = async ({ derivationPath, serializedTransactionHex, withNFT = true, }) => {
|
|
77
|
-
const resolution = await ledgerService.resolveTransaction(serializedTransactionHex, app.loadConfig, {
|
|
115
|
+
const resolution = await ledgerhq_hw_app_eth_1.ledgerService.resolveTransaction(serializedTransactionHex, app.loadConfig, {
|
|
78
116
|
externalPlugins: true,
|
|
79
117
|
erc20: true,
|
|
80
118
|
nft: withNFT,
|
|
@@ -98,7 +136,7 @@ async function createHandler(transport) {
|
|
|
98
136
|
});
|
|
99
137
|
}
|
|
100
138
|
else if (err.name === 'EthAppPleaseEnableContractData') {
|
|
101
|
-
throw new RequiresBlindSigningError();
|
|
139
|
+
throw new errors_js_1.RequiresBlindSigningError();
|
|
102
140
|
}
|
|
103
141
|
else {
|
|
104
142
|
throw err;
|
|
@@ -119,11 +157,11 @@ async function createHandler(transport) {
|
|
|
119
157
|
const message = params.message;
|
|
120
158
|
let signingPromise;
|
|
121
159
|
if (message.rawMessage) {
|
|
122
|
-
|
|
160
|
+
(0, minimalistic_assert_1.default)(Buffer.isBuffer(params.message.rawMessage), 'rawMessage must be a buffer');
|
|
123
161
|
signingPromise = app.signPersonalMessage(params.derivationPath, Buffer.from(message.rawMessage).toString('hex'));
|
|
124
162
|
}
|
|
125
163
|
else if (message.EIP712Message) {
|
|
126
|
-
|
|
164
|
+
(0, minimalistic_assert_1.default)(isEIP712Message(message.EIP712Message), 'EIP712Message must be EIP712 conformant message');
|
|
127
165
|
signingPromise = app
|
|
128
166
|
.signEIP712Message(params.derivationPath, message.EIP712Message)
|
|
129
167
|
.catch((err) => {
|
|
@@ -135,7 +173,7 @@ async function createHandler(transport) {
|
|
|
135
173
|
});
|
|
136
174
|
}
|
|
137
175
|
else {
|
|
138
|
-
|
|
176
|
+
(0, minimalistic_assert_1.default)(false, 'rawMessage or EIP712Message must be specified');
|
|
139
177
|
}
|
|
140
178
|
const { r, s, v } = await signingPromise;
|
|
141
179
|
const vNorm = v.toString(16);
|
|
@@ -145,7 +183,7 @@ async function createHandler(transport) {
|
|
|
145
183
|
};
|
|
146
184
|
}
|
|
147
185
|
const metadata = {
|
|
148
|
-
applications: [
|
|
186
|
+
applications: [applications_js_1.default.Ethereum],
|
|
149
187
|
handler: createHandler,
|
|
150
188
|
};
|
|
151
|
-
|
|
189
|
+
exports.default = metadata;
|
|
@@ -1,30 +1,36 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
import matic from './matic';
|
|
5
|
-
import ripple from './ripple';
|
|
6
|
-
import solana from './solana';
|
|
7
|
-
import tronmainnet from './tronmainnet';
|
|
8
|
-
import applications from './applications';
|
|
9
|
-
export const assetApplications = {
|
|
10
|
-
basemainnet,
|
|
11
|
-
bitcoin,
|
|
12
|
-
bitcointestnet: bitcoin,
|
|
13
|
-
bitcoinregtest: bitcoin,
|
|
14
|
-
matic,
|
|
15
|
-
ripple,
|
|
16
|
-
solana,
|
|
17
|
-
ethereum,
|
|
18
|
-
ethereumsepolia: ethereum,
|
|
19
|
-
tronmainnet,
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
20
4
|
};
|
|
21
|
-
|
|
22
|
-
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.applicationNameToBaseAssetNames = exports.supportedBaseAssetNames = exports.assetApplications = void 0;
|
|
7
|
+
const bitcoin_js_1 = __importDefault(require("./bitcoin.js"));
|
|
8
|
+
const basemainnet_js_1 = __importDefault(require("./basemainnet.js"));
|
|
9
|
+
const ethereum_js_1 = __importDefault(require("./ethereum.js"));
|
|
10
|
+
const matic_js_1 = __importDefault(require("./matic.js"));
|
|
11
|
+
const ripple_js_1 = __importDefault(require("./ripple.js"));
|
|
12
|
+
const solana_js_1 = __importDefault(require("./solana.js"));
|
|
13
|
+
const tronmainnet_js_1 = __importDefault(require("./tronmainnet.js"));
|
|
14
|
+
const applications_js_1 = __importDefault(require("./applications.js"));
|
|
15
|
+
exports.assetApplications = {
|
|
16
|
+
basemainnet: basemainnet_js_1.default,
|
|
17
|
+
bitcoin: bitcoin_js_1.default,
|
|
18
|
+
bitcointestnet: bitcoin_js_1.default,
|
|
19
|
+
bitcoinregtest: bitcoin_js_1.default,
|
|
20
|
+
matic: matic_js_1.default,
|
|
21
|
+
ripple: ripple_js_1.default,
|
|
22
|
+
solana: solana_js_1.default,
|
|
23
|
+
ethereum: ethereum_js_1.default,
|
|
24
|
+
ethereumsepolia: ethereum_js_1.default,
|
|
25
|
+
tronmainnet: tronmainnet_js_1.default,
|
|
26
|
+
};
|
|
27
|
+
exports.supportedBaseAssetNames = Object.keys(exports.assetApplications);
|
|
28
|
+
exports.applicationNameToBaseAssetNames = Object.entries(exports.assetApplications).reduce((mapping, [assetName, metadata]) => {
|
|
23
29
|
for (const { applicationName } of metadata.applications) {
|
|
24
30
|
if (!Array.isArray(mapping[applicationName])) {
|
|
25
31
|
mapping[applicationName] = [];
|
|
26
32
|
}
|
|
27
|
-
const isPrimaryAssetForApplication =
|
|
33
|
+
const isPrimaryAssetForApplication = applications_js_1.default[applicationName]?.primaryAssetName === assetName;
|
|
28
34
|
if (isPrimaryAssetForApplication) {
|
|
29
35
|
mapping[applicationName].unshift(assetName);
|
|
30
36
|
}
|
|
@@ -4,6 +4,6 @@ declare const metadata: {
|
|
|
4
4
|
supportedVersions: string;
|
|
5
5
|
primaryAssetName: string;
|
|
6
6
|
}[];
|
|
7
|
-
handler: (transport: import("@ledgerhq/hw-transport").default) => Promise<import("
|
|
7
|
+
handler: (transport: import("@ledgerhq/hw-transport").default) => Promise<import("@exodus/hw-common", { with: { "resolution-mode": "import" } }).HardwareWalletAssetHandler>;
|
|
8
8
|
};
|
|
9
9
|
export default metadata;
|
|
@@ -1,7 +1,12 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const applications_js_1 = __importDefault(require("./applications.js"));
|
|
7
|
+
const ethereum_js_1 = __importDefault(require("./ethereum.js"));
|
|
3
8
|
const metadata = {
|
|
4
|
-
applications: [
|
|
5
|
-
handler:
|
|
9
|
+
applications: [applications_js_1.default.Polygon, applications_js_1.default.Ethereum],
|
|
10
|
+
handler: ethereum_js_1.default.handler,
|
|
6
11
|
};
|
|
7
|
-
|
|
12
|
+
exports.default = metadata;
|