@onekeyfe/hd-transport-web-device 1.2.0-alpha.142 → 1.2.0-alpha.144

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.
@@ -440,6 +440,63 @@ 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
+
479
+ test('reports a stale bond when a previously confirmed Protocol V2 device stops responding', async () => {
480
+ const device = { id: 'reset-pro2-id', name: 'OneKey Pro 2' };
481
+ const nobleBle = createNobleBle(device);
482
+ const transport = configureTransport(nobleBle);
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);
488
+
489
+ await expect(
490
+ transport.acquire({ uuid: device.id, expectedProtocol: 'V2' })
491
+ ).rejects.toMatchObject({
492
+ errorCode: HardwareErrorCode.BleDeviceBondError,
493
+ });
494
+
495
+ expect(nobleBle.unsubscribe).toHaveBeenCalledWith(device.id);
496
+ expect(nobleBle.disconnect).toHaveBeenCalledWith(device.id);
497
+ expect(transport.getProtocolType(device.id)).toBeUndefined();
498
+ });
499
+
443
500
  test('probes Protocol V2 instead of trusting the Pro2 name hint', async () => {
444
501
  const device = { id: 'named-pro2-id', name: 'OneKey Pro 2' };
445
502
  const nobleBle = createNobleBle(device);
@@ -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;AAqCF,MAAM,CAAC,OAAO,OAAO,oBAAoB;IACvC,OAAO,CAAC,SAAS,CAA0D;IAE3E,OAAO,CAAC,WAAW,CAA0D;IAE7E,OAAO,CAAC,6BAA6B,CAAqB;IAE1D,IAAI,SAA0B;IAE9B,UAAU,UAAS;IAEnB,UAAU,EAAE,QAAQ,CAAC,UAAU,GAAG,MAAM,CAAC,GAAG,IAAI,CAAQ;IAExD,OAAO,CAAC,kBAAkB,CAAuB;IAEjD,GAAG,CAAC,EAAE,GAAG,CAAC;IAEV,OAAO,CAAC,EAAE,YAAY,CAAC;IAEvB,OAAO,CAAC,gBAAgB,CAA0B;IAElD,OAAO,CAAC,cAAc,CAAwC;IAE9D,OAAO,CAAC,mBAAmB,CAAwC;IAEnE,OAAO,CAAC,UAAU,CAAkC;IAEpD,OAAO,CAAC,sBAAsB,CAAkC;IAEhE,OAAO,CAAC,SAAS,CAAsE;IAEvF,OAAO,CAAC,YAAY,CAAoD;IAExE,OAAO,CAAC,aAAa,CAAwC;IAE7D,OAAO,CAAC,eAAe,CAAgD;IAEvE,OAAO,CAAC,eAAe,CAmBpB;IAGH,OAAO,CAAC,oBAAoB,CAAS;IAErC,OAAO,CAAC,oBAAoB,CAAsC;IAElE,OAAO,CAAC,WAAW,CAAsC;IAEzD,OAAO,CAAC,kBAAkB,CAAsC;IAEhE,OAAO,CAAC,kBAAkB,CAAkC;IAE5D,OAAO,CAAC,qBAAqB,CAAK;IAElC,OAAO,CAAC,oBAAoB;IA+B5B,OAAO,CAAC,kBAAkB;IAuC1B,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE,OAAO,CAAC,EAAE,YAAY;IAcxC,SAAS,CAAC,UAAU,EAAE,GAAG;IAKzB,mBAAmB,CAAC,UAAU,EAAE,GAAG;IAgB7B,MAAM;IAIN,SAAS,IAAI,OAAO,CAAC,gBAAgB,EAAE,CAAC;IAqBxC,OAAO,CAAC,KAAK,EAAE,eAAe;;;;;;;;;;;IAuG9B,OAAO,CAAC,EAAE,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,OAAO,EAAE,WAAW,CAAC,EAAE,OAAO;IAY7D,UAAU,CAAC,EAAE,EAAE,MAAM;YAKb,aAAa;YAiBb,cAAc;IAwB5B,OAAO,CAAC,2BAA2B;IAOnC,OAAO,CAAC,4BAA4B;IAOpC,OAAO,CAAC,kBAAkB;YAMZ,cAAc;IAgD5B,OAAO,CAAC,8BAA8B;YAgBxB,iCAAiC;YAwBjC,eAAe;YAkBf,eAAe;YAuBf,SAAS;YAST,wBAAwB;IAKtC,OAAO,CAAC,uBAAuB;IAc/B,OAAO,CAAC,qBAAqB;IAU7B,OAAO,CAAC,oBAAoB;IAqB5B,OAAO,CAAC,kBAAkB;IAwB1B,OAAO,CAAC,4BAA4B;IAkBpC,OAAO,CAAC,uBAAuB;IAS/B,OAAO,CAAC,sBAAsB;IAU9B,OAAO,CAAC,qBAAqB;IAI7B,OAAO,CAAC,sBAAsB;YAShB,mBAAmB;IAiBjC,OAAO,CAAC,4BAA4B;IAqB9B,IAAI,CACR,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,OAAO,CAAC,EAAE,oBAAoB;IAuB1B,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;YAatD,cAAc;YAqFd,cAAc;IA0B5B,OAAO,CAAC,uBAAuB;IAyC/B,OAAO,CAAC,6BAA6B;IA4CrC,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS;CAGxD"}
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
@@ -810,6 +810,8 @@ class ElectronBleTransport {
810
810
  this.connectedDevices = new Set();
811
811
  this.deviceProtocol = new Map();
812
812
  this.deviceProtocolHints = new Map();
813
+ this.confirmedProtocolV2 = new Set();
814
+ this.retryableV2Mismatch = new Set();
813
815
  this.deviceMtus = new Map();
814
816
  this.devicePacketCapacities = new Map();
815
817
  this.v1Buffers = new Map();
@@ -1109,8 +1111,16 @@ class ElectronBleTransport {
1109
1111
  }
1110
1112
  });
1111
1113
  }
