@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":"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"}
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
- yield window.desktopApi.nobleBle.subscribe(uuid);
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
- yield nobleBle.write(uuid, hexData, { pacingDelayMs: 0 });
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
- yield window.desktopApi.nobleBle.write(uuid, hexString);
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.159",
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.159",
25
- "@onekeyfe/hd-transport": "1.2.0-alpha.159"
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.159",
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": "302f9ff916b3769cdb0cf79d58d09a87eeac68c2"
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
- await window.desktopApi.nobleBle.subscribe(uuid);
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
- await nobleBle.write(uuid, hexData, { pacingDelayMs: 0 });
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
- await window.desktopApi.nobleBle.write(uuid, hexString);
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([