@onekeyfe/hd-transport-web-device 1.2.0-alpha.143 → 1.2.0-alpha.145
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/__tests__/electron-ble-transport.test.ts +49 -10
- package/__tests__/webusb-protocol-cache.test.ts +1 -1
- package/__tests__/webusb-protocol-v2-timeout.test.ts +9 -3
- package/dist/electron-ble-transport.d.ts +2 -0
- package/dist/electron-ble-transport.d.ts.map +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.js +47 -37
- package/dist/webusb.d.ts.map +1 -1
- package/package.json +5 -5
- package/src/electron-ble-transport.ts +28 -17
- package/src/webusb.ts +20 -19
|
@@ -440,11 +440,51 @@ describe('ElectronBleTransport protocol detection', () => {
|
|
|
440
440
|
expect(transport.getProtocolType(device.id)).toBeUndefined();
|
|
441
441
|
});
|
|
442
442
|
|
|
443
|
+
test('keeps a first expected Protocol V2 probe miss retryable', async () => {
|
|
444
|
+
const device = { id: 'first-v2-id', name: 'OneKey Pro 2' };
|
|
445
|
+
const nobleBle = createNobleBle(device);
|
|
446
|
+
const transport = configureTransport(nobleBle);
|
|
447
|
+
jest.spyOn(transport as any, 'probeProtocolV2').mockResolvedValue(false);
|
|
448
|
+
|
|
449
|
+
await expect(
|
|
450
|
+
transport.acquire({ uuid: device.id, expectedProtocol: 'V2' })
|
|
451
|
+
).rejects.toMatchObject({
|
|
452
|
+
errorCode: HardwareErrorCode.RuntimeError,
|
|
453
|
+
});
|
|
454
|
+
|
|
455
|
+
expect(nobleBle.connect).toHaveBeenCalledTimes(1);
|
|
456
|
+
expect(transport.getProtocolType(device.id)).toBeUndefined();
|
|
457
|
+
});
|
|
458
|
+
|
|
459
|
+
test('reports a stale bond after a second expected Protocol V2 probe miss', async () => {
|
|
460
|
+
const device = { id: 'retry-pro2-id', name: 'OneKey Pro 2' };
|
|
461
|
+
const nobleBle = createNobleBle(device);
|
|
462
|
+
const transport = configureTransport(nobleBle);
|
|
463
|
+
jest.spyOn(transport as any, 'probeProtocolV2').mockResolvedValue(false);
|
|
464
|
+
|
|
465
|
+
await expect(
|
|
466
|
+
transport.acquire({ uuid: device.id, expectedProtocol: 'V2' })
|
|
467
|
+
).rejects.toMatchObject({
|
|
468
|
+
errorCode: HardwareErrorCode.RuntimeError,
|
|
469
|
+
});
|
|
470
|
+
await expect(
|
|
471
|
+
transport.acquire({ uuid: device.id, expectedProtocol: 'V2' })
|
|
472
|
+
).rejects.toMatchObject({
|
|
473
|
+
errorCode: HardwareErrorCode.BleDeviceBondError,
|
|
474
|
+
});
|
|
475
|
+
|
|
476
|
+
expect(transport.getProtocolType(device.id)).toBeUndefined();
|
|
477
|
+
});
|
|
478
|
+
|
|
443
479
|
test('reports a stale bond when a previously confirmed Protocol V2 device stops responding', async () => {
|
|
444
480
|
const device = { id: 'reset-pro2-id', name: 'OneKey Pro 2' };
|
|
445
481
|
const nobleBle = createNobleBle(device);
|
|
446
482
|
const transport = configureTransport(nobleBle);
|
|
447
|
-
jest.spyOn(transport as any, 'probeProtocolV2').mockResolvedValue(
|
|
483
|
+
const probe = jest.spyOn(transport as any, 'probeProtocolV2').mockResolvedValue(true);
|
|
484
|
+
|
|
485
|
+
await transport.acquire({ uuid: device.id, expectedProtocol: 'V2' });
|
|
486
|
+
await transport.release(device.id);
|
|
487
|
+
probe.mockResolvedValue(false);
|
|
448
488
|
|
|
449
489
|
await expect(
|
|
450
490
|
transport.acquire({ uuid: device.id, expectedProtocol: 'V2' })
|
|
@@ -452,13 +492,12 @@ describe('ElectronBleTransport protocol detection', () => {
|
|
|
452
492
|
errorCode: HardwareErrorCode.BleDeviceBondError,
|
|
453
493
|
});
|
|
454
494
|
|
|
455
|
-
expect(nobleBle.connect).toHaveBeenCalledTimes(1);
|
|
456
495
|
expect(nobleBle.unsubscribe).toHaveBeenCalledWith(device.id);
|
|
457
496
|
expect(nobleBle.disconnect).toHaveBeenCalledWith(device.id);
|
|
458
497
|
expect(transport.getProtocolType(device.id)).toBeUndefined();
|
|
459
498
|
});
|
|
460
499
|
|
|
461
|
-
test('
|
|
500
|
+
test('does not take a Protocol V2 hint from the BLE name', async () => {
|
|
462
501
|
const device = { id: 'named-pro2-id', name: 'OneKey Pro 2' };
|
|
463
502
|
const nobleBle = createNobleBle(device);
|
|
464
503
|
let notificationHandler: ((deviceId: string, data: string) => void) | undefined;
|
|
@@ -488,15 +527,15 @@ describe('ElectronBleTransport protocol detection', () => {
|
|
|
488
527
|
protocolType: 'V2',
|
|
489
528
|
})
|
|
490
529
|
);
|
|
491
|
-
expect(nobleBle.write).
|
|
530
|
+
expect(nobleBle.write.mock.calls.length).toBeGreaterThan(1);
|
|
492
531
|
expect(transport.getProtocolType(device.id)).toBe('V2');
|
|
493
532
|
await expect(transport.call(device.id, 'Ping', { message: 'after-probe' })).resolves.toEqual({
|
|
494
533
|
type: 'Success',
|
|
495
534
|
message: { message: 'ok' },
|
|
496
535
|
});
|
|
497
|
-
const sentSeqs = nobleBle.write.mock.calls
|
|
498
|
-
Number.parseInt(hex.slice(12, 14), 16)
|
|
499
|
-
|
|
536
|
+
const sentSeqs = nobleBle.write.mock.calls
|
|
537
|
+
.map(([, hex]) => Number.parseInt(hex.slice(12, 14), 16))
|
|
538
|
+
.filter(seq => seq > 0);
|
|
500
539
|
expect(sentSeqs).toEqual([1, 2]);
|
|
501
540
|
} finally {
|
|
502
541
|
await transport.release(device.id);
|
|
@@ -576,9 +615,9 @@ describe('ElectronBleTransport protocol detection', () => {
|
|
|
576
615
|
message: { message: 'ok' },
|
|
577
616
|
});
|
|
578
617
|
|
|
579
|
-
const sentSeqs = nobleBle.write.mock.calls
|
|
580
|
-
Number.parseInt(hex.slice(12, 14), 16)
|
|
581
|
-
|
|
618
|
+
const sentSeqs = nobleBle.write.mock.calls
|
|
619
|
+
.map(([, hex]) => Number.parseInt(hex.slice(12, 14), 16))
|
|
620
|
+
.filter(seq => seq > 0);
|
|
582
621
|
expect(sentSeqs).toEqual([1, 2, 3]);
|
|
583
622
|
} finally {
|
|
584
623
|
await transport.release(device.id);
|
|
@@ -230,7 +230,7 @@ describe('WebUsbTransport protocol probe cache', () => {
|
|
|
230
230
|
expect(second.deviceProtocol.get(path)).toBe('V1');
|
|
231
231
|
expect(first.staleProtocolPaths.has(path)).toBe(false);
|
|
232
232
|
|
|
233
|
-
// Events without a
|
|
233
|
+
// Events without a device identity are ignored.
|
|
234
234
|
handler({ device: { serialNumber: null } });
|
|
235
235
|
handler({});
|
|
236
236
|
expect(second.staleProtocolPaths.size).toBe(1);
|
|
@@ -21,8 +21,9 @@ const schema = {
|
|
|
21
21
|
};
|
|
22
22
|
|
|
23
23
|
describe('WebUsbTransport Protocol V2 timeout recovery', () => {
|
|
24
|
-
test('
|
|
25
|
-
const filter =
|
|
24
|
+
test('enumerates OneKey USB devices even when the serial string is omitted', async () => {
|
|
25
|
+
const filter =
|
|
26
|
+
ONEKEY_WEBUSB_FILTER.find(item => item.productId === 0x4f4c) ?? ONEKEY_WEBUSB_FILTER[0];
|
|
26
27
|
const deviceWithSerial = {
|
|
27
28
|
...filter,
|
|
28
29
|
manufacturerName: 'OneKey',
|
|
@@ -32,7 +33,7 @@ describe('WebUsbTransport Protocol V2 timeout recovery', () => {
|
|
|
32
33
|
const deviceWithoutSerial = {
|
|
33
34
|
...filter,
|
|
34
35
|
manufacturerName: 'OneKey',
|
|
35
|
-
productName: 'OneKey
|
|
36
|
+
productName: 'OneKey Neo',
|
|
36
37
|
serialNumber: null,
|
|
37
38
|
} as USBDevice;
|
|
38
39
|
const webusb = new WebUsbTransport();
|
|
@@ -46,6 +47,11 @@ describe('WebUsbTransport Protocol V2 timeout recovery', () => {
|
|
|
46
47
|
device: deviceWithSerial,
|
|
47
48
|
commType: 'webusb',
|
|
48
49
|
},
|
|
50
|
+
{
|
|
51
|
+
path: 'usb-1209-4f4c-onekey-neo',
|
|
52
|
+
device: deviceWithoutSerial,
|
|
53
|
+
commType: 'webusb',
|
|
54
|
+
},
|
|
49
55
|
]);
|
|
50
56
|
});
|
|
51
57
|
|
|
@@ -27,6 +27,8 @@ export default class ElectronBleTransport {
|
|
|
27
27
|
private connectedDevices;
|
|
28
28
|
private deviceProtocol;
|
|
29
29
|
private deviceProtocolHints;
|
|
30
|
+
private confirmedProtocolV2;
|
|
31
|
+
private retryableV2Mismatch;
|
|
30
32
|
private deviceMtus;
|
|
31
33
|
private devicePacketCapacities;
|
|
32
34
|
private v1Buffers;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"electron-ble-transport.d.ts","sourceRoot":"","sources":["../src/electron-ble-transport.ts"],"names":[],"mappings":";AAsBA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAClE,OAAO,KAAK,EACV,gBAAgB,EAChB,YAAY,EAEZ,oBAAoB,EACrB,MAAM,wBAAwB,CAAC;AAChC,OAAO,KAAK,YAAY,MAAM,QAAQ,CAAC;AAIvC,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,MAAM;QACd,UAAU,CAAC,EAAE,UAAU,CAAC;KACzB;CACF;AAED,MAAM,MAAM,eAAe,GAAG;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,gBAAgB,CAAC,EAAE,YAAY,CAAC;IAChC,YAAY,CAAC,EAAE,YAAY,CAAC;CAC7B,CAAC;
|
|
1
|
+
{"version":3,"file":"electron-ble-transport.d.ts","sourceRoot":"","sources":["../src/electron-ble-transport.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -210,6 +210,10 @@ declare class ElectronBleTransport {
|
|
|
210
210
|
private connectedDevices;
|
|
211
211
|
private deviceProtocol;
|
|
212
212
|
private deviceProtocolHints;
|
|
213
|
+
/** Endpoints that answered a V2 probe in this transport lifetime. Survives disconnect. */
|
|
214
|
+
private confirmedProtocolV2;
|
|
215
|
+
/** First expected-V2 miss for an unconfirmed endpoint; the next miss is a stale bond. */
|
|
216
|
+
private retryableV2Mismatch;
|
|
213
217
|
private deviceMtus;
|
|
214
218
|
private devicePacketCapacities;
|
|
215
219
|
private v1Buffers;
|
package/dist/index.js
CHANGED
|
@@ -54,9 +54,6 @@ const PACKET_IO_RETRY_DELAY = 300;
|
|
|
54
54
|
const PROTOCOL_V1_PROBE_TIMEOUT = 5000;
|
|
55
55
|
const PROTOCOL_V2_PROBE_TIMEOUT = 1000;
|
|
56
56
|
const EXPECTED_PROTOCOL_V2_PROBE_ATTEMPTS = 2;
|
|
57
|
-
function inferProtocolHintFromDeviceName$1(name) {
|
|
58
|
-
return /\bpro\s*2\b/i.test(name !== null && name !== void 0 ? name : '') ? 'V2' : undefined;
|
|
59
|
-
}
|
|
60
57
|
let activeWebUsbTransport;
|
|
61
58
|
let usbDisconnectListenerAttached = false;
|
|
62
59
|
function registerActiveWebUsbTransport(instance, usb) {
|
|
@@ -65,11 +62,12 @@ function registerActiveWebUsbTransport(instance, usb) {
|
|
|
65
62
|
return;
|
|
66
63
|
usbDisconnectListenerAttached = true;
|
|
67
64
|
usb.addEventListener('disconnect', event => {
|
|
68
|
-
|
|
69
|
-
const serial = (_a = event.device) === null || _a === void 0 ? void 0 : _a.serialNumber;
|
|
70
|
-
if (typeof serial !== 'string' || serial.length === 0)
|
|
65
|
+
if (!event.device)
|
|
71
66
|
return;
|
|
72
|
-
|
|
67
|
+
const path = hdShared.resolveOneKeyUsbDevicePath(event.device);
|
|
68
|
+
if (!path)
|
|
69
|
+
return;
|
|
70
|
+
activeWebUsbTransport === null || activeWebUsbTransport === void 0 ? void 0 : activeWebUsbTransport.markProtocolStale(path);
|
|
73
71
|
});
|
|
74
72
|
}
|
|
75
73
|
class WebUsbTransport extends transport.ProtocolV2UsbTransportBase {
|
|
@@ -152,20 +150,23 @@ class WebUsbTransport extends transport.ProtocolV2UsbTransportBase {
|
|
|
152
150
|
const devices = yield this.usb.getDevices();
|
|
153
151
|
const onekeyDevices = devices.filter(dev => {
|
|
154
152
|
const isOneKey = hdShared.ONEKEY_WEBUSB_FILTER.some((desc) => dev.vendorId === desc.vendorId && dev.productId === desc.productId);
|
|
155
|
-
|
|
156
|
-
return isOneKey && hasSerialNumber && !hdShared.isKnownTrezorWebUsbDevice(dev);
|
|
153
|
+
return isOneKey && !hdShared.isKnownTrezorWebUsbDevice(dev);
|
|
157
154
|
});
|
|
158
|
-
this.deviceList = onekeyDevices.
|
|
159
|
-
const path = device
|
|
160
|
-
|
|
155
|
+
this.deviceList = onekeyDevices.flatMap(device => {
|
|
156
|
+
const path = hdShared.resolveOneKeyUsbDevicePath(device);
|
|
157
|
+
if (!path)
|
|
158
|
+
return [];
|
|
159
|
+
const protocolHint = hdShared.inferProtocolHintFromUsbId(device.vendorId, device.productId);
|
|
161
160
|
if (protocolHint) {
|
|
162
161
|
this.deviceProtocolHints.set(path, protocolHint);
|
|
163
162
|
}
|
|
164
|
-
return
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
163
|
+
return [
|
|
164
|
+
{
|
|
165
|
+
path,
|
|
166
|
+
device,
|
|
167
|
+
commType: 'webusb',
|
|
168
|
+
},
|
|
169
|
+
];
|
|
169
170
|
});
|
|
170
171
|
return this.deviceList;
|
|
171
172
|
});
|
|
@@ -199,10 +200,10 @@ class WebUsbTransport extends transport.ProtocolV2UsbTransportBase {
|
|
|
199
200
|
this.deviceProtocol.delete(input.path);
|
|
200
201
|
}
|
|
201
202
|
if (!this.deviceProtocol.has(input.path)) {
|
|
202
|
-
const
|
|
203
|
+
const usbDevice = (_c = this.deviceList.find(device => device.path === input.path)) === null || _c === void 0 ? void 0 : _c.device;
|
|
203
204
|
const protocolHint = input.expectedProtocol
|
|
204
205
|
? undefined
|
|
205
|
-
: (_e = (_d = input.protocolHint) !== null && _d !== void 0 ? _d : this.deviceProtocolHints.get(input.path)) !== null && _e !== void 0 ? _e :
|
|
206
|
+
: (_e = (_d = input.protocolHint) !== null && _d !== void 0 ? _d : this.deviceProtocolHints.get(input.path)) !== null && _e !== void 0 ? _e : hdShared.inferProtocolHintFromUsbId(usbDevice === null || usbDevice === void 0 ? void 0 : usbDevice.vendorId, usbDevice === null || usbDevice === void 0 ? void 0 : usbDevice.productId);
|
|
206
207
|
if (protocolHint) {
|
|
207
208
|
this.deviceProtocolHints.set(input.path, protocolHint);
|
|
208
209
|
}
|
|
@@ -792,9 +793,6 @@ function resolveBlePacketCapacity(mtu, maximumPacketCapacity, fallbackPacketCapa
|
|
|
792
793
|
}
|
|
793
794
|
|
|
794
795
|
const { parseConfigure, ProtocolV1, check } = transport__default["default"];
|
|
795
|
-
function inferProtocolHintFromDeviceName(name) {
|
|
796
|
-
return /\bpro\s*2\b/i.test(name !== null && name !== void 0 ? name : '') ? 'V2' : undefined;
|
|
797
|
-
}
|
|
798
796
|
const toBleDescriptor = (device, protocolType) => (Object.assign({ id: device.id, name: device.name, path: device.id, debug: false, commType: 'electron-ble' }, (protocolType ? { protocolType } : {})));
|
|
799
797
|
const BLE_PACKET_SIZE_FALLBACK = 192;
|
|
800
798
|
const BLE_PACKET_SIZE_MAXIMUM = 244;
|
|
@@ -810,6 +808,8 @@ class ElectronBleTransport {
|
|
|
810
808
|
this.connectedDevices = new Set();
|
|
811
809
|
this.deviceProtocol = new Map();
|
|
812
810
|
this.deviceProtocolHints = new Map();
|
|
811
|
+
this.confirmedProtocolV2 = new Set();
|
|
812
|
+
this.retryableV2Mismatch = new Set();
|
|
813
813
|
this.deviceMtus = new Map();
|
|
814
814
|
this.devicePacketCapacities = new Map();
|
|
815
815
|
this.v1Buffers = new Map();
|
|
@@ -949,10 +949,6 @@ class ElectronBleTransport {
|
|
|
949
949
|
(_b = this.Log) === null || _b === void 0 ? void 0 : _b.debug(`[Electron BLE] enumerate found ${devices.length} device(s):`);
|
|
950
950
|
for (const dev of devices) {
|
|
951
951
|
(_c = this.Log) === null || _c === void 0 ? void 0 : _c.debug(`[Electron BLE] id="${dev.id}" name="${dev.name}"`);
|
|
952
|
-
const protocolHint = inferProtocolHintFromDeviceName(dev.name);
|
|
953
|
-
if (protocolHint) {
|
|
954
|
-
this.deviceProtocolHints.set(dev.id, protocolHint);
|
|
955
|
-
}
|
|
956
952
|
}
|
|
957
953
|
return devices.map(device => toBleDescriptor(device));
|
|
958
954
|
}
|
|
@@ -963,7 +959,7 @@ class ElectronBleTransport {
|
|
|
963
959
|
});
|
|
964
960
|
}
|
|
965
961
|
acquire(input) {
|
|
966
|
-
var _a, _b, _c, _d, _e, _f, _g
|
|
962
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
967
963
|
return __awaiter(this, void 0, void 0, function* () {
|
|
968
964
|
const { uuid, forceCleanRunPromise, expectedProtocol } = input;
|
|
969
965
|
if (!uuid) {
|
|
@@ -988,7 +984,7 @@ class ElectronBleTransport {
|
|
|
988
984
|
}
|
|
989
985
|
const protocolHint = expectedProtocol
|
|
990
986
|
? undefined
|
|
991
|
-
: (
|
|
987
|
+
: (_b = input.protocolHint) !== null && _b !== void 0 ? _b : this.deviceProtocolHints.get(uuid);
|
|
992
988
|
if (protocolHint) {
|
|
993
989
|
this.deviceProtocolHints.set(uuid, protocolHint);
|
|
994
990
|
}
|
|
@@ -1012,10 +1008,10 @@ class ElectronBleTransport {
|
|
|
1012
1008
|
const connectionToken = this.notificationTokens.get(uuid);
|
|
1013
1009
|
const protocolType = yield this.detectProtocol(uuid, expectedProtocol, protocolHint);
|
|
1014
1010
|
if (protocolType === 'V2') {
|
|
1015
|
-
(
|
|
1011
|
+
(_c = this.Log) === null || _c === void 0 ? void 0 : _c.debug('[Electron BLE] Protocol V2 write configured', {
|
|
1016
1012
|
writeMode: 'withoutResponse',
|
|
1017
1013
|
negotiatedMtu: this.deviceMtus.get(uuid),
|
|
1018
|
-
packetCapacity: (
|
|
1014
|
+
packetCapacity: (_d = this.devicePacketCapacities.get(uuid)) !== null && _d !== void 0 ? _d : BLE_PACKET_SIZE_FALLBACK,
|
|
1019
1015
|
});
|
|
1020
1016
|
}
|
|
1021
1017
|
const disconnectCleanup = window.desktopApi.nobleBle.onDeviceDisconnected((disconnectedDevice) => {
|
|
@@ -1034,15 +1030,15 @@ class ElectronBleTransport {
|
|
|
1034
1030
|
return Object.assign(Object.assign({}, toBleDescriptor({ id: device.id, name: device.name }, protocolType)), { uuid });
|
|
1035
1031
|
}
|
|
1036
1032
|
catch (error) {
|
|
1037
|
-
(
|
|
1033
|
+
(_e = this.Log) === null || _e === void 0 ? void 0 : _e.error('[Electron BLE] acquire failed:', error);
|
|
1038
1034
|
try {
|
|
1039
|
-
if (((
|
|
1035
|
+
if (((_f = window.desktopApi) === null || _f === void 0 ? void 0 : _f.nobleBle) && this.connectedDevices.has(uuid)) {
|
|
1040
1036
|
yield window.desktopApi.nobleBle.unsubscribe(uuid);
|
|
1041
1037
|
yield window.desktopApi.nobleBle.disconnect(uuid);
|
|
1042
1038
|
}
|
|
1043
1039
|
}
|
|
1044
1040
|
catch (cleanupError) {
|
|
1045
|
-
(
|
|
1041
|
+
(_g = this.Log) === null || _g === void 0 ? void 0 : _g.debug('[Electron BLE] acquire cleanup failed:', cleanupError);
|
|
1046
1042
|
}
|
|
1047
1043
|
this.cleanupDeviceState(uuid);
|
|
1048
1044
|
throw error;
|
|
@@ -1109,8 +1105,16 @@ class ElectronBleTransport {
|
|
|
1109
1105
|
}
|
|
1110
1106
|
});
|
|
1111
1107
|
}
|
|
1112
|
-
createProtocolMismatchError(expected) {
|
|
1113
|
-
|
|
1108
|
+
createProtocolMismatchError(expected, uuid) {
|
|
1109
|
+
const isStaleV2Bond = expected === 'V2' &&
|
|
1110
|
+
(this.confirmedProtocolV2.has(uuid) || this.retryableV2Mismatch.has(uuid));
|
|
1111
|
+
if (expected === 'V2' && !isStaleV2Bond) {
|
|
1112
|
+
this.retryableV2Mismatch.add(uuid);
|
|
1113
|
+
}
|
|
1114
|
+
else if (isStaleV2Bond) {
|
|
1115
|
+
this.retryableV2Mismatch.delete(uuid);
|
|
1116
|
+
}
|
|
1117
|
+
return hdShared.ERRORS.TypedError(isStaleV2Bond ? hdShared.HardwareErrorCode.BleDeviceBondError : hdShared.HardwareErrorCode.RuntimeError, `Device protocol mismatch: expected ${expected}, but device did not respond to expected protocol`);
|
|
1114
1118
|
}
|
|
1115
1119
|
createProtocolDetectionError() {
|
|
1116
1120
|
return hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleTimeoutError, 'Unable to detect BLE protocol: device did not respond to Protocol V1 GetFeatures or Protocol V2 Ping');
|
|
@@ -1129,15 +1133,17 @@ class ElectronBleTransport {
|
|
|
1129
1133
|
(_a = this.Log) === null || _a === void 0 ? void 0 : _a.debug(`[Electron BLE] detectProtocol: uuid=${uuid} -> V1 (expected)`);
|
|
1130
1134
|
return 'V1';
|
|
1131
1135
|
}
|
|
1132
|
-
throw this.createProtocolMismatchError(expectedProtocol);
|
|
1136
|
+
throw this.createProtocolMismatchError(expectedProtocol, uuid);
|
|
1133
1137
|
}
|
|
1134
1138
|
if (expectedProtocol === 'V2') {
|
|
1135
1139
|
if (yield this.probeProtocolV2(uuid)) {
|
|
1136
1140
|
this.deviceProtocol.set(uuid, 'V2');
|
|
1141
|
+
this.confirmedProtocolV2.add(uuid);
|
|
1142
|
+
this.retryableV2Mismatch.delete(uuid);
|
|
1137
1143
|
(_b = this.Log) === null || _b === void 0 ? void 0 : _b.debug(`[Electron BLE] detectProtocol: uuid=${uuid} -> V2 (expected)`);
|
|
1138
1144
|
return 'V2';
|
|
1139
1145
|
}
|
|
1140
|
-
throw this.createProtocolMismatchError(expectedProtocol);
|
|
1146
|
+
throw this.createProtocolMismatchError(expectedProtocol, uuid);
|
|
1141
1147
|
}
|
|
1142
1148
|
const probeOrder = protocolHint === 'V2' || this.deviceProtocol.get(uuid) === 'V2' ? ['V2', 'V1'] : ['V1', 'V2'];
|
|
1143
1149
|
for (let i = 0; i < probeOrder.length; i += 1) {
|
|
@@ -1148,6 +1154,10 @@ class ElectronBleTransport {
|
|
|
1148
1154
|
const detected = protocol === 'V1' ? yield this.probeProtocolV1(uuid) : yield this.probeProtocolV2(uuid);
|
|
1149
1155
|
if (detected) {
|
|
1150
1156
|
this.deviceProtocol.set(uuid, protocol);
|
|
1157
|
+
if (protocol === 'V2') {
|
|
1158
|
+
this.confirmedProtocolV2.add(uuid);
|
|
1159
|
+
this.retryableV2Mismatch.delete(uuid);
|
|
1160
|
+
}
|
|
1151
1161
|
(_c = this.Log) === null || _c === void 0 ? void 0 : _c.debug(`[Electron BLE] detectProtocol: uuid=${uuid} -> ${protocol}`);
|
|
1152
1162
|
return protocol;
|
|
1153
1163
|
}
|
package/dist/webusb.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"webusb.d.ts","sourceRoot":"","sources":["../src/webusb.ts"],"names":[],"mappings":";AACA,OAAO,SAAS,EAAE,EAQhB,0BAA0B,EAE3B,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"webusb.d.ts","sourceRoot":"","sources":["../src/webusb.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@onekeyfe/hd-transport-web-device",
|
|
3
|
-
"version": "1.2.0-alpha.
|
|
3
|
+
"version": "1.2.0-alpha.145",
|
|
4
4
|
"author": "OneKey",
|
|
5
5
|
"homepage": "https://github.com/OneKeyHQ/hardware-js-sdk#readme",
|
|
6
6
|
"license": "MIT",
|
|
@@ -21,13 +21,13 @@
|
|
|
21
21
|
"lint:fix": "eslint . --fix"
|
|
22
22
|
},
|
|
23
23
|
"dependencies": {
|
|
24
|
-
"@onekeyfe/hd-shared": "1.2.0-alpha.
|
|
25
|
-
"@onekeyfe/hd-transport": "1.2.0-alpha.
|
|
24
|
+
"@onekeyfe/hd-shared": "1.2.0-alpha.145",
|
|
25
|
+
"@onekeyfe/hd-transport": "1.2.0-alpha.145"
|
|
26
26
|
},
|
|
27
27
|
"devDependencies": {
|
|
28
|
-
"@onekeyfe/hd-transport-electron": "1.2.0-alpha.
|
|
28
|
+
"@onekeyfe/hd-transport-electron": "1.2.0-alpha.145",
|
|
29
29
|
"@types/w3c-web-usb": "^1.0.6",
|
|
30
30
|
"@types/web-bluetooth": "^0.0.17"
|
|
31
31
|
},
|
|
32
|
-
"gitHead": "
|
|
32
|
+
"gitHead": "9a136f881865c15e603ef271ae820c2b5a991dcc"
|
|
33
33
|
}
|
|
@@ -51,10 +51,6 @@ interface PacketProcessResult {
|
|
|
51
51
|
error?: string;
|
|
52
52
|
}
|
|
53
53
|
|
|
54
|
-
function inferProtocolHintFromDeviceName(name?: string | null): ProtocolType | undefined {
|
|
55
|
-
return /\bpro\s*2\b/i.test(name ?? '') ? 'V2' : undefined;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
54
|
const toBleDescriptor = (
|
|
59
55
|
device: { id: string; name: string | null },
|
|
60
56
|
protocolType?: ProtocolType
|
|
@@ -105,6 +101,12 @@ export default class ElectronBleTransport {
|
|
|
105
101
|
|
|
106
102
|
private deviceProtocolHints: Map<string, ProtocolType> = new Map();
|
|
107
103
|
|
|
104
|
+
/** Endpoints that answered a V2 probe in this transport lifetime. Survives disconnect. */
|
|
105
|
+
private confirmedProtocolV2 = new Set<string>();
|
|
106
|
+
|
|
107
|
+
/** First expected-V2 miss for an unconfirmed endpoint; the next miss is a stale bond. */
|
|
108
|
+
private retryableV2Mismatch = new Set<string>();
|
|
109
|
+
|
|
108
110
|
private deviceMtus: Map<string, number> = new Map();
|
|
109
111
|
|
|
110
112
|
private devicePacketCapacities: Map<string, number> = new Map();
|
|
@@ -269,10 +271,6 @@ export default class ElectronBleTransport {
|
|
|
269
271
|
this.Log?.debug(`[Electron BLE] enumerate found ${devices.length} device(s):`);
|
|
270
272
|
for (const dev of devices) {
|
|
271
273
|
this.Log?.debug(`[Electron BLE] id="${dev.id}" name="${dev.name}"`);
|
|
272
|
-
const protocolHint = inferProtocolHintFromDeviceName(dev.name);
|
|
273
|
-
if (protocolHint) {
|
|
274
|
-
this.deviceProtocolHints.set(dev.id, protocolHint);
|
|
275
|
-
}
|
|
276
274
|
}
|
|
277
275
|
return devices.map(device => toBleDescriptor(device));
|
|
278
276
|
} catch (error) {
|
|
@@ -310,9 +308,7 @@ export default class ElectronBleTransport {
|
|
|
310
308
|
}
|
|
311
309
|
const protocolHint = expectedProtocol
|
|
312
310
|
? undefined
|
|
313
|
-
: input.protocolHint ??
|
|
314
|
-
this.deviceProtocolHints.get(uuid) ??
|
|
315
|
-
inferProtocolHintFromDeviceName(device.name);
|
|
311
|
+
: input.protocolHint ?? this.deviceProtocolHints.get(uuid);
|
|
316
312
|
if (protocolHint) {
|
|
317
313
|
this.deviceProtocolHints.set(uuid, protocolHint);
|
|
318
314
|
}
|
|
@@ -442,11 +438,20 @@ export default class ElectronBleTransport {
|
|
|
442
438
|
}
|
|
443
439
|
}
|
|
444
440
|
|
|
445
|
-
private createProtocolMismatchError(expected: ProtocolType) {
|
|
446
|
-
//
|
|
447
|
-
//
|
|
441
|
+
private createProtocolMismatchError(expected: ProtocolType, uuid: string) {
|
|
442
|
+
// Caller `expectedProtocol: 'V2'` is not proof this endpoint already answered.
|
|
443
|
+
// A first-connect or flaky Ping must stay retryable. A later miss after a
|
|
444
|
+
// confirmed V2 answer, or a second miss on the same uuid, is a stale bond.
|
|
445
|
+
const isStaleV2Bond =
|
|
446
|
+
expected === 'V2' &&
|
|
447
|
+
(this.confirmedProtocolV2.has(uuid) || this.retryableV2Mismatch.has(uuid));
|
|
448
|
+
if (expected === 'V2' && !isStaleV2Bond) {
|
|
449
|
+
this.retryableV2Mismatch.add(uuid);
|
|
450
|
+
} else if (isStaleV2Bond) {
|
|
451
|
+
this.retryableV2Mismatch.delete(uuid);
|
|
452
|
+
}
|
|
448
453
|
return ERRORS.TypedError(
|
|
449
|
-
|
|
454
|
+
isStaleV2Bond ? HardwareErrorCode.BleDeviceBondError : HardwareErrorCode.RuntimeError,
|
|
450
455
|
`Device protocol mismatch: expected ${expected}, but device did not respond to expected protocol`
|
|
451
456
|
);
|
|
452
457
|
}
|
|
@@ -475,16 +480,18 @@ export default class ElectronBleTransport {
|
|
|
475
480
|
this.Log?.debug(`[Electron BLE] detectProtocol: uuid=${uuid} -> V1 (expected)`);
|
|
476
481
|
return 'V1';
|
|
477
482
|
}
|
|
478
|
-
throw this.createProtocolMismatchError(expectedProtocol);
|
|
483
|
+
throw this.createProtocolMismatchError(expectedProtocol, uuid);
|
|
479
484
|
}
|
|
480
485
|
|
|
481
486
|
if (expectedProtocol === 'V2') {
|
|
482
487
|
if (await this.probeProtocolV2(uuid)) {
|
|
483
488
|
this.deviceProtocol.set(uuid, 'V2');
|
|
489
|
+
this.confirmedProtocolV2.add(uuid);
|
|
490
|
+
this.retryableV2Mismatch.delete(uuid);
|
|
484
491
|
this.Log?.debug(`[Electron BLE] detectProtocol: uuid=${uuid} -> V2 (expected)`);
|
|
485
492
|
return 'V2';
|
|
486
493
|
}
|
|
487
|
-
throw this.createProtocolMismatchError(expectedProtocol);
|
|
494
|
+
throw this.createProtocolMismatchError(expectedProtocol, uuid);
|
|
488
495
|
}
|
|
489
496
|
|
|
490
497
|
// Protocol must be actively probed after connection. Name, PID, and descriptors only
|
|
@@ -503,6 +510,10 @@ export default class ElectronBleTransport {
|
|
|
503
510
|
protocol === 'V1' ? await this.probeProtocolV1(uuid) : await this.probeProtocolV2(uuid);
|
|
504
511
|
if (detected) {
|
|
505
512
|
this.deviceProtocol.set(uuid, protocol);
|
|
513
|
+
if (protocol === 'V2') {
|
|
514
|
+
this.confirmedProtocolV2.add(uuid);
|
|
515
|
+
this.retryableV2Mismatch.delete(uuid);
|
|
516
|
+
}
|
|
506
517
|
this.Log?.debug(`[Electron BLE] detectProtocol: uuid=${uuid} -> ${protocol}`);
|
|
507
518
|
return protocol;
|
|
508
519
|
}
|
package/src/webusb.ts
CHANGED
|
@@ -14,7 +14,9 @@ import {
|
|
|
14
14
|
ERRORS,
|
|
15
15
|
HardwareErrorCode,
|
|
16
16
|
ONEKEY_WEBUSB_FILTER,
|
|
17
|
+
inferProtocolHintFromUsbId,
|
|
17
18
|
isKnownTrezorWebUsbDevice,
|
|
19
|
+
resolveOneKeyUsbDevicePath,
|
|
18
20
|
wait,
|
|
19
21
|
} from '@onekeyfe/hd-shared';
|
|
20
22
|
import ByteBuffer from 'bytebuffer';
|
|
@@ -45,9 +47,6 @@ const PACKET_IO_RETRY_DELAY = 300;
|
|
|
45
47
|
const PROTOCOL_V1_PROBE_TIMEOUT = 5000;
|
|
46
48
|
const PROTOCOL_V2_PROBE_TIMEOUT = 1000;
|
|
47
49
|
const EXPECTED_PROTOCOL_V2_PROBE_ATTEMPTS = 2;
|
|
48
|
-
function inferProtocolHintFromDeviceName(name?: string | null): ProtocolType | undefined {
|
|
49
|
-
return /\bpro\s*2\b/i.test(name ?? '') ? 'V2' : undefined;
|
|
50
|
-
}
|
|
51
50
|
|
|
52
51
|
/**
|
|
53
52
|
* Device information with path and WebUSB device instance
|
|
@@ -84,9 +83,10 @@ function registerActiveWebUsbTransport(instance: WebUsbTransport, usb: USB) {
|
|
|
84
83
|
if (usbDisconnectListenerAttached) return;
|
|
85
84
|
usbDisconnectListenerAttached = true;
|
|
86
85
|
usb.addEventListener('disconnect', event => {
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
86
|
+
if (!event.device) return;
|
|
87
|
+
const path = resolveOneKeyUsbDevicePath(event.device);
|
|
88
|
+
if (!path) return;
|
|
89
|
+
activeWebUsbTransport?.markProtocolStale(path);
|
|
90
90
|
});
|
|
91
91
|
}
|
|
92
92
|
|
|
@@ -256,22 +256,24 @@ export default class WebUsbTransport extends ProtocolV2UsbTransportBase<string>
|
|
|
256
256
|
(desc: { vendorId: number; productId: number }) =>
|
|
257
257
|
dev.vendorId === desc.vendorId && dev.productId === desc.productId
|
|
258
258
|
);
|
|
259
|
-
|
|
260
|
-
return isOneKey && hasSerialNumber && !isKnownTrezorWebUsbDevice(dev);
|
|
259
|
+
return isOneKey && !isKnownTrezorWebUsbDevice(dev);
|
|
261
260
|
});
|
|
262
261
|
|
|
263
|
-
this.deviceList = onekeyDevices.
|
|
264
|
-
const path = device
|
|
265
|
-
|
|
262
|
+
this.deviceList = onekeyDevices.flatMap(device => {
|
|
263
|
+
const path = resolveOneKeyUsbDevicePath(device);
|
|
264
|
+
if (!path) return [];
|
|
265
|
+
const protocolHint = inferProtocolHintFromUsbId(device.vendorId, device.productId);
|
|
266
266
|
if (protocolHint) {
|
|
267
267
|
this.deviceProtocolHints.set(path, protocolHint);
|
|
268
268
|
}
|
|
269
269
|
|
|
270
|
-
return
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
270
|
+
return [
|
|
271
|
+
{
|
|
272
|
+
path,
|
|
273
|
+
device,
|
|
274
|
+
commType: 'webusb',
|
|
275
|
+
},
|
|
276
|
+
];
|
|
275
277
|
});
|
|
276
278
|
|
|
277
279
|
return this.deviceList;
|
|
@@ -316,13 +318,12 @@ export default class WebUsbTransport extends ProtocolV2UsbTransportBase<string>
|
|
|
316
318
|
this.deviceProtocol.delete(input.path);
|
|
317
319
|
}
|
|
318
320
|
if (!this.deviceProtocol.has(input.path)) {
|
|
319
|
-
const
|
|
320
|
-
.productName;
|
|
321
|
+
const usbDevice = this.deviceList.find(device => device.path === input.path)?.device;
|
|
321
322
|
const protocolHint = input.expectedProtocol
|
|
322
323
|
? undefined
|
|
323
324
|
: input.protocolHint ??
|
|
324
325
|
this.deviceProtocolHints.get(input.path) ??
|
|
325
|
-
|
|
326
|
+
inferProtocolHintFromUsbId(usbDevice?.vendorId, usbDevice?.productId);
|
|
326
327
|
if (protocolHint) {
|
|
327
328
|
this.deviceProtocolHints.set(input.path, protocolHint);
|
|
328
329
|
}
|