Skip to content

Commit c5622d0

Browse files
committed
feat(connect): common function for DeviceEvent listeners registration
1 parent 226fc91 commit c5622d0

File tree

3 files changed

+49
-41
lines changed

3 files changed

+49
-41
lines changed

packages/connect/src/core/__tests__/onCallFirmwareUpdate.test.ts

+1
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,7 @@ const setupTest = () => {
193193
deviceList,
194194
postMessage,
195195
initDevice: () => Promise.resolve(deviceList.getAllDevices()[0]),
196+
registerEvents: () => {},
196197
log: new Log('Test', false),
197198
abortSignal: new AbortController().signal,
198199
};

packages/connect/src/core/index.ts

+35-21
Original file line numberDiff line numberDiff line change
@@ -639,21 +639,8 @@ const onCallDevice = async (
639639

640640
// device is available
641641
// set public variables, listeners and run method
642-
device.on(DEVICE.BUTTON, onDeviceButtonHandler(context, method));
643-
device.on(DEVICE.PIN, onDevicePinHandler(context));
644-
device.on(DEVICE.WORD, onDeviceWordHandler(context));
645-
device.on(
646-
DEVICE.PASSPHRASE,
647-
(method.useEmptyPassphrase ? onEmptyPassphraseHandler : onDevicePassphraseHandler)(context),
648-
);
649-
device.on(DEVICE.PASSPHRASE_ON_DEVICE, () => {
650-
sendCoreMessage(
651-
createUiMessage(UI.REQUEST_PASSPHRASE_ON_DEVICE, { device: device.toMessageObject() }),
652-
);
653-
});
654-
device.on(DEVICE.FIRMWARE_VERSION_CHANGED, payload => {
655-
sendCoreMessage(createDeviceMessage(DEVICE.FIRMWARE_VERSION_CHANGED, payload));
656-
});
642+
registerDeviceEvents(context, method)(device);
643+
657644
if (useCoreInPopup && env === 'webextension' && origin) {
658645
device.initStorage(new WebextensionStateStorage(origin));
659646
}
@@ -783,17 +770,17 @@ const closePopup = ({ popupPromise, sendCoreMessage }: CoreContext) => {
783770
* @memberof Core
784771
*/
785772
const onDeviceButtonHandler =
786-
(context: CoreContext, method: AbstractMethod<any>) =>
773+
(context: CoreContext, method?: AbstractMethod<any>) =>
787774
async ({ device, payload: request }: DeviceEvents['button']) => {
788775
const { sendCoreMessage } = context;
789776
// wait for popup handshake
790777
const addressRequest = request.code === 'ButtonRequest_Address';
791-
if (!addressRequest || (addressRequest && method.useUi)) {
778+
if (!addressRequest || (addressRequest && method?.useUi)) {
792779
await waitForPopup(context);
793780
}
794781
const data =
795-
typeof method.getButtonRequestData === 'function' && request.code
796-
? method.getButtonRequestData(request.code)
782+
typeof method?.getButtonRequestData === 'function' && request.code
783+
? method?.getButtonRequestData(request.code)
797784
: undefined;
798785
// interaction timeout
799786
startInteractionTimeout(context);
@@ -808,7 +795,7 @@ const onDeviceButtonHandler =
808795
data,
809796
}),
810797
);
811-
if (addressRequest && !method.useUi) {
798+
if (addressRequest && !method?.useUi) {
812799
sendCoreMessage(createUiMessage(UI.ADDRESS_VALIDATION, data));
813800
}
814801
};
@@ -903,6 +890,30 @@ const onEmptyPassphraseHandler =
903890
callback({ value: '' });
904891
};
905892