1112
- createProtocolMismatchError(expected) {
1113
- return hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, `Device protocol mismatch: expected ${expected}, but device did not respond to expected protocol`);
1114
+ createProtocolMismatchError(expected, uuid) {
1115
+ const isStaleV2Bond = expected === 'V2' &&
1116
+ (this.confirmedProtocolV2.has(uuid) || this.retryableV2Mismatch.has(uuid));
1117
+ if (expected === 'V2' && !isStaleV2Bond) {
1118
+ this.retryableV2Mismatch.add(uuid);
1119
+ }
1120
+ else if (isStaleV2Bond) {
1121
+ this.retryableV2Mismatch.delete(uuid);
1122
+ }
1123
+ 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
1124
  }
1115
1125
  createProtocolDetectionError() {
1116
1126
  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 +1139,17 @@ class ElectronBleTransport {
1129
1139
  (_a = this.Log) === null || _a === void 0 ? void 0 : _a.debug(`[Electron BLE] detectProtocol: uuid=${uuid} -> V1 (expected)`);
1130
1140
  return 'V1';
1131
1141
  }
1132
- throw this.createProtocolMismatchError(expectedProtocol);
1142
+ throw this.createProtocolMismatchError(expectedProtocol, uuid);
1133
1143
  }
1134
1144
  if (expectedProtocol === 'V2') {
1135
1145
  if (yield this.probeProtocolV2(uuid)) {
1136
1146
  this.deviceProtocol.set(uuid, 'V2');
1147
+ this.confirmedProtocolV2.add(uuid);
1148
+ this.retryableV2Mismatch.delete(uuid);
1137
1149
  (_b = this.Log) === null || _b === void 0 ? void 0 : _b.debug(`[Electron BLE] detectProtocol: uuid=${uuid} -> V2 (expected)`);
1138
1150
  return 'V2';
1139
1151
  }
1140
- throw this.createProtocolMismatchError(expectedProtocol);
1152
+ throw this.createProtocolMismatchError(expectedProtocol, uuid);
1141
1153
  }
1142
1154
  const probeOrder = protocolHint === 'V2' || this.deviceProtocol.get(uuid) === 'V2' ? ['V2', 'V1'] : ['V1', 'V2'];
