diff --git a/packages/suite/src/components/suite/Preloader/__tests__/Preloader.test.tsx b/packages/suite/src/components/suite/Preloader/__tests__/Preloader.test.tsx
index f1fd1ce740ff..7c72bb5fac74 100644
--- a/packages/suite/src/components/suite/Preloader/__tests__/Preloader.test.tsx
+++ b/packages/suite/src/components/suite/Preloader/__tests__/Preloader.test.tsx
@@ -20,6 +20,18 @@ jest.mock('cross-fetch', () => ({
default: () => Promise.resolve({ ok: false }),
}));
+// mock desktopApi
+jest.mock('@trezor/suite-desktop-api', () => ({
+ __esModule: true,
+ desktopApi: {
+ getBridgeStatus: () =>
+ Promise.resolve({ success: true, payload: { service: true, process: true } }),
+ getBridgeSettings: () => Promise.resolve({ success: true, payload: { enabled: true } }),
+ on: (_event: string, _cb: any) => {},
+ removeAllListeners: (_event: string) => {},
+ },
+}));
+
// jest.mock('@firmware-components/ReconnectDevicePrompt', () => ({
// __esModule: true, // export as module
// default: ({ children }: any) =>
{children}
,
@@ -230,7 +242,7 @@ describe('Preloader component', () => {
const { unmount } = renderWithProviders(store, );
expect(findByTestId('@connect-device-prompt')).not.toBeNull();
- expect(findByTestId('@connect-device-prompt/unreadable-hid')).not.toBeNull();
+ expect(findByTestId('@connect-device-prompt/unreadable-unknown')).not.toBeNull();
unmount();
});
diff --git a/packages/suite/src/components/suite/PrerequisitesGuide/DeviceUnreadable.tsx b/packages/suite/src/components/suite/PrerequisitesGuide/DeviceUnreadable.tsx
index 6bdfddd9b847..0efddc2c23c3 100644
--- a/packages/suite/src/components/suite/PrerequisitesGuide/DeviceUnreadable.tsx
+++ b/packages/suite/src/components/suite/PrerequisitesGuide/DeviceUnreadable.tsx
@@ -2,16 +2,18 @@ import { useState, MouseEvent } from 'react';
import { Button } from '@trezor/components';
import { desktopApi } from '@trezor/suite-desktop-api';
import { isDesktop, isLinux } from '@trezor/env-utils';
+import { notificationsActions } from '@suite-common/toast-notifications';
+import { selectDevice } from '@suite-common/wallet-core';
+
import { Translation, TroubleshootingTips, UdevDownload } from 'src/components/suite';
import {
- TROUBLESHOOTING_TIP_BRIDGE_STATUS,
TROUBLESHOOTING_TIP_SUITE_DESKTOP,
- TROUBLESHOOTING_TIP_CABLE,
- TROUBLESHOOTING_TIP_USB,
TROUBLESHOOTING_TIP_DIFFERENT_COMPUTER,
+ TROUBLESHOOTING_TIP_UNREADABLE_HID,
+ TROUBLESHOOTING_TIP_SUITE_DESKTOP_TOGGLE_BRIDGE,
+ TROUBLESHOOTING_TIP_RECONNECT,
} from 'src/components/suite/troubleshooting/tips';
-import { useDispatch } from 'src/hooks/suite';
-import { notificationsActions } from '@suite-common/toast-notifications';
+import { useSelector, useDispatch } from 'src/hooks/suite';
import type { TrezorDevice } from 'src/types/suite';
// linux web
@@ -99,28 +101,44 @@ const UdevDesktop = () => {
interface DeviceUnreadableProps {
device?: TrezorDevice; // this should be actually UnreadableDevice, but it is not worth type casting
- isWebUsbTransport: boolean;
}
-// We don't really know what happened, show some generic help and provide link to contact a support
-export const DeviceUnreadable = ({ device, isWebUsbTransport }: DeviceUnreadableProps) => {
- if (isWebUsbTransport) {
- // only install bridge will help (webusb + HID device)
- return (
- }
- items={[TROUBLESHOOTING_TIP_BRIDGE_STATUS, TROUBLESHOOTING_TIP_SUITE_DESKTOP]}
- offerWebUsb
- data-testid="@connect-device-prompt/unreadable-hid"
- />
- );
- }
+/**
+ * Device was detected but @trezor/connect was not able to communicate with it. Reasons could be:
+ * - initial read from device (GetFeatures) failed because of some de-synchronization or clash with another application
+ * - device can't be communicated with using currently used transport (eg. hid / node bridge + webusb)
+ * - missing udev rule on linux
+ */
+export const DeviceUnreadable = ({ device }: DeviceUnreadableProps) => {
+ const selectedDevice = useSelector(selectDevice);
// this error is dispatched by trezord when udev rules are missing
if (isLinux() && device?.error === 'LIBUSB_ERROR_ACCESS') {
return <> {isDesktop() ? : }>;
}
+ // generic troubleshooting tips
+ const items = [
+ // closing other apps and reloading should be the first step. Either we might have made a bug and let two apps to talk
+ // to device at the same time or there might be another application in the wild not really playing according to our rules
+ TROUBLESHOOTING_TIP_RECONNECT,
+ // if on web - try installing desktop. this takes you to using bridge which should be more powerful than WebUSB
+ TROUBLESHOOTING_TIP_SUITE_DESKTOP,
+ // unfortunately we have seen reports that even old bridge might not be enough for some Windows users. So the only chance
+ // is using another computer, or maybe it would be better to say another OS
+ TROUBLESHOOTING_TIP_DIFFERENT_COMPUTER,
+ ];
+
+ // only for unreadable HID devices
+ if (selectedDevice?.transportDescriptorType === 0) {
+ // If even this did not work, go to support or knowledge base
+ // 'If the last time you updated your device firmware was in 2019 and earlier please follow instructions in the knowledge base',
+ items.push(TROUBLESHOOTING_TIP_UNREADABLE_HID);
+ // you might have a very old device which is no longer supported current bridge
+ // if on desktop - try toggling between the 2 bridges we have available
+ items.push(TROUBLESHOOTING_TIP_SUITE_DESKTOP_TOGGLE_BRIDGE);
+ }
+
return (
}
- items={[
- TROUBLESHOOTING_TIP_CABLE,
- TROUBLESHOOTING_TIP_USB,
- TROUBLESHOOTING_TIP_DIFFERENT_COMPUTER,
- ]}
- offerWebUsb={isWebUsbTransport}
+ items={items}
data-testid="@connect-device-prompt/unreadable-unknown"
/>
);
diff --git a/packages/suite/src/components/suite/PrerequisitesGuide/PrerequisitesGuide.tsx b/packages/suite/src/components/suite/PrerequisitesGuide/PrerequisitesGuide.tsx
index 799e663cd56f..e4818461649e 100644
--- a/packages/suite/src/components/suite/PrerequisitesGuide/PrerequisitesGuide.tsx
+++ b/packages/suite/src/components/suite/PrerequisitesGuide/PrerequisitesGuide.tsx
@@ -61,9 +61,7 @@ export const PrerequisitesGuide = ({ allowSwitchDevice }: PrerequisitesGuideProp
case 'device-unacquired':
return ;
case 'device-unreadable':
- return (
-
- );
+ return ;
case 'device-unknown':
return ;
case 'device-seedless':
diff --git a/packages/suite/src/components/suite/PrerequisitesGuide/Transport.tsx b/packages/suite/src/components/suite/PrerequisitesGuide/Transport.tsx
index c88fc3d95ed2..7832438f60e6 100644
--- a/packages/suite/src/components/suite/PrerequisitesGuide/Transport.tsx
+++ b/packages/suite/src/components/suite/PrerequisitesGuide/Transport.tsx
@@ -1,23 +1,28 @@
import { Translation, TroubleshootingTips } from 'src/components/suite';
+
import {
TROUBLESHOOTING_TIP_SUITE_DESKTOP,
TROUBLESHOOTING_TIP_RESTART_COMPUTER,
TROUBLESHOOTING_TIP_WEBUSB_ENVIRONMENT,
} from 'src/components/suite/troubleshooting/tips';
-export const Transport = () => (
- // No transport layer (bridge/webUSB) is available
- // On web it makes sense to
- // - offer downloading Trezor Suite desktop, or
- // - use a browser that supports WebUSB
- // Desktop app should have Bridge transport layer available as it is built-in, if it is not available we fucked up something.
- }
- items={[
- TROUBLESHOOTING_TIP_WEBUSB_ENVIRONMENT,
- TROUBLESHOOTING_TIP_SUITE_DESKTOP,
- TROUBLESHOOTING_TIP_RESTART_COMPUTER,
- ]}
- data-testid="@connect-device-prompt/bridge-not-running"
- />
-);
+export const Transport = () => {
+ const items = [
+ TROUBLESHOOTING_TIP_WEBUSB_ENVIRONMENT,
+ TROUBLESHOOTING_TIP_SUITE_DESKTOP,
+ TROUBLESHOOTING_TIP_RESTART_COMPUTER,
+ ];
+
+ return (
+ // No transport layer (bridge/webUSB) is available
+ // On web it makes sense to
+ // - offer downloading Trezor Suite desktop, or
+ // - use a browser that supports WebUSB
+ // Desktop app should have Bridge transport layer available as it is built-in, if it is not available we fucked up something.
+ }
+ items={items}
+ data-testid="@connect-device-prompt/bridge-not-running"
+ />
+ );
+};
diff --git a/packages/suite/src/components/suite/troubleshooting/tips/BridgeTip.tsx b/packages/suite/src/components/suite/troubleshooting/tips/BridgeTip.tsx
index 321295e02cfa..0e3180a70ee9 100644
--- a/packages/suite/src/components/suite/troubleshooting/tips/BridgeTip.tsx
+++ b/packages/suite/src/components/suite/troubleshooting/tips/BridgeTip.tsx
@@ -5,8 +5,10 @@ import { typography } from '@trezor/theme';
import { TrezorLink } from 'src/components/suite';
import { Translation } from 'src/components/suite/Translation';
import { useOpenSuiteDesktop } from 'src/hooks/suite/useOpenSuiteDesktop';
+import { useBridgeDesktopApi } from 'src/hooks/suite/useBridgeDesktopApi';
+import { useSelector } from 'src/hooks/suite';
-const Wrapper = styled.div`
+export const Wrapper = styled.div`
a {
${typography.hint};
}
@@ -45,3 +47,34 @@ export const BridgeStatus = () => (
/>
);
+
+export const BridgeToggle = () => {
+ const { changeBridgeSettings, bridgeSettings } = useBridgeDesktopApi();
+ const transport = useSelector(state => state.suite.transport);
+
+ if (!bridgeSettings) return null;
+
+ return (
+
+ (
+ {
+ changeBridgeSettings({
+ ...bridgeSettings,
+ legacy: !bridgeSettings?.legacy,
+ });
+ }}
+ >
+ {chunks}
+
+ ),
+ }}
+ />
+
+ );
+};
diff --git a/packages/suite/src/components/suite/troubleshooting/tips/index.tsx b/packages/suite/src/components/suite/troubleshooting/tips/index.tsx
index afcf681a79d7..81b2fe205551 100644
--- a/packages/suite/src/components/suite/troubleshooting/tips/index.tsx
+++ b/packages/suite/src/components/suite/troubleshooting/tips/index.tsx
@@ -1,8 +1,10 @@
import { isWeb, isDesktop, isLinux, isAndroid } from '@trezor/env-utils';
+import { TREZOR_SUPPORT_DEVICE_URL } from '@trezor/urls';
+import { TrezorLink } from 'src/components/suite';
import { Translation } from 'src/components/suite/Translation';
-import { BridgeStatus, SuiteDesktopTip } from './BridgeTip';
+import { BridgeStatus, SuiteDesktopTip, BridgeToggle, Wrapper } from './BridgeTip';
import { UdevDescription } from './UdevDescription';
export const TROUBLESHOOTING_TIP_BRIDGE_STATUS = {
@@ -19,6 +21,25 @@ export const TROUBLESHOOTING_TIP_WEBUSB_ENVIRONMENT = {
hide: !isWeb(),
};
+export const TROUBLESHOOTING_TIP_UNREADABLE_HID = {
+ key: 'unreadable-hid',
+ heading: ,
+ description: (
+
+ (
+
+ {chunks}
+
+ ),
+ }}
+ />
+
+ ),
+};
+
export const TROUBLESHOOTING_TIP_SUITE_DESKTOP = {
key: 'suite-desktop',
heading: ,
@@ -26,6 +47,13 @@ export const TROUBLESHOOTING_TIP_SUITE_DESKTOP = {
hide: !isWeb(),
};
+export const TROUBLESHOOTING_TIP_SUITE_DESKTOP_TOGGLE_BRIDGE = {
+ key: 'suite-desktop',
+ heading: ,
+ description: ,
+ hide: isWeb() || isAndroid(),
+};
+
export const TROUBLESHOOTING_TIP_CABLE = {
key: 'cable',
heading: ,
diff --git a/packages/suite/src/support/messages.ts b/packages/suite/src/support/messages.ts
index 41aaf60d1e24..423f2204a697 100644
--- a/packages/suite/src/support/messages.ts
+++ b/packages/suite/src/support/messages.ts
@@ -7147,6 +7147,15 @@ export default defineMessages({
'Only Chromium-based browsers currently allow direct communication with USB devices.',
id: 'TR_TROUBLESHOOTING_TIP_BROWSER_WEBUSB_DESCRIPTION',
},
+ TR_TROUBLESHOOTING_TIP_UNREADABLE_HID_TITLE: {
+ defaultMessage: 'You may be using a very old Trezor model',
+ id: 'TR_TROUBLESHOOTING_TIP_UNREADABLE_HID_TITLE',
+ },
+ TR_TROUBLESHOOTING_TIP_UNREADABLE_HID_DESCRIPTION: {
+ defaultMessage:
+ 'If the last time you updated your device firmware was in 2019 and earlier please follow instructions in the knowledge base',
+ id: 'TR_TROUBLESHOOTING_TIP_UNREADABLE_HID_DESCRIPTION',
+ },
TR_TROUBLESHOOTING_TIP_SUITE_DESKTOP_TITLE: {
id: 'TR_TROUBLESHOOTING_TIP_SUITE_DESKTOP_TITLE',
defaultMessage: 'Use the Trezor Suite desktop app',
@@ -7155,6 +7164,15 @@ export default defineMessages({
id: 'TR_TROUBLESHOOTING_TIP_SUITE_DESKTOP_DESCRIPTION',
defaultMessage: 'Run the Trezor Suite desktop app',
},
+ TR_TROUBLESHOOTING_TIP_SUITE_DESKTOP_TOGGLE_BRIDGE_TITLE: {
+ id: 'TR_TROUBLESHOOTING_TIP_SUITE_DESKTOP_TOGGLE_BRIDGE_TITLE',
+ defaultMessage: 'Use another version of Trezor Bridge',
+ },
+ TR_TROUBLESHOOTING_TIP_SUITE_DESKTOP_TOGGLE_BRIDGE_DESCRIPTION: {
+ id: 'TR_TROUBLESHOOTING_TIP_SUITE_DESKTOP_TOGGLE_BRIDGE_DESCRIPTION',
+ defaultMessage:
+ 'Click to toggle an alternative bridge implementation. Current version: ({currentVersion})',
+ },
TR_TROUBLESHOOTING_TIP_UDEV_INSTALL_DESCRIPTION: {
id: 'TR_TROUBLESHOOTING_TIP_UDEV_INSTALL_DESCRIPTION',
defaultMessage:
@@ -7173,6 +7191,7 @@ export default defineMessages({
'After closing other browser tabs and windows, try quitting and reopening Trezor Suite.',
id: 'TR_TROUBLESHOOTING_CLOSE_TABS_DESCRIPTION_DESKTOP',
},
+
TR_TROUBLESHOOTING_TIP_CABLE_TITLE: {
id: 'TR_TROUBLESHOOTING_TIP_CABLE_TITLE',
defaultMessage: 'Try a different cable',
@@ -7208,11 +7227,6 @@ export default defineMessages({
defaultMessage:
'Restarting your computer may fix the communication issue between your browser and device.',
},
- TR_TROUBLESHOOTING_UNREADABLE_WEBUSB: {
- id: 'TR_TROUBLESHOOTING_UNREADABLE_WEBUSB',
- defaultMessage:
- "Your device is connected properly, but your browser can't communicate with it at the moment. You need to install Trezor Bridge.",
- },
TR_TROUBLESHOOTING_UNREADABLE_UDEV: {
id: 'TR_TROUBLESHOOTING_UNREADABLE_UDEV',
defaultMessage: 'Missing udev rules',