893+
const registerDeviceEvents =
894+
(context: CoreContext, method?: AbstractMethod<any>) => (device: Device) => {
895+
device.removeAllListeners();
896+
device.on(DEVICE.BUTTON, onDeviceButtonHandler(context, method));
897+
device.on(DEVICE.PIN, onDevicePinHandler(context));
898+
device.on(DEVICE.WORD, onDeviceWordHandler(context));
899+
device.on(
900+
DEVICE.PASSPHRASE,
901+
(method?.useEmptyPassphrase ? onEmptyPassphraseHandler : onDevicePassphraseHandler)(
902+
context,
903+
),
904+
);
905+
device.on(DEVICE.PASSPHRASE_ON_DEVICE, () => {
906+
context.sendCoreMessage(
907+
createUiMessage(UI.REQUEST_PASSPHRASE_ON_DEVICE, {
908+
device: device.toMessageObject(),
909+
}),
910+
);
911+
});
912+
device.on(DEVICE.FIRMWARE_VERSION_CHANGED, payload => {
913+
context.sendCoreMessage(createDeviceMessage(DEVICE.FIRMWARE_VERSION_CHANGED, payload));
914+
});
915+
};
916+
906917
/**
907918
* Handle popup closed by user.
908919
* @returns {void}
@@ -1158,14 +1169,17 @@ export class Core extends EventEmitter {
11581169
// means that call immediately returns error.
11591170
if (message.payload.method === 'firmwareUpdate') {
11601171
assertDeviceListConnected(this.deviceList);
1172+
1173+
const coreContext = this.getCoreContext();
11611174
onCallFirmwareUpdate({
11621175
params: message.payload,
11631176
context: {
11641177
deviceList: this.deviceList,
11651178
postMessage: this.sendCoreMessage.bind(this),
1166-
initDevice: path => initDevice(this.getCoreContext(), { path }),
1179+
initDevice: path => initDevice(coreContext, { path }),
11671180
log: _log,
11681181
abortSignal: this.abortController.signal,
1182+
registerEvents: registerDeviceEvents(coreContext),
11691183
},
11701184
})
11711185
.then(payload => {

packages/connect/src/core/onCallFirmwareUpdate.ts

+13-20
Original file line numberDiff line numberDiff line change
@@ -13,24 +13,13 @@ import { ERRORS, PROTO } from '../constants';
1313
import { getReleases } from '../data/firmwareInfo';
1414
import type { Device } from '../device/Device';
1515
import { DeviceList } from '../device/DeviceList';
16-
import { CoreEventMessage, DEVICE, UI, createDeviceMessage, createUiMessage } from '../events';
16+
import { CoreEventMessage, UI, createUiMessage } from '../events';
1717
import { CommonParams, DeviceUniquePath } from '../types';
1818
import { FirmwareUpdateResponse } from '../types/api/firmwareUpdate';
1919
import type { Log } from '../utils/debug';
2020

2121
type PostMessage = (message: CoreEventMessage) => void;
2222

23-
const registerEvents = (device: Device, postMessage: PostMessage) => {
24-
device.on(DEVICE.BUTTON, ({ device: _, payload }) => {
25-
postMessage(
26-
createDeviceMessage(DEVICE.BUTTON, {
27-
code: payload.code,
28-
device: device.toMessageObject(),
29-
}),
30-
);
31-
});
32-
};
33-
3423
type ReconnectParams = {
3524
bootloader: boolean;
3625
method: 'wait' | 'auto' | 'manual';
@@ -40,14 +29,15 @@ type ReconnectParams = {
4029
type ReconnectContext = {
4130
deviceList: DeviceList;
4231
device: Device;
32+
registerEvents: (device: Device) => void;
4333
postMessage: PostMessage;
4434
log: Log;
4535
abortSignal: AbortSignal;
4636
};
4737

4838
const waitForReconnectedDevice = async (
4939
{ bootloader, method, intermediary }: ReconnectParams,
50-
{ deviceList, device, postMessage, log, abortSignal }: ReconnectContext,
40+
{ deviceList, device, registerEvents, postMessage, log, abortSignal }: ReconnectContext,
5141
): Promise<Device> => {
5242
const target = intermediary || !bootloader ? 'normal' : 'bootloader';
5343

@@ -112,6 +102,7 @@ const waitForReconnectedDevice = async (
112102
'we were unable to read device.features on the first interaction after seeing it, retrying...',
113103
);
114104
try {
105+
registerEvents(reconnectedDevice);
115106
// todo: it keeps printing warning "Previous call is still running" on reconnect from bl to normal
116107
await reconnectedDevice.run(undefined, {
117108
skipFirmwareChecks: true,
@@ -147,7 +138,7 @@ const waitForReconnectedDevice = async (
147138
throw ERRORS.TypedError('Method_Interrupted');
148139
}
149140

150-
registerEvents(reconnectedDevice, postMessage);
141+
registerEvents(reconnectedDevice);
151142
await reconnectedDevice.waitForFirstRun();
152143

153144
if (!reconnectedDevice.isUsedHere()) {
@@ -292,6 +283,7 @@ export type Params = {
292283

293284
type Context = {
294285
deviceList: DeviceList;
286+
registerEvents: (device: Device) => void;
295287
postMessage: PostMessage;
296288
initDevice: (path?: DeviceUniquePath) => Promise<Device>;
297289
log: Log;
@@ -305,8 +297,9 @@ type OnCallFirmwareUpdateParams = {
305297

306298
export const onCallFirmwareUpdate = async ({
307299
params,
308-
context: { deviceList, postMessage, initDevice, log, abortSignal },
300+
context,
309301
}: OnCallFirmwareUpdateParams): Promise<FirmwareUpdateResponse> => {
302+
const { deviceList, registerEvents, postMessage, initDevice, log } = context;
310303
log.debug('onCallFirmwareUpdate with params: ', params);
311304

312305
const device = await initDevice(params?.device?.path);
@@ -319,7 +312,7 @@ export const onCallFirmwareUpdate = async ({
319312

320313
log.debug('onCallFirmwareUpdate', 'device', device);
321314

322-
registerEvents(device, postMessage);
315+
registerEvents(device);
323316

324317
const { manual, upgrade, language, btcOnly } = getInstallationParams(device, params);
325318
log.debug('onCallFirmwareUpdate', 'installation params', {
@@ -351,7 +344,7 @@ export const onCallFirmwareUpdate = async ({
351344

352345
reconnectedDevice = await waitForReconnectedDevice(
353346
{ bootloader: true, method: 'manual' },
354-
{ deviceList, device, log, postMessage, abortSignal },
347+
{ ...context, device },
355348
);
356349
} else {
357350
// Device supports automatic reboot to bootloader, load translation data and do it
@@ -422,7 +415,7 @@ export const onCallFirmwareUpdate = async ({
422415
}
423416
reconnectedDevice = await waitForReconnectedDevice(
424417
{ bootloader: true, method: 'auto' },
425-
{ deviceList, device, log, postMessage, abortSignal },
418+
{ ...context, device },
426419
);
427420
}
428421

@@ -449,7 +442,7 @@ export const onCallFirmwareUpdate = async ({
449442

450443
reconnectedDevice = await waitForReconnectedDevice(
451444
{ bootloader: true, method: 'manual', intermediary: true },
452-
{ deviceList, device: reconnectedDevice, log, postMessage, abortSignal },
445+
{ ...context, device: reconnectedDevice },
453446
);
454447

455448
binaryInfo = await getBinaryHelper(reconnectedDevice, params, log, postMessage, btcOnly);
@@ -467,7 +460,7 @@ export const onCallFirmwareUpdate = async ({
467460

468461
reconnectedDevice = await waitForReconnectedDevice(
469462
{ bootloader: false, method: 'wait' },
470-
{ deviceList, device: reconnectedDevice, log, postMessage, abortSignal },
463+
{ ...context, device: reconnectedDevice },
471464
);
472465

473466
// features.firmware_present non-null value implies that device was initially connected with

0 commit comments

Comments
 (0)