@onekeyfe/hd-transport-web-device 1.2.0-alpha.159 → 1.2.0-alpha.160
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.
|
@@ -500,6 +500,24 @@ describe('ElectronBleTransport protocol detection', () => {
|
|
|
500
500
|
expect(transport.getProtocolType(device.id)).toBeUndefined();
|
|
501
501
|
});
|
|
502
502
|
|
|
503
|
+
test('fails Protocol V2 acquire immediately when subscribe reports insufficient encryption', async () => {
|
|
504
|
+
const device = { id: 'stale-bond-pro2-id', name: 'OneKey Pro 2' };
|
|
505
|
+
const nobleBle = createNobleBle(device);
|
|
506
|
+
nobleBle.subscribe.mockRejectedValue(new Error('Encryption is insufficient'));
|
|
507
|
+
const transport = configureTransport(nobleBle);
|
|
508
|
+
const probe = jest.spyOn(transport as any, 'probeProtocolV2');
|
|
509
|
+
|
|
510
|
+
await expect(
|
|
511
|
+
transport.acquire({ uuid: device.id, expectedProtocol: 'V2' })
|
|
512
|
+
).rejects.toMatchObject({
|
|
513
|
+
errorCode: HardwareErrorCode.BleDeviceBondError,
|
|
514
|
+
});
|
|
515
|
+
|
|
516
|
+
expect(probe).not.toHaveBeenCalled();
|
|
517
|
+
expect(nobleBle.unsubscribe).toHaveBeenCalledWith(device.id);
|
|
518
|
+
expect(nobleBle.disconnect).toHaveBeenCalledWith(device.id);
|
|
519
|
+
});
|
|
520
|
+
|
|
503
521
|
test('reports a stale bond when a previously confirmed Protocol V2 device stops responding', async () => {
|
|
504
522
|
const device = { id: 'reset-pro2-id', name: 'OneKey Pro 2' };
|
|
505
523
|
const nobleBle = createNobleBle(device);
|
|
@@ -41,6 +41,7 @@ export default class ElectronBleTransport {
|
|
|
41
41
|
private hostDisconnectCleanup?;
|
|
42
42
|
private notificationTokens;
|
|
43
43
|
private nextNotificationToken;
|
|
44
|
+
private toStaleBondError;
|
|
44
45
|
private handleBluetoothError;
|
|
45
46
|
private cleanupDeviceState;
|
|
46
47
|
init(logger: any, emitter?: EventEmitter): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"electron-ble-transport.d.ts","sourceRoot":"","sources":["../src/electron-ble-transport.ts"],"names":[],"mappings":";
|
|
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
|
@@ -240,6 +240,7 @@ declare class ElectronBleTransport {
|
|
|
240
240
|
private hostDisconnectCleanup?;
|
|
241
241
|
private notificationTokens;
|
|
242
242
|
private nextNotificationToken;
|
|
243
|
+
private toStaleBondError;
|
|
243
244
|
private handleBluetoothError;
|
|
244
245
|
private cleanupDeviceState;
|
|
245
246
|
init(logger: any, emitter?: EventEmitter): void;
|
package/dist/index.js
CHANGED
|
@@ -852,7 +852,26 @@ class ElectronBleTransport {
|
|
|
852
852
|
this.notificationTokens = new Map();
|
|
853
853
|
this.nextNotificationToken = 1;
|
|
854
854
|
}
|
|
855
|
+
toStaleBondError(error) {
|
|
856
|
+
var _a;
|
|
857
|
+
if (hdShared.isBleStaleBondHardwareError(error)) {
|
|
858
|
+
return error;
|
|
859
|
+
}
|
|
860
|
+
const errorMessage = error && typeof error === 'object' && 'message' in error
|
|
861
|
+
? String((_a = error.message) !== null && _a !== void 0 ? _a : '')
|
|
862
|
+
: String(error !== null && error !== void 0 ? error : '');
|
|
863
|
+
if (!hdShared.isBleStaleBondErrorText(errorMessage)) {
|
|
864
|
+
return null;
|
|
865
|
+
}
|
|
866
|
+
return hdShared.ERRORS.TypedError(errorMessage.includes('Peer removed pairing information')
|
|
867
|
+
? hdShared.HardwareErrorCode.BlePeerRemovedPairingInformation
|
|
868
|
+
: hdShared.HardwareErrorCode.BleDeviceBondError, errorMessage);
|
|
869
|
+
}
|
|
855
870
|
handleBluetoothError(error) {
|
|
871
|
+
const staleBondError = this.toStaleBondError(error);
|
|
872
|
+
if (staleBondError) {
|
|
873
|
+
throw staleBondError;
|
|
874
|
+
}
|
|
856
875
|
if (error && typeof error === 'object') {
|
|
857
876
|
if ('code' in error) {
|
|
858
877
|
if (error.code === hdShared.HardwareErrorCode.BlePoweredOff) {
|
|
@@ -1022,7 +1041,12 @@ class ElectronBleTransport {
|
|
|
1022
1041
|
}
|
|
1023
1042
|
this.v1Buffers.set(uuid, { buffer: [], bufferLength: 0 });
|
|
1024
1043
|
this.v2Assemblers.set(uuid, new transport.ProtocolV2FrameAssembler(transport.PROTOCOL_V2_BLE_FRAME_MAX_BYTES));
|
|
1025
|
-
|
|
1044
|
+
try {
|
|
1045
|
+
yield window.desktopApi.nobleBle.subscribe(uuid);
|
|
1046
|
+
}
|
|
1047
|
+
catch (error) {
|
|
1048
|
+
this.handleBluetoothError(error);
|
|
1049
|
+
}
|
|
1026
1050
|
yield this.refreshBlePacketCapacity(uuid);
|
|
1027
1051
|
const cleanup = this.createNotificationSubscription(uuid);
|
|
1028
1052
|
this.notificationCleanups.set(uuid, cleanup);
|
|
@@ -1211,6 +1235,9 @@ class ElectronBleTransport {
|
|
|
1211
1235
|
catch (error) {
|
|
1212
1236
|
this.clearProbeProtocol(uuid, 'V1');
|
|
1213
1237
|
(_a = this.Log) === null || _a === void 0 ? void 0 : _a.debug('[Electron BLE] Protocol V1 GetFeatures probe failed:', error);
|
|
1238
|
+
if (hdShared.isBleStaleBondHardwareError(error)) {
|
|
1239
|
+
throw error;
|
|
1240
|
+
}
|
|
1214
1241
|
return false;
|
|
1215
1242
|
}
|
|
1216
1243
|
});
|
|
@@ -1233,6 +1260,7 @@ class ElectronBleTransport {
|
|
|
1233
1260
|
(_a = this.v2Assemblers.get(uuid)) === null || _a === void 0 ? void 0 : _a.reset();
|
|
1234
1261
|
this.resetProtocolV2Frames(uuid);
|
|
1235
1262
|
},
|
|
1263
|
+
shouldRethrow: hdShared.isBleStaleBondHardwareError,
|
|
1236
1264
|
});
|
|
1237
1265
|
if (!detected) {
|
|
1238
1266
|
this.clearProbeProtocol(uuid, 'V2');
|
|
@@ -1247,7 +1275,16 @@ class ElectronBleTransport {
|
|
|
1247
1275
|
if (!nobleBle) {
|
|
1248
1276
|
throw new Error('Noble BLE API not available');
|
|
1249
1277
|
}
|
|
1250
|
-
|
|
1278
|
+
try {
|
|
1279
|
+
yield nobleBle.write(uuid, hexData, { pacingDelayMs: 0 });
|
|
1280
|
+
}
|
|
1281
|
+
catch (error) {
|
|
1282
|
+
const staleBondError = this.toStaleBondError(error);
|
|
1283
|
+
if (staleBondError) {
|
|
1284
|
+
throw staleBondError;
|
|
1285
|
+
}
|
|
1286
|
+
throw error;
|
|
1287
|
+
}
|
|
1251
1288
|
});
|
|
1252
1289
|
}
|
|
1253
1290
|
refreshBlePacketCapacity(uuid) {
|
|
@@ -1457,7 +1494,16 @@ class ElectronBleTransport {
|
|
|
1457
1494
|
if (hexString.length === 0) {
|
|
1458
1495
|
throw new Error(`Buffer ${i + 1} is empty`);
|
|
1459
1496
|
}
|
|
1460
|
-
|
|
1497
|
+
try {
|
|
1498
|
+
yield window.desktopApi.nobleBle.write(uuid, hexString);
|
|
1499
|
+
}
|
|
1500
|
+
catch (error) {
|
|
1501
|
+
const staleBondError = this.toStaleBondError(error);
|
|
1502
|
+
if (staleBondError) {
|
|
1503
|
+
throw staleBondError;
|
|
1504
|
+
}
|
|
1505
|
+
throw error;
|
|
1506
|
+
}
|
|
1461
1507
|
}
|
|
1462
1508
|
const response = yield Promise.race([
|
|
1463
1509
|
runPromise.promise,
|
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.160",
|
|
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.160",
|
|
25
|
+
"@onekeyfe/hd-transport": "1.2.0-alpha.160"
|
|
26
26
|
},
|
|
27
27
|
"devDependencies": {
|
|
28
|
-
"@onekeyfe/hd-transport-electron": "1.2.0-alpha.
|
|
28
|
+
"@onekeyfe/hd-transport-electron": "1.2.0-alpha.160",
|
|
29
29
|
"@types/w3c-web-usb": "^1.0.6",
|
|
30
30
|
"@types/web-bluetooth": "^0.0.17"
|
|
31
31
|
},
|
|
32
|
-
"gitHead": "
|
|
32
|
+
"gitHead": "df1736352e44ac76af4185eb7a6112a081b0d68c"
|
|
33
33
|
}
|
|
@@ -16,6 +16,8 @@ import {
|
|
|
16
16
|
HardwareErrorCode,
|
|
17
17
|
HardwareErrorCodeMessage,
|
|
18
18
|
createDeferred,
|
|
19
|
+
isBleStaleBondErrorText,
|
|
20
|
+
isBleStaleBondHardwareError,
|
|
19
21
|
isHeaderChunk,
|
|
20
22
|
} from '@onekeyfe/hd-shared';
|
|
21
23
|
|
|
@@ -159,7 +161,30 @@ export default class ElectronBleTransport {
|
|
|
159
161
|
|
|
160
162
|
private nextNotificationToken = 1;
|
|
161
163
|
|
|
164
|
+
private toStaleBondError(error: unknown): Error | null {
|
|
165
|
+
if (isBleStaleBondHardwareError(error)) {
|
|
166
|
+
return error as Error;
|
|
167
|
+
}
|
|
168
|
+
const errorMessage =
|
|
169
|
+
error && typeof error === 'object' && 'message' in error
|
|
170
|
+
? String((error as { message?: unknown }).message ?? '')
|
|
171
|
+
: String(error ?? '');
|
|
172
|
+
if (!isBleStaleBondErrorText(errorMessage)) {
|
|
173
|
+
return null;
|
|
174
|
+
}
|
|
175
|
+
return ERRORS.TypedError(
|
|
176
|
+
errorMessage.includes('Peer removed pairing information')
|
|
177
|
+
? HardwareErrorCode.BlePeerRemovedPairingInformation
|
|
178
|
+
: HardwareErrorCode.BleDeviceBondError,
|
|
179
|
+
errorMessage
|
|
180
|
+
);
|
|
181
|
+
}
|
|
182
|
+
|
|
162
183
|
private handleBluetoothError(error: any): never {
|
|
184
|
+
const staleBondError = this.toStaleBondError(error);
|
|
185
|
+
if (staleBondError) {
|
|
186
|
+
throw staleBondError;
|
|
187
|
+
}
|
|
163
188
|
if (error && typeof error === 'object') {
|
|
164
189
|
if ('code' in error) {
|
|
165
190
|
if (error.code === HardwareErrorCode.BlePoweredOff) {
|
|
@@ -367,7 +392,11 @@ export default class ElectronBleTransport {
|
|
|
367
392
|
this.v1Buffers.set(uuid, { buffer: [], bufferLength: 0 });
|
|
368
393
|
this.v2Assemblers.set(uuid, new ProtocolV2FrameAssembler(PROTOCOL_V2_BLE_FRAME_MAX_BYTES));
|
|
369
394
|
|
|
370
|
-
|
|
395
|
+
try {
|
|
396
|
+
await window.desktopApi.nobleBle.subscribe(uuid);
|
|
397
|
+
} catch (error) {
|
|
398
|
+
this.handleBluetoothError(error);
|
|
399
|
+
}
|
|
371
400
|
await this.refreshBlePacketCapacity(uuid);
|
|
372
401
|
|
|
373
402
|
const cleanup = this.createNotificationSubscription(uuid);
|
|
@@ -588,6 +617,9 @@ export default class ElectronBleTransport {
|
|
|
588
617
|
} catch (error) {
|
|
589
618
|
this.clearProbeProtocol(uuid, 'V1');
|
|
590
619
|
this.Log?.debug('[Electron BLE] Protocol V1 GetFeatures probe failed:', error);
|
|
620
|
+
if (isBleStaleBondHardwareError(error)) {
|
|
621
|
+
throw error;
|
|
622
|
+
}
|
|
591
623
|
return false;
|
|
592
624
|
}
|
|
593
625
|
}
|
|
@@ -608,6 +640,7 @@ export default class ElectronBleTransport {
|
|
|
608
640
|
this.v2Assemblers.get(uuid)?.reset();
|
|
609
641
|
this.resetProtocolV2Frames(uuid);
|
|
610
642
|
},
|
|
643
|
+
shouldRethrow: isBleStaleBondHardwareError,
|
|
611
644
|
});
|
|
612
645
|
if (!detected) {
|
|
613
646
|
this.clearProbeProtocol(uuid, 'V2');
|
|
@@ -621,7 +654,15 @@ export default class ElectronBleTransport {
|
|
|
621
654
|
throw new Error('Noble BLE API not available');
|
|
622
655
|
}
|
|
623
656
|
|
|
624
|
-
|
|
657
|
+
try {
|
|
658
|
+
await nobleBle.write(uuid, hexData, { pacingDelayMs: 0 });
|
|
659
|
+
} catch (error) {
|
|
660
|
+
const staleBondError = this.toStaleBondError(error);
|
|
661
|
+
if (staleBondError) {
|
|
662
|
+
throw staleBondError;
|
|
663
|
+
}
|
|
664
|
+
throw error;
|
|
665
|
+
}
|
|
625
666
|
}
|
|
626
667
|
|
|
627
668
|
private async refreshBlePacketCapacity(uuid: string): Promise<void> {
|
|
@@ -863,7 +904,15 @@ export default class ElectronBleTransport {
|
|
|
863
904
|
if (hexString.length === 0) {
|
|
864
905
|
throw new Error(`Buffer ${i + 1} is empty`);
|
|
865
906
|
}
|
|
866
|
-
|
|
907
|
+
try {
|
|
908
|
+
await window.desktopApi.nobleBle.write(uuid, hexString);
|
|
909
|
+
} catch (error) {
|
|
910
|
+
const staleBondError = this.toStaleBondError(error);
|
|
911
|
+
if (staleBondError) {
|
|
912
|
+
throw staleBondError;
|
|
913
|
+
}
|
|
914
|
+
throw error;
|
|
915
|
+
}
|
|
867
916
|
}
|
|
868
917
|
|
|
869
918
|
const response = await Promise.race([
|