Skip to content

Commit d6bd13f

Browse files
fix: Add some exclusion to types to better handle remmaped DeviceEvent type to Redux Actions
1 parent 612976f commit d6bd13f

File tree

7 files changed

+42
-25
lines changed

7 files changed

+42
-25
lines changed

packages/suite/src/reducers/onboarding/onboardingReducer.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { OnboardingAnalytics } from '@trezor/suite-analytics';
66
import { ONBOARDING } from 'src/actions/onboarding/constants';
77
import * as STEP from 'src/constants/onboarding/steps';
88
import type { AnyPath, AnyStepId } from 'src/types/onboarding';
9-
import { Action, TrezorDevice } from 'src/types/suite';
9+
import { Action } from 'src/types/suite';
1010

1111
export interface OnboardingRootState {
1212
onboarding: OnboardingState;
@@ -26,7 +26,7 @@ export type BackupType = (typeof selectBackupTypes)[number];
2626
export interface OnboardingState {
2727
backupType: BackupType;
2828
isActive: boolean;
29-
prevDevice: TrezorDevice | null;
29+
prevDeviceId: string | null;
3030
activeStepId: AnyStepId;
3131
path: AnyPath[];
3232
onboardingAnalytics: Partial<OnboardingAnalytics>;
@@ -40,7 +40,7 @@ const initialState: OnboardingState = {
4040
// prevDevice is used only in firmwareUpdate so maybe move it to firmwareUpdate
4141
// and here leave only isMatchingPrevDevice ?
4242

43-
prevDevice: null,
43+
prevDeviceId: null,
4444
activeStepId: STEP.ID_FIRMWARE_STEP,
4545
path: [],
4646
onboardingAnalytics: {},
@@ -82,7 +82,7 @@ const onboarding = (state: OnboardingState = initialState, action: Action) => {
8282
draft.path = removePath(action.payload, state);
8383
break;
8484
case DEVICE.DISCONNECT:
85-
draft.prevDevice = action.payload;
85+
draft.prevDeviceId = action.payload.id ?? null;
8686
break;
8787
case ONBOARDING.ANALYTICS:
8888
draft.onboardingAnalytics = { ...state.onboardingAnalytics, ...action.payload };

packages/suite/src/types/suite/index.ts

+12-3
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ import { messageSystemActions } from '@suite-common/message-system';
99
import type { Route } from '@suite-common/suite-types';
1010
import { notificationsActions } from '@suite-common/toast-notifications';
1111
import { deviceActions, discoveryActions, transactionsActions } from '@suite-common/wallet-core';
12-
import type { BlockchainEvent, TransportEvent, UiEvent } from '@trezor/connect';
12+
import { BlockchainEvent, DEVICE, DeviceEvent, TransportEvent, UiEvent } from '@trezor/connect';
13+
import { FilterOutFromUnionByTypeProperty } from '@trezor/type-utils';
1314

1415
import type { BackupAction } from 'src/actions/backup/backupActions';
1516
import type { OnboardingAction } from 'src/actions/onboarding/onboardingActions';
@@ -41,7 +42,14 @@ export type {
4142
TrezorDevice,
4243
} from '@suite-common/suite-types';
4344

44-
type TrezorConnectEvents = TransportEvent | UiEvent | BlockchainEvent;
45+
type FilteredDeviceEvents = FilterOutFromUnionByTypeProperty<
46+
DeviceEvent,
47+
// Those types are remapped onto different actions in the connectInitThunks.ts and not used directly
48+
// as the rest of the DeviceEvents.
49+
typeof DEVICE.CONNECT | typeof DEVICE.CONNECT_UNACQUIRED
50+
>;
51+
52+
type TrezorConnectEvents = TransportEvent | UiEvent | FilteredDeviceEvents | BlockchainEvent;
4553

4654
export type TransactionAction = ReturnType<
4755
(typeof transactionsActions)[keyof typeof transactionsActions]
@@ -62,7 +70,7 @@ type DeviceAuthenticityAction = ReturnType<
6270

6371
// all actions from all apps used to properly type Dispatch.
6472
export type Action =
65-
| TrezorConnectEvents // Todo: This should not be here, actions shall be defined independently from Connect Events (and they shall be mapped onto them)
73+
| TrezorConnectEvents
6674
| RouterAction
6775
| WindowAction
6876
| StorageAction
@@ -113,6 +121,7 @@ export type ForegroundAppProps = {
113121
export type ToastNotificationVariant = 'success' | 'info' | 'warning' | 'error' | 'transparent';
114122

115123
export { TorStatus } from '@trezor/suite-desktop-api/src/enums';
124+
116125
export interface TorBootstrap {
117126
current: number;
118127
total: number;

packages/suite/src/views/onboarding/UnexpectedState/index.tsx

+2-3
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,11 @@ const UnexpectedState = ({ children }: UnexpectedStateProps) => {
2727
const device = useSelector(selectSelectedDevice);
2828
const prerequisite = useSelector(selectPrerequisite);
2929

30-
const { prevDevice, activeStepId, showPinMatrix } = useOnboarding();
30+
const { prevDeviceId, activeStepId, showPinMatrix } = useOnboarding();
3131

3232
const activeStep = steps.find(s => s.id === activeStepId);
3333

3434
const isNotSameDevice = useMemo(() => {
35-
const prevDeviceId = prevDevice?.id;
3635
// if no device was connected before, assume it is same device
3736
if (!prevDeviceId) {
3837
return false;
@@ -44,7 +43,7 @@ const UnexpectedState = ({ children }: UnexpectedStateProps) => {
4443
}
4544

4645
return deviceId !== prevDeviceId;
47-
}, [prevDevice, device]);
46+
}, [prevDeviceId, device]);
4847

4948
const UnexpectedStateComponent = useMemo(() => {
5049
if (!activeStep?.prerequisites) return null;

packages/type-utils/src/utils.ts

+20
Original file line numberDiff line numberDiff line change
@@ -108,3 +108,23 @@ export type DefinedUnionMember<T> = T extends string ? T : never;
108108
export type FilterPropertiesByType<T, ValueFilter> = {
109109
[Key in keyof T as T[Key] extends ValueFilter ? Key : never]: T[Key];
110110
};
111+
112+
/**
113+
* Removed the type from the union where `{ type: U }`.
114+
*
115+
* Example:
116+
* ```
117+
* type T1 =
118+
* | { type: 'A'; a: string }
119+
* | { type: 'B'; b: number }
120+
* | { type: 'C' | 'D' | 'E'; cde: boolean };
121+
*
122+
* // { type: 'A', a: string } | { type: 'B', b: number } | { type: 'D' | 'E', cde: boolean };
123+
* type NotC = FilterOutFromUnionByTypeProperty<T1, 'C'>;
124+
* ```
125+
*/
126+
export type FilterOutFromUnionByTypeProperty<T, U> = T extends { type: infer P }
127+
? P extends U
128+
? never
129+
: { type: Exclude<P, U> } & Omit<T, 'type'>
130+
: T;

suite-common/connect-init/src/connectInitThunks.ts

+3-2
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,12 @@ export const connectInitThunk = createThunk(
3535

3636
// set event listeners and dispatch as
3737
TrezorConnect.on(DEVICE_EVENT, ({ event: _, ...eventData }) => {
38-
// dispatch event as action
39-
4038
if (eventData.type === DEVICE.CONNECT || eventData.type === DEVICE.CONNECT_UNACQUIRED) {
39+
// This special case here allows us to "inject" extra data into action's payload
40+
// and change the type of the action (in this case DeviceEvent type !== Redux Action type)
4141
dispatch(deviceConnectThunks({ type: eventData.type, device: eventData.payload }));
4242
} else {
43+
// dispatch event as action
4344
dispatch({ type: eventData.type, payload: eventData.payload });
4445
}
4546
});

suite-common/wallet-core/src/device/deviceActions.ts

+1-12
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { createAction } from '@reduxjs/toolkit';
22

33
import { ButtonRequest, TrezorDevice } from '@suite-common/suite-types';
44
import { WalletType } from '@suite-common/wallet-types';
5-
import { DEVICE, Device, DeviceVersionChanged } from '@trezor/connect';
5+
import { DEVICE, Device } from '@trezor/connect';
66

77
export const DEVICE_MODULE_PREFIX = '@suite/device';
88

@@ -29,16 +29,6 @@ const deviceDisconnect = createAction(DEVICE.DISCONNECT, (payload: TrezorDevice)
2929
payload,
3030
}));
3131

32-
// this action is not used but is required because of the typings
33-
// changed here: https://github.com/trezor/trezor-suite/commit/c02412bccf80da7c827f624b7a7c85cdedf278c5#diff-2e9d057f0bfe2cc92fe50d4ce28838622d9e79fcca010ab8847a0fa288da13fd
34-
// in fact action is dispatched from connectInitThunk same as the rest of events
35-
const deviceFirmwareVersionChanged = createAction(
36-
DEVICE.FIRMWARE_VERSION_CHANGED,
37-
(payload: DeviceVersionChanged['payload']) => ({
38-
payload,
39-
}),
40-
);
41-
4232
const updatePassphraseMode = createAction(
4333
`${DEVICE_MODULE_PREFIX}/updatePassphraseMode`,
4434
(payload: { device: TrezorDevice; hidden: boolean; alwaysOnDevice?: boolean }) => ({ payload }),
@@ -118,5 +108,4 @@ export const deviceActions = {
118108
updateSelectedDevice,
119109
removeButtonRequests,
120110
setEntropyCheckFail,
121-
deviceFirmwareVersionChanged,
122111
};

suite-common/wallet-core/src/device/deviceThunks.ts

-1
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,6 @@ type SelectDeviceThunkParams = {
4444
* Called from:
4545
* - `@trezor/connect` events handler `handleDeviceConnect`, `handleDeviceDisconnect`
4646
* - from user action in `@suite-components/DeviceMenu`
47-
* @param {(Device | TrezorDevice | undefined)} device
4847
*/
4948
export const selectDeviceThunk = createThunk<void, SelectDeviceThunkParams, void>(
5049
`${DEVICE_MODULE_PREFIX}/selectDevice`,

0 commit comments

Comments
 (0)