@onekeyfe/hd-transport-web-device 1.2.2-alpha.101 → 1.2.2-alpha.102
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.
|
@@ -182,6 +182,40 @@ describe('ElectronBleTransport protocol detection', () => {
|
|
|
182
182
|
jest.clearAllMocks();
|
|
183
183
|
});
|
|
184
184
|
|
|
185
|
+
test('does not treat an error envelope from a legacy preload as a successful connect', async () => {
|
|
186
|
+
const device = { id: 'stale-bond-id', name: 'OneKey Pro 2' };
|
|
187
|
+
const nobleBle = createNobleBle(device);
|
|
188
|
+
nobleBle.connect.mockResolvedValue({
|
|
189
|
+
type: 'NobleBleIpcError',
|
|
190
|
+
success: false,
|
|
191
|
+
error: {
|
|
192
|
+
name: 'HardwareError',
|
|
193
|
+
message: 'Bluetooth pairing information is no longer valid',
|
|
194
|
+
errorCode: HardwareErrorCode.BleBondInvalid,
|
|
195
|
+
},
|
|
196
|
+
} as never);
|
|
197
|
+
const bleTransport = configureTransport(nobleBle);
|
|
198
|
+
|
|
199
|
+
await expect(
|
|
200
|
+
bleTransport.acquire({ uuid: device.id, expectedProtocol: 'V2' })
|
|
201
|
+
).rejects.toMatchObject({
|
|
202
|
+
errorCode: HardwareErrorCode.BleBondInvalid,
|
|
203
|
+
});
|
|
204
|
+
expect(nobleBle.subscribe).not.toHaveBeenCalled();
|
|
205
|
+
expect(nobleBle.disconnect).toHaveBeenCalledWith(device.id);
|
|
206
|
+
});
|
|
207
|
+
|
|
208
|
+
test('sends a native disconnect even before acquire marks the device connected', async () => {
|
|
209
|
+
const device = { id: 'pending-connect-id', name: 'OneKey Pro 2' };
|
|
210
|
+
const nobleBle = createNobleBle(device);
|
|
211
|
+
const bleTransport = configureTransport(nobleBle) as any;
|
|
212
|
+
|
|
213
|
+
await bleTransport.releaseNative(device.id);
|
|
214
|
+
|
|
215
|
+
expect(nobleBle.unsubscribe).not.toHaveBeenCalled();
|
|
216
|
+
expect(nobleBle.disconnect).toHaveBeenCalledWith(device.id);
|
|
217
|
+
});
|
|
218
|
+
|
|
185
219
|
test('keeps raw BLE lifecycle payloads off the public device event channel', async () => {
|
|
186
220
|
const device = { id: 'lifecycle-pro2-id', name: 'OneKey Pro 2' };
|
|
187
221
|
const nobleBle = createNobleBle(device);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"electron-ble-transport.d.ts","sourceRoot":"","sources":["../src/electron-ble-transport.ts"],"names":[],"mappings":";AA0BA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,KAAK,EAAE,UAAU,
|
|
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.js
CHANGED
|
@@ -823,6 +823,19 @@ function resolveBlePacketCapacity(mtu, maximumPacketCapacity, fallbackPacketCapa
|
|
|
823
823
|
|
|
824
824
|
const { parseConfigure, ProtocolV1, check } = transport__default["default"];
|
|
825
825
|
const toBleDescriptor = (device, protocolType) => (Object.assign({ id: device.id, name: device.name, path: device.id, debug: false, commType: 'electron-ble' }, (protocolType ? { protocolType } : {})));
|
|
826
|
+
const invokeNobleBle = (request) => __awaiter(void 0, void 0, void 0, function* () {
|
|
827
|
+
const response = yield request;
|
|
828
|
+
if (response &&
|
|
829
|
+
typeof response === 'object' &&
|
|
830
|
+
'type' in response &&
|
|
831
|
+
response.type === 'NobleBleIpcError' &&
|
|
832
|
+
'success' in response &&
|
|
833
|
+
response.success === false &&
|
|
834
|
+
'error' in response) {
|
|
835
|
+
return Promise.reject(response.error);
|
|
836
|
+
}
|
|
837
|
+
return response;
|
|
838
|
+
});
|
|
826
839
|
const BLE_PACKET_SIZE_FALLBACK = 192;
|
|
827
840
|
const BLE_PACKET_SIZE_MAXIMUM = 244;
|
|
828
841
|
const BLE_WRITE_DELAY_MS = 5;
|
|
@@ -991,7 +1004,7 @@ class ElectronBleTransport {
|
|
|
991
1004
|
if (!((_a = window.desktopApi) === null || _a === void 0 ? void 0 : _a.nobleBle)) {
|
|
992
1005
|
throw new Error('Noble BLE API not available');
|
|
993
1006
|
}
|
|
994
|
-
const devices = yield window.desktopApi.nobleBle.enumerate();
|
|
1007
|
+
const devices = yield invokeNobleBle(window.desktopApi.nobleBle.enumerate());
|
|
995
1008
|
(_b = this.Log) === null || _b === void 0 ? void 0 : _b.debug(`[Electron BLE] enumerate found ${devices.length} device(s):`);
|
|
996
1009
|
for (const dev of devices) {
|
|
997
1010
|
(_c = this.Log) === null || _c === void 0 ? void 0 : _c.debug(`[Electron BLE] id="${dev.id}" name="${dev.name}"`);
|
|
@@ -1024,7 +1037,7 @@ class ElectronBleTransport {
|
|
|
1024
1037
|
if (!((_a = window.desktopApi) === null || _a === void 0 ? void 0 : _a.nobleBle)) {
|
|
1025
1038
|
throw new Error('Noble BLE API not available');
|
|
1026
1039
|
}
|
|
1027
|
-
const device = yield window.desktopApi.nobleBle.getDevice(uuid);
|
|
1040
|
+
const device = yield invokeNobleBle(window.desktopApi.nobleBle.getDevice(uuid));
|
|
1028
1041
|
if (!device) {
|
|
1029
1042
|
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.DeviceNotFound, `Device ${uuid} not found`);
|
|
1030
1043
|
}
|
|
@@ -1035,7 +1048,7 @@ class ElectronBleTransport {
|
|
|
1035
1048
|
this.deviceProtocolHints.set(uuid, protocolHint);
|
|
1036
1049
|
}
|
|
1037
1050
|
try {
|
|
1038
|
-
yield window.desktopApi.nobleBle.connect(uuid);
|
|
1051
|
+
yield invokeNobleBle(window.desktopApi.nobleBle.connect(uuid));
|
|
1039
1052
|
this.connectedDevices.add(uuid);
|
|
1040
1053
|
}
|
|
1041
1054
|
catch (error) {
|
|
@@ -1048,7 +1061,7 @@ class ElectronBleTransport {
|
|
|
1048
1061
|
this.v1Buffers.set(uuid, { buffer: [], bufferLength: 0 });
|
|
1049
1062
|
this.v2Assemblers.set(uuid, new transport.ProtocolV2FrameAssembler(transport.PROTOCOL_V2_BLE_FRAME_MAX_BYTES));
|
|
1050
1063
|
try {
|
|
1051
|
-
yield window.desktopApi.nobleBle.subscribe(uuid);
|
|
1064
|
+
yield invokeNobleBle(window.desktopApi.nobleBle.subscribe(uuid));
|
|
1052
1065
|
}
|
|
1053
1066
|
catch (error) {
|
|
1054
1067
|
this.handleBluetoothError(error);
|
|
@@ -1069,9 +1082,15 @@ class ElectronBleTransport {
|
|
|
1069
1082
|
catch (error) {
|
|
1070
1083
|
(_e = this.Log) === null || _e === void 0 ? void 0 : _e.error('[Electron BLE] acquire failed:', error);
|
|
1071
1084
|
try {
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1085
|
+
const nobleBle = (_f = window.desktopApi) === null || _f === void 0 ? void 0 : _f.nobleBle;
|
|
1086
|
+
if (nobleBle) {
|
|
1087
|
+
if (this.connectedDevices.has(uuid)) {
|
|
1088
|
+
yield invokeNobleBle(nobleBle.unsubscribe(uuid)).catch(cleanupError => {
|
|
1089
|
+
var _a;
|
|
1090
|
+
(_a = this.Log) === null || _a === void 0 ? void 0 : _a.debug('[Electron BLE] acquire unsubscribe failed:', cleanupError);
|
|
1091
|
+
});
|
|
1092
|
+
}
|
|
1093
|
+
yield invokeNobleBle(nobleBle.disconnect(uuid));
|
|
1075
1094
|
}
|
|
1076
1095
|
}
|
|
1077
1096
|
catch (cleanupError) {
|
|
@@ -1104,13 +1123,17 @@ class ElectronBleTransport {
|
|
|
1104
1123
|
var _a, _b;
|
|
1105
1124
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1106
1125
|
try {
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
yield
|
|
1126
|
+
const nobleBle = (_a = window.desktopApi) === null || _a === void 0 ? void 0 : _a.nobleBle;
|
|
1127
|
+
if (nobleBle) {
|
|
1128
|
+
if (this.connectedDevices.has(id)) {
|
|
1129
|
+
yield invokeNobleBle(nobleBle.unsubscribe(id)).catch(error => {
|
|
1130
|
+
var _a;
|
|
1131
|
+
(_a = this.Log) === null || _a === void 0 ? void 0 : _a.debug('[Electron BLE] release unsubscribe failed:', error);
|
|
1132
|
+
});
|
|
1111
1133
|
}
|
|
1112
|
-
|
|
1134
|
+
yield invokeNobleBle(nobleBle.disconnect(id));
|
|
1113
1135
|
}
|
|
1136
|
+
this.cleanupDeviceState(id);
|
|
1114
1137
|
}
|
|
1115
1138
|
catch (error) {
|
|
1116
1139
|
(_b = this.Log) === null || _b === void 0 ? void 0 : _b.error('[Electron BLE] release failed:', error);
|
|
@@ -1134,7 +1157,7 @@ class ElectronBleTransport {
|
|
|
1134
1157
|
}
|
|
1135
1158
|
return;
|
|
1136
1159
|
}
|
|
1137
|
-
yield release(id, keepSession);
|
|
1160
|
+
yield invokeNobleBle(release(id, keepSession));
|
|
1138
1161
|
}
|
|
1139
1162
|
catch (error) {
|
|
1140
1163
|
(_d = this.Log) === null || _d === void 0 ? void 0 : _d.error('[Electron BLE] logical release failed:', error);
|
|
@@ -1279,7 +1302,7 @@ class ElectronBleTransport {
|
|
|
1279
1302
|
throw new Error('Noble BLE API not available');
|
|
1280
1303
|
}
|
|
1281
1304
|
try {
|
|
1282
|
-
yield nobleBle.write(uuid, hexData, { pacingDelayMs: 0 });
|
|
1305
|
+
yield invokeNobleBle(nobleBle.write(uuid, hexData, { pacingDelayMs: 0 }));
|
|
1283
1306
|
}
|
|
1284
1307
|
catch (error) {
|
|
1285
1308
|
this.handleBluetoothError(error);
|
|
@@ -1287,9 +1310,10 @@ class ElectronBleTransport {
|
|
|
1287
1310
|
});
|
|
1288
1311
|
}
|
|
1289
1312
|
refreshBlePacketCapacity(uuid) {
|
|
1290
|
-
var _a
|
|
1313
|
+
var _a;
|
|
1291
1314
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1292
|
-
const
|
|
1315
|
+
const nobleBle = (_a = window.desktopApi) === null || _a === void 0 ? void 0 : _a.nobleBle;
|
|
1316
|
+
const device = nobleBle ? yield invokeNobleBle(nobleBle.getDevice(uuid)) : undefined;
|
|
1293
1317
|
this.updateBlePacketCapacity(uuid, device === null || device === void 0 ? void 0 : device.mtu);
|
|
1294
1318
|
});
|
|
1295
1319
|
}
|
|
@@ -1512,7 +1536,7 @@ class ElectronBleTransport {
|
|
|
1512
1536
|
if (hexString.length === 0) {
|
|
1513
1537
|
throw new Error(`Buffer ${i + 1} is empty`);
|
|
1514
1538
|
}
|
|
1515
|
-
yield window.desktopApi.nobleBle.write(uuid, hexString);
|
|
1539
|
+
yield invokeNobleBle(window.desktopApi.nobleBle.write(uuid, hexString));
|
|
1516
1540
|
}
|
|
1517
1541
|
const response = yield Promise.race([
|
|
1518
1542
|
runPromise.promise,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@onekeyfe/hd-transport-web-device",
|
|
3
|
-
"version": "1.2.2-alpha.
|
|
3
|
+
"version": "1.2.2-alpha.102",
|
|
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.2-alpha.
|
|
25
|
-
"@onekeyfe/hd-transport": "1.2.2-alpha.
|
|
24
|
+
"@onekeyfe/hd-shared": "1.2.2-alpha.102",
|
|
25
|
+
"@onekeyfe/hd-transport": "1.2.2-alpha.102"
|
|
26
26
|
},
|
|
27
27
|
"devDependencies": {
|
|
28
|
-
"@onekeyfe/hd-transport-electron": "1.2.2-alpha.
|
|
28
|
+
"@onekeyfe/hd-transport-electron": "1.2.2-alpha.102",
|
|
29
29
|
"@types/w3c-web-usb": "^1.0.6",
|
|
30
30
|
"@types/web-bluetooth": "^0.0.17"
|
|
31
31
|
},
|
|
32
|
-
"gitHead": "
|
|
32
|
+
"gitHead": "abddc95e03d794d9c6fce7765d59de1f48a684d0"
|
|
33
33
|
}
|
|
@@ -25,7 +25,7 @@ import {
|
|
|
25
25
|
import { resolveBlePacketCapacity } from './ble-packet-capacity';
|
|
26
26
|
|
|
27
27
|
import type { Deferred } from '@onekeyfe/hd-shared';
|
|
28
|
-
import type { DesktopAPI } from '@onekeyfe/hd-transport-electron';
|
|
28
|
+
import type { DesktopAPI, NobleBleIpcErrorResponse } from '@onekeyfe/hd-transport-electron';
|
|
29
29
|
import type {
|
|
30
30
|
OneKeyDeviceInfo,
|
|
31
31
|
ProtocolType,
|
|
@@ -68,6 +68,22 @@ const toBleDescriptor = (
|
|
|
68
68
|
...(protocolType ? { protocolType } : {}),
|
|
69
69
|
} as OneKeyDeviceInfo);
|
|
70
70
|
|
|
71
|
+
const invokeNobleBle = async <T>(request: Promise<T>): Promise<T> => {
|
|
72
|
+
const response = await (request as Promise<T | NobleBleIpcErrorResponse>);
|
|
73
|
+
if (
|
|
74
|
+
response &&
|
|
75
|
+
typeof response === 'object' &&
|
|
76
|
+
'type' in response &&
|
|
77
|
+
response.type === 'NobleBleIpcError' &&
|
|
78
|
+
'success' in response &&
|
|
79
|
+
response.success === false &&
|
|
80
|
+
'error' in response
|
|
81
|
+
) {
|
|
82
|
+
return Promise.reject(response.error);
|
|
83
|
+
}
|
|
84
|
+
return response as T;
|
|
85
|
+
};
|
|
86
|
+
|
|
71
87
|
const BLE_PACKET_SIZE_FALLBACK = 192;
|
|
72
88
|
const BLE_PACKET_SIZE_MAXIMUM = 244;
|
|
73
89
|
const BLE_WRITE_DELAY_MS = 5;
|
|
@@ -320,7 +336,7 @@ export default class ElectronBleTransport {
|
|
|
320
336
|
if (!window.desktopApi?.nobleBle) {
|
|
321
337
|
throw new Error('Noble BLE API not available');
|
|
322
338
|
}
|
|
323
|
-
const devices = await window.desktopApi.nobleBle.enumerate();
|
|
339
|
+
const devices = await invokeNobleBle(window.desktopApi.nobleBle.enumerate());
|
|
324
340
|
this.Log?.debug(`[Electron BLE] enumerate found ${devices.length} device(s):`);
|
|
325
341
|
for (const dev of devices) {
|
|
326
342
|
this.Log?.debug(`[Electron BLE] id="${dev.id}" name="${dev.name}"`);
|
|
@@ -355,7 +371,7 @@ export default class ElectronBleTransport {
|
|
|
355
371
|
throw new Error('Noble BLE API not available');
|
|
356
372
|
}
|
|
357
373
|
|
|
358
|
-
const device = await window.desktopApi.nobleBle.getDevice(uuid);
|
|
374
|
+
const device = await invokeNobleBle(window.desktopApi.nobleBle.getDevice(uuid));
|
|
359
375
|
if (!device) {
|
|
360
376
|
throw ERRORS.TypedError(HardwareErrorCode.DeviceNotFound, `Device ${uuid} not found`);
|
|
361
377
|
}
|
|
@@ -367,7 +383,7 @@ export default class ElectronBleTransport {
|
|
|
367
383
|
}
|
|
368
384
|
|
|
369
385
|
try {
|
|
370
|
-
await window.desktopApi.nobleBle.connect(uuid);
|
|
386
|
+
await invokeNobleBle(window.desktopApi.nobleBle.connect(uuid));
|
|
371
387
|
this.connectedDevices.add(uuid);
|
|
372
388
|
} catch (error) {
|
|
373
389
|
this.handleBluetoothError(error);
|
|
@@ -382,7 +398,7 @@ export default class ElectronBleTransport {
|
|
|
382
398
|
this.v2Assemblers.set(uuid, new ProtocolV2FrameAssembler(PROTOCOL_V2_BLE_FRAME_MAX_BYTES));
|
|
383
399
|
|
|
384
400
|
try {
|
|
385
|
-
await window.desktopApi.nobleBle.subscribe(uuid);
|
|
401
|
+
await invokeNobleBle(window.desktopApi.nobleBle.subscribe(uuid));
|
|
386
402
|
} catch (error) {
|
|
387
403
|
this.handleBluetoothError(error);
|
|
388
404
|
}
|
|
@@ -407,9 +423,14 @@ export default class ElectronBleTransport {
|
|
|
407
423
|
} catch (error) {
|
|
408
424
|
this.Log?.error('[Electron BLE] acquire failed:', error);
|
|
409
425
|
try {
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
426
|
+
const nobleBle = window.desktopApi?.nobleBle;
|
|
427
|
+
if (nobleBle) {
|
|
428
|
+
if (this.connectedDevices.has(uuid)) {
|
|
429
|
+
await invokeNobleBle(nobleBle.unsubscribe(uuid)).catch(cleanupError => {
|
|
430
|
+
this.Log?.debug('[Electron BLE] acquire unsubscribe failed:', cleanupError);
|
|
431
|
+
});
|
|
432
|
+
}
|
|
433
|
+
await invokeNobleBle(nobleBle.disconnect(uuid));
|
|
413
434
|
}
|
|
414
435
|
} catch (cleanupError) {
|
|
415
436
|
this.Log?.debug('[Electron BLE] acquire cleanup failed:', cleanupError);
|
|
@@ -438,13 +459,16 @@ export default class ElectronBleTransport {
|
|
|
438
459
|
// Hard teardown, error paths only: a link presumed dead must not be reused.
|
|
439
460
|
private async releaseNative(id: string) {
|
|
440
461
|
try {
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
await
|
|
462
|
+
const nobleBle = window.desktopApi?.nobleBle;
|
|
463
|
+
if (nobleBle) {
|
|
464
|
+
if (this.connectedDevices.has(id)) {
|
|
465
|
+
await invokeNobleBle(nobleBle.unsubscribe(id)).catch(error => {
|
|
466
|
+
this.Log?.debug('[Electron BLE] release unsubscribe failed:', error);
|
|
467
|
+
});
|
|
445
468
|
}
|
|
446
|
-
|
|
469
|
+
await invokeNobleBle(nobleBle.disconnect(id));
|
|
447
470
|
}
|
|
471
|
+
this.cleanupDeviceState(id);
|
|
448
472
|
} catch (error) {
|
|
449
473
|
this.Log?.error('[Electron BLE] release failed:', error);
|
|
450
474
|
this.cleanupDeviceState(id);
|
|
@@ -470,7 +494,7 @@ export default class ElectronBleTransport {
|
|
|
470
494
|
}
|
|
471
495
|
return;
|
|
472
496
|
}
|
|
473
|
-
await release(id, keepSession);
|
|
497
|
+
await invokeNobleBle(release(id, keepSession));
|
|
474
498
|
} catch (error) {
|
|
475
499
|
this.Log?.error('[Electron BLE] logical release failed:', error);
|
|
476
500
|
this.cleanupDeviceState(id);
|
|
@@ -652,14 +676,15 @@ export default class ElectronBleTransport {
|
|
|
652
676
|
}
|
|
653
677
|
|
|
654
678
|
try {
|
|
655
|
-
await nobleBle.write(uuid, hexData, { pacingDelayMs: 0 });
|
|
679
|
+
await invokeNobleBle(nobleBle.write(uuid, hexData, { pacingDelayMs: 0 }));
|
|
656
680
|
} catch (error) {
|
|
657
681
|
this.handleBluetoothError(error);
|
|
658
682
|
}
|
|
659
683
|
}
|
|
660
684
|
|
|
661
685
|
private async refreshBlePacketCapacity(uuid: string): Promise<void> {
|
|
662
|
-
const
|
|
686
|
+
const nobleBle = window.desktopApi?.nobleBle;
|
|
687
|
+
const device = nobleBle ? await invokeNobleBle(nobleBle.getDevice(uuid)) : undefined;
|
|
663
688
|
this.updateBlePacketCapacity(uuid, device?.mtu);
|
|
664
689
|
}
|
|
665
690
|
|
|
@@ -917,7 +942,7 @@ export default class ElectronBleTransport {
|
|
|
917
942
|
if (hexString.length === 0) {
|
|
918
943
|
throw new Error(`Buffer ${i + 1} is empty`);
|
|
919
944
|
}
|
|
920
|
-
await window.desktopApi.nobleBle.write(uuid, hexString);
|
|
945
|
+
await invokeNobleBle(window.desktopApi.nobleBle.write(uuid, hexString));
|
|
921
946
|
}
|
|
922
947
|
|
|
923
948
|
const response = await Promise.race([
|