@onekeyfe/hd-transport-web-device 1.2.0-alpha.2 → 1.2.0-alpha.20

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.
@@ -1,4 +1,5 @@
1
1
  import transport, { PROTOCOL_V2_CHANNEL_BLE_UART, bytesToHex } from '@onekeyfe/hd-transport';
2
+ import { HardwareErrorCode } from '@onekeyfe/hd-shared';
2
3
 
3
4
  import ElectronBleTransport from '../src/electron-ble-transport';
4
5
 
@@ -28,21 +29,25 @@ const protocolV1Schema = {
28
29
 
29
30
  const protocolV2Schema = {
30
31
  nested: {
31
- GetProtoVersion: {
32
+ ProtocolInfoRequest: {
32
33
  fields: {},
33
34
  },
34
- ProtoVersion: {
35
+ ProtocolInfo: {
35
36
  fields: {
36
- major_version: {
37
+ version: {
37
38
  type: 'uint32',
38
39
  id: 1,
39
40
  },
40
- minor_version: {
41
+ supported_messages: {
42
+ rule: 'repeated',
41
43
  type: 'uint32',
42
44
  id: 2,
45
+ options: {
46
+ packed: false,
47
+ },
43
48
  },
44
- patch_version: {
45
- type: 'uint32',
49
+ protobuf_definition: {
50
+ type: 'string',
46
51
  id: 3,
47
52
  },
48
53
  },
@@ -65,8 +70,8 @@ const protocolV2Schema = {
65
70
  },
66
71
  MessageType: {
67
72
  values: {
68
- MessageType_GetProtoVersion: 60200,
69
- MessageType_ProtoVersion: 60201,
73
+ MessageType_ProtocolInfoRequest: 60200,
74
+ MessageType_ProtocolInfo: 60201,
70
75
  MessageType_Ping: 60206,
71
76
  MessageType_Success: 60207,
72
77
  },
@@ -241,6 +246,95 @@ describe('ElectronBleTransport protocol detection', () => {
241
246
  );
242
247
  expect(nobleBle.write).toHaveBeenCalledTimes(1);
243
248
  expect(transport.getProtocolType(device.id)).toBe('V2');
249
+ await expect(transport.call(device.id, 'Ping', { message: 'after-probe' })).resolves.toEqual({
250
+ type: 'Success',
251
+ message: { message: 'ok' },
252
+ });
253
+ const sentSeqs = nobleBle.write.mock.calls.map(([, hex]) =>
254
+ Number.parseInt(hex.slice(12, 14), 16)
255
+ );
256
+ expect(sentSeqs).toEqual([1, 2]);
257
+ } finally {
258
+ await transport.release(device.id);
259
+ }
260
+ });
261
+
262
+ test('rejects the active Protocol V2 reader when pairing is rejected', async () => {
263
+ const device = { id: 'pairing-rejected-pro2-id', name: 'OneKey Pro 2' };
264
+ const nobleBle = createNobleBle(device);
265
+ let notificationHandler: ((deviceId: string, data: string) => void) | undefined;
266
+ let pairingRejected = false;
267
+ const probeResponse = ProtocolV2.encodeFrame(
268
+ schemas,
269
+ 'Success',
270
+ { message: 'ok' },
271
+ { router: PROTOCOL_V2_CHANNEL_BLE_UART }
272
+ );
273
+
274
+ nobleBle.onNotification.mockImplementation(handler => {
275
+ notificationHandler = handler;
276
+ return jest.fn();
277
+ });
278
+ nobleBle.write.mockImplementation(() => {
279
+ setTimeout(
280
+ () =>
281
+ notificationHandler?.(
282
+ device.id,
283
+ pairingRejected ? 'PAIRING_REJECTED' : bytesToHex(probeResponse)
284
+ ),
285
+ 0
286
+ );
287
+ return Promise.resolve();
288
+ });
289
+ const transport = configureTransport(nobleBle);
290
+
291
+ try {
292
+ await transport.acquire({ uuid: device.id });
293
+ pairingRejected = true;
294
+
295
+ await expect(
296
+ transport.call(device.id, 'Ping', { message: 'pairing' }, { timeoutMs: 50 })
297
+ ).rejects.toMatchObject({ errorCode: HardwareErrorCode.BleDeviceBondedCanceled });
298
+ } finally {
299
+ await transport.release(device.id);
300
+ }
301
+ });
302
+
303
+ test('rebuilds the active link when Core acquires the same device again', async () => {
304
+ const device = { id: 'repeated-acquire-pro2-id', name: 'OneKey Pro 2' };
305
+ const nobleBle = createNobleBle(device);
306
+ let notificationHandler: ((deviceId: string, data: string) => void) | undefined;
307
+ const response = ProtocolV2.encodeFrame(
308
+ schemas,
309
+ 'Success',
310
+ { message: 'ok' },
311
+ { router: PROTOCOL_V2_CHANNEL_BLE_UART }
312
+ );
313
+
314
+ nobleBle.onNotification.mockImplementation(handler => {
315
+ notificationHandler = handler;
316
+ return jest.fn();
317
+ });
318
+ nobleBle.write.mockImplementation(() => {
319
+ setTimeout(() => notificationHandler?.(device.id, bytesToHex(response)), 0);
320
+ return Promise.resolve();
321
+ });
322
+ const transport = configureTransport(nobleBle);
323
+
324
+ try {
325
+ await transport.acquire({ uuid: device.id });
326
+ await transport.acquire({ uuid: device.id, expectedProtocol: 'V2' });
327
+ await expect(
328
+ transport.call(device.id, 'Ping', { message: 'after-reacquire' })
329
+ ).resolves.toEqual({
330
+ type: 'Success',
331
+ message: { message: 'ok' },
332
+ });
333
+
334
+ const sentSeqs = nobleBle.write.mock.calls.map(([, hex]) =>
335
+ Number.parseInt(hex.slice(12, 14), 16)
336
+ );
337
+ expect(sentSeqs).toEqual([1, 2]);
244
338
  } finally {
245
339
  await transport.release(device.id);
246
340
  }
@@ -0,0 +1,88 @@
1
+ import transport, { ProtocolV2FrameAssembler } from '@onekeyfe/hd-transport';
2
+
3
+ import WebUsbTransport from '../src/webusb';
4
+
5
+ const schema = {
6
+ nested: {
7
+ Ping: { fields: { message: { type: 'string', id: 1 } } },
8
+ Success: { fields: { message: { type: 'string', id: 1 } } },
9
+ MessageType: {
10
+ values: {
11
+ MessageType_Ping: 60206,
12
+ MessageType_Success: 60207,
13
+ },
14
+ },
15
+ },
16
+ };
17
+
18
+ describe('WebUsbTransport Protocol V2 timeout recovery', () => {
19
+ test('resets the connection between a failed V1 probe and the V2 probe', async () => {
20
+ const webusb = new WebUsbTransport() as any;
21
+ const path = 'pro2-webusb';
22
+ const events: string[] = [];
23
+ webusb.probeProtocolV1 = jest.fn().mockImplementation(() => {
24
+ events.push('probe-v1');
25
+ return Promise.resolve(false);
26
+ });
27
+ webusb.resetConnectionAfterProbe = jest.fn().mockImplementation(() => {
28
+ events.push('reset');
29
+ return Promise.resolve();
30
+ });
31
+ webusb.probeProtocolV2 = jest.fn().mockImplementation(() => {
32
+ events.push('probe-v2');
33
+ return Promise.resolve(true);
34
+ });
35
+
36
+ await expect(webusb.detectProtocol(path)).resolves.toBe('V2');
37
+
38
+ expect(events).toEqual(['probe-v1', 'reset', 'probe-v2']);
39
+ expect(webusb.deviceProtocol.get(path)).toBe('V2');
40
+ });
41
+
42
+ test('invalidates and resets the cached connection before another call can start', async () => {
43
+ const webusb = new WebUsbTransport() as any;
44
+ const path = 'pro2-webusb';
45
+ webusb.messages = transport.parseConfigure(schema);
46
+ webusb.messagesV2 = transport.parseConfigure(schema);
47
+ webusb.protocolV2Assemblers.set(path, new ProtocolV2FrameAssembler());
48
+ webusb.transferOutOnce = jest.fn().mockResolvedValue(undefined);
49
+ webusb.receiveProtocolV2Frame = jest.fn(() => new Promise<void>(() => {}));
50
+ webusb.resetConnectionAfterProbe = jest.fn().mockImplementation(() => {
51
+ webusb.protocolV2Sessions.delete(path);
52
+ webusb.protocolV2ReadTimeouts.delete(path);
53
+ webusb.protocolV2Assemblers.get(path)?.reset();
54
+ });
55
+
56
+ await expect(
57
+ webusb.callProtocolV2(path, 'Ping', { message: 'timeout' }, { timeoutMs: 10 })
58
+ ).rejects.toThrow('timeout');
59
+
60
+ expect(webusb.resetConnectionAfterProbe).toHaveBeenCalledWith(path);
61
+ expect(webusb.protocolV2Sessions.has(path)).toBe(false);
62
+ });
63
+
64
+ test('resets a stalled write while retaining the device sequence cursor', async () => {
65
+ const webusb = new WebUsbTransport() as any;
66
+ const path = 'pro2-webusb';
67
+ webusb.messages = transport.parseConfigure(schema);
68
+ webusb.messagesV2 = transport.parseConfigure(schema);
69
+ webusb.protocolV2WriteTimeoutMs = 10;
70
+ webusb.protocolV2Assemblers.set(path, new ProtocolV2FrameAssembler());
71
+ webusb.transferOutOnce = jest.fn(() => new Promise(() => {}));
72
+ webusb.receiveProtocolV2Frame = jest.fn();
73
+ webusb.resetConnectionAfterProbe = jest.fn().mockImplementation(() => {
74
+ webusb.protocolV2Sessions.delete(path);
75
+ webusb.protocolV2ReadTimeouts.delete(path);
76
+ webusb.protocolV2Assemblers.get(path)?.reset();
77
+ });
78
+
79
+ await expect(
80
+ webusb.callProtocolV2(path, 'Ping', { message: 'timeout' }, { timeoutMs: 10 })
81
+ ).rejects.toThrow('Protocol V2 write timeout after 10ms for Ping');
82
+
83
+ expect(webusb.resetConnectionAfterProbe).toHaveBeenCalledWith(path);
84
+ expect(webusb.protocolV2Sequences.has(path)).toBe(true);
85
+ expect(webusb.protocolV2Sessions.has(path)).toBe(false);
86
+ expect(webusb.receiveProtocolV2Frame).not.toHaveBeenCalled();
87
+ });
88
+ });
@@ -28,8 +28,7 @@ export default class ElectronBleTransport {
28
28
  private v2Assemblers;
29
29
  private v2FrameQueues;
30
30
  private v2FramePromises;
31
- private activeProtocolV2Call;
32
- private nextProtocolV2CallToken;
31
+ private protocolV2Links;
33
32
  private notificationCleanups;
34
33
  private disconnectCleanups;
35
34
  private notificationTokens;
@@ -62,19 +61,20 @@ export default class ElectronBleTransport {
62
61
  private probeProtocolV1;
63
62
  private probeProtocolV2;
64
63
  private writeWithChunking;
65
- private writeWithRetry;
64
+ private writeOnce;
66
65
  private handleNotification;
67
66
  private handleProtocolV2Notification;
68
67
  private getProtocolV2FrameQueue;
69
68
  private resolveProtocolV2Frame;
70
69
  private rejectAllProtocolV2Frames;
71
70
  private resetProtocolV2Frames;
72
- private isActiveProtocolV2Call;
71
+ private rejectProtocolV2Frames;
73
72
  private readProtocolV2Frame;
74
73
  private handleProtocolV1Notification;
75
74
  call(uuid: string, name: string, data: Record<string, unknown>, options?: TransportCallOptions): Promise<import("@onekeyfe/hd-transport").MessageFromOneKey>;
76
75
  private callProtocolV1;
77
76
  private callProtocolV2;
77
+ private createProtocolV2Adapter;
78
78
  private processProtocolV1Notification;
79
79
  getProtocolType(path: string): ProtocolType | undefined;
80
80
  }
@@ -1 +1 @@
1
- {"version":3,"file":"electron-ble-transport.d.ts","sourceRoot":"","sources":["../src/electron-ble-transport.ts"],"names":[],"mappings":";AAmBA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAClE,OAAO,KAAK,EAAE,gBAAgB,EAAE,YAAY,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AACnG,OAAO,KAAK,YAAY,MAAM,QAAQ,CAAC;AAevC,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;CACjC,CAAC;AAuCF,MAAM,CAAC,OAAO,OAAO,oBAAoB;IACvC,OAAO,CAAC,SAAS,CAA0D;IAE3E,OAAO,CAAC,WAAW,CAA0D;IAE7E,IAAI,SAA0B;IAE9B,UAAU,UAAS;IAEnB,UAAU,EAAE,QAAQ,CAAC,UAAU,GAAG,MAAM,CAAC,GAAG,IAAI,CAAQ;IAExD,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,SAAS,CAAsE;IAEvF,OAAO,CAAC,YAAY,CAAoD;IAExE,OAAO,CAAC,aAAa,CAAwC;IAE7D,OAAO,CAAC,eAAe,CAAgD;IAEvE,OAAO,CAAC,oBAAoB,CAAgD;IAE5E,OAAO,CAAC,uBAAuB,CAAK;IAEpC,OAAO,CAAC,oBAAoB,CAAsC;IAElE,OAAO,CAAC,kBAAkB,CAAsC;IAEhE,OAAO,CAAC,kBAAkB,CAAkC;IAE5D,OAAO,CAAC,qBAAqB,CAAK;IAElC,OAAO,CAAC,oBAAoB;IA+B5B,OAAO,CAAC,kBAAkB;IA0B1B,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE,OAAO,CAAC,EAAE,YAAY;IAcxC,SAAS,CAAC,UAAU,EAAE,GAAG;IAKzB,mBAAmB,CAAC,UAAU,EAAE,GAAG;IAK7B,MAAM;IAIN,SAAS,IAAI,OAAO,CAAC,gBAAgB,EAAE,CAAC;IAqBxC,OAAO,CAAC,KAAK,EAAE,eAAe;;;;;;;;;;;IAuF9B,OAAO,CAAC,EAAE,EAAE,MAAM;IAexB,OAAO,CAAC,2BAA2B;IAOnC,OAAO,CAAC,4BAA4B;IAOpC,OAAO,CAAC,kBAAkB;YAMZ,cAAc;IA+C5B,OAAO,CAAC,8BAA8B;YAgBxB,iCAAiC;YAoCjC,eAAe;YAgBf,eAAe;YAuBf,iBAAiB;YAsBjB,cAAc;IA4B5B,OAAO,CAAC,kBAAkB;IAuB1B,OAAO,CAAC,4BAA4B;IA2BpC,OAAO,CAAC,uBAAuB;IAS/B,OAAO,CAAC,sBAAsB;IAU9B,OAAO,CAAC,yBAAyB;IAQjC,OAAO,CAAC,qBAAqB;IAK7B,OAAO,CAAC,sBAAsB;YAIhB,mBAAmB;IAiBjC,OAAO,CAAC,4BAA4B;IAgB9B,IAAI,CACR,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,OAAO,CAAC,EAAE,oBAAoB;YA+BlB,cAAc;YAuEd,cAAc;IAmF5B,OAAO,CAAC,6BAA6B;IAsCrC,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":";AAoBA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAClE,OAAO,KAAK,EAAE,gBAAgB,EAAE,YAAY,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AACnG,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;CACjC,CAAC;AAqCF,MAAM,CAAC,OAAO,OAAO,oBAAoB;IACvC,OAAO,CAAC,SAAS,CAA0D;IAE3E,OAAO,CAAC,WAAW,CAA0D;IAE7E,IAAI,SAA0B;IAE9B,UAAU,UAAS;IAEnB,UAAU,EAAE,QAAQ,CAAC,UAAU,GAAG,MAAM,CAAC,GAAG,IAAI,CAAQ;IAExD,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,SAAS,CAAsE;IAEvF,OAAO,CAAC,YAAY,CAAoD;IAExE,OAAO,CAAC,aAAa,CAAwC;IAE7D,OAAO,CAAC,eAAe,CAAgD;IAEvE,OAAO,CAAC,eAAe,CAmBpB;IAEH,OAAO,CAAC,oBAAoB,CAAsC;IAElE,OAAO,CAAC,kBAAkB,CAAsC;IAEhE,OAAO,CAAC,kBAAkB,CAAkC;IAE5D,OAAO,CAAC,qBAAqB,CAAK;IAElC,OAAO,CAAC,oBAAoB;IA+B5B,OAAO,CAAC,kBAAkB;IA0B1B,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE,OAAO,CAAC,EAAE,YAAY;IAcxC,SAAS,CAAC,UAAU,EAAE,GAAG;IAKzB,mBAAmB,CAAC,UAAU,EAAE,GAAG;IAO7B,MAAM;IAIN,SAAS,IAAI,OAAO,CAAC,gBAAgB,EAAE,CAAC;IAqBxC,OAAO,CAAC,KAAK,EAAE,eAAe;;;;;;;;;;;IA0F9B,OAAO,CAAC,EAAE,EAAE,MAAM;IAgBxB,OAAO,CAAC,2BAA2B;IAOnC,OAAO,CAAC,4BAA4B;IAOpC,OAAO,CAAC,kBAAkB;YAMZ,cAAc;IA8C5B,OAAO,CAAC,8BAA8B;YAgBxB,iCAAiC;YAqCjC,eAAe;YAgBf,eAAe;YAuBf,iBAAiB;YAsBjB,SAAS;IASvB,OAAO,CAAC,kBAAkB;IAwB1B,OAAO,CAAC,4BAA4B;IAkBpC,OAAO,CAAC,uBAAuB;IAS/B,OAAO,CAAC,sBAAsB;IAU9B,OAAO,CAAC,yBAAyB;IAQjC,OAAO,CAAC,qBAAqB;IAK7B,OAAO,CAAC,sBAAsB;YAShB,mBAAmB;IAiBjC,OAAO,CAAC,4BAA4B;IAgB9B,IAAI,CACR,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,OAAO,CAAC,EAAE,oBAAoB;YA2BlB,cAAc;YAuEd,cAAc;IA6B5B,OAAO,CAAC,uBAAuB;IA0C/B,OAAO,CAAC,6BAA6B;IAsCrC,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS;CAGxD"}
package/dist/index.d.ts CHANGED
@@ -4,6 +4,9 @@ import { Deferred } from '@onekeyfe/hd-shared';
4
4
  import { DesktopAPI } from '@onekeyfe/hd-transport-electron';
5
5
  import EventEmitter from 'events';
6
6
 
7
+ /**
8
+ * Device information with path and WebUSB device instance
9
+ */
7
10
  interface DeviceInfo extends OneKeyDeviceInfoBase {
8
11
  path: string;
9
12
  device: USBDevice;
@@ -11,13 +14,26 @@ interface DeviceInfo extends OneKeyDeviceInfoBase {
11
14
  }
12
15
  declare class WebUsbTransport {
13
16
  messages: ReturnType<typeof _onekeyfe_hd_transport__default.parseConfigure> | undefined;
17
+ /** Protobuf schema for Protocol V2 transports. */
14
18
  messagesV2: ReturnType<typeof _onekeyfe_hd_transport__default.parseConfigure> | undefined;
19
+ /** Per-path protocol type detected by active wire-level probe. */
15
20
  private deviceProtocol;
16
21
  private deviceProtocolHints;
22
+ /** Per-device Protocol V2 assembler that retains extra frames from one read. */
17
23
  private protocolV2Assemblers;
24
+ /** Per-device Protocol V2 session that keeps sequence numbers monotonic. */
18
25
  private protocolV2Sessions;
26
+ /** Sequence cursors survive ordinary reconnects and cached session rebuilds. */
27
+ private protocolV2Sequences;
28
+ /** Read timeout for the current Protocol V2 call, consumed by cached readFrame. */
19
29
  private protocolV2ReadTimeouts;
30
+ private protocolV2WriteTimeoutMs;
31
+ /** Per-path USB endpoint / interface numbers (discovered from USB descriptors) */
20
32
  private deviceEndpoints;
33
+ /**
34
+ * Early Pro2 boards have no USB serial number. Assign a session-stable mock path per
35
+ * USBDevice instance so discovery retains them; reconnecting creates a new instance/path.
36
+ */
21
37
  private mockSerialPaths;
22
38
  private mockSerialCounter;
23
39
  name: string;
@@ -25,24 +41,75 @@ declare class WebUsbTransport {
25
41
  configured: boolean;
26
42
  Log?: any;
27
43
  usb?: USB;
44
+ /**
45
+ * Cached list of connected devices
46
+ * This is essential for maintaining device references between operations
47
+ */
28
48
  deviceList: Array<DeviceInfo>;
29
49
  configurationId: number;
30
50
  endpointId: number;
31
51
  interfaceId: number;
52
+ /**
53
+ * Initialize WebUSB transport
54
+ */
32
55
  init(logger: any): void;
56
+ /**
57
+ * Configure Protocol V1 protobuf schema (legacy chunked 0x3F framing).
58
+ */
33
59
  configure(signedData: any): void;
60
+ /**
61
+ * Cache the Protocol V2 protobuf schema.
62
+ */
34
63
  configureProtocolV2(signedData: any): void;
64
+ /**
65
+ * Request user to select a device
66
+ * This method must be called in response to a user action
67
+ * to comply with WebUSB security requirements
68
+ */
35
69
  promptDeviceAccess(): Promise<USBDevice | null>;
70
+ /**
71
+ * Enumerate already connected devices
72
+ * This method only returns devices that are already authorized by the browser
73
+ * It does NOT prompt the user to select a device
74
+ */
36
75
  enumerate(): Promise<DeviceInfo[]>;
76
+ /**
77
+ * Use the USB serial as the device path, falling back to a session-stable mock path.
78
+ */
37
79
  private getDevicePath;
80
+ /**
81
+ * Get list of connected devices
82
+ */
38
83
  getConnectedDevices(): Promise<DeviceInfo[]>;
84
+ /**
85
+ * Acquire device control
86
+ */
39
87
  acquire(input: AcquireInput): Promise<string | undefined>;
88
+ /**
89
+ * Determine protocol type after connect.
90
+ * Probe Protocol V1 first with Initialize. If it does not answer in time,
91
+ * fall back to a Protocol V2 Ping probe.
92
+ */
40
93
  private createProtocolMismatchError;
41
94
  private createProtocolDetectionError;
42
95
  private detectProtocol;
96
+ /**
97
+ * Find device by path
98
+ */
43
99
  findDevice(path: string): Promise<USBDevice>;
100
+ /**
101
+ * Connect to device with retry mechanism
102
+ */
44
103
  connect(path: string, first: boolean): Promise<void>;
104
+ /**
105
+ * Discover vendor-class (0xFF) interface and its IN/OUT endpoint numbers from USB descriptors.
106
+ * Falls back to legacy hardcoded values if no vendor interface is found.
107
+ */
45
108
  private discoverEndpoints;
109
+ /**
110
+ * Connect to specific device.
111
+ * Discovers interface/endpoint numbers from USB descriptors on first connection.
112
+ */
46
113
  connectToDevice(path: string, first: boolean): Promise<void>;
47
114
  private closeOpenDevice;
48
115
  private clearEndpointHalt;
@@ -53,17 +120,37 @@ declare class WebUsbTransport {
53
120
  private getTransferInData;
54
121
  private toArrayBuffer;
55
122
  private transferOutWithRetry;
123
+ private transferOutOnce;
56
124
  private transferInWithRetry;
57
125
  private resetConnectionAfterProbe;
58
126
  private withProtocolReadTimeout;
59
127
  private probeProtocolV1;
60
128
  private probeProtocolV2;
129
+ /**
130
+ * Call device method — branches to Protocol V1 or Protocol V2 based on active probe.
131
+ */
61
132
  call(path: string, name: string, data: Record<string, unknown>, options?: TransportCallOptions): Promise<_onekeyfe_hd_transport.MessageFromOneKey>;
62
133
  private callProtocolV1;
134
+ /**
135
+ * Send/receive a single call over Protocol V2 (0x5A framing).
136
+ *
137
+ * Encoding: protobuf message → 2-byte LE messageTypeId + pb bytes → Protocol V2 frame
138
+ * Decoding: Protocol V2 frame → messageTypeId + pb bytes → protobuf message
139
+ */
63
140
  private callProtocolV2;
64
141
  private receiveProtocolV2Frame;
142
+ /**
143
+ * Receive data from device
144
+ */
65
145
  receiveData(path: string, timeoutMs?: number): Promise<string>;
146
+ /**
147
+ * Release device
148
+ */
66
149
  release(path: string): Promise<void>;
150
+ /**
151
+ * Expose the detected protocol type for a given device path.
152
+ * Used by upper layers (e.g. TransportManager) to select the correct schema.
153
+ */
67
154
  getProtocolType(path: string): ProtocolType | undefined;
68
155
  }
69
156
 
@@ -77,6 +164,12 @@ type BleAcquireInput = {
77
164
  forceCleanRunPromise?: boolean;
78
165
  expectedProtocol?: ProtocolType;
79
166
  };
167
+ /**
168
+ * Desktop Electron BLE transport with automatic Protocol V1/V2 detection.
169
+ *
170
+ * Protocol V1 devices continue using chunked packets. Protocol V2 is detected
171
+ * after a Protocol V1 Initialize timeout by probing Protocol V2 Ping.
172
+ */
80
173
  declare class ElectronBleTransport {
81
174
  private _messages;
82
175
  private _messagesV2;
@@ -92,8 +185,7 @@ declare class ElectronBleTransport {
92
185
  private v2Assemblers;
93
186
  private v2FrameQueues;
94
187
  private v2FramePromises;
95
- private activeProtocolV2Call;
96
- private nextProtocolV2CallToken;
188
+ private protocolV2Links;
97
189
  private notificationCleanups;
98
190
  private disconnectCleanups;
99
191
  private notificationTokens;
@@ -126,19 +218,20 @@ declare class ElectronBleTransport {
126
218
  private probeProtocolV1;
127
219
  private probeProtocolV2;
128
220
  private writeWithChunking;
129
- private writeWithRetry;
221
+ private writeOnce;
130
222
  private handleNotification;
131
223
  private handleProtocolV2Notification;
132
224
  private getProtocolV2FrameQueue;
133
225
  private resolveProtocolV2Frame;
134
226
  private rejectAllProtocolV2Frames;
135
227
  private resetProtocolV2Frames;
136
- private isActiveProtocolV2Call;
228
+ private rejectProtocolV2Frames;
137
229
  private readProtocolV2Frame;
138
230
  private handleProtocolV1Notification;
139
231
  call(uuid: string, name: string, data: Record<string, unknown>, options?: TransportCallOptions): Promise<_onekeyfe_hd_transport.MessageFromOneKey>;
140
232
  private callProtocolV1;
141
233
  private callProtocolV2;
234
+ private createProtocolV2Adapter;
142
235
  private processProtocolV1Notification;
143
236
  getProtocolType(path: string): ProtocolType | undefined;
144
237
  }