1143
1155
  for (let i = 0; i < probeOrder.length; i += 1) {
@@ -1148,6 +1160,10 @@ class ElectronBleTransport {
1148
1160
  const detected = protocol === 'V1' ? yield this.probeProtocolV1(uuid) : yield this.probeProtocolV2(uuid);
1149
1161
  if (detected) {
1150
1162
  this.deviceProtocol.set(uuid, protocol);
1163
+ if (protocol === 'V2') {
1164
+ this.confirmedProtocolV2.add(uuid);
1165
+ this.retryableV2Mismatch.delete(uuid);
1166
+ }
1151
1167
  (_c = this.Log) === null || _c === void 0 ? void 0 : _c.debug(`[Electron BLE] detectProtocol: uuid=${uuid} -> ${protocol}`);
1152
1168
  return protocol;
1153
1169
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@onekeyfe/hd-transport-web-device",
3
- "version": "1.2.0-alpha.142",
3
+ "version": "1.2.0-alpha.144",
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.142",
25
- "@onekeyfe/hd-transport": "1.2.0-alpha.142"
24
+ "@onekeyfe/hd-shared": "1.2.0-alpha.144",
25
+ "@onekeyfe/hd-transport": "1.2.0-alpha.144"
26
26
  },
27
27
  "devDependencies": {
28
- "@onekeyfe/hd-transport-electron": "1.2.0-alpha.142",
28
+ "@onekeyfe/hd-transport-electron": "1.2.0-alpha.144",
29
29
  "@types/w3c-web-usb": "^1.0.6",
30
30
  "@types/web-bluetooth": "^0.0.17"
31
31
  },
32
- "gitHead": "fae9cf5fd2f2a064deab77c32a987f8b989fdd95"
32
+ "gitHead": "6240fc52a40bcad467fece58183a54f1af2631fb"
33
33
  }
@@ -105,6 +105,12 @@ export default class ElectronBleTransport {
105
105
 
106
106
  private deviceProtocolHints: Map<string, ProtocolType> = new Map();
107
107
 
108
+ /** Endpoints that answered a V2 probe in this transport lifetime. Survives disconnect. */
109
+ private confirmedProtocolV2 = new Set<string>();
110
+
111
+ /** First expected-V2 miss for an unconfirmed endpoint; the next miss is a stale bond. */
112
+ private retryableV2Mismatch = new Set<string>();
113
+
108
114
  private deviceMtus: Map<string, number> = new Map();
109
115
 
110
116
  private devicePacketCapacities: Map<string, number> = new Map();
@@ -442,9 +448,20 @@ export default class ElectronBleTransport {
442
448
  }
443
449
  }
444
450
 
445
- private createProtocolMismatchError(expected: ProtocolType) {
451
+ private createProtocolMismatchError(expected: ProtocolType, uuid: string) {
452
+ // Caller `expectedProtocol: 'V2'` is not proof this endpoint already answered.
453
+ // A first-connect or flaky Ping must stay retryable. A later miss after a
454
+ // confirmed V2 answer, or a second miss on the same uuid, is a stale bond.
455
+ const isStaleV2Bond =
456
+ expected === 'V2' &&
457
+ (this.confirmedProtocolV2.has(uuid) || this.retryableV2Mismatch.has(uuid));
458
+ if (expected === 'V2' && !isStaleV2Bond) {
459
+ this.retryableV2Mismatch.add(uuid);
460
+ } else if (isStaleV2Bond) {
461
+ this.retryableV2Mismatch.delete(uuid);
462
+ }
446
463
  return ERRORS.TypedError(
447
- HardwareErrorCode.RuntimeError,
464
+ isStaleV2Bond ? HardwareErrorCode.BleDeviceBondError : HardwareErrorCode.RuntimeError,
448
465
  `Device protocol mismatch: expected ${expected}, but device did not respond to expected protocol`
449
466
  );
450
467
  }
@@ -473,16 +490,18 @@ export default class ElectronBleTransport {
473
490
  this.Log?.debug(`[Electron BLE] detectProtocol: uuid=${uuid} -> V1 (expected)`);
474
491
  return 'V1';
475
492
  }
476
- throw this.createProtocolMismatchError(expectedProtocol);
493
+ throw this.createProtocolMismatchError(expectedProtocol, uuid);
477
494
  }
478
495
 
479
496
  if (expectedProtocol === 'V2') {
480
497
  if (await this.probeProtocolV2(uuid)) {
481
498
  this.deviceProtocol.set(uuid, 'V2');
499
+ this.confirmedProtocolV2.add(uuid);
500
+ this.retryableV2Mismatch.delete(uuid);
482
501
  this.Log?.debug(`[Electron BLE] detectProtocol: uuid=${uuid} -> V2 (expected)`);
483
502
  return 'V2';
484
503
  }
485
- throw this.createProtocolMismatchError(expectedProtocol);
504
+ throw this.createProtocolMismatchError(expectedProtocol, uuid);
486
505
  }
487
506
 
488
507
  // Protocol must be actively probed after connection. Name, PID, and descriptors only
@@ -501,6 +520,10 @@ export default class ElectronBleTransport {
501
520
  protocol === 'V1' ? await this.probeProtocolV1(uuid) : await this.probeProtocolV2(uuid);
502
521
  if (detected) {
503
522
  this.deviceProtocol.set(uuid, protocol);
523
+ if (protocol === 'V2') {
524
+ this.confirmedProtocolV2.add(uuid);
525
+ this.retryableV2Mismatch.delete(uuid);
526
+ }
504
527
  this.Log?.debug(`[Electron BLE] detectProtocol: uuid=${uuid} -> ${protocol}`);
505
528
  return protocol;
506
529
  }