mirror of
https://github.com/trezor/trezor-suite.git
synced 2026-02-20 00:33:07 +01:00
feat(connect): add DEVICE.THP_PAIRING_STATUS_CHANGED event
This commit is contained in:
committed by
Szymon Lesisz
parent
4c0d26f872
commit
b2fd9e2d9e
@@ -560,6 +560,19 @@ const onThpCredentialsChangedHandler =
|
||||
);
|
||||
};
|
||||
|
||||
const onThpPhaseChangedHandler =
|
||||
(device: Device, context: CoreContext) =>
|
||||
(payload: DeviceEvents['device-thp_pairing_status_changed']) => {
|
||||
const { sendCoreMessage } = context;
|
||||
|
||||
sendCoreMessage(
|
||||
createDeviceMessage(DEVICE.THP_PAIRING_STATUS_CHANGED, {
|
||||
device: device.toMessageObject(),
|
||||
...payload,
|
||||
}),
|
||||
);
|
||||
};
|
||||
|
||||
const registerDeviceEvents =
|
||||
(context: CoreContext, method?: AbstractMethod<any>) => (device: Device) => {
|
||||
device.removeAllListeners();
|
||||
@@ -585,6 +598,7 @@ const registerDeviceEvents =
|
||||
});
|
||||
device.on(DEVICE.THP_PAIRING, onThpPairingHandler(device, context));
|
||||
device.on(DEVICE.THP_CREDENTIALS_CHANGED, onThpCredentialsChangedHandler(device, context));
|
||||
device.on(DEVICE.THP_PAIRING_STATUS_CHANGED, onThpPhaseChangedHandler(device, context));
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -37,6 +37,7 @@ import {
|
||||
DeviceButtonRequestPayload,
|
||||
DeviceThpCredentialsChangedPayload,
|
||||
DeviceThpPairingPayload,
|
||||
DeviceThpPairingStatus,
|
||||
DeviceVersionChanged,
|
||||
UI,
|
||||
UiResponsePassphrase,
|
||||
@@ -112,6 +113,7 @@ export interface DeviceEvents {
|
||||
callback: (response: Result<UiResponseThpPairingTag['payload']>) => void;
|
||||
};
|
||||
[DEVICE.THP_CREDENTIALS_CHANGED]: DeviceThpCredentialsChangedPayload;
|
||||
[DEVICE.THP_PAIRING_STATUS_CHANGED]: DeviceThpPairingStatus;
|
||||
}
|
||||
|
||||
interface DeviceLifecycleEvents {
|
||||
|
||||
@@ -39,17 +39,37 @@ export const getThpChannel = async (device: Device, withInteraction?: boolean) =
|
||||
await thpHandshake(device, isPinLocked);
|
||||
}
|
||||
}
|
||||
if (thpState.phase === 'pairing' && withInteraction) {
|
||||
const startPairing = thpState.phase === 'pairing' && withInteraction;
|
||||
if (startPairing) {
|
||||
device.emit(DEVICE.THP_PAIRING_STATUS_CHANGED, { status: 'started' });
|
||||
// start pairing with UI interaction
|
||||
await thpPairing(device);
|
||||
}
|
||||
|
||||
if (thpState.phase !== 'paired') {
|
||||
device.emit(DEVICE.THP_PAIRING_STATUS_CHANGED, {
|
||||
status: 'failed',
|
||||
message: 'THP Locked',
|
||||
});
|
||||
|
||||
return 'thp-locked';
|
||||
} else if (startPairing) {
|
||||
device.emit(DEVICE.THP_PAIRING_STATUS_CHANGED, { status: 'finished' });
|
||||
}
|
||||
} catch (error) {
|
||||
thpState.resetState();
|
||||
|
||||
if (error.code === 'Device_ThpPairingTagInvalid') {
|
||||
// ignore. phase already changed to 'invalid-tag'
|
||||
} else if (error.code === 'Failure_ActionCancelled') {
|
||||
device.emit(DEVICE.THP_PAIRING_STATUS_CHANGED, { status: 'canceled' });
|
||||
} else {
|
||||
device.emit(DEVICE.THP_PAIRING_STATUS_CHANGED, {
|
||||
status: 'failed',
|
||||
message: error.message,
|
||||
});
|
||||
}
|
||||
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -208,6 +208,13 @@ const waitForPairingTag = async (device: Device) => {
|
||||
// catch pairing tag mismatch
|
||||
// DataError since 2.10.0 https://github.com/trezor/trezor-firmware/commit/b0c3be9b1d95946471ebdab27918a3f652cf11e9
|
||||
if (e.code === 'Failure_FirmwareError' || e.code === 'Failure_DataError') {
|
||||
if ('tag' in pairingResponse) {
|
||||
device.emit(DEVICE.THP_PAIRING_STATUS_CHANGED, {
|
||||
status: 'invalid-tag',
|
||||
tag: pairingResponse.tag,
|
||||
});
|
||||
}
|
||||
|
||||
// 'Unexpected Code Entry Tag'
|
||||
throw ERRORS.TypedError('Device_ThpPairingTagInvalid', e.message);
|
||||
}
|
||||
|
||||
@@ -103,6 +103,7 @@ export const abortThpWorkflow = async (device: Device) => {
|
||||
await thpState.pairingTagPromise.abort();
|
||||
await device.getCurrentSession().cancelCall();
|
||||
thpState.resetState();
|
||||
device.emit(DEVICE.THP_PAIRING_STATUS_CHANGED, { status: 'canceled' });
|
||||
} else if (thpState.cancelablePromise) {
|
||||
thpState.sync('send', 'Cancel');
|
||||
await device.getCurrentSession().send('Cancel', {});
|
||||
|
||||
@@ -39,6 +39,7 @@ export const DEVICE = {
|
||||
PASSPHRASE_ON_DEVICE: 'passphrase_on_device',
|
||||
WORD: 'word',
|
||||
THP_PAIRING: 'thp_pairing', // ask UI for pairing tag
|
||||
THP_PAIRING_STATUS_CHANGED: 'device-thp_pairing_status_changed',
|
||||
} as const;
|
||||
|
||||
export interface DeviceButtonRequestPayload extends Omit<PROTO.ButtonRequest, 'code'> {
|
||||
@@ -63,6 +64,26 @@ export type DeviceThpCredentialsChangedPayload = {
|
||||
credentials: ThpCredentials;
|
||||
};
|
||||
|
||||
export type DeviceThpPairingStatus =
|
||||
| {
|
||||
status: 'started' | 'canceled' | 'finished';
|
||||
}
|
||||
| {
|
||||
status: 'failed';
|
||||
message: string;
|
||||
}
|
||||
| {
|
||||
status: 'invalid-tag';
|
||||
tag: string;
|
||||
};
|
||||
|
||||
export interface DeviceThpPairingStatusChanged {
|
||||
type: typeof DEVICE.THP_PAIRING_STATUS_CHANGED;
|
||||
payload: DeviceThpPairingStatus & {
|
||||
device: Device;
|
||||
};
|
||||
}
|
||||
|
||||
export type DeviceThpPairingPayload = {
|
||||
availableMethods: ThpPairingMethod[];
|
||||
selectedMethod: ThpPairingMethod; // expected pairing method
|
||||
@@ -94,6 +115,7 @@ export type DeviceEvent =
|
||||
}
|
||||
| DeviceButtonRequest
|
||||
| DeviceThpCredentialsChanged
|
||||
| DeviceThpPairingStatusChanged
|
||||
| DeviceVersionChanged
|
||||
| DeviceTrezorPushNotification;
|
||||
|
||||
|
||||
@@ -44,6 +44,17 @@ export const events = (api: TrezorConnect) => {
|
||||
if (event.type === 'device-trezor_push_notification') {
|
||||
return;
|
||||
}
|
||||
if (event.type === 'device-thp_pairing_status_changed') {
|
||||
const { payload } = event;
|
||||
if (payload.status === 'invalid-tag') {
|
||||
payload.tag.toLowerCase();
|
||||
}
|
||||
if (payload.status === 'failed') {
|
||||
payload.message.toLowerCase();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
const { payload } = event;
|
||||
payload.path.toLowerCase();
|
||||
if (payload.type === 'acquired') {
|
||||
|
||||
Reference in New Issue
Block a user