@exodus/hardware-wallets 1.6.0 → 1.7.1
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 +6 -0
- package/lib/atoms/index.d.ts +11 -0
- package/lib/atoms/index.js +43 -0
- package/lib/index.d.ts +21 -0
- package/lib/index.js +8 -0
- package/lib/module/hardware-wallets.js +1 -1
- package/lib/module/interfaces.d.ts +1 -0
- package/lib/plugin/index.d.ts +17 -0
- package/lib/plugin/index.js +34 -0
- package/lib/redux/id.d.ts +2 -0
- package/lib/redux/id.js +2 -0
- package/lib/redux/index.d.ts +22 -0
- package/lib/redux/index.js +16 -0
- package/lib/redux/initial-state.d.ts +6 -0
- package/lib/redux/initial-state.js +4 -0
- package/lib/redux/selectors/index.d.ts +11 -0
- package/lib/redux/selectors/index.js +3 -0
- package/lib/redux/selectors/isAssetNameConnectedForWalletAccount.d.ts +13 -0
- package/lib/redux/selectors/isAssetNameConnectedForWalletAccount.js +9 -0
- package/package.json +13 -10
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,12 @@
|
|
|
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
|
+
## [1.7.0](https://github.com/ExodusMovement/exodus-hydra/compare/@exodus/hardware-wallets@1.6.0...@exodus/hardware-wallets@1.7.0) (2024-11-13)
|
|
7
|
+
|
|
8
|
+
### Features
|
|
9
|
+
|
|
10
|
+
- feat: add isAssetNameConnectedForWalletAccountSelector (#10416)
|
|
11
|
+
|
|
6
12
|
## [1.6.0](https://github.com/ExodusMovement/exodus-hydra/compare/@exodus/hardware-wallets@1.5.1...@exodus/hardware-wallets@1.6.0) (2024-10-22)
|
|
7
13
|
|
|
8
14
|
### Features
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
type WalletAccountName = string;
|
|
2
|
+
type AssetName = string;
|
|
3
|
+
export type WalletAccountNameToConnectedAssetNamesMap = Record<WalletAccountName, AssetName[]>;
|
|
4
|
+
export declare const createHardwareWalletConnectedAssetNamesAtom: ({ assetsModule, hardwareWalletPublicKeysAtom, walletAccountsAtom, }: any) => import("@exodus/atoms").ReadonlyAtom<unknown>;
|
|
5
|
+
export declare const hardwareWalletConnectedAssetNamesAtomDefinition: {
|
|
6
|
+
readonly id: "hardwareWalletConnectedAssetNamesAtom";
|
|
7
|
+
readonly type: "atom";
|
|
8
|
+
readonly factory: ({ assetsModule, hardwareWalletPublicKeysAtom, walletAccountsAtom, }: any) => import("@exodus/atoms").ReadonlyAtom<unknown>;
|
|
9
|
+
readonly dependencies: readonly ["hardwareWalletPublicKeysAtom", "assetsModule", "walletAccountsAtom"];
|
|
10
|
+
};
|
|
11
|
+
export {};
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { combine, compute } from '@exodus/atoms';
|
|
2
|
+
import { memoize } from '@exodus/basic-utils';
|
|
3
|
+
import { HARDENED_OFFSET } from '@exodus/bip32';
|
|
4
|
+
export const createHardwareWalletConnectedAssetNamesAtom = ({ assetsModule, hardwareWalletPublicKeysAtom, walletAccountsAtom, }) => {
|
|
5
|
+
const selector = memoize(({ hardwareWalletPublicKeys, walletAccounts }) => {
|
|
6
|
+
const result = Object.create(null);
|
|
7
|
+
const assets = assetsModule.getAssets();
|
|
8
|
+
for (const [walletAccountName, walletAccount] of Object.entries(walletAccounts)) {
|
|
9
|
+
if (!walletAccount.isHardware) {
|
|
10
|
+
continue;
|
|
11
|
+
}
|
|
12
|
+
const derivationPaths = Object.keys(hardwareWalletPublicKeys[walletAccountName] ?? Object.create(null));
|
|
13
|
+
if (derivationPaths.length === 0) {
|
|
14
|
+
continue;
|
|
15
|
+
}
|
|
16
|
+
const bip44Regex = /^m\/\d+'\/(\d+)'/u;
|
|
17
|
+
const bip44Values = new Set(derivationPaths
|
|
18
|
+
.map((path) => {
|
|
19
|
+
const match = path.match(bip44Regex);
|
|
20
|
+
return match ? match[1] : null;
|
|
21
|
+
})
|
|
22
|
+
.filter(Boolean));
|
|
23
|
+
const syncedAssetNames = Object.values(assets)
|
|
24
|
+
.filter((asset) => bip44Values.has(String(asset.baseAsset.bip44 - HARDENED_OFFSET)))
|
|
25
|
+
.map((asset) => asset.name);
|
|
26
|
+
result[walletAccountName] = syncedAssetNames;
|
|
27
|
+
}
|
|
28
|
+
return result;
|
|
29
|
+
}, (deps) => JSON.stringify(deps));
|
|
30
|
+
return compute({
|
|
31
|
+
atom: combine({
|
|
32
|
+
hardwareWalletPublicKeys: hardwareWalletPublicKeysAtom,
|
|
33
|
+
walletAccounts: walletAccountsAtom,
|
|
34
|
+
}),
|
|
35
|
+
selector,
|
|
36
|
+
});
|
|
37
|
+
};
|
|
38
|
+
export const hardwareWalletConnectedAssetNamesAtomDefinition = {
|
|
39
|
+
id: 'hardwareWalletConnectedAssetNamesAtom',
|
|
40
|
+
type: 'atom',
|
|
41
|
+
factory: createHardwareWalletConnectedAssetNamesAtom,
|
|
42
|
+
dependencies: ['hardwareWalletPublicKeysAtom', 'assetsModule', 'walletAccountsAtom'],
|
|
43
|
+
};
|
package/lib/index.d.ts
CHANGED
|
@@ -36,6 +36,27 @@ declare const hardwareWallets: () => {
|
|
|
36
36
|
readonly dependencies: readonly ["assetsModule", "logger", "ledgerDiscovery", "userInterface", "publicKeyStore", "wallet", "walletAccountsAtom", "walletAccounts"];
|
|
37
37
|
readonly public: true;
|
|
38
38
|
};
|
|
39
|
+
}, {
|
|
40
|
+
readonly definition: {
|
|
41
|
+
readonly id: "hardwareWalletConnectedAssetNamesAtom";
|
|
42
|
+
readonly type: "atom";
|
|
43
|
+
readonly factory: ({ assetsModule, hardwareWalletPublicKeysAtom, walletAccountsAtom, }: any) => import("libraries/atoms/lib/index.js").ReadonlyAtom<unknown>;
|
|
44
|
+
readonly dependencies: readonly ["hardwareWalletPublicKeysAtom", "assetsModule", "walletAccountsAtom"];
|
|
45
|
+
};
|
|
46
|
+
}, {
|
|
47
|
+
readonly definition: {
|
|
48
|
+
readonly id: "hardwareWalletsPlugin";
|
|
49
|
+
readonly type: "plugin";
|
|
50
|
+
readonly factory: ({ hardwareWalletConnectedAssetNamesAtom, port, }: {
|
|
51
|
+
hardwareWalletConnectedAssetNamesAtom: import("libraries/atoms/lib/index.js").Atom<import("./atoms/index.js").WalletAccountNameToConnectedAssetNamesMap>;
|
|
52
|
+
port: import("./shared/types.js").Port;
|
|
53
|
+
}) => {
|
|
54
|
+
onUnlock: () => void;
|
|
55
|
+
onLoad: () => void;
|
|
56
|
+
onStop: () => void;
|
|
57
|
+
};
|
|
58
|
+
readonly dependencies: readonly ["hardwareWalletConnectedAssetNamesAtom", "port"];
|
|
59
|
+
};
|
|
39
60
|
}];
|
|
40
61
|
};
|
|
41
62
|
export type HardwareWalletsApi = ReturnType<typeof hardwareWalletsApiDefinition.factory>;
|
package/lib/index.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import hardwareWalletsApiDefinition from './api/index.js';
|
|
2
2
|
import hardwareWalletsModuleDefinition from './module/hardware-wallets.js';
|
|
3
|
+
import { hardwareWalletConnectedAssetNamesAtomDefinition } from './atoms/index.js';
|
|
4
|
+
import hardwareWalletsPluginDefinition from './plugin/index.js';
|
|
3
5
|
const hardwareWallets = () => {
|
|
4
6
|
return {
|
|
5
7
|
id: 'hardwareWallets',
|
|
@@ -10,6 +12,12 @@ const hardwareWallets = () => {
|
|
|
10
12
|
{
|
|
11
13
|
definition: hardwareWalletsModuleDefinition,
|
|
12
14
|
},
|
|
15
|
+
{
|
|
16
|
+
definition: hardwareWalletConnectedAssetNamesAtomDefinition,
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
definition: hardwareWalletsPluginDefinition,
|
|
20
|
+
},
|
|
13
21
|
],
|
|
14
22
|
};
|
|
15
23
|
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import assert from 'minimalistic-assert';
|
|
2
2
|
import { WalletAccount } from '@exodus/models';
|
|
3
3
|
import Emitter from '@exodus/wild-emitter';
|
|
4
|
-
import randomBytes from '
|
|
4
|
+
import { randomBytes } from '@exodus/crypto/randomBytes';
|
|
5
5
|
import delay from 'delay';
|
|
6
6
|
import { NoDeviceFoundError, UserRefusedError } from '@exodus/hw-common';
|
|
7
7
|
export class HardwareWallets {
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { Atom } from '@exodus/atoms';
|
|
2
|
+
import type { Port } from '../shared/types';
|
|
3
|
+
import type { WalletAccountNameToConnectedAssetNamesMap } from '../atoms/index.js';
|
|
4
|
+
declare const hardwareWalletsPluginDefinition: {
|
|
5
|
+
readonly id: "hardwareWalletsPlugin";
|
|
6
|
+
readonly type: "plugin";
|
|
7
|
+
readonly factory: ({ hardwareWalletConnectedAssetNamesAtom, port, }: {
|
|
8
|
+
hardwareWalletConnectedAssetNamesAtom: Atom<WalletAccountNameToConnectedAssetNamesMap>;
|
|
9
|
+
port: Port;
|
|
10
|
+
}) => {
|
|
11
|
+
onUnlock: () => void;
|
|
12
|
+
onLoad: () => void;
|
|
13
|
+
onStop: () => void;
|
|
14
|
+
};
|
|
15
|
+
readonly dependencies: readonly ["hardwareWalletConnectedAssetNamesAtom", "port"];
|
|
16
|
+
};
|
|
17
|
+
export default hardwareWalletsPluginDefinition;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { createAtomObserver } from '@exodus/atoms';
|
|
2
|
+
const createHardwareWalletsPlugin = ({ hardwareWalletConnectedAssetNamesAtom, port, }) => {
|
|
3
|
+
const observers = [
|
|
4
|
+
createAtomObserver({
|
|
5
|
+
atom: hardwareWalletConnectedAssetNamesAtom,
|
|
6
|
+
port,
|
|
7
|
+
event: 'hardwareWalletConnectedAssetNames',
|
|
8
|
+
}),
|
|
9
|
+
];
|
|
10
|
+
observers.forEach((observer) => observer.register());
|
|
11
|
+
const start = () => {
|
|
12
|
+
observers.forEach((observer) => observer.start());
|
|
13
|
+
};
|
|
14
|
+
const stop = () => {
|
|
15
|
+
observers.forEach((observer) => observer.unregister());
|
|
16
|
+
};
|
|
17
|
+
const onUnlock = () => {
|
|
18
|
+
start();
|
|
19
|
+
};
|
|
20
|
+
const onLoad = () => {
|
|
21
|
+
start();
|
|
22
|
+
};
|
|
23
|
+
const onStop = () => {
|
|
24
|
+
stop();
|
|
25
|
+
};
|
|
26
|
+
return { onUnlock, onLoad, onStop };
|
|
27
|
+
};
|
|
28
|
+
const hardwareWalletsPluginDefinition = {
|
|
29
|
+
id: 'hardwareWalletsPlugin',
|
|
30
|
+
type: 'plugin',
|
|
31
|
+
factory: createHardwareWalletsPlugin,
|
|
32
|
+
dependencies: ['hardwareWalletConnectedAssetNamesAtom', 'port'],
|
|
33
|
+
};
|
|
34
|
+
export default hardwareWalletsPluginDefinition;
|
package/lib/redux/id.js
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { type HardwareWalletsState } from './initial-state.js';
|
|
2
|
+
declare const hardwareWalletsReduxDefinition: {
|
|
3
|
+
readonly id: "hardwareWallets";
|
|
4
|
+
readonly type: "redux-module";
|
|
5
|
+
readonly initialState: HardwareWalletsState;
|
|
6
|
+
readonly eventReducers: {
|
|
7
|
+
readonly hardwareWalletConnectedAssetNames: (state: HardwareWalletsState, payload: boolean) => {
|
|
8
|
+
walletAccountNameToConnectedAssetNamesMap: boolean;
|
|
9
|
+
};
|
|
10
|
+
};
|
|
11
|
+
readonly selectorDefinitions: {
|
|
12
|
+
readonly id: "isAssetNameConnectedForWalletAccount";
|
|
13
|
+
readonly selectorFactory: (selfSelector: any) => ({ walletAccountName, assetName }: {
|
|
14
|
+
walletAccountName: string;
|
|
15
|
+
assetName: string;
|
|
16
|
+
}) => import("reselect").OutputSelector<unknown, boolean, (res: HardwareWalletsState) => boolean>;
|
|
17
|
+
readonly dependencies: readonly [{
|
|
18
|
+
readonly selector: string;
|
|
19
|
+
}];
|
|
20
|
+
}[];
|
|
21
|
+
};
|
|
22
|
+
export default hardwareWalletsReduxDefinition;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import id from './id.js';
|
|
2
|
+
import initialState from './initial-state.js';
|
|
3
|
+
import selectorDefinitions from './selectors/index.js';
|
|
4
|
+
const hardwareWalletsReduxDefinition = {
|
|
5
|
+
id,
|
|
6
|
+
type: 'redux-module',
|
|
7
|
+
initialState,
|
|
8
|
+
eventReducers: {
|
|
9
|
+
hardwareWalletConnectedAssetNames: (state, payload) => ({
|
|
10
|
+
...state,
|
|
11
|
+
walletAccountNameToConnectedAssetNamesMap: payload,
|
|
12
|
+
}),
|
|
13
|
+
},
|
|
14
|
+
selectorDefinitions,
|
|
15
|
+
};
|
|
16
|
+
export default hardwareWalletsReduxDefinition;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { WalletAccountNameToConnectedAssetNamesMap } from '../atoms/index.js';
|
|
2
|
+
export type HardwareWalletsState = {
|
|
3
|
+
walletAccountNameToConnectedAssetNamesMap: WalletAccountNameToConnectedAssetNamesMap;
|
|
4
|
+
};
|
|
5
|
+
declare const initialState: HardwareWalletsState;
|
|
6
|
+
export default initialState;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
declare const hardwareWalletsSelectors: {
|
|
2
|
+
readonly id: "isAssetNameConnectedForWalletAccount";
|
|
3
|
+
readonly selectorFactory: (selfSelector: any) => ({ walletAccountName, assetName }: {
|
|
4
|
+
walletAccountName: string;
|
|
5
|
+
assetName: string;
|
|
6
|
+
}) => import("reselect").OutputSelector<unknown, boolean, (res: import("../initial-state.js").HardwareWalletsState) => boolean>;
|
|
7
|
+
readonly dependencies: readonly [{
|
|
8
|
+
readonly selector: string;
|
|
9
|
+
}];
|
|
10
|
+
}[];
|
|
11
|
+
export default hardwareWalletsSelectors;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { HardwareWalletsState } from '../initial-state.js';
|
|
2
|
+
type isAssetNameConnectedForWalletAccountParams = {
|
|
3
|
+
walletAccountName: string;
|
|
4
|
+
assetName: string;
|
|
5
|
+
};
|
|
6
|
+
declare const isAssetNameConnectedForWalletAccountSelectorDefinition: {
|
|
7
|
+
readonly id: "isAssetNameConnectedForWalletAccount";
|
|
8
|
+
readonly selectorFactory: (selfSelector: any) => ({ walletAccountName, assetName }: isAssetNameConnectedForWalletAccountParams) => import("reselect").OutputSelector<unknown, boolean, (res: HardwareWalletsState) => boolean>;
|
|
9
|
+
readonly dependencies: readonly [{
|
|
10
|
+
readonly selector: string;
|
|
11
|
+
}];
|
|
12
|
+
};
|
|
13
|
+
export default isAssetNameConnectedForWalletAccountSelectorDefinition;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { MY_STATE } from '@exodus/redux-dependency-injection';
|
|
2
|
+
import { createSelector } from 'reselect';
|
|
3
|
+
const selectorFactory = (selfSelector) => ({ walletAccountName, assetName }) => createSelector(selfSelector, ({ walletAccountNameToConnectedAssetNamesMap }) => walletAccountNameToConnectedAssetNamesMap[walletAccountName]?.includes(assetName) ?? false);
|
|
4
|
+
const isAssetNameConnectedForWalletAccountSelectorDefinition = {
|
|
5
|
+
id: 'isAssetNameConnectedForWalletAccount',
|
|
6
|
+
selectorFactory,
|
|
7
|
+
dependencies: [{ selector: MY_STATE }],
|
|
8
|
+
};
|
|
9
|
+
export default isAssetNameConnectedForWalletAccountSelectorDefinition;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@exodus/hardware-wallets",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.7.1",
|
|
4
4
|
"description": "An Exodus SDK feature that provides a high level abstraction for interacting with hardware wallet devices",
|
|
5
5
|
"author": "Exodus Movement, Inc.",
|
|
6
6
|
"repository": {
|
|
@@ -28,21 +28,24 @@
|
|
|
28
28
|
"prepublishOnly": "yarn run -T build --scope @exodus/hardware-wallets"
|
|
29
29
|
},
|
|
30
30
|
"dependencies": {
|
|
31
|
+
"@exodus/atoms": "^9.0.0",
|
|
32
|
+
"@exodus/basic-utils": "^3.2.0",
|
|
33
|
+
"@exodus/bip32": "^3.3.0",
|
|
34
|
+
"@exodus/crypto": "^1.0.0-rc.14",
|
|
31
35
|
"@exodus/hw-common": "^3.1.0",
|
|
32
36
|
"@exodus/models": "^12.0.1",
|
|
37
|
+
"@exodus/redux-dependency-injection": "^4.0.0",
|
|
33
38
|
"@exodus/wild-emitter": "^1.1.0",
|
|
34
39
|
"delay": "^5.0.0",
|
|
35
40
|
"minimalistic-assert": "^1.0.1",
|
|
36
|
-
"
|
|
41
|
+
"reselect": "^3.0.1"
|
|
37
42
|
},
|
|
38
43
|
"devDependencies": {
|
|
39
|
-
"@exodus/
|
|
40
|
-
"@exodus/dependency-types": "^2.1.0",
|
|
44
|
+
"@exodus/dependency-types": "workspace:^",
|
|
41
45
|
"@exodus/key-identifier": "^1.3.0",
|
|
42
|
-
"@exodus/logger": "
|
|
43
|
-
"@exodus/public-key-provider": "
|
|
44
|
-
"
|
|
45
|
-
"
|
|
46
|
-
}
|
|
47
|
-
"gitHead": "6a40d50082582568d68206d8926737eea560fa50"
|
|
46
|
+
"@exodus/logger": "workspace:^",
|
|
47
|
+
"@exodus/public-key-provider": "workspace:^",
|
|
48
|
+
"p-defer": "^4.0.1",
|
|
49
|
+
"redux": "^4.2.1"
|
|
50
|
+
}
|
|
48
51
|
}
|