@exodus/hardware-wallets 3.0.2 → 3.2.0

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,18 @@
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.2.0](https://github.com/ExodusMovement/exodus-hydra/compare/@exodus/hardware-wallets@3.1.0...@exodus/hardware-wallets@3.2.0) (2025-10-09)
7
+
8
+ ### Features
9
+
10
+ - feat: add trezor safe 7 support (#13965)
11
+
12
+ ## [3.1.0](https://github.com/ExodusMovement/exodus-hydra/compare/@exodus/hardware-wallets@3.0.2...@exodus/hardware-wallets@3.1.0) (2025-10-01)
13
+
14
+ ### Features
15
+
16
+ - feat(hardware-wallets): add baseAssetName to signRequest (#13962)
17
+
6
18
  ## [3.0.2](https://github.com/ExodusMovement/exodus-hydra/compare/@exodus/hardware-wallets@3.0.1...@exodus/hardware-wallets@3.0.2) (2025-08-08)
7
19
 
8
20
  ### Bug Fixes
@@ -23,6 +23,8 @@ declare const hardwareWalletsApiDefinition: {
23
23
  create: ({ syncedKeysId, isMultisig }: import("../module/interfaces.js").CreateParams) => Promise<import("libraries/models/lib/index.js").WalletAccount>;
24
24
  retrySigningRequest: (id: string) => Promise<void>;
25
25
  cancelSigningRequest: (id: string, fromUI: boolean) => Promise<void>;
26
+ submitPairingCode: ({ code }: import("../module/interfaces.js").ProcessPairingCodeParams) => Promise<any>;
27
+ clearPairingRequest: () => () => Promise<void>;
26
28
  };
27
29
  };
28
30
  readonly dependencies: readonly ["hardwareWallets", "txLogMonitors", "restoreProgressTracker"];
package/lib/api/index.js CHANGED
@@ -30,6 +30,8 @@ const createHardwareWalletsApi = ({ hardwareWallets, restoreProgressTracker, txL
30
30
  create: hardwareWallets.create,
31
31
  retrySigningRequest: hardwareWallets.retrySigningRequest,
32
32
  cancelSigningRequest: hardwareWallets.cancelSigningRequest,
33
+ submitPairingCode: hardwareWallets.submitPairingCode,
34
+ clearPairingRequest: () => hardwareWallets.clearPairingRequest,
33
35
  },
34
36
  };
35
37
  };
@@ -0,0 +1,6 @@
1
+ export declare const hardwareWalletPairingPromptAtomDefinition: {
2
+ readonly id: "hardwareWalletPairingPromptAtom";
3
+ readonly type: "atom";
4
+ readonly factory: () => import("@exodus/atoms").Atom<boolean>;
5
+ readonly public: true;
6
+ };
@@ -0,0 +1,9 @@
1
+ import { createInMemoryAtom } from '@exodus/atoms';
2
+ export const hardwareWalletPairingPromptAtomDefinition = {
3
+ id: 'hardwareWalletPairingPromptAtom',
4
+ type: 'atom',
5
+ factory: () => createInMemoryAtom({
6
+ defaultValue: false,
7
+ }),
8
+ public: true,
9
+ };
@@ -1,4 +1,5 @@
1
1
  export { hardwareWalletSigningRequestsAtomDefinition } from './hardwareWalletSigningRequestsAtom.js';
2
+ export { hardwareWalletPairingPromptAtomDefinition } from './hardwareWalletPairingPromptAtom.js';
2
3
  type WalletAccountName = string;
3
4
  type AssetName = string;
4
5
  export type WalletAccountNameToConnectedAssetNamesMap = Record<WalletAccountName, AssetName[]>;
@@ -2,6 +2,7 @@ import { combine, compute } from '@exodus/atoms';
2
2
  import { memoize } from '@exodus/basic-utils';
3
3
  import { HARDENED_OFFSET } from '@exodus/bip32';
4
4
  export { hardwareWalletSigningRequestsAtomDefinition } from './hardwareWalletSigningRequestsAtom.js';
5
+ export { hardwareWalletPairingPromptAtomDefinition } from './hardwareWalletPairingPromptAtom.js';
5
6
  export const createHardwareWalletConnectedAssetNamesAtom = ({ hardwareWalletPublicKeysAtom, assetsModule, walletAccountsAtom, availableAssetNamesAtom, }) => {
6
7
  const selector = memoize(({ hardwareWalletPublicKeys, walletAccounts, availableAssetNames }) => {
7
8
  const result = Object.create(null);
package/lib/index.d.ts CHANGED
@@ -26,6 +26,8 @@ declare const hardwareWallets: () => {
26
26
  create: ({ syncedKeysId, isMultisig }: import("./module/interfaces.js").CreateParams) => Promise<import("libraries/models/lib/index.js").WalletAccount>;
27
27
  retrySigningRequest: (id: string) => Promise<void>;
28
28
  cancelSigningRequest: (id: string, fromUI: boolean) => Promise<void>;
29
+ submitPairingCode: ({ code }: import("./module/interfaces.js").ProcessPairingCodeParams) => Promise<any>;
30
+ clearPairingRequest: () => () => Promise<void>;
29
31
  };
30
32
  };
31
33
  readonly dependencies: readonly ["hardwareWallets", "txLogMonitors", "restoreProgressTracker"];
@@ -35,7 +37,7 @@ declare const hardwareWallets: () => {
35
37
  readonly id: "hardwareWallets";
36
38
  readonly type: "module";
37
39
  readonly factory: (opts: import("./module/hardware-wallets.js").Dependencies) => import("./module/hardware-wallets.js").HardwareWallets;
38
- readonly dependencies: readonly ["assetsModule", "logger", "ledgerDiscovery", "publicKeyStore", "hardwareWalletSigningRequestsAtom", "wallet", "walletAccountsAtom", "walletAccounts"];
40
+ readonly dependencies: readonly ["assetsModule", "logger", "ledgerDiscovery", "trezorDiscovery", "publicKeyStore", "hardwareWalletSigningRequestsAtom", "hardwareWalletPairingPromptAtom", "wallet", "walletAccountsAtom", "walletAccounts"];
39
41
  readonly public: true;
40
42
  };
41
43
  }, {
@@ -53,20 +55,28 @@ declare const hardwareWallets: () => {
53
55
  readonly dependencies: readonly [];
54
56
  readonly public: false;
55
57
  };
58
+ }, {
59
+ readonly definition: {
60
+ readonly id: "hardwareWalletPairingPromptAtom";
61
+ readonly type: "atom";
62
+ readonly factory: () => import("libraries/atoms/lib/index.js").Atom<boolean>;
63
+ readonly public: true;
64
+ };
56
65
  }, {
57
66
  readonly definition: {
58
67
  readonly id: "hardwareWalletsPlugin";
59
68
  readonly type: "plugin";
60
- readonly factory: ({ hardwareWalletConnectedAssetNamesAtom, hardwareWalletSigningRequestsAtom, port, }: {
69
+ readonly factory: ({ hardwareWalletConnectedAssetNamesAtom, hardwareWalletSigningRequestsAtom, hardwareWalletPairingPromptAtom, port, }: {
61
70
  hardwareWalletConnectedAssetNamesAtom: import("libraries/atoms/lib/index.js").Atom<import("./atoms/index.js").WalletAccountNameToConnectedAssetNamesMap>;
62
71
  hardwareWalletSigningRequestsAtom: import("libraries/atoms/lib/index.js").Atom<import("./module/interfaces.js").SigningRequestState>;
72
+ hardwareWalletPairingPromptAtom: import("libraries/atoms/lib/index.js").Atom<boolean>;
63
73
  port: import("./shared/types.js").Port;
64
74
  }) => {
65
75
  onUnlock: () => void;
66
76
  onLoad: () => void;
67
77
  onStop: () => void;
68
78
  };
69
- readonly dependencies: readonly ["hardwareWalletConnectedAssetNamesAtom", "hardwareWalletSigningRequestsAtom", "port"];
79
+ readonly dependencies: readonly ["hardwareWalletConnectedAssetNamesAtom", "hardwareWalletSigningRequestsAtom", "hardwareWalletPairingPromptAtom", "port"];
70
80
  };
71
81
  }];
72
82
  };
package/lib/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import hardwareWalletsApiDefinition from './api/index.js';
2
2
  import hardwareWalletsModuleDefinition from './module/hardware-wallets.js';
3
- import { hardwareWalletConnectedAssetNamesAtomDefinition, hardwareWalletSigningRequestsAtomDefinition, } from './atoms/index.js';
3
+ import { hardwareWalletConnectedAssetNamesAtomDefinition, hardwareWalletSigningRequestsAtomDefinition, hardwareWalletPairingPromptAtomDefinition, } from './atoms/index.js';
4
4
  import hardwareWalletsPluginDefinition from './plugin/index.js';
5
5
  const hardwareWallets = () => {
6
6
  return {
@@ -18,6 +18,9 @@ const hardwareWallets = () => {
18
18
  {
19
19
  definition: hardwareWalletSigningRequestsAtomDefinition,
20
20
  },
21
+ {
22
+ definition: hardwareWalletPairingPromptAtomDefinition,
23
+ },
21
24
  {
22
25
  definition: hardwareWalletsPluginDefinition,
23
26
  },
@@ -1,6 +1,6 @@
1
1
  import { WalletAccount } from '@exodus/models';
2
2
  import Emitter from '@exodus/wild-emitter';
3
- import type { HardwareSignerProvider, CanAccessAssetParams, CreateParams, StoreSyncedKeysParams, ScanParams, SyncParams, EnsureApplicationIsOpenedParams, SignTransactionParams, ScanResult, SyncedKeysId, GetAddressParams, RequireDeviceForParams, SigningRequestState } from './interfaces.js';
3
+ import type { HardwareSignerProvider, CanAccessAssetParams, CreateParams, StoreSyncedKeysParams, ScanParams, SyncParams, EnsureApplicationIsOpenedParams, SignTransactionParams, ScanResult, SyncedKeysId, GetAddressParams, RequireDeviceForParams, ProcessPairingCodeParams, SigningRequestState } from './interfaces.js';
4
4
  import type { HardwareWalletDiscovery, SignMessageParams } from '@exodus/hw-common';
5
5
  import type { Atom } from '@exodus/atoms';
6
6
  import type { IPublicKeyStore } from '@exodus/public-key-provider/lib/module/store/types';
@@ -8,8 +8,13 @@ import type { Logger } from '@exodus/logger';
8
8
  export type Dependencies = {
9
9
  assetsModule: any;
10
10
  ledgerDiscovery: HardwareWalletDiscovery;
11
+ trezorDiscovery: HardwareWalletDiscovery & {
12
+ connected: boolean;
13
+ submitPairingCode: (code: string) => Promise<any>;
14
+ };
11
15
  logger: Logger;
12
16
  hardwareWalletSigningRequestsAtom: Atom<SigningRequestState>;
17
+ hardwareWalletPairingPromptAtom: Atom<boolean>;
13
18
  publicKeyStore: IPublicKeyStore;
14
19
  wallet: any;
15
20
  walletAccountsAtom: Atom<WalletAccount>;
@@ -20,7 +25,7 @@ export type Dependencies = {
20
25
  export declare class HardwareWallets implements HardwareSignerProvider {
21
26
  #private;
22
27
  readonly events: Emitter<string, any>;
23
- constructor({ assetsModule, ledgerDiscovery, logger, hardwareWalletSigningRequestsAtom, publicKeyStore, wallet, walletAccountsAtom, walletAccounts, }: Dependencies);
28
+ constructor({ assetsModule, ledgerDiscovery, trezorDiscovery, logger, hardwareWalletSigningRequestsAtom, hardwareWalletPairingPromptAtom, publicKeyStore, wallet, walletAccountsAtom, walletAccounts, }: Dependencies);
24
29
  retrySigningRequest: (id: string) => Promise<void>;
25
30
  cancelSigningRequest: (id: string, fromUI: boolean) => Promise<void>;
26
31
  signTransaction: ({ baseAssetName, unsignedTx, walletAccount, multisigData, }: SignTransactionParams) => Promise<any>;
@@ -39,6 +44,8 @@ export declare class HardwareWallets implements HardwareSignerProvider {
39
44
  sync: ({ accountIndex: index, isMultisig }?: SyncParams) => Promise<SyncedKeysId>;
40
45
  addPublicKeysToWalletAccount: ({ walletAccount, syncedKeysId }: StoreSyncedKeysParams) => Promise<void>;
41
46
  create: ({ syncedKeysId, isMultisig }: CreateParams) => Promise<WalletAccount>;
47
+ clearPairingRequest: () => Promise<void>;
48
+ submitPairingCode: ({ code }: ProcessPairingCodeParams) => Promise<any>;
42
49
  requireDeviceFor: ({ walletAccount }: RequireDeviceForParams) => Promise<{
43
50
  signTransaction: ({ baseAssetName, unsignedTx, walletAccount, multisigData, }: SignTransactionParams) => Promise<any>;
44
51
  signMessage: ({ assetName, derivationPath, message }: SignMessageParams) => Promise<any>;
@@ -48,7 +55,7 @@ declare const hardwareWalletsModuleDefinition: {
48
55
  readonly id: "hardwareWallets";
49
56
  readonly type: "module";
50
57
  readonly factory: (opts: Dependencies) => HardwareWallets;
51
- readonly dependencies: readonly ["assetsModule", "logger", "ledgerDiscovery", "publicKeyStore", "hardwareWalletSigningRequestsAtom", "wallet", "walletAccountsAtom", "walletAccounts"];
58
+ readonly dependencies: readonly ["assetsModule", "logger", "ledgerDiscovery", "trezorDiscovery", "publicKeyStore", "hardwareWalletSigningRequestsAtom", "hardwareWalletPairingPromptAtom", "wallet", "walletAccountsAtom", "walletAccounts"];
52
59
  readonly public: true;
53
60
  };
54
61
  export default hardwareWalletsModuleDefinition;
@@ -9,27 +9,35 @@ import pDefer from 'p-defer';
9
9
  export class HardwareWallets {
10
10
  #assetsModule;
11
11
  #ledgerDiscovery;
12
+ #trezorDiscovery;
12
13
  #logger;
13
14
  #publicKeyStore;
14
15
  #signingRequestAtom;
16
+ #pairingPromptAtom;
15
17
  #wallet;
16
18
  #walletAccountsAtom;
17
19
  #walletAccounts;
18
20
  #syncedKeysMap = new Map();
19
21
  #signingRequest;
20
22
  events = new Emitter();
21
- constructor({ assetsModule, ledgerDiscovery, logger, hardwareWalletSigningRequestsAtom, publicKeyStore, wallet, walletAccountsAtom, walletAccounts, }) {
23
+ constructor({ assetsModule, ledgerDiscovery, trezorDiscovery, logger, hardwareWalletSigningRequestsAtom, hardwareWalletPairingPromptAtom, publicKeyStore, wallet, walletAccountsAtom, walletAccounts, }) {
22
24
  this.#assetsModule = assetsModule;
23
25
  this.#ledgerDiscovery = ledgerDiscovery;
26
+ this.#trezorDiscovery = trezorDiscovery;
24
27
  this.#logger = logger;
25
28
  this.#publicKeyStore = publicKeyStore;
26
29
  this.#signingRequestAtom = hardwareWalletSigningRequestsAtom;
30
+ this.#pairingPromptAtom = hardwareWalletPairingPromptAtom;
27
31
  this.#wallet = wallet;
28
32
  this.#walletAccountsAtom = walletAccountsAtom;
29
33
  this.#walletAccounts = walletAccounts;
30
34
  }
31
35
  #getSelectedDevice = async () => {
32
- const descriptors = await this.#ledgerDiscovery.list();
36
+ const [trezors, ledgers] = await Promise.all([
37
+ this.#trezorDiscovery.list().catch(() => []),
38
+ this.#ledgerDiscovery.list().catch(() => []),
39
+ ]);
40
+ const descriptors = [...trezors, ...ledgers];
33
41
  if (descriptors[0]) {
34
42
  return { device: await descriptors[0].get() };
35
43
  }
@@ -84,6 +92,7 @@ export class HardwareWallets {
84
92
  id,
85
93
  scenario: 'error',
86
94
  error: _error,
95
+ baseAssetName: this.#signingRequest.baseAssetName,
87
96
  });
88
97
  }
89
98
  };
@@ -114,6 +123,7 @@ export class HardwareWallets {
114
123
  const deferred = pDefer();
115
124
  this.#signingRequest = {
116
125
  id,
126
+ baseAssetName,
117
127
  sign: async ({ device }) => {
118
128
  await this.#updateSigningRequest({
119
129
  id,
@@ -154,6 +164,9 @@ export class HardwareWallets {
154
164
  return this.#signGeneric({ baseAssetName, scenario: 'signMessage', sign });
155
165
  };
156
166
  isDeviceConnected = async () => {
167
+ if (this.#trezorDiscovery.connected) {
168
+ return true;
169
+ }
157
170
  try {
158
171
  const devices = await this.#ledgerDiscovery.list();
159
172
  return devices.length > 0;
@@ -163,12 +176,16 @@ export class HardwareWallets {
163
176
  }
164
177
  };
165
178
  scanForDevices = async () => {
179
+ this.#trezorDiscovery.stopScan(true);
166
180
  this.#ledgerDiscovery.stopScan(true);
167
- return this.#ledgerDiscovery.scan();
181
+ await Promise.all([this.#ledgerDiscovery.scan(), this.#trezorDiscovery.scan()]);
168
182
  };
169
183
  getAvailableDevices = async () => {
170
- const devices = await this.#ledgerDiscovery.list();
171
- return devices.map((device) => ({
184
+ const [ledgers, trezors] = await Promise.all([
185
+ this.#ledgerDiscovery.list().catch(() => []),
186
+ this.#trezorDiscovery.list().catch(() => []),
187
+ ]);
188
+ return [...ledgers, ...trezors].map((device) => ({
172
189
  model: device.model,
173
190
  name: device.name,
174
191
  }));
@@ -202,18 +219,18 @@ export class HardwareWallets {
202
219
  };
203
220
  getAddress = async ({ assetName, accountIndex, addressIndex, multisigData, displayOnDevice, }) => {
204
221
  const asset = this.#assetsModule.getAsset(assetName);
222
+ const { device } = await this.#getSelectedDevice();
205
223
  const supportedPurposes = asset.baseAsset.api.getSupportedPurposes({
206
- compatibilityMode: 'ledger',
224
+ compatibilityMode: device.descriptor.manufacturer,
207
225
  isMultisig: !!multisigData,
208
226
  });
209
227
  const { derivationPath } = asset.baseAsset.api.getKeyIdentifier({
210
- compatibilityMode: 'ledger',
228
+ compatibilityMode: device.descriptor.manufacturer,
211
229
  purpose: supportedPurposes[0],
212
230
  accountIndex,
213
231
  chainIndex: 0,
214
232
  addressIndex,
215
233
  });
216
- const { device } = await this.#getSelectedDevice();
217
234
  return device.getAddress({
218
235
  assetName,
219
236
  derivationPath,
@@ -224,7 +241,7 @@ export class HardwareWallets {
224
241
  #getXPUB = async ({ device, baseAsset, purpose, accountIndex, }) => {
225
242
  try {
226
243
  const keyIdentifier = baseAsset.api.getKeyIdentifier({
227
- compatibilityMode: 'ledger',
244
+ compatibilityMode: device.descriptor.manufacturer,
228
245
  purpose,
229
246
  accountIndex,
230
247
  chainIndex: undefined,
@@ -242,7 +259,8 @@ export class HardwareWallets {
242
259
  }
243
260
  catch (error) {
244
261
  if (error.name === 'XPubUnsupportedError' ||
245
- error.message.includes(`XPUB derivation is not allowed`)) {
262
+ error.message.includes(`XPUB derivation is not allowed`) ||
263
+ error.message.includes('getXPub not supported')) {
246
264
  this.#logger.warn(`Retrieving XPUBs for ${baseAsset.name} is not supported`, error);
247
265
  return null;
248
266
  }
@@ -251,7 +269,7 @@ export class HardwareWallets {
251
269
  };
252
270
  #getPublicKey = async ({ device, baseAsset, purpose, accountIndex, }) => {
253
271
  const keyIdentifier = baseAsset.api.getKeyIdentifier({
254
- compatibilityMode: 'ledger',
272
+ compatibilityMode: device.descriptor.manufacturer,
255
273
  purpose,
256
274
  accountIndex,
257
275
  });
@@ -288,11 +306,13 @@ export class HardwareWallets {
288
306
  return addressToBalanceMap;
289
307
  };
290
308
  scan = async ({ assetName, accountIndexes, addressLimit = 2, addressOffset = 0, }) => {
309
+ const { device } = await this.#getSelectedDevice();
310
+ const source = device.descriptor.manufacturer;
291
311
  let usedAccountIndexes = [];
292
312
  if (await this.#wallet.exists()) {
293
313
  const walletAccounts = Object.values(await this.#walletAccountsAtom.get());
294
314
  usedAccountIndexes = walletAccounts
295
- .filter(({ source }) => source === WalletAccount.LEDGER_SRC)
315
+ .filter(({ source: s }) => source === s)
296
316
  .map(({ index }) => index);
297
317
  }
298
318
  const accounts = accountIndexes.map((accountIndex) => ({ accountIndex }));
@@ -311,7 +331,8 @@ export class HardwareWallets {
311
331
  sync = async ({ accountIndex: index, isMultisig } = {}) => {
312
332
  const keysToSync = [];
313
333
  const { device } = await this.#getSelectedDevice();
314
- const accountIndex = index ?? this.#walletAccounts.getNextIndex({ source: WalletAccount.LEDGER_SRC });
334
+ const source = device.descriptor.manufacturer;
335
+ const accountIndex = index ?? this.#walletAccounts.getNextIndex({ source });
315
336
  const useableAssetNames = new Set(await device.listUseableAssetNames());
316
337
  for (const assetName of useableAssetNames) {
317
338
  const asset = this.#assetsModule.getAsset(assetName);
@@ -321,7 +342,7 @@ export class HardwareWallets {
321
342
  }
322
343
  const baseAsset = asset.baseAsset;
323
344
  const supportedPurposes = baseAsset.api.getSupportedPurposes({
324
- compatibilityMode: 'ledger',
345
+ compatibilityMode: source,
325
346
  isMultisig,
326
347
  });
327
348
  for (const purpose of supportedPurposes) {
@@ -350,11 +371,14 @@ export class HardwareWallets {
350
371
  };
351
372
  create = async ({ syncedKeysId, isMultisig }) => {
352
373
  assert(this.#syncedKeysMap.has(syncedKeysId), `no synchronized keys found for id ${syncedKeysId}`);
374
+ const { device } = await this.#getSelectedDevice();
375
+ const source = device.descriptor.manufacturer;
376
+ const label = source === WalletAccount.LEDGER_SRC ? 'Ledger' : 'Trezor';
353
377
  const { accountIndex, model } = this.#syncedKeysMap.get(syncedKeysId);
354
378
  const walletAccount = new WalletAccount({
355
- label: `Ledger${accountIndex === 0 ? '' : ' ' + accountIndex}`,
356
- icon: 'ledger',
357
- source: WalletAccount.LEDGER_SRC,
379
+ label: `${label}${accountIndex === 0 ? '' : '_' + accountIndex}`,
380
+ icon: source,
381
+ source,
358
382
  model,
359
383
  index: accountIndex,
360
384
  id: randomBytes(32).toString('hex'),
@@ -366,6 +390,12 @@ export class HardwareWallets {
366
390
  await this.addPublicKeysToWalletAccount({ walletAccount, syncedKeysId });
367
391
  return walletAccount;
368
392
  };
393
+ clearPairingRequest = async () => {
394
+ await this.#pairingPromptAtom.set(false);
395
+ };
396
+ submitPairingCode = async ({ code }) => {
397
+ return this.#trezorDiscovery.submitPairingCode(code);
398
+ };
369
399
  requireDeviceFor = async ({ walletAccount }) => {
370
400
  return {
371
401
  signTransaction: this.signTransaction,
@@ -382,8 +412,10 @@ const hardwareWalletsModuleDefinition = {
382
412
  'assetsModule',
383
413
  'logger',
384
414
  'ledgerDiscovery',
415
+ 'trezorDiscovery',
385
416
  'publicKeyStore',
386
417
  'hardwareWalletSigningRequestsAtom',
418
+ 'hardwareWalletPairingPromptAtom',
387
419
  'wallet',
388
420
  'walletAccountsAtom',
389
421
  'walletAccounts',
@@ -13,6 +13,7 @@ export interface HardwareSignerProvider {
13
13
  create: ({ syncedKeysId, isMultisig }: CreateParams) => Promise<WalletAccount>;
14
14
  signTransaction: ({ baseAssetName, unsignedTx, walletAccount, }: SignTransactionParams) => Promise<any>;
15
15
  signMessage: ({ assetName, derivationPath, message }: SignMessageParams) => Promise<any>;
16
+ submitPairingCode: ({ code }: ProcessPairingCodeParams) => Promise<any>;
16
17
  }
17
18
  type Asset = {
18
19
  name: string;
@@ -92,6 +93,7 @@ export interface SigningRequestState {
92
93
  }
93
94
  export interface SigningRequest {
94
95
  id: string;
96
+ baseAssetName?: string;
95
97
  sign: GenericSignCallback;
96
98
  resolve: (result: any) => void;
97
99
  reject: (error: Error) => void;
@@ -141,4 +143,7 @@ export type FetchBalanceResult = any | null;
141
143
  export interface RequireDeviceForParams {
142
144
  walletAccount: WalletAccount;
143
145
  }
146
+ export interface ProcessPairingCodeParams {
147
+ code: string;
148
+ }
144
149
  export {};
@@ -5,15 +5,16 @@ import type { SigningRequestState } from '../module/interfaces.js';
5
5
  declare const hardwareWalletsPluginDefinition: {
6
6
  readonly id: "hardwareWalletsPlugin";
7
7
  readonly type: "plugin";
8
- readonly factory: ({ hardwareWalletConnectedAssetNamesAtom, hardwareWalletSigningRequestsAtom, port, }: {
8
+ readonly factory: ({ hardwareWalletConnectedAssetNamesAtom, hardwareWalletSigningRequestsAtom, hardwareWalletPairingPromptAtom, port, }: {
9
9
  hardwareWalletConnectedAssetNamesAtom: Atom<WalletAccountNameToConnectedAssetNamesMap>;
10
10
  hardwareWalletSigningRequestsAtom: Atom<SigningRequestState>;
11
+ hardwareWalletPairingPromptAtom: Atom<boolean>;
11
12
  port: Port;
12
13
  }) => {
13
14
  onUnlock: () => void;
14
15
  onLoad: () => void;
15
16
  onStop: () => void;
16
17
  };
17
- readonly dependencies: readonly ["hardwareWalletConnectedAssetNamesAtom", "hardwareWalletSigningRequestsAtom", "port"];
18
+ readonly dependencies: readonly ["hardwareWalletConnectedAssetNamesAtom", "hardwareWalletSigningRequestsAtom", "hardwareWalletPairingPromptAtom", "port"];
18
19
  };
19
20
  export default hardwareWalletsPluginDefinition;
@@ -1,5 +1,5 @@
1
1
  import { createAtomObserver } from '@exodus/atoms';
2
- const createHardwareWalletsPlugin = ({ hardwareWalletConnectedAssetNamesAtom, hardwareWalletSigningRequestsAtom, port, }) => {
2
+ const createHardwareWalletsPlugin = ({ hardwareWalletConnectedAssetNamesAtom, hardwareWalletSigningRequestsAtom, hardwareWalletPairingPromptAtom, port, }) => {
3
3
  const observers = [
4
4
  createAtomObserver({
5
5
  atom: hardwareWalletConnectedAssetNamesAtom,
@@ -11,6 +11,11 @@ const createHardwareWalletsPlugin = ({ hardwareWalletConnectedAssetNamesAtom, ha
11
11
  port,
12
12
  event: 'hardwareWalletSigningRequests',
13
13
  }),
14
+ createAtomObserver({
15
+ atom: hardwareWalletPairingPromptAtom,
16
+ port,
17
+ event: 'hardwareWalletPairingPrompt',
18
+ }),
14
19
  ];
15
20
  observers.forEach((observer) => observer.register());
16
21
  const start = () => {
@@ -37,6 +42,7 @@ const hardwareWalletsPluginDefinition = {
37
42
  dependencies: [
38
43
  'hardwareWalletConnectedAssetNamesAtom',
39
44
  'hardwareWalletSigningRequestsAtom',
45
+ 'hardwareWalletPairingPromptAtom',
40
46
  'port',
41
47
  ],
42
48
  };
@@ -8,24 +8,25 @@ declare const hardwareWalletsReduxDefinition: {
8
8
  readonly hardwareWalletConnectedAssetNames: (state: HardwareWalletsState, payload: boolean) => {
9
9
  walletAccountNameToConnectedAssetNamesMap: boolean;
10
10
  signingRequests: SigningRequestState;
11
+ pairingPrompt: boolean;
11
12
  };
12
13
  readonly hardwareWalletSigningRequests: (state: HardwareWalletsState, payload: SigningRequestState) => {
13
14
  signingRequests: SigningRequestState;
14
15
  walletAccountNameToConnectedAssetNamesMap: import("../atoms/index.js").WalletAccountNameToConnectedAssetNamesMap;
16
+ pairingPrompt: boolean;
17
+ };
18
+ readonly hardwareWalletPairingPrompt: (state: HardwareWalletsState, payload: boolean) => {
19
+ pairingPrompt: boolean;
20
+ walletAccountNameToConnectedAssetNamesMap: import("../atoms/index.js").WalletAccountNameToConnectedAssetNamesMap;
21
+ signingRequests: SigningRequestState;
15
22
  };
16
23
  };
17
- readonly selectorDefinitions: ({
24
+ readonly selectorDefinitions: {
18
25
  readonly id: "isAssetNameConnectedForWalletAccount";
19
26
  readonly selectorFactory: (selfSelector: any) => any;
20
27
  readonly dependencies: readonly [{
21
28
  readonly selector: string;
22
29
  }];
23
- } | {
24
- readonly id: "getSigningRequests";
25
- readonly resultFunction: (self: HardwareWalletsState) => SigningRequestState;
26
- readonly dependencies: readonly [{
27
- readonly selector: string;
28
- }];
29
- })[];
30
+ }[];
30
31
  };
31
32
  export default hardwareWalletsReduxDefinition;
@@ -14,6 +14,10 @@ const hardwareWalletsReduxDefinition = {
14
14
  ...state,
15
15
  signingRequests: payload,
16
16
  }),
17
+ hardwareWalletPairingPrompt: (state, payload) => ({
18
+ ...state,
19
+ pairingPrompt: payload,
20
+ }),
17
21
  },
18
22
  selectorDefinitions,
19
23
  };
@@ -3,6 +3,7 @@ import type { SigningRequestState } from '../module/interfaces.js';
3
3
  export type HardwareWalletsState = {
4
4
  walletAccountNameToConnectedAssetNamesMap: WalletAccountNameToConnectedAssetNamesMap;
5
5
  signingRequests: SigningRequestState;
6
+ pairingPrompt: boolean;
6
7
  };
7
8
  declare const initialState: HardwareWalletsState;
8
9
  export default initialState;
@@ -1,5 +1,6 @@
1
1
  const initialState = {
2
2
  walletAccountNameToConnectedAssetNamesMap: Object.create(null),
3
3
  signingRequests: Object.create(null),
4
+ pairingPrompt: false,
4
5
  };
5
6
  export default initialState;
@@ -1,14 +1,8 @@
1
- declare const hardwareWalletsSelectors: ({
1
+ declare const hardwareWalletsSelectors: {
2
2
  readonly id: "isAssetNameConnectedForWalletAccount";
3
3
  readonly selectorFactory: (selfSelector: any) => any;
4
4
  readonly dependencies: readonly [{
5
5
  readonly selector: string;
6
6
  }];
7
- } | {
8
- readonly id: "getSigningRequests";
9
- readonly resultFunction: (self: import("../initial-state.js").HardwareWalletsState) => import("../../module/interfaces.js").SigningRequestState;
10
- readonly dependencies: readonly [{
11
- readonly selector: string;
12
- }];
13
- })[];
7
+ }[];
14
8
  export default hardwareWalletsSelectors;
@@ -1,7 +1,3 @@
1
1
  import isAssetNameConnectedForWalletAccountSelectorDefinition from './isAssetNameConnectedForWalletAccount.js';
2
- import getSigningRequests from './getSigningRequests.js';
3
- const hardwareWalletsSelectors = [
4
- isAssetNameConnectedForWalletAccountSelectorDefinition,
5
- getSigningRequests,
6
- ];
2
+ const hardwareWalletsSelectors = [isAssetNameConnectedForWalletAccountSelectorDefinition];
7
3
  export default hardwareWalletsSelectors;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@exodus/hardware-wallets",
3
- "version": "3.0.2",
3
+ "version": "3.2.0",
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": {
@@ -32,7 +32,7 @@
32
32
  "@exodus/basic-utils": "^3.2.0",
33
33
  "@exodus/bip32": "^4.0.2",
34
34
  "@exodus/crypto": "^1.0.0-rc.14",
35
- "@exodus/hw-common": "^3.1.0",
35
+ "@exodus/hw-common": "^3.2.0",
36
36
  "@exodus/models": "^12.11.0",
37
37
  "@exodus/redux-dependency-injection": "^4.0.0",
38
38
  "@exodus/wild-emitter": "^1.1.0",
@@ -50,7 +50,8 @@
50
50
  "redux": "^4.2.1"
51
51
  },
52
52
  "publishConfig": {
53
- "access": "public"
53
+ "access": "public",
54
+ "provenance": false
54
55
  },
55
- "gitHead": "918fd19c3b78e2400f8e98a0e4d6a3cb79368e61"
56
+ "gitHead": "842023663c2b9fa3dce880a297e7f5a76446a684"
56
57
  }
@@ -1,9 +0,0 @@
1
- import type { HardwareWalletsState } from '../initial-state.js';
2
- declare const assetDataSelectorDefinition: {
3
- readonly id: "getSigningRequests";
4
- readonly resultFunction: (self: HardwareWalletsState) => import("../../module/interfaces.js").SigningRequestState;
5
- readonly dependencies: readonly [{
6
- readonly selector: string;
7
- }];
8
- };
9
- export default assetDataSelectorDefinition;
@@ -1,8 +0,0 @@
1
- import { MY_STATE } from '@exodus/redux-dependency-injection';
2
- const resultFunction = (self) => self.signingRequests;
3
- const assetDataSelectorDefinition = {
4
- id: 'getSigningRequests',
5
- resultFunction,
6
- dependencies: [{ selector: MY_STATE }],
7
- };
8
- export default assetDataSelectorDefinition;