Skip to content

Commit d7d5505

Browse files
feat(extension,cardano,core): LW-9808 revamp hardware wallet onboarding (#1020)
* feat(extension,cardano,core): revamp hardware wallet connection in onboarding * feat(extension,cardano,staking): bump hardware-ledger, web-extension and wallet SDK packages * feat(extension): changes after self review * feat(extension): improve error cases * feat(extension): improve error handling in creation and reorganize the code * feat(cardano): allow only supported ledger devices * test(extension): fix unit tests of useWalletManager hook * refactor(extension): use enums insted of string unions * feat(extension): update hw walet creation generic error message * feat(extension,cardano,core): add unit tests, restrict allowed HW devices * refactor(extension): remove redundant eslint disable comment * fix(extension): fix typo --------- Co-authored-by: Emir Hodzic <emir.hodzich@gmail.com>
1 parent 19f1506 commit d7d5505

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+1023
-687
lines changed

apps/browser-extension-wallet/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,8 @@
4545
"@cardano-sdk/input-selection": "0.12.26",
4646
"@cardano-sdk/tx-construction": "0.18.2",
4747
"@cardano-sdk/util": "0.15.0",
48-
"@cardano-sdk/wallet": "0.35.2",
49-
"@cardano-sdk/web-extension": "0.26.1",
48+
"@cardano-sdk/wallet": "0.36.0",
49+
"@cardano-sdk/web-extension": "0.26.2",
5050
"@emurgo/cip14-js": "~3.0.1",
5151
"@koralabs/handles-public-api-interfaces": "^1.6.6",
5252
"@lace/cardano": "0.1.0",

apps/browser-extension-wallet/src/hooks/__tests__/useWalletManager.test.tsx

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import SpyInstance = jest.SpyInstance;
1313
const mockEmip3decrypt = jest.fn();
1414
const mockEmip3encrypt = jest.fn();
1515
const mockConnectDevice = jest.fn();
16+
const mockGetHwExtendedAccountPublicKey = jest.fn();
1617
const mockRestoreWalletFromKeyAgent = jest.fn();
1718
const mockSwitchKeyAgents = jest.fn();
1819
const mockLedgerCheckDeviceConnection = jest.fn();
@@ -80,6 +81,7 @@ jest.mock('@lace/cardano', () => {
8081
restoreWalletFromKeyAgent: mockRestoreWalletFromKeyAgent,
8182
switchKeyAgents: mockSwitchKeyAgents,
8283
connectDevice: mockConnectDevice,
84+
getHwExtendedAccountPublicKey: mockGetHwExtendedAccountPublicKey,
8385
KeyManagement: {
8486
...actual.Wallet.KeyManagement,
8587
emip3decrypt: mockEmip3decrypt,
@@ -382,7 +384,7 @@ describe('Testing useWalletManager hook', () => {
382384
describe('createHardwareWallet', () => {
383385
test('should use cardano manager to create wallet', async () => {
384386
const walletId = 'walletId';
385-
mockLedgerGetXpub.mockResolvedValue('pubkey');
387+
mockGetHwExtendedAccountPublicKey.mockResolvedValue('pubkey');
386388
(walletApiUi.walletRepository as any).addWallet = jest.fn().mockResolvedValue(walletId);
387389
(walletApiUi.walletRepository as any).addAccount = jest.fn().mockResolvedValue(undefined);
388390
(walletApiUi.walletManager as any).activate = jest.fn().mockResolvedValue(undefined);
@@ -696,11 +698,11 @@ describe('Testing useWalletManager hook', () => {
696698
},
697699
{
698700
type: WalletType.Trezor,
699-
prepare: () => mockTrezorGetXpub.mockResolvedValueOnce(extendedAccountPublicKey)
701+
prepare: () => mockGetHwExtendedAccountPublicKey.mockResolvedValueOnce(extendedAccountPublicKey)
700702
},
701703
{
702704
type: WalletType.Ledger,
703-
prepare: () => mockLedgerGetXpub.mockResolvedValueOnce(extendedAccountPublicKey)
705+
prepare: () => mockGetHwExtendedAccountPublicKey.mockResolvedValueOnce(extendedAccountPublicKey)
704706
}
705707
];
706708

apps/browser-extension-wallet/src/hooks/useWalletManager.ts

Lines changed: 51 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -44,12 +44,6 @@ export interface CreateWallet {
4444
chainId?: Wallet.Cardano.ChainId;
4545
}
4646

47-
export interface SetWallet {
48-
walletInstance: Wallet.CardanoWallet;
49-
chainName?: Wallet.ChainName;
50-
mnemonicVerificationFrequency?: string;
51-
}
52-
5347
export interface CreateHardwareWallet {
5448
accountIndex?: number;
5549
name: string;
@@ -66,6 +60,14 @@ type WalletManagerAddAccountProps = {
6660

6761
type ActivateWalletProps = Omit<WalletManagerActivateProps, 'chainId'>;
6862

63+
type CreateHardwareWalletRevampedParams = {
64+
accountIndex: number;
65+
name: string;
66+
connection: Wallet.HardwareWalletConnection;
67+
};
68+
69+
type CreateHardwareWalletRevamped = (params: CreateHardwareWalletRevampedParams) => Promise<Wallet.CardanoWallet>;
70+
6971
export interface UseWalletManager {
7072
walletManager: WalletManagerApi;
7173
walletRepository: WalletRepositoryApi<Wallet.WalletMetadata, Wallet.AccountMetadata>;
@@ -78,7 +80,9 @@ export interface UseWalletManager {
7880
createWallet: (args: CreateWallet) => Promise<Wallet.CardanoWallet>;
7981
activateWallet: (args: Omit<WalletManagerActivateProps, 'chainId'>) => Promise<void>;
8082
createHardwareWallet: (args: CreateHardwareWallet) => Promise<Wallet.CardanoWallet>;
83+
createHardwareWalletRevamped: CreateHardwareWalletRevamped;
8184
connectHardwareWallet: (model: Wallet.HardwareWallets) => Promise<Wallet.DeviceConnection>;
85+
connectHardwareWalletRevamped: typeof connectHardwareWalletRevamped;
8286
saveHardwareWallet: (wallet: Wallet.CardanoWallet, chainName?: Wallet.ChainName) => Promise<void>;
8387
/**
8488
* @returns active wallet id after deleting the wallet; undefined if deleted the last wallet
@@ -95,27 +99,6 @@ const clearBytes = (bytes: Uint8Array) => {
9599
}
96100
};
97101

98-
const getHwExtendedAccountPublicKey = async (
99-
walletType: Wallet.HardwareWallets,
100-
accountIndex: number,
101-
deviceConnection?: Wallet.DeviceConnection
102-
) => {
103-
switch (walletType) {
104-
case WalletType.Ledger:
105-
await Wallet.Ledger.LedgerKeyAgent.checkDeviceConnection(Wallet.KeyManagement.CommunicationType.Web);
106-
return Wallet.Ledger.LedgerKeyAgent.getXpub({
107-
communicationType: Wallet.KeyManagement.CommunicationType.Web,
108-
deviceConnection: typeof deviceConnection !== 'boolean' ? deviceConnection : undefined,
109-
accountIndex
110-
});
111-
case WalletType.Trezor:
112-
return Wallet.Trezor.TrezorKeyAgent.getXpub({
113-
communicationType: Wallet.KeyManagement.CommunicationType.Web,
114-
accountIndex
115-
});
116-
}
117-
};
118-
119102
const getExtendedAccountPublicKey = async (
120103
wallet: AnyBip32Wallet<Wallet.WalletMetadata, Wallet.AccountMetadata>,
121104
accountIndex: number,
@@ -143,7 +126,7 @@ const getExtendedAccountPublicKey = async (
143126
}
144127
case WalletType.Ledger:
145128
case WalletType.Trezor:
146-
return getHwExtendedAccountPublicKey(wallet.type, accountIndex);
129+
return Wallet.getHwExtendedAccountPublicKey(wallet.type, accountIndex);
147130
}
148131
};
149132

@@ -210,6 +193,9 @@ const encryptMnemonic = async (mnemonic: string[], passphrase: Uint8Array) => {
210193
export const connectHardwareWallet = async (model: Wallet.HardwareWallets): Promise<Wallet.DeviceConnection> =>
211194
await Wallet.connectDevice(model);
212195

196+
const connectHardwareWalletRevamped = async (usbDevice: USBDevice): Promise<Wallet.HardwareWalletConnection> =>
197+
Wallet.connectDeviceRevamped(usbDevice);
198+
213199
export const useWalletManager = (): UseWalletManager => {
214200
const {
215201
walletLock,
@@ -241,25 +227,21 @@ export const useWalletManager = (): UseWalletManager => {
241227
return (storedChain?.chainName && chainIdFromName(storedChain.chainName)) || DEFAULT_CHAIN_ID;
242228
}, [currentChain]);
243229

244-
/**
245-
* Creates a Ledger or Trezor hardware wallet
246-
* and saves it in browser storage with the data to lock/unlock it
247-
*/
248-
const createHardwareWallet = useCallback(
249-
async ({
250-
accountIndex = 0,
251-
deviceConnection,
252-
name,
253-
connectedDevice
254-
}: CreateHardwareWallet): Promise<Wallet.CardanoWallet> => {
255-
const extendedAccountPublicKey = await getHwExtendedAccountPublicKey(
256-
connectedDevice,
257-
accountIndex,
258-
deviceConnection
259-
);
230+
const createHardwareWalletRevamped = useCallback<CreateHardwareWalletRevamped>(
231+
async ({ accountIndex, connection, name }) => {
232+
let extendedAccountPublicKey;
233+
try {
234+
extendedAccountPublicKey = await Wallet.getHwExtendedAccountPublicKey(
235+
connection.type,
236+
accountIndex,
237+
connection.type === WalletType.Ledger ? connection.value : undefined
238+
);
239+
} catch (error: unknown) {
240+
throw error;
241+
}
260242
const addWalletProps: AddWalletProps<Wallet.WalletMetadata, Wallet.AccountMetadata> = {
261243
metadata: { name, lastActiveAccountIndex: accountIndex },
262-
type: connectedDevice,
244+
type: connection.type,
263245
accounts: [
264246
{
265247
extendedAccountPublicKey,
@@ -291,6 +273,28 @@ export const useWalletManager = (): UseWalletManager => {
291273
[getCurrentChainId]
292274
);
293275

276+
/**
277+
* Creates a Ledger or Trezor hardware wallet
278+
* and saves it in browser storage with the data to lock/unlock it
279+
*/
280+
const createHardwareWallet = useCallback(
281+
async ({
282+
accountIndex = 0,
283+
deviceConnection,
284+
name,
285+
connectedDevice
286+
}: CreateHardwareWallet): Promise<Wallet.CardanoWallet> =>
287+
createHardwareWalletRevamped({
288+
accountIndex,
289+
connection: {
290+
type: connectedDevice,
291+
value: typeof deviceConnection !== 'boolean' ? deviceConnection : undefined
292+
},
293+
name
294+
}),
295+
[createHardwareWalletRevamped]
296+
);
297+
294298
const tryMigrateToWalletRepository = useCallback(async (): Promise<
295299
AnyWallet<Wallet.WalletMetadata, Wallet.AccountMetadata>[] | undefined
296300
> => {
@@ -742,7 +746,9 @@ export const useWalletManager = (): UseWalletManager => {
742746
loadWallet,
743747
createWallet,
744748
createHardwareWallet,
749+
createHardwareWalletRevamped,
745750
connectHardwareWallet,
751+
connectHardwareWalletRevamped,
746752
saveHardwareWallet,
747753
deleteWallet,
748754
switchNetwork,

apps/browser-extension-wallet/src/lib/translations/en.json

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -494,9 +494,6 @@
494494
"browserView.walletSetup.mnemonicResetModal.content": "In order to keep you safe, we'll show you a new set of 24 words.",
495495
"browserView.walletSetup.mnemonicResetModal.cancel": "Cancel",
496496
"browserView.walletSetup.mnemonicResetModal.confirm": "OK",
497-
"browserView.walletSetup.confirmExperimentalHwDapp.header": "Limited support for Dapp connection",
498-
"browserView.walletSetup.confirmExperimentalHwDapp.content": "This current version does not support signing transactions through the Dapp connection feature with hardware wallets. Please stay tuned for upcoming releases and new features through @lace on Twitter.",
499-
"browserView.walletSetup.confirmExperimentalHwDapp.confirm": "OK",
500497
"browserView.crypto.emptyDashboard.welcome": "Welcome",
501498
"browserView.crypto.emptyDashboard.addSomeFundsYoStartYourJourney": "Add some funds to start your journey",
502499
"browserView.crypto.emptyDashboard.useThisAddressOrScanTheQRCodeToTransferFunds": "Use this address or scan the QR code to transfer funds",
@@ -647,13 +644,11 @@
647644
"browserView.staking.details.noFundsModal.buttons.confirm": "Add funds",
648645
"browserView.staking.details.errors.utxoFullyDepleted": "UTxO has been fully depleted",
649646
"browserView.staking.details.errors.utxoBalanceInsufficient": "Balance Insufficient",
650-
"browserView.onboarding.commonError.title": "Oops! Something went wrong",
651-
"browserView.onboarding.commonError.description": "Please check your hardware device.",
652-
"browserView.onboarding.commonError.ok": "OK",
653-
"browserView.onboarding.notDetectedError.title": "Failed to detect device",
654-
"browserView.onboarding.notDetectedError.description": "Please make sure your device is unlocked and the Cardano app is open.",
655-
"browserView.onboarding.notDetectedError.agree": "Agree",
656-
"browserView.onboarding.notDetectedError.trezorDescription": "Please make sure your device is unlocked.",
647+
"browserView.onboarding.errorDialog.title": "Opps! Something went wrong",
648+
"browserView.onboarding.errorDialog.cta": "OK",
649+
"browserView.onboarding.errorDialog.messageDeviceDisconnected": "Please check your hardware device connection and for Ledger, if Cardano App is open",
650+
"browserView.onboarding.errorDialog.messagePublicKeyExportRejected": "Public key export unsuccessful. User declined action on hardware wallet device.",
651+
"browserView.onboarding.errorDialog.messageGeneric": "Try connecting you device again",
657652
"browserView.onboarding.startOver.title": "Are you sure you want to start again?",
658653
"browserView.onboarding.startOver.description": "Connection to this device will be cancelled and you will need to re-connect.",
659654
"browserView.onboarding.startOver.cancel": "Cancel",
@@ -1263,6 +1258,18 @@
12631258
"core.walletSetupConnectHardwareWalletStep.supportedDevices": "Lace is supporting Ledger Nano X, Nano S and Nano S Plus",
12641259
"core.walletSetupConnectHardwareWalletStep.connectDevice": "Just connect your device to your computer, unlock and open the Cardano app to hit continue.",
12651260
"core.walletSetupConnectHardwareWalletStep.connectDeviceFull": "Just connect your device to your computer and unlock it to continue. If you're using a Ledger device, make sure you open the Cardano App.",
1261+
"core.walletSetupConnectHardwareWalletStepRevamp.title": "Connect your device",
1262+
"core.walletSetupConnectHardwareWalletStepRevamp.subTitleLedgerOnly": "Lace supports Ledger Nano X, Nano S, Nano S Plus. Unlock your device and open the Cardano app.",
1263+
"core.walletSetupConnectHardwareWalletStepRevamp.subTitle": "Lace supports Ledger Nano X, Nano S, Nano S Plus, Trezor Model T. Unlock your device and for Ledger, open the Cardano app.",
1264+
"core.walletSetupConnectHardwareWalletStepRevamp.errorMessage.userGestureRequired": "It appears the page reload interrupted the search for connected hardware wallet devices.",
1265+
"core.walletSetupConnectHardwareWalletStepRevamp.errorMessage.devicePickerRejected": "No hardware wallet device was chosen.",
1266+
"core.walletSetupConnectHardwareWalletStepRevamp.errorMessage.deviceLocked": "Your hardware wallet device seems to be locked. Please unlock it to proceed.",
1267+
"core.walletSetupConnectHardwareWalletStepRevamp.errorMessage.deviceBusy": "Your hardware wallet device seems to be busy with some other App. Please ensure it is free to connect.",
1268+
"core.walletSetupConnectHardwareWalletStepRevamp.errorMessage.cardanoAppNotOpen": "Cardano App is not open on your hardware wallet device. Please open it to proceed.",
1269+
"core.walletSetupConnectHardwareWalletStepRevamp.errorMessage.generic": "Something went wrong. Please try again.",
1270+
"core.walletSetupConnectHardwareWalletStepRevamp.errorCta": "Try again",
1271+
"core.walletSetupCreateStep.title": "Creating your wallet",
1272+
"core.walletSetupCreateStep.description": "Confirm exporting your public key on your hardware wallet device to create your Lace wallet.",
12661273
"core.walletSetupRestoreStep.title": "Restoring your wallet",
12671274
"core.walletSetupMnemonicStep.writePassphrase": "Write down your secret passphrase",
12681275
"core.walletSetupMnemonicStep.enterPassphrase": "Enter your secret passphrase",
@@ -1392,6 +1399,13 @@
13921399
"multiWallet.confirmationDialog.description": "You'll have to start over.",
13931400
"multiWallet.confirmationDialog.cancel": "Go back",
13941401
"multiWallet.confirmationDialog.confirm": "Proceed",
1402+
"multiWallet.errorDialog.commonError.title": "Oops! Something went wrong",
1403+
"multiWallet.errorDialog.commonError.description": "Please check your hardware device.",
1404+
"multiWallet.errorDialog.commonError.ok": "OK",
1405+
"multiWallet.errorDialog.notDetectedError.title": "Failed to detect device",
1406+
"multiWallet.errorDialog.notDetectedError.description": "Please make sure your device is unlocked and the Cardano app is open.",
1407+
"multiWallet.errorDialog.notDetectedError.agree": "Agree",
1408+
"multiWallet.errorDialog.notDetectedError.trezorDescription": "Please make sure your device is unlocked.",
13951409
"multiWallet.activated.wallet": "Wallet \"{{walletName}}\" activated",
13961410
"multiWallet.activated.account": "Account \"{{accountName}}\" activated",
13971411
"multiWallet.popupHwAccountEnable": "Hardware wallets require the <0>expanded view</0> to enable accounts",

apps/browser-extension-wallet/src/views/browser-view/features/multi-wallet/MultiWallet.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ export const SetupHardwareWallet = ({ shouldShowDialog$ }: ConfirmationDialog):
4242
const { t } = useTranslation();
4343
const { connectHardwareWallet, createHardwareWallet, walletRepository } = useWalletManager();
4444
const analytics = useAnalyticsContext();
45-
const disconnectHardwareWallet$ = useMemo(() => new Subject<HIDConnectionEvent>(), []);
45+
const disconnectHardwareWallet$ = useMemo(() => new Subject<USBConnectionEvent>(), []);
4646

4747
const hardwareWalletProviders = useMemo(
4848
(): Providers => ({
@@ -83,14 +83,14 @@ export const SetupHardwareWallet = ({ shouldShowDialog$ }: ConfirmationDialog):
8383
);
8484

8585
useEffect(() => {
86-
const onHardwareWalletDisconnect = (event: HIDConnectionEvent) => {
86+
const onHardwareWalletDisconnect = (event: USBConnectionEvent) => {
8787
disconnectHardwareWallet$.next(event);
8888
};
8989

90-
navigator.hid.addEventListener('disconnect', onHardwareWalletDisconnect);
90+
navigator.usb.addEventListener('disconnect', onHardwareWalletDisconnect);
9191

9292
return () => {
93-
navigator.hid.removeEventListener('disconnect', onHardwareWalletDisconnect);
93+
navigator.usb.removeEventListener('disconnect', onHardwareWalletDisconnect);
9494
disconnectHardwareWallet$.complete();
9595
};
9696
}, [disconnectHardwareWallet$]);

apps/browser-extension-wallet/src/views/browser-view/features/multi-wallet/hardware-wallet/HardwareWallet.test.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,15 +59,15 @@ describe('Multi Wallet Setup/Hardware Wallet', () => {
5959
let providers = {} as {
6060
connectHardwareWallet: jest.Mock;
6161
createWallet: jest.Mock;
62-
disconnectHardwareWallet$: Subject<HIDConnectionEvent>;
62+
disconnectHardwareWallet$: Subject<USBConnectionEvent>;
6363
shouldShowDialog$: Subject<boolean>;
6464
};
6565

6666
beforeEach(() => {
6767
providers = {
6868
connectHardwareWallet: jest.fn(),
6969
createWallet: jest.fn(),
70-
disconnectHardwareWallet$: new Subject<HIDConnectionEvent>(),
70+
disconnectHardwareWallet$: new Subject<USBConnectionEvent>(),
7171
shouldShowDialog$: new Subject()
7272
};
7373
});
@@ -101,7 +101,7 @@ describe('Multi Wallet Setup/Hardware Wallet', () => {
101101
await selectAccountStep();
102102

103103
act(() => {
104-
providers.disconnectHardwareWallet$.next({ device: { opened: true } } as HIDConnectionEvent);
104+
providers.disconnectHardwareWallet$.next({ device: { opened: true } } as USBConnectionEvent);
105105
});
106106

107107
await waitFor(() => expect(screen.queryByText('Oops! Something went wrong')).toBeInTheDocument());

apps/browser-extension-wallet/src/views/browser-view/features/multi-wallet/hardware-wallet/context.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ interface State {
1515
setAccount: (account: number) => void;
1616
resetConnection: () => void;
1717
createWallet: () => Promise<void>;
18-
disconnectHardwareWallet$: Observable<HIDConnectionEvent>;
18+
disconnectHardwareWallet$: Observable<USBConnectionEvent>;
1919
}
2020

2121
// eslint-disable-next-line unicorn/no-null

apps/browser-extension-wallet/src/views/browser-view/features/multi-wallet/hardware-wallet/steps/Connect.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import { WalletSetupConnectHardwareWalletStep } from '@lace/core';
22
import React, { useState } from 'react';
33
import { useTranslation } from 'react-i18next';
44
import { useHistory } from 'react-router';
5-
import { isTrezorHWSupported } from '../../../wallet-setup/helpers';
65
import { Wallet } from '@lace/cardano';
76
import { useHardwareWallet } from '../context';
87
import { walletRoutePaths } from '@routes';
@@ -11,6 +10,8 @@ import { WalletType } from '@cardano-sdk/web-extension';
1110
import { useAnalyticsContext } from '@providers';
1211
import { PostHogAction } from '@lace/common';
1312

13+
export const isTrezorHWSupported = (): boolean => process.env.USE_TREZOR_HW === 'true';
14+
1415
interface State {
1516
error?: 'notDetectedLedger' | 'notDetectedTrezor';
1617
}

apps/browser-extension-wallet/src/views/browser-view/features/multi-wallet/hardware-wallet/steps/ErrorHandling.tsx

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,29 @@
11
import React, { useEffect, useState } from 'react';
22
import { useHistory } from 'react-router';
33
import { useHardwareWallet } from '../context';
4-
import { ErrorDialog } from '../../../wallet-setup/components/ErrorDialog';
4+
import { makeErrorDialog } from '../../../wallet-setup/components/HardwareWalletFlow';
55
import { walletRoutePaths } from '@routes';
66

77
type Errors = 'notDetectedLedger' | 'notDetectedTrezor' | 'common';
88

9+
const ErrorDialog = makeErrorDialog<Errors>({
10+
common: {
11+
title: 'multiWallet.errorDialog.commonError.title',
12+
description: 'multiWallet.errorDialog.commonError.description',
13+
confirm: 'multiWallet.errorDialog.commonError.ok'
14+
},
15+
notDetectedLedger: {
16+
title: 'multiWallet.errorDialog.notDetectedError.title',
17+
description: 'multiWallet.errorDialog.notDetectedError.description',
18+
confirm: 'multiWallet.errorDialog.notDetectedError.agree'
19+
},
20+
notDetectedTrezor: {
21+
title: 'multiWallet.errorDialog.notDetectedError.title',
22+
description: 'multiWallet.errorDialog.notDetectedError.trezorDescription',
23+
confirm: 'multiWallet.errorDialog.notDetectedError.agree'
24+
}
25+
});
26+
927
interface State {
1028
error?: Errors;
1129
}
@@ -21,7 +39,7 @@ export const ErrorHandling = ({ error, onRetry }: Props): JSX.Element => {
2139
const [state, setState] = useState<State>({});
2240

2341
useEffect(() => {
24-
const subscription = disconnectHardwareWallet$.subscribe((event: HIDConnectionEvent) => {
42+
const subscription = disconnectHardwareWallet$.subscribe((event: USBConnectionEvent) => {
2543
if (event.device.opened) {
2644
setState({ error: 'common' });
2745
}

0 commit comments

Comments
 (0)